diff options
author | Roland McGrath <roland@gnu.org> | 1996-06-25 10:20:09 +0000 |
---|---|---|
committer | Roland McGrath <roland@gnu.org> | 1996-06-25 10:20:09 +0000 |
commit | c66273aae5213e7e4460631e6b823dc2bf8a79d1 (patch) | |
tree | c5aa151e2bd9b5373cd01cce47210a7cf512a31c /nss | |
parent | 5f0e6fc702296840d2daa39f83f6cb1e40073d58 (diff) | |
download | glibc-c66273aae5213e7e4460631e6b823dc2bf8a79d1.zip glibc-c66273aae5213e7e4460631e6b823dc2bf8a79d1.tar.gz glibc-c66273aae5213e7e4460631e6b823dc2bf8a79d1.tar.bz2 |
* 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.
Diffstat (limited to 'nss')
-rw-r--r-- | nss/nss_files/files-parse.c | 1 | ||||
-rw-r--r-- | nss/nsswitch.c | 89 |
2 files changed, 57 insertions, 33 deletions
diff --git a/nss/nss_files/files-parse.c b/nss/nss_files/files-parse.c index a93bee1..ff67e97 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 4c2ccf6..2b3ae0b 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; } |