[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#560333: libc6: getpwnam shows shadow passwords of NIS users



The attached patch seems to solve the problems. It works with nscd as well as 
without nscd. Authentication works fine now.

It makes the following changes:

* In nis-pwd.c, do not mangle encrypted password from 
   passwd.adjunct.byname map  into the password field
   of passwd map, instead mangle an 'x' into the field

* In nis-spwd.c, look for key in passwd.adjunct.byname if shadow.byname
   does not exist and add the two missing fields (passwd.adjunct.byname
   has two fields less than shadow)

Maybe some people can have a look over my patch to see if I missed anything. 
diff -Naurp glibc-2.7.original/nis/nss_nis/nis-pwd.c glibc-2.7/nis/nss_nis/nis-pwd.c
--- glibc-2.7.original/nis/nss_nis/nis-pwd.c	2006-05-02 00:31:15.000000000 +0200
+++ glibc-2.7/nis/nss_nis/nis-pwd.c	2009-12-22 09:04:46.000000000 +0100
@@ -275,8 +275,8 @@ internal_nis_getpwent_r (struct passwd *
 	      yp_match (domain, "passwd.adjunct.byname", result, namelen,
 			&result2, &len2)) == YPERR_SUCCESS)
 	{
-	  /* We found a passwd.adjunct entry.  Merge encrypted
-	     password therein into original result.  */
+	  /* We found a passwd.adjunct entry.  Merge "x"
+	     into original result.  */
 	  char *encrypted = strchr (result2, ':');
 	  char *endp;
 	  size_t restlen;
@@ -304,7 +304,7 @@ internal_nis_getpwent_r (struct passwd *
 
 	  mempcpy (mempcpy (mempcpy (mempcpy (buffer, result, namelen),
 				     ":", 1),
-			    encrypted, endp - encrypted),
+			    "x", 1),
 		   p, restlen + 1);
 	  p = buffer;
 
@@ -408,8 +408,8 @@ _nss_nis_getpwnam_r (const char *name, s
       && yp_match (domain, "passwd.adjunct.byname", name, namelen,
 		   &result2, &len2) == YPERR_SUCCESS)
     {
-      /* We found a passwd.adjunct entry.  Merge encrypted password
-	 therein into original result.  */
+      /* We found a passwd.adjunct entry.  Merge "x"
+	 into original result.  */
       char *encrypted = strchr (result2, ':');
       char *endp;
 
@@ -436,7 +436,7 @@ _nss_nis_getpwnam_r (const char *name, s
 
       __mempcpy (__mempcpy (__mempcpy (__mempcpy (buffer, name, namelen),
 				       ":", 1),
-			    encrypted, endp - encrypted),
+			    "x", 1),
 		 p, restlen + 1);
       p = buffer;
 
@@ -509,8 +509,8 @@ _nss_nis_getpwuid_r (uid_t uid, struct p
 	  yp_match (domain, "passwd.adjunct.byname", result, namelen,
 		    &result2, &len2)) == YPERR_SUCCESS)
     {
-      /* We found a passwd.adjunct entry.  Merge encrypted password
-	 therein into original result.  */
+      /* We found a passwd.adjunct entry.  Merge "x"
+	 into original result.  */
       char *encrypted = strchr (result2, ':');
       char *endp;
       size_t restlen;
@@ -538,7 +538,7 @@ _nss_nis_getpwuid_r (uid_t uid, struct p
 
       __mempcpy (__mempcpy (__mempcpy (__mempcpy (buffer, result, namelen),
 				       ":", 1),
-			    encrypted, endp - encrypted),
+			    "x", 1),
 		 p, restlen + 1);
       p = buffer;
 
diff -Naurp glibc-2.7.original/nis/nss_nis/nis-spwd.c glibc-2.7/nis/nss_nis/nis-spwd.c
--- glibc-2.7.original/nis/nss_nis/nis-spwd.c	2006-04-29 03:09:49.000000000 +0200
+++ glibc-2.7/nis/nss_nis/nis-spwd.c	2009-12-22 10:02:25.000000000 +0100
@@ -78,17 +78,42 @@ internal_nis_getspent_r (struct spwd *sp
     {
       char *result;
       char *outkey;
+      char *p;
       int len;
       int keylen;
       int yperr;
+      int adjunct_used = 0;
 
-      if (new_start)
+      if (new_start) {
         yperr = yp_first (domain, "shadow.byname", &outkey, &keylen, &result,
 			  &len);
-      else
+        
+        if (yperr == YPERR_MAP) {
+	  if (result != NULL)
+	    free result;
+
+	  yperr = yp_first (domain, "passwd.adjunct.byname", &outkey, &keylen, &result,
+			    &len);
+
+	  adjunct_used = 1;
+	}
+      }
+          
+      else {
         yperr = yp_next (domain, "shadow.byname", oldkey, oldkeylen, &outkey,
 			 &keylen, &result, &len);
 
+        if (yperr == YPERR_MAP) {
+	  if (result != NULL)
+	    free result;
+
+	  yperr = yp_next (domain, "passwd.adjunct.byname", oldkey, oldkeylen, &outkey,
+			   &keylen, &result, &len);
+	  
+	  adjunct_used = 1;
+	}
+      }
+
       if (__builtin_expect (yperr != YPERR_SUCCESS, 0))
         {
 	  enum nss_status retval = yperr2nss (yperr);
@@ -98,15 +123,32 @@ internal_nis_getspent_r (struct spwd *sp
           return retval;
         }
 
-      if (__builtin_expect ((size_t) (len + 1) > buflen, 0))
-        {
-          free (result);
-	  *errnop = ERANGE;
-          return NSS_STATUS_TRYAGAIN;
-        }
+      if (! adjunct_used)
+	{
+	  if (__builtin_expect ((size_t) (len + 1) > buflen, 0))
+	    {
+	      free (result);
+	      *errnop = ERANGE;
+	      return NSS_STATUS_TRYAGAIN;
+	    }
+
+	  p = strncpy (buffer, result, len);
+	  buffer[len] = '\0';  
+	}
+      else
+	{
+	  if (__builtin_expect ((size_t) (len + 3) > buflen, 0))
+	    {
+	      free (result);
+	      *errnop = ERANGE;
+	      return NSS_STATUS_TRYAGAIN;
+	    }
+
+	  p = strncpy (buffer, result, len);
+	  buffer[len] = '\0';  
+	  p = strcat (buffer, "::");
+	}
 
-      char *p = strncpy (buffer, result, len);
-      buffer[len] = '\0';
       while (isspace (*p))
         ++p;
       free (result);
@@ -149,6 +191,9 @@ enum nss_status
 _nss_nis_getspnam_r (const char *name, struct spwd *sp,
 		     char *buffer, size_t buflen, int *errnop)
 {
+  int adjunct_used = 0;
+  char *p;
+
   if (name == NULL)
     {
       *errnop = EINVAL;
@@ -164,6 +209,15 @@ _nss_nis_getspnam_r (const char *name, s
   int yperr = yp_match (domain, "shadow.byname", name, strlen (name), &result,
 			&len);
 
+  if (yperr == YPERR_MAP) {
+    if (result != NULL)
+      free result;
+
+    yperr = yp_match (domain, "passwd.adjunct.byname", name, strlen (name), &result,
+		      &len);
+    adjunct_used = 1;
+  }
+
   if (__builtin_expect (yperr != YPERR_SUCCESS, 0))
     {
       enum nss_status retval = yperr2nss (yperr);
@@ -173,15 +227,32 @@ _nss_nis_getspnam_r (const char *name, s
       return retval;
     }
 
-  if (__builtin_expect ((size_t) (len + 1) > buflen, 0))
+  if (! adjunct_used)
     {
-      free (result);
-      *errnop = ERANGE;
-      return NSS_STATUS_TRYAGAIN;
+      if (__builtin_expect ((size_t) (len + 1) > buflen, 0))
+	{
+	  free (result);
+	  *errnop = ERANGE;
+	  return NSS_STATUS_TRYAGAIN;
+	}
+
+      p = strncpy (buffer, result, len);
+      buffer[len] = '\0';  
     }
+  else
+    {
+      if (__builtin_expect ((size_t) (len + 3) > buflen, 0))
+	{
+	  free (result);
+	  *errnop = ERANGE;
+	  return NSS_STATUS_TRYAGAIN;
+	}
 
-  char *p = strncpy (buffer, result, len);
-  buffer[len] = '\0';
+      p = strncpy (buffer, result, len);
+      buffer[len] = '\0';  
+      p = strcat (buffer, "::");
+    }
+  
   while (isspace (*p))
     ++p;
   free (result);

Reply to: