This is the mail archive of the libc-alpha@sourceware.cygnus.com mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: [bill@kayhay.com] libc/1625: resolver ignores "multi on" in /etc/host.conf


On Fri, Mar 03, 2000 at 09:29:16AM +0100, Andreas Jaeger wrote:
> 
> Hi glibc folks,
> 
> we received the appended bug report.  IMHO we cannot support "multi on"
> at all with glibc (at least not in /etc/hosts) - and should remove the
> support for parsing "multi on" from res_hconf.c.  We parse this
> correctly - but never use it at all.
> 
> Does somebody see a way to fix this?
> 

Here is a patch. It seems to work for me.


H.J.
-----
2000-03-03  H.J. Lu  <hjl@gnu.org>

	* nss/nss_db/db-XXX.c (DB_LOOKUP): Add byname.

	* nss/nss_files/files-XXX.c (internal_getent): Add bufused,
	return the size of buffer used.
	(DB_LOOKUP): Add byname. Used by gethostbyname.

	* nss/nss_files/files-ethers.c: Pass byname == 0 to DB_LOOKUP.
	* nss/nss_files/files-grp.c: Likewise.
	* nss/nss_files/files-network.c: Likewise.
	* nss/nss_files/files-proto.c: Likewise.
	* nss/nss_files/files-pwd.c: Likewise.
	* nss/nss_files/files-rpc.c: Likewise.
	* nss/nss_files/files-service.c: Likewise.
	* nss/nss_files/files-spwd.c: Likewise.

	* nss/nss_files/files-hosts.c (GETHOSTNAME): New.
	Pass byname == (_res_hconf.flags & HCONF_FLAG_MULTI) to
	DB_LOOKUP and replace LOOKUP_NAME_CASE with GETHOSTNAME.
