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:
@@ -64,9 +64,14 @@ struct iolog_info {
|
||||
char *runas_group;
|
||||
char *tty;
|
||||
char *cmd;
|
||||
time_t tstamp;
|
||||
char *host;
|
||||
struct timespec tstamp;
|
||||
int lines;
|
||||
int cols;
|
||||
uid_t runas_uid;
|
||||
gid_t runas_gid;
|
||||
char **argv;
|
||||
char **envp;
|
||||
};
|
||||
|
||||
struct timing_closure {
|
||||
@@ -123,7 +128,7 @@ bool iolog_mkpath(char *path);
|
||||
bool iolog_nextid(char *iolog_dir, char sessid[7]);
|
||||
bool iolog_open(struct iolog_file *iol, int dfd, int iofd, const char *mode);
|
||||
bool iolog_rename(const char *from, const char *to);
|
||||
bool iolog_write_info_file(int dfd, const char *parent, struct iolog_info *log_info, char * const argv[]);
|
||||
bool iolog_write_info_file(int dfd, const char *parent, struct iolog_info *log_info);
|
||||
char *iolog_gets(struct iolog_file *iol, char *buf, size_t nbytes, const char **errsttr);
|
||||
const char *iolog_fd_to_name(int iofd);
|
||||
int iolog_openat(int fdf, const char *path, int flags);
|
||||
|
@@ -221,17 +221,17 @@ iolog_fileio.lo: $(srcdir)/iolog_fileio.c $(incdir)/compat/stdbool.h \
|
||||
$(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
|
||||
$(incdir)/sudo_debug.h $(incdir)/sudo_event.h \
|
||||
$(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
|
||||
$(incdir)/sudo_iolog.h $(incdir)/sudo_queue.h \
|
||||
$(incdir)/sudo_util.h $(top_builddir)/config.h \
|
||||
$(top_builddir)/pathnames.h
|
||||
$(incdir)/sudo_iolog.h $(incdir)/sudo_json.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)/iolog_fileio.c
|
||||
iolog_fileio.i: $(srcdir)/iolog_fileio.c $(incdir)/compat/stdbool.h \
|
||||
$(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
|
||||
$(incdir)/sudo_debug.h $(incdir)/sudo_event.h \
|
||||
$(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
|
||||
$(incdir)/sudo_iolog.h $(incdir)/sudo_queue.h \
|
||||
$(incdir)/sudo_util.h $(top_builddir)/config.h \
|
||||
$(top_builddir)/pathnames.h
|
||||
$(incdir)/sudo_iolog.h $(incdir)/sudo_json.h \
|
||||
$(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
|
||||
$(top_builddir)/config.h $(top_builddir)/pathnames.h
|
||||
$(CC) -E -o $@ $(CPPFLAGS) $<
|
||||
iolog_fileio.plog: iolog_fileio.i
|
||||
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/iolog_fileio.c --i-file $< --output-file $@
|
||||
|
@@ -50,6 +50,7 @@
|
||||
#include "sudo_conf.h"
|
||||
#include "sudo_debug.h"
|
||||
#include "sudo_event.h"
|
||||
#include "sudo_json.h"
|
||||
#include "sudo_queue.h"
|
||||
#include "sudo_util.h"
|
||||
#include "sudo_fatal.h"
|
||||
@@ -869,12 +870,12 @@ iolog_gets(struct iolog_file *iol, char *buf, size_t nbytes,
|
||||
}
|
||||
|
||||
/*
|
||||
* Write the I/O log file that contains the user and command info.
|
||||
* Write the legacy I/O log file that contains the user and command info.
|
||||
* This file is not compressed.
|
||||
*/
|
||||
bool
|
||||
iolog_write_info_file(int dfd, const char *parent, struct iolog_info *log_info,
|
||||
char * const argv[])
|
||||
static bool
|
||||
iolog_write_info_file_legacy(int dfd, const char *parent,
|
||||
struct iolog_info *log_info)
|
||||
{
|
||||
char * const *av;
|
||||
FILE *fp;
|
||||
@@ -896,7 +897,7 @@ iolog_write_info_file(int dfd, const char *parent, struct iolog_info *log_info,
|
||||
}
|
||||
|
||||
fprintf(fp, "%lld:%s:%s:%s:%s:%d:%d\n%s\n",
|
||||
(long long)log_info->tstamp,
|
||||
(long long)log_info->tstamp.tv_sec,
|
||||
log_info->user ? log_info->user : "unknown",
|
||||
log_info->runas_user ? log_info->runas_user : RUNAS_DEFAULT,
|
||||
log_info->runas_group ? log_info->runas_group : "",
|
||||
@@ -904,7 +905,7 @@ iolog_write_info_file(int dfd, const char *parent, struct iolog_info *log_info,
|
||||
log_info->lines, log_info->cols,
|
||||
log_info->cwd ? log_info->cwd : "unknown");
|
||||
fputs(log_info->cmd ? log_info->cmd : "unknown", fp);
|
||||
for (av = argv + 1; *av != NULL; av++) {
|
||||
for (av = log_info->argv + 1; *av != NULL; av++) {
|
||||
fputc(' ', fp);
|
||||
fputs(*av, fp);
|
||||
}
|
||||
@@ -919,6 +920,181 @@ iolog_write_info_file(int dfd, const char *parent, struct iolog_info *log_info,
|
||||
debug_return_bool(!error);
|
||||
}
|
||||
|
||||
/*
|
||||
* Write the "log.json" file that contains the user and command info.
|
||||
* This file is not compressed.
|
||||
*/
|
||||
static bool
|
||||
iolog_write_info_file_json(int dfd, const char *parent, struct iolog_info *info)
|
||||
{
|
||||
struct json_container json;
|
||||
struct json_value json_value;
|
||||
bool ret = false;
|
||||
FILE *fp = NULL;
|
||||
int fd = -1;
|
||||
debug_decl(iolog_write_info_file_json, SUDO_DEBUG_UTIL);
|
||||
|
||||
if (info->cmd == NULL || info->user == NULL || info->runas_user == NULL)
|
||||
debug_return_bool(false);
|
||||
|
||||
if (!sudo_json_init(&json, 4, false, false))
|
||||
debug_return_bool(false);
|
||||
|
||||
/* Timestamp */
|
||||
if (!sudo_json_open_object(&json, "timestamp"))
|
||||
goto oom;
|
||||
|
||||
json_value.type = JSON_NUMBER;
|
||||
json_value.u.number = info->tstamp.tv_sec;
|
||||
if (!sudo_json_add_value(&json, "seconds", &json_value))
|
||||
goto oom;
|
||||
|
||||
json_value.type = JSON_NUMBER;
|
||||
json_value.u.number = info->tstamp.tv_nsec;
|
||||
if (!sudo_json_add_value(&json, "nanoseconds", &json_value))
|
||||
goto oom;
|
||||
|
||||
if (!sudo_json_close_object(&json))
|
||||
goto oom;
|
||||
|
||||
json_value.type = JSON_NUMBER;
|
||||
json_value.u.number = info->cols;
|
||||
if (!sudo_json_add_value(&json, "columns", &json_value))
|
||||
goto oom;
|
||||
|
||||
/* Required */
|
||||
json_value.type = JSON_STRING;
|
||||
json_value.u.string = info->cmd;
|
||||
if (!sudo_json_add_value(&json, "command", &json_value))
|
||||
goto oom;
|
||||
|
||||
json_value.type = JSON_NUMBER;
|
||||
json_value.u.number = info->lines;
|
||||
if (!sudo_json_add_value(&json, "lines", &json_value))
|
||||
goto oom;
|
||||
|
||||
if (info->argv != NULL) {
|
||||
json_value.type = JSON_ARRAY;
|
||||
json_value.u.array = info->argv;
|
||||
if (!sudo_json_add_value(&json, "runargv", &json_value))
|
||||
goto oom;
|
||||
}
|
||||
|
||||
if (info->envp != NULL) {
|
||||
json_value.type = JSON_ARRAY;
|
||||
json_value.u.array = info->envp;
|
||||
if (!sudo_json_add_value(&json, "runenv", &json_value))
|
||||
goto oom;
|
||||
}
|
||||
|
||||
if (info->runas_group!= NULL) {
|
||||
if (info->runas_uid != (uid_t)-1) {
|
||||
json_value.type = JSON_ID;
|
||||
json_value.u.id = info->runas_gid;
|
||||
if (!sudo_json_add_value(&json, "rungid", &json_value))
|
||||
goto oom;
|
||||
}
|
||||
|
||||
json_value.type = JSON_STRING;
|
||||
json_value.u.string = info->runas_group;
|
||||
if (!sudo_json_add_value(&json, "rungroup", &json_value))
|
||||
goto oom;
|
||||
}
|
||||
|
||||
if (info->runas_uid != (uid_t)-1) {
|
||||
json_value.type = JSON_ID;
|
||||
json_value.u.id = info->runas_uid;
|
||||
if (!sudo_json_add_value(&json, "runuid", &json_value))
|
||||
goto oom;
|
||||
}
|
||||
|
||||
/* Required */
|
||||
json_value.type = JSON_STRING;
|
||||
json_value.u.string = info->runas_user;
|
||||
if (!sudo_json_add_value(&json, "runuser", &json_value))
|
||||
goto oom;
|
||||
|
||||
if (info->cwd != NULL) {
|
||||
json_value.type = JSON_STRING;
|
||||
json_value.u.string = info->cwd;
|
||||
if (!sudo_json_add_value(&json, "submitcwd", &json_value))
|
||||
goto oom;
|
||||
}
|
||||
|
||||
if (info->host != NULL) {
|
||||
json_value.type = JSON_STRING;
|
||||
json_value.u.string = info->host;
|
||||
if (!sudo_json_add_value(&json, "submithost", &json_value))
|
||||
goto oom;
|
||||
}
|
||||
|
||||
/* Required */
|
||||
json_value.type = JSON_STRING;
|
||||
json_value.u.string = info->user;
|
||||
if (!sudo_json_add_value(&json, "submituser", &json_value))
|
||||
goto oom;
|
||||
|
||||
if (info->tty != NULL) {
|
||||
json_value.type = JSON_STRING;
|
||||
json_value.u.string = info->tty;
|
||||
if (!sudo_json_add_value(&json, "ttyname", &json_value))
|
||||
goto oom;
|
||||
}
|
||||
|
||||
fd = iolog_openat(dfd, "log.json", O_CREAT|O_TRUNC|O_WRONLY);
|
||||
if (fd == -1 || (fp = fdopen(fd, "w")) == NULL) {
|
||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
|
||||
"unable to open %s/log.json", parent);
|
||||
goto done;
|
||||
}
|
||||
fd = -1;
|
||||
if (fchown(fd, iolog_uid, iolog_gid) != 0) {
|
||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO,
|
||||
"%s: unable to fchown %d:%d %s/log", __func__,
|
||||
(int)iolog_uid, (int)iolog_gid, parent);
|
||||
}
|
||||
|
||||
fprintf(fp, "{%s\n}\n", sudo_json_get_buf(&json));
|
||||
fflush(fp);
|
||||
if (ferror(fp)) {
|
||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
|
||||
"unable to write to I/O log file %s/log.json", parent);
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret = true;
|
||||
goto done;
|
||||
|
||||
oom:
|
||||
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
|
||||
done:
|
||||
sudo_json_free(&json);
|
||||
if (fp != NULL)
|
||||
fclose(fp);
|
||||
if (fd != -1)
|
||||
close(fd);
|
||||
|
||||
debug_return_bool(ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* Write the I/O log and log.json files that contain user and command info.
|
||||
* These files are not compressed.
|
||||
*/
|
||||
bool
|
||||
iolog_write_info_file(int dfd, const char *parent,
|
||||
struct iolog_info *log_info)
|
||||
{
|
||||
debug_decl(iolog_write_info_file, SUDO_DEBUG_UTIL);
|
||||
|
||||
if (!iolog_write_info_file_legacy(dfd, parent, log_info))
|
||||
debug_return_bool(false);
|
||||
if (!iolog_write_info_file_json(dfd, parent, log_info))
|
||||
debug_return_bool(false);
|
||||
|
||||
debug_return_bool(true);
|
||||
}
|
||||
|
||||
/*
|
||||
* Map IOFD_* -> name.
|
||||
*/
|
||||
|
@@ -95,6 +95,8 @@ iolog_parse_loginfo(int dfd, const char *iolog_dir)
|
||||
*/
|
||||
if ((li = calloc(1, sizeof(*li))) == NULL)
|
||||
sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
|
||||
li->runas_uid = (uid_t)-1;
|
||||
li->runas_gid = (gid_t)-1;
|
||||
if (getdelim(&buf, &bufsize, '\n', fp) == -1 ||
|
||||
getdelim(&li->cwd, &cwdsize, '\n', fp) == -1 ||
|
||||
getdelim(&li->cmd, &cmdsize, '\n', fp) == -1) {
|
||||
@@ -122,7 +124,7 @@ iolog_parse_loginfo(int dfd, const char *iolog_dir)
|
||||
goto bad;
|
||||
}
|
||||
*ep = '\0';
|
||||
li->tstamp = sudo_strtonum(cp, 0, TIME_T_MAX, &errstr);
|
||||
li->tstamp.tv_sec = sudo_strtonum(cp, 0, TIME_T_MAX, &errstr);
|
||||
if (errstr != NULL) {
|
||||
sudo_warn(U_("%s: time stamp %s: %s"), iolog_dir, cp, errstr);
|
||||
goto bad;
|
||||
@@ -427,6 +429,7 @@ iolog_free_loginfo(struct iolog_info *li)
|
||||
free(li->runas_group);
|
||||
free(li->tty);
|
||||
free(li->cmd);
|
||||
free(li->host);
|
||||
free(li);
|
||||
}
|
||||
}
|
||||
|
@@ -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 &&
|
||||
|
@@ -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
|
||||
|
@@ -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];
|
||||
};
|
||||
|
||||
|
@@ -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. */
|
||||
|
@@ -1828,24 +1828,24 @@ match_command.plog: match_command.i
|
||||
match_digest.lo: $(srcdir)/match_digest.c $(devdir)/def_data.h \
|
||||
$(devdir)/gram.h $(incdir)/compat/stdbool.h \
|
||||
$(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
|
||||
$(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
|
||||
$(incdir)/sudo_gettext.h $(incdir)/sudo_plugin.h \
|
||||
$(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
|
||||
$(srcdir)/defaults.h $(srcdir)/logging.h $(srcdir)/parse.h \
|
||||
$(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
|
||||
$(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
|
||||
$(top_builddir)/pathnames.h
|
||||
$(incdir)/sudo_debug.h $(incdir)/sudo_digest.h \
|
||||
$(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
|
||||
$(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
|
||||
$(incdir)/sudo_util.h $(srcdir)/defaults.h \
|
||||
$(srcdir)/logging.h $(srcdir)/parse.h $(srcdir)/sudo_nss.h \
|
||||
$(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
|
||||
$(top_builddir)/config.h $(top_builddir)/pathnames.h
|
||||
$(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/match_digest.c
|
||||
match_digest.i: $(srcdir)/match_digest.c $(devdir)/def_data.h \
|
||||
$(devdir)/gram.h $(incdir)/compat/stdbool.h \
|
||||
$(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
|
||||
$(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
|
||||
$(incdir)/sudo_gettext.h $(incdir)/sudo_plugin.h \
|
||||
$(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
|
||||
$(srcdir)/defaults.h $(srcdir)/logging.h $(srcdir)/parse.h \
|
||||
$(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
|
||||
$(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
|
||||
$(top_builddir)/pathnames.h
|
||||
$(incdir)/sudo_debug.h $(incdir)/sudo_digest.h \
|
||||
$(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
|
||||
$(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
|
||||
$(incdir)/sudo_util.h $(srcdir)/defaults.h \
|
||||
$(srcdir)/logging.h $(srcdir)/parse.h $(srcdir)/sudo_nss.h \
|
||||
$(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
|
||||
$(top_builddir)/config.h $(top_builddir)/pathnames.h
|
||||
$(CC) -E -o $@ $(CPPFLAGS) $<
|
||||
match_digest.plog: match_digest.i
|
||||
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/match_digest.c --i-file $< --output-file $@
|
||||
|
@@ -490,17 +490,22 @@ write_info_log(int dfd, char *iolog_dir, struct iolog_details *details)
|
||||
|
||||
/* XXX - just use iolog_info in the first place? */
|
||||
memset(&iolog_info, 0, sizeof(iolog_info));
|
||||
time(&iolog_info.tstamp);
|
||||
iolog_info.cwd = (char *)details->cwd;
|
||||
iolog_info.user = (char *)details->user;
|
||||
iolog_info.runas_user = details->runas_pw->pw_name;
|
||||
iolog_info.runas_group = details->runas_gr ? details->runas_gr->gr_name: NULL;
|
||||
iolog_info.tty = (char *)details->tty;
|
||||
iolog_info.cwd = (char *)details->cwd;
|
||||
iolog_info.cmd = (char *)details->command;
|
||||
iolog_info.host = (char *)details->host;
|
||||
sudo_gettime_real(&iolog_info.tstamp);
|
||||
iolog_info.lines = details->lines;
|
||||
iolog_info.cols = details->cols;
|
||||
iolog_info.runas_uid = details->runas_pw->pw_uid;
|
||||
iolog_info.runas_gid = details->runas_gr ? details->runas_gr->gr_gid: (gid_t)-1;
|
||||
iolog_info.argv = (char **)details->argv;
|
||||
iolog_info.envp = (char **)details->user_env;
|
||||
|
||||
if (!iolog_write_info_file(dfd, iolog_dir, &iolog_info, details->argv)) {
|
||||
if (!iolog_write_info_file(dfd, iolog_dir, &iolog_info)) {
|
||||
log_warning(SLOG_SEND_MAIL,
|
||||
N_("unable to write to I/O log file: %s"), strerror(errno));
|
||||
warned = true;
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: ISC
|
||||
*
|
||||
* Copyright (c) 2018-2019 Todd C. Miller <Todd.Miller@sudo.ws>
|
||||
* Copyright (c) 2018-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
|
||||
@@ -133,9 +133,9 @@ validate_iolog_info(const char *log_dir)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (info->tstamp < now - 10 || info->tstamp > now + 10) {
|
||||
if (info->tstamp.tv_sec < now - 10 || info->tstamp.tv_sec > now + 10) {
|
||||
sudo_warnx("bad tstamp: want %lld got %lld", (long long)now,
|
||||
(long long)info->tstamp);
|
||||
(long long)info->tstamp.tv_sec);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@@ -124,7 +124,7 @@ struct search_node {
|
||||
bool or;
|
||||
union {
|
||||
regex_t cmdre;
|
||||
time_t tstamp;
|
||||
struct timespec tstamp;
|
||||
char *cwd;
|
||||
char *tty;
|
||||
char *user;
|
||||
@@ -1224,8 +1224,9 @@ parse_expr(struct search_node_list *head, char *argv[], bool sub_expr)
|
||||
if (regcomp(&sn->u.cmdre, *av, REG_EXTENDED|REG_NOSUB) != 0)
|
||||
sudo_fatalx(U_("invalid regular expression: %s"), *av);
|
||||
} else if (type == ST_TODATE || type == ST_FROMDATE) {
|
||||
sn->u.tstamp = get_date(*av);
|
||||
if (sn->u.tstamp == -1)
|
||||
sn->u.tstamp.tv_sec = get_date(*av);
|
||||
sn->u.tstamp.tv_nsec = 0;
|
||||
if (sn->u.tstamp.tv_sec == -1)
|
||||
sudo_fatalx(U_("could not parse date \"%s\""), *av);
|
||||
} else {
|
||||
sn->u.ptr = *av;
|
||||
@@ -1283,10 +1284,10 @@ match_expr(struct search_node_list *head, struct iolog_info *log, bool last_matc
|
||||
res = rc == REG_NOMATCH ? 0 : 1;
|
||||
break;
|
||||
case ST_FROMDATE:
|
||||
res = log->tstamp >= sn->u.tstamp;
|
||||
res = sudo_timespeccmp(&log->tstamp, &sn->u.tstamp, >=);
|
||||
break;
|
||||
case ST_TODATE:
|
||||
res = log->tstamp <= sn->u.tstamp;
|
||||
res = sudo_timespeccmp(&log->tstamp, &sn->u.tstamp, <=);
|
||||
break;
|
||||
default:
|
||||
sudo_fatalx(U_("unknown search type %d"), sn->type);
|
||||
@@ -1332,7 +1333,7 @@ list_session(char *log_dir, regex_t *re, const char *user, const char *tty)
|
||||
idstr = cp;
|
||||
}
|
||||
/* XXX - print lines + cols? */
|
||||
timestr = get_timestr(li->tstamp, 1);
|
||||
timestr = get_timestr(li->tstamp.tv_sec, 1);
|
||||
printf("%s : %s : TTY=%s ; CWD=%s ; USER=%s ; ",
|
||||
timestr ? timestr : "invalid date",
|
||||
li->user, li->tty, li->cwd, li->runas_user);
|
||||
|
Reference in New Issue
Block a user