* stdlib/quick_exit.c (quick_exit): Pass &__quick_exit_funcs
[glibc.git] / nscd / connections.c
blob3d0727f33b2a3f0667531e42f65ae3171f623859
1 /* Inner loops of cache daemon.
2 Copyright (C) 1998-2007, 2008, 2009 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4 Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published
8 by the Free Software Foundation; version 2 of the License, or
9 (at your option) any later version.
11 This program 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
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software Foundation,
18 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
20 #include <alloca.h>
21 #include <assert.h>
22 #include <atomic.h>
23 #include <error.h>
24 #include <errno.h>
25 #include <fcntl.h>
26 #include <grp.h>
27 #include <libintl.h>
28 #include <pthread.h>
29 #include <pwd.h>
30 #include <resolv.h>
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <unistd.h>
34 #include <arpa/inet.h>
35 #ifdef HAVE_EPOLL
36 # include <sys/epoll.h>
37 #endif
38 #ifdef HAVE_INOTIFY
39 # include <sys/inotify.h>
40 #endif
41 #include <sys/mman.h>
42 #include <sys/param.h>
43 #include <sys/poll.h>
44 #ifdef HAVE_SENDFILE
45 # include <sys/sendfile.h>
46 #endif
47 #include <sys/socket.h>
48 #include <sys/stat.h>
49 #include <sys/un.h>
51 #include "nscd.h"
52 #include "dbg_log.h"
53 #include "selinux.h"
54 #include <resolv/resolv.h>
55 #ifdef HAVE_SENDFILE
56 # include <kernel-features.h>
57 #endif
60 /* Wrapper functions with error checking for standard functions. */
61 extern void *xmalloc (size_t n);
62 extern void *xcalloc (size_t n, size_t s);
63 extern void *xrealloc (void *o, size_t n);
65 /* Support to run nscd as an unprivileged user */
66 const char *server_user;
67 static uid_t server_uid;
68 static gid_t server_gid;
69 const char *stat_user;
70 uid_t stat_uid;
71 static gid_t *server_groups;
72 #ifndef NGROUPS
73 # define NGROUPS 32
74 #endif
75 static int server_ngroups;
77 static pthread_attr_t attr;
79 static void begin_drop_privileges (void);
80 static void finish_drop_privileges (void);
82 /* Map request type to a string. */
83 const char *const serv2str[LASTREQ] =
85 [GETPWBYNAME] = "GETPWBYNAME",
86 [GETPWBYUID] = "GETPWBYUID",
87 [GETGRBYNAME] = "GETGRBYNAME",
88 [GETGRBYGID] = "GETGRBYGID",
89 [GETHOSTBYNAME] = "GETHOSTBYNAME",
90 [GETHOSTBYNAMEv6] = "GETHOSTBYNAMEv6",
91 [GETHOSTBYADDR] = "GETHOSTBYADDR",
92 [GETHOSTBYADDRv6] = "GETHOSTBYADDRv6",
93 [SHUTDOWN] = "SHUTDOWN",
94 [GETSTAT] = "GETSTAT",
95 [INVALIDATE] = "INVALIDATE",
96 [GETFDPW] = "GETFDPW",
97 [GETFDGR] = "GETFDGR",
98 [GETFDHST] = "GETFDHST",
99 [GETAI] = "GETAI",
100 [INITGROUPS] = "INITGROUPS",
101 [GETSERVBYNAME] = "GETSERVBYNAME",
102 [GETSERVBYPORT] = "GETSERVBYPORT",
103 [GETFDSERV] = "GETFDSERV"
106 /* The control data structures for the services. */
107 struct database_dyn dbs[lastdb] =
109 [pwddb] = {
110 .lock = PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP,
111 .prune_lock = PTHREAD_MUTEX_INITIALIZER,
112 .prune_run_lock = PTHREAD_MUTEX_INITIALIZER,
113 .enabled = 0,
114 .check_file = 1,
115 .persistent = 0,
116 .propagate = 1,
117 .shared = 0,
118 .max_db_size = DEFAULT_MAX_DB_SIZE,
119 .suggested_module = DEFAULT_SUGGESTED_MODULE,
120 .reset_res = 0,
121 .filename = "/etc/passwd",
122 .db_filename = _PATH_NSCD_PASSWD_DB,
123 .disabled_iov = &pwd_iov_disabled,
124 .postimeout = 3600,
125 .negtimeout = 20,
126 .wr_fd = -1,
127 .ro_fd = -1,
128 .mmap_used = false
130 [grpdb] = {
131 .lock = PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP,
132 .prune_lock = PTHREAD_MUTEX_INITIALIZER,
133 .prune_run_lock = PTHREAD_MUTEX_INITIALIZER,
134 .enabled = 0,
135 .check_file = 1,
136 .persistent = 0,
137 .propagate = 1,
138 .shared = 0,
139 .max_db_size = DEFAULT_MAX_DB_SIZE,
140 .suggested_module = DEFAULT_SUGGESTED_MODULE,
141 .reset_res = 0,
142 .filename = "/etc/group",
143 .db_filename = _PATH_NSCD_GROUP_DB,
144 .disabled_iov = &grp_iov_disabled,
145 .postimeout = 3600,
146 .negtimeout = 60,
147 .wr_fd = -1,
148 .ro_fd = -1,
149 .mmap_used = false
151 [hstdb] = {
152 .lock = PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP,
153 .prune_lock = PTHREAD_MUTEX_INITIALIZER,
154 .prune_run_lock = PTHREAD_MUTEX_INITIALIZER,
155 .enabled = 0,
156 .check_file = 1,
157 .persistent = 0,
158 .propagate = 0, /* Not used. */
159 .shared = 0,
160 .max_db_size = DEFAULT_MAX_DB_SIZE,
161 .suggested_module = DEFAULT_SUGGESTED_MODULE,
162 .reset_res = 1,
163 .filename = "/etc/hosts",
164 .db_filename = _PATH_NSCD_HOSTS_DB,
165 .disabled_iov = &hst_iov_disabled,
166 .postimeout = 3600,
167 .negtimeout = 20,
168 .wr_fd = -1,
169 .ro_fd = -1,
170 .mmap_used = false
172 [servdb] = {
173 .lock = PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP,
174 .prune_lock = PTHREAD_MUTEX_INITIALIZER,
175 .prune_run_lock = PTHREAD_MUTEX_INITIALIZER,
176 .enabled = 0,
177 .check_file = 1,
178 .persistent = 0,
179 .propagate = 0, /* Not used. */
180 .shared = 0,
181 .max_db_size = DEFAULT_MAX_DB_SIZE,
182 .suggested_module = DEFAULT_SUGGESTED_MODULE,
183 .reset_res = 0,
184 .filename = "/etc/services",
185 .db_filename = _PATH_NSCD_SERVICES_DB,
186 .disabled_iov = &serv_iov_disabled,
187 .postimeout = 28800,
188 .negtimeout = 20,
189 .wr_fd = -1,
190 .ro_fd = -1,
191 .mmap_used = false
196 /* Mapping of request type to database. */
197 static struct
199 bool data_request;
200 struct database_dyn *db;
201 } const reqinfo[LASTREQ] =
203 [GETPWBYNAME] = { true, &dbs[pwddb] },
204 [GETPWBYUID] = { true, &dbs[pwddb] },
205 [GETGRBYNAME] = { true, &dbs[grpdb] },
206 [GETGRBYGID] = { true, &dbs[grpdb] },
207 [GETHOSTBYNAME] = { true, &dbs[hstdb] },
208 [GETHOSTBYNAMEv6] = { true, &dbs[hstdb] },
209 [GETHOSTBYADDR] = { true, &dbs[hstdb] },
210 [GETHOSTBYADDRv6] = { true, &dbs[hstdb] },
211 [SHUTDOWN] = { false, NULL },
212 [GETSTAT] = { false, NULL },
213 [SHUTDOWN] = { false, NULL },
214 [GETFDPW] = { false, &dbs[pwddb] },
215 [GETFDGR] = { false, &dbs[grpdb] },
216 [GETFDHST] = { false, &dbs[hstdb] },
217 [GETAI] = { true, &dbs[hstdb] },
218 [INITGROUPS] = { true, &dbs[grpdb] },
219 [GETSERVBYNAME] = { true, &dbs[servdb] },
220 [GETSERVBYPORT] = { true, &dbs[servdb] },
221 [GETFDSERV] = { false, &dbs[servdb] }
225 /* Initial number of threads to use. */
226 int nthreads = -1;
227 /* Maximum number of threads to use. */
228 int max_nthreads = 32;
230 /* Socket for incoming connections. */
231 static int sock;
233 #ifdef HAVE_INOTIFY
234 /* Inotify descriptor. */
235 static int inotify_fd = -1;
237 /* Watch descriptor for resolver configuration file. */
238 static int resolv_conf_descr = -1;
239 #endif
241 #ifndef __ASSUME_SOCK_CLOEXEC
242 /* Negative if SOCK_CLOEXEC is not supported, positive if it is, zero
243 before be know the result. */
244 static int have_sock_cloexec;
245 #endif
246 #ifndef __ASSUME_ACCEPT4
247 static int have_accept4;
248 #endif
250 /* Number of times clients had to wait. */
251 unsigned long int client_queued;
254 ssize_t
255 writeall (int fd, const void *buf, size_t len)
257 size_t n = len;
258 ssize_t ret;
261 ret = TEMP_FAILURE_RETRY (send (fd, buf, n, MSG_NOSIGNAL));
262 if (ret <= 0)
263 break;
264 buf = (const char *) buf + ret;
265 n -= ret;
267 while (n > 0);
268 return ret < 0 ? ret : len - n;
272 #ifdef HAVE_SENDFILE
273 ssize_t
274 sendfileall (int tofd, int fromfd, off_t off, size_t len)
276 ssize_t n = len;
277 ssize_t ret;
281 ret = TEMP_FAILURE_RETRY (sendfile (tofd, fromfd, &off, n));
282 if (ret <= 0)
283 break;
284 n -= ret;
286 while (n > 0);
287 return ret < 0 ? ret : len - n;
289 #endif
292 enum usekey
294 use_not = 0,
295 /* The following three are not really used, they are symbolic constants. */
296 use_first = 16,
297 use_begin = 32,
298 use_end = 64,
300 use_he = 1,
301 use_he_begin = use_he | use_begin,
302 use_he_end = use_he | use_end,
303 #if SEPARATE_KEY
304 use_key = 2,
305 use_key_begin = use_key | use_begin,
306 use_key_end = use_key | use_end,
307 use_key_first = use_key_begin | use_first,
308 #endif
309 use_data = 3,
310 use_data_begin = use_data | use_begin,
311 use_data_end = use_data | use_end,
312 use_data_first = use_data_begin | use_first
316 static int
317 check_use (const char *data, nscd_ssize_t first_free, uint8_t *usemap,
318 enum usekey use, ref_t start, size_t len)
320 assert (len >= 2);
322 if (start > first_free || start + len > first_free
323 || (start & BLOCK_ALIGN_M1))
324 return 0;
326 if (usemap[start] == use_not)
328 /* Add the start marker. */
329 usemap[start] = use | use_begin;
330 use &= ~use_first;
332 while (--len > 0)
333 if (usemap[++start] != use_not)
334 return 0;
335 else
336 usemap[start] = use;
338 /* Add the end marker. */
339 usemap[start] = use | use_end;
341 else if ((usemap[start] & ~use_first) == ((use | use_begin) & ~use_first))
343 /* Hash entries can't be shared. */
344 if (use == use_he)
345 return 0;
347 usemap[start] |= (use & use_first);
348 use &= ~use_first;
350 while (--len > 1)
351 if (usemap[++start] != use)
352 return 0;
354 if (usemap[++start] != (use | use_end))
355 return 0;
357 else
358 /* Points to a wrong object or somewhere in the middle. */
359 return 0;
361 return 1;
365 /* Verify data in persistent database. */
366 static int
367 verify_persistent_db (void *mem, struct database_pers_head *readhead, int dbnr)
369 assert (dbnr == pwddb || dbnr == grpdb || dbnr == hstdb || dbnr == servdb);
371 time_t now = time (NULL);
373 struct database_pers_head *head = mem;
374 struct database_pers_head head_copy = *head;
376 /* Check that the header that was read matches the head in the database. */
377 if (memcmp (head, readhead, sizeof (*head)) != 0)
378 return 0;
380 /* First some easy tests: make sure the database header is sane. */
381 if (head->version != DB_VERSION
382 || head->header_size != sizeof (*head)
383 /* We allow a timestamp to be one hour ahead of the current time.
384 This should cover daylight saving time changes. */
385 || head->timestamp > now + 60 * 60 + 60
386 || (head->gc_cycle & 1)
387 || head->module == 0
388 || (size_t) head->module > INT32_MAX / sizeof (ref_t)
389 || (size_t) head->data_size > INT32_MAX - head->module * sizeof (ref_t)
390 || head->first_free < 0
391 || head->first_free > head->data_size
392 || (head->first_free & BLOCK_ALIGN_M1) != 0
393 || head->maxnentries < 0
394 || head->maxnsearched < 0)
395 return 0;
397 uint8_t *usemap = calloc (head->first_free, 1);
398 if (usemap == NULL)
399 return 0;
401 const char *data = (char *) &head->array[roundup (head->module,
402 ALIGN / sizeof (ref_t))];
404 nscd_ssize_t he_cnt = 0;
405 for (nscd_ssize_t cnt = 0; cnt < head->module; ++cnt)
407 ref_t trail = head->array[cnt];
408 ref_t work = trail;
409 int tick = 0;
411 while (work != ENDREF)
413 if (! check_use (data, head->first_free, usemap, use_he, work,
414 sizeof (struct hashentry)))
415 goto fail;
417 /* Now we know we can dereference the record. */
418 struct hashentry *here = (struct hashentry *) (data + work);
420 ++he_cnt;
422 /* Make sure the record is for this type of service. */
423 if (here->type >= LASTREQ
424 || reqinfo[here->type].db != &dbs[dbnr])
425 goto fail;
427 /* Validate boolean field value. */
428 if (here->first != false && here->first != true)
429 goto fail;
431 if (here->len < 0)
432 goto fail;
434 /* Now the data. */
435 if (here->packet < 0
436 || here->packet > head->first_free
437 || here->packet + sizeof (struct datahead) > head->first_free)
438 goto fail;
440 struct datahead *dh = (struct datahead *) (data + here->packet);
442 if (! check_use (data, head->first_free, usemap,
443 use_data | (here->first ? use_first : 0),
444 here->packet, dh->allocsize))
445 goto fail;
447 if (dh->allocsize < sizeof (struct datahead)
448 || dh->recsize > dh->allocsize
449 || (dh->notfound != false && dh->notfound != true)
450 || (dh->usable != false && dh->usable != true))
451 goto fail;
453 if (here->key < here->packet + sizeof (struct datahead)
454 || here->key > here->packet + dh->allocsize
455 || here->key + here->len > here->packet + dh->allocsize)
457 #if SEPARATE_KEY
458 /* If keys can appear outside of data, this should be done
459 instead. But gc doesn't mark the data in that case. */
460 if (! check_use (data, head->first_free, usemap,
461 use_key | (here->first ? use_first : 0),
462 here->key, here->len))
463 #endif
464 goto fail;
467 work = here->next;
469 if (work == trail)
470 /* A circular list, this must not happen. */
471 goto fail;
472 if (tick)
473 trail = ((struct hashentry *) (data + trail))->next;
474 tick = 1 - tick;
478 if (he_cnt != head->nentries)
479 goto fail;
481 /* See if all data and keys had at least one reference from
482 he->first == true hashentry. */
483 for (ref_t idx = 0; idx < head->first_free; ++idx)
485 #if SEPARATE_KEY
486 if (usemap[idx] == use_key_begin)
487 goto fail;
488 #endif
489 if (usemap[idx] == use_data_begin)
490 goto fail;
493 /* Finally, make sure the database hasn't changed since the first test. */
494 if (memcmp (mem, &head_copy, sizeof (*head)) != 0)
495 goto fail;
497 free (usemap);
498 return 1;
500 fail:
501 free (usemap);
502 return 0;
506 #ifdef O_CLOEXEC
507 # define EXTRA_O_FLAGS O_CLOEXEC
508 #else
509 # define EXTRA_O_FLAGS 0
510 #endif
513 /* Initialize database information structures. */
514 void
515 nscd_init (void)
517 /* Look up unprivileged uid/gid/groups before we start listening on the
518 socket */
519 if (server_user != NULL)
520 begin_drop_privileges ();
522 if (nthreads == -1)
523 /* No configuration for this value, assume a default. */
524 nthreads = 4;
526 #ifdef HAVE_INOTIFY
527 /* Use inotify to recognize changed files. */
528 inotify_fd = inotify_init1 (IN_NONBLOCK);
529 # ifndef __ASSUME_IN_NONBLOCK
530 if (inotify_fd == -1 && errno == ENOSYS)
532 inotify_fd = inotify_init ();
533 if (inotify_fd != -1)
534 fcntl (inotify_fd, F_SETFL, O_RDONLY | O_NONBLOCK);
536 # endif
537 #endif
539 for (size_t cnt = 0; cnt < lastdb; ++cnt)
540 if (dbs[cnt].enabled)
542 pthread_rwlock_init (&dbs[cnt].lock, NULL);
543 pthread_mutex_init (&dbs[cnt].memlock, NULL);
545 if (dbs[cnt].persistent)
547 /* Try to open the appropriate file on disk. */
548 int fd = open (dbs[cnt].db_filename, O_RDWR | EXTRA_O_FLAGS);
549 if (fd != -1)
551 char *msg = NULL;
552 struct stat64 st;
553 void *mem;
554 size_t total;
555 struct database_pers_head head;
556 ssize_t n = TEMP_FAILURE_RETRY (read (fd, &head,
557 sizeof (head)));
558 if (n != sizeof (head) || fstat64 (fd, &st) != 0)
560 fail_db_errno:
561 /* The code is single-threaded at this point so
562 using strerror is just fine. */
563 msg = strerror (errno);
564 fail_db:
565 dbg_log (_("invalid persistent database file \"%s\": %s"),
566 dbs[cnt].db_filename, msg);
567 unlink (dbs[cnt].db_filename);
569 else if (head.module == 0 && head.data_size == 0)
571 /* The file has been created, but the head has not
572 been initialized yet. */
573 msg = _("uninitialized header");
574 goto fail_db;
576 else if (head.header_size != (int) sizeof (head))
578 msg = _("header size does not match");
579 goto fail_db;
581 else if ((total = (sizeof (head)
582 + roundup (head.module * sizeof (ref_t),
583 ALIGN)
584 + head.data_size))
585 > st.st_size
586 || total < sizeof (head))
588 msg = _("file size does not match");
589 goto fail_db;
591 /* Note we map with the maximum size allowed for the
592 database. This is likely much larger than the
593 actual file size. This is OK on most OSes since
594 extensions of the underlying file will
595 automatically translate more pages available for
596 memory access. */
597 else if ((mem = mmap (NULL, dbs[cnt].max_db_size,
598 PROT_READ | PROT_WRITE,
599 MAP_SHARED, fd, 0))
600 == MAP_FAILED)
601 goto fail_db_errno;
602 else if (!verify_persistent_db (mem, &head, cnt))
604 munmap (mem, total);
605 msg = _("verification failed");
606 goto fail_db;
608 else
610 /* Success. We have the database. */
611 dbs[cnt].head = mem;
612 dbs[cnt].memsize = total;
613 dbs[cnt].data = (char *)
614 &dbs[cnt].head->array[roundup (dbs[cnt].head->module,
615 ALIGN / sizeof (ref_t))];
616 dbs[cnt].mmap_used = true;
618 if (dbs[cnt].suggested_module > head.module)
619 dbg_log (_("suggested size of table for database %s larger than the persistent database's table"),
620 dbnames[cnt]);
622 dbs[cnt].wr_fd = fd;
623 fd = -1;
624 /* We also need a read-only descriptor. */
625 if (dbs[cnt].shared)
627 dbs[cnt].ro_fd = open (dbs[cnt].db_filename,
628 O_RDONLY | EXTRA_O_FLAGS);
629 if (dbs[cnt].ro_fd == -1)
630 dbg_log (_("\
631 cannot create read-only descriptor for \"%s\"; no mmap"),
632 dbs[cnt].db_filename);
635 // XXX Shall we test whether the descriptors actually
636 // XXX point to the same file?
639 /* Close the file descriptors in case something went
640 wrong in which case the variable have not been
641 assigned -1. */
642 if (fd != -1)
643 close (fd);
645 else if (errno == EACCES)
646 error (EXIT_FAILURE, 0, _("cannot access '%s'"),
647 dbs[cnt].db_filename);
650 if (dbs[cnt].head == NULL)
652 /* No database loaded. Allocate the data structure,
653 possibly on disk. */
654 struct database_pers_head head;
655 size_t total = (sizeof (head)
656 + roundup (dbs[cnt].suggested_module
657 * sizeof (ref_t), ALIGN)
658 + (dbs[cnt].suggested_module
659 * DEFAULT_DATASIZE_PER_BUCKET));
661 /* Try to create the database. If we do not need a
662 persistent database create a temporary file. */
663 int fd;
664 int ro_fd = -1;
665 if (dbs[cnt].persistent)
667 fd = open (dbs[cnt].db_filename,
668 O_RDWR | O_CREAT | O_EXCL | O_TRUNC | EXTRA_O_FLAGS,
669 S_IRUSR | S_IWUSR);
670 if (fd != -1 && dbs[cnt].shared)
671 ro_fd = open (dbs[cnt].db_filename,
672 O_RDONLY | EXTRA_O_FLAGS);
674 else
676 char fname[] = _PATH_NSCD_XYZ_DB_TMP;
677 fd = mkostemp (fname, EXTRA_O_FLAGS);
679 /* We do not need the file name anymore after we
680 opened another file descriptor in read-only mode. */
681 if (fd != -1)
683 if (dbs[cnt].shared)
684 ro_fd = open (fname, O_RDONLY | EXTRA_O_FLAGS);
686 unlink (fname);
690 if (fd == -1)
692 if (errno == EEXIST)
694 dbg_log (_("database for %s corrupted or simultaneously used; remove %s manually if necessary and restart"),
695 dbnames[cnt], dbs[cnt].db_filename);
696 // XXX Correct way to terminate?
697 exit (1);
700 if (dbs[cnt].persistent)
701 dbg_log (_("cannot create %s; no persistent database used"),
702 dbs[cnt].db_filename);
703 else
704 dbg_log (_("cannot create %s; no sharing possible"),
705 dbs[cnt].db_filename);
707 dbs[cnt].persistent = 0;
708 // XXX remember: no mmap
710 else
712 /* Tell the user if we could not create the read-only
713 descriptor. */
714 if (ro_fd == -1 && dbs[cnt].shared)
715 dbg_log (_("\
716 cannot create read-only descriptor for \"%s\"; no mmap"),
717 dbs[cnt].db_filename);
719 /* Before we create the header, initialiye the hash
720 table. So that if we get interrupted if writing
721 the header we can recognize a partially initialized
722 database. */
723 size_t ps = sysconf (_SC_PAGESIZE);
724 char tmpbuf[ps];
725 assert (~ENDREF == 0);
726 memset (tmpbuf, '\xff', ps);
728 size_t remaining = dbs[cnt].suggested_module * sizeof (ref_t);
729 off_t offset = sizeof (head);
731 size_t towrite;
732 if (offset % ps != 0)
734 towrite = MIN (remaining, ps - (offset % ps));
735 if (pwrite (fd, tmpbuf, towrite, offset) != towrite)
736 goto write_fail;
737 offset += towrite;
738 remaining -= towrite;
741 while (remaining > ps)
743 if (pwrite (fd, tmpbuf, ps, offset) == -1)
744 goto write_fail;
745 offset += ps;
746 remaining -= ps;
749 if (remaining > 0
750 && pwrite (fd, tmpbuf, remaining, offset) != remaining)
751 goto write_fail;
753 /* Create the header of the file. */
754 struct database_pers_head head =
756 .version = DB_VERSION,
757 .header_size = sizeof (head),
758 .module = dbs[cnt].suggested_module,
759 .data_size = (dbs[cnt].suggested_module
760 * DEFAULT_DATASIZE_PER_BUCKET),
761 .first_free = 0
763 void *mem;
765 if ((TEMP_FAILURE_RETRY (write (fd, &head, sizeof (head)))
766 != sizeof (head))
767 || (TEMP_FAILURE_RETRY_VAL (posix_fallocate (fd, 0, total))
768 != 0)
769 || (mem = mmap (NULL, dbs[cnt].max_db_size,
770 PROT_READ | PROT_WRITE,
771 MAP_SHARED, fd, 0)) == MAP_FAILED)
773 write_fail:
774 unlink (dbs[cnt].db_filename);
775 dbg_log (_("cannot write to database file %s: %s"),
776 dbs[cnt].db_filename, strerror (errno));
777 dbs[cnt].persistent = 0;
779 else
781 /* Success. */
782 dbs[cnt].head = mem;
783 dbs[cnt].data = (char *)
784 &dbs[cnt].head->array[roundup (dbs[cnt].head->module,
785 ALIGN / sizeof (ref_t))];
786 dbs[cnt].memsize = total;
787 dbs[cnt].mmap_used = true;
789 /* Remember the descriptors. */
790 dbs[cnt].wr_fd = fd;
791 dbs[cnt].ro_fd = ro_fd;
792 fd = -1;
793 ro_fd = -1;
796 if (fd != -1)
797 close (fd);
798 if (ro_fd != -1)
799 close (ro_fd);
803 #if !defined O_CLOEXEC || !defined __ASSUME_O_CLOEXEC
804 /* We do not check here whether the O_CLOEXEC provided to the
805 open call was successful or not. The two fcntl calls are
806 only performed once each per process start-up and therefore
807 is not noticeable at all. */
808 if (paranoia
809 && ((dbs[cnt].wr_fd != -1
810 && fcntl (dbs[cnt].wr_fd, F_SETFD, FD_CLOEXEC) == -1)
811 || (dbs[cnt].ro_fd != -1
812 && fcntl (dbs[cnt].ro_fd, F_SETFD, FD_CLOEXEC) == -1)))
814 dbg_log (_("\
815 cannot set socket to close on exec: %s; disabling paranoia mode"),
816 strerror (errno));
817 paranoia = 0;
819 #endif
821 if (dbs[cnt].head == NULL)
823 /* We do not use the persistent database. Just
824 create an in-memory data structure. */
825 assert (! dbs[cnt].persistent);
827 dbs[cnt].head = xmalloc (sizeof (struct database_pers_head)
828 + (dbs[cnt].suggested_module
829 * sizeof (ref_t)));
830 memset (dbs[cnt].head, '\0', sizeof (struct database_pers_head));
831 assert (~ENDREF == 0);
832 memset (dbs[cnt].head->array, '\xff',
833 dbs[cnt].suggested_module * sizeof (ref_t));
834 dbs[cnt].head->module = dbs[cnt].suggested_module;
835 dbs[cnt].head->data_size = (DEFAULT_DATASIZE_PER_BUCKET
836 * dbs[cnt].head->module);
837 dbs[cnt].data = xmalloc (dbs[cnt].head->data_size);
838 dbs[cnt].head->first_free = 0;
840 dbs[cnt].shared = 0;
841 assert (dbs[cnt].ro_fd == -1);
844 dbs[cnt].inotify_descr = -1;
845 if (dbs[cnt].check_file)
847 #ifdef HAVE_INOTIFY
848 if (inotify_fd < 0
849 || (dbs[cnt].inotify_descr
850 = inotify_add_watch (inotify_fd, dbs[cnt].filename,
851 IN_DELETE_SELF | IN_MODIFY)) < 0)
852 /* We cannot notice changes in the main thread. */
853 #endif
855 /* We need the modification date of the file. */
856 struct stat64 st;
858 if (stat64 (dbs[cnt].filename, &st) < 0)
860 /* We cannot stat() the file, disable file checking. */
861 dbg_log (_("cannot stat() file `%s': %s"),
862 dbs[cnt].filename, strerror (errno));
863 dbs[cnt].check_file = 0;
865 else
866 dbs[cnt].file_mtime = st.st_mtime;
870 #ifdef HAVE_INOTIFY
871 if (cnt == hstdb && inotify_fd >= -1)
872 /* We also monitor the resolver configuration file. */
873 resolv_conf_descr = inotify_add_watch (inotify_fd,
874 _PATH_RESCONF,
875 IN_DELETE_SELF | IN_MODIFY);
876 #endif
879 /* Create the socket. */
880 #ifndef __ASSUME_SOCK_CLOEXEC
881 sock = -1;
882 if (have_sock_cloexec >= 0)
883 #endif
885 sock = socket (AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);
886 #ifndef __ASSUME_SOCK_CLOEXEC
887 if (have_sock_cloexec == 0)
888 have_sock_cloexec = sock != -1 || errno != EINVAL ? 1 : -1;
889 #endif
891 #ifndef __ASSUME_SOCK_CLOEXEC
892 if (have_sock_cloexec < 0)
893 sock = socket (AF_UNIX, SOCK_STREAM, 0);
894 #endif
895 if (sock < 0)
897 dbg_log (_("cannot open socket: %s"), strerror (errno));
898 exit (errno == EACCES ? 4 : 1);
900 /* Bind a name to the socket. */
901 struct sockaddr_un sock_addr;
902 sock_addr.sun_family = AF_UNIX;
903 strcpy (sock_addr.sun_path, _PATH_NSCDSOCKET);
904 if (bind (sock, (struct sockaddr *) &sock_addr, sizeof (sock_addr)) < 0)
906 dbg_log ("%s: %s", _PATH_NSCDSOCKET, strerror (errno));
907 exit (errno == EACCES ? 4 : 1);
910 #ifndef __ASSUME_SOCK_CLOEXEC
911 if (have_sock_cloexec < 0)
913 /* We don't want to get stuck on accept. */
914 int fl = fcntl (sock, F_GETFL);
915 if (fl == -1 || fcntl (sock, F_SETFL, fl | O_NONBLOCK) == -1)
917 dbg_log (_("cannot change socket to nonblocking mode: %s"),
918 strerror (errno));
919 exit (1);
922 /* The descriptor needs to be closed on exec. */
923 if (paranoia && fcntl (sock, F_SETFD, FD_CLOEXEC) == -1)
925 dbg_log (_("cannot set socket to close on exec: %s"),
926 strerror (errno));
927 exit (1);
930 #endif
932 /* Set permissions for the socket. */
933 chmod (_PATH_NSCDSOCKET, DEFFILEMODE);
935 /* Set the socket up to accept connections. */
936 if (listen (sock, SOMAXCONN) < 0)
938 dbg_log (_("cannot enable socket to accept connections: %s"),
939 strerror (errno));
940 exit (1);
943 /* Change to unprivileged uid/gid/groups if specifed in config file */
944 if (server_user != NULL)
945 finish_drop_privileges ();
949 /* Close the connections. */
950 void
951 close_sockets (void)
953 close (sock);
957 static void
958 invalidate_cache (char *key, int fd)
960 dbtype number;
961 int32_t resp;
963 for (number = pwddb; number < lastdb; ++number)
964 if (strcmp (key, dbnames[number]) == 0)
966 if (dbs[number].reset_res)
967 res_init ();
969 break;
972 if (number == lastdb)
974 resp = EINVAL;
975 writeall (fd, &resp, sizeof (resp));
976 return;
979 if (dbs[number].enabled)
981 pthread_mutex_lock (&dbs[number].prune_run_lock);
982 prune_cache (&dbs[number], LONG_MAX, fd);
983 pthread_mutex_unlock (&dbs[number].prune_run_lock);
985 else
987 resp = 0;
988 writeall (fd, &resp, sizeof (resp));
993 #ifdef SCM_RIGHTS
994 static void
995 send_ro_fd (struct database_dyn *db, char *key, int fd)
997 /* If we do not have an read-only file descriptor do nothing. */
998 if (db->ro_fd == -1)
999 return;
1001 /* We need to send some data along with the descriptor. */
1002 uint64_t mapsize = (db->head->data_size
1003 + roundup (db->head->module * sizeof (ref_t), ALIGN)
1004 + sizeof (struct database_pers_head));
1005 struct iovec iov[2];
1006 iov[0].iov_base = key;
1007 iov[0].iov_len = strlen (key) + 1;
1008 iov[1].iov_base = &mapsize;
1009 iov[1].iov_len = sizeof (mapsize);
1011 /* Prepare the control message to transfer the descriptor. */
1012 union
1014 struct cmsghdr hdr;
1015 char bytes[CMSG_SPACE (sizeof (int))];
1016 } buf;
1017 struct msghdr msg = { .msg_iov = iov, .msg_iovlen = 2,
1018 .msg_control = buf.bytes,
1019 .msg_controllen = sizeof (buf) };
1020 struct cmsghdr *cmsg = CMSG_FIRSTHDR (&msg);
1022 cmsg->cmsg_level = SOL_SOCKET;
1023 cmsg->cmsg_type = SCM_RIGHTS;
1024 cmsg->cmsg_len = CMSG_LEN (sizeof (int));
1026 *(int *) CMSG_DATA (cmsg) = db->ro_fd;
1028 msg.msg_controllen = cmsg->cmsg_len;
1030 /* Send the control message. We repeat when we are interrupted but
1031 everything else is ignored. */
1032 #ifndef MSG_NOSIGNAL
1033 # define MSG_NOSIGNAL 0
1034 #endif
1035 (void) TEMP_FAILURE_RETRY (sendmsg (fd, &msg, MSG_NOSIGNAL));
1037 if (__builtin_expect (debug_level > 0, 0))
1038 dbg_log (_("provide access to FD %d, for %s"), db->ro_fd, key);
1040 #endif /* SCM_RIGHTS */
1043 /* Handle new request. */
1044 static void
1045 handle_request (int fd, request_header *req, void *key, uid_t uid, pid_t pid)
1047 if (__builtin_expect (req->version, NSCD_VERSION) != NSCD_VERSION)
1049 if (debug_level > 0)
1050 dbg_log (_("\
1051 cannot handle old request version %d; current version is %d"),
1052 req->version, NSCD_VERSION);
1053 return;
1056 /* Perform the SELinux check before we go on to the standard checks. */
1057 if (selinux_enabled && nscd_request_avc_has_perm (fd, req->type) != 0)
1059 if (debug_level > 0)
1061 #ifdef SO_PEERCRED
1062 # ifdef PATH_MAX
1063 char buf[PATH_MAX];
1064 # else
1065 char buf[4096];
1066 # endif
1068 snprintf (buf, sizeof (buf), "/proc/%ld/exe", (long int) pid);
1069 ssize_t n = readlink (buf, buf, sizeof (buf) - 1);
1071 if (n <= 0)
1072 dbg_log (_("\
1073 request from %ld not handled due to missing permission"), (long int) pid);
1074 else
1076 buf[n] = '\0';
1077 dbg_log (_("\
1078 request from '%s' [%ld] not handled due to missing permission"),
1079 buf, (long int) pid);
1081 #else
1082 dbg_log (_("request not handled due to missing permission"));
1083 #endif
1085 return;
1088 struct database_dyn *db = reqinfo[req->type].db;
1090 /* See whether we can service the request from the cache. */
1091 if (__builtin_expect (reqinfo[req->type].data_request, true))
1093 if (__builtin_expect (debug_level, 0) > 0)
1095 if (req->type == GETHOSTBYADDR || req->type == GETHOSTBYADDRv6)
1097 char buf[INET6_ADDRSTRLEN];
1099 dbg_log ("\t%s (%s)", serv2str[req->type],
1100 inet_ntop (req->type == GETHOSTBYADDR
1101 ? AF_INET : AF_INET6,
1102 key, buf, sizeof (buf)));
1104 else
1105 dbg_log ("\t%s (%s)", serv2str[req->type], (char *) key);
1108 /* Is this service enabled? */
1109 if (__builtin_expect (!db->enabled, 0))
1111 /* No, sent the prepared record. */
1112 if (TEMP_FAILURE_RETRY (send (fd, db->disabled_iov->iov_base,
1113 db->disabled_iov->iov_len,
1114 MSG_NOSIGNAL))
1115 != (ssize_t) db->disabled_iov->iov_len
1116 && __builtin_expect (debug_level, 0) > 0)
1118 /* We have problems sending the result. */
1119 char buf[256];
1120 dbg_log (_("cannot write result: %s"),
1121 strerror_r (errno, buf, sizeof (buf)));
1124 return;
1127 /* Be sure we can read the data. */
1128 if (__builtin_expect (pthread_rwlock_tryrdlock (&db->lock) != 0, 0))
1130 ++db->head->rdlockdelayed;
1131 pthread_rwlock_rdlock (&db->lock);
1134 /* See whether we can handle it from the cache. */
1135 struct datahead *cached;
1136 cached = (struct datahead *) cache_search (req->type, key, req->key_len,
1137 db, uid);
1138 if (cached != NULL)
1140 /* Hurray it's in the cache. */
1141 ssize_t nwritten;
1143 #ifdef HAVE_SENDFILE
1144 if (__builtin_expect (db->mmap_used, 1))
1146 assert (db->wr_fd != -1);
1147 assert ((char *) cached->data > (char *) db->data);
1148 assert ((char *) cached->data - (char *) db->head
1149 + cached->recsize
1150 <= (sizeof (struct database_pers_head)
1151 + db->head->module * sizeof (ref_t)
1152 + db->head->data_size));
1153 nwritten = sendfileall (fd, db->wr_fd,
1154 (char *) cached->data
1155 - (char *) db->head, cached->recsize);
1156 # ifndef __ASSUME_SENDFILE
1157 if (nwritten == -1 && errno == ENOSYS)
1158 goto use_write;
1159 # endif
1161 else
1162 # ifndef __ASSUME_SENDFILE
1163 use_write:
1164 # endif
1165 #endif
1166 nwritten = writeall (fd, cached->data, cached->recsize);
1168 if (nwritten != cached->recsize
1169 && __builtin_expect (debug_level, 0) > 0)
1171 /* We have problems sending the result. */
1172 char buf[256];
1173 dbg_log (_("cannot write result: %s"),
1174 strerror_r (errno, buf, sizeof (buf)));
1177 pthread_rwlock_unlock (&db->lock);
1179 return;
1182 pthread_rwlock_unlock (&db->lock);
1184 else if (__builtin_expect (debug_level, 0) > 0)
1186 if (req->type == INVALIDATE)
1187 dbg_log ("\t%s (%s)", serv2str[req->type], (char *) key);
1188 else
1189 dbg_log ("\t%s", serv2str[req->type]);
1192 /* Handle the request. */
1193 switch (req->type)
1195 case GETPWBYNAME:
1196 addpwbyname (db, fd, req, key, uid);
1197 break;
1199 case GETPWBYUID:
1200 addpwbyuid (db, fd, req, key, uid);
1201 break;
1203 case GETGRBYNAME:
1204 addgrbyname (db, fd, req, key, uid);
1205 break;
1207 case GETGRBYGID:
1208 addgrbygid (db, fd, req, key, uid);
1209 break;
1211 case GETHOSTBYNAME:
1212 addhstbyname (db, fd, req, key, uid);
1213 break;
1215 case GETHOSTBYNAMEv6:
1216 addhstbynamev6 (db, fd, req, key, uid);
1217 break;
1219 case GETHOSTBYADDR:
1220 addhstbyaddr (db, fd, req, key, uid);
1221 break;
1223 case GETHOSTBYADDRv6:
1224 addhstbyaddrv6 (db, fd, req, key, uid);
1225 break;
1227 case GETAI:
1228 addhstai (db, fd, req, key, uid);
1229 break;
1231 case INITGROUPS:
1232 addinitgroups (db, fd, req, key, uid);
1233 break;
1235 case GETSERVBYNAME:
1236 addservbyname (db, fd, req, key, uid);
1237 break;
1239 case GETSERVBYPORT:
1240 addservbyport (db, fd, req, key, uid);
1241 break;
1243 case GETSTAT:
1244 case SHUTDOWN:
1245 case INVALIDATE:
1247 /* Get the callers credentials. */
1248 #ifdef SO_PEERCRED
1249 struct ucred caller;
1250 socklen_t optlen = sizeof (caller);
1252 if (getsockopt (fd, SOL_SOCKET, SO_PEERCRED, &caller, &optlen) < 0)
1254 char buf[256];
1256 dbg_log (_("error getting caller's id: %s"),
1257 strerror_r (errno, buf, sizeof (buf)));
1258 break;
1261 uid = caller.uid;
1262 #else
1263 /* Some systems have no SO_PEERCRED implementation. They don't
1264 care about security so we don't as well. */
1265 uid = 0;
1266 #endif
1269 /* Accept shutdown, getstat and invalidate only from root. For
1270 the stat call also allow the user specified in the config file. */
1271 if (req->type == GETSTAT)
1273 if (uid == 0 || uid == stat_uid)
1274 send_stats (fd, dbs);
1276 else if (uid == 0)
1278 if (req->type == INVALIDATE)
1279 invalidate_cache (key, fd);
1280 else
1281 termination_handler (0);
1283 break;
1285 case GETFDPW:
1286 case GETFDGR:
1287 case GETFDHST:
1288 case GETFDSERV:
1289 #ifdef SCM_RIGHTS
1290 send_ro_fd (reqinfo[req->type].db, key, fd);
1291 #endif
1292 break;
1294 default:
1295 /* Ignore the command, it's nothing we know. */
1296 break;
1301 /* Restart the process. */
1302 static void
1303 restart (void)
1305 /* First determine the parameters. We do not use the parameters
1306 passed to main() since in case nscd is started by running the
1307 dynamic linker this will not work. Yes, this is not the usual
1308 case but nscd is part of glibc and we occasionally do this. */
1309 size_t buflen = 1024;
1310 char *buf = alloca (buflen);
1311 size_t readlen = 0;
1312 int fd = open ("/proc/self/cmdline", O_RDONLY);
1313 if (fd == -1)
1315 dbg_log (_("\
1316 cannot open /proc/self/cmdline: %s; disabling paranoia mode"),
1317 strerror (errno));
1319 paranoia = 0;
1320 return;
1323 while (1)
1325 ssize_t n = TEMP_FAILURE_RETRY (read (fd, buf + readlen,
1326 buflen - readlen));
1327 if (n == -1)
1329 dbg_log (_("\
1330 cannot read /proc/self/cmdline: %s; disabling paranoia mode"),
1331 strerror (errno));
1333 close (fd);
1334 paranoia = 0;
1335 return;
1338 readlen += n;
1340 if (readlen < buflen)
1341 break;
1343 /* We might have to extend the buffer. */
1344 size_t old_buflen = buflen;
1345 char *newp = extend_alloca (buf, buflen, 2 * buflen);
1346 buf = memmove (newp, buf, old_buflen);
1349 close (fd);
1351 /* Parse the command line. Worst case scenario: every two
1352 characters form one parameter (one character plus NUL). */
1353 char **argv = alloca ((readlen / 2 + 1) * sizeof (argv[0]));
1354 int argc = 0;
1356 char *cp = buf;
1357 while (cp < buf + readlen)
1359 argv[argc++] = cp;
1360 cp = (char *) rawmemchr (cp, '\0') + 1;
1362 argv[argc] = NULL;
1364 /* Second, change back to the old user if we changed it. */
1365 if (server_user != NULL)
1367 if (setresuid (old_uid, old_uid, old_uid) != 0)
1369 dbg_log (_("\
1370 cannot change to old UID: %s; disabling paranoia mode"),
1371 strerror (errno));
1373 paranoia = 0;
1374 return;
1377 if (setresgid (old_gid, old_gid, old_gid) != 0)
1379 dbg_log (_("\
1380 cannot change to old GID: %s; disabling paranoia mode"),
1381 strerror (errno));
1383 setuid (server_uid);
1384 paranoia = 0;
1385 return;
1389 /* Next change back to the old working directory. */
1390 if (chdir (oldcwd) == -1)
1392 dbg_log (_("\
1393 cannot change to old working directory: %s; disabling paranoia mode"),
1394 strerror (errno));
1396 if (server_user != NULL)
1398 setuid (server_uid);
1399 setgid (server_gid);
1401 paranoia = 0;
1402 return;
1405 /* Synchronize memory. */
1406 int32_t certainly[lastdb];
1407 for (int cnt = 0; cnt < lastdb; ++cnt)
1408 if (dbs[cnt].enabled)
1410 /* Make sure nobody keeps using the database. */
1411 dbs[cnt].head->timestamp = 0;
1412 certainly[cnt] = dbs[cnt].head->nscd_certainly_running;
1413 dbs[cnt].head->nscd_certainly_running = 0;
1415 if (dbs[cnt].persistent)
1416 // XXX async OK?
1417 msync (dbs[cnt].head, dbs[cnt].memsize, MS_ASYNC);
1420 /* The preparations are done. */
1421 execv ("/proc/self/exe", argv);
1423 /* If we come here, we will never be able to re-exec. */
1424 dbg_log (_("re-exec failed: %s; disabling paranoia mode"),
1425 strerror (errno));
1427 if (server_user != NULL)
1429 setuid (server_uid);
1430 setgid (server_gid);
1432 if (chdir ("/") != 0)
1433 dbg_log (_("cannot change current working directory to \"/\": %s"),
1434 strerror (errno));
1435 paranoia = 0;
1437 /* Reenable the databases. */
1438 time_t now = time (NULL);
1439 for (int cnt = 0; cnt < lastdb; ++cnt)
1440 if (dbs[cnt].enabled)
1442 dbs[cnt].head->timestamp = now;
1443 dbs[cnt].head->nscd_certainly_running = certainly[cnt];
1448 /* List of file descriptors. */
1449 struct fdlist
1451 int fd;
1452 struct fdlist *next;
1454 /* Memory allocated for the list. */
1455 static struct fdlist *fdlist;
1456 /* List of currently ready-to-read file descriptors. */
1457 static struct fdlist *readylist;
1459 /* Conditional variable and mutex to signal availability of entries in
1460 READYLIST. The condvar is initialized dynamically since we might
1461 use a different clock depending on availability. */
1462 static pthread_cond_t readylist_cond = PTHREAD_COND_INITIALIZER;
1463 static pthread_mutex_t readylist_lock = PTHREAD_MUTEX_INITIALIZER;
1465 /* The clock to use with the condvar. */
1466 static clockid_t timeout_clock = CLOCK_REALTIME;
1468 /* Number of threads ready to handle the READYLIST. */
1469 static unsigned long int nready;
1472 /* Function for the clean-up threads. */
1473 static void *
1474 __attribute__ ((__noreturn__))
1475 nscd_run_prune (void *p)
1477 const long int my_number = (long int) p;
1478 assert (dbs[my_number].enabled);
1480 int dont_need_update = setup_thread (&dbs[my_number]);
1482 time_t now = time (NULL);
1484 /* We are running. */
1485 dbs[my_number].head->timestamp = now;
1487 struct timespec prune_ts;
1488 if (__builtin_expect (clock_gettime (timeout_clock, &prune_ts) == -1, 0))
1489 /* Should never happen. */
1490 abort ();
1492 /* Compute the initial timeout time. Prevent all the timers to go
1493 off at the same time by adding a db-based value. */
1494 prune_ts.tv_sec += CACHE_PRUNE_INTERVAL + my_number;
1495 dbs[my_number].wakeup_time = now + CACHE_PRUNE_INTERVAL + my_number;
1497 pthread_mutex_t *prune_lock = &dbs[my_number].prune_lock;
1498 pthread_mutex_t *prune_run_lock = &dbs[my_number].prune_run_lock;
1499 pthread_cond_t *prune_cond = &dbs[my_number].prune_cond;
1501 pthread_mutex_lock (prune_lock);
1502 while (1)
1504 /* Wait, but not forever. */
1505 int e = 0;
1506 if (! dbs[my_number].clear_cache)
1507 e = pthread_cond_timedwait (prune_cond, prune_lock, &prune_ts);
1508 assert (__builtin_expect (e == 0 || e == ETIMEDOUT, 1));
1510 time_t next_wait;
1511 now = time (NULL);
1512 if (e == ETIMEDOUT || now >= dbs[my_number].wakeup_time
1513 || dbs[my_number].clear_cache)
1515 /* We will determine the new timout values based on the
1516 cache content. Should there be concurrent additions to
1517 the cache which are not accounted for in the cache
1518 pruning we want to know about it. Therefore set the
1519 timeout to the maximum. It will be descreased when adding
1520 new entries to the cache, if necessary. */
1521 if (sizeof (time_t) == sizeof (long int))
1522 dbs[my_number].wakeup_time = LONG_MAX;
1523 else
1524 dbs[my_number].wakeup_time = INT_MAX;
1526 /* Unconditionally reset the flag. */
1527 time_t prune_now = dbs[my_number].clear_cache ? LONG_MAX : now;
1528 dbs[my_number].clear_cache = 0;
1530 pthread_mutex_unlock (prune_lock);
1532 /* We use a separate lock for running the prune function (instead
1533 of keeping prune_lock locked) because this enables concurrent
1534 invocations of cache_add which might modify the timeout value. */
1535 pthread_mutex_lock (prune_run_lock);
1536 next_wait = prune_cache (&dbs[my_number], prune_now, -1);
1537 pthread_mutex_unlock (prune_run_lock);
1539 next_wait = MAX (next_wait, CACHE_PRUNE_INTERVAL);
1540 /* If clients cannot determine for sure whether nscd is running
1541 we need to wake up occasionally to update the timestamp.
1542 Wait 90% of the update period. */
1543 #define UPDATE_MAPPING_TIMEOUT (MAPPING_TIMEOUT * 9 / 10)
1544 if (__builtin_expect (! dont_need_update, 0))
1546 next_wait = MIN (UPDATE_MAPPING_TIMEOUT, next_wait);
1547 dbs[my_number].head->timestamp = now;
1550 pthread_mutex_lock (prune_lock);
1552 /* Make it known when we will wake up again. */
1553 if (now + next_wait < dbs[my_number].wakeup_time)
1554 dbs[my_number].wakeup_time = now + next_wait;
1555 else
1556 next_wait = dbs[my_number].wakeup_time - now;
1558 else
1559 /* The cache was just pruned. Do not do it again now. Just
1560 use the new timeout value. */
1561 next_wait = dbs[my_number].wakeup_time - now;
1563 if (clock_gettime (timeout_clock, &prune_ts) == -1)
1564 /* Should never happen. */
1565 abort ();
1567 /* Compute next timeout time. */
1568 prune_ts.tv_sec += next_wait;
1573 /* This is the main loop. It is replicated in different threads but
1574 the the use of the ready list makes sure only one thread handles an
1575 incoming connection. */
1576 static void *
1577 __attribute__ ((__noreturn__))
1578 nscd_run_worker (void *p)
1580 char buf[256];
1582 /* Initial locking. */
1583 pthread_mutex_lock (&readylist_lock);
1585 /* One more thread available. */
1586 ++nready;
1588 while (1)
1590 while (readylist == NULL)
1591 pthread_cond_wait (&readylist_cond, &readylist_lock);
1593 struct fdlist *it = readylist->next;
1594 if (readylist->next == readylist)
1595 /* Just one entry on the list. */
1596 readylist = NULL;
1597 else
1598 readylist->next = it->next;
1600 /* Extract the information and mark the record ready to be used
1601 again. */
1602 int fd = it->fd;
1603 it->next = NULL;
1605 /* One more thread available. */
1606 --nready;
1608 /* We are done with the list. */
1609 pthread_mutex_unlock (&readylist_lock);
1611 #ifndef __ASSUME_ACCEPT4
1612 if (have_accept4 < 0)
1614 /* We do not want to block on a short read or so. */
1615 int fl = fcntl (fd, F_GETFL);
1616 if (fl == -1 || fcntl (fd, F_SETFL, fl | O_NONBLOCK) == -1)
1617 goto close_and_out;
1619 #endif
1621 /* Now read the request. */
1622 request_header req;
1623 if (__builtin_expect (TEMP_FAILURE_RETRY (read (fd, &req, sizeof (req)))
1624 != sizeof (req), 0))
1626 /* We failed to read data. Note that this also might mean we
1627 failed because we would have blocked. */
1628 if (debug_level > 0)
1629 dbg_log (_("short read while reading request: %s"),
1630 strerror_r (errno, buf, sizeof (buf)));
1631 goto close_and_out;
1634 /* Check whether this is a valid request type. */
1635 if (req.type < GETPWBYNAME || req.type >= LASTREQ)
1636 goto close_and_out;
1638 /* Some systems have no SO_PEERCRED implementation. They don't
1639 care about security so we don't as well. */
1640 uid_t uid = -1;
1641 #ifdef SO_PEERCRED
1642 pid_t pid = 0;
1644 if (__builtin_expect (debug_level > 0, 0))
1646 struct ucred caller;
1647 socklen_t optlen = sizeof (caller);
1649 if (getsockopt (fd, SOL_SOCKET, SO_PEERCRED, &caller, &optlen) == 0)
1650 pid = caller.pid;
1652 #else
1653 const pid_t pid = 0;
1654 #endif
1656 /* It should not be possible to crash the nscd with a silly
1657 request (i.e., a terribly large key). We limit the size to 1kb. */
1658 if (__builtin_expect (req.key_len, 1) < 0
1659 || __builtin_expect (req.key_len, 1) > MAXKEYLEN)
1661 if (debug_level > 0)
1662 dbg_log (_("key length in request too long: %d"), req.key_len);
1664 else
1666 /* Get the key. */
1667 char keybuf[MAXKEYLEN];
1669 if (__builtin_expect (TEMP_FAILURE_RETRY (read (fd, keybuf,
1670 req.key_len))
1671 != req.key_len, 0))
1673 /* Again, this can also mean we would have blocked. */
1674 if (debug_level > 0)
1675 dbg_log (_("short read while reading request key: %s"),
1676 strerror_r (errno, buf, sizeof (buf)));
1677 goto close_and_out;
1680 if (__builtin_expect (debug_level, 0) > 0)
1682 #ifdef SO_PEERCRED
1683 if (pid != 0)
1684 dbg_log (_("\
1685 handle_request: request received (Version = %d) from PID %ld"),
1686 req.version, (long int) pid);
1687 else
1688 #endif
1689 dbg_log (_("\
1690 handle_request: request received (Version = %d)"), req.version);
1693 /* Phew, we got all the data, now process it. */
1694 handle_request (fd, &req, keybuf, uid, pid);
1697 close_and_out:
1698 /* We are done. */
1699 close (fd);
1701 /* Re-locking. */
1702 pthread_mutex_lock (&readylist_lock);
1704 /* One more thread available. */
1705 ++nready;
1710 static unsigned int nconns;
1712 static void
1713 fd_ready (int fd)
1715 pthread_mutex_lock (&readylist_lock);
1717 /* Find an empty entry in FDLIST. */
1718 size_t inner;
1719 for (inner = 0; inner < nconns; ++inner)
1720 if (fdlist[inner].next == NULL)
1721 break;
1722 assert (inner < nconns);
1724 fdlist[inner].fd = fd;
1726 if (readylist == NULL)
1727 readylist = fdlist[inner].next = &fdlist[inner];
1728 else
1730 fdlist[inner].next = readylist->next;
1731 readylist = readylist->next = &fdlist[inner];
1734 bool do_signal = true;
1735 if (__builtin_expect (nready == 0, 0))
1737 ++client_queued;
1738 do_signal = false;
1740 /* Try to start another thread to help out. */
1741 pthread_t th;
1742 if (nthreads < max_nthreads
1743 && pthread_create (&th, &attr, nscd_run_worker,
1744 (void *) (long int) nthreads) == 0)
1746 /* We got another thread. */
1747 ++nthreads;
1748 /* The new thread might need a kick. */
1749 do_signal = true;
1754 pthread_mutex_unlock (&readylist_lock);
1756 /* Tell one of the worker threads there is work to do. */
1757 if (do_signal)
1758 pthread_cond_signal (&readylist_cond);
1762 /* Check whether restarting should happen. */
1763 static inline int
1764 restart_p (time_t now)
1766 return (paranoia && readylist == NULL && nready == nthreads
1767 && now >= restart_time);
1771 /* Array for times a connection was accepted. */
1772 static time_t *starttime;
1775 static void
1776 __attribute__ ((__noreturn__))
1777 main_loop_poll (void)
1779 struct pollfd *conns = (struct pollfd *) xmalloc (nconns
1780 * sizeof (conns[0]));
1782 conns[0].fd = sock;
1783 conns[0].events = POLLRDNORM;
1784 size_t nused = 1;
1785 size_t firstfree = 1;
1787 #ifdef HAVE_INOTIFY
1788 if (inotify_fd != -1)
1790 conns[1].fd = inotify_fd;
1791 conns[1].events = POLLRDNORM;
1792 nused = 2;
1793 firstfree = 2;
1795 #endif
1797 while (1)
1799 /* Wait for any event. We wait at most a couple of seconds so
1800 that we can check whether we should close any of the accepted
1801 connections since we have not received a request. */
1802 #define MAX_ACCEPT_TIMEOUT 30
1803 #define MIN_ACCEPT_TIMEOUT 5
1804 #define MAIN_THREAD_TIMEOUT \
1805 (MAX_ACCEPT_TIMEOUT * 1000 \
1806 - ((MAX_ACCEPT_TIMEOUT - MIN_ACCEPT_TIMEOUT) * 1000 * nused) / (2 * nconns))
1808 int n = poll (conns, nused, MAIN_THREAD_TIMEOUT);
1810 time_t now = time (NULL);
1812 /* If there is a descriptor ready for reading or there is a new
1813 connection, process this now. */
1814 if (n > 0)
1816 if (conns[0].revents != 0)
1818 /* We have a new incoming connection. Accept the connection. */
1819 int fd;
1821 #ifndef __ASSUME_ACCEPT4
1822 fd = -1;
1823 if (have_accept4 >= 0)
1824 #endif
1826 fd = TEMP_FAILURE_RETRY (accept4 (sock, NULL, NULL,
1827 SOCK_NONBLOCK));
1828 #ifndef __ASSUME_ACCEPT4
1829 if (have_accept4 == 0)
1830 have_accept4 = fd != -1 || errno != ENOSYS ? 1 : -1;
1831 #endif
1833 #ifndef __ASSUME_ACCEPT4
1834 if (have_accept4 < 0)
1835 fd = TEMP_FAILURE_RETRY (accept (sock, NULL, NULL));
1836 #endif
1838 /* Use the descriptor if we have not reached the limit. */
1839 if (fd >= 0)
1841 if (firstfree < nconns)
1843 conns[firstfree].fd = fd;
1844 conns[firstfree].events = POLLRDNORM;
1845 starttime[firstfree] = now;
1846 if (firstfree >= nused)
1847 nused = firstfree + 1;
1850 ++firstfree;
1851 while (firstfree < nused && conns[firstfree].fd != -1);
1853 else
1854 /* We cannot use the connection so close it. */
1855 close (fd);
1858 --n;
1861 size_t first = 1;
1862 #ifdef HAVE_INOTIFY
1863 if (inotify_fd != -1 && conns[1].fd == inotify_fd)
1865 if (conns[1].revents != 0)
1867 bool to_clear[lastdb] = { false, };
1868 union
1870 # ifndef PATH_MAX
1871 # define PATH_MAX 1024
1872 # endif
1873 struct inotify_event i;
1874 char buf[sizeof (struct inotify_event) + PATH_MAX];
1875 } inev;
1877 while (1)
1879 ssize_t nb = TEMP_FAILURE_RETRY (read (inotify_fd, &inev,
1880 sizeof (inev)));
1881 if (nb < (ssize_t) sizeof (struct inotify_event))
1883 if (__builtin_expect (nb == -1 && errno != EAGAIN,
1886 /* Something went wrong when reading the inotify
1887 data. Better disable inotify. */
1888 dbg_log (_("\
1889 disabled inotify after read error %d"),
1890 errno);
1891 conns[1].fd = -1;
1892 firstfree = 1;
1893 if (nused == 2)
1894 nused = 1;
1895 close (inotify_fd);
1896 inotify_fd = -1;
1898 break;
1901 /* Check which of the files changed. */
1902 for (size_t dbcnt = 0; dbcnt < lastdb; ++dbcnt)
1903 if (inev.i.wd == dbs[dbcnt].inotify_descr)
1905 to_clear[dbcnt] = true;
1906 goto next;
1909 if (inev.i.wd == resolv_conf_descr)
1911 res_init ();
1912 to_clear[hstdb] = true;
1914 next:;
1917 /* Actually perform the cache clearing. */
1918 for (size_t dbcnt = 0; dbcnt < lastdb; ++dbcnt)
1919 if (to_clear[dbcnt])
1921 pthread_mutex_lock (&dbs[dbcnt].prune_lock);
1922 dbs[dbcnt].clear_cache = 1;
1923 pthread_mutex_unlock (&dbs[dbcnt].prune_lock);
1924 pthread_cond_signal (&dbs[dbcnt].prune_cond);
1927 --n;
1930 first = 2;
1932 #endif
1934 for (size_t cnt = first; cnt < nused && n > 0; ++cnt)
1935 if (conns[cnt].revents != 0)
1937 fd_ready (conns[cnt].fd);
1939 /* Clean up the CONNS array. */
1940 conns[cnt].fd = -1;
1941 if (cnt < firstfree)
1942 firstfree = cnt;
1943 if (cnt == nused - 1)
1945 --nused;
1946 while (conns[nused - 1].fd == -1);
1948 --n;
1952 /* Now find entries which have timed out. */
1953 assert (nused > 0);
1955 /* We make the timeout length depend on the number of file
1956 descriptors currently used. */
1957 #define ACCEPT_TIMEOUT \
1958 (MAX_ACCEPT_TIMEOUT \
1959 - ((MAX_ACCEPT_TIMEOUT - MIN_ACCEPT_TIMEOUT) * nused) / nconns)
1960 time_t laststart = now - ACCEPT_TIMEOUT;
1962 for (size_t cnt = nused - 1; cnt > 0; --cnt)
1964 if (conns[cnt].fd != -1 && starttime[cnt] < laststart)
1966 /* Remove the entry, it timed out. */
1967 (void) close (conns[cnt].fd);
1968 conns[cnt].fd = -1;
1970 if (cnt < firstfree)
1971 firstfree = cnt;
1972 if (cnt == nused - 1)
1974 --nused;
1975 while (conns[nused - 1].fd == -1);
1979 if (restart_p (now))
1980 restart ();
1985 #ifdef HAVE_EPOLL
1986 static void
1987 main_loop_epoll (int efd)
1989 struct epoll_event ev = { 0, };
1990 int nused = 1;
1991 size_t highest = 0;
1993 /* Add the socket. */
1994 ev.events = EPOLLRDNORM;
1995 ev.data.fd = sock;
1996 if (epoll_ctl (efd, EPOLL_CTL_ADD, sock, &ev) == -1)
1997 /* We cannot use epoll. */
1998 return;
2000 # ifdef HAVE_INOTIFY
2001 if (inotify_fd != -1)
2003 ev.events = EPOLLRDNORM;
2004 ev.data.fd = inotify_fd;
2005 if (epoll_ctl (efd, EPOLL_CTL_ADD, inotify_fd, &ev) == -1)
2006 /* We cannot use epoll. */
2007 return;
2008 nused = 2;
2010 # endif
2012 while (1)
2014 struct epoll_event revs[100];
2015 # define nrevs (sizeof (revs) / sizeof (revs[0]))
2017 int n = epoll_wait (efd, revs, nrevs, MAIN_THREAD_TIMEOUT);
2019 time_t now = time (NULL);
2021 for (int cnt = 0; cnt < n; ++cnt)
2022 if (revs[cnt].data.fd == sock)
2024 /* A new connection. */
2025 int fd;
2027 # ifndef __ASSUME_ACCEPT4
2028 fd = -1;
2029 if (have_accept4 >= 0)
2030 # endif
2032 fd = TEMP_FAILURE_RETRY (accept4 (sock, NULL, NULL,
2033 SOCK_NONBLOCK));
2034 # ifndef __ASSUME_ACCEPT4
2035 if (have_accept4 == 0)
2036 have_accept4 = fd != -1 || errno != ENOSYS ? 1 : -1;
2037 # endif
2039 # ifndef __ASSUME_ACCEPT4
2040 if (have_accept4 < 0)
2041 fd = TEMP_FAILURE_RETRY (accept (sock, NULL, NULL));
2042 # endif
2044 /* Use the descriptor if we have not reached the limit. */
2045 if (fd >= 0)
2047 /* Try to add the new descriptor. */
2048 ev.data.fd = fd;
2049 if (fd >= nconns
2050 || epoll_ctl (efd, EPOLL_CTL_ADD, fd, &ev) == -1)
2051 /* The descriptor is too large or something went
2052 wrong. Close the descriptor. */
2053 close (fd);
2054 else
2056 /* Remember when we accepted the connection. */
2057 starttime[fd] = now;
2059 if (fd > highest)
2060 highest = fd;
2062 ++nused;
2066 # ifdef HAVE_INOTIFY
2067 else if (revs[cnt].data.fd == inotify_fd)
2069 bool to_clear[lastdb] = { false, };
2070 union
2072 struct inotify_event i;
2073 char buf[sizeof (struct inotify_event) + PATH_MAX];
2074 } inev;
2076 while (1)
2078 ssize_t nb = TEMP_FAILURE_RETRY (read (inotify_fd, &inev,
2079 sizeof (inev)));
2080 if (nb < (ssize_t) sizeof (struct inotify_event))
2082 if (__builtin_expect (nb == -1 && errno != EAGAIN, 0))
2084 /* Something went wrong when reading the inotify
2085 data. Better disable inotify. */
2086 dbg_log (_("disabled inotify after read error %d"),
2087 errno);
2088 (void) epoll_ctl (efd, EPOLL_CTL_DEL, inotify_fd,
2089 NULL);
2090 close (inotify_fd);
2091 inotify_fd = -1;
2093 break;
2096 /* Check which of the files changed. */
2097 for (size_t dbcnt = 0; dbcnt < lastdb; ++dbcnt)
2098 if (inev.i.wd == dbs[dbcnt].inotify_descr)
2100 to_clear[dbcnt] = true;
2101 goto next;
2104 if (inev.i.wd == resolv_conf_descr)
2106 res_init ();
2107 to_clear[hstdb] = true;
2109 next:;
2112 /* Actually perform the cache clearing. */
2113 for (size_t dbcnt = 0; dbcnt < lastdb; ++dbcnt)
2114 if (to_clear[dbcnt])
2116 pthread_mutex_lock (&dbs[dbcnt].prune_lock);
2117 dbs[dbcnt].clear_cache = 1;
2118 pthread_mutex_unlock (&dbs[dbcnt].prune_lock);
2119 pthread_cond_signal (&dbs[dbcnt].prune_cond);
2122 # endif
2123 else
2125 /* Remove the descriptor from the epoll descriptor. */
2126 (void) epoll_ctl (efd, EPOLL_CTL_DEL, revs[cnt].data.fd, NULL);
2128 /* Get a worker to handle the request. */
2129 fd_ready (revs[cnt].data.fd);
2131 /* Reset the time. */
2132 starttime[revs[cnt].data.fd] = 0;
2133 if (revs[cnt].data.fd == highest)
2135 --highest;
2136 while (highest > 0 && starttime[highest] == 0);
2138 --nused;
2141 /* Now look for descriptors for accepted connections which have
2142 no reply in too long of a time. */
2143 time_t laststart = now - ACCEPT_TIMEOUT;
2144 assert (starttime[sock] == 0);
2145 assert (inotify_fd == -1 || starttime[inotify_fd] == 0);
2146 for (int cnt = highest; cnt > STDERR_FILENO; --cnt)
2147 if (starttime[cnt] != 0 && starttime[cnt] < laststart)
2149 /* We are waiting for this one for too long. Close it. */
2150 (void) epoll_ctl (efd, EPOLL_CTL_DEL, cnt, NULL);
2152 (void) close (cnt);
2154 starttime[cnt] = 0;
2155 if (cnt == highest)
2156 --highest;
2158 else if (cnt != sock && starttime[cnt] == 0 && cnt == highest)
2159 --highest;
2161 if (restart_p (now))
2162 restart ();
2165 #endif
2168 /* Start all the threads we want. The initial process is thread no. 1. */
2169 void
2170 start_threads (void)
2172 /* Initialize the conditional variable we will use. The only
2173 non-standard attribute we might use is the clock selection. */
2174 pthread_condattr_t condattr;
2175 pthread_condattr_init (&condattr);
2177 #if defined _POSIX_CLOCK_SELECTION && _POSIX_CLOCK_SELECTION >= 0 \
2178 && defined _POSIX_MONOTONIC_CLOCK && _POSIX_MONOTONIC_CLOCK >= 0
2179 /* Determine whether the monotonous clock is available. */
2180 struct timespec dummy;
2181 # if _POSIX_MONOTONIC_CLOCK == 0
2182 if (sysconf (_SC_MONOTONIC_CLOCK) > 0)
2183 # endif
2184 # if _POSIX_CLOCK_SELECTION == 0
2185 if (sysconf (_SC_CLOCK_SELECTION) > 0)
2186 # endif
2187 if (clock_getres (CLOCK_MONOTONIC, &dummy) == 0
2188 && pthread_condattr_setclock (&condattr, CLOCK_MONOTONIC) == 0)
2189 timeout_clock = CLOCK_MONOTONIC;
2190 #endif
2192 /* Create the attribute for the threads. They are all created
2193 detached. */
2194 pthread_attr_init (&attr);
2195 pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
2196 /* Use 1MB stacks, twice as much for 64-bit architectures. */
2197 pthread_attr_setstacksize (&attr, NSCD_THREAD_STACKSIZE);
2199 /* We allow less than LASTDB threads only for debugging. */
2200 if (debug_level == 0)
2201 nthreads = MAX (nthreads, lastdb);
2203 /* Create the threads which prune the databases. */
2204 // XXX Ideally this work would be done by some of the worker threads.
2205 // XXX But this is problematic since we would need to be able to wake
2206 // XXX them up explicitly as well as part of the group handling the
2207 // XXX ready-list. This requires an operation where we can wait on
2208 // XXX two conditional variables at the same time. This operation
2209 // XXX does not exist (yet).
2210 for (long int i = 0; i < lastdb; ++i)
2212 /* Initialize the conditional variable. */
2213 if (pthread_cond_init (&dbs[i].prune_cond, &condattr) != 0)
2215 dbg_log (_("could not initialize conditional variable"));
2216 exit (1);
2219 pthread_t th;
2220 if (dbs[i].enabled
2221 && pthread_create (&th, &attr, nscd_run_prune, (void *) i) != 0)
2223 dbg_log (_("could not start clean-up thread; terminating"));
2224 exit (1);
2228 pthread_condattr_destroy (&condattr);
2230 for (long int i = 0; i < nthreads; ++i)
2232 pthread_t th;
2233 if (pthread_create (&th, &attr, nscd_run_worker, NULL) != 0)
2235 if (i == 0)
2237 dbg_log (_("could not start any worker thread; terminating"));
2238 exit (1);
2241 break;
2245 /* Determine how much room for descriptors we should initially
2246 allocate. This might need to change later if we cap the number
2247 with MAXCONN. */
2248 const long int nfds = sysconf (_SC_OPEN_MAX);
2249 #define MINCONN 32
2250 #define MAXCONN 16384
2251 if (nfds == -1 || nfds > MAXCONN)
2252 nconns = MAXCONN;
2253 else if (nfds < MINCONN)
2254 nconns = MINCONN;
2255 else
2256 nconns = nfds;
2258 /* We need memory to pass descriptors on to the worker threads. */
2259 fdlist = (struct fdlist *) xcalloc (nconns, sizeof (fdlist[0]));
2260 /* Array to keep track when connection was accepted. */
2261 starttime = (time_t *) xcalloc (nconns, sizeof (starttime[0]));
2263 /* In the main thread we execute the loop which handles incoming
2264 connections. */
2265 #ifdef HAVE_EPOLL
2266 int efd = epoll_create (100);
2267 if (efd != -1)
2269 main_loop_epoll (efd);
2270 close (efd);
2272 #endif
2274 main_loop_poll ();
2278 /* Look up the uid, gid, and supplementary groups to run nscd as. When
2279 this function is called, we are not listening on the nscd socket yet so
2280 we can just use the ordinary lookup functions without causing a lockup */
2281 static void
2282 begin_drop_privileges (void)
2284 struct passwd *pwd = getpwnam (server_user);
2286 if (pwd == NULL)
2288 dbg_log (_("Failed to run nscd as user '%s'"), server_user);
2289 error (EXIT_FAILURE, 0, _("Failed to run nscd as user '%s'"),
2290 server_user);
2293 server_uid = pwd->pw_uid;
2294 server_gid = pwd->pw_gid;
2296 /* Save the old UID/GID if we have to change back. */
2297 if (paranoia)
2299 old_uid = getuid ();
2300 old_gid = getgid ();
2303 if (getgrouplist (server_user, server_gid, NULL, &server_ngroups) == 0)
2305 /* This really must never happen. */
2306 dbg_log (_("Failed to run nscd as user '%s'"), server_user);
2307 error (EXIT_FAILURE, errno, _("initial getgrouplist failed"));
2310 server_groups = (gid_t *) xmalloc (server_ngroups * sizeof (gid_t));
2312 if (getgrouplist (server_user, server_gid, server_groups, &server_ngroups)
2313 == -1)
2315 dbg_log (_("Failed to run nscd as user '%s'"), server_user);
2316 error (EXIT_FAILURE, errno, _("getgrouplist failed"));
2321 /* Call setgroups(), setgid(), and setuid() to drop root privileges and
2322 run nscd as the user specified in the configuration file. */
2323 static void
2324 finish_drop_privileges (void)
2326 #if defined HAVE_LIBAUDIT && defined HAVE_LIBCAP
2327 /* We need to preserve the capabilities to connect to the audit daemon. */
2328 cap_t new_caps = preserve_capabilities ();
2329 #endif
2331 if (setgroups (server_ngroups, server_groups) == -1)
2333 dbg_log (_("Failed to run nscd as user '%s'"), server_user);
2334 error (EXIT_FAILURE, errno, _("setgroups failed"));
2337 int res;
2338 if (paranoia)
2339 res = setresgid (server_gid, server_gid, old_gid);
2340 else
2341 res = setgid (server_gid);
2342 if (res == -1)
2344 dbg_log (_("Failed to run nscd as user '%s'"), server_user);
2345 perror ("setgid");
2346 exit (4);
2349 if (paranoia)
2350 res = setresuid (server_uid, server_uid, old_uid);
2351 else
2352 res = setuid (server_uid);
2353 if (res == -1)
2355 dbg_log (_("Failed to run nscd as user '%s'"), server_user);
2356 perror ("setuid");
2357 exit (4);
2360 #if defined HAVE_LIBAUDIT && defined HAVE_LIBCAP
2361 /* Remove the temporary capabilities. */
2362 install_real_capabilities (new_caps);
2363 #endif