1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-08-01 10:06:57 +03:00

Last minute change.

Mon Aug 12 04:33:09 1996  Ulrich Drepper  <drepper@cygnus.com>

	* nss/nsswitch.c (__nss_database_lookup): Always release locks
 	before returning.  Reported by Miles Bader.

	(distributes): Add databases.def.
This commit is contained in:
Ulrich Drepper
1996-08-12 02:44:03 +00:00
parent a3e59be8d1
commit a8874eadae
16 changed files with 272 additions and 80 deletions

View File

@ -21,13 +21,16 @@
#
subdir := nss
headers := nss.h
distribute := nsswitch.h XXX-lookup.c getXXbyYY.c getXXbyYY_r.c \
getXXent.c getXXent_r.c
getXXent.c getXXent_r.c databases.def
# This is the trivial part which goes into libc itself.
routines = nsswitch $(addsuffix -lookup,$(databases))
# These are the databases that go through nss dispatch.
# Caution: if you add a database here, you must add its real name
# in databases.def, too.
databases = proto service hosts network grp pwd rpc ethers \
spwd

View File

@ -35,25 +35,26 @@ Boston, MA 02111-1307, USA. */
#define CONCAT3_1(Pre, Name, Post) CONCAT3_2 (Pre, Name, Post)
#define CONCAT3_2(Pre, Name, Post) Pre##Name##Post
#define DATABASE_NAME_SYMBOL CONCAT3_1 (__nss_, DATABASE_NAME, _database)
#define DATABASE_NAME_STRING STRINGIFY1 (DATABASE_NAME)
#define STRINGIFY1(Name) STRINGIFY2 (Name)
#define STRINGIFY2(Name) #Name
#ifndef DEFAULT_CONFIG
#define DEFAULT_CONFIG 0
#define DEFAULT_CONFIG NULL
#endif
static service_user *database = NULL;
service_user *DATABASE_NAME_SYMBOL = NULL;
int
DB_LOOKUP_FCT (service_user **ni, const char *fct_name, void **fctp)
{
if (database == NULL
if (DATABASE_NAME_SYMBOL == NULL
&& __nss_database_lookup (DATABASE_NAME_STRING, DEFAULT_CONFIG,
&database) < 0)
&DATABASE_NAME_SYMBOL) < 0)
return -1;
*ni = database;
*ni = DATABASE_NAME_SYMBOL;
return __nss_lookup (ni, fct_name, fctp);
}

31
nss/databases.def Normal file
View File

@ -0,0 +1,31 @@
/* List of all databases defined for the NSS in GNU C Library.
Copyright (C) 1996 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* This list must be kept sorted!!! */
DEFINE_DATABASE (ethers)
DEFINE_DATABASE (group)
DEFINE_DATABASE (hosts)
DEFINE_DATABASE (networks)
DEFINE_DATABASE (passwd)
DEFINE_DATABASE (protocols)
DEFINE_DATABASE (rpc)
DEFINE_DATABASE (services)
DEFINE_DATABASE (shadow)

54
nss/nss.h Normal file
View File

@ -0,0 +1,54 @@
/* Copyright (C) 1996 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 Library General Public License as
published by the Free Software Foundation; either version 2 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* Define interface to NSS. This is meant for the interface functions
and for implementors of new services. */
#ifndef _NSS_H
#define _NSS_H 1
#include <features.h>
/* Revision number of NSS interface (must be a string). */
#define NSS_SHLIB_REVISION ".1"
__BEGIN_DECLS
/* Possible results of lookup using a nss_* function. */
enum nss_status
{
NSS_STATUS_TRYAGAIN = -2,
NSS_STATUS_UNAVAIL,
NSS_STATUS_NOTFOUND,
NSS_STATUS_SUCCESS,
};
/* Overwrite service selection for database DBNAME using specification
in STRING.
This function should only be used by system programs which have to
work around non-existing services (e.e., while booting).
Attention: Using this function repeatedly will slowly eat up the
whole memory since previous selection data cannot be freed. */
extern int __nss_configure_lookup __P ((__const char *__dbname,
__const char *__string));
__END_DECLS
#endif /* nss.h */

View File

