Allow the group set by "sudo -g" to be any of the target user's groups.
Previously, this was only allowed if the group matched the target user's primary group ID (from the passwd database entry). The sudoers policy will now allow the group if it is one of the target user's supplemental groups as well.
This commit is contained in:
@@ -154,6 +154,22 @@ userlist_matches(struct sudoers_parse_tree *parse_tree, const struct passwd *pw,
|
|||||||
debug_return_int(matched);
|
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.
|
* Check for user described by pw in a list of members.
|
||||||
* If both lists are empty compare against def_runas_default.
|
* 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 (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 */
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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 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);
|
int userlist_matches(struct sudoers_parse_tree *parse_tree, const struct passwd *pw, const struct member_list *list);
|
||||||
const char *sudo_getdomainname(void);
|
const char *sudo_getdomainname(void);
|
||||||
|
struct gid_list *runas_getgroups(void);
|
||||||
|
|
||||||
/* toke.c */
|
/* toke.c */
|
||||||
void init_lexer(void);
|
void init_lexer(void);
|
||||||
|
@@ -1695,19 +1695,11 @@ bad:
|
|||||||
static struct gid_list *
|
static struct gid_list *
|
||||||
runas_setgroups(void)
|
runas_setgroups(void)
|
||||||
{
|
{
|
||||||
struct passwd *pw;
|
|
||||||
struct gid_list *gidlist;
|
struct gid_list *gidlist;
|
||||||
debug_decl(runas_setgroups, SUDOERS_DEBUG_PERMS)
|
debug_decl(runas_setgroups, SUDOERS_DEBUG_PERMS)
|
||||||
|
|
||||||
if (def_preserve_groups) {
|
gidlist = runas_getgroups();
|
||||||
sudo_gidlist_addref(user_gid_list);
|
if (gidlist != NULL && !def_preserve_groups) {
|
||||||
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) {
|
|
||||||
if (sudo_setgroups(gidlist->ngids, gidlist->gids) < 0) {
|
if (sudo_setgroups(gidlist->ngids, gidlist->gids) < 0) {
|
||||||
sudo_gidlist_delref(gidlist);
|
sudo_gidlist_delref(gidlist);
|
||||||
gidlist = NULL;
|
gidlist = NULL;
|
||||||
|
Reference in New Issue
Block a user