2
0
mirror of https://github.com/sudo-project/sudo.git synced 2025-09-03 15:55:40 +00:00

No longer need to pass exit params to eventlog_exit(), use struct eventlog.

Now that struct eventlog includes the exit parameters we can simplify
how eventlog_exit() is called.
This commit is contained in:
Todd C. Miller
2021-10-19 08:58:34 -06:00
parent d415624ffc
commit bddf03fe45
4 changed files with 62 additions and 54 deletions

View File

@@ -129,7 +129,7 @@ struct json_container;
typedef bool (*eventlog_json_callback_t)(struct json_container *, void *); 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); bool eventlog_accept(const struct eventlog *evlog, int flags, eventlog_json_callback_t info_cb, void *info);
bool eventlog_exit(const struct eventlog *evlog, int flags, struct timespec *run_time, int exit_value, const char *signal_name, bool core_dumped); 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_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_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 *json, const struct eventlog *evlog); bool eventlog_store_json(struct json_container *json, const struct eventlog *evlog);

View File

@@ -80,10 +80,7 @@
struct eventlog_args { struct eventlog_args {
const char *reason; const char *reason;
const char *errstr; const char *errstr;
const char *signal_name;
const struct timespec *event_time; const struct timespec *event_time;
int exit_value;
bool core_dumped;
eventlog_json_callback_t json_info_cb; eventlog_json_callback_t json_info_cb;
void *json_info; void *json_info;
}; };
@@ -201,10 +198,12 @@ new_logline(int event_type, int flags, struct eventlog_args *args,
len += strlen(evlog->argv[i]) + 1; len += strlen(evlog->argv[i]) + 1;
} }
if (event_type == EVLOG_EXIT) { if (event_type == EVLOG_EXIT) {
if (args->signal_name != NULL) if (evlog->signal_name != NULL)
len += sizeof(LL_SIGNAL_STR) + 2 + strlen(args->signal_name); len += sizeof(LL_SIGNAL_STR) + 2 + strlen(evlog->signal_name);
(void)snprintf(exit_str, sizeof(exit_str), "%d", args->exit_value); if (evlog->exit_value != -1) {
len += sizeof(LL_EXIT_STR) + 2 + strlen(exit_str); (void)snprintf(exit_str, sizeof(exit_str), "%d", evlog->exit_value);
len += sizeof(LL_EXIT_STR) + 2 + strlen(exit_str);
}
} }
} }
@@ -289,16 +288,18 @@ new_logline(int event_type, int flags, struct eventlog_args *args,
} }
} }
if (event_type == EVLOG_EXIT) { if (event_type == EVLOG_EXIT) {
if (args->signal_name != NULL) { if (evlog->signal_name != NULL) {
if (strlcat(line, " ; ", len) >= len || if (strlcat(line, " ; ", len) >= len ||
strlcat(line, LL_SIGNAL_STR, len) >= len || strlcat(line, LL_SIGNAL_STR, len) >= len ||
strlcat(line, args->signal_name, len) >= len) strlcat(line, evlog->signal_name, len) >= len)
goto toobig;
}
if (evlog->exit_value != -1) {
if (strlcat(line, " ; ", len) >= len ||
strlcat(line, LL_EXIT_STR, len) >= len ||
strlcat(line, exit_str, len) >= len)
goto toobig; goto toobig;
} }
if (strlcat(line, " ; ", len) >= len ||
strlcat(line, LL_EXIT_STR, len) >= len ||
strlcat(line, exit_str, len) >= len)
goto toobig;
} }
} }
@@ -819,7 +820,6 @@ format_json(int event_type, struct eventlog_args *args,
struct json_container json = { 0 }; struct json_container json = { 0 };
struct json_value json_value; struct json_value json_value;
const char *time_str, *type_str; const char *time_str, *type_str;
bool format_timestamp = true;
struct timespec now; struct timespec now;
debug_decl(format_json, SUDO_DEBUG_UTIL); debug_decl(format_json, SUDO_DEBUG_UTIL);
@@ -849,8 +849,7 @@ format_json(int event_type, struct eventlog_args *args,
break; break;
case EVLOG_EXIT: case EVLOG_EXIT:
type_str = "exit"; type_str = "exit";
time_str = "run_time"; time_str = "exit_time";
format_timestamp = false;
break; break;
default: default:
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO, sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
@@ -901,7 +900,7 @@ format_json(int event_type, struct eventlog_args *args,
/* Log event time from client */ /* Log event time from client */
if (args->event_time != NULL) { if (args->event_time != NULL) {
if (!json_add_timestamp(&json, time_str, args->event_time, format_timestamp)) { if (!json_add_timestamp(&json, time_str, args->event_time, true)) {
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO, sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
"unable format timestamp"); "unable format timestamp");
goto bad; goto bad;
@@ -915,19 +914,26 @@ format_json(int event_type, struct eventlog_args *args,
info = NULL; info = NULL;
} }
if (args->signal_name != NULL) { if (sudo_timespecisset(&evlog->run_time)) {
if (!json_add_timestamp(&json, "run_time", &evlog->run_time, false)) {
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
"unable format timestamp");
goto bad;
}
}
if (evlog->signal_name != NULL) {
json_value.type = JSON_STRING; json_value.type = JSON_STRING;
json_value.u.string = args->signal_name; json_value.u.string = evlog->signal_name;
if (!sudo_json_add_value(&json, "signal", &json_value)) if (!sudo_json_add_value(&json, "signal", &json_value))
goto bad; goto bad;
json_value.type = JSON_BOOL; json_value.type = JSON_BOOL;
json_value.u.boolean = args->core_dumped; json_value.u.boolean = evlog->dumped_core;
if (!sudo_json_add_value(&json, "dumped_core", &json_value)) if (!sudo_json_add_value(&json, "dumped_core", &json_value))
goto bad; goto bad;
} }
json_value.type = JSON_NUMBER; json_value.type = JSON_NUMBER;
json_value.u.number = args->exit_value; json_value.u.number = evlog->exit_value;
if (!sudo_json_add_value(&json, "exit_value", &json_value)) if (!sudo_json_add_value(&json, "exit_value", &json_value))
goto bad; goto bad;
} }
@@ -1369,20 +1375,19 @@ eventlog_alert(const struct eventlog *evlog, int flags,
} }
bool bool
eventlog_exit(const struct eventlog *evlog, int flags, eventlog_exit(const struct eventlog *evlog, int flags)
struct timespec *run_time, int exit_value, const char *signal_name,
bool core_dumped)
{ {
const struct eventlog_config *evl_conf = eventlog_getconf(); const struct eventlog_config *evl_conf = eventlog_getconf();
const int log_type = evl_conf->type; const int log_type = evl_conf->type;
struct eventlog_args args = { NULL }; struct eventlog_args args = { NULL };
struct timespec exit_time;
bool ret = true; bool ret = true;
debug_decl(eventlog_exit, SUDO_DEBUG_UTIL); debug_decl(eventlog_exit, SUDO_DEBUG_UTIL);
args.signal_name = signal_name; if (sudo_timespecisset(&evlog->run_time)) {
args.core_dumped = core_dumped; sudo_timespecadd(&evlog->submit_time, &evlog->run_time, &exit_time);
args.exit_value = exit_value; args.event_time = &exit_time;
args.event_time = run_time; }
if (ISSET(log_type, EVLOG_SYSLOG)) { if (ISSET(log_type, EVLOG_SYSLOG)) {
if (!do_syslog(EVLOG_EXIT, flags, &args, evlog)) if (!do_syslog(EVLOG_EXIT, flags, &args, evlog))

View File

@@ -262,9 +262,7 @@ done:
} }
static bool static bool
store_exit_info_json(int dfd, struct timespec *run_time, int exit_value, store_exit_info_json(int dfd, struct eventlog *evlog)
const char *signal_name, bool core_dumped,
struct connection_closure *closure)
{ {
struct json_container json = { 0 }; struct json_container json = { 0 };
struct json_value json_value; struct json_value json_value;
@@ -280,7 +278,7 @@ store_exit_info_json(int dfd, struct timespec *run_time, int exit_value,
fd = openat(dfd, "log.json", O_RDWR); fd = openat(dfd, "log.json", O_RDWR);
if (fd == -1) { if (fd == -1) {
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO, sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
"unable to open to %s/log.json", closure->evlog->iolog_path); "unable to open to %s/log.json", evlog->iolog_path);
if (errno == ENOENT) { if (errno == ENOENT) {
/* Ignore missing log.json file. */ /* Ignore missing log.json file. */
ret = true; ret = true;
@@ -288,17 +286,17 @@ store_exit_info_json(int dfd, struct timespec *run_time, int exit_value,
goto done; goto done;
} }
if (run_time != NULL) { if (sudo_timespecisset(&evlog->run_time)) {
if (!sudo_json_open_object(&json, "run_time")) if (!sudo_json_open_object(&json, "run_time"))
goto done; goto done;
json_value.type = JSON_NUMBER; json_value.type = JSON_NUMBER;
json_value.u.number = run_time->tv_sec; json_value.u.number = evlog->run_time.tv_sec;
if (!sudo_json_add_value(&json, "seconds", &json_value)) if (!sudo_json_add_value(&json, "seconds", &json_value))
goto done; goto done;
json_value.type = JSON_NUMBER; json_value.type = JSON_NUMBER;
json_value.u.number = run_time->tv_nsec; json_value.u.number = evlog->run_time.tv_nsec;
if (!sudo_json_add_value(&json, "nanoseconds", &json_value)) if (!sudo_json_add_value(&json, "nanoseconds", &json_value))
goto done; goto done;
@@ -306,20 +304,20 @@ store_exit_info_json(int dfd, struct timespec *run_time, int exit_value,
goto done; goto done;
} }
if (signal_name != NULL) { if (evlog->signal_name != NULL) {
json_value.type = JSON_STRING; json_value.type = JSON_STRING;
json_value.u.string = signal_name; json_value.u.string = evlog->signal_name;
if (!sudo_json_add_value(&json, "signal", &json_value)) if (!sudo_json_add_value(&json, "signal", &json_value))
goto done; goto done;
json_value.type = JSON_BOOL; json_value.type = JSON_BOOL;
json_value.u.boolean = core_dumped; json_value.u.boolean = evlog->dumped_core;
if (!sudo_json_add_value(&json, "dumped_core", &json_value)) if (!sudo_json_add_value(&json, "dumped_core", &json_value))
goto done; goto done;
} }
json_value.type = JSON_NUMBER; json_value.type = JSON_NUMBER;
json_value.u.number = exit_value; json_value.u.number = evlog->exit_value;
if (!sudo_json_add_value(&json, "exit_value", &json_value)) if (!sudo_json_add_value(&json, "exit_value", &json_value))
goto done; goto done;
@@ -327,7 +325,7 @@ store_exit_info_json(int dfd, struct timespec *run_time, int exit_value,
pos = lseek(fd, -3, SEEK_END); pos = lseek(fd, -3, SEEK_END);
if (pos == -1) { if (pos == -1) {
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO, sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
"unable to rewind %s/log.json 3 bytes", closure->evlog->iolog_path); "unable to rewind %s/log.json 3 bytes", evlog->iolog_path);
goto done; goto done;
} }
@@ -340,7 +338,7 @@ store_exit_info_json(int dfd, struct timespec *run_time, int exit_value,
iov[2].iov_len = 3; iov[2].iov_len = 3;
if (writev(fd, iov, 3) == -1) { if (writev(fd, iov, 3) == -1) {
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO, sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
"unable to write %s/log.json", closure->evlog->iolog_path); "unable to write %s/log.json", evlog->iolog_path);
/* Back up and try to restore to original state. */ /* Back up and try to restore to original state. */
if (lseek(fd, pos, SEEK_SET) != -1) { if (lseek(fd, pos, SEEK_SET) != -1) {
ignore_result(write(fd, "\n}\n", 3)); ignore_result(write(fd, "\n}\n", 3));
@@ -361,28 +359,31 @@ bool
store_exit_local(ExitMessage *msg, uint8_t *buf, size_t len, store_exit_local(ExitMessage *msg, uint8_t *buf, size_t len,
struct connection_closure *closure) struct connection_closure *closure)
{ {
struct timespec ts, *run_time = NULL; struct eventlog *evlog = closure->evlog;
const char *signame = NULL;
int flags = 0; int flags = 0;
debug_decl(store_exit_local, SUDO_DEBUG_UTIL); debug_decl(store_exit_local, SUDO_DEBUG_UTIL);
if (msg->run_time != NULL) { if (msg->run_time != NULL) {
ts.tv_sec = msg->run_time->tv_sec; evlog->run_time.tv_sec = msg->run_time->tv_sec;
ts.tv_nsec = msg->run_time->tv_nsec; evlog->run_time.tv_nsec = msg->run_time->tv_nsec;
run_time = &ts;
} }
evlog->exit_value = msg->exit_value;
if (msg->signal != NULL && msg->signal[0] != '\0') { if (msg->signal != NULL && msg->signal[0] != '\0') {
signame = msg->signal;
sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO, sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
"command was killed by SIG%s%s", msg->signal, "command was killed by SIG%s%s", msg->signal,
msg->dumped_core ? " (core dumped)" : ""); msg->dumped_core ? " (core dumped)" : "");
evlog->signal_name = strdup(msg->signal);
if (evlog->signal_name == NULL) {
closure->errstr = _("unable to allocate memory");
debug_return_bool(false);
}
evlog->dumped_core = msg->dumped_core;
} else { } else {
sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO, sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
"command exited with %d", msg->exit_value); "command exited with %d", msg->exit_value);
} }
if (logsrvd_conf_log_exit()) { if (logsrvd_conf_log_exit()) {
if (!eventlog_exit(closure->evlog, flags, run_time, msg->exit_value, if (!eventlog_exit(closure->evlog, flags)) {
signame, msg->dumped_core)) {
closure->errstr = _("error logging exit event"); closure->errstr = _("error logging exit event");
debug_return_bool(false); debug_return_bool(false);
} }
@@ -390,8 +391,7 @@ store_exit_local(ExitMessage *msg, uint8_t *buf, size_t len,
if (closure->log_io) { if (closure->log_io) {
/* Store the run time and exit status in log.json. */ /* Store the run time and exit status in log.json. */
if (!store_exit_info_json(closure->iolog_dir_fd, run_time, if (!store_exit_info_json(closure->iolog_dir_fd, evlog)) {
msg->exit_value, signame, msg->dumped_core, closure)) {
closure->errstr = _("error logging exit event"); closure->errstr = _("error logging exit event");
debug_return_bool(false); debug_return_bool(false);
} }

View File

@@ -575,8 +575,11 @@ log_exit_status(int exit_status)
if (!def_log_exit_status) if (!def_log_exit_status)
SET(evl_flags, EVLOG_MAIL_ONLY); SET(evl_flags, EVLOG_MAIL_ONLY);
} }
if (!eventlog_exit(&evlog, evl_flags, &run_time, ecode, signame, evlog.run_time = run_time;
dumped_core)) evlog.exit_value = ecode;
evlog.signal_name = signame;
evlog.dumped_core = dumped_core;
if (!eventlog_exit(&evlog, evl_flags))
ret = false; ret = false;
sudoers_setlocale(oldlocale, NULL); sudoers_setlocale(oldlocale, NULL);