mirror of
https://sourceware.org/git/glibc.git
synced 2025-07-30 22:43:12 +03:00
Update.
* grp/initgroups.c: Move compat_call implementation... * grp/compat-initgroups.c: ...to here. New file. * grp/Makefile (distribute): Add compat-initgroups.c. (CFLAGS-initgroups.c): Add -DUSE_NSCD=1. * mscd/initgrcache.c: New file. * nscd/nscd_initgroups.c: New file. * nscd/Makefile (routines): Add nscd_initgroups. (nscd-modules): Add initgrcache. * nscd/cache.c (prune_cache): Add support for INITGROUPS entries. * nscd/connections.c: Handle INITGROUPS requests. * nscd/nscd-client.h: Define INITGROUPS, initgr_response_header. Add initgrdata element to struct datahead. Fix typo in comment. * nscd/nscd_proto.h: Declare __nscd_getgrouplist. Fix parameter type in __nscd_getgrgrid_r. * nscd/selinux.c (perms): Add INITGROUPS entry. * nscd/nscd_getai.c: No need to include <sys/mman.h>. * sunrpc/get_myaddr.c (get_myaddress): Account for interfaces without assigned addresses. * sunrpc/pmap_clnt.c (__get_myaddress): Likewise. * sunrpc/pmap_rmt.c (getbroadcastnets): Likewise. * sunrpc/clnt_udp.c (is_network_up): Likewise.
This commit is contained in:
98
grp/compat-initgroups.c
Normal file
98
grp/compat-initgroups.c
Normal file
@ -0,0 +1,98 @@
|
||||
/* Prototype for the setgrent functions we use here. */
|
||||
typedef enum nss_status (*set_function) (void);
|
||||
|
||||
/* Prototype for the endgrent functions we use here. */
|
||||
typedef enum nss_status (*end_function) (void);
|
||||
|
||||
/* Prototype for the setgrent functions we use here. */
|
||||
typedef enum nss_status (*get_function) (struct group *, char *,
|
||||
size_t, int *);
|
||||
|
||||
static enum nss_status
|
||||
compat_call (service_user *nip, const char *user, gid_t group, long int *start,
|
||||
long int *size, gid_t **groupsp, long int limit, int *errnop)
|
||||
{
|
||||
struct group grpbuf;
|
||||
size_t buflen = __sysconf (_SC_GETGR_R_SIZE_MAX);
|
||||
char *tmpbuf;
|
||||
enum nss_status status;
|
||||
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)
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
|
||||
setgrent_fct = __nss_lookup_function (nip, "setgrent");
|
||||
if (setgrent_fct)
|
||||
{
|
||||
status = DL_CALL_FCT (setgrent_fct, ());
|
||||
if (status != NSS_STATUS_SUCCESS)
|
||||
return status;
|
||||
}
|
||||
|
||||
endgrent_fct = __nss_lookup_function (nip, "endgrent");
|
||||
|
||||
tmpbuf = __alloca (buflen);
|
||||
|
||||
do
|
||||
{
|
||||
while ((status = DL_CALL_FCT (getgrent_fct,
|
||||
(&grpbuf, tmpbuf, buflen, errnop)),
|
||||
status == NSS_STATUS_TRYAGAIN)
|
||||
&& *errnop == ERANGE)
|
||||
{
|
||||
buflen *= 2;
|
||||
tmpbuf = __alloca (buflen);
|
||||
}
|
||||
|
||||
if (status != NSS_STATUS_SUCCESS)
|
||||
goto done;
|
||||
|
||||
if (grpbuf.gr_gid != group)
|
||||
{
|
||||
char **m;
|
||||
|
||||
for (m = grpbuf.gr_mem; *m != NULL; ++m)
|
||||
if (strcmp (*m, user) == 0)
|
||||
{
|
||||
/* Matches user. Insert this group. */
|
||||
if (__builtin_expect (*start == *size, 0))
|
||||
{
|
||||
/* Need a bigger buffer. */
|
||||
gid_t *newgroups;
|
||||
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 = newsize;
|
||||
}
|
||||
|
||||
groups[*start] = grpbuf.gr_gid;
|
||||
*start += 1;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
while (status == NSS_STATUS_SUCCESS);
|
||||
|
||||
done:
|
||||
if (endgrent_fct)
|
||||
DL_CALL_FCT (endgrent_fct, ());
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
Reference in New Issue
Block a user