summaryrefslogtreecommitdiff
path: root/nis/nss_compat/compat-initgroups.c
diff options
context:
space:
mode:
Diffstat (limited to 'nis/nss_compat/compat-initgroups.c')
-rw-r--r--nis/nss_compat/compat-initgroups.c19
1 files changed, 16 insertions, 3 deletions
diff --git a/nis/nss_compat/compat-initgroups.c b/nis/nss_compat/compat-initgroups.c
index 4d14615126..558433e0ba 100644
--- a/nis/nss_compat/compat-initgroups.c
+++ b/nis/nss_compat/compat-initgroups.c
@@ -27,6 +27,7 @@
#include <rpcsvc/yp.h>
#include <rpcsvc/ypclnt.h>
#include <rpcsvc/nis.h>
+#include <sys/param.h>
#include <nsswitch.h>
#include "nss-nis.h"
@@ -589,7 +590,8 @@ internal_getgrent_r (struct group *gr, ent_t *ent, char *buffer,
enum nss_status
_nss_compat_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)
{
struct group grpbuf, *g;
size_t buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
@@ -631,11 +633,22 @@ _nss_compat_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] = g->gr_gid;