summaryrefslogtreecommitdiff
path: root/nis/nss_nis/nis-spwd.c
diff options
context:
space:
mode:
Diffstat (limited to 'nis/nss_nis/nis-spwd.c')
-rw-r--r--nis/nss_nis/nis-spwd.c79
1 files changed, 58 insertions, 21 deletions
diff --git a/nis/nss_nis/nis-spwd.c b/nis/nss_nis/nis-spwd.c
index 0fc4e17c42..3cf913b4cd 100644
--- a/nis/nss_nis/nis-spwd.c
+++ b/nis/nss_nis/nis-spwd.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996-1998,2001,2002,2003,2006 Free Software Foundation, Inc.
+/* Copyright (C) 1996-1998,2001-2003,2006,2010 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1996.
@@ -31,6 +31,7 @@
#include <rpcsvc/ypclnt.h>
#include "nss-nis.h"
+#include <libnsl.h>
/* Get the declaration of the parser function. */
#define ENTNAME spent
@@ -41,7 +42,8 @@
/* Protect global state against multiple changers */
__libc_lock_define_initialized (static, lock)
-static bool_t new_start = 1;
+static bool new_start = true;
+static bool ent_adjunct_used;
static char *oldkey;
static int oldkeylen;
@@ -50,7 +52,8 @@ _nss_nis_setspent (int stayopen)
{
__libc_lock_lock (lock);
- new_start = 1;
+ new_start = true;
+ ent_adjunct_used = false;
free (oldkey);
oldkey = NULL;
oldkeylen = 0;
@@ -83,32 +86,50 @@ internal_nis_getspent_r (struct spwd *sp, char *buffer, size_t buflen,
int yperr;
if (new_start)
- yperr = yp_first (domain, "shadow.byname", &outkey, &keylen, &result,
- &len);
+ {
+ yperr = yp_first (domain, "shadow.byname", &outkey, &keylen, &result,
+ &len);
+ if (__builtin_expect (yperr == YPERR_MAP, 0)
+ && (_nsl_default_nss () & NSS_FLAG_ADJUNCT_AS_SHADOW))
+ {
+ free (result);
+ yperr = yp_first (domain, "passwd.adjunct.byname", &outkey,
+ &keylen, &result, &len);
+ ent_adjunct_used = true;
+ }
+ }
else
- yperr = yp_next (domain, "shadow.byname", oldkey, oldkeylen, &outkey,
- &keylen, &result, &len);
+ yperr = yp_next (domain, (ent_adjunct_used
+ ? "passwd.adjunct.byname" : "shadow.byname"),
+ oldkey, oldkeylen, &outkey, &keylen, &result, &len);
if (__builtin_expect (yperr != YPERR_SUCCESS, 0))
- {
+ {
enum nss_status retval = yperr2nss (yperr);
if (retval == NSS_STATUS_TRYAGAIN)
*errnop = errno;
- return retval;
- }
+ return retval;
+ }
- if (__builtin_expect ((size_t) (len + 1) > buflen, 0))
- {
- free (result);
+ if (__builtin_expect ((size_t) (len + (ent_adjunct_used ? 3 : 1))
+ > buflen, 0))
+ {
+ free (result);
*errnop = ERANGE;
- return NSS_STATUS_TRYAGAIN;
- }
+ return NSS_STATUS_TRYAGAIN;
+ }
char *p = strncpy (buffer, result, len);
- buffer[len] = '\0';
+ if (ent_adjunct_used)
+ /* This is an ugly trick. The format of passwd.adjunct.byname almost
+ matches the shadow.byname format except that the last two fields
+ are missing. Synthesize them by marking them empty. */
+ strcpy (&buffer[len], "::");
+ else
+ buffer[len] = '\0';
while (isspace (*p))
- ++p;
+ ++p;
free (result);
parse_res = _nss_files_parse_spent (p, sp, (void *) buffer, buflen,
@@ -123,7 +144,7 @@ internal_nis_getspent_r (struct spwd *sp, char *buffer, size_t buflen,
free (oldkey);
oldkey = outkey;
oldkeylen = keylen;
- new_start = 0;
+ new_start = false;
}
while (!parse_res);
@@ -154,15 +175,25 @@ _nss_nis_getspnam_r (const char *name, struct spwd *sp,
*errnop = EINVAL;
return NSS_STATUS_UNAVAIL;
}
+ const size_t name_len = strlen (name);
char *domain;
if (__builtin_expect (yp_get_default_domain (&domain), 0))
return NSS_STATUS_UNAVAIL;
+ bool adjunct_used = false;
char *result;
int len;
- int yperr = yp_match (domain, "shadow.byname", name, strlen (name), &result,
+ int yperr = yp_match (domain, "shadow.byname", name, name_len, &result,
&len);
+ if (__builtin_expect (yperr == YPERR_MAP, 0)
+ && (_nsl_default_nss () & NSS_FLAG_ADJUNCT_AS_SHADOW))
+ {
+ free (result);
+ yperr = yp_match (domain, "passwd.adjunct.byname", name, name_len,
+ &result, &len);
+ adjunct_used = true;
+ }
if (__builtin_expect (yperr != YPERR_SUCCESS, 0))
{
@@ -173,7 +204,7 @@ _nss_nis_getspnam_r (const char *name, 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;
@@ -181,7 +212,13 @@ _nss_nis_getspnam_r (const char *name, struct spwd *sp,
}
char *p = strncpy (buffer, result, len);
- buffer[len] = '\0';
+ if (__builtin_expect (adjunct_used, false))
+ /* This is an ugly trick. The format of passwd.adjunct.byname almost
+ matches the shadow.byname format except that the last two fields
+ are missing. Synthesize them by marking them empty. */
+ strcpy (&buffer[len], "::");
+ else
+ buffer[len] = '\0';
while (isspace (*p))
++p;
free (result);