2010-01-06 Christoph Pleger <Christoph.Pleger@cs.tu-dortmund.de> Aurelien Jarno <aurelien@aurel32.net> * nis/nss_nis/nis-pwd.c (internal_nis_getpwent_r): When adjunct style secret password is returned, mangle 'x' instead of the encrypted password. (_nss_nis_getpwnam_r): Likewise. (_nss_nis_getpwuid_r): Likewise. * nis/nss_nis/nis-spwd.c (internal_nis_getspent_r): When shadow.byname does not exist, look in passwd.adjunct.byname and adapt the result. (_nss_nis_getspnam_r): Likewise. diff -Naurp glibc-2.6.1/nis/nss_nis/nis-pwd.c glibc-2.6.1.oden/nis/nss_nis/nis-pwd.c --- glibc-2.6.1/nis/nss_nis/nis-pwd.c 2006-05-01 18:31:15.000000000 -0400 +++ glibc-2.6.1.oden/nis/nss_nis/nis-pwd.c 2010-06-07 11:49:57.000000000 -0400 @@ -266,49 +266,32 @@ internal_nis_getpwent_r (struct passwd * /* Check for adjunct style secret passwords. They can be recognized by a password starting with "##". */ char *p = strchr (result, ':'); - size_t namelen; - char *result2; - int len2; if (p != NULL /* This better should be true in all cases. */ - && p[1] == '#' && p[2] == '#' - && (namelen = p - result, - yp_match (domain, "passwd.adjunct.byname", result, namelen, - &result2, &len2)) == YPERR_SUCCESS) + && p[1] == '#' && p[2] == '#') { - /* We found a passwd.adjunct entry. Merge encrypted - password therein into original result. */ - char *encrypted = strchr (result2, ':'); - char *endp; - size_t restlen; - - if (encrypted == NULL - || (endp = strchr (++encrypted, ':')) == NULL - || (p = strchr (p + 1, ':')) == NULL) + size_t namelen = p - result; + if ((p = strchr (p + 1, ':')) == NULL) { /* Invalid format of the entry. This never should happen unless the data from which the NIS table is generated is wrong. We simply ignore it. */ - free (result2); goto non_adjunct; } - restlen = len - (p - result); - if (__builtin_expect ((size_t) (namelen + (endp - encrypted) - + restlen + 2) > buflen, 0)) + /* We found an adjunct style secret password. Replace + it by 'x' into the result. */ + size_t restlen = len - (p - result); + if (__builtin_expect ((namelen + restlen + 3) > buflen, 0)) { - free (result2); free (result); *errnop = ERANGE; return NSS_STATUS_TRYAGAIN; } - mempcpy (mempcpy (mempcpy (mempcpy (buffer, result, namelen), - ":", 1), - encrypted, endp - encrypted), + mempcpy (mempcpy (mempcpy (buffer, result, namelen), + ":x", 2), p, restlen + 1); p = buffer; - - free (result2); } else { @@ -400,47 +383,33 @@ _nss_nis_getpwnam_r (const char *name, s /* Check for adjunct style secret passwords. They can be recognized by a password starting with "##". */ - char *result2; - int len2; char *p = strchr (result, ':'); if (p != NULL /* This better should be true in all cases. */ - && p[1] == '#' && p[2] == '#' - && yp_match (domain, "passwd.adjunct.byname", name, namelen, - &result2, &len2) == YPERR_SUCCESS) + && p[1] == '#' && p[2] == '#') { - /* We found a passwd.adjunct entry. Merge encrypted password - therein into original result. */ - char *encrypted = strchr (result2, ':'); - char *endp; - - if (encrypted == NULL - || (endp = strchr (++encrypted, ':')) == NULL - || (p = strchr (p + 1, ':')) == NULL) + size_t namelen = p - result; + if ((p = strchr (p + 1, ':')) == NULL) { /* Invalid format of the entry. This never should happen unless the data from which the NIS table is generated is wrong. We simply ignore it. */ - free (result2); goto non_adjunct; } + /* We found an adjunct style secret password. Replace + it by 'x' into the result. */ size_t restlen = len - (p - result); - if (__builtin_expect ((size_t) (namelen + (endp - encrypted) - + restlen + 2) > buflen, 0)) + if (__builtin_expect ((namelen + restlen + 3) > buflen, 0)) { - free (result2); free (result); *errnop = ERANGE; return NSS_STATUS_TRYAGAIN; } - __mempcpy (__mempcpy (__mempcpy (__mempcpy (buffer, name, namelen), - ":", 1), - encrypted, endp - encrypted), - p, restlen + 1); + mempcpy (mempcpy (mempcpy (buffer, result, namelen), + ":x", 2), + p, restlen + 1); p = buffer; - - free (result2); } else { @@ -499,50 +468,33 @@ _nss_nis_getpwuid_r (uid_t uid, struct p /* Check for adjunct style secret passwords. They can be recognized by a password starting with "##". */ - char *result2; - int len2; - size_t namelen; char *p = strchr (result, ':'); if (p != NULL /* This better should be true in all cases. */ - && p[1] == '#' && p[2] == '#' - && (namelen = p - result, - yp_match (domain, "passwd.adjunct.byname", result, namelen, - &result2, &len2)) == YPERR_SUCCESS) + && p[1] == '#' && p[2] == '#') { - /* We found a passwd.adjunct entry. Merge encrypted password - therein into original result. */ - char *encrypted = strchr (result2, ':'); - char *endp; - size_t restlen; - - if (encrypted == NULL - || (endp = strchr (++encrypted, ':')) == NULL - || (p = strchr (p + 1, ':')) == NULL) + size_t namelen = p - result; + if ((p = strchr (p + 1, ':')) == NULL) { /* Invalid format of the entry. This never should happen unless the data from which the NIS table is generated is wrong. We simply ignore it. */ - free (result2); goto non_adjunct; } - restlen = len - (p - result); - if (__builtin_expect ((size_t) (namelen + (endp - encrypted) - + restlen + 2) > buflen, 0)) + /* We found an adjunct style secret password. Replace + it by 'x' into the result. */ + size_t restlen = len - (p - result); + if (__builtin_expect ((namelen + restlen + 3) > buflen, 0)) { - free (result2); free (result); *errnop = ERANGE; return NSS_STATUS_TRYAGAIN; } - __mempcpy (__mempcpy (__mempcpy (__mempcpy (buffer, result, namelen), - ":", 1), - encrypted, endp - encrypted), - p, restlen + 1); + mempcpy (mempcpy (mempcpy (buffer, result, namelen), + ":x", 2), + p, restlen + 1); p = buffer; - - free (result2); } else { diff -Naurp glibc-2.6.1/nis/nss_nis/nis-spwd.c glibc-2.6.1.oden/nis/nss_nis/nis-spwd.c --- glibc-2.6.1/nis/nss_nis/nis-spwd.c 2006-04-28 21:09:49.000000000 -0400 +++ glibc-2.6.1.oden/nis/nss_nis/nis-spwd.c 2010-06-07 11:49:57.000000000 -0400 @@ -81,13 +81,38 @@ internal_nis_getspent_r (struct spwd *sp int len; int keylen; int yperr; + int adjunct_used = 0; if (new_start) - yperr = yp_first (domain, "shadow.byname", &outkey, &keylen, &result, - &len); + { + yperr = yp_first (domain, "shadow.byname", &outkey, &keylen, &result, + &len); + + 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); + { + 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)) { @@ -98,7 +123,7 @@ internal_nis_getspent_r (struct spwd *sp return retval; } - if (__builtin_expect ((size_t) (len + 1) > buflen, 0)) + if (__builtin_expect ((size_t) (len + (adjunct_used ? 3 : 1)) > buflen, 0)) { free (result); *errnop = ERANGE; @@ -107,6 +132,9 @@ internal_nis_getspent_r (struct spwd *sp char *p = strncpy (buffer, result, len); buffer[len] = '\0'; + if (adjunct_used) + p = strcat (buffer, "::"); + while (isspace (*p)) ++p; free (result); @@ -149,6 +177,8 @@ enum nss_status _nss_nis_getspnam_r (const char *name, struct spwd *sp, char *buffer, size_t buflen, int *errnop) { + int adjunct_used = 0; + if (name == NULL) { *errnop = EINVAL; @@ -164,6 +194,16 @@ _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,7 +213,7 @@ _nss_nis_getspnam_r (const char *name, s return retval; } - if (__builtin_expect ((size_t) (len + 1) > buflen, 0)) + if (__builtin_expect ((size_t) (len + (adjunct_used ? 3 : 1)) > buflen, 0)) { free (result); *errnop = ERANGE; @@ -182,6 +222,9 @@ _nss_nis_getspnam_r (const char *name, s char *p = strncpy (buffer, result, len); buffer[len] = '\0'; + if (adjunct_used) + p = strcat (buffer, "::"); + while (isspace (*p)) ++p; free (result);