Updated to fedora-glibc-20090204T2135
[glibc.git] / nscd / connections.c
blob7e3a406185e2535176c0ea54fb429e4e8ea75f52
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;
253 /* Data structure for recording in-flight memory allocation. */
254 __thread struct mem_in_flight mem_in_flight attribute_tls_model_ie;
255 /* Global list of the mem_in_flight variables of all the threads. */
256 struct mem_in_flight *mem_in_flight_list;
259 ssize_t
260 writeall (int fd, const void *buf, size_t len)
262 size_t n = len;
263 ssize_t ret;
266 ret = TEMP_FAILURE_RETRY (send (fd, buf, n, MSG_NOSIGNAL));
267 if (ret <= 0)
268 break;
269 buf = (const char *) buf + ret;
270 n -= ret;
272 while (n > 0);
273 return ret < 0 ? ret : len - n;
277 #ifdef HAVE_SENDFILE
278 ssize_t
279 sendfileall (int tofd, int fromfd, off_t off, size_t len)
281 ssize_t n = len;
282 ssize_t ret;
286 ret = TEMP_FAILURE_RETRY (sendfile (tofd, fromfd, &off, n));
287 if (ret <= 0)
288 break;
289 n -= ret;
291 while (n > 0);
292 return ret < 0 ? ret : len - n;
294 #endif
297 enum usekey
299 use_not = 0,
300 /* The following three are not really used, they are symbolic constants. */
301 use_first = 16,
302 use_begin = 32,
303 use_end = 64,
305 use_he = 1,
306 use_he_begin = use_he | use_begin,
307 use_he_end = use_he | use_end,
308 #if SEPARATE_KEY
309 use_key = 2,
310 use_key_begin = use_key | use_begin,
311 use_key_end = use_key | use_end,
312 use_key_first = use_key_begin | use_first,
313 #endif
314 use_data = 3,
315 use_data_begin = use_data | use_begin,
316 use_data_end = use_data | use_end,
317 use_data_first = use_data_begin | use_first
321 static int
322 check_use (const char *data, nscd_ssize_t first_free, uint8_t *usemap,
323 enum usekey use, ref_t start, size_t len)
325 assert (len >= 2);
327 if (start > first_free || start + len > first_free
328 || (start & BLOCK_ALIGN_M1))
329 return 0;
331 if (usemap[start] == use_not)
333 /* Add the start marker. */
334 usemap[start] = use | use_begin;
335 use &= ~use_first;
337 while (--len > 0)
338 if (usemap[++start] != use_not)
339 return 0;
340 else
341 usemap[start] = use;
343 /* Add the end marker. */
344 usemap[start] = use | use_end;
346 else if ((usemap[start] & ~use_first) == ((use | use_begin) & ~use_first))
348 /* Hash entries can't be shared. */
349 if (use == use_he)
350 return 0;
352 usemap[start] |= (use & use_first);
353 use &= ~use_first;
355 while (--len > 1)
356 if (usemap[++start] != use)
357 return 0;
359 if (usemap[++start] != (use | use_end))
360 return 0;
362 else
363 /* Points to a wrong object or somewhere in the middle. */
364 return 0;
366 return 1;
370 /* Verify data in persistent database. */
371 static int
372 verify_persistent_db (void *mem, struct database_pers_head *readhead, int dbnr)
374 assert (dbnr == pwddb || dbnr == grpdb || dbnr == hstdb || dbnr == servdb);
376 time_t now = time (NULL);
378 struct database_pers_head *head = mem;
379 struct database_pers_head head_copy = *head;
381 /* Check that the header that was read matches the head in the database. */
382 if (memcmp (head, readhead, sizeof (*head)) != 0)
383 return 0;
385 /* First some easy tests: make sure the database header is sane. */
386 if (head->version != DB_VERSION
387 || head->header_size != sizeof (*head)
388 /* We allow a timestamp to be one hour ahead of the current time.
389 This should cover daylight saving time changes. */
390 || head->timestamp > now + 60 * 60 + 60
391 || (head->gc_cycle & 1)
392 || head->module == 0
393 || (size_t) head->module > INT32_MAX / sizeof (ref_t)
394 || (size_t) head->data_size > INT32_MAX - head->module * sizeof (ref_t)
395 || head->first_free < 0
396 || head->first_free > head->data_size
397 || (head->first_free & BLOCK_ALIGN_M1) != 0
398 || head->maxnentries < 0
399 || head->maxnsearched < 0)
400 return 0;
402 uint8_t *usemap = calloc (head->first_free, 1);
403 if (usemap == NULL)
404 return 0;
406 const char *data = (char *) &head->array[roundup (head->module,
407 ALIGN / sizeof (ref_t))];
409 nscd_ssize_t he_cnt = 0;
410 for (nscd_ssize_t cnt = 0; cnt < head->module; ++cnt)
412 ref_t trail = head->array[cnt];
413 ref_t work = trail;
414 int tick = 0;
416 while (work != ENDREF)
418 if (! check_use (data, head->first_free, usemap, use_he, work,
419 sizeof (struct hashentry)))
420 goto fail;
422 /* Now we know we can dereference the record. */
423 struct hashentry *here = (struct hashentry *) (data + work);
425 ++he_cnt;
427 /* Make sure the record is for this type of service. */
428 if (here->type >= LASTREQ
429 || reqinfo[here->type].db != &dbs[dbnr])
430 goto fail;
432 /* Validate boolean field value. */
433 if (here->first != false && here->first != true)
434 goto fail;
436 if (here->len < 0)
437 goto fail;
439 /* Now the data. */
440 if (here->packet < 0
441 || here->packet > head->first_free
442 || here->packet + sizeof (struct datahead) > head->first_free)
443 goto fail;
445 struct datahead *dh = (struct datahead *) (data + here->packet);
447 if (! check_use (data, head->first_free, usemap,
448 use_data | (here->first ? use_first : 0),
449 here->packet, dh->allocsize))
450 goto fail;
452 if (dh->allocsize < sizeof (struct datahead)
453 || dh->recsize > dh->allocsize
454 || (dh->notfound != false && dh->notfound != true)
455 || (dh->usable != false && dh->usable != true))
456 goto fail;
458 if (here->key < here->packet + sizeof (struct datahead)
459 || here->key > here->packet + dh->allocsize
460 || here->key + here->len > here->packet + dh->allocsize)
462 #if SEPARATE_KEY
463 /* If keys can appear outside of data, this should be done
464 instead. But gc doesn't mark the data in that case. */
465 if (! check_use (data, head->first_free, usemap,
466 use_key | (here->first ? use_first : 0),
467 here->key, here->len))
468 #endif
469 goto fail;
472 work = here->next;
474 if (work == trail)
475 /* A circular list, this must not happen. */
476 goto fail;
477 if (tick)
478 trail = ((struct hashentry *) (data + trail))->next;
479 tick = 1 - tick;
483 if (he_cnt != head->nentries)
484 goto fail;
486 /* See if all data and keys had at least one reference from
487 he->first == true hashentry. */
488 for (ref_t idx = 0; idx < head->first_free; ++idx)
490 #if SEPARATE_KEY
491 if (usemap[idx] == use_key_begin)
492 goto fail;
493 #endif
494 if (usemap[idx] == use_data_begin)
495 goto fail;
498 /* Finally, make sure the database hasn't changed since the first test. */
499 if (memcmp (mem, &head_copy, sizeof (*head)) != 0)
500 goto fail;
502 free (usemap);
503 return 1;
505 fail:
506 free (usemap);
507 return 0;
511 #ifdef O_CLOEXEC
512 # define EXTRA_O_FLAGS O_CLOEXEC
513 #else
514 # define EXTRA_O_FLAGS 0
515 #endif
518 /* Initialize database information structures. */
519 void
520 nscd_init (void)
522 /* Look up unprivileged uid/gid/groups before we start listening on the
523 socket */
524 if (server_user != NULL)
525 begin_drop_privileges ();
527 if (nthreads == -1)
528 /* No configuration for this value, assume a default. */
529 nthreads = 4;
531 #ifdef HAVE_INOTIFY
532 /* Use inotify to recognize changed files. */
533 inotify_fd = inotify_init1 (IN_NONBLOCK);
534 # ifndef __ASSUME_IN_NONBLOCK
535 if (inotify_fd == -1 && errno == ENOSYS)
537 inotify_fd = inotify_init ();
538 if (inotify_fd != -1)
539 fcntl (inotify_fd, F_SETFL, O_RDONLY | O_NONBLOCK);
541 # endif
542 #endif
544 for (size_t cnt = 0; cnt < lastdb; ++cnt)
545 if (dbs[cnt].enabled)
547 pthread_rwlock_init (&dbs[cnt].lock, NULL);
548 pthread_mutex_init (&dbs[cnt].memlock, NULL);
550 if (dbs[cnt].persistent)
552 /* Try to open the appropriate file on disk. */
553 int fd = open (dbs[cnt].db_filename, O_RDWR | EXTRA_O_FLAGS);
554 if (fd != -1)
556 char *msg = NULL;
557 struct stat64 st;
558 void *mem;
559 size_t total;
560 struct database_pers_head head;
561 ssize_t n = TEMP_FAILURE_RETRY (read (fd, &head,
562 sizeof (head)));
563 if (n != sizeof (head) || fstat64 (fd, &st) != 0)
565 fail_db_errno:
566 /* The code is single-threaded at this point so
567 using strerror is just fine. */
568 msg = strerror (errno);
569 fail_db:
570 dbg_log (_("invalid persistent database file \"%s\": %s"),
571 dbs[cnt].db_filename, msg);
572 unlink (dbs[cnt].db_filename);
574 else if (head.module == 0 && head.data_size == 0)
576 /* The file has been created, but the head has not
577 been initialized yet. */
578 msg = _("uninitialized header");
579 goto fail_db;
581 else if (head.header_size != (int) sizeof (head))
583 msg = _("header size does not match");
584 goto fail_db;
586 else if ((total = (sizeof (head)
587 + roundup (head.module * sizeof (ref_t),
588 ALIGN)
589 + head.data_size))
590 > st.st_size
591 || total < sizeof (head))
593 msg = _("file size does not match");
594 goto fail_db;
596 /* Note we map with the maximum size allowed for the
597 database. This is likely much larger than the
598 actual file size. This is OK on most OSes since
599 extensions of the underlying file will
600 automatically translate more pages available for
601 memory access. */
602 else if ((mem = mmap (NULL, dbs[cnt].max_db_size,
603 PROT_READ | PROT_WRITE,
604 MAP_SHARED, fd, 0))
605 == MAP_FAILED)
606 goto fail_db_errno;
607 else if (!verify_persistent_db (mem, &head, cnt))
609 munmap (mem, total);
610 msg = _("verification failed");
611 goto fail_db;
613 else
615 /* Success. We have the database. */
616 dbs[cnt].head = mem;
617 dbs[cnt].memsize = total;
618 dbs[cnt].data = (char *)
619 &dbs[cnt].head->array[roundup (dbs[cnt].head->module,
620 ALIGN / sizeof (ref_t))];
621 dbs[cnt].mmap_used = true;
623 if (dbs[cnt].suggested_module > head.module)
624 dbg_log (_("suggested size of table for database %s larger than the persistent database's table"),
625 dbnames[cnt]);
627 dbs[cnt].wr_fd = fd;
628 fd = -1;
629 /* We also need a read-only descriptor. */
630 if (dbs[cnt].shared)
632 dbs[cnt].ro_fd = open (dbs[cnt].db_filename,
633 O_RDONLY | EXTRA_O_FLAGS);
634 if (dbs[cnt].ro_fd == -1)
635 dbg_log (_("\
636 cannot create read-only descriptor for \"%s\"; no mmap"),
637 dbs[cnt].db_filename);
640 // XXX Shall we test whether the descriptors actually
641 // XXX point to the same file?
644 /* Close the file descriptors in case something went
645 wrong in which case the variable have not been
646 assigned -1. */
647 if (fd != -1)
648 close (fd);
650 else if (errno == EACCES)
651 error (EXIT_FAILURE, 0, _("cannot access '%s'"),
652 dbs[cnt].db_filename);
655 if (dbs[cnt].head == NULL)
657 /* No database loaded. Allocate the data structure,
658 possibly on disk. */
659 struct database_pers_head head;
660 size_t total = (sizeof (head)
661 + roundup (dbs[cnt].suggested_module
662 * sizeof (ref_t), ALIGN)
663 + (dbs[cnt].suggested_module
664 * DEFAULT_DATASIZE_PER_BUCKET));
666 /* Try to create the database. If we do not need a
667 persistent database create a temporary file. */
668 int fd;
669 int ro_fd = -1;
670 if (dbs[cnt].persistent)
672 fd = open (dbs[cnt].db_filename,
673 O_RDWR | O_CREAT | O_EXCL | O_TRUNC | EXTRA_O_FLAGS,
674 S_IRUSR | S_IWUSR);
675 if (fd != -1 && dbs[cnt].shared)
676 ro_fd = open (dbs[cnt].db_filename,
677 O_RDONLY | EXTRA_O_FLAGS);
679 else
681 char fname[] = _PATH_NSCD_XYZ_DB_TMP;
682 fd = mkostemp (fname, EXTRA_O_FLAGS);
684 /* We do not need the file name anymore after we
685 opened another file descriptor in read-only mode. */
686 if (fd != -1)
688 if (dbs[cnt].shared)
689 ro_fd = open (fname, O_RDONLY | EXTRA_O_FLAGS);
691 unlink (fname);
695 if (fd == -1)
697 if (errno == EEXIST)
699 dbg_log (_("database for %s corrupted or simultaneously used; remove %s manually if necessary and restart"),
700 dbnames[cnt], dbs[cnt].db_filename);
701 // XXX Correct way to terminate?
702 exit (1);
705 if (dbs[cnt].persistent)
706 dbg_log (_("cannot create %s; no persistent database used"),
707 dbs[cnt].db_filename);
708 else
709 dbg_log (_("cannot create %s; no sharing possible"),
710 dbs[cnt].db_filename);
712 dbs[cnt].persistent = 0;
713 // XXX remember: no mmap
715 else
717 /* Tell the user if we could not create the read-only
718 descriptor. */
719 if (ro_fd == -1 && dbs[cnt].shared)
720 dbg_log (_("\
721 cannot create read-only descriptor for \"%s\"; no mmap"),
722 dbs[cnt].db_filename);
724 /* Before we create the header, initialiye the hash
725 table. So that if we get interrupted if writing
726 the header we can recognize a partially initialized
727 database. */
728 size_t ps = sysconf (_SC_PAGESIZE);
729 char tmpbuf[ps];
730 assert (~ENDREF == 0);
731 memset (tmpbuf, '\xff', ps);
733 size_t remaining = dbs[cnt].suggested_module * sizeof (ref_t);
734 off_t offset = sizeof (head);
736 size_t towrite;
737 if (offset % ps != 0)
739 towrite = MIN (remaining, ps - (offset % ps));
740 if (pwrite (fd, tmpbuf, towrite, offset) != towrite)
741 goto write_fail;
742 offset += towrite;
743 remaining -= towrite;
746 while (remaining > ps)
748 if (pwrite (fd, tmpbuf, ps, offset) == -1)
749 goto write_fail;
750 offset += ps;
751 remaining -= ps;
754 if (remaining > 0
755 && pwrite (fd, tmpbuf, remaining, offset) != remaining)
756 goto write_fail;
758 /* Create the header of the file. */
759 struct database_pers_head head =
761 .version = DB_VERSION,
762 .header_size = sizeof (head),
763 .module = dbs[cnt].suggested_module,
764 .data_size = (dbs[cnt].suggested_module
765 * DEFAULT_DATASIZE_PER_BUCKET),
766 .first_free = 0
768 void *mem;
770 if ((TEMP_FAILURE_RETRY (write (fd, &head, sizeof (head)))
771 != sizeof (head))
772 || (TEMP_FAILURE_RETRY_VAL (posix_fallocate (fd, 0, total))
773 != 0)
774 || (mem = mmap (NULL, dbs[cnt].max_db_size,
775 PROT_READ | PROT_WRITE,
776 MAP_SHARED, fd, 0)) == MAP_FAILED)
778 write_fail:
779 unlink (dbs[cnt].db_filename);
780 dbg_log (_("cannot write to database file %s: %s"),
781 dbs[cnt].db_filename, strerror (errno));
782 dbs[cnt].persistent = 0;
784 else
786 /* Success. */
787 dbs[cnt].head = mem;
788 dbs[cnt].data = (char *)
789 &dbs[cnt].head->array[roundup (dbs[cnt].head->module,
790 ALIGN / sizeof (ref_t))];
791 dbs[cnt].memsize = total;
792 dbs[cnt].mmap_used = true;
794 /* Remember the descriptors. */
795 dbs[cnt].wr_fd = fd;
796 dbs[cnt].ro_fd = ro_fd;
797 fd = -1;
798 ro_fd = -1;
801 if (fd != -1)
802 close (fd);
803 if (ro_fd != -1)
804 close (ro_fd);
808 #if !defined O_CLOEXEC || !defined __ASSUME_O_CLOEXEC
809 /* We do not check here whether the O_CLOEXEC provided to the
810 open call was successful or not. The two fcntl calls are
811 only performed once each per process start-up and therefore
812 is not noticeable at all. */
813 if (paranoia
814 && ((dbs[cnt].wr_fd != -1
815 && fcntl (dbs[cnt].wr_fd, F_SETFD, FD_CLOEXEC) == -1)
816 || (dbs[cnt].ro_fd != -1
817 && fcntl (dbs[cnt].ro_fd, F_SETFD, FD_CLOEXEC) == -1)))
819 dbg_log (_("\
820 cannot set socket to close on exec: %s; disabling paranoia mode"),
821 strerror (errno));
822 paranoia = 0;
824 #endif
826 if (dbs[cnt].head == NULL)
828 /* We do not use the persistent database. Just
829 create an in-memory data structure. */
830 assert (! dbs[cnt].persistent);
832 dbs[cnt].head = xmalloc (sizeof (struct database_pers_head)
833 + (dbs[cnt].suggested_module
834 * sizeof (ref_t)));
835 memset (dbs[cnt].head, '\0', sizeof (struct database_pers_head));
836 assert (~ENDREF == 0);
837 memset (dbs[cnt].head->array, '\xff',
838 dbs[cnt].suggested_module * sizeof (ref_t));
839 dbs[cnt].head->module = dbs[cnt].suggested_module;
840 dbs[cnt].head->data_size = (DEFAULT_DATASIZE_PER_BUCKET
841 * dbs[cnt].head->module);
842 dbs[cnt].data = xmalloc (dbs[cnt].head->data_size);
843 dbs[cnt].head->first_free = 0;
845 dbs[cnt].shared = 0;
846 assert (dbs[cnt].ro_fd == -1);
849 dbs[cnt].inotify_descr = -1;
850 if (dbs[cnt].check_file)
852 #ifdef HAVE_INOTIFY
853 if (inotify_fd < 0
854 || (dbs[cnt].inotify_descr
855 = inotify_add_watch (inotify_fd, dbs[cnt].filename,
856 IN_DELETE_SELF | IN_MODIFY)) < 0)
857 /* We cannot notice changes in the main thread. */
858 #endif
860 /* We need the modification date of the file. */
861 struct stat64 st;
863 if (stat64 (dbs[cnt].filename, &st) < 0)
865 /* We cannot stat() the file, disable file checking. */
866 dbg_log (_("cannot stat() file `%s': %s"),
867 dbs[cnt].filename, strerror (errno));
868 dbs[cnt].check_file = 0;
870 else
871 dbs[cnt].file_mtime = st.st_mtime;
875 #ifdef HAVE_INOTIFY
876 if (cnt == hstdb && inotify_fd >= -1)
877 /* We also monitor the resolver configuration file. */
878 resolv_conf_descr = inotify_add_watch (inotify_fd,
879 _PATH_RESCONF,
880 IN_DELETE_SELF | IN_MODIFY);
881 #endif
884 /* Create the socket. */
885 #ifndef __ASSUME_SOCK_CLOEXEC
886 sock = -1;
887 if (have_sock_cloexec >= 0)
888 #endif
890 sock = socket (AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);
891 #ifndef __ASSUME_SOCK_CLOEXEC
892 if (have_sock_cloexec == 0)
893 have_sock_cloexec = sock != -1 || errno != EINVAL ? 1 : -1;
894 #endif
896 #ifndef __ASSUME_SOCK_CLOEXEC
897 if (have_sock_cloexec < 0)
898 sock = socket (AF_UNIX, SOCK_STREAM, 0);
899 #endif
900 if (sock < 0)
902 dbg_log (_("cannot open socket: %s"), strerror (errno));
903 exit (errno == EACCES ? 4 : 1);
905 /* Bind a name to the socket. */
906 struct sockaddr_un sock_addr;
907 sock_addr.sun_family = AF_UNIX;
908 strcpy (sock_addr.sun_path, _PATH_NSCDSOCKET);
909 if (bind (sock, (struct sockaddr *) &sock_addr, sizeof (sock_addr)) < 0)
911 dbg_log ("%s: %s", _PATH_NSCDSOCKET, strerror (errno));
912 exit (errno == EACCES ? 4 : 1);
915 #ifndef __ASSUME_SOCK_CLOEXEC
916 if (have_sock_cloexec < 0)
918 /* We don't want to get stuck on accept. */
919 int fl = fcntl (sock, F_GETFL);
920 if (fl == -1 || fcntl (sock, F_SETFL, fl | O_NONBLOCK) == -1)
922 dbg_log (_("cannot change socket to nonblocking mode: %s"),
923 strerror (errno));
924 exit (1);
927 /* The descriptor needs to be closed on exec. */
928 if (paranoia && fcntl (sock, F_SETFD, FD_CLOEXEC) == -1)
930 dbg_log (_("cannot set socket to close on exec: %s"),
931 strerror (errno));
932 exit (1);
935 #endif
937 /* Set permissions for the socket. */
938 chmod (_PATH_NSCDSOCKET, DEFFILEMODE);
940 /* Set the socket up to accept connections. */
941 if (listen (sock, SOMAXCONN) < 0)
943 dbg_log (_("cannot enable socket to accept connections: %s"),
944 strerror (errno));
945 exit (1);
948 /* Change to unprivileged uid/gid/groups if specifed in config file */
949 if (server_user != NULL)
950 finish_drop_privileges ();
954 /* Close the connections. */
955 void
956 close_sockets (void)
958 close (sock);
962 static void
963 invalidate_cache (char *key, int fd)
965 dbtype number;
966 int32_t resp;
968 for (number = pwddb; number < lastdb; ++number)
969 if (strcmp (key, dbnames[number]) == 0)
971 if (dbs[number].reset_res)
972 res_init ();
974 break;
977 if (number == lastdb)
979 resp = EINVAL;
980 writeall (fd, &resp, sizeof (resp));
981 return;
984 if (dbs[number].enabled)
986 pthread_mutex_lock (&dbs[number].prune_run_lock);
987 prune_cache (&dbs[number], LONG_MAX, fd);
988 pthread_mutex_unlock (&dbs[number].prune_run_lock);
990 else
992 resp = 0;
993 writeall (fd, &resp, sizeof (resp));
998 #ifdef SCM_RIGHTS
999 static void
1000 send_ro_fd (struct database_dyn *db, char *key, int fd)
1002 /* If we do not have an read-only file descriptor do nothing. */
1003 if (db->ro_fd == -1)
1004 return;
1006 /* We need to send some data along with the descriptor. */
1007 uint64_t mapsize = (db->head->data_size
1008 + roundup (db->head->module * sizeof (ref_t), ALIGN)
1009 + sizeof (struct database_pers_head));
1010 struct iovec iov[2];
1011 iov[0].iov_base = key;
1012 iov[0].iov_len = strlen (key) + 1;
1013 iov[1].iov_base = &mapsize;
1014 iov[1].iov_len = sizeof (mapsize);
1016 /* Prepare the control message to transfer the descriptor. */
1017 union
1019 struct cmsghdr hdr;
1020 char bytes[CMSG_SPACE (sizeof (int))];
1021 } buf;
1022 struct msghdr msg = { .msg_iov = iov, .msg_iovlen = 2,
1023 .msg_control = buf.bytes,
1024 .msg_controllen = sizeof (buf) };
1025 struct cmsghdr *cmsg = CMSG_FIRSTHDR (&msg);
1027 cmsg->cmsg_level = SOL_SOCKET;
1028 cmsg->cmsg_type = SCM_RIGHTS;
1029 cmsg->cmsg_len = CMSG_LEN (sizeof (int));
1031 *(int *) CMSG_DATA (cmsg) = db->ro_fd;
1033 msg.msg_controllen = cmsg->cmsg_len;
1035 /* Send the control message. We repeat when we are interrupted but
1036 everything else is ignored. */
1037 #ifndef MSG_NOSIGNAL
1038 # define MSG_NOSIGNAL 0
1039 #endif
1040 (void) TEMP_FAILURE_RETRY (sendmsg (fd, &msg, MSG_NOSIGNAL));
1042 if (__builtin_expect (debug_level > 0, 0))
1043 dbg_log (_("provide access to FD %d, for %s"), db->ro_fd, key);
1045 #endif /* SCM_RIGHTS */
1048 /* Handle new request. */
1049 static void
1050 handle_request (int fd, request_header *req, void *key, uid_t uid, pid_t pid)
1052 if (__builtin_expect (req->version, NSCD_VERSION) != NSCD_VERSION)
1054 if (debug_level > 0)
1055 dbg_log (_("\
1056 cannot handle old request version %d; current version is %d"),
1057 req->version, NSCD_VERSION);
1058 return;
1061 /* Perform the SELinux check before we go on to the standard checks. */
1062 if (selinux_enabled && nscd_request_avc_has_perm (fd, req->type) != 0)
1064 if (debug_level > 0)
1066 #ifdef SO_PEERCRED
1067 # ifdef PATH_MAX
1068 char buf[PATH_MAX];
1069 # else
1070 char buf[4096];
1071 # endif
1073 snprintf (buf, sizeof (buf), "/proc/%ld/exe", (long int) pid);
1074 ssize_t n = readlink (buf, buf, sizeof (buf) - 1);
1076 if (n <= 0)
1077 dbg_log (_("\
1078 request from %ld not handled due to missing permission"), (long int) pid);
1079 else
1081 buf[n] = '\0';
1082 dbg_log (_("\
1083 request from '%s' [%ld] not handled due to missing permission"),
1084 buf, (long int) pid);
1086 #else
1087 dbg_log (_("request not handled due to missing permission"));
1088 #endif
1090 return;
1093 struct database_dyn *db = reqinfo[req->type].db;
1095 /* See whether we can service the request from the cache. */
1096 if (__builtin_expect (reqinfo[req->type].data_request, true))
1098 if (__builtin_expect (debug_level, 0) > 0)
1100 if (req->type == GETHOSTBYADDR || req->type == GETHOSTBYADDRv6)
1102 char buf[INET6_ADDRSTRLEN];
1104 dbg_log ("\t%s (%s)", serv2str[req->type],
1105 inet_ntop (req->type == GETHOSTBYADDR
1106 ? AF_INET : AF_INET6,
1107 key, buf, sizeof (buf)));
1109 else
1110 dbg_log ("\t%s (%s)", serv2str[req->type], (char *) key);
1113 /* Is this service enabled? */
1114 if (__builtin_expect (!db->enabled, 0))
1116 /* No, sent the prepared record. */
1117 if (TEMP_FAILURE_RETRY (send (fd, db->disabled_iov->iov_base,
1118 db->disabled_iov->iov_len,
1119 MSG_NOSIGNAL))
1120 != (ssize_t) db->disabled_iov->iov_len
1121 && __builtin_expect (debug_level, 0) > 0)
1123 /* We have problems sending the result. */
1124 char buf[256];
1125 dbg_log (_("cannot write result: %s"),
1126 strerror_r (errno, buf, sizeof (buf)));
1129 return;
1132 /* Be sure we can read the data. */
1133 if (__builtin_expect (pthread_rwlock_tryrdlock (&db->lock) != 0, 0))
1135 ++db->head->rdlockdelayed;
1136 pthread_rwlock_rdlock (&db->lock);
1139 /* See whether we can handle it from the cache. */
1140 struct datahead *cached;
1141 cached = (struct datahead *) cache_search (req->type, key, req->key_len,
1142 db, uid);
1143 if (cached != NULL)
1145 /* Hurray it's in the cache. */
1146 ssize_t nwritten;
1148 #ifdef HAVE_SENDFILE
1149 if (__builtin_expect (db->mmap_used, 1))
1151 assert (db->wr_fd != -1);
1152 assert ((char *) cached->data > (char *) db->data);
1153 assert ((char *) cached->data - (char *) db->head
1154 + cached->recsize
1155 <= (sizeof (struct database_pers_head)
1156 + db->head->module * sizeof (ref_t)
1157 + db->head->data_size));
1158 nwritten = sendfileall (fd, db->wr_fd,
1159 (char *) cached->data
1160 - (char *) db->head, cached->recsize);
1161 # ifndef __ASSUME_SENDFILE
1162 if (nwritten == -1 && errno == ENOSYS)
1163 goto use_write;
1164 # endif
1166 else
1167 # ifndef __ASSUME_SENDFILE
1168 use_write:
1169 # endif
1170 #endif
1171 nwritten = writeall (fd, cached->data, cached->recsize);
1173 if (nwritten != cached->recsize
1174 && __builtin_expect (debug_level, 0) > 0)
1176 /* We have problems sending the result. */
1177 char buf[256];
1178 dbg_log (_("cannot write result: %s"),
1179 strerror_r (errno, buf, sizeof (buf)));
1182 pthread_rwlock_unlock (&db->lock);
1184 return;
1187 pthread_rwlock_unlock (&db->lock);
1189 else if (__builtin_expect (debug_level, 0) > 0)
1191 if (req->type == INVALIDATE)
1192 dbg_log ("\t%s (%s)", serv2str[req->type], (char *) key);
1193 else
1194 dbg_log ("\t%s", serv2str[req->type]);
1197 /* Handle the request. */
1198 switch (req->type)
1200 case GETPWBYNAME:
1201 addpwbyname (db, fd, req, key, uid);
1202 break;
1204 case GETPWBYUID:
1205 addpwbyuid (db, fd, req, key, uid);
1206 break;
1208 case GETGRBYNAME:
1209 addgrbyname (db, fd, req, key, uid);
1210 break;
1212 case GETGRBYGID:
1213 addgrbygid (db, fd, req, key, uid);
1214 break;
1216 case GETHOSTBYNAME:
1217 addhstbyname (db, fd, req, key, uid);
1218 break;
1220 case GETHOSTBYNAMEv6:
1221 addhstbynamev6 (db, fd, req, key, uid);
1222 break;
1224 case GETHOSTBYADDR:
1225 addhstbyaddr (db, fd, req, key, uid);
1226 break;
1228 case GETHOSTBYADDRv6:
1229 addhstbyaddrv6 (db, fd, req, key, uid);
1230 break;
1232 case GETAI:
1233 addhstai (db, fd, req, key, uid);
1234 break;
1236 case INITGROUPS:
1237 addinitgroups (db, fd, req, key, uid);
1238 break;
1240 case GETSERVBYNAME:
1241 addservbyname (db, fd, req, key, uid);
1242 break;
1244 case GETSERVBYPORT:
1245 addservbyport (db, fd, req, key, uid);
1246 break;
1248 case GETSTAT:
1249 case SHUTDOWN:
1250 case INVALIDATE:
1252 /* Get the callers credentials. */
1253 #ifdef SO_PEERCRED
1254 struct ucred caller;
1255 socklen_t optlen = sizeof (caller);
1257 if (getsockopt (fd, SOL_SOCKET, SO_PEERCRED, &caller, &optlen) < 0)
1259 char buf[256];
1261 dbg_log (_("error getting caller's id: %s"),
1262 strerror_r (errno, buf, sizeof (buf)));
1263 break;
1266 uid = caller.uid;
1267 #else
1268 /* Some systems have no SO_PEERCRED implementation. They don't
1269 care about security so we don't as well. */
1270 uid = 0;
1271 #endif
1274 /* Accept shutdown, getstat and invalidate only from root. For
1275 the stat call also allow the user specified in the config file. */
1276 if (req->type == GETSTAT)
1278 if (uid == 0 || uid == stat_uid)
1279 send_stats (fd, dbs);
1281 else if (uid == 0)
1283 if (req->type == INVALIDATE)
1284 invalidate_cache (key, fd);
1285 else
1286 termination_handler (0);
1288 break;
1290 case GETFDPW:
1291 case GETFDGR:
1292 case GETFDHST:
1293 case GETFDSERV:
1294 #ifdef SCM_RIGHTS
1295 send_ro_fd (reqinfo[req->type].db, key, fd);
1296 #endif
1297 break;
1299 default:
1300 /* Ignore the command, it's nothing we know. */
1301 break;
1306 /* Restart the process. */
1307 static void
1308 restart (void)
1310 /* First determine the parameters. We do not use the parameters
1311 passed to main() since in case nscd is started by running the
1312 dynamic linker this will not work. Yes, this is not the usual
1313 case but nscd is part of glibc and we occasionally do this. */
1314 size_t buflen = 1024;
1315 char *buf = alloca (buflen);
1316 size_t readlen = 0;
1317 int fd = open ("/proc/self/cmdline", O_RDONLY);
1318 if (fd == -1)
1320 dbg_log (_("\
1321 cannot open /proc/self/cmdline: %s; disabling paranoia mode"),
1322 strerror (errno));
1324 paranoia = 0;
1325 return;
1328 while (1)
1330 ssize_t n = TEMP_FAILURE_RETRY (read (fd, buf + readlen,
1331 buflen - readlen));
1332 if (n == -1)
1334 dbg_log (_("\
1335 cannot read /proc/self/cmdline: %s; disabling paranoia mode"),
1336 strerror (errno));
1338 close (fd);
1339 paranoia = 0;
1340 return;
1343 readlen += n;
1345 if (readlen < buflen)
1346 break;
1348 /* We might have to extend the buffer. */
1349 size_t old_buflen = buflen;
1350 char *newp = extend_alloca (buf, buflen, 2 * buflen);
1351 buf = memmove (newp, buf, old_buflen);
1354 close (fd);
1356 /* Parse the command line. Worst case scenario: every two
1357 characters form one parameter (one character plus NUL). */
1358 char **argv = alloca ((readlen / 2 + 1) * sizeof (argv[0]));
1359 int argc = 0;
1361 char *cp = buf;
1362 while (cp < buf + readlen)
1364 argv[argc++] = cp;
1365 cp = (char *) rawmemchr (cp, '\0') + 1;
1367 argv[argc] = NULL;
1369 /* Second, change back to the old user if we changed it. */
1370 if (server_user != NULL)
1372 if (setresuid (old_uid, old_uid, old_uid) != 0)
1374 dbg_log (_("\
1375 cannot change to old UID: %s; disabling paranoia mode"),
1376 strerror (errno));
1378 paranoia = 0;
1379 return;
1382 if (setresgid (old_gid, old_gid, old_gid) != 0)
1384 dbg_log (_("\
1385 cannot change to old GID: %s; disabling paranoia mode"),
1386 strerror (errno));
1388 setuid (server_uid);
1389 paranoia = 0;
1390 return;
1394 /* Next change back to the old working directory. */
1395 if (chdir (oldcwd) == -1)
1397 dbg_log (_("\
1398 cannot change to old working directory: %s; disabling paranoia mode"),
1399 strerror (errno));
1401 if (server_user != NULL)
1403 setuid (server_uid);
1404 setgid (server_gid);
1406 paranoia = 0;
1407 return;
1410 /* Synchronize memory. */
1411 int32_t certainly[lastdb];
1412 for (int cnt = 0; cnt < lastdb; ++cnt)
1413 if (dbs[cnt].enabled)
1415 /* Make sure nobody keeps using the database. */
1416 dbs[cnt].head->timestamp = 0;
1417 certainly[cnt] = dbs[cnt].head->nscd_certainly_running;
1418 dbs[cnt].head->nscd_certainly_running = 0;
1420 if (dbs[cnt].persistent)
1421 // XXX async OK?
1422 msync (dbs[cnt].head, dbs[cnt].memsize, MS_ASYNC);
1425 /* The preparations are done. */
1426 execv ("/proc/self/exe", argv);
1428 /* If we come here, we will never be able to re-exec. */
1429 dbg_log (_("re-exec failed: %s; disabling paranoia mode"),
1430 strerror (errno));
1432 if (server_user != NULL)
1434 setuid (server_uid);
1435 setgid (server_gid);
1437 if (chdir ("/") != 0)
1438 dbg_log (_("cannot change current working directory to \"/\": %s"),
1439 strerror (errno));
1440 paranoia = 0;
1442 /* Reenable the databases. */
1443 time_t now = time (NULL);
1444 for (int cnt = 0; cnt < lastdb; ++cnt)
1445 if (dbs[cnt].enabled)
1447 dbs[cnt].head->timestamp = now;
1448 dbs[cnt].head->nscd_certainly_running = certainly[cnt];
1453 /* List of file descriptors. */
1454 struct fdlist
1456 int fd;
1457 struct fdlist *next;
1459 /* Memory allocated for the list. */
1460 static struct fdlist *fdlist;
1461 /* List of currently ready-to-read file descriptors. */
1462 static struct fdlist *readylist;
1464 /* Conditional variable and mutex to signal availability of entries in
1465 READYLIST. The condvar is initialized dynamically since we might
1466 use a different clock depending on availability. */
1467 static pthread_cond_t readylist_cond = PTHREAD_COND_INITIALIZER;
1468 static pthread_mutex_t readylist_lock = PTHREAD_MUTEX_INITIALIZER;
1470 /* The clock to use with the condvar. */
1471 static clockid_t timeout_clock = CLOCK_REALTIME;
1473 /* Number of threads ready to handle the READYLIST. */
1474 static unsigned long int nready;
1477 /* Function for the clean-up threads. */
1478 static void *
1479 __attribute__ ((__noreturn__))
1480 nscd_run_prune (void *p)
1482 const long int my_number = (long int) p;
1483 assert (dbs[my_number].enabled);
1485 int dont_need_update = setup_thread (&dbs[my_number]);
1487 time_t now = time (NULL);
1489 /* We are running. */
1490 dbs[my_number].head->timestamp = now;
1492 struct timespec prune_ts;
1493 if (__builtin_expect (clock_gettime (timeout_clock, &prune_ts) == -1, 0))
1494 /* Should never happen. */
1495 abort ();
1497 /* Compute the initial timeout time. Prevent all the timers to go
1498 off at the same time by adding a db-based value. */
1499 prune_ts.tv_sec += CACHE_PRUNE_INTERVAL + my_number;
1500 dbs[my_number].wakeup_time = now + CACHE_PRUNE_INTERVAL + my_number;
1502 pthread_mutex_t *prune_lock = &dbs[my_number].prune_lock;
1503 pthread_mutex_t *prune_run_lock = &dbs[my_number].prune_run_lock;
1504 pthread_cond_t *prune_cond = &dbs[my_number].prune_cond;
1506 pthread_mutex_lock (prune_lock);
1507 while (1)
1509 /* Wait, but not forever. */
1510 int e = 0;
1511 if (! dbs[my_number].clear_cache)
1512 e = pthread_cond_timedwait (prune_cond, prune_lock, &prune_ts);
1513 assert (__builtin_expect (e == 0 || e == ETIMEDOUT, 1));
1515 time_t next_wait;
1516 now = time (NULL);
1517 if (e == ETIMEDOUT || now >= dbs[my_number].wakeup_time
1518 || dbs[my_number].clear_cache)
1520 /* We will determine the new timout values based on the
1521 cache content. Should there be concurrent additions to
1522 the cache which are not accounted for in the cache
1523 pruning we want to know about it. Therefore set the
1524 timeout to the maximum. It will be descreased when adding
1525 new entries to the cache, if necessary. */
1526 if (sizeof (time_t) == sizeof (long int))
1527 dbs[my_number].wakeup_time = LONG_MAX;
1528 else
1529 dbs[my_number].wakeup_time = INT_MAX;
1531 /* Unconditionally reset the flag. */
1532 time_t prune_now = dbs[my_number].clear_cache ? LONG_MAX : now;
1533 dbs[my_number].clear_cache = 0;
1535 pthread_mutex_unlock (prune_lock);
1537 /* We use a separate lock for running the prune function (instead
1538 of keeping prune_lock locked) because this enables concurrent
1539 invocations of cache_add which might modify the timeout value. */
1540 pthread_mutex_lock (prune_run_lock);
1541 next_wait = prune_cache (&dbs[my_number], prune_now, -1);
1542 pthread_mutex_unlock (prune_run_lock);
1544 next_wait = MAX (next_wait, CACHE_PRUNE_INTERVAL);
1545 /* If clients cannot determine for sure whether nscd is running
1546 we need to wake up occasionally to update the timestamp.
1547 Wait 90% of the update period. */
1548 #define UPDATE_MAPPING_TIMEOUT (MAPPING_TIMEOUT * 9 / 10)
1549 if (__builtin_expect (! dont_need_update, 0))
1551 next_wait = MIN (UPDATE_MAPPING_TIMEOUT, next_wait);
1552 dbs[my_number].head->timestamp = now;
1555 pthread_mutex_lock (prune_lock);
1557 /* Make it known when we will wake up again. */
1558 if (now + next_wait < dbs[my_number].wakeup_time)
1559 dbs[my_number].wakeup_time = now + next_wait;
1560 else
1561 next_wait = dbs[my_number].wakeup_time - now;
1563 else
1564 /* The cache was just pruned. Do not do it again now. Just
1565 use the new timeout value. */
1566 next_wait = dbs[my_number].wakeup_time - now;
1568 if (clock_gettime (timeout_clock, &prune_ts) == -1)
1569 /* Should never happen. */
1570 abort ();
1572 /* Compute next timeout time. */
1573 prune_ts.tv_sec += next_wait;
1578 /* This is the main loop. It is replicated in different threads but
1579 the the use of the ready list makes sure only one thread handles an
1580 incoming connection. */
1581 static void *
1582 __attribute__ ((__noreturn__))
1583 nscd_run_worker (void *p)
1585 char buf[256];
1587 /* Initialize the memory-in-flight list. */
1588 for (enum in_flight idx = 0; idx < IDX_last; ++idx)
1589 mem_in_flight.block[idx].dbidx = -1;
1590 /* And queue this threads structure. */
1592 mem_in_flight.next = mem_in_flight_list;
1593 while (atomic_compare_and_exchange_bool_acq (&mem_in_flight_list,
1594 &mem_in_flight,
1595 mem_in_flight.next) != 0);
1597 /* Initial locking. */
1598 pthread_mutex_lock (&readylist_lock);
1600 /* One more thread available. */
1601 ++nready;
1603 while (1)
1605 while (readylist == NULL)
1606 pthread_cond_wait (&readylist_cond, &readylist_lock);
1608 struct fdlist *it = readylist->next;
1609 if (readylist->next == readylist)
1610 /* Just one entry on the list. */
1611 readylist = NULL;
1612 else
1613 readylist->next = it->next;
1615 /* Extract the information and mark the record ready to be used
1616 again. */
1617 int fd = it->fd;
1618 it->next = NULL;
1620 /* One more thread available. */
1621 --nready;
1623 /* We are done with the list. */
1624 pthread_mutex_unlock (&readylist_lock);
1626 #ifndef __ASSUME_ACCEPT4
1627 if (have_accept4 < 0)
1629 /* We do not want to block on a short read or so. */
1630 int fl = fcntl (fd, F_GETFL);
1631 if (fl == -1 || fcntl (fd, F_SETFL, fl | O_NONBLOCK) == -1)
1632 goto close_and_out;
1634 #endif
1636 /* Now read the request. */
1637 request_header req;
1638 if (__builtin_expect (TEMP_FAILURE_RETRY (read (fd, &req, sizeof (req)))
1639 != sizeof (req), 0))
1641 /* We failed to read data. Note that this also might mean we
1642 failed because we would have blocked. */
1643 if (debug_level > 0)
1644 dbg_log (_("short read while reading request: %s"),
1645 strerror_r (errno, buf, sizeof (buf)));
1646 goto close_and_out;
1649 /* Check whether this is a valid request type. */
1650 if (req.type < GETPWBYNAME || req.type >= LASTREQ)
1651 goto close_and_out;
1653 /* Some systems have no SO_PEERCRED implementation. They don't
1654 care about security so we don't as well. */
1655 uid_t uid = -1;
1656 #ifdef SO_PEERCRED
1657 pid_t pid = 0;
1659 if (__builtin_expect (debug_level > 0, 0))
1661 struct ucred caller;
1662 socklen_t optlen = sizeof (caller);
1664 if (getsockopt (fd, SOL_SOCKET, SO_PEERCRED, &caller, &optlen) == 0)
1665 pid = caller.pid;
1667 #else
1668 const pid_t pid = 0;
1669 #endif
1671 /* It should not be possible to crash the nscd with a silly
1672 request (i.e., a terribly large key). We limit the size to 1kb. */
1673 if (__builtin_expect (req.key_len, 1) < 0
1674 || __builtin_expect (req.key_len, 1) > MAXKEYLEN)
1676 if (debug_level > 0)
1677 dbg_log (_("key length in request too long: %d"), req.key_len);
1679 else
1681 /* Get the key. */
1682 char keybuf[MAXKEYLEN];
1684 if (__builtin_expect (TEMP_FAILURE_RETRY (read (fd, keybuf,
1685 req.key_len))
1686 != req.key_len, 0))
1688 /* Again, this can also mean we would have blocked. */
1689 if (debug_level > 0)
1690 dbg_log (_("short read while reading request key: %s"),
1691 strerror_r (errno, buf, sizeof (buf)));
1692 goto close_and_out;
1695 if (__builtin_expect (debug_level, 0) > 0)
1697 #ifdef SO_PEERCRED
1698 if (pid != 0)
1699 dbg_log (_("\
1700 handle_request: request received (Version = %d) from PID %ld"),
1701 req.version, (long int) pid);
1702 else
1703 #endif
1704 dbg_log (_("\
1705 handle_request: request received (Version = %d)"), req.version);
1708 /* Phew, we got all the data, now process it. */
1709 handle_request (fd, &req, keybuf, uid, pid);
1712 close_and_out:
1713 /* We are done. */
1714 close (fd);
1716 /* Re-locking. */
1717 pthread_mutex_lock (&readylist_lock);
1719 /* One more thread available. */
1720 ++nready;
1725 static unsigned int nconns;
1727 static void
1728 fd_ready (int fd)
1730 pthread_mutex_lock (&readylist_lock);
1732 /* Find an empty entry in FDLIST. */
1733 size_t inner;
1734 for (inner = 0; inner < nconns; ++inner)
1735 if (fdlist[inner].next == NULL)
1736 break;
1737 assert (inner < nconns);
1739 fdlist[inner].fd = fd;
1741 if (readylist == NULL)
1742 readylist = fdlist[inner].next = &fdlist[inner];
1743 else
1745 fdlist[inner].next = readylist->next;
1746 readylist = readylist->next = &fdlist[inner];
1749 bool do_signal = true;
1750 if (__builtin_expect (nready == 0, 0))
1752 ++client_queued;
1753 do_signal = false;
1755 /* Try to start another thread to help out. */
1756 pthread_t th;
1757 if (nthreads < max_nthreads
1758 && pthread_create (&th, &attr, nscd_run_worker,
1759 (void *) (long int) nthreads) == 0)
1761 /* We got another thread. */
1762 ++nthreads;
1763 /* The new thread might need a kick. */
1764 do_signal = true;
1769 pthread_mutex_unlock (&readylist_lock);
1771 /* Tell one of the worker threads there is work to do. */
1772 if (do_signal)
1773 pthread_cond_signal (&readylist_cond);
1777 /* Check whether restarting should happen. */
1778 static inline int
1779 restart_p (time_t now)
1781 return (paranoia && readylist == NULL && nready == nthreads
1782 && now >= restart_time);
1786 /* Array for times a connection was accepted. */
1787 static time_t *starttime;
1790 static void
1791 __attribute__ ((__noreturn__))
1792 main_loop_poll (void)
1794 struct pollfd *conns = (struct pollfd *) xmalloc (nconns
1795 * sizeof (conns[0]));
1797 conns[0].fd = sock;
1798 conns[0].events = POLLRDNORM;
1799 size_t nused = 1;
1800 size_t firstfree = 1;
1802 #ifdef HAVE_INOTIFY
1803 if (inotify_fd != -1)
1805 conns[1].fd = inotify_fd;
1806 conns[1].events = POLLRDNORM;
1807 nused = 2;
1808 firstfree = 2;
1810 #endif
1812 while (1)
1814 /* Wait for any event. We wait at most a couple of seconds so
1815 that we can check whether we should close any of the accepted
1816 connections since we have not received a request. */
1817 #define MAX_ACCEPT_TIMEOUT 30
1818 #define MIN_ACCEPT_TIMEOUT 5
1819 #define MAIN_THREAD_TIMEOUT \
1820 (MAX_ACCEPT_TIMEOUT * 1000 \
1821 - ((MAX_ACCEPT_TIMEOUT - MIN_ACCEPT_TIMEOUT) * 1000 * nused) / (2 * nconns))
1823 int n = poll (conns, nused, MAIN_THREAD_TIMEOUT);
1825 time_t now = time (NULL);
1827 /* If there is a descriptor ready for reading or there is a new
1828 connection, process this now. */
1829 if (n > 0)
1831 if (conns[0].revents != 0)
1833 /* We have a new incoming connection. Accept the connection. */
1834 int fd;
1836 #ifndef __ASSUME_ACCEPT4
1837 fd = -1;
1838 if (have_accept4 >= 0)
1839 #endif
1841 fd = TEMP_FAILURE_RETRY (accept4 (sock, NULL, NULL,
1842 SOCK_NONBLOCK));
1843 #ifndef __ASSUME_ACCEPT4
1844 if (have_accept4 == 0)
1845 have_accept4 = fd != -1 || errno != ENOSYS ? 1 : -1;
1846 #endif
1848 #ifndef __ASSUME_ACCEPT4
1849 if (have_accept4 < 0)
1850 fd = TEMP_FAILURE_RETRY (accept (sock, NULL, NULL));
1851 #endif
1853 /* Use the descriptor if we have not reached the limit. */
1854 if (fd >= 0)
1856 if (firstfree < nconns)
1858 conns[firstfree].fd = fd;
1859 conns[firstfree].events = POLLRDNORM;
1860 starttime[firstfree] = now;
1861 if (firstfree >= nused)
1862 nused = firstfree + 1;
1865 ++firstfree;
1866 while (firstfree < nused && conns[firstfree].fd != -1);
1868 else
1869 /* We cannot use the connection so close it. */
1870 close (fd);
1873 --n;
1876 size_t first = 1;
1877 #ifdef HAVE_INOTIFY
1878 if (inotify_fd != -1 && conns[1].fd == inotify_fd)
1880 if (conns[1].revents != 0)
1882 bool to_clear[lastdb] = { false, };
1883 union
1885 # ifndef PATH_MAX
1886 # define PATH_MAX 1024
1887 # endif
1888 struct inotify_event i;
1889 char buf[sizeof (struct inotify_event) + PATH_MAX];
1890 } inev;
1892 while (1)
1894 ssize_t nb = TEMP_FAILURE_RETRY (read (inotify_fd, &inev,
1895 sizeof (inev)));
1896 if (nb < (ssize_t) sizeof (struct inotify_event))
1898 if (__builtin_expect (nb == -1 && errno != EAGAIN,
1901 /* Something went wrong when reading the inotify
1902 data. Better disable inotify. */
1903 dbg_log (_("\
1904 disabled inotify after read error %d"),
1905 errno);
1906 conns[1].fd = -1;
1907 firstfree = 1;
1908 if (nused == 2)
1909 nused = 1;
1910 close (inotify_fd);
1911 inotify_fd = -1;
1913 break;
1916 /* Check which of the files changed. */
1917 for (size_t dbcnt = 0; dbcnt < lastdb; ++dbcnt)
1918 if (inev.i.wd == dbs[dbcnt].inotify_descr)
1920 to_clear[dbcnt] = true;
1921 goto next;
1924 if (inev.i.wd == resolv_conf_descr)
1926 res_init ();
1927 to_clear[hstdb] = true;
1929 next:;
1932 /* Actually perform the cache clearing. */
1933 for (size_t dbcnt = 0; dbcnt < lastdb; ++dbcnt)
1934 if (to_clear[dbcnt])
1936 pthread_mutex_lock (&dbs[dbcnt].prune_lock);
1937 dbs[dbcnt].clear_cache = 1;
1938 pthread_mutex_unlock (&dbs[dbcnt].prune_lock);
1939 pthread_cond_signal (&dbs[dbcnt].prune_cond);
1942 --n;
1945 first = 2;
1947 #endif
1949 for (size_t cnt = first; cnt < nused && n > 0; ++cnt)
1950 if (conns[cnt].revents != 0)
1952 fd_ready (conns[cnt].fd);
1954 /* Clean up the CONNS array. */
1955 conns[cnt].fd = -1;
1956 if (cnt < firstfree)
1957 firstfree = cnt;
1958 if (cnt == nused - 1)
1960 --nused;
1961 while (conns[nused - 1].fd == -1);
1963 --n;
1967 /* Now find entries which have timed out. */
1968 assert (nused > 0);
1970 /* We make the timeout length depend on the number of file
1971 descriptors currently used. */
1972 #define ACCEPT_TIMEOUT \
1973 (MAX_ACCEPT_TIMEOUT \
1974 - ((MAX_ACCEPT_TIMEOUT - MIN_ACCEPT_TIMEOUT) * nused) / nconns)
1975 time_t laststart = now - ACCEPT_TIMEOUT;
1977 for (size_t cnt = nused - 1; cnt > 0; --cnt)
1979 if (conns[cnt].fd != -1 && starttime[cnt] < laststart)
1981 /* Remove the entry, it timed out. */
1982 (void) close (conns[cnt].fd);
1983 conns[cnt].fd = -1;
1985 if (cnt < firstfree)
1986 firstfree = cnt;
1987 if (cnt == nused - 1)
1989 --nused;
1990 while (conns[nused - 1].fd == -1);
1994 if (restart_p (now))
1995 restart ();
2000 #ifdef HAVE_EPOLL
2001 static void
2002 main_loop_epoll (int efd)
2004 struct epoll_event ev = { 0, };
2005 int nused = 1;
2006 size_t highest = 0;
2008 /* Add the socket. */
2009 ev.events = EPOLLRDNORM;
2010 ev.data.fd = sock;
2011 if (epoll_ctl (efd, EPOLL_CTL_ADD, sock, &ev) == -1)
2012 /* We cannot use epoll. */
2013 return;
2015 # ifdef HAVE_INOTIFY
2016 if (inotify_fd != -1)
2018 ev.events = EPOLLRDNORM;
2019 ev.data.fd = inotify_fd;
2020 if (epoll_ctl (efd, EPOLL_CTL_ADD, inotify_fd, &ev) == -1)
2021 /* We cannot use epoll. */
2022 return;
2023 nused = 2;
2025 # endif
2027 while (1)
2029 struct epoll_event revs[100];
2030 # define nrevs (sizeof (revs) / sizeof (revs[0]))
2032 int n = epoll_wait (efd, revs, nrevs, MAIN_THREAD_TIMEOUT);
2034 time_t now = time (NULL);
2036 for (int cnt = 0; cnt < n; ++cnt)
2037 if (revs[cnt].data.fd == sock)
2039 /* A new connection. */
2040 int fd;
2042 # ifndef __ASSUME_ACCEPT4
2043 fd = -1;
2044 if (have_accept4 >= 0)
2045 # endif
2047 fd = TEMP_FAILURE_RETRY (accept4 (sock, NULL, NULL,
2048 SOCK_NONBLOCK));
2049 # ifndef __ASSUME_ACCEPT4
2050 if (have_accept4 == 0)
2051 have_accept4 = fd != -1 || errno != ENOSYS ? 1 : -1;
2052 # endif
2054 # ifndef __ASSUME_ACCEPT4
2055 if (have_accept4 < 0)
2056 fd = TEMP_FAILURE_RETRY (accept (sock, NULL, NULL));
2057 # endif
2059 /* Use the descriptor if we have not reached the limit. */
2060 if (fd >= 0)
2062 /* Try to add the new descriptor. */
2063 ev.data.fd = fd;
2064 if (fd >= nconns
2065 || epoll_ctl (efd, EPOLL_CTL_ADD, fd, &ev) == -1)
2066 /* The descriptor is too large or something went
2067 wrong. Close the descriptor. */
2068 close (fd);
2069 else
2071 /* Remember when we accepted the connection. */
2072 starttime[fd] = now;
2074 if (fd > highest)
2075 highest = fd;
2077 ++nused;
2081 # ifdef HAVE_INOTIFY
2082 else if (revs[cnt].data.fd == inotify_fd)
2084 bool to_clear[lastdb] = { false, };
2085 union
2087 struct inotify_event i;
2088 char buf[sizeof (struct inotify_event) + PATH_MAX];
2089 } inev;
2091 while (1)
2093 ssize_t nb = TEMP_FAILURE_RETRY (read (inotify_fd, &inev,
2094 sizeof (inev)));
2095 if (nb < (ssize_t) sizeof (struct inotify_event))
2097 if (__builtin_expect (nb == -1 && errno != EAGAIN, 0))
2099 /* Something went wrong when reading the inotify
2100 data. Better disable inotify. */
2101 dbg_log (_("disabled inotify after read error %d"),
2102 errno);
2103 (void) epoll_ctl (efd, EPOLL_CTL_DEL, inotify_fd,
2104 NULL);
2105 close (inotify_fd);
2106 inotify_fd = -1;
2108 break;
2111 /* Check which of the files changed. */
2112 for (size_t dbcnt = 0; dbcnt < lastdb; ++dbcnt)
2113 if (inev.i.wd == dbs[dbcnt].inotify_descr)
2115 to_clear[dbcnt] = true;
2116 goto next;
2119 if (inev.i.wd == resolv_conf_descr)
2121 res_init ();
2122 to_clear[hstdb] = true;
2124 next:;
2127 /* Actually perform the cache clearing. */
2128 for (size_t dbcnt = 0; dbcnt < lastdb; ++dbcnt)
2129 if (to_clear[dbcnt])
2131 pthread_mutex_lock (&dbs[dbcnt].prune_lock);
2132 dbs[dbcnt].clear_cache = 1;
2133 pthread_mutex_unlock (&dbs[dbcnt].prune_lock);
2134 pthread_cond_signal (&dbs[dbcnt].prune_cond);
2137 # endif
2138 else
2140 /* Remove the descriptor from the epoll descriptor. */
2141 (void) epoll_ctl (efd, EPOLL_CTL_DEL, revs[cnt].data.fd, NULL);
2143 /* Get a worker to handle the request. */
2144 fd_ready (revs[cnt].data.fd);
2146 /* Reset the time. */
2147 starttime[revs[cnt].data.fd] = 0;
2148 if (revs[cnt].data.fd == highest)
2150 --highest;
2151 while (highest > 0 && starttime[highest] == 0);
2153 --nused;
2156 /* Now look for descriptors for accepted connections which have
2157 no reply in too long of a time. */
2158 time_t laststart = now - ACCEPT_TIMEOUT;
2159 assert (starttime[sock] == 0);
2160 assert (inotify_fd == -1 || starttime[inotify_fd] == 0);
2161 for (int cnt = highest; cnt > STDERR_FILENO; --cnt)
2162 if (starttime[cnt] != 0 && starttime[cnt] < laststart)
2164 /* We are waiting for this one for too long. Close it. */
2165 (void) epoll_ctl (efd, EPOLL_CTL_DEL, cnt, NULL);
2167 (void) close (cnt);
2169 starttime[cnt] = 0;
2170 if (cnt == highest)
2171 --highest;
2173 else if (cnt != sock && starttime[cnt] == 0 && cnt == highest)
2174 --highest;
2176 if (restart_p (now))
2177 restart ();
2180 #endif
2183 /* Start all the threads we want. The initial process is thread no. 1. */
2184 void
2185 start_threads (void)
2187 /* Initialize the conditional variable we will use. The only
2188 non-standard attribute we might use is the clock selection. */
2189 pthread_condattr_t condattr;
2190 pthread_condattr_init (&condattr);
2192 #if defined _POSIX_CLOCK_SELECTION && _POSIX_CLOCK_SELECTION >= 0 \
2193 && defined _POSIX_MONOTONIC_CLOCK && _POSIX_MONOTONIC_CLOCK >= 0
2194 /* Determine whether the monotonous clock is available. */
2195 struct timespec dummy;
2196 # if _POSIX_MONOTONIC_CLOCK == 0
2197 if (sysconf (_SC_MONOTONIC_CLOCK) > 0)
2198 # endif
2199 # if _POSIX_CLOCK_SELECTION == 0
2200 if (sysconf (_SC_CLOCK_SELECTION) > 0)
2201 # endif
2202 if (clock_getres (CLOCK_MONOTONIC, &dummy) == 0
2203 && pthread_condattr_setclock (&condattr, CLOCK_MONOTONIC) == 0)
2204 timeout_clock = CLOCK_MONOTONIC;
2205 #endif
2207 /* Create the attribute for the threads. They are all created
2208 detached. */
2209 pthread_attr_init (&attr);
2210 pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
2211 /* Use 1MB stacks, twice as much for 64-bit architectures. */
2212 pthread_attr_setstacksize (&attr, NSCD_THREAD_STACKSIZE);
2214 /* We allow less than LASTDB threads only for debugging. */
2215 if (debug_level == 0)
2216 nthreads = MAX (nthreads, lastdb);
2218 /* Create the threads which prune the databases. */
2219 // XXX Ideally this work would be done by some of the worker threads.
2220 // XXX But this is problematic since we would need to be able to wake
2221 // XXX them up explicitly as well as part of the group handling the
2222 // XXX ready-list. This requires an operation where we can wait on
2223 // XXX two conditional variables at the same time. This operation
2224 // XXX does not exist (yet).
2225 for (long int i = 0; i < lastdb; ++i)
2227 /* Initialize the conditional variable. */
2228 if (pthread_cond_init (&dbs[i].prune_cond, &condattr) != 0)
2230 dbg_log (_("could not initialize conditional variable"));
2231 exit (1);
2234 pthread_t th;
2235 if (dbs[i].enabled
2236 && pthread_create (&th, &attr, nscd_run_prune, (void *) i) != 0)
2238 dbg_log (_("could not start clean-up thread; terminating"));
2239 exit (1);
2243 pthread_condattr_destroy (&condattr);
2245 for (long int i = 0; i < nthreads; ++i)
2247 pthread_t th;
2248 if (pthread_create (&th, &attr, nscd_run_worker, NULL) != 0)
2250 if (i == 0)
2252 dbg_log (_("could not start any worker thread; terminating"));
2253 exit (1);
2256 break;
2260 /* Determine how much room for descriptors we should initially
2261 allocate. This might need to change later if we cap the number
2262 with MAXCONN. */
2263 const long int nfds = sysconf (_SC_OPEN_MAX);
2264 #define MINCONN 32
2265 #define MAXCONN 16384
2266 if (nfds == -1 || nfds > MAXCONN)
2267 nconns = MAXCONN;
2268 else if (nfds < MINCONN)
2269 nconns = MINCONN;
2270 else
2271 nconns = nfds;
2273 /* We need memory to pass descriptors on to the worker threads. */
2274 fdlist = (struct fdlist *) xcalloc (nconns, sizeof (fdlist[0]));
2275 /* Array to keep track when connection was accepted. */
2276 starttime = (time_t *) xcalloc (nconns, sizeof (starttime[0]));
2278 /* In the main thread we execute the loop which handles incoming
2279 connections. */
2280 #ifdef HAVE_EPOLL
2281 int efd = epoll_create (100);
2282 if (efd != -1)
2284 main_loop_epoll (efd);
2285 close (efd);
2287 #endif
2289 main_loop_poll ();
2293 /* Look up the uid, gid, and supplementary groups to run nscd as. When
2294 this function is called, we are not listening on the nscd socket yet so
2295 we can just use the ordinary lookup functions without causing a lockup */
2296 static void
2297 begin_drop_privileges (void)
2299 struct passwd *pwd = getpwnam (server_user);
2301 if (pwd == NULL)
2303 dbg_log (_("Failed to run nscd as user '%s'"), server_user);
2304 error (EXIT_FAILURE, 0, _("Failed to run nscd as user '%s'"),
2305 server_user);
2308 server_uid = pwd->pw_uid;
2309 server_gid = pwd->pw_gid;
2311 /* Save the old UID/GID if we have to change back. */
2312 if (paranoia)
2314 old_uid = getuid ();
2315 old_gid = getgid ();
2318 if (getgrouplist (server_user, server_gid, NULL, &server_ngroups) == 0)
2320 /* This really must never happen. */
2321 dbg_log (_("Failed to run nscd as user '%s'"), server_user);
2322 error (EXIT_FAILURE, errno, _("initial getgrouplist failed"));
2325 server_groups = (gid_t *) xmalloc (server_ngroups * sizeof (gid_t));
2327 if (getgrouplist (server_user, server_gid, server_groups, &server_ngroups)
2328 == -1)
2330 dbg_log (_("Failed to run nscd as user '%s'"), server_user);
2331 error (EXIT_FAILURE, errno, _("getgrouplist failed"));
2336 /* Call setgroups(), setgid(), and setuid() to drop root privileges and
2337 run nscd as the user specified in the configuration file. */
2338 static void
2339 finish_drop_privileges (void)
2341 #if defined HAVE_LIBAUDIT && defined HAVE_LIBCAP
2342 /* We need to preserve the capabilities to connect to the audit daemon. */
2343 cap_t new_caps = preserve_capabilities ();
2344 #endif
2346 if (setgroups (server_ngroups, server_groups) == -1)
2348 dbg_log (_("Failed to run nscd as user '%s'"), server_user);
2349 error (EXIT_FAILURE, errno, _("setgroups failed"));
2352 int res;
2353 if (paranoia)
2354 res = setresgid (server_gid, server_gid, old_gid);
2355 else
2356 res = setgid (server_gid);
2357 if (res == -1)
2359 dbg_log (_("Failed to run nscd as user '%s'"), server_user);
2360 perror ("setgid");
2361 exit (4);
2364 if (paranoia)
2365 res = setresuid (server_uid, server_uid, old_uid);
2366 else
2367 res = setuid (server_uid);
2368 if (res == -1)
2370 dbg_log (_("Failed to run nscd as user '%s'"), server_user);
2371 perror ("setuid");
2372 exit (4);
2375 #if defined HAVE_LIBAUDIT && defined HAVE_LIBCAP
2376 /* Remove the temporary capabilities. */
2377 install_real_capabilities (new_caps);
2378 #endif