Write an extended I/O info log in JSON format.

This will be used by sudoreplay if it exists to get more information
about the command being replayed.
This commit is contained in:
Todd C. Miller
2020-03-29 05:05:08 -06:00
parent a644c1d1d2
commit ea9b711a70
12 changed files with 270 additions and 47 deletions

View File

@@ -552,7 +552,7 @@ do_logfile_sudo(const char *reason, const struct iolog_details *details)
goto done;
}
if ((timeptr = localtime(&details->submit_time)) != NULL) {
if ((timeptr = localtime(&details->submit_time.tv_sec)) != NULL) {
/* strftime() does not guarantee to NUL-terminate so we must check. */
timebuf[sizeof(timebuf) - 1] = '\0';
if (strftime(timebuf, sizeof(timebuf), timefmt, timeptr) != 0 &&

View File

@@ -145,11 +145,14 @@ iolog_details_fill(struct iolog_details *details, TimeSpec *submit_time,
memset(details, 0, sizeof(*details));
/* Submit time. */
details->submit_time = submit_time->tv_sec;
details->submit_time.tv_sec = submit_time->tv_sec;
details->submit_time.tv_nsec = submit_time->tv_nsec;
/* Default values */
details->lines = 24;
details->columns = 80;
details->runuid = (uid_t)-1;
details->rungid = (gid_t)-1;
/* Pull out values by key from info array. */
for (idx = 0; idx < infolen; idx++) {
@@ -211,6 +214,18 @@ iolog_details_fill(struct iolog_details *details, TimeSpec *submit_time,
}
continue;
}
if (strcmp(key, "rungid") == 0) {
if (!has_numval(info)) {
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
"rungid specified but not a number");
} else if (info->numval <= 0 || info->numval > INT_MAX) {
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
"rungid (%" PRId64 ") out of range", info->numval);
} else {
details->rungid = info->numval;
}
continue;
}
if (strcmp(key, "rungroup") == 0) {
if (has_strval(info)) {
if ((details->rungroup = strdup(info->strval)) == NULL) {
@@ -225,6 +240,18 @@ iolog_details_fill(struct iolog_details *details, TimeSpec *submit_time,
}
continue;
}
if (strcmp(key, "runuid") == 0) {
if (!has_numval(info)) {
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
"runuid specified but not a number");
} else if (info->numval <= 0 || info->numval > INT_MAX) {
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
"runuid (%" PRId64 ") out of range", info->numval);
} else {
details->runuid = info->numval;
}
continue;
}
if (strcmp(key, "runuser") == 0) {
if (has_strval(info)) {
if ((details->runuser = strdup(info->strval)) == NULL) {
@@ -595,12 +622,16 @@ iolog_details_write(struct iolog_details *details,
log_info.runas_group = details->rungroup;
log_info.tty = details->ttyname;
log_info.cmd = details->command;
log_info.host = details->submithost;
log_info.tstamp = details->submit_time;
log_info.lines = details->lines;
log_info.cols = details->columns;
log_info.runas_uid = details->runuid;
log_info.runas_gid = details->rungid;
log_info.argv = details->argv;
debug_return_bool(iolog_write_info_file(closure->iolog_dir_fd,
details->iolog_path, &log_info, details->argv));
details->iolog_path, &log_info));
}
static bool

View File

@@ -59,10 +59,12 @@ struct iolog_details {
char *ttyname;
char **argv;
char **env_add;
time_t submit_time;
struct timespec submit_time;
int argc;
int lines;
int columns;
uid_t runuid;
gid_t rungid;
char sessid[7];
};

View File

@@ -631,8 +631,8 @@ fmt_accept_message(struct client_closure *closure)
}
/* Sudo I/O logs only store start time in seconds. */
tv.tv_sec = log_info->tstamp;
tv.tv_nsec = 0;
tv.tv_sec = log_info->tstamp.tv_sec;
tv.tv_nsec = log_info->tstamp.tv_nsec;
accept_msg.submit_time = &tv;
/* Client will send IoBuffer messages. */