From c66273aae5213e7e4460631e6b823dc2bf8a79d1 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Tue, 25 Jun 1996 10:20:09 +0000 Subject: * nss/nss_files/files-parse.c (parse_list): Reset ELT for elements after the first! * nss/nsswitch.c (__nss_database_lookup): If nsswitch.conf is missing or doesn't mention DATABASE, use an internal default equivalent to "DATABASE: compat [NOTFOUND=return] dns [NOTFOUND=return] files". (nss_lookup_function): Call nss_new_service as needed. (nss_parse_file): Don't bother calling nss_new_service here. * grp/fgetgrent.c (LINE_PARSER): Pass zero SWALLOW arg for fields. * pwd/fgetpwent.c: Likewise. --- nss/nss_files/files-parse.c | 1 + nss/nsswitch.c | 89 ++++++++++++++++++++++++++++----------------- 2 files changed, 57 insertions(+), 33 deletions(-) (limited to 'nss') diff --git a/nss/nss_files/files-parse.c b/nss/nss_files/files-parse.c index a93bee1ab3..ff67e974aa 100644 --- a/nss/nss_files/files-parse.c +++ b/nss/nss_files/files-parse.c @@ -137,6 +137,7 @@ parse_list (char *line, struct parser_data *data, int datalen) do ++line; while (TRAILING_LIST_SEPARATOR_P (*line)); + elt = line; } else if (*line == '\0' || *line == '\n') { diff --git a/nss/nsswitch.c b/nss/nsswitch.c index 4c2ccf692f..2b3ae0bbe1 100644 --- a/nss/nsswitch.c +++ b/nss/nsswitch.c @@ -86,29 +86,50 @@ nss_init (void) int __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; + if (nss_initialized == 0) + nss_init (); /* Test whether configuration data is available. */ - if (service_table == NULL) + if (service_table) { - if (nss_initialized == 0) - nss_init (); - - if (service_table == NULL) - return -1; + /* 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. */ + for (entry = service_table->entry; entry != NULL; entry = entry->next) + if (strcmp (database, entry->name) == 0) + { + *ni = entry->service; + return 0; + } } - /* XXX Could use some faster mechanism here. But each database is - only requested once and so this might not be critical. */ - for (entry = service_table->entry; entry != NULL; entry = entry->next) - if (strcmp (database, entry->name) == 0) - break; - - if (entry == NULL || (*ni = entry->service) == NULL) - return -1; - + /* 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; + } return 0; } @@ -196,15 +217,26 @@ nss_lookup_function (service_user *ni, const char *fct_name) if (nss_find_entry (&ni->known, fct_name, &result) >= 0) return result; - /* If we failed to allocate the needed data structures for the - service return an error. This should only happen when we are out - of memory. */ - if (ni->library == NULL) - return NULL; - /* We now modify global data. Protect it. */ __libc_lock_lock (lock); + 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. */ + __libc_lock_unlock (lock); + return NULL; + } + } + if (ni->library->lib_handle == NULL) { /* Load the shared library. */ @@ -374,15 +406,6 @@ nss_parse_file (const char *fname) /* Close configuration file. */ fclose (fp); - /* Now create for each service we could use an entry in LIBRARY list. */ - for (last = result->entry; last != NULL; last = last->next) - { - service_user *runp; - - for (runp = last->service; runp != NULL; runp = runp->next) - runp->library = nss_new_service (result, runp->name); - } - return result; } -- cgit v1.2.1