aboutsummaryrefslogtreecommitdiff
path: root/nscd/connections.c
diff options
context:
space:
mode:
Diffstat (limited to 'nscd/connections.c')
-rw-r--r--nscd/connections.c67
1 files changed, 31 insertions, 36 deletions
diff --git a/nscd/connections.c b/nscd/connections.c
index c80ba96dc5..5cb73eb252 100644
--- a/nscd/connections.c
+++ b/nscd/connections.c
@@ -48,6 +48,8 @@ extern void *xrealloc (void *o, size_t n);
const char *server_user;
static uid_t server_uid;
static gid_t server_gid;
+const char *stat_user;
+uid_t stat_uid;
static gid_t *server_groups;
#ifndef NGROUPS
# define NGROUPS 32
@@ -88,7 +90,7 @@ const char *serv2str[LASTREQ] =
};
/* The control data structures for the services. */
-static struct database dbs[lastdb] =
+struct database dbs[lastdb] =
{
[pwddb] = {
.lock = PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP,
@@ -137,20 +139,11 @@ unsigned long int client_queued;
/* Initialize database information structures. */
void
-nscd_init (const char *conffile)
+nscd_init (void)
{
struct sockaddr_un sock_addr;
size_t cnt;
- /* Read the configuration file. */
- if (nscd_parse_file (conffile, dbs) != 0)
- {
- /* We couldn't read the configuration file. Disable all services
- by shutting down the srever. */
- dbg_log (_("cannot read configuration file; this is fatal"));
- exit (1);
- }
-
/* Secure mode and unprivileged mode are incompatible */
if (server_user != NULL && secure_in_use)
{
@@ -237,6 +230,7 @@ close_sockets (void)
close (sock);
}
+
static void
invalidate_cache (char *key)
{
@@ -384,20 +378,9 @@ cannot handle old request version %d; current version is %d"),
case GETSTAT:
case SHUTDOWN:
case INVALIDATE:
- /* Accept shutdown, getstat and invalidate only from root */
- if (secure_in_use && uid == 0)
+ if (! secure_in_use)
{
- if (req->type == GETSTAT)
- send_stats (fd, dbs);
- else if (req->type == INVALIDATE)
- invalidate_cache (key);
- else
- termination_handler (0);
- }
- else
- {
- /* Some systems have no SO_PEERCRED implementation. They don't
- care about security so we don't as well. */
+ /* Get the callers credentials. */
#ifdef SO_PEERCRED
struct ucred caller;
socklen_t optlen = sizeof (caller);
@@ -408,18 +391,30 @@ cannot handle old request version %d; current version is %d"),
dbg_log (_("error getting callers id: %s"),
strerror_r (errno, buf, sizeof (buf)));
+ break;
}
- else
- if (caller.uid == 0)
+
+ uid = caller.uid;
+#else
+ /* Some systems have no SO_PEERCRED implementation. They don't
+ care about security so we don't as well. */
+ uid = 0;
#endif
- {
- if (req->type == GETSTAT)
- send_stats (fd, dbs);
- else if (req->type == INVALIDATE)
- invalidate_cache (key);
- else
- termination_handler (0);
- }
+ }
+
+ /* Accept shutdown, getstat and invalidate only from root. For
+ the stat call also allow the user specified in the config file. */
+ if (req->type == GETSTAT)
+ {
+ if (uid == 0 || uid == stat_uid)
+ send_stats (fd, dbs);
+ }
+ else if (uid == 0)
+ {
+ if (req->type == INVALIDATE)
+ invalidate_cache (key);
+ else
+ termination_handler (0);
}
break;
@@ -480,7 +475,7 @@ nscd_run (void *p)
int fd = TEMP_FAILURE_RETRY (accept (conn.fd, NULL, NULL));
request_header req;
char buf[256];
- uid_t uid = 0;
+ uid_t uid = -1;
#ifdef SO_PEERCRED
pid_t pid = 0;
#endif
@@ -526,7 +521,7 @@ nscd_run (void *p)
|| secure[serv2db[req.type]])
uid = caller.uid;
- pid = caller.pid;
+ pid = caller.pid;
}
else if (__builtin_expect (debug_level > 0, 0))
{