1 /* Inner loops of cache daemon.
2 Copyright (C) 1998-2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4 Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published
8 by the Free Software Foundation; version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software Foundation,
18 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
34 #include <arpa/inet.h>
36 # include <sys/epoll.h>
39 #include <sys/param.h>
42 # include <sys/sendfile.h>
44 #include <sys/socket.h>
52 # include <kernel-features.h>
56 /* Wrapper functions with error checking for standard functions. */
57 extern void *xmalloc (size_t n
);
58 extern void *xcalloc (size_t n
, size_t s
);
59 extern void *xrealloc (void *o
, size_t n
);
61 /* Support to run nscd as an unprivileged user */
62 const char *server_user
;
63 static uid_t server_uid
;
64 static gid_t server_gid
;
65 const char *stat_user
;
67 static gid_t
*server_groups
;
71 static int server_ngroups
;
72 static volatile int sighup_pending
;
74 static pthread_attr_t attr
;
76 static void begin_drop_privileges (void);
77 static void finish_drop_privileges (void);
79 /* Map request type to a string. */
80 const char *const serv2str
[LASTREQ
] =
82 [GETPWBYNAME
] = "GETPWBYNAME",
83 [GETPWBYUID
] = "GETPWBYUID",
84 [GETGRBYNAME
] = "GETGRBYNAME",
85 [GETGRBYGID
] = "GETGRBYGID",
86 [GETHOSTBYNAME
] = "GETHOSTBYNAME",
87 [GETHOSTBYNAMEv6
] = "GETHOSTBYNAMEv6",
88 [GETHOSTBYADDR
] = "GETHOSTBYADDR",
89 [GETHOSTBYADDRv6
] = "GETHOSTBYADDRv6",
90 [SHUTDOWN
] = "SHUTDOWN",
91 [GETSTAT
] = "GETSTAT",
92 [INVALIDATE
] = "INVALIDATE",
93 [GETFDPW
] = "GETFDPW",
94 [GETFDGR
] = "GETFDGR",
95 [GETFDHST
] = "GETFDHST",
97 [INITGROUPS
] = "INITGROUPS",
98 [GETSERVBYNAME
] = "GETSERVBYNAME",
99 [GETSERVBYPORT
] = "GETSERVBYPORT",
100 [GETFDSERV
] = "GETFDSERV"
103 /* The control data structures for the services. */
104 struct database_dyn dbs
[lastdb
] =
107 .lock
= PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP
,
108 .prunelock
= PTHREAD_MUTEX_INITIALIZER
,
114 .max_db_size
= DEFAULT_MAX_DB_SIZE
,
116 .filename
= "/etc/passwd",
117 .db_filename
= _PATH_NSCD_PASSWD_DB
,
118 .disabled_iov
= &pwd_iov_disabled
,
126 .lock
= PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP
,
127 .prunelock
= PTHREAD_MUTEX_INITIALIZER
,
133 .max_db_size
= DEFAULT_MAX_DB_SIZE
,
135 .filename
= "/etc/group",
136 .db_filename
= _PATH_NSCD_GROUP_DB
,
137 .disabled_iov
= &grp_iov_disabled
,
145 .lock
= PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP
,
146 .prunelock
= PTHREAD_MUTEX_INITIALIZER
,
150 .propagate
= 0, /* Not used. */
152 .max_db_size
= DEFAULT_MAX_DB_SIZE
,
154 .filename
= "/etc/hosts",
155 .db_filename
= _PATH_NSCD_HOSTS_DB
,
156 .disabled_iov
= &hst_iov_disabled
,
164 .lock
= PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP
,
165 .prunelock
= PTHREAD_MUTEX_INITIALIZER
,
169 .propagate
= 0, /* Not used. */
171 .max_db_size
= DEFAULT_MAX_DB_SIZE
,
173 .filename
= "/etc/services",
174 .db_filename
= _PATH_NSCD_SERVICES_DB
,
175 .disabled_iov
= &serv_iov_disabled
,
185 /* Mapping of request type to database. */
189 struct database_dyn
*db
;
190 } const reqinfo
[LASTREQ
] =
192 [GETPWBYNAME
] = { true, &dbs
[pwddb
] },
193 [GETPWBYUID
] = { true, &dbs
[pwddb
] },
194 [GETGRBYNAME
] = { true, &dbs
[grpdb
] },
195 [GETGRBYGID
] = { true, &dbs
[grpdb
] },
196 [GETHOSTBYNAME
] = { true, &dbs
[hstdb
] },
197 [GETHOSTBYNAMEv6
] = { true, &dbs
[hstdb
] },
198 [GETHOSTBYADDR
] = { true, &dbs
[hstdb
] },
199 [GETHOSTBYADDRv6
] = { true, &dbs
[hstdb
] },
200 [SHUTDOWN
] = { false, NULL
},
201 [GETSTAT
] = { false, NULL
},
202 [SHUTDOWN
] = { false, NULL
},
203 [GETFDPW
] = { false, &dbs
[pwddb
] },
204 [GETFDGR
] = { false, &dbs
[grpdb
] },
205 [GETFDHST
] = { false, &dbs
[hstdb
] },
206 [GETAI
] = { true, &dbs
[hstdb
] },
207 [INITGROUPS
] = { true, &dbs
[grpdb
] },
208 [GETSERVBYNAME
] = { true, &dbs
[servdb
] },
209 [GETSERVBYPORT
] = { true, &dbs
[servdb
] },
210 [GETFDSERV
] = { false, &dbs
[servdb
] }
214 /* Number of seconds between two cache pruning runs. */
215 #define CACHE_PRUNE_INTERVAL 15
218 /* Initial number of threads to use. */
220 /* Maximum number of threads to use. */
221 int max_nthreads
= 32;
223 /* Socket for incoming connections. */
226 /* Number of times clients had to wait. */
227 unsigned long int client_queued
;
231 writeall (int fd
, const void *buf
, size_t len
)
237 ret
= TEMP_FAILURE_RETRY (send (fd
, buf
, n
, MSG_NOSIGNAL
));
240 buf
= (const char *) buf
+ ret
;
244 return ret
< 0 ? ret
: len
- n
;
250 sendfileall (int tofd
, int fromfd
, off_t off
, size_t len
)
257 ret
= TEMP_FAILURE_RETRY (sendfile (tofd
, fromfd
, &off
, n
));
263 return ret
< 0 ? ret
: len
- n
;
271 /* The following three are not really used, they are symbolic constants. */
277 use_he_begin
= use_he
| use_begin
,
278 use_he_end
= use_he
| use_end
,
281 use_key_begin
= use_key
| use_begin
,
282 use_key_end
= use_key
| use_end
,
283 use_key_first
= use_key_begin
| use_first
,
286 use_data_begin
= use_data
| use_begin
,
287 use_data_end
= use_data
| use_end
,
288 use_data_first
= use_data_begin
| use_first
293 check_use (const char *data
, nscd_ssize_t first_free
, uint8_t *usemap
,
294 enum usekey use
, ref_t start
, size_t len
)
298 if (start
> first_free
|| start
+ len
> first_free
299 || (start
& BLOCK_ALIGN_M1
))
302 if (usemap
[start
] == use_not
)
304 /* Add the start marker. */
305 usemap
[start
] = use
| use_begin
;
309 if (usemap
[++start
] != use_not
)
314 /* Add the end marker. */
315 usemap
[start
] = use
| use_end
;
317 else if ((usemap
[start
] & ~use_first
) == ((use
| use_begin
) & ~use_first
))
319 /* Hash entries can't be shared. */
323 usemap
[start
] |= (use
& use_first
);
327 if (usemap
[++start
] != use
)
330 if (usemap
[++start
] != (use
| use_end
))
334 /* Points to a wrong object or somewhere in the middle. */
341 /* Verify data in persistent database. */
343 verify_persistent_db (void *mem
, struct database_pers_head
*readhead
, int dbnr
)
345 assert (dbnr
== pwddb
|| dbnr
== grpdb
|| dbnr
== hstdb
|| dbnr
== servdb
);
347 time_t now
= time (NULL
);
349 struct database_pers_head
*head
= mem
;
350 struct database_pers_head head_copy
= *head
;
352 /* Check that the header that was read matches the head in the database. */
353 if (readhead
!= NULL
&& memcmp (head
, readhead
, sizeof (*head
)) != 0)
356 /* First some easy tests: make sure the database header is sane. */
357 if (head
->version
!= DB_VERSION
358 || head
->header_size
!= sizeof (*head
)
359 /* We allow a timestamp to be one hour ahead of the current time.
360 This should cover daylight saving time changes. */
361 || head
->timestamp
> now
+ 60 * 60 + 60
362 || (head
->gc_cycle
& 1)
363 || (size_t) head
->module
> INT32_MAX
/ sizeof (ref_t
)
364 || (size_t) head
->data_size
> INT32_MAX
- head
->module
* sizeof (ref_t
)
365 || head
->first_free
< 0
366 || head
->first_free
> head
->data_size
367 || (head
->first_free
& BLOCK_ALIGN_M1
) != 0
368 || head
->maxnentries
< 0
369 || head
->maxnsearched
< 0)
372 uint8_t *usemap
= calloc (head
->first_free
, 1);
376 const char *data
= (char *) &head
->array
[roundup (head
->module
,
377 ALIGN
/ sizeof (ref_t
))];
379 nscd_ssize_t he_cnt
= 0;
380 for (nscd_ssize_t cnt
= 0; cnt
< head
->module
; ++cnt
)
382 ref_t work
= head
->array
[cnt
];
384 while (work
!= ENDREF
)
386 if (! check_use (data
, head
->first_free
, usemap
, use_he
, work
,
387 sizeof (struct hashentry
)))
390 /* Now we know we can dereference the record. */
391 struct hashentry
*here
= (struct hashentry
*) (data
+ work
);
395 /* Make sure the record is for this type of service. */
396 if (here
->type
>= LASTREQ
397 || reqinfo
[here
->type
].db
!= &dbs
[dbnr
])
400 /* Validate boolean field value. */
401 if (here
->first
!= false && here
->first
!= true)
409 || here
->packet
> head
->first_free
410 || here
->packet
+ sizeof (struct datahead
) > head
->first_free
)
413 struct datahead
*dh
= (struct datahead
*) (data
+ here
->packet
);
415 if (! check_use (data
, head
->first_free
, usemap
,
416 use_data
| (here
->first
? use_first
: 0),
417 here
->packet
, dh
->allocsize
))
420 if (dh
->allocsize
< sizeof (struct datahead
)
421 || dh
->recsize
> dh
->allocsize
422 || (dh
->notfound
!= false && dh
->notfound
!= true)
423 || (dh
->usable
!= false && dh
->usable
!= true))
426 if (here
->key
< here
->packet
+ sizeof (struct datahead
)
427 || here
->key
> here
->packet
+ dh
->allocsize
428 || here
->key
+ here
->len
> here
->packet
+ dh
->allocsize
)
431 /* If keys can appear outside of data, this should be done
432 instead. But gc doesn't mark the data in that case. */
433 if (! check_use (data
, head
->first_free
, usemap
,
434 use_key
| (here
->first
? use_first
: 0),
435 here
->key
, here
->len
))
444 if (he_cnt
!= head
->nentries
)
447 /* See if all data and keys had at least one reference from
448 he->first == true hashentry. */
449 for (ref_t idx
= 0; idx
< head
->first_free
; ++idx
)
452 if (usemap
[idx
] == use_key_begin
)
455 if (usemap
[idx
] == use_data_begin
)
459 /* Finally, make sure the database hasn't changed since the first test. */
460 if (memcmp (mem
, &head_copy
, sizeof (*head
)) != 0)
472 /* Initialize database information structures. */
476 /* Look up unprivileged uid/gid/groups before we start listening on the
478 if (server_user
!= NULL
)
479 begin_drop_privileges ();
482 /* No configuration for this value, assume a default. */
483 nthreads
= 2 * lastdb
;
485 for (size_t cnt
= 0; cnt
< lastdb
; ++cnt
)
486 if (dbs
[cnt
].enabled
)
488 pthread_rwlock_init (&dbs
[cnt
].lock
, NULL
);
489 pthread_mutex_init (&dbs
[cnt
].memlock
, NULL
);
491 if (dbs
[cnt
].persistent
)
493 /* Try to open the appropriate file on disk. */
494 int fd
= open (dbs
[cnt
].db_filename
, O_RDWR
);
500 struct database_pers_head head
;
501 ssize_t n
= TEMP_FAILURE_RETRY (read (fd
, &head
,
503 if (n
!= sizeof (head
) || fstat64 (fd
, &st
) != 0)
506 dbg_log (_("invalid persistent database file \"%s\": %s"),
507 dbs
[cnt
].db_filename
, strerror (errno
));
508 unlink (dbs
[cnt
].db_filename
);
510 else if (head
.module
== 0 && head
.data_size
== 0)
512 /* The file has been created, but the head has not been
513 initialized yet. Remove the old file. */
514 unlink (dbs
[cnt
].db_filename
);
516 else if (head
.header_size
!= (int) sizeof (head
))
518 dbg_log (_("invalid persistent database file \"%s\": %s"),
519 dbs
[cnt
].db_filename
,
520 _("header size does not match"));
521 unlink (dbs
[cnt
].db_filename
);
523 else if ((total
= (sizeof (head
)
524 + roundup (head
.module
* sizeof (ref_t
),
528 || total
< sizeof (head
))
530 dbg_log (_("invalid persistent database file \"%s\": %s"),
531 dbs
[cnt
].db_filename
,
532 _("file size does not match"));
533 unlink (dbs
[cnt
].db_filename
);
535 /* Note we map with the maximum size allowed for the
536 database. This is likely much larger than the
537 actual file size. This is OK on most OSes since
538 extensions of the underlying file will
539 automatically translate more pages available for
541 else if ((mem
= mmap (NULL
, dbs
[cnt
].max_db_size
,
542 PROT_READ
| PROT_WRITE
,
546 else if (!verify_persistent_db (mem
, &head
, cnt
))
549 dbg_log (_("invalid persistent database file \"%s\": %s"),
550 dbs
[cnt
].db_filename
,
551 _("verification failed"));
552 unlink (dbs
[cnt
].db_filename
);
556 /* Success. We have the database. */
558 dbs
[cnt
].memsize
= total
;
559 dbs
[cnt
].data
= (char *)
560 &dbs
[cnt
].head
->array
[roundup (dbs
[cnt
].head
->module
,
561 ALIGN
/ sizeof (ref_t
))];
562 dbs
[cnt
].mmap_used
= true;
564 if (dbs
[cnt
].suggested_module
> head
.module
)
565 dbg_log (_("suggested size of table for database %s larger than the persistent database's table"),
570 /* We also need a read-only descriptor. */
573 dbs
[cnt
].ro_fd
= open (dbs
[cnt
].db_filename
, O_RDONLY
);
574 if (dbs
[cnt
].ro_fd
== -1)
576 cannot create read-only descriptor for \"%s\"; no mmap"),
577 dbs
[cnt
].db_filename
);
580 // XXX Shall we test whether the descriptors actually
581 // XXX point to the same file?
584 /* Close the file descriptors in case something went
585 wrong in which case the variable have not been
592 if (dbs
[cnt
].head
== NULL
)
594 /* No database loaded. Allocate the data structure,
596 struct database_pers_head head
;
597 size_t total
= (sizeof (head
)
598 + roundup (dbs
[cnt
].suggested_module
599 * sizeof (ref_t
), ALIGN
)
600 + (dbs
[cnt
].suggested_module
601 * DEFAULT_DATASIZE_PER_BUCKET
));
603 /* Try to create the database. If we do not need a
604 persistent database create a temporary file. */
607 if (dbs
[cnt
].persistent
)
609 fd
= open (dbs
[cnt
].db_filename
,
610 O_RDWR
| O_CREAT
| O_EXCL
| O_TRUNC
,
612 if (fd
!= -1 && dbs
[cnt
].shared
)
613 ro_fd
= open (dbs
[cnt
].db_filename
, O_RDONLY
);
617 char fname
[] = _PATH_NSCD_XYZ_DB_TMP
;
618 fd
= mkstemp (fname
);
620 /* We do not need the file name anymore after we
621 opened another file descriptor in read-only mode. */
625 ro_fd
= open (fname
, O_RDONLY
);
635 dbg_log (_("database for %s corrupted or simultaneously used; remove %s manually if necessary and restart"),
636 dbnames
[cnt
], dbs
[cnt
].db_filename
);
637 // XXX Correct way to terminate?
641 if (dbs
[cnt
].persistent
)
642 dbg_log (_("cannot create %s; no persistent database used"),
643 dbs
[cnt
].db_filename
);
645 dbg_log (_("cannot create %s; no sharing possible"),
646 dbs
[cnt
].db_filename
);
648 dbs
[cnt
].persistent
= 0;
649 // XXX remember: no mmap
653 /* Tell the user if we could not create the read-only
655 if (ro_fd
== -1 && dbs
[cnt
].shared
)
657 cannot create read-only descriptor for \"%s\"; no mmap"),
658 dbs
[cnt
].db_filename
);
660 /* Before we create the header, initialiye the hash
661 table. So that if we get interrupted if writing
662 the header we can recognize a partially initialized
664 size_t ps
= sysconf (_SC_PAGESIZE
);
666 assert (~ENDREF
== 0);
667 memset (tmpbuf
, '\xff', ps
);
669 size_t remaining
= dbs
[cnt
].suggested_module
* sizeof (ref_t
);
670 off_t offset
= sizeof (head
);
673 if (offset
% ps
!= 0)
675 towrite
= MIN (remaining
, ps
- (offset
% ps
));
676 if (pwrite (fd
, tmpbuf
, towrite
, offset
) != towrite
)
679 remaining
-= towrite
;
682 while (remaining
> ps
)
684 if (pwrite (fd
, tmpbuf
, ps
, offset
) == -1)
691 && pwrite (fd
, tmpbuf
, remaining
, offset
) != remaining
)
694 /* Create the header of the file. */
695 struct database_pers_head head
=
697 .version
= DB_VERSION
,
698 .header_size
= sizeof (head
),
699 .module
= dbs
[cnt
].suggested_module
,
700 .data_size
= (dbs
[cnt
].suggested_module
701 * DEFAULT_DATASIZE_PER_BUCKET
),
706 if ((TEMP_FAILURE_RETRY (write (fd
, &head
, sizeof (head
)))
708 || (TEMP_FAILURE_RETRY_VAL (posix_fallocate (fd
, 0, total
))
710 || (mem
= mmap (NULL
, dbs
[cnt
].max_db_size
,
711 PROT_READ
| PROT_WRITE
,
712 MAP_SHARED
, fd
, 0)) == MAP_FAILED
)
715 unlink (dbs
[cnt
].db_filename
);
716 dbg_log (_("cannot write to database file %s: %s"),
717 dbs
[cnt
].db_filename
, strerror (errno
));
718 dbs
[cnt
].persistent
= 0;
724 dbs
[cnt
].data
= (char *)
725 &dbs
[cnt
].head
->array
[roundup (dbs
[cnt
].head
->module
,
726 ALIGN
/ sizeof (ref_t
))];
727 dbs
[cnt
].memsize
= total
;
728 dbs
[cnt
].mmap_used
= true;
730 /* Remember the descriptors. */
732 dbs
[cnt
].ro_fd
= ro_fd
;
745 && ((dbs
[cnt
].wr_fd
!= -1
746 && fcntl (dbs
[cnt
].wr_fd
, F_SETFD
, FD_CLOEXEC
) == -1)
747 || (dbs
[cnt
].ro_fd
!= -1
748 && fcntl (dbs
[cnt
].ro_fd
, F_SETFD
, FD_CLOEXEC
) == -1)))
751 cannot set socket to close on exec: %s; disabling paranoia mode"),
756 if (dbs
[cnt
].head
== NULL
)
758 /* We do not use the persistent database. Just
759 create an in-memory data structure. */
760 assert (! dbs
[cnt
].persistent
);
762 dbs
[cnt
].head
= xmalloc (sizeof (struct database_pers_head
)
763 + (dbs
[cnt
].suggested_module
765 memset (dbs
[cnt
].head
, '\0', sizeof (struct database_pers_head
));
766 assert (~ENDREF
== 0);
767 memset (dbs
[cnt
].head
->array
, '\xff',
768 dbs
[cnt
].suggested_module
* sizeof (ref_t
));
769 dbs
[cnt
].head
->module
= dbs
[cnt
].suggested_module
;
770 dbs
[cnt
].head
->data_size
= (DEFAULT_DATASIZE_PER_BUCKET
771 * dbs
[cnt
].head
->module
);
772 dbs
[cnt
].data
= xmalloc (dbs
[cnt
].head
->data_size
);
773 dbs
[cnt
].head
->first_free
= 0;
776 assert (dbs
[cnt
].ro_fd
== -1);
779 if (dbs
[cnt
].check_file
)
781 /* We need the modification date of the file. */
784 if (stat64 (dbs
[cnt
].filename
, &st
) < 0)
786 /* We cannot stat() the file, disable file checking. */
787 dbg_log (_("cannot stat() file `%s': %s"),
788 dbs
[cnt
].filename
, strerror (errno
));
789 dbs
[cnt
].check_file
= 0;
792 dbs
[cnt
].file_mtime
= st
.st_mtime
;
796 /* Create the socket. */
797 sock
= socket (AF_UNIX
, SOCK_STREAM
, 0);
800 dbg_log (_("cannot open socket: %s"), strerror (errno
));
801 exit (errno
== EACCES
? 4 : 1);
803 /* Bind a name to the socket. */
804 struct sockaddr_un sock_addr
;
805 sock_addr
.sun_family
= AF_UNIX
;
806 strcpy (sock_addr
.sun_path
, _PATH_NSCDSOCKET
);
807 if (bind (sock
, (struct sockaddr
*) &sock_addr
, sizeof (sock_addr
)) < 0)
809 dbg_log ("%s: %s", _PATH_NSCDSOCKET
, strerror (errno
));
810 exit (errno
== EACCES
? 4 : 1);
813 /* We don't want to get stuck on accept. */
814 int fl
= fcntl (sock
, F_GETFL
);
815 if (fl
== -1 || fcntl (sock
, F_SETFL
, fl
| O_NONBLOCK
) == -1)
817 dbg_log (_("cannot change socket to nonblocking mode: %s"),
822 /* The descriptor needs to be closed on exec. */
823 if (paranoia
&& fcntl (sock
, F_SETFD
, FD_CLOEXEC
) == -1)
825 dbg_log (_("cannot set socket to close on exec: %s"),
830 /* Set permissions for the socket. */
831 chmod (_PATH_NSCDSOCKET
, DEFFILEMODE
);
833 /* Set the socket up to accept connections. */
834 if (listen (sock
, SOMAXCONN
) < 0)
836 dbg_log (_("cannot enable socket to accept connections: %s"),
841 /* Change to unprivileged uid/gid/groups if specifed in config file */
842 if (server_user
!= NULL
)
843 finish_drop_privileges ();
847 /* Close the connections. */
856 invalidate_cache (char *key
, int fd
)
861 for (number
= pwddb
; number
< lastdb
; ++number
)
862 if (strcmp (key
, dbnames
[number
]) == 0)
864 if (dbs
[number
].reset_res
)
870 if (number
== lastdb
)
873 writeall (fd
, &resp
, sizeof (resp
));
877 if (dbs
[number
].enabled
)
878 prune_cache (&dbs
[number
], LONG_MAX
, fd
);
882 writeall (fd
, &resp
, sizeof (resp
));
889 send_ro_fd (struct database_dyn
*db
, char *key
, int fd
)
891 /* If we do not have an read-only file descriptor do nothing. */
895 /* We need to send some data along with the descriptor. */
897 iov
[0].iov_base
= key
;
898 iov
[0].iov_len
= strlen (key
) + 1;
900 /* Prepare the control message to transfer the descriptor. */
904 char bytes
[CMSG_SPACE (sizeof (int))];
906 struct msghdr msg
= { .msg_iov
= iov
, .msg_iovlen
= 1,
907 .msg_control
= buf
.bytes
,
908 .msg_controllen
= sizeof (buf
) };
909 struct cmsghdr
*cmsg
= CMSG_FIRSTHDR (&msg
);
911 cmsg
->cmsg_level
= SOL_SOCKET
;
912 cmsg
->cmsg_type
= SCM_RIGHTS
;
913 cmsg
->cmsg_len
= CMSG_LEN (sizeof (int));
915 *(int *) CMSG_DATA (cmsg
) = db
->ro_fd
;
917 msg
.msg_controllen
= cmsg
->cmsg_len
;
919 /* Send the control message. We repeat when we are interrupted but
920 everything else is ignored. */
922 # define MSG_NOSIGNAL 0
924 (void) TEMP_FAILURE_RETRY (sendmsg (fd
, &msg
, MSG_NOSIGNAL
));
926 if (__builtin_expect (debug_level
> 0, 0))
927 dbg_log (_("provide access to FD %d, for %s"), db
->ro_fd
, key
);
929 #endif /* SCM_RIGHTS */
932 /* Handle new request. */
934 handle_request (int fd
, request_header
*req
, void *key
, uid_t uid
)
936 if (__builtin_expect (req
->version
, NSCD_VERSION
) != NSCD_VERSION
)
940 cannot handle old request version %d; current version is %d"),
941 req
->version
, NSCD_VERSION
);
945 /* Make the SELinux check before we go on to the standard checks. */
946 if (selinux_enabled
&& nscd_request_avc_has_perm (fd
, req
->type
) != 0)
949 struct database_dyn
*db
= reqinfo
[req
->type
].db
;
951 /* See whether we can service the request from the cache. */
952 if (__builtin_expect (reqinfo
[req
->type
].data_request
, true))
954 if (__builtin_expect (debug_level
, 0) > 0)
956 if (req
->type
== GETHOSTBYADDR
|| req
->type
== GETHOSTBYADDRv6
)
958 char buf
[INET6_ADDRSTRLEN
];
960 dbg_log ("\t%s (%s)", serv2str
[req
->type
],
961 inet_ntop (req
->type
== GETHOSTBYADDR
962 ? AF_INET
: AF_INET6
,
963 key
, buf
, sizeof (buf
)));
966 dbg_log ("\t%s (%s)", serv2str
[req
->type
], (char *) key
);
969 /* Is this service enabled? */
970 if (__builtin_expect (!db
->enabled
, 0))
972 /* No, sent the prepared record. */
973 if (TEMP_FAILURE_RETRY (send (fd
, db
->disabled_iov
->iov_base
,
974 db
->disabled_iov
->iov_len
,
976 != (ssize_t
) db
->disabled_iov
->iov_len
977 && __builtin_expect (debug_level
, 0) > 0)
979 /* We have problems sending the result. */
981 dbg_log (_("cannot write result: %s"),
982 strerror_r (errno
, buf
, sizeof (buf
)));
988 /* Be sure we can read the data. */
989 if (__builtin_expect (pthread_rwlock_tryrdlock (&db
->lock
) != 0, 0))
991 ++db
->head
->rdlockdelayed
;
992 pthread_rwlock_rdlock (&db
->lock
);
995 /* See whether we can handle it from the cache. */
996 struct datahead
*cached
;
997 cached
= (struct datahead
*) cache_search (req
->type
, key
, req
->key_len
,
1001 /* Hurray it's in the cache. */
1004 #ifdef HAVE_SENDFILE
1005 if (db
->mmap_used
|| !cached
->notfound
)
1007 assert (db
->wr_fd
!= -1);
1008 assert ((char *) cached
->data
> (char *) db
->data
);
1009 assert ((char *) cached
->data
- (char *) db
->head
1011 <= (sizeof (struct database_pers_head
)
1012 + db
->head
->module
* sizeof (ref_t
)
1013 + db
->head
->data_size
));
1014 nwritten
= sendfileall (fd
, db
->wr_fd
,
1015 (char *) cached
->data
1016 - (char *) db
->head
, cached
->recsize
);
1017 # ifndef __ASSUME_SENDFILE
1018 if (nwritten
== -1 && errno
== ENOSYS
)
1023 # ifndef __ASSUME_SENDFILE
1027 nwritten
= writeall (fd
, cached
->data
, cached
->recsize
);
1029 if (nwritten
!= cached
->recsize
1030 && __builtin_expect (debug_level
, 0) > 0)
1032 /* We have problems sending the result. */
1034 dbg_log (_("cannot write result: %s"),
1035 strerror_r (errno
, buf
, sizeof (buf
)));
1038 pthread_rwlock_unlock (&db
->lock
);
1043 pthread_rwlock_unlock (&db
->lock
);
1045 else if (__builtin_expect (debug_level
, 0) > 0)
1047 if (req
->type
== INVALIDATE
)
1048 dbg_log ("\t%s (%s)", serv2str
[req
->type
], (char *) key
);
1050 dbg_log ("\t%s", serv2str
[req
->type
]);
1053 /* Handle the request. */
1057 addpwbyname (db
, fd
, req
, key
, uid
);
1061 addpwbyuid (db
, fd
, req
, key
, uid
);
1065 addgrbyname (db
, fd
, req
, key
, uid
);
1069 addgrbygid (db
, fd
, req
, key
, uid
);
1073 addhstbyname (db
, fd
, req
, key
, uid
);
1076 case GETHOSTBYNAMEv6
:
1077 addhstbynamev6 (db
, fd
, req
, key
, uid
);
1081 addhstbyaddr (db
, fd
, req
, key
, uid
);
1084 case GETHOSTBYADDRv6
:
1085 addhstbyaddrv6 (db
, fd
, req
, key
, uid
);
1089 addhstai (db
, fd
, req
, key
, uid
);
1093 addinitgroups (db
, fd
, req
, key
, uid
);
1097 addservbyname (db
, fd
, req
, key
, uid
);
1101 addservbyport (db
, fd
, req
, key
, uid
);
1108 /* Get the callers credentials. */
1110 struct ucred caller
;
1111 socklen_t optlen
= sizeof (caller
);
1113 if (getsockopt (fd
, SOL_SOCKET
, SO_PEERCRED
, &caller
, &optlen
) < 0)
1117 dbg_log (_("error getting caller's id: %s"),
1118 strerror_r (errno
, buf
, sizeof (buf
)));
1124 /* Some systems have no SO_PEERCRED implementation. They don't
1125 care about security so we don't as well. */
1130 /* Accept shutdown, getstat and invalidate only from root. For
1131 the stat call also allow the user specified in the config file. */
1132 if (req
->type
== GETSTAT
)
1134 if (uid
== 0 || uid
== stat_uid
)
1135 send_stats (fd
, dbs
);
1139 if (req
->type
== INVALIDATE
)
1140 invalidate_cache (key
, fd
);
1142 termination_handler (0);
1151 send_ro_fd (reqinfo
[req
->type
].db
, key
, fd
);
1156 /* Ignore the command, it's nothing we know. */
1162 /* Restart the process. */
1166 /* First determine the parameters. We do not use the parameters
1167 passed to main() since in case nscd is started by running the
1168 dynamic linker this will not work. Yes, this is not the usual
1169 case but nscd is part of glibc and we occasionally do this. */
1170 size_t buflen
= 1024;
1171 char *buf
= alloca (buflen
);
1173 int fd
= open ("/proc/self/cmdline", O_RDONLY
);
1177 cannot open /proc/self/cmdline: %s; disabling paranoia mode"),
1186 ssize_t n
= TEMP_FAILURE_RETRY (read (fd
, buf
+ readlen
,
1191 cannot read /proc/self/cmdline: %s; disabling paranoia mode"),
1201 if (readlen
< buflen
)
1204 /* We might have to extend the buffer. */
1205 size_t old_buflen
= buflen
;
1206 char *newp
= extend_alloca (buf
, buflen
, 2 * buflen
);
1207 buf
= memmove (newp
, buf
, old_buflen
);
1212 /* Parse the command line. Worst case scenario: every two
1213 characters form one parameter (one character plus NUL). */
1214 char **argv
= alloca ((readlen
/ 2 + 1) * sizeof (argv
[0]));
1218 while (cp
< buf
+ readlen
)
1221 cp
= (char *) rawmemchr (cp
, '\0') + 1;
1225 /* Second, change back to the old user if we changed it. */
1226 if (server_user
!= NULL
)
1228 if (setresuid (old_uid
, old_uid
, old_uid
) != 0)
1231 cannot change to old UID: %s; disabling paranoia mode"),
1238 if (setresgid (old_gid
, old_gid
, old_gid
) != 0)
1241 cannot change to old GID: %s; disabling paranoia mode"),
1244 setuid (server_uid
);
1250 /* Next change back to the old working directory. */
1251 if (chdir (oldcwd
) == -1)
1254 cannot change to old working directory: %s; disabling paranoia mode"),
1257 if (server_user
!= NULL
)
1259 setuid (server_uid
);
1260 setgid (server_gid
);
1266 /* Synchronize memory. */
1267 for (int cnt
= 0; cnt
< lastdb
; ++cnt
)
1269 /* Make sure nobody keeps using the database. */
1270 dbs
[cnt
].head
->timestamp
= 0;
1272 if (dbs
[cnt
].persistent
)
1274 msync (dbs
[cnt
].head
, dbs
[cnt
].memsize
, MS_ASYNC
);
1277 /* The preparations are done. */
1278 execv ("/proc/self/exe", argv
);
1280 /* If we come here, we will never be able to re-exec. */
1281 dbg_log (_("re-exec failed: %s; disabling paranoia mode"),
1284 if (server_user
!= NULL
)
1286 setuid (server_uid
);
1287 setgid (server_gid
);
1289 if (chdir ("/") != 0)
1290 dbg_log (_("cannot change current working directory to \"/\": %s"),
1296 /* List of file descriptors. */
1300 struct fdlist
*next
;
1302 /* Memory allocated for the list. */
1303 static struct fdlist
*fdlist
;
1304 /* List of currently ready-to-read file descriptors. */
1305 static struct fdlist
*readylist
;
1307 /* Conditional variable and mutex to signal availability of entries in
1308 READYLIST. The condvar is initialized dynamically since we might
1309 use a different clock depending on availability. */
1310 static pthread_cond_t readylist_cond
;
1311 static pthread_mutex_t readylist_lock
= PTHREAD_MUTEX_INITIALIZER
;
1313 /* The clock to use with the condvar. */
1314 static clockid_t timeout_clock
= CLOCK_REALTIME
;
1316 /* Number of threads ready to handle the READYLIST. */
1317 static unsigned long int nready
;
1320 /* This is the main loop. It is replicated in different threads but the
1321 `poll' call makes sure only one thread handles an incoming connection. */
1323 __attribute__ ((__noreturn__
))
1326 const long int my_number
= (long int) p
;
1327 const int run_prune
= my_number
< lastdb
&& dbs
[my_number
].enabled
;
1328 struct timespec prune_ts
;
1334 setup_thread (&dbs
[my_number
]);
1336 /* We are running. */
1337 dbs
[my_number
].head
->timestamp
= time (NULL
);
1339 if (clock_gettime (timeout_clock
, &prune_ts
) == -1)
1340 /* Should never happen. */
1343 /* Compute timeout time. */
1344 prune_ts
.tv_sec
+= CACHE_PRUNE_INTERVAL
;
1347 /* Initial locking. */
1348 pthread_mutex_lock (&readylist_lock
);
1350 /* One more thread available. */
1355 while (readylist
== NULL
)
1359 /* Wait, but not forever. */
1360 to
= pthread_cond_timedwait (&readylist_cond
, &readylist_lock
,
1363 /* If we were woken and there is no work to be done,
1364 just start pruning. */
1365 if (readylist
== NULL
&& to
== ETIMEDOUT
)
1372 pthread_mutex_unlock (&readylist_lock
);
1377 /* No need to timeout. */
1378 pthread_cond_wait (&readylist_cond
, &readylist_lock
);
1384 pthread_cond_signal (&readylist_cond
);
1387 pthread_mutex_unlock (&readylist_lock
);
1389 /* Prune the password database. */
1390 if (dbs
[pwddb
].enabled
)
1391 prune_cache (&dbs
[pwddb
], LONG_MAX
, -1);
1393 /* Prune the group database. */
1394 if (dbs
[grpdb
].enabled
)
1395 prune_cache (&dbs
[grpdb
], LONG_MAX
, -1);
1397 /* Prune the host database. */
1398 if (dbs
[hstdb
].enabled
)
1399 prune_cache (&dbs
[hstdb
], LONG_MAX
, -1);
1402 pthread_mutex_lock (&readylist_lock
);
1404 /* One more thread available. */
1409 struct fdlist
*it
= readylist
->next
;
1410 if (readylist
->next
== readylist
)
1411 /* Just one entry on the list. */
1414 readylist
->next
= it
->next
;
1416 /* Extract the information and mark the record ready to be used
1421 /* One more thread available. */
1424 /* We are done with the list. */
1425 pthread_mutex_unlock (&readylist_lock
);
1427 /* We do not want to block on a short read or so. */
1428 int fl
= fcntl (fd
, F_GETFL
);
1429 if (fl
== -1 || fcntl (fd
, F_SETFL
, fl
| O_NONBLOCK
) == -1)
1432 /* Now read the request. */
1434 if (__builtin_expect (TEMP_FAILURE_RETRY (read (fd
, &req
, sizeof (req
)))
1435 != sizeof (req
), 0))
1437 /* We failed to read data. Note that this also might mean we
1438 failed because we would have blocked. */
1439 if (debug_level
> 0)
1440 dbg_log (_("short read while reading request: %s"),
1441 strerror_r (errno
, buf
, sizeof (buf
)));
1445 /* Check whether this is a valid request type. */
1446 if (req
.type
< GETPWBYNAME
|| req
.type
>= LASTREQ
)
1449 /* Some systems have no SO_PEERCRED implementation. They don't
1450 care about security so we don't as well. */
1455 if (__builtin_expect (debug_level
> 0, 0))
1457 struct ucred caller
;
1458 socklen_t optlen
= sizeof (caller
);
1460 if (getsockopt (fd
, SOL_SOCKET
, SO_PEERCRED
, &caller
, &optlen
) == 0)
1465 /* It should not be possible to crash the nscd with a silly
1466 request (i.e., a terribly large key). We limit the size to 1kb. */
1467 if (__builtin_expect (req
.key_len
, 1) < 0
1468 || __builtin_expect (req
.key_len
, 1) > MAXKEYLEN
)
1470 if (debug_level
> 0)
1471 dbg_log (_("key length in request too long: %d"), req
.key_len
);
1476 char keybuf
[MAXKEYLEN
];
1478 if (__builtin_expect (TEMP_FAILURE_RETRY (read (fd
, keybuf
,
1482 /* Again, this can also mean we would have blocked. */
1483 if (debug_level
> 0)
1484 dbg_log (_("short read while reading request key: %s"),
1485 strerror_r (errno
, buf
, sizeof (buf
)));
1489 if (__builtin_expect (debug_level
, 0) > 0)
1494 handle_request: request received (Version = %d) from PID %ld"),
1495 req
.version
, (long int) pid
);
1499 handle_request: request received (Version = %d)"), req
.version
);
1502 /* Phew, we got all the data, now process it. */
1503 handle_request (fd
, &req
, keybuf
, uid
);
1510 /* Check whether we should be pruning the cache. */
1511 assert (run_prune
|| to
== 0);
1512 if (to
== ETIMEDOUT
)
1515 /* The pthread_cond_timedwait() call timed out. It is time
1516 to clean up the cache. */
1517 assert (my_number
< lastdb
);
1518 prune_cache (&dbs
[my_number
], time (NULL
), -1);
1520 if (clock_gettime (timeout_clock
, &prune_ts
) == -1)
1521 /* Should never happen. */
1524 /* Compute next timeout time. */
1525 prune_ts
.tv_sec
+= CACHE_PRUNE_INTERVAL
;
1527 /* In case the list is emtpy we do not want to run the prune
1528 code right away again. */
1533 pthread_mutex_lock (&readylist_lock
);
1535 /* One more thread available. */
1541 static unsigned int nconns
;
1546 pthread_mutex_lock (&readylist_lock
);
1548 /* Find an empty entry in FDLIST. */
1550 for (inner
= 0; inner
< nconns
; ++inner
)
1551 if (fdlist
[inner
].next
== NULL
)
1553 assert (inner
< nconns
);
1555 fdlist
[inner
].fd
= fd
;
1557 if (readylist
== NULL
)
1558 readylist
= fdlist
[inner
].next
= &fdlist
[inner
];
1561 fdlist
[inner
].next
= readylist
->next
;
1562 readylist
= readylist
->next
= &fdlist
[inner
];
1565 bool do_signal
= true;
1566 if (__builtin_expect (nready
== 0, 0))
1571 /* Try to start another thread to help out. */
1573 if (nthreads
< max_nthreads
1574 && pthread_create (&th
, &attr
, nscd_run
,
1575 (void *) (long int) nthreads
) == 0)
1577 /* We got another thread. */
1579 /* The new thread might need a kick. */
1585 pthread_mutex_unlock (&readylist_lock
);
1587 /* Tell one of the worker threads there is work to do. */
1589 pthread_cond_signal (&readylist_cond
);
1593 /* Check whether restarting should happen. */
1595 restart_p (time_t now
)
1597 return (paranoia
&& readylist
== NULL
&& nready
== nthreads
1598 && now
>= restart_time
);
1602 /* Array for times a connection was accepted. */
1603 static time_t *starttime
;
1607 __attribute__ ((__noreturn__
))
1608 main_loop_poll (void)
1610 struct pollfd
*conns
= (struct pollfd
*) xmalloc (nconns
1611 * sizeof (conns
[0]));
1614 conns
[0].events
= POLLRDNORM
;
1616 size_t firstfree
= 1;
1620 /* Wait for any event. We wait at most a couple of seconds so
1621 that we can check whether we should close any of the accepted
1622 connections since we have not received a request. */
1623 #define MAX_ACCEPT_TIMEOUT 30
1624 #define MIN_ACCEPT_TIMEOUT 5
1625 #define MAIN_THREAD_TIMEOUT \
1626 (MAX_ACCEPT_TIMEOUT * 1000 \
1627 - ((MAX_ACCEPT_TIMEOUT - MIN_ACCEPT_TIMEOUT) * 1000 * nused) / (2 * nconns))
1629 int n
= poll (conns
, nused
, MAIN_THREAD_TIMEOUT
);
1631 time_t now
= time (NULL
);
1633 /* If there is a descriptor ready for reading or there is a new
1634 connection, process this now. */
1637 if (conns
[0].revents
!= 0)
1639 /* We have a new incoming connection. Accept the connection. */
1640 int fd
= TEMP_FAILURE_RETRY (accept (sock
, NULL
, NULL
));
1642 /* Use the descriptor if we have not reached the limit. */
1645 if (firstfree
< nconns
)
1647 conns
[firstfree
].fd
= fd
;
1648 conns
[firstfree
].events
= POLLRDNORM
;
1649 starttime
[firstfree
] = now
;
1650 if (firstfree
>= nused
)
1651 nused
= firstfree
+ 1;
1655 while (firstfree
< nused
&& conns
[firstfree
].fd
!= -1);
1658 /* We cannot use the connection so close it. */
1665 for (size_t cnt
= 1; cnt
< nused
&& n
> 0; ++cnt
)
1666 if (conns
[cnt
].revents
!= 0)
1668 fd_ready (conns
[cnt
].fd
);
1670 /* Clean up the CONNS array. */
1672 if (cnt
< firstfree
)
1674 if (cnt
== nused
- 1)
1677 while (conns
[nused
- 1].fd
== -1);
1683 /* Now find entries which have timed out. */
1686 /* We make the timeout length depend on the number of file
1687 descriptors currently used. */
1688 #define ACCEPT_TIMEOUT \
1689 (MAX_ACCEPT_TIMEOUT \
1690 - ((MAX_ACCEPT_TIMEOUT - MIN_ACCEPT_TIMEOUT) * nused) / nconns)
1691 time_t laststart
= now
- ACCEPT_TIMEOUT
;
1693 for (size_t cnt
= nused
- 1; cnt
> 0; --cnt
)
1695 if (conns
[cnt
].fd
!= -1 && starttime
[cnt
] < laststart
)
1697 /* Remove the entry, it timed out. */
1698 (void) close (conns
[cnt
].fd
);
1701 if (cnt
< firstfree
)
1703 if (cnt
== nused
- 1)
1706 while (conns
[nused
- 1].fd
== -1);
1710 if (restart_p (now
))
1718 main_loop_epoll (int efd
)
1720 struct epoll_event ev
= { 0, };
1724 /* Add the socket. */
1725 ev
.events
= EPOLLRDNORM
;
1727 if (epoll_ctl (efd
, EPOLL_CTL_ADD
, sock
, &ev
) == -1)
1728 /* We cannot use epoll. */
1733 struct epoll_event revs
[100];
1734 # define nrevs (sizeof (revs) / sizeof (revs[0]))
1736 int n
= epoll_wait (efd
, revs
, nrevs
, MAIN_THREAD_TIMEOUT
);
1738 time_t now
= time (NULL
);
1740 for (int cnt
= 0; cnt
< n
; ++cnt
)
1741 if (revs
[cnt
].data
.fd
== sock
)
1743 /* A new connection. */
1744 int fd
= TEMP_FAILURE_RETRY (accept (sock
, NULL
, NULL
));
1748 /* Try to add the new descriptor. */
1751 || epoll_ctl (efd
, EPOLL_CTL_ADD
, fd
, &ev
) == -1)
1752 /* The descriptor is too large or something went
1753 wrong. Close the descriptor. */
1757 /* Remember when we accepted the connection. */
1758 starttime
[fd
] = now
;
1769 /* Remove the descriptor from the epoll descriptor. */
1770 (void) epoll_ctl (efd
, EPOLL_CTL_DEL
, revs
[cnt
].data
.fd
, NULL
);
1772 /* Get a worker to handle the request. */
1773 fd_ready (revs
[cnt
].data
.fd
);
1775 /* Reset the time. */
1776 starttime
[revs
[cnt
].data
.fd
] = 0;
1777 if (revs
[cnt
].data
.fd
== highest
)
1780 while (highest
> 0 && starttime
[highest
] == 0);
1785 /* Now look for descriptors for accepted connections which have
1786 no reply in too long of a time. */
1787 time_t laststart
= now
- ACCEPT_TIMEOUT
;
1788 for (int cnt
= highest
; cnt
> STDERR_FILENO
; --cnt
)
1789 if (cnt
!= sock
&& starttime
[cnt
] != 0 && starttime
[cnt
] < laststart
)
1791 /* We are waiting for this one for too long. Close it. */
1792 (void) epoll_ctl (efd
, EPOLL_CTL_DEL
, cnt
, NULL
);
1800 else if (cnt
!= sock
&& starttime
[cnt
] == 0 && cnt
== highest
)
1803 if (restart_p (now
))
1810 /* Start all the threads we want. The initial process is thread no. 1. */
1812 start_threads (void)
1814 /* Initialize the conditional variable we will use. The only
1815 non-standard attribute we might use is the clock selection. */
1816 pthread_condattr_t condattr
;
1817 pthread_condattr_init (&condattr
);
1819 #if defined _POSIX_CLOCK_SELECTION && _POSIX_CLOCK_SELECTION >= 0 \
1820 && defined _POSIX_MONOTONIC_CLOCK && _POSIX_MONOTONIC_CLOCK >= 0
1821 /* Determine whether the monotonous clock is available. */
1822 struct timespec dummy
;
1823 # if _POSIX_MONOTONIC_CLOCK == 0
1824 if (sysconf (_SC_MONOTONIC_CLOCK
) > 0)
1826 # if _POSIX_CLOCK_SELECTION == 0
1827 if (sysconf (_SC_CLOCK_SELECTION
) > 0)
1829 if (clock_getres (CLOCK_MONOTONIC
, &dummy
) == 0
1830 && pthread_condattr_setclock (&condattr
, CLOCK_MONOTONIC
) == 0)
1831 timeout_clock
= CLOCK_MONOTONIC
;
1834 pthread_cond_init (&readylist_cond
, &condattr
);
1835 pthread_condattr_destroy (&condattr
);
1838 /* Create the attribute for the threads. They are all created
1840 pthread_attr_init (&attr
);
1841 pthread_attr_setdetachstate (&attr
, PTHREAD_CREATE_DETACHED
);
1842 /* Use 1MB stacks, twice as much for 64-bit architectures. */
1843 pthread_attr_setstacksize (&attr
, 1024 * 1024 * (sizeof (void *) / 4));
1845 /* We allow less than LASTDB threads only for debugging. */
1846 if (debug_level
== 0)
1847 nthreads
= MAX (nthreads
, lastdb
);
1850 for (long int i
= 0; i
< nthreads
; ++i
)
1853 if (pthread_create (&th
, &attr
, nscd_run
, (void *) (i
- nfailed
)) != 0)
1856 if (nthreads
- nfailed
< lastdb
)
1858 /* We could not start enough threads. */
1859 dbg_log (_("could only start %d threads; terminating"),
1860 nthreads
- nfailed
);
1864 /* Determine how much room for descriptors we should initially
1865 allocate. This might need to change later if we cap the number
1867 const long int nfds
= sysconf (_SC_OPEN_MAX
);
1869 #define MAXCONN 16384
1870 if (nfds
== -1 || nfds
> MAXCONN
)
1872 else if (nfds
< MINCONN
)
1877 /* We need memory to pass descriptors on to the worker threads. */
1878 fdlist
= (struct fdlist
*) xcalloc (nconns
, sizeof (fdlist
[0]));
1879 /* Array to keep track when connection was accepted. */
1880 starttime
= (time_t *) xcalloc (nconns
, sizeof (starttime
[0]));
1882 /* In the main thread we execute the loop which handles incoming
1885 int efd
= epoll_create (100);
1888 main_loop_epoll (efd
);
1897 /* Look up the uid, gid, and supplementary groups to run nscd as. When
1898 this function is called, we are not listening on the nscd socket yet so
1899 we can just use the ordinary lookup functions without causing a lockup */
1901 begin_drop_privileges (void)
1903 struct passwd
*pwd
= getpwnam (server_user
);
1907 dbg_log (_("Failed to run nscd as user '%s'"), server_user
);
1908 error (EXIT_FAILURE
, 0, _("Failed to run nscd as user '%s'"),
1912 server_uid
= pwd
->pw_uid
;
1913 server_gid
= pwd
->pw_gid
;
1915 /* Save the old UID/GID if we have to change back. */
1918 old_uid
= getuid ();
1919 old_gid
= getgid ();
1922 if (getgrouplist (server_user
, server_gid
, NULL
, &server_ngroups
) == 0)
1924 /* This really must never happen. */
1925 dbg_log (_("Failed to run nscd as user '%s'"), server_user
);
1926 error (EXIT_FAILURE
, errno
, _("initial getgrouplist failed"));
1929 server_groups
= (gid_t
*) xmalloc (server_ngroups
* sizeof (gid_t
));
1931 if (getgrouplist (server_user
, server_gid
, server_groups
, &server_ngroups
)
1934 dbg_log (_("Failed to run nscd as user '%s'"), server_user
);
1935 error (EXIT_FAILURE
, errno
, _("getgrouplist failed"));
1940 /* Call setgroups(), setgid(), and setuid() to drop root privileges and
1941 run nscd as the user specified in the configuration file. */
1943 finish_drop_privileges (void)
1945 #if defined HAVE_LIBAUDIT && defined HAVE_LIBCAP
1946 /* We need to preserve the capabilities to connect to the audit daemon. */
1947 cap_t new_caps
= preserve_capabilities ();
1950 if (setgroups (server_ngroups
, server_groups
) == -1)
1952 dbg_log (_("Failed to run nscd as user '%s'"), server_user
);
1953 error (EXIT_FAILURE
, errno
, _("setgroups failed"));
1958 res
= setresgid (server_gid
, server_gid
, old_gid
);
1960 res
= setgid (server_gid
);
1963 dbg_log (_("Failed to run nscd as user '%s'"), server_user
);
1969 res
= setresuid (server_uid
, server_uid
, old_uid
);
1971 res
= setuid (server_uid
);
1974 dbg_log (_("Failed to run nscd as user '%s'"), server_user
);
1979 #if defined HAVE_LIBAUDIT && defined HAVE_LIBCAP
1980 /* Remove the temporary capabilities. */
1981 install_real_capabilities (new_caps
);
1985 /* Handle the HUP signal which will force a dump of the cache */
1987 sighup_handler (int signum
)