mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-21 20:40:05 +00:00
Add self-contained test for NSS.
While at it fix interaction between __nss_configure_lookup and nscd. Otherwise the test fails if nscd is runnung.
This commit is contained in:
parent
f15ce4d8dc
commit
c3e2f19bb9
20
ChangeLog
20
ChangeLog
@ -1,3 +1,23 @@
|
||||
2010-08-11 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* nss/Makefile: Add rules to build and run tst-nss-test1.
|
||||
* shlib-versions: Add entry for libnss_test1.
|
||||
* nss/nss_test1.c: New file.
|
||||
* nss/tst-nss-test1.c: New file.
|
||||
|
||||
* nss/nsswitch.c (__nss_database_custom): Define new variable.
|
||||
(__nss_configure_lookup): Set appropriate entry in
|
||||
__nss_configure_lookup to true.
|
||||
* nss/nsswitch.h: Define enum with indeces of databases in
|
||||
databases and __nss_database_custom arrays. Declare
|
||||
__nss_database_custom.
|
||||
* grp/initgroups.c (internal_getgrouplist): Use __nss_database_custom
|
||||
to avoid using nscd when custom rules are installed.
|
||||
* nss/getXXbyYY_r.c: Likewise.
|
||||
* sysdeps/posix/getaddrinfo.c (gaih_inet): Likewise.
|
||||
|
||||
* nss/nss_files/files-parse.c: Whitespace fixes.
|
||||
|
||||
2010-08-09 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
[BZ #11883]
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 1989,91,93,1996-2005,2006,2008 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1989,91,93,1996-2006,2008,2010 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
@ -56,7 +56,8 @@ internal_getgrouplist (const char *user, gid_t group, long int *size,
|
||||
if (__nss_not_use_nscd_group > 0
|
||||
&& ++__nss_not_use_nscd_group > NSS_NSCD_RETRY)
|
||||
__nss_not_use_nscd_group = 0;
|
||||
if (!__nss_not_use_nscd_group)
|
||||
if (!__nss_not_use_nscd_group
|
||||
&& !__nss_database_custom[NSS_DBSIDX_group])
|
||||
{
|
||||
int n = __nscd_getgrouplist (user, group, size, groupsp, limit);
|
||||
if (n >= 0)
|
||||
|
16
nss/Makefile
16
nss/Makefile
@ -1,4 +1,5 @@
|
||||
# Copyright (C) 1996-1998,2000-2002,2007,2009 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1996-1998,2000-2002,2007,2009,2010
|
||||
# Free Software Foundation, Inc.
|
||||
# This file is part of the GNU C Library.
|
||||
|
||||
# The GNU C Library is free software; you can redistribute it and/or
|
||||
@ -39,7 +40,7 @@ databases = proto service hosts network grp pwd rpc ethers \
|
||||
others := getent
|
||||
install-bin := getent
|
||||
|
||||
tests = test-netdb
|
||||
tests = test-netdb tst-nss-test1
|
||||
xtests = bug-erange
|
||||
|
||||
include ../Makeconfig
|
||||
@ -84,3 +85,14 @@ endif
|
||||
# a statically-linked program that hasn't already loaded it.
|
||||
$(services:%=$(objpfx)libnss_%.so): $(common-objpfx)libc.so \
|
||||
$(common-objpfx)libc_nonshared.a
|
||||
|
||||
|
||||
distribute += nss_test1.c
|
||||
|
||||
CFLAGS-nss_test1.c = -DNOT_IN_libc=1
|
||||
$(objpfx)/libnss_test1.so: $(objpfx)nss_test1.os $(common-objpfx)libc.so \
|
||||
$(common-objpfx)libc_nonshared.a
|
||||
$(build-module)
|
||||
$(objpfx)/libnss_test1.so$(libnss_test1.so-version): $(objpfx)/libnss_test1.so
|
||||
$(make-link)
|
||||
$(objpfx)tst-nss-test1.out: $(objpfx)/libnss_test1.so$(libnss_test1.so-version)
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 1996-2004, 2006, 2007, 2009 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1996-2004,2006,2007,2009,2010 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
|
||||
|
||||
@ -87,6 +87,8 @@
|
||||
# define NOT_USENSCD_NAME ADD_NOT_NSCDUSE (DATABASE_NAME)
|
||||
# define ADD_NOT_NSCDUSE(name) ADD_NOT_NSCDUSE1 (name)
|
||||
# define ADD_NOT_NSCDUSE1(name) __nss_not_use_nscd_##name
|
||||
# define CONCAT2(arg1, arg2) CONCAT2_2 (arg1, arg2)
|
||||
# define CONCAT2_2(arg1, arg2) arg1##arg2
|
||||
#endif
|
||||
|
||||
#define FUNCTION_NAME_STRING STRINGIZE (FUNCTION_NAME)
|
||||
@ -186,7 +188,8 @@ INTERNAL (REENTRANT_NAME) (ADD_PARAMS, LOOKUP_TYPE *resbuf, char *buffer,
|
||||
if (NOT_USENSCD_NAME > 0 && ++NOT_USENSCD_NAME > NSS_NSCD_RETRY)
|
||||
NOT_USENSCD_NAME = 0;
|
||||
|
||||
if (!NOT_USENSCD_NAME)
|
||||
if (!NOT_USENSCD_NAME
|
||||
&& !__nss_database_custom[CONCAT2 (NSS_DBSIDX_, DATABASE_NAME)])
|
||||
{
|
||||
nscd_status = NSCD_NAME (ADD_VARIABLES, resbuf, buffer, buflen, result
|
||||
H_ERRNO_VAR);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Common code for file-based database parsers in nss_files module.
|
||||
Copyright (C) 1996-2000, 2003, 2004, 2009 Free Software Foundation, Inc.
|
||||
Copyright (C) 1996-2000,2003,2004,2009,2010 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
@ -29,7 +29,7 @@
|
||||
DATABASE -- string of the database file's name ("hosts", "passwd").
|
||||
|
||||
ENTDATA -- if defined, `struct ENTDATA' is used by the parser to store
|
||||
things pointed to by the resultant `struct STRUCTURE'.
|
||||
things pointed to by the resultant `struct STRUCTURE'.
|
||||
|
||||
NEED_H_ERRNO - defined iff an arg `int *herrnop' is used.
|
||||
|
||||
@ -229,7 +229,7 @@ strtou32 (const char *nptr, char **endptr, int base)
|
||||
char **list = parse_list (&line, buf_start, buf_end, '\0', errnop); \
|
||||
if (list) \
|
||||
result->TRAILING_LIST_MEMBER = list; \
|
||||
else \
|
||||
else \
|
||||
return -1; /* -1 indicates we ran out of space. */ \
|
||||
}
|
||||
|
||||
|
154
nss/nss_test1.c
Normal file
154
nss/nss_test1.c
Normal file
@ -0,0 +1,154 @@
|
||||
#include <errno.h>
|
||||
#include <nss.h>
|
||||
#include <pthread.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#define COPY_IF_ROOM(s) \
|
||||
({ size_t len_ = strlen (s) + 1; \
|
||||
char *start_ = cp; \
|
||||
buflen - (cp - buffer) < len_ \
|
||||
? NULL \
|
||||
: (cp = mempcpy (cp, s, len_), start_); })
|
||||
|
||||
|
||||
/* Password handling. */
|
||||
#include <pwd.h>
|
||||
|
||||
static struct passwd pwd_data[] =
|
||||
{
|
||||
#define PWD(u) \
|
||||
{ .pw_name = (char *) "name" #u, .pw_passwd = (char *) "*", .pw_uid = u, \
|
||||
.pw_gid = 100, .pw_gecos = (char *) "*", .pw_dir = (char *) "*", \
|
||||
.pw_shell = (char *) "*" }
|
||||
PWD (100),
|
||||
PWD (30),
|
||||
PWD (200),
|
||||
PWD (60),
|
||||
PWD (20000)
|
||||
};
|
||||
#define npwd_data (sizeof (pwd_data) / sizeof (pwd_data[0]))
|
||||
|
||||
static size_t pwd_iter;
|
||||
#define CURPWD pwd_data[pwd_iter]
|
||||
|
||||
static pthread_mutex_t pwd_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
|
||||
enum nss_status
|
||||
_nss_test1_setpwent (int stayopen)
|
||||
{
|
||||
pwd_iter = 0;
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
enum nss_status
|
||||
_nss_test1_endpwent (void)
|
||||
{
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
enum nss_status
|
||||
_nss_test1_getpwent_r (struct passwd *result, char *buffer, size_t buflen,
|
||||
int *errnop)
|
||||
{
|
||||
char *cp = buffer;
|
||||
int res = NSS_STATUS_SUCCESS;
|
||||
|
||||
pthread_mutex_lock (&pwd_lock);
|
||||
|
||||
if (pwd_iter >= npwd_data)
|
||||
res = NSS_STATUS_NOTFOUND;
|
||||
else
|
||||
{
|
||||
result->pw_name = COPY_IF_ROOM (CURPWD.pw_name);
|
||||
result->pw_passwd = COPY_IF_ROOM (CURPWD.pw_passwd);
|
||||
result->pw_uid = CURPWD.pw_uid;
|
||||
result->pw_gid = CURPWD.pw_gid;
|
||||
result->pw_gecos = COPY_IF_ROOM (CURPWD.pw_gecos);
|
||||
result->pw_dir = COPY_IF_ROOM (CURPWD.pw_dir);
|
||||
result->pw_shell = COPY_IF_ROOM (CURPWD.pw_shell);
|
||||
|
||||
if (result->pw_name == NULL || result->pw_passwd == NULL
|
||||
|| result->pw_gecos == NULL || result->pw_dir == NULL
|
||||
|| result->pw_shell == NULL)
|
||||
{
|
||||
*errnop = ERANGE;
|
||||
res = NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
|
||||
++pwd_iter;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock (&pwd_lock);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
enum nss_status
|
||||
_nss_test1_getpwuid_r (uid_t uid, struct passwd *result, char *buffer,
|
||||
size_t buflen, int *errnop)
|
||||
{
|
||||
for (size_t idx = 0; idx < npwd_data; ++idx)
|
||||
if (pwd_data[idx].pw_uid == uid)
|
||||
{
|
||||
char *cp = buffer;
|
||||
int res = NSS_STATUS_SUCCESS;
|
||||
|
||||
result->pw_name = COPY_IF_ROOM (pwd_data[idx].pw_name);
|
||||
result->pw_passwd = COPY_IF_ROOM (pwd_data[idx].pw_passwd);
|
||||
result->pw_uid = pwd_data[idx].pw_uid;
|
||||
result->pw_gid = pwd_data[idx].pw_gid;
|
||||
result->pw_gecos = COPY_IF_ROOM (pwd_data[idx].pw_gecos);
|
||||
result->pw_dir = COPY_IF_ROOM (pwd_data[idx].pw_dir);
|
||||
result->pw_shell = COPY_IF_ROOM (pwd_data[idx].pw_shell);
|
||||
|
||||
if (result->pw_name == NULL || result->pw_passwd == NULL
|
||||
|| result->pw_gecos == NULL || result->pw_dir == NULL
|
||||
|| result->pw_shell == NULL)
|
||||
{
|
||||
*errnop = ERANGE;
|
||||
res = NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
}
|
||||
|
||||
|
||||
enum nss_status
|
||||
_nss_test1_getpwnam_r (const char *name, struct passwd *result, char *buffer,
|
||||
size_t buflen, int *errnop)
|
||||
{
|
||||
for (size_t idx = 0; idx < npwd_data; ++idx)
|
||||
if (strcmp (pwd_data[idx].pw_name, name) == 0)
|
||||
{
|
||||
char *cp = buffer;
|
||||
int res = NSS_STATUS_SUCCESS;
|
||||
|
||||
result->pw_name = COPY_IF_ROOM (pwd_data[idx].pw_name);
|
||||
result->pw_passwd = COPY_IF_ROOM (pwd_data[idx].pw_passwd);
|
||||
result->pw_uid = pwd_data[idx].pw_uid;
|
||||
result->pw_gid = pwd_data[idx].pw_gid;
|
||||
result->pw_gecos = COPY_IF_ROOM (pwd_data[idx].pw_gecos);
|
||||
result->pw_dir = COPY_IF_ROOM (pwd_data[idx].pw_dir);
|
||||
result->pw_shell = COPY_IF_ROOM (pwd_data[idx].pw_shell);
|
||||
|
||||
if (result->pw_name == NULL || result->pw_passwd == NULL
|
||||
|| result->pw_gecos == NULL || result->pw_dir == NULL
|
||||
|| result->pw_shell == NULL)
|
||||
{
|
||||
*errnop = ERANGE;
|
||||
res = NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 1996-1999, 2001-2007, 2009 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1996-1999,2001-2007,2009,2010 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
|
||||
|
||||
@ -71,6 +71,9 @@ static const struct
|
||||
};
|
||||
#define ndatabases (sizeof (databases) / sizeof (databases[0]))
|
||||
|
||||
/* Flags whether custom rules for database is set. */
|
||||
bool __nss_database_custom[NSS_DBSIDX_max];
|
||||
|
||||
|
||||
__libc_lock_define_initialized (static, lock)
|
||||
|
||||
@ -265,6 +268,7 @@ __nss_configure_lookup (const char *dbname, const char *service_line)
|
||||
|
||||
/* Install new rules. */
|
||||
*databases[cnt].dbp = new_db;
|
||||
__nss_database_custom[cnt] = true;
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 1996-1999,2001,2002,2003,2004,2007
|
||||
/* Copyright (C) 1996-1999,2001,2002,2003,2004,2007,2010
|
||||
Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
@ -28,6 +28,7 @@
|
||||
#include <resolv.h>
|
||||
#include <search.h>
|
||||
#include <dlfcn.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
/* Actions performed after lookup finished. */
|
||||
typedef enum
|
||||
@ -96,6 +97,19 @@ typedef struct name_database
|
||||
} name_database;
|
||||
|
||||
|
||||
/* Indices into DATABASES in nsswitch.c and __NSS_DATABASE_CUSTOM. */
|
||||
enum
|
||||
{
|
||||
#define DEFINE_DATABASE(arg) NSS_DBSIDX_##arg,
|
||||
#include "databases.def"
|
||||
#undef DEFINE_DATABASE
|
||||
NSS_DBSIDX_max
|
||||
};
|
||||
|
||||
/* Flags whether custom rules for database is set. */
|
||||
extern bool __nss_database_custom[NSS_DBSIDX_max];
|
||||
|
||||
|
||||
/* Interface functions for NSS. */
|
||||
|
||||
/* Get the data structure representing the specified database.
|
||||
|
72
nss/tst-nss-test1.c
Normal file
72
nss/tst-nss-test1.c
Normal file
@ -0,0 +1,72 @@
|
||||
#include <nss.h>
|
||||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
static int
|
||||
do_test (void)
|
||||
{
|
||||
int retval = 0;
|
||||
|
||||
__nss_configure_lookup ("passwd", "test1");
|
||||
|
||||
static const unsigned int pwdids[] = { 100, 30, 200, 60, 20000 };
|
||||
#define npwdids (sizeof (pwdids) / sizeof (pwdids[0]))
|
||||
setpwent ();
|
||||
|
||||
const unsigned int *np = pwdids;
|
||||
for (struct passwd *p = getpwent (); p != NULL; ++np, p = getpwent ())
|
||||
if (p->pw_uid != *np || strncmp (p->pw_name, "name", 4) != 0
|
||||
|| atol (p->pw_name + 4) != *np)
|
||||
{
|
||||
printf ("passwd entry %ju wrong (%s, %u)\n",
|
||||
np - pwdids, p->pw_name, p->pw_uid);
|
||||
retval = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
endpwent ();
|
||||
|
||||
for (int i = npwdids - 1; i >= 0; --i)
|
||||
{
|
||||
char buf[30];
|
||||
snprintf (buf, sizeof (buf), "name%u", pwdids[i]);
|
||||
|
||||
struct passwd *p = getpwnam (buf);
|
||||
if (p == NULL || p->pw_uid != pwdids[i] || strcmp (buf, p->pw_name) != 0)
|
||||
{
|
||||
printf ("passwd entry \"%s\" wrong\n", buf);
|
||||
retval = 1;
|
||||
}
|
||||
|
||||
p = getpwuid (pwdids[i]);
|
||||
if (p == NULL || p->pw_uid != pwdids[i] || strcmp (buf, p->pw_name) != 0)
|
||||
{
|
||||
printf ("passwd entry %u wrong\n", pwdids[i]);
|
||||
retval = 1;
|
||||
}
|
||||
|
||||
snprintf (buf, sizeof (buf), "name%u", pwdids[i] + 1);
|
||||
|
||||
p = getpwnam (buf);
|
||||
if (p != NULL)
|
||||
{
|
||||
printf ("passwd entry \"%s\" wrong\n", buf);
|
||||
retval = 1;
|
||||
}
|
||||
|
||||
p = getpwuid (pwdids[i] + 1);
|
||||
if (p != NULL)
|
||||
{
|
||||
printf ("passwd entry %u wrong\n", pwdids[i] + 1);
|
||||
retval = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
#define TEST_FUNCTION do_test ()
|
||||
#include "../test-skeleton.c"
|
@ -114,6 +114,10 @@ alpha.*-.*-linux.* libresolv=2.1
|
||||
.*-.*-.* libnss_ldap=2
|
||||
.*-.*-.* libnss_hesiod=2
|
||||
|
||||
# Tests for NSS. They must have the same NSS_SHLIB_REVISION number as
|
||||
# the rest.
|
||||
.*-.*-.* libnss_test1=2
|
||||
|
||||
# Version for libnsl with YP and NIS+ functions.
|
||||
alpha.*-.*-linux.* libnsl=1.1
|
||||
.*-.*-.* libnsl=1
|
||||
|
@ -600,7 +600,8 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||
&& ++__nss_not_use_nscd_hosts > NSS_NSCD_RETRY)
|
||||
__nss_not_use_nscd_hosts = 0;
|
||||
|
||||
if (!__nss_not_use_nscd_hosts)
|
||||
if (!__nss_not_use_nscd_hosts
|
||||
&& !__nss_database_custom[NSS_DBSIDX_hosts])
|
||||
{
|
||||
/* Try to use nscd. */
|
||||
struct nscd_ai_result *air = NULL;
|
||||
|
Loading…
Reference in New Issue
Block a user