Add log_exit_status sudoers option to log when a command exits.
This option defaults to off.
This commit is contained in:
@@ -25,7 +25,7 @@
|
|||||||
.nr BA @BAMAN@
|
.nr BA @BAMAN@
|
||||||
.nr LC @LCMAN@
|
.nr LC @LCMAN@
|
||||||
.nr PS @PSMAN@
|
.nr PS @PSMAN@
|
||||||
.TH "SUDOERS" "@mansectform@" "May 7, 2021" "Sudo @PACKAGE_VERSION@" "File Formats Manual"
|
.TH "SUDOERS" "@mansectform@" "July 9, 2021" "Sudo @PACKAGE_VERSION@" "File Formats Manual"
|
||||||
.nh
|
.nh
|
||||||
.if n .ad l
|
.if n .ad l
|
||||||
.SH "NAME"
|
.SH "NAME"
|
||||||
@@ -2728,6 +2728,17 @@ by default.
|
|||||||
.sp
|
.sp
|
||||||
This setting is only supported by version 1.8.29 or higher.
|
This setting is only supported by version 1.8.29 or higher.
|
||||||
.TP 18n
|
.TP 18n
|
||||||
|
log_exit_status
|
||||||
|
If set,
|
||||||
|
\fBsudoers\fR
|
||||||
|
will log the exit value of commands that are run to syslog and/or a log file.
|
||||||
|
If a command was terminated by a signal, the signal name is logged as well.
|
||||||
|
This flag is
|
||||||
|
\fIoff\fR
|
||||||
|
by default.
|
||||||
|
.sp
|
||||||
|
This setting is only supported by version 1.9.8 or higher.
|
||||||
|
.TP 18n
|
||||||
log_host
|
log_host
|
||||||
If set, the host name will be included in log entries written to
|
If set, the host name will be included in log entries written to
|
||||||
the file configured by the
|
the file configured by the
|
||||||
|
@@ -24,7 +24,7 @@
|
|||||||
.nr BA @BAMAN@
|
.nr BA @BAMAN@
|
||||||
.nr LC @LCMAN@
|
.nr LC @LCMAN@
|
||||||
.nr PS @PSMAN@
|
.nr PS @PSMAN@
|
||||||
.Dd May 7, 2021
|
.Dd July 9, 2021
|
||||||
.Dt SUDOERS @mansectform@
|
.Dt SUDOERS @mansectform@
|
||||||
.Os Sudo @PACKAGE_VERSION@
|
.Os Sudo @PACKAGE_VERSION@
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@@ -2573,6 +2573,16 @@ This flag is
|
|||||||
by default.
|
by default.
|
||||||
.Pp
|
.Pp
|
||||||
This setting is only supported by version 1.8.29 or higher.
|
This setting is only supported by version 1.8.29 or higher.
|
||||||
|
.It log_exit_status
|
||||||
|
If set,
|
||||||
|
.Nm
|
||||||
|
will log the exit value of commands that are run to syslog and/or a log file.
|
||||||
|
If a command was terminated by a signal, the signal name is logged as well.
|
||||||
|
This flag is
|
||||||
|
.Em off
|
||||||
|
by default.
|
||||||
|
.Pp
|
||||||
|
This setting is only supported by version 1.9.8 or higher.
|
||||||
.It log_host
|
.It log_host
|
||||||
If set, the host name will be included in log entries written to
|
If set, the host name will be included in log entries written to
|
||||||
the file configured by the
|
the file configured by the
|
||||||
|
@@ -577,6 +577,10 @@ struct sudo_defs_types sudo_defs_table[] = {
|
|||||||
"admin_flag", T_STR|T_BOOL|T_CHPATH,
|
"admin_flag", T_STR|T_BOOL|T_CHPATH,
|
||||||
N_("Path to the file that is created the first time sudo is run: %s"),
|
N_("Path to the file that is created the first time sudo is run: %s"),
|
||||||
NULL,
|
NULL,
|
||||||
|
}, {
|
||||||
|
"log_exit_status", T_FLAG,
|
||||||
|
N_("Log the exit status of commands"),
|
||||||
|
NULL,
|
||||||
}, {
|
}, {
|
||||||
NULL, 0, NULL
|
NULL, 0, NULL
|
||||||
}
|
}
|
||||||
|
@@ -266,6 +266,8 @@
|
|||||||
#define def_selinux (sudo_defs_table[I_SELINUX].sd_un.flag)
|
#define def_selinux (sudo_defs_table[I_SELINUX].sd_un.flag)
|
||||||
#define I_ADMIN_FLAG 132
|
#define I_ADMIN_FLAG 132
|
||||||
#define def_admin_flag (sudo_defs_table[I_ADMIN_FLAG].sd_un.str)
|
#define def_admin_flag (sudo_defs_table[I_ADMIN_FLAG].sd_un.str)
|
||||||
|
#define I_LOG_EXIT_STATUS 133
|
||||||
|
#define def_log_exit_status (sudo_defs_table[I_LOG_EXIT_STATUS].sd_un.flag)
|
||||||
|
|
||||||
enum def_tuple {
|
enum def_tuple {
|
||||||
never,
|
never,
|
||||||
|
@@ -415,3 +415,6 @@ selinux
|
|||||||
admin_flag
|
admin_flag
|
||||||
T_STR|T_BOOL|T_CHPATH
|
T_STR|T_BOOL|T_CHPATH
|
||||||
"Path to the file that is created the first time sudo is run: %s"
|
"Path to the file that is created the first time sudo is run: %s"
|
||||||
|
log_exit_status
|
||||||
|
T_FLAG
|
||||||
|
"Log the exit status of commands"
|
||||||
|
@@ -492,6 +492,63 @@ log_allowed(void)
|
|||||||
debug_return_bool(ret);
|
debug_return_bool(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
log_exit_status(int exit_status)
|
||||||
|
{
|
||||||
|
struct eventlog evlog;
|
||||||
|
int evl_flags = 0;
|
||||||
|
int ecode = 0;
|
||||||
|
int oldlocale;
|
||||||
|
struct timespec run_time;
|
||||||
|
char sigbuf[SIG2STR_MAX];
|
||||||
|
char *signame = NULL;
|
||||||
|
bool dumped_core = false;
|
||||||
|
bool ret = true;
|
||||||
|
debug_decl(log_exit_status, SUDOERS_DEBUG_LOGGING);
|
||||||
|
|
||||||
|
if (def_log_exit_status || def_mail_always) {
|
||||||
|
if (sudo_gettime_real(&run_time) == -1) {
|
||||||
|
sudo_warn("%s", U_("unable to get time of day"));
|
||||||
|
ret = false;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
sudo_timespecsub(&run_time, &sudo_user.submit_time, &run_time);
|
||||||
|
|
||||||
|
if (WIFEXITED(exit_status)) {
|
||||||
|
ecode = WEXITSTATUS(exit_status);
|
||||||
|
} else if (WIFSIGNALED(exit_status)) {
|
||||||
|
int signo = WTERMSIG(exit_status);
|
||||||
|
if (signo <= 0 || sig2str(signo, sigbuf) == -1)
|
||||||
|
(void)snprintf(sigbuf, sizeof(sigbuf), "%d", signo);
|
||||||
|
signame = sigbuf;
|
||||||
|
ecode = signo | 128;
|
||||||
|
dumped_core = WCOREDUMP(exit_status);
|
||||||
|
} else {
|
||||||
|
sudo_warnx("invalid exit status 0x%x", exit_status);
|
||||||
|
ret = false;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Log and mail messages should be in the sudoers locale. */
|
||||||
|
sudoers_setlocale(SUDOERS_LOCALE_SUDOERS, &oldlocale);
|
||||||
|
|
||||||
|
sudoers_to_eventlog(&evlog, NewArgv, env_get());
|
||||||
|
if (def_mail_always) {
|
||||||
|
SET(evl_flags, EVLOG_MAIL);
|
||||||
|
if (!def_log_exit_status)
|
||||||
|
SET(evl_flags, EVLOG_MAIL_ONLY);
|
||||||
|
}
|
||||||
|
if (!eventlog_exit(&evlog, evl_flags, &run_time, ecode, signame,
|
||||||
|
dumped_core, NULL, NULL))
|
||||||
|
ret = false;
|
||||||
|
|
||||||
|
sudoers_setlocale(oldlocale, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
debug_return_bool(ret);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Perform logging for log_warning()/log_warningx().
|
* Perform logging for log_warning()/log_warningx().
|
||||||
*/
|
*/
|
||||||
|
@@ -57,6 +57,7 @@ int sudoers_getlocale(void);
|
|||||||
int audit_failure(char *const argv[], char const *const fmt, ...) __printflike(2, 3);
|
int audit_failure(char *const argv[], char const *const fmt, ...) __printflike(2, 3);
|
||||||
int vaudit_failure(char *const argv[], char const *const fmt, va_list ap) __printflike(2, 0);
|
int vaudit_failure(char *const argv[], char const *const fmt, va_list ap) __printflike(2, 0);
|
||||||
bool log_allowed(void);
|
bool log_allowed(void);
|
||||||
|
bool log_exit_status(int exit_status);
|
||||||
bool log_auth_failure(int status, unsigned int tries);
|
bool log_auth_failure(int status, unsigned int tries);
|
||||||
bool log_denial(int status, bool inform_user);
|
bool log_denial(int status, bool inform_user);
|
||||||
bool log_failure(int status, int flags);
|
bool log_failure(int status, int flags);
|
||||||
|
@@ -961,10 +961,11 @@ sudoers_policy_close(int exit_status, int error_code)
|
|||||||
/* Close the session we opened in sudoers_policy_init_session(). */
|
/* Close the session we opened in sudoers_policy_init_session(). */
|
||||||
(void)sudo_auth_end_session(runas_pw);
|
(void)sudo_auth_end_session(runas_pw);
|
||||||
|
|
||||||
/* We do not currently log the exit status. */
|
|
||||||
if (error_code) {
|
if (error_code) {
|
||||||
errno = error_code;
|
errno = error_code;
|
||||||
sudo_warn(U_("unable to execute %s"), safe_cmnd);
|
sudo_warn(U_("unable to execute %s"), safe_cmnd);
|
||||||
|
} else {
|
||||||
|
log_exit_status(exit_status);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1044,8 +1045,8 @@ sudoers_policy_check(int argc, char * const argv[], char *env_add[],
|
|||||||
#ifndef NO_LEAKS
|
#ifndef NO_LEAKS
|
||||||
if (ret == true && sudo_version >= SUDO_API_MKVERSION(1, 3)) {
|
if (ret == true && sudo_version >= SUDO_API_MKVERSION(1, 3)) {
|
||||||
/* Unset close function if we don't need it to avoid extra process. */
|
/* Unset close function if we don't need it to avoid extra process. */
|
||||||
if (!def_log_input && !def_log_output && !def_use_pty &&
|
if (!def_log_input && !def_log_output && !def_log_exit_status &&
|
||||||
!sudo_auth_needs_end_session())
|
!def_use_pty && !sudo_auth_needs_end_session())
|
||||||
sudoers_policy.close = NULL;
|
sudoers_policy.close = NULL;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@@ -704,6 +704,13 @@ log_failure(int status, int flags)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* STUB */
|
||||||
|
bool
|
||||||
|
log_exit_status(int exit_status)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/* STUB */
|
/* STUB */
|
||||||
int
|
int
|
||||||
audit_failure(char *const argv[], char const *const fmt, ...)
|
audit_failure(char *const argv[], char const *const fmt, ...)
|
||||||
|
Reference in New Issue
Block a user