summary refs log tree commit diff
path: root/grp/compat-initgroups.c
diff options
context:
space:
mode:
Diffstat (limited to 'grp/compat-initgroups.c')
-rw-r--r--grp/compat-initgroups.c61
1 files changed, 36 insertions, 25 deletions
diff --git a/grp/compat-initgroups.c b/grp/compat-initgroups.c
index 585c4aecbb..efd875a689 100644
--- a/grp/compat-initgroups.c
+++ b/grp/compat-initgroups.c
@@ -58,31 +58,42 @@ compat_call (service_user *nip, const char *user, gid_t group, long int *start,
           for (m = grpbuf.gr_mem; *m != NULL; ++m)
             if (strcmp (*m, user) == 0)
               {
-                /* Matches user.  Insert this group.  */
-                if (__builtin_expect (*start == *size, 0))
-                  {
-                    /* Need a bigger buffer.  */
-		    gid_t *newgroups;
-		    long int newsize;
-
-		    if (limit > 0 && *size == limit)
-		      /* We reached the maximum.  */
-		      goto done;
-
-		    if (limit <= 0)
-		      newsize = 2 * *size;
-		    else
-		      newsize = MIN (limit, 2 * *size);
-
-                    newgroups = realloc (groups, newsize * sizeof (*groups));
-                    if (newgroups == NULL)
-                      goto done;
-		    *groupsp = groups = newgroups;
-                    *size = newsize;
-                  }
-
-                groups[*start] = grpbuf.gr_gid;
-                *start += 1;
+		/* Check whether the group is already on the list.  */
+		long int cnt;
+		for (cnt = 0; cnt < *start; ++cnt)
+		  if (groups[cnt] == grpbuf.gr_gid)
+		    break;
+
+		if (cnt == *start)
+		  {
+		    /* Matches user and not yet on the list.  Insert
+		       this group.  */
+		    if (__builtin_expect (*start == *size, 0))
+		      {
+			/* Need a bigger buffer.  */
+			gid_t *newgroups;
+			long int newsize;
+
+			if (limit > 0 && *size == limit)
+			  /* We reached the maximum.  */
+			  goto done;
+
+			if (limit <= 0)
+			  newsize = 2 * *size;
+			else
+			  newsize = MIN (limit, 2 * *size);
+
+			newgroups = realloc (groups,
+					     newsize * sizeof (*groups));
+			if (newgroups == NULL)
+			  goto done;
+			*groupsp = groups = newgroups;
+			*size = newsize;
+		      }
+
+		    groups[*start] = grpbuf.gr_gid;
+		    *start += 1;
+		  }
 
                 break;
               }