aboutsummaryrefslogtreecommitdiff
path: root/nss
diff options
context:
space:
mode:
Diffstat (limited to 'nss')
-rw-r--r--nss/XXX-lookup.c10
-rw-r--r--nss/file-lookup.c22
-rw-r--r--nss/host-lookup.c1
-rw-r--r--nss/network-lookup.c1
-rw-r--r--nss/nss_files/files-parse.c2
-rw-r--r--nss/nsswitch.c205
-rw-r--r--nss/nsswitch.h7
7 files changed, 118 insertions, 130 deletions
diff --git a/nss/XXX-lookup.c b/nss/XXX-lookup.c
index 1f8cbbf..4a2d25c 100644
--- a/nss/XXX-lookup.c
+++ b/nss/XXX-lookup.c
@@ -25,6 +25,10 @@ Boston, MA 02111-1307, USA. */
|* DATABASE_NAME - name of the database the function accesses *|
|* (e.g., hosts, servicess, ...) *|
|* *|
+|* One additional symbol may optionally be defined: *|
+|* *|
+|* DEFAULT_CONFIG - string for default conf (e.g. "dns files") *|
+|* *|
\*******************************************************************/
#define DB_LOOKUP_FCT CONCAT3_1 (__nss_, DATABASE_NAME, _lookup)
@@ -35,6 +39,9 @@ Boston, MA 02111-1307, USA. */
#define STRINGIFY1(Name) STRINGIFY2 (Name)
#define STRINGIFY2(Name) #Name
+#ifndef DEFAULT_CONFIG
+#define DEFAULT_CONFIG 0
+#endif
static service_user *database = NULL;
@@ -42,7 +49,8 @@ int
DB_LOOKUP_FCT (service_user **ni, const char *fct_name, void **fctp)
{
if (database == NULL
- && __nss_database_lookup (DATABASE_NAME_STRING, &database) < 0)
+ && __nss_database_lookup (DATABASE_NAME_STRING, DEFAULT_CONFIG,
+ &database) < 0)
return -1;
*ni = database;
diff --git a/nss/file-lookup.c b/nss/file-lookup.c
deleted file mode 100644
index d9f7c67..0000000
--- a/nss/file-lookup.c
+++ /dev/null
@@ -1,22 +0,0 @@
-/* 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. */
-
-#define DATABASE_NAME hosts
-
-#include "XXX-lookup.c"
diff --git a/nss/host-lookup.c b/nss/host-lookup.c
index d9f7c67..f511393 100644
--- a/nss/host-lookup.c
+++ b/nss/host-lookup.c
@@ -18,5 +18,6 @@ not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#define DATABASE_NAME hosts
+#define DEFAULT_CONFIG "dns [!UNAVAIL=return] files"
#include "XXX-lookup.c"
diff --git a/nss/network-lookup.c b/nss/network-lookup.c
index ab6e51f..39a5ebd 100644
--- a/nss/network-lookup.c
+++ b/nss/network-lookup.c
@@ -18,5 +18,6 @@ not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#define DATABASE_NAME networks
+#define DEFAULT_CONFIG "dns files"
#include "XXX-lookup.c"
diff --git a/nss/nss_files/files-parse.c b/nss/nss_files/files-parse.c
index ff67e97..de45699 100644
--- a/nss/nss_files/files-parse.c
+++ b/nss/nss_files/files-parse.c
@@ -107,7 +107,7 @@ parse_list (char *line, struct parser_data *data, int datalen)
char *eol, **list, **p;
/* Find the end of the line buffer. */
- eol = strchr (line, '\0');
+ eol = strchr (line, '\0') + 1;
/* Adjust the pointer so it is aligned for storing pointers. */
eol += (eol - (char *) 0) % __alignof__ (char *);
/* We will start the storage here for the vector of pointers. */
diff --git a/nss/nsswitch.c b/nss/nsswitch.c
index 2b3ae0b..9b6c4eb 100644
--- a/nss/nsswitch.c
+++ b/nss/nsswitch.c
@@ -38,6 +38,7 @@ static void nss_insert_entry (struct entry **knownp, const char *key,
void *val);
static name_database *nss_parse_file (const char *fname);
static name_database_entry *nss_getline (char *line);
+static service_user *nss_parse_service_list (const char *line);
static service_library *nss_new_service (name_database *database,
const char *name);
@@ -49,17 +50,6 @@ __libc_lock_define_initialized (static, lock);
struct __res_state _res;
-/* Known aliases for service names. */
-static struct {
- const char *alias;
- const char *value;
-} service_alias[] =
-{
- { "nis+", "nisplus" },
- { "yp", "nis" }
-};
-
-
/* Nonzero if the sevices are already initialized. */
static int nss_initialized;
@@ -84,8 +74,11 @@ nss_init (void)
/* -1 == database not found
0 == database entry pointer stored */
int
-__nss_database_lookup (const char *database, service_user **ni)
+__nss_database_lookup (const char *database, const char *defconfig,
+ service_user **ni)
{
+ name_database_entry *entry;
+
if (nss_initialized == 0)
nss_init ();
@@ -94,7 +87,6 @@ __nss_database_lookup (const char *database, service_user **ni)
{
/* Return first `service_user' entry for DATABASE.
XXX Will use perfect hashing function for known databases. */
- 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. */
@@ -107,29 +99,17 @@ __nss_database_lookup (const char *database, service_user **ni)
}
/* No configuration data is available, either because nsswitch.conf
- doesn't exist or because it doesn't have a line for this database.
- Use a default equivalent to:
- database: compat [NOTFOUND=return] dns [NOTFOUND=return] files
- */
- {
-#define DEFAULT_SERVICE(name, next) \
- static service_user default_##name = \
- { \
- #name, \
- { \
- NSS_ACTION_CONTINUE, \
- NSS_ACTION_CONTINUE, \
- NSS_ACTION_RETURN, \
- NSS_ACTION_RETURN, \
- }, \
- NULL, NULL, \
- next \
- }
- DEFAULT_SERVICE (files, NULL);
- DEFAULT_SERVICE (dns, &default_files);
- DEFAULT_SERVICE (compat, &default_dns);
- *ni = &default_compat;
- }
+ 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");
+
+ *ni = entry->service;
return 0;
}
@@ -246,9 +226,7 @@ nss_lookup_function (service_user *ni, const char *fct_name)
void do_open (void)
{
- /* The used function is found in GNU ld.so. XXX The first
- argument to _dl_open used to be `_dl_loaded'. But this
- does (currently) not work. */
+ /* Open and relocate the shared object. */
ni->library->lib_handle = _dl_open (shlib_name, RTLD_LAZY);
}
@@ -370,7 +348,7 @@ nss_parse_file (const char *fname)
ssize_t n;
char *cp;
- n = getline (&line, &len, fp);
+ n = __getline (&line, &len, fp);
if (n < 0)
break;
if (line[n - 1] == '\n')
@@ -410,48 +388,16 @@ nss_parse_file (const char *fname)
}
-static name_database_entry *
-nss_getline (char *line)
+/* Read the source names: `<source> ( "[" <status> "=" <action> "]" )*'. */
+static service_user *
+nss_parse_service_list (const char *line)
{
- const char *name;
- name_database_entry *result;
- service_user *last;
-
- /* Ignore leading white spaces. ATTENTION: this is different from
- what is implemented in Solaris. The Solaris man page says a line
- beginning with a white space character is ignored. We regard
- this as just another misfeature in Solaris. */
- while (isspace (line[0]))
- ++line;
-
- /* Recognize `<database> ":"'. */
- name = line;
- while (line[0] != '\0' && !isspace (line[0]) && line[0] != ':')
- ++line;
- if (line[0] == '\0' || name == line)
- /* Syntax error. */
- return NULL;
- *line++ = '\0';
+ service_user *result = NULL, **nextp = &result;
- result = (name_database_entry *) malloc (sizeof (name_database_entry));
- if (result == NULL)
- return NULL;
-
- result->name = strdup (name);
- if (result->name == NULL)
- {
- free (result);
- return NULL;
- }
- result->service = NULL;
- result->next = NULL;
- last = NULL;
-
- /* Read the source names: `<source> ( "[" <status> "=" <action> "]" )*'. */
while (1)
{
service_user *new_service;
- size_t n;
+ char *name;
while (isspace (line[0]))
++line;
@@ -470,15 +416,6 @@ nss_getline (char *line)
new_service = (service_user *) malloc (sizeof (service_user));
if (new_service == NULL)
return result;
-
- /* Test whether the source name is one of the aliases. */
- for (n = 0; n < sizeof (service_alias) / sizeof (service_alias[0]); ++n)
- if (strncmp (service_alias[n].alias, name, line - name) == 0
- && service_alias[n].alias[line - name] == '\0')
- break;
-
- if (n < sizeof (service_alias) / sizeof (service_alias[0]))
- new_service->name = service_alias[n].value;
else
{
char *source = (char *) malloc (line - name + 1);
@@ -507,8 +444,6 @@ nss_getline (char *line)
if (line[0] == '[')
{
- int status;
-
/* Read criterions. */
do
++line;
@@ -516,6 +451,14 @@ nss_getline (char *line)
do
{
+ int not;
+ enum nss_status status;
+ lookup_actions action;
+
+ /* Grok ! before name to mean all statii but that one. */
+ if (not = line[0] == '!')
+ ++line;
+
/* Read status name. */
name = line;
while (line[0] != '\0' && !isspace (line[0]) && line[0] != '='
@@ -525,18 +468,18 @@ nss_getline (char *line)
/* Compare with known statii. */
if (line - name == 7)
{
- if (strncasecmp (name, "SUCCESS", 7) == 0)
+ if (__strncasecmp (name, "SUCCESS", 7) == 0)
status = NSS_STATUS_SUCCESS;
- else if (strncasecmp (name, "UNAVAIL", 7) == 0)
+ else if (__strncasecmp (name, "UNAVAIL", 7) == 0)
status = NSS_STATUS_UNAVAIL;
else
return result;
}
else if (line - name == 8)
{
- if (strncasecmp (name, "NOTFOUND", 8) == 0)
+ if (__strncasecmp (name, "NOTFOUND", 8) == 0)
status = NSS_STATUS_NOTFOUND;
- else if (strncasecmp (name, "TRYAGAIN", 8) == 0)
+ else if (__strncasecmp (name, "TRYAGAIN", 8) == 0)
status = NSS_STATUS_TRYAGAIN;
else
return result;
@@ -557,15 +500,29 @@ nss_getline (char *line)
&& line[0] != ']')
++line;
- if (line - name == 6 && strncasecmp (name, "RETURN", 6) == 0)
- new_service->actions[2 + status] = NSS_ACTION_RETURN;
+ if (line - name == 6 && __strncasecmp (name, "RETURN", 6) == 0)
+ action = NSS_ACTION_RETURN;
else if (line - name == 8
- && strncasecmp (name, "CONTINUE", 8) == 0)
- new_service->actions[2 + status] = NSS_ACTION_CONTINUE;
+ && __strncasecmp (name, "CONTINUE", 8) == 0)
+ action = NSS_ACTION_CONTINUE;
else
return result;
- /* Match white spaces. */
+ if (not)
+ {
+ /* Save the current action setting for this status,
+ set them all to the given action, and reset this one. */
+ const lookup_actions save = new_service->actions[2 + status];
+ new_service->actions[2 + NSS_STATUS_TRYAGAIN] = action;
+ new_service->actions[2 + NSS_STATUS_UNAVAIL] = action;
+ new_service->actions[2 + NSS_STATUS_NOTFOUND] = action;
+ new_service->actions[2 + NSS_STATUS_SUCCESS] = action;
+ new_service->actions[2 + status] = save;
+ }
+ else
+ new_service->actions[2 + status] = action;
+
+ /* Skip white spaces. */
while (isspace (line[0]))
++line;
}
@@ -575,14 +532,54 @@ nss_getline (char *line)
++line;
}
- if (last == NULL)
- result->service = new_service;
- else
- last->next = new_service;
- last = new_service;
+ *nextp = new_service;
+ nextp = &new_service->next;
}
- /* NOTREACHED */
- return NULL;
+}
+
+static name_database_entry *
+nss_getline (char *line)
+{
+ const char *name;
+ name_database_entry *result;
+
+ /* Ignore leading white spaces. ATTENTION: this is different from
+ what is implemented in Solaris. The Solaris man page says a line
+ beginning with a white space character is ignored. We regard
+ this as just another misfeature in Solaris. */
+ while (isspace (line[0]))
+ ++line;
+
+ /* Recognize `<database> ":"'. */
+ name = line;
+ while (line[0] != '\0' && !isspace (line[0]) && line[0] != ':')
+ ++line;
+ if (line[0] == '\0' || name == line)
+ /* Syntax error. */
+ return NULL;
+ *line++ = '\0';
+
+ result = (name_database_entry *) malloc (sizeof (name_database_entry));
+ if (result == NULL)
+ return NULL;
+
+ /* Save the database name. */
+ {
+ const size_t len = strlen (name) + 1;
+ char *new = malloc (len);
+ if (new == NULL)
+ {
+ free (result);
+ return NULL;
+ }
+ result->name = memcpy (new, name, len);
+ }
+
+ /* Parse the list of services. */
+ result->service = nss_parse_service_list (line);
+
+ result->next = NULL;
+ return result;
}
diff --git a/nss/nsswitch.h b/nss/nsswitch.h
index f597a58..d95d432 100644
--- a/nss/nsswitch.h
+++ b/nss/nsswitch.h
@@ -108,9 +108,12 @@ typedef struct name_database
/* Interface functions for NSS. */
-/* Get the data structure representing the specified database. More
+/* Get the data structure representing the specified database.
+ If there is no configuration for this database in the file,
+ parse a service list from DEFCONFIG and use that. More
than one function can use the database. */
-int __nss_database_lookup (const char *database, service_user **ni);
+int __nss_database_lookup (const char *database, const char *defconfig,
+ service_user **ni);
/* Put first function with name FCT_NAME for SERVICE in FCTP. The