]> granicus.if.org Git - shadow/commitdiff
newgrp: avoid unnecessary group lookups
authorTomas Mraz <tmraz@fedoraproject.org>
Mon, 14 Aug 2017 09:38:46 +0000 (11:38 +0200)
committerTomas Mraz <tmraz@fedoraproject.org>
Mon, 14 Aug 2017 09:38:46 +0000 (11:38 +0200)
In case a system uses remote identity server (LDAP) the group lookup
can be very slow. We avoid it when we already know the user has the
group membership.

src/newgrp.c

index b0fa8d5aefae8fdf91c87ae583ca084afdac9015..221b0baa29358a60970bec4bcc8ffcea88cf0242 100644 (file)
@@ -83,15 +83,29 @@ static void usage (void)
        }
 }
 
+static bool ingroup(const char *name, struct group *gr)
+{
+       char **look;
+       bool notfound = true;
+
+       look = gr->gr_mem;
+       while (*look && notfound)
+               notfound = strcmp (*look++, name);
+
+       return !notfound;
+}
+
 /*
- * find_matching_group - search all groups of a given group id for
+ * find_matching_group - search all groups of a gr's group id for
  *                       membership of a given username
+ *                       but check gr itself first
  */
-static /*@null@*/struct group *find_matching_group (const char *name, gid_t gid)
+static /*@null@*/struct group *find_matching_group (const char *name, struct group *gr)
 {
-       struct group *gr;
-       char **look;
-       bool notfound = true;
+       gid_t gid = gr->gr_gid;
+
+       if (ingroup(name, gr))
+               return gr;
 
        setgrent ();
        while ((gr = getgrent ()) != NULL) {
@@ -103,14 +117,8 @@ static /*@null@*/struct group *find_matching_group (const char *name, gid_t gid)
                 * A group with matching GID was found.
                 * Test for membership of 'name'.
                 */
-               look = gr->gr_mem;
-               while ((NULL != *look) && notfound) {
-                       notfound = (strcmp (*look, name) != 0);
-                       look++;
-               }
-               if (!notfound) {
+               if (ingroup(name, gr))
                        break;
-               }
        }
        endgrent ();
        return gr;
@@ -643,17 +651,19 @@ int main (int argc, char **argv)
         * groups of the same GID like the requested group for
         * membership of the current user.
         */
-       grp = find_matching_group (name, grp->gr_gid);
-       if (NULL == grp) {
-               /*
-                * No matching group found. As we already know that
-                * the group exists, this happens only in the case
-                * of a requested group where the user is not member.
-                *
-                * Re-read the group entry for further processing.
-                */
-               grp = xgetgrnam (group);
-               assert (NULL != grp);
+       if (!is_member) {
+               grp = find_matching_group (name, grp);
+               if (NULL == grp) {
+                       /*
+                        * No matching group found. As we already know that
+                        * the group exists, this happens only in the case
+                        * of a requested group where the user is not member.
+                        *
+                        * Re-read the group entry for further processing.
+                        */
+                       grp = xgetgrnam (group);
+                       assert (NULL != grp);
+               }
        }
 #ifdef SHADOWGRP
        sgrp = getsgnam (group);