* misc/error.c [_LIBC]: Include <stdbool.h> and <stdint.h>.
[glibc.git] / nscd / connections.c
blob347862e521f59b1b4cb06b13868e838612cfa813
1 /* Inner loops of cache daemon.
2 Copyright (C) 1998-2003, 2004, 2005 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4 Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
11 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with the GNU C Library; if not, write to the Free
18 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA. */
21 #include <alloca.h>
22 #include <assert.h>
23 #include <atomic.h>
24 #include <error.h>
25 #include <errno.h>
26 #include <fcntl.h>
27 #include <grp.h>
28 #include <libintl.h>
29 #include <pthread.h>
30 #include <pwd.h>
31 #include <resolv.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <unistd.h>
35 #include <arpa/inet.h>
36 #ifdef HAVE_EPOLL
37 # include <sys/epoll.h>
38 #endif
39 #include <sys/mman.h>
40 #include <sys/param.h>
41 #include <sys/poll.h>
42 #include <sys/socket.h>
43 #include <sys/stat.h>
44 #include <sys/un.h>
46 #include "nscd.h"
47 #include "dbg_log.h"
48 #include "selinux.h"
51 /* Number of bytes of data we initially reserve for each hash table bucket. */
52 #define DEFAULT_DATASIZE_PER_BUCKET 1024
55 /* Wrapper functions with error checking for standard functions. */
56 extern void *xmalloc (size_t n);
57 extern void *xcalloc (size_t n, size_t s);
58 extern void *xrealloc (void *o, size_t n);
60 /* Support to run nscd as an unprivileged user */
61 const char *server_user;
62 static uid_t server_uid;
63 static gid_t server_gid;
64 const char *stat_user;
65 uid_t stat_uid;
66 static gid_t *server_groups;
67 #ifndef NGROUPS
68 # define NGROUPS 32
69 #endif
70 static int server_ngroups;
72 static pthread_attr_t attr;
74 static void begin_drop_privileges (void);
75 static void finish_drop_privileges (void);
77 /* Map request type to a string. */
78 const char *serv2str[LASTREQ] =
80 [GETPWBYNAME] = "GETPWBYNAME",
81 [GETPWBYUID] = "GETPWBYUID",
82 [GETGRBYNAME] = "GETGRBYNAME",
83 [GETGRBYGID] = "GETGRBYGID",
84 [GETHOSTBYNAME] = "GETHOSTBYNAME",
85 [GETHOSTBYNAMEv6] = "GETHOSTBYNAMEv6",
86 [GETHOSTBYADDR] = "GETHOSTBYADDR",
87 [GETHOSTBYADDRv6] = "GETHOSTBYADDRv6",
88 [SHUTDOWN] = "SHUTDOWN",
89 [GETSTAT] = "GETSTAT",
90 [INVALIDATE] = "INVALIDATE",
91 [GETFDPW] = "GETFDPW",
92 [GETFDGR] = "GETFDGR",
93 [GETFDHST] = "GETFDHST",
94 [GETAI] = "GETAI",
95 [INITGROUPS] = "INITGROUPS"
98 /* The control data structures for the services. */
99 struct database_dyn dbs[lastdb] =
101 [pwddb] = {
102 .lock = PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP,
103 .enabled = 0,
104 .check_file = 1,
105 .persistent = 0,
106 .shared = 0,
107 .filename = "/etc/passwd",
108 .db_filename = _PATH_NSCD_PASSWD_DB,
109 .disabled_iov = &pwd_iov_disabled,
110 .postimeout = 3600,
111 .negtimeout = 20,
112 .wr_fd = -1,
113 .ro_fd = -1,
114 .mmap_used = false
116 [grpdb] = {
117 .lock = PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP,
118 .enabled = 0,
119 .check_file = 1,
120 .persistent = 0,
121 .shared = 0,
122 .filename = "/etc/group",
123 .db_filename = _PATH_NSCD_GROUP_DB,
124 .disabled_iov = &grp_iov_disabled,
125 .postimeout = 3600,
126 .negtimeout = 60,
127 .wr_fd = -1,
128 .ro_fd = -1,
129 .mmap_used = false
131 [hstdb] = {
132 .lock = PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP,
133 .enabled = 0,
134 .check_file = 1,
135 .persistent = 0,
136 .shared = 0,
137 .filename = "/etc/hosts",
138 .db_filename = _PATH_NSCD_HOSTS_DB,
139 .disabled_iov = &hst_iov_disabled,
140 .postimeout = 3600,
141 .negtimeout = 20,
142 .wr_fd = -1,
143 .ro_fd = -1,
144 .mmap_used = false
149 /* Mapping of request type to database. */
150 static struct database_dyn *const serv2db[LASTREQ] =
152 [GETPWBYNAME] = &dbs[pwddb],
153 [GETPWBYUID] = &dbs[pwddb],
154 [GETGRBYNAME] = &dbs[grpdb],
155 [GETGRBYGID] = &dbs[grpdb],
156 [GETHOSTBYNAME] = &dbs[hstdb],
157 [GETHOSTBYNAMEv6] = &dbs[hstdb],
158 [GETHOSTBYADDR] = &dbs[hstdb],
159 [GETHOSTBYADDRv6] = &dbs[hstdb],
160 [GETFDPW] = &dbs[pwddb],
161 [GETFDGR] = &dbs[grpdb],
162 [GETFDHST] = &dbs[hstdb],
163 [GETAI] = &dbs[hstdb],
164 [INITGROUPS] = &dbs[grpdb]
168 /* Number of seconds between two cache pruning runs. */
169 #define CACHE_PRUNE_INTERVAL 15
172 /* Initial number of threads to use. */
173 int nthreads = -1;
174 /* Maximum number of threads to use. */
175 int max_nthreads = 32;
177 /* Socket for incoming connections. */
178 static int sock;
180 /* Number of times clients had to wait. */
181 unsigned long int client_queued;
184 ssize_t
185 writeall (int fd, const void *buf, size_t len)
187 size_t n = len;
188 ssize_t ret;
191 ret = TEMP_FAILURE_RETRY (write (fd, buf, n));
192 if (ret <= 0)
193 break;
194 buf = (const char *) buf + ret;
195 n -= ret;
197 while (n > 0);
198 return ret < 0 ? ret : len - n;
202 /* Initialize database information structures. */
203 void
204 nscd_init (void)
206 /* Secure mode and unprivileged mode are incompatible */
207 if (server_user != NULL && secure_in_use)
209 dbg_log (_("Cannot run nscd in secure mode as unprivileged user"));
210 exit (4);
213 /* Look up unprivileged uid/gid/groups before we start listening on the
214 socket */
215 if (server_user != NULL)
216 begin_drop_privileges ();
218 if (nthreads == -1)
219 /* No configuration for this value, assume a default. */
220 nthreads = 2 * lastdb;
222 for (size_t cnt = 0; cnt < lastdb; ++cnt)
223 if (dbs[cnt].enabled)
225 pthread_rwlock_init (&dbs[cnt].lock, NULL);
226 pthread_mutex_init (&dbs[cnt].memlock, NULL);
228 if (dbs[cnt].persistent)
230 /* Try to open the appropriate file on disk. */
231 int fd = open (dbs[cnt].db_filename, O_RDWR);
232 if (fd != -1)
234 struct stat64 st;
235 void *mem;
236 size_t total;
237 struct database_pers_head head;
238 ssize_t n = TEMP_FAILURE_RETRY (read (fd, &head,
239 sizeof (head)));
240 if (n != sizeof (head) || fstat64 (fd, &st) != 0)
242 fail_db:
243 dbg_log (_("invalid persistent database file \"%s\": %s"),
244 dbs[cnt].db_filename, strerror (errno));
245 dbs[cnt].persistent = 0;
247 else if (head.module == 0 && head.data_size == 0)
249 /* The file has been created, but the head has not been
250 initialized yet. Remove the old file. */
251 unlink (dbs[cnt].db_filename);
253 else if (head.header_size != (int) sizeof (head))
255 dbg_log (_("invalid persistent database file \"%s\": %s"),
256 dbs[cnt].db_filename,
257 _("header size does not match"));
258 dbs[cnt].persistent = 0;
260 else if ((total = (sizeof (head)
261 + roundup (head.module * sizeof (ref_t),
262 ALIGN)
263 + head.data_size))
264 > st.st_size)
266 dbg_log (_("invalid persistent database file \"%s\": %s"),
267 dbs[cnt].db_filename,
268 _("file size does not match"));
269 dbs[cnt].persistent = 0;
271 else if ((mem = mmap (NULL, total, PROT_READ | PROT_WRITE,
272 MAP_SHARED, fd, 0)) == MAP_FAILED)
273 goto fail_db;
274 else
276 /* Success. We have the database. */
277 dbs[cnt].head = mem;
278 dbs[cnt].memsize = total;
279 dbs[cnt].data = (char *)
280 &dbs[cnt].head->array[roundup (dbs[cnt].head->module,
281 ALIGN / sizeof (ref_t))];
282 dbs[cnt].mmap_used = true;
284 if (dbs[cnt].suggested_module > head.module)
285 dbg_log (_("suggested size of table for database %s larger than the persistent database's table"),
286 dbnames[cnt]);
288 dbs[cnt].wr_fd = fd;
289 fd = -1;
290 /* We also need a read-only descriptor. */
291 if (dbs[cnt].shared)
293 dbs[cnt].ro_fd = open (dbs[cnt].db_filename, O_RDONLY);
294 if (dbs[cnt].ro_fd == -1)
295 dbg_log (_("\
296 cannot create read-only descriptor for \"%s\"; no mmap"),
297 dbs[cnt].db_filename);
300 // XXX Shall we test whether the descriptors actually
301 // XXX point to the same file?
304 /* Close the file descriptors in case something went
305 wrong in which case the variable have not been
306 assigned -1. */
307 if (fd != -1)
308 close (fd);
312 if (dbs[cnt].head == NULL)
314 /* No database loaded. Allocate the data structure,
315 possibly on disk. */
316 struct database_pers_head head;
317 size_t total = (sizeof (head)
318 + roundup (dbs[cnt].suggested_module
319 * sizeof (ref_t), ALIGN)
320 + (dbs[cnt].suggested_module
321 * DEFAULT_DATASIZE_PER_BUCKET));
323 /* Try to create the database. If we do not need a
324 persistent database create a temporary file. */
325 int fd;
326 int ro_fd = -1;
327 if (dbs[cnt].persistent)
329 fd = open (dbs[cnt].db_filename,
330 O_RDWR | O_CREAT | O_EXCL | O_TRUNC,
331 S_IRUSR | S_IWUSR);
332 if (fd != -1 && dbs[cnt].shared)
333 ro_fd = open (dbs[cnt].db_filename, O_RDONLY);
335 else
337 char fname[] = _PATH_NSCD_XYZ_DB_TMP;
338 fd = mkstemp (fname);
340 /* We do not need the file name anymore after we
341 opened another file descriptor in read-only mode. */
342 if (fd != -1)
344 if (dbs[cnt].shared)
345 ro_fd = open (fname, O_RDONLY);
347 unlink (fname);
351 if (fd == -1)
353 if (errno == EEXIST)
355 dbg_log (_("database for %s corrupted or simultaneously used; remove %s manually if necessary and restart"),
356 dbnames[cnt], dbs[cnt].db_filename);
357 // XXX Correct way to terminate?
358 exit (1);
361 if (dbs[cnt].persistent)
362 dbg_log (_("cannot create %s; no persistent database used"),
363 dbs[cnt].db_filename);
364 else
365 dbg_log (_("cannot create %s; no sharing possible"),
366 dbs[cnt].db_filename);
368 dbs[cnt].persistent = 0;
369 // XXX remember: no mmap
371 else
373 /* Tell the user if we could not create the read-only
374 descriptor. */
375 if (ro_fd == -1 && dbs[cnt].shared)
376 dbg_log (_("\
377 cannot create read-only descriptor for \"%s\"; no mmap"),
378 dbs[cnt].db_filename);
380 /* Before we create the header, initialiye the hash
381 table. So that if we get interrupted if writing
382 the header we can recognize a partially initialized
383 database. */
384 size_t ps = sysconf (_SC_PAGESIZE);
385 char tmpbuf[ps];
386 assert (~ENDREF == 0);
387 memset (tmpbuf, '\xff', ps);
389 size_t remaining = dbs[cnt].suggested_module * sizeof (ref_t);
390 off_t offset = sizeof (head);
392 size_t towrite;
393 if (offset % ps != 0)
395 towrite = MIN (remaining, ps - (offset % ps));
396 if (pwrite (fd, tmpbuf, towrite, offset) != towrite)
397 goto write_fail;
398 offset += towrite;
399 remaining -= towrite;
402 while (remaining > ps)
404 if (pwrite (fd, tmpbuf, ps, offset) == -1)
405 goto write_fail;
406 offset += ps;
407 remaining -= ps;
410 if (remaining > 0
411 && pwrite (fd, tmpbuf, remaining, offset) != remaining)
412 goto write_fail;
414 /* Create the header of the file. */
415 struct database_pers_head head =
417 .version = DB_VERSION,
418 .header_size = sizeof (head),
419 .module = dbs[cnt].suggested_module,
420 .data_size = (dbs[cnt].suggested_module
421 * DEFAULT_DATASIZE_PER_BUCKET),
422 .first_free = 0
424 void *mem;
426 if ((TEMP_FAILURE_RETRY (write (fd, &head, sizeof (head)))
427 != sizeof (head))
428 || ftruncate (fd, total) != 0
429 || (mem = mmap (NULL, total, PROT_READ | PROT_WRITE,
430 MAP_SHARED, fd, 0)) == MAP_FAILED)
432 write_fail:
433 unlink (dbs[cnt].db_filename);
434 dbg_log (_("cannot write to database file %s: %s"),
435 dbs[cnt].db_filename, strerror (errno));
436 dbs[cnt].persistent = 0;
438 else
440 /* Success. */
441 dbs[cnt].head = mem;
442 dbs[cnt].data = (char *)
443 &dbs[cnt].head->array[roundup (dbs[cnt].head->module,
444 ALIGN / sizeof (ref_t))];
445 dbs[cnt].memsize = total;
446 dbs[cnt].mmap_used = true;
448 /* Remember the descriptors. */
449 dbs[cnt].wr_fd = fd;
450 dbs[cnt].ro_fd = ro_fd;
451 fd = -1;
452 ro_fd = -1;
455 if (fd != -1)
456 close (fd);
457 if (ro_fd != -1)
458 close (ro_fd);
462 if (paranoia
463 && ((dbs[cnt].wr_fd != -1
464 && fcntl (dbs[cnt].wr_fd, F_SETFD, FD_CLOEXEC) == -1)
465 || (dbs[cnt].ro_fd != -1
466 && fcntl (dbs[cnt].ro_fd, F_SETFD, FD_CLOEXEC) == -1)))
468 dbg_log (_("\
469 cannot set socket to close on exec: %s; disabling paranoia mode"),
470 strerror (errno));
471 paranoia = 0;
474 if (dbs[cnt].head == NULL)
476 /* We do not use the persistent database. Just
477 create an in-memory data structure. */
478 assert (! dbs[cnt].persistent);
480 dbs[cnt].head = xmalloc (sizeof (struct database_pers_head)
481 + (dbs[cnt].suggested_module
482 * sizeof (ref_t)));
483 memset (dbs[cnt].head, '\0', sizeof (dbs[cnt].head));
484 assert (~ENDREF == 0);
485 memset (dbs[cnt].head->array, '\xff',
486 dbs[cnt].suggested_module * sizeof (ref_t));
487 dbs[cnt].head->module = dbs[cnt].suggested_module;
488 dbs[cnt].head->data_size = (DEFAULT_DATASIZE_PER_BUCKET
489 * dbs[cnt].head->module);
490 dbs[cnt].data = xmalloc (dbs[cnt].head->data_size);
491 dbs[cnt].head->first_free = 0;
493 dbs[cnt].shared = 0;
494 assert (dbs[cnt].ro_fd == -1);
497 if (dbs[cnt].check_file)
499 /* We need the modification date of the file. */
500 struct stat st;
502 if (stat (dbs[cnt].filename, &st) < 0)
504 /* We cannot stat() the file, disable file checking. */
505 dbg_log (_("cannot stat() file `%s': %s"),
506 dbs[cnt].filename, strerror (errno));
507 dbs[cnt].check_file = 0;
509 else
510 dbs[cnt].file_mtime = st.st_mtime;
514 /* Create the socket. */
515 sock = socket (AF_UNIX, SOCK_STREAM, 0);
516 if (sock < 0)
518 dbg_log (_("cannot open socket: %s"), strerror (errno));
519 exit (errno == EACCES ? 4 : 1);
521 /* Bind a name to the socket. */
522 struct sockaddr_un sock_addr;
523 sock_addr.sun_family = AF_UNIX;
524 strcpy (sock_addr.sun_path, _PATH_NSCDSOCKET);
525 if (bind (sock, (struct sockaddr *) &sock_addr, sizeof (sock_addr)) < 0)
527 dbg_log ("%s: %s", _PATH_NSCDSOCKET, strerror (errno));
528 exit (errno == EACCES ? 4 : 1);
531 /* We don't want to get stuck on accept. */
532 int fl = fcntl (sock, F_GETFL);
533 if (fl == -1 || fcntl (sock, F_SETFL, fl | O_NONBLOCK) == -1)
535 dbg_log (_("cannot change socket to nonblocking mode: %s"),
536 strerror (errno));
537 exit (1);
540 /* The descriptor needs to be closed on exec. */
541 if (paranoia && fcntl (sock, F_SETFD, FD_CLOEXEC) == -1)
543 dbg_log (_("cannot set socket to close on exec: %s"),
544 strerror (errno));
545 exit (1);
548 /* Set permissions for the socket. */
549 chmod (_PATH_NSCDSOCKET, DEFFILEMODE);
551 /* Set the socket up to accept connections. */
552 if (listen (sock, SOMAXCONN) < 0)
554 dbg_log (_("cannot enable socket to accept connections: %s"),
555 strerror (errno));
556 exit (1);
559 /* Change to unprivileged uid/gid/groups if specifed in config file */
560 if (server_user != NULL)
561 finish_drop_privileges ();
565 /* Close the connections. */
566 void
567 close_sockets (void)
569 close (sock);
573 static void
574 invalidate_cache (char *key)
576 dbtype number;
578 if (strcmp (key, "passwd") == 0)
579 number = pwddb;
580 else if (strcmp (key, "group") == 0)
581 number = grpdb;
582 else if (__builtin_expect (strcmp (key, "hosts"), 0) == 0)
584 number = hstdb;
586 /* Re-initialize the resolver. resolv.conf might have changed. */
587 res_init ();
589 else
590 return;
592 if (dbs[number].enabled)
593 prune_cache (&dbs[number], LONG_MAX);
597 #ifdef SCM_RIGHTS
598 static void
599 send_ro_fd (struct database_dyn *db, char *key, int fd)
601 /* If we do not have an read-only file descriptor do nothing. */
602 if (db->ro_fd == -1)
603 return;
605 /* We need to send some data along with the descriptor. */
606 struct iovec iov[1];
607 iov[0].iov_base = key;
608 iov[0].iov_len = strlen (key) + 1;
610 /* Prepare the control message to transfer the descriptor. */
611 union
613 struct cmsghdr hdr;
614 char bytes[CMSG_SPACE (sizeof (int))];
615 } buf;
616 struct msghdr msg = { .msg_iov = iov, .msg_iovlen = 1,
617 .msg_control = buf.bytes,
618 .msg_controllen = sizeof (buf) };
619 struct cmsghdr *cmsg = CMSG_FIRSTHDR (&msg);
621 cmsg->cmsg_level = SOL_SOCKET;
622 cmsg->cmsg_type = SCM_RIGHTS;
623 cmsg->cmsg_len = CMSG_LEN (sizeof (int));
625 *(int *) CMSG_DATA (cmsg) = db->ro_fd;
627 msg.msg_controllen = cmsg->cmsg_len;
629 /* Send the control message. We repeat when we are interrupted but
630 everything else is ignored. */
631 #ifndef MSG_NOSIGNAL
632 # define MSG_NOSIGNAL 0
633 #endif
634 (void) TEMP_FAILURE_RETRY (sendmsg (fd, &msg, MSG_NOSIGNAL));
636 if (__builtin_expect (debug_level > 0, 0))
637 dbg_log (_("provide access to FD %d, for %s"), db->ro_fd, key);
639 #endif /* SCM_RIGHTS */
642 /* Handle new request. */
643 static void
644 handle_request (int fd, request_header *req, void *key, uid_t uid)
646 if (__builtin_expect (req->version, NSCD_VERSION) != NSCD_VERSION)
648 if (debug_level > 0)
649 dbg_log (_("\
650 cannot handle old request version %d; current version is %d"),
651 req->version, NSCD_VERSION);
652 return;
655 /* Make the SELinux check before we go on to the standard checks. We
656 need to verify that the request type is valid, since it has not
657 yet been checked at this point. */
658 if (selinux_enabled
659 && __builtin_expect (req->type, GETPWBYNAME) >= GETPWBYNAME
660 && __builtin_expect (req->type, LASTREQ) < LASTREQ
661 && nscd_request_avc_has_perm (fd, req->type) != 0)
662 return;
664 struct database_dyn *db = serv2db[req->type];
666 // XXX Clean up so that each new command need not introduce a
667 // XXX new conditional.
668 if ((__builtin_expect (req->type, GETPWBYNAME) >= GETPWBYNAME
669 && __builtin_expect (req->type, LASTDBREQ) <= LASTDBREQ)
670 || req->type == GETAI || req->type == INITGROUPS)
672 if (__builtin_expect (debug_level, 0) > 0)
674 if (req->type == GETHOSTBYADDR || req->type == GETHOSTBYADDRv6)
676 char buf[INET6_ADDRSTRLEN];
678 dbg_log ("\t%s (%s)", serv2str[req->type],
679 inet_ntop (req->type == GETHOSTBYADDR
680 ? AF_INET : AF_INET6,
681 key, buf, sizeof (buf)));
683 else
684 dbg_log ("\t%s (%s)", serv2str[req->type], (char *) key);
687 /* Is this service enabled? */
688 if (!db->enabled)
690 /* No, sent the prepared record. */
691 if (TEMP_FAILURE_RETRY (write (fd, db->disabled_iov->iov_base,
692 db->disabled_iov->iov_len))
693 != (ssize_t) db->disabled_iov->iov_len
694 && __builtin_expect (debug_level, 0) > 0)
696 /* We have problems sending the result. */
697 char buf[256];
698 dbg_log (_("cannot write result: %s"),
699 strerror_r (errno, buf, sizeof (buf)));
702 return;
705 /* Be sure we can read the data. */
706 if (__builtin_expect (pthread_rwlock_tryrdlock (&db->lock) != 0, 0))
708 ++db->head->rdlockdelayed;
709 pthread_rwlock_rdlock (&db->lock);
712 /* See whether we can handle it from the cache. */
713 struct datahead *cached;
714 cached = (struct datahead *) cache_search (req->type, key, req->key_len,
715 db, uid);
716 if (cached != NULL)
718 /* Hurray it's in the cache. */
719 if (writeall (fd, cached->data, cached->recsize)
720 != cached->recsize
721 && __builtin_expect (debug_level, 0) > 0)
723 /* We have problems sending the result. */
724 char buf[256];
725 dbg_log (_("cannot write result: %s"),
726 strerror_r (errno, buf, sizeof (buf)));
729 pthread_rwlock_unlock (&db->lock);
731 return;
734 pthread_rwlock_unlock (&db->lock);
736 else if (__builtin_expect (debug_level, 0) > 0)
738 if (req->type == INVALIDATE)
739 dbg_log ("\t%s (%s)", serv2str[req->type], (char *) key);
740 else
741 dbg_log ("\t%s", serv2str[req->type]);
744 /* Handle the request. */
745 switch (req->type)
747 case GETPWBYNAME:
748 addpwbyname (db, fd, req, key, uid);
749 break;
751 case GETPWBYUID:
752 addpwbyuid (db, fd, req, key, uid);
753 break;
755 case GETGRBYNAME:
756 addgrbyname (db, fd, req, key, uid);
757 break;
759 case GETGRBYGID:
760 addgrbygid (db, fd, req, key, uid);
761 break;
763 case GETHOSTBYNAME:
764 addhstbyname (db, fd, req, key, uid);
765 break;
767 case GETHOSTBYNAMEv6:
768 addhstbynamev6 (db, fd, req, key, uid);
769 break;
771 case GETHOSTBYADDR:
772 addhstbyaddr (db, fd, req, key, uid);
773 break;
775 case GETHOSTBYADDRv6:
776 addhstbyaddrv6 (db, fd, req, key, uid);
777 break;
779 case GETAI:
780 addhstai (db, fd, req, key, uid);
781 break;
783 case INITGROUPS:
784 addinitgroups (db, fd, req, key, uid);
785 break;
787 case GETSTAT:
788 case SHUTDOWN:
789 case INVALIDATE:
790 if (! secure_in_use)
792 /* Get the callers credentials. */
793 #ifdef SO_PEERCRED
794 struct ucred caller;
795 socklen_t optlen = sizeof (caller);
797 if (getsockopt (fd, SOL_SOCKET, SO_PEERCRED, &caller, &optlen) < 0)
799 char buf[256];
801 dbg_log (_("error getting callers id: %s"),
802 strerror_r (errno, buf, sizeof (buf)));
803 break;
806 uid = caller.uid;
807 #else
808 /* Some systems have no SO_PEERCRED implementation. They don't
809 care about security so we don't as well. */
810 uid = 0;
811 #endif
814 /* Accept shutdown, getstat and invalidate only from root. For
815 the stat call also allow the user specified in the config file. */
816 if (req->type == GETSTAT)
818 if (uid == 0 || uid == stat_uid)
819 send_stats (fd, dbs);
821 else if (uid == 0)
823 if (req->type == INVALIDATE)
824 invalidate_cache (key);
825 else
826 termination_handler (0);
828 break;
830 case GETFDPW:
831 case GETFDGR:
832 case GETFDHST:
833 #ifdef SCM_RIGHTS
834 send_ro_fd (serv2db[req->type], key, fd);
835 #endif
836 break;
838 default:
839 /* Ignore the command, it's nothing we know. */
840 break;
845 /* Restart the process. */
846 static void
847 restart (void)
849 /* First determine the parameters. We do not use the parameters
850 passed to main() since in case nscd is started by running the
851 dynamic linker this will not work. Yes, this is not the usual
852 case but nscd is part of glibc and we occasionally do this. */
853 size_t buflen = 1024;
854 char *buf = alloca (buflen);
855 size_t readlen = 0;
856 int fd = open ("/proc/self/cmdline", O_RDONLY);
857 if (fd == -1)
859 dbg_log (_("\
860 cannot open /proc/self/cmdline: %s; disabling paranoia mode"),
861 strerror (errno));
863 paranoia = 0;
864 return;
867 while (1)
869 ssize_t n = TEMP_FAILURE_RETRY (read (fd, buf + readlen,
870 buflen - readlen));
871 if (n == -1)
873 dbg_log (_("\
874 cannot open /proc/self/cmdline: %s; disabling paranoia mode"),
875 strerror (errno));
877 close (fd);
878 paranoia = 0;
879 return;
882 readlen += n;
884 if (readlen < buflen)
885 break;
887 /* We might have to extend the buffer. */
888 size_t old_buflen = buflen;
889 char *newp = extend_alloca (buf, buflen, 2 * buflen);
890 buf = memmove (newp, buf, old_buflen);
893 close (fd);
895 /* Parse the command line. Worst case scenario: every two
896 characters form one parameter (one character plus NUL). */
897 char **argv = alloca ((readlen / 2 + 1) * sizeof (argv[0]));
898 int argc = 0;
900 char *cp = buf;
901 while (cp < buf + readlen)
903 argv[argc++] = cp;
904 cp = (char *) rawmemchr (cp, '\0') + 1;
906 argv[argc] = NULL;
908 /* Second, change back to the old user if we changed it. */
909 if (server_user != NULL)
911 if (setuid (old_uid) != 0)
913 dbg_log (_("\
914 cannot change to old UID: %s; disabling paranoia mode"),
915 strerror (errno));
917 paranoia = 0;
918 return;
921 if (setgid (old_gid) != 0)
923 dbg_log (_("\
924 cannot change to old GID: %s; disabling paranoia mode"),
925 strerror (errno));
927 setuid (server_uid);
928 paranoia = 0;
929 return;
933 /* Next change back to the old working directory. */
934 if (chdir (oldcwd) == -1)
936 dbg_log (_("\
937 cannot change to old working directory: %s; disabling paranoia mode"),
938 strerror (errno));
940 if (server_user != NULL)
942 setuid (server_uid);
943 setgid (server_gid);
945 paranoia = 0;
946 return;
949 /* Synchronize memory. */
950 for (int cnt = 0; cnt < lastdb; ++cnt)
952 /* Make sure nobody keeps using the database. */
953 dbs[cnt].head->timestamp = 0;
955 if (dbs[cnt].persistent)
956 // XXX async OK?
957 msync (dbs[cnt].head, dbs[cnt].memsize, MS_ASYNC);
960 /* The preparations are done. */
961 execv ("/proc/self/exe", argv);
963 /* If we come here, we will never be able to re-exec. */
964 dbg_log (_("re-exec failed: %s; disabling paranoia mode"),
965 strerror (errno));
967 if (server_user != NULL)
969 setuid (server_uid);
970 setgid (server_gid);
972 if (chdir ("/") != 0)
973 dbg_log (_("cannot change current working directory to \"/\": %s"),
974 strerror (errno));
975 paranoia = 0;
979 /* List of file descriptors. */
980 struct fdlist
982 int fd;
983 struct fdlist *next;
985 /* Memory allocated for the list. */
986 static struct fdlist *fdlist;
987 /* List of currently ready-to-read file descriptors. */
988 static struct fdlist *readylist;
990 /* Conditional variable and mutex to signal availability of entries in
991 READYLIST. The condvar is initialized dynamically since we might
992 use a different clock depending on availability. */
993 static pthread_cond_t readylist_cond;
994 static pthread_mutex_t readylist_lock = PTHREAD_MUTEX_INITIALIZER;
996 /* The clock to use with the condvar. */
997 static clockid_t timeout_clock = CLOCK_REALTIME;
999 /* Number of threads ready to handle the READYLIST. */
1000 static unsigned long int nready;
1003 /* This is the main loop. It is replicated in different threads but the
1004 `poll' call makes sure only one thread handles an incoming connection. */
1005 static void *
1006 __attribute__ ((__noreturn__))
1007 nscd_run (void *p)
1009 const long int my_number = (long int) p;
1010 const int run_prune = my_number < lastdb && dbs[my_number].enabled;
1011 struct timespec prune_ts;
1012 int to = 0;
1013 char buf[256];
1015 if (run_prune)
1017 setup_thread (&dbs[my_number]);
1019 /* We are running. */
1020 dbs[my_number].head->timestamp = time (NULL);
1022 if (clock_gettime (timeout_clock, &prune_ts) == -1)
1023 /* Should never happen. */
1024 abort ();
1026 /* Compute timeout time. */
1027 prune_ts.tv_sec += CACHE_PRUNE_INTERVAL;
1030 /* Initial locking. */
1031 pthread_mutex_lock (&readylist_lock);
1033 /* One more thread available. */
1034 ++nready;
1036 while (1)
1038 while (readylist == NULL)
1040 if (run_prune)
1042 /* Wait, but not forever. */
1043 to = pthread_cond_timedwait (&readylist_cond, &readylist_lock,
1044 &prune_ts);
1046 /* If we were woken and there is no work to be done,
1047 just start pruning. */
1048 if (readylist == NULL && to == ETIMEDOUT)
1050 --nready;
1051 pthread_mutex_unlock (&readylist_lock);
1052 goto only_prune;
1055 else
1056 /* No need to timeout. */
1057 pthread_cond_wait (&readylist_cond, &readylist_lock);
1060 struct fdlist *it = readylist->next;
1061 if (readylist->next == readylist)
1062 /* Just one entry on the list. */
1063 readylist = NULL;
1064 else
1065 readylist->next = it->next;
1067 /* Extract the information and mark the record ready to be used
1068 again. */
1069 int fd = it->fd;
1070 it->next = NULL;
1072 /* One more thread available. */
1073 --nready;
1075 /* We are done with the list. */
1076 pthread_mutex_unlock (&readylist_lock);
1078 /* We do not want to block on a short read or so. */
1079 int fl = fcntl (fd, F_GETFL);
1080 if (fl == -1 || fcntl (fd, F_SETFL, fl | O_NONBLOCK) == -1)
1081 goto close_and_out;
1083 /* Now read the request. */
1084 request_header req;
1085 if (__builtin_expect (TEMP_FAILURE_RETRY (read (fd, &req, sizeof (req)))
1086 != sizeof (req), 0))
1088 /* We failed to read data. Note that this also might mean we
1089 failed because we would have blocked. */
1090 if (debug_level > 0)
1091 dbg_log (_("short read while reading request: %s"),
1092 strerror_r (errno, buf, sizeof (buf)));
1093 goto close_and_out;
1096 /* Check whether this is a valid request type. */
1097 if (req.type < GETPWBYNAME || req.type >= LASTREQ)
1098 goto close_and_out;
1100 /* Some systems have no SO_PEERCRED implementation. They don't
1101 care about security so we don't as well. */
1102 uid_t uid = -1;
1103 #ifdef SO_PEERCRED
1104 pid_t pid = 0;
1106 if (secure_in_use)
1108 struct ucred caller;
1109 socklen_t optlen = sizeof (caller);
1111 if (getsockopt (fd, SOL_SOCKET, SO_PEERCRED, &caller, &optlen) < 0)
1113 dbg_log (_("error getting callers id: %s"),
1114 strerror_r (errno, buf, sizeof (buf)));
1115 goto close_and_out;
1118 if (req.type < GETPWBYNAME || req.type > LASTDBREQ
1119 || serv2db[req.type]->secure)
1120 uid = caller.uid;
1122 pid = caller.pid;
1124 else if (__builtin_expect (debug_level > 0, 0))
1126 struct ucred caller;
1127 socklen_t optlen = sizeof (caller);
1129 if (getsockopt (fd, SOL_SOCKET, SO_PEERCRED, &caller, &optlen) == 0)
1130 pid = caller.pid;
1132 #endif
1134 /* It should not be possible to crash the nscd with a silly
1135 request (i.e., a terribly large key). We limit the size to 1kb. */
1136 #define MAXKEYLEN 1024
1137 if (__builtin_expect (req.key_len, 1) < 0
1138 || __builtin_expect (req.key_len, 1) > MAXKEYLEN)
1140 if (debug_level > 0)
1141 dbg_log (_("key length in request too long: %d"), req.key_len);
1143 else
1145 /* Get the key. */
1146 char keybuf[MAXKEYLEN];
1148 if (__builtin_expect (TEMP_FAILURE_RETRY (read (fd, keybuf,
1149 req.key_len))
1150 != req.key_len, 0))
1152 /* Again, this can also mean we would have blocked. */
1153 if (debug_level > 0)
1154 dbg_log (_("short read while reading request key: %s"),
1155 strerror_r (errno, buf, sizeof (buf)));
1156 goto close_and_out;
1159 if (__builtin_expect (debug_level, 0) > 0)
1161 #ifdef SO_PEERCRED
1162 if (pid != 0)
1163 dbg_log (_("\
1164 handle_request: request received (Version = %d) from PID %ld"),
1165 req.version, (long int) pid);
1166 else
1167 #endif
1168 dbg_log (_("\
1169 handle_request: request received (Version = %d)"), req.version);
1172 /* Phew, we got all the data, now process it. */
1173 handle_request (fd, &req, keybuf, uid);
1176 close_and_out:
1177 /* We are done. */
1178 close (fd);
1180 /* Check whether we should be pruning the cache. */
1181 assert (run_prune || to == 0);
1182 if (to == ETIMEDOUT)
1184 only_prune:
1185 /* The pthread_cond_timedwait() call timed out. It is time
1186 to clean up the cache. */
1187 assert (my_number < lastdb);
1188 prune_cache (&dbs[my_number], time (NULL));
1190 if (clock_gettime (timeout_clock, &prune_ts) == -1)
1191 /* Should never happen. */
1192 abort ();
1194 /* Compute next timeout time. */
1195 prune_ts.tv_sec += CACHE_PRUNE_INTERVAL;
1197 /* In case the list is emtpy we do not want to run the prune
1198 code right away again. */
1199 to = 0;
1202 /* Re-locking. */
1203 pthread_mutex_lock (&readylist_lock);
1205 /* One more thread available. */
1206 ++nready;
1211 static unsigned int nconns;
1213 static void
1214 fd_ready (int fd)
1216 pthread_mutex_lock (&readylist_lock);
1218 /* Find an empty entry in FDLIST. */
1219 size_t inner;
1220 for (inner = 0; inner < nconns; ++inner)
1221 if (fdlist[inner].next == NULL)
1222 break;
1223 assert (inner < nconns);
1225 fdlist[inner].fd = fd;
1227 if (readylist == NULL)
1228 readylist = fdlist[inner].next = &fdlist[inner];
1229 else
1231 fdlist[inner].next = readylist->next;
1232 readylist = readylist->next = &fdlist[inner];
1235 bool do_signal = true;
1236 if (__builtin_expect (nready == 0, 0))
1238 ++client_queued;
1239 do_signal = false;
1241 /* Try to start another thread to help out. */
1242 pthread_t th;
1243 if (nthreads < max_nthreads
1244 && pthread_create (&th, &attr, nscd_run,
1245 (void *) (long int) nthreads) == 0)
1247 /* We got another thread. */
1248 ++nthreads;
1249 /* The new thread might new a kick. */
1250 do_signal = true;
1255 pthread_mutex_unlock (&readylist_lock);
1257 /* Tell one of the worker threads there is work to do. */
1258 if (do_signal)
1259 pthread_cond_signal (&readylist_cond);
1263 /* Check whether restarting should happen. */
1264 static inline int
1265 restart_p (time_t now)
1267 return (paranoia && readylist == NULL && nready == nthreads
1268 && now >= restart_time);
1272 /* Array for times a connection was accepted. */
1273 static time_t *starttime;
1276 static void
1277 __attribute__ ((__noreturn__))
1278 main_loop_poll (void)
1280 struct pollfd *conns = (struct pollfd *) xmalloc (nconns
1281 * sizeof (conns[0]));
1283 conns[0].fd = sock;
1284 conns[0].events = POLLRDNORM;
1285 size_t nused = 1;
1286 size_t firstfree = 1;
1288 while (1)
1290 /* Wait for any event. We wait at most a couple of seconds so
1291 that we can check whether we should close any of the accepted
1292 connections since we have not received a request. */
1293 #define MAX_ACCEPT_TIMEOUT 30
1294 #define MIN_ACCEPT_TIMEOUT 5
1295 #define MAIN_THREAD_TIMEOUT \
1296 (MAX_ACCEPT_TIMEOUT * 1000 \
1297 - ((MAX_ACCEPT_TIMEOUT - MIN_ACCEPT_TIMEOUT) * 1000 * nused) / (2 * nconns))
1299 int n = poll (conns, nused, MAIN_THREAD_TIMEOUT);
1301 time_t now = time (NULL);
1303 /* If there is a descriptor ready for reading or there is a new
1304 connection, process this now. */
1305 if (n > 0)
1307 if (conns[0].revents != 0)
1309 /* We have a new incoming connection. Accept the connection. */
1310 int fd = TEMP_FAILURE_RETRY (accept (sock, NULL, NULL));
1312 /* use the descriptor if we have not reached the limit. */
1313 if (fd >= 0 && firstfree < nconns)
1315 conns[firstfree].fd = fd;
1316 conns[firstfree].events = POLLRDNORM;
1317 starttime[firstfree] = now;
1318 if (firstfree >= nused)
1319 nused = firstfree + 1;
1322 ++firstfree;
1323 while (firstfree < nused && conns[firstfree].fd != -1);
1326 --n;
1329 for (size_t cnt = 1; cnt < nused && n > 0; ++cnt)
1330 if (conns[cnt].revents != 0)
1332 fd_ready (conns[cnt].fd);
1334 /* Clean up the CONNS array. */
1335 conns[cnt].fd = -1;
1336 if (cnt < firstfree)
1337 firstfree = cnt;
1338 if (cnt == nused - 1)
1340 --nused;
1341 while (conns[nused - 1].fd == -1);
1343 --n;
1347 /* Now find entries which have timed out. */
1348 assert (nused > 0);
1350 /* We make the timeout length depend on the number of file
1351 descriptors currently used. */
1352 #define ACCEPT_TIMEOUT \
1353 (MAX_ACCEPT_TIMEOUT \
1354 - ((MAX_ACCEPT_TIMEOUT - MIN_ACCEPT_TIMEOUT) * nused) / nconns)
1355 time_t laststart = now - ACCEPT_TIMEOUT;
1357 for (size_t cnt = nused - 1; cnt > 0; --cnt)
1359 if (conns[cnt].fd != -1 && starttime[cnt] < laststart)
1361 /* Remove the entry, it timed out. */
1362 (void) close (conns[cnt].fd);
1363 conns[cnt].fd = -1;
1365 if (cnt < firstfree)
1366 firstfree = cnt;
1367 if (cnt == nused - 1)
1369 --nused;
1370 while (conns[nused - 1].fd == -1);
1374 if (restart_p (now))
1375 restart ();
1380 #ifdef HAVE_EPOLL
1381 static void
1382 main_loop_epoll (int efd)
1384 struct epoll_event ev = { 0, };
1385 int nused = 1;
1386 size_t highest = 0;
1388 /* Add the socket. */
1389 ev.events = EPOLLRDNORM;
1390 ev.data.fd = sock;
1391 if (epoll_ctl (efd, EPOLL_CTL_ADD, sock, &ev) == -1)
1392 /* We cannot use epoll. */
1393 return;
1395 while (1)
1397 struct epoll_event revs[100];
1398 # define nrevs (sizeof (revs) / sizeof (revs[0]))
1400 int n = epoll_wait (efd, revs, nrevs, MAIN_THREAD_TIMEOUT);
1402 time_t now = time (NULL);
1404 for (int cnt = 0; cnt < n; ++cnt)
1405 if (revs[cnt].data.fd == sock)
1407 /* A new connection. */
1408 int fd = TEMP_FAILURE_RETRY (accept (sock, NULL, NULL));
1410 if (fd >= 0)
1412 /* Try to add the new descriptor. */
1413 ev.data.fd = fd;
1414 if (fd >= nconns
1415 || epoll_ctl (efd, EPOLL_CTL_ADD, fd, &ev) == -1)
1416 /* The descriptor is too large or something went
1417 wrong. Close the descriptor. */
1418 close (fd);
1419 else
1421 /* Remember when we accepted the connection. */
1422 starttime[fd] = now;
1424 if (fd > highest)
1425 highest = fd;
1427 ++nused;
1431 else
1433 /* Remove the descriptor from the epoll descriptor. */
1434 struct epoll_event ev = { 0, };
1435 (void) epoll_ctl (efd, EPOLL_CTL_DEL, revs[cnt].data.fd, &ev);
1437 /* Get a worked to handle the request. */
1438 fd_ready (revs[cnt].data.fd);
1440 /* Reset the time. */
1441 starttime[revs[cnt].data.fd] = 0;
1442 if (revs[cnt].data.fd == highest)
1444 --highest;
1445 while (highest > 0 && starttime[highest] == 0);
1447 --nused;
1450 /* Now look for descriptors for accepted connections which have
1451 no reply in too long of a time. */
1452 time_t laststart = now - ACCEPT_TIMEOUT;
1453 for (int cnt = highest; cnt > STDERR_FILENO; --cnt)
1454 if (cnt != sock && starttime[cnt] != 0 && starttime[cnt] < laststart)
1456 /* We are waiting for this one for too long. Close it. */
1457 struct epoll_event ev = {0, };
1458 (void) epoll_ctl (efd, EPOLL_CTL_DEL, cnt, &ev);
1460 (void) close (cnt);
1462 starttime[cnt] = 0;
1463 if (cnt == highest)
1464 --highest;
1466 else if (cnt != sock && starttime[cnt] == 0 && cnt == highest)
1467 --highest;
1469 if (restart_p (now))
1470 restart ();
1473 #endif
1476 /* Start all the threads we want. The initial process is thread no. 1. */
1477 void
1478 start_threads (void)
1480 /* Initialize the conditional variable we will use. The only
1481 non-standard attribute we might use is the clock selection. */
1482 pthread_condattr_t condattr;
1483 pthread_condattr_init (&condattr);
1485 #if defined _POSIX_CLOCK_SELECTION && _POSIX_CLOCK_SELECTION >= 0 \
1486 && defined _POSIX_MONOTONIC_CLOCK && _POSIX_MONOTONIC_CLOCK >= 0
1487 /* Determine whether the monotonous clock is available. */
1488 struct timespec dummy;
1489 # if _POSIX_MONOTONIC_CLOCK == 0
1490 if (sysconf (_SC_MONOTONIC_CLOCK) > 0)
1491 # endif
1492 # if _POSIX_CLOCK_SELECTION == 0
1493 if (sysconf (_SC_CLOCK_SELECTION) > 0)
1494 # endif
1495 if (clock_getres (CLOCK_MONOTONIC, &dummy) == 0
1496 && pthread_condattr_setclock (&condattr, CLOCK_MONOTONIC) == 0)
1497 timeout_clock = CLOCK_MONOTONIC;
1498 #endif
1500 pthread_cond_init (&readylist_cond, &condattr);
1501 pthread_condattr_destroy (&condattr);
1504 /* Create the attribute for the threads. They are all created
1505 detached. */
1506 pthread_attr_init (&attr);
1507 pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
1508 /* Use 1MB stacks, twice as much for 64-bit architectures. */
1509 pthread_attr_setstacksize (&attr, 1024 * 1024 * (sizeof (void *) / 4));
1511 /* We allow less than LASTDB threads only for debugging. */
1512 if (debug_level == 0)
1513 nthreads = MAX (nthreads, lastdb);
1515 int nfailed = 0;
1516 for (long int i = 0; i < nthreads; ++i)
1518 pthread_t th;
1519 if (pthread_create (&th, &attr, nscd_run, (void *) (i - nfailed)) != 0)
1520 ++nfailed;
1522 if (nthreads - nfailed < lastdb)
1524 /* We could not start enough threads. */
1525 dbg_log (_("could only start %d threads; terminating"),
1526 nthreads - nfailed);
1527 exit (1);
1530 /* Determine how much room for descriptors we should initially
1531 allocate. This might need to change later if we cap the number
1532 with MAXCONN. */
1533 const long int nfds = sysconf (_SC_OPEN_MAX);
1534 #define MINCONN 32
1535 #define MAXCONN 16384
1536 if (nfds == -1 || nfds > MAXCONN)
1537 nconns = MAXCONN;
1538 else if (nfds < MINCONN)
1539 nconns = MINCONN;
1540 else
1541 nconns = nfds;
1543 /* We need memory to pass descriptors on to the worker threads. */
1544 fdlist = (struct fdlist *) xcalloc (nconns, sizeof (fdlist[0]));
1545 /* Array to keep track when connection was accepted. */
1546 starttime = (time_t *) xcalloc (nconns, sizeof (starttime[0]));
1548 /* In the main thread we execute the loop which handles incoming
1549 connections. */
1550 #ifdef HAVE_EPOLL
1551 int efd = epoll_create (100);
1552 if (efd != -1)
1554 main_loop_epoll (efd);
1555 close (efd);
1557 #endif
1559 main_loop_poll ();
1563 /* Look up the uid, gid, and supplementary groups to run nscd as. When
1564 this function is called, we are not listening on the nscd socket yet so
1565 we can just use the ordinary lookup functions without causing a lockup */
1566 static void
1567 begin_drop_privileges (void)
1569 struct passwd *pwd = getpwnam (server_user);
1571 if (pwd == NULL)
1573 dbg_log (_("Failed to run nscd as user '%s'"), server_user);
1574 error (EXIT_FAILURE, 0, _("Failed to run nscd as user '%s'"),
1575 server_user);
1578 server_uid = pwd->pw_uid;
1579 server_gid = pwd->pw_gid;
1581 /* Save the old UID/GID if we have to change back. */
1582 if (paranoia)
1584 old_uid = getuid ();
1585 old_gid = getgid ();
1588 if (getgrouplist (server_user, server_gid, NULL, &server_ngroups) == 0)
1590 /* This really must never happen. */
1591 dbg_log (_("Failed to run nscd as user '%s'"), server_user);
1592 error (EXIT_FAILURE, errno, _("initial getgrouplist failed"));
1595 server_groups = (gid_t *) xmalloc (server_ngroups * sizeof (gid_t));
1597 if (getgrouplist (server_user, server_gid, server_groups, &server_ngroups)
1598 == -1)
1600 dbg_log (_("Failed to run nscd as user '%s'"), server_user);
1601 error (EXIT_FAILURE, errno, _("getgrouplist failed"));
1606 /* Call setgroups(), setgid(), and setuid() to drop root privileges and
1607 run nscd as the user specified in the configuration file. */
1608 static void
1609 finish_drop_privileges (void)
1611 if (setgroups (server_ngroups, server_groups) == -1)
1613 dbg_log (_("Failed to run nscd as user '%s'"), server_user);
1614 error (EXIT_FAILURE, errno, _("setgroups failed"));
1617 if (setgid (server_gid) == -1)
1619 dbg_log (_("Failed to run nscd as user '%s'"), server_user);
1620 perror ("setgid");
1621 exit (4);
1624 if (setuid (server_uid) == -1)
1626 dbg_log (_("Failed to run nscd as user '%s'"), server_user);
1627 perror ("setuid");
1628 exit (4);