This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] nscd: added passthru option value


The addition of a "passthru" option value for the enable-cache option allows
nscd to act as an nsd, name service daemon, without caching functionality. The
effect is the same as using nscd with a cache TTL of 0, but without the overhead
of actually looking up cached values or writing them.

This adds the benefit that ns(c)d can be used as a safety mechanism to load
potentially unsafe or broken NSS modules. The idea for this came up as a result
of the discussion at
https://sourceware.org/ml/libc-help/2016-12/msg00005.html.

2017-01-18  Alexander Kahl  <ak@sodosopa.io>

	* nscd/nscd.c: Added passthru option value.
	* nscd/connections.c: Likewise.
	* nscd/grpcache.c: Likewise.
	* nscd/hstcache.c: Likewise.
	* nscd/netgroupcache.c: Likewise.
	* nscd/nscd.conf: Likewise.
	* nscd/nscd.h: Likewise.
	* nscd/nscd_conf.c: Likewise.
	* nscd/pwdcache.c: Likewise.
	* nscd/servicescache.c: Likewise.
---
 ChangeLog            | 13 +++++++++++++
 nscd/connections.c   | 19 ++++++++++---------
 nscd/grpcache.c      |  5 ++++-
 nscd/hstcache.c      |  6 ++++--
 nscd/netgroupcache.c |  4 ++--
 nscd/nscd.c          |  2 +-
 nscd/nscd.conf       |  2 +-
 nscd/nscd.h          |  9 ++++++++-
 nscd/nscd_conf.c     |  6 ++++--
 nscd/pwdcache.c      |  6 ++++--
 nscd/servicescache.c |  4 +++-
 11 files changed, 54 insertions(+), 22 deletions(-)

diff --git a/nscd/connections.c b/nscd/connections.c
index 26d2c00..e520d2c 100644
--- a/nscd/connections.c
+++ b/nscd/connections.c
@@ -520,7 +520,7 @@ nscd_init (void)
     nthreads = 4;
 
   for (size_t cnt = 0; cnt < lastdb; ++cnt)
-    if (dbs[cnt].enabled)
+    if (dbs[cnt].enabled == cache_enabled)
       {
 	pthread_rwlock_init (&dbs[cnt].lock, NULL);
 	pthread_mutex_init (&dbs[cnt].memlock, NULL);
@@ -853,7 +853,7 @@ cannot set socket to close on exec: %s; disabling paranoia mode"),
     }
 
 #ifdef HAVE_NETLINK