@ -19,6 +19,7 @@ Boston, MA 02111-1307, USA. */
#include <ctype.h>
#include <dlfcn.h>
#include <errno.h>
#include <netdb.h>
#include <libc-lock.h>
#include <search.h>
@ -30,7 +31,6 @@ Boston, MA 02111-1307, USA. */
#include "../elf/link.h" /* We need some help from ld.so. */
/* Prototypes for the local functions. */
static void nss_init (void);
static void *nss_lookup_function (service_user *ni, const char *fct_name);
static name_database *nss_parse_file (const char *fname);
static name_database_entry *nss_getline (char *line);
@ -39,6 +39,27 @@ static service_library *nss_new_service (name_database *database,
const char *name);
/* Declare external database variables. */
#define DEFINE_DATABASE(name) \
extern service_user *__nss_##name##_database; \
weak_extern (__nss_##name##_database)
#include "databases.def"
#undef DEFINE_DATABASE
/* Structure to map database name to variable. */
static struct
{
const char *name;
service_user **dbp;
} databases[] =
{
#define DEFINE_DATABASE(name) \
{ #name, &__nss_##name##_database },
#include "databases.def"
#undef DEFINE_DATABASE
};
__libc_lock_define_initialized (static, lock)
@ -50,35 +71,29 @@ static int nss_initialized;
static name_database *service_table;
static void
nss_init (void)
{
/* Prevent multiple threads to change the service table. */
__libc_lock_lock (lock);
if (service_table == NULL)
service_table = nss_parse_file (_PATH_NSSWITCH_CONF);
__libc_lock_unlock (lock);
}
/* -1 == database not found
0 == database entry pointer stored */
int
__nss_database_lookup (const char *database, const char *defconfig,
service_user **ni)
{
name_database_entry *entry;
/* Prevent multiple threads to change the service table. */
__libc_lock_lock (lock);
if (nss_initialized == 0)
nss_init ();
/* Reconsider database variable in case some other thread called
`__nss_configure_lookup' while we waited for the lock. */
if (*ni != NULL)
return 0;
if (nss_initialized == 0 && service_table == NULL)
/* Read config file. */
service_table = nss_parse_file (_PATH_NSSWITCH_CONF);
/* Test whether configuration data is available. */
if (service_table)
if (service_table != NULL)
{
/* Return first `service_user' entry for DATABASE.
XXX Will use perfect hashing function for known databases. */
/* Return first `service_user' entry for DATABASE. */
name_database_entry *entry;
/* XXX Could use some faster mechanism here. But each database is
only requested once and so this might not be critical. */
@ -91,17 +106,14 @@ __nss_database_lookup (const char *database, const char *defconfig,
}
/* No configuration data is available, either because nsswitch.conf
doesn't exist or because it doesn't have a line for this database. */
entry = malloc (sizeof *entry);
if (entry == NULL)
return -1;
entry->name = database;
/* DEFCONFIG specifies the default service list for this database,
or null to use the most common default. */
entry->service = nss_parse_service_list (defconfig ?:
"compat [NOTFOUND=return] files");
doesn't exist or because it doesn't has a line for this database.
DEFCONFIG specifies the default service list for this database,
or null to use the most common default. */
*ni = nss_parse_service_list (defconfig ?: "compat [NOTFOUND=return] files");
__libc_lock_unlock (lock);
*ni = entry->service;
return 0;
}
@ -168,6 +180,48 @@ __nss_next (service_user **ni, const char *fct_name, void **fctp, int status,
}
int
__nss_configure_lookup (const char *dbname, const char *service_line)
{
service_user *new_db;
size_t cnt;
for (cnt = 0; cnt < sizeof databases; ++cnt)
if (strcmp (dbname, databases[cnt].name) == 0)
break;
if (cnt == sizeof databases)
{
errno = EINVAL;
return -1;
}
/* Test whether it is really used. */
if (databases[cnt].dbp == NULL)
/* Nothing to do, but we could do. */
return 0;
/* Try to generate new data. */
new_db = nss_parse_service_list (service_line);
if (new_db == NULL)
{
/* Illegal service specification. */
errno = EINVAL;
return -1;
}
/* Prevent multiple threads to change the service table. */
__libc_lock_lock (lock);
/* Install new rules. */
*databases[cnt].dbp = new_db;
__libc_lock_unlock (lock);
return 0;
}
static int
nss_dlerror_run (void (*operate) (void))
{
@ -385,7 +439,9 @@ nss_parse_file (const char *fname)
}
/* Read the source names: `<source> ( "[" <status> "=" <action> "]" )*'. */
/* Read the source names:
`( <source> ( "[" "!"? (<status> "=" <action> )+ "]" )? )*'
*/
static service_user *
nss_parse_service_list (const char *line)
{

View File

@ -23,24 +23,11 @@ Boston, MA 02111-1307, USA. */
#include <arpa/nameser.h>
#include <netinet/in.h>
#include <nss.h>
#include <resolv.h>
#include <search.h>
/* Revision number of NSS interface (must be a string). */
#define NSS_SHLIB_REVISION ".1"
/* Possible results of lookup using a nss_* function. */
enum nss_status
{
NSS_STATUS_TRYAGAIN = -2,
NSS_STATUS_UNAVAIL,
NSS_STATUS_NOTFOUND,
NSS_STATUS_SUCCESS,
};
/* Actions performed after lookup finished. */
typedef enum
{