diff options
Diffstat (limited to 'nss')
-rw-r--r-- | nss/XXX-lookup.c | 10 | ||||
-rw-r--r-- | nss/file-lookup.c | 22 | ||||
-rw-r--r-- | nss/host-lookup.c | 1 | ||||
-rw-r--r-- | nss/network-lookup.c | 1 | ||||
-rw-r--r-- | nss/nss_files/files-parse.c | 2 | ||||
-rw-r--r-- | nss/nsswitch.c | 205 | ||||
-rw-r--r-- | nss/nsswitch.h | 7 |
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 |