]> granicus.if.org Git - sudo/commitdiff
Add match_group_by_gid Defaults option to allow sites with slow
authorTodd C. Miller <Todd.Miller@courtesan.com>
Tue, 30 Aug 2016 19:42:42 +0000 (13:42 -0600)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Tue, 30 Aug 2016 19:42:42 +0000 (13:42 -0600)
group lookups and a small number of groups in sudoers to match
groups by group ID instead of by group name.

plugins/sudoers/def_data.c
plugins/sudoers/def_data.h
plugins/sudoers/def_data.in
plugins/sudoers/pwutil.c

index 7b84efcc97ed079373e204763c8dc72d541bc3d2..b433a7fe9eac33264882e543591d4222a4b8ced5 100644 (file)
@@ -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
     }
index 6f99d3fd50786b1de4c8170ab8e4e8bd1a2bc49d..1b3cd1e603a881acef35b26fe0e9aab83e229cfe 100644 (file)
 #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,
index 57f198661dd9d9ba0da57a490231fcaa05f68aa1..bc23912735a06e0138a722bb9146db5e532b71a9 100644 (file)
@@ -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"
index 18ad555e4c3d0c431b662da00f4cbfed7e566edb..30551d4728971b459e2e2509529f9d2f7b8005bb 100644 (file)
@@ -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;
+           }
        }
     }