Add struct sudoers_runas_context and move runas-specific bits into it.

This commit is contained in:
Todd C. Miller
2023-08-12 14:20:30 -06:00
parent d8b28dad97
commit a321e6cedf
26 changed files with 386 additions and 356 deletions

View File

@@ -92,7 +92,7 @@ bsdauth_init(struct passwd *pw, sudo_auth *auth)
if (auth_setitem(state.as, AUTHV_STYLE, login_style) < 0 ||
auth_setitem(state.as, AUTHV_NAME, pw->pw_name) < 0 ||
auth_setitem(state.as, AUTHV_CLASS, user_ctx.class) < 0) {
auth_setitem(state.as, AUTHV_CLASS, runas_ctx.class) < 0) {
log_warningx(0, N_("unable to initialize BSD authentication"));
goto bad;
}

View File

@@ -94,8 +94,8 @@ resolve_host(const char *host, char **longp, char **shortp)
}
/*
* Look up the fully qualified domain name of host and runhost in user_ctx.
* Sets user_ctx.host, user_ctx.shost, user_ctx.runhost and user_ctx.srunhost.
* Look up the fully qualified domain name of user and runas hosts.
* Sets user_ctx.host, user_ctx.shost, runas_ctx.host and runas_ctx.shost.
*/
static bool
cb_fqdn(const char *file, int line, int column,
@@ -110,12 +110,12 @@ cb_fqdn(const char *file, int line, int column,
if (sd_un != NULL && !sd_un->flag)
debug_return_bool(true);
/* If the -h flag was given we need to resolve both host and runhost. */
remote = strcmp(user_ctx.runhost, user_ctx.host) != 0;
/* If the -h flag was given we need to resolve both host names. */
remote = strcmp(runas_ctx.host, user_ctx.host) != 0;
/* First resolve user_ctx.host, setting host and shost. */
if (resolve_host(user_ctx.host, &lhost, &shost) != 0) {
if ((rc = resolve_host(user_ctx.runhost, &lhost, &shost)) != 0) {
if ((rc = resolve_host(runas_ctx.host, &lhost, &shost)) != 0) {
gai_log_warning(SLOG_PARSE_ERROR|SLOG_RAW_MSG, rc,
N_("unable to resolve host %s"), user_ctx.host);
debug_return_bool(false);
@@ -127,12 +127,12 @@ cb_fqdn(const char *file, int line, int column,
user_ctx.host = lhost;
user_ctx.shost = shost;
/* Next resolve user_ctx.runhost, setting runhost and srunhost. */
/* Next resolve runas_ctx.host, setting host and shost in runas_ctx. */
lhost = shost = NULL;
if (remote) {
if ((rc = resolve_host(user_ctx.runhost, &lhost, &shost)) != 0) {
if ((rc = resolve_host(runas_ctx.host, &lhost, &shost)) != 0) {
gai_log_warning(SLOG_NO_LOG|SLOG_RAW_MSG, rc,
N_("unable to resolve host %s"), user_ctx.runhost);
N_("unable to resolve host %s"), runas_ctx.host);
debug_return_bool(false);
}
} else {
@@ -152,16 +152,16 @@ cb_fqdn(const char *file, int line, int column,
}
}
if (lhost != NULL && shost != NULL) {
if (user_ctx.srunhost != user_ctx.runhost)
free(user_ctx.srunhost);
free(user_ctx.runhost);
user_ctx.runhost = lhost;
user_ctx.srunhost = shost;
if (runas_ctx.shost != runas_ctx.host)
free(runas_ctx.shost);
free(runas_ctx.host);
runas_ctx.host = lhost;
runas_ctx.shost = shost;
}
sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
"host %s, shost %s, runhost %s, srunhost %s",
user_ctx.host, user_ctx.shost, user_ctx.runhost, user_ctx.srunhost);
"host %s, shost %s, runas host %s, runas shost %s",
user_ctx.host, user_ctx.shost, runas_ctx.host, runas_ctx.shost);
debug_return_bool(true);
}

View File

@@ -197,17 +197,17 @@ check_user(unsigned int validated, unsigned int mode)
ret = true;
goto done;
}
if (user_ctx.uid == 0 || (user_ctx.uid == user_ctx.runas_pw->pw_uid &&
(user_ctx.runas_gr == NULL ||
user_in_group(user_ctx.pw, user_ctx.runas_gr->gr_name)))) {
if (user_ctx.uid == 0 || (user_ctx.uid == runas_ctx.pw->pw_uid &&
(runas_ctx.gr == NULL ||
user_in_group(user_ctx.pw, runas_ctx.gr->gr_name)))) {
#ifdef HAVE_SELINUX
if (user_ctx.role == NULL && user_ctx.type == NULL)
if (runas_ctx.role == NULL && runas_ctx.type == NULL)
#endif
#ifdef HAVE_APPARMOR
if (user_ctx.apparmor_profile == NULL)
if (runas_ctx.apparmor_profile == NULL)
#endif
#ifdef HAVE_PRIV_SET
if (user_ctx.privs == NULL && user_ctx.limitprivs == NULL)
if (runas_ctx.privs == NULL && runas_ctx.limitprivs == NULL)
#endif
{
sudo_debug_printf(SUDO_DEBUG_INFO,
@@ -338,7 +338,7 @@ user_is_exempt(void)
/*
* Get passwd entry for the user we are going to authenticate as.
* By default, this is the user invoking sudo. In the most common
* case, this matches user_ctx.pw or user_ctx.runas_pw.
* case, this matches user_ctx.pw or runas_ctx.pw.
*/
static struct passwd *
get_authpw(unsigned int mode)
@@ -361,13 +361,13 @@ get_authpw(unsigned int mode)
N_("unknown user %s"), def_runas_default);
}
} else if (def_targetpw) {
if (user_ctx.runas_pw->pw_name == NULL) {
if (runas_ctx.pw->pw_name == NULL) {
/* This should never be NULL as we fake up the passwd struct */
log_warningx(SLOG_RAW_MSG, N_("unknown uid %u"),
(unsigned int) user_ctx.runas_pw->pw_uid);
(unsigned int) runas_ctx.pw->pw_uid);
} else {
sudo_pw_addref(user_ctx.runas_pw);
pw = user_ctx.runas_pw;
sudo_pw_addref(runas_ctx.pw);
pw = runas_ctx.pw;
}
} else {
sudo_pw_addref(user_ctx.pw);

View File

@@ -57,7 +57,7 @@ check_user_shell(const struct passwd *pw)
}
/*
* Check whether user_ctx.runchroot matches def_runchroot.
* Check whether runas_ctx.chroot matches def_runchroot.
* Returns true if matched, false if not matched and -1 on error.
*/
int
@@ -65,20 +65,20 @@ check_user_runchroot(void)
{
debug_decl(check_user_runchroot, SUDOERS_DEBUG_AUTH);
if (user_ctx.runchroot == NULL)
if (runas_ctx.chroot == NULL)
debug_return_bool(true);
sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
"def_runchroot %s, user_ctx.runchroot %s",
"def_runchroot %s, runas_ctx.chroot %s",
def_runchroot ? def_runchroot : "none",
user_ctx.runchroot ? user_ctx.runchroot : "none");
runas_ctx.chroot ? runas_ctx.chroot : "none");
/* User may only specify a root dir if runchroot is "*" */
if (def_runchroot == NULL || strcmp(def_runchroot, "*") != 0)
debug_return_bool(false);
free(def_runchroot);
if ((def_runchroot = strdup(user_ctx.runchroot)) == NULL) {
if ((def_runchroot = strdup(runas_ctx.chroot)) == NULL) {
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
debug_return_int(-1);
}
@@ -86,7 +86,7 @@ check_user_runchroot(void)
}
/*
* Check whether user_ctx.runcwd matches def_runcwd.
* Check whether runas_ctx.cwd matches def_runcwd.
* Returns true if matched, false if not matched and -1 on error.
*/
int
@@ -94,20 +94,20 @@ check_user_runcwd(void)
{
debug_decl(check_user_runcwd, SUDOERS_DEBUG_AUTH);
if (user_ctx.runcwd == NULL)
if (runas_ctx.cwd == NULL)
debug_return_bool(true);
sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
"def_runcwd %s, user_ctx.runcwd %s",
"def_runcwd %s, runas_ctx.cwd %s",
def_runcwd ? def_runcwd : "none",
user_ctx.runcwd ? user_ctx.runcwd : "none");
runas_ctx.cwd ? runas_ctx.cwd : "none");
/* User may only specify a cwd if runcwd is "*" */
if (def_runcwd == NULL || strcmp(def_runcwd, "*") != 0)
debug_return_bool(false);
free(def_runcwd);
if ((def_runcwd = strdup(user_ctx.runcwd)) == NULL) {
if ((def_runcwd = strdup(runas_ctx.cwd)) == NULL) {
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
debug_return_int(-1);
}

View File

@@ -62,6 +62,7 @@
*/
struct cvtsudoers_filter *filters;
struct sudoers_user_context user_ctx;
struct sudoers_runas_context runas_ctx;
struct passwd *list_pw;
static FILE *logfp;
static const char short_opts[] = "b:c:d:ef:hi:I:l:m:Mo:O:pP:s:V";

View File

@@ -466,7 +466,7 @@ display_privs(const struct sudo_nss_list *snl, struct passwd *pw, bool verbose)
sudo_lbuf_init(&priv_buf, output, 8, NULL, cols);
sudo_lbuf_append(&def_buf, _("Matching Defaults entries for %s on %s:\n"),
pw->pw_name, user_ctx.srunhost);
pw->pw_name, runas_ctx.shost);
count = 0;
TAILQ_FOREACH(nss, snl, entries) {
n = display_defaults(nss->parse_tree, pw, &def_buf);
@@ -502,7 +502,7 @@ display_privs(const struct sudo_nss_list *snl, struct passwd *pw, bool verbose)
/* Display privileges from all sources. */
sudo_lbuf_append(&priv_buf,
_("User %s may run the following commands on %s:\n"),
pw->pw_name, user_ctx.srunhost);
pw->pw_name, runas_ctx.shost);
count = 0;
TAILQ_FOREACH(nss, snl, entries) {
if (nss->query(nss, pw) != -1) {
@@ -517,7 +517,7 @@ display_privs(const struct sudo_nss_list *snl, struct passwd *pw, bool verbose)
priv_buf.len = 0;
sudo_lbuf_append(&priv_buf,
_("User %s is not allowed to run sudo on %s.\n"),
pw->pw_name, user_ctx.srunhost);
pw->pw_name, runas_ctx.shost);
}
if (sudo_lbuf_error(&def_buf) || sudo_lbuf_error(&priv_buf))
goto bad;

View File

@@ -901,11 +901,11 @@ rebuild_env(void)
if (!ISSET(sudo_mode, MODE_LOGIN_SHELL)) {
#ifdef HAVE_LOGIN_CAP_H
/* Insert login class environment variables. */
if (user_ctx.class) {
login_cap_t *lc = login_getclass(user_ctx.class);
if (runas_ctx.class) {
login_cap_t *lc = login_getclass(runas_ctx.class);
if (lc != NULL) {
setusercontext(lc, user_ctx.runas_pw,
user_ctx.runas_pw->pw_uid, LOGIN_SETPATH|LOGIN_SETENV);
setusercontext(lc, runas_ctx.pw,
runas_ctx.pw->pw_uid, LOGIN_SETPATH|LOGIN_SETENV);
login_close(lc);
}
}
@@ -951,15 +951,15 @@ rebuild_env(void)
* on sudoers options).
*/
if (ISSET(sudo_mode, MODE_LOGIN_SHELL)) {
CHECK_SETENV2("SHELL", user_ctx.runas_pw->pw_shell,
CHECK_SETENV2("SHELL", runas_ctx.pw->pw_shell,
ISSET(didvar, DID_SHELL), true);
#ifdef _AIX
CHECK_SETENV2("LOGIN", user_ctx.runas_pw->pw_name,
CHECK_SETENV2("LOGIN", runas_ctx.pw->pw_name,
ISSET(didvar, DID_LOGIN), true);
#endif
CHECK_SETENV2("LOGNAME", user_ctx.runas_pw->pw_name,
CHECK_SETENV2("LOGNAME", runas_ctx.pw->pw_name,
ISSET(didvar, DID_LOGNAME), true);
CHECK_SETENV2("USER", user_ctx.runas_pw->pw_name,
CHECK_SETENV2("USER", runas_ctx.pw->pw_name,
ISSET(didvar, DID_USER), true);
} else {
/* We will set LOGNAME later in the def_set_logname case. */
@@ -986,10 +986,10 @@ rebuild_env(void)
if (ISSET(sudo_mode, MODE_LOGIN_SHELL) || !ISSET(didvar, KEPT_MAIL)) {
if (_PATH_MAILDIR[sizeof(_PATH_MAILDIR) - 2] == '/') {
len = asprintf(&cp, "MAIL=%s%s", _PATH_MAILDIR,
user_ctx.runas_pw->pw_name);
runas_ctx.pw->pw_name);
} else {
len = asprintf(&cp, "MAIL=%s/%s", _PATH_MAILDIR,
user_ctx.runas_pw->pw_name);
runas_ctx.pw->pw_name);
}
if (len == -1)
goto bad;
@@ -1036,10 +1036,10 @@ rebuild_env(void)
if ((didvar & KEPT_USER_VARIABLES) == 0) {
/* Nothing preserved, set them all. */
#ifdef _AIX
CHECK_SETENV2("LOGIN", user_ctx.runas_pw->pw_name, true, true);
CHECK_SETENV2("LOGIN", runas_ctx.pw->pw_name, true, true);
#endif
CHECK_SETENV2("LOGNAME", user_ctx.runas_pw->pw_name, true, true);
CHECK_SETENV2("USER", user_ctx.runas_pw->pw_name, true, true);
CHECK_SETENV2("LOGNAME", runas_ctx.pw->pw_name, true, true);
CHECK_SETENV2("USER", runas_ctx.pw->pw_name, true, true);
} else if ((didvar & KEPT_USER_VARIABLES) != KEPT_USER_VARIABLES) {
/*
* Preserved some of LOGIN, LOGNAME, USER but not all.
@@ -1071,11 +1071,11 @@ rebuild_env(void)
/* Set $HOME to target user if not preserving user's value. */
if (reset_home)
CHECK_SETENV2("HOME", user_ctx.runas_pw->pw_dir, true, true);
CHECK_SETENV2("HOME", runas_ctx.pw->pw_dir, true, true);
/* Provide default values for $SHELL, $TERM and $PATH if not set. */
if (!ISSET(didvar, DID_SHELL))
CHECK_SETENV2("SHELL", user_ctx.runas_pw->pw_shell, false, false);
CHECK_SETENV2("SHELL", runas_ctx.pw->pw_shell, false, false);
if (!ISSET(didvar, DID_TERM))
CHECK_PUTENV("TERM=unknown", false, false);
if (!ISSET(didvar, DID_PATH))

View File

@@ -86,7 +86,7 @@ static size_t
fill_runas_user(char *str, size_t strsize, void *unused)
{
debug_decl(fill_runas_user, SUDOERS_DEBUG_UTIL);
debug_return_size_t(strlcpy(str, user_ctx.runas_pw->pw_name, strsize));
debug_return_size_t(strlcpy(str, runas_ctx.pw->pw_name, strsize));
}
static size_t
@@ -96,15 +96,15 @@ fill_runas_group(char *str, size_t strsize, void *unused)
size_t len;
debug_decl(fill_runas_group, SUDOERS_DEBUG_UTIL);
if (user_ctx.runas_gr != NULL) {
len = strlcpy(str, user_ctx.runas_gr->gr_name, strsize);
if (runas_ctx.gr != NULL) {
len = strlcpy(str, runas_ctx.gr->gr_name, strsize);
} else {
if ((grp = sudo_getgrgid(user_ctx.runas_pw->pw_gid)) != NULL) {
if ((grp = sudo_getgrgid(runas_ctx.pw->pw_gid)) != NULL) {
len = strlcpy(str, grp->gr_name, strsize);
sudo_gr_delref(grp);
} else {
len = (size_t)snprintf(str, strsize, "#%u",
(unsigned int)user_ctx.runas_pw->pw_gid);
(unsigned int)runas_ctx.pw->pw_gid);
}
}
debug_return_size_t(len);

View File

@@ -329,8 +329,8 @@ sudo_ldap_check_non_unix_group(const struct sudo_nss *nss, LDAPMessage *entry,
}
if (*val == '+') {
if (netgr_matches(nss, val,
def_netgroup_tuple ? user_ctx.runhost : NULL,
def_netgroup_tuple ? user_ctx.srunhost : NULL, pw->pw_name))
def_netgroup_tuple ? runas_ctx.host : NULL,
def_netgroup_tuple ? runas_ctx.shost : NULL, pw->pw_name))
ret = true;
DPRINTF2("ldap sudoUser netgroup '%s%s' ... %s",
negated ? "!" : "", val, ret ? "MATCH!" : "not");
@@ -666,11 +666,11 @@ sudo_netgroup_lookup(LDAP *ld, struct passwd *pw,
if ((escaped_user = sudo_ldap_value_dup(pw->pw_name)) == NULL)
goto oom;
if (def_netgroup_tuple) {
escaped_host = sudo_ldap_value_dup(user_ctx.runhost);
if (user_ctx.runhost == user_ctx.srunhost)
escaped_host = sudo_ldap_value_dup(runas_ctx.host);
if (runas_ctx.host == runas_ctx.shost)
escaped_shost = escaped_host;
else
escaped_shost = sudo_ldap_value_dup(user_ctx.srunhost);
escaped_shost = sudo_ldap_value_dup(runas_ctx.shost);
if (escaped_host == NULL || escaped_shost == NULL)
goto oom;
}
@@ -1925,7 +1925,7 @@ sudo_ldap_query(const struct sudo_nss *nss, struct passwd *pw)
free_userspecs(&handle->parse_tree.userspecs);
DPRINTF1("%s: ldap search user %s, host %s", __func__, pw->pw_name,
user_ctx.runhost);
runas_ctx.host);
if ((lres = sudo_ldap_result_get(nss, pw)) == NULL)
goto done;

View File

@@ -263,7 +263,7 @@ log_reject(const char *message, bool logit, bool mailit)
if (!logit)
SET(evl_flags, EVLOG_MAIL_ONLY);
}
sudoers_to_eventlog(&evlog, user_ctx.cmnd_safe, NewArgv, env_get(), uuid_str);
sudoers_to_eventlog(&evlog, runas_ctx.cmnd, NewArgv, env_get(), uuid_str);
ret = eventlog_reject(&evlog, evl_flags, message, NULL, NULL);
if (!log_server_reject(&evlog, message))
ret = false;
@@ -316,12 +316,12 @@ log_denial(unsigned int status, bool inform_user)
"file.\n"), user_ctx.name);
} else if (ISSET(status, FLAG_NO_HOST)) {
sudo_printf(SUDO_CONV_ERROR_MSG, _("%s is not allowed to run sudo "
"on %s.\n"), user_ctx.name, user_ctx.srunhost);
"on %s.\n"), user_ctx.name, runas_ctx.shost);
} else if (ISSET(status, FLAG_NO_CHECK)) {
sudo_printf(SUDO_CONV_ERROR_MSG, _("Sorry, user %s may not run "
"sudo on %s.\n"), user_ctx.name, user_ctx.srunhost);
"sudo on %s.\n"), user_ctx.name, runas_ctx.shost);
} else {
const struct passwd *runas_pw = list_pw ? list_pw : user_ctx.runas_pw;
const struct passwd *runas_pw = list_pw ? list_pw : runas_ctx.pw;
const char *cmnd1 = user_ctx.cmnd;
const char *cmnd2 = "";
@@ -335,8 +335,8 @@ log_denial(unsigned int status, bool inform_user)
user_ctx.name, cmnd1, cmnd2, user_ctx.cmnd_args ? " " : "",
user_ctx.cmnd_args ? user_ctx.cmnd_args : "",
runas_pw ? runas_pw->pw_name : user_ctx.name,
user_ctx.runas_gr ? ":" : "",
user_ctx.runas_gr ? user_ctx.runas_gr->gr_name : "",
runas_ctx.gr ? ":" : "",
runas_ctx.gr ? runas_ctx.gr->gr_name : "",
user_ctx.host);
}
if (mailit) {
@@ -729,7 +729,7 @@ vlog_warning(unsigned int flags, int errnum, const char * restrict fmt,
if (ISSET(flags, SLOG_NO_LOG))
SET(evl_flags, EVLOG_MAIL_ONLY);
}
sudoers_to_eventlog(&evlog, user_ctx.cmnd_safe, NewArgv, env_get(),
sudoers_to_eventlog(&evlog, runas_ctx.cmnd, NewArgv, env_get(),
user_ctx.uuid_str);
if (!eventlog_alert(&evlog, evl_flags, &now, message, errstr))
ret = false;
@@ -844,7 +844,7 @@ mail_parse_errors(void)
sudo_warn("%s", U_("unable to get time of day"));
goto done;
}
sudoers_to_eventlog(&evlog, user_ctx.cmnd_safe, NewArgv, env_get(),
sudoers_to_eventlog(&evlog, runas_ctx.cmnd, NewArgv, env_get(),
user_ctx.uuid_str);
/* Convert parse_error_list to a string vector. */
@@ -970,12 +970,12 @@ sudoers_to_eventlog(struct eventlog *evlog, const char *cmnd,
}
if (def_runcwd && strcmp(def_runcwd, "*") != 0) {
evlog->runcwd = def_runcwd;
} else if (ISSET(sudo_mode, MODE_LOGIN_SHELL) && user_ctx.runas_pw != NULL) {
evlog->runcwd = user_ctx.runas_pw->pw_dir;
} else if (ISSET(sudo_mode, MODE_LOGIN_SHELL) && runas_ctx.pw != NULL) {
evlog->runcwd = runas_ctx.pw->pw_dir;
} else {
evlog->runcwd = user_ctx.cwd;
}
evlog->rungroup = user_ctx.runas_gr ? user_ctx.runas_gr->gr_name : user_ctx.runas_group;
evlog->rungroup = runas_ctx.gr ? runas_ctx.gr->gr_name : runas_ctx.group;
evlog->source = user_ctx.source;
evlog->submithost = user_ctx.host;
evlog->submituser = user_ctx.name;
@@ -988,14 +988,14 @@ sudoers_to_eventlog(struct eventlog *evlog, const char *cmnd,
evlog->submit_time = user_ctx.submit_time;
evlog->lines = user_ctx.lines;
evlog->columns = user_ctx.cols;
if (user_ctx.runas_pw != NULL) {
evlog->rungid = user_ctx.runas_pw->pw_gid;
evlog->runuid = user_ctx.runas_pw->pw_uid;
evlog->runuser = user_ctx.runas_pw->pw_name;
if (runas_ctx.pw != NULL) {
evlog->rungid = runas_ctx.pw->pw_gid;
evlog->runuid = runas_ctx.pw->pw_uid;
evlog->runuser = runas_ctx.pw->pw_name;
} else {
evlog->rungid = (gid_t)-1;
evlog->runuid = (uid_t)-1;
evlog->runuser = user_ctx.runas_user;
evlog->runuser = runas_ctx.user;
}
if (uuid_str == NULL) {
unsigned char uuid[16];

View File

@@ -291,13 +291,13 @@ sudoers_lookup_check(struct sudo_nss *nss, struct passwd *pw,
if (cmnd_match != UNSPEC) {
/*
* If user is running command as themselves,
* set user_ctx.runas_pw = user_ctx.pw.
* set runas_ctx.pw = user_ctx.pw.
* XXX - hack, want more general solution
*/
if (matching_user && matching_user->type == MYSELF) {
sudo_pw_delref(user_ctx.runas_pw);
sudo_pw_delref(runas_ctx.pw);
sudo_pw_addref(user_ctx.pw);
user_ctx.runas_pw = user_ctx.pw;
runas_ctx.pw = user_ctx.pw;
}
*matching_cs = cs;
*defs = &priv->defaults;
@@ -327,93 +327,93 @@ apply_cmndspec(struct cmndspec *cs)
if (cs != NULL) {
#ifdef HAVE_SELINUX
/* Set role and type if not specified on command line. */
if (user_ctx.role == NULL) {
if (runas_ctx.role == NULL) {
if (cs->role != NULL) {
user_ctx.role = strdup(cs->role);
if (user_ctx.role == NULL) {
runas_ctx.role = strdup(cs->role);
if (runas_ctx.role == NULL) {
sudo_warnx(U_("%s: %s"), __func__,
U_("unable to allocate memory"));
debug_return_bool(false);
}
} else {
user_ctx.role = def_role;
runas_ctx.role = def_role;
def_role = NULL;
}
if (user_ctx.role != NULL) {
if (runas_ctx.role != NULL) {
sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
"user_ctx.role -> %s", user_ctx.role);
"runas_ctx.role -> %s", runas_ctx.role);
}
}
if (user_ctx.type == NULL) {
if (runas_ctx.type == NULL) {
if (cs->type != NULL) {
user_ctx.type = strdup(cs->type);
if (user_ctx.type == NULL) {
runas_ctx.type = strdup(cs->type);
if (runas_ctx.type == NULL) {
sudo_warnx(U_("%s: %s"), __func__,
U_("unable to allocate memory"));
debug_return_bool(false);
}
} else {
user_ctx.type = def_type;
runas_ctx.type = def_type;
def_type = NULL;
}
if (user_ctx.type != NULL) {
if (runas_ctx.type != NULL) {
sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
"user_ctx.type -> %s", user_ctx.type);
"runas_ctx.type -> %s", runas_ctx.type);
}
}
#endif /* HAVE_SELINUX */
#ifdef HAVE_APPARMOR
/* Set AppArmor profile, if specified */
if (cs->apparmor_profile != NULL) {
user_ctx.apparmor_profile = strdup(cs->apparmor_profile);
if (user_ctx.apparmor_profile == NULL) {
runas_ctx.apparmor_profile = strdup(cs->apparmor_profile);
if (runas_ctx.apparmor_profile == NULL) {
sudo_warnx(U_("%s: %s"), __func__,
U_("unable to allocate memory"));
debug_return_bool(false);
}
} else {
user_ctx.apparmor_profile = def_apparmor_profile;
runas_ctx.apparmor_profile = def_apparmor_profile;
def_apparmor_profile = NULL;
}
if (user_ctx.apparmor_profile != NULL) {
if (runas_ctx.apparmor_profile != NULL) {
sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
"user_ctx.apparmor_profile -> %s", user_ctx.apparmor_profile);
"runas_ctx.apparmor_profile -> %s", runas_ctx.apparmor_profile);
}
#endif
#ifdef HAVE_PRIV_SET
/* Set Solaris privilege sets */
if (user_ctx.privs == NULL) {
if (runas_ctx.privs == NULL) {
if (cs->privs != NULL) {
user_ctx.privs = strdup(cs->privs);
if (user_ctx.privs == NULL) {
runas_ctx.privs = strdup(cs->privs);
if (runas_ctx.privs == NULL) {
sudo_warnx(U_("%s: %s"), __func__,
U_("unable to allocate memory"));
debug_return_bool(false);
}
} else {
user_ctx.privs = def_privs;
runas_ctx.privs = def_privs;
def_privs = NULL;
}
if (user_ctx.privs != NULL) {
if (runas_ctx.privs != NULL) {
sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
"user_ctx.privs -> %s", user_ctx.privs);
"runas_ctx.privs -> %s", runas_ctx.privs);
}
}
if (user_ctx.limitprivs == NULL) {
if (runas_ctx.limitprivs == NULL) {
if (cs->limitprivs != NULL) {
user_ctx.limitprivs = strdup(cs->limitprivs);
if (user_ctx.limitprivs == NULL) {
runas_ctx.limitprivs = strdup(cs->limitprivs);
if (runas_ctx.limitprivs == NULL) {
sudo_warnx(U_("%s: %s"), __func__,
U_("unable to allocate memory"));
debug_return_bool(false);
}
} else {
user_ctx.limitprivs = def_limitprivs;
runas_ctx.limitprivs = def_limitprivs;
def_limitprivs = NULL;
}
if (user_ctx.limitprivs != NULL) {
if (runas_ctx.limitprivs != NULL) {
sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
"user_ctx.limitprivs -> %s", user_ctx.limitprivs);
"runas_ctx.limitprivs -> %s", runas_ctx.limitprivs);
}
}
#endif /* HAVE_PRIV_SET */

View File

@@ -66,8 +66,8 @@ int
user_matches(const struct sudoers_parse_tree *parse_tree,
const struct passwd *pw, const struct member *m)
{
const char *lhost = parse_tree->lhost ? parse_tree->lhost : user_ctx.runhost;
const char *shost = parse_tree->shost ? parse_tree->shost : user_ctx.srunhost;
const char *lhost = parse_tree->lhost ? parse_tree->lhost : runas_ctx.host;
const char *shost = parse_tree->shost ? parse_tree->shost : runas_ctx.shost;
int matched = UNSPEC;
struct alias *a;
debug_decl(user_matches, SUDOERS_DEBUG_MATCH);
@@ -135,7 +135,7 @@ runas_getgroups(void)
}
/* Only use results from a group db query, not the front end. */
pw = user_ctx.runas_pw ? user_ctx.runas_pw : user_ctx.pw;
pw = runas_ctx.pw ? runas_ctx.pw : user_ctx.pw;
debug_return_ptr(sudo_get_gidlist(pw, ENTRY_TYPE_QUERIED));
}
@@ -149,8 +149,8 @@ static int
runas_userlist_matches(const struct sudoers_parse_tree *parse_tree,
const struct member_list *user_list, struct member **matching_user)
{
const char *lhost = parse_tree->lhost ? parse_tree->lhost : user_ctx.runhost;
const char *shost = parse_tree->shost ? parse_tree->shost : user_ctx.srunhost;
const char *lhost = parse_tree->lhost ? parse_tree->lhost : runas_ctx.host;
const char *shost = parse_tree->shost ? parse_tree->shost : runas_ctx.shost;
int user_matched = UNSPEC;
struct member *m;
struct alias *a;
@@ -165,11 +165,11 @@ runas_userlist_matches(const struct sudoers_parse_tree *parse_tree,
if (netgr_matches(parse_tree->nss, m->name,
def_netgroup_tuple ? lhost : NULL,
def_netgroup_tuple ? shost : NULL,
user_ctx.runas_pw->pw_name))
runas_ctx.pw->pw_name))
user_matched = !m->negated;
break;
case USERGROUP:
if (usergr_matches(m->name, user_ctx.runas_pw->pw_name, user_ctx.runas_pw))
if (usergr_matches(m->name, runas_ctx.pw->pw_name, runas_ctx.pw))
user_matched = !m->negated;
break;
case ALIAS:
@@ -184,7 +184,7 @@ runas_userlist_matches(const struct sudoers_parse_tree *parse_tree,
}
FALLTHROUGH;
case WORD:
if (userpw_matches(m->name, user_ctx.runas_pw->pw_name, user_ctx.runas_pw))
if (userpw_matches(m->name, runas_ctx.pw->pw_name, runas_ctx.pw))
user_matched = !m->negated;
break;
case MYSELF:
@@ -195,7 +195,7 @@ runas_userlist_matches(const struct sudoers_parse_tree *parse_tree,
*/
if ((!ISSET(user_ctx.flags, RUNAS_USER_SPECIFIED) &&
ISSET(user_ctx.flags, RUNAS_GROUP_SPECIFIED)) ||
strcmp(user_ctx.name, user_ctx.runas_pw->pw_name) == 0)
strcmp(user_ctx.name, runas_ctx.pw->pw_name) == 0)
user_matched = !m->negated;
break;
}
@@ -240,7 +240,7 @@ runas_grouplist_matches(const struct sudoers_parse_tree *parse_tree,
}
FALLTHROUGH;
case WORD:
if (group_matches(m->name, user_ctx.runas_gr))
if (group_matches(m->name, runas_ctx.gr))
group_matched = !m->negated;
break;
}
@@ -257,13 +257,13 @@ runas_grouplist_matches(const struct sudoers_parse_tree *parse_tree,
* The runas group was not explicitly allowed by sudoers.
* Check whether it is one of the target user's groups.
*/
if (user_ctx.runas_pw->pw_gid == user_ctx.runas_gr->gr_gid) {
if (runas_ctx.pw->pw_gid == runas_ctx.gr->gr_gid) {
group_matched = ALLOW; /* runas group matches passwd db */
} else if ((runas_groups = runas_getgroups()) != NULL) {
int i;
for (i = 0; i < runas_groups->ngids; i++) {
if (runas_groups->gids[i] == user_ctx.runas_gr->gr_gid) {
if (runas_groups->gids[i] == runas_ctx.gr->gr_gid) {
group_matched = ALLOW; /* matched aux group vector */
break;
}
@@ -310,7 +310,7 @@ runaslist_matches(const struct sudoers_parse_tree *parse_tree,
if (user_matched == DENY || group_matched == DENY)
debug_return_int(DENY);
if (user_matched == group_matched || user_ctx.runas_gr == NULL)
if (user_matched == group_matched || runas_ctx.gr == NULL)
debug_return_int(user_matched);
debug_return_int(UNSPEC);
}
@@ -337,15 +337,15 @@ hostlist_matches_int(const struct sudoers_parse_tree *parse_tree,
}
/*
* Check for user_ctx.runhost and user_ctx.srunhost in a list of members.
* Check for runas_ctx.host and runas_ctx.shost in a list of members.
* Returns ALLOW, DENY or UNSPEC.
*/
int
hostlist_matches(const struct sudoers_parse_tree *parse_tree,
const struct passwd *pw, const struct member_list *list)
{
const char *lhost = parse_tree->lhost ? parse_tree->lhost : user_ctx.runhost;
const char *shost = parse_tree->shost ? parse_tree->shost : user_ctx.srunhost;
const char *lhost = parse_tree->lhost ? parse_tree->lhost : runas_ctx.host;
const char *shost = parse_tree->shost ? parse_tree->shost : runas_ctx.shost;
return hostlist_matches_int(parse_tree, pw, lhost, shost, list);
}

View File

@@ -202,8 +202,8 @@ set_cmnd_fd(int fd, int rootfd)
{
debug_decl(set_cmnd_fd, SUDOERS_DEBUG_MATCH);
if (user_ctx.execfd != -1)
close(user_ctx.execfd);
if (runas_ctx.execfd != -1)
close(runas_ctx.execfd);
if (fd != -1) {
if (def_fdexec == never) {
@@ -240,7 +240,7 @@ set_cmnd_fd(int fd, int rootfd)
}
}
user_ctx.execfd = fd;
runas_ctx.execfd = fd;
debug_return;
}
@@ -289,8 +289,8 @@ command_matches_dir(const char *sudoers_dir, size_t dlen, int rootfd,
user_ctx.cmnd_stat->st_ino == sudoers_stat.st_ino)) {
if (!digest_matches(fd, path, digests))
goto done;
free(user_ctx.cmnd_safe);
if ((user_ctx.cmnd_safe = strdup(path)) == NULL) {
free(runas_ctx.cmnd);
if ((runas_ctx.cmnd = strdup(path)) == NULL) {
sudo_warnx(U_("%s: %s"), __func__,
U_("unable to allocate memory"));
}
@@ -371,7 +371,7 @@ command_matches_all(int rootfd, bool intercepted,
goto bad;
set_cmnd_fd(fd, rootfd);
/* No need to set user_ctx.cmnd_safe for ALL. */
/* No need to set runas_ctx.cmnd for ALL. */
debug_return_bool(true);
bad:
if (fd != -1)
@@ -427,7 +427,7 @@ command_matches_fnmatch(const char *sudoers_cmnd, const char *sudoers_args,
goto bad;
set_cmnd_fd(fd, rootfd);
/* No need to set user_ctx.cmnd_safe since cmnd matches sudoers_cmnd */
/* No need to set runas_ctx.cmnd since cmnd matches sudoers_cmnd */
debug_return_bool(true);
bad:
if (fd != -1)
@@ -485,7 +485,7 @@ command_matches_regex(const char *sudoers_cmnd, const char *sudoers_args,
goto bad;
set_cmnd_fd(fd, rootfd);
/* No need to set user_ctx.cmnd_safe since cmnd matches sudoers_cmnd */
/* No need to set runas_ctx.cmnd since cmnd matches sudoers_cmnd */
debug_return_bool(true);
bad:
if (fd != -1)
@@ -557,8 +557,8 @@ command_matches_glob(const char *sudoers_cmnd, const char *sudoers_args,
bad_digest = true;
continue;
}
free(user_ctx.cmnd_safe);
if ((user_ctx.cmnd_safe = strdup(cp)) == NULL) {
free(runas_ctx.cmnd);
if ((runas_ctx.cmnd = strdup(cp)) == NULL) {
sudo_warnx(U_("%s: %s"), __func__,
U_("unable to allocate memory"));
cp = NULL; /* fail closed */
@@ -623,8 +623,8 @@ command_matches_glob(const char *sudoers_cmnd, const char *sudoers_args,
user_ctx.cmnd_stat->st_ino == sudoers_stat.st_ino)) {
if (!digest_matches(fd, cp, digests))
continue;
free(user_ctx.cmnd_safe);
if ((user_ctx.cmnd_safe = strdup(cp)) == NULL) {
free(runas_ctx.cmnd);
if ((runas_ctx.cmnd = strdup(cp)) == NULL) {
sudo_warnx(U_("%s: %s"), __func__,
U_("unable to allocate memory"));
cp = NULL; /* fail closed */
@@ -637,7 +637,7 @@ done:
globfree(&gl);
if (cp != NULL) {
if (command_args_match(sudoers_cmnd, sudoers_args)) {
/* user_ctx.cmnd_safe was set above. */
/* runas_ctx.cmnd was set above. */
set_cmnd_fd(fd, rootfd);
debug_return_bool(true);
}
@@ -719,8 +719,8 @@ command_matches_normal(const char *sudoers_cmnd, const char *sudoers_args,
/* XXX - log functions not available but we should log very loudly */
goto bad;
}
free(user_ctx.cmnd_safe);
if ((user_ctx.cmnd_safe = strdup(sudoers_cmnd)) == NULL) {
free(runas_ctx.cmnd);
if ((runas_ctx.cmnd = strdup(sudoers_cmnd)) == NULL) {
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
goto bad;
}
@@ -764,8 +764,8 @@ command_matches_normal(const char *sudoers_cmnd, const char *sudoers_args,
goto bad;
/* Successful match. */
free(user_ctx.cmnd_safe);
if ((user_ctx.cmnd_safe = strdup(sudoers_cmnd)) == NULL) {
free(runas_ctx.cmnd);
if ((runas_ctx.cmnd = strdup(sudoers_cmnd)) == NULL) {
sudo_warnx(U_("%s: %s"), __func__,
U_("unable to allocate memory"));
goto bad;
@@ -798,14 +798,14 @@ command_matches(const char *sudoers_cmnd, const char *sudoers_args,
bool rc = false;
debug_decl(command_matches, SUDOERS_DEBUG_MATCH);
if (user_ctx.runchroot != NULL) {
if (runas_ctx.chroot != NULL) {
if (runchroot != NULL && strcmp(runchroot, "*") != 0 &&
strcmp(runchroot, user_ctx.runchroot) != 0) {
strcmp(runchroot, runas_ctx.chroot) != 0) {
/* CHROOT mismatch */
goto done;
}
/* User-specified runchroot (cmnd_stat already set appropriately). */
runchroot = user_ctx.runchroot;
runchroot = runas_ctx.chroot;
} else if (runchroot == NULL) {
/* No rule-specific runchroot, use global (cmnd_stat already set). */
if (def_runchroot != NULL && strcmp(def_runchroot, "*") != '\0')
@@ -864,7 +864,7 @@ command_matches(const char *sudoers_cmnd, const char *sudoers_args,
strcmp(sudoers_cmnd, "sudoedit") == 0) {
if (strcmp(user_ctx.cmnd, sudoers_cmnd) == 0 &&
command_args_match(sudoers_cmnd, sudoers_args)) {
/* No need to set cmnd_safe since cmnd == sudoers_cmnd */
/* No need to set user_ctx.cmnd since cmnd == sudoers_cmnd */
rc = true;
}
}

View File

@@ -200,8 +200,8 @@ sudoers_policy_deserialize_info(void *v, struct defaults_list *defaults)
}
if (MATCHES(*cur, "cmnd_chroot=")) {
CHECK(*cur, "cmnd_chroot=");
user_ctx.runchroot = *cur + sizeof("cmnd_chroot=") - 1;
if (strlen(user_ctx.runchroot) >= PATH_MAX) {
runas_ctx.chroot = *cur + sizeof("cmnd_chroot=") - 1;
if (strlen(runas_ctx.chroot) >= PATH_MAX) {
sudo_warnx(U_("path name for \"%s\" too long"), "cmnd_chroot");
goto bad;
}
@@ -209,8 +209,8 @@ sudoers_policy_deserialize_info(void *v, struct defaults_list *defaults)
}
if (MATCHES(*cur, "cmnd_cwd=")) {
CHECK(*cur, "cmnd_cwd=");
user_ctx.runcwd = *cur + sizeof("cmnd_cwd=") - 1;
if (strlen(user_ctx.runcwd) >= PATH_MAX) {
runas_ctx.cwd = *cur + sizeof("cmnd_cwd=") - 1;
if (strlen(runas_ctx.cwd) >= PATH_MAX) {
sudo_warnx(U_("path name for \"%s\" too long"), "cmnd_cwd");
goto bad;
}
@@ -218,13 +218,13 @@ sudoers_policy_deserialize_info(void *v, struct defaults_list *defaults)
}
if (MATCHES(*cur, "runas_user=")) {
CHECK(*cur, "runas_user=");
user_ctx.runas_user = *cur + sizeof("runas_user=") - 1;
runas_ctx.user = *cur + sizeof("runas_user=") - 1;
SET(user_ctx.flags, RUNAS_USER_SPECIFIED);
continue;
}
if (MATCHES(*cur, "runas_group=")) {
CHECK(*cur, "runas_group=");
user_ctx.runas_group = *cur + sizeof("runas_group=") - 1;
runas_ctx.group = *cur + sizeof("runas_group=") - 1;
SET(user_ctx.flags, RUNAS_GROUP_SPECIFIED);
continue;
}
@@ -297,7 +297,7 @@ sudoers_policy_deserialize_info(void *v, struct defaults_list *defaults)
}
if (MATCHES(*cur, "login_class=")) {
CHECK(*cur, "login_class=");
user_ctx.class = *cur + sizeof("login_class=") - 1;
runas_ctx.class = *cur + sizeof("login_class=") - 1;
if (!append_default("use_loginclass", NULL, true, NULL, defaults))
goto oom;
continue;
@@ -317,17 +317,17 @@ sudoers_policy_deserialize_info(void *v, struct defaults_list *defaults)
#ifdef HAVE_SELINUX
if (MATCHES(*cur, "selinux_role=")) {
CHECK(*cur, "selinux_role=");
free(user_ctx.role);
user_ctx.role = strdup(*cur + sizeof("selinux_role=") - 1);
if (user_ctx.role == NULL)
free(runas_ctx.role);
runas_ctx.role = strdup(*cur + sizeof("selinux_role=") - 1);
if (runas_ctx.role == NULL)
goto oom;
continue;
}
if (MATCHES(*cur, "selinux_type=")) {
CHECK(*cur, "selinux_type=");
free(user_ctx.type);
user_ctx.type = strdup(*cur + sizeof("selinux_type=") - 1);
if (user_ctx.type == NULL)
free(runas_ctx.type);
runas_ctx.type = strdup(*cur + sizeof("selinux_type=") - 1);
if (runas_ctx.type == NULL)
goto oom;
continue;
}
@@ -335,9 +335,9 @@ sudoers_policy_deserialize_info(void *v, struct defaults_list *defaults)
#ifdef HAVE_APPARMOR
if (MATCHES(*cur, "apparmor_profile=")) {
CHECK(*cur, "apparmor_profile=");
free(user_ctx.apparmor_profile);
user_ctx.apparmor_profile = strdup(*cur + sizeof("apparmor_profile=") - 1);
if (user_ctx.apparmor_profile == NULL)
free(runas_ctx.apparmor_profile);
runas_ctx.apparmor_profile = strdup(*cur + sizeof("apparmor_profile=") - 1);
if (runas_ctx.apparmor_profile == NULL)
goto oom;
continue;
}
@@ -537,17 +537,17 @@ sudoers_policy_deserialize_info(void *v, struct defaults_list *defaults)
goto bad;
}
if (user_ctx.srunhost != user_ctx.runhost)
free(user_ctx.srunhost);
free(user_ctx.runhost);
if ((user_ctx.runhost = strdup(remhost ? remhost : user_ctx.host)) == NULL)
if (runas_ctx.shost != runas_ctx.host)
free(runas_ctx.shost);
free(runas_ctx.host);
if ((runas_ctx.host = strdup(remhost ? remhost : user_ctx.host)) == NULL)
goto oom;
if ((p = strchr(user_ctx.runhost, '.')) != NULL) {
user_ctx.srunhost = strndup(user_ctx.runhost, (size_t)(p - user_ctx.runhost));
if (user_ctx.srunhost == NULL)
if ((p = strchr(runas_ctx.host, '.')) != NULL) {
runas_ctx.shost = strndup(runas_ctx.host, (size_t)(p - runas_ctx.host));
if (runas_ctx.shost == NULL)
goto oom;
} else {
user_ctx.srunhost = user_ctx.runhost;
runas_ctx.shost = runas_ctx.host;
}
if (user_ctx.cwd == NULL) {
if ((user_ctx.cwd = strdup("unknown")) == NULL)
@@ -577,7 +577,7 @@ sudoers_policy_deserialize_info(void *v, struct defaults_list *defaults)
def_env_reset = true;
/* Some systems support fexecve() which we use for digest matches. */
user_ctx.execfd = -1;
runas_ctx.execfd = -1;
/* Create a UUID to store in the event log. */
sudo_uuid_create(uuid);
@@ -672,8 +672,8 @@ sudoers_policy_store_result(bool accepted, char *argv[], char *envp[],
if (command_info == NULL)
goto oom;
if (user_ctx.cmnd_safe != NULL) {
command_info[info_len] = sudo_new_key_val("command", user_ctx.cmnd_safe);
if (runas_ctx.cmnd != NULL) {
command_info[info_len] = sudo_new_key_val("command", runas_ctx.cmnd);
if (command_info[info_len++] == NULL)
goto oom;
}
@@ -746,7 +746,7 @@ sudoers_policy_store_result(bool accepted, char *argv[], char *envp[],
}
if (def_runcwd && strcmp(def_runcwd, "*") != 0) {
/* Set cwd to explicit value (sudoers or user-specified). */
if (!expand_tilde(&def_runcwd, user_ctx.runas_pw->pw_name)) {
if (!expand_tilde(&def_runcwd, runas_ctx.pw->pw_name)) {
sudo_warnx(U_("invalid working directory: %s"), def_runcwd);
goto bad;
}
@@ -754,15 +754,15 @@ sudoers_policy_store_result(bool accepted, char *argv[], char *envp[],
goto oom;
} else if (ISSET(sudo_mode, MODE_LOGIN_SHELL)) {
/* Set cwd to run user's homedir. */
if ((command_info[info_len++] = sudo_new_key_val("cwd", user_ctx.runas_pw->pw_dir)) == NULL)
if ((command_info[info_len++] = sudo_new_key_val("cwd", runas_ctx.pw->pw_dir)) == NULL)
goto oom;
if ((command_info[info_len++] = strdup("cwd_optional=true")) == NULL)
goto oom;
}
if ((command_info[info_len++] = sudo_new_key_val("runas_user", user_ctx.runas_pw->pw_name)) == NULL)
if ((command_info[info_len++] = sudo_new_key_val("runas_user", runas_ctx.pw->pw_name)) == NULL)
goto oom;
if (user_ctx.runas_gr != NULL) {
if ((command_info[info_len++] = sudo_new_key_val("runas_group", user_ctx.runas_gr->gr_name)) == NULL)
if (runas_ctx.gr != NULL) {
if ((command_info[info_len++] = sudo_new_key_val("runas_group", runas_ctx.gr->gr_name)) == NULL)
goto oom;
}
if (def_stay_setuid) {
@@ -773,19 +773,19 @@ sudoers_policy_store_result(bool accepted, char *argv[], char *envp[],
(unsigned int)user_ctx.gid) == -1)
goto oom;
if (asprintf(&command_info[info_len++], "runas_euid=%u",
(unsigned int)user_ctx.runas_pw->pw_uid) == -1)
(unsigned int)runas_ctx.pw->pw_uid) == -1)
goto oom;
if (asprintf(&command_info[info_len++], "runas_egid=%u",
user_ctx.runas_gr ? (unsigned int)user_ctx.runas_gr->gr_gid :
(unsigned int)user_ctx.runas_pw->pw_gid) == -1)
runas_ctx.gr ? (unsigned int)runas_ctx.gr->gr_gid :
(unsigned int)runas_ctx.pw->pw_gid) == -1)
goto oom;
} else {
if (asprintf(&command_info[info_len++], "runas_uid=%u",
(unsigned int)user_ctx.runas_pw->pw_uid) == -1)
(unsigned int)runas_ctx.pw->pw_uid) == -1)
goto oom;
if (asprintf(&command_info[info_len++], "runas_gid=%u",
user_ctx.runas_gr ? (unsigned int)user_ctx.runas_gr->gr_gid :
(unsigned int)user_ctx.runas_pw->pw_gid) == -1)
runas_ctx.gr ? (unsigned int)runas_ctx.gr->gr_gid :
(unsigned int)runas_ctx.pw->pw_gid) == -1)
goto oom;
}
if (def_preserve_groups) {
@@ -799,7 +799,7 @@ sudoers_policy_store_result(bool accepted, char *argv[], char *envp[],
struct gid_list *gidlist;
/* Only use results from a group db query, not the front end. */
gidlist = sudo_get_gidlist(user_ctx.runas_pw, ENTRY_TYPE_QUERIED);
gidlist = sudo_get_gidlist(runas_ctx.pw, ENTRY_TYPE_QUERIED);
/* We reserve an extra spot in the list for the effective gid. */
glsize = sizeof("runas_groups=") - 1 +
@@ -814,8 +814,8 @@ sudoers_policy_store_result(bool accepted, char *argv[], char *envp[],
glsize -= (size_t)(cp - gid_list);
/* On BSD systems the effective gid is the first group in the list. */
egid = user_ctx.runas_gr ? (unsigned int)user_ctx.runas_gr->gr_gid :
(unsigned int)user_ctx.runas_pw->pw_gid;
egid = runas_ctx.gr ? (unsigned int)runas_ctx.gr->gr_gid :
(unsigned int)runas_ctx.pw->pw_gid;
len = snprintf(cp, glsize, "%u", (unsigned int)egid);
if (len < 0 || (size_t)len >= glsize) {
sudo_warnx(U_("internal error, %s overflow"), __func__);
@@ -879,7 +879,7 @@ sudoers_policy_store_result(bool accepted, char *argv[], char *envp[],
goto oom;
}
if (def_utmp_runas) {
if ((command_info[info_len++] = sudo_new_key_val("utmp_user", user_ctx.runas_pw->pw_name)) == NULL)
if ((command_info[info_len++] = sudo_new_key_val("utmp_user", runas_ctx.pw->pw_name)) == NULL)
goto oom;
}
if (def_iolog_mode != (S_IRUSR|S_IWUSR)) {
@@ -933,7 +933,7 @@ sudoers_policy_store_result(bool accepted, char *argv[], char *envp[],
goto oom;
}
if (def_runchroot != NULL && strcmp(def_runchroot, "*") != 0) {
if (!expand_tilde(&def_runchroot, user_ctx.runas_pw->pw_name)) {
if (!expand_tilde(&def_runchroot, runas_ctx.pw->pw_name)) {
sudo_warnx(U_("invalid chroot directory: %s"), def_runchroot);
goto bad;
}
@@ -948,13 +948,13 @@ sudoers_policy_store_result(bool accepted, char *argv[], char *envp[],
if ((command_info[info_len++] = strdup("umask_override=true")) == NULL)
goto oom;
}
if (user_ctx.execfd != -1) {
if (runas_ctx.execfd != -1) {
if (sudo_version < SUDO_API_MKVERSION(1, 9)) {
/* execfd only supported by plugin API 1.9 and higher */
close(user_ctx.execfd);
user_ctx.execfd = -1;
close(runas_ctx.execfd);
runas_ctx.execfd = -1;
} else {
if (asprintf(&command_info[info_len++], "execfd=%d", user_ctx.execfd) == -1)
if (asprintf(&command_info[info_len++], "execfd=%d", runas_ctx.execfd) == -1)
goto oom;
}
}
@@ -1009,33 +1009,33 @@ sudoers_policy_store_result(bool accepted, char *argv[], char *envp[],
}
#ifdef HAVE_LOGIN_CAP_H
if (def_use_loginclass) {
if ((command_info[info_len++] = sudo_new_key_val("login_class", user_ctx.class)) == NULL)
if ((command_info[info_len++] = sudo_new_key_val("login_class", runas_ctx.class)) == NULL)
goto oom;
}
#endif /* HAVE_LOGIN_CAP_H */
#ifdef HAVE_SELINUX
if (def_selinux && user_ctx.role != NULL) {
if ((command_info[info_len++] = sudo_new_key_val("selinux_role", user_ctx.role)) == NULL)
if (def_selinux && runas_ctx.role != NULL) {
if ((command_info[info_len++] = sudo_new_key_val("selinux_role", runas_ctx.role)) == NULL)
goto oom;
}
if (def_selinux && user_ctx.type != NULL) {
if ((command_info[info_len++] = sudo_new_key_val("selinux_type", user_ctx.type)) == NULL)
if (def_selinux && runas_ctx.type != NULL) {
if ((command_info[info_len++] = sudo_new_key_val("selinux_type", runas_ctx.type)) == NULL)
goto oom;
}
#endif /* HAVE_SELINUX */
#ifdef HAVE_APPARMOR
if (user_ctx.apparmor_profile != NULL) {
if ((command_info[info_len++] = sudo_new_key_val("apparmor_profile", user_ctx.apparmor_profile)) == NULL)
if (runas_ctx.apparmor_profile != NULL) {
if ((command_info[info_len++] = sudo_new_key_val("apparmor_profile", runas_ctx.apparmor_profile)) == NULL)
goto oom;
}
#endif /* HAVE_APPARMOR */
#ifdef HAVE_PRIV_SET
if (user_ctx.privs != NULL) {
if ((command_info[info_len++] = sudo_new_key_val("privs", user_ctx.privs)) == NULL)
if (runas_ctx.privs != NULL) {
if ((command_info[info_len++] = sudo_new_key_val("privs", runas_ctx.privs)) == NULL)
goto oom;
}
if (user_ctx.limitprivs != NULL) {
if ((command_info[info_len++] = sudo_new_key_val("limitprivs", user_ctx.limitprivs)) == NULL)
if (runas_ctx.limitprivs != NULL) {
if ((command_info[info_len++] = sudo_new_key_val("limitprivs", runas_ctx.limitprivs)) == NULL)
goto oom;
}
#endif /* HAVE_PRIV_SET */
@@ -1123,11 +1123,11 @@ sudoers_policy_close(int exit_status, int error_code)
if (session_opened) {
/* Close the session we opened in sudoers_policy_init_session(). */
(void)sudo_auth_end_session(user_ctx.runas_pw);
(void)sudo_auth_end_session(runas_ctx.pw);
if (error_code) {
errno = error_code;
sudo_warn(U_("unable to execute %s"), user_ctx.cmnd_safe);
sudo_warn(U_("unable to execute %s"), runas_ctx.cmnd);
} else {
log_exit_status(exit_status);
}

View File

@@ -75,7 +75,7 @@ expand_prompt(const char *old_prompt, const char *auth_user)
break;
case 'U':
p++;
len += strlen(user_ctx.runas_pw->pw_name) - 2;
len += strlen(runas_ctx.pw->pw_name) - 2;
subst = 1;
break;
case '%':
@@ -132,7 +132,7 @@ expand_prompt(const char *old_prompt, const char *auth_user)
continue;
case 'U':
p++;
n = strlcpy(np, user_ctx.runas_pw->pw_name, len);
n = strlcpy(np, runas_ctx.pw->pw_name, len);
if (n >= len)
goto oflow;
np += n;

View File

@@ -32,6 +32,7 @@
#include <def_data.c>
struct sudoers_user_context user_ctx;
struct sudoers_runas_context runas_ctx;
struct test_data {
const char *input;

View File

@@ -50,6 +50,7 @@ static const char *orig_cmnd;
/* Required to link with parser. */
struct sudoers_user_context user_ctx;
struct sudoers_runas_context runas_ctx;
struct passwd *list_pw;
sudo_conv_t sudo_conv = fuzz_conversation;
sudo_printf_t sudo_printf = fuzz_printf;
@@ -285,7 +286,7 @@ LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
sudo_pw_delref(pw);
/* The minimum needed to perform matching (cmnd must be dynamic). */
user_ctx.host = user_ctx.shost = user_ctx.runhost = user_ctx.srunhost =
user_ctx.host = user_ctx.shost = runas_ctx.host = runas_ctx.shost =
(char *)"localhost";
orig_cmnd = (char *)"/usr/bin/id";
user_ctx.cmnd = strdup(orig_cmnd);
@@ -336,38 +337,38 @@ LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
}
/* Run user. */
if (user_ctx.runas_pw != NULL)
sudo_pw_delref(user_ctx.runas_pw);
if (runas_ctx.pw != NULL)
sudo_pw_delref(runas_ctx.pw);
if (ud->runuser != NULL) {
user_ctx.runas_user = (char *)ud->runuser;
runas_ctx.user = (char *)ud->runuser;
SET(user_ctx.flags, RUNAS_USER_SPECIFIED);
user_ctx.runas_pw = sudo_getpwnam(user_ctx.runas_user);
runas_ctx.pw = sudo_getpwnam(runas_ctx.user);
} else {
user_ctx.runas_user = NULL;
runas_ctx.user = NULL;
CLR(user_ctx.flags, RUNAS_USER_SPECIFIED);
user_ctx.runas_pw = sudo_getpwnam("root");
runas_ctx.pw = sudo_getpwnam("root");
}
if (user_ctx.runas_pw == NULL) {
sudo_warnx_nodebug("unknown run user %s", user_ctx.runas_user);
if (runas_ctx.pw == NULL) {
sudo_warnx_nodebug("unknown run user %s", runas_ctx.user);
continue;
}
/* Run group. */
if (user_ctx.runas_gr != NULL)
sudo_gr_delref(user_ctx.runas_gr);
if (runas_ctx.gr != NULL)
sudo_gr_delref(runas_ctx.gr);
if (ud->rungroup != NULL) {
user_ctx.runas_group = (char *)ud->rungroup;
runas_ctx.group = (char *)ud->rungroup;
SET(user_ctx.flags, RUNAS_GROUP_SPECIFIED);
user_ctx.runas_gr = sudo_getgrnam(user_ctx.runas_group);
if (user_ctx.runas_gr == NULL) {
runas_ctx.gr = sudo_getgrnam(runas_ctx.group);
if (runas_ctx.gr == NULL) {
sudo_warnx_nodebug("unknown run group %s",
user_ctx.runas_group);
runas_ctx.group);
continue;
}
} else {
user_ctx.runas_group = NULL;
runas_ctx.group = NULL;
CLR(user_ctx.flags, RUNAS_GROUP_SPECIFIED);
user_ctx.runas_gr = NULL;
runas_ctx.gr = NULL;
}
update_defaults(&parse_tree, NULL, SETDEF_ALL, false);
@@ -385,12 +386,12 @@ LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
}
/* Expand tildes in runcwd and runchroot. */
if (user_ctx.runas_pw != NULL) {
if (runas_ctx.pw != NULL) {
if (def_runcwd != NULL && strcmp(def_runcwd, "*") != 0) {
expand_tilde(&def_runcwd, user_ctx.runas_pw->pw_name);
expand_tilde(&def_runcwd, runas_ctx.pw->pw_name);
}
if (def_runchroot != NULL && strcmp(def_runchroot, "*") != 0) {
expand_tilde(&def_runchroot, user_ctx.runas_pw->pw_name);
expand_tilde(&def_runchroot, runas_ctx.pw->pw_name);
}
}
@@ -406,16 +407,17 @@ done:
reset_parser();
if (user_ctx.pw != NULL)
sudo_pw_delref(user_ctx.pw);
if (user_ctx.runas_pw != NULL)
sudo_pw_delref(user_ctx.runas_pw);
if (user_ctx.runas_gr != NULL)
sudo_gr_delref(user_ctx.runas_gr);
if (runas_ctx.pw != NULL)
sudo_pw_delref(runas_ctx.pw);
if (runas_ctx.gr != NULL)
sudo_gr_delref(runas_ctx.gr);
sudo_freepwcache();
sudo_freegrcache();
free(user_ctx.cmnd);
free(user_ctx.cmnd_safe);
free(runas_ctx.cmnd);
free(user_ctx.cmnd_list);
memset(&user_ctx, 0, sizeof(user_ctx));
memset(&runas_ctx, 0, sizeof(runas_ctx));
sudoers_setlocale(SUDOERS_LOCALE_USER, NULL);
sudoers_debug_deregister();
fflush(stdout);

View File

@@ -33,6 +33,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
/* Required to link with parser. */
struct sudoers_user_context user_ctx;
struct sudoers_runas_context runas_ctx;
struct passwd *list_pw;
sudo_printf_t sudo_printf = fuzz_printf;

View File

@@ -37,6 +37,7 @@
extern struct io_plugin sudoers_io;
struct sudoers_user_context user_ctx;
struct sudoers_runas_context runas_ctx;
struct passwd *list_pw;
sudo_printf_t sudo_printf;
sudo_conv_t sudo_conv;
@@ -248,9 +249,9 @@ test_endpoints(int *ntests, int *nerrors, const char *iolog_dir, char *envp[])
/* Set runas uid/gid to root. */
snprintf(runas_uid, sizeof(runas_uid), "runas_uid=%u",
(unsigned int)user_ctx.runas_pw->pw_uid);
(unsigned int)runas_ctx.pw->pw_uid);
snprintf(runas_gid, sizeof(runas_gid), "runas_gid=%u",
(unsigned int)user_ctx.runas_pw->pw_gid);
(unsigned int)runas_ctx.pw->pw_gid);
/* Set path to the iolog directory the user passed in. */
snprintf(iolog_path, sizeof(iolog_path), "iolog_path=%s", iolog_dir);
@@ -385,7 +386,7 @@ main(int argc, char *argv[], char *envp[])
if ((tpw = getpwnam("root")) == NULL)
sudo_fatalx("unable to look up uid 0 or root");
}
user_ctx.runas_pw = pw_dup(tpw);
runas_ctx.pw = pw_dup(tpw);
/* Set invoking user. */
if ((tpw = getpwuid(geteuid())) == NULL)

View File

@@ -271,7 +271,7 @@ set_perms(int perm)
case PERM_RUNAS:
state->rgid = ostate->rgid;
state->egid = user_ctx.runas_gr ? user_ctx.runas_gr->gr_gid : user_ctx.runas_pw->pw_gid;
state->egid = runas_ctx.gr ? runas_ctx.gr->gr_gid : runas_ctx.pw->pw_gid;
state->sgid = ostate->sgid;
sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_RUNAS: gid: "
"[%d, %d, %d] -> [%d, %d, %d]", __func__,
@@ -287,7 +287,7 @@ set_perms(int perm)
goto bad;
}
state->ruid = ostate->ruid;
state->euid = user_ctx.runas_pw ? user_ctx.runas_pw->pw_uid : user_ctx.uid;
state->euid = runas_ctx.pw ? runas_ctx.pw->pw_uid : user_ctx.uid;
state->suid = ostate->suid;
sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_RUNAS: uid: "
"[%d, %d, %d] -> [%d, %d, %d]", __func__,
@@ -600,7 +600,7 @@ set_perms(int perm)
case PERM_RUNAS:
state->rgid = ostate->rgid;
state->egid = user_ctx.runas_gr ? user_ctx.runas_gr->gr_gid : user_ctx.runas_pw->pw_gid;
state->egid = runas_ctx.gr ? runas_ctx.gr->gr_gid : runas_ctx.pw->pw_gid;
state->sgid = ostate->sgid;
sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_RUNAS: gid: "
"[%d, %d, %d] -> [%d, %d, %d]", __func__,
@@ -616,7 +616,7 @@ set_perms(int perm)
goto bad;
}
state->ruid = ostate->ruid;
state->euid = user_ctx.runas_pw ? user_ctx.runas_pw->pw_uid : user_ctx.uid;
state->euid = runas_ctx.pw ? runas_ctx.pw->pw_uid : user_ctx.uid;
state->suid = ostate->suid;
sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_RUNAS: uid: "
"[%d, %d, %d] -> [%d, %d, %d]", __func__,
@@ -1002,7 +1002,7 @@ set_perms(int perm)
case PERM_RUNAS:
state->rgid = ostate->rgid;
state->egid = user_ctx.runas_gr ? user_ctx.runas_gr->gr_gid : user_ctx.runas_pw->pw_gid;
state->egid = runas_ctx.gr ? runas_ctx.gr->gr_gid : runas_ctx.pw->pw_gid;
sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_RUNAS: gid: "
"[%d, %d] -> [%d, %d]", __func__, (int)ostate->rgid,
(int)ostate->egid, (int)state->rgid, (int)state->egid);
@@ -1016,7 +1016,7 @@ set_perms(int perm)
goto bad;
}
state->ruid = ROOT_UID;
state->euid = user_ctx.runas_pw ? user_ctx.runas_pw->pw_uid : user_ctx.uid;
state->euid = runas_ctx.pw ? runas_ctx.pw->pw_uid : user_ctx.uid;
sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_RUNAS: uid: "
"[%d, %d] -> [%d, %d]", __func__, (int)ostate->ruid,
(int)ostate->euid, (int)state->ruid, (int)state->euid);
@@ -1316,7 +1316,7 @@ set_perms(int perm)
case PERM_RUNAS:
state->rgid = ostate->rgid;
state->egid = user_ctx.runas_gr ? user_ctx.runas_gr->gr_gid : user_ctx.runas_pw->pw_gid;
state->egid = runas_ctx.gr ? runas_ctx.gr->gr_gid : runas_ctx.pw->pw_gid;
sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_RUNAS: gid: "
"[%d, %d] -> [%d, %d]", __func__, (int)ostate->rgid,
(int)ostate->egid, (int)state->rgid, (int)state->egid);
@@ -1330,7 +1330,7 @@ set_perms(int perm)
goto bad;
}
state->ruid = ostate->ruid;
state->euid = user_ctx.runas_pw ? user_ctx.runas_pw->pw_uid : user_ctx.uid;
state->euid = runas_ctx.pw ? runas_ctx.pw->pw_uid : user_ctx.uid;
sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_RUNAS: uid: "
"[%d, %d] -> [%d, %d]", __func__, (int)ostate->ruid,
(int)ostate->euid, (int)state->ruid, (int)state->euid);

View File

@@ -165,8 +165,8 @@ get_ipa_hostname(char **shostp, char **lhostp)
static bool
sudo_sss_check_user(struct sudo_sss_handle *handle, struct sss_sudo_rule *rule)
{
const char *host = handle->ipa_host ? handle->ipa_host : user_ctx.runhost;
const char *shost = handle->ipa_shost ? handle->ipa_shost : user_ctx.srunhost;
const char *host = handle->ipa_host ? handle->ipa_host : runas_ctx.host;
const char *shost = handle->ipa_shost ? handle->ipa_shost : runas_ctx.shost;
char **val_array;
int i, rc, ret = false;
debug_decl(sudo_sss_check_user, SUDOERS_DEBUG_SSSD);
@@ -628,10 +628,10 @@ sudo_sss_open(struct sudo_nss *nss)
}
/*
* If runhost is the same as the local host, check for ipa_hostname
* in sssd.conf and use it in preference to user_ctx.runhost.
* If the runas host matches the local host, check for ipa_hostname
* in sssd.conf and use it in preference to runas_ctx.host.
*/
if (strcasecmp(user_ctx.runhost, user_ctx.host) == 0) {
if (strcasecmp(runas_ctx.host, user_ctx.host) == 0) {
if (get_ipa_hostname(&handle->ipa_shost, &handle->ipa_host) == -1) {
free(handle);
debug_return_int(ENOMEM);
@@ -681,7 +681,7 @@ sudo_sss_query(const struct sudo_nss *nss, struct passwd *pw)
sudo_debug_printf(SUDO_DEBUG_DIAG,
"searching SSSD/LDAP for sudoers entries for user %s, host %s",
pw->pw_name, user_ctx.runhost);
pw->pw_name, runas_ctx.host);
/* Stash a ref to the passwd struct in the handle. */
sudo_pw_addref(pw);

View File

@@ -133,8 +133,8 @@ get_hostname(void)
if (user_ctx.host == NULL)
sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
}
user_ctx.runhost = user_ctx.host;
user_ctx.srunhost = user_ctx.shost;
runas_ctx.host = user_ctx.host;
runas_ctx.shost = user_ctx.shost;
debug_return;
}

View File

@@ -80,6 +80,7 @@ static bool tty_present(void);
* Globals
*/
struct sudoers_user_context user_ctx;
struct sudoers_runas_context runas_ctx;
struct passwd *list_pw;
unsigned int sudo_mode;
@@ -268,7 +269,7 @@ sudoers_init(void *info, sudoers_logger_t logger, char * const envp[])
}
/* Set login class if applicable (after sudoers is parsed). */
if (set_loginclass(user_ctx.runas_pw ? user_ctx.runas_pw : user_ctx.pw))
if (set_loginclass(runas_ctx.pw ? runas_ctx.pw : user_ctx.pw))
ret = true;
cleanup:
@@ -412,8 +413,8 @@ sudoers_check_common(int pwflag)
}
}
if (user_ctx.cmnd_safe == NULL) {
if ((user_ctx.cmnd_safe = strdup(user_ctx.cmnd)) == NULL) {
if (runas_ctx.cmnd == NULL) {
if ((runas_ctx.cmnd = strdup(user_ctx.cmnd)) == NULL) {
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
goto done;
}
@@ -422,13 +423,13 @@ sudoers_check_common(int pwflag)
/* Defer uid/gid checks until after defaults have been updated. */
if (unknown_runas_uid && !def_runas_allow_unknown_id) {
log_warningx(SLOG_AUDIT, N_("unknown user %s"),
user_ctx.runas_pw->pw_name);
runas_ctx.pw->pw_name);
goto done;
}
if (user_ctx.runas_gr != NULL) {
if (runas_ctx.gr != NULL) {
if (unknown_runas_gid && !def_runas_allow_unknown_id) {
log_warningx(SLOG_AUDIT, N_("unknown group %s"),
user_ctx.runas_gr->gr_name);
runas_ctx.gr->gr_name);
goto done;
}
}
@@ -449,10 +450,10 @@ sudoers_check_common(int pwflag)
/* Check runas user's shell if running (or checking) a command. */
if (ISSET(sudo_mode, MODE_RUN|MODE_CHECK)) {
if (!check_user_shell(user_ctx.runas_pw)) {
if (!check_user_shell(runas_ctx.pw)) {
log_warningx(SLOG_RAW_MSG|SLOG_AUDIT,
N_("invalid shell for user %s: %s"),
user_ctx.runas_pw->pw_name, user_ctx.runas_pw->pw_shell);
runas_ctx.pw->pw_name, runas_ctx.pw->pw_shell);
goto bad;
}
}
@@ -487,14 +488,14 @@ sudoers_check_common(int pwflag)
goto done;
}
/* Check whether user_ctx.runchroot is permitted (if specified). */
/* Check whether runas_ctx.chroot is permitted (if specified). */
switch (check_user_runchroot()) {
case true:
break;
case false:
log_warningx(SLOG_NO_STDERR|SLOG_AUDIT,
N_("user not allowed to change root directory to %s"),
user_ctx.runchroot);
runas_ctx.chroot);
sudo_warnx(U_("you are not permitted to use the -R option with %s"),
user_ctx.cmnd);
goto bad;
@@ -502,13 +503,13 @@ sudoers_check_common(int pwflag)
goto done;
}
/* Check whether user_ctx.runcwd is permitted (if specified). */
/* Check whether runas_ctx.cwd is permitted (if specified). */
switch (check_user_runcwd()) {
case true:
break;
case false:
log_warningx(SLOG_NO_STDERR|SLOG_AUDIT,
N_("user not allowed to change directory to %s"), user_ctx.runcwd);
N_("user not allowed to change directory to %s"), runas_ctx.cwd);
sudo_warnx(U_("you are not permitted to use the -D option with %s"),
user_ctx.cmnd);
goto bad;
@@ -663,8 +664,8 @@ sudoers_check_cmnd(int argc, char * const argv[], char *env_add[],
memcpy(NewArgv, argv, (size_t)argc * sizeof(char *));
NewArgc = argc;
NewArgv[NewArgc] = NULL;
if (ISSET(sudo_mode, MODE_LOGIN_SHELL) && user_ctx.runas_pw != NULL) {
NewArgv[0] = strdup(user_ctx.runas_pw->pw_shell);
if (ISSET(sudo_mode, MODE_LOGIN_SHELL) && runas_ctx.pw != NULL) {
NewArgv[0] = strdup(runas_ctx.pw->pw_shell);
if (NewArgv[0] == NULL) {
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
goto error;
@@ -734,10 +735,10 @@ sudoers_check_cmnd(int argc, char * const argv[], char *env_add[],
#endif
#ifdef HAVE_LOGIN_CAP_H
/* Set environment based on login class. */
if (user_ctx.class) {
login_cap_t *lc = login_getclass(user_ctx.class);
if (runas_ctx.class) {
login_cap_t *lc = login_getclass(runas_ctx.class);
if (lc != NULL) {
setusercontext(lc, user_ctx.runas_pw, user_ctx.runas_pw->pw_uid,
setusercontext(lc, runas_ctx.pw, runas_ctx.pw->pw_uid,
LOGIN_SETPATH|LOGIN_SETENV);
login_close(lc);
}
@@ -769,10 +770,10 @@ sudoers_check_cmnd(int argc, char * const argv[], char *env_add[],
int edit_argc;
sudoedit_nfiles = NewArgc - 1;
free(user_ctx.cmnd_safe);
user_ctx.cmnd_safe = find_editor(sudoedit_nfiles, NewArgv + 1,
free(runas_ctx.cmnd);
runas_ctx.cmnd = find_editor(sudoedit_nfiles, NewArgv + 1,
&edit_argc, &edit_argv, NULL, &env_editor);
if (user_ctx.cmnd_safe == NULL) {
if (runas_ctx.cmnd == NULL) {
switch (errno) {
case ENOENT:
audit_failure(NewArgv, N_("%s: command not found"),
@@ -806,7 +807,7 @@ sudoers_check_cmnd(int argc, char * const argv[], char *env_add[],
/* Save the initial command and argv so we have it for exit logging. */
if (user_ctx.cmnd_saved == NULL) {
user_ctx.cmnd_saved = strdup(user_ctx.cmnd_safe);
user_ctx.cmnd_saved = strdup(runas_ctx.cmnd);
if (user_ctx.cmnd_saved == NULL) {
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
goto error;
@@ -1056,15 +1057,15 @@ init_vars(char * const envp[])
* Note that if runas_group was specified without runas_user we
* run the command as the invoking user.
*/
if (user_ctx.runas_group != NULL) {
if (!set_runasgr(user_ctx.runas_group, false))
if (runas_ctx.group != NULL) {
if (!set_runasgr(runas_ctx.group, false))
debug_return_bool(false);
if (!set_runaspw(user_ctx.runas_user ?
user_ctx.runas_user : user_ctx.name, false))
if (!set_runaspw(runas_ctx.user ?
runas_ctx.user : user_ctx.name, false))
debug_return_bool(false);
} else {
if (!set_runaspw(user_ctx.runas_user ?
user_ctx.runas_user : def_runas_default, false))
if (!set_runaspw(runas_ctx.user ?
runas_ctx.user : def_runas_default, false))
debug_return_bool(false);
}
@@ -1175,12 +1176,12 @@ set_cmnd(void)
}
/* Re-initialize for when we are called multiple times. */
free(user_ctx.cmnd_safe);
user_ctx.cmnd_safe = NULL;
free(runas_ctx.cmnd);
runas_ctx.cmnd = NULL;
if (ISSET(sudo_mode, MODE_RUN|MODE_EDIT|MODE_CHECK)) {
if (!ISSET(sudo_mode, MODE_EDIT)) {
const char *runchroot = user_ctx.runchroot;
const char *runchroot = runas_ctx.chroot;
if (runchroot == NULL && def_runchroot != NULL &&
strcmp(def_runchroot, "*") != 0)
runchroot = def_runchroot;
@@ -1371,30 +1372,30 @@ set_loginclass(struct passwd *pw)
if (!def_use_loginclass)
goto done;
if (user_ctx.class && strcmp(user_ctx.class, "-") != 0) {
if (runas_ctx.class && strcmp(runas_ctx.class, "-") != 0) {
if (user_ctx.uid != 0 && pw->pw_uid != 0) {
sudo_warnx(U_("only root can use \"-c %s\""), user_ctx.class);
sudo_warnx(U_("only root can use \"-c %s\""), runas_ctx.class);
ret = false;
goto done;
}
} else {
user_ctx.class = pw->pw_class;
if (!user_ctx.class || !*user_ctx.class)
user_ctx.class = (char *)
runas_ctx.class = pw->pw_class;
if (!runas_ctx.class || !*runas_ctx.class)
runas_ctx.class = (char *)
((pw->pw_uid == 0) ? LOGIN_DEFROOTCLASS : LOGIN_DEFCLASS);
}
/* Make sure specified login class is valid. */
lc = login_getclass(user_ctx.class);
if (!lc || !lc->lc_class || strcmp(lc->lc_class, user_ctx.class) != 0) {
lc = login_getclass(runas_ctx.class);
if (!lc || !lc->lc_class || strcmp(lc->lc_class, runas_ctx.class) != 0) {
/*
* Don't make it an error if the user didn't specify the login
* class themselves. We do this because if login.conf gets
* corrupted we want the admin to be able to use sudo to fix it.
*/
log_warningx(errflags, N_("unknown login class %s"), user_ctx.class);
log_warningx(errflags, N_("unknown login class %s"), runas_ctx.class);
def_use_loginclass = false;
if (user_ctx.class)
if (runas_ctx.class)
ret = false;
}
login_close(lc);
@@ -1411,7 +1412,7 @@ set_loginclass(struct passwd *pw)
/*
* Get passwd entry for the user we are going to run commands as
* and store it in user_ctx.runas_pw. By default, commands run as "root".
* and store it in runas_ctx.pw. By default, commands run as "root".
*/
static bool
set_runaspw(const char *user, bool quiet)
@@ -1437,15 +1438,15 @@ set_runaspw(const char *user, bool quiet)
debug_return_bool(false);
}
}
if (user_ctx.runas_pw != NULL)
sudo_pw_delref(user_ctx.runas_pw);
user_ctx.runas_pw = pw;
if (runas_ctx.pw != NULL)
sudo_pw_delref(runas_ctx.pw);
runas_ctx.pw = pw;
debug_return_bool(true);
}
/*
* Get group entry for the group we are going to run commands as
* and store it in user_ctx.runas_gr.
* and store it in runas_ctx.gr.
*/
static bool
set_runasgr(const char *group, bool quiet)
@@ -1471,9 +1472,9 @@ set_runasgr(const char *group, bool quiet)
debug_return_bool(false);
}
}
if (user_ctx.runas_gr != NULL)
sudo_gr_delref(user_ctx.runas_gr);
user_ctx.runas_gr = gr;
if (runas_ctx.gr != NULL)
sudo_gr_delref(runas_ctx.gr);
runas_ctx.gr = gr;
debug_return_bool(true);
}
@@ -1487,7 +1488,7 @@ cb_runas_default(const char *file, int line, int column,
debug_decl(cb_runas_default, SUDOERS_DEBUG_PLUGIN);
/* Only reset runaspw if user didn't specify one. */
if (user_ctx.runas_user == NULL && user_ctx.runas_group == NULL)
if (runas_ctx.user == NULL && runas_ctx.group == NULL)
debug_return_bool(set_runaspw(sd_un->str, true));
debug_return_bool(true);
}
@@ -1503,10 +1504,6 @@ sudoers_user_ctx_free(void)
/* Free remaining references to password and group entries. */
if (user_ctx.pw != NULL)
sudo_pw_delref(user_ctx.pw);
if (user_ctx.runas_pw != NULL)
sudo_pw_delref(user_ctx.runas_pw);
if (user_ctx.runas_gr != NULL)
sudo_gr_delref(user_ctx.runas_gr);
if (user_ctx.gid_list != NULL)
sudo_gidlist_delref(user_ctx.gid_list);
@@ -1521,29 +1518,49 @@ sudoers_user_ctx_free(void)
if (user_ctx.shost != user_ctx.host)
free(user_ctx.shost);
free(user_ctx.host);
if (user_ctx.srunhost != user_ctx.runhost)
free(user_ctx.srunhost);
free(user_ctx.runhost);
free(user_ctx.cmnd);
canon_path_free(user_ctx.cmnd_dir);
free(user_ctx.cmnd_args);
free(user_ctx.cmnd_list);
free(user_ctx.cmnd_safe);
free(user_ctx.cmnd_saved);
free(user_ctx.source);
free(user_ctx.cmnd_stat);
memset(&user_ctx, 0, sizeof(user_ctx));
debug_return;
}
/*
* Free memory allocated for struct sudoers_runas_context.
*/
static void
sudoers_runas_ctx_free(void)
{
debug_decl(sudoers_runas_ctx_free, SUDOERS_DEBUG_PLUGIN);
/* Free remaining references to password and group entries. */
if (runas_ctx.pw != NULL)
sudo_pw_delref(runas_ctx.pw);
if (runas_ctx.gr != NULL)
sudo_gr_delref(runas_ctx.gr);
/* Free dynamic contents of runas_ctx. */
free(runas_ctx.cmnd);
if (runas_ctx.shost != runas_ctx.host)
free(runas_ctx.shost);
free(runas_ctx.host);
#ifdef HAVE_SELINUX
free(user_ctx.role);
free(user_ctx.type);
free(runas_ctx.role);
free(runas_ctx.type);
#endif
#ifdef HAVE_APPARMOR
free(user_ctx.apparmor_profile);
free(runas_ctx.apparmor_profile);
#endif
#ifdef HAVE_PRIV_SET
free(user_ctx.privs);
free(user_ctx.limitprivs);
free(runas_ctx.privs);
free(runas_ctx.limitprivs);
#endif
memset(&user_ctx, 0, sizeof(user_ctx));
memset(&runas_ctx, 0, sizeof(runas_ctx));
debug_return;
}
@@ -1576,6 +1593,7 @@ sudoers_cleanup(void)
if (def_group_plugin)
group_plugin_unload();
sudoers_user_ctx_free();
sudoers_runas_ctx_free();
sudo_freepwcache();
sudo_freegrcache();
canon_path_free_cache();

View File

@@ -1,7 +1,7 @@
/*
* SPDX-License-Identifier: ISC
*
* Copyright (c) 1993-1996, 1998-2005, 2007-2022
* Copyright (c) 1993-1996, 1998-2005, 2007-2023
* Todd C. Miller <Todd.Miller@sudo.ws>
*
* Permission to use, copy, modify, and distribute this software for any
@@ -82,50 +82,28 @@ struct group_list {
struct sudoers_user_context {
struct timespec submit_time;
struct passwd *pw;
struct passwd *runas_pw;
struct group *runas_gr;
struct stat *cmnd_stat;
char *cwd;
char *name;
char *runas_user;
char *runas_group;
char *path;
char *tty;
char *ttypath;
char *host;
char *shost;
char *runhost;
char *srunhost;
char *runchroot;
char *runcwd;
char *prompt;
char *cmnd;
char *cmnd_args;
char *cmnd_base;
char *cmnd_dir;
char *cmnd_list;
char *cmnd_safe;
char *cmnd_saved;
char *class;
char *ccname;
char *source;
struct gid_list *gid_list;
char * const * env_vars;
#ifdef HAVE_SELINUX
char *role;
char *type;
#endif
#ifdef HAVE_APPARMOR
char *apparmor_profile;
#endif
#ifdef HAVE_PRIV_SET
char *privs;
char *limitprivs;
#endif
char *iolog_file;
char *iolog_path;
GETGROUPS_T *gids;
int execfd;
int ngids;
int closefrom;
int lines;
@@ -141,6 +119,31 @@ struct sudoers_user_context {
char uuid_str[37];
};
struct sudoers_runas_context {
struct passwd *pw;
struct group *gr;
char *chroot;
char *class;
char *cmnd;
char *cwd;
char *group;
char *host;
char *shost;
char *user;
#ifdef HAVE_SELINUX
char *role;
char *type;
#endif
#ifdef HAVE_APPARMOR
char *apparmor_profile;
#endif
#ifdef HAVE_PRIV_SET
char *privs;
char *limitprivs;
#endif
int execfd;
};
/*
* sudo_get_gidlist() type values
*/
@@ -376,6 +379,7 @@ int sudoers_validate_user(void);
void sudoers_cleanup(void);
bool sudoers_override_umask(void);
extern struct sudoers_user_context user_ctx;
extern struct sudoers_runas_context runas_ctx;
extern struct passwd *list_pw;
extern unsigned int sudo_mode;
extern int sudoedit_nfiles;

View File

@@ -80,6 +80,7 @@ static int testsudoers_query(const struct sudo_nss *nss, struct passwd *pw);
* Globals
*/
struct sudoers_user_context user_ctx;
struct sudoers_runas_context runas_ctx;
struct passwd *list_pw;
static const char *orig_cmnd;
static char *runas_group, *runas_user;
@@ -136,7 +137,7 @@ main(int argc, char *argv[])
while ((ch = getopt(argc, argv, "+D:dg:G:h:i:L:lP:p:R:T:tu:U:v")) != -1) {
switch (ch) {
case 'D':
user_ctx.runcwd = optarg;
runas_ctx.cwd = optarg;
break;
case 'd':
dflag = 1;
@@ -193,7 +194,7 @@ main(int argc, char *argv[])
sudo_fatalx("invalid time: %s", optarg);
break;
case 'R':
user_ctx.runchroot = optarg;
runas_ctx.chroot = optarg;
break;
case 't':
trace_print = testsudoers_error;
@@ -284,8 +285,8 @@ main(int argc, char *argv[])
} else {
user_ctx.shost = user_ctx.host;
}
user_ctx.runhost = user_ctx.host;
user_ctx.srunhost = user_ctx.shost;
runas_ctx.host = user_ctx.host;
runas_ctx.shost = user_ctx.shost;
/* Fill in user_ctx.cmnd_args from argv. */
if (argc > 0) {
@@ -385,21 +386,21 @@ main(int argc, char *argv[])
/* Validate user-specified chroot or cwd (if any) and runas user shell. */
if (ISSET(validated, VALIDATE_SUCCESS)) {
if (!check_user_shell(user_ctx.runas_pw)) {
if (!check_user_shell(runas_ctx.pw)) {
printf(U_("\nInvalid shell for user %s: %s\n"),
user_ctx.runas_pw->pw_name, user_ctx.runas_pw->pw_shell);
runas_ctx.pw->pw_name, runas_ctx.pw->pw_shell);
CLR(validated, VALIDATE_SUCCESS);
SET(validated, VALIDATE_FAILURE);
}
if (check_user_runchroot() != true) {
printf("\nUser %s is not allowed to change root directory to %s\n",
user_ctx.name, user_ctx.runchroot);
user_ctx.name, runas_ctx.chroot);
CLR(validated, VALIDATE_SUCCESS);
SET(validated, VALIDATE_FAILURE);
}
if (check_user_runcwd() != true) {
printf("\nUser %s is not allowed to change directory to %s\n",
user_ctx.name, user_ctx.runcwd);
user_ctx.name, runas_ctx.cwd);
CLR(validated, VALIDATE_SUCCESS);
SET(validated, VALIDATE_FAILURE);
}
@@ -454,9 +455,9 @@ set_runaspw(const char *user)
if ((pw = sudo_getpwnam(user)) == NULL)
sudo_fatalx(U_("unknown user %s"), user);
}
if (user_ctx.runas_pw != NULL)
sudo_pw_delref(user_ctx.runas_pw);
user_ctx.runas_pw = pw;
if (runas_ctx.pw != NULL)
sudo_pw_delref(runas_ctx.pw);
runas_ctx.pw = pw;
debug_return;
}
@@ -478,9 +479,9 @@ set_runasgr(const char *group)
if ((gr = sudo_getgrnam(group)) == NULL)
sudo_fatalx(U_("unknown group %s"), group);
}
if (user_ctx.runas_gr != NULL)
sudo_gr_delref(user_ctx.runas_gr);
user_ctx.runas_gr = gr;
if (runas_ctx.gr != NULL)
sudo_gr_delref(runas_ctx.gr);
runas_ctx.gr = gr;
debug_return;
}

View File

@@ -109,6 +109,7 @@ extern void get_hostname(void);
* Globals
*/
struct sudoers_user_context user_ctx;
struct sudoers_runas_context runas_ctx;
struct passwd *list_pw;
static const char *path_sudoers = _PATH_SUDOERS;
static struct sudoersfile_list sudoerslist = TAILQ_HEAD_INITIALIZER(sudoerslist);