Index: nss/nss_db/db-XXX.c
===================================================================
RCS file: /work/cvs/gnu/glibc-2.1/nss/nss_db/db-XXX.c,v
retrieving revision 1.1.1.11
diff -u -p -r1.1.1.11 db-XXX.c
--- nss/nss_db/db-XXX.c	1998/11/19 18:45:50	1.1.1.11
+++ nss/nss_db/db-XXX.c	2000/03/04 01:57:00
@@ -250,6 +250,8 @@ lookup (DBT *key, struct STRUCTURE *resu
 
    NAME is the name of the lookup; e.g. `pwnam'.
 
+   BYNAME ignored here but used by ../nss_files/files-XXX.c.
+
    KEYPATTERN gives `printf' args to construct a key string;
    e.g. `(".%s", name)'.
 
@@ -261,7 +263,7 @@ lookup (DBT *key, struct STRUCTURE *resu
 
    BREAK_IF_MATCH is ignored, but used by ../nss_files/files-XXX.c.  */
 
-#define DB_LOOKUP(name, keysize, keypattern, break_if_match, proto...)	      \
+#define DB_LOOKUP(name, byname, keysize, keypattern, break_if_match, proto...) \
 enum nss_status								      \
 _nss_db_get##name##_r (proto,						      \
 		       struct STRUCTURE *result,			      \
Index: nss/nss_files/files-XXX.c
===================================================================
RCS file: /work/cvs/gnu/glibc-2.1/nss/nss_files/files-XXX.c,v
retrieving revision 1.1.1.13
diff -u -p -r1.1.1.13 files-XXX.c
--- nss/nss_files/files-XXX.c	1999/02/14 17:07:28	1.1.1.13
+++ nss/nss_files/files-XXX.c	2000/03/04 02:56:59
@@ -161,7 +161,8 @@ CONCAT(_nss_files_end,ENTNAME) (void)
 
 static enum nss_status
 internal_getent (struct STRUCTURE *result,
-		 char *buffer, size_t buflen, int *errnop H_ERRNO_PROTO)
+		 char *buffer, size_t buflen, size_t *bufused,
+		 int *errnop H_ERRNO_PROTO)
 {
   char *p;
   struct parser_data *data = (void *) buffer;
@@ -197,6 +198,9 @@ internal_getent (struct STRUCTURE *resul
 	  return NSS_STATUS_TRYAGAIN;
 	}
 
+      if (bufused)
+	*bufused = sizeof *data + strlen (data->linebuffer) + 1;
+
       /* Skip leading blanks.  */
       while (isspace (*p))
 	++p;
@@ -248,8 +252,8 @@ CONCAT(_nss_files_get,ENTNAME_r) (struct
 
       if (status == NSS_STATUS_SUCCESS)
 	{
-	  status = internal_getent (result, buffer, buflen, errnop
-				    H_ERRNO_ARG);
+	  status = internal_getent (result, buffer, buflen, NULL,
+	  			    errnop H_ERRNO_ARG);
 
 	  /* Remember this position if we were successful.  If the
 	     operation failed we give the user a chance to repeat the
@@ -271,6 +275,8 @@ CONCAT(_nss_files_get,ENTNAME_r) (struct
 
    NAME is the name of the lookup; e.g. `hostbyname'.
 
+   BYNAME indicates if it is a gethostbyname function.
+
    KEYSIZE and KEYPATTERN are ignored here but used by ../nss_db/db-XXX.c.
 
    PROTO describes the arguments for the lookup key;
@@ -279,13 +285,18 @@ CONCAT(_nss_files_get,ENTNAME_r) (struct
    BREAK_IF_MATCH is a block of code which compares `struct STRUCTURE *result'
    to the lookup key arguments and does `break;' if they match.  */
 
-#define DB_LOOKUP(name, keysize, keypattern, break_if_match, proto...)	      \
+#define DB_LOOKUP(name, byname, keysize, keypattern, break_if_match, proto...) \
 enum nss_status								      \
 _nss_files_get##name##_r (proto,					      \
 			  struct STRUCTURE *result, char *buffer,	      \
 			  size_t buflen, int *errnop H_ERRNO_PROTO)	      \
 {									      \
   enum nss_status status;						      \
+  struct STRUCTURE entry;						      \
+  char *bufend __attribute__ ((unused)) = buffer + buflen;		      \
+									      \
+  if (byname)								      \
+    memset (&entry, 0, sizeof entry);					      \
 									      \
   __libc_lock_lock (lock);						      \
 									      \
@@ -294,13 +305,22 @@ _nss_files_get##name##_r (proto,					   
 									      \
   if (status == NSS_STATUS_SUCCESS)					      \
     {									      \
+       enum nss_status ever = NSS_STATUS_NOTFOUND;			      \
+       size_t bufused;							      \
+									      \
       /* Tell getent function that we have repositioned the file pointer.  */ \
       last_use = getby;							      \
 									      \
-      while ((status = internal_getent (result, buffer, buflen, errnop	      \
-					H_ERRNO_ARG))			      \
+      while ((status = internal_getent (result, buffer, buflen, &bufused,     \
+					errnop H_ERRNO_ARG))		      \
 	     == NSS_STATUS_SUCCESS)					      \
 	{ break_if_match }						      \
+									      \
+      if (byname && ever == NSS_STATUS_SUCCESS)				      \
+	{								      \
+	  status = ever;						      \
+	  *result = entry;						      \
+	}								      \
 									      \
       if (! keep_stream)						      \
 	internal_endent ();						      \
Index: nss/nss_files/files-ethers.c
===================================================================
RCS file: /work/cvs/gnu/glibc-2.1/nss/nss_files/files-ethers.c,v
retrieving revision 1.1.1.1
diff -u -p -r1.1.1.1 files-ethers.c
--- nss/nss_files/files-ethers.c	1997/02/25 17:48:12	1.1.1.1
+++ nss/nss_files/files-ethers.c	2000/03/04 02:20:17
@@ -58,13 +58,13 @@ LINE_PARSER
 
 #include GENERIC
 
-DB_LOOKUP (hostton, 1 + strlen (name), (".%s", name),
+DB_LOOKUP (hostton, 0, 1 + strlen (name), (".%s", name),
 	   {
 	     if (strcmp (result->e_name, name) == 0)
 	       break;
 	   }, const char *name)
 
-DB_LOOKUP (ntohost, 18, ("=%x:%x:%x:%x:%x:%x",
+DB_LOOKUP (ntohost, 0, 18, ("=%x:%x:%x:%x:%x:%x",
 			 addr->ether_addr_octet[0], addr->ether_addr_octet[1],
 			 addr->ether_addr_octet[2], addr->ether_addr_octet[3],
 			 addr->ether_addr_octet[4], addr->ether_addr_octet[5]),
Index: nss/nss_files/files-grp.c
===================================================================
RCS file: /work/cvs/gnu/glibc-2.1/nss/nss_files/files-grp.c,v
retrieving revision 1.1.1.1
diff -u -p -r1.1.1.1 files-grp.c
--- nss/nss_files/files-grp.c	1997/02/25 17:48:12	1.1.1.1
+++ nss/nss_files/files-grp.c	2000/03/04 02:22:47
@@ -30,14 +30,14 @@ struct grent_data {};
 #include "files-parse.c"
 #include GENERIC
 
-DB_LOOKUP (grnam, 1 + strlen (name), (".%s", name),
+DB_LOOKUP (grnam, 0, 1 + strlen (name), (".%s", name),
 	   {
 	     if (name[0] != '-' && name[0] != '+'
 		 && ! strcmp (name, result->gr_name))
 	       break;
 	   }, const char *name)
 
-DB_LOOKUP (grgid, 20, ("=%lu", (unsigned long int) gid),
+DB_LOOKUP (grgid, 0, 20, ("=%lu", (unsigned long int) gid),
 	   {
 	     if (result->gr_gid == gid && result->gr_name[0] != '+'
 		 && result->gr_name[0] != '-')
Index: nss/nss_files/files-hosts.c
===================================================================
RCS file: /work/cvs/gnu/glibc-2.1/nss/nss_files/files-hosts.c,v
retrieving revision 1.1.1.6
diff -u -p -r1.1.1.6 files-hosts.c
--- nss/nss_files/files-hosts.c	1998/01/21 18:33:22	1.1.1.6
+++ nss/nss_files/files-hosts.c	2000/03/04 03:01:14
@@ -22,6 +22,7 @@
 #include <arpa/nameser.h>
 #include <netdb.h>
 #include <resolv.h>
+#include <resolv/res_hconf.h>
 
 
 /* Get implementation for some internal functions.  */
@@ -35,7 +36,7 @@
 #define ENTDATA hostent_data
 struct hostent_data
   {
-    unsigned char host_addr[16]; /* IPv4 or IPv6 address.  */
+    unsigned char host_addr[IN6ADDRSZ]; /* IPv4 or IPv6 address.  */
     char *h_addr_ptrs[2];	/* Points to that and null terminator.  */
   };
 
@@ -82,24 +83,98 @@ LINE_PARSER
    STRING_FIELD (result->h_name, isspace, 1);
  })
 
+#define GETHOSTNAME							      \
+  if (_res_hconf.flags & HCONF_FLAG_MULTI)				      \
+    {									      \
+      int match = 1;							      \
+      while (1)								      \
+	{								      \
+	  LOOKUP_NAME_CASE (h_name, h_aliases)				      \
+	  match = 0;							      \
+	  break;							      \
+	}								      \
+      if (match)							      \
+	{								      \
+	  buffer += bufused;						      \
+	  buflen -= bufused;						      \
+	  if (buflen <= 0)						      \
+	    {								      \
+	    memory:							      \
+	      *errnop = ERANGE;						      \
+	      H_ERRNO_SET (NETDB_INTERNAL);				      \
+	      return NSS_STATUS_TRYAGAIN;				      \
+	    }								      \
+									      \
+	  if (entry.h_addr_list == NULL)				      \
+	    {								      \
+	      entry = *result;						      \
+	      ever = status;						      \
+	    }								      \
+	  else								      \
+	    {								      \
+	      int i, n;							      \
+	      char **h_addr_ptrs;					      \
+									      \
+	      for (n = 0; entry.h_addr_list [n] != NULL; n++);		      \
+									      \
+	      if (n == 1)						      \
+		{							      \
+		  /* It is the first time. We have to copy it to the	      \
+		     buffer. It takes IN6ADDRSZ bytes for address and	      \
+		     space for 2 pointers. */				      \
+		  bufend -= IN6ADDRSZ + sizeof (char *) * 2;		      \
+		  buflen -= IN6ADDRSZ + sizeof (char *) * 2;		      \
+		  if (buflen <= 0)					      \
+		    goto memory;					      \
+		  h_addr_ptrs = (char **) &bufend [IN6ADDRSZ];		      \
+		  memcpy (bufend, entry.h_addr_list [0], IN6ADDRSZ);	      \
+		  h_addr_ptrs [0] = bufend;				      \
+		  h_addr_ptrs [1] = NULL;				      \
+		}							      \
+									      \
+	      /* Allocate space in buffer for host address.  It is	      \
+	         IN6ADDRSZ bytes + a pointer. */			      \
+	      bufend -= IN6ADDRSZ + sizeof (char *);			      \
+	      buflen -= IN6ADDRSZ + sizeof (char *);			      \
+	      if (buflen <= 0)						      \
+		goto memory;						      \
+									      \
+	      n++;							      \
+	      memcpy (bufend, result->h_addr_list [0], IN6ADDRSZ);	      \
+	      for (i = 1; i < n; i++)					      \
+		memmove (&bufend [IN6ADDRSZ * i],			      \
+			 entry.h_addr_list [i - 1], IN6ADDRSZ);		      \
+									      \
+	      h_addr_ptrs = (char **) &bufend [IN6ADDRSZ * n];		      \
+	      for (i = 0; i < n; i++)					      \
+		h_addr_ptrs [i] = &bufend [IN6ADDRSZ * i];		      \
+	      entry.h_addr_list = h_addr_ptrs;				      \
+	    }								      \
+	}								      \
+    }									      \
+  else									      \
+    LOOKUP_NAME_CASE (h_name, h_aliases)
+
 #include "files-XXX.c"
 
-DB_LOOKUP (hostbyname, ,,
+DB_LOOKUP (hostbyname,
+	   (_res_hconf.flags & HCONF_FLAG_MULTI), ,,
 	   {
 	     if (result->h_addrtype != ((_res.options & RES_USE_INET6)
 					? AF_INET6 : AF_INET))
 	       continue;
-	     LOOKUP_NAME_CASE (h_name, h_aliases)
+	     GETHOSTNAME
 	   }, const char *name)
 
-DB_LOOKUP (hostbyname2, ,,
+DB_LOOKUP (hostbyname2,
+	   (_res_hconf.flags & HCONF_FLAG_MULTI), ,,
 	   {
 	     if (result->h_addrtype != af)
 	       continue;
-	     LOOKUP_NAME_CASE (h_name, h_aliases)
+	     GETHOSTNAME
 	   }, const char *name, int af)
 
-DB_LOOKUP (hostbyaddr, ,,
+DB_LOOKUP (hostbyaddr, NULL, ,,
 	   {
 	     if (result->h_addrtype == type && result->h_length == len &&
 		 ! memcmp (addr, result->h_addr_list[0], len))
Index: nss/nss_files/files-network.c
===================================================================
RCS file: /work/cvs/gnu/glibc-2.1/nss/nss_files/files-network.c,v
retrieving revision 1.1.1.3
diff -u -p -r1.1.1.3 files-network.c
--- nss/nss_files/files-network.c	1998/01/27 18:53:30	1.1.1.3
+++ nss/nss_files/files-network.c	2000/03/04 02:22:57
@@ -44,11 +44,11 @@ LINE_PARSER
 
 #include "files-XXX.c"
 
-DB_LOOKUP (netbyname, ,,
+DB_LOOKUP (netbyname, 0, ,,
 	   LOOKUP_NAME_CASE (n_name, n_aliases),
 	   const char *name)
 
-DB_LOOKUP (netbyaddr, ,,
+DB_LOOKUP (netbyaddr, 0, ,,
 	   {
 	     if (result->n_addrtype == type && result->n_net == net)
 	       /* Bingo!  */
Index: nss/nss_files/files-proto.c
===================================================================
RCS file: /work/cvs/gnu/glibc-2.1/nss/nss_files/files-proto.c,v
retrieving revision 1.1.1.1
diff -u -p -r1.1.1.1 files-proto.c
--- nss/nss_files/files-proto.c	1997/02/25 17:48:12	1.1.1.1
+++ nss/nss_files/files-proto.c	2000/03/04 02:23:07
@@ -36,11 +36,11 @@ LINE_PARSER
 
 #include GENERIC
 
-DB_LOOKUP (protobyname, 1 + strlen (name), (".%s", name),
+DB_LOOKUP (protobyname, 0, 1 + strlen (name), (".%s", name),
 	   LOOKUP_NAME (p_name, p_aliases),
 	   const char *name)
 
-DB_LOOKUP (protobynumber, 20, ("=%d", proto),
+DB_LOOKUP (protobynumber, 0, 20, ("=%d", proto),
 	   {
 	     if (result->p_proto == proto)
 	       break;
Index: nss/nss_files/files-pwd.c
===================================================================
RCS file: /work/cvs/gnu/glibc-2.1/nss/nss_files/files-pwd.c,v
retrieving revision 1.1.1.1
diff -u -p -r1.1.1.1 files-pwd.c
--- nss/nss_files/files-pwd.c	1997/02/25 17:48:12	1.1.1.1
+++ nss/nss_files/files-pwd.c	2000/03/04 02:23:19
@@ -30,14 +30,14 @@ struct pwent_data {};
 #include "files-parse.c"
 #include GENERIC
 
-DB_LOOKUP (pwnam, 1 + strlen (name), (".%s", name),
+DB_LOOKUP (pwnam, 0, 1 + strlen (name), (".%s", name),
 	   {
 	     if (name[0] != '+' && name[0] != '-'
 		 && ! strcmp (name, result->pw_name))
 	       break;
 	   }, const char *name)
 
-DB_LOOKUP (pwuid, 20, ("=%lu", (unsigned long int) uid),
+DB_LOOKUP (pwuid, 0, 20, ("=%lu", (unsigned long int) uid),
 	   {
 	     if (result->pw_uid == uid && result->pw_name[0] != '+'
 		 && result->pw_name[0] != '-')
Index: nss/nss_files/files-rpc.c
===================================================================
RCS file: /work/cvs/gnu/glibc-2.1/nss/nss_files/files-rpc.c,v
retrieving revision 1.1.1.1
diff -u -p -r1.1.1.1 files-rpc.c
--- nss/nss_files/files-rpc.c	1997/02/25 17:48:12	1.1.1.1
+++ nss/nss_files/files-rpc.c	2000/03/04 02:23:28
@@ -36,11 +36,11 @@ LINE_PARSER
 
 #include GENERIC
 
-DB_LOOKUP (rpcbyname, 1 + strlen (name), (".%s", name),
+DB_LOOKUP (rpcbyname, 0, 1 + strlen (name), (".%s", name),
 	   LOOKUP_NAME (r_name, r_aliases),
 	   const char *name)
 
-DB_LOOKUP (rpcbynumber, 20, ("=%d", number),
+DB_LOOKUP (rpcbynumber, 0, 20, ("=%d", number),
 	   {
 	     if (result->r_number == number)
 	       break;
Index: nss/nss_files/files-service.c
===================================================================
RCS file: /work/cvs/gnu/glibc-2.1/nss/nss_files/files-service.c,v
retrieving revision 1.1.1.5
diff -u -p -r1.1.1.5 files-service.c
--- nss/nss_files/files-service.c	1998/02/01 23:56:55	1.1.1.5
+++ nss/nss_files/files-service.c	2000/03/04 02:23:38
@@ -39,7 +39,7 @@ LINE_PARSER
 
 #include GENERIC
 
-DB_LOOKUP (servbyname, 2 + strlen (name) + (proto ? strlen (proto) : 0),
+DB_LOOKUP (servbyname, 0, 2 + strlen (name) + (proto ? strlen (proto) : 0),
 	   (".%s/%s", name, proto ?: ""),
 	   {
 	     /* Must match both protocol (if specified) and name.  */
@@ -49,7 +49,7 @@ DB_LOOKUP (servbyname, 2 + strlen (name)
 	   },
 	   const char *name, const char *proto)
 
-DB_LOOKUP (servbyport, 21 + (proto ? strlen (proto) : 0),
+DB_LOOKUP (servbyport, 0, 21 + (proto ? strlen (proto) : 0),
 	   ("=%d/%s", ntohs (port), proto ?: ""),
 	   {
 	     /* Must match both port and protocol.  */
Index: nss/nss_files/files-spwd.c
===================================================================
RCS file: /work/cvs/gnu/glibc-2.1/nss/nss_files/files-spwd.c,v
retrieving revision 1.1.1.1
diff -u -p -r1.1.1.1 files-spwd.c
--- nss/nss_files/files-spwd.c	1997/02/25 17:48:12	1.1.1.1
+++ nss/nss_files/files-spwd.c	2000/03/04 02:23:43
@@ -30,7 +30,7 @@ struct spent_data {};
 #include "files-parse.c"
 #include GENERIC
 
-DB_LOOKUP (spnam, 1 + strlen (name), (".%s", name),
+DB_LOOKUP (spnam, 0, 1 + strlen (name), (".%s", name),
 	   {
 	     if (name[0] != '+' && name[0] != '-'
 		 && ! strcmp (name, result->sp_namp))

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]