[PATCH v2 08/23] nscd: Fix data races in client retry counters (bug 33654)

Florian Weimer fweimer@redhat.com
Fri Mar 20 20:42:04 GMT 2026


Store the skip counters inside struct mapped_database.  Introduce
helper functions __nscd_use_database, __nscd_defer_database,
__nscd_disable_database to access these counters.

Teach the NSS code to translate to nscd database indices when
calling these functions.

Remove the special check from getaddrinfo (in get_nscd_addresses)
that avoided fallback to an in-process operation for nscd protocol
errors.  Errors from service modules still produce a response
from the nscd, so this check only avoided fallback if there were
certain nscd communication errors.  Checking the skip counters
in this way for nscd usage was not reliable because another thread
might have updated the skip counters.
---
 nscd/nscd-client.h     |  7 +++++++
 nscd/nscd-dbtype.h     |  3 +++
 nscd/nscd_getai.c      |  9 +++------
 nscd/nscd_getgr_r.c    |  6 ++----
 nscd/nscd_gethst_r.c   | 10 ++++------
 nscd/nscd_getpw_r.c    |  6 ++----
 nscd/nscd_getserv_r.c  |  7 ++-----
 nscd/nscd_helper.c     | 41 +++++++++++++++++++++++++++++++++++++++++
 nscd/nscd_initgroups.c |  5 +++--
 nscd/nscd_netgroup.c   | 10 ++++------
 nscd/nscd_proto.h      | 15 +++++++++------
 nss/getXXbyYY_r.c      | 11 +++--------
 nss/getaddrinfo.c      | 19 +++++--------------
 nss/getnetgrent_r.c    | 15 +++------------
 nss/initgroups.c       | 10 ++--------
 nss/nss_database.c     | 23 ++++++++++++++++++++++-
 nss/nss_module.c       |  8 +++-----
 nss/nsswitch.c         |  5 -----
 nss/nsswitch.h         | 20 ++++++++------------
 19 files changed, 126 insertions(+), 104 deletions(-)

diff --git a/nscd/nscd-client.h b/nscd/nscd-client.h
index aff303b757..dd7421c5d1 100644
--- a/nscd/nscd-client.h
+++ b/nscd/nscd-client.h
@@ -354,6 +354,13 @@ struct mapped_database
   size_t mapsize;		/* Zero means not in use.  */
   size_t datasize;
 
+  /* This is set to 1 by nscd client functions to request not using nscd
+     for a bit.  The main NSS code increments them until NSS_NSCD_RETRY
+     is reached, at which point nscd is attempted again.  If the counter
+     is 0 (the default), use of nscd is attempted.  If it is -1, nscd is
+     never used for this database.  */
+  int skip_counter;
+
   /* Use of the mapping must acquire a read lock.  If the mapping is
      changed, acquire a write lock.  */
   __libc_rwlock_define (, lock);
diff --git a/nscd/nscd-dbtype.h b/nscd/nscd-dbtype.h
index 7d553d020a..262c96fd78 100644
--- a/nscd/nscd-dbtype.h
+++ b/nscd/nscd-dbtype.h
@@ -19,6 +19,9 @@
 #ifndef NSCD_DBTYPE_H
 #define NSCD_DBTYPE_H
 
+/* Note: If you add new database types here, you must add another call
+   to __nscd_disable_database in __nss_configure_lookup.  */
+
 typedef enum
 {
   pwddb,
diff --git a/nscd/nscd_getai.c b/nscd/nscd_getai.c
index a2e5da6b1c..65970b59ee 100644
--- a/nscd/nscd_getai.c
+++ b/nscd/nscd_getai.c
@@ -28,9 +28,6 @@
 #include "nscd_proto.h"
 
 
-/* Define in nscd_gethst_r.c.  */
-extern int __nss_not_use_nscd_hosts;
-
 /* Defined in nscd_gethst_r.c.  */
 extern int __nss_have_localdomain attribute_hidden;
 
@@ -44,7 +41,7 @@ __nscd_getai (const char *key, struct nscd_ai_result **result, int *h_errnop)
 	__nss_have_localdomain = getenv ("LOCALDOMAIN") != NULL ? 1 : -1;
       if (__nss_have_localdomain > 0)
 	{
-	  __nss_not_use_nscd_hosts = 1;
+	  __nscd_defer_database (hstdb);
 	  return -1;
 	}
     }
