Skip to content

Commit

Permalink
Update.
Browse files Browse the repository at this point in the history
	* 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  <[email protected]>
  • Loading branch information
Ulrich Drepper committed Jul 24, 2000
1 parent 945b22e commit cf9e9ad
Show file tree
Hide file tree
Showing 7 changed files with 93 additions and 48 deletions.
16 changes: 16 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
2000-07-23 Ulrich Drepper <[email protected]>

* 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 <[email protected]>

* locale/iso-639.def: Some errors corrected.
Expand Down
37 changes: 20 additions & 17 deletions grp/initgroups.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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)
Expand Down Expand Up @@ -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;
}
}
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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)
Expand All @@ -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
}
2 changes: 1 addition & 1 deletion hesiod/Versions
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
41 changes: 34 additions & 7 deletions hesiod/nss_hesiod/hesiod-grp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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;
Expand All @@ -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);

Expand Down
9 changes: 6 additions & 3 deletions nis/Versions
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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;
}
}

Expand Down
18 changes: 8 additions & 10 deletions nis/nss_compat/compat-initgroups.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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;
}
}
Expand Down
18 changes: 8 additions & 10 deletions nis/nss_nis/nis-initgroups.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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;
}
}
Expand Down

0 comments on commit cf9e9ad

Please sign in to comment.