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>
This commit is contained in:
parent
945b22ed04
commit
cf9e9ad98f
16
ChangeLog
16
ChangeLog
|
@ -1,3 +1,19 @@
|
||||||
|
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>
|
2000-07-23 Ulrich Drepper <drepper@redhat.com>
|
||||||
|
|
||||||
* locale/iso-639.def: Some errors corrected.
|
* locale/iso-639.def: Some errors corrected.
|
||||||
|
|
|
@ -49,7 +49,7 @@ extern service_user *__nss_group_database;
|
||||||
|
|
||||||
static enum nss_status
|
static enum nss_status
|
||||||
compat_call (service_user *nip, const char *user, gid_t group, long int *start,
|
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;
|
struct group grpbuf;
|
||||||
size_t buflen = __sysconf (_SC_GETGR_R_SIZE_MAX);
|
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;
|
set_function setgrent_fct;
|
||||||
get_function getgrent_fct;
|
get_function getgrent_fct;
|
||||||
end_function endgrent_fct;
|
end_function endgrent_fct;
|
||||||
|
gid_t *groups = *groupsp;
|
||||||
|
|
||||||
getgrent_fct = __nss_lookup_function (nip, "getgrent_r");
|
getgrent_fct = __nss_lookup_function (nip, "getgrent_r");
|
||||||
if (getgrent_fct == NULL)
|
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)
|
if (strcmp (*m, user) == 0)
|
||||||
{
|
{
|
||||||
/* Matches user. Insert this group. */
|
/* Matches user. Insert this group. */
|
||||||
if (*start == *size && limit <= 0)
|
if (__builtin_expect (*start == *size, 0))
|
||||||
{
|
{
|
||||||
/* Need a bigger buffer. */
|
/* Need a bigger buffer. */
|
||||||
groups = realloc (groups, 2 * *size * sizeof (*groups));
|
gid_t *newgroups;
|
||||||
if (groups == NULL)
|
newgroups = realloc (groups, 2 * *size * sizeof (*groups));
|
||||||
|
if (newgroups == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
|
*groupsp = groups = newgroups;
|
||||||
*size *= 2;
|
*size *= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
groups[*start] = grpbuf.gr_gid;
|
groups[*start] = grpbuf.gr_gid;
|
||||||
*start += 1;
|
*start += 1;
|
||||||
|
|
||||||
if (*start == limit)
|
|
||||||
/* Can't take any more groups; stop searching. */
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -149,10 +148,9 @@ initgroups (user, group)
|
||||||
long int start = 1;
|
long int start = 1;
|
||||||
long int size;
|
long int size;
|
||||||
gid_t *groups;
|
gid_t *groups;
|
||||||
|
int result;
|
||||||
#ifdef NGROUPS_MAX
|
#ifdef NGROUPS_MAX
|
||||||
# define limit NGROUPS_MAX
|
size = NGROUPS_MAX;
|
||||||
|
|
||||||
size = limit;
|
|
||||||
#else
|
#else
|
||||||
long int limit = __sysconf (_SC_NGROUPS_MAX);
|
long int limit = __sysconf (_SC_NGROUPS_MAX);
|
||||||
|
|
||||||
|
@ -181,19 +179,19 @@ initgroups (user, group)
|
||||||
|
|
||||||
while (! no_more)
|
while (! no_more)
|
||||||
{
|
{
|
||||||
fct = __nss_lookup_function (nip, "initgroups");
|
fct = __nss_lookup_function (nip, "initgroups_dyn");
|
||||||
|
|
||||||
if (fct == NULL)
|
if (fct == NULL)
|
||||||
{
|
{
|
||||||
status = compat_call (nip, user, group, &start, &size, groups,
|
status = compat_call (nip, user, group, &start, &size, &groups,
|
||||||
limit, &errno);
|
&errno);
|
||||||
|
|
||||||
if (nss_next_action (nip, NSS_STATUS_UNAVAIL) != NSS_ACTION_CONTINUE)
|
if (nss_next_action (nip, NSS_STATUS_UNAVAIL) != NSS_ACTION_CONTINUE)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
status = DL_CALL_FCT (fct, (user, group, &start, &size, groups, limit,
|
status = DL_CALL_FCT (fct, (user, group, &start, &size, &groups,
|
||||||
&errno));
|
&errno));
|
||||||
|
|
||||||
/* This is really only for debugging. */
|
/* This is really only for debugging. */
|
||||||
if (NSS_STATUS_TRYAGAIN > status || status > NSS_STATUS_RETURN)
|
if (NSS_STATUS_TRYAGAIN > status || status > NSS_STATUS_RETURN)
|
||||||
|
@ -209,6 +207,11 @@ initgroups (user, group)
|
||||||
nip = nip->next;
|
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
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ libnss_hesiod {
|
||||||
_nss_hesiod_getservbyname_r;
|
_nss_hesiod_getservbyname_r;
|
||||||
}
|
}
|
||||||
GLIBC_2.2 {
|
GLIBC_2.2 {
|
||||||
_nss_hesiod_initgroups;
|
_nss_hesiod_initgroups_dyn;
|
||||||
_nss_hesiod_getservbyport_r;
|
_nss_hesiod_getservbyport_r;
|
||||||
_nss_hesiod_setprotoent; _nss_hesiod_endprotoent;
|
_nss_hesiod_setprotoent; _nss_hesiod_endprotoent;
|
||||||
_nss_hesiod_getprotobyname_r; _nss_hesiod_getprotobynumber_r;
|
_nss_hesiod_getprotobyname_r; _nss_hesiod_getprotobynumber_r;
|
||||||
|
|
|
@ -164,14 +164,14 @@ internal_gid_from_group (void *context, const char *groupname, gid_t *group)
|
||||||
}
|
}
|
||||||
|
|
||||||
enum nss_status
|
enum nss_status
|
||||||
_nss_hesiod_initgroups (const char *user, gid_t group, long int *start,
|
_nss_hesiod_initgroups_dyn (const char *user, gid_t group, long int *start,
|
||||||
long int *size, gid_t *groups, long int limit,
|
long int *size, gid_t **groupsp, int *errnop)
|
||||||
int *errnop)
|
|
||||||
{
|
{
|
||||||
enum nss_status status = NSS_STATUS_SUCCESS;
|
enum nss_status status = NSS_STATUS_SUCCESS;
|
||||||
char **list = NULL;
|
char **list = NULL;
|
||||||
char *p;
|
char *p;
|
||||||
void *context;
|
void *context;
|
||||||
|
gid_t *groups = *groupsp;
|
||||||
|
|
||||||
context = _nss_hesiod_init ();
|
context = _nss_hesiod_init ();
|
||||||
if (context == NULL)
|
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;
|
return errno == ENOENT ? NSS_STATUS_NOTFOUND : NSS_STATUS_UNAVAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!internal_gid_in_list (groups, group, *start) && *start < limit)
|
if (!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 = *list;
|
p = *list;
|
||||||
while (*p != '\0' && *start < limit)
|
while (*p != '\0')
|
||||||
{
|
{
|
||||||
char *endp;
|
char *endp;
|
||||||
char *q;
|
char *q;
|
||||||
|
@ -214,12 +227,26 @@ _nss_hesiod_initgroups (const char *user, gid_t group, long int *start,
|
||||||
|
|
||||||
if (status == NSS_STATUS_SUCCESS
|
if (status == NSS_STATUS_SUCCESS
|
||||||
&& !internal_gid_in_list (groups, group, *start))
|
&& !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;
|
p = q;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
hesiod_free_list (context, list);
|
hesiod_free_list (context, list);
|
||||||
hesiod_end (context);
|
hesiod_end (context);
|
||||||
|
|
||||||
|
|
|
@ -64,9 +64,12 @@ libnss_compat {
|
||||||
_nss_compat_endgrent; _nss_compat_endpwent; _nss_compat_endspent;
|
_nss_compat_endgrent; _nss_compat_endpwent; _nss_compat_endspent;
|
||||||
_nss_compat_getgrent_r; _nss_compat_getgrgid_r; _nss_compat_getgrnam_r;
|
_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_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;
|
_nss_compat_setgrent; _nss_compat_setpwent; _nss_compat_setspent;
|
||||||
}
|
}
|
||||||
|
GLIBC_2.2 {
|
||||||
|
_nss_compat_initgroups_dyn;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
libnss_nis {
|
libnss_nis {
|
||||||
|
@ -85,14 +88,14 @@ libnss_nis {
|
||||||
_nss_nis_getpwnam_r; _nss_nis_getpwuid_r; _nss_nis_getrpcbyname_r;
|
_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_getrpcbynumber_r; _nss_nis_getrpcent_r; _nss_nis_getsecretkey;
|
||||||
_nss_nis_getservbyname_r; _nss_nis_getservbyport_r; _nss_nis_getservent_r;
|
_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_netname2user; _nss_nis_setaliasent; _nss_nis_setetherent;
|
||||||
_nss_nis_setgrent; _nss_nis_sethostent; _nss_nis_setnetent;
|
_nss_nis_setgrent; _nss_nis_sethostent; _nss_nis_setnetent;
|
||||||
_nss_nis_setnetgrent; _nss_nis_setprotoent; _nss_nis_setpwent;
|
_nss_nis_setnetgrent; _nss_nis_setprotoent; _nss_nis_setpwent;
|
||||||
_nss_nis_setrpcent; _nss_nis_setservent; _nss_nis_setspent;
|
_nss_nis_setrpcent; _nss_nis_setservent; _nss_nis_setspent;
|
||||||
}
|
}
|
||||||
GLIBC_2.2 {
|
GLIBC_2.2 {
|
||||||
_nss_nis_getipnodebyname_r;
|
_nss_nis_getipnodebyname_r; _nss_nis_initgroups_dyn;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -588,15 +588,15 @@ internal_getgrent_r (struct group *gr, ent_t *ent, char *buffer,
|
||||||
}
|
}
|
||||||
|
|
||||||
enum nss_status
|
enum nss_status
|
||||||
_nss_compat_initgroups (const char *user, gid_t group, long int *start,
|
_nss_compat_initgroups_dyn (const char *user, gid_t group, long int *start,
|
||||||
long int *size, gid_t *groups, long int limit,
|
long int *size, gid_t **groupsp, int *errnop)
|
||||||
int *errnop)
|
|
||||||
{
|
{
|
||||||
struct group grpbuf, *g;
|
struct group grpbuf, *g;
|
||||||
size_t buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
|
size_t buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
|
||||||
char *tmpbuf;
|
char *tmpbuf;
|
||||||
enum nss_status status;
|
enum nss_status status;
|
||||||
ent_t intern = {0, 0, NULL, 0, NULL, NULL, {NULL, 0, 0}};
|
ent_t intern = {0, 0, NULL, 0, NULL, NULL, {NULL, 0, 0}};
|
||||||
|
gid_t *groups = *groupsp;
|
||||||
|
|
||||||
status = internal_setgrent (&intern);
|
status = internal_setgrent (&intern);
|
||||||
if (status != NSS_STATUS_SUCCESS)
|
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)
|
if (strcmp (*m, user) == 0)
|
||||||
{
|
{
|
||||||
/* Matches user. Insert this group. */
|
/* Matches user. Insert this group. */
|
||||||
if (*start == *size && limit <= 0)
|
if (*start == *size)
|
||||||
{
|
{
|
||||||
/* Need a bigger buffer. */
|
/* Need a bigger buffer. */
|
||||||
groups = realloc (groups, 2 * *size * sizeof (*groups));
|
gid_t *newgroups;
|
||||||
if (groups == NULL)
|
newgroups = realloc (groups, 2 * *size * sizeof (*groups));
|
||||||
|
if (newgroups == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
|
*groupsp = groups = newgroups;
|
||||||
*size *= 2;
|
*size *= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
groups[*start] = g->gr_gid;
|
groups[*start] = g->gr_gid;
|
||||||
*start += 1;
|
*start += 1;
|
||||||
|
|
||||||
if (*start == limit)
|
|
||||||
/* Can't take any more groups; stop searching. */
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -137,15 +137,15 @@ internal_getgrent_r (struct group *grp, char *buffer, size_t buflen,
|
||||||
}
|
}
|
||||||
|
|
||||||
enum nss_status
|
enum nss_status
|
||||||
_nss_nis_initgroups (const char *user, gid_t group, long int *start,
|
_nss_nis_initgroups_dyn (const char *user, gid_t group, long int *start,
|
||||||
long int *size, gid_t *groups, long int limit,
|
long int *size, gid_t **groupsp, int *errnop)
|
||||||
int *errnop)
|
|
||||||
{
|
{
|
||||||
struct group grpbuf, *g;
|
struct group grpbuf, *g;
|
||||||
size_t buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
|
size_t buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
|
||||||
char *tmpbuf;
|
char *tmpbuf;
|
||||||
enum nss_status status;
|
enum nss_status status;
|
||||||
intern_t intern = { NULL, NULL };
|
intern_t intern = { NULL, NULL };
|
||||||
|
gid_t *groups = *groupsp;
|
||||||
|
|
||||||
status = internal_setgrent (&intern);
|
status = internal_setgrent (&intern);
|
||||||
if (status != NSS_STATUS_SUCCESS)
|
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)
|
if (strcmp (*m, user) == 0)
|
||||||
{
|
{
|
||||||
/* Matches user. Insert this group. */
|
/* Matches user. Insert this group. */
|
||||||
if (*start == *size && limit <= 0)
|
if (*start == *size)
|
||||||
{
|
{
|
||||||
/* Need a bigger buffer. */
|
/* Need a bigger buffer. */
|
||||||
groups = realloc (groups, 2 * *size * sizeof (*groups));
|
gid_t *newgroups;
|
||||||
if (groups == NULL)
|
newgroups = realloc (groups, 2 * *size * sizeof (*groups));
|
||||||
|
if (newgroups == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
|
*groupsp = groups = newgroups;
|
||||||
*size *= 2;
|
*size *= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
groups[*start] = g->gr_gid;
|
groups[*start] = g->gr_gid;
|
||||||
*start += 1;
|
*start += 1;
|
||||||
|
|
||||||
if (*start == limit)
|
|
||||||
/* Can't take any more groups; stop searching. */
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue