mirror of
https://sourceware.org/git/glibc.git
synced 2025-12-24 17:51:17 +03:00
Generalize framework to register monitoring of files in nscd
nscd can clear caches when certain files change. The list of files was hardcoded so far and worked for nss_files and nss_dns and those modules which need no monitoring. nss_db, for instance, has its own set of files to monitor. Now the NSS modules themselves can request that certain files are monitored.
This commit is contained in:
@@ -66,14 +66,14 @@ vpath %.c $(subdir-dirs) ../locale/programs ../intl
|
||||
|
||||
|
||||
libnss_files-routines := $(addprefix files-,$(databases)) \
|
||||
files-initgroups files-have_o_cloexec
|
||||
files-initgroups files-have_o_cloexec files-init
|
||||
distribute += files-XXX.c files-parse.c
|
||||
|
||||
libnss_db-dbs := $(addprefix db-,\
|
||||
$(filter-out hosts network key alias,\
|
||||
$(databases))) \
|
||||
db-initgroups
|
||||
libnss_db-routines := $(libnss_db-dbs) db-open hash-string
|
||||
libnss_db-routines := $(libnss_db-dbs) db-open db-init hash-string
|
||||
generated += $(filter-out db-alias.c db-netgrp.c, \
|
||||
$(addsuffix .c,$(libnss_db-dbs)))
|
||||
distribute += $(addprefix nss_db/, db-XXX.c nss_db.h)
|
||||
|
||||
@@ -97,6 +97,8 @@ libnss_files {
|
||||
_nss_files_getsecretkey;
|
||||
|
||||
_nss_files_initgroups_dyn;
|
||||
|
||||
_nss_files_init;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -153,5 +155,7 @@ libnss_db {
|
||||
_nss_db_getspnam_r;
|
||||
|
||||
_nss_db_initgroups_dyn;
|
||||
|
||||
_nss_db_init;
|
||||
}
|
||||
}
|
||||
|
||||
54
nss/nss_db/db-init.c
Normal file
54
nss/nss_db/db-init.c
Normal file
@@ -0,0 +1,54 @@
|
||||
/* Initialization in nss_db module.
|
||||
Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <paths.h>
|
||||
#include <nscd/nscd.h>
|
||||
|
||||
|
||||
static union
|
||||
{
|
||||
struct traced_file file;
|
||||
char buf[sizeof (struct traced_file) + sizeof (_PATH_VARDB "passwd.db")];
|
||||
} pwd_traced_file;
|
||||
|
||||
static union
|
||||
{
|
||||
struct traced_file file;
|
||||
char buf[sizeof (struct traced_file) + sizeof (_PATH_VARDB "group.db")];
|
||||
} grp_traced_file;
|
||||
|
||||
static union
|
||||
{
|
||||
struct traced_file file;
|
||||
char buf[sizeof (struct traced_file) + sizeof (_PATH_VARDB "services.db")];
|
||||
} serv_traced_file;
|
||||
|
||||
|
||||
void
|
||||
_nss_db_init (void (*cb) (size_t, struct traced_file *))
|
||||
{
|
||||
strcpy (pwd_traced_file.file.fname,_PATH_VARDB "passwd.db");
|
||||
cb (pwddb, &pwd_traced_file.file);
|
||||
|
||||
strcpy (grp_traced_file.file.fname, _PATH_VARDB "group.db");
|
||||
cb (grpdb, &grp_traced_file.file);
|
||||
|
||||
strcpy (serv_traced_file.file.fname, _PATH_VARDB "services.db");
|
||||
cb (servdb, &serv_traced_file.file);
|
||||
}
|
||||
72
nss/nss_files/files-init.c
Normal file
72
nss/nss_files/files-init.c
Normal file
@@ -0,0 +1,72 @@
|
||||
/* Initialization in nss_files module.
|
||||
Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <nscd/nscd.h>
|
||||
|
||||
|
||||
static union
|
||||
{
|
||||
struct traced_file file;
|
||||
char buf[sizeof (struct traced_file) + sizeof ("/etc/passwd")];
|
||||
} pwd_traced_file;
|
||||
|
||||
static union
|
||||
{
|
||||
struct traced_file file;
|
||||
char buf[sizeof (struct traced_file) + sizeof ("/etc/group")];
|
||||
} grp_traced_file;
|
||||
|
||||
static union
|
||||
{
|
||||
struct traced_file file;
|
||||
char buf[sizeof (struct traced_file) + sizeof ("/etc/hosts")];
|
||||
} hst_traced_file;
|
||||
|
||||
static union
|
||||
{
|
||||
struct traced_file file;
|
||||
char buf[sizeof (struct traced_file) + sizeof ("/etc/resolv.conf")];
|
||||
} resolv_traced_file;
|
||||
|
||||
static union
|
||||
{
|
||||
struct traced_file file;
|
||||
char buf[sizeof (struct traced_file) + sizeof ("/etc/services")];
|
||||
} serv_traced_file;
|
||||
|
||||
|
||||
void
|
||||
_nss_files_init (void (*cb) (size_t, struct traced_file *))
|
||||
{
|
||||
strcpy (pwd_traced_file.file.fname, "/etc/passwd");
|
||||
cb (pwddb, &pwd_traced_file.file);
|
||||
|
||||
strcpy (grp_traced_file.file.fname, "/etc/group");
|
||||
cb (grpdb, &grp_traced_file.file);
|
||||
|
||||
strcpy (hst_traced_file.file.fname, "/etc/hosts");
|
||||
cb (hstdb, &hst_traced_file.file);
|
||||
|
||||
resolv_traced_file.file.call_res_init = 1;
|
||||
strcpy (resolv_traced_file.file.fname, "/etc/resolv.conf");
|
||||
cb (hstdb, &resolv_traced_file.file);
|
||||
|
||||
strcpy (serv_traced_file.file.fname, "/etc/services");
|
||||
cb (servdb, &serv_traced_file.file);
|
||||
}
|
||||
165
nss/nsswitch.c
165
nss/nsswitch.c
@@ -1,4 +1,5 @@
|
||||
/* Copyright (C) 1996-1999,2001-2007,2009,2010 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1996-1999,2001-2007,2009,2010,2011
|
||||
Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
|
||||
|
||||
@@ -40,6 +41,7 @@
|
||||
|
||||
#include "nsswitch.h"
|
||||
#include "../nscd/nscd_proto.h"
|
||||
#include <sysdep.h>
|
||||
|
||||
/* Prototypes for the local functions. */
|
||||
static name_database *nss_parse_file (const char *fname) internal_function;
|
||||
@@ -86,6 +88,12 @@ static const char *const __nss_shlib_revision = LIBNSS_FILES_SO + 15;
|
||||
static name_database *service_table;
|
||||
|
||||
|
||||
/* Nonzero if this is the nscd process. */
|
||||
static bool is_nscd;
|
||||
/* The callback passed to the init functions when nscd is used. */
|
||||
static void (*nscd_init_cb) (size_t, struct traced_file *);
|
||||
|
||||
|
||||
/* -1 == database not found
|
||||
0 == database entry pointer stored */
|
||||
int
|
||||
@@ -129,7 +137,7 @@ __nss_database_lookup (const char *database, const char *alternate_name,
|
||||
}
|
||||
|
||||
/* No configuration data is available, either because nsswitch.conf
|
||||
doesn't exist or because it doesn't has a line for this database.
|
||||
doesn't exist or because it doesn't have a line for this database.
|
||||
|
||||
DEFCONFIG specifies the default service list for this database,
|
||||
or null to use the most common default. */
|
||||
@@ -285,6 +293,79 @@ known_compare (const void *p1, const void *p2)
|
||||
}
|
||||
|
||||
|
||||
#if !defined DO_STATIC_NSS || defined SHARED
|
||||
/* Load library. */
|
||||
static int
|
||||
nss_load_library (service_user *ni)
|
||||
{
|
||||
if (ni->library == NULL)
|
||||
{
|
||||
/* This service has not yet been used. Fetch the service
|
||||
library for it, creating a new one if need be. If there
|
||||
is no service table from the file, this static variable
|
||||
holds the head of the service_library list made from the
|
||||
default configuration. */
|
||||
static name_database default_table;
|
||||
ni->library = nss_new_service (service_table ?: &default_table,
|
||||
ni->name);
|
||||
if (ni->library == NULL)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ni->library->lib_handle == NULL)
|
||||
{
|
||||
/* Load the shared library. */
|
||||
size_t shlen = (7 + strlen (ni->library->name) + 3
|
||||
+ strlen (__nss_shlib_revision) + 1);
|
||||
int saved_errno = errno;
|
||||
char shlib_name[shlen];
|
||||
|
||||
/* Construct shared object name. */
|
||||
__stpcpy (__stpcpy (__stpcpy (__stpcpy (shlib_name,
|
||||
"libnss_"),
|
||||
ni->library->name),
|
||||
".so"),
|
||||
__nss_shlib_revision);
|
||||
|
||||
ni->library->lib_handle = __libc_dlopen (shlib_name);
|
||||
if (ni->library->lib_handle == NULL)
|
||||
{
|
||||
/* Failed to load the library. */
|
||||
ni->library->lib_handle = (void *) -1l;
|
||||
__set_errno (saved_errno);
|
||||
}
|
||||
else if (is_nscd)
|
||||
{
|
||||
/* Call the init function when nscd is used. */
|
||||
size_t initlen = (5 + strlen (ni->library->name)
|
||||
+ strlen ("_init") + 1);
|
||||
char init_name[initlen];
|
||||
|
||||
/* Construct the init function name. */
|
||||
__stpcpy (__stpcpy (__stpcpy (init_name,
|
||||
"_nss_"),
|
||||
ni->library->name),
|
||||
"_init");
|
||||
|
||||
/* Find the optional init function. */
|
||||
void (*ifct) (void (*) (size_t, struct traced_file *))
|
||||
= __libc_dlsym (ni->library->lib_handle, init_name);
|
||||
if (ifct != NULL)
|
||||
{
|
||||
void (*cb) (size_t, struct traced_file *) = nscd_init_cb;
|
||||
# ifdef PTR_DEMANGLE
|
||||
PTR_DEMANGLE (cb);
|
||||
# endif
|
||||
ifct (cb);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void *
|
||||
__nss_lookup_function (service_user *ni, const char *fct_name)
|
||||
{
|
||||
@@ -331,47 +412,13 @@ __nss_lookup_function (service_user *ni, const char *fct_name)
|
||||
*found = known;
|
||||
known->fct_name = fct_name;
|
||||
|
||||
if (ni->library == NULL)
|
||||
{
|
||||
/* This service has not yet been used. Fetch the service
|
||||
library for it, creating a new one if need be. If there
|
||||
is no service table from the file, this static variable
|
||||
holds the head of the service_library list made from the
|
||||
default configuration. */
|
||||
static name_database default_table;
|
||||
ni->library = nss_new_service (service_table ?: &default_table,
|
||||
ni->name);
|
||||
if (ni->library == NULL)
|
||||
{
|
||||
/* This only happens when out of memory. */
|
||||
free (known);
|
||||
goto remove_from_tree;
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined DO_STATIC_NSS || defined SHARED
|
||||
if (ni->library->lib_handle == NULL)
|
||||
/* Load the appropriate library. */
|
||||
if (nss_load_library (ni) != 0)
|
||||
{
|
||||
/* Load the shared library. */
|
||||
size_t shlen = (7 + strlen (ni->library->name) + 3
|
||||
+ strlen (__nss_shlib_revision) + 1);
|
||||
int saved_errno = errno;
|
||||
char shlib_name[shlen];
|
||||
|
||||
/* Construct shared object name. */
|
||||
__stpcpy (__stpcpy (__stpcpy (__stpcpy (shlib_name,
|
||||
"libnss_"),
|
||||
ni->library->name),
|
||||
".so"),
|
||||
__nss_shlib_revision);
|
||||
|
||||
ni->library->lib_handle = __libc_dlopen (shlib_name);
|
||||
if (ni->library->lib_handle == NULL)
|
||||
{
|
||||
/* Failed to load the library. */
|
||||
ni->library->lib_handle = (void *) -1l;
|
||||
__set_errno (saved_errno);
|
||||
}
|
||||
/* This only happens when out of memory. */
|
||||
free (known);
|
||||
goto remove_from_tree;
|
||||
}
|
||||
|
||||
if (ni->library->lib_handle == (void *) -1l)
|
||||
@@ -463,7 +510,10 @@ nss_parse_file (const char *fname)
|
||||
|
||||
result = (name_database *) malloc (sizeof (name_database));
|
||||
if (result == NULL)
|
||||
return NULL;
|
||||
{
|
||||
fclose (fp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
result->entry = NULL;
|
||||
result->library = NULL;
|
||||
@@ -724,16 +774,45 @@ nss_new_service (name_database *database, const char *name)
|
||||
}
|
||||
|
||||
|
||||
#ifdef SHARED
|
||||
/* Load all libraries for the service. */
|
||||
static void
|
||||
nss_load_all_libraries (const char *service, const char *def)
|
||||
{
|
||||
service_user *ni = NULL;
|
||||
|
||||
if (__nss_database_lookup (service, NULL, def, &ni) == 0)
|
||||
while (ni != NULL)
|
||||
{
|
||||
nss_load_library (ni);
|
||||
ni = ni->next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Called by nscd and nscd alone. */
|
||||
void
|
||||
__nss_disable_nscd (void)
|
||||
__nss_disable_nscd (void (*cb) (size_t, struct traced_file *))
|
||||
{
|
||||
# ifdef PTR_MANGLE
|
||||
PTR_MANGLE (cb);
|
||||
# endif
|
||||
nscd_init_cb = cb;
|
||||
is_nscd = true;
|
||||
|
||||
/* Find all the relevant modules so that the init functions are called. */
|
||||
nss_load_all_libraries ("passwd", "compat [NOTFOUND=return] files");
|
||||
nss_load_all_libraries ("group", "compat [NOTFOUND=return] files");
|
||||
nss_load_all_libraries ("hosts", "dns [!UNAVAIL=return] files");
|
||||
nss_load_all_libraries ("services", NULL);
|
||||
|
||||
/* Disable all uses of NSCD. */
|
||||
__nss_not_use_nscd_passwd = -1;
|
||||
__nss_not_use_nscd_group = -1;
|
||||
__nss_not_use_nscd_hosts = -1;
|
||||
__nss_not_use_nscd_services = -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* Free all resources if necessary. */
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 1996-1999,2001,2002,2003,2004,2007,2010
|
||||
/* Copyright (C) 1996-1999,2001,2002,2003,2004,2007,2010,2011
|
||||
Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
@@ -153,8 +153,10 @@ extern void *__nss_lookup_function (service_user *ni, const char *fct_name);
|
||||
libc_hidden_proto (__nss_lookup_function)
|
||||
|
||||
|
||||
/* Called by NSCD to disable recursive calls. */
|
||||
extern void __nss_disable_nscd (void);
|
||||
/* Called by NSCD to disable recursive calls and enable special handling
|
||||
when used in nscd. */
|
||||
struct traced_file;
|
||||
extern void __nss_disable_nscd (void (*) (size_t, struct traced_file *));
|
||||
|
||||
|
||||
typedef int (*db_lookup_function) (service_user **, const char *, const char *,
|
||||
|
||||
Reference in New Issue
Block a user