comparison src/logerr.c @ 5526:b1a3d9055662 draft

privsep: Allow logfile reopening in a chroot Now that only the privileged actioneer does the actual logging we can safely reopen the file we are logging to. This also closes and re-opens the syslog connection.
author Roy Marples <roy@marples.name>
date Fri, 30 Oct 2020 14:19:16 +0000
parents 26b5d9bc2985
children 071a9ea18363
comparison
equal deleted inserted replaced
5525:26b5d9bc2985 5526:b1a3d9055662
46 #ifdef SMALL 46 #ifdef SMALL
47 #undef LOGERR_TAG 47 #undef LOGERR_TAG
48 #endif 48 #endif
49 49
50 /* syslog protocol is 1k message max, RFC 3164 section 4.1 */ 50 /* syslog protocol is 1k message max, RFC 3164 section 4.1 */
51 #define LOGERR_SYSLOGBUF 1024 + sizeof(int) 51 #define LOGERR_SYSLOGBUF 1024 + sizeof(int) + sizeof(pid_t)
52 52
53 #define UNUSED(a) (void)(a) 53 #define UNUSED(a) (void)(a)
54 54
55 struct logctx { 55 struct logctx {
56 char log_buf[BUFSIZ]; 56 char log_buf[BUFSIZ];
57 unsigned int log_opts; 57 unsigned int log_opts;
58 int log_syslogfd; 58 int log_fd;
59 pid_t log_pid;
59 #ifndef SMALL 60 #ifndef SMALL
60 FILE *log_file; 61 FILE *log_file;
61 #ifdef LOGERR_TAG 62 #ifdef LOGERR_TAG
62 const char *log_tag; 63 const char *log_tag;
63 #endif 64 #endif
65 }; 66 };
66 67
67 static struct logctx _logctx = { 68 static struct logctx _logctx = {
68 /* syslog style, but without the hostname or tag. */ 69 /* syslog style, but without the hostname or tag. */
69 .log_opts = LOGERR_LOG | LOGERR_LOG_DATE | LOGERR_LOG_PID, 70 .log_opts = LOGERR_LOG | LOGERR_LOG_DATE | LOGERR_LOG_PID,
70 .log_syslogfd = -1, 71 .log_fd = -1,
72 .log_pid = 0,
71 }; 73 };
72 74
73 #if defined(__linux__) 75 #if defined(__linux__)
74 /* Poor man's getprogname(3). */ 76 /* Poor man's getprogname(3). */
75 static char *_logprog; 77 static char *_logprog;
153 #endif 155 #endif
154 156
155 log_pid = ((stream == stderr && ctx->log_opts & LOGERR_ERR_PID) || 157 log_pid = ((stream == stderr && ctx->log_opts & LOGERR_ERR_PID) ||
156 (stream != stderr && ctx->log_opts & LOGERR_LOG_PID)); 158 (stream != stderr && ctx->log_opts & LOGERR_LOG_PID));
157 if (log_pid) { 159 if (log_pid) {
158 if ((e = fprintf(stream, "[%d]", getpid())) == -1) 160 pid_t pid;
161
162 if (ctx->log_pid == 0)
163 pid = getpid();
164 else
165 pid = ctx->log_pid;
166 if ((e = fprintf(stream, "[%d]", pid)) == -1)
159 return -1; 167 return -1;
160 len += e; 168 len += e;
161 } 169 }
162 170
163 #ifdef LOGERR_TAG 171 #ifdef LOGERR_TAG
204 vlogmessage(int pri, const char *fmt, va_list args) 212 vlogmessage(int pri, const char *fmt, va_list args)
205 { 213 {
206 struct logctx *ctx = &_logctx; 214 struct logctx *ctx = &_logctx;
207 int len = 0; 215 int len = 0;
208 216
209 if (ctx->log_syslogfd != -1) { 217 if (ctx->log_fd != -1) {
210 char buf[LOGERR_SYSLOGBUF]; 218 char buf[LOGERR_SYSLOGBUF];
219 pid_t pid;
211 220
212 memcpy(buf, &pri, sizeof(pri)); 221 memcpy(buf, &pri, sizeof(pri));
213 len = vsnprintf(buf + sizeof(pri), sizeof(buf) - sizeof(pri), 222 pid = getpid();
223 memcpy(buf + sizeof(pri), &pid, sizeof(pid));
224 len = vsnprintf(buf + sizeof(pri) + sizeof(pid),
225 sizeof(buf) - sizeof(pri) - sizeof(pid),
214 fmt, args); 226 fmt, args);
215 if (len != -1) 227 if (len != -1)
216 len = (int)write(ctx->log_syslogfd, buf, 228 len = (int)write(ctx->log_fd, buf,
217 ((size_t)++len) + sizeof(pri)); 229 ((size_t)++len) + sizeof(pri) + sizeof(pid));
218 return len; 230 return len;
219 } 231 }
220 232
221 if (ctx->log_opts & LOGERR_ERR && 233 if (ctx->log_opts & LOGERR_ERR &&
222 (pri <= LOG_ERR || 234 (pri <= LOG_ERR ||
349 vlogmessage(LOG_ERR, fmt, args); 361 vlogmessage(LOG_ERR, fmt, args);
350 va_end(args); 362 va_end(args);
351 } 363 }
352 364
353 int 365 int
354 loggetsyslogfd(void) 366 loggetfd(void)
355 { 367 {
356 struct logctx *ctx = &_logctx; 368 struct logctx *ctx = &_logctx;
357 369
358 return ctx->log_syslogfd; 370 return ctx->log_fd;
359 } 371 }
360 372
361 void 373 void
362 logsetsyslogfd(int fd) 374 logsetfd(int fd)
363 { 375 {
364 struct logctx *ctx = &_logctx; 376 struct logctx *ctx = &_logctx;
365 377
366 ctx->log_syslogfd = fd; 378 ctx->log_fd = fd;
379 #ifndef SMALL
380 if (fd != -1 && ctx->log_file != NULL) {
381 fclose(ctx->log_file);
382 ctx->log_file = NULL;
383 }
384 #endif
367 } 385 }
368 386
369 int 387 int
370 loghandlesyslogfd(int fd) 388 logreadfd(int fd)
371 { 389 {
390 struct logctx *ctx = &_logctx;
372 char buf[LOGERR_SYSLOGBUF]; 391 char buf[LOGERR_SYSLOGBUF];
373 int len, pri; 392 int len, pri;
374 393
375 len = (int)read(fd, buf, sizeof(buf)); 394 len = (int)read(fd, buf, sizeof(buf));
376 if (len == -1) 395 if (len == -1)
377 return -1; 396 return -1;
378 397
379 /* Ensure we have pri and a terminator */ 398 /* Ensure we have pri, pid and a terminator */
380 if (len < (int)sizeof(pri) + 1 || buf[len - 1] != '\0') { 399 if (len < (int)(sizeof(pri) + sizeof(pid_t) + 1) ||
400 buf[len - 1] != '\0')
401 {
381 errno = EINVAL; 402 errno = EINVAL;
382 return -1; 403 return -1;
383 } 404 }
384 405
385 memcpy(&pri, buf, sizeof(pri)); 406 memcpy(&pri, buf, sizeof(pri));
386 logmessage(pri, "%s", buf + sizeof(pri)); 407 memcpy(&ctx->log_pid, buf + sizeof(pri), sizeof(ctx->log_pid));
408 logmessage(pri, "%s", buf + sizeof(pri) + sizeof(ctx->log_pid));
409 ctx->log_pid = 0;
387 return len; 410 return len;
388 } 411 }
389 412
390 unsigned int 413 unsigned int
391 loggetopts(void) 414 loggetopts(void)