From cf9e9ad98feb55d11f93aa4e069c81ee06c2a6a3 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Mon, 24 Jul 2000 01:26:01 +0000 Subject: Update. * grp/initgroups.c (initgroups): Don't limit the possible number of groups to NGROUPS_MAX. Allow dynamic resizing. Loop around the setgroups call while the call fails and descrease the number of groups each round. The name of the initgroups function in the NSS modules changed. (compat_call): Adapt for dynamic resizing. * hesiod/nss_hesiod/hesiod-grp.c (_nss_hesiod_initgroups_dyn): Implement dynamic resizing. * nis/nss_compat/compat-initgroups.c (_nss_compat_initgroups_dyn): Likewise. * nis/nss_nis/compat-initgroups.c (_nss_nis_initgroups_dyn): Likewise. * hesiod/Versions: Change exported interface name. * nis/Versions: Change exported interface name. 2000-07-23 Ulrich Drepper --- grp/initgroups.c | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) (limited to 'grp/initgroups.c') diff --git a/grp/initgroups.c b/grp/initgroups.c index 06c48bb..950ebfe 100644 --- a/grp/initgroups.c +++ b/grp/initgroups.c @@ -49,7 +49,7 @@ extern service_user *__nss_group_database; static enum nss_status compat_call (service_user *nip, const char *user, gid_t group, long int *start, - long int *size, gid_t *groups, long int limit, int *errnop) + long int *size, gid_t **groupsp, int *errnop) { struct group grpbuf; size_t buflen = __sysconf (_SC_GETGR_R_SIZE_MAX); @@ -58,6 +58,7 @@ compat_call (service_user *nip, const char *user, gid_t group, long int *start, set_function setgrent_fct; get_function getgrent_fct; end_function endgrent_fct; + gid_t *groups = *groupsp; getgrent_fct = __nss_lookup_function (nip, "getgrent_r"); if (getgrent_fct == NULL) @@ -97,22 +98,20 @@ compat_call (service_user *nip, const char *user, gid_t group, long int *start, if (strcmp (*m, user) == 0) { /* Matches user. Insert this group. */ - if (*start == *size && limit <= 0) + if (__builtin_expect (*start == *size, 0)) { /* Need a bigger buffer. */ - groups = realloc (groups, 2 * *size * sizeof (*groups)); - if (groups == NULL) + gid_t *newgroups; + newgroups = realloc (groups, 2 * *size * sizeof (*groups)); + if (newgroups == NULL) goto done; + *groupsp = groups = newgroups; *size *= 2; } groups[*start] = grpbuf.gr_gid; *start += 1; - if (*start == limit) - /* Can't take any more groups; stop searching. */ - goto done; - break; } } @@ -149,10 +148,9 @@ initgroups (user, group) long int start = 1; long int size; gid_t *groups; + int result; #ifdef NGROUPS_MAX -# define limit NGROUPS_MAX - - size = limit; + size = NGROUPS_MAX; #else long int limit = __sysconf (_SC_NGROUPS_MAX); @@ -181,19 +179,19 @@ initgroups (user, group) while (! no_more) { - fct = __nss_lookup_function (nip, "initgroups"); + fct = __nss_lookup_function (nip, "initgroups_dyn"); if (fct == NULL) { - status = compat_call (nip, user, group, &start, &size, groups, - limit, &errno); + status = compat_call (nip, user, group, &start, &size, &groups, + &errno); if (nss_next_action (nip, NSS_STATUS_UNAVAIL) != NSS_ACTION_CONTINUE) break; } else - status = DL_CALL_FCT (fct, (user, group, &start, &size, groups, limit, - &errno)); + status = DL_CALL_FCT (fct, (user, group, &start, &size, &groups, + &errno)); /* This is really only for debugging. */ if (NSS_STATUS_TRYAGAIN > status || status > NSS_STATUS_RETURN) @@ -209,6 +207,11 @@ initgroups (user, group) nip = nip->next; } - return setgroups (start, groups); + /* Try to set the maximum number of groups the kernel can handle. */ + do + result = setgroups (start, groups); + while (result == -1 && errno == EINVAL && --start > 0); + + return result; #endif } -- cgit v1.1