@@ -93,7 +90,7 @@ __nscd_getai (const char *key, struct nscd_ai_result **result, int *h_errnop)
       if (sock == -1)
 	{
 	  /* nscd not running or wrong version.  */
-	  __nss_not_use_nscd_hosts = 1;
+	  __nscd_defer_database (hstdb);
 	  goto out;
 	}
     }
@@ -168,7 +165,7 @@ __nscd_getai (const char *key, struct nscd_ai_result **result, int *h_errnop)
       if (__glibc_unlikely (ai_resp.found == -1))
 	{
 	  /* The daemon does not cache this database.  */
-	  __nss_not_use_nscd_hosts = 1;
+	  __nscd_defer_database (hstdb);
 	  goto out_close;
 	}
 
diff --git a/nscd/nscd_getgr_r.c b/nscd/nscd_getgr_r.c
index 746b11d792..f77650b25f 100644
--- a/nscd/nscd_getgr_r.c
+++ b/nscd/nscd_getgr_r.c
@@ -36,8 +36,6 @@
 #include "nscd-dbtype.h"
 #include "nscd_proto.h"
 
-int __nss_not_use_nscd_group;
-
 static int nscd_getgr_r (const char *key, size_t keylen, request_type type,
 			 struct group *resultbuf, char *buffer,
 			 size_t buflen, struct group **result);
@@ -117,7 +115,7 @@ nscd_getgr_r (const char *key, size_t keylen, request_type type,
 				 sizeof (gr_resp));
       if (sock == -1)
 	{
-	  __nss_not_use_nscd_group = 1;
+	  __nscd_defer_database (grpdb);
 	  goto out;
 	}
     }
