Skip to content

Commit

Permalink
Update.
Browse files Browse the repository at this point in the history
	* 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.
  • Loading branch information
Ulrich Drepper committed Sep 30, 2004
1 parent 04c785b commit f7e7a39
Show file tree
Hide file tree
Showing 17 changed files with 738 additions and 108 deletions.
24 changes: 24 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,5 +1,29 @@
2004-09-29 Ulrich Drepper <drepper@redhat.com>

* 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.

* nscd/nscd.c: Define getaddrinfo hidden so that it is never found
outside.

Expand Down
4 changes: 2 additions & 2 deletions grp/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
subdir := grp
headers := grp.h

distribute := tst_fgetgrent.c tst_fgetgrent.sh
distribute := tst_fgetgrent.c tst_fgetgrent.sh compat-initgroups.c

routines := fgetgrent initgroups setgroups \
getgrent getgrgid getgrnam putgrent \
Expand Down Expand Up @@ -54,7 +54,7 @@ CFLAGS-getgrent.c = -fexceptions
CFLAGS-fgetgrent.c = -fexceptions
CFLAGS-fgetgrent_r.c = -fexceptions -D_IO_MTSAFE_IO
CFLAGS-putgrent.c = -fexceptions -D_IO_MTSAFE_IO
CFLAGS-initgroups.c = -fexceptions
CFLAGS-initgroups.c = -DUSE_NSCD=1 -fexceptions
CFLAGS-getgrgid.c = -fexceptions

endif
Expand Down
98 changes: 98 additions & 0 deletions grp/compat-initgroups.c
Original file line number Diff line number Diff line change
@@ -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;
}
119 changes: 24 additions & 95 deletions grp/initgroups.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,19 +27,14 @@
#include <sys/types.h>
#include <nsswitch.h>

#include "../nscd/nscd-client.h"
#include "../nscd/nscd_proto.h"


/* Type of the lookup function. */
typedef enum nss_status (*initgroups_dyn_function) (const char *, gid_t,
long int *, long int *,
gid_t **, long int, int *);
/* 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 *);

/* The lookup function for the first entry of this service. */
extern int __nss_group_lookup (service_user **nip, const char *name,
Expand All @@ -48,99 +43,29 @@ extern void *__nss_lookup_function (service_user *ni, const char *fct_name);

extern service_user *__nss_group_database attribute_hidden;

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");
#include "compat-initgroups.c"

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;
}

static int
internal_getgrouplist (const char *user, gid_t group, long int *size,
gid_t **groupsp, long int limit)
{
#ifdef USE_NSCD
if (__nss_not_use_nscd_group > 0
&& ++__nss_not_use_nscd_group > NSS_NSCD_RETRY)
__nss_not_use_nscd_group = 0;
if (!__nss_not_use_nscd_group)
{
int n = __nscd_getgrouplist (user, group, size, groupsp, limit);
if (n >= 0)
return n;

/* nscd is not usable. */
__nss_not_use_nscd_group = 1;
}
#endif

service_user *nip = NULL;
initgroups_dyn_function fct;
enum nss_status status = NSS_STATUS_UNAVAIL;
Expand Down Expand Up @@ -205,6 +130,10 @@ getgrouplist (const char *user, gid_t group, gid_t *groups, int *ngroups)
newgroups = (gid_t *) malloc (size * sizeof (gid_t));
if (__builtin_expect (newgroups == NULL, 0))
/* No more memory. */
// XXX This is wrong. The user provided memory, we have to use
// XXX it. The internal functions must be called with the user
// XXX provided buffer and not try to increase the size if it is
// XXX too small. For initgroups a flag could say: increase size.
return -1;

result = internal_getgrouplist (user, group, &size, &newgroups, -1);
Expand Down
4 changes: 2 additions & 2 deletions nscd/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
#
subdir := nscd

routines := nscd_getpw_r nscd_getgr_r nscd_gethst_r nscd_getai
routines := nscd_getpw_r nscd_getgr_r nscd_gethst_r nscd_getai nscd_initgroups
aux := nscd_helper

include ../Makeconfig
Expand All @@ -32,7 +32,7 @@ vpath %.c ../locale/programs
nscd-modules := nscd connections pwdcache getpwnam_r getpwuid_r grpcache \
getgrnam_r getgrgid_r hstcache gethstbyad_r gethstbynm2_r \
dbg_log nscd_conf nscd_stat cache mem nscd_setup_thread \
xmalloc xstrdup aicache
xmalloc xstrdup aicache initgrcache

ifeq ($(have-thread-library),yes)

Expand Down
4 changes: 4 additions & 0 deletions nscd/cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,10 @@ prune_cache (struct database_dyn *table, time_t now)
readdhstai (table, runp, dh);
break;

case INITGROUPS:
readdinitgroups (table, runp, dh);
break;

default:
assert (! "should never happen");
}
Expand Down
12 changes: 10 additions & 2 deletions nscd/connections.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,8 @@ const char *serv2str[LASTREQ] =
[GETFDPW] = "GETFDPW",
[GETFDGR] = "GETFDGR",
[GETFDHST] = "GETFDHST",
[GETAI] = "GETAI"
[GETAI] = "GETAI",
[INITGROUPS] = "INITGROUPS"
};

/* The control data structures for the services. */
Expand Down Expand Up @@ -154,6 +155,7 @@ static struct database_dyn *const serv2db[LASTREQ] =
[GETFDGR] = &dbs[grpdb],
[GETFDHST] = &dbs[hstdb],
[GETAI] = &dbs[hstdb],
[INITGROUPS] = &dbs[grpdb]
};


Expand Down Expand Up @@ -604,9 +606,11 @@ cannot handle old request version %d; current version is %d"),

struct database_dyn *db = serv2db[req->type];

// XXX Clean up so that each new command need not introduce a
// XXX new conditional.
if ((__builtin_expect (req->type, GETPWBYNAME) >= GETPWBYNAME
&& __builtin_expect (req->type, LASTDBREQ) <= LASTDBREQ)
|| req->type == GETAI)
|| req->type == GETAI || req->type == INITGROUPS)
{
if (__builtin_expect (debug_level, 0) > 0)
{
Expand Down Expand Up @@ -719,6 +723,10 @@ cannot handle old request version %d; current version is %d"),
addhstai (db, fd, req, key, uid);
break;

case INITGROUPS:
addinitgroups (db, fd, req, key, uid);
break;

case GETSTAT:
case SHUTDOWN:
case INVALIDATE:
Expand Down
Loading

0 comments on commit f7e7a39

Please sign in to comment.