From: Todd C. Miller Date: Tue, 30 Aug 2016 19:42:42 +0000 (-0600) Subject: Add match_group_by_gid Defaults option to allow sites with slow X-Git-Tag: SUDO_1_8_18^2~52 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=9cfd556853bbac5a6ccd2239aecf998b0dcedab9;p=sudo Add match_group_by_gid Defaults option to allow sites with slow group lookups and a small number of groups in sudoers to match groups by group ID instead of by group name. --- diff --git a/plugins/sudoers/def_data.c b/plugins/sudoers/def_data.c index 7b84efcc9..b433a7fe9 100644 --- a/plugins/sudoers/def_data.c +++ b/plugins/sudoers/def_data.c @@ -414,6 +414,10 @@ struct sudo_defs_types sudo_defs_table[] = { "ignore_logfile_errors", T_FLAG, N_("Allow commands to be run even if sudo cannot write to the log file"), NULL, + }, { + "match_group_by_gid", T_FLAG, + N_("Resolve groups in sudoers and match on the group ID, not the name"), + NULL, }, { NULL, 0, NULL } diff --git a/plugins/sudoers/def_data.h b/plugins/sudoers/def_data.h index 6f99d3fd5..1b3cd1e60 100644 --- a/plugins/sudoers/def_data.h +++ b/plugins/sudoers/def_data.h @@ -194,6 +194,8 @@ #define I_IGNORE_IOLOG_ERRORS 96 #define def_ignore_logfile_errors (sudo_defs_table[97].sd_un.flag) #define I_IGNORE_LOGFILE_ERRORS 97 +#define def_match_group_by_gid (sudo_defs_table[98].sd_un.flag) +#define I_MATCH_GROUP_BY_GID 98 enum def_tuple { never, diff --git a/plugins/sudoers/def_data.in b/plugins/sudoers/def_data.in index 57f198661..bc2391273 100644 --- a/plugins/sudoers/def_data.in +++ b/plugins/sudoers/def_data.in @@ -307,3 +307,6 @@ ignore_iolog_errors ignore_logfile_errors T_FLAG "Allow commands to be run even if sudo cannot write to the log file" +match_group_by_gid + T_FLAG + "Resolve groups in sudoers and match on the group ID, not the name" diff --git a/plugins/sudoers/pwutil.c b/plugins/sudoers/pwutil.c index 18ad555e4..30551d472 100644 --- a/plugins/sudoers/pwutil.c +++ b/plugins/sudoers/pwutil.c @@ -973,23 +973,48 @@ user_in_group(const struct passwd *pw, const char *group) } /* - * Next check the supplementary group vector. - * On BSD it includes the password db group too. + * Next match the group name. By default, sudoers resolves all the user's + * group IDs to names and matches by name. If match_group_by_gid is + * set, each group is sudoers is resolved and matching is by group ID. */ - if ((grlist = sudo_get_grlist(pw)) != NULL) { + if (def_match_group_by_gid) { + gid_t gid; + + /* Look up the ID of the group in sudoers. */ + if ((grp = sudo_getgrnam(group)) == NULL) + goto done; + gid = grp->gr_gid; + + /* Check against user's primary (passwd file) group ID. */ + if (gid == pw->pw_gid) { + matched = true; + goto done; + } + + /* Check the supplementary group vector. */ + if (gidlist == NULL && (gidlist = sudo_get_gidlist(pw)) != NULL) { + for (i = 0; i < gidlist->ngids; i++) { + if (gid == gidlist->gids[i]) { + matched = true; + goto done; + } + } + } + } else if ((grlist = sudo_get_grlist(pw)) != NULL) { + /* Check the supplementary group vector. */ for (i = 0; i < grlist->ngroups; i++) { if (strcasecmp(group, grlist->groups[i]) == 0) { matched = true; goto done; } } - } - /* Finally check against user's primary (passwd file) group. */ - if ((grp = sudo_getgrgid(pw->pw_gid)) != NULL) { - if (strcasecmp(group, grp->gr_name) == 0) { - matched = true; - goto done; + /* Check against user's primary (passwd file) group. */ + if ((grp = sudo_getgrgid(pw->pw_gid)) != NULL) { + if (strcasecmp(group, grp->gr_name) == 0) { + matched = true; + goto done; + } } }