-  if (dbs[hstdb].enabled)
+  if (dbs[hstdb].enabled != cache_disabled)
     {
       /* Try to open netlink socket to monitor network setting changes.  */
       nl_status_fd = socket (AF_NETLINK,
@@ -1022,7 +1022,7 @@ invalidate_cache (char *key, int fd)
       return;
     }
 
-  if (dbs[number].enabled)
+  if (dbs[number].enabled == cache_enabled)
     {
       pthread_mutex_lock (&dbs[number].prune_run_lock);
       prune_cache (&dbs[number], LONG_MAX, fd);
@@ -1135,7 +1135,8 @@ request from '%s' [%ld] not handled due to missing permission"),
   struct database_dyn *db = reqinfo[req->type].db;
 
   /* See whether we can service the request from the cache.  */
-  if (__builtin_expect (reqinfo[req->type].data_request, true))
+  if (__builtin_expect (reqinfo[req->type].data_request, true)
+      && db->enabled != cache_passthru)
     {
       if (__builtin_expect (debug_level, 0) > 0)
 	{
@@ -1153,7 +1154,7 @@ request from '%s' [%ld] not handled due to missing permission"),
 	}
 
       /* Is this service enabled?  */
-      if (__glibc_unlikely (!db->enabled))
+      if (__glibc_unlikely (db->enabled == cache_disabled))
 	{
 	  /* No, sent the prepared record.  */
 	  if (TEMP_FAILURE_RETRY (send (fd, db->disabled_iov->iov_base,
@@ -1461,7 +1462,7 @@ cannot change to old working directory: %s; disabling paranoia mode"),
   /* Synchronize memory.  */
   int32_t certainly[lastdb];
   for (int cnt = 0; cnt < lastdb; ++cnt)
-    if (dbs[cnt].enabled)
+    if (dbs[cnt].enabled == cache_enabled)
       {
 	/* Make sure nobody keeps using the database.  */
 	dbs[cnt].head->timestamp = 0;
@@ -1507,7 +1508,7 @@ cannot change to old working directory: %s; disabling paranoia mode"),
   /* Reenable the databases.  */
   time_t now = time (NULL);
   for (int cnt = 0; cnt < lastdb; ++cnt)
-    if (dbs[cnt].enabled)
+    if (dbs[cnt].enabled == cache_enabled)
       {
 	dbs[cnt].head->timestamp = now;
 	dbs[cnt].head->nscd_certainly_running = certainly[cnt];
@@ -1545,7 +1546,7 @@ __attribute__ ((__noreturn__))
 nscd_run_prune (void *p)
 {
   const long int my_number = (long int) p;
-  assert (dbs[my_number].enabled);
+  assert (dbs[my_number].enabled == cache_enabled);
 
   int dont_need_update = setup_thread (&dbs[my_number]);
 
@@ -2479,7 +2480,7 @@ start_threads (void)
 	}
 
       pthread_t th;
-      if (dbs[i].enabled
+      if (dbs[i].enabled == cache_enabled
 	  && pthread_create (&th, &attr, nscd_run_prune, (void *) i) != 0)
 	{
 	  dbg_log (_("could not start clean-up thread; terminating"));
diff --git a/nscd/grpcache.c b/nscd/grpcache.c
index d2ad535..a0975f2 100644
--- a/nscd/grpcache.c
+++ b/nscd/grpcache.c
@@ -495,7 +495,10 @@ addgrbyX (struct database_dyn *db, int fd, request_header *req,
 	buffer = (char *) extend_alloca (buffer, buflen, 2 * buflen);
     }
 
-  time_t timeout = cache_addgr (db, fd, req, keystr, grp, uid, he, dh, errval);
+  time_t timeout = 0;
+
+  if (db->enabled != cache_passthru)
+    timeout = cache_addgr (db, fd, req, keystr, grp, uid, he, dh, errval);
 
   if (use_malloc)
     free (buffer);
diff --git a/nscd/hstcache.c b/nscd/hstcache.c
index 9f6ce97..b2959cc 100644
--- a/nscd/hstcache.c
+++ b/nscd/hstcache.c
@@ -521,8 +521,10 @@ addhstbyX (struct database_dyn *db, int fd, request_header *req,
 	buffer = (char *) extend_alloca (buffer, buflen, 2 * buflen);
     }
 
-  time_t timeout = cache_addhst (db, fd, req, key, hst, uid, he, dh,
-				 h_errno == TRY_AGAIN ? errval : 0, ttl);
+  time_t timeout = 0;
+  if (db->enabled != cache_passthru)
+    timeout = cache_addhst (db, fd, req, key, hst, uid, he, dh,
+                            h_errno == TRY_AGAIN ? errval : 0, ttl);
 
   if (use_malloc)
     free (buffer);
diff --git a/nscd/netgroupcache.c b/nscd/netgroupcache.c
index cd0c3ea..102a1a5 100644
--- a/nscd/netgroupcache.c
+++ b/nscd/netgroupcache.c
@@ -442,7 +442,7 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
 	}
     }
 
-  if (cacheable)
+  if (cacheable && db->enabled != cache_passthru)
     {
       /* If necessary, we also propagate the data to disk.  */
       if (db->persistent)
@@ -624,7 +624,7 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req,
 	}
     }
 
-  if (cacheable)
+  if (cacheable && db->enabled != cache_passthru)
     {
       /* If necessary, we also propagate the data to disk.  */
       if (db->persistent)
diff --git a/nscd/nscd.c b/nscd/nscd.c
index 69ef413..e9dd8c2 100644
--- a/nscd/nscd.c
+++ b/nscd/nscd.c
@@ -557,7 +557,7 @@ termination_handler (int signum)
   /* Synchronize memory.  */
   for (int cnt = 0; cnt < lastdb; ++cnt)
     {
-      if (!dbs[cnt].enabled || dbs[cnt].head == NULL)
+      if (dbs[cnt].enabled == cache_disabled || dbs[cnt].head == NULL)
 	continue;
 
       /* Make sure nobody keeps using the database.  */
diff --git a/nscd/nscd.conf b/nscd/nscd.conf
index 39b8759..a5d64ef 100644
--- a/nscd/nscd.conf
+++ b/nscd/nscd.conf
@@ -16,7 +16,7 @@
 #	paranoia		<yes|no>
 #	restart-interval	<time in seconds>
 #
-#       enable-cache		<service> <yes|no>
+#       enable-cache		<service> <yes|no|passthru>
 #	positive-time-to-live	<service> <time in seconds>
 #	negative-time-to-live   <service> <time in seconds>
 #       suggested-size		<service> <prime number>
diff --git a/nscd/nscd.h b/nscd/nscd.h
index c6b0a3c..a1aefa3 100644
--- a/nscd/nscd.h
+++ b/nscd/nscd.h
@@ -41,6 +41,13 @@ typedef enum
   lastdb
 } dbtype;
 
+/* Activation types.  */
+typedef enum
+{
+  cache_disabled,
+  cache_enabled,
+  cache_passthru
+} cache_enable_t;
 
 /* Default limit on the number of times a value gets reloaded without
    being used in the meantime.  NSCD does not throw a value out as
@@ -132,7 +139,7 @@ struct database_dyn
   pthread_mutex_t prune_run_lock;
   time_t wakeup_time;
 
-  int enabled;
+  cache_enable_t enabled;
   int check_file;
   int clear_cache;
   int persistent;
diff --git a/nscd/nscd_conf.c b/nscd/nscd_conf.c
index 9c301ad..9c575f7 100644
--- a/nscd/nscd_conf.c
+++ b/nscd/nscd_conf.c
@@ -146,9 +146,11 @@ nscd_parse_file (const char *fname, struct database_dyn dbs[lastdb])
 	  if (idx >= 0)
 	    {
 	      if (strcmp (arg2, "no") == 0)
-		dbs[idx].enabled = 0;
+		dbs[idx].enabled = cache_disabled;
 	      else if (strcmp (arg2, "yes") == 0)
-		dbs[idx].enabled = 1;
+		dbs[idx].enabled = cache_enabled;
+	      else if (strcmp (arg2, "passthru") == 0)
+		dbs[idx].enabled = cache_passthru;
 	    }
 	}
       else if (strcmp (entry, "check-files") == 0)
diff --git a/nscd/pwdcache.c b/nscd/pwdcache.c
index 721f4c6..7b8f877 100644
--- a/nscd/pwdcache.c
+++ b/nscd/pwdcache.c
@@ -474,8 +474,10 @@ addpwbyX (struct database_dyn *db, int fd, request_header *req,
     }
 
   /* Add the entry to the cache.  */
-  time_t timeout = cache_addpw (db, fd, req, keystr, pwd, c_uid, he, dh,
-				errval);
+  time_t timeout = 0;
+  if (db->enabled != cache_passthru)
+    timeout = cache_addpw (db, fd, req, keystr, pwd, c_uid, he, dh,
+                           errval);
 
   if (use_malloc)
     free (buffer);
diff --git a/nscd/servicescache.c b/nscd/servicescache.c
index 131ba6d..82591f3 100644
--- a/nscd/servicescache.c
+++ b/nscd/servicescache.c
@@ -421,7 +421,9 @@ addservbyX (struct database_dyn *db, int fd, request_header *req,
 	buffer = (char *) extend_alloca (buffer, buflen, 2 * buflen);
     }
 
-  time_t timeout = cache_addserv (db, fd, req, key, serv, uid, he, dh, errval);
+  time_t timeout = 0;
+  if (db->enabled != cache_passthru)
+    timeout = cache_addserv (db, fd, req, key, serv, uid, he, dh, errval);
 
   if (use_malloc)
     free (buffer);
-- 
2.10.0

Attachment: signature.asc
Description: PGP signature


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]