diff --git a/plugins/sudoers/match.c b/plugins/sudoers/match.c index 2611b420a..7faae7399 100644 --- a/plugins/sudoers/match.c +++ b/plugins/sudoers/match.c @@ -154,6 +154,22 @@ userlist_matches(struct sudoers_parse_tree *parse_tree, const struct passwd *pw, debug_return_int(matched); } +struct gid_list * +runas_getgroups(void) +{ + const struct passwd *pw; + debug_decl(runas_getgroups, SUDOERS_DEBUG_MATCH) + + if (def_preserve_groups) { + sudo_gidlist_addref(user_gid_list); + debug_return_ptr(user_gid_list); + } + + /* Only use results from a group db query, not the front end. */ + pw = runas_pw ? runas_pw : sudo_user.pw; + debug_return_ptr(sudo_get_gidlist(pw, ENTRY_TYPE_QUERIED)); +} + /* * Check for user described by pw in a list of members. * If both lists are empty compare against def_runas_default. @@ -263,8 +279,23 @@ runaslist_matches(struct sudoers_parse_tree *parse_tree, } } if (group_matched == UNSPEC) { - if (runas_pw->pw_gid == runas_gr->gr_gid) + struct gid_list *runas_groups; + /* + * The runas group was not explicitly allowed by sudoers. + * Check whether it is one of the target user's groups. + */ + if (runas_pw->pw_gid == runas_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] == runas_gr->gr_gid) { + group_matched = ALLOW; /* matched aux group vector */ + break; + } + } + } } } diff --git a/plugins/sudoers/parse.h b/plugins/sudoers/parse.h index 426144c53..7dcbdca63 100644 --- a/plugins/sudoers/parse.h +++ b/plugins/sudoers/parse.h @@ -314,6 +314,7 @@ int runaslist_matches(struct sudoers_parse_tree *parse_tree, const struct member int user_matches(struct sudoers_parse_tree *parse_tree, const struct passwd *pw, const struct member *m); int userlist_matches(struct sudoers_parse_tree *parse_tree, const struct passwd *pw, const struct member_list *list); const char *sudo_getdomainname(void); +struct gid_list *runas_getgroups(void); /* toke.c */ void init_lexer(void); diff --git a/plugins/sudoers/set_perms.c b/plugins/sudoers/set_perms.c index 6bdc7b977..5b8348829 100644 --- a/plugins/sudoers/set_perms.c +++ b/plugins/sudoers/set_perms.c @@ -1695,19 +1695,11 @@ bad: static struct gid_list * runas_setgroups(void) { - struct passwd *pw; struct gid_list *gidlist; debug_decl(runas_setgroups, SUDOERS_DEBUG_PERMS) - if (def_preserve_groups) { - sudo_gidlist_addref(user_gid_list); - debug_return_ptr(user_gid_list); - } - - /* Only use results from a group db query, not the front end. */ - pw = runas_pw ? runas_pw : sudo_user.pw; - gidlist = sudo_get_gidlist(pw, ENTRY_TYPE_QUERIED); - if (gidlist != NULL) { + gidlist = runas_getgroups(); + if (gidlist != NULL && !def_preserve_groups) { if (sudo_setgroups(gidlist->ngids, gidlist->gids) < 0) { sudo_gidlist_delref(gidlist); gidlist = NULL;