From c66273aae5213e7e4460631e6b823dc2bf8a79d1 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Tue, 25 Jun 1996 10:20:09 +0000 Subject: [PATCH] * 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. --- ChangeLog | 12 +++++ grp/fgetgrent.c | 6 +-- nss/nss_files/files-parse.c | 1 + nss/nsswitch.c | 87 +++++++++++++++++++++++-------------- pwd/fgetpwent.c | 12 ++--- 5 files changed, 77 insertions(+), 41 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2721aa9244..7630460e46 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,17 @@ Tue Jun 25 02:59:11 1996 Roland McGrath + * 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. + * malloc/malloc.h: Declare malloc_object_allocated_size, malloc_walk. * malloc/Makefile (dist-routines): Add malloc-size, malloc-walk. * malloc/malloc-size.c: New file. diff --git a/grp/fgetgrent.c b/grp/fgetgrent.c index 031ccb9c92..aced929621 100644 --- a/grp/fgetgrent.c +++ b/grp/fgetgrent.c @@ -31,9 +31,9 @@ struct grent_data {}; #include "../nss/nss_files/files-parse.c" LINE_PARSER ( - STRING_FIELD (result->gr_name, ISCOLON); - STRING_FIELD (result->gr_passwd, ISCOLON); - INT_FIELD (result->gr_gid, ISCOLON, 10,); + STRING_FIELD (result->gr_name, ISCOLON, 0); + STRING_FIELD (result->gr_passwd, ISCOLON, 0); + INT_FIELD (result->gr_gid, ISCOLON, 0, 10,); ) 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 (); + /* Return first `service_user' entry for DATABASE. + XXX Will use perfect hashing function for known databases. */ + name_database_entry *entry; - if (service_table == NULL) - return -1; + /* 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; } diff --git a/pwd/fgetpwent.c b/pwd/fgetpwent.c index ba9f834905..c29e96ec68 100644 --- a/pwd/fgetpwent.c +++ b/pwd/fgetpwent.c @@ -29,12 +29,12 @@ struct pwent_data {}; #include "../nss/nss_files/files-parse.c" LINE_PARSER ( - STRING_FIELD (result->pw_name, ISCOLON); - STRING_FIELD (result->pw_passwd, ISCOLON); - INT_FIELD (result->pw_uid, ISCOLON, 10,); - INT_FIELD (result->pw_gid, ISCOLON, 10,); - STRING_FIELD (result->pw_gecos, ISCOLON); - STRING_FIELD (result->pw_dir, ISCOLON); + STRING_FIELD (result->pw_name, ISCOLON, 0); + STRING_FIELD (result->pw_passwd, ISCOLON, 0); + INT_FIELD (result->pw_uid, ISCOLON, 0, 10,); + INT_FIELD (result->pw_gid, ISCOLON, 0, 10,); + STRING_FIELD (result->pw_gecos, ISCOLON, 0); + STRING_FIELD (result->pw_dir, ISCOLON, 0); result->pw_shell = line; )