2
0
mirror of https://github.com/sudo-project/sudo.git synced 2025-08-22 09:57:41 +00:00

Move eventlog config code into eventlog_conf.c

This commit is contained in:
Todd C. Miller 2021-02-24 14:25:39 -07:00
parent f399c449ad
commit 4128582723
5 changed files with 303 additions and 239 deletions

View File

@ -104,6 +104,7 @@ include/sudo_util.h
install-sh install-sh
lib/eventlog/Makefile.in lib/eventlog/Makefile.in
lib/eventlog/eventlog.c lib/eventlog/eventlog.c
lib/eventlog/eventlog_conf.c
lib/eventlog/eventlog_free.c lib/eventlog/eventlog_free.c
lib/eventlog/logwrap.c lib/eventlog/logwrap.c
lib/eventlog/regress/logwrap/check_wrap.c lib/eventlog/regress/logwrap/check_wrap.c

View File

@ -66,7 +66,7 @@ enum eventlog_format {
#define EVENTLOG_INDENT " " #define EVENTLOG_INDENT " "
/* /*
* Event log config, used with eventlog_setconf() * Event log config, used with eventlog_getconf()
*/ */
struct eventlog_config { struct eventlog_config {
int type; int type;
@ -144,5 +144,6 @@ void eventlog_set_mailto(const char *to_addr);
void eventlog_set_mailsub(const char *subject); void eventlog_set_mailsub(const char *subject);
void eventlog_set_open_log(FILE *(*fn)(int type, const char *)); void eventlog_set_open_log(FILE *(*fn)(int type, const char *));
void eventlog_set_close_log(void (*fn)(int type, FILE *)); void eventlog_set_close_log(void (*fn)(int type, FILE *));
const struct eventlog_config *eventlog_getconf(void);
#endif /* SUDO_EVENTLOG_H */ #endif /* SUDO_EVENTLOG_H */

View File

@ -82,7 +82,7 @@ SHELL = @SHELL@
TEST_PROGS = check_wrap TEST_PROGS = check_wrap
LIBEVENTLOG_OBJS = eventlog.lo eventlog_free.lo logwrap.lo LIBEVENTLOG_OBJS = eventlog.lo eventlog_conf.lo eventlog_free.lo logwrap.lo
IOBJS = $(LIBEVENTLOG_OBJS:.lo=.i) IOBJS = $(LIBEVENTLOG_OBJS:.lo=.i)
@ -213,6 +213,24 @@ eventlog.i: $(srcdir)/eventlog.c $(incdir)/compat/stdbool.h \
$(CC) -E -o $@ $(CPPFLAGS) $< $(CC) -E -o $@ $(CPPFLAGS) $<
eventlog.plog: eventlog.i eventlog.plog: eventlog.i
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/eventlog.c --i-file $< --output-file $@ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/eventlog.c --i-file $< --output-file $@
eventlog_conf.lo: $(srcdir)/eventlog_conf.c $(incdir)/compat/stdbool.h \
$(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
$(incdir)/sudo_eventlog.h $(incdir)/sudo_fatal.h \
$(incdir)/sudo_gettext.h $(incdir)/sudo_json.h \
$(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
$(incdir)/sudo_util.h $(top_builddir)/config.h \
$(top_builddir)/pathnames.h
$(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/eventlog_conf.c
eventlog_conf.i: $(srcdir)/eventlog_conf.c $(incdir)/compat/stdbool.h \
$(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
$(incdir)/sudo_eventlog.h $(incdir)/sudo_fatal.h \
$(incdir)/sudo_gettext.h $(incdir)/sudo_json.h \
$(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
$(incdir)/sudo_util.h $(top_builddir)/config.h \
$(top_builddir)/pathnames.h
$(CC) -E -o $@ $(CPPFLAGS) $<
eventlog_conf.plog: eventlog_conf.i
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/eventlog_conf.c --i-file $< --output-file $@
eventlog_free.lo: $(srcdir)/eventlog_free.c $(incdir)/compat/stdbool.h \ eventlog_free.lo: $(srcdir)/eventlog_free.c $(incdir)/compat/stdbool.h \
$(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \ $(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
$(incdir)/sudo_eventlog.h $(incdir)/sudo_queue.h \ $(incdir)/sudo_eventlog.h $(incdir)/sudo_queue.h \

View File

@ -75,35 +75,6 @@
isalnum((unsigned char)(s)[6]) && isalnum((unsigned char)(s)[7]) && \ isalnum((unsigned char)(s)[6]) && isalnum((unsigned char)(s)[7]) && \
(s)[8] == '\0') (s)[8] == '\0')
static FILE *eventlog_stub_open_log(int type, const char *logfile);
static void eventlog_stub_close_log(int type, FILE *fp);
/* Eventlog config settings (default values). */
static struct eventlog_config evl_conf = {
EVLOG_NONE, /* type */
EVLOG_SUDO, /* format */
LOG_NOTICE, /* syslog_acceptpri */
LOG_ALERT, /* syslog_rejectpri */
LOG_ALERT, /* syslog_alertpri */
MAXSYSLOGLEN, /* syslog_maxlen */
0, /* file_maxlen */
ROOT_UID, /* mailuid */
false, /* omit_hostname */
_PATH_SUDO_LOGFILE, /* logpath */
"%h %e %T", /* time_fmt */
#ifdef _PATH_SUDO_SENDMAIL
_PATH_SUDO_SENDMAIL, /* mailerpath */
#else
NULL, /* mailerpath (disabled) */
#endif
"-t", /* mailerflags */
NULL, /* mailfrom */
MAILTO, /* mailto */
N_(MAILSUBJECT), /* mailsub */
eventlog_stub_open_log, /* open_log */
eventlog_stub_close_log /* close_log */
};
/* /*
* Allocate and fill in a new logline. * Allocate and fill in a new logline.
*/ */
@ -111,6 +82,7 @@ static char *
new_logline(int flags, const char *message, const char *errstr, new_logline(int flags, const char *message, const char *errstr,
const struct eventlog *evlog) const struct eventlog *evlog)
{ {
const struct eventlog_config *evl_conf = eventlog_getconf();
char *line = NULL, *evstr = NULL; char *line = NULL, *evstr = NULL;
const char *iolog_file = evlog->iolog_file; const char *iolog_file = evlog->iolog_file;
const char *tty, *tsid = NULL; const char *tty, *tsid = NULL;
@ -159,7 +131,7 @@ new_logline(int flags, const char *message, const char *errstr,
len += strlen(message) + 3; len += strlen(message) + 3;
if (errstr != NULL) if (errstr != NULL)
len += strlen(errstr) + 3; len += strlen(errstr) + 3;
if (evlog->submithost != NULL && !evl_conf.omit_hostname) if (evlog->submithost != NULL && !evl_conf->omit_hostname)
len += sizeof(LL_HOST_STR) + 2 + strlen(evlog->submithost); len += sizeof(LL_HOST_STR) + 2 + strlen(evlog->submithost);
if (tty != NULL) if (tty != NULL)
len += sizeof(LL_TTY_STR) + 2 + strlen(tty); len += sizeof(LL_TTY_STR) + 2 + strlen(tty);
@ -218,7 +190,7 @@ new_logline(int flags, const char *message, const char *errstr,
strlcat(line, " ; ", len) >= len) strlcat(line, " ; ", len) >= len)
goto toobig; goto toobig;
} }
if (evlog->submithost != NULL && !evl_conf.omit_hostname) { if (evlog->submithost != NULL && !evl_conf->omit_hostname) {
if (strlcat(line, LL_HOST_STR, len) >= len || if (strlcat(line, LL_HOST_STR, len) >= len ||
strlcat(line, evlog->submithost, len) >= len || strlcat(line, evlog->submithost, len) >= len ||
strlcat(line, " ; ", len) >= len) strlcat(line, " ; ", len) >= len)
@ -331,8 +303,9 @@ closefrom_nodebug(int lowfd)
static void __attribute__((__noreturn__)) static void __attribute__((__noreturn__))
exec_mailer(int pipein) exec_mailer(int pipein)
{ {
const struct eventlog_config *evl_conf = eventlog_getconf();
char *last, *mflags, *p, *argv[MAX_MAILFLAGS + 1]; char *last, *mflags, *p, *argv[MAX_MAILFLAGS + 1];
const char *mpath = evl_conf.mailerpath; const char *mpath = evl_conf->mailerpath;
int i; int i;
char * const root_envp[] = { char * const root_envp[] = {
"HOME=/", "HOME=/",
@ -356,7 +329,7 @@ exec_mailer(int pipein)
} }
/* Build up an argv based on the mailer path and flags */ /* Build up an argv based on the mailer path and flags */
if ((mflags = strdup(evl_conf.mailerflags)) == NULL) { if ((mflags = strdup(evl_conf->mailerflags)) == NULL) {
syslog(LOG_ERR, _("unable to allocate memory")); // -V618 syslog(LOG_ERR, _("unable to allocate memory")); // -V618
sudo_debug_exit(__func__, __FILE__, __LINE__, sudo_debug_subsys); sudo_debug_exit(__func__, __FILE__, __LINE__, sudo_debug_subsys);
_exit(127); _exit(127);
@ -379,14 +352,14 @@ exec_mailer(int pipein)
sudo_debug_printf(SUDO_DEBUG_ERROR, "unable to change uid to %u", sudo_debug_printf(SUDO_DEBUG_ERROR, "unable to change uid to %u",
ROOT_UID); ROOT_UID);
} }
if (evl_conf.mailuid != ROOT_UID) { if (evl_conf->mailuid != ROOT_UID) {
if (setuid(evl_conf.mailuid) != 0) { if (setuid(evl_conf->mailuid) != 0) {
sudo_debug_printf(SUDO_DEBUG_ERROR, "unable to change uid to %u", sudo_debug_printf(SUDO_DEBUG_ERROR, "unable to change uid to %u",
(unsigned int)evl_conf.mailuid); (unsigned int)evl_conf->mailuid);
} }
} }
sudo_debug_exit(__func__, __FILE__, __LINE__, sudo_debug_subsys); sudo_debug_exit(__func__, __FILE__, __LINE__, sudo_debug_subsys);
if (evl_conf.mailuid == ROOT_UID) if (evl_conf->mailuid == ROOT_UID)
execve(mpath, argv, root_envp); execve(mpath, argv, root_envp);
else else
execv(mpath, argv); execv(mpath, argv);
@ -400,7 +373,8 @@ exec_mailer(int pipein)
static bool static bool
send_mail(const struct eventlog *evlog, const char *fmt, ...) send_mail(const struct eventlog *evlog, const char *fmt, ...)
{ {
const char *cp, *timefmt = evl_conf.time_fmt; const struct eventlog_config *evl_conf = eventlog_getconf();
const char *cp, *timefmt = evl_conf->time_fmt;
char timebuf[1024]; char timebuf[1024];
struct tm *tm; struct tm *tm;
time_t now; time_t now;
@ -415,11 +389,11 @@ send_mail(const struct eventlog *evlog, const char *fmt, ...)
debug_decl(send_mail, SUDO_DEBUG_UTIL); debug_decl(send_mail, SUDO_DEBUG_UTIL);
/* If mailer is disabled just return. */ /* If mailer is disabled just return. */
if (evl_conf.mailerpath == NULL || evl_conf.mailto == NULL) if (evl_conf->mailerpath == NULL || evl_conf->mailto == NULL)
debug_return_bool(true); debug_return_bool(true);
/* Make sure the mailer exists and is a regular file. */ /* Make sure the mailer exists and is a regular file. */
if (stat(evl_conf.mailerpath, &sb) != 0 || !S_ISREG(sb.st_mode)) if (stat(evl_conf->mailerpath, &sb) != 0 || !S_ISREG(sb.st_mode))
debug_return_bool(false); debug_return_bool(false);
time(&now); time(&now);
@ -516,11 +490,11 @@ send_mail(const struct eventlog *evlog, const char *fmt, ...)
/* Pipes are all setup, send message. */ /* Pipes are all setup, send message. */
(void) fprintf(mail, "To: %s\nFrom: %s\nAuto-Submitted: %s\nSubject: ", (void) fprintf(mail, "To: %s\nFrom: %s\nAuto-Submitted: %s\nSubject: ",
evl_conf.mailto, evl_conf->mailto,
evl_conf.mailfrom ? evl_conf.mailfrom : evl_conf->mailfrom ? evl_conf->mailfrom :
(evlog ? evlog->submituser : "root"), (evlog ? evlog->submituser : "root"),
"auto-generated"); "auto-generated");
for (cp = _(evl_conf.mailsub); *cp; cp++) { for (cp = _(evl_conf->mailsub); *cp; cp++) {
/* Expand escapes in the subject */ /* Expand escapes in the subject */
if (*cp == '%' && *(cp+1) != '%') { if (*cp == '%' && *(cp+1) != '%') {
switch (*(++cp)) { switch (*(++cp)) {
@ -576,7 +550,8 @@ static bool
json_add_timestamp(struct json_container *json, const char *name, json_add_timestamp(struct json_container *json, const char *name,
const struct timespec *ts) const struct timespec *ts)
{ {
const char *timefmt = evl_conf.time_fmt; const struct eventlog_config *evl_conf = eventlog_getconf();
const char *timefmt = evl_conf->time_fmt;
struct json_value json_value; struct json_value json_value;
time_t secs = ts->tv_sec; time_t secs = ts->tv_sec;
char timebuf[1024]; char timebuf[1024];
@ -880,12 +855,13 @@ bad:
static bool static bool
do_syslog_sudo(int pri, char *logline, const struct eventlog *evlog) do_syslog_sudo(int pri, char *logline, const struct eventlog *evlog)
{ {
const struct eventlog_config *evl_conf = eventlog_getconf();
size_t len, maxlen; size_t len, maxlen;
char *p, *tmp, save; char *p, *tmp, save;
const char *fmt; const char *fmt;
debug_decl(do_syslog_sudo, SUDO_DEBUG_UTIL); debug_decl(do_syslog_sudo, SUDO_DEBUG_UTIL);
evl_conf.open_log(EVLOG_SYSLOG, NULL); evl_conf->open_log(EVLOG_SYSLOG, NULL);
if (evlog == NULL) { if (evlog == NULL) {
/* Not a command, just log it as-is. */ /* Not a command, just log it as-is. */
@ -897,7 +873,7 @@ do_syslog_sudo(int pri, char *logline, const struct eventlog *evlog)
* Log the full line, breaking into multiple syslog(3) calls if necessary * Log the full line, breaking into multiple syslog(3) calls if necessary
*/ */
fmt = _("%8s : %s"); fmt = _("%8s : %s");
maxlen = evl_conf.syslog_maxlen - maxlen = evl_conf->syslog_maxlen -
(strlen(fmt) - 5 + strlen(evlog->submituser)); (strlen(fmt) - 5 + strlen(evlog->submituser));
for (p = logline; *p != '\0'; ) { for (p = logline; *p != '\0'; ) {
len = strlen(p); len = strlen(p);
@ -926,11 +902,11 @@ do_syslog_sudo(int pri, char *logline, const struct eventlog *evlog)
p += len; p += len;
} }
fmt = _("%8s : (command continued) %s"); fmt = _("%8s : (command continued) %s");
maxlen = evl_conf.syslog_maxlen - maxlen = evl_conf->syslog_maxlen -
(strlen(fmt) - 5 + strlen(evlog->submituser)); (strlen(fmt) - 5 + strlen(evlog->submituser));
} }
done: done:
evl_conf.close_log(EVLOG_SYSLOG, NULL); evl_conf->close_log(EVLOG_SYSLOG, NULL);
debug_return_bool(true); debug_return_bool(true);
} }
@ -941,6 +917,7 @@ do_syslog_json(int pri, int event_type, const char *reason,
const struct timespec *event_time, const struct timespec *event_time,
eventlog_json_callback_t info_cb, void *info) eventlog_json_callback_t info_cb, void *info)
{ {
const struct eventlog_config *evl_conf = eventlog_getconf();
char *json_str; char *json_str;
debug_decl(do_syslog_json, SUDO_DEBUG_UTIL); debug_decl(do_syslog_json, SUDO_DEBUG_UTIL);
@ -951,10 +928,10 @@ do_syslog_json(int pri, int event_type, const char *reason,
debug_return_bool(false); debug_return_bool(false);
/* Syslog it in a sudo object with a @cee: prefix. */ /* Syslog it in a sudo object with a @cee: prefix. */
/* TODO: use evl_conf.syslog_maxlen to break up long messages. */ /* TODO: use evl_conf->syslog_maxlen to break up long messages. */
evl_conf.open_log(EVLOG_SYSLOG, NULL); evl_conf->open_log(EVLOG_SYSLOG, NULL);
syslog(pri, "@cee:{\"sudo\":{%s}}", json_str); syslog(pri, "@cee:{\"sudo\":{%s}}", json_str);
evl_conf.close_log(EVLOG_SYSLOG, NULL); evl_conf->close_log(EVLOG_SYSLOG, NULL);
free(json_str); free(json_str);
debug_return_bool(true); debug_return_bool(true);
} }
@ -967,13 +944,14 @@ do_syslog(int event_type, int flags, const char *reason, const char *errstr,
const struct eventlog *evlog, const struct timespec *event_time, const struct eventlog *evlog, const struct timespec *event_time,
eventlog_json_callback_t info_cb, void *info) eventlog_json_callback_t info_cb, void *info)
{ {
const struct eventlog_config *evl_conf = eventlog_getconf();
char *logline = NULL; char *logline = NULL;
bool ret = false; bool ret = false;
int pri; int pri;
debug_decl(do_syslog, SUDO_DEBUG_UTIL); debug_decl(do_syslog, SUDO_DEBUG_UTIL);
/* Sudo format logs and mailed logs use the same log line format. */ /* Sudo format logs and mailed logs use the same log line format. */
if (evl_conf.format == EVLOG_SUDO || ISSET(flags, EVLOG_MAIL)) { if (evl_conf->format == EVLOG_SUDO || ISSET(flags, EVLOG_MAIL)) {
logline = new_logline(flags, reason, errstr, evlog); logline = new_logline(flags, reason, errstr, evlog);
if (logline == NULL) if (logline == NULL)
debug_return_bool(false); debug_return_bool(false);
@ -992,13 +970,13 @@ do_syslog(int event_type, int flags, const char *reason, const char *errstr,
switch (event_type) { switch (event_type) {
case EVLOG_ACCEPT: case EVLOG_ACCEPT:
pri = evl_conf.syslog_acceptpri; pri = evl_conf->syslog_acceptpri;
break; break;
case EVLOG_REJECT: case EVLOG_REJECT:
pri = evl_conf.syslog_rejectpri; pri = evl_conf->syslog_rejectpri;
break; break;
case EVLOG_ALERT: case EVLOG_ALERT:
pri = evl_conf.syslog_alertpri; pri = evl_conf->syslog_alertpri;
break; break;
default: default:
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO, sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
@ -1012,7 +990,7 @@ do_syslog(int event_type, int flags, const char *reason, const char *errstr,
debug_return_bool(true); debug_return_bool(true);
} }
switch (evl_conf.format) { switch (evl_conf->format) {
case EVLOG_SUDO: case EVLOG_SUDO:
ret = do_syslog_sudo(pri, logline, evlog); ret = do_syslog_sudo(pri, logline, evlog);
break; break;
@ -1022,7 +1000,7 @@ do_syslog(int event_type, int flags, const char *reason, const char *errstr,
break; break;
default: default:
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO, sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
"unexpected eventlog format %d", evl_conf.format); "unexpected eventlog format %d", evl_conf->format);
break; break;
} }
free(logline); free(logline);
@ -1034,9 +1012,10 @@ static bool
do_logfile_sudo(const char *logline, const struct eventlog *evlog, do_logfile_sudo(const char *logline, const struct eventlog *evlog,
const struct timespec *event_time) const struct timespec *event_time)
{ {
const struct eventlog_config *evl_conf = eventlog_getconf();
char *full_line, timebuf[8192], *timestr = NULL; char *full_line, timebuf[8192], *timestr = NULL;
const char *timefmt = evl_conf.time_fmt; const char *timefmt = evl_conf->time_fmt;
const char *logfile = evl_conf.logpath; const char *logfile = evl_conf->logpath;
time_t tv_sec = event_time->tv_sec; time_t tv_sec = event_time->tv_sec;
struct tm *timeptr; struct tm *timeptr;
bool ret = false; bool ret = false;
@ -1044,7 +1023,7 @@ do_logfile_sudo(const char *logline, const struct eventlog *evlog,
int len; int len;
debug_decl(do_logfile_sudo, SUDO_DEBUG_UTIL); debug_decl(do_logfile_sudo, SUDO_DEBUG_UTIL);
if ((fp = evl_conf.open_log(EVLOG_FILE, logfile)) == NULL) if ((fp = evl_conf->open_log(EVLOG_FILE, logfile)) == NULL)
debug_return_bool(false); debug_return_bool(false);
if (!sudo_lock_file(fileno(fp), SUDO_LOCK)) { if (!sudo_lock_file(fileno(fp), SUDO_LOCK)) {
@ -1067,7 +1046,7 @@ do_logfile_sudo(const char *logline, const struct eventlog *evlog,
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory")); sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
goto done; goto done;
} }
eventlog_writeln(fp, full_line, len, evl_conf.file_maxlen); eventlog_writeln(fp, full_line, len, evl_conf->file_maxlen);
(void)fflush(fp); (void)fflush(fp);
if (ferror(fp)) { if (ferror(fp)) {
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO, sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
@ -1078,7 +1057,7 @@ do_logfile_sudo(const char *logline, const struct eventlog *evlog,
done: done:
(void)sudo_lock_file(fileno(fp), SUDO_UNLOCK); (void)sudo_lock_file(fileno(fp), SUDO_UNLOCK);
evl_conf.close_log(EVLOG_FILE, fp); evl_conf->close_log(EVLOG_FILE, fp);
debug_return_bool(ret); debug_return_bool(ret);
} }
@ -1087,14 +1066,15 @@ do_logfile_json(int event_type, const char *reason, const char *errstr,
const struct eventlog *evlog, const struct timespec *event_time, const struct eventlog *evlog, const struct timespec *event_time,
eventlog_json_callback_t info_cb, void *info) eventlog_json_callback_t info_cb, void *info)
{ {
const char *logfile = evl_conf.logpath; const struct eventlog_config *evl_conf = eventlog_getconf();
const char *logfile = evl_conf->logpath;
struct stat sb; struct stat sb;
char *json_str; char *json_str;
int ret = false; int ret = false;
FILE *fp; FILE *fp;
debug_decl(do_logfile_json, SUDO_DEBUG_UTIL); debug_decl(do_logfile_json, SUDO_DEBUG_UTIL);
if ((fp = evl_conf.open_log(EVLOG_FILE, logfile)) == NULL) if ((fp = evl_conf->open_log(EVLOG_FILE, logfile)) == NULL)
debug_return_bool(false); debug_return_bool(false);
json_str = format_json(event_type, reason, errstr, evlog, event_time, json_str = format_json(event_type, reason, errstr, evlog, event_time,
@ -1135,7 +1115,7 @@ do_logfile_json(int event_type, const char *reason, const char *errstr,
done: done:
free(json_str); free(json_str);
(void)sudo_lock_file(fileno(fp), SUDO_UNLOCK); (void)sudo_lock_file(fileno(fp), SUDO_UNLOCK);
evl_conf.close_log(EVLOG_FILE, fp); evl_conf->close_log(EVLOG_FILE, fp);
debug_return_bool(ret); debug_return_bool(ret);
} }
@ -1144,12 +1124,13 @@ do_logfile(int event_type, int flags, const char *reason, const char *errstr,
const struct eventlog *evlog, const struct timespec *event_time, const struct eventlog *evlog, const struct timespec *event_time,
eventlog_json_callback_t info_cb, void *info) eventlog_json_callback_t info_cb, void *info)
{ {
const struct eventlog_config *evl_conf = eventlog_getconf();
bool ret = false; bool ret = false;
char *logline = NULL; char *logline = NULL;
debug_decl(do_logfile, SUDO_DEBUG_UTIL); debug_decl(do_logfile, SUDO_DEBUG_UTIL);
/* Sudo format logs and mailed logs use the same log line format. */ /* Sudo format logs and mailed logs use the same log line format. */
if (evl_conf.format == EVLOG_SUDO || ISSET(flags, EVLOG_MAIL)) { if (evl_conf->format == EVLOG_SUDO || ISSET(flags, EVLOG_MAIL)) {
logline = new_logline(flags, reason, errstr, evlog); logline = new_logline(flags, reason, errstr, evlog);
if (logline == NULL) if (logline == NULL)
debug_return_bool(false); debug_return_bool(false);
@ -1166,7 +1147,7 @@ do_logfile(int event_type, int flags, const char *reason, const char *errstr,
} }
} }
switch (evl_conf.format) { switch (evl_conf->format) {
case EVLOG_SUDO: case EVLOG_SUDO:
ret = do_logfile_sudo(logline ? logline : reason, evlog, event_time); ret = do_logfile_sudo(logline ? logline : reason, evlog, event_time);
break; break;
@ -1176,7 +1157,7 @@ do_logfile(int event_type, int flags, const char *reason, const char *errstr,
break; break;
default: default:
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO, sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
"unexpected eventlog format %d", evl_conf.format); "unexpected eventlog format %d", evl_conf->format);
break; break;
} }
free(logline); free(logline);
@ -1188,7 +1169,8 @@ bool
eventlog_accept(const struct eventlog *evlog, int flags, eventlog_accept(const struct eventlog *evlog, int flags,
eventlog_json_callback_t info_cb, void *info) eventlog_json_callback_t info_cb, void *info)
{ {
const int log_type = evl_conf.type; const struct eventlog_config *evl_conf = eventlog_getconf();
const int log_type = evl_conf->type;
bool ret = true; bool ret = true;
debug_decl(log_accept, SUDO_DEBUG_UTIL); debug_decl(log_accept, SUDO_DEBUG_UTIL);
@ -1214,7 +1196,8 @@ bool
eventlog_reject(const struct eventlog *evlog, int flags, const char *reason, eventlog_reject(const struct eventlog *evlog, int flags, const char *reason,
eventlog_json_callback_t info_cb, void *info) eventlog_json_callback_t info_cb, void *info)
{ {
const int log_type = evl_conf.type; const struct eventlog_config *evl_conf = eventlog_getconf();
const int log_type = evl_conf->type;
bool ret = true; bool ret = true;
debug_decl(log_reject, SUDO_DEBUG_UTIL); debug_decl(log_reject, SUDO_DEBUG_UTIL);
@ -1237,7 +1220,8 @@ bool
eventlog_alert(const struct eventlog *evlog, int flags, eventlog_alert(const struct eventlog *evlog, int flags,
struct timespec *alert_time, const char *reason, const char *errstr) struct timespec *alert_time, const char *reason, const char *errstr)
{ {
const int log_type = evl_conf.type; const struct eventlog_config *evl_conf = eventlog_getconf();
const int log_type = evl_conf->type;
bool ret = true; bool ret = true;
debug_decl(log_alert, SUDO_DEBUG_UTIL); debug_decl(log_alert, SUDO_DEBUG_UTIL);
@ -1255,169 +1239,3 @@ eventlog_alert(const struct eventlog *evlog, int flags,
debug_return_bool(ret); debug_return_bool(ret);
} }
static FILE *
eventlog_stub_open_log(int type, const char *logfile)
{
debug_decl(eventlog_stub_open_log, SUDO_DEBUG_UTIL);
sudo_debug_printf(SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO,
"open_log not set, using stub");
debug_return_ptr(NULL);
}
static void
eventlog_stub_close_log(int type, FILE *fp)
{
debug_decl(eventlog_stub_close_log, SUDO_DEBUG_UTIL);
sudo_debug_printf(SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO,
"close_log not set, using stub");
debug_return;
}
/*
* Set eventlog config settings.
*/
void
eventlog_set_type(int type)
{
evl_conf.type = type;
}
void
eventlog_set_format(enum eventlog_format format)
{
evl_conf.format = format;
}
void
eventlog_set_syslog_acceptpri(int pri)
{
evl_conf.syslog_acceptpri = pri;
}
void
eventlog_set_syslog_rejectpri(int pri)
{
evl_conf.syslog_rejectpri = pri;
}
void
eventlog_set_syslog_alertpri(int pri)
{
evl_conf.syslog_alertpri = pri;
}
void
eventlog_set_syslog_maxlen(int len)
{
evl_conf.syslog_maxlen = len;
}
void
eventlog_set_file_maxlen(int len)
{
evl_conf.file_maxlen = len;
}
void
eventlog_set_mailuid(uid_t uid)
{
evl_conf.mailuid = uid;
}
void
eventlog_set_omit_hostname(bool omit_hostname)
{
evl_conf.omit_hostname = omit_hostname;
}
void
eventlog_set_logpath(const char *path)
{
evl_conf.logpath = path;
}
void
eventlog_set_time_fmt(const char *fmt)
{
evl_conf.time_fmt = fmt;
}
void
eventlog_set_mailerpath(const char *path)
{
evl_conf.mailerpath = path;
}
void
eventlog_set_mailerflags(const char *mflags)
{
evl_conf.mailerflags = mflags;
}
void
eventlog_set_mailfrom(const char *from_addr)
{
evl_conf.mailfrom = from_addr;
}
void
eventlog_set_mailto(const char *to_addr)
{
evl_conf.mailto = to_addr;
}
void
eventlog_set_mailsub(const char *subject)
{
evl_conf.mailsub = subject;
}
void
eventlog_set_open_log(FILE *(*fn)(int type, const char *))
{
evl_conf.open_log = fn;
}
void
eventlog_set_close_log(void (*fn)(int type, FILE *))
{
evl_conf.close_log = fn;
}
bool
eventlog_setconf(struct eventlog_config *conf)
{
debug_decl(eventlog_setconf, SUDO_DEBUG_UTIL);
if (conf != NULL) {
memcpy(&evl_conf, conf, sizeof(evl_conf));
} else {
memset(&evl_conf, 0, sizeof(evl_conf));
}
/* Apply default values where possible. */
if (evl_conf.syslog_maxlen == 0)
evl_conf.syslog_maxlen = MAXSYSLOGLEN;
if (evl_conf.logpath == NULL)
evl_conf.logpath = _PATH_SUDO_LOGFILE;
if (evl_conf.time_fmt == NULL)
evl_conf.time_fmt = "%h %e %T";
#ifdef _PATH_SUDO_SENDMAIL
if (evl_conf.mailerpath == NULL)
evl_conf.mailerpath = _PATH_SUDO_SENDMAIL;
#endif
if (evl_conf.mailerflags == NULL)
evl_conf.mailerflags = "-t";
if (evl_conf.mailto == NULL)
evl_conf.mailto = MAILTO;
if (evl_conf.mailsub == NULL)
evl_conf.mailsub = N_(MAILSUBJECT);
if (evl_conf.open_log == NULL)
evl_conf.open_log = eventlog_stub_open_log;
if (evl_conf.close_log == NULL)
evl_conf.close_log = eventlog_stub_close_log;
debug_return_bool(true);
}

View File

@ -0,0 +1,226 @@
/*
* SPDX-License-Identifier: ISC
*
* Copyright (c) 1994-1996, 1998-2020 Todd C. Miller <Todd.Miller@sudo.ws>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Sponsored in part by the Defense Advanced Research Projects
* Agency (DARPA) and Air Force Research Laboratory, Air Force
* Materiel Command, USAF, under agreement number F39502-99-1-0512.
*/
/*
* This is an open source non-commercial project. Dear PVS-Studio, please check it.
* PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
*/
#include <config.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <netinet/in.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <grp.h>
#include <locale.h>
#include <pwd.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <time.h>
#include <unistd.h>
#include "pathnames.h"
#include "sudo_compat.h"
#include "sudo_debug.h"
#include "sudo_eventlog.h"
#include "sudo_fatal.h"
#include "sudo_gettext.h"
#include "sudo_json.h"
#include "sudo_queue.h"
#include "sudo_util.h"
static FILE *eventlog_stub_open_log(int type, const char *logfile);
static void eventlog_stub_close_log(int type, FILE *fp);
/* Eventlog config settings (default values). */
static struct eventlog_config evl_conf = {
EVLOG_NONE, /* type */
EVLOG_SUDO, /* format */
LOG_NOTICE, /* syslog_acceptpri */
LOG_ALERT, /* syslog_rejectpri */
LOG_ALERT, /* syslog_alertpri */
MAXSYSLOGLEN, /* syslog_maxlen */
0, /* file_maxlen */
ROOT_UID, /* mailuid */
false, /* omit_hostname */
_PATH_SUDO_LOGFILE, /* logpath */
"%h %e %T", /* time_fmt */
#ifdef _PATH_SUDO_SENDMAIL
_PATH_SUDO_SENDMAIL, /* mailerpath */
#else
NULL, /* mailerpath (disabled) */
#endif
"-t", /* mailerflags */
NULL, /* mailfrom */
MAILTO, /* mailto */
N_(MAILSUBJECT), /* mailsub */
eventlog_stub_open_log, /* open_log */
eventlog_stub_close_log /* close_log */
};
static FILE *
eventlog_stub_open_log(int type, const char *logfile)
{
debug_decl(eventlog_stub_open_log, SUDO_DEBUG_UTIL);
sudo_debug_printf(SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO,
"open_log not set, using stub");
debug_return_ptr(NULL);
}
static void
eventlog_stub_close_log(int type, FILE *fp)
{
debug_decl(eventlog_stub_close_log, SUDO_DEBUG_UTIL);
sudo_debug_printf(SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO,
"close_log not set, using stub");
debug_return;
}
/*
* eventlog config setters.
*/
void
eventlog_set_type(int type)
{
evl_conf.type = type;
}
void
eventlog_set_format(enum eventlog_format format)
{
evl_conf.format = format;
}
void
eventlog_set_syslog_acceptpri(int pri)
{
evl_conf.syslog_acceptpri = pri;
}
void
eventlog_set_syslog_rejectpri(int pri)
{
evl_conf.syslog_rejectpri = pri;
}
void
eventlog_set_syslog_alertpri(int pri)
{
evl_conf.syslog_alertpri = pri;
}
void
eventlog_set_syslog_maxlen(int len)
{
evl_conf.syslog_maxlen = len;
}
void
eventlog_set_file_maxlen(int len)
{
evl_conf.file_maxlen = len;
}
void
eventlog_set_mailuid(uid_t uid)
{
evl_conf.mailuid = uid;
}
void
eventlog_set_omit_hostname(bool omit_hostname)
{
evl_conf.omit_hostname = omit_hostname;
}
void
eventlog_set_logpath(const char *path)
{
evl_conf.logpath = path;
}
void
eventlog_set_time_fmt(const char *fmt)
{
evl_conf.time_fmt = fmt;
}
void
eventlog_set_mailerpath(const char *path)
{
evl_conf.mailerpath = path;
}
void
eventlog_set_mailerflags(const char *mflags)
{
evl_conf.mailerflags = mflags;
}
void
eventlog_set_mailfrom(const char *from_addr)
{
evl_conf.mailfrom = from_addr;
}
void
eventlog_set_mailto(const char *to_addr)
{
evl_conf.mailto = to_addr;
}
void
eventlog_set_mailsub(const char *subject)
{
evl_conf.mailsub = subject;
}
void
eventlog_set_open_log(FILE *(*fn)(int type, const char *))
{
evl_conf.open_log = fn;
}
void
eventlog_set_close_log(void (*fn)(int type, FILE *))
{
evl_conf.close_log = fn;
}
/*
* get eventlog config.
*/
const struct eventlog_config *
eventlog_getconf(void)
{
return &evl_conf;
}