diff options
author | Todd C. Miller <Todd.Miller@sudo.ws> | 2023-01-22 15:27:53 -0700 |
---|---|---|
committer | Todd C. Miller <Todd.Miller@sudo.ws> | 2023-01-22 15:27:53 -0700 |
commit | c542aa073dff5981fd8317d095dfc9afb99eeeff (patch) | |
tree | 204e2b5c24d8a729f2f9ff97ed728c39876e67d3 | |
parent | d097542fe1b7d6bbffd88097b20f187482f1816e (diff) | |
download | sudo-c542aa073dff5981fd8317d095dfc9afb99eeeff.tar.gz |
Add eventlog_store_sudo() and use it in sudoreplay.
This replaces the custom log formatting used by "sudoreplay -l".
-rw-r--r-- | include/sudo_eventlog.h | 9 | ||||
-rw-r--r-- | lib/eventlog/eventlog.c | 135 | ||||
-rw-r--r-- | plugins/sudoers/sudoreplay.c | 84 |
3 files changed, 87 insertions, 141 deletions
diff --git a/include/sudo_eventlog.h b/include/sudo_eventlog.h index b4552f2e6..55feee5d2 100644 --- a/include/sudo_eventlog.h +++ b/include/sudo_eventlog.h @@ -47,9 +47,10 @@ enum eventlog_format { }; /* Eventlog flag values. */ -#define EVLOG_RAW 0x01 -#define EVLOG_MAIL 0x02 -#define EVLOG_MAIL_ONLY 0x04 +#define EVLOG_RAW 0x01 /* only include message and errstr */ +#define EVLOG_MAIL 0x02 /* mail the log message too */ +#define EVLOG_MAIL_ONLY 0x04 /* only mail the message, no other logging */ +#define EVLOG_CWD 0x08 /* log cwd if no runcwd and use CWD, not PWD */ /* * Maximum number of characters to log per entry. The syslogger @@ -126,6 +127,7 @@ struct eventlog { /* Callback from eventlog code to write log info */ struct json_container; +struct sudo_lbuf; typedef bool (*eventlog_json_callback_t)(struct json_container *, void *); bool eventlog_accept(const struct eventlog *evlog, int flags, eventlog_json_callback_t info_cb, void *info); @@ -133,6 +135,7 @@ bool eventlog_exit(const struct eventlog *evlog, int flags); bool eventlog_alert(const struct eventlog *evlog, int flags, struct timespec *alert_time, const char *reason, const char *errstr); bool eventlog_reject(const struct eventlog *evlog, int flags, const char *reason, eventlog_json_callback_t info_cb, void *info); bool eventlog_store_json(struct json_container *jsonc, const struct eventlog *evlog); +bool eventlog_store_sudo(int event_type, const struct eventlog *evlog, struct sudo_lbuf *lbuf); size_t eventlog_writeln(FILE *fp, char *line, size_t len, size_t maxlen); void eventlog_free(struct eventlog *evlog); void eventlog_set_type(int type); diff --git a/lib/eventlog/eventlog.c b/lib/eventlog/eventlog.c index e5dae626a..cc4e63267 100644 --- a/lib/eventlog/eventlog.c +++ b/lib/eventlog/eventlog.c @@ -77,33 +77,30 @@ struct eventlog_args { /* * Allocate and fill in a new logline. */ -static char * +static bool new_logline(int event_type, int flags, struct eventlog_args *args, - const struct eventlog *evlog) + const struct eventlog *evlog, struct sudo_lbuf *lbuf) { const struct eventlog_config *evl_conf = eventlog_getconf(); const char *iolog_file; const char *tty, *tsid = NULL; char exit_str[(((sizeof(int) * 8) + 2) / 3) + 2]; char sessid[7], offsetstr[64] = ""; - struct sudo_lbuf lbuf; int i; debug_decl(new_logline, SUDO_DEBUG_UTIL); - sudo_lbuf_init(&lbuf, NULL, 0, NULL, 0); - if (ISSET(flags, EVLOG_RAW) || evlog == NULL) { if (args->reason != NULL) { if (args->errstr != NULL) { - sudo_lbuf_append_esc(&lbuf, LBUF_ESC_CNTRL, "%s: %s", + sudo_lbuf_append_esc(lbuf, LBUF_ESC_CNTRL, "%s: %s", args->reason, args->errstr); } else { - sudo_lbuf_append_esc(&lbuf, LBUF_ESC_CNTRL, "%s", args->reason); + sudo_lbuf_append_esc(lbuf, LBUF_ESC_CNTRL, "%s", args->reason); } - if (sudo_lbuf_error(&lbuf)) + if (sudo_lbuf_error(lbuf)) goto oom; } - debug_return_str(lbuf.buf); + debug_return_bool(true); } /* A TSID may be a sudoers-style session ID or a free-form string. */ @@ -145,62 +142,70 @@ new_logline(int event_type, int flags, struct eventlog_args *args, * octal form (#0nn). Error checking (ENOMEM) is done at the end. */ if (args->reason != NULL) { - sudo_lbuf_append_esc(&lbuf, LBUF_ESC_CNTRL, "%s%s", args->reason, + sudo_lbuf_append_esc(lbuf, LBUF_ESC_CNTRL, "%s%s", args->reason, args->errstr ? " : " : " ; "); } if (args->errstr != NULL) { - sudo_lbuf_append_esc(&lbuf, LBUF_ESC_CNTRL, "%s ; ", args->errstr); + sudo_lbuf_append_esc(lbuf, LBUF_ESC_CNTRL, "%s ; ", args->errstr); } if (evlog->submithost != NULL && !evl_conf->omit_hostname) { - sudo_lbuf_append_esc(&lbuf, LBUF_ESC_CNTRL, "HOST=%s ; ", + sudo_lbuf_append_esc(lbuf, LBUF_ESC_CNTRL, "HOST=%s ; ", evlog->submithost); } if (tty != NULL) { - sudo_lbuf_append_esc(&lbuf, LBUF_ESC_CNTRL, "TTY=%s ; ", tty); + sudo_lbuf_append_esc(lbuf, LBUF_ESC_CNTRL, "TTY=%s ; ", tty); } if (evlog->runchroot != NULL) { - sudo_lbuf_append_esc(&lbuf, LBUF_ESC_CNTRL, "CHROOT=%s ; ", + sudo_lbuf_append_esc(lbuf, LBUF_ESC_CNTRL, "CHROOT=%s ; ", evlog->runchroot); } - if (evlog->runcwd != NULL) { - sudo_lbuf_append_esc(&lbuf, LBUF_ESC_CNTRL, "PWD=%s ; ", - evlog->runcwd); + if (evlog->runcwd != NULL || evlog->cwd != NULL) { + if (ISSET(flags, EVLOG_CWD)) { + /* For sudoreplay -l output format. */ + sudo_lbuf_append_esc(lbuf, LBUF_ESC_CNTRL, "CWD=%s ; ", + evlog->runcwd ? evlog->runcwd : evlog->cwd); + } else if (evlog->runcwd != NULL) { + /* For backwards compatibility with sudo log format. */ + sudo_lbuf_append_esc(lbuf, LBUF_ESC_CNTRL, "PWD=%s ; ", + evlog->runcwd); + } } if (evlog->runuser != NULL) { - sudo_lbuf_append_esc(&lbuf, LBUF_ESC_CNTRL, "USER=%s ; ", + sudo_lbuf_append_esc(lbuf, LBUF_ESC_CNTRL, "USER=%s ; ", evlog->runuser); } if (evlog->rungroup != NULL) { - sudo_lbuf_append_esc(&lbuf, LBUF_ESC_CNTRL, "GROUP=%s ; ", + sudo_lbuf_append_esc(lbuf, LBUF_ESC_CNTRL, "GROUP=%s ; ", evlog->rungroup); } if (tsid != NULL) { - sudo_lbuf_append_esc(&lbuf, LBUF_ESC_CNTRL, "TSID=%s%s ; ", tsid, + sudo_lbuf_append_esc(lbuf, LBUF_ESC_CNTRL, "TSID=%s%s ; ", tsid, offsetstr); } if (evlog->env_add != NULL && evlog->env_add[0] != NULL) { - sudo_lbuf_append_esc(&lbuf, LBUF_ESC_CNTRL, "ENV=%s", + sudo_lbuf_append_esc(lbuf, LBUF_ESC_CNTRL, "ENV=%s", evlog->env_add[0]); for (i = 1; evlog->env_add[i] != NULL; i++) { - sudo_lbuf_append_esc(&lbuf, LBUF_ESC_CNTRL, " %s", + sudo_lbuf_append_esc(lbuf, LBUF_ESC_CNTRL, " %s", evlog->env_add[i]); } } - if (evlog->command != NULL) { - sudo_lbuf_append_esc(&lbuf, LBUF_ESC_CNTRL|LBUF_ESC_BLANK, + if (evlog->command != NULL && evlog->argv != NULL) { + /* Command plus argv. */ + sudo_lbuf_append_esc(lbuf, LBUF_ESC_CNTRL|LBUF_ESC_BLANK, "COMMAND=%s", evlog->command); - if (evlog->argv != NULL && evlog->argv[0] != NULL) { + if (evlog->argv[0] != NULL) { for (i = 1; evlog->argv[i] != NULL; i++) { - sudo_lbuf_append(&lbuf, " "); + sudo_lbuf_append(lbuf, " "); if (strchr(evlog->argv[i], ' ') != NULL) { /* Wrap args containing spaces in single quotes. */ - sudo_lbuf_append(&lbuf, "'"); - sudo_lbuf_append_esc(&lbuf, LBUF_ESC_CNTRL|LBUF_ESC_QUOTE, + sudo_lbuf_append(lbuf, "'"); + sudo_lbuf_append_esc(lbuf, LBUF_ESC_CNTRL|LBUF_ESC_QUOTE, "%s", evlog->argv[i]); - sudo_lbuf_append(&lbuf, "'"); + sudo_lbuf_append(lbuf, "'"); } else { /* Escape quotes here too for consistency. */ - sudo_lbuf_append_esc(&lbuf, + sudo_lbuf_append_esc(lbuf, LBUF_ESC_CNTRL|LBUF_ESC_BLANK|LBUF_ESC_QUOTE, "%s", evlog->argv[i]); } @@ -208,23 +213,36 @@ new_logline(int event_type, int flags, struct eventlog_args *args, } if (event_type == EVLOG_EXIT) { if (evlog->signal_name != NULL) { - sudo_lbuf_append_esc(&lbuf, LBUF_ESC_CNTRL, " ; SIGNAL=%s", + sudo_lbuf_append_esc(lbuf, LBUF_ESC_CNTRL, " ; SIGNAL=%s", evlog->signal_name); } if (evlog->exit_value != -1) { (void)snprintf(exit_str, sizeof(exit_str), "%d", evlog->exit_value); - sudo_lbuf_append_esc(&lbuf, LBUF_ESC_CNTRL, " ; EXIT=%s", + sudo_lbuf_append_esc(lbuf, LBUF_ESC_CNTRL, " ; EXIT=%s", exit_str); } } + } else if (evlog->command != NULL) { + /* Just the command, no argv. */ + sudo_lbuf_append_esc(lbuf, LBUF_ESC_CNTRL, "COMMAND=%s", + evlog->command); } - if (!sudo_lbuf_error(&lbuf)) - debug_return_str(lbuf.buf); + + if (!sudo_lbuf_error(lbuf)) + debug_return_bool(true); oom: - sudo_lbuf_destroy(&lbuf); sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory")); - debug_return_str(NULL); + debug_return_bool(false); +} + +bool +eventlog_store_sudo(int event_type, const struct eventlog *evlog, + struct sudo_lbuf *lbuf) +{ + struct eventlog_args args = { NULL }; + + return new_logline(event_type, EVLOG_CWD, &args, evlog, lbuf); } static void @@ -1008,25 +1026,26 @@ do_syslog(int event_type, int flags, struct eventlog_args *args, const struct eventlog *evlog) { const struct eventlog_config *evl_conf = eventlog_getconf(); - char *logline = NULL; + struct sudo_lbuf lbuf; bool ret = false; int pri; debug_decl(do_syslog, SUDO_DEBUG_UTIL); + sudo_lbuf_init(&lbuf, NULL, 0, NULL, 0); + /* Sudo format logs and mailed logs use the same log line format. */ if (evl_conf->format == EVLOG_SUDO || ISSET(flags, EVLOG_MAIL)) { - logline = new_logline(event_type, flags, args, evlog); - if (logline == NULL) - debug_return_bool(false); + if (!new_logline(event_type, flags, args, evlog, &lbuf)) + goto done; if (ISSET(flags, EVLOG_MAIL)) { - if (!send_mail(evlog, "%s", logline)) { + if (!send_mail(evlog, "%s", lbuf.buf)) { sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO, "unable to mail log line"); } if (ISSET(flags, EVLOG_MAIL_ONLY)) { - free(logline); - debug_return_bool(true); + ret = true; + goto done; } } } @@ -1050,13 +1069,13 @@ do_syslog(int event_type, int flags, struct eventlog_args *args, } if (pri == -1) { /* syslog disabled for this message type */ - free(logline); - debug_return_bool(true); + ret = true; + goto done; } switch (evl_conf->format) { case EVLOG_SUDO: - ret = do_syslog_sudo(pri, logline, evlog); + ret = do_syslog_sudo(pri, lbuf.buf, evlog); break; case EVLOG_JSON: ret = do_syslog_json(pri, event_type, args, evlog); @@ -1066,8 +1085,8 @@ do_syslog(int event_type, int flags, struct eventlog_args *args, "unexpected eventlog format %d", evl_conf->format); break; } - free(logline); - +done: + sudo_lbuf_destroy(&lbuf); debug_return_bool(ret); } @@ -1193,31 +1212,32 @@ do_logfile(int event_type, int flags, struct eventlog_args *args, const struct eventlog *evlog) { const struct eventlog_config *evl_conf = eventlog_getconf(); + struct sudo_lbuf lbuf; bool ret = false; - char *logline = NULL; debug_decl(do_logfile, SUDO_DEBUG_UTIL); + sudo_lbuf_init(&lbuf, NULL, 0, NULL, 0); + /* Sudo format logs and mailed logs use the same log line format. */ if (evl_conf->format == EVLOG_SUDO || ISSET(flags, EVLOG_MAIL)) { - logline = new_logline(event_type, flags, args, evlog); - if (logline == NULL) - debug_return_bool(false); + if (!new_logline(event_type, flags, args, evlog, &lbuf)) + goto done; if (ISSET(flags, EVLOG_MAIL)) { - if (!send_mail(evlog, "%s", logline)) { + if (!send_mail(evlog, "%s", lbuf.buf)) { sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO, "unable to mail log line"); } if (ISSET(flags, EVLOG_MAIL_ONLY)) { - free(logline); - debug_return_bool(true); + ret = true; + goto done; } } } switch (evl_conf->format) { case EVLOG_SUDO: - ret = do_logfile_sudo(logline ? logline : args->reason, evlog, + ret = do_logfile_sudo(lbuf.buf ? lbuf.buf : args->reason, evlog, args->event_time); break; case EVLOG_JSON: @@ -1228,8 +1248,9 @@ do_logfile(int event_type, int flags, struct eventlog_args *args, "unexpected eventlog format %d", evl_conf->format); break; } - free(logline); +done: + sudo_lbuf_destroy(&lbuf); debug_return_bool(ret); } diff --git a/plugins/sudoers/sudoreplay.c b/plugins/sudoers/sudoreplay.c index 43ff23999..0f068f05c 100644 --- a/plugins/sudoers/sudoreplay.c +++ b/plugins/sudoers/sudoreplay.c @@ -191,14 +191,6 @@ sudo_noreturn static void usage(void); isalnum((unsigned char)(s)[3]) && isalnum((unsigned char)(s)[4]) && \ isalnum((unsigned char)(s)[5]) && (s)[6] == '\0') -#define IS_IDLOG(s) ( \ - isalnum((unsigned char)(s)[0]) && isalnum((unsigned char)(s)[1]) && \ - (s)[2] == '/' && \ - isalnum((unsigned char)(s)[3]) && isalnum((unsigned char)(s)[4]) && \ - (s)[5] == '/' && \ - isalnum((unsigned char)(s)[6]) && isalnum((unsigned char)(s)[7]) && \ - (s)[8] == '\0') - sudo_dso_public int main(int argc, char *argv[]); int @@ -1436,10 +1428,9 @@ static int list_session(struct sudo_lbuf *lbuf, char *log_dir, regex_t *re, const char *user, const char *tty) { - char idbuf[7], *idstr, *cp; struct eventlog *evlog = NULL; const char *timestr; - int i, ret = -1; + int ret = -1; debug_decl(list_session, SUDO_DEBUG_UTIL); if ((evlog = iolog_parse_loginfo(-1, log_dir)) == NULL) @@ -1449,86 +1440,17 @@ list_session(struct sudo_lbuf *lbuf, char *log_dir, regex_t *re, evlog->runuser == NULL) { goto done; } + evlog->iolog_file = log_dir + strlen(session_dir) + 1; /* Match on search expression if there is one. */ if (!STAILQ_EMPTY(&search_expr) && !match_expr(&search_expr, evlog, true)) goto done; - /* Convert from /var/log/sudo-sessions/00/00/01 to 000001 */ - cp = log_dir + strlen(session_dir) + 1; - if (IS_IDLOG(cp)) { - idbuf[0] = cp[0]; - idbuf[1] = cp[1]; - idbuf[2] = cp[3]; - idbuf[3] = cp[4]; - idbuf[4] = cp[6]; - idbuf[5] = cp[7]; - idbuf[6] = '\0'; - idstr = idbuf; - } else { - /* Not an id, use as-is. */ - idstr = cp; - } - /* XXX - print lines + cols? */ timestr = get_timestr(evlog->submit_time.tv_sec, 1); sudo_lbuf_append_esc(lbuf, LBUF_ESC_CNTRL, "%s : %s : ", timestr ? timestr : "invalid date", evlog->submituser); - if (evlog->submithost != NULL) { - sudo_lbuf_append_esc(lbuf, LBUF_ESC_CNTRL, "HOST=%s ; ", - evlog->submithost); - } - if (evlog->ttyname != NULL) { - sudo_lbuf_append_esc(lbuf, LBUF_ESC_CNTRL, "TTY=%s ; ", - evlog->ttyname); - } - if (evlog->runchroot != NULL) { - sudo_lbuf_append_esc(lbuf, LBUF_ESC_CNTRL, "CHROOT=%s ; ", - evlog->runchroot); - } - if (evlog->runcwd != NULL || evlog->cwd != NULL) { - sudo_lbuf_append_esc(lbuf, LBUF_ESC_CNTRL, "CWD=%s ; ", - evlog->runcwd ? evlog->runcwd : evlog->cwd); - } - sudo_lbuf_append_esc(lbuf, LBUF_ESC_CNTRL, "USER=%s ; ", evlog->runuser); - if (evlog->rungroup != NULL) { - sudo_lbuf_append_esc(lbuf, LBUF_ESC_CNTRL, "GROUP=%s ; ", - evlog->rungroup); - } - sudo_lbuf_append_esc(lbuf, LBUF_ESC_CNTRL, "TSID=%s ; ", idstr); - - /* - * If we have both command and argv from info.json we can escape - * blanks in the the command and arguments. If all we have is a - * single string containing both the command and arguments we cannot. - */ - if (evlog->argv != NULL) { - /* Command plus argv from the info.json file. */ - sudo_lbuf_append_esc(lbuf, LBUF_ESC_CNTRL|LBUF_ESC_BLANK, - "COMMAND=%s", evlog->command); - if (evlog->argv[0] != NULL) { - for (i = 1; evlog->argv[i] != NULL; i++) { - sudo_lbuf_append(lbuf, " "); - if (strchr(evlog->argv[i], ' ') != NULL) { - /* Wrap args containing spaces in single quotes. */ - sudo_lbuf_append(lbuf, "'"); - sudo_lbuf_append_esc(lbuf, LBUF_ESC_CNTRL|LBUF_ESC_QUOTE, - "%s", evlog->argv[i]); - sudo_lbuf_append(lbuf, "'"); - } else { - /* Escape quotes here too for consistency. */ - sudo_lbuf_append_esc(lbuf, - LBUF_ESC_CNTRL|LBUF_ESC_BLANK|LBUF_ESC_QUOTE, - "%s", evlog->argv[i]); - } - } - } - } else { - /* Single string from the legacy info file. */ - sudo_lbuf_append_esc(lbuf, LBUF_ESC_CNTRL, "COMMAND=%s", - evlog->command); - } - if (!sudo_lbuf_error(lbuf)) { + if (eventlog_store_sudo(EVLOG_ACCEPT, evlog, lbuf)) { puts(lbuf->buf); ret = 0; } |