@@ -128,7 +126,7 @@ nscd_getgr_r (const char *key, size_t keylen, request_type type,
   if (__glibc_unlikely (gr_resp.found == -1))
     {
       /* The daemon does not cache this database.  */
-      __nss_not_use_nscd_group = 1;
+      __nscd_defer_database (grpdb);
       goto out_close;
     }
 
diff --git a/nscd/nscd_gethst_r.c b/nscd/nscd_gethst_r.c
index 15d747fc33..9bb52614b7 100644
--- a/nscd/nscd_gethst_r.c
+++ b/nscd/nscd_gethst_r.c
@@ -27,8 +27,6 @@
 #include "nscd-dbtype.h"
 #include "nscd_proto.h"
 
-int __nss_not_use_nscd_hosts;
-
 static int nscd_gethst_r (const char *key, size_t keylen, request_type type,
 			  struct hostent *resultbuf, char *buffer,
 			  size_t buflen, struct hostent **result,
@@ -81,7 +79,7 @@ __nscd_gethostbyaddr_r (const void *addr, socklen_t len, int type,
 uint32_t
 __nscd_get_nl_timestamp (void)
 {
-  if (__nss_not_use_nscd_hosts != 0)
+  if (!__nscd_use_database (hstdb))
     return 0;
 
   int gc_cycle;
@@ -112,7 +110,7 @@ nscd_gethst_r (const char *key, size_t keylen, request_type type,
 	__nss_have_localdomain = getenv ("LOCALDOMAIN") != NULL ? 1 : -1;
       if (__nss_have_localdomain > 0)
 	{
-	  __nss_not_use_nscd_hosts = 1;
+	  __nscd_defer_database (hstdb);
 	  return -1;
 	}
     }
@@ -186,7 +184,7 @@ nscd_gethst_r (const char *key, size_t keylen, request_type type,
 				 sizeof (hst_resp));
       if (sock == -1)
 	{
-	  __nss_not_use_nscd_hosts = 1;
+	  __nscd_defer_database (hstdb);
 	  goto out;
 	}
     }
@@ -197,7 +195,7 @@ nscd_gethst_r (const char *key, size_t keylen, request_type type,
   if (__glibc_unlikely (hst_resp.found == -1))
     {
       /* The daemon does not cache this database.  */
-      __nss_not_use_nscd_hosts = 1;
+      __nscd_defer_database (hstdb);
       goto out_close;
     }
 
diff --git a/nscd/nscd_getpw_r.c b/nscd/nscd_getpw_r.c
index 938eac9c70..8ce1009fe0 100644
--- a/nscd/nscd_getpw_r.c
+++ b/nscd/nscd_getpw_r.c
@@ -34,8 +34,6 @@
 #include "nscd-dbtype.h"
 #include "nscd_proto.h"
 
-int __nss_not_use_nscd_passwd;
-
 static int nscd_getpw_r (const char *key, size_t keylen, request_type type,
 			 struct passwd *resultbuf, char *buffer,
 			 size_t buflen, struct passwd **result);
@@ -108,7 +106,7 @@ nscd_getpw_r (const char *key, size_t keylen, request_type type,
 				 sizeof (pw_resp));
       if (sock == -1)
 	{
-	  __nss_not_use_nscd_passwd = 1;
+	  __nscd_defer_database (pwddb);
 	  goto out;
 	}
     }
@@ -119,7 +117,7 @@ nscd_getpw_r (const char *key, size_t keylen, request_type type,
   if (__glibc_unlikely (pw_resp.found == -1))
     {
       /* The daemon does not cache this database.  */
-      __nss_not_use_nscd_passwd = 1;
+      __nscd_defer_database (pwddb);
       goto out_close;
     }
 
diff --git a/nscd/nscd_getserv_r.c b/nscd/nscd_getserv_r.c
index 519078d8fe..8f0c010118 100644
--- a/nscd/nscd_getserv_r.c
+++ b/nscd/nscd_getserv_r.c
@@ -27,9 +27,6 @@
 #include "nscd_proto.h"
 
 
-int __nss_not_use_nscd_services;
-
-
 static int nscd_getserv_r (const char *crit, size_t critlen, const char *proto,
 			   request_type type, struct servent *resultbuf,
 			   char *buf, size_t buflen, struct servent **result);
@@ -162,7 +159,7 @@ nscd_getserv_r (const char *crit, size_t critlen, const char *proto,
 				 sizeof (serv_resp));
       if (sock == -1)
 	{
-	  __nss_not_use_nscd_services = 1;
+	  __nscd_defer_database (servdb);
 	  goto out;
 	}
     }
@@ -173,7 +170,7 @@ nscd_getserv_r (const char *crit, size_t critlen, const char *proto,
   if (__glibc_unlikely (serv_resp.found == -1))
     {
       /* The daemon does not cache this database.  */
-      __nss_not_use_nscd_services = 1;
+      __nscd_defer_database (servdb);
       goto out_close;
     }
 
diff --git a/nscd/nscd_helper.c b/nscd/nscd_helper.c
index d3bfc208ad..2a60c3572e 100644
--- a/nscd/nscd_helper.c
+++ b/nscd/nscd_helper.c
@@ -40,6 +40,7 @@
 
 #include "nscd-client.h"
 #include "nscd-dbtype.h"
+#include "nscd_proto.h"
 
 /* Extra time we wait if the socket is still receiving data.  This
    value is in milliseconds.  Note that the other side is nscd on the
@@ -413,6 +414,46 @@ __nscd_get_mapping (unsigned int db)
   __libc_rwlock_rdlock (mapped->lock);
 }
 
+bool
+__nscd_use_database (unsigned int db)
+{
+  assert (db < lastdb);
+
+  int *pcounter = &__nscd_mapped_databases[db].skip_counter;
+  int counter;
+  while (true)
+    {
+      counter = atomic_load_relaxed (pcounter);
+      if (counter <= 0)
+        break;
+      else if (counter > 0)
+        {
+          int old_counter = counter;
+          ++counter;
+          if (counter > NSS_NSCD_RETRY)
+            counter = 0;
+          if (atomic_compare_exchange_weak_relaxed
+	      (pcounter, &old_counter, counter))
+            break;
+        }
+    }
+  return counter == 0;
+}
+
+void
+__nscd_defer_database (unsigned int db)
+{
+  assert (db < lastdb);
+  atomic_store_relaxed (&__nscd_mapped_databases[db].skip_counter, 1);
+}
+
+void
+__nscd_disable_database (unsigned int db)
+{
+  assert (db < lastdb);
+  atomic_store_relaxed (&__nscd_mapped_databases[db].skip_counter, -1);
+}
+
 struct mapped_database *
 __nscd_get_map_ref (unsigned int db, int *gc_cyclep)
 {
diff --git a/nscd/nscd_initgroups.c b/nscd/nscd_initgroups.c
index f1e821b8d0..acc799cf55 100644
--- a/nscd/nscd_initgroups.c
+++ b/nscd/nscd_initgroups.c
@@ -16,6 +16,7 @@
    <https://www.gnu.org/licenses/>.  */
 
 #include <assert.h>
+#include <atomic.h>
 #include <errno.h>
 #include <grp.h>
 #include <stdlib.h>
@@ -79,7 +80,7 @@ __nscd_getgrouplist (const char *user, gid_t group, long int *size,
       if (sock == -1)
 	{
 	  /* nscd not running or wrong version.  */
-	  __nss_not_use_nscd_group = 1;
+	  __nscd_disable_database (grpdb);
 	  goto out;
 	}
     }
@@ -128,7 +129,7 @@ __nscd_getgrouplist (const char *user, gid_t group, long int *size,
       if (__glibc_unlikely (initgr_resp.found == -1))
 	{
 	  /* The daemon does not cache this database.  */
-	  __nss_not_use_nscd_group = 1;
+	  __nscd_disable_database (grpdb);
 	  goto out_close;
 	}
 
diff --git a/nscd/nscd_netgroup.c b/nscd/nscd_netgroup.c
index 53649adc82..22c7cdcc9c 100644
--- a/nscd/nscd_netgroup.c
+++ b/nscd/nscd_netgroup.c
@@ -25,8 +25,6 @@
 #include "nscd-dbtype.h"
 #include "nscd_proto.h"
 
-int __nss_not_use_nscd_netgroup;
-
 int
 __nscd_setnetgrent (const char *group, struct __netgrent *datap)
 {
@@ -70,7 +68,7 @@ __nscd_setnetgrent (const char *group, struct __netgrent *datap)
       if (sock == -1)
 	{
 	  /* nscd not running or wrong version.  */
-	  __nss_not_use_nscd_netgroup = 1;
+	  __nscd_defer_database (netgrdb);
 	  goto out;
 	}
     }
@@ -110,7 +108,7 @@ __nscd_setnetgrent (const char *group, struct __netgrent *datap)
       if (__glibc_unlikely (netgroup_resp.found == -1))
 	{
 	  /* The daemon does not cache this database.  */
-	  __nss_not_use_nscd_netgroup = 1;
+	  __nscd_defer_database (netgrdb);
 	  goto out_close;
 	}
 
@@ -207,7 +205,7 @@ __nscd_innetgr (const char *netgroup, const char *host, const char *user,
   if (sock == -1)
     {
       /* nscd not running or wrong version.  */
-      __nss_not_use_nscd_netgroup = 1;
+      __nscd_defer_database (netgrdb);
       goto out;
     }
 
@@ -219,7 +217,7 @@ __nscd_innetgr (const char *netgroup, const char *host, const char *user,
       if (__glibc_unlikely (innetgroup_resp.found == -1))
 	{
 	  /* The daemon does not cache this database.  */
-	  __nss_not_use_nscd_netgroup = 1;
+	  __nscd_defer_database (netgrdb);
 	  goto out_close;
 	}
 
diff --git a/nscd/nscd_proto.h b/nscd/nscd_proto.h
index 917324aebd..6c4a318bc0 100644
--- a/nscd/nscd_proto.h
+++ b/nscd/nscd_proto.h
@@ -28,13 +28,16 @@
 /* Type needed in the interfaces.  */
 struct nscd_ai_result;
 
+/* Update the internal per-database counters if necessary and return
+   true if nscd should be used for DB for the next lookup.
+   DB is defined in <nscd-dbtype.h>.  */
+_Bool __nscd_use_database (unsigned int db) attribute_hidden;
 
-/* Variables for communication between NSCD handler functions and NSS.  */
-extern int __nss_not_use_nscd_passwd attribute_hidden;
-extern int __nss_not_use_nscd_group attribute_hidden;
-extern int __nss_not_use_nscd_hosts attribute_hidden;
-extern int __nss_not_use_nscd_services attribute_hidden;
-extern int __nss_not_use_nscd_netgroup attribute_hidden;
+/* Stop using DB until NSS_NSCD_RETRY lookups have been performed.  */
+void __nscd_defer_database (unsigned int db) attribute_hidden;
+
+/* Completely stop using DB.  */
+void __nscd_disable_database (unsigned int db) attribute_hidden;
 
 extern int __nscd_getpwnam_r (const char *name, struct passwd *resultbuf,
 			      char *buffer, size_t buflen,
diff --git a/nss/getXXbyYY_r.c b/nss/getXXbyYY_r.c
index 21e82886b0..9527b6722d 100644
--- a/nss/getXXbyYY_r.c
+++ b/nss/getXXbyYY_r.c
@@ -23,6 +23,7 @@
 #include "sysdep.h"
 #ifdef USE_NSCD
 # include <nscd/nscd_proto.h>
+# include <nscd/nscd-dbtype.h>
 #endif
 #ifdef NEED__RES
 # include <resolv/resolv_context.h>
@@ -78,9 +79,7 @@
 # define NSCD_NAME ADD_NSCD (REENTRANT_NAME)
 # define ADD_NSCD(name) ADD_NSCD1 (name)
 # define ADD_NSCD1(name) __nscd_##name
-# 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 NSS_DATABASE_INDEX CONCAT2 (NSS_DBSIDX_, DATABASE_NAME)
 # define CONCAT2(arg1, arg2) CONCAT2_2 (arg1, arg2)
 # define CONCAT2_2(arg1, arg2) arg1##arg2
 #endif
@@ -235,11 +234,7 @@ INTERNAL (REENTRANT_NAME) (ADD_PARAMS, LOOKUP_TYPE *resbuf, char *buffer,
 #endif
 
 #ifdef USE_NSCD
-  if (NOT_USENSCD_NAME > 0 && ++NOT_USENSCD_NAME > NSS_NSCD_RETRY)
-    NOT_USENSCD_NAME = 0;
-
-  if (!NOT_USENSCD_NAME
-      && !__nss_database_custom[CONCAT2 (NSS_DBSIDX_, DATABASE_NAME)])
+  if (__nscd_use_database (NSS_DATABASE_INDEX))
     {
       nscd_status = NSCD_NAME (ADD_VARIABLES, resbuf, buffer, buflen, result
 			       H_ERRNO_VAR);
diff --git a/nss/getaddrinfo.c b/nss/getaddrinfo.c
index 4f6ac3358a..233801052e 100644
--- a/nss/getaddrinfo.c
+++ b/nss/getaddrinfo.c
@@ -81,7 +81,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <libc-lock.h>
 #include <not-cancel.h>
 #include <nscd/nscd-client.h>
-#include <nscd/nscd_proto.h>
+#ifdef USE_NSCD
+# include <nscd/nscd_proto.h>
+# include <nscd/nscd-dbtype.h>
+#endif
 #include <scratch_buffer.h>
 #include <inet/net-internal.h>
 
@@ -485,13 +488,9 @@ static int
 get_nscd_addresses (const char *name, const struct addrinfo *req,
 		    struct gaih_result *res)
 {
-  if (__nss_not_use_nscd_hosts > 0
-      && ++__nss_not_use_nscd_hosts > NSS_NSCD_RETRY)
-    __nss_not_use_nscd_hosts = 0;
-
   res->at = NULL;
 
-  if (__nss_not_use_nscd_hosts || __nss_database_custom[NSS_DBSIDX_hosts])
+  if (!__nscd_use_database (hstdb))
     return 0;
 
   /* Try to use nscd.  */
@@ -508,14 +507,6 @@ get_nscd_addresses (const char *name, const struct addrinfo *req,
 	    return -EAI_AGAIN;
 	  return -EAI_NONAME;
 	}
-      if (__nss_not_use_nscd_hosts == 0)
-	{
-	  if (h_errno == NETDB_INTERNAL && errno == ENOMEM)
-	    return -EAI_MEMORY;
-	  if (h_errno == TRY_AGAIN)
-	    return -EAI_AGAIN;
-	  return -EAI_SYSTEM;
-	}
       return 0;
     }
 
diff --git a/nss/getnetgrent_r.c b/nss/getnetgrent_r.c
index d391e2ac66..569087d3b0 100644
--- a/nss/getnetgrent_r.c
+++ b/nss/getnetgrent_r.c
@@ -27,6 +27,7 @@
 #include "nsswitch.h"
 #include <sysdep.h>
 #include <nscd/nscd_proto.h>
+#include <nscd/nscd-dbtype.h>
 
 
 /* Protect above variable against multiple uses at the same time.  */
@@ -150,12 +151,7 @@ static int
 nscd_setnetgrent (const char *group)
 {
 #ifdef USE_NSCD
-  if (__nss_not_use_nscd_netgroup > 0
-      && ++__nss_not_use_nscd_netgroup > NSS_NSCD_RETRY)
-    __nss_not_use_nscd_netgroup = 0;
-
-  if (!__nss_not_use_nscd_netgroup
-      && !__nss_database_custom[NSS_DBSIDX_netgroup])
+  if (__nscd_use_database (netgrdb))
     return __nscd_setnetgrent (group, &dataset);
 #endif
   return -1;
@@ -357,12 +353,7 @@ innetgr (const char *netgroup, const char *host, const char *user,
 	 const char *domain)
 {
 #ifdef USE_NSCD
-  if (__nss_not_use_nscd_netgroup > 0
-      && ++__nss_not_use_nscd_netgroup > NSS_NSCD_RETRY)
-    __nss_not_use_nscd_netgroup = 0;
-
-  if (!__nss_not_use_nscd_netgroup
-      && !__nss_database_custom[NSS_DBSIDX_netgroup])
+  if (__nscd_use_database (netgrdb))
     {
       int result = __nscd_innetgr (netgroup, host, user, domain);
       if (result >= 0)
diff --git a/nss/initgroups.c b/nss/initgroups.c
index f4106226ec..95691542fb 100644
--- a/nss/initgroups.c
+++ b/nss/initgroups.c
@@ -29,6 +29,7 @@
 #include <config.h>
 
 #include "../nscd/nscd-client.h"
+#include "../nscd/nscd-dbtype.h"
 #include "../nscd/nscd_proto.h"
 
 /* Type of the lookup function.  */
@@ -47,18 +48,11 @@ internal_getgrouplist (const char *user, gid_t group, long int *size,
 		       gid_t **groupsp, long int limit)
 {
 #ifdef USE_NSCD
-  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
-      && !__nss_database_custom[NSS_DBSIDX_group])
+  if (__nscd_use_database (grpdb))
     {
       int n = __nscd_getgrouplist (user, group, size, groupsp, limit);
       if (n >= 0)
 	return n;
-
-      /* nscd is not usable.  */
-      __nss_not_use_nscd_group = 1;
     }
 #endif
 
diff --git a/nss/nss_database.c b/nss/nss_database.c
index 076d5a63fe..5861454467 100644
--- a/nss/nss_database.c
+++ b/nss/nss_database.c
@@ -28,6 +28,10 @@
 #include <netdb.h>
 #include <stdio_ext.h>
 #include <string.h>
+#ifdef USE_NSCD
+# include <nscd/nscd_proto.h>
+# include <nscd/nscd-dbtype.h>
+#endif
 
 struct nss_database_state
 {
@@ -256,7 +260,24 @@ __nss_configure_lookup (const char *dbname, const char *service_line)
   local->data.services[db] = result;
 
 #ifdef USE_NSCD
-  __nss_database_custom[db] = true;
+  switch (db)
+    {
+    case nss_database_group:
+      __nscd_disable_database (grpdb);
+      break;
+    case nss_database_hosts:
+      __nscd_disable_database (hstdb);
+      break;
+    case nss_database_netgroup:
+      __nscd_disable_database (netgrdb);
+      break;
+    case nss_database_passwd:
+      __nscd_disable_database (pwddb);
+      break;
+    case nss_database_services:
+      __nscd_disable_database (servdb);
+      break;
+    }
 #endif
 
   return 0;
diff --git a/nss/nss_module.c b/nss/nss_module.c
index cb8fde38b4..fbbc6a266a 100644
--- a/nss/nss_module.c
+++ b/nss/nss_module.c
@@ -33,6 +33,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <pointer_guard.h>
+#include <nscd/nscd-dbtype.h>
 
 /* 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
@@ -395,11 +396,8 @@ __nss_disable_nscd (void (*cb) (size_t, struct traced_file *))
   cb1 (netgrdb, &netgr_traced_file.file);
 
   /* Disable all uses of NSCD.  */
-  __nss_not_use_nscd_passwd = -1;
-  __nss_not_use_nscd_group = -1;
-  __nss_not_use_nscd_hosts = -1;
-  __nss_not_use_nscd_services = -1;
-  __nss_not_use_nscd_netgroup = -1;
+  for (int i = 0; i < lastdb; ++i)
+    __nscd_disable_database (i);
 }
 #endif
 
diff --git a/nss/nsswitch.c b/nss/nsswitch.c
index 97cedff826..ff69ede948 100644
--- a/nss/nsswitch.c
+++ b/nss/nsswitch.c
@@ -42,11 +42,6 @@
 #include <sysdep.h>
 #include <config.h>
 
-#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 == not found
diff --git a/nss/nsswitch.h b/nss/nsswitch.h
index 1b18794fee..b7cfb4f602 100644
--- a/nss/nsswitch.h
+++ b/nss/nsswitch.h
@@ -62,19 +62,15 @@ typedef struct
 /* To access the action based on the status value use this macro.  */
 #define nss_next_action(ni, status) nss_action_get (ni, status)
 
-
 #ifdef USE_NSCD
-/* 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] attribute_hidden;
+/* Compile-time mapping of NSS databases to nscd dbtype values from
+   <nscd/nscd-dbtype.h>.  This is used to update nscd usage counters
+   in nscd-enabled builds if getXbyY_r routines are called.  */
+# define NSS_DBSIDX_group grpdb
+# define NSS_DBSIDX_hosts hstdb
+# define NSS_DBSIDX_netgroup netgrdb
+# define NSS_DBSIDX_passwd pwddb
+# define NSS_DBSIDX_services servdb
 #endif
 
 /* Warning for NSS functions, which don't require dlopen if glibc
-- 
2.53.0




More information about the Libc-alpha mailing list