2005-04-17 David S. Miller <davem@davemloft.net>
[kopensolaris-gnu/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 /* Initialize database information structures.  */
203 void
204 nscd_init (void)
205 {
206   /* Secure mode and unprivileged mode are incompatible */
207   if (server_user != NULL && secure_in_use)
208     {
209       dbg_log (_("Cannot run nscd in secure mode as unprivileged user"));
210       exit (1);
211     }
212
213   /* Look up unprivileged uid/gid/groups before we start listening on the
214      socket  */
215   if (server_user != NULL)
216     begin_drop_privileges ();
217
218   if (nthreads == -1)
219     /* No configuration for this value, assume a default.  */
220     nthreads = 2 * lastdb;
221
222   for (size_t cnt = 0; cnt < lastdb; ++cnt)
223     if (dbs[cnt].enabled)
224       {
225         pthread_rwlock_init (&dbs[cnt].lock, NULL);
226         pthread_mutex_init (&dbs[cnt].memlock, NULL);
227
228         if (dbs[cnt].persistent)
229           {
230             /* Try to open the appropriate file on disk.  */
231             int fd = open (dbs[cnt].db_filename, O_RDWR);
232             if (fd != -1)
233               {
234                 struct stat64 st;
235                 void *mem;
236                 size_t total;
237                 struct database_pers_head head;
238                 ssize_t n = TEMP_FAILURE_RETRY (read (fd, &head,
239                                                       sizeof (head)));
240                 if (n != sizeof (head) || fstat64 (fd, &st) != 0)
241                   {
242                   fail_db:
243                     dbg_log (_("invalid persistent database file \"%s\": %s"),
244                              dbs[cnt].db_filename, strerror (errno));
245                     dbs[cnt].persistent = 0;
246                   }
247                 else if (head.module == 0 && head.data_size == 0)
248                   {
249                     /* The file has been created, but the head has not been
250                        initialized yet.  Remove the old file.  */
251                     unlink (dbs[cnt].db_filename);
252                   }
253                 else if (head.header_size != (int) sizeof (head))
254                   {
255                     dbg_log (_("invalid persistent database file \"%s\": %s"),
256                              dbs[cnt].db_filename,
257                              _("header size does not match"));
258                     dbs[cnt].persistent = 0;
259                   }
260                 else if ((total = (sizeof (head)
261                                    + roundup (head.module * sizeof (ref_t),
262                                               ALIGN)
263                                    + head.data_size))
264                          > st.st_size)
265                   {
266                     dbg_log (_("invalid persistent database file \"%s\": %s"),
267                              dbs[cnt].db_filename,
268                              _("file size does not match"));
269                     dbs[cnt].persistent = 0;
270                   }
271                 else if ((mem = mmap (NULL, total, PROT_READ | PROT_WRITE,
272                                       MAP_SHARED, fd, 0)) == MAP_FAILED)
273                   goto fail_db;
274                 else
275                   {
276                     /* Success.  We have the database.  */
277                     dbs[cnt].head = mem;
278                     dbs[cnt].memsize = total;
279                     dbs[cnt].data = (char *)
280                       &dbs[cnt].head->array[roundup (dbs[cnt].head->module,
281                                                      ALIGN / sizeof (ref_t))];
282                     dbs[cnt].mmap_used = true;
283
284                     if (dbs[cnt].suggested_module > head.module)
285                       dbg_log (_("suggested size of table for database %s larger than the persistent database's table"),
286                                dbnames[cnt]);
287
288                     dbs[cnt].wr_fd = fd;
289                     fd = -1;
290                     /* We also need a read-only descriptor.  */
291                     if (dbs[cnt].shared)
292                       {
293                         dbs[cnt].ro_fd = open (dbs[cnt].db_filename, O_RDONLY);
294                         if (dbs[cnt].ro_fd == -1)
295                           dbg_log (_("\
296 cannot create read-only descriptor for \"%s\"; no mmap"),
297                                    dbs[cnt].db_filename);
298                       }
299
300                     // XXX Shall we test whether the descriptors actually
301                     // XXX point to the same file?
302                   }
303
304                 /* Close the file descriptors in case something went
305                    wrong in which case the variable have not been
306                    assigned -1.  */
307                 if (fd != -1)
308                   close (fd);
309               }
310           }
311
312         if (dbs[cnt].head == NULL)
313           {
314             /* No database loaded.  Allocate the data structure,
315                possibly on disk.  */
316             struct database_pers_head head;
317             size_t total = (sizeof (head)
318                             + roundup (dbs[cnt].suggested_module
319                                        * sizeof (ref_t), ALIGN)
320                             + (dbs[cnt].suggested_module
321                                * DEFAULT_DATASIZE_PER_BUCKET));
322
323             /* Try to create the database.  If we do not need a
324                persistent database create a temporary file.  */
325             int fd;
326             int ro_fd = -1;
327             if (dbs[cnt].persistent)
328               {
329                 fd = open (dbs[cnt].db_filename,
330                            O_RDWR | O_CREAT | O_EXCL | O_TRUNC,
331                            S_IRUSR | S_IWUSR);
332                 if (fd != -1 && dbs[cnt].shared)
333                   ro_fd = open (dbs[cnt].db_filename, O_RDONLY);
334               }
335             else
336               {
337                 char fname[] = _PATH_NSCD_XYZ_DB_TMP;
338                 fd = mkstemp (fname);
339
340                 /* We do not need the file name anymore after we
341                    opened another file descriptor in read-only mode.  */
342                 if (fd != -1)
343                   {
344                     if (dbs[cnt].shared)
345                       ro_fd = open (fname, O_RDONLY);
346
347                     unlink (fname);
348                   }
349               }
350
351             if (fd == -1)
352               {
353                 if (errno == EEXIST)
354                   {
355                     dbg_log (_("database for %s corrupted or simultaneously used; remove %s manually if necessary and restart"),
356                              dbnames[cnt], dbs[cnt].db_filename);
357                     // XXX Correct way to terminate?
358                     exit (1);
359                   }
360
361                 if  (dbs[cnt].persistent)
362                   dbg_log (_("cannot create %s; no persistent database used"),
363                            dbs[cnt].db_filename);
364                 else
365                   dbg_log (_("cannot create %s; no sharing possible"),
366                            dbs[cnt].db_filename);
367
368                 dbs[cnt].persistent = 0;
369                 // XXX remember: no mmap
370               }
371             else
372               {
373                 /* Tell the user if we could not create the read-only
374                    descriptor.  */
375                 if (ro_fd == -1 && dbs[cnt].shared)
376                   dbg_log (_("\
377 cannot create read-only descriptor for \"%s\"; no mmap"),
378                            dbs[cnt].db_filename);
379
380                 /* Before we create the header, initialiye the hash
381                    table.  So that if we get interrupted if writing
382                    the header we can recognize a partially initialized
383                    database.  */
384                 size_t ps = sysconf (_SC_PAGESIZE);
385                 char tmpbuf[ps];
386                 assert (~ENDREF == 0);
387                 memset (tmpbuf, '\xff', ps);
388
389                 size_t remaining = dbs[cnt].suggested_module * sizeof (ref_t);
390                 off_t offset = sizeof (head);
391
392                 size_t towrite;
393                 if (offset % ps != 0)
394                   {
395                     towrite = MIN (remaining, ps - (offset % ps));
396                     pwrite (fd, tmpbuf, towrite, offset);
397                     offset += towrite;
398                     remaining -= towrite;
399                   }
400
401                 while (remaining > ps)
402                   {
403                     pwrite (fd, tmpbuf, ps, offset);
404                     offset += ps;
405                     remaining -= ps;
406                   }
407
408                 if (remaining > 0)
409                   pwrite (fd, tmpbuf, remaining, offset);
410
411                 /* Create the header of the file.  */
412                 struct database_pers_head head =
413                   {
414                     .version = DB_VERSION,
415                     .header_size = sizeof (head),
416                     .module = dbs[cnt].suggested_module,
417                     .data_size = (dbs[cnt].suggested_module
418                                   * DEFAULT_DATASIZE_PER_BUCKET),
419                     .first_free = 0
420                   };
421                 void *mem;
422
423                 if ((TEMP_FAILURE_RETRY (write (fd, &head, sizeof (head)))
424                      != sizeof (head))
425                     || ftruncate (fd, total) != 0
426                     || (mem = mmap (NULL, total, PROT_READ | PROT_WRITE,
427                                     MAP_SHARED, fd, 0)) == MAP_FAILED)
428                   {
429                     unlink (dbs[cnt].db_filename);
430                     dbg_log (_("cannot write to database file %s: %s"),
431                              dbs[cnt].db_filename, strerror (errno));
432                     dbs[cnt].persistent = 0;
433                   }
434                 else
435                   {
436                     /* Success.  */
437                     dbs[cnt].head = mem;
438                     dbs[cnt].data = (char *)
439                       &dbs[cnt].head->array[roundup (dbs[cnt].head->module,
440                                                      ALIGN / sizeof (ref_t))];
441                     dbs[cnt].memsize = total;
442                     dbs[cnt].mmap_used = true;
443
444                     /* Remember the descriptors.  */
445                     dbs[cnt].wr_fd = fd;
446                     dbs[cnt].ro_fd = ro_fd;
447                     fd = -1;
448                     ro_fd = -1;
449                   }
450
451                 if (fd != -1)
452                   close (fd);
453                 if (ro_fd != -1)
454                   close (ro_fd);
455               }
456           }
457
458         if (paranoia
459             && ((dbs[cnt].wr_fd != -1
460                  && fcntl (dbs[cnt].wr_fd, F_SETFD, FD_CLOEXEC) == -1)
461                 || (dbs[cnt].ro_fd != -1
462                     && fcntl (dbs[cnt].ro_fd, F_SETFD, FD_CLOEXEC) == -1)))
463           {
464             dbg_log (_("\
465 cannot set socket to close on exec: %s; disabling paranoia mode"),
466                      strerror (errno));
467             paranoia = 0;
468           }
469
470         if (dbs[cnt].head == NULL)
471           {
472             /* We do not use the persistent database.  Just
473                create an in-memory data structure.  */
474             assert (! dbs[cnt].persistent);
475
476             dbs[cnt].head = xmalloc (sizeof (struct database_pers_head)
477                                      + (dbs[cnt].suggested_module
478                                         * sizeof (ref_t)));
479             memset (dbs[cnt].head, '\0', sizeof (dbs[cnt].head));
480             assert (~ENDREF == 0);
481             memset (dbs[cnt].head->array, '\xff',
482                     dbs[cnt].suggested_module * sizeof (ref_t));
483             dbs[cnt].head->module = dbs[cnt].suggested_module;
484             dbs[cnt].head->data_size = (DEFAULT_DATASIZE_PER_BUCKET
485                                         * dbs[cnt].head->module);
486             dbs[cnt].data = xmalloc (dbs[cnt].head->data_size);
487             dbs[cnt].head->first_free = 0;
488
489             dbs[cnt].shared = 0;
490             assert (dbs[cnt].ro_fd == -1);
491           }
492
493         if (dbs[cnt].check_file)
494           {
495             /* We need the modification date of the file.  */
496             struct stat st;
497
498             if (stat (dbs[cnt].filename, &st) < 0)
499               {
500                 /* We cannot stat() the file, disable file checking.  */
501                 dbg_log (_("cannot stat() file `%s': %s"),
502                          dbs[cnt].filename, strerror (errno));
503                 dbs[cnt].check_file = 0;
504               }
505             else
506               dbs[cnt].file_mtime = st.st_mtime;
507           }
508       }
509
510   /* Create the socket.  */
511   sock = socket (AF_UNIX, SOCK_STREAM, 0);
512   if (sock < 0)
513     {
514       dbg_log (_("cannot open socket: %s"), strerror (errno));
515       exit (1);
516     }
517   /* Bind a name to the socket.  */
518   struct sockaddr_un sock_addr;
519   sock_addr.sun_family = AF_UNIX;
520   strcpy (sock_addr.sun_path, _PATH_NSCDSOCKET);
521   if (bind (sock, (struct sockaddr *) &sock_addr, sizeof (sock_addr)) < 0)
522     {
523       dbg_log ("%s: %s", _PATH_NSCDSOCKET, strerror (errno));
524       exit (1);
525     }
526
527   /* We don't want to get stuck on accept.  */
528   int fl = fcntl (sock, F_GETFL);
529   if (fl == -1 || fcntl (sock, F_SETFL, fl | O_NONBLOCK) == -1)
530     {
531       dbg_log (_("cannot change socket to nonblocking mode: %s"),
532                strerror (errno));
533       exit (1);
534     }
535
536   /* The descriptor needs to be closed on exec.  */
537   if (paranoia && fcntl (sock, F_SETFD, FD_CLOEXEC) == -1)
538     {
539       dbg_log (_("cannot set socket to close on exec: %s"),
540                strerror (errno));
541       exit (1);
542     }
543
544   /* Set permissions for the socket.  */
545   chmod (_PATH_NSCDSOCKET, DEFFILEMODE);
546
547   /* Set the socket up to accept connections.  */
548   if (listen (sock, SOMAXCONN) < 0)
549     {
550       dbg_log (_("cannot enable socket to accept connections: %s"),
551                strerror (errno));
552       exit (1);
553     }
554
555   /* Change to unprivileged uid/gid/groups if specifed in config file */
556   if (server_user != NULL)
557     finish_drop_privileges ();
558 }
559
560
561 /* Close the connections.  */
562 void
563 close_sockets (void)
564 {
565   close (sock);
566 }
567
568
569 static void
570 invalidate_cache (char *key)
571 {
572   dbtype number;
573
574   if (strcmp (key, "passwd") == 0)
575     number = pwddb;
576   else if (strcmp (key, "group") == 0)
577     number = grpdb;
578   else if (__builtin_expect (strcmp (key, "hosts"), 0) == 0)
579     {
580       number = hstdb;
581
582       /* Re-initialize the resolver.  resolv.conf might have changed.  */
583       res_init ();
584     }
585   else
586     return;
587
588   if (dbs[number].enabled)
589     prune_cache (&dbs[number], LONG_MAX);
590 }
591
592
593 #ifdef SCM_RIGHTS
594 static void
595 send_ro_fd (struct database_dyn *db, char *key, int fd)
596 {
597   /* If we do not have an read-only file descriptor do nothing.  */
598   if (db->ro_fd == -1)
599     return;
600
601   /* We need to send some data along with the descriptor.  */
602   struct iovec iov[1];
603   iov[0].iov_base = key;
604   iov[0].iov_len = strlen (key) + 1;
605
606   /* Prepare the control message to transfer the descriptor.  */
607   char buf[CMSG_SPACE (sizeof (int))];
608   struct msghdr msg = { .msg_iov = iov, .msg_iovlen = 1,
609                         .msg_control = buf, .msg_controllen = sizeof (buf) };
610   struct cmsghdr *cmsg = CMSG_FIRSTHDR (&msg);
611
612   cmsg->cmsg_level = SOL_SOCKET;
613   cmsg->cmsg_type = SCM_RIGHTS;
614   cmsg->cmsg_len = CMSG_LEN (sizeof (int));
615
616   *(int *) CMSG_DATA (cmsg) = db->ro_fd;
617
618   msg.msg_controllen = cmsg->cmsg_len;
619
620   /* Send the control message.  We repeat when we are interrupted but
621      everything else is ignored.  */
622 #ifndef MSG_NOSIGNAL
623 # define MSG_NOSIGNAL 0
624 #endif
625   (void) TEMP_FAILURE_RETRY (sendmsg (fd, &msg, MSG_NOSIGNAL));
626
627   if (__builtin_expect (debug_level > 0, 0))
628     dbg_log (_("provide access to FD %d, for %s"), db->ro_fd, key);
629 }
630 #endif  /* SCM_RIGHTS */
631
632
633 /* Handle new request.  */
634 static void
635 handle_request (int fd, request_header *req, void *key, uid_t uid)
636 {
637   if (__builtin_expect (req->version, NSCD_VERSION) != NSCD_VERSION)
638     {
639       if (debug_level > 0)
640         dbg_log (_("\
641 cannot handle old request version %d; current version is %d"),
642                  req->version, NSCD_VERSION);
643       return;
644     }
645
646   /* Make the SELinux check before we go on to the standard checks.  We
647      need to verify that the request type is valid, since it has not
648      yet been checked at this point.  */
649   if (selinux_enabled
650       && __builtin_expect (req->type, GETPWBYNAME) >= GETPWBYNAME
651       && __builtin_expect (req->type, LASTREQ) < LASTREQ
652       && nscd_request_avc_has_perm (fd, req->type) != 0)
653     return;
654
655   struct database_dyn *db = serv2db[req->type];
656
657   // XXX Clean up so that each new command need not introduce a
658   // XXX new conditional.
659   if ((__builtin_expect (req->type, GETPWBYNAME) >= GETPWBYNAME
660        && __builtin_expect (req->type, LASTDBREQ) <= LASTDBREQ)
661       || req->type == GETAI || req->type == INITGROUPS)
662     {
663       if (__builtin_expect (debug_level, 0) > 0)
664         {
665           if (req->type == GETHOSTBYADDR || req->type == GETHOSTBYADDRv6)
666             {
667               char buf[INET6_ADDRSTRLEN];
668
669               dbg_log ("\t%s (%s)", serv2str[req->type],
670                        inet_ntop (req->type == GETHOSTBYADDR
671                                   ? AF_INET : AF_INET6,
672                                   key, buf, sizeof (buf)));
673             }
674           else
675             dbg_log ("\t%s (%s)", serv2str[req->type], (char *) key);
676         }
677
678       /* Is this service enabled?  */
679       if (!db->enabled)
680         {
681           /* No, sent the prepared record.  */
682           if (TEMP_FAILURE_RETRY (write (fd, db->disabled_iov->iov_base,
683                                          db->disabled_iov->iov_len))
684               != (ssize_t) db->disabled_iov->iov_len
685               && __builtin_expect (debug_level, 0) > 0)
686             {
687               /* We have problems sending the result.  */
688               char buf[256];
689               dbg_log (_("cannot write result: %s"),
690                        strerror_r (errno, buf, sizeof (buf)));
691             }
692
693           return;
694         }
695
696       /* Be sure we can read the data.  */
697       if (__builtin_expect (pthread_rwlock_tryrdlock (&db->lock) != 0, 0))
698         {
699           ++db->head->rdlockdelayed;
700           pthread_rwlock_rdlock (&db->lock);
701         }
702
703       /* See whether we can handle it from the cache.  */
704       struct datahead *cached;
705       cached = (struct datahead *) cache_search (req->type, key, req->key_len,
706                                                  db, uid);
707       if (cached != NULL)
708         {
709           /* Hurray it's in the cache.  */
710           if (writeall (fd, cached->data, cached->recsize)
711               != cached->recsize
712               && __builtin_expect (debug_level, 0) > 0)
713             {
714               /* We have problems sending the result.  */
715               char buf[256];
716               dbg_log (_("cannot write result: %s"),
717                        strerror_r (errno, buf, sizeof (buf)));
718             }
719
720           pthread_rwlock_unlock (&db->lock);
721
722           return;
723         }
724
725       pthread_rwlock_unlock (&db->lock);
726     }
727   else if (__builtin_expect (debug_level, 0) > 0)
728     {
729       if (req->type == INVALIDATE)
730         dbg_log ("\t%s (%s)", serv2str[req->type], (char *) key);
731       else
732         dbg_log ("\t%s", serv2str[req->type]);
733     }
734
735   /* Handle the request.  */
736   switch (req->type)
737     {
738     case GETPWBYNAME:
739       addpwbyname (db, fd, req, key, uid);
740       break;
741
742     case GETPWBYUID:
743       addpwbyuid (db, fd, req, key, uid);
744       break;
745
746     case GETGRBYNAME:
747       addgrbyname (db, fd, req, key, uid);
748       break;
749
750     case GETGRBYGID:
751       addgrbygid (db, fd, req, key, uid);
752       break;
753
754     case GETHOSTBYNAME:
755       addhstbyname (db, fd, req, key, uid);
756       break;
757
758     case GETHOSTBYNAMEv6:
759       addhstbynamev6 (db, fd, req, key, uid);
760       break;
761
762     case GETHOSTBYADDR:
763       addhstbyaddr (db, fd, req, key, uid);
764       break;
765
766     case GETHOSTBYADDRv6:
767       addhstbyaddrv6 (db, fd, req, key, uid);
768       break;
769
770     case GETAI:
771       addhstai (db, fd, req, key, uid);
772       break;
773
774     case INITGROUPS:
775       addinitgroups (db, fd, req, key, uid);
776       break;
777
778     case GETSTAT:
779     case SHUTDOWN:
780     case INVALIDATE:
781       if (! secure_in_use)
782         {
783           /* Get the callers credentials.  */
784 #ifdef SO_PEERCRED
785           struct ucred caller;
786           socklen_t optlen = sizeof (caller);
787
788           if (getsockopt (fd, SOL_SOCKET, SO_PEERCRED, &caller, &optlen) < 0)
789             {
790               char buf[256];
791
792               dbg_log (_("error getting callers id: %s"),
793                        strerror_r (errno, buf, sizeof (buf)));
794               break;
795             }
796
797           uid = caller.uid;
798 #else
799           /* Some systems have no SO_PEERCRED implementation.  They don't
800              care about security so we don't as well.  */
801           uid = 0;
802 #endif
803         }
804
805       /* Accept shutdown, getstat and invalidate only from root.  For
806          the stat call also allow the user specified in the config file.  */
807       if (req->type == GETSTAT)
808         {
809           if (uid == 0 || uid == stat_uid)
810             send_stats (fd, dbs);
811         }
812       else if (uid == 0)
813         {
814           if (req->type == INVALIDATE)
815             invalidate_cache (key);
816           else
817             termination_handler (0);
818         }
819       break;
820
821     case GETFDPW:
822     case GETFDGR:
823     case GETFDHST:
824 #ifdef SCM_RIGHTS
825       send_ro_fd (serv2db[req->type], key, fd);
826 #endif
827       break;
828
829     default:
830       /* Ignore the command, it's nothing we know.  */
831       break;
832     }
833 }
834
835
836 /* Restart the process.  */
837 static void
838 restart (void)
839 {
840   /* First determine the parameters.  We do not use the parameters
841      passed to main() since in case nscd is started by running the
842      dynamic linker this will not work.  Yes, this is not the usual
843      case but nscd is part of glibc and we occasionally do this.  */
844   size_t buflen = 1024;
845   char *buf = alloca (buflen);
846   size_t readlen = 0;
847   int fd = open ("/proc/self/cmdline", O_RDONLY);
848   if (fd == -1)
849     {
850       dbg_log (_("\
851 cannot open /proc/self/cmdline: %s; disabling paranoia mode"),
852                strerror (errno));
853
854       paranoia = 0;
855       return;
856     }
857
858   while (1)
859     {
860       ssize_t n = TEMP_FAILURE_RETRY (read (fd, buf + readlen,
861                                             buflen - readlen));
862       if (n == -1)
863         {
864           dbg_log (_("\
865 cannot open /proc/self/cmdline: %s; disabling paranoia mode"),
866                    strerror (errno));
867
868           close (fd);
869           paranoia = 0;
870           return;
871         }
872
873       readlen += n;
874
875       if (readlen < buflen)
876         break;
877
878       /* We might have to extend the buffer.  */
879       size_t old_buflen = buflen;
880       char *newp = extend_alloca (buf, buflen, 2 * buflen);
881       buf = memmove (newp, buf, old_buflen);
882     }
883
884   close (fd);
885
886   /* Parse the command line.  Worst case scenario: every two
887      characters form one parameter (one character plus NUL).  */
888   char **argv = alloca ((readlen / 2 + 1) * sizeof (argv[0]));
889   int argc = 0;
890
891   char *cp = buf;
892   while (cp < buf + readlen)
893     {
894       argv[argc++] = cp;
895       cp = (char *) rawmemchr (cp, '\0') + 1;
896     }
897   argv[argc] = NULL;
898
899   /* Second, change back to the old user if we changed it.  */
900   if (server_user != NULL)
901     {
902       if (setuid (old_uid) != 0)
903         {
904           dbg_log (_("\
905 cannot change to old UID: %s; disabling paranoia mode"),
906                    strerror (errno));
907
908           paranoia = 0;
909           return;
910         }
911
912       if (setgid (old_gid) != 0)
913         {
914           dbg_log (_("\
915 cannot change to old GID: %s; disabling paranoia mode"),
916                    strerror (errno));
917
918           setuid (server_uid);
919           paranoia = 0;
920           return;
921         }
922     }
923
924   /* Next change back to the old working directory.  */
925   if (chdir (oldcwd) == -1)
926     {
927       dbg_log (_("\
928 cannot change to old working directory: %s; disabling paranoia mode"),
929                strerror (errno));
930
931       if (server_user != NULL)
932         {
933           setuid (server_uid);
934           setgid (server_gid);
935         }
936       paranoia = 0;
937       return;
938     }
939
940   /* Synchronize memory.  */
941   for (int cnt = 0; cnt < lastdb; ++cnt)
942     {
943       /* Make sure nobody keeps using the database.  */
944       dbs[cnt].head->timestamp = 0;
945
946       if (dbs[cnt].persistent)
947         // XXX async OK?
948         msync (dbs[cnt].head, dbs[cnt].memsize, MS_ASYNC);
949     }
950
951   /* The preparations are done.  */
952   execv ("/proc/self/exe", argv);
953
954   /* If we come here, we will never be able to re-exec.  */
955   dbg_log (_("re-exec failed: %s; disabling paranoia mode"),
956            strerror (errno));
957
958   if (server_user != NULL)
959     {
960       setuid (server_uid);
961       setgid (server_gid);
962     }
963   chdir ("/");
964   paranoia = 0;
965 }
966
967
968 /* List of file descriptors.  */
969 struct fdlist
970 {
971   int fd;
972   struct fdlist *next;
973 };
974 /* Memory allocated for the list.  */
975 static struct fdlist *fdlist;
976 /* List of currently ready-to-read file descriptors.  */
977 static struct fdlist *readylist;
978
979 /* Conditional variable and mutex to signal availability of entries in
980    READYLIST.  The condvar is initialized dynamically since we might
981    use a different clock depending on availability.  */
982 static pthread_cond_t readylist_cond;
983 static pthread_mutex_t readylist_lock = PTHREAD_MUTEX_INITIALIZER;
984
985 /* The clock to use with the condvar.  */
986 static clockid_t timeout_clock = CLOCK_REALTIME;
987
988 /* Number of threads ready to handle the READYLIST.  */
989 static unsigned long int nready;
990
991
992 /* This is the main loop.  It is replicated in different threads but the
993    `poll' call makes sure only one thread handles an incoming connection.  */
994 static void *
995 __attribute__ ((__noreturn__))
996 nscd_run (void *p)
997 {
998   const long int my_number = (long int) p;
999   const int run_prune = my_number < lastdb && dbs[my_number].enabled;
1000   struct timespec prune_ts;
1001   int to = 0;
1002   char buf[256];
1003
1004   if (run_prune)
1005     {
1006       setup_thread (&dbs[my_number]);
1007
1008       /* We are running.  */
1009       dbs[my_number].head->timestamp = time (NULL);
1010
1011       if (clock_gettime (timeout_clock, &prune_ts) == -1)
1012         /* Should never happen.  */
1013         abort ();
1014
1015       /* Compute timeout time.  */
1016       prune_ts.tv_sec += CACHE_PRUNE_INTERVAL;
1017     }
1018
1019   /* Initial locking.  */
1020   pthread_mutex_lock (&readylist_lock);
1021
1022   /* One more thread available.  */
1023   ++nready;
1024
1025   while (1)
1026     {
1027       while (readylist == NULL)
1028         {
1029           if (run_prune)
1030             {
1031               /* Wait, but not forever.  */
1032               to = pthread_cond_timedwait (&readylist_cond, &readylist_lock,
1033                                            &prune_ts);
1034
1035               /* If we were woken and there is no work to be done,
1036                  just start pruning.  */
1037               if (readylist == NULL && to == ETIMEDOUT)
1038                 {
1039                   --nready;
1040                   pthread_mutex_unlock (&readylist_lock);
1041                   goto only_prune;
1042                 }
1043             }
1044           else
1045             /* No need to timeout.  */
1046             pthread_cond_wait (&readylist_cond, &readylist_lock);
1047         }
1048
1049       struct fdlist *it = readylist->next;
1050       if (readylist->next == readylist)
1051         /* Just one entry on the list.  */
1052         readylist = NULL;
1053       else
1054         readylist->next = it->next;
1055
1056       /* Extract the information and mark the record ready to be used
1057          again.  */
1058       int fd = it->fd;
1059       it->next = NULL;
1060
1061       /* One more thread available.  */
1062       --nready;
1063
1064       /* We are done with the list.  */
1065       pthread_mutex_unlock (&readylist_lock);
1066
1067       /* We do not want to block on a short read or so.  */
1068       int fl = fcntl (fd, F_GETFL);
1069       if (fl == -1 || fcntl (fd, F_SETFL, fl | O_NONBLOCK) == -1)
1070         goto close_and_out;
1071
1072       /* Now read the request.  */
1073       request_header req;
1074       if (__builtin_expect (TEMP_FAILURE_RETRY (read (fd, &req, sizeof (req)))
1075                             != sizeof (req), 0))
1076         {
1077           /* We failed to read data.  Note that this also might mean we
1078              failed because we would have blocked.  */
1079           if (debug_level > 0)
1080             dbg_log (_("short read while reading request: %s"),
1081                      strerror_r (errno, buf, sizeof (buf)));
1082           goto close_and_out;
1083         }
1084
1085       /* Check whether this is a valid request type.  */
1086       if (req.type < GETPWBYNAME || req.type >= LASTREQ)
1087         goto close_and_out;
1088
1089       /* Some systems have no SO_PEERCRED implementation.  They don't
1090          care about security so we don't as well.  */
1091       uid_t uid = -1;
1092 #ifdef SO_PEERCRED
1093       pid_t pid = 0;
1094
1095       if (secure_in_use)
1096         {
1097           struct ucred caller;
1098           socklen_t optlen = sizeof (caller);
1099
1100           if (getsockopt (fd, SOL_SOCKET, SO_PEERCRED, &caller, &optlen) < 0)
1101             {
1102               dbg_log (_("error getting callers id: %s"),
1103                        strerror_r (errno, buf, sizeof (buf)));
1104               goto close_and_out;
1105             }
1106
1107           if (req.type < GETPWBYNAME || req.type > LASTDBREQ
1108               || serv2db[req.type]->secure)
1109             uid = caller.uid;
1110
1111           pid = caller.pid;
1112         }
1113       else if (__builtin_expect (debug_level > 0, 0))
1114         {
1115           struct ucred caller;
1116           socklen_t optlen = sizeof (caller);
1117
1118           if (getsockopt (fd, SOL_SOCKET, SO_PEERCRED, &caller, &optlen) == 0)
1119             pid = caller.pid;
1120         }
1121 #endif
1122
1123       /* It should not be possible to crash the nscd with a silly
1124          request (i.e., a terribly large key).  We limit the size to 1kb.  */
1125 #define MAXKEYLEN 1024
1126       if (__builtin_expect (req.key_len, 1) < 0
1127           || __builtin_expect (req.key_len, 1) > MAXKEYLEN)
1128         {
1129           if (debug_level > 0)
1130             dbg_log (_("key length in request too long: %d"), req.key_len);
1131         }
1132       else
1133         {
1134           /* Get the key.  */
1135           char keybuf[MAXKEYLEN];
1136
1137           if (__builtin_expect (TEMP_FAILURE_RETRY (read (fd, keybuf,
1138                                                           req.key_len))
1139                                 != req.key_len, 0))
1140             {
1141               /* Again, this can also mean we would have blocked.  */
1142               if (debug_level > 0)
1143                 dbg_log (_("short read while reading request key: %s"),
1144                          strerror_r (errno, buf, sizeof (buf)));
1145               goto close_and_out;
1146             }
1147
1148           if (__builtin_expect (debug_level, 0) > 0)
1149             {
1150 #ifdef SO_PEERCRED
1151               if (pid != 0)
1152                 dbg_log (_("\
1153 handle_request: request received (Version = %d) from PID %ld"),
1154                          req.version, (long int) pid);
1155               else
1156 #endif
1157                 dbg_log (_("\
1158 handle_request: request received (Version = %d)"), req.version);
1159             }
1160
1161           /* Phew, we got all the data, now process it.  */
1162           handle_request (fd, &req, keybuf, uid);
1163         }
1164
1165     close_and_out:
1166       /* We are done.  */
1167       close (fd);
1168
1169       /* Check whether we should be pruning the cache. */
1170       assert (run_prune || to == 0);
1171       if (to == ETIMEDOUT)
1172         {
1173         only_prune:
1174           /* The pthread_cond_timedwait() call timed out.  It is time
1175                  to clean up the cache.  */
1176           assert (my_number < lastdb);
1177           prune_cache (&dbs[my_number],
1178                        prune_ts.tv_sec + (prune_ts.tv_nsec >= 500000000));
1179
1180           if (clock_gettime (timeout_clock, &prune_ts) == -1)
1181             /* Should never happen.  */
1182             abort ();
1183
1184           /* Compute next timeout time.  */
1185           prune_ts.tv_sec += CACHE_PRUNE_INTERVAL;
1186
1187           /* In case the list is emtpy we do not want to run the prune
1188              code right away again.  */
1189           to = 0;
1190         }
1191
1192       /* Re-locking.  */
1193       pthread_mutex_lock (&readylist_lock);
1194
1195       /* One more thread available.  */
1196       ++nready;
1197     }
1198 }
1199
1200
1201 static unsigned int nconns;
1202
1203 static void
1204 fd_ready (int fd)
1205 {
1206   pthread_mutex_lock (&readylist_lock);
1207
1208   /* Find an empty entry in FDLIST.  */
1209   size_t inner;
1210   for (inner = 0; inner < nconns; ++inner)
1211     if (fdlist[inner].next == NULL)
1212       break;
1213   assert (inner < nconns);
1214
1215   fdlist[inner].fd = fd;
1216
1217   if (readylist == NULL)
1218     readylist = fdlist[inner].next = &fdlist[inner];
1219   else
1220     {
1221       fdlist[inner].next = readylist->next;
1222       readylist = readylist->next = &fdlist[inner];
1223     }
1224
1225   bool do_signal = true;
1226   if (__builtin_expect (nready == 0, 0))
1227     {
1228       ++client_queued;
1229       do_signal = false;
1230
1231       /* Try to start another thread to help out.  */
1232       pthread_t th;
1233       if (nthreads < max_nthreads
1234           && pthread_create (&th, &attr, nscd_run,
1235                              (void *) (long int) nthreads) == 0)
1236         {
1237           /* We got another thread.  */
1238           ++nthreads;
1239           /* The new thread might new a kick.  */
1240           do_signal = true;
1241         }
1242
1243     }
1244
1245   pthread_mutex_unlock (&readylist_lock);
1246
1247   /* Tell one of the worker threads there is work to do.  */
1248   if (do_signal)
1249     pthread_cond_signal (&readylist_cond);
1250 }
1251
1252
1253 /* Check whether restarting should happen.  */
1254 static inline int
1255 restart_p (time_t now)
1256 {
1257   return (paranoia && readylist == NULL && nready == nthreads
1258           && now >= restart_time);
1259 }
1260
1261
1262 /* Array for times a connection was accepted.  */
1263 static time_t *starttime;
1264
1265
1266 static void
1267 __attribute__ ((__noreturn__))
1268 main_loop_poll (void)
1269 {
1270   struct pollfd *conns = (struct pollfd *) xmalloc (nconns
1271                                                     * sizeof (conns[0]));
1272
1273   conns[0].fd = sock;
1274   conns[0].events = POLLRDNORM;
1275   size_t nused = 1;
1276   size_t firstfree = 1;
1277
1278   while (1)
1279     {
1280       /* Wait for any event.  We wait at most a couple of seconds so
1281          that we can check whether we should close any of the accepted
1282          connections since we have not received a request.  */
1283 #define MAX_ACCEPT_TIMEOUT 30
1284 #define MIN_ACCEPT_TIMEOUT 5
1285 #define MAIN_THREAD_TIMEOUT \
1286   (MAX_ACCEPT_TIMEOUT * 1000                                                  \
1287    - ((MAX_ACCEPT_TIMEOUT - MIN_ACCEPT_TIMEOUT) * 1000 * nused) / (2 * nconns))
1288
1289       int n = poll (conns, nused, MAIN_THREAD_TIMEOUT);
1290
1291       time_t now = time (NULL);
1292
1293       /* If there is a descriptor ready for reading or there is a new
1294          connection, process this now.  */
1295       if (n > 0)
1296         {
1297           if (conns[0].revents != 0)
1298             {
1299               /* We have a new incoming connection.  Accept the connection.  */
1300               int fd = TEMP_FAILURE_RETRY (accept (sock, NULL, NULL));
1301
1302               /* use the descriptor if we have not reached the limit.  */
1303               if (fd >= 0 && firstfree < nconns)
1304                 {
1305                   conns[firstfree].fd = fd;
1306                   conns[firstfree].events = POLLRDNORM;
1307                   starttime[firstfree] = now;
1308                   if (firstfree >= nused)
1309                     nused = firstfree + 1;
1310
1311                   do
1312                     ++firstfree;
1313                   while (firstfree < nused && conns[firstfree].fd != -1);
1314                 }
1315
1316               --n;
1317             }
1318
1319           for (size_t cnt = 1; cnt < nused && n > 0; ++cnt)
1320             if (conns[cnt].revents != 0)
1321               {
1322                 fd_ready (conns[cnt].fd);
1323
1324                 /* Clean up the CONNS array.  */
1325                 conns[cnt].fd = -1;
1326                 if (cnt < firstfree)
1327                   firstfree = cnt;
1328                 if (cnt == nused - 1)
1329                   do
1330                     --nused;
1331                   while (conns[nused - 1].fd == -1);
1332
1333                 --n;
1334               }
1335         }
1336
1337       /* Now find entries which have timed out.  */
1338       assert (nused > 0);
1339
1340       /* We make the timeout length depend on the number of file
1341          descriptors currently used.  */
1342 #define ACCEPT_TIMEOUT \
1343   (MAX_ACCEPT_TIMEOUT                                                         \
1344    - ((MAX_ACCEPT_TIMEOUT - MIN_ACCEPT_TIMEOUT) * nused) / nconns)
1345       time_t laststart = now - ACCEPT_TIMEOUT;
1346
1347       for (size_t cnt = nused - 1; cnt > 0; --cnt)
1348         {
1349           if (conns[cnt].fd != -1 && starttime[cnt] < laststart)
1350             {
1351               /* Remove the entry, it timed out.  */
1352               (void) close (conns[cnt].fd);
1353               conns[cnt].fd = -1;
1354
1355               if (cnt < firstfree)
1356                 firstfree = cnt;
1357               if (cnt == nused - 1)
1358                 do
1359                   --nused;
1360                 while (conns[nused - 1].fd == -1);
1361             }
1362         }
1363
1364       if (restart_p (now))
1365         restart ();
1366     }
1367 }
1368
1369
1370 #ifdef HAVE_EPOLL
1371 static void
1372 main_loop_epoll (int efd)
1373 {
1374   struct epoll_event ev = { 0, };
1375   int nused = 1;
1376   size_t highest = 0;
1377
1378   /* Add the socket.  */
1379   ev.events = EPOLLRDNORM;
1380   ev.data.fd = sock;
1381   if (epoll_ctl (efd, EPOLL_CTL_ADD, sock, &ev) == -1)
1382     /* We cannot use epoll.  */
1383     return;
1384
1385   while (1)
1386     {
1387       struct epoll_event revs[100];
1388 # define nrevs (sizeof (revs) / sizeof (revs[0]))
1389
1390       int n = epoll_wait (efd, revs, nrevs, MAIN_THREAD_TIMEOUT);
1391
1392       time_t now = time (NULL);
1393
1394       for (int cnt = 0; cnt < n; ++cnt)
1395         if (revs[cnt].data.fd == sock)
1396           {
1397             /* A new connection.  */
1398             int fd = TEMP_FAILURE_RETRY (accept (sock, NULL, NULL));
1399
1400             if (fd >= 0)
1401               {
1402                 /* Try to add the  new descriptor.  */
1403                 ev.data.fd = fd;
1404                 if (fd >= nconns
1405                     || epoll_ctl (efd, EPOLL_CTL_ADD, fd, &ev) == -1)
1406                   /* The descriptor is too large or something went
1407                      wrong.  Close the descriptor.  */
1408                   close (fd);
1409                 else
1410                   {
1411                     /* Remember when we accepted the connection.  */
1412                     starttime[fd] = now;
1413
1414                     if (fd > highest)
1415                       highest = fd;
1416
1417                     ++nused;
1418                   }
1419               }
1420           }
1421         else
1422           {
1423             /* Remove the descriptor from the epoll descriptor.  */
1424             struct epoll_event ev = { 0, };
1425             (void) epoll_ctl (efd, EPOLL_CTL_DEL, revs[cnt].data.fd, &ev);
1426
1427             /* Get a worked to handle the request.  */
1428             fd_ready (revs[cnt].data.fd);
1429
1430             /* Reset the time.  */
1431             starttime[revs[cnt].data.fd] = 0;
1432             if (revs[cnt].data.fd == highest)
1433               do
1434                 --highest;
1435               while (highest > 0 && starttime[highest] == 0);
1436
1437             --nused;
1438           }
1439
1440       /*  Now look for descriptors for accepted connections which have
1441           no reply in too long of a time.  */
1442       time_t laststart = now - ACCEPT_TIMEOUT;
1443       for (int cnt = highest; cnt > STDERR_FILENO; --cnt)
1444         if (cnt != sock && starttime[cnt] != 0 && starttime[cnt] < laststart)
1445           {
1446             /* We are waiting for this one for too long.  Close it.  */
1447             struct epoll_event ev = {0, };
1448             (void) epoll_ctl (efd, EPOLL_CTL_DEL, cnt, &ev);
1449
1450             (void) close (cnt);
1451
1452             starttime[cnt] = 0;
1453             if (cnt == highest)
1454               --highest;
1455           }
1456         else if (cnt != sock && starttime[cnt] == 0 && cnt == highest)
1457           --highest;
1458
1459       if (restart_p (now))
1460         restart ();
1461     }
1462 }
1463 #endif
1464
1465
1466 /* Start all the threads we want.  The initial process is thread no. 1.  */
1467 void
1468 start_threads (void)
1469 {
1470   /* Initialize the conditional variable we will use.  The only
1471      non-standard attribute we might use is the clock selection.  */
1472   pthread_condattr_t condattr;
1473   pthread_condattr_init (&condattr);
1474
1475 #if defined _POSIX_CLOCK_SELECTION && _POSIX_CLOCK_SELECTION >= 0 \
1476     && defined _POSIX_MONOTONIC_CLOCK && _POSIX_MONOTONIC_CLOCK >= 0
1477   /* Determine whether the monotonous clock is available.  */
1478   struct timespec dummy;
1479 # if _POSIX_MONOTONIC_CLOCK == 0
1480   if (sysconf (_SC_MONOTONIC_CLOCK) > 0)
1481 # endif
1482 # if _POSIX_CLOCK_SELECTION == 0
1483     if (sysconf (_SC_CLOCK_SELECTION) > 0)
1484 # endif
1485       if (clock_getres (CLOCK_MONOTONIC, &dummy) == 0
1486           && pthread_condattr_setclock (&condattr, CLOCK_MONOTONIC) == 0)
1487         timeout_clock = CLOCK_MONOTONIC;
1488 #endif
1489
1490   pthread_cond_init (&readylist_cond, &condattr);
1491   pthread_condattr_destroy (&condattr);
1492
1493
1494   /* Create the attribute for the threads.  They are all created
1495      detached.  */
1496   pthread_attr_init (&attr);
1497   pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
1498   /* Use 1MB stacks, twice as much for 64-bit architectures.  */
1499   pthread_attr_setstacksize (&attr, 1024 * 1024 * (sizeof (void *) / 4));
1500
1501   /* We allow less than LASTDB threads only for debugging.  */
1502   if (debug_level == 0)
1503     nthreads = MAX (nthreads, lastdb);
1504
1505   int nfailed = 0;
1506   for (long int i = 0; i < nthreads; ++i)
1507     {
1508       pthread_t th;
1509       if (pthread_create (&th, &attr, nscd_run, (void *) (i - nfailed)) != 0)
1510         ++nfailed;
1511     }
1512   if (nthreads - nfailed < lastdb)
1513     {
1514       /* We could not start enough threads.  */
1515       dbg_log (_("could only start %d threads; terminating"),
1516                nthreads - nfailed);
1517       exit (1);
1518     }
1519
1520   /* Determine how much room for descriptors we should initially
1521      allocate.  This might need to change later if we cap the number
1522      with MAXCONN.  */
1523   const long int nfds = sysconf (_SC_OPEN_MAX);
1524 #define MINCONN 32
1525 #define MAXCONN 16384
1526   if (nfds == -1 || nfds > MAXCONN)
1527     nconns = MAXCONN;
1528   else if (nfds < MINCONN)
1529     nconns = MINCONN;
1530   else
1531     nconns = nfds;
1532
1533   /* We need memory to pass descriptors on to the worker threads.  */
1534   fdlist = (struct fdlist *) xcalloc (nconns, sizeof (fdlist[0]));
1535   /* Array to keep track when connection was accepted.  */
1536   starttime = (time_t *) xcalloc (nconns, sizeof (starttime[0]));
1537
1538   /* In the main thread we execute the loop which handles incoming
1539      connections.  */
1540 #ifdef HAVE_EPOLL
1541   int efd = epoll_create (100);
1542   if (efd != -1)
1543     {
1544       main_loop_epoll (efd);
1545       close (efd);
1546     }
1547 #endif
1548
1549   main_loop_poll ();
1550 }
1551
1552
1553 /* Look up the uid, gid, and supplementary groups to run nscd as. When
1554    this function is called, we are not listening on the nscd socket yet so
1555    we can just use the ordinary lookup functions without causing a lockup  */
1556 static void
1557 begin_drop_privileges (void)
1558 {
1559   struct passwd *pwd = getpwnam (server_user);
1560
1561   if (pwd == NULL)
1562     {
1563       dbg_log (_("Failed to run nscd as user '%s'"), server_user);
1564       error (EXIT_FAILURE, 0, _("Failed to run nscd as user '%s'"),
1565              server_user);
1566     }
1567
1568   server_uid = pwd->pw_uid;
1569   server_gid = pwd->pw_gid;
1570
1571   /* Save the old UID/GID if we have to change back.  */
1572   if (paranoia)
1573     {
1574       old_uid = getuid ();
1575       old_gid = getgid ();
1576     }
1577
1578   if (getgrouplist (server_user, server_gid, NULL, &server_ngroups) == 0)
1579     {
1580       /* This really must never happen.  */
1581       dbg_log (_("Failed to run nscd as user '%s'"), server_user);
1582       error (EXIT_FAILURE, errno, _("initial getgrouplist failed"));
1583     }
1584
1585   server_groups = (gid_t *) xmalloc (server_ngroups * sizeof (gid_t));
1586
1587   if (getgrouplist (server_user, server_gid, server_groups, &server_ngroups)
1588       == -1)
1589     {
1590       dbg_log (_("Failed to run nscd as user '%s'"), server_user);
1591       error (EXIT_FAILURE, errno, _("getgrouplist failed"));
1592     }
1593 }
1594
1595
1596 /* Call setgroups(), setgid(), and setuid() to drop root privileges and
1597    run nscd as the user specified in the configuration file.  */
1598 static void
1599 finish_drop_privileges (void)
1600 {
1601   if (setgroups (server_ngroups, server_groups) == -1)
1602     {
1603       dbg_log (_("Failed to run nscd as user '%s'"), server_user);
1604       error (EXIT_FAILURE, errno, _("setgroups failed"));
1605     }
1606
1607   if (setgid (server_gid) == -1)
1608     {
1609       dbg_log (_("Failed to run nscd as user '%s'"), server_user);
1610       perror ("setgid");
1611       exit (1);
1612     }
1613
1614   if (setuid (server_uid) == -1)
1615     {
1616       dbg_log (_("Failed to run nscd as user '%s'"), server_user);
1617       perror ("setuid");
1618       exit (1);
1619     }
1620 }