]> git.ipfire.org Git - thirdparty/glibc.git/blob - nscd/connections.c
* nscd/cache.c (prune_cache): Use stat64 not stat.
[thirdparty/glibc.git] / nscd / connections.c
1 /* Inner loops of cache daemon.
2 Copyright (C) 1998-2003, 2004, 2005 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4 Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
5
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
10
11 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public
17 License along with the GNU C Library; if not, write to the Free
18 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA. */
20
21 #include <alloca.h>
22 #include <assert.h>
23 #include <atomic.h>
24 #include <error.h>
25 #include <errno.h>
26 #include <fcntl.h>
27 #include <grp.h>
28 #include <libintl.h>
29 #include <pthread.h>
30 #include <pwd.h>
31 #include <resolv.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <unistd.h>
35 #include <arpa/inet.h>
36 #ifdef HAVE_EPOLL
37 # include <sys/epoll.h>
38 #endif
39 #include <sys/mman.h>
40 #include <sys/param.h>
41 #include <sys/poll.h>
42 #include <sys/socket.h>
43 #include <sys/stat.h>
44 #include <sys/un.h>
45
46 #include "nscd.h"
47 #include "dbg_log.h"
48 #include "selinux.h"
49
50
51 /* Number of bytes of data we initially reserve for each hash table bucket. */
52 #define DEFAULT_DATASIZE_PER_BUCKET 1024
53
54
55 /* Wrapper functions with error checking for standard functions. */
56 extern void *xmalloc (size_t n);
57 extern void *xcalloc (size_t n, size_t s);
58 extern void *xrealloc (void *o, size_t n);
59
60 /* Support to run nscd as an unprivileged user */
61 const char *server_user;
62 static uid_t server_uid;
63 static gid_t server_gid;
64 const char *stat_user;
65 uid_t stat_uid;
66 static gid_t *server_groups;
67 #ifndef NGROUPS
68 # define NGROUPS 32
69 #endif
70 static int server_ngroups;
71
72 static pthread_attr_t attr;
73
74 static void begin_drop_privileges (void);
75 static void finish_drop_privileges (void);
76
77 /* Map request type to a string. */
78 const char *serv2str[LASTREQ] =
79 {
80 [GETPWBYNAME] = "GETPWBYNAME",
81 [GETPWBYUID] = "GETPWBYUID",
82 [GETGRBYNAME] = "GETGRBYNAME",
83 [GETGRBYGID] = "GETGRBYGID",
84 [GETHOSTBYNAME] = "GETHOSTBYNAME",
85 [GETHOSTBYNAMEv6] = "GETHOSTBYNAMEv6",
86 [GETHOSTBYADDR] = "GETHOSTBYADDR",
87 [GETHOSTBYADDRv6] = "GETHOSTBYADDRv6",
88 [SHUTDOWN] = "SHUTDOWN",
89 [GETSTAT] = "GETSTAT",
90 [INVALIDATE] = "INVALIDATE",
91 [GETFDPW] = "GETFDPW",
92 [GETFDGR] = "GETFDGR",
93 [GETFDHST] = "GETFDHST",
94 [GETAI] = "GETAI",
95 [INITGROUPS] = "INITGROUPS"
96 };
97
98 /* The control data structures for the services. */
99 struct database_dyn dbs[lastdb] =
100 {
101 [pwddb] = {
102 .lock = PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP,
103 .enabled = 0,
104 .check_file = 1,
105 .persistent = 0,
106 .shared = 0,
107 .filename = "/etc/passwd",
108 .db_filename = _PATH_NSCD_PASSWD_DB,
109 .disabled_iov = &pwd_iov_disabled,
110 .postimeout = 3600,
111 .negtimeout = 20,
112 .wr_fd = -1,
113 .ro_fd = -1,
114 .mmap_used = false
115 },
116 [grpdb] = {
117 .lock = PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP,
118 .enabled = 0,
119 .check_file = 1,
120 .persistent = 0,
121 .shared = 0,
122 .filename = "/etc/group",
123 .db_filename = _PATH_NSCD_GROUP_DB,
124 .disabled_iov = &grp_iov_disabled,
125 .postimeout = 3600,
126 .negtimeout = 60,
127 .wr_fd = -1,
128 .ro_fd = -1,
129 .mmap_used = false
130 },
131 [hstdb] = {
132 .lock = PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP,
133 .enabled = 0,
134 .check_file = 1,
135 .persistent = 0,
136 .shared = 0,
137 .filename = "/etc/hosts",
138 .db_filename = _PATH_NSCD_HOSTS_DB,
139 .disabled_iov = &hst_iov_disabled,
140 .postimeout = 3600,
141 .negtimeout = 20,
142 .wr_fd = -1,
143 .ro_fd = -1,
144 .mmap_used = false
145 }
146 };
147
148
149 /* Mapping of request type to database. */
150 static struct database_dyn *const serv2db[LASTREQ] =
151 {
152 [GETPWBYNAME] = &dbs[pwddb],
153 [GETPWBYUID] = &dbs[pwddb],
154 [GETGRBYNAME] = &dbs[grpdb],
155 [GETGRBYGID] = &dbs[grpdb],
156 [GETHOSTBYNAME] = &dbs[hstdb],
157 [GETHOSTBYNAMEv6] = &dbs[hstdb],
158 [GETHOSTBYADDR] = &dbs[hstdb],
159 [GETHOSTBYADDRv6] = &dbs[hstdb],
160 [GETFDPW] = &dbs[pwddb],
161 [GETFDGR] = &dbs[grpdb],
162 [GETFDHST] = &dbs[hstdb],
163 [GETAI] = &dbs[hstdb],
164 [INITGROUPS] = &dbs[grpdb]
165 };
166
167
168 /* Number of seconds between two cache pruning runs. */
169 #define CACHE_PRUNE_INTERVAL 15
170
171
172 /* Initial number of threads to use. */
173 int nthreads = -1;
174 /* Maximum number of threads to use. */
175 int max_nthreads = 32;
176
177 /* Socket for incoming connections. */
178 static int sock;
179
180 /* Number of times clients had to wait. */
181 unsigned long int client_queued;
182
183
184 ssize_t
185 writeall (int fd, const void *buf, size_t len)
186 {
187 size_t n = len;
188 ssize_t ret;
189 do
190 {
191 ret = TEMP_FAILURE_RETRY (write (fd, buf, n));
192 if (ret <= 0)
193 break;
194 buf = (const char *) buf + ret;
195 n -= ret;
196 }
197 while (n > 0);
198 return ret < 0 ? ret : len - n;
199 }
200
201
202 enum usekey
203 {
204 use_not = 0,
205 /* The following three are not really used, they are symbolic constants. */
206 use_first = 16,
207 use_begin = 32,
208 use_end = 64,
209
210 use_he = 1,
211 use_he_begin = use_he | use_begin,
212 use_he_end = use_he | use_end,
213 #if SEPARATE_KEY
214 use_key = 2,
215 use_key_begin = use_key | use_begin,
216 use_key_end = use_key | use_end,
217 use_key_first = use_key_begin | use_first,
218 #endif
219 use_data = 3,
220 use_data_begin = use_data | use_begin,
221 use_data_end = use_data | use_end,
222 use_data_first = use_data_begin | use_first
223 };
224
225
226 static int
227 check_use (const char *data, nscd_ssize_t first_free, uint8_t *usemap,
228 enum usekey use, ref_t start, size_t len)
229 {
230 assert (len >= 2);
231
232 if (start > first_free || start + len > first_free
233 || (start & BLOCK_ALIGN_M1))
234 return 0;
235
236 if (usemap[start] == use_not)
237 {
238 /* Add the start marker. */
239 usemap[start] = use | use_begin;
240 use &= ~use_first;
241
242 while (--len > 0)
243 if (usemap[++start] != use_not)
244 return 0;
245 else
246 usemap[start] = use;
247
248 /* Add the end marker. */
249 usemap[start] = use | use_end;
250 }
251 else if ((usemap[start] & ~use_first) == ((use | use_begin) & ~use_first))
252 {
253 /* Hash entries can't be shared. */
254 if (use == use_he)
255 return 0;
256
257 usemap[start] |= (use & use_first);
258 use &= ~use_first;
259
260 while (--len > 1)
261 if (usemap[++start] != use)
262 return 0;
263
264 if (usemap[++start] != (use | use_end))
265 return 0;
266 }
267 else
268 /* Points to a wrong object or somewhere in the middle. */
269 return 0;
270
271 return 1;
272 }
273
274
275 /* Verify data in persistent database. */
276 static int
277 verify_persistent_db (void *mem, struct database_pers_head *readhead, int dbnr)
278 {
279 assert (dbnr == pwddb || dbnr == grpdb || dbnr == hstdb);
280
281 time_t now = time (NULL);
282
283 struct database_pers_head *head = mem;
284 struct database_pers_head head_copy = *head;
285
286 /* Check that the header that was read matches the head in the database. */
287 if (readhead != NULL && memcmp (head, readhead, sizeof (*head)) != 0)
288 return 0;
289
290 /* First some easy tests: make sure the database header is sane. */
291 if (head->version != DB_VERSION
292 || head->header_size != sizeof (*head)
293 /* We allow a timestamp to be one hour ahead of the current time.
294 This should cover daylight saving time changes. */
295 || head->timestamp > now + 60 * 60 + 60
296 || (head->gc_cycle & 1)
297 || (size_t) head->module > INT32_MAX / sizeof (ref_t)
298 || (size_t) head->data_size > INT32_MAX - head->module * sizeof (ref_t)
299 || head->first_free < 0
300 || head->first_free > head->data_size
301 || (head->first_free & BLOCK_ALIGN_M1) != 0
302 || head->maxnentries < 0
303 || head->maxnsearched < 0)
304 return 0;
305
306 uint8_t *usemap = calloc (head->first_free, 1);
307 if (usemap == NULL)
308 return 0;
309
310 const char *data = (char *) &head->array[roundup (head->module,
311 ALIGN / sizeof (ref_t))];
312
313 nscd_ssize_t he_cnt = 0;
314 for (nscd_ssize_t cnt = 0; cnt < head->module; ++cnt)
315 {
316 ref_t work = head->array[cnt];
317
318 while (work != ENDREF)
319 {
320 if (! check_use (data, head->first_free, usemap, use_he, work,
321 sizeof (struct hashentry)))
322 goto fail;
323
324 /* Now we know we can dereference the record. */
325 struct hashentry *here = (struct hashentry *) (data + work);
326
327 ++he_cnt;
328
329 /* Make sure the record is for this type of service. */
330 if (here->type >= LASTREQ
331 || serv2db[here->type] != &dbs[dbnr])
332 goto fail;
333
334 /* Validate boolean field value. */
335 if (here->first != false && here->first != true)
336 goto fail;
337
338 if (here->len < 0)
339 goto fail;
340
341 /* Now the data. */
342 if (here->packet < 0
343 || here->packet > head->first_free
344 || here->packet + sizeof (struct datahead) > head->first_free)
345 goto fail;
346
347 struct datahead *dh = (struct datahead *) (data + here->packet);
348
349 if (! check_use (data, head->first_free, usemap,
350 use_data | (here->first ? use_first : 0),
351 here->packet, dh->allocsize))
352 goto fail;
353
354 if (dh->allocsize < sizeof (struct datahead)
355 || dh->recsize > dh->allocsize
356 || (dh->notfound != false && dh->notfound != true)
357 || (dh->usable != false && dh->usable != true))
358 goto fail;
359
360 if (here->key < here->packet + sizeof (struct datahead)
361 || here->key > here->packet + dh->allocsize
362 || here->key + here->len > here->packet + dh->allocsize)
363 {
364 #if SEPARATE_KEY
365 /* If keys can appear outside of data, this should be done
366 instead. But gc doesn't mark the data in that case. */
367 if (! check_use (data, head->first_free, usemap,
368 use_key | (here->first ? use_first : 0),
369 here->key, here->len))
370 #endif
371 goto fail;
372 }
373
374 work = here->next;
375 }
376 }
377
378 if (he_cnt != head->nentries)
379 goto fail;
380
381 /* See if all data and keys had at least one reference from
382 he->first == true hashentry. */
383 for (ref_t idx = 0; idx < head->first_free; ++idx)
384 {
385 #if SEPARATE_KEY
386 if (usemap[idx] == use_key_begin)
387 goto fail;
388 #endif
389 if (usemap[idx] == use_data_begin)
390 goto fail;
391 }
392
393 /* Finally, make sure the database hasn't changed since the first test. */
394 if (memcmp (mem, &head_copy, sizeof (*head)) != 0)
395 goto fail;
396
397 free (usemap);
398 return 1;
399
400 fail:
401 free (usemap);
402 return 0;
403 }
404
405
406 /* Initialize database information structures. */
407 void
408 nscd_init (void)
409 {
410 /* Secure mode and unprivileged mode are incompatible */
411 if (server_user != NULL && secure_in_use)
412 {
413 dbg_log (_("Cannot run nscd in secure mode as unprivileged user"));
414 exit (4);
415 }
416
417 /* Look up unprivileged uid/gid/groups before we start listening on the
418 socket */
419 if (server_user != NULL)
420 begin_drop_privileges ();
421
422 if (nthreads == -1)
423 /* No configuration for this value, assume a default. */
424 nthreads = 2 * lastdb;
425
426 for (size_t cnt = 0; cnt < lastdb; ++cnt)
427 if (dbs[cnt].enabled)
428 {
429 pthread_rwlock_init (&dbs[cnt].lock, NULL);
430 pthread_mutex_init (&dbs[cnt].memlock, NULL);
431
432 if (dbs[cnt].persistent)
433 {
434 /* Try to open the appropriate file on disk. */
435 int fd = open (dbs[cnt].db_filename, O_RDWR);
436 if (fd != -1)
437 {
438 struct stat64 st;
439 void *mem;
440 size_t total;
441 struct database_pers_head head;
442 ssize_t n = TEMP_FAILURE_RETRY (read (fd, &head,
443 sizeof (head)));
444 if (n != sizeof (head) || fstat64 (fd, &st) != 0)
445 {
446 fail_db:
447 dbg_log (_("invalid persistent database file \"%s\": %s"),
448 dbs[cnt].db_filename, strerror (errno));
449 unlink (dbs[cnt].db_filename);
450 }
451 else if (head.module == 0 && head.data_size == 0)
452 {
453 /* The file has been created, but the head has not been
454 initialized yet. Remove the old file. */
455 unlink (dbs[cnt].db_filename);
456 }
457 else if (head.header_size != (int) sizeof (head))
458 {
459 dbg_log (_("invalid persistent database file \"%s\": %s"),
460 dbs[cnt].db_filename,
461 _("header size does not match"));
462 unlink (dbs[cnt].db_filename);
463 }
464 else if ((total = (sizeof (head)
465 + roundup (head.module * sizeof (ref_t),
466 ALIGN)
467 + head.data_size))
468 > st.st_size
469 || total < sizeof (head))
470 {
471 dbg_log (_("invalid persistent database file \"%s\": %s"),
472 dbs[cnt].db_filename,
473 _("file size does not match"));
474 unlink (dbs[cnt].db_filename);
475 }
476 else if ((mem = mmap (NULL, total, PROT_READ | PROT_WRITE,
477 MAP_SHARED, fd, 0)) == MAP_FAILED)
478 goto fail_db;
479 else if (!verify_persistent_db (mem, &head, cnt))
480 {
481 munmap (mem, total);
482 dbg_log (_("invalid persistent database file \"%s\": %s"),
483 dbs[cnt].db_filename,
484 _("verification failed"));
485 unlink (dbs[cnt].db_filename);
486 }
487 else
488 {
489 /* Success. We have the database. */
490 dbs[cnt].head = mem;
491 dbs[cnt].memsize = total;
492 dbs[cnt].data = (char *)
493 &dbs[cnt].head->array[roundup (dbs[cnt].head->module,
494 ALIGN / sizeof (ref_t))];
495 dbs[cnt].mmap_used = true;
496
497 if (dbs[cnt].suggested_module > head.module)
498 dbg_log (_("suggested size of table for database %s larger than the persistent database's table"),
499 dbnames[cnt]);
500
501 dbs[cnt].wr_fd = fd;
502 fd = -1;
503 /* We also need a read-only descriptor. */
504 if (dbs[cnt].shared)
505 {
506 dbs[cnt].ro_fd = open (dbs[cnt].db_filename, O_RDONLY);
507 if (dbs[cnt].ro_fd == -1)
508 dbg_log (_("\
509 cannot create read-only descriptor for \"%s\"; no mmap"),
510 dbs[cnt].db_filename);
511 }
512
513 // XXX Shall we test whether the descriptors actually
514 // XXX point to the same file?
515 }
516
517 /* Close the file descriptors in case something went
518 wrong in which case the variable have not been
519 assigned -1. */
520 if (fd != -1)
521 close (fd);
522 }
523 }
524
525 if (dbs[cnt].head == NULL)
526 {
527 /* No database loaded. Allocate the data structure,
528 possibly on disk. */
529 struct database_pers_head head;
530 size_t total = (sizeof (head)
531 + roundup (dbs[cnt].suggested_module
532 * sizeof (ref_t), ALIGN)
533 + (dbs[cnt].suggested_module
534 * DEFAULT_DATASIZE_PER_BUCKET));
535
536 /* Try to create the database. If we do not need a
537 persistent database create a temporary file. */
538 int fd;
539 int ro_fd = -1;
540 if (dbs[cnt].persistent)
541 {
542 fd = open (dbs[cnt].db_filename,
543 O_RDWR | O_CREAT | O_EXCL | O_TRUNC,
544 S_IRUSR | S_IWUSR);
545 if (fd != -1 && dbs[cnt].shared)
546 ro_fd = open (dbs[cnt].db_filename, O_RDONLY);
547 }
548 else
549 {
550 char fname[] = _PATH_NSCD_XYZ_DB_TMP;
551 fd = mkstemp (fname);
552
553 /* We do not need the file name anymore after we
554 opened another file descriptor in read-only mode. */
555 if (fd != -1)
556 {
557 if (dbs[cnt].shared)
558 ro_fd = open (fname, O_RDONLY);
559
560 unlink (fname);
561 }
562 }
563
564 if (fd == -1)
565 {
566 if (errno == EEXIST)
567 {
568 dbg_log (_("database for %s corrupted or simultaneously used; remove %s manually if necessary and restart"),
569 dbnames[cnt], dbs[cnt].db_filename);
570 // XXX Correct way to terminate?
571 exit (1);
572 }
573
574 if (dbs[cnt].persistent)
575 dbg_log (_("cannot create %s; no persistent database used"),
576 dbs[cnt].db_filename);
577 else
578 dbg_log (_("cannot create %s; no sharing possible"),
579 dbs[cnt].db_filename);
580
581 dbs[cnt].persistent = 0;
582 // XXX remember: no mmap
583 }
584 else
585 {
586 /* Tell the user if we could not create the read-only
587 descriptor. */
588 if (ro_fd == -1 && dbs[cnt].shared)
589 dbg_log (_("\
590 cannot create read-only descriptor for \"%s\"; no mmap"),
591 dbs[cnt].db_filename);
592
593 /* Before we create the header, initialiye the hash
594 table. So that if we get interrupted if writing
595 the header we can recognize a partially initialized
596 database. */
597 size_t ps = sysconf (_SC_PAGESIZE);
598 char tmpbuf[ps];
599 assert (~ENDREF == 0);
600 memset (tmpbuf, '\xff', ps);
601
602 size_t remaining = dbs[cnt].suggested_module * sizeof (ref_t);
603 off_t offset = sizeof (head);
604
605 size_t towrite;
606 if (offset % ps != 0)
607 {
608 towrite = MIN (remaining, ps - (offset % ps));
609 if (pwrite (fd, tmpbuf, towrite, offset) != towrite)
610 goto write_fail;
611 offset += towrite;
612 remaining -= towrite;
613 }
614
615 while (remaining > ps)
616 {
617 if (pwrite (fd, tmpbuf, ps, offset) == -1)
618 goto write_fail;
619 offset += ps;
620 remaining -= ps;
621 }
622
623 if (remaining > 0
624 && pwrite (fd, tmpbuf, remaining, offset) != remaining)
625 goto write_fail;
626
627 /* Create the header of the file. */
628 struct database_pers_head head =
629 {
630 .version = DB_VERSION,
631 .header_size = sizeof (head),
632 .module = dbs[cnt].suggested_module,
633 .data_size = (dbs[cnt].suggested_module
634 * DEFAULT_DATASIZE_PER_BUCKET),
635 .first_free = 0
636 };
637 void *mem;
638
639 if ((TEMP_FAILURE_RETRY (write (fd, &head, sizeof (head)))
640 != sizeof (head))
641 || posix_fallocate (fd, 0, total) != 0
642 || (mem = mmap (NULL, total, PROT_READ | PROT_WRITE,
643 MAP_SHARED, fd, 0)) == MAP_FAILED)
644 {
645 write_fail:
646 unlink (dbs[cnt].db_filename);
647 dbg_log (_("cannot write to database file %s: %s"),
648 dbs[cnt].db_filename, strerror (errno));
649 dbs[cnt].persistent = 0;
650 }
651 else
652 {
653 /* Success. */
654 dbs[cnt].head = mem;
655 dbs[cnt].data = (char *)
656 &dbs[cnt].head->array[roundup (dbs[cnt].head->module,
657 ALIGN / sizeof (ref_t))];
658 dbs[cnt].memsize = total;
659 dbs[cnt].mmap_used = true;
660
661 /* Remember the descriptors. */
662 dbs[cnt].wr_fd = fd;
663 dbs[cnt].ro_fd = ro_fd;
664 fd = -1;
665 ro_fd = -1;
666 }
667
668 if (fd != -1)
669 close (fd);
670 if (ro_fd != -1)
671 close (ro_fd);
672 }
673 }
674
675 if (paranoia
676 && ((dbs[cnt].wr_fd != -1
677 && fcntl (dbs[cnt].wr_fd, F_SETFD, FD_CLOEXEC) == -1)
678 || (dbs[cnt].ro_fd != -1
679 && fcntl (dbs[cnt].ro_fd, F_SETFD, FD_CLOEXEC) == -1)))
680 {
681 dbg_log (_("\
682 cannot set socket to close on exec: %s; disabling paranoia mode"),
683 strerror (errno));
684 paranoia = 0;
685 }
686
687 if (dbs[cnt].head == NULL)
688 {
689 /* We do not use the persistent database. Just
690 create an in-memory data structure. */
691 assert (! dbs[cnt].persistent);
692
693 dbs[cnt].head = xmalloc (sizeof (struct database_pers_head)
694 + (dbs[cnt].suggested_module
695 * sizeof (ref_t)));
696 memset (dbs[cnt].head, '\0', sizeof (dbs[cnt].head));
697 assert (~ENDREF == 0);
698 memset (dbs[cnt].head->array, '\xff',
699 dbs[cnt].suggested_module * sizeof (ref_t));
700 dbs[cnt].head->module = dbs[cnt].suggested_module;
701 dbs[cnt].head->data_size = (DEFAULT_DATASIZE_PER_BUCKET
702 * dbs[cnt].head->module);
703 dbs[cnt].data = xmalloc (dbs[cnt].head->data_size);
704 dbs[cnt].head->first_free = 0;
705
706 dbs[cnt].shared = 0;
707 assert (dbs[cnt].ro_fd == -1);
708 }
709
710 if (dbs[cnt].check_file)
711 {
712 /* We need the modification date of the file. */
713 struct stat64 st;
714
715 if (stat64 (dbs[cnt].filename, &st) < 0)
716 {
717 /* We cannot stat() the file, disable file checking. */
718 dbg_log (_("cannot stat() file `%s': %s"),
719 dbs[cnt].filename, strerror (errno));
720 dbs[cnt].check_file = 0;
721 }
722 else
723 dbs[cnt].file_mtime = st.st_mtime;
724 }
725 }
726
727 /* Create the socket. */
728 sock = socket (AF_UNIX, SOCK_STREAM, 0);
729 if (sock < 0)
730 {
731 dbg_log (_("cannot open socket: %s"), strerror (errno));
732 exit (errno == EACCES ? 4 : 1);
733 }
734 /* Bind a name to the socket. */
735 struct sockaddr_un sock_addr;
736 sock_addr.sun_family = AF_UNIX;
737 strcpy (sock_addr.sun_path, _PATH_NSCDSOCKET);
738 if (bind (sock, (struct sockaddr *) &sock_addr, sizeof (sock_addr)) < 0)
739 {
740 dbg_log ("%s: %s", _PATH_NSCDSOCKET, strerror (errno));
741 exit (errno == EACCES ? 4 : 1);
742 }
743
744 /* We don't want to get stuck on accept. */
745 int fl = fcntl (sock, F_GETFL);
746 if (fl == -1 || fcntl (sock, F_SETFL, fl | O_NONBLOCK) == -1)
747 {
748 dbg_log (_("cannot change socket to nonblocking mode: %s"),
749 strerror (errno));
750 exit (1);
751 }
752
753 /* The descriptor needs to be closed on exec. */
754 if (paranoia && fcntl (sock, F_SETFD, FD_CLOEXEC) == -1)
755 {
756 dbg_log (_("cannot set socket to close on exec: %s"),
757 strerror (errno));
758 exit (1);
759 }
760
761 /* Set permissions for the socket. */
762 chmod (_PATH_NSCDSOCKET, DEFFILEMODE);
763
764 /* Set the socket up to accept connections. */
765 if (listen (sock, SOMAXCONN) < 0)
766 {
767 dbg_log (_("cannot enable socket to accept connections: %s"),
768 strerror (errno));
769 exit (1);
770 }
771
772 /* Change to unprivileged uid/gid/groups if specifed in config file */
773 if (server_user != NULL)
774 finish_drop_privileges ();
775 }
776
777
778 /* Close the connections. */
779 void
780 close_sockets (void)
781 {
782 close (sock);
783 }
784
785
786 static void
787 invalidate_cache (char *key)
788 {
789 dbtype number;
790
791 if (strcmp (key, "passwd") == 0)
792 number = pwddb;
793 else if (strcmp (key, "group") == 0)
794 number = grpdb;
795 else if (__builtin_expect (strcmp (key, "hosts"), 0) == 0)
796 {
797 number = hstdb;
798
799 /* Re-initialize the resolver. resolv.conf might have changed. */
800 res_init ();
801 }
802 else
803 return;
804
805 if (dbs[number].enabled)
806 prune_cache (&dbs[number], LONG_MAX);
807 }
808
809
810 #ifdef SCM_RIGHTS
811 static void
812 send_ro_fd (struct database_dyn *db, char *key, int fd)
813 {
814 /* If we do not have an read-only file descriptor do nothing. */
815 if (db->ro_fd == -1)
816 return;
817
818 /* We need to send some data along with the descriptor. */
819 struct iovec iov[1];
820 iov[0].iov_base = key;
821 iov[0].iov_len = strlen (key) + 1;
822
823 /* Prepare the control message to transfer the descriptor. */
824 union
825 {
826 struct cmsghdr hdr;
827 char bytes[CMSG_SPACE (sizeof (int))];
828 } buf;
829 struct msghdr msg = { .msg_iov = iov, .msg_iovlen = 1,
830 .msg_control = buf.bytes,
831 .msg_controllen = sizeof (buf) };
832 struct cmsghdr *cmsg = CMSG_FIRSTHDR (&msg);
833
834 cmsg->cmsg_level = SOL_SOCKET;
835 cmsg->cmsg_type = SCM_RIGHTS;
836 cmsg->cmsg_len = CMSG_LEN (sizeof (int));
837
838 *(int *) CMSG_DATA (cmsg) = db->ro_fd;
839
840 msg.msg_controllen = cmsg->cmsg_len;
841
842 /* Send the control message. We repeat when we are interrupted but
843 everything else is ignored. */
844 #ifndef MSG_NOSIGNAL
845 # define MSG_NOSIGNAL 0
846 #endif
847 (void) TEMP_FAILURE_RETRY (sendmsg (fd, &msg, MSG_NOSIGNAL));
848
849 if (__builtin_expect (debug_level > 0, 0))
850 dbg_log (_("provide access to FD %d, for %s"), db->ro_fd, key);
851 }
852 #endif /* SCM_RIGHTS */
853
854
855 /* Handle new request. */
856 static void
857 handle_request (int fd, request_header *req, void *key, uid_t uid)
858 {
859 if (__builtin_expect (req->version, NSCD_VERSION) != NSCD_VERSION)
860 {
861 if (debug_level > 0)
862 dbg_log (_("\
863 cannot handle old request version %d; current version is %d"),
864 req->version, NSCD_VERSION);
865 return;
866 }
867
868 /* Make the SELinux check before we go on to the standard checks. We
869 need to verify that the request type is valid, since it has not
870 yet been checked at this point. */
871 if (selinux_enabled
872 && __builtin_expect (req->type, GETPWBYNAME) >= GETPWBYNAME
873 && __builtin_expect (req->type, LASTREQ) < LASTREQ
874 && nscd_request_avc_has_perm (fd, req->type) != 0)
875 return;
876
877 struct database_dyn *db = serv2db[req->type];
878
879 // XXX Clean up so that each new command need not introduce a
880 // XXX new conditional.
881 if ((__builtin_expect (req->type, GETPWBYNAME) >= GETPWBYNAME
882 && __builtin_expect (req->type, LASTDBREQ) <= LASTDBREQ)
883 || req->type == GETAI || req->type == INITGROUPS)
884 {
885 if (__builtin_expect (debug_level, 0) > 0)
886 {
887 if (req->type == GETHOSTBYADDR || req->type == GETHOSTBYADDRv6)
888 {
889 char buf[INET6_ADDRSTRLEN];
890
891 dbg_log ("\t%s (%s)", serv2str[req->type],
892 inet_ntop (req->type == GETHOSTBYADDR
893 ? AF_INET : AF_INET6,
894 key, buf, sizeof (buf)));
895 }
896 else
897 dbg_log ("\t%s (%s)", serv2str[req->type], (char *) key);
898 }
899
900 /* Is this service enabled? */
901 if (!db->enabled)
902 {
903 /* No, sent the prepared record. */
904 if (TEMP_FAILURE_RETRY (write (fd, db->disabled_iov->iov_base,
905 db->disabled_iov->iov_len))
906 != (ssize_t) db->disabled_iov->iov_len
907 && __builtin_expect (debug_level, 0) > 0)
908 {
909 /* We have problems sending the result. */
910 char buf[256];
911 dbg_log (_("cannot write result: %s"),
912 strerror_r (errno, buf, sizeof (buf)));
913 }
914
915 return;
916 }
917
918 /* Be sure we can read the data. */
919 if (__builtin_expect (pthread_rwlock_tryrdlock (&db->lock) != 0, 0))
920 {
921 ++db->head->rdlockdelayed;
922 pthread_rwlock_rdlock (&db->lock);
923 }
924
925 /* See whether we can handle it from the cache. */
926 struct datahead *cached;
927 cached = (struct datahead *) cache_search (req->type, key, req->key_len,
928 db, uid);
929 if (cached != NULL)
930 {
931 /* Hurray it's in the cache. */
932 if (writeall (fd, cached->data, cached->recsize)
933 != cached->recsize
934 && __builtin_expect (debug_level, 0) > 0)
935 {
936 /* We have problems sending the result. */
937 char buf[256];
938 dbg_log (_("cannot write result: %s"),
939 strerror_r (errno, buf, sizeof (buf)));
940 }
941
942 pthread_rwlock_unlock (&db->lock);
943
944 return;
945 }
946
947 pthread_rwlock_unlock (&db->lock);
948 }
949 else if (__builtin_expect (debug_level, 0) > 0)
950 {
951 if (req->type == INVALIDATE)
952 dbg_log ("\t%s (%s)", serv2str[req->type], (char *) key);
953 else
954 dbg_log ("\t%s", serv2str[req->type]);
955 }
956
957 /* Handle the request. */
958 switch (req->type)
959 {
960 case GETPWBYNAME:
961 addpwbyname (db, fd, req, key, uid);
962 break;
963
964 case GETPWBYUID:
965 addpwbyuid (db, fd, req, key, uid);
966 break;
967
968 case GETGRBYNAME:
969 addgrbyname (db, fd, req, key, uid);
970 break;
971
972 case GETGRBYGID:
973 addgrbygid (db, fd, req, key, uid);
974 break;
975
976 case GETHOSTBYNAME:
977 addhstbyname (db, fd, req, key, uid);
978 break;
979
980 case GETHOSTBYNAMEv6:
981 addhstbynamev6 (db, fd, req, key, uid);
982 break;
983
984 case GETHOSTBYADDR:
985 addhstbyaddr (db, fd, req, key, uid);
986 break;
987
988 case GETHOSTBYADDRv6:
989 addhstbyaddrv6 (db, fd, req, key, uid);
990 break;
991
992 case GETAI:
993 addhstai (db, fd, req, key, uid);
994 break;
995
996 case INITGROUPS:
997 addinitgroups (db, fd, req, key, uid);
998 break;
999
1000 case GETSTAT:
1001 case SHUTDOWN:
1002 case INVALIDATE:
1003 if (! secure_in_use)
1004 {
1005 /* Get the callers credentials. */
1006 #ifdef SO_PEERCRED
1007 struct ucred caller;
1008 socklen_t optlen = sizeof (caller);
1009
1010 if (getsockopt (fd, SOL_SOCKET, SO_PEERCRED, &caller, &optlen) < 0)
1011 {
1012 char buf[256];
1013
1014 dbg_log (_("error getting callers id: %s"),
1015 strerror_r (errno, buf, sizeof (buf)));
1016 break;
1017 }
1018
1019 uid = caller.uid;
1020 #else
1021 /* Some systems have no SO_PEERCRED implementation. They don't
1022 care about security so we don't as well. */
1023 uid = 0;
1024 #endif
1025 }
1026
1027 /* Accept shutdown, getstat and invalidate only from root. For
1028 the stat call also allow the user specified in the config file. */
1029 if (req->type == GETSTAT)
1030 {
1031 if (uid == 0 || uid == stat_uid)
1032 send_stats (fd, dbs);
1033 }
1034 else if (uid == 0)
1035 {
1036 if (req->type == INVALIDATE)
1037 invalidate_cache (key);
1038 else
1039 termination_handler (0);
1040 }
1041 break;
1042
1043 case GETFDPW:
1044 case GETFDGR:
1045 case GETFDHST:
1046 #ifdef SCM_RIGHTS
1047 send_ro_fd (serv2db[req->type], key, fd);
1048 #endif
1049 break;
1050
1051 default:
1052 /* Ignore the command, it's nothing we know. */
1053 break;
1054 }
1055 }
1056
1057
1058 /* Restart the process. */
1059 static void
1060 restart (void)
1061 {
1062 /* First determine the parameters. We do not use the parameters
1063 passed to main() since in case nscd is started by running the
1064 dynamic linker this will not work. Yes, this is not the usual
1065 case but nscd is part of glibc and we occasionally do this. */
1066 size_t buflen = 1024;
1067 char *buf = alloca (buflen);
1068 size_t readlen = 0;
1069 int fd = open ("/proc/self/cmdline", O_RDONLY);
1070 if (fd == -1)
1071 {
1072 dbg_log (_("\
1073 cannot open /proc/self/cmdline: %s; disabling paranoia mode"),
1074 strerror (errno));
1075
1076 paranoia = 0;
1077 return;
1078 }
1079
1080 while (1)
1081 {
1082 ssize_t n = TEMP_FAILURE_RETRY (read (fd, buf + readlen,
1083 buflen - readlen));
1084 if (n == -1)
1085 {
1086 dbg_log (_("\
1087 cannot open /proc/self/cmdline: %s; disabling paranoia mode"),
1088 strerror (errno));
1089
1090 close (fd);
1091 paranoia = 0;
1092 return;
1093 }
1094
1095 readlen += n;
1096
1097 if (readlen < buflen)
1098 break;
1099
1100 /* We might have to extend the buffer. */
1101 size_t old_buflen = buflen;
1102 char *newp = extend_alloca (buf, buflen, 2 * buflen);
1103 buf = memmove (newp, buf, old_buflen);
1104 }
1105
1106 close (fd);
1107
1108 /* Parse the command line. Worst case scenario: every two
1109 characters form one parameter (one character plus NUL). */
1110 char **argv = alloca ((readlen / 2 + 1) * sizeof (argv[0]));
1111 int argc = 0;
1112
1113 char *cp = buf;
1114 while (cp < buf + readlen)
1115 {
1116 argv[argc++] = cp;
1117 cp = (char *) rawmemchr (cp, '\0') + 1;
1118 }
1119 argv[argc] = NULL;
1120
1121 /* Second, change back to the old user if we changed it. */
1122 if (server_user != NULL)
1123 {
1124 if (setuid (old_uid) != 0)
1125 {
1126 dbg_log (_("\
1127 cannot change to old UID: %s; disabling paranoia mode"),
1128 strerror (errno));
1129
1130 paranoia = 0;
1131 return;
1132 }
1133
1134 if (setgid (old_gid) != 0)
1135 {
1136 dbg_log (_("\
1137 cannot change to old GID: %s; disabling paranoia mode"),
1138 strerror (errno));
1139
1140 setuid (server_uid);
1141 paranoia = 0;
1142 return;
1143 }
1144 }
1145
1146 /* Next change back to the old working directory. */
1147 if (chdir (oldcwd) == -1)
1148 {
1149 dbg_log (_("\
1150 cannot change to old working directory: %s; disabling paranoia mode"),
1151 strerror (errno));
1152
1153 if (server_user != NULL)
1154 {
1155 setuid (server_uid);
1156 setgid (server_gid);
1157 }
1158 paranoia = 0;
1159 return;
1160 }
1161
1162 /* Synchronize memory. */
1163 for (int cnt = 0; cnt < lastdb; ++cnt)
1164 {
1165 /* Make sure nobody keeps using the database. */
1166 dbs[cnt].head->timestamp = 0;
1167
1168 if (dbs[cnt].persistent)
1169 // XXX async OK?
1170 msync (dbs[cnt].head, dbs[cnt].memsize, MS_ASYNC);
1171 }
1172
1173 /* The preparations are done. */
1174 execv ("/proc/self/exe", argv);
1175
1176 /* If we come here, we will never be able to re-exec. */
1177 dbg_log (_("re-exec failed: %s; disabling paranoia mode"),
1178 strerror (errno));
1179
1180 if (server_user != NULL)
1181 {
1182 setuid (server_uid);
1183 setgid (server_gid);
1184 }
1185 if (chdir ("/") != 0)
1186 dbg_log (_("cannot change current working directory to \"/\": %s"),
1187 strerror (errno));
1188 paranoia = 0;
1189 }
1190
1191
1192 /* List of file descriptors. */
1193 struct fdlist
1194 {
1195 int fd;
1196 struct fdlist *next;
1197 };
1198 /* Memory allocated for the list. */
1199 static struct fdlist *fdlist;
1200 /* List of currently ready-to-read file descriptors. */
1201 static struct fdlist *readylist;
1202
1203 /* Conditional variable and mutex to signal availability of entries in
1204 READYLIST. The condvar is initialized dynamically since we might
1205 use a different clock depending on availability. */
1206 static pthread_cond_t readylist_cond;
1207 static pthread_mutex_t readylist_lock = PTHREAD_MUTEX_INITIALIZER;
1208
1209 /* The clock to use with the condvar. */
1210 static clockid_t timeout_clock = CLOCK_REALTIME;
1211
1212 /* Number of threads ready to handle the READYLIST. */
1213 static unsigned long int nready;
1214
1215
1216 /* This is the main loop. It is replicated in different threads but the
1217 `poll' call makes sure only one thread handles an incoming connection. */
1218 static void *
1219 __attribute__ ((__noreturn__))
1220 nscd_run (void *p)
1221 {
1222 const long int my_number = (long int) p;
1223 const int run_prune = my_number < lastdb && dbs[my_number].enabled;
1224 struct timespec prune_ts;
1225 int to = 0;
1226 char buf[256];
1227
1228 if (run_prune)
1229 {
1230 setup_thread (&dbs[my_number]);
1231
1232 /* We are running. */
1233 dbs[my_number].head->timestamp = time (NULL);
1234
1235 if (clock_gettime (timeout_clock, &prune_ts) == -1)
1236 /* Should never happen. */
1237 abort ();
1238
1239 /* Compute timeout time. */
1240 prune_ts.tv_sec += CACHE_PRUNE_INTERVAL;
1241 }
1242
1243 /* Initial locking. */
1244 pthread_mutex_lock (&readylist_lock);
1245
1246 /* One more thread available. */
1247 ++nready;
1248
1249 while (1)
1250 {
1251 while (readylist == NULL)
1252 {
1253 if (run_prune)
1254 {
1255 /* Wait, but not forever. */
1256 to = pthread_cond_timedwait (&readylist_cond, &readylist_lock,
1257 &prune_ts);
1258
1259 /* If we were woken and there is no work to be done,
1260 just start pruning. */
1261 if (readylist == NULL && to == ETIMEDOUT)
1262 {
1263 --nready;
1264 pthread_mutex_unlock (&readylist_lock);
1265 goto only_prune;
1266 }
1267 }
1268 else
1269 /* No need to timeout. */
1270 pthread_cond_wait (&readylist_cond, &readylist_lock);
1271 }
1272
1273 struct fdlist *it = readylist->next;
1274 if (readylist->next == readylist)
1275 /* Just one entry on the list. */
1276 readylist = NULL;
1277 else
1278 readylist->next = it->next;
1279
1280 /* Extract the information and mark the record ready to be used
1281 again. */
1282 int fd = it->fd;
1283 it->next = NULL;
1284
1285 /* One more thread available. */
1286 --nready;
1287
1288 /* We are done with the list. */
1289 pthread_mutex_unlock (&readylist_lock);
1290
1291 /* We do not want to block on a short read or so. */
1292 int fl = fcntl (fd, F_GETFL);
1293 if (fl == -1 || fcntl (fd, F_SETFL, fl | O_NONBLOCK) == -1)
1294 goto close_and_out;
1295
1296 /* Now read the request. */
1297 request_header req;
1298 if (__builtin_expect (TEMP_FAILURE_RETRY (read (fd, &req, sizeof (req)))
1299 != sizeof (req), 0))
1300 {
1301 /* We failed to read data. Note that this also might mean we
1302 failed because we would have blocked. */
1303 if (debug_level > 0)
1304 dbg_log (_("short read while reading request: %s"),
1305 strerror_r (errno, buf, sizeof (buf)));
1306 goto close_and_out;
1307 }
1308
1309 /* Check whether this is a valid request type. */
1310 if (req.type < GETPWBYNAME || req.type >= LASTREQ)
1311 goto close_and_out;
1312
1313 /* Some systems have no SO_PEERCRED implementation. They don't
1314 care about security so we don't as well. */
1315 uid_t uid = -1;
1316 #ifdef SO_PEERCRED
1317 pid_t pid = 0;
1318
1319 if (secure_in_use)
1320 {
1321 struct ucred caller;
1322 socklen_t optlen = sizeof (caller);
1323
1324 if (getsockopt (fd, SOL_SOCKET, SO_PEERCRED, &caller, &optlen) < 0)
1325 {
1326 dbg_log (_("error getting callers id: %s"),
1327 strerror_r (errno, buf, sizeof (buf)));
1328 goto close_and_out;
1329 }
1330
1331 if (req.type < GETPWBYNAME || req.type > LASTDBREQ
1332 || serv2db[req.type]->secure)
1333 uid = caller.uid;
1334
1335 pid = caller.pid;
1336 }
1337 else if (__builtin_expect (debug_level > 0, 0))
1338 {
1339 struct ucred caller;
1340 socklen_t optlen = sizeof (caller);
1341
1342 if (getsockopt (fd, SOL_SOCKET, SO_PEERCRED, &caller, &optlen) == 0)
1343 pid = caller.pid;
1344 }
1345 #endif
1346
1347 /* It should not be possible to crash the nscd with a silly
1348 request (i.e., a terribly large key). We limit the size to 1kb. */
1349 #define MAXKEYLEN 1024
1350 if (__builtin_expect (req.key_len, 1) < 0
1351 || __builtin_expect (req.key_len, 1) > MAXKEYLEN)
1352 {
1353 if (debug_level > 0)
1354 dbg_log (_("key length in request too long: %d"), req.key_len);
1355 }
1356 else
1357 {
1358 /* Get the key. */
1359 char keybuf[MAXKEYLEN];
1360
1361 if (__builtin_expect (TEMP_FAILURE_RETRY (read (fd, keybuf,
1362 req.key_len))
1363 != req.key_len, 0))
1364 {
1365 /* Again, this can also mean we would have blocked. */
1366 if (debug_level > 0)
1367 dbg_log (_("short read while reading request key: %s"),
1368 strerror_r (errno, buf, sizeof (buf)));
1369 goto close_and_out;
1370 }
1371
1372 if (__builtin_expect (debug_level, 0) > 0)
1373 {
1374 #ifdef SO_PEERCRED
1375 if (pid != 0)
1376 dbg_log (_("\
1377 handle_request: request received (Version = %d) from PID %ld"),
1378 req.version, (long int) pid);
1379 else
1380 #endif
1381 dbg_log (_("\
1382 handle_request: request received (Version = %d)"), req.version);
1383 }
1384
1385 /* Phew, we got all the data, now process it. */
1386 handle_request (fd, &req, keybuf, uid);
1387 }
1388
1389 close_and_out:
1390 /* We are done. */
1391 close (fd);
1392
1393 /* Check whether we should be pruning the cache. */
1394 assert (run_prune || to == 0);
1395 if (to == ETIMEDOUT)
1396 {
1397 only_prune:
1398 /* The pthread_cond_timedwait() call timed out. It is time
1399 to clean up the cache. */
1400 assert (my_number < lastdb);
1401 prune_cache (&dbs[my_number], time (NULL));
1402
1403 if (clock_gettime (timeout_clock, &prune_ts) == -1)
1404 /* Should never happen. */
1405 abort ();
1406
1407 /* Compute next timeout time. */
1408 prune_ts.tv_sec += CACHE_PRUNE_INTERVAL;
1409
1410 /* In case the list is emtpy we do not want to run the prune
1411 code right away again. */
1412 to = 0;
1413 }
1414
1415 /* Re-locking. */
1416 pthread_mutex_lock (&readylist_lock);
1417
1418 /* One more thread available. */
1419 ++nready;
1420 }
1421 }
1422
1423
1424 static unsigned int nconns;
1425
1426 static void
1427 fd_ready (int fd)
1428 {
1429 pthread_mutex_lock (&readylist_lock);
1430
1431 /* Find an empty entry in FDLIST. */
1432 size_t inner;
1433 for (inner = 0; inner < nconns; ++inner)
1434 if (fdlist[inner].next == NULL)
1435 break;
1436 assert (inner < nconns);
1437
1438 fdlist[inner].fd = fd;
1439
1440 if (readylist == NULL)
1441 readylist = fdlist[inner].next = &fdlist[inner];
1442 else
1443 {
1444 fdlist[inner].next = readylist->next;
1445 readylist = readylist->next = &fdlist[inner];
1446 }
1447
1448 bool do_signal = true;
1449 if (__builtin_expect (nready == 0, 0))
1450 {
1451 ++client_queued;
1452 do_signal = false;
1453
1454 /* Try to start another thread to help out. */
1455 pthread_t th;
1456 if (nthreads < max_nthreads
1457 && pthread_create (&th, &attr, nscd_run,
1458 (void *) (long int) nthreads) == 0)
1459 {
1460 /* We got another thread. */
1461 ++nthreads;
1462 /* The new thread might need a kick. */
1463 do_signal = true;
1464 }
1465
1466 }
1467
1468 pthread_mutex_unlock (&readylist_lock);
1469
1470 /* Tell one of the worker threads there is work to do. */
1471 if (do_signal)
1472 pthread_cond_signal (&readylist_cond);
1473 }
1474
1475
1476 /* Check whether restarting should happen. */
1477 static inline int
1478 restart_p (time_t now)
1479 {
1480 return (paranoia && readylist == NULL && nready == nthreads
1481 && now >= restart_time);
1482 }
1483
1484
1485 /* Array for times a connection was accepted. */
1486 static time_t *starttime;
1487
1488
1489 static void
1490 __attribute__ ((__noreturn__))
1491 main_loop_poll (void)
1492 {
1493 struct pollfd *conns = (struct pollfd *) xmalloc (nconns
1494 * sizeof (conns[0]));
1495
1496 conns[0].fd = sock;
1497 conns[0].events = POLLRDNORM;
1498 size_t nused = 1;
1499 size_t firstfree = 1;
1500
1501 while (1)
1502 {
1503 /* Wait for any event. We wait at most a couple of seconds so
1504 that we can check whether we should close any of the accepted
1505 connections since we have not received a request. */
1506 #define MAX_ACCEPT_TIMEOUT 30
1507 #define MIN_ACCEPT_TIMEOUT 5
1508 #define MAIN_THREAD_TIMEOUT \
1509 (MAX_ACCEPT_TIMEOUT * 1000 \
1510 - ((MAX_ACCEPT_TIMEOUT - MIN_ACCEPT_TIMEOUT) * 1000 * nused) / (2 * nconns))
1511
1512 int n = poll (conns, nused, MAIN_THREAD_TIMEOUT);
1513
1514 time_t now = time (NULL);
1515
1516 /* If there is a descriptor ready for reading or there is a new
1517 connection, process this now. */
1518 if (n > 0)
1519 {
1520 if (conns[0].revents != 0)
1521 {
1522 /* We have a new incoming connection. Accept the connection. */
1523 int fd = TEMP_FAILURE_RETRY (accept (sock, NULL, NULL));
1524
1525 /* use the descriptor if we have not reached the limit. */
1526 if (fd >= 0 && firstfree < nconns)
1527 {
1528 conns[firstfree].fd = fd;
1529 conns[firstfree].events = POLLRDNORM;
1530 starttime[firstfree] = now;
1531 if (firstfree >= nused)
1532 nused = firstfree + 1;
1533
1534 do
1535 ++firstfree;
1536 while (firstfree < nused && conns[firstfree].fd != -1);
1537 }
1538
1539 --n;
1540 }
1541
1542 for (size_t cnt = 1; cnt < nused && n > 0; ++cnt)
1543 if (conns[cnt].revents != 0)
1544 {
1545 fd_ready (conns[cnt].fd);
1546
1547 /* Clean up the CONNS array. */
1548 conns[cnt].fd = -1;
1549 if (cnt < firstfree)
1550 firstfree = cnt;
1551 if (cnt == nused - 1)
1552 do
1553 --nused;
1554 while (conns[nused - 1].fd == -1);
1555
1556 --n;
1557 }
1558 }
1559
1560 /* Now find entries which have timed out. */
1561 assert (nused > 0);
1562
1563 /* We make the timeout length depend on the number of file
1564 descriptors currently used. */
1565 #define ACCEPT_TIMEOUT \
1566 (MAX_ACCEPT_TIMEOUT \
1567 - ((MAX_ACCEPT_TIMEOUT - MIN_ACCEPT_TIMEOUT) * nused) / nconns)
1568 time_t laststart = now - ACCEPT_TIMEOUT;
1569
1570 for (size_t cnt = nused - 1; cnt > 0; --cnt)
1571 {
1572 if (conns[cnt].fd != -1 && starttime[cnt] < laststart)
1573 {
1574 /* Remove the entry, it timed out. */
1575 (void) close (conns[cnt].fd);
1576 conns[cnt].fd = -1;
1577
1578 if (cnt < firstfree)
1579 firstfree = cnt;
1580 if (cnt == nused - 1)
1581 do
1582 --nused;
1583 while (conns[nused - 1].fd == -1);
1584 }
1585 }
1586
1587 if (restart_p (now))
1588 restart ();
1589 }
1590 }
1591
1592
1593 #ifdef HAVE_EPOLL
1594 static void
1595 main_loop_epoll (int efd)
1596 {
1597 struct epoll_event ev = { 0, };
1598 int nused = 1;
1599 size_t highest = 0;
1600
1601 /* Add the socket. */
1602 ev.events = EPOLLRDNORM;
1603 ev.data.fd = sock;
1604 if (epoll_ctl (efd, EPOLL_CTL_ADD, sock, &ev) == -1)
1605 /* We cannot use epoll. */
1606 return;
1607
1608 while (1)
1609 {
1610 struct epoll_event revs[100];
1611 # define nrevs (sizeof (revs) / sizeof (revs[0]))
1612
1613 int n = epoll_wait (efd, revs, nrevs, MAIN_THREAD_TIMEOUT);
1614
1615 time_t now = time (NULL);
1616
1617 for (int cnt = 0; cnt < n; ++cnt)
1618 if (revs[cnt].data.fd == sock)
1619 {
1620 /* A new connection. */
1621 int fd = TEMP_FAILURE_RETRY (accept (sock, NULL, NULL));
1622
1623 if (fd >= 0)
1624 {
1625 /* Try to add the new descriptor. */
1626 ev.data.fd = fd;
1627 if (fd >= nconns
1628 || epoll_ctl (efd, EPOLL_CTL_ADD, fd, &ev) == -1)
1629 /* The descriptor is too large or something went
1630 wrong. Close the descriptor. */
1631 close (fd);
1632 else
1633 {
1634 /* Remember when we accepted the connection. */
1635 starttime[fd] = now;
1636
1637 if (fd > highest)
1638 highest = fd;
1639
1640 ++nused;
1641 }
1642 }
1643 }
1644 else
1645 {
1646 /* Remove the descriptor from the epoll descriptor. */
1647 (void) epoll_ctl (efd, EPOLL_CTL_DEL, revs[cnt].data.fd, NULL);
1648
1649 /* Get a worked to handle the request. */
1650 fd_ready (revs[cnt].data.fd);
1651
1652 /* Reset the time. */
1653 starttime[revs[cnt].data.fd] = 0;
1654 if (revs[cnt].data.fd == highest)
1655 do
1656 --highest;
1657 while (highest > 0 && starttime[highest] == 0);
1658
1659 --nused;
1660 }
1661
1662 /* Now look for descriptors for accepted connections which have
1663 no reply in too long of a time. */
1664 time_t laststart = now - ACCEPT_TIMEOUT;
1665 for (int cnt = highest; cnt > STDERR_FILENO; --cnt)
1666 if (cnt != sock && starttime[cnt] != 0 && starttime[cnt] < laststart)
1667 {
1668 /* We are waiting for this one for too long. Close it. */
1669 (void) epoll_ctl (efd, EPOLL_CTL_DEL, cnt, NULL);
1670
1671 (void) close (cnt);
1672
1673 starttime[cnt] = 0;
1674 if (cnt == highest)
1675 --highest;
1676 }
1677 else if (cnt != sock && starttime[cnt] == 0 && cnt == highest)
1678 --highest;
1679
1680 if (restart_p (now))
1681 restart ();
1682 }
1683 }
1684 #endif
1685
1686
1687 /* Start all the threads we want. The initial process is thread no. 1. */
1688 void
1689 start_threads (void)
1690 {
1691 /* Initialize the conditional variable we will use. The only
1692 non-standard attribute we might use is the clock selection. */
1693 pthread_condattr_t condattr;
1694 pthread_condattr_init (&condattr);
1695
1696 #if defined _POSIX_CLOCK_SELECTION && _POSIX_CLOCK_SELECTION >= 0 \
1697 && defined _POSIX_MONOTONIC_CLOCK && _POSIX_MONOTONIC_CLOCK >= 0
1698 /* Determine whether the monotonous clock is available. */
1699 struct timespec dummy;
1700 # if _POSIX_MONOTONIC_CLOCK == 0
1701 if (sysconf (_SC_MONOTONIC_CLOCK) > 0)
1702 # endif
1703 # if _POSIX_CLOCK_SELECTION == 0
1704 if (sysconf (_SC_CLOCK_SELECTION) > 0)
1705 # endif
1706 if (clock_getres (CLOCK_MONOTONIC, &dummy) == 0
1707 && pthread_condattr_setclock (&condattr, CLOCK_MONOTONIC) == 0)
1708 timeout_clock = CLOCK_MONOTONIC;
1709 #endif
1710
1711 pthread_cond_init (&readylist_cond, &condattr);
1712 pthread_condattr_destroy (&condattr);
1713
1714
1715 /* Create the attribute for the threads. They are all created
1716 detached. */
1717 pthread_attr_init (&attr);
1718 pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
1719 /* Use 1MB stacks, twice as much for 64-bit architectures. */
1720 pthread_attr_setstacksize (&attr, 1024 * 1024 * (sizeof (void *) / 4));
1721
1722 /* We allow less than LASTDB threads only for debugging. */
1723 if (debug_level == 0)
1724 nthreads = MAX (nthreads, lastdb);
1725
1726 int nfailed = 0;
1727 for (long int i = 0; i < nthreads; ++i)
1728 {
1729 pthread_t th;
1730 if (pthread_create (&th, &attr, nscd_run, (void *) (i - nfailed)) != 0)
1731 ++nfailed;
1732 }
1733 if (nthreads - nfailed < lastdb)
1734 {
1735 /* We could not start enough threads. */
1736 dbg_log (_("could only start %d threads; terminating"),
1737 nthreads - nfailed);
1738 exit (1);
1739 }
1740
1741 /* Determine how much room for descriptors we should initially
1742 allocate. This might need to change later if we cap the number
1743 with MAXCONN. */
1744 const long int nfds = sysconf (_SC_OPEN_MAX);
1745 #define MINCONN 32
1746 #define MAXCONN 16384
1747 if (nfds == -1 || nfds > MAXCONN)
1748 nconns = MAXCONN;
1749 else if (nfds < MINCONN)
1750 nconns = MINCONN;
1751 else
1752 nconns = nfds;
1753
1754 /* We need memory to pass descriptors on to the worker threads. */
1755 fdlist = (struct fdlist *) xcalloc (nconns, sizeof (fdlist[0]));
1756 /* Array to keep track when connection was accepted. */
1757 starttime = (time_t *) xcalloc (nconns, sizeof (starttime[0]));
1758
1759 /* In the main thread we execute the loop which handles incoming
1760 connections. */
1761 #ifdef HAVE_EPOLL
1762 int efd = epoll_create (100);
1763 if (efd != -1)
1764 {
1765 main_loop_epoll (efd);
1766 close (efd);
1767 }
1768 #endif
1769
1770 main_loop_poll ();
1771 }
1772
1773
1774 /* Look up the uid, gid, and supplementary groups to run nscd as. When
1775 this function is called, we are not listening on the nscd socket yet so
1776 we can just use the ordinary lookup functions without causing a lockup */
1777 static void
1778 begin_drop_privileges (void)
1779 {
1780 struct passwd *pwd = getpwnam (server_user);
1781
1782 if (pwd == NULL)
1783 {
1784 dbg_log (_("Failed to run nscd as user '%s'"), server_user);
1785 error (EXIT_FAILURE, 0, _("Failed to run nscd as user '%s'"),
1786 server_user);
1787 }
1788
1789 server_uid = pwd->pw_uid;
1790 server_gid = pwd->pw_gid;
1791
1792 /* Save the old UID/GID if we have to change back. */
1793 if (paranoia)
1794 {
1795 old_uid = getuid ();
1796 old_gid = getgid ();
1797 }
1798
1799 if (getgrouplist (server_user, server_gid, NULL, &server_ngroups) == 0)
1800 {
1801 /* This really must never happen. */
1802 dbg_log (_("Failed to run nscd as user '%s'"), server_user);
1803 error (EXIT_FAILURE, errno, _("initial getgrouplist failed"));
1804 }
1805
1806 server_groups = (gid_t *) xmalloc (server_ngroups * sizeof (gid_t));
1807
1808 if (getgrouplist (server_user, server_gid, server_groups, &server_ngroups)
1809 == -1)
1810 {
1811 dbg_log (_("Failed to run nscd as user '%s'"), server_user);
1812 error (EXIT_FAILURE, errno, _("getgrouplist failed"));
1813 }
1814 }
1815
1816
1817 /* Call setgroups(), setgid(), and setuid() to drop root privileges and
1818 run nscd as the user specified in the configuration file. */
1819 static void
1820 finish_drop_privileges (void)
1821 {
1822 if (setgroups (server_ngroups, server_groups) == -1)
1823 {
1824 dbg_log (_("Failed to run nscd as user '%s'"), server_user);
1825 error (EXIT_FAILURE, errno, _("setgroups failed"));
1826 }
1827
1828 if (setgid (server_gid) == -1)
1829 {
1830 dbg_log (_("Failed to run nscd as user '%s'"), server_user);
1831 perror ("setgid");
1832 exit (4);
1833 }
1834
1835 if (setuid (server_uid) == -1)
1836 {
1837 dbg_log (_("Failed to run nscd as user '%s'"), server_user);
1838 perror ("setuid");
1839 exit (4);
1840 }
1841 }