diff --git a/include/sudo_eventlog.h b/include/sudo_eventlog.h index 76947d239..74a67dd46 100644 --- a/include/sudo_eventlog.h +++ b/include/sudo_eventlog.h @@ -111,6 +111,7 @@ struct eventlog { char **env_add; char **envp; struct timespec submit_time; + struct timespec iolog_offset; int lines; int columns; uid_t runuid; diff --git a/lib/eventlog/eventlog.c b/lib/eventlog/eventlog.c index 26c5f6dc7..0e86fbf63 100644 --- a/lib/eventlog/eventlog.c +++ b/lib/eventlog/eventlog.c @@ -100,7 +100,7 @@ new_logline(int event_type, int flags, struct eventlog_args *args, const char *iolog_file = evlog->iolog_file; const char *tty, *tsid = NULL; char exit_str[(((sizeof(int) * 8) + 2) / 3) + 2]; - char sessid[7]; + char sessid[7], offsetstr[64] = ""; size_t len = 0; int i; debug_decl(new_logline, SUDO_DEBUG_UTIL); @@ -132,6 +132,10 @@ new_logline(int event_type, int flags, struct eventlog_args *args, } else { tsid = iolog_file; } + if (sudo_timespecisset(&evlog->iolog_offset)) { + (void)snprintf(offsetstr, sizeof(offsetstr), "@%lld.%09ld", + evlog->iolog_offset.tv_sec, evlog->iolog_offset.tv_nsec); + } } /* Sudo-format logs use the short form of the ttyname. */ @@ -159,8 +163,9 @@ new_logline(int event_type, int flags, struct eventlog_args *args, len += sizeof(LL_USER_STR) + 2 + strlen(evlog->runuser); if (evlog->rungroup != NULL) len += sizeof(LL_GROUP_STR) + 2 + strlen(evlog->rungroup); - if (tsid != NULL) - len += sizeof(LL_TSID_STR) + 2 + strlen(tsid); + if (tsid != NULL) { + len += sizeof(LL_TSID_STR) + 2 + strlen(tsid) + strlen(offsetstr); + } if (evlog->env_add != NULL) { size_t evlen = 0; char * const *ep; @@ -251,6 +256,7 @@ new_logline(int event_type, int flags, struct eventlog_args *args, if (tsid != NULL) { if (strlcat(line, LL_TSID_STR, len) >= len || strlcat(line, tsid, len) >= len || + strlcat(line, offsetstr, len) >= len || strlcat(line, " ; ", len) >= len) goto toobig; } @@ -860,14 +866,14 @@ format_json(int event_type, struct eventlog_args *args, /* Log event time on server (set earlier) */ if (!json_add_timestamp(&json, "server_time", &now, true)) { - sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO|SUDO_DEBUG_LINENO, + sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO, "unable format timestamp"); goto bad; } /* Log event time from client */ if (!json_add_timestamp(&json, time_str, args->event_time, format_timestamp)) { - sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO|SUDO_DEBUG_LINENO, + sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO, "unable format timestamp"); goto bad; } @@ -910,6 +916,14 @@ format_json(int event_type, struct eventlog_args *args, json_value.u.string = evlog->iolog_path; if (!sudo_json_add_value(&json, "iolog_path", &json_value)) goto bad; + + if (sudo_timespecisset(&evlog->iolog_offset)) { + if (!json_add_timestamp(&json, "iolog_offset", &evlog->iolog_offset, false)) { + sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO, + "unable format timestamp"); + goto bad; + } + } } } diff --git a/logsrvd/logsrvd_local.c b/logsrvd/logsrvd_local.c index c8b17774b..58c0323aa 100644 --- a/logsrvd/logsrvd_local.c +++ b/logsrvd/logsrvd_local.c @@ -166,6 +166,20 @@ store_accept_local(AcceptMessage *msg, uint8_t *buf, size_t len, closure->log_io = true; log_id = closure->evlog->iolog_path; } + } else if (closure->log_io) { + /* Sub-command from an existing session, set iolog and offset. */ + evlog->iolog_path = strdup(closure->evlog->iolog_path); + if (evlog->iolog_path == NULL) { + sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory")); + closure->errstr = _("unable to allocate memory"); + goto done; + } + if (closure->evlog->iolog_file != NULL) { + evlog->iolog_file = evlog->iolog_path + + (closure->evlog->iolog_file - closure->evlog->iolog_path); + } + sudo_timespecsub(&evlog->submit_time, &closure->evlog->submit_time, + &evlog->iolog_offset); } if (!eventlog_accept(evlog, 0, logsrvd_json_log_cb, &info)) { @@ -215,6 +229,20 @@ store_reject_local(RejectMessage *msg, uint8_t *buf, size_t len, if (closure->evlog == NULL) { /* Initial command in session. */ closure->evlog = evlog; + } else if (closure->log_io) { + /* Sub-command from an existing session, set iolog and offset. */ + evlog->iolog_path = strdup(closure->evlog->iolog_path); + if (evlog->iolog_path == NULL) { + sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory")); + closure->errstr = _("unable to allocate memory"); + goto done; + } + if (closure->evlog->iolog_file != NULL) { + evlog->iolog_file = evlog->iolog_path + + (closure->evlog->iolog_file - closure->evlog->iolog_path); + } + sudo_timespecsub(&evlog->submit_time, &closure->evlog->submit_time, + &evlog->iolog_offset); } if (!eventlog_reject(evlog, 0, msg->reason, logsrvd_json_log_cb, &info)) { diff --git a/plugins/sudoers/logging.c b/plugins/sudoers/logging.c index 668c4d87b..1e1e37fa1 100644 --- a/plugins/sudoers/logging.c +++ b/plugins/sudoers/logging.c @@ -804,6 +804,14 @@ sudoers_to_eventlog(struct eventlog *evlog, char * const argv[], } else { strlcpy(evlog->uuid_str, uuid_str, sizeof(evlog->uuid_str)); } + if (ISSET(sudo_mode, MODE_POLICY_INTERCEPTED)) { + struct timespec now; + if (sudo_gettime_real(&now) == -1) { + sudo_warn("%s", U_("unable to get time of day")); + } else { + sudo_timespecsub(&now, &sudo_user.submit_time, &evlog->iolog_offset); + } + } debug_return; }