about summary refs log tree commit diff
path: root/hesiod/nss_hesiod/hesiod-grp.c
diff options
context:
space:
mode:
Diffstat (limited to 'hesiod/nss_hesiod/hesiod-grp.c')
-rw-r--r--hesiod/nss_hesiod/hesiod-grp.c34
1 files changed, 29 insertions, 5 deletions
diff --git a/hesiod/nss_hesiod/hesiod-grp.c b/hesiod/nss_hesiod/hesiod-grp.c
index a89ed4edaf..5551d7d012 100644
--- a/hesiod/nss_hesiod/hesiod-grp.c
+++ b/hesiod/nss_hesiod/hesiod-grp.c
@@ -25,6 +25,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <sys/param.h>
 
 #include "nss_hesiod.h"
 
@@ -165,7 +166,8 @@ internal_gid_from_group (void *context, const char *groupname, gid_t *group)
 
 enum nss_status
 _nss_hesiod_initgroups_dyn (const char *user, gid_t group, long int *start,
-			    long int *size, gid_t **groupsp, int *errnop)
+			    long int *size, gid_t **groupsp, long int limit,
+			    int *errnop)
 {
   enum nss_status status = NSS_STATUS_SUCCESS;
   char **list = NULL;
@@ -191,11 +193,22 @@ _nss_hesiod_initgroups_dyn (const char *user, gid_t group, long int *start,
 	{
 	  /* Need a bigger buffer.  */
 	  gid_t *newgroups;
-	  newgroups = realloc (groups, 2 * *size * sizeof (*groups));
+	  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 *= 2;
+	  *size = newsize;
 	}
 
       groups[(*start)++] = group;
@@ -232,11 +245,22 @@ _nss_hesiod_initgroups_dyn (const char *user, gid_t group, long int *start,
 		{
 		  /* Need a bigger buffer.  */
 		  gid_t *newgroups;
-		  newgroups = realloc (groups, 2 * *size * sizeof (*groups));
+		  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 *= 2;
+		  *size = newsize;
 		}
 
 	      groups[(*start)++] = group;