diff options
Diffstat (limited to 'nscd')
-rw-r--r-- | nscd/connections.c | 36 | ||||
-rw-r--r-- | nscd/nscd-client.h | 7 | ||||
-rw-r--r-- | nscd/nscd.c | 40 | ||||
-rw-r--r-- | nscd/nscd.conf | 2 |
4 files changed, 76 insertions, 9 deletions
diff --git a/nscd/connections.c b/nscd/connections.c index eef2568863..cbacf9650a 100644 --- a/nscd/connections.c +++ b/nscd/connections.c @@ -61,7 +61,8 @@ const char *serv2str[LASTREQ] = [GETHOSTBYADDR] = "GETHOSTBYADDR", [GETHOSTBYADDRv6] = "GETHOSTBYADDRv6", [SHUTDOWN] = "SHUTDOWN", - [GETSTAT] = "GETSTAT" + [GETSTAT] = "GETSTAT", + [INVALIDATE] = "INVALIDATE" }; /* The control data structures for the services. */ @@ -193,6 +194,22 @@ close_sockets (void) close (sock); } +static void +invalidate_cache (void *key) +{ + dbtype number; + + if (strcmp (key, "passwd") == 0) + number = pwddb; + else if (strcmp (key, "group") == 0) + number = grpdb; + else if (strcmp (key, "hosts") == 0) + number = hstdb; + else return; + + prune_cache (&dbs[number], LONG_MAX); +} + /* Handle new request. */ static void @@ -272,9 +289,13 @@ cannot handle old request version %d; current version is %d"), pthread_rwlock_unlock (&db->lock); } - else - if (debug_level > 0) - dbg_log ("\t%s", serv2str[req->type]); + else if (debug_level > 0) + { + if (req->type == INVALIDATE) + dbg_log ("\t%s (%s)", serv2str[req->type], key); + else + dbg_log ("\t%s", serv2str[req->type]); + } /* Handle the request. */ switch (req->type) @@ -313,11 +334,14 @@ cannot handle old request version %d; current version is %d"), case GETSTAT: case SHUTDOWN: - /* Accept shutdown and getstat only from root */ + case INVALIDATE: + /* Accept shutdown, getstat and invalidate only from root */ if (secure_in_use && uid == 0) { if (req->type == GETSTAT) send_stats (fd, dbs); + else if (req->type == INVALIDATE) + invalidate_cache (key); else termination_handler (0); } @@ -338,6 +362,8 @@ cannot handle old request version %d; current version is %d"), { if (req->type == GETSTAT) send_stats (fd, dbs); + else if (req->type == INVALIDATE) + invalidate_cache (key); else termination_handler (0); } diff --git a/nscd/nscd-client.h b/nscd/nscd-client.h index 0c52f91c36..33c4845aee 100644 --- a/nscd/nscd-client.h +++ b/nscd/nscd-client.h @@ -1,6 +1,6 @@ -/* Copyright (c) 1998 Free Software Foundation, Inc. +/* Copyright (c) 1998, 1999 Free Software Foundation, Inc. This file is part of the GNU C Library. - Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1998. + Contributed by Thorsten Kukuk <kukuk@suse.de>, 1998. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as @@ -50,7 +50,8 @@ typedef enum LASTDBREQ = GETHOSTBYADDRv6, SHUTDOWN, /* Shut the server down. */ GETSTAT, /* Get the server statistic. */ - LASTREQ, + INVALIDATE, /* Invalidate one special cache. */ + LASTREQ } request_type; diff --git a/nscd/nscd.c b/nscd/nscd.c index 8c61406d2f..c4187f13bc 100644 --- a/nscd/nscd.c +++ b/nscd/nscd.c @@ -84,6 +84,8 @@ static const struct argp_option options[] = { "nthreads", 't', N_("NUMBER"), 0, N_("Start NUMBER threads") }, { "shutdown", 'K', NULL, 0, N_("Shut the server down") }, { "statistic", 'g', NULL, 0, N_("Print current configuration statistic") }, + { "invalidate", 'i', N_("TABLE"), 0, + N_("Invalidate the specified cache") }, { "secure", 'S', N_("TABLE,yes"), 0, N_("Use separate cache for each user")}, { NULL, 0, NULL, 0, NULL } }; @@ -210,6 +212,44 @@ parse_opt (int key, char *arg, struct argp_state *state) receive_print_stats (); /* Does not return. */ + case 'i': + if (getuid () != 0) + error (EXIT_FAILURE, 0, _("Only root is allowed to use this option!")); + else + { + int sock = nscd_open_socket (); + request_header req; + ssize_t nbytes; + + if (sock == -1) + exit (EXIT_FAILURE); + + if (strcmp (arg, "passwd") == 0) + req.key_len = sizeof "passwd"; + else if (strcmp (arg, "group") == 0) + req.key_len = sizeof "group"; + else if (strcmp (arg, "hosts") == 0) + req.key_len = sizeof "hosts"; + else + return ARGP_ERR_UNKNOWN; + + req.version = NSCD_VERSION; + req.type = INVALIDATE; + nbytes = TEMP_FAILURE_RETRY (write (sock, &req, + sizeof (request_header))); + if (nbytes != sizeof (request_header)) + { + close (sock); + exit (EXIT_FAILURE); + } + + nbytes = TEMP_FAILURE_RETRY (write (sock, (void *)arg, req.key_len)); + + close (sock); + + exit (nbytes != req.key_len ? EXIT_FAILURE : EXIT_SUCCESS); + } + case 't': nthreads = atol (arg); break; diff --git a/nscd/nscd.conf b/nscd/nscd.conf index d2b53a7aa3..0e43da33f5 100644 --- a/nscd/nscd.conf +++ b/nscd/nscd.conf @@ -19,7 +19,7 @@ # -# logfile /var/adm/nscd.log +# logfile /var/log/nscd.log # threads 6 debug-level 0 |