summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTodd C. Miller <Todd.Miller@sudo.ws>2023-01-22 15:27:53 -0700
committerTodd C. Miller <Todd.Miller@sudo.ws>2023-01-22 15:27:53 -0700
commitc542aa073dff5981fd8317d095dfc9afb99eeeff (patch)
tree204e2b5c24d8a729f2f9ff97ed728c39876e67d3
parentd097542fe1b7d6bbffd88097b20f187482f1816e (diff)
downloadsudo-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.h9
-rw-r--r--lib/eventlog/eventlog.c135
-rw-r--r--plugins/sudoers/sudoreplay.c84
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;
}