summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog12
-rw-r--r--grp/fgetgrent.c6
-rw-r--r--nss/nss_files/files-parse.c1
-rw-r--r--nss/nsswitch.c89
-rw-r--r--pwd/fgetpwent.c12
5 files changed, 78 insertions, 42 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  <roland@delasyd.gnu.ai.mit.edu>
 
+	* 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 ();
-
-      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;
 }
 
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;
 )