Bug#560333: libc6: getpwnam shows shadow passwords of NIS users
On Wed, Jan 06, 2010 at 08:49:48AM +0100, Christoph Pleger wrote:
> Hello,
>
> On Tue, 5 Jan 2010 21:50:34 +0100
> Aurelien Jarno <aurelien@aurel32.net> wrote:
>
> > This should probably be free(result). Also there is indentation
> > issues.
>
> Oops, my mistake, obviously I sent an obsolete version of the patch. I
> remember that I got a compilation error because of the missing
> parantheses.
>
> Now, I have attached the version of the patch that I really used to
> compile the package successfully.
Thanks, it's better. I have fixed the others comments of your patch, and
included it in eglibc 2.10.1-4. Please find it attached.
If nobody reports problem with this patch in a few days, I'll do the
necessary to get a security upload for lenny.
--
Aurelien Jarno GPG: 1024D/F1BCDB73
aurelien@aurel32.net http://www.aurel32.net
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: