Set runas_pw early and adjust runaslist_matches() to deal. Since

we now set runas_default early there is no need to call update_defaults
with SETDEF_RUNAS after sudoers has been parsed.
This commit is contained in:
Todd C. Miller
2016-08-10 10:56:05 -06:00
parent 56ead73886
commit a08ea1b14d
7 changed files with 59 additions and 70 deletions

View File

@@ -153,10 +153,17 @@ runaslist_matches(const struct member_list *user_list,
int group_matched = UNSPEC;
debug_decl(runaslist_matches, SUDOERS_DEBUG_MATCH)
if (runas_pw != NULL) {
/*
* Skip checking runas user if it is the same as the invoking user
* and a runas group was specified.
* This logic assumes that we cache and refcount passwd structs.
*/
if (!(runas_pw == sudo_user.pw && runas_gr != NULL)) {
/* If no runas user or runas group listed in sudoers, use default. */
if (user_list == NULL && group_list == NULL)
debug_return_int(userpw_matches(def_runas_default, runas_pw->pw_name, runas_pw));
if (user_list == NULL && group_list == NULL) {
debug_return_int(userpw_matches(def_runas_default,
runas_pw->pw_name, runas_pw));
}
if (user_list != NULL) {
TAILQ_FOREACH_REVERSE(m, user_list, member_list, entries) {
@@ -204,6 +211,9 @@ runaslist_matches(const struct member_list *user_list,
}
}
/*
* Skip checking runas group if none was specified.
*/
if (runas_gr != NULL) {
if (user_matched == UNSPEC) {
if (runas_pw == NULL || strcmp(runas_pw->pw_name, user_name) == 0)

View File

@@ -132,7 +132,8 @@ sudo_file_setdefs(struct sudo_nss *nss)
if (nss->handle == NULL)
debug_return_int(-1);
if (!update_defaults(SETDEF_GENERIC|SETDEF_HOST|SETDEF_USER, false))
if (!update_defaults(SETDEF_GENERIC|SETDEF_HOST|SETDEF_USER|SETDEF_RUNAS,
false))
debug_return_int(-1);
debug_return_int(0);
}

View File

@@ -205,32 +205,7 @@ sudoers_policy_init(void *info, char * const envp[])
goto cleanup;
}
/* XXX - collect post-sudoers parse settings into a function */
/*
* Set runas passwd/group entries based on command line or sudoers.
* Note that if runas_group was specified without runas_user we
* defer setting runas_pw so the match routines know to ignore it.
*/
/* XXX - qpm4u does more here as it may have already set runas_pw */
if (runas_group != NULL) {
if (!set_runasgr(runas_group, false))
goto cleanup;
if (runas_user != NULL) {
if (!set_runaspw(runas_user, false))
goto cleanup;
}
} else {
if (!set_runaspw(runas_user ? runas_user : def_runas_default, false))
goto cleanup;
}
if (!update_defaults(SETDEF_RUNAS, false)) {
log_warningx(SLOG_SEND_MAIL|SLOG_NO_STDERR,
N_("problem with defaults entries"));
}
/* Set login class if applicable. */
/* Set login class if applicable (after sudoers is parsed). */
if (set_loginclass(runas_pw ? runas_pw : sudo_user.pw))
rval = true;
@@ -389,13 +364,6 @@ sudoers_policy_main(int argc, char * const argv[], int pwflag, char *env_add[],
}
}
/* If only a group was specified, set runas_pw based on invoking user. */
if (runas_pw == NULL) {
if (!set_runaspw(user_name, false)) {
goto done;
}
}
/*
* Look up the timestamp dir owner if one is specified.
*/
@@ -707,8 +675,8 @@ init_vars(char * const envp[])
}
/*
* Get a local copy of the user's struct passwd if we don't already
* have one.
* Get a local copy of the user's passwd struct and group list if we
* don't already have them.
*/
if (sudo_user.pw == NULL) {
if ((sudo_user.pw = sudo_getpwnam(user_name)) == NULL) {
@@ -727,12 +695,10 @@ init_vars(char * const envp[])
unknown_user = true;
}
}
/*
* Get group list and store initialize permissions.
*/
if (user_group_list == NULL)
user_group_list = sudo_get_grlist(sudo_user.pw);
/* Store initialize permissions so we can restore them later. */
if (!set_perms(PERM_INITIAL))
debug_return_bool(false);
@@ -758,6 +724,21 @@ init_vars(char * const envp[])
debug_return_bool(false);
}
/*
* Set runas passwd/group entries based on command line or sudoers.
* Note that if runas_group was specified without runas_user we
* run the command as the invoking user.
*/
if (runas_group != NULL) {
if (!set_runasgr(runas_group, false))
debug_return_bool(false);
if (!set_runaspw(runas_user ? runas_user : user_name, false))
debug_return_bool(false);
} else {
if (!set_runaspw(runas_user ? runas_user : def_runas_default, false))
debug_return_bool(false);
}
debug_return_bool(true);
}

View File

@@ -261,6 +261,17 @@ main(int argc, char *argv[])
/* Allocate space for data structures in the parser. */
init_parser("sudoers", false);
/*
* Set runas passwd/group entries based on command line or sudoers.
* Note that if runas_group was specified without runas_user we
* run the command as the invoking user.
*/
if (runas_group != NULL) {
set_runasgr(runas_group);
set_runaspw(runas_user ? runas_user : user_name);
} else
set_runaspw(runas_user ? runas_user : def_runas_default);
sudoers_setlocale(SUDOERS_LOCALE_SUDOERS, NULL);
if (sudoersparse() != 0 || parse_error) {
parse_error = true;
@@ -277,18 +288,6 @@ main(int argc, char *argv[])
(void) fputs(" (problem with defaults entries)", stdout);
puts(".");
/*
* Set runas passwd/group entries based on command line or sudoers.
* Note that if runas_group was specified without runas_user we
* defer setting runas_pw so the match routines know to ignore it.
*/
if (runas_group != NULL) {
set_runasgr(runas_group);
if (runas_user != NULL)
set_runaspw(runas_user);
} else
set_runaspw(runas_user ? runas_user : def_runas_default);
if (dflag) {
(void) putchar('\n');
dump_sudoers();