1 /*        $NetBSD: daemon.c,v 1.3 2021/08/14 16:14:58 christos Exp $  */
2 
3 /* $OpenLDAP$ */
4 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5  *
6  * Copyright 1998-2021 The OpenLDAP Foundation.
7  * Portions Copyright 2007 by Howard Chu, Symas Corporation.
8  * All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted only as authorized by the OpenLDAP
12  * Public License.
13  *
14  * A copy of this license is available in the file LICENSE in the
15  * top-level directory of the distribution or, alternatively, at
16  * <http://www.OpenLDAP.org/license.html>.
17  */
18 /* Portions Copyright (c) 1995 Regents of the University of Michigan.
19  * All rights reserved.
20  *
21  * Redistribution and use in source and binary forms are permitted
22  * provided that this notice is preserved and that due credit is given
23  * to the University of Michigan at Ann Arbor. The name of the University
24  * may not be used to endorse or promote products derived from this
25  * software without specific prior written permission. This software
26  * is provided ``as is'' without express or implied warranty.
27  */
28 
29 #include <sys/cdefs.h>
30 __RCSID("$NetBSD: daemon.c,v 1.3 2021/08/14 16:14:58 christos Exp $");
31 
32 #include "portable.h"
33 
34 #include <stdio.h>
35 
36 #include <ac/ctype.h>
37 #include <ac/errno.h>
38 #include <ac/socket.h>
39 #include <ac/string.h>
40 #include <ac/time.h>
41 #include <ac/unistd.h>
42 
43 #include "slap.h"
44 #include "ldap_pvt_thread.h"
45 #include "lutil.h"
46 
47 #include "ldap_rq.h"
48 
49 #ifdef HAVE_SYSTEMD_SD_DAEMON_H
50 #include <systemd/sd-daemon.h>
51 #endif
52 
53 #ifdef HAVE_POLL
54 #include <poll.h>
55 #endif
56 
57 #ifdef HAVE_KQUEUE
58 # include <sys/types.h>
59 # include <sys/event.h>
60 # include <sys/time.h>
61 #elif defined(HAVE_SYS_EPOLL_H) && defined(HAVE_EPOLL)
62 # include <sys/epoll.h>
63 #elif defined(SLAP_X_DEVPOLL) && defined(HAVE_SYS_DEVPOLL_H) && defined(HAVE_DEVPOLL)
64 # include <sys/types.h>
65 # include <sys/stat.h>
66 # include <fcntl.h>
67 # include <sys/devpoll.h>
68 #endif /* ! kqueue && ! epoll && ! /dev/poll */
69 
70 #ifdef HAVE_TCPD
71 int allow_severity = LOG_INFO;
72 int deny_severity = LOG_NOTICE;
73 #endif /* TCP Wrappers */
74 
75 #ifdef LDAP_PF_LOCAL
76 # include <sys/stat.h>
77 /* this should go in <ldap.h> as soon as it is accepted */
78 # define LDAPI_MOD_URLEXT               "x-mod"
79 #endif /* LDAP_PF_LOCAL */
80 
81 #ifdef LDAP_PF_INET6
82 int slap_inet4or6 = AF_UNSPEC;
83 #else /* ! INETv6 */
84 int slap_inet4or6 = AF_INET;
85 #endif /* ! INETv6 */
86 
87 /* globals */
88 time_t starttime;
89 ber_socket_t dtblsize;
90 slap_ssf_t local_ssf = LDAP_PVT_SASL_LOCAL_SSF;
91 struct runqueue_s slapd_rq;
92 
93 int slapd_daemon_threads = 1;
94 int slapd_daemon_mask;
95 
96 #ifdef LDAP_TCP_BUFFER
97 int slapd_tcp_rmem;
98 int slapd_tcp_wmem;
99 #endif /* LDAP_TCP_BUFFER */
100 
101 Listener **slap_listeners = NULL;
102 static volatile sig_atomic_t listening = 1; /* 0 when slap_listeners closed */
103 
104 #ifndef SLAPD_LISTEN_BACKLOG
105 #define SLAPD_LISTEN_BACKLOG 2048
106 #endif /* ! SLAPD_LISTEN_BACKLOG */
107 
108 #define   DAEMON_ID(fd)       (fd & slapd_daemon_mask)
109 
110 typedef ber_socket_t sdpair[2];
111 
112 static sdpair *wake_sds;
113 static ldap_pvt_thread_mutex_t emfile_mutex;
114 static int emfile;
115 
116 static volatile int waking;
117 #define WAKE_LISTENER(l,w)    do { \
118           if (w) { \
119                     (void)!tcp_write( SLAP_FD2SOCK(wake_sds[l][1]), "0", 1 ); \
120           } \
121 } while (0)
122 
123 ldap_pvt_thread_mutex_t slapd_init_mutex;
124 ldap_pvt_thread_cond_t slapd_init_cond;
125 int slapd_ready = 0;
126 
127 volatile sig_atomic_t slapd_shutdown = 0;
128 volatile sig_atomic_t slapd_gentle_shutdown = 0;
129 volatile sig_atomic_t slapd_abrupt_shutdown = 0;
130 
131 #ifdef HAVE_WINSOCK
132 ldap_pvt_thread_mutex_t slapd_ws_mutex;
133 SOCKET *slapd_ws_sockets;
134 #define   SD_READ 1
135 #define   SD_WRITE  2
136 #define   SD_ACTIVE 4
137 #define   SD_LISTENER         8
138 #endif
139 
140 #ifdef HAVE_TCPD
141 static ldap_pvt_thread_mutex_t          sd_tcpd_mutex;
142 #endif /* TCP Wrappers */
143 
144 typedef struct slap_daemon_st {
145           ldap_pvt_thread_mutex_t       sd_mutex;
146 
147           ber_socket_t                  sd_nactives;
148           int                           sd_nwriters;
149           int                           sd_nfds;
150           ldap_pvt_thread_t   sd_tid;
151 
152 #if defined(HAVE_KQUEUE)
153           uint8_t*        sd_fdmodes; /* indexed by fd */
154           Listener**      sd_l;       /* indexed by fd */
155           /* Double buffer the kqueue changes to avoid holding the sd_mutex \
156            * during a kevent() call. \
157            */
158           struct kq_change {
159               struct kevent*  sd_changes;
160               int             sd_nchanges;
161               int             sd_maxchanges;
162           }               sd_kqc[2];
163           int             sd_changeidx; /* index to current change buffer */
164           int             sd_kq;
165 #elif defined(HAVE_EPOLL)
166 
167           struct epoll_event  *sd_epolls;
168           int                           *sd_index;
169           int                           sd_epfd;
170 #elif defined(SLAP_X_DEVPOLL) && defined(HAVE_DEVPOLL)
171           /* eXperimental */
172           struct pollfd                 *sd_pollfd;
173           int                           *sd_index;
174           Listener            **sd_l;
175           int                           sd_dpfd;
176 #else /* ! kqueue && ! epoll && ! /dev/poll */
177 #ifdef HAVE_WINSOCK
178           char      *sd_flags;
179           char      *sd_rflags;
180 #else /* ! HAVE_WINSOCK */
181           fd_set                        sd_actives;
182           fd_set                        sd_readers;
183           fd_set                        sd_writers;
184 #endif /* ! HAVE_WINSOCK */
185 #endif /* ! kqueue && ! epoll && ! /dev/poll */
186 } slap_daemon_st;
187 
188 static slap_daemon_st *slap_daemon;
189 
190 /*
191  * NOTE: naming convention for macros:
192  *
193  * - SLAP_SOCK_* and SLAP_EVENT_* for public interface that deals
194  *   with file descriptors and events respectively
195  *
196  * - SLAP_<type>_* for private interface; type by now is one of
197  *   EPOLL, DEVPOLL, SELECT, KQUEUE
198  *
199  * private interface should not be used in the code.
200  */
201 #ifdef HAVE_KQUEUE
202 # define SLAP_EVENT_FNAME                   "kqueue"
203 # define SLAP_EVENTS_ARE_INDEXED        0
204 # define SLAP_EVENT_MAX(t)             (2 * dtblsize)  /* each fd can have a read & a write event */
205 
206 # define SLAP_EVENT_DECL \
207      static struct kevent* events = NULL
208 
209 # define SLAP_EVENT_INIT(t) do {\
210     if (!events) { \
211         events = ch_malloc(sizeof(*events) * SLAP_EVENT_MAX(t)); \
212     } \
213 } while (0)
214 
215 # define SLAP_SOCK_INIT(t) do { \
216     int kq_i; \
217     size_t kq_nbytes; \
218     Debug(LDAP_DEBUG_ANY, "daemon: SLAP_SOCK_INIT: dtblsize=%d\n", dtblsize); \
219     slap_daemon[t].sd_nfds       = 0; \
220     slap_daemon[t].sd_changeidx  = 0; \
221     for (kq_i = 0;  kq_i < 2;  kq_i++) { \
222         struct kq_change* kqc = &slap_daemon[t].sd_kqc[kq_i]; \
223         kqc->sd_nchanges   = 0; \
224         kqc->sd_maxchanges = 256; /* will grow as needed */ \
225         kq_nbytes = sizeof(*kqc->sd_changes) * kqc->sd_maxchanges; \
226         kqc->sd_changes = ch_calloc(1, kq_nbytes); \
227     } \
228     kq_nbytes = sizeof(*slap_daemon[t].sd_fdmodes) * dtblsize; \
229     slap_daemon[t].sd_fdmodes = ch_calloc(1, kq_nbytes); \
230     kq_nbytes = sizeof(*slap_daemon[t].sd_l) * dtblsize; \
231     slap_daemon[t].sd_l = ch_calloc(1, kq_nbytes); \
232     slap_daemon[t].sd_kq = kqueue(); \
233 } while (0)
234 
235 /* a kqueue fd obtained before a fork can't be used in child process.
236  * close it and reacquire it.
237  */
238 # define SLAP_SOCK_INIT2() do { \
239           close(slap_daemon[0].sd_kq); \
240           slap_daemon[0].sd_kq = kqueue(); \
241 } while (0)
242 
243 # define SLAP_SOCK_DESTROY(t) do { \
244           int kq_i; \
245     if (slap_daemon[t].sd_kq > 0) { \
246         close(slap_daemon[t].sd_kq); \
247         slap_daemon[t].sd_kq = -1; \
248     } \
249     for (kq_i = 0;  kq_i < 2;  kq_i++) { \
250         if (slap_daemon[t].sd_kqc[kq_i].sd_changes != NULL) { \
251             ch_free(slap_daemon[t].sd_kqc[kq_i].sd_changes); \
252             slap_daemon[t].sd_kqc[kq_i].sd_changes = NULL; \
253         } \
254         slap_daemon[t].sd_kqc[kq_i].sd_nchanges = 0; \
255         slap_daemon[t].sd_kqc[kq_i].sd_maxchanges = 0; \
256     } \
257     if (slap_daemon[t].sd_l != NULL) { \
258         ch_free(slap_daemon[t].sd_l); \
259         slap_daemon[t].sd_l = NULL; \
260     } \
261     if (slap_daemon[t].sd_fdmodes != NULL) { \
262         ch_free(slap_daemon[t].sd_fdmodes); \
263         slap_daemon[t].sd_fdmodes = NULL; \
264     } \
265     slap_daemon[t].sd_nfds = 0; \
266 } while (0)
267 
268 # define SLAP_KQUEUE_SOCK_ACTIVE        0x01
269 # define SLAP_KQUEUE_SOCK_READ_ENABLED  0x02
270 # define SLAP_KQUEUE_SOCK_WRITE_ENABLED 0x04
271 
272 # define SLAP_SOCK_IS_ACTIVE(t,s)  (slap_daemon[t].sd_fdmodes[(s)] != 0)
273 # define SLAP_SOCK_NOT_ACTIVE(t,s) (slap_daemon[t].sd_fdmodes[(s)] == 0)
274 # define SLAP_SOCK_IS_READ(t,s)    (slap_daemon[t].sd_fdmodes[(s)] & SLAP_KQUEUE_SOCK_READ_ENABLED)
275 # define SLAP_SOCK_IS_WRITE(t,s)   (slap_daemon[t].sd_fdmodes[(s)] & SLAP_KQUEUE_SOCK_WRITE_ENABLED)
276 
277 /*
278  * SLAP_SOCK_SET_* & SLAP_SOCK_CLR_* get called a _lot_.  Since kevent()
279  * processes changes before it looks for events, batch up the changes which
280  * will get submitted the next time kevent() is called for events.
281  */
282 
283 # define SLAP_KQUEUE_CHANGE(t, s, filter, flag) do { \
284     /* If maxchanges is reached, have to realloc to make room for more. \
285      * Ideally we'd call kevent(), but the daemon thread could be sitting \
286      * in kevent() waiting for events. \
287      */ \
288     struct kq_change* kqc = &slap_daemon[t].sd_kqc[slap_daemon[t].sd_changeidx]; \
289     if (kqc->sd_nchanges == kqc->sd_maxchanges) { \
290         /* Don't want to do this very often.  Double the size. */ \
291         size_t kq_nbytes; \
292         Debug(LDAP_DEBUG_CONNS, \
293               "daemon: SLAP_KQUEUE_CHANGE: increasing slap_daemon.sd_kqc[%d].maxchanges from %d to %d\n", \
294               slap_daemon[t].sd_changeidx, kqc->sd_maxchanges, 2*kqc->sd_maxchanges); \
295         kqc->sd_maxchanges += kqc->sd_maxchanges; \
296         kq_nbytes = sizeof(*kqc->sd_changes) * kqc->sd_maxchanges; \
297         kqc->sd_changes = ch_realloc(kqc->sd_changes, kq_nbytes); \
298     } \
299     EV_SET(&kqc->sd_changes[kqc->sd_nchanges++], \
300            (s), (filter), (flag), 0, 0, slap_daemon[t].sd_l[(s)]); \
301 } while (0)
302 
303 # define SLAP_KQUEUE_SOCK_SET(t, s, filter, mode) do { \
304     if ((slap_daemon[t].sd_fdmodes[(s)] & (mode)) != (mode)) { \
305         slap_daemon[t].sd_fdmodes[(s)] |= (mode); \
306         SLAP_KQUEUE_CHANGE(t, (s), (filter), EV_ENABLE); \
307     } \
308 } while (0)
309 
310 # define SLAP_KQUEUE_SOCK_CLR(t, s, filter, mode) do { \
311     if (slap_daemon[t].sd_fdmodes[(s)] & (mode)) { \
312         slap_daemon[t].sd_fdmodes[(s)] &= ~(mode); \
313         SLAP_KQUEUE_CHANGE(t, (s), (filter), EV_DISABLE); \
314     } \
315 } while (0)
316 
317 # define SLAP_SOCK_SET_READ(t, s)  SLAP_KQUEUE_SOCK_SET(t, (s), EVFILT_READ,  SLAP_KQUEUE_SOCK_READ_ENABLED)
318 # define SLAP_SOCK_SET_WRITE(t, s) SLAP_KQUEUE_SOCK_SET(t, (s), EVFILT_WRITE, SLAP_KQUEUE_SOCK_WRITE_ENABLED)
319 # define SLAP_SOCK_CLR_READ(t, s)  SLAP_KQUEUE_SOCK_CLR(t, (s), EVFILT_READ,  SLAP_KQUEUE_SOCK_READ_ENABLED)
320 # define SLAP_SOCK_CLR_WRITE(t, s) SLAP_KQUEUE_SOCK_CLR(t, (s), EVFILT_WRITE, SLAP_KQUEUE_SOCK_WRITE_ENABLED)
321 
322 /* kqueue doesn't need to do anything to clear the event. */
323 # define SLAP_EVENT_CLR_READ(i)     do {} while (0)
324 # define SLAP_EVENT_CLR_WRITE(i)    do {} while (0)
325 
326 # define SLAP_SOCK_ADD(t, s, l) do { \
327     assert( s < dtblsize ); \
328     slap_daemon[t].sd_l[(s)] = (l); \
329     slap_daemon[t].sd_fdmodes[(s)] = SLAP_KQUEUE_SOCK_ACTIVE | SLAP_KQUEUE_SOCK_READ_ENABLED; \
330     ++slap_daemon[t].sd_nfds; \
331     SLAP_KQUEUE_CHANGE(t, (s), EVFILT_READ, EV_ADD); \
332     SLAP_KQUEUE_CHANGE(t, (s), EVFILT_WRITE, EV_ADD | EV_DISABLE); \
333 } while (0)
334 
335 # define SLAP_SOCK_DEL(t, s) do { \
336     SLAP_KQUEUE_CHANGE(t, (s), EVFILT_READ, EV_DELETE); \
337     SLAP_KQUEUE_CHANGE(t, (s), EVFILT_WRITE, EV_DELETE); \
338     slap_daemon[t].sd_l[(s)] = NULL; \
339     slap_daemon[t].sd_fdmodes[(s)] = 0; \
340     --slap_daemon[t].sd_nfds; \
341 } while (0)
342 
343 # define SLAP_EVENT_FD(t, i)          (events[(i)].ident)
344 
345 # define SLAP_EVENT_IS_READ(t, i) \
346     (events[(i)].filter == EVFILT_READ && SLAP_SOCK_IS_READ(t, SLAP_EVENT_FD(0, i)))
347 
348 # define SLAP_EVENT_IS_WRITE(t, i) \
349     (events[(i)].filter == EVFILT_WRITE && SLAP_SOCK_IS_WRITE(t, SLAP_EVENT_FD(0, i)))
350 
351 # define SLAP_EVENT_IS_LISTENER(t, i) \
352     (events[(i)].udata && SLAP_SOCK_IS_READ(t, SLAP_EVENT_FD(t, i)))
353 
354 # define SLAP_EVENT_LISTENER(t, i)    ((Listener*)(events[(i)].udata))
355 
356 # define SLAP_EVENT_WAIT(t, tvp, nsp) do { \
357     struct timespec  kq_ts; \
358     struct timespec* kq_tsp; \
359     int kq_idx; \
360     if (tvp) { \
361         TIMEVAL_TO_TIMESPEC((tvp), &kq_ts); \
362         kq_tsp = &kq_ts; \
363     } else { \
364         kq_tsp = NULL; \
365     } \
366     /* Save the change buffer index for use when the mutex is unlocked, \
367      * then switch the index so new changes go to the other buffer. \
368      */ \
369     ldap_pvt_thread_mutex_lock( &slap_daemon[t].sd_mutex ); \
370     kq_idx = slap_daemon[t].sd_changeidx; \
371     slap_daemon[t].sd_changeidx ^= 1; \
372     ldap_pvt_thread_mutex_unlock( &slap_daemon[t].sd_mutex ); \
373     *(nsp) = kevent(slap_daemon[t].sd_kq, \
374                     slap_daemon[t].sd_kqc[kq_idx].sd_nchanges \
375                         ? slap_daemon[t].sd_kqc[kq_idx].sd_changes : NULL, \
376                     slap_daemon[t].sd_kqc[kq_idx].sd_nchanges, \
377                     events, SLAP_EVENT_MAX(t), kq_tsp); \
378     slap_daemon[t].sd_kqc[kq_idx].sd_nchanges = 0; \
379 } while(0)
380 
381 /*-------------------------------------------------------------------------------*/
382 
383 #elif defined(HAVE_EPOLL)
384 /***************************************
385  * Use epoll infrastructure - epoll(4) *
386  ***************************************/
387 # define SLAP_EVENT_FNAME               "epoll"
388 # define SLAP_EVENTS_ARE_INDEXED        0
389 # define SLAP_EPOLL_SOCK_IX(t,s)                  (slap_daemon[t].sd_index[(s)])
390 # define SLAP_EPOLL_SOCK_EP(t,s)                  (slap_daemon[t].sd_epolls[SLAP_EPOLL_SOCK_IX(t,s)])
391 # define SLAP_EPOLL_SOCK_EV(t,s)                  (SLAP_EPOLL_SOCK_EP(t,s).events)
392 # define SLAP_SOCK_IS_ACTIVE(t,s)                 (SLAP_EPOLL_SOCK_IX(t,s) != -1)
393 # define SLAP_SOCK_NOT_ACTIVE(t,s)      (SLAP_EPOLL_SOCK_IX(t,s) == -1)
394 # define SLAP_EPOLL_SOCK_IS_SET(t,s, mode)        (SLAP_EPOLL_SOCK_EV(t,s) & (mode))
395 
396 # define SLAP_SOCK_IS_READ(t,s)                   SLAP_EPOLL_SOCK_IS_SET(t,(s), EPOLLIN)
397 # define SLAP_SOCK_IS_WRITE(t,s)                  SLAP_EPOLL_SOCK_IS_SET(t,(s), EPOLLOUT)
398 
399 # define SLAP_EPOLL_SOCK_SET(t,s, mode) do { \
400           if ( (SLAP_EPOLL_SOCK_EV(t,s) & (mode)) != (mode) ) {       \
401                     SLAP_EPOLL_SOCK_EV(t,s) |= (mode); \
402                     epoll_ctl( slap_daemon[t].sd_epfd, EPOLL_CTL_MOD, (s), \
403                               &SLAP_EPOLL_SOCK_EP(t,s) ); \
404           } \
405 } while (0)
406 
407 # define SLAP_EPOLL_SOCK_CLR(t,s, mode) do { \
408           if ( (SLAP_EPOLL_SOCK_EV(t,s) & (mode)) ) { \
409                     SLAP_EPOLL_SOCK_EV(t,s) &= ~(mode);     \
410                     epoll_ctl( slap_daemon[t].sd_epfd, EPOLL_CTL_MOD, s, \
411                               &SLAP_EPOLL_SOCK_EP(t,s) ); \
412           } \
413 } while (0)
414 
415 # define SLAP_SOCK_SET_READ(t,s)                  SLAP_EPOLL_SOCK_SET(t,s, EPOLLIN)
416 # define SLAP_SOCK_SET_WRITE(t,s)                 SLAP_EPOLL_SOCK_SET(t,s, EPOLLOUT)
417 
418 # define SLAP_SOCK_CLR_READ(t,s)                  SLAP_EPOLL_SOCK_CLR(t,(s), EPOLLIN)
419 # define SLAP_SOCK_CLR_WRITE(t,s)                 SLAP_EPOLL_SOCK_CLR(t,(s), EPOLLOUT)
420 
421 #  define SLAP_SOCK_SET_SUSPEND(t,s) \
422           ( slap_daemon[t].sd_suspend[SLAP_EPOLL_SOCK_IX(t,s)] = 1 )
423 #  define SLAP_SOCK_CLR_SUSPEND(t,s) \
424           ( slap_daemon[t].sd_suspend[SLAP_EPOLL_SOCK_IX(t,s)] = 0 )
425 #  define SLAP_SOCK_IS_SUSPEND(t,s) \
426           ( slap_daemon[t].sd_suspend[SLAP_EPOLL_SOCK_IX(t,s)] == 1 )
427 
428 # define SLAP_EPOLL_EVENT_CLR(i, mode)  (revents[(i)].events &= ~(mode))
429 
430 # define SLAP_EVENT_MAX(t)                        slap_daemon[t].sd_nfds
431 
432 /* If a Listener address is provided, store that as the epoll data.
433  * Otherwise, store the address of this socket's slot in the
434  * index array. If we can't do this add, the system is out of
435  * resources and we need to shutdown.
436  */
437 # define SLAP_SOCK_ADD(t, s, l)                   do { \
438           int rc; \
439           SLAP_EPOLL_SOCK_IX(t,(s)) = slap_daemon[t].sd_nfds; \
440           SLAP_EPOLL_SOCK_EP(t,(s)).data.ptr = (l) ? (l) : (void *)(&SLAP_EPOLL_SOCK_IX(t,s)); \
441           SLAP_EPOLL_SOCK_EV(t,(s)) = EPOLLIN; \
442           rc = epoll_ctl(slap_daemon[t].sd_epfd, EPOLL_CTL_ADD, \
443                     (s), &SLAP_EPOLL_SOCK_EP(t,(s))); \
444           if ( rc == 0 ) { \
445                     slap_daemon[t].sd_nfds++; \
446           } else { \
447                     int saved_errno = errno; \
448                     Debug( LDAP_DEBUG_ANY, \
449                               "daemon: epoll_ctl(ADD,fd=%d) failed, errno=%d, shutting down\n", \
450                               s, saved_errno ); \
451                     slapd_shutdown = 2; \
452           } \
453 } while (0)
454 
455 # define SLAP_EPOLL_EV_LISTENER(t,ptr) \
456           (((int *)(ptr) >= slap_daemon[t].sd_index && \
457           (int *)(ptr) <= &slap_daemon[t].sd_index[dtblsize]) ? 0 : 1 )
458 
459 # define SLAP_EPOLL_EV_PTRFD(t,ptr)               (SLAP_EPOLL_EV_LISTENER(t,ptr) ? \
460           ((Listener *)ptr)->sl_sd : \
461           (ber_socket_t) ((int *)(ptr) - slap_daemon[t].sd_index))
462 
463 # define SLAP_SOCK_DEL(t,s)             do { \
464           int fd, rc, index = SLAP_EPOLL_SOCK_IX(t,(s)); \
465           if ( index < 0 ) break; \
466           rc = epoll_ctl(slap_daemon[t].sd_epfd, EPOLL_CTL_DEL, \
467                     (s), &SLAP_EPOLL_SOCK_EP(t,(s))); \
468           slap_daemon[t].sd_epolls[index] = \
469                     slap_daemon[t].sd_epolls[slap_daemon[t].sd_nfds-1]; \
470           fd = SLAP_EPOLL_EV_PTRFD(t,slap_daemon[t].sd_epolls[index].data.ptr); \
471           slap_daemon[t].sd_index[fd] = index; \
472           slap_daemon[t].sd_index[(s)] = -1; \
473           slap_daemon[t].sd_nfds--; \
474 } while (0)
475 
476 # define SLAP_EVENT_CLR_READ(i)                   SLAP_EPOLL_EVENT_CLR((i), EPOLLIN)
477 # define SLAP_EVENT_CLR_WRITE(i)        SLAP_EPOLL_EVENT_CLR((i), EPOLLOUT)
478 
479 # define SLAP_EPOLL_EVENT_CHK(i, mode)  (revents[(i)].events & mode)
480 
481 # define SLAP_EVENT_IS_READ(i)                    SLAP_EPOLL_EVENT_CHK((i), EPOLLIN)
482 # define SLAP_EVENT_IS_WRITE(i)                   SLAP_EPOLL_EVENT_CHK((i), EPOLLOUT)
483 # define SLAP_EVENT_IS_LISTENER(t,i)    SLAP_EPOLL_EV_LISTENER(t,revents[(i)].data.ptr)
484 # define SLAP_EVENT_LISTENER(t,i)                 ((Listener *)(revents[(i)].data.ptr))
485 
486 # define SLAP_EVENT_FD(t,i)             SLAP_EPOLL_EV_PTRFD(t,revents[(i)].data.ptr)
487 
488 # define SLAP_SOCK_INIT(t)              do { \
489           int j; \
490           slap_daemon[t].sd_epolls = ch_calloc(1, \
491                     ( sizeof(struct epoll_event) * 2 \
492                               + sizeof(int) ) * dtblsize * 2); \
493           slap_daemon[t].sd_index = (int *)&slap_daemon[t].sd_epolls[ 2 * dtblsize ]; \
494           slap_daemon[t].sd_epfd = epoll_create( dtblsize / slapd_daemon_threads ); \
495           for ( j = 0; j < dtblsize; j++ ) slap_daemon[t].sd_index[j] = -1; \
496 } while (0)
497 
498 # define SLAP_SOCK_INIT2()
499 
500 # define SLAP_SOCK_DESTROY(t)           do { \
501           if ( slap_daemon[t].sd_epolls != NULL ) { \
502                     ch_free( slap_daemon[t].sd_epolls ); \
503                     slap_daemon[t].sd_epolls = NULL; \
504                     slap_daemon[t].sd_index = NULL; \
505                     close( slap_daemon[t].sd_epfd ); \
506           } \
507 } while ( 0 )
508 
509 # define SLAP_EVENT_DECL                struct epoll_event *revents
510 
511 # define SLAP_EVENT_INIT(t)             do { \
512           revents = slap_daemon[t].sd_epolls + dtblsize; \
513 } while (0)
514 
515 # define SLAP_EVENT_WAIT(t, tvp, nsp)   do { \
516           *(nsp) = epoll_wait( slap_daemon[t].sd_epfd, revents, \
517                     dtblsize, (tvp) ? ((tvp)->tv_sec * 1000 + (tvp)->tv_usec / 1000) : -1 ); \
518 } while (0)
519 
520 #elif defined(SLAP_X_DEVPOLL) && defined(HAVE_DEVPOLL)
521 
522 /*************************************************************
523  * Use Solaris' (>= 2.7) /dev/poll infrastructure - poll(7d) *
524  *************************************************************/
525 # define SLAP_EVENT_FNAME               "/dev/poll"
526 # define SLAP_EVENTS_ARE_INDEXED        0
527 /*
528  * - sd_index       is used much like with epoll()
529  * - sd_l is maintained as an array containing the address
530  *                  of the listener; the index is the fd itself
531  * - sd_pollfd      is used to keep track of what data has been
532  *                  registered in /dev/poll
533  */
534 # define SLAP_DEVPOLL_SOCK_IX(t,s)      (slap_daemon[t].sd_index[(s)])
535 # define SLAP_DEVPOLL_SOCK_LX(t,s)      (slap_daemon[t].sd_l[(s)])
536 # define SLAP_DEVPOLL_SOCK_EP(t,s)      (slap_daemon[t].sd_pollfd[SLAP_DEVPOLL_SOCK_IX(t,(s))])
537 # define SLAP_DEVPOLL_SOCK_FD(t,s)      (SLAP_DEVPOLL_SOCK_EP(t,(s)).fd)
538 # define SLAP_DEVPOLL_SOCK_EV(t,s)      (SLAP_DEVPOLL_SOCK_EP(t,(s)).events)
539 # define SLAP_SOCK_IS_ACTIVE(t,s)                 (SLAP_DEVPOLL_SOCK_IX(t,(s)) != -1)
540 # define SLAP_SOCK_NOT_ACTIVE(t,s)      (SLAP_DEVPOLL_SOCK_IX(t,(s)) == -1)
541 # define SLAP_SOCK_IS_SET(t,s, mode)    (SLAP_DEVPOLL_SOCK_EV(t,(s)) & (mode))
542 
543 # define SLAP_SOCK_IS_READ(t,s)                   SLAP_SOCK_IS_SET(t,(s), POLLIN)
544 # define SLAP_SOCK_IS_WRITE(t,s)                  SLAP_SOCK_IS_SET(t,(s), POLLOUT)
545 
546 /* as far as I understand, any time we need to communicate with the kernel
547  * about the number and/or properties of a file descriptor we need it to
548  * wait for, we have to rewrite the whole set */
549 # define SLAP_DEVPOLL_WRITE_POLLFD(t,s, pfd, n, what, shdn) do { \
550           int rc; \
551           size_t size = (n) * sizeof( struct pollfd ); \
552           /* FIXME: use pwrite? */ \
553           rc = write( slap_daemon[t].sd_dpfd, (pfd), size ); \
554           if ( rc != size ) { \
555                     int saved_errno = errno; \
556                     Debug( LDAP_DEBUG_ANY, "daemon: " SLAP_EVENT_FNAME ": " \
557                               "%s fd=%d failed errno=%d\n", \
558                               (what), (s), saved_errno ); \
559                     if ( (shdn) ) { \
560                               slapd_shutdown = 2; \
561                     } \
562           } \
563 } while (0)
564 
565 # define SLAP_DEVPOLL_SOCK_SET(t,s, mode)         do { \
566           Debug( LDAP_DEBUG_CONNS, "SLAP_SOCK_SET_%s(%d)=%d\n", \
567                     (mode) == POLLIN ? "READ" : "WRITE", (s), \
568                     ( (SLAP_DEVPOLL_SOCK_EV(t,(s)) & (mode)) != (mode) ) ); \
569           if ( (SLAP_DEVPOLL_SOCK_EV(t,(s)) & (mode)) != (mode) ) { \
570                     struct pollfd pfd; \
571                     SLAP_DEVPOLL_SOCK_EV(t,(s)) |= (mode); \
572                     pfd.fd = SLAP_DEVPOLL_SOCK_FD(t,(s)); \
573                     pfd.events = /* (mode) */ SLAP_DEVPOLL_SOCK_EV(t,(s)); \
574                     SLAP_DEVPOLL_WRITE_POLLFD(t,(s), &pfd, 1, "SET", 0); \
575           } \
576 } while (0)
577 
578 # define SLAP_DEVPOLL_SOCK_CLR(t,s, mode)                   do { \
579           Debug( LDAP_DEBUG_CONNS, "SLAP_SOCK_CLR_%s(%d)=%d\n", \
580                     (mode) == POLLIN ? "READ" : "WRITE", (s), \
581                     ( (SLAP_DEVPOLL_SOCK_EV(t,(s)) & (mode)) == (mode) ) ); \
582           if ((SLAP_DEVPOLL_SOCK_EV(t,(s)) & (mode)) == (mode) ) { \
583                     struct pollfd pfd[2]; \
584                     SLAP_DEVPOLL_SOCK_EV(t,(s)) &= ~(mode); \
585                     pfd[0].fd = SLAP_DEVPOLL_SOCK_FD(t,(s)); \
586                     pfd[0].events = POLLREMOVE; \
587                     pfd[1] = SLAP_DEVPOLL_SOCK_EP(t,(s)); \
588                     SLAP_DEVPOLL_WRITE_POLLFD(t,(s), &pfd[0], 2, "CLR", 0); \
589           } \
590 } while (0)
591 
592 # define SLAP_SOCK_SET_READ(t,s)                  SLAP_DEVPOLL_SOCK_SET(t,s, POLLIN)
593 # define SLAP_SOCK_SET_WRITE(t,s)                 SLAP_DEVPOLL_SOCK_SET(t,s, POLLOUT)
594 
595 # define SLAP_SOCK_CLR_READ(t,s)                  SLAP_DEVPOLL_SOCK_CLR(t,(s), POLLIN)
596 # define SLAP_SOCK_CLR_WRITE(t,s)                 SLAP_DEVPOLL_SOCK_CLR(t,(s), POLLOUT)
597 
598 #  define SLAP_SOCK_SET_SUSPEND(t,s) \
599           ( slap_daemon[t].sd_suspend[SLAP_DEVPOLL_SOCK_IX(t,(s))] = 1 )
600 #  define SLAP_SOCK_CLR_SUSPEND(t,s) \
601           ( slap_daemon[t].sd_suspend[SLAP_DEVPOLL_SOCK_IX(t,(s))] = 0 )
602 #  define SLAP_SOCK_IS_SUSPEND(t,s) \
603           ( slap_daemon[t].sd_suspend[SLAP_DEVPOLL_SOCK_IX(t,(s))] == 1 )
604 
605 # define SLAP_DEVPOLL_EVENT_CLR(i, mode)          (revents[(i)].events &= ~(mode))
606 
607 # define SLAP_EVENT_MAX(t)                        slap_daemon[t].sd_nfds
608 
609 /* If a Listener address is provided, store that in the sd_l array.
610  * If we can't do this add, the system is out of resources and we
611  * need to shutdown.
612  */
613 # define SLAP_SOCK_ADD(t, s, l)                   do { \
614           Debug( LDAP_DEBUG_CONNS, "SLAP_SOCK_ADD(%d, %p)\n", (s), (l) ); \
615           SLAP_DEVPOLL_SOCK_IX(t,(s)) = slap_daemon[t].sd_nfds; \
616           SLAP_DEVPOLL_SOCK_LX(t,(s)) = (l); \
617           SLAP_DEVPOLL_SOCK_FD(t,(s)) = (s); \
618           SLAP_DEVPOLL_SOCK_EV(t,(s)) = POLLIN; \
619           SLAP_DEVPOLL_WRITE_POLLFD(t,(s), &SLAP_DEVPOLL_SOCK_EP(t, (s)), 1, "ADD", 1); \
620           slap_daemon[t].sd_nfds++; \
621 } while (0)
622 
623 # define SLAP_DEVPOLL_EV_LISTENER(ptr)  ((ptr) != NULL)
624 
625 # define SLAP_SOCK_DEL(t,s)             do { \
626           int fd, index = SLAP_DEVPOLL_SOCK_IX(t,(s)); \
627           Debug( LDAP_DEBUG_CONNS, "SLAP_SOCK_DEL(%d)\n", (s) ); \
628           if ( index < 0 ) break; \
629           if ( index < slap_daemon[t].sd_nfds - 1 ) { \
630                     struct pollfd pfd = slap_daemon[t].sd_pollfd[index]; \
631                     fd = slap_daemon[t].sd_pollfd[slap_daemon[t].sd_nfds - 1].fd; \
632                     slap_daemon[t].sd_pollfd[index] = slap_daemon[t].sd_pollfd[slap_daemon[t].sd_nfds - 1]; \
633                     slap_daemon[t].sd_pollfd[slap_daemon[t].sd_nfds - 1] = pfd; \
634                     slap_daemon[t].sd_index[fd] = index; \
635           } \
636           slap_daemon[t].sd_index[(s)] = -1; \
637           slap_daemon[t].sd_pollfd[slap_daemon[t].sd_nfds - 1].events = POLLREMOVE; \
638           SLAP_DEVPOLL_WRITE_POLLFD(t,(s), &slap_daemon[t].sd_pollfd[slap_daemon[t].sd_nfds - 1], 1, "DEL", 0); \
639           slap_daemon[t].sd_pollfd[slap_daemon[t].sd_nfds - 1].events = 0; \
640           slap_daemon[t].sd_nfds--; \
641 } while (0)
642 
643 # define SLAP_EVENT_CLR_READ(i)                   SLAP_DEVPOLL_EVENT_CLR((i), POLLIN)
644 # define SLAP_EVENT_CLR_WRITE(i)        SLAP_DEVPOLL_EVENT_CLR((i), POLLOUT)
645 
646 # define SLAP_DEVPOLL_EVENT_CHK(i, mode)          (revents[(i)].events & (mode))
647 
648 # define SLAP_EVENT_FD(t,i)             (revents[(i)].fd)
649 
650 # define SLAP_EVENT_IS_READ(i)                    SLAP_DEVPOLL_EVENT_CHK((i), POLLIN)
651 # define SLAP_EVENT_IS_WRITE(i)                   SLAP_DEVPOLL_EVENT_CHK((i), POLLOUT)
652 # define SLAP_EVENT_IS_LISTENER(t,i)    SLAP_DEVPOLL_EV_LISTENER(SLAP_DEVPOLL_SOCK_LX(t, SLAP_EVENT_FD(t,(i))))
653 # define SLAP_EVENT_LISTENER(t,i)                 SLAP_DEVPOLL_SOCK_LX(t, SLAP_EVENT_FD(t,(i)))
654 
655 # define SLAP_SOCK_DESTROY(t)           do { \
656           if ( slap_daemon[t].sd_pollfd != NULL ) { \
657                     ch_free( slap_daemon[t].sd_pollfd ); \
658                     slap_daemon[t].sd_pollfd = NULL; \
659                     slap_daemon[t].sd_index = NULL; \
660                     slap_daemon[t].sd_l = NULL; \
661                     close( slap_daemon[t].sd_dpfd ); \
662           } \
663 } while ( 0 )
664 
665 # define SLAP_SOCK_INIT(t)              do { \
666           slap_daemon[t].sd_pollfd = ch_calloc( 1, \
667                     ( sizeof(struct pollfd) * 2 \
668                               + sizeof( int ) \
669                               + sizeof( Listener * ) ) * dtblsize ); \
670           slap_daemon[t].sd_index = (int *)&slap_daemon[t].sd_pollfd[ 2 * dtblsize ]; \
671           slap_daemon[t].sd_l = (Listener **)&slap_daemon[t].sd_index[ dtblsize ]; \
672           slap_daemon[t].sd_dpfd = open( SLAP_EVENT_FNAME, O_RDWR ); \
673           if ( slap_daemon[t].sd_dpfd == -1 ) { \
674                     int saved_errno = errno; \
675                     Debug( LDAP_DEBUG_ANY, "daemon: " SLAP_EVENT_FNAME ": " \
676                               "open(\"" SLAP_EVENT_FNAME "\") failed errno=%d\n", \
677                               saved_errno ); \
678                     SLAP_SOCK_DESTROY(t); \
679                     return -1; \
680           } \
681           for ( i = 0; i < dtblsize; i++ ) { \
682                     slap_daemon[t].sd_pollfd[i].fd = -1; \
683                     slap_daemon[t].sd_index[i] = -1; \
684           } \
685 } while (0)
686 
687 # define SLAP_SOCK_INIT2()
688 
689 # define SLAP_EVENT_DECL                struct pollfd *revents
690 
691 # define SLAP_EVENT_INIT(t)             do { \
692           revents = &slap_daemon[t].sd_pollfd[ dtblsize ]; \
693 } while (0)
694 
695 # define SLAP_EVENT_WAIT(t, tvp, nsp)   do { \
696           struct dvpoll                 sd_dvpoll; \
697           sd_dvpoll.dp_timeout = (tvp) ? ((tvp)->tv_sec * 1000 + (tvp)->tv_usec / 1000) : -1; \
698           sd_dvpoll.dp_nfds = dtblsize; \
699           sd_dvpoll.dp_fds = revents; \
700           *(nsp) = ioctl( slap_daemon[t].sd_dpfd, DP_POLL, &sd_dvpoll ); \
701 } while (0)
702 
703 #else /* ! kqueue && ! epoll && ! /dev/poll */
704 # ifdef HAVE_WINSOCK
705 # define SLAP_EVENT_FNAME               "WSselect"
706 /* Winsock provides a "select" function but its fd_sets are
707  * actually arrays of sockets. Since these sockets are handles
708  * and not a contiguous range of small integers, we manage our
709  * own "fd" table of socket handles and use their indices as
710  * descriptors.
711  *
712  * All of our listener/connection structures use fds; the actual
713  * I/O functions use sockets. The SLAP_FD2SOCK macro in proto-slap.h
714  * handles the mapping.
715  *
716  * Despite the mapping overhead, this is about 45% more efficient
717  * than just using Winsock's select and FD_ISSET directly.
718  *
719  * Unfortunately Winsock's select implementation doesn't scale well
720  * as the number of connections increases. This probably needs to be
721  * rewritten to use the Winsock overlapped/asynchronous I/O functions.
722  */
723 # define SLAP_EVENTS_ARE_INDEXED        1
724 # define SLAP_EVENT_DECL                fd_set readfds, writefds; char *rflags
725 # define SLAP_EVENT_INIT(t)   do { \
726           int i; \
727           FD_ZERO( &readfds ); \
728           FD_ZERO( &writefds ); \
729           rflags = slap_daemon[t].sd_rflags; \
730           memset( rflags, 0, slap_daemon[t].sd_nfds ); \
731           for ( i=0; i<slap_daemon[t].sd_nfds; i++ ) { \
732                     if ( slap_daemon[t].sd_flags[i] & SD_READ ) \
733                               FD_SET( slapd_ws_sockets[i], &readfds );\
734                     if ( slap_daemon[t].sd_flags[i] & SD_WRITE ) \
735                               FD_SET( slapd_ws_sockets[i], &writefds ); \
736           } } while ( 0 )
737 
738 # define SLAP_EVENT_MAX(t)              slap_daemon[t].sd_nfds
739 
740 # define SLAP_EVENT_WAIT(t, tvp, nsp)   do { \
741           int i; \
742           *(nsp) = select( SLAP_EVENT_MAX(t), &readfds, \
743                     nwriters > 0 ? &writefds : NULL, NULL, (tvp) ); \
744           for ( i=0; i<readfds.fd_count; i++) { \
745                     int fd = slapd_sock2fd(readfds.fd_array[i]); \
746                     if ( fd >= 0 ) { \
747                               slap_daemon[t].sd_rflags[fd] = SD_READ; \
748                               if ( fd >= *(nsp)) *(nsp) = fd+1; \
749                     } \
750           } \
751           for ( i=0; i<writefds.fd_count; i++) { \
752                     int fd = slapd_sock2fd(writefds.fd_array[i]); \
753                     if ( fd >= 0 ) { \
754                               slap_daemon[t].sd_rflags[fd] = SD_WRITE; \
755                               if ( fd >= *(nsp)) *(nsp) = fd+1; \
756                     } \
757           } \
758 } while (0)
759 
760 # define SLAP_EVENT_IS_READ(fd)                   (rflags[fd] & SD_READ)
761 # define SLAP_EVENT_IS_WRITE(fd)        (rflags[fd] & SD_WRITE)
762 
763 # define SLAP_EVENT_CLR_READ(fd)        rflags[fd] &= ~SD_READ
764 # define SLAP_EVENT_CLR_WRITE(fd)       rflags[fd] &= ~SD_WRITE
765 
766 # define SLAP_SOCK_INIT(t)              do { \
767           if (!t) { \
768           ldap_pvt_thread_mutex_init( &slapd_ws_mutex ); \
769           slapd_ws_sockets = ch_malloc( dtblsize * ( sizeof(SOCKET) + 2)); \
770           memset( slapd_ws_sockets, -1, dtblsize * sizeof(SOCKET) ); \
771           } \
772           slap_daemon[t].sd_flags = (char *)(slapd_ws_sockets + dtblsize); \
773           slap_daemon[t].sd_rflags = slap_daemon[t].sd_flags + dtblsize; \
774           memset( slap_daemon[t].sd_flags, 0, dtblsize ); \
775           slapd_ws_sockets[t*2] = wake_sds[t][0]; \
776           slapd_ws_sockets[t*2+1] = wake_sds[t][1]; \
777           wake_sds[t][0] = t*2; \
778           wake_sds[t][1] = t*2+1; \
779           slap_daemon[t].sd_nfds = t*2 + 2; \
780           } while ( 0 )
781 
782 # define SLAP_SOCK_INIT2()
783 
784 # define SLAP_SOCK_DESTROY(t) do { \
785           ch_free( slapd_ws_sockets ); slapd_ws_sockets = NULL; \
786           slap_daemon[t].sd_flags = NULL; \
787           slap_daemon[t].sd_rflags = NULL; \
788           ldap_pvt_thread_mutex_destroy( &slapd_ws_mutex ); \
789           } while ( 0 )
790 
791 # define SLAP_SOCK_IS_ACTIVE(t,fd) ( slap_daemon[t].sd_flags[fd] & SD_ACTIVE )
792 # define SLAP_SOCK_IS_READ(t,fd) ( slap_daemon[t].sd_flags[fd] & SD_READ )
793 # define SLAP_SOCK_IS_WRITE(t,fd) ( slap_daemon[t].sd_flags[fd] & SD_WRITE )
794 # define SLAP_SOCK_NOT_ACTIVE(t,fd)     (!slap_daemon[t].sd_flags[fd])
795 
796 # define SLAP_SOCK_SET_READ(t,fd)                 ( slap_daemon[t].sd_flags[fd] |= SD_READ )
797 # define SLAP_SOCK_SET_WRITE(t,fd)                ( slap_daemon[t].sd_flags[fd] |= SD_WRITE )
798 
799 # define SLAP_SELECT_ADDTEST(t,s)       do { \
800           if ((s) >= slap_daemon[t].sd_nfds) slap_daemon[t].sd_nfds = (s)+1; \
801 } while (0)
802 
803 # define SLAP_SOCK_CLR_READ(t,fd)                 ( slap_daemon[t].sd_flags[fd] &= ~SD_READ )
804 # define SLAP_SOCK_CLR_WRITE(t,fd)                ( slap_daemon[t].sd_flags[fd] &= ~SD_WRITE )
805 
806 # define SLAP_SOCK_ADD(t,s, l)          do { \
807           SLAP_SELECT_ADDTEST(t,(s)); \
808           slap_daemon[t].sd_flags[s] = SD_ACTIVE|SD_READ; \
809 } while ( 0 )
810 
811 # define SLAP_SOCK_DEL(t,s) do { \
812           slap_daemon[t].sd_flags[s] = 0; \
813           slapd_sockdel( s ); \
814 } while ( 0 )
815 
816 # else /* !HAVE_WINSOCK */
817 
818 /**************************************
819  * Use select system call - select(2) *
820  **************************************/
821 # define SLAP_EVENT_FNAME               "select"
822 /* select */
823 # define SLAP_EVENTS_ARE_INDEXED        1
824 # define SLAP_EVENT_DECL                fd_set readfds, writefds
825 
826 # define SLAP_EVENT_INIT(t)             do { \
827           AC_MEMCPY( &readfds, &slap_daemon[t].sd_readers, sizeof(fd_set) );    \
828           if ( nwriters )     { \
829                     AC_MEMCPY( &writefds, &slap_daemon[t].sd_writers, sizeof(fd_set) ); \
830           } else { \
831                     FD_ZERO( &writefds ); \
832           } \
833 } while (0)
834 
835 # ifdef FD_SETSIZE
836 #  define SLAP_SELECT_CHK_SETSIZE       do { \
837           if (dtblsize > FD_SETSIZE) dtblsize = FD_SETSIZE; \
838 } while (0)
839 # else /* ! FD_SETSIZE */
840 #  define SLAP_SELECT_CHK_SETSIZE       do { ; } while (0)
841 # endif /* ! FD_SETSIZE */
842 
843 # define SLAP_SOCK_INIT(t)                        do { \
844           SLAP_SELECT_CHK_SETSIZE; \
845           FD_ZERO(&slap_daemon[t].sd_actives); \
846           FD_ZERO(&slap_daemon[t].sd_readers); \
847           FD_ZERO(&slap_daemon[t].sd_writers); \
848 } while (0)
849 
850 # define SLAP_SOCK_INIT2()
851 
852 # define SLAP_SOCK_DESTROY(t)
853 
854 # define SLAP_SOCK_IS_ACTIVE(t,fd)      FD_ISSET((fd), &slap_daemon[t].sd_actives)
855 # define SLAP_SOCK_IS_READ(t,fd)                  FD_ISSET((fd), &slap_daemon[t].sd_readers)
856 # define SLAP_SOCK_IS_WRITE(t,fd)                 FD_ISSET((fd), &slap_daemon[t].sd_writers)
857 
858 # define SLAP_SOCK_NOT_ACTIVE(t,fd)     (!SLAP_SOCK_IS_ACTIVE(t,fd) && \
859            !SLAP_SOCK_IS_READ(t,fd) && !SLAP_SOCK_IS_WRITE(t,fd))
860 
861 # define SLAP_SOCK_SET_READ(t,fd)       FD_SET((fd), &slap_daemon[t].sd_readers)
862 # define SLAP_SOCK_SET_WRITE(t,fd)      FD_SET((fd), &slap_daemon[t].sd_writers)
863 
864 # define SLAP_EVENT_MAX(t)              slap_daemon[t].sd_nfds
865 # define SLAP_SELECT_ADDTEST(t,s)       do { \
866           if ((s) >= slap_daemon[t].sd_nfds) slap_daemon[t].sd_nfds = (s)+1; \
867 } while (0)
868 
869 # define SLAP_SOCK_CLR_READ(t,fd)                 FD_CLR((fd), &slap_daemon[t].sd_readers)
870 # define SLAP_SOCK_CLR_WRITE(t,fd)      FD_CLR((fd), &slap_daemon[t].sd_writers)
871 
872 # define SLAP_SOCK_ADD(t,s, l)                    do { \
873           SLAP_SELECT_ADDTEST(t,(s)); \
874           FD_SET((s), &slap_daemon[t].sd_actives); \
875           FD_SET((s), &slap_daemon[t].sd_readers); \
876 } while (0)
877 
878 # define SLAP_SOCK_DEL(t,s)             do { \
879           FD_CLR((s), &slap_daemon[t].sd_actives); \
880           FD_CLR((s), &slap_daemon[t].sd_readers); \
881           FD_CLR((s), &slap_daemon[t].sd_writers); \
882 } while (0)
883 
884 # define SLAP_EVENT_IS_READ(fd)                   FD_ISSET((fd), &readfds)
885 # define SLAP_EVENT_IS_WRITE(fd)        FD_ISSET((fd), &writefds)
886 
887 # define SLAP_EVENT_CLR_READ(fd)        FD_CLR((fd), &readfds)
888 # define SLAP_EVENT_CLR_WRITE(fd)       FD_CLR((fd), &writefds)
889 
890 # define SLAP_EVENT_WAIT(t, tvp, nsp)   do { \
891           *(nsp) = select( SLAP_EVENT_MAX(t), &readfds, \
892                     nwriters > 0 ? &writefds : NULL, NULL, (tvp) ); \
893 } while (0)
894 # endif /* !HAVE_WINSOCK */
895 #endif /* ! kqueue && ! epoll && ! /dev/poll */
896 
897 #ifdef HAVE_SLP
898 /*
899  * SLP related functions
900  */
901 #include <slp.h>
902 
903 #define LDAP_SRVTYPE_PREFIX "service:ldap://"
904 #define LDAPS_SRVTYPE_PREFIX "service:ldaps://"
905 static char** slapd_srvurls = NULL;
906 static SLPHandle slapd_hslp = 0;
907 int slapd_register_slp = 0;
908 const char *slapd_slp_attrs = NULL;
909 
910 static SLPError slapd_slp_cookie;
911 
912 static void
slapd_slp_init(const char * urls)913 slapd_slp_init( const char* urls )
914 {
915           int i;
916           SLPError err;
917 
918           slapd_srvurls = ldap_str2charray( urls, " " );
919 
920           if ( slapd_srvurls == NULL ) return;
921 
922           /* find and expand INADDR_ANY URLs */
923           for ( i = 0; slapd_srvurls[i] != NULL; i++ ) {
924                     if ( strcmp( slapd_srvurls[i], "ldap:///" ) == 0 ) {
925                               slapd_srvurls[i] = (char *) ch_realloc( slapd_srvurls[i],
926                                         global_host_bv.bv_len +
927                                         sizeof( LDAP_SRVTYPE_PREFIX ) );
928                               strcpy( lutil_strcopy(slapd_srvurls[i],
929                                         LDAP_SRVTYPE_PREFIX ), global_host_bv.bv_val );
930                     } else if ( strcmp( slapd_srvurls[i], "ldaps:///" ) == 0 ) {
931                               slapd_srvurls[i] = (char *) ch_realloc( slapd_srvurls[i],
932                                         global_host_bv.bv_len +
933                                         sizeof( LDAPS_SRVTYPE_PREFIX ) );
934                               strcpy( lutil_strcopy(slapd_srvurls[i],
935                                         LDAPS_SRVTYPE_PREFIX ), global_host_bv.bv_val );
936                     }
937           }
938 
939           /* open the SLP handle */
940           err = SLPOpen( "en", 0, &slapd_hslp );
941 
942           if ( err != SLP_OK ) {
943                     Debug( LDAP_DEBUG_CONNS, "daemon: SLPOpen() failed with %ld\n",
944                               (long)err );
945           }
946 }
947 
948 static void
slapd_slp_deinit(void)949 slapd_slp_deinit( void )
950 {
951           if ( slapd_srvurls == NULL ) return;
952 
953           ldap_charray_free( slapd_srvurls );
954           slapd_srvurls = NULL;
955 
956           /* close the SLP handle */
957           SLPClose( slapd_hslp );
958 }
959 
960 static void
slapd_slp_regreport(SLPHandle hslp,SLPError errcode,void * cookie)961 slapd_slp_regreport(
962           SLPHandle hslp,
963           SLPError  errcode,
964           void                *cookie )
965 {
966           /* return the error code in the cookie */
967           *(SLPError*)cookie = errcode;
968 }
969 
970 static void
slapd_slp_reg()971 slapd_slp_reg()
972 {
973           int i;
974           SLPError err;
975 
976           if ( slapd_srvurls == NULL ) return;
977 
978           for ( i = 0; slapd_srvurls[i] != NULL; i++ ) {
979                     if ( strncmp( slapd_srvurls[i], LDAP_SRVTYPE_PREFIX,
980                                         sizeof( LDAP_SRVTYPE_PREFIX ) - 1 ) == 0 ||
981                               strncmp( slapd_srvurls[i], LDAPS_SRVTYPE_PREFIX,
982                                         sizeof( LDAPS_SRVTYPE_PREFIX ) - 1 ) == 0 )
983                     {
984                               err = SLPReg( slapd_hslp,
985                                         slapd_srvurls[i],
986                                         SLP_LIFETIME_MAXIMUM,
987                                         "ldap",
988                                         (slapd_slp_attrs) ? slapd_slp_attrs : "",
989                                         SLP_TRUE,
990                                         slapd_slp_regreport,
991                                         &slapd_slp_cookie );
992 
993                               if ( err != SLP_OK || slapd_slp_cookie != SLP_OK ) {
994                                         Debug( LDAP_DEBUG_CONNS,
995                                                   "daemon: SLPReg(%s) failed with %ld, cookie = %ld\n",
996                                                   slapd_srvurls[i], (long)err, (long)slapd_slp_cookie );
997                               }
998                     }
999           }
1000 }
1001 
1002 static void
slapd_slp_dereg(void)1003 slapd_slp_dereg( void )
1004 {
1005           int i;
1006           SLPError err;
1007 
1008           if ( slapd_srvurls == NULL ) return;
1009 
1010           for ( i = 0; slapd_srvurls[i] != NULL; i++ ) {
1011                     err = SLPDereg( slapd_hslp,
1012                               slapd_srvurls[i],
1013                               slapd_slp_regreport,
1014                               &slapd_slp_cookie );
1015 
1016                     if ( err != SLP_OK || slapd_slp_cookie != SLP_OK ) {
1017                               Debug( LDAP_DEBUG_CONNS,
1018                                         "daemon: SLPDereg(%s) failed with %ld, cookie = %ld\n",
1019                                         slapd_srvurls[i], (long)err, (long)slapd_slp_cookie );
1020                     }
1021           }
1022 }
1023 #endif /* HAVE_SLP */
1024 
1025 #ifdef HAVE_WINSOCK
1026 /* Manage the descriptor to socket table */
1027 ber_socket_t
slapd_socknew(ber_socket_t s)1028 slapd_socknew( ber_socket_t s )
1029 {
1030           ber_socket_t i;
1031           ldap_pvt_thread_mutex_lock( &slapd_ws_mutex );
1032           for ( i = 0; i < dtblsize && slapd_ws_sockets[i] != INVALID_SOCKET; i++ );
1033           if ( i == dtblsize ) {
1034                     WSASetLastError( WSAEMFILE );
1035           } else {
1036                     slapd_ws_sockets[i] = s;
1037           }
1038           ldap_pvt_thread_mutex_unlock( &slapd_ws_mutex );
1039           return i;
1040 }
1041 
1042 void
slapd_sockdel(ber_socket_t s)1043 slapd_sockdel( ber_socket_t s )
1044 {
1045           ldap_pvt_thread_mutex_lock( &slapd_ws_mutex );
1046           slapd_ws_sockets[s] = INVALID_SOCKET;
1047           ldap_pvt_thread_mutex_unlock( &slapd_ws_mutex );
1048 }
1049 
1050 ber_socket_t
slapd_sock2fd(ber_socket_t s)1051 slapd_sock2fd( ber_socket_t s )
1052 {
1053           ber_socket_t i;
1054           for ( i=0; i<dtblsize && slapd_ws_sockets[i] != s; i++);
1055           if ( i == dtblsize )
1056                     i = -1;
1057           return i;
1058 }
1059 #endif
1060 
1061 #ifdef DEBUG_CLOSE
1062 /* Was used to find a bug causing slapd's descriptors to be closed
1063  * out from under it. Tracked it down to a long-standing (from 2009)
1064  * bug in Heimdal https://github.com/heimdal/heimdal/issues/431 .
1065  * Leaving this here for future use, if necessary.
1066  */
1067 #include <dlfcn.h>
1068 #ifndef RTLD_NEXT
1069 #define RTLD_NEXT   (void *)-1L
1070 #endif
1071 static char *newconns;
1072 typedef int (closefunc)(int fd);
1073 static closefunc *close_ptr;
close(int s)1074 int close( int s )
1075 {
1076           if (newconns) {
1077                     Debug( LDAP_DEBUG_CONNS,
1078                               "daemon: close(%d)\n", s );
1079                     if (s >= 0 && s < dtblsize && newconns[s])
1080                               assert(newconns[s] == 2);
1081           }
1082           return close_ptr ? close_ptr(s) : -1;
1083 }
1084 
slapd_debug_close()1085 void slapd_debug_close()
1086 {
1087           if (dtblsize)
1088                     newconns = ch_calloc(1, dtblsize);
1089           close_ptr = dlsym(RTLD_NEXT, "close");
1090 }
1091 
slapd_set_close(int fd)1092 void slapd_set_close(int fd)
1093 {
1094           newconns[fd] = 3;
1095 }
1096 #define SETUP_CLOSE()         slapd_debug_close()
1097 #define SET_CLOSE(fd)         slapd_set_close(fd)
1098 #define CLR_CLOSE(fd)         if (newconns[fd]) newconns[fd]--
1099 #else
1100 #define SETUP_CLOSE(fd)
1101 #define SET_CLOSE(fd)
1102 #define CLR_CLOSE(fd)
1103 #endif
1104 
1105 /*
1106  * Add a descriptor to daemon control
1107  *
1108  * If isactive, the descriptor is a live server session and is subject
1109  * to idletimeout control. Otherwise, the descriptor is a passive
1110  * listener or an outbound client session, and not subject to
1111  * idletimeout. The underlying event handler may record the Listener
1112  * argument to differentiate Listener's from real sessions.
1113  */
1114 static void
slapd_add(ber_socket_t s,int isactive,Listener * sl,int id)1115 slapd_add( ber_socket_t s, int isactive, Listener *sl, int id )
1116 {
1117           if (id < 0)
1118                     id = DAEMON_ID(s);
1119           ldap_pvt_thread_mutex_lock( &slap_daemon[id].sd_mutex );
1120 
1121           assert( SLAP_SOCK_NOT_ACTIVE(id, s) );
1122 
1123           if ( isactive ) slap_daemon[id].sd_nactives++;
1124 
1125           SLAP_SOCK_ADD(id, s, sl);
1126 
1127           Debug( LDAP_DEBUG_CONNS, "daemon: added %ldr%s listener=%p\n",
1128                     (long) s, isactive ? " (active)" : "", (void *)sl );
1129 
1130           ldap_pvt_thread_mutex_unlock( &slap_daemon[id].sd_mutex );
1131 
1132           WAKE_LISTENER(id,1);
1133 }
1134 
1135 /*
1136  * Remove the descriptor from daemon control
1137  */
1138 void
slapd_remove(ber_socket_t s,Sockbuf * sb,int wasactive,int wake,int locked)1139 slapd_remove(
1140           ber_socket_t s,
1141           Sockbuf *sb,
1142           int wasactive,
1143           int wake,
1144           int locked )
1145 {
1146           int waswriter;
1147           int wasreader;
1148           int id = DAEMON_ID(s);
1149 
1150           if ( !locked )
1151                     ldap_pvt_thread_mutex_lock( &slap_daemon[id].sd_mutex );
1152 
1153           assert( SLAP_SOCK_IS_ACTIVE( id, s ));
1154 
1155           if ( wasactive ) slap_daemon[id].sd_nactives--;
1156 
1157           waswriter = SLAP_SOCK_IS_WRITE(id, s);
1158           wasreader = SLAP_SOCK_IS_READ(id, s);
1159 
1160           Debug( LDAP_DEBUG_CONNS, "daemon: removing %ld%s%s\n",
1161                     (long) s,
1162                     wasreader ? "r" : "",
1163                     waswriter ? "w" : "" );
1164 
1165           if ( waswriter ) slap_daemon[id].sd_nwriters--;
1166 
1167           SLAP_SOCK_DEL(id, s);
1168           CLR_CLOSE(s);
1169 
1170           if ( sb )
1171                     ber_sockbuf_free(sb);
1172 
1173           /* If we ran out of file descriptors, we dropped a listener from
1174            * the select() loop. Now that we're removing a session from our
1175            * control, we can try to resume a dropped listener to use.
1176            */
1177           ldap_pvt_thread_mutex_lock( &emfile_mutex );
1178           if ( emfile && listening ) {
1179                     int i;
1180                     for ( i = 0; slap_listeners[i] != NULL; i++ ) {
1181                               Listener *lr = slap_listeners[i];
1182 
1183                               if ( lr->sl_sd == AC_SOCKET_INVALID ) continue;
1184                               if ( lr->sl_sd == s ) continue;
1185                               if ( lr->sl_mute ) {
1186                                         lr->sl_mute = 0;
1187                                         emfile--;
1188                                         if ( DAEMON_ID(lr->sl_sd) != id )
1189                                                   WAKE_LISTENER(DAEMON_ID(lr->sl_sd), wake);
1190                                         break;
1191                               }
1192                     }
1193                     /* Walked the entire list without enabling anything; emfile
1194                      * counter is stale. Reset it.
1195                      */
1196                     if ( slap_listeners[i] == NULL ) emfile = 0;
1197           }
1198           ldap_pvt_thread_mutex_unlock( &emfile_mutex );
1199           ldap_pvt_thread_mutex_unlock( &slap_daemon[id].sd_mutex );
1200           WAKE_LISTENER(id, wake || slapd_gentle_shutdown == 2);
1201 }
1202 
1203 void
slapd_clr_write(ber_socket_t s,int wake)1204 slapd_clr_write( ber_socket_t s, int wake )
1205 {
1206           int id = DAEMON_ID(s);
1207           ldap_pvt_thread_mutex_lock( &slap_daemon[id].sd_mutex );
1208 
1209           if ( SLAP_SOCK_IS_WRITE( id, s )) {
1210                     assert( SLAP_SOCK_IS_ACTIVE( id, s ));
1211 
1212                     SLAP_SOCK_CLR_WRITE( id, s );
1213                     slap_daemon[id].sd_nwriters--;
1214           }
1215 
1216           ldap_pvt_thread_mutex_unlock( &slap_daemon[id].sd_mutex );
1217           WAKE_LISTENER(id,wake);
1218 }
1219 
1220 void
slapd_set_write(ber_socket_t s,int wake)1221 slapd_set_write( ber_socket_t s, int wake )
1222 {
1223           int id = DAEMON_ID(s);
1224           ldap_pvt_thread_mutex_lock( &slap_daemon[id].sd_mutex );
1225 
1226           assert( SLAP_SOCK_IS_ACTIVE( id, s ));
1227 
1228           if ( !SLAP_SOCK_IS_WRITE( id, s )) {
1229                     SLAP_SOCK_SET_WRITE( id, s );
1230                     slap_daemon[id].sd_nwriters++;
1231           }
1232 
1233           ldap_pvt_thread_mutex_unlock( &slap_daemon[id].sd_mutex );
1234           WAKE_LISTENER(id,wake);
1235 }
1236 
1237 int
slapd_clr_read(ber_socket_t s,int wake)1238 slapd_clr_read( ber_socket_t s, int wake )
1239 {
1240           int rc = 1;
1241           int id = DAEMON_ID(s);
1242           ldap_pvt_thread_mutex_lock( &slap_daemon[id].sd_mutex );
1243 
1244           if ( SLAP_SOCK_IS_ACTIVE( id, s )) {
1245                     SLAP_SOCK_CLR_READ( id, s );
1246                     rc = 0;
1247           }
1248           ldap_pvt_thread_mutex_unlock( &slap_daemon[id].sd_mutex );
1249           if ( !rc )
1250                     WAKE_LISTENER(id,wake);
1251           return rc;
1252 }
1253 
1254 void
slapd_set_read(ber_socket_t s,int wake)1255 slapd_set_read( ber_socket_t s, int wake )
1256 {
1257           int do_wake = 1;
1258           int id = DAEMON_ID(s);
1259           ldap_pvt_thread_mutex_lock( &slap_daemon[id].sd_mutex );
1260 
1261           if( SLAP_SOCK_IS_ACTIVE( id, s ) && !SLAP_SOCK_IS_READ( id, s )) {
1262                     SLAP_SOCK_SET_READ( id, s );
1263           } else {
1264                     do_wake = 0;
1265           }
1266           ldap_pvt_thread_mutex_unlock( &slap_daemon[id].sd_mutex );
1267           if ( do_wake )
1268                     WAKE_LISTENER(id,wake);
1269 }
1270 
1271 static void
slapd_close(ber_socket_t s)1272 slapd_close( ber_socket_t s )
1273 {
1274           Debug( LDAP_DEBUG_CONNS, "daemon: closing %ld\n",
1275                     (long) s );
1276           CLR_CLOSE( SLAP_FD2SOCK(s) );
1277           tcp_close( SLAP_FD2SOCK(s) );
1278 #ifdef HAVE_WINSOCK
1279           slapd_sockdel( s );
1280 #endif
1281 }
1282 
1283 void
slapd_shutsock(ber_socket_t s)1284 slapd_shutsock( ber_socket_t s )
1285 {
1286           Debug( LDAP_DEBUG_CONNS, "daemon: shutdown socket %ld\n",
1287                     (long) s );
1288           shutdown( SLAP_FD2SOCK(s), 2 );
1289 }
1290 
1291 static void
slap_free_listener_addresses(struct sockaddr ** sal)1292 slap_free_listener_addresses( struct sockaddr **sal )
1293 {
1294           struct sockaddr **sap;
1295           if (sal == NULL) return;
1296           for (sap = sal; *sap != NULL; sap++) ch_free(*sap);
1297           ch_free(sal);
1298 }
1299 
1300 #if defined(LDAP_PF_LOCAL) || defined(SLAP_X_LISTENER_MOD)
1301 static int
get_url_perms(char ** exts,mode_t * perms,int * crit)1302 get_url_perms(
1303           char      **exts,
1304           mode_t    *perms,
1305           int       *crit )
1306 {
1307           int       i;
1308 
1309           assert( exts != NULL );
1310           assert( perms != NULL );
1311           assert( crit != NULL );
1312 
1313           *crit = 0;
1314           for ( i = 0; exts[ i ]; i++ ) {
1315                     char      *type = exts[ i ];
1316                     int       c = 0;
1317 
1318                     if ( type[ 0 ] == '!' ) {
1319                               c = 1;
1320                               type++;
1321                     }
1322 
1323                     if ( strncasecmp( type, LDAPI_MOD_URLEXT "=",
1324                               sizeof(LDAPI_MOD_URLEXT "=") - 1 ) == 0 )
1325                     {
1326                               char *value = type + ( sizeof(LDAPI_MOD_URLEXT "=") - 1 );
1327                               mode_t p = 0;
1328                               int j;
1329 
1330                               switch (strlen(value)) {
1331                               case 4:
1332                                         /* skip leading '0' */
1333                                         if ( value[ 0 ] != '0' ) return LDAP_OTHER;
1334                                         value++;
1335 
1336                               case 3:
1337                                         for ( j = 0; j < 3; j++) {
1338                                                   int       v;
1339 
1340                                                   v = value[ j ] - '0';
1341 
1342                                                   if ( v < 0 || v > 7 ) return LDAP_OTHER;
1343 
1344                                                   p |= v << 3*(2-j);
1345                                         }
1346                                         break;
1347 
1348                               case 10:
1349                                         for ( j = 1; j < 10; j++ ) {
1350                                                   static mode_t       m[] = { 0,
1351                                                             S_IRUSR, S_IWUSR, S_IXUSR,
1352                                                             S_IRGRP, S_IWGRP, S_IXGRP,
1353                                                             S_IROTH, S_IWOTH, S_IXOTH
1354                                                   };
1355                                                   static const char   c[] = "-rwxrwxrwx";
1356 
1357                                                   if ( value[ j ] == c[ j ] ) {
1358                                                             p |= m[ j ];
1359 
1360                                                   } else if ( value[ j ] != '-' ) {
1361                                                             return LDAP_OTHER;
1362                                                   }
1363                                         }
1364                                         break;
1365 
1366                               default:
1367                                         return LDAP_OTHER;
1368                               }
1369 
1370                               *crit = c;
1371                               *perms = p;
1372 
1373                               return LDAP_SUCCESS;
1374                     }
1375           }
1376 
1377           return LDAP_OTHER;
1378 }
1379 #endif /* LDAP_PF_LOCAL || SLAP_X_LISTENER_MOD */
1380 
1381 /* port = 0 indicates AF_LOCAL */
1382 static int
slap_get_listener_addresses(const char * host,unsigned short port,struct sockaddr *** sal)1383 slap_get_listener_addresses(
1384           const char *host,
1385           unsigned short port,
1386           struct sockaddr ***sal )
1387 {
1388           struct sockaddr **sap;
1389 
1390 #ifdef LDAP_PF_LOCAL
1391           if ( port == 0 ) {
1392                     sap = *sal = ch_malloc(2 * sizeof(void *));
1393 
1394                     *sap = ch_malloc(sizeof(struct sockaddr_un));
1395                     sap[1] = NULL;
1396 
1397                     if ( strlen(host) >
1398                               (sizeof(((struct sockaddr_un *)*sap)->sun_path) - 1) )
1399                     {
1400                               Debug( LDAP_DEBUG_ANY,
1401                                         "daemon: domain socket path (%s) too long in URL",
1402                                         host );
1403                               goto errexit;
1404                     }
1405 
1406                     (void)memset( (void *)*sap, '\0', sizeof(struct sockaddr_un) );
1407                     (*sap)->sa_family = AF_LOCAL;
1408                     strcpy( ((struct sockaddr_un *)*sap)->sun_path, host );
1409           } else
1410 #endif /* LDAP_PF_LOCAL */
1411           {
1412 #ifdef HAVE_GETADDRINFO
1413                     struct addrinfo hints, *res, *sai;
1414                     int n, err;
1415                     char serv[7];
1416 
1417                     memset( &hints, '\0', sizeof(hints) );
1418                     hints.ai_flags = AI_PASSIVE;
1419                     hints.ai_socktype = SOCK_STREAM;
1420                     hints.ai_family = slap_inet4or6;
1421                     snprintf(serv, sizeof serv, "%d", port);
1422 
1423                     if ( (err = getaddrinfo(host, serv, &hints, &res)) ) {
1424                               Debug( LDAP_DEBUG_ANY, "daemon: getaddrinfo() failed: %s\n",
1425                                         AC_GAI_STRERROR(err) );
1426                               return -1;
1427                     }
1428 
1429                     sai = res;
1430                     for (n=2; (sai = sai->ai_next) != NULL; n++) {
1431                               /* EMPTY */ ;
1432                     }
1433                     sap = *sal = ch_calloc(n, sizeof(void *));
1434                     *sap = NULL;
1435 
1436                     for ( sai=res; sai; sai=sai->ai_next ) {
1437                               if( sai->ai_addr == NULL ) {
1438                                         Debug( LDAP_DEBUG_ANY, "slap_get_listener_addresses: "
1439                                                   "getaddrinfo ai_addr is NULL?\n" );
1440                                         freeaddrinfo(res);
1441                                         goto errexit;
1442                               }
1443 
1444                               switch (sai->ai_family) {
1445 #  ifdef LDAP_PF_INET6
1446                               case AF_INET6:
1447                                         *sap = ch_malloc(sizeof(struct sockaddr_in6));
1448                                         *(struct sockaddr_in6 *)*sap =
1449                                                   *((struct sockaddr_in6 *)sai->ai_addr);
1450                                         break;
1451 #  endif /* LDAP_PF_INET6 */
1452                               case AF_INET:
1453                                         *sap = ch_malloc(sizeof(struct sockaddr_in));
1454                                         *(struct sockaddr_in *)*sap =
1455                                                   *((struct sockaddr_in *)sai->ai_addr);
1456                                         break;
1457                               default:
1458                                         *sap = NULL;
1459                                         break;
1460                               }
1461 
1462                               if (*sap != NULL) {
1463                                         (*sap)->sa_family = sai->ai_family;
1464                                         sap++;
1465                                         *sap = NULL;
1466                               }
1467                     }
1468 
1469                     freeaddrinfo(res);
1470 
1471 #else /* ! HAVE_GETADDRINFO */
1472                     int i, n = 1;
1473                     struct in_addr in;
1474                     struct hostent *he = NULL;
1475 
1476                     if ( host == NULL ) {
1477                               in.s_addr = htonl(INADDR_ANY);
1478 
1479                     } else if ( !inet_aton( host, &in ) ) {
1480                               he = gethostbyname( host );
1481                               if( he == NULL ) {
1482                                         Debug( LDAP_DEBUG_ANY,
1483                                                   "daemon: invalid host %s", host );
1484                                         return -1;
1485                               }
1486                               for (n = 0; he->h_addr_list[n]; n++) /* empty */;
1487                     }
1488 
1489                     sap = *sal = ch_malloc((n+1) * sizeof(void *));
1490 
1491                     for ( i = 0; i<n; i++ ) {
1492                               sap[i] = ch_calloc(1, sizeof(struct sockaddr_in));
1493                               sap[i]->sa_family = AF_INET;
1494                               ((struct sockaddr_in *)sap[i])->sin_port = htons(port);
1495                               AC_MEMCPY( &((struct sockaddr_in *)sap[i])->sin_addr,
1496                                         he ? (struct in_addr *)he->h_addr_list[i] : &in,
1497                                         sizeof(struct in_addr) );
1498                     }
1499                     sap[i] = NULL;
1500 #endif /* ! HAVE_GETADDRINFO */
1501           }
1502 
1503           return 0;
1504 
1505 errexit:
1506           slap_free_listener_addresses(*sal);
1507           return -1;
1508 }
1509 
1510 static int
slap_open_listener(const char * url,int * listeners,int * cur)1511 slap_open_listener(
1512           const char* url,
1513           int *listeners,
1514           int *cur )
1515 {
1516           int       num, tmp, rc;
1517           Listener l;
1518           Listener *li;
1519           LDAPURLDesc *lud;
1520           unsigned short port;
1521           int err, addrlen = 0;
1522           struct sockaddr **sal = NULL, **psal;
1523           int socktype = SOCK_STREAM;   /* default to COTS */
1524           ber_socket_t s;
1525           char ebuf[128];
1526 
1527 #if defined(LDAP_PF_LOCAL) || defined(SLAP_X_LISTENER_MOD)
1528           /*
1529            * use safe defaults
1530            */
1531           int       crit = 1;
1532 #endif /* LDAP_PF_LOCAL || SLAP_X_LISTENER_MOD */
1533 
1534           rc = ldap_url_parse( url, &lud );
1535 
1536           if( rc != LDAP_URL_SUCCESS ) {
1537                     Debug( LDAP_DEBUG_ANY,
1538                               "daemon: listen URL \"%s\" parse error=%d\n",
1539                               url, rc );
1540                     return rc;
1541           }
1542 
1543           l.sl_url.bv_val = NULL;
1544           l.sl_mute = 0;
1545           l.sl_busy = 0;
1546 
1547 #ifndef HAVE_TLS
1548           if( ldap_pvt_url_scheme2tls( lud->lud_scheme ) ) {
1549                     Debug( LDAP_DEBUG_ANY, "daemon: TLS not supported (%s)\n",
1550                               url );
1551                     ldap_free_urldesc( lud );
1552                     return -1;
1553           }
1554 
1555           if(! lud->lud_port ) lud->lud_port = LDAP_PORT;
1556 
1557 #else /* HAVE_TLS */
1558           l.sl_is_tls = ldap_pvt_url_scheme2tls( lud->lud_scheme );
1559 
1560           if(! lud->lud_port ) {
1561                     lud->lud_port = l.sl_is_tls ? LDAPS_PORT : LDAP_PORT;
1562           }
1563 #endif /* HAVE_TLS */
1564 
1565           l.sl_is_proxied = ldap_pvt_url_scheme2proxied( lud->lud_scheme );
1566 
1567 #ifdef LDAP_TCP_BUFFER
1568           l.sl_tcp_rmem = 0;
1569           l.sl_tcp_wmem = 0;
1570 #endif /* LDAP_TCP_BUFFER */
1571 
1572           port = (unsigned short) lud->lud_port;
1573 
1574           tmp = ldap_pvt_url_scheme2proto(lud->lud_scheme);
1575           if ( tmp == LDAP_PROTO_IPC ) {
1576 #ifdef LDAP_PF_LOCAL
1577                     if ( lud->lud_host == NULL || lud->lud_host[0] == '\0' ) {
1578                               err = slap_get_listener_addresses(LDAPI_SOCK, 0, &sal);
1579                     } else {
1580                               err = slap_get_listener_addresses(lud->lud_host, 0, &sal);
1581                     }
1582 #else /* ! LDAP_PF_LOCAL */
1583 
1584                     Debug( LDAP_DEBUG_ANY, "daemon: URL scheme not supported: %s",
1585                               url );
1586                     ldap_free_urldesc( lud );
1587                     return -1;
1588 #endif /* ! LDAP_PF_LOCAL */
1589           } else {
1590                     if( lud->lud_host == NULL || lud->lud_host[0] == '\0'
1591                               || strcmp(lud->lud_host, "*") == 0 )
1592                     {
1593                               err = slap_get_listener_addresses(NULL, port, &sal);
1594                     } else {
1595                               err = slap_get_listener_addresses(lud->lud_host, port, &sal);
1596                     }
1597           }
1598 
1599 #ifdef LDAP_CONNECTIONLESS
1600           l.sl_is_udp = ( tmp == LDAP_PROTO_UDP );
1601 #endif /* LDAP_CONNECTIONLESS */
1602 
1603 #if defined(LDAP_PF_LOCAL) || defined(SLAP_X_LISTENER_MOD)
1604           if ( lud->lud_exts ) {
1605                     err = get_url_perms( lud->lud_exts, &l.sl_perms, &crit );
1606           } else {
1607                     l.sl_perms = S_IRWXU | S_IRWXO;
1608           }
1609 #endif /* LDAP_PF_LOCAL || SLAP_X_LISTENER_MOD */
1610 
1611           if ( lud->lud_dn && lud->lud_dn[0] ) {
1612                     sprintf( (char *)url, "%s://%s/", lud->lud_scheme, lud->lud_host );
1613                     Debug( LDAP_DEBUG_ANY, "daemon: listener URL %s<junk> DN must be absent (%s)\n",
1614                               url, lud->lud_dn );
1615                     ldap_free_urldesc( lud );
1616                     return -1;
1617           }
1618 
1619           ldap_free_urldesc( lud );
1620           if ( err ) {
1621                     slap_free_listener_addresses(sal);
1622                     return -1;
1623           }
1624 
1625           /* If we got more than one address returned, we need to make space
1626            * for it in the slap_listeners array.
1627            */
1628           for ( num=0; sal[num]; num++ ) /* empty */;
1629           if ( num > 1 ) {
1630                     *listeners += num-1;
1631                     slap_listeners = ch_realloc( slap_listeners,
1632                               (*listeners + 1) * sizeof(Listener *) );
1633           }
1634 
1635           psal = sal;
1636           while ( *sal != NULL ) {
1637                     char *af;
1638                     switch( (*sal)->sa_family ) {
1639                     case AF_INET:
1640                               af = "IPv4";
1641                               break;
1642 #ifdef LDAP_PF_INET6
1643                     case AF_INET6:
1644                               af = "IPv6";
1645                               break;
1646 #endif /* LDAP_PF_INET6 */
1647 #ifdef LDAP_PF_LOCAL
1648                     case AF_LOCAL:
1649                               af = "Local";
1650                               break;
1651 #endif /* LDAP_PF_LOCAL */
1652                     default:
1653                               sal++;
1654                               continue;
1655                     }
1656 
1657 #ifdef LDAP_CONNECTIONLESS
1658                     if( l.sl_is_udp ) socktype = SOCK_DGRAM;
1659 #endif /* LDAP_CONNECTIONLESS */
1660 
1661                     s = socket( (*sal)->sa_family, socktype, 0);
1662                     if ( s == AC_SOCKET_INVALID ) {
1663                               int err = sock_errno();
1664                               Debug( LDAP_DEBUG_ANY,
1665                                         "daemon: %s socket() failed errno=%d (%s)\n",
1666                                         af, err, sock_errstr(err, ebuf, sizeof(ebuf)) );
1667                               sal++;
1668                               continue;
1669                     }
1670                     l.sl_sd = SLAP_SOCKNEW( s );
1671 
1672                     if ( l.sl_sd >= dtblsize ) {
1673                               Debug( LDAP_DEBUG_ANY,
1674                                         "daemon: listener descriptor %ld is too great %ld\n",
1675                                         (long) l.sl_sd, (long) dtblsize );
1676                               tcp_close( s );
1677                               sal++;
1678                               continue;
1679                     }
1680 
1681 #ifdef LDAP_PF_LOCAL
1682                     if ( (*sal)->sa_family == AF_LOCAL ) {
1683                               unlink( ((struct sockaddr_un *)*sal)->sun_path );
1684                     } else
1685 #endif /* LDAP_PF_LOCAL */
1686                     {
1687 #ifdef SO_REUSEADDR
1688                               /* enable address reuse */
1689                               tmp = 1;
1690                               rc = setsockopt( s, SOL_SOCKET, SO_REUSEADDR,
1691                                         (char *) &tmp, sizeof(tmp) );
1692                               if ( rc == AC_SOCKET_ERROR ) {
1693                                         int err = sock_errno();
1694                                         Debug( LDAP_DEBUG_ANY, "slapd(%ld): "
1695                                                   "setsockopt(SO_REUSEADDR) failed errno=%d (%s)\n",
1696                                                   (long) l.sl_sd, err, sock_errstr(err, ebuf, sizeof(ebuf)) );
1697                               }
1698 #endif /* SO_REUSEADDR */
1699                     }
1700 
1701                     switch( (*sal)->sa_family ) {
1702                     case AF_INET:
1703                               addrlen = sizeof(struct sockaddr_in);
1704                               break;
1705 #ifdef LDAP_PF_INET6
1706                     case AF_INET6:
1707 #ifdef IPV6_V6ONLY
1708                               /* Try to use IPv6 sockets for IPv6 only */
1709                               tmp = 1;
1710                               rc = setsockopt( s , IPPROTO_IPV6, IPV6_V6ONLY,
1711                                         (char *) &tmp, sizeof(tmp) );
1712                               if ( rc == AC_SOCKET_ERROR ) {
1713                                         int err = sock_errno();
1714                                         Debug( LDAP_DEBUG_ANY, "slapd(%ld): "
1715                                                   "setsockopt(IPV6_V6ONLY) failed errno=%d (%s)\n",
1716                                                   (long) l.sl_sd, err, sock_errstr(err, ebuf, sizeof(ebuf)) );
1717                               }
1718 #endif /* IPV6_V6ONLY */
1719                               addrlen = sizeof(struct sockaddr_in6);
1720                               break;
1721 #endif /* LDAP_PF_INET6 */
1722 
1723 #ifdef LDAP_PF_LOCAL
1724                     case AF_LOCAL:
1725 #ifdef LOCAL_CREDS
1726                               {
1727                                         int one = 1;
1728                                         setsockopt( s, 0, LOCAL_CREDS, &one, sizeof( one ) );
1729                               }
1730 #endif /* LOCAL_CREDS */
1731 
1732                               addrlen = sizeof( struct sockaddr_un );
1733                               break;
1734 #endif /* LDAP_PF_LOCAL */
1735                     }
1736 
1737 #ifdef LDAP_PF_LOCAL
1738                     /* create socket with all permissions set for those systems
1739                      * that honor permissions on sockets (e.g. Linux); typically,
1740                      * only write is required.  To exploit filesystem permissions,
1741                      * place the socket in a directory and use directory's
1742                      * permissions.  Need write perms to the directory to
1743                      * create/unlink the socket; likely need exec perms to access
1744                      * the socket (ITS#4709) */
1745                     {
1746                               mode_t old_umask = 0;
1747 
1748                               if ( (*sal)->sa_family == AF_LOCAL ) {
1749                                         old_umask = umask( 0 );
1750                               }
1751 #endif /* LDAP_PF_LOCAL */
1752                               rc = bind( s, *sal, addrlen );
1753 #ifdef LDAP_PF_LOCAL
1754                               if ( old_umask != 0 ) {
1755                                         umask( old_umask );
1756                               }
1757                     }
1758 #endif /* LDAP_PF_LOCAL */
1759                     if ( rc ) {
1760                               err = sock_errno();
1761                               Debug( LDAP_DEBUG_ANY,
1762                                         "daemon: bind(%ld) failed errno=%d (%s)\n",
1763                                         (long)l.sl_sd, err, sock_errstr( err, ebuf, sizeof(ebuf) ) );
1764                               tcp_close( s );
1765                               sal++;
1766                               continue;
1767                     }
1768 
1769                     switch ( (*sal)->sa_family ) {
1770 #ifdef LDAP_PF_LOCAL
1771                     case AF_LOCAL: {
1772                               char *path = ((struct sockaddr_un *)*sal)->sun_path;
1773                               l.sl_name.bv_len = strlen(path) + STRLENOF("PATH=");
1774                               l.sl_name.bv_val = ch_malloc( l.sl_name.bv_len + 1 );
1775                               snprintf( l.sl_name.bv_val, l.sl_name.bv_len + 1,
1776                                         "PATH=%s", path );
1777                     } break;
1778 #endif /* LDAP_PF_LOCAL */
1779 
1780                     case AF_INET: {
1781                               char addr[INET_ADDRSTRLEN];
1782                               const char *s;
1783 #if defined( HAVE_GETADDRINFO ) && defined( HAVE_INET_NTOP )
1784                               s = inet_ntop( AF_INET, &((struct sockaddr_in *)*sal)->sin_addr,
1785                                         addr, sizeof(addr) );
1786 #else /* ! HAVE_GETADDRINFO || ! HAVE_INET_NTOP */
1787                               s = inet_ntoa( ((struct sockaddr_in *) *sal)->sin_addr );
1788 #endif /* ! HAVE_GETADDRINFO || ! HAVE_INET_NTOP */
1789                               if (!s) s = SLAP_STRING_UNKNOWN;
1790                               port = ntohs( ((struct sockaddr_in *)*sal) ->sin_port );
1791                               l.sl_name.bv_val =
1792                                         ch_malloc( sizeof("IP=255.255.255.255:65535") );
1793                               snprintf( l.sl_name.bv_val, sizeof("IP=255.255.255.255:65535"),
1794                                         "IP=%s:%d", s, port );
1795                               l.sl_name.bv_len = strlen( l.sl_name.bv_val );
1796                     } break;
1797 
1798 #ifdef LDAP_PF_INET6
1799                     case AF_INET6: {
1800                               char addr[INET6_ADDRSTRLEN];
1801                               const char *s;
1802                               s = inet_ntop( AF_INET6, &((struct sockaddr_in6 *)*sal)->sin6_addr,
1803                                         addr, sizeof addr);
1804                               if (!s) s = SLAP_STRING_UNKNOWN;
1805                               port = ntohs( ((struct sockaddr_in6 *)*sal)->sin6_port );
1806                               l.sl_name.bv_len = strlen(s) + sizeof("IP=[]:65535");
1807                               l.sl_name.bv_val = ch_malloc( l.sl_name.bv_len );
1808                               snprintf( l.sl_name.bv_val, l.sl_name.bv_len, "IP=[%s]:%d",
1809                                         s, port );
1810                               l.sl_name.bv_len = strlen( l.sl_name.bv_val );
1811                     } break;
1812 #endif /* LDAP_PF_INET6 */
1813 
1814                     default:
1815                               Debug( LDAP_DEBUG_ANY, "daemon: unsupported address family (%d)\n",
1816                                         (int) (*sal)->sa_family );
1817                               break;
1818                     }
1819 
1820                     AC_MEMCPY(&l.sl_sa, *sal, addrlen);
1821                     ber_str2bv( url, 0, 1, &l.sl_url);
1822                     li = ch_malloc( sizeof( Listener ) );
1823                     *li = l;
1824                     slap_listeners[*cur] = li;
1825                     (*cur)++;
1826                     sal++;
1827           }
1828 
1829           slap_free_listener_addresses(psal);
1830 
1831           if ( l.sl_url.bv_val == NULL ) {
1832                     Debug( LDAP_DEBUG_TRACE,
1833                               "slap_open_listener: failed on %s\n", url );
1834                     return -1;
1835           }
1836 
1837           Debug( LDAP_DEBUG_TRACE, "daemon: listener initialized %s\n",
1838                     l.sl_url.bv_val );
1839           return 0;
1840 }
1841 
1842 static int sockinit(void);
1843 static int sockdestroy(void);
1844 
1845 static int daemon_inited = 0;
1846 
1847 int
slapd_daemon_init(const char * urls)1848 slapd_daemon_init( const char *urls )
1849 {
1850           int i, j, n, rc;
1851           char **u;
1852 
1853           Debug( LDAP_DEBUG_ARGS, "daemon_init: %s\n",
1854                     urls ? urls : "<null>" );
1855 
1856           wake_sds = ch_malloc( slapd_daemon_threads * sizeof( sdpair ));
1857           for ( i=0; i<slapd_daemon_threads; i++ ) {
1858                     wake_sds[i][0] = AC_SOCKET_INVALID;
1859                     wake_sds[i][1] = AC_SOCKET_INVALID;
1860           }
1861 
1862           slap_daemon = ch_calloc( slapd_daemon_threads, sizeof( slap_daemon_st ));
1863           ldap_pvt_thread_mutex_init( &slap_daemon[0].sd_mutex );
1864 #ifdef HAVE_TCPD
1865           ldap_pvt_thread_mutex_init( &sd_tcpd_mutex );
1866 #endif /* TCP Wrappers */
1867           ldap_pvt_thread_mutex_init( &emfile_mutex );
1868 
1869           daemon_inited = 1;
1870 
1871           if( (rc = sockinit()) != 0 ) return rc;
1872 
1873 #ifdef HAVE_SYSCONF
1874           dtblsize = sysconf( _SC_OPEN_MAX );
1875 #elif defined(HAVE_GETDTABLESIZE)
1876           dtblsize = getdtablesize();
1877 #else /* ! HAVE_SYSCONF && ! HAVE_GETDTABLESIZE */
1878           dtblsize = FD_SETSIZE;
1879 #endif /* ! HAVE_SYSCONF && ! HAVE_GETDTABLESIZE */
1880 
1881           SETUP_CLOSE();
1882 
1883           /* open a pipe (or something equivalent connected to itself).
1884            * we write a byte on this fd whenever we catch a signal. The main
1885            * loop will be select'ing on this socket, and will wake up when
1886            * this byte arrives.
1887            */
1888           if( (rc = lutil_pair( wake_sds[0] )) < 0 ) {
1889                     Debug( LDAP_DEBUG_ANY,
1890                               "daemon: lutil_pair() failed rc=%d\n", rc );
1891                     return rc;
1892           }
1893           ber_pvt_socket_set_nonblock( wake_sds[0][1], 1 );
1894 
1895           SLAP_SOCK_INIT(0);
1896 
1897           if( urls == NULL ) urls = "ldap:///";
1898 
1899           u = ldap_str2charray( urls, " " );
1900 
1901           if( u == NULL || u[0] == NULL ) {
1902                     Debug( LDAP_DEBUG_ANY, "daemon_init: no urls (%s) provided.\n",
1903                               urls );
1904                     if ( u )
1905                               ldap_charray_free( u );
1906                     return -1;
1907           }
1908 
1909           for( i=0; u[i] != NULL; i++ ) {
1910                     Debug( LDAP_DEBUG_TRACE, "daemon_init: listen on %s\n",
1911                               u[i] );
1912           }
1913 
1914           if( i == 0 ) {
1915                     Debug( LDAP_DEBUG_ANY, "daemon_init: no listeners to open (%s)\n",
1916                               urls );
1917                     ldap_charray_free( u );
1918                     return -1;
1919           }
1920 
1921           Debug( LDAP_DEBUG_TRACE, "daemon_init: %d listeners to open...\n",
1922                     i );
1923           slap_listeners = ch_malloc( (i+1)*sizeof(Listener *) );
1924 
1925           for(n = 0, j = 0; u[n]; n++ ) {
1926                     if ( slap_open_listener( u[n], &i, &j ) ) {
1927                               ldap_charray_free( u );
1928                               return -1;
1929                     }
1930           }
1931           slap_listeners[j] = NULL;
1932 
1933           Debug( LDAP_DEBUG_TRACE, "daemon_init: %d listeners opened\n",
1934                     i );
1935 
1936 
1937 #ifdef HAVE_SLP
1938           if( slapd_register_slp ) {
1939                     slapd_slp_init( urls );
1940                     slapd_slp_reg();
1941           }
1942 #endif /* HAVE_SLP */
1943 
1944           ldap_charray_free( u );
1945 
1946           return !i;
1947 }
1948 
1949 /* transfer control of active sockets from old to new listener threads */
1950 static void
slapd_socket_realloc(int newnum)1951 slapd_socket_realloc( int newnum )
1952 {
1953           int i, j, oldid, newid;
1954           int newmask = newnum - 1;
1955           Listener *sl;
1956           int num_listeners;
1957 
1958           for ( i=0; slap_listeners[i] != NULL; i++ ) ;
1959           num_listeners = i;
1960 
1961           for ( i=0; i<dtblsize; i++ ) {
1962                     int skip = 0;
1963 
1964                     /* don't bother with wake_sds, they're assigned independent of mask */
1965                     for (j=0; j<slapd_daemon_threads; j++) {
1966                               if ( i == wake_sds[j][0] || i == wake_sds[j][1] ) {
1967                                         skip = 1;
1968                                         break;
1969                               }
1970                     }
1971                     if ( skip ) continue;
1972 
1973                     oldid = DAEMON_ID(i);
1974                     newid = i & newmask;
1975                     if ( oldid == newid ) continue;
1976                     if ( !SLAP_SOCK_IS_ACTIVE( oldid, i )) continue;
1977                     sl = NULL;
1978                     if ( num_listeners ) {
1979                               for ( j=0; slap_listeners[j] != NULL; j++ ) {
1980                                         if ( slap_listeners[j]->sl_sd == i ) {
1981                                                   sl = slap_listeners[j];
1982                                                   num_listeners--;
1983                                                   break;
1984                                         }
1985                               }
1986                     }
1987                     SLAP_SOCK_ADD( newid, i, sl );
1988                     if ( SLAP_SOCK_IS_READ( oldid, i )) {
1989                               SLAP_SOCK_SET_READ( newid, i );
1990                     }
1991                     if ( SLAP_SOCK_IS_WRITE( oldid, i )) {
1992                               SLAP_SOCK_SET_WRITE( newid, i );
1993                               slap_daemon[oldid].sd_nwriters--;
1994                               slap_daemon[newid].sd_nwriters++;
1995                     }
1996                     if ( connection_is_active( i )) {
1997                               slap_daemon[oldid].sd_nactives--;
1998                               slap_daemon[newid].sd_nactives++;
1999                     }
2000                     SLAP_SOCK_DEL( oldid, i );
2001           }
2002 }
2003 
2004 
2005 int
slapd_daemon_destroy(void)2006 slapd_daemon_destroy( void )
2007 {
2008           connections_destroy();
2009           if ( daemon_inited ) {
2010                     int i;
2011 
2012                     for ( i=0; i<slapd_daemon_threads; i++ ) {
2013 #ifdef HAVE_WINSOCK
2014                               if ( wake_sds[i][1] != INVALID_SOCKET &&
2015                                         SLAP_FD2SOCK( wake_sds[i][1] ) != SLAP_FD2SOCK( wake_sds[i][0] ))
2016 #endif /* HAVE_WINSOCK */
2017                                         tcp_close( SLAP_FD2SOCK(wake_sds[i][1]) );
2018 #ifdef HAVE_WINSOCK
2019                               if ( wake_sds[i][0] != INVALID_SOCKET )
2020 #endif /* HAVE_WINSOCK */
2021                                         tcp_close( SLAP_FD2SOCK(wake_sds[i][0]) );
2022                               ldap_pvt_thread_mutex_destroy( &slap_daemon[i].sd_mutex );
2023                               SLAP_SOCK_DESTROY(i);
2024                     }
2025                     daemon_inited = 0;
2026                     ldap_pvt_thread_mutex_destroy( &emfile_mutex );
2027 #ifdef HAVE_TCPD
2028                     ldap_pvt_thread_mutex_destroy( &sd_tcpd_mutex );
2029 #endif /* TCP Wrappers */
2030           }
2031           sockdestroy();
2032 
2033 #ifdef HAVE_SLP
2034           if( slapd_register_slp ) {
2035                     slapd_slp_dereg();
2036                     slapd_slp_deinit();
2037           }
2038 #endif /* HAVE_SLP */
2039 
2040           return 0;
2041 }
2042 
2043 
2044 static void
close_listeners(int remove)2045 close_listeners(
2046           int remove )
2047 {
2048           int l;
2049 
2050           if ( !listening )
2051                     return;
2052           listening = 0;
2053 
2054           for ( l = 0; slap_listeners[l] != NULL; l++ ) {
2055                     Listener *lr = slap_listeners[l];
2056 
2057                     if ( lr->sl_sd != AC_SOCKET_INVALID ) {
2058                               int s = lr->sl_sd;
2059                               lr->sl_sd = AC_SOCKET_INVALID;
2060                               if ( remove ) slapd_remove( s, NULL, 0, 0, 0 );
2061 
2062 #ifdef LDAP_PF_LOCAL
2063                               if ( lr->sl_sa.sa_addr.sa_family == AF_LOCAL ) {
2064                                         unlink( lr->sl_sa.sa_un_addr.sun_path );
2065                               }
2066 #endif /* LDAP_PF_LOCAL */
2067 
2068                               slapd_close( s );
2069                     }
2070           }
2071 }
2072 
2073 static void
destroy_listeners(void)2074 destroy_listeners( void )
2075 {
2076           Listener *lr, **ll = slap_listeners;
2077 
2078           if ( ll == NULL )
2079                     return;
2080 
2081           while ( (lr = *ll++) != NULL ) {
2082                     if ( lr->sl_url.bv_val ) {
2083                               ber_memfree( lr->sl_url.bv_val );
2084                     }
2085 
2086                     if ( lr->sl_name.bv_val ) {
2087                               ber_memfree( lr->sl_name.bv_val );
2088                     }
2089 
2090                     free( lr );
2091           }
2092 
2093           free( slap_listeners );
2094           slap_listeners = NULL;
2095 }
2096 
2097 static int
slap_listener(Listener * sl)2098 slap_listener(
2099           Listener *sl )
2100 {
2101           Sockaddr            from;
2102 
2103           ber_socket_t s, sfd;
2104           ber_socklen_t len = sizeof(from);
2105           Connection *c;
2106           slap_ssf_t ssf = 0;
2107           struct berval authid = BER_BVNULL;
2108 #ifdef SLAPD_RLOOKUPS
2109           char hbuf[NI_MAXHOST];
2110 #endif /* SLAPD_RLOOKUPS */
2111 
2112           char      *dnsname = NULL;
2113           /* we assume INET6_ADDRSTRLEN > INET_ADDRSTRLEN */
2114           char peername[LDAP_IPADDRLEN];
2115           struct berval peerbv = BER_BVC(peername);
2116 #ifdef LDAP_PF_LOCAL_SENDMSG
2117           char peerbuf[8];
2118           struct berval peerbv = BER_BVNULL;
2119 #endif
2120           int cflag;
2121           int tid;
2122           char ebuf[128];
2123 
2124           Debug( LDAP_DEBUG_TRACE,
2125                     ">>> slap_listener(%s)\n",
2126                     sl->sl_url.bv_val );
2127 
2128           peername[0] = '\0';
2129 
2130 #ifdef LDAP_CONNECTIONLESS
2131           if ( sl->sl_is_udp ) return 1;
2132 #endif /* LDAP_CONNECTIONLESS */
2133 
2134 #  ifdef LDAP_PF_LOCAL
2135           /* FIXME: apparently accept doesn't fill
2136            * the sun_path sun_path member */
2137           from.sa_un_addr.sun_path[0] = '\0';
2138 #  endif /* LDAP_PF_LOCAL */
2139 
2140           s = accept( SLAP_FD2SOCK( sl->sl_sd ), (struct sockaddr *) &from, &len );
2141           if ( s != AC_SOCKET_INVALID ) {
2142                     SET_CLOSE(s);
2143           }
2144           Debug( LDAP_DEBUG_CONNS,
2145                     "daemon: accept() = %d\n", s );
2146 
2147           /* Resume the listener FD to allow concurrent-processing of
2148            * additional incoming connections.
2149            */
2150           sl->sl_busy = 0;
2151           WAKE_LISTENER(DAEMON_ID(sl->sl_sd),1);
2152 
2153           if ( s == AC_SOCKET_INVALID ) {
2154                     int err = sock_errno();
2155 
2156                     if(
2157 #ifdef EMFILE
2158                         err == EMFILE ||
2159 #endif /* EMFILE */
2160 #ifdef ENFILE
2161                         err == ENFILE ||
2162 #endif /* ENFILE */
2163                         0 )
2164                     {
2165                               ldap_pvt_thread_mutex_lock( &emfile_mutex );
2166                               emfile++;
2167                               /* Stop listening until an existing session closes */
2168                               sl->sl_mute = 1;
2169                               ldap_pvt_thread_mutex_unlock( &emfile_mutex );
2170                     }
2171 
2172                     Debug( LDAP_DEBUG_ANY,
2173                               "daemon: accept(%ld) failed errno=%d (%s)\n",
2174                               (long) sl->sl_sd, err, sock_errstr(err, ebuf, sizeof(ebuf)) );
2175                     ldap_pvt_thread_yield();
2176                     return 0;
2177           }
2178           sfd = SLAP_SOCKNEW( s );
2179 
2180           /* make sure descriptor number isn't too great */
2181           if ( sfd >= dtblsize ) {
2182                     Debug( LDAP_DEBUG_ANY,
2183                               "daemon: %ld beyond descriptor table size %ld\n",
2184                               (long) sfd, (long) dtblsize );
2185 
2186                     tcp_close(s);
2187                     ldap_pvt_thread_yield();
2188                     return 0;
2189           }
2190           tid = DAEMON_ID(sfd);
2191 
2192 #ifdef LDAP_DEBUG
2193           ldap_pvt_thread_mutex_lock( &slap_daemon[tid].sd_mutex );
2194           /* newly accepted stream should not be in any of the FD SETS */
2195           assert( SLAP_SOCK_NOT_ACTIVE( tid, sfd ));
2196           ldap_pvt_thread_mutex_unlock( &slap_daemon[tid].sd_mutex );
2197 #endif /* LDAP_DEBUG */
2198 
2199 #if defined( SO_KEEPALIVE ) || defined( TCP_NODELAY )
2200 #ifdef LDAP_PF_LOCAL
2201           /* for IPv4 and IPv6 sockets only */
2202           if ( from.sa_addr.sa_family != AF_LOCAL )
2203 #endif /* LDAP_PF_LOCAL */
2204           {
2205                     int rc;
2206                     int tmp;
2207 #ifdef SO_KEEPALIVE
2208                     /* enable keep alives */
2209                     tmp = 1;
2210                     rc = setsockopt( s, SOL_SOCKET, SO_KEEPALIVE,
2211                               (char *) &tmp, sizeof(tmp) );
2212                     if ( rc == AC_SOCKET_ERROR ) {
2213                               int err = sock_errno();
2214                               Debug( LDAP_DEBUG_ANY,
2215                                         "slapd(%ld): setsockopt(SO_KEEPALIVE) failed "
2216                                         "errno=%d (%s)\n", (long) sfd, err, sock_errstr(err, ebuf, sizeof(ebuf)) );
2217                               slapd_close(sfd);
2218                               return 0;
2219                     }
2220 #endif /* SO_KEEPALIVE */
2221 #ifdef TCP_NODELAY
2222                     /* enable no delay */
2223                     tmp = 1;
2224                     rc = setsockopt( s, IPPROTO_TCP, TCP_NODELAY,
2225                               (char *)&tmp, sizeof(tmp) );
2226                     if ( rc == AC_SOCKET_ERROR ) {
2227                               int err = sock_errno();
2228                               Debug( LDAP_DEBUG_ANY,
2229                                         "slapd(%ld): setsockopt(TCP_NODELAY) failed "
2230                                         "errno=%d (%s)\n", (long) sfd, err, sock_errstr(err, ebuf, sizeof(ebuf)) );
2231                               slapd_close(sfd);
2232                               return 0;
2233                     }
2234 #endif /* TCP_NODELAY */
2235           }
2236 #endif /* SO_KEEPALIVE || TCP_NODELAY */
2237 
2238           Debug( LDAP_DEBUG_CONNS,
2239                     "daemon: listen=%ld, new connection on %ld\n",
2240                     (long) sl->sl_sd, (long) sfd );
2241 
2242           cflag = 0;
2243           switch ( from.sa_addr.sa_family ) {
2244 #  ifdef LDAP_PF_LOCAL
2245           case AF_LOCAL:
2246                     cflag |= CONN_IS_IPC;
2247 
2248                     /* FIXME: apparently accept doesn't fill
2249                      * the sun_path sun_path member */
2250                     if ( from.sa_un_addr.sun_path[0] == '\0' ) {
2251                               AC_MEMCPY( from.sa_un_addr.sun_path,
2252                                                   sl->sl_sa.sa_un_addr.sun_path,
2253                                                   sizeof( from.sa_un_addr.sun_path ) );
2254                     }
2255 
2256                     sprintf( peername, "PATH=%s", from.sa_un_addr.sun_path );
2257                     ssf = local_ssf;
2258                     {
2259                               uid_t uid;
2260                               gid_t gid;
2261 
2262 #ifdef LDAP_PF_LOCAL_SENDMSG
2263                               peerbv.bv_val = peerbuf;
2264                               peerbv.bv_len = sizeof( peerbuf );
2265 #endif
2266                               if( LUTIL_GETPEEREID( s, &uid, &gid, &peerbv ) == 0 ) {
2267                                         authid.bv_val = ch_malloc(
2268                                                   STRLENOF( "gidNumber=4294967295+uidNumber=4294967295,"
2269                                                   "cn=peercred,cn=external,cn=auth" ) + 1 );
2270                                         authid.bv_len = sprintf( authid.bv_val,
2271                                                   "gidNumber=%d+uidNumber=%d,"
2272                                                   "cn=peercred,cn=external,cn=auth",
2273                                                   (int) gid, (int) uid );
2274                                         assert( authid.bv_len <=
2275                                                   STRLENOF( "gidNumber=4294967295+uidNumber=4294967295,"
2276                                                   "cn=peercred,cn=external,cn=auth" ) );
2277                               }
2278                     }
2279                     dnsname = "local";
2280                     break;
2281 #endif /* LDAP_PF_LOCAL */
2282 
2283 #  ifdef LDAP_PF_INET6
2284           case AF_INET6:
2285 #  endif /* LDAP_PF_INET6 */
2286           case AF_INET:
2287                     if ( sl->sl_is_proxied ) {
2288                               if ( !proxyp( sfd, &from ) ) {
2289                                         Debug( LDAP_DEBUG_ANY, "slapd(%ld): proxyp failed\n", (long)sfd );
2290                                         slapd_close( sfd );
2291                                         return 0;
2292                               }
2293                     }
2294                     ldap_pvt_sockaddrstr( &from, &peerbv );
2295                     break;
2296 
2297           default:
2298                     slapd_close(sfd);
2299                     return 0;
2300           }
2301 
2302           if ( ( from.sa_addr.sa_family == AF_INET )
2303 #ifdef LDAP_PF_INET6
2304                     || ( from.sa_addr.sa_family == AF_INET6 )
2305 #endif /* LDAP_PF_INET6 */
2306                     )
2307           {
2308                     dnsname = NULL;
2309 #ifdef SLAPD_RLOOKUPS
2310                     if ( use_reverse_lookup ) {
2311                               char *herr;
2312                               if (ldap_pvt_get_hname( (const struct sockaddr *)&from, len, hbuf,
2313                                         sizeof(hbuf), &herr ) == 0) {
2314                                         ldap_pvt_str2lower( hbuf );
2315                                         dnsname = hbuf;
2316                               }
2317                     }
2318 #endif /* SLAPD_RLOOKUPS */
2319 
2320 #ifdef HAVE_TCPD
2321                     {
2322                               int rc;
2323                               char *peeraddr, *paend;
2324                               peeraddr = peerbv.bv_val + 3;
2325                               if ( *peeraddr == '[' ) {
2326                                         peeraddr++;
2327                                         paend = strrchr( peeraddr, ']' );
2328                               } else {
2329                                         paend = strrchr( peeraddr, ':' );
2330                               }
2331                               if ( paend )
2332                                         *paend = '\0';
2333                               ldap_pvt_thread_mutex_lock( &sd_tcpd_mutex );
2334                               rc = hosts_ctl("slapd",
2335                                         dnsname != NULL ? dnsname : SLAP_STRING_UNKNOWN,
2336                                         peeraddr,
2337                                         SLAP_STRING_UNKNOWN );
2338                               ldap_pvt_thread_mutex_unlock( &sd_tcpd_mutex );
2339                               if ( !rc ) {
2340                                         /* DENY ACCESS */
2341                                         Debug( LDAP_DEBUG_STATS,
2342                                                   "fd=%ld DENIED from %s (%s)\n",
2343                                                   (long) sfd,
2344                                                   dnsname != NULL ? dnsname : SLAP_STRING_UNKNOWN,
2345                                                   peeraddr );
2346                                         slapd_close(sfd);
2347                                         return 0;
2348                               }
2349                               if ( paend ) {
2350                                         if ( peeraddr[-1] == '[' )
2351                                                   *paend = ']';
2352                                         else
2353                                                   *paend = ':';
2354                               }
2355                     }
2356 #endif /* HAVE_TCPD */
2357           }
2358 
2359 #ifdef HAVE_TLS
2360           if ( sl->sl_is_tls ) cflag |= CONN_IS_TLS;
2361 #endif
2362           c = connection_init(sfd, sl,
2363                     dnsname != NULL ? dnsname : SLAP_STRING_UNKNOWN,
2364                     peername, cflag, ssf,
2365                     authid.bv_val ? &authid : NULL
2366                     LDAP_PF_LOCAL_SENDMSG_ARG(&peerbv));
2367 
2368           if( authid.bv_val ) ch_free(authid.bv_val);
2369 
2370           if( !c ) {
2371                     Debug( LDAP_DEBUG_ANY,
2372                               "daemon: connection_init(%ld, %s, %s) failed.\n",
2373                               (long) sfd, peername, sl->sl_name.bv_val );
2374                     slapd_close(sfd);
2375           }
2376 
2377           return 0;
2378 }
2379 
2380 static void*
slap_listener_thread(void * ctx,void * ptr)2381 slap_listener_thread(
2382           void* ctx,
2383           void* ptr )
2384 {
2385           int                 rc;
2386           Listener  *sl = (Listener *)ptr;
2387 
2388           rc = slap_listener( sl );
2389 
2390           if( rc != LDAP_SUCCESS ) {
2391                     Debug( LDAP_DEBUG_ANY,
2392                               "slap_listener_thread(%s): failed err=%d",
2393                               sl->sl_url.bv_val, rc );
2394           }
2395 
2396           return (void*)NULL;
2397 }
2398 
2399 static int
slap_listener_activate(Listener * sl)2400 slap_listener_activate(
2401           Listener* sl )
2402 {
2403           int rc;
2404 
2405           Debug( LDAP_DEBUG_TRACE, "slap_listener_activate(%d): %s\n",
2406                     sl->sl_sd, sl->sl_busy ? "busy" : "" );
2407 
2408           sl->sl_busy = 1;
2409 
2410           rc = ldap_pvt_thread_pool_submit( &connection_pool,
2411                     slap_listener_thread, (void *) sl );
2412 
2413           if( rc != 0 ) {
2414                     Debug( LDAP_DEBUG_ANY,
2415                               "slap_listener_activate(%d): submit failed (%d)\n",
2416                               sl->sl_sd, rc );
2417           }
2418           return rc;
2419 }
2420 
2421 static void *
slapd_daemon_task(void * ptr)2422 slapd_daemon_task(
2423           void *ptr )
2424 {
2425           int l;
2426           time_t last_idle_check = 0;
2427           int ebadf = 0;
2428           int tid = (slap_daemon_st *) ptr - slap_daemon;
2429           char ebuf[128];
2430 
2431 #define SLAPD_IDLE_CHECK_LIMIT 4
2432 
2433           slapd_add( wake_sds[tid][0], 0, NULL, tid );
2434           if ( tid )
2435                     goto loop;
2436 
2437           /* Init stuff done only by thread 0 */
2438 
2439           last_idle_check = slap_get_time();
2440 
2441           for ( l = 0; slap_listeners[l] != NULL; l++ ) {
2442                     if ( slap_listeners[l]->sl_sd == AC_SOCKET_INVALID ) continue;
2443 
2444 #ifdef LDAP_CONNECTIONLESS
2445                     /* Since this is connectionless, the data port is the
2446                      * listening port. The listen() and accept() calls
2447                      * are unnecessary.
2448                      */
2449                     if ( slap_listeners[l]->sl_is_udp )
2450                               continue;
2451 #endif /* LDAP_CONNECTIONLESS */
2452 
2453                     /* FIXME: TCP-only! */
2454 #ifdef LDAP_TCP_BUFFER
2455                     if ( 1 ) {
2456                               int origsize, size, realsize, rc;
2457                               socklen_t optlen;
2458 
2459                               size = 0;
2460                               if ( slap_listeners[l]->sl_tcp_rmem > 0 ) {
2461                                         size = slap_listeners[l]->sl_tcp_rmem;
2462                               } else if ( slapd_tcp_rmem > 0 ) {
2463                                         size = slapd_tcp_rmem;
2464                               }
2465 
2466                               if ( size > 0 ) {
2467                                         optlen = sizeof( origsize );
2468                                         rc = getsockopt( SLAP_FD2SOCK( slap_listeners[l]->sl_sd ),
2469                                                   SOL_SOCKET,
2470                                                   SO_RCVBUF,
2471                                                   (void *)&origsize,
2472                                                   &optlen );
2473 
2474                                         if ( rc ) {
2475                                                   int err = sock_errno();
2476                                                   Debug( LDAP_DEBUG_ANY,
2477                                                             "slapd_daemon_task: getsockopt(SO_RCVBUF) failed errno=%d (%s)\n",
2478                                                             err, sock_errstr(err, ebuf, sizeof(ebuf)) );
2479                                         }
2480 
2481                                         optlen = sizeof( size );
2482                                         rc = setsockopt( SLAP_FD2SOCK( slap_listeners[l]->sl_sd ),
2483                                                   SOL_SOCKET,
2484                                                   SO_RCVBUF,
2485                                                   (const void *)&size,
2486                                                   optlen );
2487 
2488                                         if ( rc ) {
2489                                                   int err = sock_errno();
2490                                                   Debug( LDAP_DEBUG_ANY,
2491                                                             "slapd_daemon_task: setsockopt(SO_RCVBUF) failed errno=%d (%s)\n",
2492                                                             err, sock_errstr(err, ebuf, sizeof(ebuf)) );
2493                                         }
2494 
2495                                         optlen = sizeof( realsize );
2496                                         rc = getsockopt( SLAP_FD2SOCK( slap_listeners[l]->sl_sd ),
2497                                                   SOL_SOCKET,
2498                                                   SO_RCVBUF,
2499                                                   (void *)&realsize,
2500                                                   &optlen );
2501 
2502                                         if ( rc ) {
2503                                                   int err = sock_errno();
2504                                                   Debug( LDAP_DEBUG_ANY,
2505                                                             "slapd_daemon_task: getsockopt(SO_RCVBUF) failed errno=%d (%s)\n",
2506                                                             err, sock_errstr(err, ebuf, sizeof(ebuf)) );
2507                                         }
2508 
2509                                         Debug(LDAP_DEBUG_ANY,
2510                                               "slapd_daemon_task: url=%s (#%d) RCVBUF original size=%d requested size=%d real size=%d\n",
2511                                               slap_listeners[l]->sl_url.bv_val, l,
2512                                               origsize, size, realsize );
2513                               }
2514 
2515                               size = 0;
2516                               if ( slap_listeners[l]->sl_tcp_wmem > 0 ) {
2517                                         size = slap_listeners[l]->sl_tcp_wmem;
2518                               } else if ( slapd_tcp_wmem > 0 ) {
2519                                         size = slapd_tcp_wmem;
2520                               }
2521 
2522                               if ( size > 0 ) {
2523                                         optlen = sizeof( origsize );
2524                                         rc = getsockopt( SLAP_FD2SOCK( slap_listeners[l]->sl_sd ),
2525                                                   SOL_SOCKET,
2526                                                   SO_SNDBUF,
2527                                                   (void *)&origsize,
2528                                                   &optlen );
2529 
2530                                         if ( rc ) {
2531                                                   int err = sock_errno();
2532                                                   Debug( LDAP_DEBUG_ANY,
2533                                                             "slapd_daemon_task: getsockopt(SO_SNDBUF) failed errno=%d (%s)\n",
2534                                                             err, sock_errstr(err, ebuf, sizeof(ebuf)) );
2535                                         }
2536 
2537                                         optlen = sizeof( size );
2538                                         rc = setsockopt( SLAP_FD2SOCK( slap_listeners[l]->sl_sd ),
2539                                                   SOL_SOCKET,
2540                                                   SO_SNDBUF,
2541                                                   (const void *)&size,
2542                                                   optlen );
2543 
2544                                         if ( rc ) {
2545                                                   int err = sock_errno();
2546                                                   Debug( LDAP_DEBUG_ANY,
2547                                                             "slapd_daemon_task: setsockopt(SO_SNDBUF) failed errno=%d (%s)",
2548                                                             err, sock_errstr(err, ebuf, sizeof(ebuf)) );
2549                                         }
2550 
2551                                         optlen = sizeof( realsize );
2552                                         rc = getsockopt( SLAP_FD2SOCK( slap_listeners[l]->sl_sd ),
2553                                                   SOL_SOCKET,
2554                                                   SO_SNDBUF,
2555                                                   (void *)&realsize,
2556                                                   &optlen );
2557 
2558                                         if ( rc ) {
2559                                                   int err = sock_errno();
2560                                                   Debug( LDAP_DEBUG_ANY,
2561                                                             "slapd_daemon_task: getsockopt(SO_SNDBUF) failed errno=%d (%s)\n",
2562                                                             err, sock_errstr(err, ebuf, sizeof(ebuf)) );
2563                                         }
2564 
2565                                         Debug(LDAP_DEBUG_ANY,
2566                                               "slapd_daemon_task: url=%s (#%d) SNDBUF original size=%d requested size=%d real size=%d\n",
2567                                               slap_listeners[l]->sl_url.bv_val, l,
2568                                               origsize, size, realsize );
2569                               }
2570                     }
2571 #endif /* LDAP_TCP_BUFFER */
2572 
2573                     if ( listen( SLAP_FD2SOCK( slap_listeners[l]->sl_sd ), SLAPD_LISTEN_BACKLOG ) == -1 ) {
2574                               int err = sock_errno();
2575 
2576 #ifdef LDAP_PF_INET6
2577                               /* If error is EADDRINUSE, we are trying to listen to INADDR_ANY and
2578                                * we are already listening to in6addr_any, then we want to ignore
2579                                * this and continue.
2580                                */
2581                               if ( err == EADDRINUSE ) {
2582                                         int i;
2583                                         struct sockaddr_in sa = slap_listeners[l]->sl_sa.sa_in_addr;
2584                                         struct sockaddr_in6 sa6;
2585 
2586                                         if ( sa.sin_family == AF_INET &&
2587                                              sa.sin_addr.s_addr == htonl(INADDR_ANY) ) {
2588                                                   for ( i = 0 ; i < l; i++ ) {
2589                                                             sa6 = slap_listeners[i]->sl_sa.sa_in6_addr;
2590                                                             if ( sa6.sin6_family == AF_INET6 &&
2591                                                                  !memcmp( &sa6.sin6_addr, &in6addr_any,
2592                                                                                 sizeof(struct in6_addr) ) )
2593                                                             {
2594                                                                       break;
2595                                                             }
2596                                                   }
2597 
2598                                                   if ( i < l ) {
2599                                                             /* We are already listening to in6addr_any */
2600                                                             Debug( LDAP_DEBUG_CONNS,
2601                                                                       "daemon: Attempt to listen to 0.0.0.0 failed, "
2602                                                                       "already listening on ::, assuming IPv4 included\n" );
2603                                                             slapd_close( slap_listeners[l]->sl_sd );
2604                                                             slap_listeners[l]->sl_sd = AC_SOCKET_INVALID;
2605                                                             continue;
2606                                                   }
2607                                         }
2608                               }
2609 #endif /* LDAP_PF_INET6 */
2610                               Debug( LDAP_DEBUG_ANY,
2611                                         "daemon: listen(%s, 5) failed errno=%d (%s)\n",
2612                                                   slap_listeners[l]->sl_url.bv_val, err,
2613                                                   sock_errstr(err, ebuf, sizeof(ebuf)) );
2614                               ldap_pvt_thread_mutex_lock( &slapd_init_mutex );
2615                               slapd_shutdown = 2;
2616                               ldap_pvt_thread_cond_signal( &slapd_init_cond );
2617                               ldap_pvt_thread_mutex_unlock( &slapd_init_mutex );
2618                               return (void*)-1;
2619                     }
2620 
2621                     /* make the listening socket non-blocking */
2622                     if ( ber_pvt_socket_set_nonblock( SLAP_FD2SOCK( slap_listeners[l]->sl_sd ), 1 ) < 0 ) {
2623                               Debug( LDAP_DEBUG_ANY, "slapd_daemon_task: "
2624                                         "set nonblocking on a listening socket failed\n" );
2625                               ldap_pvt_thread_mutex_lock( &slapd_init_mutex );
2626                               slapd_shutdown = 2;
2627                               ldap_pvt_thread_cond_signal( &slapd_init_cond );
2628                               ldap_pvt_thread_mutex_unlock( &slapd_init_mutex );
2629                               return (void*)-1;
2630                     }
2631 
2632                     slapd_add( slap_listeners[l]->sl_sd, 0, slap_listeners[l], -1 );
2633           }
2634 
2635           ldap_pvt_thread_mutex_lock( &slapd_init_mutex );
2636           slapd_ready = 1;
2637           ldap_pvt_thread_cond_signal( &slapd_init_cond );
2638           ldap_pvt_thread_mutex_unlock( &slapd_init_mutex );
2639 
2640 #ifdef HAVE_NT_SERVICE_MANAGER
2641           if ( started_event != NULL ) {
2642                     ldap_pvt_thread_cond_signal( &started_event );
2643           }
2644 #endif /* HAVE_NT_SERVICE_MANAGER */
2645 
2646 loop:
2647 
2648           /* initialization complete. Here comes the loop. */
2649 
2650           while ( !slapd_shutdown ) {
2651                     ber_socket_t                  i;
2652                     int                           ns, nwriters;
2653                     int                           at;
2654                     ber_socket_t                  nfds;
2655 #if SLAP_EVENTS_ARE_INDEXED
2656                     ber_socket_t                  nrfds, nwfds;
2657 #endif /* SLAP_EVENTS_ARE_INDEXED */
2658 #define SLAPD_EBADF_LIMIT 16
2659 
2660                     time_t                        now;
2661 
2662                     SLAP_EVENT_DECL;
2663 
2664                     struct timeval                tv;
2665                     struct timeval                *tvp;
2666 
2667                     struct timeval                cat;
2668                     time_t                        tdelta = 1;
2669                     struct re_s*                  rtask;
2670 
2671                     now = slap_get_time();
2672 
2673                     if ( !tid && ( global_idletimeout > 0 )) {
2674                               int check = 0;
2675                               /* Set the select timeout.
2676                                * Don't just truncate, preserve the fractions of
2677                                * seconds to prevent sleeping for zero time.
2678                                */
2679                               {
2680                                         tv.tv_sec = global_idletimeout / SLAPD_IDLE_CHECK_LIMIT;
2681                                         tv.tv_usec = global_idletimeout - \
2682                                                   ( tv.tv_sec * SLAPD_IDLE_CHECK_LIMIT );
2683                                         tv.tv_usec *= 1000000 / SLAPD_IDLE_CHECK_LIMIT;
2684                                         if ( difftime( last_idle_check +
2685                                                   global_idletimeout/SLAPD_IDLE_CHECK_LIMIT, now ) < 0 )
2686                                                   check = 1;
2687                               }
2688                               if ( check ) {
2689                                         connections_timeout_idle( now );
2690                                         last_idle_check = now;
2691                               }
2692                     } else {
2693                               tv.tv_sec = 0;
2694                               tv.tv_usec = 0;
2695                     }
2696 
2697 #ifdef SIGHUP
2698                     if ( slapd_gentle_shutdown ) {
2699                               ber_socket_t active;
2700 
2701                               if ( !tid && slapd_gentle_shutdown == 1 ) {
2702                                         BackendDB *be;
2703                                         Debug( LDAP_DEBUG_ANY, "slapd gentle shutdown\n" );
2704                                         close_listeners( 1 );
2705                                         frontendDB->be_restrictops |= SLAP_RESTRICT_OP_WRITES;
2706                                         LDAP_STAILQ_FOREACH(be, &backendDB, be_next) {
2707                                                   be->be_restrictops |= SLAP_RESTRICT_OP_WRITES;
2708                                         }
2709                                         slapd_gentle_shutdown = 2;
2710                               }
2711 
2712                               ldap_pvt_thread_mutex_lock( &slap_daemon[tid].sd_mutex );
2713                               active = slap_daemon[tid].sd_nactives;
2714                               ldap_pvt_thread_mutex_unlock( &slap_daemon[tid].sd_mutex );
2715 
2716                               if ( active == 0 ) {
2717                                         if ( !tid ) {
2718                                                   for ( l=1; l<slapd_daemon_threads; l++ ) {
2719                                                             ldap_pvt_thread_mutex_lock( &slap_daemon[l].sd_mutex );
2720                                                             active += slap_daemon[l].sd_nactives;
2721                                                             ldap_pvt_thread_mutex_unlock( &slap_daemon[l].sd_mutex );
2722                                                   }
2723                                                   if ( !active )
2724                                                             slapd_shutdown = 1;
2725                                         }
2726                                         if ( !active )
2727                                                   break;
2728                               }
2729                     }
2730 #endif /* SIGHUP */
2731                     at = 0;
2732 
2733                     ldap_pvt_thread_mutex_lock( &slap_daemon[tid].sd_mutex );
2734 
2735                     nwriters = slap_daemon[tid].sd_nwriters;
2736 
2737                     if ( listening )
2738                     for ( l = 0; slap_listeners[l] != NULL; l++ ) {
2739                               Listener *lr = slap_listeners[l];
2740 
2741                               if ( lr->sl_sd == AC_SOCKET_INVALID ) continue;
2742                               if ( DAEMON_ID( lr->sl_sd ) != tid ) continue;
2743                               if ( !SLAP_SOCK_IS_ACTIVE( tid, lr->sl_sd )) continue;
2744 
2745                               if ( lr->sl_mute || lr->sl_busy )
2746                               {
2747                                         SLAP_SOCK_CLR_READ( tid, lr->sl_sd );
2748                               } else {
2749                                         SLAP_SOCK_SET_READ( tid, lr->sl_sd );
2750                               }
2751                     }
2752 
2753                     SLAP_EVENT_INIT(tid);
2754 
2755                     nfds = SLAP_EVENT_MAX(tid);
2756 
2757                     if (( global_idletimeout ) && slap_daemon[tid].sd_nactives ) at = 1;
2758 
2759                     ldap_pvt_thread_mutex_unlock( &slap_daemon[tid].sd_mutex );
2760 
2761                     if ( at
2762 #if defined(HAVE_YIELDING_SELECT)
2763                               &&  ( tv.tv_sec || tv.tv_usec )
2764 #endif /* HAVE_YIELDING_SELECT */
2765                               )
2766                     {
2767                               tvp = &tv;
2768                     } else {
2769                               tvp = NULL;
2770                     }
2771 
2772                     /* Only thread 0 handles runqueue */
2773                     if ( !tid ) {
2774                               ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex );
2775                               rtask = ldap_pvt_runqueue_next_sched( &slapd_rq, &cat );
2776                               while ( rtask && cat.tv_sec && cat.tv_sec <= now ) {
2777                                         if ( ldap_pvt_runqueue_isrunning( &slapd_rq, rtask )) {
2778                                                   ldap_pvt_runqueue_resched( &slapd_rq, rtask, 0 );
2779                                         } else {
2780                                                   ldap_pvt_runqueue_runtask( &slapd_rq, rtask );
2781                                                   ldap_pvt_runqueue_resched( &slapd_rq, rtask, 0 );
2782                                                   ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex );
2783                                                   ldap_pvt_thread_pool_submit2( &connection_pool,
2784                                                             rtask->routine, (void *) rtask, &rtask->pool_cookie );
2785                                                   ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex );
2786                                         }
2787                                         rtask = ldap_pvt_runqueue_next_sched( &slapd_rq, &cat );
2788                               }
2789                               ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex );
2790 
2791                               if ( rtask && cat.tv_sec ) {
2792                                         /* NOTE: diff __should__ always be >= 0,
2793                                          * AFAI understand; however (ITS#4872),
2794                                          * time_t might be unsigned in some systems,
2795                                          * while difftime() returns a double */
2796                                         double diff = difftime( cat.tv_sec, now );
2797                                         if ( diff <= 0 ) {
2798                                                   diff = tdelta;
2799                                         }
2800                                         if ( tvp == NULL || diff < tv.tv_sec ) {
2801                                                   tv.tv_sec = diff;
2802                                                   tv.tv_usec = 0;
2803                                                   tvp = &tv;
2804                                         }
2805                               }
2806                     }
2807 
2808                     for ( l = 0; slap_listeners[l] != NULL; l++ ) {
2809                               Listener *lr = slap_listeners[l];
2810 
2811                               if ( lr->sl_sd == AC_SOCKET_INVALID ) {
2812                                         continue;
2813                               }
2814 
2815                               if ( DAEMON_ID( lr->sl_sd ) != tid ) continue;
2816 
2817                               if ( lr->sl_mute ) {
2818                                         Debug( LDAP_DEBUG_CONNS,
2819                                                   "daemon: " SLAP_EVENT_FNAME ": "
2820                                                   "listen=%d muted\n",
2821                                                   lr->sl_sd );
2822                                         continue;
2823                               }
2824 
2825                               if ( lr->sl_busy ) {
2826                                         Debug( LDAP_DEBUG_CONNS,
2827                                                   "daemon: " SLAP_EVENT_FNAME ": "
2828                                                   "listen=%d busy\n",
2829                                                   lr->sl_sd );
2830                                         continue;
2831                               }
2832 
2833                               Debug( LDAP_DEBUG_CONNS,
2834                                         "daemon: " SLAP_EVENT_FNAME ": "
2835                                         "listen=%d active_threads=%d tvp=%s\n",
2836                                         lr->sl_sd, at, tvp == NULL ? "NULL" : "zero" );
2837                     }
2838 
2839                     SLAP_EVENT_WAIT( tid, tvp, &ns );
2840                     switch ( ns ) {
2841                     case -1: {          /* failure - try again */
2842                                         int err = sock_errno();
2843 
2844                                         if ( err != EINTR ) {
2845                                                   ebadf++;
2846 
2847                                                   /* Don't log unless we got it twice in a row */
2848                                                   if ( !( ebadf & 1 ) ) {
2849                                                             Debug( LDAP_DEBUG_ANY,
2850                                                                       "daemon: "
2851                                                                       SLAP_EVENT_FNAME
2852                                                                       " failed count %d "
2853                                                                       "err (%d): %s\n",
2854                                                                       ebadf, err,
2855                                                                       sock_errstr( err, ebuf, sizeof(ebuf) ) );
2856                                                   }
2857                                                   if ( ebadf >= SLAPD_EBADF_LIMIT ) {
2858                                                             slapd_shutdown = 2;
2859                                                   }
2860                                         }
2861                               }
2862                               continue;
2863 
2864                     case 0:             /* timeout - let threads run */
2865                               ebadf = 0;
2866 #ifndef HAVE_YIELDING_SELECT
2867                               Debug( LDAP_DEBUG_CONNS, "daemon: " SLAP_EVENT_FNAME
2868                                         "timeout - yielding\n" );
2869 
2870                               ldap_pvt_thread_yield();
2871 #endif /* ! HAVE_YIELDING_SELECT */
2872                               continue;
2873 
2874                     default:  /* something happened - deal with it */
2875                               if ( slapd_shutdown ) continue;
2876 
2877                               ebadf = 0;
2878                               Debug( LDAP_DEBUG_CONNS,
2879                                         "daemon: activity on %d descriptor%s\n",
2880                                         ns, ns != 1 ? "s" : "" );
2881                               /* FALL THRU */
2882                     }
2883 
2884 #if SLAP_EVENTS_ARE_INDEXED
2885                     if ( SLAP_EVENT_IS_READ( wake_sds[tid][0] ) ) {
2886                               char c[BUFSIZ];
2887                               SLAP_EVENT_CLR_READ( wake_sds[tid][0] );
2888                               waking = 0;
2889                               tcp_read( SLAP_FD2SOCK(wake_sds[tid][0]), c, sizeof(c) );
2890                               Debug( LDAP_DEBUG_CONNS, "daemon: waked\n" );
2891                               continue;
2892                     }
2893 
2894                     /* The event slot equals the descriptor number - this is
2895                      * true for Unix select and poll. We treat Windows select
2896                      * like this too, even though it's a kludge.
2897                      */
2898                     if ( listening )
2899                     for ( l = 0; slap_listeners[l] != NULL; l++ ) {
2900                               int rc;
2901 
2902                               if ( ns <= 0 ) break;
2903                               if ( slap_listeners[l]->sl_sd == AC_SOCKET_INVALID ) continue;
2904                               if ( DAEMON_ID( slap_listeners[l]->sl_sd ) != tid ) continue;
2905 #ifdef LDAP_CONNECTIONLESS
2906                               if ( slap_listeners[l]->sl_is_udp ) continue;
2907 #endif /* LDAP_CONNECTIONLESS */
2908                               if ( !SLAP_EVENT_IS_READ( slap_listeners[l]->sl_sd ) ) continue;
2909 
2910                               /* clear events */
2911                               SLAP_EVENT_CLR_READ( slap_listeners[l]->sl_sd );
2912                               SLAP_EVENT_CLR_WRITE( slap_listeners[l]->sl_sd );
2913                               ns--;
2914 
2915                               rc = slap_listener_activate( slap_listeners[l] );
2916                     }
2917 
2918                     /* bypass the following tests if no descriptors left */
2919                     if ( ns <= 0 ) {
2920 #ifndef HAVE_YIELDING_SELECT
2921                               ldap_pvt_thread_yield();
2922 #endif /* HAVE_YIELDING_SELECT */
2923                               continue;
2924                     }
2925 
2926                     Debug( LDAP_DEBUG_CONNS, "daemon: activity on:" );
2927                     nrfds = 0;
2928                     nwfds = 0;
2929                     for ( i = 0; i < nfds; i++ ) {
2930                               int       r, w;
2931 
2932                               r = SLAP_EVENT_IS_READ( i );
2933                               /* writefds was not initialized if nwriters was zero */
2934                               w = nwriters ? SLAP_EVENT_IS_WRITE( i ) : 0;
2935                               if ( r || w ) {
2936                                         Debug( LDAP_DEBUG_CONNS, " %d%s%s", i,
2937                                             r ? "r" : "", w ? "w" : "" );
2938                                         if ( r ) {
2939                                                   nrfds++;
2940                                                   ns--;
2941                                         }
2942                                         if ( w ) {
2943                                                   nwfds++;
2944                                                   ns--;
2945                                         }
2946                               }
2947                               if ( ns <= 0 ) break;
2948                     }
2949                     Debug( LDAP_DEBUG_CONNS, "\n" );
2950 
2951                     /* loop through the writers */
2952                     for ( i = 0; nwfds > 0; i++ ) {
2953                               ber_socket_t wd;
2954                               if ( ! SLAP_EVENT_IS_WRITE( i ) ) continue;
2955                               wd = i;
2956 
2957                               SLAP_EVENT_CLR_WRITE( wd );
2958                               nwfds--;
2959 
2960                               Debug( LDAP_DEBUG_CONNS,
2961                                         "daemon: write active on %d\n",
2962                                         wd );
2963 
2964                               /*
2965                                * NOTE: it is possible that the connection was closed
2966                                * and that the stream is now inactive.
2967                                * connection_write() must validate the stream is still
2968                                * active.
2969                                *
2970                                * ITS#4338: if the stream is invalid, there is no need to
2971                                * close it here. It has already been closed in connection.c.
2972                                */
2973                               if ( connection_write( wd ) < 0 ) {
2974                                         if ( SLAP_EVENT_IS_READ( wd ) ) {
2975                                                   SLAP_EVENT_CLR_READ( (unsigned) wd );
2976                                                   nrfds--;
2977                                         }
2978                               }
2979                     }
2980 
2981                     for ( i = 0; nrfds > 0; i++ ) {
2982                               ber_socket_t rd;
2983                               if ( ! SLAP_EVENT_IS_READ( i ) ) continue;
2984                               rd = i;
2985                               SLAP_EVENT_CLR_READ( rd );
2986                               nrfds--;
2987 
2988                               Debug ( LDAP_DEBUG_CONNS,
2989                                         "daemon: read activity on %d\n", rd );
2990                               /*
2991                                * NOTE: it is possible that the connection was closed
2992                                * and that the stream is now inactive.
2993                                * connection_read() must valid the stream is still
2994                                * active.
2995                                */
2996 
2997                               connection_read_activate( rd );
2998                     }
2999 #else     /* !SLAP_EVENTS_ARE_INDEXED */
3000           /* FIXME */
3001           /* The events are returned in an arbitrary list. This is true
3002            * for /dev/poll, epoll and kqueue. In order to prioritize things
3003            * so that we can handle wake_sds first, listeners second, and then
3004            * all other connections last (as we do for select), we would need
3005            * to use multiple event handles and cascade them.
3006            *
3007            * That seems like a bit of hassle. So the wake_sds check has been
3008            * skipped. For epoll and kqueue we can associate arbitrary data with
3009            * an event, so we could use pointers to the listener structure
3010            * instead of just the file descriptor. For /dev/poll we have to
3011            * search the listeners array for a matching descriptor.
3012            *
3013            * We now handle wake events when we see them; they are not given
3014            * higher priority.
3015            */
3016 #ifdef LDAP_DEBUG
3017                     Debug( LDAP_DEBUG_CONNS, "daemon: activity on:" );
3018 
3019                     for ( i = 0; i < ns; i++ ) {
3020                               int       r, w, fd;
3021 
3022                               /* Don't log listener events */
3023                               if ( SLAP_EVENT_IS_LISTENER( tid, i )
3024 #ifdef LDAP_CONNECTIONLESS
3025                                         && !( (SLAP_EVENT_LISTENER( tid, i ))->sl_is_udp )
3026 #endif /* LDAP_CONNECTIONLESS */
3027                                         )
3028                               {
3029                                         continue;
3030                               }
3031 
3032                               fd = SLAP_EVENT_FD( tid, i );
3033                               /* Don't log internal wake events */
3034                               if ( fd == wake_sds[tid][0] ) continue;
3035 
3036 #ifdef HAVE_KQUEUE
3037                               r = SLAP_EVENT_IS_READ( tid, i );
3038                               w = SLAP_EVENT_IS_WRITE( tid, i );
3039 #else
3040                               r = SLAP_EVENT_IS_READ( i );
3041                               w = SLAP_EVENT_IS_WRITE( i );
3042 #endif /* HAVE_KQUEUE */
3043                               if ( r || w ) {
3044                                         Debug( LDAP_DEBUG_CONNS, " %d%s%s", fd,
3045                                             r ? "r" : "", w ? "w" : "" );
3046                               }
3047                     }
3048                     Debug( LDAP_DEBUG_CONNS, "\n" );
3049 #endif /* LDAP_DEBUG */
3050 
3051                     for ( i = 0; i < ns; i++ ) {
3052                               int rc = 1, fd, w = 0, r = 0;
3053 
3054                               if ( SLAP_EVENT_IS_LISTENER( tid, i ) ) {
3055                                         rc = slap_listener_activate( SLAP_EVENT_LISTENER( tid, i ) );
3056                               }
3057 
3058                               /* If we found a regular listener, rc is now zero, and we
3059                                * can skip the data portion. But if it was a UDP listener
3060                                * then rc is still 1, and we want to handle the data.
3061                                */
3062                               if ( rc ) {
3063                                         fd = SLAP_EVENT_FD( tid, i );
3064 
3065                                         /* Handle wake events */
3066                                         if ( fd == wake_sds[tid][0] ) {
3067                                                   char c[BUFSIZ];
3068                                                   waking = 0;
3069                                                   (void)!tcp_read( SLAP_FD2SOCK(wake_sds[tid][0]), c, sizeof(c) );
3070                                                   continue;
3071                                         }
3072 
3073 #ifdef HAVE_KQUEUE
3074                                         if ( SLAP_EVENT_IS_WRITE( tid, i ) )
3075 #else
3076                                         if ( SLAP_EVENT_IS_WRITE( i ) )
3077 #endif  /* HAVE_KQUEUE */
3078                                         {
3079                                                   Debug( LDAP_DEBUG_CONNS,
3080                                                             "daemon: write active on %d\n",
3081                                                             fd );
3082 
3083                                                   SLAP_EVENT_CLR_WRITE( i );
3084                                                   w = 1;
3085 
3086                                                   /*
3087                                                    * NOTE: it is possible that the connection was closed
3088                                                    * and that the stream is now inactive.
3089                                                    * connection_write() must valid the stream is still
3090                                                    * active.
3091                                                    */
3092                                                   if ( connection_write( fd ) < 0 ) {
3093                                                             continue;
3094                                                   }
3095                                         }
3096                                         /* If event is a read */
3097 #ifdef HAVE_KQUEUE
3098                                         if ( SLAP_EVENT_IS_READ( tid, i ))
3099 #else
3100                                         if ( SLAP_EVENT_IS_READ( i ))
3101 #endif /* HAVE_KQUEUE */
3102                                         {
3103                                                   r = 1;
3104                                                   Debug( LDAP_DEBUG_CONNS,
3105                                                             "daemon: read active on %d\n",
3106                                                             fd );
3107 
3108                                                   SLAP_EVENT_CLR_READ( i );
3109                                                   connection_read_activate( fd );
3110                                         } else if ( !w ) {
3111 #ifdef HAVE_EPOLL
3112                                                   /* Don't keep reporting the hangup
3113                                                    */
3114                                                   if ( SLAP_SOCK_IS_ACTIVE( tid, fd )) {
3115                                                             SLAP_EPOLL_SOCK_SET( tid, fd, EPOLLET );
3116                                                   }
3117 #endif
3118                                         }
3119                               }
3120                     }
3121 #endif    /* SLAP_EVENTS_ARE_INDEXED */
3122 
3123                     /* Was number of listener threads decreased? */
3124                     if ( ldap_pvt_thread_pool_pausecheck_native( &connection_pool )) {
3125                               /* decreased, let this thread finish */
3126                               if ( tid >= slapd_daemon_threads )
3127                                         break;
3128                     }
3129 
3130 #ifndef HAVE_YIELDING_SELECT
3131                     ldap_pvt_thread_yield();
3132 #endif /* ! HAVE_YIELDING_SELECT */
3133           }
3134 
3135           /* Only thread 0 handles shutdown */
3136           if ( tid )
3137                     return NULL;
3138 
3139           if ( slapd_shutdown == 1 ) {
3140                     Debug( LDAP_DEBUG_ANY,
3141                               "daemon: shutdown requested and initiated.\n" );
3142 
3143           } else if ( slapd_shutdown == 2 ) {
3144 #ifdef HAVE_NT_SERVICE_MANAGER
3145                               Debug( LDAP_DEBUG_ANY,
3146                                      "daemon: shutdown initiated by Service Manager.\n" );
3147 #else /* !HAVE_NT_SERVICE_MANAGER */
3148                               Debug( LDAP_DEBUG_ANY,
3149                                      "daemon: abnormal condition, shutdown initiated.\n" );
3150 #endif /* !HAVE_NT_SERVICE_MANAGER */
3151           } else {
3152                     Debug( LDAP_DEBUG_ANY,
3153                            "daemon: no active streams, shutdown initiated.\n" );
3154           }
3155 
3156           close_listeners( 1 );
3157 
3158           if ( !slapd_gentle_shutdown ) {
3159                     slapd_abrupt_shutdown = 1;
3160                     connections_shutdown();
3161           }
3162 
3163 #ifdef HAVE_KQUEUE
3164      close( slap_daemon[tid].sd_kq );
3165 #endif
3166 
3167           if ( LogTest( LDAP_DEBUG_ANY )) {
3168                     int t = ldap_pvt_thread_pool_backload( &connection_pool );
3169                     Debug( LDAP_DEBUG_ANY,
3170                               "slapd shutdown: waiting for %d operations/tasks to finish\n",
3171                               t );
3172           }
3173           ldap_pvt_thread_pool_close( &connection_pool, 1 );
3174 
3175           return NULL;
3176 }
3177 
3178 typedef struct slap_tid_waiter {
3179           int num_tids;
3180           ldap_pvt_thread_t tids[0];
3181 } slap_tid_waiter;
3182 
3183 static void *
slapd_daemon_tid_cleanup(void * ctx,void * ptr)3184 slapd_daemon_tid_cleanup(
3185           void *ctx,
3186           void *ptr )
3187 {
3188           slap_tid_waiter *tids = ptr;
3189           int i;
3190 
3191           for ( i=0; i<tids->num_tids; i++ )
3192                     ldap_pvt_thread_join( tids->tids[i], (void *)NULL );
3193           ch_free( ptr );
3194           return NULL;
3195 }
3196 
3197 int
slapd_daemon_resize(int newnum)3198 slapd_daemon_resize( int newnum )
3199 {
3200           int i, rc;
3201 
3202           if ( newnum == slapd_daemon_threads )
3203                     return 0;
3204 
3205           /* wake up all current listener threads */
3206           for ( i=0; i<slapd_daemon_threads; i++ )
3207                     WAKE_LISTENER(i,1);
3208 
3209           /* mutexes may not survive realloc, so destroy & recreate later */
3210           for ( i=0; i<slapd_daemon_threads; i++ )
3211                     ldap_pvt_thread_mutex_destroy( &slap_daemon[i].sd_mutex );
3212 
3213           if ( newnum > slapd_daemon_threads ) {
3214                     wake_sds = ch_realloc( wake_sds, newnum * sizeof( sdpair ));
3215                     slap_daemon = ch_realloc( slap_daemon, newnum * sizeof( slap_daemon_st ));
3216 
3217                     for ( i=slapd_daemon_threads; i<newnum; i++ )
3218                     {
3219                               memset( &slap_daemon[i], 0, sizeof( slap_daemon_st ));
3220                               if( (rc = lutil_pair( wake_sds[i] )) < 0 ) {
3221                                         Debug( LDAP_DEBUG_ANY,
3222                                                   "daemon: lutil_pair() failed rc=%d\n", rc );
3223                                         return rc;
3224                               }
3225                               ber_pvt_socket_set_nonblock( wake_sds[i][1], 1 );
3226 
3227                               SLAP_SOCK_INIT(i);
3228                     }
3229 
3230                     for ( i=0; i<newnum; i++ )
3231                               ldap_pvt_thread_mutex_init( &slap_daemon[i].sd_mutex );
3232 
3233                     slapd_socket_realloc( newnum );
3234 
3235                     for ( i=slapd_daemon_threads; i<newnum; i++ )
3236                     {
3237                               /* listener as a separate THREAD */
3238                               rc = ldap_pvt_thread_create( &slap_daemon[i].sd_tid,
3239                                         0, slapd_daemon_task, &slap_daemon[i] );
3240 
3241                               if ( rc != 0 ) {
3242                                         Debug( LDAP_DEBUG_ANY,
3243                                         "listener ldap_pvt_thread_create failed (%d)\n", rc );
3244                                         return rc;
3245                               }
3246                     }
3247           } else {
3248                     int j;
3249                     slap_tid_waiter *tids = ch_malloc( sizeof(slap_tid_waiter) +
3250                               ((slapd_daemon_threads - newnum) * sizeof(ldap_pvt_thread_t )));
3251                     slapd_socket_realloc( newnum );
3252                     tids->num_tids = slapd_daemon_threads - newnum;
3253                     for ( i=newnum, j=0; i<slapd_daemon_threads; i++, j++ ) {
3254                               tids->tids[j] = slap_daemon[i].sd_tid;
3255 #ifdef HAVE_WINSOCK
3256                               if ( wake_sds[i][1] != INVALID_SOCKET &&
3257                                         SLAP_FD2SOCK( wake_sds[i][1] ) != SLAP_FD2SOCK( wake_sds[i][0] ))
3258 #endif /* HAVE_WINSOCK */
3259                                         tcp_close( SLAP_FD2SOCK(wake_sds[i][1]) );
3260 #ifdef HAVE_WINSOCK
3261                               if ( wake_sds[i][0] != INVALID_SOCKET )
3262 #endif /* HAVE_WINSOCK */
3263                                         tcp_close( SLAP_FD2SOCK(wake_sds[i][0]) );
3264 
3265                               SLAP_SOCK_DESTROY( i );
3266                     }
3267 
3268                     wake_sds = ch_realloc( wake_sds, newnum * sizeof( sdpair ));
3269                     slap_daemon = ch_realloc( slap_daemon, newnum * sizeof( slap_daemon_st ));
3270                     for ( i=0; i<newnum; i++ )
3271                               ldap_pvt_thread_mutex_init( &slap_daemon[i].sd_mutex );
3272                     ldap_pvt_thread_pool_submit( &connection_pool,
3273                               slapd_daemon_tid_cleanup, (void *) tids );
3274           }
3275           slapd_daemon_threads = newnum;
3276           slapd_daemon_mask = newnum - 1;
3277           return 0;
3278 }
3279 
3280 #ifdef LDAP_CONNECTIONLESS
3281 static int
connectionless_init(void)3282 connectionless_init( void )
3283 {
3284           int l;
3285 
3286           for ( l = 0; slap_listeners[l] != NULL; l++ ) {
3287                     Listener *lr = slap_listeners[l];
3288                     Connection *c;
3289 
3290                     if ( !lr->sl_is_udp ) {
3291                               continue;
3292                     }
3293 
3294                     c = connection_init( lr->sl_sd, lr, "", "",
3295                               CONN_IS_UDP, (slap_ssf_t) 0, NULL
3296                               LDAP_PF_LOCAL_SENDMSG_ARG(NULL));
3297 
3298                     if ( !c ) {
3299                               Debug( LDAP_DEBUG_TRACE,
3300                                         "connectionless_init: failed on %s (%d)\n",
3301                                         lr->sl_url.bv_val, lr->sl_sd );
3302                               return -1;
3303                     }
3304                     lr->sl_is_udp++;
3305           }
3306 
3307           return 0;
3308 }
3309 #endif /* LDAP_CONNECTIONLESS */
3310 
3311 int
slapd_daemon(void)3312 slapd_daemon( void )
3313 {
3314           int i, rc;
3315 
3316 #ifdef LDAP_CONNECTIONLESS
3317           connectionless_init();
3318 #endif /* LDAP_CONNECTIONLESS */
3319 
3320           SLAP_SOCK_INIT2();
3321 
3322           /* daemon_init only inits element 0 */
3323           for ( i=1; i<slapd_daemon_threads; i++ )
3324           {
3325                     ldap_pvt_thread_mutex_init( &slap_daemon[i].sd_mutex );
3326 
3327                     if( (rc = lutil_pair( wake_sds[i] )) < 0 ) {
3328                               Debug( LDAP_DEBUG_ANY,
3329                                         "daemon: lutil_pair() failed rc=%d\n", rc );
3330                               return rc;
3331                     }
3332                     ber_pvt_socket_set_nonblock( wake_sds[i][1], 1 );
3333 
3334                     SLAP_SOCK_INIT(i);
3335           }
3336 
3337           for ( i=0; i<slapd_daemon_threads; i++ )
3338           {
3339                     /* listener as a separate THREAD */
3340                     rc = ldap_pvt_thread_create( &slap_daemon[i].sd_tid,
3341                               0, slapd_daemon_task, &slap_daemon[i] );
3342 
3343                     if ( rc != 0 ) {
3344                               Debug( LDAP_DEBUG_ANY,
3345                               "listener ldap_pvt_thread_create failed (%d)\n", rc );
3346                               return rc;
3347                     }
3348           }
3349 
3350           ldap_pvt_thread_mutex_lock( &slapd_init_mutex );
3351           while ( !slapd_ready && !slapd_shutdown ) {
3352                     ldap_pvt_thread_cond_wait( &slapd_init_cond, &slapd_init_mutex );
3353           }
3354           ldap_pvt_thread_mutex_unlock( &slapd_init_mutex );
3355 
3356           if ( slapd_shutdown ) {
3357                     Debug( LDAP_DEBUG_ANY,
3358                               "listener initialization failed\n" );
3359                     return 1;
3360           }
3361 
3362 #ifdef HAVE_SYSTEMD
3363           rc = sd_notify( 1, "READY=1" );
3364           if ( rc < 0 ) {
3365                     Debug( LDAP_DEBUG_ANY,
3366                               "systemd sd_notify failed (%d)\n", rc );
3367           }
3368 #endif /* HAVE_SYSTEMD */
3369 
3370           /* wait for the listener threads to complete */
3371           for ( i=0; i<slapd_daemon_threads; i++ )
3372                     ldap_pvt_thread_join( slap_daemon[i].sd_tid, (void *)NULL );
3373 
3374           destroy_listeners();
3375 
3376           return 0;
3377 }
3378 
3379 static int
sockinit(void)3380 sockinit( void )
3381 {
3382 #if defined( HAVE_WINSOCK2 )
3383           WORD wVersionRequested;
3384           WSADATA wsaData;
3385           int err;
3386 
3387           wVersionRequested = MAKEWORD( 2, 0 );
3388 
3389           err = WSAStartup( wVersionRequested, &wsaData );
3390           if ( err != 0 ) {
3391                     /* Tell the user that we couldn't find a usable */
3392                     /* WinSock DLL.                                              */
3393                     return -1;
3394           }
3395 
3396           /* Confirm that the WinSock DLL supports 2.0.*/
3397           /* Note that if the DLL supports versions greater    */
3398           /* than 2.0 in addition to 2.0, it will still return */
3399           /* 2.0 in wVersion since that is the version we        */
3400           /* requested.                                                    */
3401 
3402           if ( LOBYTE( wsaData.wVersion ) != 2 ||
3403                     HIBYTE( wsaData.wVersion ) != 0 )
3404           {
3405               /* Tell the user that we couldn't find a usable */
3406               /* WinSock DLL.                                    */
3407               WSACleanup();
3408               return -1;
3409           }
3410 
3411           /* The WinSock DLL is acceptable. Proceed. */
3412 #elif defined( HAVE_WINSOCK )
3413           WSADATA wsaData;
3414           if ( WSAStartup( 0x0101, &wsaData ) != 0 ) return -1;
3415 #endif /* ! HAVE_WINSOCK2 && ! HAVE_WINSOCK */
3416 
3417           return 0;
3418 }
3419 
3420 static int
sockdestroy(void)3421 sockdestroy( void )
3422 {
3423 #if defined( HAVE_WINSOCK2 ) || defined( HAVE_WINSOCK )
3424           WSACleanup();
3425 #endif /* HAVE_WINSOCK2 || HAVE_WINSOCK */
3426 
3427           return 0;
3428 }
3429 
3430 RETSIGTYPE
slap_sig_shutdown(int sig)3431 slap_sig_shutdown( int sig )
3432 {
3433           int save_errno = errno;
3434           int i;
3435 
3436 #if 0
3437           Debug(LDAP_DEBUG_TRACE, "slap_sig_shutdown: signal %d\n", sig);
3438 #endif
3439 
3440           /*
3441            * If the NT Service Manager is controlling the server, we don't
3442            * want SIGBREAK to kill the server. For some strange reason,
3443            * SIGBREAK is generated when a user logs out.
3444            */
3445 
3446 #if defined(HAVE_NT_SERVICE_MANAGER) && defined(SIGBREAK)
3447           if (is_NT_Service && sig == SIGBREAK) {
3448                     /* empty */;
3449           } else
3450 #endif /* HAVE_NT_SERVICE_MANAGER && SIGBREAK */
3451 #ifdef SIGHUP
3452           if (sig == SIGHUP && global_gentlehup && slapd_gentle_shutdown == 0) {
3453                     slapd_gentle_shutdown = 1;
3454           } else
3455 #endif /* SIGHUP */
3456           {
3457                     slapd_shutdown = 1;
3458           }
3459 
3460           for (i=0; i<slapd_daemon_threads; i++) {
3461                     WAKE_LISTENER(i,1);
3462           }
3463 
3464           /* reinstall self */
3465           (void) SIGNAL_REINSTALL( sig, slap_sig_shutdown );
3466 
3467           errno = save_errno;
3468 }
3469 
3470 RETSIGTYPE
slap_sig_wake(int sig)3471 slap_sig_wake( int sig )
3472 {
3473           int save_errno = errno;
3474 
3475           WAKE_LISTENER(0,1);
3476 
3477           /* reinstall self */
3478           (void) SIGNAL_REINSTALL( sig, slap_sig_wake );
3479 
3480           errno = save_errno;
3481 }
3482 
3483 int
slap_pause_server(void)3484 slap_pause_server( void )
3485 {
3486           BackendInfo *bi;
3487           int rc = LDAP_SUCCESS;
3488 
3489           rc = ldap_pvt_thread_pool_pause( &connection_pool );
3490 
3491           LDAP_STAILQ_FOREACH(bi, &backendInfo, bi_next) {
3492                     if ( bi->bi_pause ) {
3493                               rc = bi->bi_pause( bi );
3494                               if ( rc != LDAP_SUCCESS ) {
3495                                         Debug( LDAP_DEBUG_ANY, "slap_pause_server: "
3496                                                             "bi_pause failed for backend %s\n",
3497                                                             bi->bi_type );
3498                                         return rc;
3499                               }
3500                     }
3501           }
3502 
3503           return rc;
3504 }
3505 
3506 int
slap_unpause_server(void)3507 slap_unpause_server( void )
3508 {
3509           BackendInfo *bi;
3510           int rc = LDAP_SUCCESS;
3511 
3512           LDAP_STAILQ_FOREACH(bi, &backendInfo, bi_next) {
3513                     if ( bi->bi_unpause ) {
3514                               rc = bi->bi_unpause( bi );
3515                               if ( rc != LDAP_SUCCESS ) {
3516                                         Debug( LDAP_DEBUG_ANY, "slap_unpause_server: "
3517                                                             "bi_unpause failed for backend %s\n",
3518                                                             bi->bi_type );
3519                                         return rc;
3520                               }
3521                     }
3522           }
3523 
3524           rc = ldap_pvt_thread_pool_resume( &connection_pool );
3525           return rc;
3526 }
3527 
3528 
3529 void
slapd_add_internal(ber_socket_t s,int isactive)3530 slapd_add_internal( ber_socket_t s, int isactive )
3531 {
3532           if (!isactive) {
3533                     SET_CLOSE(s);
3534           }
3535           slapd_add( s, isactive, NULL, -1 );
3536 }
3537 
3538 Listener **
slapd_get_listeners(void)3539 slapd_get_listeners( void )
3540 {
3541           /* Could return array with no listeners if !listening, but current
3542            * callers mostly look at the URLs.  E.g. syncrepl uses this to
3543            * identify the server, which means it wants the startup arguments.
3544            */
3545           return slap_listeners;
3546 }
3547 
3548 /* Reject all incoming requests */
3549 void
slap_suspend_listeners(void)3550 slap_suspend_listeners( void )
3551 {
3552           int i;
3553           for (i=0; slap_listeners[i]; i++) {
3554                     slap_listeners[i]->sl_mute = 1;
3555                     listen( slap_listeners[i]->sl_sd, 0 );
3556           }
3557 }
3558 
3559 /* Resume after a suspend */
3560 void
slap_resume_listeners(void)3561 slap_resume_listeners( void )
3562 {
3563           int i;
3564           for (i=0; slap_listeners[i]; i++) {
3565                     slap_listeners[i]->sl_mute = 0;
3566                     listen( slap_listeners[i]->sl_sd, SLAPD_LISTEN_BACKLOG );
3567           }
3568 }
3569 
3570 void
slap_wake_listener()3571 slap_wake_listener()
3572 {
3573           WAKE_LISTENER(0,1);
3574 }
3575 
3576 /* return 0 on timeout, 1 on writer ready
3577  * -1 on general error
3578  */
3579 int
slapd_wait_writer(ber_socket_t sd)3580 slapd_wait_writer( ber_socket_t sd )
3581 {
3582 #ifdef HAVE_WINSOCK
3583           fd_set writefds;
3584           struct timeval tv, *tvp;
3585 
3586           FD_ZERO( &writefds );
3587           FD_SET( slapd_ws_sockets[sd], &writefds );
3588           if ( global_writetimeout ) {
3589                     tv.tv_sec = global_writetimeout;
3590                     tv.tv_usec = 0;
3591                     tvp = &tv;
3592           } else {
3593                     tvp = NULL;
3594           }
3595           return select( 0, NULL, &writefds, NULL, tvp );
3596 #else
3597           struct pollfd fds;
3598           int timeout = global_writetimeout ? global_writetimeout * 1000 : -1;
3599 
3600           fds.fd = sd;
3601           fds.events = POLLOUT;
3602 
3603           return poll( &fds, 1, timeout );
3604 #endif
3605 }
3606