diff --git a/nscd/aicache.c b/nscd/aicache.c index 1b4245ea53..737ace11cc 100644 --- a/nscd/aicache.c +++ b/nscd/aicache.c @@ -77,9 +77,7 @@ addhstaiX (struct database_dyn *db, int fd, request_header *req, int rc4 = 0; int herrno = 0; - no_more = __nss_database_lookup2 ("hosts", NULL, - "dns [!UNAVAIL=return] files", - &nip); + no_more = !__nss_database_get (nss_database_hosts, &nip); /* Initialize configurations. */ struct resolv_context *ctx = __resolv_context_get (); diff --git a/nscd/initgrcache.c b/nscd/initgrcache.c index f7e326811f..62d7316f70 100644 --- a/nscd/initgrcache.c +++ b/nscd/initgrcache.c @@ -82,8 +82,7 @@ addinitgroupsX (struct database_dyn *db, int fd, request_header *req, int no_more; if (group_database == NULL) - no_more = __nss_database_lookup2 ("group", NULL, "files", - &group_database); + no_more = !__nss_database_get (nss_database_group, &group_database); else no_more = 0; nip = group_database; diff --git a/nscd/netgroupcache.c b/nscd/netgroupcache.c index ad2daddafd..2f71bf2999 100644 --- a/nscd/netgroupcache.c +++ b/nscd/netgroupcache.c @@ -143,7 +143,7 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req, *tofreep = NULL; if (netgroup_database == NULL - && __nss_database_lookup2 ("netgroup", NULL, NULL, &netgroup_database)) + && !__nss_database_get (nss_database_netgroup, &netgroup_database)) { /* No such service. */ cacheable = do_notfound (db, fd, req, key, &dataset, &total, &timeout, diff --git a/nss/Makefile b/nss/Makefile index 0906202db9..71fbe583bf 100644 --- a/nss/Makefile +++ b/nss/Makefile @@ -63,6 +63,7 @@ tests = test-netdb test-digits-dots tst-nss-getpwent bug17079 \ xtests = bug-erange tests-container = \ + tst-nss-compat1 \ tst-nss-test3 \ tst-nss-files-hosts-long \ tst-nss-db-endpwent \ diff --git a/nss/Versions b/nss/Versions index 71703750bf..fdddea104c 100644 --- a/nss/Versions +++ b/nss/Versions @@ -17,7 +17,7 @@ libc { __nss_passwd_lookup2; __nss_group_lookup2; __nss_hosts_lookup2; __nss_services_lookup2; __nss_next2; __nss_lookup; - __nss_hash; __nss_database_lookup2; + __nss_hash; __nss_database_get; __nss_files_fopen; __nss_readline; __nss_parse_line_result; } } diff --git a/nss/XXX-lookup.c b/nss/XXX-lookup.c index 48fc7b92fc..f1c97f7c8e 100644 --- a/nss/XXX-lookup.c +++ b/nss/XXX-lookup.c @@ -37,27 +37,20 @@ #define CONCAT3_1(Pre, Name, Post) CONCAT3_2 (Pre, Name, Post) #define CONCAT3_2(Pre, Name, Post) Pre##Name##Post +#define DATABASE_NAME_ID CONCAT2_1 (nss_database_, DATABASE_NAME) +#define CONCAT2_1(Pre, Name) CONCAT2_2 (Pre, Name) +#define CONCAT2_2(Pre, Name) Pre##Name + #define DATABASE_NAME_SYMBOL CONCAT3_1 (__nss_, DATABASE_NAME, _database) #define DATABASE_NAME_STRING STRINGIFY1 (DATABASE_NAME) #define STRINGIFY1(Name) STRINGIFY2 (Name) #define STRINGIFY2(Name) #Name -#ifdef ALTERNATE_NAME -#define ALTERNATE_NAME_STRING STRINGIFY1 (ALTERNATE_NAME) -#else -#define ALTERNATE_NAME_STRING NULL -#endif - -#ifndef DEFAULT_CONFIG -#define DEFAULT_CONFIG NULL -#endif - int DB_LOOKUP_FCT (nss_action_list *ni, const char *fct_name, const char *fct2_name, void **fctp) { - if (__nss_database_lookup2 (DATABASE_NAME_STRING, ALTERNATE_NAME_STRING, - DEFAULT_CONFIG, &DATABASE_NAME_SYMBOL) < 0) + if (! __nss_database_get (DATABASE_NAME_ID, &DATABASE_NAME_SYMBOL)) return -1; *ni = DATABASE_NAME_SYMBOL; diff --git a/nss/databases.def b/nss/databases.def index df5fab4168..3dc95648a8 100644 --- a/nss/databases.def +++ b/nss/databases.def @@ -23,17 +23,20 @@ DEFINE_DATABASE (aliases) DEFINE_DATABASE (ethers) DEFINE_DATABASE (group) +DEFINE_DATABASE (group_compat) DEFINE_DATABASE (gshadow) DEFINE_DATABASE (hosts) DEFINE_DATABASE (initgroups) DEFINE_DATABASE (netgroup) DEFINE_DATABASE (networks) DEFINE_DATABASE (passwd) +DEFINE_DATABASE (passwd_compat) DEFINE_DATABASE (protocols) DEFINE_DATABASE (publickey) DEFINE_DATABASE (rpc) DEFINE_DATABASE (services) DEFINE_DATABASE (shadow) +DEFINE_DATABASE (shadow_compat) /* Local Variables: diff --git a/nss/grp-lookup.c b/nss/grp-lookup.c index 7099544be5..034fa2ab7f 100644 --- a/nss/grp-lookup.c +++ b/nss/grp-lookup.c @@ -19,6 +19,5 @@ #include #define DATABASE_NAME group -#define DEFAULT_CONFIG "files" #include "XXX-lookup.c" diff --git a/nss/hosts-lookup.c b/nss/hosts-lookup.c index c96b60ed66..1acafd01cd 100644 --- a/nss/hosts-lookup.c +++ b/nss/hosts-lookup.c @@ -17,6 +17,5 @@ . */ #define DATABASE_NAME hosts -#define DEFAULT_CONFIG "dns [!UNAVAIL=return] files" #include "XXX-lookup.c" diff --git a/nss/key-lookup.c b/nss/key-lookup.c index 60d803ded5..aa267d36f9 100644 --- a/nss/key-lookup.c +++ b/nss/key-lookup.c @@ -17,6 +17,5 @@ . */ #define DATABASE_NAME publickey -#define DEFAULT_CONFIG "nis nisplus" #include "XXX-lookup.c" diff --git a/nss/network-lookup.c b/nss/network-lookup.c index 8c1eeb3c84..eed4dc3d0f 100644 --- a/nss/network-lookup.c +++ b/nss/network-lookup.c @@ -17,6 +17,5 @@ . */ #define DATABASE_NAME networks -#define DEFAULT_CONFIG "dns [!UNAVAIL=return] files" #include "XXX-lookup.c" diff --git a/nss/nss_compat/compat-grp.c b/nss/nss_compat/compat-grp.c index eb4c68d5d4..aaf35e75b4 100644 --- a/nss/nss_compat/compat-grp.c +++ b/nss/nss_compat/compat-grp.c @@ -81,7 +81,7 @@ static bool in_blacklist (const char *, int, ent_t *); static void init_nss_interface (void) { - if (__nss_database_lookup2 ("group_compat", NULL, "nis", &ni) >= 0) + if (__nss_database_get (nss_database_group_compat, &ni)) { setgrent_impl = __nss_lookup_function (ni, "setgrent"); getgrnam_r_impl = __nss_lookup_function (ni, "getgrnam_r"); diff --git a/nss/nss_compat/compat-initgroups.c b/nss/nss_compat/compat-initgroups.c index cfd36b64b8..c3b065c931 100644 --- a/nss/nss_compat/compat-initgroups.c +++ b/nss/nss_compat/compat-initgroups.c @@ -91,7 +91,7 @@ init_nss_interface (void) /* Retest. */ if (ni == NULL - && __nss_database_lookup2 ("group_compat", NULL, "nis", &ni) >= 0) + && __nss_database_get (nss_database_group_compat, &ni)) { initgroups_dyn_impl = __nss_lookup_function (ni, "initgroups_dyn"); getgrnam_r_impl = __nss_lookup_function (ni, "getgrnam_r"); diff --git a/nss/nss_compat/compat-pwd.c b/nss/nss_compat/compat-pwd.c index f536754559..64d708ff63 100644 --- a/nss/nss_compat/compat-pwd.c +++ b/nss/nss_compat/compat-pwd.c @@ -91,7 +91,7 @@ static bool in_blacklist (const char *, int, ent_t *); static void init_nss_interface (void) { - if (__nss_database_lookup2 ("passwd_compat", NULL, "nis", &ni) >= 0) + if (__nss_database_get (nss_database_passwd_compat, &ni)) { setpwent_impl = __nss_lookup_function (ni, "setpwent"); getpwnam_r_impl = __nss_lookup_function (ni, "getpwnam_r"); diff --git a/nss/nss_compat/compat-spwd.c b/nss/nss_compat/compat-spwd.c index 5c91f9572a..b548dfbee1 100644 --- a/nss/nss_compat/compat-spwd.c +++ b/nss/nss_compat/compat-spwd.c @@ -88,8 +88,7 @@ static bool in_blacklist (const char *, int, ent_t *); static void init_nss_interface (void) { - if (__nss_database_lookup2 ("shadow_compat", "passwd_compat", - "nis", &ni) >= 0) + if (__nss_database_get (nss_database_shadow_compat, &ni)) { setspent_impl = __nss_lookup_function (ni, "setspent"); getspnam_r_impl = __nss_lookup_function (ni, "getspnam_r"); diff --git a/nss/nss_database.c b/nss/nss_database.c index fb72d0cc03..1e11294406 100644 --- a/nss/nss_database.c +++ b/nss/nss_database.c @@ -93,13 +93,16 @@ enum nss_database_default static const char per_database_defaults[NSS_DATABASE_COUNT] = { [nss_database_group] = nss_database_default_compat, + [nss_database_group_compat] = nss_database_default_nis, [nss_database_gshadow] = nss_database_default_files, [nss_database_hosts] = nss_database_default_dns, [nss_database_initgroups] = nss_database_default_none, [nss_database_networks] = nss_database_default_dns, [nss_database_passwd] = nss_database_default_compat, + [nss_database_passwd_compat] = nss_database_default_nis, [nss_database_publickey] = nss_database_default_nis_nisplus, [nss_database_shadow] = nss_database_default_compat, + [nss_database_shadow_compat] = nss_database_default_nis, }; struct nss_database_default_cache @@ -166,13 +169,12 @@ nss_database_select_default (struct nss_database_default_cache *cache, assert (errno == ENOMEM); return false; } - else - return true; + return true; } /* database_name must be large enough for each individual name plus a null terminator. */ -typedef char database_name[11]; +typedef char database_name[14]; #define DEFINE_DATABASE(name) \ _Static_assert (sizeof (#name) <= sizeof (database_name), #name); #include "databases.def" @@ -323,14 +325,43 @@ nss_database_reload (struct nss_database_data *staging, /* No other threads have access to fp. */ __fsetlocking (fp, FSETLOCKING_BYCALLER); + /* We start with all of *staging pointing to NULL. */ + bool ok = true; if (fp != NULL) ok = nss_database_reload_1 (staging, fp); + /* Now we have non-NULL entries where the user explictly listed the + service in nsswitch.conf. */ + /* Apply defaults. */ if (ok) { struct nss_database_default_cache cache = { }; + + /* These three default to other services if the user listed the + other service. */ + + /* "shadow_compat" defaults to "passwd_compat" if only the + latter is given. */ + if (staging->services[nss_database_shadow_compat] == NULL) + staging->services[nss_database_shadow_compat] = + staging->services[nss_database_passwd_compat]; + + /* "shadow" defaults to "passwd" if only the latter is + given. */ + if (staging->services[nss_database_shadow] == NULL) + staging->services[nss_database_shadow] = + staging->services[nss_database_passwd]; + + /* "gshadow" defaults to "group" if only the latter is + given. */ + if (staging->services[nss_database_gshadow] == NULL) + staging->services[nss_database_gshadow] = + staging->services[nss_database_group]; + + /* For anything still unspecified, load the default configs. */ + for (int i = 0; i < NSS_DATABASE_COUNT; ++i) if (staging->services[i] == NULL) { @@ -440,6 +471,7 @@ __nss_database_get (enum nss_database db, nss_action_list *actions) struct nss_database_state *local = nss_database_state_get (); return nss_database_check_reload_and_get (local, actions, db); } +libc_hidden_def (__nss_database_get) nss_action_list __nss_database_get_noreload (enum nss_database db) diff --git a/nss/nss_database.h b/nss/nss_database.h index 1f827e6def..d4b23b5295 100644 --- a/nss/nss_database.h +++ b/nss/nss_database.h @@ -52,12 +52,11 @@ enum nss_database NSS_DATABASE_COUNT }; - /* Looks up the action list for DB and stores it in *ACTIONS. Returns true on success or false on failure. Success can mean that *ACTIONS is NULL. */ -bool __nss_database_get (enum nss_database db, nss_action_list *actions) - attribute_hidden; +bool __nss_database_get (enum nss_database db, nss_action_list *actions); +libc_hidden_proto (__nss_database_get) /* Like __nss_database_get, but does not reload /etc/nsswitch.conf from disk. This assumes that there has been a previous successful diff --git a/nss/nss_module.c b/nss/nss_module.c index 6c5f341f3e..60c070c851 100644 --- a/nss/nss_module.c +++ b/nss/nss_module.c @@ -31,14 +31,6 @@ #include #include -#ifdef LINK_OBSOLETE_NSL -# define DEFAULT_CONFIG "compat [NOTFOUND=return] files" -# define DEFAULT_DEFCONFIG "nis [NOTFOUND=return] files" -#else -# define DEFAULT_CONFIG "files" -# define DEFAULT_DEFCONFIG "files" -#endif - /* Suffix after .so of NSS service modules. This is a bit of magic, but we assume LIBNSS_FILES_SO looks like "libnss_files.so.2" and we want a pointer to the ".2" part. We have no API to extract this @@ -292,11 +284,11 @@ __nss_module_get_function (struct nss_module *module, const char *name) #if defined SHARED && defined USE_NSCD /* Load all libraries for the service. */ static void -nss_load_all_libraries (const char *service, const char *def) +nss_load_all_libraries (enum nss_database service) { nss_action_list ni = NULL; - if (__nss_database_lookup2 (service, NULL, def, &ni) == 0) + if (__nss_database_get (service, &ni)) while (ni->module != NULL) { __nss_module_load (ni->module); @@ -323,10 +315,10 @@ __nss_disable_nscd (void (*cb) (size_t, struct traced_file *)) is_nscd = true; /* Find all the relevant modules so that the init functions are called. */ - nss_load_all_libraries ("passwd", DEFAULT_CONFIG); - nss_load_all_libraries ("group", DEFAULT_CONFIG); - nss_load_all_libraries ("hosts", "dns [!UNAVAIL=return] files"); - nss_load_all_libraries ("services", NULL); + nss_load_all_libraries (nss_database_passwd); + nss_load_all_libraries (nss_database_group); + nss_load_all_libraries (nss_database_hosts); + nss_load_all_libraries (nss_database_services); /* Make sure NSCD purges its cache if nsswitch.conf changes. */ init_traced_file (&pwd_traced_file.file, _PATH_NSSWITCH_CONF, 0); diff --git a/nss/nss_test.h b/nss/nss_test.h index f8b81c27a7..db3d617585 100644 --- a/nss/nss_test.h +++ b/nss/nss_test.h @@ -33,11 +33,13 @@ #include #include +#include #include typedef struct test_tables { struct passwd *pwd_table; struct group *grp_table; + struct spwd *spwd_table; struct hostent *host_table; } test_tables; @@ -46,10 +48,12 @@ extern void _nss_test2_init_hook (test_tables *) __attribute__((weak)); #define PWD_LAST() { .pw_name = NULL, .pw_uid = 0 } #define GRP_LAST() { .gr_name = NULL, .gr_gid = 0 } +#define SPWD_LAST() { .sp_namp = NULL, .sp_pwdp = NULL } #define HOST_LAST() { .h_name = NULL, .h_aliases = NULL, .h_length = 0, .h_addr_list = NULL } #define PWD_ISLAST(p) ((p)->pw_name == NULL && (p)->pw_uid == 0) #define GRP_ISLAST(g) ((g)->gr_name == NULL && (g)->gr_gid == 0) +#define SPWD_ISLAST(s) ((s)->sp_namp == NULL && (s)->sp_pwdp == 0) #define HOST_ISLAST(h) ((h)->h_name == NULL && (h)->h_length == 0) /* Macros to fill in the tables easily. */ @@ -76,6 +80,9 @@ extern void _nss_test2_init_hook (test_tables *) __attribute__((weak)); { .gr_name = (char *) n, .gr_passwd = (char *) "*", .gr_gid = u, \ .gr_mem = (char **) m } +#define SPWD(u) \ + { .sp_namp = (char *) "name" #u, .sp_pwdp = (char *) "passwd" #u } + #define HOST(u) \ { .h_name = (char *) "name" #u, .h_aliases = NULL, .h_addrtype = u, \ .h_length = 4, \ diff --git a/nss/nss_test1.c b/nss/nss_test1.c index f73c7a6cd8..f8d81831ee 100644 --- a/nss/nss_test1.c +++ b/nss/nss_test1.c @@ -66,6 +66,9 @@ static int npwd_data = default_npwd_data; static struct group *grp_data = NULL; static int ngrp_data = 0; +static struct spwd *spwd_data = NULL; +static int nspwd_data = 0; + static struct hostent *host_data = NULL; static int nhost_data = 0; @@ -102,6 +105,13 @@ init(void) ; ngrp_data = i; } + if (t.spwd_table) + { + spwd_data = t.spwd_table; + for (i=0; ! SPWD_ISLAST(& spwd_data[i]); i++) + ; + nspwd_data = i; + } if (t.host_table) { host_data = t.host_table; @@ -323,6 +333,89 @@ NAME(getgrnam_r) (const char *name, struct group *result, char *buffer, return NSS_STATUS_NOTFOUND; } +/* -------------------------------------------------- */ +/* Shadow password handling. */ + +static size_t spwd_iter; +#define CURSPWD spwd_data[spwd_iter] + +static pthread_mutex_t spwd_lock = PTHREAD_MUTEX_INITIALIZER; + +enum nss_status +NAME(setspent) (int stayopen) +{ + init(); + spwd_iter = 0; + return NSS_STATUS_SUCCESS; +} + + +enum nss_status +NAME(endspwent) (void) +{ + init(); + return NSS_STATUS_SUCCESS; +} + +static enum nss_status +copy_shadow (struct spwd *result, struct spwd *local, + char *buffer, size_t buflen, int *errnop) +{ + struct alloc_buffer buf = alloc_buffer_create (buffer, buflen); + + result->sp_namp = alloc_buffer_maybe_copy_string (&buf, local->sp_namp); + result->sp_pwdp = alloc_buffer_maybe_copy_string (&buf, local->sp_pwdp); + result->sp_lstchg = local->sp_lstchg; + result->sp_min = local->sp_min; + result->sp_max = local->sp_max; + result->sp_warn = local->sp_warn; + result->sp_inact = local->sp_inact; + result->sp_expire = local->sp_expire; + result->sp_flag = local->sp_flag; + + if (alloc_buffer_has_failed (&buf)) + { + *errnop = ERANGE; + return NSS_STATUS_TRYAGAIN; + } + + return NSS_STATUS_SUCCESS; +} + +enum nss_status +NAME(getspent_r) (struct spwd *result, char *buffer, size_t buflen, + int *errnop) +{ + int res = NSS_STATUS_SUCCESS; + + init(); + pthread_mutex_lock (&spwd_lock); + + if (spwd_iter >= nspwd_data) + res = NSS_STATUS_NOTFOUND; + else + { + res = copy_shadow (result, &CURSPWD, buffer, buflen, errnop); + ++spwd_iter; + } + + pthread_mutex_unlock (&spwd_lock); + + return res; +} + +enum nss_status +NAME(getspnam_r) (const char *name, struct spwd *result, char *buffer, + size_t buflen, int *errnop) +{ + init(); + for (size_t idx = 0; idx < nspwd_data; ++idx) + if (strcmp (spwd_data[idx].sp_namp, name) == 0) + return copy_shadow (result, &spwd_data[idx], buffer, buflen, errnop); + + return NSS_STATUS_NOTFOUND; +} + /* -------------------------------------------------- */ /* Host handling. */ diff --git a/nss/nsswitch.c b/nss/nsswitch.c index 46f232d720..6b7d4c780b 100644 --- a/nss/nsswitch.c +++ b/nss/nsswitch.c @@ -51,53 +51,13 @@ #undef DEFINE_DATABASE -#undef DEFINE_DATABASE -#define DEFINE_DATABASE(name) #name, -static const char * database_names[] = { -#include "databases.def" - NULL -}; - #ifdef USE_NSCD /* Flags whether custom rules for database is set. */ bool __nss_database_custom[NSS_DBSIDX_max]; #endif - /*__libc_lock_define_initialized (static, lock)*/ -/* -1 == database not found - 0 == database entry pointer stored */ -int -__nss_database_lookup2 (const char *database, const char *alternate_name, - const char *defconfig, nss_action_list *ni) -{ - int database_id; - - for (database_id = 0; database_names[database_id]; database_id++) - if (strcmp (database_names[database_id], database) == 0) - break; - - if (database_names[database_id] == NULL) - return -1; - - /* If *NI is NULL, the database was not mentioned in nsswitch.conf. - If *NI is not NULL, but *NI->module is NULL, the database was in - nsswitch.conf but listed no actions. We test for the former. */ - if (__nss_database_get (database_id, ni) && *ni != NULL) - { - /* Success. */ - return 0; - } - else - { - /* Failure. */ - return -1; - } -} -libc_hidden_def (__nss_database_lookup2) - - /* -1 == not found 0 == function found 1 == finished */ diff --git a/nss/nsswitch.h b/nss/nsswitch.h index c483bbd891..ab782b605e 100644 --- a/nss/nsswitch.h +++ b/nss/nsswitch.h @@ -88,15 +88,6 @@ extern bool __nss_database_custom[NSS_DBSIDX_max] attribute_hidden; /* Interface functions for NSS. */ -/* Get the data structure representing the specified database. - If there is no configuration for this database in the file, - parse a service list from DEFCONFIG and use that. More - than one function can use the database. */ -extern int __nss_database_lookup2 (const char *database, - const char *alternative_name, - const char *defconfig, struct nss_action **ni); -libc_hidden_proto (__nss_database_lookup2) - /* Put first function with name FCT_NAME for SERVICE in FCTP. The position is remembered in NI. The function returns a value < 0 if an error occurred or no such function exists. */ diff --git a/nss/pwd-lookup.c b/nss/pwd-lookup.c index 4f5c47422f..5ec8a8b485 100644 --- a/nss/pwd-lookup.c +++ b/nss/pwd-lookup.c @@ -19,6 +19,5 @@ #include #define DATABASE_NAME passwd -#define DEFAULT_CONFIG "files" #include "XXX-lookup.c" diff --git a/nss/sgrp-lookup.c b/nss/sgrp-lookup.c index 6df4c49ff1..9a2becc202 100644 --- a/nss/sgrp-lookup.c +++ b/nss/sgrp-lookup.c @@ -17,7 +17,5 @@ . */ #define DATABASE_NAME gshadow -#define ALTERNATE_NAME group -#define DEFAULT_CONFIG "files" #include "XXX-lookup.c" diff --git a/nss/spwd-lookup.c b/nss/spwd-lookup.c index e3c8c1df7b..e9e661af12 100644 --- a/nss/spwd-lookup.c +++ b/nss/spwd-lookup.c @@ -19,7 +19,5 @@ #include #define DATABASE_NAME shadow -#define ALTERNATE_NAME passwd -#define DEFAULT_CONFIG "files" #include "XXX-lookup.c" diff --git a/nss/tst-nss-compat1.c b/nss/tst-nss-compat1.c new file mode 100644 index 0000000000..670cffe538 --- /dev/null +++ b/nss/tst-nss-compat1.c @@ -0,0 +1,81 @@ +/* Test error checking for group entries. + Copyright (C) 2021 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 + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include +#include +#include + +#include + +#include +#include + +#include "nss_test.h" + +static struct passwd pwd_table[] = { + PWD (100), + PWD (30), + PWD_LAST () + }; + +static struct spwd spwd_table[] = { + SPWD (100), + SPWD (30), + SPWD_LAST () + }; + +void +_nss_test1_init_hook(test_tables *t) +{ + t->pwd_table = pwd_table; + t->spwd_table = spwd_table; +} + +static int +do_test (void) +{ + struct passwd *p = NULL; + struct spwd *s = NULL; + struct group *g = NULL; + + /* Test that compat-to-test works. */ + p = getpwuid (100); + if (p == NULL) + FAIL_EXIT1("getpwuid-compat-test1 p"); + else if (strcmp (p->pw_name, "name100") != 0) + FAIL_EXIT1("getpwuid-compat-test1 name100"); + + /* Shadow compat should use passwd via the alternate name. */ + s = getspnam ("name30"); + if (s == NULL) + FAIL_EXIT1("getspnam-compat-test1 s"); + else if (strcmp (s->sp_namp, "name30") != 0) + FAIL_EXIT1("getpwuid-compat-test1 name30"); + + /* Test that internal defconfig works. */ + g = getgrgid (100); + if (g == NULL) + FAIL_EXIT1("getgrgid-compat-null"); + if (strcmp (g->gr_name, "wilma") != 0) + FAIL_EXIT1("getgrgid-compat-name"); + + return 0; +} + +#include diff --git a/nss/tst-nss-compat1.root/etc/group b/nss/tst-nss-compat1.root/etc/group new file mode 100644 index 0000000000..ee467c7950 --- /dev/null +++ b/nss/tst-nss-compat1.root/etc/group @@ -0,0 +1 @@ +wilma:x:100: diff --git a/nss/tst-nss-compat1.root/etc/nsswitch.conf b/nss/tst-nss-compat1.root/etc/nsswitch.conf new file mode 100644 index 0000000000..7fe69d5ffa --- /dev/null +++ b/nss/tst-nss-compat1.root/etc/nsswitch.conf @@ -0,0 +1,3 @@ +passwd : compat +passwd_compat : test1 + diff --git a/nss/tst-nss-compat1.root/etc/passwd b/nss/tst-nss-compat1.root/etc/passwd new file mode 100644 index 0000000000..84635587bd --- /dev/null +++ b/nss/tst-nss-compat1.root/etc/passwd @@ -0,0 +1,3 @@ +name5:x:5:555:name5 for testing:/home/name5:/bin/nologin ++name100 ++name30 diff --git a/nss/tst-nss-compat1.root/etc/shadow b/nss/tst-nss-compat1.root/etc/shadow new file mode 100644 index 0000000000..cba3152172 --- /dev/null +++ b/nss/tst-nss-compat1.root/etc/shadow @@ -0,0 +1,2 @@ ++name100 ++name30 diff --git a/nss/tst-nss-compat1.root/tst-nss-compat1.script b/nss/tst-nss-compat1.root/tst-nss-compat1.script new file mode 100644 index 0000000000..fe6e863f01 --- /dev/null +++ b/nss/tst-nss-compat1.root/tst-nss-compat1.script @@ -0,0 +1 @@ +cp $B/nss/libnss_test1.so $L/libnss_test1.so.2 diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c index 92d2a1c284..b7e1aee80f 100644 --- a/sysdeps/posix/getaddrinfo.c +++ b/sysdeps/posix/getaddrinfo.c @@ -720,9 +720,7 @@ gaih_inet (const char *name, const struct gaih_service *service, } #endif - no_more = __nss_database_lookup2 ("hosts", NULL, - "dns [!UNAVAIL=return] files", - &nip); + no_more = !__nss_database_get (nss_database_hosts, &nip); /* If we are looking for both IPv4 and IPv6 address we don't want the lookup functions to automatically promote IPv4