diff --git a/ChangeLog b/ChangeLog index 257cc320d5..53f636ec10 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,51 @@ +2007-10-29 Ulrich Drepper + + * nscd/Makefile (nscd-modules): Replace gethstbynm2_r with + gethstbynm3_r. + * nscd/gethstbynm2_r.c: Remove. + * nscd/gethstbynm3_r.c: New file. + * nscd/aicache.c (addhstaiX): Use __gethostbyaddr2_r instead of + __gethostbyaddr_r. + * nscd/gethstbyad_r.c: Generate __gethostbyaddr2_r function. Define + __gethostbyaddr_r compatibility wrapper. + * nscd/hstcache.c (cache_addhst): Add ttl parameter. Use it when + determining timeout of entry. + (lookup): Take new parameter and pass it to __gethostbyname3_r and + __gethostbyaddr2_r. + (addhstbyX): Pass reference to variable for TTL to lookup and + cache_addhst. + * nss/Versions [glibc] (GLIBC_PRIVATE): Export __nss_passwd_lookup2, + __nss_group_lookup2, __nss_hosts_lookup2, __nss_services_lookup2, + and __nss_next2. Remove __nss_services_lookup. + * nss/XXX-lookup.c: Name function now *_lookup2. Add new parameter. + Add compat wrapper. + * nss/getXXbyYY_r.c: Changes to call new *_lookup2 functions and + __nss_next2. + * nss/getXXent_r.c: Likewise. + * nss/getnssent_r.c: Likewise. + * nss/nsswitch.c (__nss_lookup): Add new parameter. If first function + does not exist in module, try the optional second name. + (__nss_next2): New function. + (__nss_next): Now wrapper around __nss_next2. + * nss/nsswitch.h: Adjust __nss_lookup prototype. + Declare __nss_next2. + Adjust definition of db_lookup_function type. + * nss/service-lookup.c: Define NO_COMPAT. + * include/netdb.h: Declare __gethostbyaddr2_r and __gethostbyname3_r. + * inet/ether_hton.c: Use __nss_next2 instead of __nss_next. + * inet/ether_ntoh.c: Likewise. + * sunrpc/netname.c: Likewise. + * sunrpc/publickey.c: Likewise. + * inet/getnetgrent.c: Likewise. Adjust calls to __nss_lookup. + * inet/gethstbyad_r.c (DB_LOOKUP_FCT): Change to __nss_hosts_lookup2. + * inet/gethstbynm2_r.c (DB_LOOKUP_FCT): Likewise. + * inet/gethstbynm_r.c (DB_LOOKUP_FCT): Likewise. + * inet/gethstent_r.c (DB_LOOKUP_FCT): Likewise. + + * nscd/aicache.c (addhstaiX): Fix default TTL handling. + + * inet/getnetgrent.c (setup): Encrypt static pointer. + 2007-10-28 Ulrich Drepper [BZ #5204] diff --git a/inet/ether_hton.c b/inet/ether_hton.c index 64f5ab5d36..2bff47d472 100644 --- a/inet/ether_hton.c +++ b/inet/ether_hton.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1996, 1999, 2002 Free Software Foundation, Inc. +/* Copyright (C) 1996, 1999, 2002, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 1996. @@ -71,7 +71,7 @@ ether_hostton (const char *hostname, struct ether_addr *addr) status = (*fct.f) (hostname, ðerent, buffer, sizeof buffer, &errno); - no_more = __nss_next (&nip, "gethostton_r", &fct.ptr, status, 0); + no_more = __nss_next2 (&nip, "gethostton_r", NULL, &fct.ptr, status, 0); } if (status == NSS_STATUS_SUCCESS) diff --git a/inet/ether_ntoh.c b/inet/ether_ntoh.c index ad4165cb3e..9bc26b9fb6 100644 --- a/inet/ether_ntoh.c +++ b/inet/ether_ntoh.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1996, 1997, 1999, 2001, 2002 Free Software Foundation, Inc. +/* Copyright (C) 1996,1997,1999,2001,2002,2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 1996. @@ -72,7 +72,7 @@ ether_ntohost (char *hostname, const struct ether_addr *addr) status = (*fct.f) (addr, ðerent, buffer, sizeof buffer, &errno); - no_more = __nss_next (&nip, "getntohost_r", &fct.ptr, status, 0); + no_more = __nss_next2 (&nip, "getntohost_r", NULL, &fct.ptr, status, 0); } if (status == NSS_STATUS_SUCCESS) diff --git a/inet/gethstbyad_r.c b/inet/gethstbyad_r.c index 020ac489ef..b1f0f496f1 100644 --- a/inet/gethstbyad_r.c +++ b/inet/gethstbyad_r.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1996,1997,1998,1999,2000,2002 Free Software Foundation, Inc. +/* Copyright (C) 1996-2000,2002,2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 1996. @@ -48,6 +48,6 @@ } /* Special name for the lookup function. */ -#define DB_LOOKUP_FCT __nss_hosts_lookup +#define DB_LOOKUP_FCT __nss_hosts_lookup2 #include "../nss/getXXbyYY_r.c" diff --git a/inet/gethstbynm2_r.c b/inet/gethstbynm2_r.c index e1e691b2b5..de33dfc93b 100644 --- a/inet/gethstbynm2_r.c +++ b/inet/gethstbynm2_r.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1996, 1997, 2002 Free Software Foundation, Inc. +/* Copyright (C) 1996, 1997, 2002, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 1996. @@ -41,6 +41,6 @@ #define HAVE_AF 1 /* Special name for the lookup function. */ -#define DB_LOOKUP_FCT __nss_hosts_lookup +#define DB_LOOKUP_FCT __nss_hosts_lookup2 #include "../nss/getXXbyYY_r.c" diff --git a/inet/gethstbynm_r.c b/inet/gethstbynm_r.c index 5bc65f1391..16cc194641 100644 --- a/inet/gethstbynm_r.c +++ b/inet/gethstbynm_r.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1996, 1997, 1998, 2002 Free Software Foundation, Inc. +/* Copyright (C) 1996, 1997, 1998, 2002, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 1996. @@ -40,6 +40,6 @@ #define HAVE_LOOKUP_BUFFER 1 /* Special name for the lookup function. */ -#define DB_LOOKUP_FCT __nss_hosts_lookup +#define DB_LOOKUP_FCT __nss_hosts_lookup2 #include "../nss/getXXbyYY_r.c" diff --git a/inet/gethstent_r.c b/inet/gethstent_r.c index a7424a4188..943cf04550 100644 --- a/inet/gethstent_r.c +++ b/inet/gethstent_r.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1996, 2002 Free Software Foundation, Inc. +/* Copyright (C) 1996, 2002, 2007 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 @@ -30,6 +30,6 @@ #define NEED__RES 1 /* Special name for the lookup function. */ -#define DB_LOOKUP_FCT __nss_hosts_lookup +#define DB_LOOKUP_FCT __nss_hosts_lookup2 #include "../nss/getXXent_r.c" diff --git a/inet/getnetgrent_r.c b/inet/getnetgrent_r.c index 97b2b809f0..38701857cb 100644 --- a/inet/getnetgrent_r.c +++ b/inet/getnetgrent_r.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1996, 1997, 1998, 1999, 2002, 2004, 2005 +/* Copyright (C) 1996, 1997, 1998, 1999, 2002, 2004, 2005, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -18,13 +18,16 @@ 02111-1307 USA. */ #include +#include #include #include #include +#include #include #include #include "netgroup.h" #include "nsswitch.h" +#include /* Protect above variable against multiple uses at the same time. */ @@ -44,25 +47,32 @@ static int setup (void **fctp, service_user **nipp) { /* Remember the first service_entry, it's always the same. */ + static bool startp_initialized; static service_user *startp; int no_more; - if (startp == NULL) + if (!startp_initialized) { /* Executing this more than once at the same time must yield the same result every time. So we need no locking. */ no_more = __nss_netgroup_lookup (nipp, "setnetgrent", fctp); startp = no_more ? (service_user *) -1 : *nipp; + PTR_MANGLE (startp); + atomic_write_barrier (); + startp_initialized = true; } - else if (startp == (service_user *) -1) - /* No services at all. */ - return 1; else { + service_user *nip = startp; + PTR_DEMANGLE (nip); + if (nip == (service_user *) -1) + /* No services at all. */ + return 1; + /* Reset to the beginning of the service list. */ - *nipp = startp; + *nipp = nip; /* Look up the first function. */ - no_more = __nss_lookup (nipp, "setnetgrent", fctp); + no_more = __nss_lookup (nipp, "setnetgrent", NULL, fctp); } return no_more; } @@ -122,11 +132,12 @@ __internal_setnetgrent_reuse (const char *group, struct __netgrent *datap, { assert (datap->data == NULL); - /* Ignore status, we force check in `__nss_next'. */ + /* Ignore status, we force check in `__nss_next2'. */ status = (*fct.f) (group, datap); service_user *old_nip = datap->nip; - no_more = __nss_next (&datap->nip, "setnetgrent", &fct.ptr, status, 0); + no_more = __nss_next2 (&datap->nip, "setnetgrent", NULL, &fct.ptr, + status, 0); if (status == NSS_STATUS_SUCCESS && ! no_more) { @@ -423,8 +434,8 @@ innetgr (const char *netgroup, const char *host, const char *user, break; /* Look for the next service. */ - no_more = __nss_next (&entry.nip, "setnetgrent", - &setfct.ptr, status, 0); + no_more = __nss_next2 (&entry.nip, "setnetgrent", NULL, + &setfct.ptr, status, 0); } if (result == 0 && entry.needed_groups != NULL) diff --git a/nscd/Makefile b/nscd/Makefile index ecd8c89998..f83e40049a 100644 --- a/nscd/Makefile +++ b/nscd/Makefile @@ -32,7 +32,7 @@ include ../Makeconfig vpath %.c ../locale/programs nscd-modules := nscd connections pwdcache getpwnam_r getpwuid_r grpcache \ - getgrnam_r getgrgid_r hstcache gethstbyad_r gethstbynm2_r \ + getgrnam_r getgrgid_r hstcache gethstbyad_r gethstbynm3_r \ getsrvbynm_r getsrvbypt_r servicescache \ dbg_log nscd_conf nscd_stat cache mem nscd_setup_thread \ xmalloc xstrdup aicache initgrcache gai res_hconf @@ -106,7 +106,7 @@ CFLAGS-getgrnam_r.c += $(nscd-cflags) CFLAGS-getgrgid_r.c += $(nscd-cflags) CFLAGS-hstcache.c += $(nscd-cflags) CFLAGS-gethstbyad_r.c += $(nscd-cflags) -CFLAGS-gethstbynm2_r.c += $(nscd-cflags) +CFLAGS-gethstbynm3_r.c += $(nscd-cflags) CFLAGS-dbg_log.c += $(nscd-cflags) CFLAGS-nscd_conf.c += $(nscd-cflags) CFLAGS-nscd_stat.c += $(nscd-cflags) diff --git a/nscd/aicache.c b/nscd/aicache.c index 0dc892bc74..68706a4cf7 100644 --- a/nscd/aicache.c +++ b/nscd/aicache.c @@ -110,7 +110,7 @@ addhstaiX (struct database_dyn *db, int fd, request_header *req, size_t tmpbuf4len = 0; char *tmpbuf4 = NULL; char *canon = NULL; - int32_t ttl = UINT32_MAX; + int32_t ttl = INT32_MAX; ssize_t total = 0; char *key_copy = NULL; bool alloca_used = false; @@ -163,7 +163,7 @@ addhstaiX (struct database_dyn *db, int fd, request_header *req, rc4 = 0; status[1] = DL_CALL_FCT (fct, (key, AF_INET, &th[1], tmpbuf4, tmpbuf4len, &rc4, &herrno, - ttl == UINT32_MAX ? &ttl : NULL, + ttl == INT32_MAX ? &ttl : NULL, canon == NULL ? &canon : NULL)); if (rc4 != ERANGE || herrno != NETDB_INTERNAL) break; @@ -233,9 +233,9 @@ addhstaiX (struct database_dyn *db, int fd, request_header *req, int rc; while (1) { - rc = __gethostbyaddr_r (addr, addrlen, addrfamily, - &he_mem, tmpbuf, tmpbuflen, - &he, &herrno); + rc = __gethostbyaddr2_r (addr, addrlen, addrfamily, + &he_mem, tmpbuf, tmpbuflen, + &he, &herrno, NULL); if (rc != ERANGE || herrno != NETDB_INTERNAL) break; tmpbuf = extend_alloca (tmpbuf, tmpbuflen, @@ -285,7 +285,8 @@ addhstaiX (struct database_dyn *db, int fd, request_header *req, dataset->head.usable = true; /* Compute the timeout time. */ - dataset->head.timeout = time (NULL) + MIN (db->postimeout, ttl); + dataset->head.timeout = time (NULL) + (ttl == INT32_MAX + ? db->postimeout : ttl); dataset->resp.version = NSCD_VERSION; dataset->resp.found = 1; diff --git a/nscd/gethstbyad_r.c b/nscd/gethstbyad_r.c index e2e8dfe2cc..2e7a09c2bd 100644 --- a/nscd/gethstbyad_r.c +++ b/nscd/gethstbyad_r.c @@ -20,12 +20,25 @@ #define LOOKUP_TYPE struct hostent -#define FUNCTION_NAME gethostbyaddr +#define FUNCTION_NAME gethostbyaddr2 +#define FUNCTION2_NAME gethostbyaddr #define DATABASE_NAME hosts #define ADD_PARAMS const void *addr, socklen_t len, int type +#define EXTRA_PARAMS , int32_t *ttlp #define ADD_VARIABLES addr, len, type +#define EXTRA_VARIABLES , ttlp #define NEED_H_ERRNO 1 #define NEED__RES 1 #define NEED__RES_HCONF 1 #include "../nss/getXXbyYY_r.c" + + +int +__gethostbyaddr_r (const void *addr, socklen_t len, int type, + struct hostent *result_buf, char *buf, size_t buflen, + struct hostent **result, int *h_errnop) +{ + return __gethostbyaddr2_r (addr, len, type, result_buf, buf, buflen, + result, h_errnop, NULL); +} diff --git a/nscd/gethstbynm2_r.c b/nscd/gethstbynm3_r.c similarity index 76% rename from nscd/gethstbynm2_r.c rename to nscd/gethstbynm3_r.c index 85e95d4a63..a917f893b1 100644 --- a/nscd/gethstbynm2_r.c +++ b/nscd/gethstbynm3_r.c @@ -25,10 +25,13 @@ #define LOOKUP_TYPE struct hostent -#define FUNCTION_NAME gethostbyname2 +#define FUNCTION_NAME gethostbyname3 +#define FUNCTION2_NAME gethostbyname2 #define DATABASE_NAME hosts #define ADD_PARAMS const char *name, int af +#define EXTRA_PARAMS , int32_t *ttlp, char **canonp #define ADD_VARIABLES name, af +#define EXTRA_VARIABLES , ttlp, canonp #define NEED_H_ERRNO 1 #define NEED__RES_HCONF 1 @@ -39,3 +42,12 @@ #define __inet_aton inet_aton #include "../nss/getXXbyYY_r.c" + + +int +__gethostbyname2_r (const char *name, int af, struct hostent *ret, char *buf, + size_t buflen, struct hostent **result, int *h_errnop) +{ + return __gethostbyname3_r (name, af, ret, buf, buflen, result, h_errnop, + NULL, NULL); +} diff --git a/nscd/hstcache.c b/nscd/hstcache.c index 54222a3408..c93691dcfd 100644 --- a/nscd/hstcache.c +++ b/nscd/hstcache.c @@ -80,7 +80,8 @@ static const hst_response_header notfound = static void cache_addhst (struct database_dyn *db, int fd, request_header *req, const void *key, struct hostent *hst, uid_t owner, - struct hashentry *he, struct datahead *dh, int errval) + struct hashentry *he, struct datahead *dh, int errval, + int32_t ttl) { ssize_t total; ssize_t written; @@ -131,7 +132,8 @@ cache_addhst (struct database_dyn *db, int fd, request_header *req, dataset->head.usable = true; /* Compute the timeout time. */ - dataset->head.timeout = t + db->negtimeout; + dataset->head.timeout = t + (ttl == INT32_MAX + ? db->negtimeout : ttl); /* This is the reply. */ memcpy (&dataset->resp, ¬found, total); @@ -247,7 +249,7 @@ cache_addhst (struct database_dyn *db, int fd, request_header *req, dataset->head.usable = true; /* Compute the timeout time. */ - dataset->head.timeout = t + db->postimeout; + dataset->head.timeout = t + (ttl == INT32_MAX ? db->postimeout : ttl); dataset->resp.version = NSCD_VERSION; dataset->resp.found = 1; @@ -423,19 +425,19 @@ cache_addhst (struct database_dyn *db, int fd, request_header *req, static int lookup (int type, void *key, struct hostent *resultbufp, char *buffer, - size_t buflen, struct hostent **hst) + size_t buflen, struct hostent **hst, int32_t *ttlp) { if (type == GETHOSTBYNAME) - return __gethostbyname2_r (key, AF_INET, resultbufp, buffer, buflen, hst, - &h_errno); + return __gethostbyname3_r (key, AF_INET, resultbufp, buffer, buflen, hst, + &h_errno, ttlp, NULL); if (type == GETHOSTBYNAMEv6) - return __gethostbyname2_r (key, AF_INET6, resultbufp, buffer, buflen, hst, - &h_errno); + return __gethostbyname3_r (key, AF_INET6, resultbufp, buffer, buflen, hst, + &h_errno, ttlp, NULL); if (type == GETHOSTBYADDR) - return __gethostbyaddr_r (key, NS_INADDRSZ, AF_INET, resultbufp, buffer, - buflen, hst, &h_errno); - return __gethostbyaddr_r (key, NS_IN6ADDRSZ, AF_INET6, resultbufp, buffer, - buflen, hst, &h_errno); + return __gethostbyaddr2_r (key, NS_INADDRSZ, AF_INET, resultbufp, buffer, + buflen, hst, &h_errno, ttlp); + return __gethostbyaddr2_r (key, NS_IN6ADDRSZ, AF_INET6, resultbufp, buffer, + buflen, hst, &h_errno, ttlp); } @@ -453,6 +455,7 @@ addhstbyX (struct database_dyn *db, int fd, request_header *req, struct hostent *hst; bool use_malloc = false; int errval = 0; + int32_t ttl = INT32_MAX; if (__builtin_expect (debug_level > 0, 0)) { @@ -470,7 +473,7 @@ addhstbyX (struct database_dyn *db, int fd, request_header *req, dbg_log (_("Reloading \"%s\" in hosts cache!"), (char *) str); } - while (lookup (req->type, key, &resultbuf, buffer, buflen, &hst) != 0 + while (lookup (req->type, key, &resultbuf, buffer, buflen, &hst, &ttl) != 0 && h_errno == NETDB_INTERNAL && (errval = errno) == ERANGE) { @@ -504,7 +507,7 @@ addhstbyX (struct database_dyn *db, int fd, request_header *req, } cache_addhst (db, fd, req, key, hst, uid, he, dh, - h_errno == TRY_AGAIN ? errval : 0); + h_errno == TRY_AGAIN ? errval : 0, ttl); if (use_malloc) free (buffer); diff --git a/nss/Versions b/nss/Versions index 365f9e229b..8f2f0fb371 100644 --- a/nss/Versions +++ b/nss/Versions @@ -9,7 +9,10 @@ libc { } GLIBC_PRIVATE { _nss_files_parse_grent; _nss_files_parse_pwent; _nss_files_parse_spent; - __nss_disable_nscd; __nss_lookup_function; __nss_services_lookup; + __nss_disable_nscd; __nss_lookup_function; + + __nss_passwd_lookup2; __nss_group_lookup2; __nss_hosts_lookup2; + __nss_services_lookup2; __nss_next2; } } diff --git a/nss/XXX-lookup.c b/nss/XXX-lookup.c index da0e6f4510..f88d69e9ec 100644 --- a/nss/XXX-lookup.c +++ b/nss/XXX-lookup.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1996, 1997, 1999, 2000, 2002 Free Software Foundation, Inc. +/* Copyright (C) 1996, 1997, 1999, 2000, 2002, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 1996. @@ -34,7 +34,8 @@ |* *| \*******************************************************************/ -#define DB_LOOKUP_FCT CONCAT3_1 (__nss_, DATABASE_NAME, _lookup) +#define DB_LOOKUP_FCT CONCAT3_1 (__nss_, DATABASE_NAME, _lookup2) +#define DB_COMPAT_FCT CONCAT3_1 (__nss_, DATABASE_NAME, _lookup) #define CONCAT3_1(Pre, Name, Post) CONCAT3_2 (Pre, Name, Post) #define CONCAT3_2(Pre, Name, Post) Pre##Name##Post @@ -56,12 +57,14 @@ service_user *DATABASE_NAME_SYMBOL attribute_hidden; extern int DB_LOOKUP_FCT (service_user **ni, const char *fct_name, - void **fctp) internal_function; + const char *fct2_name, void **fctp) + internal_function; libc_hidden_proto (DB_LOOKUP_FCT) int internal_function -DB_LOOKUP_FCT (service_user **ni, const char *fct_name, void **fctp) +DB_LOOKUP_FCT (service_user **ni, const char *fct_name, const char *fct2_name, + void **fctp) { if (DATABASE_NAME_SYMBOL == NULL && __nss_database_lookup (DATABASE_NAME_STRING, ALTERNATE_NAME_STRING, @@ -70,6 +73,16 @@ DB_LOOKUP_FCT (service_user **ni, const char *fct_name, void **fctp) *ni = DATABASE_NAME_SYMBOL; - return __nss_lookup (ni, fct_name, fctp); + return __nss_lookup (ni, fct_name, fct2_name, fctp); } libc_hidden_def (DB_LOOKUP_FCT) + + +#ifndef NO_COMPAT +int +internal_function attribute_compat_text_section +DB_COMPAT_FCT (service_user **ni, const char *fct_name, void **fctp) +{ + return DB_LOOKUP_FCT (ni, fct_name, NULL, fctp); +} +#endif diff --git a/nss/getXXbyYY_r.c b/nss/getXXbyYY_r.c index 6c90ba543d..b535f67a7b 100644 --- a/nss/getXXbyYY_r.c +++ b/nss/getXXbyYY_r.c @@ -42,12 +42,18 @@ |* DATABASE_NAME - name of the database the function accesses *| |* (e.g., host, services, ...) *| |* *| -|* ADD_PARAMS - additional parameter, can vary in number *| +|* ADD_PARAMS - additional parameters, can vary in number *| |* *| -|* ADD_VARIABLES - names of additional parameter *| +|* ADD_VARIABLES - names of additional parameters *| |* *| |* Optionally the following vars can be defined: *| |* *| +|* EXTRA_PARAMS - optional parameters, can vary in number *| +|* *| +|* EXTRA_VARIABLES - names of optional parameter *| +|* *| +|* FUNCTION_NAME - alternative name of the non-reentrant function *| +|* *| |* NEED_H_ERRNO - an extra parameter will be passed to point to *| |* the global `h_errno' variable. *| |* *| @@ -62,6 +68,11 @@ /* To make the real sources a bit prettier. */ #define REENTRANT_NAME APPEND_R (FUNCTION_NAME) +#ifdef FUNCTION2_NAME +# define REENTRANT2_NAME APPEND_R (FUNCTION2_NAME) +#else +# define REENTRANT2_NAME NULL +#endif #define APPEND_R(name) APPEND_R1 (name) #define APPEND_R1(name) name##_r #define INTERNAL(name) INTERNAL1 (name) @@ -80,12 +91,17 @@ #define FUNCTION_NAME_STRING STRINGIZE (FUNCTION_NAME) #define REENTRANT_NAME_STRING STRINGIZE (REENTRANT_NAME) +#ifdef FUNCTION2_NAME +# define REENTRANT2_NAME_STRING STRINGIZE (REENTRANT2_NAME) +#else +# define REENTRANT2_NAME_STRING NULL +#endif #define DATABASE_NAME_STRING STRINGIZE (DATABASE_NAME) #define STRINGIZE(name) STRINGIZE1 (name) #define STRINGIZE1(name) #name #ifndef DB_LOOKUP_FCT -# define DB_LOOKUP_FCT CONCAT3_1 (__nss_, DATABASE_NAME, _lookup) +# define DB_LOOKUP_FCT CONCAT3_1 (__nss_, DATABASE_NAME, _lookup2) # define CONCAT3_1(Pre, Name, Post) CONCAT3_2 (Pre, Name, Post) # define CONCAT3_2(Pre, Name, Post) Pre##Name##Post #endif @@ -101,6 +117,13 @@ # define H_ERRNO_VAR_P NULL #endif +#ifndef EXTRA_PARAMS +# define EXTRA_PARAMS +#endif +#ifndef EXTRA_VARIABLES +# define EXTRA_VARIABLES +#endif + #ifdef HAVE_AF # define AF_VAL af #else @@ -109,17 +132,20 @@ /* Type of the lookup function we need here. */ typedef enum nss_status (*lookup_function) (ADD_PARAMS, LOOKUP_TYPE *, char *, - size_t, int * H_ERRNO_PARM); + size_t, int * H_ERRNO_PARM + EXTRA_PARAMS); /* The lookup function for the first entry of this service. */ -extern int DB_LOOKUP_FCT (service_user **nip, const char *name, void **fctp) +extern int DB_LOOKUP_FCT (service_user **nip, const char *name, + const char *name2, void **fctp) internal_function; libc_hidden_proto (DB_LOOKUP_FCT) int INTERNAL (REENTRANT_NAME) (ADD_PARAMS, LOOKUP_TYPE *resbuf, char *buffer, - size_t buflen, LOOKUP_TYPE **result H_ERRNO_PARM) + size_t buflen, LOOKUP_TYPE **result H_ERRNO_PARM + EXTRA_PARAMS) { static bool startp_initialized; static service_user *startp; @@ -171,7 +197,8 @@ INTERNAL (REENTRANT_NAME) (ADD_PARAMS, LOOKUP_TYPE *resbuf, char *buffer, if (! startp_initialized) { - no_more = DB_LOOKUP_FCT (&nip, REENTRANT_NAME_STRING, &fct.ptr); + no_more = DB_LOOKUP_FCT (&nip, REENTRANT_NAME_STRING, + REENTRANT2_NAME_STRING, &fct.ptr); if (no_more) { void *tmp_ptr = (service_user *) -1l; @@ -224,7 +251,7 @@ INTERNAL (REENTRANT_NAME) (ADD_PARAMS, LOOKUP_TYPE *resbuf, char *buffer, #endif status = DL_CALL_FCT (fct.l, (ADD_VARIABLES, resbuf, buffer, buflen, - &errno H_ERRNO_VAR)); + &errno H_ERRNO_VAR EXTRA_VARIABLES)); /* The status is NSS_STATUS_TRYAGAIN and errno is ERANGE the provided buffer is too small. In this case we should give @@ -238,8 +265,8 @@ INTERNAL (REENTRANT_NAME) (ADD_PARAMS, LOOKUP_TYPE *resbuf, char *buffer, && errno == ERANGE) break; - no_more = __nss_next (&nip, REENTRANT_NAME_STRING, - &fct.ptr, status, 0); + no_more = __nss_next2 (&nip, REENTRANT_NAME_STRING, + REENTRANT2_NAME_STRING, &fct.ptr, status, 0); } #ifdef HANDLE_DIGITS_DOTS @@ -274,10 +301,11 @@ done: } -#include -#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1_2) -#define OLD(name) OLD1 (name) -#define OLD1(name) __old_##name +#ifndef FUNCTION2_NAME +# include +# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1_2) +# define OLD(name) OLD1 (name) +# define OLD1(name) __old_##name int attribute_compat_text_section @@ -293,19 +321,20 @@ OLD (REENTRANT_NAME) (ADD_PARAMS, LOOKUP_TYPE *resbuf, char *buffer, return ret; } -#define do_symbol_version(real, name, version) \ +# define do_symbol_version(real, name, version) \ compat_symbol (libc, real, name, version) do_symbol_version (OLD (REENTRANT_NAME), REENTRANT_NAME, GLIBC_2_0); -#endif +# endif /* As INTERNAL (REENTRANT_NAME) may be hidden, we need an alias in between so that the REENTRANT_NAME@@GLIBC_2.1.2 is not hidden too. */ strong_alias (INTERNAL (REENTRANT_NAME), NEW (REENTRANT_NAME)); -#define do_default_symbol_version(real, name, version) \ +# define do_default_symbol_version(real, name, version) \ versioned_symbol (libc, real, name, version) do_default_symbol_version (NEW (REENTRANT_NAME), REENTRANT_NAME, GLIBC_2_1_2); +#endif static_link_warning (REENTRANT_NAME) diff --git a/nss/getXXent_r.c b/nss/getXXent_r.c index db4abaf5d7..7a881c02ac 100644 --- a/nss/getXXent_r.c +++ b/nss/getXXent_r.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1996,97,98,99,2000,2002,2004 Free Software Foundation, Inc. +/* Copyright (C) 1996-2000,2002,2004,2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 1996. @@ -64,7 +64,7 @@ #define STRINGIZE1(Name) #Name #ifndef DB_LOOKUP_FCT -# define DB_LOOKUP_FCT CONCAT3_1 (__nss_, DATABASE_NAME, _lookup) +# define DB_LOOKUP_FCT CONCAT3_1 (__nss_, DATABASE_NAME, _lookup2) # define CONCAT3_1(Pre, Name, Post) CONCAT3_2 (Pre, Name, Post) # define CONCAT3_2(Pre, Name, Post) Pre##Name##Post #endif @@ -113,7 +113,8 @@ static STAYOPEN_TMP; __libc_lock_define_initialized (static, lock) /* The lookup function for the first entry of this service. */ -extern int DB_LOOKUP_FCT (service_user **nip, const char *name, void **fctp) +extern int DB_LOOKUP_FCT (service_user **nip, const char *name, + const char *name2, void **fctp) internal_function; libc_hidden_proto (DB_LOOKUP_FCT) diff --git a/nss/getnssent_r.c b/nss/getnssent_r.c index a0cfa72bd2..f50667a18e 100644 --- a/nss/getnssent_r.c +++ b/nss/getnssent_r.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000, 2002, 2004 Free Software Foundation, Inc. +/* Copyright (C) 2000, 2002, 2004, 2007 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 @@ -30,7 +30,7 @@ setup (const char *func_name, db_lookup_function lookup_fct, int no_more; if (*startp == NULL) { - no_more = lookup_fct (nip, func_name, fctp); + no_more = lookup_fct (nip, func_name, NULL, fctp); *startp = no_more ? (service_user *) -1l : *nip; } else if (*startp == (service_user *) -1l) @@ -42,7 +42,7 @@ setup (const char *func_name, db_lookup_function lookup_fct, /* Reset to the beginning of the service list. */ *nip = *startp; /* Look up the first function. */ - no_more = __nss_lookup (nip, func_name, fctp); + no_more = __nss_lookup (nip, func_name, NULL, fctp); } return no_more; } @@ -80,8 +80,7 @@ __nss_setent (const char *func_name, db_lookup_function lookup_fct, else status = DL_CALL_FCT (fct.f, (0)); - no_more = __nss_next (nip, func_name, &fct.ptr, - status, 0); + no_more = __nss_next2 (nip, func_name, NULL, &fct.ptr, status, 0); if (is_last_nip) *last_nip = *nip; } @@ -120,7 +119,7 @@ __nss_endent (const char *func_name, db_lookup_function lookup_fct, /* We have processed all services which were used. */ break; - no_more = __nss_next (nip, func_name, &fct.ptr, 0, 1); + no_more = __nss_next2 (nip, func_name, NULL, &fct.ptr, 0, 1); } *last_nip = *nip = NULL; } @@ -177,8 +176,8 @@ __nss_getent_r (const char *getent_func_name, do { - no_more = __nss_next (nip, getent_func_name, &fct.ptr, - status, 0); + no_more = __nss_next2 (nip, getent_func_name, NULL, &fct.ptr, + status, 0); if (is_last_nip) *last_nip = *nip; @@ -192,8 +191,7 @@ __nss_getent_r (const char *getent_func_name, void *ptr; } sfct; - no_more = __nss_lookup (nip, setent_func_name, - &sfct.ptr); + no_more = __nss_lookup (nip, setent_func_name, NULL, &sfct.ptr); if (! no_more) { diff --git a/nss/nsswitch.c b/nss/nsswitch.c index 46965fd8ff..28aa1b4f34 100644 --- a/nss/nsswitch.c +++ b/nss/nsswitch.c @@ -145,9 +145,12 @@ libc_hidden_def (__nss_database_lookup) 0 == function found 1 == finished */ int -__nss_lookup (service_user **ni, const char *fct_name, void **fctp) +__nss_lookup (service_user **ni, const char *fct_name, const char *fct2_name, + void **fctp) { *fctp = __nss_lookup_function (*ni, fct_name); + if (*fctp == NULL && fct2_name != NULL) + *fctp = __nss_lookup_function (*ni, fct_name); while (*fctp == NULL && nss_next_action (*ni, NSS_STATUS_UNAVAIL) == NSS_ACTION_CONTINUE @@ -156,6 +159,8 @@ __nss_lookup (service_user **ni, const char *fct_name, void **fctp) *ni = (*ni)->next; *fctp = __nss_lookup_function (*ni, fct_name); + if (*fctp == NULL && fct2_name != NULL) + *fctp = __nss_lookup_function (*ni, fct_name); } return *fctp != NULL ? 0 : (*ni)->next == NULL ? 1 : -1; @@ -166,8 +171,8 @@ __nss_lookup (service_user **ni, const char *fct_name, void **fctp) 0 == adjusted for next function 1 == finished */ int -__nss_next (service_user **ni, const char *fct_name, void **fctp, int status, - int all_values) +__nss_next2 (service_user **ni, const char *fct_name, const char *fct2_name, + void **fctp, int status, int all_values) { if (all_values) { @@ -180,7 +185,8 @@ __nss_next (service_user **ni, const char *fct_name, void **fctp, int status, else { /* This is really only for debugging. */ - if (NSS_STATUS_TRYAGAIN > status || status > NSS_STATUS_RETURN) + if (__builtin_expect (NSS_STATUS_TRYAGAIN > status + || status > NSS_STATUS_RETURN, 0)) __libc_fatal ("illegal status in __nss_next"); if (nss_next_action (*ni, status) == NSS_ACTION_RETURN) @@ -195,6 +201,8 @@ __nss_next (service_user **ni, const char *fct_name, void **fctp, int status, *ni = (*ni)->next; *fctp = __nss_lookup_function (*ni, fct_name); + if (*fctp == NULL && fct2_name != NULL) + *fctp = __nss_lookup_function (*ni, fct2_name); } while (*fctp == NULL && nss_next_action (*ni, NSS_STATUS_UNAVAIL) == NSS_ACTION_CONTINUE @@ -202,7 +210,16 @@ __nss_next (service_user **ni, const char *fct_name, void **fctp, int status, return *fctp != NULL ? 0 : -1; } -libc_hidden_def (__nss_next) +libc_hidden_def (__nss_next2) + + +int +attribute_compat_text_section +__nss_next (service_user **ni, const char *fct_name, void **fctp, int status, + int all_values) +{ + return __nss_next2 (ni, fct_name, NULL, fctp, status, all_values); +} int diff --git a/nss/nsswitch.h b/nss/nsswitch.h index d222e0d443..b80edef651 100644 --- a/nss/nsswitch.h +++ b/nss/nsswitch.h @@ -110,7 +110,8 @@ libc_hidden_proto (__nss_database_lookup) /* 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. */ -extern int __nss_lookup (service_user **ni, const char *fct_name, void **fctp); +extern int __nss_lookup (service_user **ni, const char *fct_name, + const char *fct2_name, void **fctp) attribute_hidden; /* Determine the next step in the lookup process according to the result STATUS of the call to the last function returned by @@ -125,9 +126,12 @@ extern int __nss_lookup (service_user **ni, const char *fct_name, void **fctp); services. In other words, only if all four lookup results have the action RETURN associated the lookup process stops before the natural end. */ +extern int __nss_next2 (service_user **ni, const char *fct_name, + const char *fct2_name, void **fctp, int status, + int all_values) attribute_hidden; +libc_hidden_proto (__nss_next2) extern int __nss_next (service_user **ni, const char *fct_name, void **fctp, int status, int all_values); -libc_hidden_proto (__nss_next) /* Search for the service described in NI for a function named FCT_NAME and return a pointer to this function if successful. */ @@ -139,7 +143,8 @@ libc_hidden_proto (__nss_lookup_function) extern void __nss_disable_nscd (void); -typedef int (*db_lookup_function) (service_user **, const char *, void **) +typedef int (*db_lookup_function) (service_user **, const char *, const char *, + void **) internal_function; typedef enum nss_status (*setent_function) (int); typedef enum nss_status (*endent_function) (void); diff --git a/nss/service-lookup.c b/nss/service-lookup.c index 67d401e080..f3561855d4 100644 --- a/nss/service-lookup.c +++ b/nss/service-lookup.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1996, 1997 Free Software Foundation, Inc. +/* Copyright (C) 1996, 1997, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 1996. @@ -18,5 +18,6 @@ 02111-1307 USA. */ #define DATABASE_NAME services +#define NO_COMPAT #include "XXX-lookup.c" diff --git a/sunrpc/netname.c b/sunrpc/netname.c index 07cddb7c38..07ff768e6a 100644 --- a/sunrpc/netname.c +++ b/sunrpc/netname.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1997, 1998, 1999, 2002 Free Software Foundation, Inc. +/* Copyright (C) 1997, 1998, 1999, 2002, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Thorsten Kukuk , 1997. @@ -176,7 +176,7 @@ netname2user (const char netname[MAXNETNAMELEN + 1], uid_t * uidp, gid_t * gidp, { status = (*fct.f) (netname, uidp, gidp, gidlenp, gidlist); - no_more = __nss_next (&nip, "netname2user", &fct.ptr, status, 0); + no_more = __nss_next2 (&nip, "netname2user", NULL, &fct.ptr, status, 0); } return status == NSS_STATUS_SUCCESS; diff --git a/sunrpc/publickey.c b/sunrpc/publickey.c index 5b95edf632..dbadacaecd 100644 --- a/sunrpc/publickey.c +++ b/sunrpc/publickey.c @@ -1,5 +1,5 @@ /* Get public or secret key from key server. - Copyright (C) 1996, 1997, 1998, 1999, 2002 Free Software Foundation, Inc. + Copyright (C) 1996-1999,2002,2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 1996. @@ -71,7 +71,7 @@ getpublickey (const char *name, char *key) { status = (*fct.f) (name, key, &errno); - no_more = __nss_next (&nip, "getpublickey", &fct.ptr, status, 0); + no_more = __nss_next2 (&nip, "getpublickey", NULL, &fct.ptr, status, 0); } return status == NSS_STATUS_SUCCESS; @@ -114,7 +114,7 @@ getsecretkey (const char *name, char *key, const char *passwd) { status = (*fct.f) (name, key, passwd, &errno); - no_more = __nss_next (&nip, "getsecretkey", &fct.ptr, status, 0); + no_more = __nss_next2 (&nip, "getsecretkey", NULL, &fct.ptr, status, 0); } return status == NSS_STATUS_SUCCESS;