summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2000-07-24 01:26:01 +0000
committerUlrich Drepper <drepper@redhat.com>2000-07-24 01:26:01 +0000
commitcf9e9ad98feb55d11f93aa4e069c81ee06c2a6a3 (patch)
tree2da802067a7b55b2580a49786505794ace48ac0c
parent945b22ed04767342dac1654f7e92ad5f8870361b (diff)
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 <drepper@redhat.com>
-rw-r--r--ChangeLog16
-rw-r--r--grp/initgroups.c37
-rw-r--r--hesiod/Versions2
-rw-r--r--hesiod/nss_hesiod/hesiod-grp.c41
-rw-r--r--nis/Versions9
-rw-r--r--nis/nss_compat/compat-initgroups.c18
-rw-r--r--nis/nss_nis/nis-initgroups.c18
7 files changed, 93 insertions, 48 deletions
diff --git a/ChangeLog b/ChangeLog
index 25c83be513..46fc4bdd18 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,21 @@
2000-07-23 Ulrich Drepper <drepper@redhat.com>
+ * 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 <drepper@redhat.com>
+
* locale/iso-639.def: Some errors corrected.
Patch by Keld Simonsen.
diff --git a/grp/initgroups.c b/grp/initgroups.c
index 06c48bb040..950ebfec0b 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
}
diff --git a/hesiod/Versions b/hesiod/Versions
index c51dee9c50..180befb5b3 100644
--- a/hesiod/Versions
+++ b/hesiod/Versions
@@ -8,7 +8,7 @@ libnss_hesiod {
_nss_hesiod_getservbyname_r;
}
GLIBC_2.2 {
- _nss_hesiod_initgroups;
+ _nss_hesiod_initgroups_dyn;
_nss_hesiod_getservbyport_r;
_nss_hesiod_setprotoent; _nss_hesiod_endprotoent;
_nss_hesiod_getprotobyname_r; _nss_hesiod_getprotobynumber_r;
diff --git a/hesiod/nss_hesiod/hesiod-grp.c b/hesiod/nss_hesiod/hesiod-grp.c
index 2d5b96b7f9..a89ed4edaf 100644
--- a/hesiod/nss_hesiod/hesiod-grp.c
+++ b/hesiod/nss_hesiod/hesiod-grp.c
@@ -164,14 +164,14 @@ internal_gid_from_group (void *context, const char *groupname, gid_t *group)
}
enum nss_status
-_nss_hesiod_initgroups (const char *user, gid_t group, long int *start,
- long int *size, gid_t *groups, long int limit,
- int *errnop)
+_nss_hesiod_initgroups_dyn (const char *user, gid_t group, long int *start,
+ long int *size, gid_t **groupsp, int *errnop)
{
enum nss_status status = NSS_STATUS_SUCCESS;
char **list = NULL;
char *p;
void *context;
+ gid_t *groups = *groupsp;
context = _nss_hesiod_init ();
if (context == NULL)
@@ -185,11 +185,24 @@ _nss_hesiod_initgroups (const char *user, gid_t group, long int *start,
return errno == ENOENT ? NSS_STATUS_NOTFOUND : NSS_STATUS_UNAVAIL;
}
- if (!internal_gid_in_list (groups, group, *start) && *start < limit)
- groups[(*start)++] = group;
+ if (!internal_gid_in_list (groups, group, *start))
+ {
+ if (__builtin_expect (*start == *size, 0))
+ {
+ /* Need a bigger buffer. */
+ gid_t *newgroups;
+ newgroups = realloc (groups, 2 * *size * sizeof (*groups));
+ if (newgroups == NULL)
+ goto done;
+ *groupsp = groups = newgroups;
+ *size *= 2;
+ }
+
+ groups[(*start)++] = group;
+ }
p = *list;
- while (*p != '\0' && *start < limit)
+ while (*p != '\0')
{
char *endp;
char *q;
@@ -214,12 +227,26 @@ _nss_hesiod_initgroups (const char *user, gid_t group, long int *start,
if (status == NSS_STATUS_SUCCESS
&& !internal_gid_in_list (groups, group, *start))
- groups[(*start)++] = group;
+ {
+ if (__builtin_expect (*start == *size, 0))
+ {
+ /* Need a bigger buffer. */
+ gid_t *newgroups;
+ newgroups = realloc (groups, 2 * *size * sizeof (*groups));
+ if (newgroups == NULL)
+ goto done;
+ *groupsp = groups = newgroups;
+ *size *= 2;
+ }
+
+ groups[(*start)++] = group;
+ }
}
p = q;
}
+ done:
hesiod_free_list (context, list);
hesiod_end (context);
diff --git a/nis/Versions b/nis/Versions
index ec8ade0dd3..8bcf9a8f0e 100644
--- a/nis/Versions
+++ b/nis/Versions
@@ -64,9 +64,12 @@ libnss_compat {
_nss_compat_endgrent; _nss_compat_endpwent; _nss_compat_endspent;
_nss_compat_getgrent_r; _nss_compat_getgrgid_r; _nss_compat_getgrnam_r;
_nss_compat_getpwent_r; _nss_compat_getpwnam_r; _nss_compat_getpwuid_r;
- _nss_compat_getspent_r; _nss_compat_getspnam_r; _nss_compat_initgroups;
+ _nss_compat_getspent_r; _nss_compat_getspnam_r;
_nss_compat_setgrent; _nss_compat_setpwent; _nss_compat_setspent;
}
+ GLIBC_2.2 {
+ _nss_compat_initgroups_dyn;
+ }
}
libnss_nis {
@@ -85,14 +88,14 @@ libnss_nis {
_nss_nis_getpwnam_r; _nss_nis_getpwuid_r; _nss_nis_getrpcbyname_r;
_nss_nis_getrpcbynumber_r; _nss_nis_getrpcent_r; _nss_nis_getsecretkey;
_nss_nis_getservbyname_r; _nss_nis_getservbyport_r; _nss_nis_getservent_r;
- _nss_nis_getspent_r; _nss_nis_getspnam_r; _nss_nis_initgroups;
+ _nss_nis_getspent_r; _nss_nis_getspnam_r;
_nss_nis_netname2user; _nss_nis_setaliasent; _nss_nis_setetherent;
_nss_nis_setgrent; _nss_nis_sethostent; _nss_nis_setnetent;
_nss_nis_setnetgrent; _nss_nis_setprotoent; _nss_nis_setpwent;
_nss_nis_setrpcent; _nss_nis_setservent; _nss_nis_setspent;
}
GLIBC_2.2 {
- _nss_nis_getipnodebyname_r;
+ _nss_nis_getipnodebyname_r; _nss_nis_initgroups_dyn;
}
}
diff --git a/nis/nss_compat/compat-initgroups.c b/nis/nss_compat/compat-initgroups.c
index 6051a1ae99..4d14615126 100644
--- a/nis/nss_compat/compat-initgroups.c
+++ b/nis/nss_compat/compat-initgroups.c
@@ -588,15 +588,15 @@ internal_getgrent_r (struct group *gr, ent_t *ent, char *buffer,
}
enum nss_status
-_nss_compat_initgroups (const char *user, gid_t group, long int *start,
- long int *size, gid_t *groups, long int limit,
- int *errnop)
+_nss_compat_initgroups_dyn (const char *user, gid_t group, long int *start,
+ long int *size, gid_t **groupsp, int *errnop)
{
struct group grpbuf, *g;
size_t buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
char *tmpbuf;
enum nss_status status;
ent_t intern = {0, 0, NULL, 0, NULL, NULL, {NULL, 0, 0}};
+ gid_t *groups = *groupsp;
status = internal_setgrent (&intern);
if (status != NSS_STATUS_SUCCESS)
@@ -627,22 +627,20 @@ _nss_compat_initgroups (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 (*start == *size)
{
/* 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] = g->gr_gid;
*start += 1;
- if (*start == limit)
- /* Can't take any more groups; stop searching. */
- goto done;
-
break;
}
}
diff --git a/nis/nss_nis/nis-initgroups.c b/nis/nss_nis/nis-initgroups.c
index 9e18a2027a..ec13dbd140 100644
--- a/nis/nss_nis/nis-initgroups.c
+++ b/nis/nss_nis/nis-initgroups.c
@@ -137,15 +137,15 @@ internal_getgrent_r (struct group *grp, char *buffer, size_t buflen,
}
enum nss_status
-_nss_nis_initgroups (const char *user, gid_t group, long int *start,
- long int *size, gid_t *groups, long int limit,
- int *errnop)
+_nss_nis_initgroups_dyn (const char *user, gid_t group, long int *start,
+ long int *size, gid_t **groupsp, int *errnop)
{
struct group grpbuf, *g;
size_t buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
char *tmpbuf;
enum nss_status status;
intern_t intern = { NULL, NULL };
+ gid_t *groups = *groupsp;
status = internal_setgrent (&intern);
if (status != NSS_STATUS_SUCCESS)
@@ -177,22 +177,20 @@ _nss_nis_initgroups (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 (*start == *size)
{
/* 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] = g->gr_gid;
*start += 1;
- if (*start == limit)
- /* Can't take any more groups; stop searching. */
- goto done;
-
break;
}
}