Move sudo_mode into struct sudoers_context.

This commit is contained in:
Todd C. Miller
2023-08-21 10:47:23 -06:00
parent 837da1bef0
commit 3473bf9360
12 changed files with 147 additions and 137 deletions

View File

@@ -249,7 +249,7 @@ audit_to_eventlog(const struct sudoers_context *ctx, struct eventlog *evlog,
#ifdef SUDOERS_LOG_CLIENT #ifdef SUDOERS_LOG_CLIENT
static bool static bool
log_server_accept(struct eventlog *evlog) log_server_accept(const struct sudoers_context *ctx, struct eventlog *evlog)
{ {
struct timespec now; struct timespec now;
bool ret = false; bool ret = false;
@@ -258,7 +258,7 @@ log_server_accept(struct eventlog *evlog)
if (SLIST_EMPTY(&def_log_servers)) if (SLIST_EMPTY(&def_log_servers))
debug_return_bool(true); debug_return_bool(true);
if (client_closure != NULL && ISSET(sudo_mode, MODE_POLICY_INTERCEPTED)) { if (client_closure != NULL && ISSET(ctx->mode, MODE_POLICY_INTERCEPTED)) {
/* Older servers don't support multiple commands per session. */ /* Older servers don't support multiple commands per session. */
if (!client_closure->subcommands) if (!client_closure->subcommands)
debug_return_bool(true); debug_return_bool(true);
@@ -325,7 +325,7 @@ log_server_exit(int status_type, int status)
} }
#else #else
static bool static bool
log_server_accept(struct eventlog *evlog) log_server_accept(struct sudoers_context *ctx, struct eventlog *evlog)
{ {
return true; return true;
} }
@@ -359,22 +359,26 @@ sudoers_audit_accept(const char *plugin_name, unsigned int plugin_type,
if (audit_success(ctx, run_argv) != 0 && !def_ignore_audit_errors) if (audit_success(ctx, run_argv) != 0 && !def_ignore_audit_errors)
ret = false; ret = false;
if (!ISSET(sudo_mode, MODE_POLICY_INTERCEPTED)) if (!ISSET(ctx->mode, MODE_POLICY_INTERCEPTED))
uuid_str = ctx->user.uuid_str; uuid_str = ctx->user.uuid_str;
audit_to_eventlog(ctx, &evlog, command_info, run_argv, run_envp, uuid_str); audit_to_eventlog(ctx, &evlog, command_info, run_argv, run_envp, uuid_str);
if (!log_allowed(&evlog) && !def_ignore_logfile_errors) if (!log_allowed(ctx, &evlog) && !def_ignore_logfile_errors)
ret = false; ret = false;
if (!log_server_accept(&evlog)) { if (!log_server_accept(ctx, &evlog)) {
if (!def_ignore_logfile_errors) if (!def_ignore_logfile_errors)
ret = false; ret = false;
} }
if (first) { if (first) {
/* log_subcmds doesn't go through sudo_policy_main again to set this. */ /* log_subcmds doesn't go through sudo_policy_main again to set this. */
if (def_log_subcmds) if (def_log_subcmds) {
SET(sudo_mode, MODE_POLICY_INTERCEPTED); if (!sudoers_set_mode(MODE_POLICY_INTERCEPTED, UINT_MAX)) {
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
"unable to set 0x%x in ctx->mode", MODE_POLICY_INTERCEPTED);
}
}
first = false; first = false;
} }
@@ -407,7 +411,7 @@ sudoers_audit_reject(const char *plugin_name, unsigned int plugin_type,
if (!eventlog_reject(&evlog, 0, message, NULL, NULL)) if (!eventlog_reject(&evlog, 0, message, NULL, NULL))
ret = false; ret = false;
if (!log_server_reject(&evlog, message)) if (!log_server_reject(ctx, &evlog, message))
ret = false; ret = false;
debug_return_int(ret); debug_return_int(ret);
@@ -442,7 +446,7 @@ sudoers_audit_error(const char *plugin_name, unsigned int plugin_type,
if (!eventlog_alert(&evlog, 0, &now, message, NULL)) if (!eventlog_alert(&evlog, 0, &now, message, NULL))
ret = false; ret = false;
if (!log_server_alert(&evlog, &now, message, NULL)) if (!log_server_alert(ctx, &evlog, &now, message, NULL))
ret = false; ret = false;
debug_return_int(ret); debug_return_int(ret);

View File

@@ -102,7 +102,7 @@ static pam_handle_t *pamh;
static struct conv_filter *conv_filter; static struct conv_filter *conv_filter;
static void static void
conv_filter_init(void) conv_filter_init(const struct sudoers_context *ctx)
{ {
debug_decl(conv_filter_init, SUDOERS_DEBUG_AUTH); debug_decl(conv_filter_init, SUDOERS_DEBUG_AUTH);
@@ -112,7 +112,7 @@ conv_filter_init(void)
* management (in trusted mode) or session management (regular mode). * management (in trusted mode) or session management (regular mode).
* Filter those out in the conversation function unless running a shell. * Filter those out in the conversation function unless running a shell.
*/ */
if (!ISSET(sudo_mode, MODE_SHELL|MODE_LOGIN_SHELL)) { if (!ISSET(ctx->mode, MODE_SHELL|MODE_LOGIN_SHELL)) {
int i, nfilt = 0, maxfilters = 0; int i, nfilt = 0, maxfilters = 0;
struct conv_filter *newfilt; struct conv_filter *newfilt;
nl_catd catd; nl_catd catd;
@@ -217,10 +217,10 @@ sudo_pam_init2(const struct sudoers_context *ctx, struct passwd *pw,
pam_closure.ctx = ctx; pam_closure.ctx = ctx;
/* Initialize PAM. */ /* Initialize PAM. */
if (ISSET(sudo_mode, MODE_ASKPASS) && def_pam_askpass_service != NULL) { if (ISSET(ctx->mode, MODE_ASKPASS) && def_pam_askpass_service != NULL) {
pam_service = def_pam_askpass_service; pam_service = def_pam_askpass_service;
} else { } else {
pam_service = ISSET(sudo_mode, MODE_LOGIN_SHELL) ? pam_service = ISSET(ctx->mode, MODE_LOGIN_SHELL) ?
def_pam_login_service : def_pam_service; def_pam_login_service : def_pam_service;
} }
pam_status = pam_start(pam_service, pw->pw_name, &pam_conv, &pamh); pam_status = pam_start(pam_service, pw->pw_name, &pam_conv, &pamh);
@@ -235,7 +235,7 @@ sudo_pam_init2(const struct sudoers_context *ctx, struct passwd *pw,
} }
/* Initialize conversation function message filter. */ /* Initialize conversation function message filter. */
conv_filter_init(); conv_filter_init(ctx);
/* /*
* Set PAM_RUSER to the invoking user (the "from" user). * Set PAM_RUSER to the invoking user (the "from" user).
@@ -498,7 +498,7 @@ sudo_pam_begin_session(const struct sudoers_context *ctx, struct passwd *pw,
* We use PAM_SILENT to prevent pam_lastlog from printing last login * We use PAM_SILENT to prevent pam_lastlog from printing last login
* information except when explicitly running a shell. * information except when explicitly running a shell.
*/ */
const bool silent = !ISSET(sudo_mode, MODE_SHELL|MODE_LOGIN_SHELL); const bool silent = !ISSET(ctx->mode, MODE_SHELL|MODE_LOGIN_SHELL);
rc = pam_open_session(pamh, silent ? PAM_SILENT : 0); rc = pam_open_session(pamh, silent ? PAM_SILENT : 0);
switch (rc) { switch (rc) {
case PAM_SUCCESS: case PAM_SUCCESS:
@@ -538,7 +538,7 @@ sudo_pam_begin_session(const struct sudoers_context *ctx, struct passwd *pw,
char **pam_envp = pam_getenvlist(pamh); char **pam_envp = pam_getenvlist(pamh);
if (pam_envp != NULL) { if (pam_envp != NULL) {
/* Merge pam env with user env. */ /* Merge pam env with user env. */
if (!env_init(*user_envp) || !env_merge(pam_envp)) if (!env_init(*user_envp) || !env_merge(ctx, pam_envp))
status = AUTH_FATAL; status = AUTH_FATAL;
*user_envp = env_get(); *user_envp = env_get();
free(pam_envp); free(pam_envp);

View File

@@ -173,7 +173,7 @@ check_user(struct sudoers_context *ctx, unsigned int validated,
* In intercept mode, only check the user if configured to do so. * In intercept mode, only check the user if configured to do so.
* We already have a session so no need to init the auth subsystem. * We already have a session so no need to init the auth subsystem.
*/ */
if (ISSET(sudo_mode, MODE_POLICY_INTERCEPTED)) { if (ISSET(ctx->mode, MODE_POLICY_INTERCEPTED)) {
if (!def_intercept_authenticate) { if (!def_intercept_authenticate) {
debug_return_int(true); debug_return_int(true);
} }

View File

@@ -703,13 +703,14 @@ matches_env_check(const char *var, bool *full_match)
* Returns true if the variable is allowed else false. * Returns true if the variable is allowed else false.
*/ */
static bool static bool
matches_env_keep(const char *var, bool *full_match) matches_env_keep(const struct sudoers_context *ctx, const char *var,
bool *full_match)
{ {
bool keepit = false; bool keepit = false;
debug_decl(matches_env_keep, SUDOERS_DEBUG_ENV); debug_decl(matches_env_keep, SUDOERS_DEBUG_ENV);
/* Preserve SHELL variable for "sudo -s". */ /* Preserve SHELL variable for "sudo -s". */
if (ISSET(sudo_mode, MODE_SHELL) && strncmp(var, "SHELL=", 6) == 0) { if (ISSET(ctx->mode, MODE_SHELL) && strncmp(var, "SHELL=", 6) == 0) {
keepit = true; keepit = true;
} else if (matches_env_list(var, &def_env_keep, full_match)) { } else if (matches_env_list(var, &def_env_keep, full_match)) {
keepit = true; keepit = true;
@@ -742,7 +743,7 @@ env_should_delete(const char *var)
* Returns true if the variable is allowed else false. * Returns true if the variable is allowed else false.
*/ */
static bool static bool
env_should_keep(const char *var) env_should_keep(const struct sudoers_context *ctx, const char *var)
{ {
int keepit; int keepit;
bool full_match = false; bool full_match = false;
@@ -751,7 +752,7 @@ env_should_keep(const char *var)
keepit = matches_env_check(var, &full_match); keepit = matches_env_check(var, &full_match);
if (keepit == -1) if (keepit == -1)
keepit = matches_env_keep(var, &full_match); keepit = matches_env_keep(ctx, var, &full_match);
/* Skip bash functions unless we matched on the value as well as name. */ /* Skip bash functions unless we matched on the value as well as name. */
if (keepit && !full_match) { if (keepit && !full_match) {
@@ -773,7 +774,7 @@ env_should_keep(const char *var)
* Returns true on success or false on failure. * Returns true on success or false on failure.
*/ */
bool bool
env_merge(char * const envp[]) env_merge(const struct sudoers_context *ctx, char * const envp[])
{ {
char * const *ep; char * const *ep;
bool ret = true; bool ret = true;
@@ -781,7 +782,7 @@ env_merge(char * const envp[])
for (ep = envp; *ep != NULL; ep++) { for (ep = envp; *ep != NULL; ep++) {
/* XXX - avoid checking value here, should only check name */ /* XXX - avoid checking value here, should only check name */
bool overwrite = def_env_reset ? !env_should_keep(*ep) : env_should_delete(*ep); bool overwrite = def_env_reset ? !env_should_keep(ctx, *ep) : env_should_delete(*ep);
if (sudo_putenv(*ep, true, overwrite) == -1) { if (sudo_putenv(*ep, true, overwrite) == -1) {
/* XXX cannot undo on failure */ /* XXX cannot undo on failure */
ret = false; ret = false;
@@ -884,21 +885,21 @@ rebuild_env(const struct sudoers_context *ctx)
#endif #endif
/* Reset HOME based on target user if configured to. */ /* Reset HOME based on target user if configured to. */
if (ISSET(sudo_mode, MODE_RUN)) { if (ISSET(ctx->mode, MODE_RUN)) {
if (def_always_set_home || if (def_always_set_home ||
ISSET(sudo_mode, MODE_RESET_HOME | MODE_LOGIN_SHELL) || ISSET(ctx->mode, MODE_RESET_HOME | MODE_LOGIN_SHELL) ||
(ISSET(sudo_mode, MODE_SHELL) && def_set_home)) (ISSET(ctx->mode, MODE_SHELL) && def_set_home))
reset_home = true; reset_home = true;
} }
if (def_env_reset || ISSET(sudo_mode, MODE_LOGIN_SHELL)) { if (def_env_reset || ISSET(ctx->mode, MODE_LOGIN_SHELL)) {
/* /*
* If starting with a fresh environment, initialize it based on * If starting with a fresh environment, initialize it based on
* /etc/environment or login.conf. For "sudo -i" we want those * /etc/environment or login.conf. For "sudo -i" we want those
* variables to override the invoking user's environment, so we * variables to override the invoking user's environment, so we
* defer reading them until later. * defer reading them until later.
*/ */
if (!ISSET(sudo_mode, MODE_LOGIN_SHELL)) { if (!ISSET(ctx->mode, MODE_LOGIN_SHELL)) {
#ifdef HAVE_LOGIN_CAP_H #ifdef HAVE_LOGIN_CAP_H
/* Insert login class environment variables. */ /* Insert login class environment variables. */
if (ctx->runas.class) { if (ctx->runas.class) {
@@ -912,7 +913,7 @@ rebuild_env(const struct sudoers_context *ctx)
#endif /* HAVE_LOGIN_CAP_H */ #endif /* HAVE_LOGIN_CAP_H */
#if defined(_AIX) || (defined(__linux__) && !defined(HAVE_PAM)) #if defined(_AIX) || (defined(__linux__) && !defined(HAVE_PAM))
/* Insert system-wide environment variables. */ /* Insert system-wide environment variables. */
if (!read_env_file(_PATH_ENVIRONMENT, true, false)) if (!read_env_file(ctx, _PATH_ENVIRONMENT, true, false))
sudo_warn("%s", _PATH_ENVIRONMENT); sudo_warn("%s", _PATH_ENVIRONMENT);
#endif #endif
for (ep = env.envp; *ep; ep++) for (ep = env.envp; *ep; ep++)
@@ -927,7 +928,7 @@ rebuild_env(const struct sudoers_context *ctx)
/* /*
* Look up the variable in the env_check and env_keep lists. * Look up the variable in the env_check and env_keep lists.
*/ */
keepit = env_should_keep(*ep); keepit = env_should_keep(ctx, *ep);
/* /*
* Do SUDO_PS1 -> PS1 conversion. * Do SUDO_PS1 -> PS1 conversion.
@@ -950,7 +951,7 @@ rebuild_env(const struct sudoers_context *ctx)
* otherwise they may be from the user's environment (depends * otherwise they may be from the user's environment (depends
* on sudoers options). * on sudoers options).
*/ */
if (ISSET(sudo_mode, MODE_LOGIN_SHELL)) { if (ISSET(ctx->mode, MODE_LOGIN_SHELL)) {
CHECK_SETENV2("SHELL", ctx->runas.pw->pw_shell, CHECK_SETENV2("SHELL", ctx->runas.pw->pw_shell,
ISSET(didvar, DID_SHELL), true); ISSET(didvar, DID_SHELL), true);
#ifdef _AIX #ifdef _AIX
@@ -983,7 +984,7 @@ rebuild_env(const struct sudoers_context *ctx)
* Set MAIL to target user in -i mode or if MAIL is not preserved * Set MAIL to target user in -i mode or if MAIL is not preserved
* from user's environment. * from user's environment.
*/ */
if (ISSET(sudo_mode, MODE_LOGIN_SHELL) || !ISSET(didvar, KEPT_MAIL)) { if (ISSET(ctx->mode, MODE_LOGIN_SHELL) || !ISSET(didvar, KEPT_MAIL)) {
if (_PATH_MAILDIR[sizeof(_PATH_MAILDIR) - 2] == '/') { if (_PATH_MAILDIR[sizeof(_PATH_MAILDIR) - 2] == '/') {
len = asprintf(&cp, "MAIL=%s%s", _PATH_MAILDIR, len = asprintf(&cp, "MAIL=%s%s", _PATH_MAILDIR,
ctx->runas.pw->pw_name); ctx->runas.pw->pw_name);
@@ -1032,7 +1033,7 @@ rebuild_env(const struct sudoers_context *ctx)
* disabled. We skip this if we are running a login shell (because * disabled. We skip this if we are running a login shell (because
* they have already been set). * they have already been set).
*/ */
if (def_set_logname && !ISSET(sudo_mode, MODE_LOGIN_SHELL)) { if (def_set_logname && !ISSET(ctx->mode, MODE_LOGIN_SHELL)) {
if ((didvar & KEPT_USER_VARIABLES) == 0) { if ((didvar & KEPT_USER_VARIABLES) == 0) {
/* Nothing preserved, set them all. */ /* Nothing preserved, set them all. */
#ifdef _AIX #ifdef _AIX
@@ -1172,7 +1173,7 @@ validate_env_vars(const struct sudoers_context *ctx, char * const env_vars[])
strncmp(*ep, "PATH=", 5) == 0) { strncmp(*ep, "PATH=", 5) == 0) {
okvar = false; okvar = false;
} else if (def_env_reset) { } else if (def_env_reset) {
okvar = env_should_keep(*ep); okvar = env_should_keep(ctx, *ep);
} else { } else {
okvar = !env_should_delete(*ep); okvar = !env_should_delete(*ep);
} }
@@ -1328,7 +1329,8 @@ register_env_file(void * (*ef_open)(const char *), void (*ef_close)(void *),
} }
bool bool
read_env_file(const char *path, bool overwrite, bool restricted) read_env_file(const struct sudoers_context *ctx, const char *path,
bool overwrite, bool restricted)
{ {
struct sudoers_env_file *ef; struct sudoers_env_file *ef;
bool ret = true; bool ret = true;
@@ -1363,7 +1365,7 @@ read_env_file(const char *path, bool overwrite, bool restricted)
* when env_reset is set or env_delete when it is not. * when env_reset is set or env_delete when it is not.
*/ */
if (restricted) { if (restricted) {
if (def_env_reset ? !env_should_keep(envstr) : env_should_delete(envstr)) { if (def_env_reset ? !env_should_keep(ctx, envstr) : env_should_delete(envstr)) {
free(envstr); free(envstr);
continue; continue;
} }

View File

@@ -67,7 +67,7 @@ STAILQ_HEAD(parse_error_list, parse_error);
static struct parse_error_list parse_error_list = static struct parse_error_list parse_error_list =
STAILQ_HEAD_INITIALIZER(parse_error_list); STAILQ_HEAD_INITIALIZER(parse_error_list);
static bool should_mail(unsigned int); static bool should_mail(const struct sudoers_context *ctx, unsigned int);
static bool warned = false; static bool warned = false;
#ifdef SUDOERS_LOG_CLIENT #ifdef SUDOERS_LOG_CLIENT
@@ -127,7 +127,8 @@ init_log_details(struct log_details *details, struct eventlog *evlog)
} }
bool bool
log_server_reject(struct eventlog *evlog, const char *message) log_server_reject(const struct sudoers_context *ctx, struct eventlog *evlog,
const char *message)
{ {
bool ret = false; bool ret = false;
debug_decl(log_server_reject, SUDOERS_DEBUG_LOGGING); debug_decl(log_server_reject, SUDOERS_DEBUG_LOGGING);
@@ -135,7 +136,7 @@ log_server_reject(struct eventlog *evlog, const char *message)
if (SLIST_EMPTY(&def_log_servers)) if (SLIST_EMPTY(&def_log_servers))
debug_return_bool(true); debug_return_bool(true);
if (ISSET(sudo_mode, MODE_POLICY_INTERCEPTED)) { if (ISSET(ctx->mode, MODE_POLICY_INTERCEPTED)) {
/* Older servers don't support multiple commands per session. */ /* Older servers don't support multiple commands per session. */
if (!client_closure->subcommands) if (!client_closure->subcommands)
debug_return_bool(true); debug_return_bool(true);
@@ -173,8 +174,8 @@ done:
} }
bool bool
log_server_alert(struct eventlog *evlog, struct timespec *now, log_server_alert(const struct sudoers_context *ctx, struct eventlog *evlog,
const char *message, const char *errstr) struct timespec *now, const char *message, const char *errstr)
{ {
struct log_details details; struct log_details details;
char *emessage = NULL; char *emessage = NULL;
@@ -191,7 +192,7 @@ log_server_alert(struct eventlog *evlog, struct timespec *now,
} }
} }
if (ISSET(sudo_mode, MODE_POLICY_INTERCEPTED)) { if (ISSET(ctx->mode, MODE_POLICY_INTERCEPTED)) {
/* Older servers don't support multiple commands per session. */ /* Older servers don't support multiple commands per session. */
if (!client_closure->subcommands) { if (!client_closure->subcommands) {
ret = true; ret = true;
@@ -230,14 +231,15 @@ done:
} }
#else #else
bool bool
log_server_reject(struct eventlog *evlog, const char *message) log_server_reject(const struct sudoers_context *ctx, struct eventlog *evlog,
const char *message)
{ {
return true; return true;
} }
bool bool
log_server_alert(struct eventlog *evlog, struct timespec *now, log_server_alert(const struct sudoers_context *ctx, struct eventlog *evlog,
const char *message, const char *errstr) struct timespec *now, const char *message, const char *errstr)
{ {
return true; return true;
} }
@@ -256,7 +258,7 @@ log_reject(const struct sudoers_context *ctx, const char *message,
bool ret; bool ret;
debug_decl(log_reject, SUDOERS_DEBUG_LOGGING); debug_decl(log_reject, SUDOERS_DEBUG_LOGGING);
if (!ISSET(sudo_mode, MODE_POLICY_INTERCEPTED)) if (!ISSET(ctx->mode, MODE_POLICY_INTERCEPTED))
uuid_str = ctx->user.uuid_str; uuid_str = ctx->user.uuid_str;
if (mailit) { if (mailit) {
@@ -267,7 +269,7 @@ log_reject(const struct sudoers_context *ctx, const char *message,
sudoers_to_eventlog(ctx, &evlog, ctx->runas.cmnd, ctx->runas.argv, sudoers_to_eventlog(ctx, &evlog, ctx->runas.cmnd, ctx->runas.argv,
env_get(), uuid_str); env_get(), uuid_str);
ret = eventlog_reject(&evlog, evl_flags, message, NULL, NULL); ret = eventlog_reject(&evlog, evl_flags, message, NULL, NULL);
if (!log_server_reject(&evlog, message)) if (!log_server_reject(ctx, &evlog, message))
ret = false; ret = false;
debug_return_bool(ret); debug_return_bool(ret);
@@ -286,7 +288,7 @@ log_denial(const struct sudoers_context *ctx, unsigned int status,
debug_decl(log_denial, SUDOERS_DEBUG_LOGGING); debug_decl(log_denial, SUDOERS_DEBUG_LOGGING);
/* Send mail based on status. */ /* Send mail based on status. */
mailit = should_mail(status); mailit = should_mail(ctx, status);
/* Set error message. */ /* Set error message. */
if (ISSET(status, FLAG_NO_USER)) if (ISSET(status, FLAG_NO_USER))
@@ -329,7 +331,7 @@ log_denial(const struct sudoers_context *ctx, unsigned int status,
const char *cmnd1 = ctx->user.cmnd; const char *cmnd1 = ctx->user.cmnd;
const char *cmnd2 = ""; const char *cmnd2 = "";
if (ISSET(sudo_mode, MODE_CHECK)) { if (ISSET(ctx->mode, MODE_CHECK)) {
/* For "sudo -l command" the command run is in runas.argv[1]. */ /* For "sudo -l command" the command run is in runas.argv[1]. */
cmnd1 = "list "; cmnd1 = "list ";
cmnd2 = ctx->runas.argv[1]; cmnd2 = ctx->runas.argv[1];
@@ -371,7 +373,7 @@ log_failure(const struct sudoers_context *ctx, unsigned int status,
if (!inform_user) { if (!inform_user) {
const char *cmnd = ctx->user.cmnd; const char *cmnd = ctx->user.cmnd;
if (ISSET(sudo_mode, MODE_CHECK)) if (ISSET(ctx->mode, MODE_CHECK))
cmnd = ctx->user.cmnd_list ? ctx->user.cmnd_list : ctx->runas.argv[1]; cmnd = ctx->user.cmnd_list ? ctx->user.cmnd_list : ctx->runas.argv[1];
/* /*
@@ -515,7 +517,7 @@ log_auth_failure(const struct sudoers_context *ctx, unsigned int status,
logit = false; logit = false;
} else { } else {
/* Command denied, auth failed; make sure we don't send mail twice. */ /* Command denied, auth failed; make sure we don't send mail twice. */
if (def_mail_badpass && !should_mail(status)) if (def_mail_badpass && !should_mail(ctx, status))
mailit = true; mailit = true;
/* Don't log the bad password message, we'll log a denial instead. */ /* Don't log the bad password message, we'll log a denial instead. */
logit = false; logit = false;
@@ -565,7 +567,7 @@ log_auth_failure(const struct sudoers_context *ctx, unsigned int status,
* Log and potentially mail the allowed command. * Log and potentially mail the allowed command.
*/ */
bool bool
log_allowed(struct eventlog *evlog) log_allowed(const struct sudoers_context *ctx, struct eventlog *evlog)
{ {
int oldlocale; int oldlocale;
int evl_flags = 0; int evl_flags = 0;
@@ -573,7 +575,7 @@ log_allowed(struct eventlog *evlog)
debug_decl(log_allowed, SUDOERS_DEBUG_LOGGING); debug_decl(log_allowed, SUDOERS_DEBUG_LOGGING);
/* Send mail based on status. */ /* Send mail based on status. */
mailit = should_mail(VALIDATE_SUCCESS); mailit = should_mail(ctx, VALIDATE_SUCCESS);
if (def_log_allowed || mailit) { if (def_log_allowed || mailit) {
/* Log and mail messages should be in the sudoers locale. */ /* Log and mail messages should be in the sudoers locale. */
@@ -740,7 +742,7 @@ vlog_warning(const struct sudoers_context *ctx, unsigned int flags,
env_get(), ctx->user.uuid_str); env_get(), ctx->user.uuid_str);
if (!eventlog_alert(&evlog, evl_flags, &now, message, errstr)) if (!eventlog_alert(&evlog, evl_flags, &now, message, errstr))
ret = false; ret = false;
if (!log_server_alert(&evlog, &now, message, errstr)) if (!log_server_alert(ctx, &evlog, &now, message, errstr))
ret = false; ret = false;
} }
@@ -941,7 +943,7 @@ log_parse_error(const struct sudoers_context *ctx, const char *file,
* Determine whether we should send mail based on "status" and defaults options. * Determine whether we should send mail based on "status" and defaults options.
*/ */
static bool static bool
should_mail(unsigned int status) should_mail(const struct sudoers_context *ctx, unsigned int status)
{ {
debug_decl(should_mail, SUDOERS_DEBUG_LOGGING); debug_decl(should_mail, SUDOERS_DEBUG_LOGGING);
@@ -949,7 +951,7 @@ should_mail(unsigned int status)
debug_return_bool(false); debug_return_bool(false);
debug_return_bool(def_mail_always || ISSET(status, VALIDATE_ERROR) || debug_return_bool(def_mail_always || ISSET(status, VALIDATE_ERROR) ||
(def_mail_all_cmnds && ISSET(sudo_mode, (MODE_RUN|MODE_EDIT))) || (def_mail_all_cmnds && ISSET(ctx->mode, (MODE_RUN|MODE_EDIT))) ||
(def_mail_no_user && ISSET(status, FLAG_NO_USER)) || (def_mail_no_user && ISSET(status, FLAG_NO_USER)) ||
(def_mail_no_host && ISSET(status, FLAG_NO_HOST)) || (def_mail_no_host && ISSET(status, FLAG_NO_HOST)) ||
(def_mail_no_perms && !ISSET(status, VALIDATE_SUCCESS))); (def_mail_no_perms && !ISSET(status, VALIDATE_SUCCESS)));
@@ -981,7 +983,7 @@ sudoers_to_eventlog(const struct sudoers_context *ctx, struct eventlog *evlog,
} }
if (def_runcwd && strcmp(def_runcwd, "*") != 0) { if (def_runcwd && strcmp(def_runcwd, "*") != 0) {
evlog->runcwd = def_runcwd; evlog->runcwd = def_runcwd;
} else if (ISSET(sudo_mode, MODE_LOGIN_SHELL) && ctx->runas.pw != NULL) { } else if (ISSET(ctx->mode, MODE_LOGIN_SHELL) && ctx->runas.pw != NULL) {
evlog->runcwd = ctx->runas.pw->pw_dir; evlog->runcwd = ctx->runas.pw->pw_dir;
} else { } else {
evlog->runcwd = ctx->user.cwd; evlog->runcwd = ctx->user.cwd;
@@ -1017,7 +1019,7 @@ sudoers_to_eventlog(const struct sudoers_context *ctx, struct eventlog *evlog,
} else { } else {
strlcpy(evlog->uuid_str, uuid_str, sizeof(evlog->uuid_str)); strlcpy(evlog->uuid_str, uuid_str, sizeof(evlog->uuid_str));
} }
if (ISSET(sudo_mode, MODE_POLICY_INTERCEPTED)) { if (ISSET(ctx->mode, MODE_POLICY_INTERCEPTED)) {
struct timespec now; struct timespec now;
if (sudo_gettime_real(&now) == -1) { if (sudo_gettime_real(&now) == -1) {
sudo_warn("%s", U_("unable to get time of day")); sudo_warn("%s", U_("unable to get time of day"));

View File

@@ -73,13 +73,13 @@ bool sudoers_setlocale(int locale_type, int *prev_locale);
int sudoers_getlocale(void); int sudoers_getlocale(void);
int audit_failure(const struct sudoers_context *ctx, char *const argv[], char const * restrict const fmt, ...) sudo_printflike(3, 4); int audit_failure(const struct sudoers_context *ctx, char *const argv[], char const * restrict const fmt, ...) sudo_printflike(3, 4);
int vaudit_failure(const struct sudoers_context *ctx, char *const argv[], char const * restrict const fmt, va_list ap) sudo_printflike(3, 0); int vaudit_failure(const struct sudoers_context *ctx, char *const argv[], char const * restrict const fmt, va_list ap) sudo_printflike(3, 0);
bool log_allowed(struct eventlog *evlog); bool log_allowed(const struct sudoers_context *ctx, struct eventlog *evlog);
bool log_exit_status(const struct sudoers_context *ctx, int exit_status); bool log_exit_status(const struct sudoers_context *ctx, int exit_status);
bool log_auth_failure(const struct sudoers_context *ctx, unsigned int status, unsigned int tries); bool log_auth_failure(const struct sudoers_context *ctx, unsigned int status, unsigned int tries);
bool log_denial(const struct sudoers_context *ctx, unsigned int status, bool inform_user); bool log_denial(const struct sudoers_context *ctx, unsigned int status, bool inform_user);
bool log_failure(const struct sudoers_context *ctx, unsigned int status, int flags); bool log_failure(const struct sudoers_context *ctx, unsigned int status, int flags);
bool log_server_alert(struct eventlog *evlog, struct timespec *now, const char *message, const char *errstr); bool log_server_alert(const struct sudoers_context *ctx, struct eventlog *evlog, struct timespec *now, const char *message, const char *errstr);
bool log_server_reject(struct eventlog *evlog, const char *message); bool log_server_reject(const struct sudoers_context *ctx, struct eventlog *evlog, const char *message);
bool log_warning(const struct sudoers_context *ctx, unsigned int flags, const char * restrict fmt, ...) sudo_printflike(3, 4); bool log_warning(const struct sudoers_context *ctx, unsigned int flags, const char * restrict fmt, ...) sudo_printflike(3, 4);
bool log_warningx(const struct sudoers_context *ctx, unsigned int flags, const char * restrict fmt, ...) sudo_printflike(3, 4); bool log_warningx(const struct sudoers_context *ctx, unsigned int flags, const char * restrict fmt, ...) sudo_printflike(3, 4);
bool gai_log_warning(const struct sudoers_context *ctx, unsigned int flags, int errnum, const char * restrict fmt, ...) sudo_printflike(4, 5); bool gai_log_warning(const struct sudoers_context *ctx, unsigned int flags, int errnum, const char * restrict fmt, ...) sudo_printflike(4, 5);

View File

@@ -221,10 +221,10 @@ sudoers_lookup_pseudo(struct sudo_nss_list *snl, struct sudoers_context *ctx,
} }
static void static void
init_cmnd_info(struct cmnd_info *info) init_cmnd_info(struct sudoers_context *ctx, struct cmnd_info *info)
{ {
memset(info, 0, sizeof(*info)); memset(info, 0, sizeof(*info));
if (def_intercept || ISSET(sudo_mode, MODE_POLICY_INTERCEPTED)) if (def_intercept || ISSET(ctx->mode, MODE_POLICY_INTERCEPTED))
info->intercepted = true; info->intercepted = true;
} }
@@ -240,7 +240,7 @@ sudoers_lookup_check(struct sudo_nss *nss, struct sudoers_context *ctx,
struct member *matching_user; struct member *matching_user;
debug_decl(sudoers_lookup_check, SUDOERS_DEBUG_PARSER); debug_decl(sudoers_lookup_check, SUDOERS_DEBUG_PARSER);
init_cmnd_info(info); init_cmnd_info(ctx, info);
TAILQ_FOREACH_REVERSE(us, &nss->parse_tree->userspecs, userspec_list, entries) { TAILQ_FOREACH_REVERSE(us, &nss->parse_tree->userspecs, userspec_list, entries) {
int user_match = userlist_matches(nss->parse_tree, ctx->user.pw, &us->users); int user_match = userlist_matches(nss->parse_tree, ctx->user.pw, &us->users);
@@ -310,7 +310,7 @@ sudoers_lookup_check(struct sudo_nss *nss, struct sudoers_context *ctx,
debug_return_int(cmnd_match); debug_return_int(cmnd_match);
} }
free(info->cmnd_path); free(info->cmnd_path);
init_cmnd_info(info); init_cmnd_info(ctx, info);
} }
} }
} }

View File

@@ -184,7 +184,7 @@ sudoers_policy_deserialize_info(struct sudoers_context *ctx, void *v,
ctx->settings.flags = 0; ctx->settings.flags = 0;
ctx->user.closefrom = -1; ctx->user.closefrom = -1;
sudoedit_nfiles = 0; sudoedit_nfiles = 0;
sudo_mode = 0; ctx->mode = 0;
for (cur = info->settings; *cur != NULL; cur++) { for (cur = info->settings; *cur != NULL; cur++) {
if (MATCHES(*cur, "closefrom=")) { if (MATCHES(*cur, "closefrom=")) {
p = *cur + sizeof("closefrom=") - 1; p = *cur + sizeof("closefrom=") - 1;
@@ -563,7 +563,7 @@ sudoers_policy_deserialize_info(struct sudoers_context *ctx, void *v,
* YP/NIS/NIS+/LDAP/etc daemon has died. * YP/NIS/NIS+/LDAP/etc daemon has died.
* For all others we will log a proper error later on. * For all others we will log a proper error later on.
*/ */
if (sudo_mode == MODE_KILL || sudo_mode == MODE_INVALIDATE) { if (ctx->mode == MODE_KILL || ctx->mode == MODE_INVALIDATE) {
sudo_warnx(U_("unknown user %s"), ctx->user.name); sudo_warnx(U_("unknown user %s"), ctx->user.name);
goto bad; goto bad;
} }
@@ -721,7 +721,7 @@ sudoers_policy_store_result(struct sudoers_context *ctx, bool accepted,
goto oom; goto oom;
} }
} }
if (ISSET(sudo_mode, MODE_EDIT)) { if (ISSET(ctx->mode, MODE_EDIT)) {
if ((command_info[info_len++] = strdup("sudoedit=true")) == NULL) if ((command_info[info_len++] = strdup("sudoedit=true")) == NULL)
goto oom; goto oom;
if (sudoedit_nfiles > 0) { if (sudoedit_nfiles > 0) {
@@ -746,7 +746,7 @@ sudoers_policy_store_result(struct sudoers_context *ctx, bool accepted,
} }
if ((command_info[info_len++] = sudo_new_key_val("cwd", def_runcwd)) == NULL) if ((command_info[info_len++] = sudo_new_key_val("cwd", def_runcwd)) == NULL)
goto oom; goto oom;
} else if (ISSET(sudo_mode, MODE_LOGIN_SHELL)) { } else if (ISSET(ctx->mode, MODE_LOGIN_SHELL)) {
/* Set cwd to run user's homedir. */ /* Set cwd to run user's homedir. */
if ((command_info[info_len++] = sudo_new_key_val("cwd", ctx->runas.pw->pw_dir)) == NULL) if ((command_info[info_len++] = sudo_new_key_val("cwd", ctx->runas.pw->pw_dir)) == NULL)
goto oom; goto oom;
@@ -1182,19 +1182,20 @@ sudoers_policy_check(int argc, char * const argv[], char *env_add[],
char **command_infop[], char **argv_out[], char **user_env_out[], char **command_infop[], char **argv_out[], char **user_env_out[],
const char **errstr) const char **errstr)
{ {
const struct sudoers_context *ctx = sudoers_get_context();
unsigned int valid_flags = RUN_VALID_FLAGS; unsigned int valid_flags = RUN_VALID_FLAGS;
unsigned int flags = MODE_RUN;
struct sudoers_exec_args exec_args; struct sudoers_exec_args exec_args;
int ret; int ret;
debug_decl(sudoers_policy_check, SUDOERS_DEBUG_PLUGIN); debug_decl(sudoers_policy_check, SUDOERS_DEBUG_PLUGIN);
if (ISSET(sudo_mode, MODE_EDIT)) if (ISSET(ctx->mode, MODE_EDIT)) {
valid_flags = EDIT_VALID_FLAGS; valid_flags = EDIT_VALID_FLAGS;
else flags = 0;
SET(sudo_mode, MODE_RUN); }
if (!sudoers_set_mode(flags, valid_flags)) {
if ((sudo_mode & valid_flags) != sudo_mode) {
sudo_warnx(U_("%s: invalid mode flags from sudo front end: 0x%x"), sudo_warnx(U_("%s: invalid mode flags from sudo front end: 0x%x"),
__func__, sudo_mode); __func__, ctx->mode);
debug_return_int(-1); debug_return_int(-1);
} }
@@ -1223,13 +1224,13 @@ sudoers_policy_check(int argc, char * const argv[], char *env_add[],
static int static int
sudoers_policy_validate(const char **errstr) sudoers_policy_validate(const char **errstr)
{ {
const struct sudoers_context *ctx = sudoers_get_context();
int ret; int ret;
debug_decl(sudoers_policy_validate, SUDOERS_DEBUG_PLUGIN); debug_decl(sudoers_policy_validate, SUDOERS_DEBUG_PLUGIN);
SET(sudo_mode, MODE_VALIDATE); if (!sudoers_set_mode(MODE_VALIDATE, VALIDATE_VALID_FLAGS)) {
if ((sudo_mode & VALIDATE_VALID_FLAGS) != sudo_mode) {
sudo_warnx(U_("%s: invalid mode flags from sudo front end: 0x%x"), sudo_warnx(U_("%s: invalid mode flags from sudo front end: 0x%x"),
__func__, sudo_mode); __func__, ctx->mode);
debug_return_int(-1); debug_return_int(-1);
} }
@@ -1246,14 +1247,14 @@ sudoers_policy_validate(const char **errstr)
static void static void
sudoers_policy_invalidate(int unlinkit) sudoers_policy_invalidate(int unlinkit)
{ {
const struct sudoers_context *ctx = sudoers_get_context();
debug_decl(sudoers_policy_invalidate, SUDOERS_DEBUG_PLUGIN); debug_decl(sudoers_policy_invalidate, SUDOERS_DEBUG_PLUGIN);
SET(sudo_mode, MODE_INVALIDATE); if (!sudoers_set_mode(MODE_INVALIDATE, INVALIDATE_VALID_FLAGS)) {
if ((sudo_mode & INVALIDATE_VALID_FLAGS) != sudo_mode) {
sudo_warnx(U_("%s: invalid mode flags from sudo front end: 0x%x"), sudo_warnx(U_("%s: invalid mode flags from sudo front end: 0x%x"),
__func__, sudo_mode); __func__, ctx->mode);
} else { } else {
timestamp_remove(sudoers_get_context(), unlinkit); timestamp_remove(ctx, unlinkit);
} }
debug_return; debug_return;
@@ -1263,17 +1264,13 @@ static int
sudoers_policy_list(int argc, char * const argv[], int verbose, sudoers_policy_list(int argc, char * const argv[], int verbose,
const char *list_user, const char **errstr) const char *list_user, const char **errstr)
{ {
const struct sudoers_context *ctx = sudoers_get_context();
int ret; int ret;
debug_decl(sudoers_policy_list, SUDOERS_DEBUG_PLUGIN); debug_decl(sudoers_policy_list, SUDOERS_DEBUG_PLUGIN);
if (argc == 0) if (!sudoers_set_mode(argc ? MODE_CHECK : MODE_LIST, LIST_VALID_FLAGS)) {
SET(sudo_mode, MODE_LIST);
else
SET(sudo_mode, MODE_CHECK);
if ((sudo_mode & LIST_VALID_FLAGS) != sudo_mode) {
sudo_warnx(U_("%s: invalid mode flags from sudo front end: 0x%x"), sudo_warnx(U_("%s: invalid mode flags from sudo front end: 0x%x"),
__func__, sudo_mode); __func__, ctx->mode);
debug_return_int(-1); debug_return_int(-1);
} }

View File

@@ -51,7 +51,6 @@ static const char *orig_cmnd;
/* Required to link with parser. */ /* Required to link with parser. */
sudo_conv_t sudo_conv = fuzz_conversation; sudo_conv_t sudo_conv = fuzz_conversation;
sudo_printf_t sudo_printf = fuzz_printf; sudo_printf_t sudo_printf = fuzz_printf;
unsigned int sudo_mode;
FILE * FILE *
open_sudoers(const char *file, char **outfile, bool doedit, bool *keepopen) open_sudoers(const char *file, char **outfile, bool doedit, bool *keepopen)

View File

@@ -79,8 +79,6 @@ static bool tty_present(struct sudoers_context *ctx);
/* /*
* Globals * Globals
*/ */
unsigned int sudo_mode;
static char *prev_user; static char *prev_user;
static struct sudoers_context sudoers_ctx = SUDOERS_CONTEXT_INITIALIZER; static struct sudoers_context sudoers_ctx = SUDOERS_CONTEXT_INITIALIZER;
static struct sudo_nss_list *snl; static struct sudo_nss_list *snl;
@@ -176,7 +174,7 @@ sudoers_reinit_defaults(struct sudoers_context *ctx)
sudoers_error_hook = logger; sudoers_error_hook = logger;
/* No need to check the admin flag file multiple times. */ /* No need to check the admin flag file multiple times. */
if (ISSET(sudo_mode, MODE_POLICY_INTERCEPTED)) { if (ISSET(ctx->mode, MODE_POLICY_INTERCEPTED)) {
free(def_admin_flag); free(def_admin_flag);
def_admin_flag = NULL; def_admin_flag = NULL;
} }
@@ -215,9 +213,9 @@ sudoers_init(void *info, sudoers_logger_t logger, char * const envp[])
} }
/* Parse info from front-end. */ /* Parse info from front-end. */
sudo_mode = sudoers_policy_deserialize_info(&sudoers_ctx, info, sudoers_ctx.mode = sudoers_policy_deserialize_info(&sudoers_ctx, info,
&initial_defaults); &initial_defaults);
if (ISSET(sudo_mode, MODE_ERROR)) if (ISSET(sudoers_ctx.mode, MODE_ERROR))
debug_return_int(-1); debug_return_int(-1);
if (!init_vars(&sudoers_ctx, envp)) if (!init_vars(&sudoers_ctx, envp))
@@ -353,7 +351,7 @@ sudoers_check_common(struct sudoers_context *ctx, int pwflag)
debug_decl(sudoers_check_common, SUDOERS_DEBUG_PLUGIN); debug_decl(sudoers_check_common, SUDOERS_DEBUG_PLUGIN);
/* If given the -P option, set the "preserve_groups" flag. */ /* If given the -P option, set the "preserve_groups" flag. */
if (ISSET(sudo_mode, MODE_PRESERVE_GROUPS)) if (ISSET(ctx->mode, MODE_PRESERVE_GROUPS))
def_preserve_groups = true; def_preserve_groups = true;
/* Find command in path and apply per-command Defaults. */ /* Find command in path and apply per-command Defaults. */
@@ -431,7 +429,7 @@ sudoers_check_common(struct sudoers_context *ctx, int pwflag)
} }
/* If no command line args and "shell_noargs" is not set, error out. */ /* If no command line args and "shell_noargs" is not set, error out. */
if (ISSET(sudo_mode, MODE_IMPLIED_SHELL) && !def_shell_noargs) { if (ISSET(ctx->mode, MODE_IMPLIED_SHELL) && !def_shell_noargs) {
/* Not an audit event. */ /* Not an audit event. */
ret = -2; /* usage error */ ret = -2; /* usage error */
goto done; goto done;
@@ -445,7 +443,7 @@ sudoers_check_common(struct sudoers_context *ctx, int pwflag)
} }
/* Check runas user's shell if running (or checking) a command. */ /* Check runas user's shell if running (or checking) a command. */
if (ISSET(sudo_mode, MODE_RUN|MODE_CHECK)) { if (ISSET(ctx->mode, MODE_RUN|MODE_CHECK)) {
if (!check_user_shell(ctx->runas.pw)) { if (!check_user_shell(ctx->runas.pw)) {
log_warningx(ctx, SLOG_RAW_MSG|SLOG_AUDIT, log_warningx(ctx, SLOG_RAW_MSG|SLOG_AUDIT,
N_("invalid shell for user %s: %s"), N_("invalid shell for user %s: %s"),
@@ -458,8 +456,8 @@ sudoers_check_common(struct sudoers_context *ctx, int pwflag)
* We don't reset the environment for sudoedit or if the user * We don't reset the environment for sudoedit or if the user
* specified the -E command line flag and they have setenv privs. * specified the -E command line flag and they have setenv privs.
*/ */
if (ISSET(sudo_mode, MODE_EDIT) || if (ISSET(ctx->mode, MODE_EDIT) ||
(ISSET(sudo_mode, MODE_PRESERVE_ENV) && def_setenv)) (ISSET(ctx->mode, MODE_PRESERVE_ENV) && def_setenv))
def_env_reset = false; def_env_reset = false;
/* Build a new environment that avoids any nasty bits. */ /* Build a new environment that avoids any nasty bits. */
@@ -467,7 +465,7 @@ sudoers_check_common(struct sudoers_context *ctx, int pwflag)
goto bad; goto bad;
/* Require a password if sudoers says so. */ /* Require a password if sudoers says so. */
switch (check_user(ctx, validated, sudo_mode)) { switch (check_user(ctx, validated, ctx->mode)) {
case true: case true:
/* user authenticated successfully. */ /* user authenticated successfully. */
break; break;
@@ -515,7 +513,7 @@ sudoers_check_common(struct sudoers_context *ctx, int pwflag)
/* If run as root with SUDO_USER set, set ctx->user.pw to that user. */ /* If run as root with SUDO_USER set, set ctx->user.pw to that user. */
/* XXX - causes confusion when root is not listed in sudoers */ /* XXX - causes confusion when root is not listed in sudoers */
if (ISSET(sudo_mode, MODE_RUN|MODE_EDIT) && prev_user != NULL) { if (ISSET(ctx->mode, MODE_RUN|MODE_EDIT) && prev_user != NULL) {
if (ctx->user.uid == 0 && strcmp(prev_user, "root") != 0) { if (ctx->user.uid == 0 && strcmp(prev_user, "root") != 0) {
struct passwd *pw; struct passwd *pw;
@@ -545,7 +543,7 @@ sudoers_check_common(struct sudoers_context *ctx, int pwflag)
sudo_warnx(U_("ignoring \"%s\" found in '.'\nUse \"sudo ./%s\" if this is the \"%s\" you wish to run."), ctx->user.cmnd, ctx->user.cmnd, ctx->user.cmnd); sudo_warnx(U_("ignoring \"%s\" found in '.'\nUse \"sudo ./%s\" if this is the \"%s\" you wish to run."), ctx->user.cmnd, ctx->user.cmnd, ctx->user.cmnd);
goto bad; goto bad;
} else if (cmnd_status == NOT_FOUND) { } else if (cmnd_status == NOT_FOUND) {
if (ISSET(sudo_mode, MODE_CHECK)) { if (ISSET(ctx->mode, MODE_CHECK)) {
audit_failure(ctx, ctx->runas.argv, N_("%s: command not found"), audit_failure(ctx, ctx->runas.argv, N_("%s: command not found"),
ctx->runas.argv[1]); ctx->runas.argv[1]);
sudo_warnx(U_("%s: command not found"), ctx->runas.argv[1]); sudo_warnx(U_("%s: command not found"), ctx->runas.argv[1]);
@@ -576,8 +574,8 @@ sudoers_check_common(struct sudoers_context *ctx, int pwflag)
} }
/* If user specified env vars make sure sudoers allows it. */ /* If user specified env vars make sure sudoers allows it. */
if (ISSET(sudo_mode, MODE_RUN) && !def_setenv) { if (ISSET(ctx->mode, MODE_RUN) && !def_setenv) {
if (ISSET(sudo_mode, MODE_PRESERVE_ENV)) { if (ISSET(ctx->mode, MODE_PRESERVE_ENV)) {
log_warningx(ctx, SLOG_NO_STDERR|SLOG_AUDIT, log_warningx(ctx, SLOG_NO_STDERR|SLOG_AUDIT,
N_("user not allowed to preserve the environment")); N_("user not allowed to preserve the environment"));
sudo_warnx("%s", sudo_warnx("%s",
@@ -623,12 +621,12 @@ sudoers_check_cmnd(int argc, char * const argv[], char *env_add[],
if (need_reinit) { if (need_reinit) {
/* Was previous command intercepted? */ /* Was previous command intercepted? */
if (ISSET(sudo_mode, MODE_RUN) && def_intercept) if (ISSET(sudoers_ctx.mode, MODE_RUN) && def_intercept)
SET(sudo_mode, MODE_POLICY_INTERCEPTED); SET(sudoers_ctx.mode, MODE_POLICY_INTERCEPTED);
/* Only certain mode flags are legal for intercepted commands. */ /* Only certain mode flags are legal for intercepted commands. */
if (ISSET(sudo_mode, MODE_POLICY_INTERCEPTED)) if (ISSET(sudoers_ctx.mode, MODE_POLICY_INTERCEPTED))
sudo_mode &= MODE_INTERCEPT_MASK; sudoers_ctx.mode &= MODE_INTERCEPT_MASK;
/* Re-initialize defaults if we are called multiple times. */ /* Re-initialize defaults if we are called multiple times. */
if (!sudoers_reinit_defaults(&sudoers_ctx)) if (!sudoers_reinit_defaults(&sudoers_ctx))
@@ -662,7 +660,7 @@ sudoers_check_cmnd(int argc, char * const argv[], char *env_add[],
memcpy(sudoers_ctx.runas.argv, argv, (size_t)argc * sizeof(char *)); memcpy(sudoers_ctx.runas.argv, argv, (size_t)argc * sizeof(char *));
sudoers_ctx.runas.argc = argc; sudoers_ctx.runas.argc = argc;
sudoers_ctx.runas.argv[sudoers_ctx.runas.argc] = NULL; sudoers_ctx.runas.argv[sudoers_ctx.runas.argc] = NULL;
if (ISSET(sudo_mode, MODE_LOGIN_SHELL) && sudoers_ctx.runas.pw != NULL) { if (ISSET(sudoers_ctx.mode, MODE_LOGIN_SHELL) && sudoers_ctx.runas.pw != NULL) {
sudoers_ctx.runas.argv[0] = strdup(sudoers_ctx.runas.pw->pw_shell); sudoers_ctx.runas.argv[0] = strdup(sudoers_ctx.runas.pw->pw_shell);
if (sudoers_ctx.runas.argv[0] == NULL) { if (sudoers_ctx.runas.argv[0] == NULL) {
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory")); sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
@@ -703,7 +701,7 @@ sudoers_check_cmnd(int argc, char * const argv[], char *env_add[],
cmnd_umask |= sudoers_ctx.user.umask; cmnd_umask |= sudoers_ctx.user.umask;
} }
if (ISSET(sudo_mode, MODE_LOGIN_SHELL)) { if (ISSET(sudoers_ctx.mode, MODE_LOGIN_SHELL)) {
char *p; char *p;
/* Convert /bin/sh -> -sh so shell knows it is a login shell */ /* Convert /bin/sh -> -sh so shell knows it is a login shell */
@@ -729,7 +727,7 @@ sudoers_check_cmnd(int argc, char * const argv[], char *env_add[],
#if defined(_AIX) || (defined(__linux__) && !defined(HAVE_PAM)) #if defined(_AIX) || (defined(__linux__) && !defined(HAVE_PAM))
/* Insert system-wide environment variables. */ /* Insert system-wide environment variables. */
if (!read_env_file(_PATH_ENVIRONMENT, true, false)) if (!read_env_file(&sudoers_ctx, _PATH_ENVIRONMENT, true, false))
sudo_warn("%s", _PATH_ENVIRONMENT); sudo_warn("%s", _PATH_ENVIRONMENT);
#endif #endif
#ifdef HAVE_LOGIN_CAP_H #ifdef HAVE_LOGIN_CAP_H
@@ -747,11 +745,11 @@ sudoers_check_cmnd(int argc, char * const argv[], char *env_add[],
/* Insert system-wide environment variables. */ /* Insert system-wide environment variables. */
if (def_restricted_env_file) { if (def_restricted_env_file) {
if (!read_env_file(def_restricted_env_file, false, true)) if (!read_env_file(&sudoers_ctx, def_restricted_env_file, false, true))
sudo_warn("%s", def_restricted_env_file); sudo_warn("%s", def_restricted_env_file);
} }
if (def_env_file) { if (def_env_file) {
if (!read_env_file(def_env_file, false, false)) if (!read_env_file(&sudoers_ctx, def_env_file, false, false))
sudo_warn("%s", def_env_file); sudo_warn("%s", def_env_file);
} }
@@ -763,7 +761,7 @@ sudoers_check_cmnd(int argc, char * const argv[], char *env_add[],
} }
/* Note: must call audit before uid change. */ /* Note: must call audit before uid change. */
if (ISSET(sudo_mode, MODE_EDIT)) { if (ISSET(sudoers_ctx.mode, MODE_EDIT)) {
const char *env_editor = NULL; const char *env_editor = NULL;
char **edit_argv; char **edit_argv;
int edit_argc; int edit_argc;
@@ -950,7 +948,7 @@ sudoers_list(int argc, char * const argv[], const char *list_user, bool verbose)
goto done; goto done;
pw = sudoers_ctx.runas.list_pw ? sudoers_ctx.runas.list_pw : sudoers_ctx.user.pw; pw = sudoers_ctx.runas.list_pw ? sudoers_ctx.runas.list_pw : sudoers_ctx.user.pw;
if (ISSET(sudo_mode, MODE_CHECK)) if (ISSET(sudoers_ctx.mode, MODE_CHECK))
ret = display_cmnd(&sudoers_ctx, snl, pw, verbose); ret = display_cmnd(&sudoers_ctx, snl, pw, verbose);
else else
ret = display_privs(&sudoers_ctx, snl, pw, verbose); ret = display_privs(&sudoers_ctx, snl, pw, verbose);
@@ -1070,7 +1068,7 @@ set_cmnd_path(struct sudoers_context *ctx, const char *runchroot)
int ret, pivot_fds[2]; int ret, pivot_fds[2];
debug_decl(set_cmnd_path, SUDOERS_DEBUG_PLUGIN); debug_decl(set_cmnd_path, SUDOERS_DEBUG_PLUGIN);
cmnd_in = ISSET(sudo_mode, MODE_CHECK) ? cmnd_in = ISSET(ctx->mode, MODE_CHECK) ?
ctx->runas.argv[1] : ctx->runas.argv[0]; ctx->runas.argv[1] : ctx->runas.argv[0];
free(ctx->user.cmnd_list); free(ctx->user.cmnd_list);
@@ -1115,7 +1113,7 @@ set_cmnd_path(struct sudoers_context *ctx, const char *runchroot)
} }
} }
if (ISSET(sudo_mode, MODE_CHECK)) if (ISSET(ctx->mode, MODE_CHECK))
ctx->user.cmnd_list = cmnd_out; ctx->user.cmnd_list = cmnd_out;
else else
ctx->user.cmnd = cmnd_out; ctx->user.cmnd = cmnd_out;
@@ -1165,8 +1163,8 @@ set_cmnd(struct sudoers_context *ctx)
free(ctx->runas.cmnd); free(ctx->runas.cmnd);
ctx->runas.cmnd = NULL; ctx->runas.cmnd = NULL;
if (ISSET(sudo_mode, MODE_RUN|MODE_EDIT|MODE_CHECK)) { if (ISSET(ctx->mode, MODE_RUN|MODE_EDIT|MODE_CHECK)) {
if (!ISSET(sudo_mode, MODE_EDIT)) { if (!ISSET(ctx->mode, MODE_EDIT)) {
const char *runchroot = ctx->runas.chroot; const char *runchroot = ctx->runas.chroot;
if (runchroot == NULL && def_runchroot != NULL && if (runchroot == NULL && def_runchroot != NULL &&
strcmp(def_runchroot, "*") != 0) strcmp(def_runchroot, "*") != 0)
@@ -1185,7 +1183,7 @@ set_cmnd(struct sudoers_context *ctx)
/* set ctx->user.cmnd_args */ /* set ctx->user.cmnd_args */
free(ctx->user.cmnd_args); free(ctx->user.cmnd_args);
ctx->user.cmnd_args = NULL; ctx->user.cmnd_args = NULL;
if (ISSET(sudo_mode, MODE_CHECK)) { if (ISSET(ctx->mode, MODE_CHECK)) {
if (ctx->runas.argc > 2) { if (ctx->runas.argc > 2) {
/* Skip the command being listed in ctx->runas.argv[1]. */ /* Skip the command being listed in ctx->runas.argv[1]. */
ctx->user.cmnd_args = strvec_join(ctx->runas.argv + 2, ' ', NULL); ctx->user.cmnd_args = strvec_join(ctx->runas.argv + 2, ' ', NULL);
@@ -1193,8 +1191,8 @@ set_cmnd(struct sudoers_context *ctx)
debug_return_int(NOT_FOUND_ERROR); debug_return_int(NOT_FOUND_ERROR);
} }
} else if (ctx->runas.argc > 1) { } else if (ctx->runas.argc > 1) {
if (ISSET(sudo_mode, MODE_SHELL|MODE_LOGIN_SHELL) && if (ISSET(ctx->mode, MODE_SHELL|MODE_LOGIN_SHELL) &&
ISSET(sudo_mode, MODE_RUN)) { ISSET(ctx->mode, MODE_RUN)) {
/* /*
* When running a command via a shell, the sudo front-end * When running a command via a shell, the sudo front-end
* escapes potential meta chars. We unescape non-spaces * escapes potential meta chars. We unescape non-spaces
@@ -1219,11 +1217,11 @@ set_cmnd(struct sudoers_context *ctx)
ctx->user.cmnd_base = sudo_basename(ctx->user.cmnd); ctx->user.cmnd_base = sudo_basename(ctx->user.cmnd);
/* Convert "sudo sudoedit" -> "sudoedit" */ /* Convert "sudo sudoedit" -> "sudoedit" */
if (ISSET(sudo_mode, MODE_RUN) && strcmp(ctx->user.cmnd_base, "sudoedit") == 0) { if (ISSET(ctx->mode, MODE_RUN) && strcmp(ctx->user.cmnd_base, "sudoedit") == 0) {
char *new_cmnd; char *new_cmnd;
CLR(sudo_mode, MODE_RUN); CLR(ctx->mode, MODE_RUN);
SET(sudo_mode, MODE_EDIT); SET(ctx->mode, MODE_EDIT);
sudo_warnx("%s", U_("sudoedit doesn't need to be run via sudo")); sudo_warnx("%s", U_("sudoedit doesn't need to be run via sudo"));
if ((new_cmnd = strdup("sudoedit")) == NULL) { if ((new_cmnd = strdup("sudoedit")) == NULL) {
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory")); sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
@@ -1547,6 +1545,13 @@ tty_present(struct sudoers_context *ctx)
debug_return_bool(true); debug_return_bool(true);
} }
bool
sudoers_set_mode(unsigned int flags, unsigned int mask)
{
SET(sudoers_ctx.mode, flags);
return ((sudoers_ctx.mode & mask) == sudoers_ctx.mode);
}
const struct sudoers_context * const struct sudoers_context *
sudoers_get_context(void) sudoers_get_context(void)
{ {

View File

@@ -193,6 +193,7 @@ struct sudoers_context {
struct sudoers_plugin_settings settings; struct sudoers_plugin_settings settings;
struct sudoers_user_context user; struct sudoers_user_context user;
struct sudoers_runas_context runas; struct sudoers_runas_context runas;
unsigned int mode;
}; };
/* /*
@@ -392,12 +393,12 @@ extern const struct iolog_path_escape *sudoers_iolog_path_escapes;
/* env.c */ /* env.c */
char **env_get(void); char **env_get(void);
bool env_merge(char * const envp[]); bool env_merge(const struct sudoers_context *ctx, char * const envp[]);
bool env_swap_old(void); bool env_swap_old(void);
bool env_init(char * const envp[]); bool env_init(char * const envp[]);
bool init_envtables(void); bool init_envtables(void);
bool insert_env_vars(char * const envp[]); bool insert_env_vars(char * const envp[]);
bool read_env_file(const char *path, bool overwrite, bool restricted); bool read_env_file(const struct sudoers_context *ctx, const char *path, bool overwrite, bool restricted);
bool rebuild_env(const struct sudoers_context *ctx); bool rebuild_env(const struct sudoers_context *ctx);
bool validate_env_vars(const struct sudoers_context *ctx, char * const envp[]); bool validate_env_vars(const struct sudoers_context *ctx, char * const envp[]);
int sudo_setenv(const char *var, const char *val, int overwrite); int sudo_setenv(const char *var, const char *val, int overwrite);
@@ -432,7 +433,7 @@ int sudoers_validate_user(void);
void sudoers_cleanup(void); void sudoers_cleanup(void);
bool sudoers_override_umask(void); bool sudoers_override_umask(void);
const struct sudoers_context *sudoers_get_context(void); const struct sudoers_context *sudoers_get_context(void);
extern unsigned int sudo_mode; bool sudoers_set_mode(unsigned int flags, unsigned int mask);
extern int sudoedit_nfiles; extern int sudoedit_nfiles;
extern sudo_conv_t sudo_conv; extern sudo_conv_t sudo_conv;
extern sudo_printf_t sudo_printf; extern sudo_printf_t sudo_printf;

View File

@@ -81,7 +81,6 @@ static int testsudoers_query(struct sudoers_context *ctx, const struct sudo_nss
*/ */
static const char *orig_cmnd; static const char *orig_cmnd;
static char *runas_group, *runas_user; static char *runas_group, *runas_user;
unsigned int sudo_mode = MODE_RUN;
#if defined(SUDO_DEVEL) && defined(__OpenBSD__) #if defined(SUDO_DEVEL) && defined(__OpenBSD__)
extern char *malloc_options; extern char *malloc_options;
@@ -131,6 +130,7 @@ main(int argc, char *argv[])
dflag = 0; dflag = 0;
grfile = pwfile = NULL; grfile = pwfile = NULL;
test_ctx.mode = MODE_RUN;
while ((ch = getopt(argc, argv, "+D:dg:G:h:i:L:lP:p:R:T:tu:U:v")) != -1) { while ((ch = getopt(argc, argv, "+D:dg:G:h:i:L:lP:p:R:T:tu:U:v")) != -1) {
switch (ch) { switch (ch) {
case 'D': case 'D':
@@ -174,12 +174,12 @@ main(int argc, char *argv[])
} }
FALLTHROUGH; FALLTHROUGH;
case 'l': case 'l':
if (sudo_mode != MODE_RUN) { if (test_ctx.mode != MODE_RUN) {
sudo_warnx( sudo_warnx(
"only one of the -l or -v flags may be specified"); "only one of the -l or -v flags may be specified");
usage(); usage();
} }
sudo_mode = MODE_LIST; test_ctx.mode = MODE_LIST;
pwflag = I_LISTPW; pwflag = I_LISTPW;
orig_cmnd = "list"; orig_cmnd = "list";
break; break;
@@ -211,12 +211,12 @@ main(int argc, char *argv[])
SET(test_ctx.settings.flags, RUNAS_USER_SPECIFIED); SET(test_ctx.settings.flags, RUNAS_USER_SPECIFIED);
break; break;
case 'v': case 'v':
if (sudo_mode != MODE_RUN) { if (test_ctx.mode != MODE_RUN) {
sudo_warnx( sudo_warnx(
"only one of the -l or -v flags may be specified"); "only one of the -l or -v flags may be specified");
usage(); usage();
} }
sudo_mode = MODE_VALIDATE; test_ctx.mode = MODE_VALIDATE;
pwflag = I_VERIFYPW; pwflag = I_VERIFYPW;
orig_cmnd = "validate"; orig_cmnd = "validate";
break; break;
@@ -255,8 +255,8 @@ main(int argc, char *argv[])
} }
argc = 0; argc = 0;
} else { } else {
if (argc > 2 && sudo_mode == MODE_LIST) if (argc > 2 && test_ctx.mode == MODE_LIST)
sudo_mode = MODE_CHECK; test_ctx.mode = MODE_CHECK;
test_ctx.user.name = strdup(*argv++); test_ctx.user.name = strdup(*argv++);
if (test_ctx.user.name == NULL) { if (test_ctx.user.name == NULL) {
sudo_fatalx(U_("%s: %s"), __func__, sudo_fatalx(U_("%s: %s"), __func__,