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;