Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Implement caching of nscd
  • Loading branch information
Ulrich Drepper committed Oct 7, 2011
1 parent 21fd49a commit 684ae51
Show file tree
Hide file tree
Showing 19 changed files with 1,196 additions and 30 deletions.
40 changes: 40 additions & 0 deletions ChangeLog
@@ -1,5 +1,45 @@
2011-10-07 Ulrich Drepper <drepper@gmail.com>

* inet/getnetgrent_r.c: Hook up nscd.
* nscd/Makefile (routines): Add nscd_netgroup.
(nscd-modules): Add netgroupcache.
(CFLAGS-netgroupcache.c): Define.
* nscd/cache.c (readdfcts): Add entries for GETNETGRENT and INNETGR.
(cache_search): Add const to second parameter.
* nscd/connections.c (serv2str): Add entries for GETNETGRENT and
INNETGR.
(dbs): Add netgrdb entry.
(reqinfo): Add entries for GETNETGRENT, INNETGR, and GETFDNETGR.
(verify_persistent_db): Handle netgrdb.
(handle_request): Handle GETNETGRENT, INNETGR, and GETFDNETGR.
* nscd/nscd-client.h (request_type): Add GETNETGRENT, INNETGR, and
GETFDNETGR.
(netgroup_response_header): Define.
(innetgroup_response_header): Define.
(datahead): Add netgroup_response_header and innetgroup_response_header
elements.
* nscd/nscd.conf: Add entries for netgroup cache.
* nscd/nscd.h (dbtype): Add netgrdb.
(_PATH_NSCD_NETGROUP_DB): Define.
(netgroup_iov_disabled): Declare.
(xmalloc, xcalloc, xrealloc): Move declarations here.
(cache_search): Adjust prototype.
Add netgroup-related prototypes.
* nscd/nscd_conf.c (dbnames): Add netgrdb entry.
* nscd/nscd_proto.h (__nss_not_use_nscd_netgroup): Declare.
(__nscd_innetgr): Declare.
* nscd/selinux.c (perms): Use access_vector_t as element type and
add netgroup-related initializers.
* nscd/netgroupcache.c: New file.
* nscd/nscd_netgroup.c: New file.
* nss/Versions [libc] (GLIBC_PRIVATE): Export __nss_lookup.
* nss/getent.c (netgroup_keys): Use setnetgrent only for one parameter.
For four parameters use innetgr.
* nss/nss_files/files-init.c: Add definition and callback for netgr.
* nss/nsswitch.c (__nss_lookup): Add libc_hidden_def.
(__nss_disable_nscd): Set __nss_not_use_nscd_netgroup.
* nss/nsswitch.h (__nss_lookup): Add libc_hidden_proto.

* nscd/connections.c (register_traced_file): Don't register file
for disabled databases.

Expand Down
5 changes: 4 additions & 1 deletion NEWS
@@ -1,4 +1,4 @@
GNU C Library NEWS -- history of user-visible changes. 2011-9-11
GNU C Library NEWS -- history of user-visible changes. 2011-10-7
Copyright (C) 1992-2009, 2010, 2011 Free Software Foundation, Inc.
See the end for copying conditions.

Expand Down Expand Up @@ -38,6 +38,9 @@ Version 2.15

* Checking versions of FD_SET, FD_CLR, and FD_ISSET added.
Implemented by Ulrich Drepper.

* nscd now also caches the netgroup database.
Implemented by Ulrich Drepper.

Version 2.14

Expand Down
65 changes: 60 additions & 5 deletions inet/getnetgrent_r.c
Expand Up @@ -28,6 +28,7 @@
#include "netgroup.h"
#include "nsswitch.h"
#include <sysdep.h>
#include <nscd/nscd_proto.h>


/* Protect above variable against multiple uses at the same time. */
Expand Down Expand Up @@ -101,7 +102,7 @@ endnetgrent_hook (struct __netgrent *datap)
{
enum nss_status (*endfct) (struct __netgrent *);

if (datap->nip == NULL)
if (datap->nip == NULL || datap->nip == (service_user *) -1l)
return;

endfct = __nss_lookup_function (datap->nip, "endnetgrent");
Expand Down Expand Up @@ -189,8 +190,21 @@ setnetgrent (const char *group)

__libc_lock_lock (lock);

if (__nss_not_use_nscd_netgroup > 0
&& ++__nss_not_use_nscd_netgroup > NSS_NSCD_RETRY)
__nss_not_use_nscd_netgroup = 0;

if (!__nss_not_use_nscd_netgroup
&& !__nss_database_custom[NSS_DBSIDX_netgroup])
{
result = __nscd_setnetgrent (group, &dataset);
if (result >= 0)
goto out;
}

result = internal_setnetgrent (group, &dataset);

out:
__libc_lock_unlock (lock);

return result;
Expand Down Expand Up @@ -226,6 +240,26 @@ int internal_getnetgrent_r (char **hostp, char **userp, char **domainp,
char *buffer, size_t buflen, int *errnop);
libc_hidden_proto (internal_getnetgrent_r)


static enum nss_status
nscd_getnetgrent (struct __netgrent *datap, char *buffer, size_t buflen,
int *errnop)
{
if (datap->cursor >= datap->data + datap->data_size)
return NSS_STATUS_UNAVAIL;

datap->type = triple_val;
datap->val.triple.host = datap->cursor;
datap->cursor = (char *) rawmemchr (datap->cursor, '\0') + 1;
datap->val.triple.user = datap->cursor;
datap->cursor = (char *) rawmemchr (datap->cursor, '\0') + 1;
datap->val.triple.domain = datap->cursor;
datap->cursor = (char *) rawmemchr (datap->cursor, '\0') + 1;

return NSS_STATUS_SUCCESS;
}


int
internal_getnetgrent_r (char **hostp, char **userp, char **domainp,
struct __netgrent *datap,
Expand All @@ -239,9 +273,18 @@ internal_getnetgrent_r (char **hostp, char **userp, char **domainp,
/* Run through available functions, starting with the same function last
run. We will repeat each function as long as it succeeds, and then go
on to the next service action. */
int no_more = (datap->nip == NULL
|| (fct = __nss_lookup_function (datap->nip, "getnetgrent_r"))
== NULL);
int no_more = datap->nip == NULL;
if (! no_more)
{
if (datap->nip == (service_user *) -1l)
fct = nscd_getnetgrent;
else
{
fct = __nss_lookup_function (datap->nip, "getnetgrent_r");
no_more = fct == NULL;
}
}

while (! no_more)
{
status = DL_CALL_FCT (*fct, (datap, buffer, buflen, &errno));
Expand Down Expand Up @@ -342,6 +385,18 @@ int
innetgr (const char *netgroup, const char *host, const char *user,
const char *domain)
{
if (__nss_not_use_nscd_netgroup > 0
&& ++__nss_not_use_nscd_netgroup > NSS_NSCD_RETRY)
__nss_not_use_nscd_netgroup = 0;

if (!__nss_not_use_nscd_netgroup
&& !__nss_database_custom[NSS_DBSIDX_netgroup])
{
int result = __nscd_innetgr (netgroup, host, user, domain);
if (result >= 0)
return result;
}

union
{
enum nss_status (*f) (const char *, struct __netgrent *);
Expand Down Expand Up @@ -453,7 +508,7 @@ innetgr (const char *netgroup, const char *host, const char *user,
entry.needed_groups = tmp->next;
tmp->next = entry.known_groups;
entry.known_groups = tmp;
current_group = entry.known_groups->name;
current_group = tmp->name;
continue;
}

Expand Down
6 changes: 4 additions & 2 deletions nscd/Makefile
Expand Up @@ -22,7 +22,7 @@
subdir := nscd

routines := nscd_getpw_r nscd_getgr_r nscd_gethst_r nscd_getai \
nscd_initgroups nscd_getserv_r
nscd_initgroups nscd_getserv_r nscd_netgroup
aux := nscd_helper

include ../Makeconfig
Expand All @@ -34,7 +34,8 @@ nscd-modules := nscd connections pwdcache getpwnam_r getpwuid_r grpcache \
getgrnam_r getgrgid_r hstcache gethstbyad_r gethstbynm3_r \
getsrvbynm_r getsrvbypt_r servicescache \
dbg_log nscd_conf nscd_stat cache mem nscd_setup_thread \
xmalloc xstrdup aicache initgrcache gai res_hconf
xmalloc xstrdup aicache initgrcache gai res_hconf \
netgroupcache

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

Expand Down Expand Up @@ -121,6 +122,7 @@ CFLAGS-servicescache.c += $(nscd-cflags)
CFLAGS-getsrvbynm_r.c += $(nscd-cflags)
CFLAGS-getsrvbypt_r.c += $(nscd-cflags)
CFLAGS-res_hconf.c += $(nscd-cflags)
CFLAGS-netgroupcache.c += $(nscd-cflags)

ifeq (yesyes,$(have-fpie)$(build-shared))
LDFLAGS-nscd = -Wl,-z,now
Expand Down
6 changes: 4 additions & 2 deletions nscd/cache.c
Expand Up @@ -60,7 +60,9 @@ static time_t (*const readdfcts[LASTREQ]) (struct database_dyn *,
[GETAI] = readdhstai,
[INITGROUPS] = readdinitgroups,
[GETSERVBYNAME] = readdservbyname,
[GETSERVBYPORT] = readdservbyport
[GETSERVBYPORT] = readdservbyport,
[GETNETGRENT] = readdgetnetgrent,
[INNETGR] = readdinnetgr
};


Expand All @@ -70,7 +72,7 @@ static time_t (*const readdfcts[LASTREQ]) (struct database_dyn *,
This function must be called with the read-lock held. */
struct datahead *
cache_search (request_type type, void *key, size_t len,
cache_search (request_type type, const void *key, size_t len,
struct database_dyn *table, uid_t owner)
{
unsigned long int hash = __nis_hash (key, len) % table->head->module;
Expand Down
46 changes: 38 additions & 8 deletions nscd/connections.c
Expand Up @@ -57,11 +57,6 @@
#endif


/* Wrapper functions with error checking for standard functions. */
extern void *xmalloc (size_t n);
extern void *xcalloc (size_t n, size_t s);
extern void *xrealloc (void *o, size_t n);

/* Support to run nscd as an unprivileged user */
const char *server_user;
static uid_t server_uid;
Expand Down Expand Up @@ -100,7 +95,10 @@ const char *const serv2str[LASTREQ] =
[INITGROUPS] = "INITGROUPS",
[GETSERVBYNAME] = "GETSERVBYNAME",
[GETSERVBYPORT] = "GETSERVBYPORT",
[GETFDSERV] = "GETFDSERV"
[GETFDSERV] = "GETFDSERV",
[GETNETGRENT] = "GETNETGRENT",
[INNETGR] = "INNETGR",
[GETFDNETGR] = "GETFDNETGR"
};

/* The control data structures for the services. */
Expand Down Expand Up @@ -181,6 +179,25 @@ struct database_dyn dbs[lastdb] =
.wr_fd = -1,
.ro_fd = -1,
.mmap_used = false
},
[netgrdb] = {
.lock = PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP,
.prune_lock = PTHREAD_MUTEX_INITIALIZER,
.prune_run_lock = PTHREAD_MUTEX_INITIALIZER,
.enabled = 0,
.check_file = 1,
.persistent = 0,
.propagate = 0, /* Not used. */
.shared = 0,
.max_db_size = DEFAULT_MAX_DB_SIZE,
.suggested_module = DEFAULT_SUGGESTED_MODULE,
.db_filename = _PATH_NSCD_NETGROUP_DB,
.disabled_iov = &netgroup_iov_disabled,
.postimeout = 28800,
.negtimeout = 20,
.wr_fd = -1,
.ro_fd = -1,
.mmap_used = false
}
};

Expand Down Expand Up @@ -210,7 +227,10 @@ static struct
[INITGROUPS] = { true, &dbs[grpdb] },
[GETSERVBYNAME] = { true, &dbs[servdb] },
[GETSERVBYPORT] = { true, &dbs[servdb] },
[GETFDSERV] = { false, &dbs[servdb] }
[GETFDSERV] = { false, &dbs[servdb] },
[GETNETGRENT] = { true, &dbs[netgrdb] },
[INNETGR] = { true, &dbs[netgrdb] },
[GETFDNETGR] = { false, &dbs[netgrdb] }
};


Expand Down Expand Up @@ -355,7 +375,8 @@ check_use (const char *data, nscd_ssize_t first_free, uint8_t *usemap,
static int
verify_persistent_db (void *mem, struct database_pers_head *readhead, int dbnr)
{
assert (dbnr == pwddb || dbnr == grpdb || dbnr == hstdb || dbnr == servdb);
assert (dbnr == pwddb || dbnr == grpdb || dbnr == hstdb || dbnr == servdb
|| dbnr == netgrdb);

time_t now = time (NULL);

Expand Down Expand Up @@ -1230,6 +1251,14 @@ request from '%s' [%ld] not handled due to missing permission"),
addservbyport (db, fd, req, key, uid);
break;

case GETNETGRENT:
addgetnetgrent (db, fd, req, key, uid);
break;

case INNETGR:
addinnetgr (db, fd, req, key, uid);
break;

case GETSTAT:
case SHUTDOWN:
case INVALIDATE:
Expand Down Expand Up @@ -1276,6 +1305,7 @@ request from '%s' [%ld] not handled due to missing permission"),
case GETFDGR:
case GETFDHST:
case GETFDSERV:
case GETFDNETGR:
#ifdef SCM_RIGHTS
send_ro_fd (reqinfo[req->type].db, key, fd);
#endif
Expand Down

0 comments on commit 684ae51

Please sign in to comment.