diff --git a/logsrvd/eventlog.c b/logsrvd/eventlog.c index 8a76ebfa1..d35fc93b9 100644 --- a/logsrvd/eventlog.c +++ b/logsrvd/eventlog.c @@ -397,26 +397,6 @@ bad: debug_return_str(NULL); } -/* - * We do an openlog(3)/closelog(3) for each message because some - * authentication methods (notably PAM) use syslog(3) for their - * own nefarious purposes and may call openlog(3) and closelog(3). - * XXX - no longer need openlog/closelog dance, move openlog call - */ -static void -mysyslog(int pri, const char *fmt, ...) -{ - va_list ap; - debug_decl(mysyslog, SUDO_DEBUG_UTIL); - - openlog("sudo", 0, logsrvd_conf_syslog_facility()); - va_start(ap, fmt); - vsyslog(pri, fmt, ap); - va_end(ap); - closelog(); - debug_return; -} - /* * Log a message to syslog, pre-pending the username and splitting the * message into parts if it is longer than syslog_maxlen. @@ -457,7 +437,7 @@ do_syslog_sudo(int pri, const char *reason, const struct iolog_details *details) save = *tmp; *tmp = '\0'; - mysyslog(pri, fmt, details->submituser, p); + syslog(pri, fmt, details->submituser, p); *tmp = save; /* restore saved character */ @@ -465,7 +445,7 @@ do_syslog_sudo(int pri, const char *reason, const struct iolog_details *details) for (p = tmp; *p == ' '; p++) continue; } else { - mysyslog(pri, fmt, details->submituser, p); + syslog(pri, fmt, details->submituser, p); p += len; } fmt = _("%8s : (command continued) %s"); @@ -496,7 +476,7 @@ do_syslog_json(int pri, ClientMessage__TypeCase event_type, const char *reason, /* Syslog it with a @cee: prefix */ /* TODO: use logsrvd_conf_syslog_maxlen() to break up long messages. */ - mysyslog(pri, "@cee:{%s }", json_str); + syslog(pri, "@cee:{%s }", json_str); free(json_str); debug_return_bool(true); } @@ -556,24 +536,16 @@ do_logfile_sudo(const char *reason, const struct iolog_details *details) { const char *timefmt = logsrvd_conf_logfile_time_format(); const char *logfile = logsrvd_conf_logfile_path(); + FILE *fp = logsrvd_conf_logfile_stream(); char *logline, timebuf[8192], *timestr = NULL; struct tm *timeptr; bool ret = false; - mode_t oldmask; - FILE *fp; + debug_decl(do_logfile_sudo, SUDO_DEBUG_UTIL); if ((logline = new_logline(reason, NULL, details)) == NULL) debug_return_bool(false); - oldmask = umask(S_IRWXG|S_IRWXO); - fp = fopen(logfile, "a"); - (void) umask(oldmask); - if (fp == NULL) { - sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO, - "unable to open log file %s", logfile); - goto done; - } if (!sudo_lock_file(fileno(fp), SUDO_LOCK)) { sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO, "unable to lock log file %s", logfile); @@ -599,9 +571,8 @@ do_logfile_sudo(const char *reason, const struct iolog_details *details) ret = true; done: - if (fp != NULL) - (void) fclose(fp); free(logline); + (void)sudo_lock_file(fileno(fp), SUDO_UNLOCK); debug_return_bool(ret); } @@ -610,11 +581,10 @@ do_logfile_json(ClientMessage__TypeCase event_type, const char *reason, TimeSpec *event_time, InfoMessage **info_msgs, size_t infolen) { const char *logfile = logsrvd_conf_logfile_path(); + FILE *fp = logsrvd_conf_logfile_stream(); struct stat sb; char *json_str; - mode_t oldmask; - FILE *fp = NULL; - int fd, ret = false; + int ret = false; debug_decl(do_logfile_json, SUDO_DEBUG_UTIL); json_str = format_json(event_type, reason, event_time, info_msgs, @@ -622,16 +592,6 @@ do_logfile_json(ClientMessage__TypeCase event_type, const char *reason, if (json_str == NULL) goto done; - oldmask = umask(S_IRWXG|S_IRWXO); - fd = open(logfile, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR); - (void)umask(oldmask); - if (fd == -1 || (fp = fdopen(fd, "w")) == NULL) { - sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO, - "unable to open log file %s", logfile); - if (fd != -1) - close(fd); - goto done; - } if (!sudo_lock_file(fileno(fp), SUDO_LOCK)) { sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO, "unable to lock log file %s", logfile); @@ -657,15 +617,14 @@ do_logfile_json(ClientMessage__TypeCase event_type, const char *reason, } fputs(json_str, fp); fputs("\n}\n", fp); /* close JSON */ - fclose(fp); + fflush(fp); /* XXX - check for file error and recover */ ret = true; done: free(json_str); - if (fp != NULL) - fclose(fp); + (void)sudo_lock_file(fileno(fp), SUDO_UNLOCK); debug_return_bool(ret); } diff --git a/logsrvd/logsrvd.h b/logsrvd/logsrvd.h index a6f14f163..9536d563e 100644 --- a/logsrvd/logsrvd.h +++ b/logsrvd/logsrvd.h @@ -205,6 +205,7 @@ int logsrvd_conf_syslog_rejectpri(void); int logsrvd_conf_syslog_alertpri(void); mode_t logsrvd_conf_iolog_mode(void); const char *logsrvd_conf_logfile_path(void); +FILE *logsrvd_conf_logfile_stream(void); const char *logsrvd_conf_logfile_time_format(void); #endif /* SUDO_LOGSRVD_H */ diff --git a/logsrvd/logsrvd_conf.c b/logsrvd/logsrvd_conf.c index dd7fd7b5d..85c0138ad 100644 --- a/logsrvd/logsrvd_conf.c +++ b/logsrvd/logsrvd_conf.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -106,6 +107,7 @@ static struct logsrvd_config { struct logsrvd_config_logfile { char *path; char *time_format; + FILE *stream; } logfile; } *logsrvd_config; @@ -221,6 +223,12 @@ logsrvd_conf_logfile_path(void) return logsrvd_config->logfile.path; } +FILE * +logsrvd_conf_logfile_stream(void) +{ + return logsrvd_config->logfile.stream; +} + const char * logsrvd_conf_logfile_time_format(void) { @@ -685,7 +693,6 @@ cb_logfile_path(struct logsrvd_config *config, const char *str) debug_return_bool(false); } - /* TODO: open log file */ free(config->logfile.path); config->logfile.path = copy; @@ -850,6 +857,36 @@ done: debug_return_bool(ret); } +static FILE * +logsrvd_open_eventlog(struct logsrvd_config *config) +{ + mode_t oldmask; + FILE *fp = NULL; + const char *omode; + int fd, flags; + debug_decl(logsrvd_open_eventlog, SUDO_DEBUG_UTIL); + + /* Cannot append to a JSON file. */ + if (config->eventlog.log_format == EVLOG_JSON) { + flags = O_RDWR|O_CREAT; + omode = "w"; + } else { + flags = O_WRONLY|O_APPEND|O_CREAT; + omode = "a"; + } + oldmask = umask(S_IRWXG|S_IRWXO); + fd = open(config->logfile.path, flags, S_IRUSR|S_IWUSR); + (void)umask(oldmask); + if (fd == -1 || (fp = fdopen(fd, omode)) == NULL) { + sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO, + "unable to open log file %s", config->logfile.path); + if (fd != -1) + close(fd); + } + + debug_return_ptr(fp); +} + /* Free the specified struct logsrvd_config and its contents. */ void logsrvd_conf_free(struct logsrvd_config *config) @@ -873,6 +910,8 @@ logsrvd_conf_free(struct logsrvd_config *config) /* struct logsrvd_config_logfile */ free(config->logfile.path); free(config->logfile.time_format); + if (config->logfile.stream != NULL) + fclose(config->logfile.stream); #if defined(HAVE_OPENSSL) free(config->server.tls_config.pkey_path); @@ -974,6 +1013,24 @@ logsrvd_conf_apply(struct logsrvd_config *config) debug_return_bool(false); } + /* Open event log if specified. */ + switch (config->eventlog.log_type) { + case EVLOG_SYSLOG: + openlog("sudo", 0, config->syslog.facility); + break; + case EVLOG_FILE: + config->logfile.stream = logsrvd_open_eventlog(config); + if (config->logfile.stream == NULL) + debug_return_bool(false); + break; + case EVLOG_NONE: + break; + default: + sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO, + "cannot open unknown log type %d", config->eventlog.log_type); + break; + } + /* Set I/O log library settings */ iolog_set_defaults(); iolog_set_compress(config->iolog.compress);