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

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



I created the attached patch, which completely disables mangling of passwd and 
passwd.adjunct.byname maps. Additionally, the encrypted password is looked 
for in the map passwd.adjunct.byname if the map shadow.byname does not exist.

This make getpwnam and getspnam work like I think is correct (that is, 
getpwnam does not show encrypted passwords for anyone and getspnam shows 
encrypted passwords only if called by root).

But now, NIS users cannot authenticate any more. The error message 
in /var/log/auth.log is:

 FAILED LOGIN (1) on 'tty2' FOR `pleger', Authentication service cannot 
retrieve authentication info

Regards
  Christoph
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-15 17:21:00.000000000 +0100
@@ -270,6 +270,7 @@ internal_nis_getpwent_r (struct passwd *
       char *result2;
       int len2;
       if (p != NULL	/* This better should be true in all cases.  */
+	  && (1 == 0)	/* Nobody can see encrypted passwords */
 	  && p[1] == '#' && p[2] == '#'
 	  && (namelen = p - result,
 	      yp_match (domain, "passwd.adjunct.byname", result, namelen,
@@ -404,6 +405,7 @@ _nss_nis_getpwnam_r (const char *name, s
   int len2;
   char *p = strchr (result, ':');
   if (p != NULL	/* This better should be true in all cases.  */
+      && (1 == 0)	/* Nobody can see encrypted passwords */
       && p[1] == '#' && p[2] == '#'
       && yp_match (domain, "passwd.adjunct.byname", name, namelen,
 		   &result2, &len2) == YPERR_SUCCESS)
@@ -504,6 +506,7 @@ _nss_nis_getpwuid_r (uid_t uid, struct p
   size_t namelen;
   char *p = strchr (result, ':');
   if (p != NULL	/* This better should be true in all cases.  */
+      && (1 == 0)	/* Nobody can see encrypted passwords */
       && p[1] == '#' && p[2] == '#'
       && (namelen = p - result,
 	  yp_match (domain, "passwd.adjunct.byname", result, namelen,
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-15 17:18:25.000000000 +0100
@@ -78,17 +78,36 @@ 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) {
+	  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) {
+	  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);
@@ -105,8 +124,14 @@ internal_nis_getspent_r (struct spwd *sp
           return NSS_STATUS_TRYAGAIN;
         }
 
-      char *p = strncpy (buffer, result, len);
-      buffer[len] = '\0';
+      if (! adjunct_used) 
+	p = strncpy (buffer, result, len);
+      else {
+	p = strncpy (buffer, result, len-2);
+	buffer[len-2] = ':';
+	buffer[len-1] = ':';
+      } 
+  
       while (isspace (*p))
         ++p;
       free (result);
@@ -149,6 +174,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 +192,12 @@ _nss_nis_getspnam_r (const char *name, s
   int yperr = yp_match (domain, "shadow.byname", name, strlen (name), &result,
 			&len);
 
+  if (yperr == YPERR_MAP) {
+    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);
@@ -180,7 +214,14 @@ _nss_nis_getspnam_r (const char *name, s
       return NSS_STATUS_TRYAGAIN;
     }
 
-  char *p = strncpy (buffer, result, len);
+  if (! adjunct_used) 
+    p = strncpy (buffer, result, len);
+  else {
+    p = strncpy (buffer, result, len-2);
+    buffer[len-2] = ':';
+    buffer[len-1] = ':';
+  } 
+  
   buffer[len] = '\0';
   while (isspace (*p))
     ++p;

Reply to: