]> git.sur5r.net Git - openldap/blob - servers/slapd/daemon.c
0f8700c94811f69ee1c732589ada4f5936dcb693
[openldap] / servers / slapd / daemon.c
1 /* $OpenLDAP$ */
2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
3  *
4  * Copyright 1998-2005 The OpenLDAP Foundation.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted only as authorized by the OpenLDAP
9  * Public License.
10  *
11  * A copy of this license is available in the file LICENSE in the
12  * top-level directory of the distribution or, alternatively, at
13  * <http://www.OpenLDAP.org/license.html>.
14  */
15 /* Portions Copyright (c) 1995 Regents of the University of Michigan.
16  * All rights reserved.
17  *
18  * Redistribution and use in source and binary forms are permitted
19  * provided that this notice is preserved and that due credit is given
20  * to the University of Michigan at Ann Arbor. The name of the University
21  * may not be used to endorse or promote products derived from this
22  * software without specific prior written permission. This software
23  * is provided ``as is'' without express or implied warranty.
24  */
25
26 #include "portable.h"
27
28 #include <stdio.h>
29
30 #include <ac/ctype.h>
31 #include <ac/errno.h>
32 #include <ac/socket.h>
33 #include <ac/string.h>
34 #include <ac/time.h>
35 #include <ac/unistd.h>
36
37 #include "slap.h"
38 #include "ldap_pvt_thread.h"
39 #include "lutil.h"
40
41 #include "ldap_rq.h"
42
43 #if defined(HAVE_SYS_EPOLL_H) && defined(HAVE_EPOLL)
44 #include <sys/epoll.h>
45 #endif
46
47 #ifdef HAVE_TCPD
48 #include <tcpd.h>
49 int allow_severity = LOG_INFO;
50 int deny_severity = LOG_NOTICE;
51
52 #define SLAP_STRING_UNKNOWN     STRING_UNKNOWN
53 #else /* ! TCP Wrappers */
54 #define SLAP_STRING_UNKNOWN     "unknown"
55 #endif /* ! TCP Wrappers */
56
57 #ifdef LDAP_PF_LOCAL
58 #include <sys/stat.h>
59 /* this should go in <ldap.h> as soon as it is accepted */
60 #define LDAPI_MOD_URLEXT                "x-mod"
61 #endif /* LDAP_PF_LOCAL */
62
63 #ifdef LDAP_PF_INET6
64 int slap_inet4or6 = AF_UNSPEC;
65 #else
66 int slap_inet4or6 = AF_INET;
67 #endif
68
69 /* globals */
70 time_t starttime;
71 ber_socket_t dtblsize;
72 slap_ssf_t local_ssf = LDAP_PVT_SASL_LOCAL_SSF;
73 struct runqueue_s slapd_rq;
74
75 Listener **slap_listeners = NULL;
76
77 #ifndef SLAPD_LISTEN_BACKLOG
78 #define SLAPD_LISTEN_BACKLOG 1024
79 #endif
80
81 static ber_socket_t wake_sds[2];
82 static int emfile;
83
84 static int waking;
85 #define WAKE_LISTENER(w)        do { \
86         if ((w) && waking < 5) { \
87                 waking++; \
88                 tcp_write( wake_sds[1], "0", 1 ); \
89         } \
90 } while(0)
91
92 volatile sig_atomic_t slapd_shutdown = 0, slapd_gentle_shutdown = 0;
93 volatile sig_atomic_t slapd_abrupt_shutdown = 0;
94
95 static struct slap_daemon {
96         ldap_pvt_thread_mutex_t sd_mutex;
97
98         ber_socket_t sd_nactives;
99         int sd_nwriters;
100
101 #ifdef HAVE_EPOLL
102         struct epoll_event *sd_epolls;
103         int     sd_nepolls;
104         int     *sd_index;
105         int     sd_epfd;
106         int     sd_nfds;
107 # ifdef SLAP_LIGHTWEIGHT_LISTENER
108         int *sd_suspend;  /* 0: suspended, 1: not suspended */
109 # endif
110
111 #else
112 #ifndef HAVE_WINSOCK
113         /* In winsock, accept() returns values higher than dtblsize
114                 so don't bother with this optimization */
115         int sd_nfds;
116 #endif
117         fd_set sd_actives;
118         fd_set sd_readers;
119         fd_set sd_writers;
120 # ifdef SLAP_LIGHTWEIGHT_LISTENER
121         fd_set sd_suspend;  /* unset: suspended, set: not suspended */
122 # endif
123 #endif
124 } slap_daemon;
125
126 #ifdef HAVE_EPOLL
127 # define SLAP_EVENTS_ARE_INDEXED        0
128 # define SLAP_SOCK_IX(s)        (slap_daemon.sd_index[(s)])
129 # define SLAP_SOCK_EP(s)        (slap_daemon.sd_epolls[SLAP_SOCK_IX(s)])
130 # define SLAP_SOCK_EV(s)        (SLAP_SOCK_EP(s).events)
131 # define SLAP_SOCK_IS_ACTIVE(s) (SLAP_SOCK_IX(s) != -1)
132 # define SLAP_SOCK_NOT_ACTIVE(s)        (SLAP_SOCK_IX(s) == -1)
133 # define SLAP_SOCK_IS_SET(s, mode)      (SLAP_SOCK_EV(s) & (mode))
134
135 # define SLAP_SOCK_IS_READ(s)   SLAP_SOCK_IS_SET((s), EPOLLIN)
136 # define SLAP_SOCK_IS_WRITE(s)  SLAP_SOCK_IS_SET((s), EPOLLOUT)
137
138 # define SLAP_SET_SOCK(s, mode) do { \
139         if ((SLAP_SOCK_EV(s) & (mode)) != (mode)) {     \
140                 SLAP_SOCK_EV(s) |= (mode); \
141                 epoll_ctl(slap_daemon.sd_epfd, EPOLL_CTL_MOD, (s), \
142                         &SLAP_SOCK_EP(s)); \
143         } \
144 } while(0)
145
146 # define SLAP_CLR_SOCK(s, mode) do { \
147         if ((SLAP_SOCK_EV(s) & (mode))) { \
148                 SLAP_SOCK_EV(s) &= ~(mode);     \
149                 epoll_ctl(slap_daemon.sd_epfd, EPOLL_CTL_MOD, s, \
150                         &SLAP_SOCK_EP(s)); \
151         } \
152 } while(0)
153
154 # define SLAP_SOCK_SET_READ(s)  SLAP_SET_SOCK(s, EPOLLIN)
155 # define SLAP_SOCK_SET_WRITE(s) SLAP_SET_SOCK(s, EPOLLOUT)
156
157 # ifdef SLAP_LIGHTWEIGHT_LISTENER
158 #  define SLAP_SOCK_SET_SUSPEND(s) \
159         ( slap_daemon.sd_suspend[SLAP_SOCK_IX(s)] = 1 )
160 #  define SLAP_SOCK_CLR_SUSPEND(s) \
161         ( slap_daemon.sd_suspend[SLAP_SOCK_IX(s)] = 0 )
162 #  define SLAP_SOCK_IS_SUSPEND(s) \
163         ( slap_daemon.sd_suspend[SLAP_SOCK_IX(s)] == 1 )
164 # endif
165
166 # define SLAP_SOCK_CLR_READ(s)  SLAP_CLR_SOCK((s), EPOLLIN)
167 # define SLAP_SOCK_CLR_WRITE(s) SLAP_CLR_SOCK((s), EPOLLOUT)
168
169 # define SLAP_CLR_EVENT(i, mode)        (revents[(i)].events &= ~(mode))
170
171 # define SLAP_EVENT_MAX slap_daemon.sd_nfds
172
173 /* If a Listener address is provided, store that as the epoll data.
174  * Otherwise, store the address of this socket's slot in the
175  * index array. If we can't do this add, the system is out of
176  * resources and we need to shutdown.
177  */
178 # define SLAP_ADD_SOCK(s, l) do { \
179         int rc; \
180         SLAP_SOCK_IX((s)) = slap_daemon.sd_nfds; \
181         SLAP_SOCK_EP((s)).data.ptr = (l) ? (l) : (void *)(&SLAP_SOCK_IX(s)); \
182         SLAP_SOCK_EV((s)) = EPOLLIN; \
183         rc = epoll_ctl(slap_daemon.sd_epfd, EPOLL_CTL_ADD, \
184                 (s), &SLAP_SOCK_EP((s))); \
185         if ( rc == 0 ) { \
186                 slap_daemon.sd_nfds++; \
187         } else { \
188                 Debug( LDAP_DEBUG_ANY, \
189                         "daemon: epoll_ctl ADD failed, errno %d, shutting down\n", \
190                         errno, 0, 0 ); \
191                 slapd_shutdown = 2; \
192         } \
193 } while (0)
194
195 # define SLAP_EV_LISTENER(ptr) (((int *)(ptr) >= slap_daemon.sd_index && \
196         (int *)(ptr) <= (slap_daemon.sd_index+dtblsize)) ? 0 : 1 )
197
198 # define SLAP_EV_PTRFD(ptr) (SLAP_EV_LISTENER(ptr) ? \
199         ((Listener *)ptr)->sl_sd : (int *)(ptr) - slap_daemon.sd_index)
200
201 # ifdef SLAP_LIGHTWEIGHT_LISTENER
202 #  define SLAP_DEL_SOCK(s) do { \
203         int fd, rc, suspend, index = SLAP_SOCK_IX((s)); \
204         rc = epoll_ctl(slap_daemon.sd_epfd, EPOLL_CTL_DEL, \
205                 (s), &SLAP_SOCK_EP((s))); \
206         slap_daemon.sd_epolls[index] = \
207                 slap_daemon.sd_epolls[slap_daemon.sd_nfds-1]; \
208         fd = SLAP_EV_PTRFD(slap_daemon.sd_epolls[index].data.ptr); \
209         slap_daemon.sd_suspend[index] = \
210                 slap_daemon.sd_suspend[slap_daemon.sd_nfds-1]; \
211         slap_daemon.sd_suspend[slap_daemon.sd_nfds-1] = 0; \
212         slap_daemon.sd_index[fd] = index; \
213         slap_daemon.sd_index[(s)] = -1; \
214         slap_daemon.sd_nfds--; \
215 } while (0)
216 # else
217 #  define SLAP_DEL_SOCK(s) do { \
218         int fd, rc, index = SLAP_SOCK_IX((s)); \
219         rc = epoll_ctl(slap_daemon.sd_epfd, EPOLL_CTL_DEL, \
220                 (s), &SLAP_SOCK_EP((s))); \
221         slap_daemon.sd_epolls[index] = \
222                 slap_daemon.sd_epolls[slap_daemon.sd_nfds-1]; \
223         fd = SLAP_EV_PTRFD(slap_daemon.sd_epolls[index].data.ptr); \
224         slap_daemon.sd_index[fd] = index; \
225         slap_daemon.sd_index[(s)] = -1; \
226         slap_daemon.sd_nfds--; \
227 } while (0)
228 # endif
229
230 # define SLAP_EVENT_CLR_READ(i) SLAP_CLR_EVENT((i), EPOLLIN)
231 # define SLAP_EVENT_CLR_WRITE(i)        SLAP_CLR_EVENT((i), EPOLLOUT)
232
233 # define SLAP_CHK_EVENT(i, mode)        (revents[(i)].events & mode)
234
235 # define SLAP_EVENT_IS_READ(i)  SLAP_CHK_EVENT((i), EPOLLIN)
236 # define SLAP_EVENT_IS_WRITE(i) SLAP_CHK_EVENT((i), EPOLLOUT)
237 # define SLAP_EVENT_IS_LISTENER(i)      SLAP_EV_LISTENER(revents[(i)].data.ptr)
238 # define SLAP_EVENT_LISTENER(i) (revents[(i)].data.ptr)
239
240 # define SLAP_EVENT_FD(i)       SLAP_EV_PTRFD(revents[(i)].data.ptr)
241 # define SLAP_SOCK_SET_MUTE(s)  SLAP_SOCK_CLR_READ((s))
242 # define SLAP_SOCK_CLR_MUTE(s)  SLAP_SOCK_SET_READ((s))
243 # define SLAP_SOCK_IS_MUTE(s)   (!SLAP_SOCK_IS_READ((s)))
244
245 # ifdef SLAP_LIGHTWEIGHT_LISTENER
246 #  define SLAP_SOCK_SET_INIT do { \
247         slap_daemon.sd_epolls = \
248                 ch_malloc( sizeof(struct epoll_event) * dtblsize * 2 ); \
249         slap_daemon.sd_index = ch_malloc(sizeof(int) * dtblsize); \
250         slap_daemon.sd_epfd = epoll_create( dtblsize ); \
251         for (i=0; i<dtblsize; i++) slap_daemon.sd_index[i] = -1; \
252         slap_daemon.sd_suspend = ch_malloc(sizeof(int) * dtblsize); \
253         for (i=0; i<dtblsize; i++) slap_daemon.sd_suspend[i] = 0; \
254 } while (0)
255 # else
256 #  define SLAP_SOCK_SET_INIT do { \
257         slap_daemon.sd_epolls = ch_calloc(1, \
258                 sizeof(struct epoll_event) * dtblsize * 2); \
259         slap_daemon.sd_index = ch_malloc(sizeof(int) * dtblsize); \
260         slap_daemon.sd_epfd = epoll_create( dtblsize ); \
261         for (i=0; i<dtblsize; i++) slap_daemon.sd_index[i] = -1 \
262 } while (0)
263 # endif
264
265 # define SLAP_EVENT_DECL struct epoll_event *revents
266
267 # define SLAP_EVENT_INIT do { \
268         revents = slap_daemon.sd_epolls + dtblsize; \
269 } while (0)
270
271 # define SLAP_EVENT_WAIT(tvp) \
272         epoll_wait( slap_daemon.sd_epfd, revents, \
273                 dtblsize, (tvp) ? (tvp)->tv_sec * 1000 : -1 )
274
275 #else
276 /* select */
277
278 # define SLAP_EVENTS_ARE_INDEXED 1
279 # define SLAP_EVENT_DECL        \
280         fd_set readfds, writefds
281
282 # define SLAP_EVENT_INIT do { \
283         AC_MEMCPY( &readfds, &slap_daemon.sd_readers, sizeof(fd_set) ); \
284         if ( nwriters ) { \
285                 AC_MEMCPY( &writefds, &slap_daemon.sd_writers, sizeof(fd_set) ); \
286         } else { \
287                 FD_ZERO( &writefds ); \
288         } \
289 } while (0)
290
291 # ifdef FD_SETSIZE
292 #  define       CHK_SETSIZE do { \
293         if (dtblsize > FD_SETSIZE) dtblsize = FD_SETSIZE; \
294 } while (0)
295 # else
296 #  define        CHK_SETSIZE do { ; } while (0)
297 # endif
298
299 # ifdef SLAP_LIGHTWEIGHT_LISTENER
300 #  define       SLAP_SOCK_SET_INIT do { \
301         CHK_SETSIZE; \
302         FD_ZERO(&slap_daemon.sd_readers); \
303         FD_ZERO(&slap_daemon.sd_writers); \
304         FD_ZERO(&slap_daemon.sd_suspend); \
305 } while (0)
306 # else
307 #  define       SLAP_SOCK_SET_INIT do { \
308         CHK_SETSIZE; \
309         FD_ZERO(&slap_daemon.sd_readers); \
310         FD_ZERO(&slap_daemon.sd_writers); \
311 } while (0)
312 # endif
313
314 # define SLAP_SOCK_IS_ACTIVE(fd)        FD_ISSET((fd), &slap_daemon.sd_actives)
315 # define SLAP_SOCK_IS_READ(fd)          FD_ISSET((fd), &slap_daemon.sd_readers)
316 # define SLAP_SOCK_IS_WRITE(fd)         FD_ISSET((fd), &slap_daemon.sd_writers)
317
318 # define SLAP_SOCK_NOT_ACTIVE(fd)       (!SLAP_SOCK_IS_ACTIVE(fd) && \
319          !SLAP_SOCK_IS_READ(fd) && !SLAP_SOCK_IS_WRITE(fd))
320
321 # ifdef SLAP_LIGHTWEIGHT_LISTENER
322 #  define SLAP_SOCK_SET_SUSPEND(s)      FD_SET((s), &slap_daemon.sd_suspend)
323 #  define SLAP_SOCK_CLR_SUSPEND(s)  FD_CLR((s), &slap_daemon.sd_suspend)
324 #  define SLAP_SOCK_IS_SUSPEND(s)       FD_ISSET((s), &slap_daemon.sd_suspend)
325 # endif
326
327 # ifdef HAVE_WINSOCK
328 #  define SLAP_SOCK_SET_READ(fd)        do { \
329         if (!SLAP_SOCK_IS_READ(fd)) { FD_SET((fd), &slap_daemon.sd_readers); } \
330 } while(0)
331 #  define SLAP_SOCK_SET_WRITE(fd)       do { \
332         if (!SLAP_SOCK_IS_WRITE(fd)) { FD_SET((fd), &slap_daemon.sd_writers); } \
333 } while(0)
334
335 #  define SLAP_ADDTEST(s)       do { } while 0
336 #  define SLAP_EVENT_MAX        dtblsize
337 # else
338 #  define SLAP_SOCK_SET_READ(fd)        FD_SET((fd), &slap_daemon.sd_readers)
339 #  define SLAP_SOCK_SET_WRITE(fd)       FD_SET((fd), &slap_daemon.sd_writers)
340
341 #  define SLAP_EVENT_MAX        slap_daemon.sd_nfds
342 #  define SLAP_ADDTEST(s)       do { \
343         if ((s) >= slap_daemon.sd_nfds) slap_daemon.sd_nfds = (s)+1; \
344 } while (0)
345 # endif
346
347 # define SLAP_SOCK_CLR_READ(fd)         FD_CLR((fd), &slap_daemon.sd_readers)
348 # define SLAP_SOCK_CLR_WRITE(fd)        FD_CLR((fd), &slap_daemon.sd_writers)
349
350 # define SLAP_ADD_SOCK(s, l) do { \
351         SLAP_ADDTEST((s)); \
352         FD_SET((s), &slap_daemon.sd_actives); \
353         FD_SET((s), &slap_daemon.sd_readers); \
354 } while(0)
355
356 # define SLAP_DEL_SOCK(s) do { \
357         FD_CLR((s), &slap_daemon.sd_actives); \
358         FD_CLR((s), &slap_daemon.sd_readers); \
359         FD_CLR((s), &slap_daemon.sd_writers); \
360 } while(0)
361
362 # define SLAP_EVENT_IS_READ(fd)         FD_ISSET((fd), &readfds)
363 # define SLAP_EVENT_IS_WRITE(fd)        FD_ISSET((fd), &writefds)
364
365 # define SLAP_EVENT_CLR_READ(fd)        FD_CLR((fd), &readfds)
366 # define SLAP_EVENT_CLR_WRITE(fd)       FD_CLR((fd), &writefds)
367
368 # define SLAP_EVENT_WAIT(tvp) \
369         select( SLAP_EVENT_MAX, &readfds, \
370                 nwriters > 0 ? &writefds : NULL, NULL, (tvp) )
371
372 # define        SLAP_SOCK_SET_MUTE(s)   FD_CLR((s), &readfds)
373 # define        SLAP_SOCK_CLR_MUTE(s)   FD_SET((s), &readfds)
374 # define        SLAP_SOCK_IS_MUTE(s)    (!FD_ISSET((s), &readfds))
375 #endif
376
377 #ifdef HAVE_SLP
378 /*
379  * SLP related functions
380  */
381 #include <slp.h>
382
383 #define LDAP_SRVTYPE_PREFIX "service:ldap://"
384 #define LDAPS_SRVTYPE_PREFIX "service:ldaps://"
385 static char** slapd_srvurls = NULL;
386 static SLPHandle slapd_hslp = 0;
387 int slapd_register_slp = 0;
388
389 void slapd_slp_init( const char* urls ) {
390         int i;
391
392         slapd_srvurls = ldap_str2charray( urls, " " );
393
394         if( slapd_srvurls == NULL ) return;
395
396         /* find and expand INADDR_ANY URLs */
397         for( i=0; slapd_srvurls[i] != NULL; i++ ) {
398                 if( strcmp( slapd_srvurls[i], "ldap:///" ) == 0) {
399                         char *host = ldap_pvt_get_fqdn( NULL );
400                         if ( host != NULL ) {
401                                 slapd_srvurls[i] = (char *) ch_realloc( slapd_srvurls[i],
402                                         strlen( host ) +
403                                         sizeof( LDAP_SRVTYPE_PREFIX ) );
404                                 strcpy( lutil_strcopy(slapd_srvurls[i],
405                                         LDAP_SRVTYPE_PREFIX ), host );
406
407                                 ch_free( host );
408                         }
409
410                 } else if ( strcmp( slapd_srvurls[i], "ldaps:///" ) == 0) {
411                         char *host = ldap_pvt_get_fqdn( NULL );
412                         if ( host != NULL ) {
413                                 slapd_srvurls[i] = (char *) ch_realloc( slapd_srvurls[i],
414                                         strlen( host ) +
415                                         sizeof( LDAPS_SRVTYPE_PREFIX ) );
416                                 strcpy( lutil_strcopy(slapd_srvurls[i],
417                                         LDAPS_SRVTYPE_PREFIX ), host );
418
419                                 ch_free( host );
420                         }
421                 }
422         }
423
424         /* open the SLP handle */
425         SLPOpen( "en", 0, &slapd_hslp );
426 }
427
428 void slapd_slp_deinit() {
429         if( slapd_srvurls == NULL ) return;
430
431         ldap_charray_free( slapd_srvurls );
432         slapd_srvurls = NULL;
433
434         /* close the SLP handle */
435         SLPClose( slapd_hslp );
436 }
437
438 void slapd_slp_regreport(
439         SLPHandle hslp,
440         SLPError errcode,
441         void* cookie )
442 {
443         /* empty report */
444 }
445
446 void slapd_slp_reg() {
447         int i;
448
449         if( slapd_srvurls == NULL ) return;
450
451         for( i=0; slapd_srvurls[i] != NULL; i++ ) {
452                 if( strncmp( slapd_srvurls[i], LDAP_SRVTYPE_PREFIX,
453                                 sizeof( LDAP_SRVTYPE_PREFIX ) - 1 ) == 0 ||
454                     strncmp( slapd_srvurls[i], LDAPS_SRVTYPE_PREFIX,
455                                 sizeof( LDAPS_SRVTYPE_PREFIX ) - 1 ) == 0 )
456                 {
457                         SLPReg( slapd_hslp,
458                                 slapd_srvurls[i],
459                                 SLP_LIFETIME_MAXIMUM,
460                                 "ldap",
461                                 "",
462                                 1,
463                                 slapd_slp_regreport,
464                                 NULL );
465                 }
466         }
467 }
468
469 void slapd_slp_dereg() {
470         int i;
471
472         if( slapd_srvurls == NULL ) return;
473
474         for( i=0; slapd_srvurls[i] != NULL; i++ ) {
475                 SLPDereg( slapd_hslp,
476                         slapd_srvurls[i],
477                         slapd_slp_regreport,
478                         NULL );
479         }
480 }
481 #endif /* HAVE_SLP */
482
483 /*
484  * Add a descriptor to daemon control
485  *
486  * If isactive, the descriptor is a live server session and is subject
487  * to idletimeout control. Otherwise, the descriptor is a passive
488  * listener or an outbound client session, and not subject to
489  * idletimeout. The underlying event handler may record the Listener
490  * argument to differentiate Listener's from real sessions.
491  */
492 static void slapd_add(ber_socket_t s, int isactive, Listener *sl) {
493         ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
494
495         assert( SLAP_SOCK_NOT_ACTIVE(s) );
496
497         if ( isactive ) slap_daemon.sd_nactives++;
498
499         SLAP_ADD_SOCK(s, sl);
500
501         Debug( LDAP_DEBUG_CONNS, "daemon: added %ldr\n",
502                 (long) s, 0, 0 );
503
504         ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
505
506 #ifdef SLAP_LIGHTWEIGHT_LISTENER
507         WAKE_LISTENER(1);
508 #endif
509 }
510
511 /*
512  * Remove the descriptor from daemon control
513  */
514 void slapd_remove(
515         ber_socket_t s,
516         int wasactive,
517         int wake )
518 {
519         int waswriter;
520
521         ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
522
523         if ( wasactive ) slap_daemon.sd_nactives--;
524         waswriter = SLAP_SOCK_IS_WRITE(s);
525
526         Debug( LDAP_DEBUG_CONNS, "daemon: removing %ld%s%s\n",
527                 (long) s, SLAP_SOCK_IS_READ(s) ? "r" : "",
528                 waswriter ? "w" : "" );
529         if ( waswriter ) slap_daemon.sd_nwriters--;
530
531 #ifdef SLAP_LIGHTWEIGHT_LISTENER
532         SLAP_SOCK_CLR_SUSPEND(s);
533 #endif
534
535         SLAP_DEL_SOCK(s);
536         /* If we ran out of file descriptors, we dropped a listener from
537          * the select() loop. Now that we're removing a session from our
538          * control, we can try to resume a dropped listener to use.
539          */
540         if ( emfile ) {
541                 int i;
542                 for ( i = 0; slap_listeners[i] != NULL; i++ ) {
543                         if ( slap_listeners[i]->sl_sd != AC_SOCKET_INVALID ) {
544                                 if ( slap_listeners[i]->sl_sd == s ) continue;
545                                 if ( slap_listeners[i]->sl_is_mute ) {
546                                         slap_listeners[i]->sl_is_mute = 0;
547                                         emfile--;
548                                         break;
549                                 }
550                         }
551                 }
552                 /* Walked the entire list without enabling anything; emfile
553                  * counter is stale. Reset it.
554                  */
555                 if ( slap_listeners[i] == NULL ) emfile = 0;
556         }
557         ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
558         WAKE_LISTENER(wake || slapd_gentle_shutdown == 2);
559 }
560
561 #ifdef SLAP_LIGHTWEIGHT_LISTENER
562 /*
563  * Temporarily suspend submitting events on the descriptor to the pool.
564  * Reading on the descriptor will be resumed by a connection procseeing thread
565  * when data (LDAP requests) on it are read.
566  * slapd_suspend() returns 1 when it is suspended otherwise returns 0
567  */
568 int slapd_suspend(ber_socket_t s) {
569         int rc = 0;
570
571         ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
572
573         if ( !SLAP_SOCK_IS_SUSPEND( s ) && SLAP_SOCK_IS_ACTIVE( s ) &&
574                         SLAP_SOCK_IS_READ( s ) )
575         {
576                 SLAP_SOCK_SET_SUSPEND( s );
577                 SLAP_SOCK_CLR_READ( s );
578                 rc = 1;
579         }
580
581         ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
582         return rc;
583 }
584
585 void slapd_resume ( ber_socket_t s ) {
586         ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
587
588         SLAP_SOCK_SET_READ( s );
589
590         assert( SLAP_SOCK_IS_SUSPEND( s ) );
591
592         SLAP_SOCK_CLR_SUSPEND ( s );
593
594         ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
595
596         WAKE_LISTENER(1);
597 }
598 #endif
599
600 void slapd_clr_write(ber_socket_t s, int wake) {
601         ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
602
603         assert( SLAP_SOCK_IS_ACTIVE( s ));
604
605         if ( SLAP_SOCK_IS_WRITE( s )) {
606                 SLAP_SOCK_CLR_WRITE( s );
607                 slap_daemon.sd_nwriters--;
608         }
609
610         ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
611         WAKE_LISTENER(wake);
612 }
613
614 void slapd_set_write(ber_socket_t s, int wake) {
615         ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
616
617         assert( SLAP_SOCK_IS_ACTIVE( s ));
618
619         if ( !SLAP_SOCK_IS_WRITE( s )) {
620                 SLAP_SOCK_SET_WRITE( s );
621                 slap_daemon.sd_nwriters++;
622         }
623
624         ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
625         WAKE_LISTENER(wake);
626 }
627
628 void slapd_clr_read(ber_socket_t s, int wake) {
629         ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
630
631         assert( SLAP_SOCK_IS_ACTIVE( s ));
632         SLAP_SOCK_CLR_READ( s );
633
634         ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
635         WAKE_LISTENER(wake);
636 }
637
638 void slapd_set_read(ber_socket_t s, int wake) {
639         ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
640
641         assert( SLAP_SOCK_IS_ACTIVE( s ));
642         if (!SLAP_SOCK_IS_READ( s ))
643                 SLAP_SOCK_SET_READ( s );
644
645         ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
646         WAKE_LISTENER(wake);
647 }
648
649 static void slapd_close(ber_socket_t s) {
650         Debug( LDAP_DEBUG_CONNS, "daemon: closing %ld\n",
651                 (long) s, 0, 0 );
652         tcp_close(s);
653 }
654
655 static void slap_free_listener_addresses(struct sockaddr **sal)
656 {
657         struct sockaddr **sap;
658
659         if (sal == NULL) return;
660
661         for (sap = sal; *sap != NULL; sap++) {
662                 ch_free(*sap);
663         }
664
665         ch_free(sal);
666 }
667
668 #if defined(LDAP_PF_LOCAL) || defined(SLAP_X_LISTENER_MOD)
669 static int get_url_perms(
670         char    **exts,
671         mode_t  *perms,
672         int     *crit )
673 {
674         int     i;
675
676         assert( exts != NULL );
677         assert( perms != NULL );
678         assert( crit != NULL );
679
680         *crit = 0;
681         for ( i = 0; exts[ i ]; i++ ) {
682                 char    *type = exts[ i ];
683                 int     c = 0;
684
685                 if ( type[ 0 ] == '!' ) {
686                         c = 1;
687                         type++;
688                 }
689
690                 if ( strncasecmp( type, LDAPI_MOD_URLEXT "=",
691                         sizeof(LDAPI_MOD_URLEXT "=") - 1 ) == 0 )
692                 {
693                         char *value = type + ( sizeof(LDAPI_MOD_URLEXT "=") - 1 );
694                         mode_t p = 0;
695                         int j;
696
697                         switch (strlen(value)) {
698                         case 4:
699                                 /* skip leading '0' */
700                                 if ( value[ 0 ] != '0' ) return LDAP_OTHER;
701                                 value++;
702
703                         case 3:
704                                 for ( j = 0; j < 3; j++) {
705                                         int     v;
706
707                                         v = value[ j ] - '0';
708
709                                         if ( v < 0 || v > 7 ) return LDAP_OTHER;
710
711                                         p |= v << 3*(2-j);
712                                 }
713                                 break;
714
715                         case 10:
716                                 for ( j = 1; j < 10; j++ ) {
717                                         static mode_t   m[] = { 0, 
718                                                 S_IRUSR, S_IWUSR, S_IXUSR,
719                                                 S_IRGRP, S_IWGRP, S_IXGRP,
720                                                 S_IROTH, S_IWOTH, S_IXOTH
721                                         };
722                                         static char     c[] = "-rwxrwxrwx"; 
723
724                                         if ( value[ j ] == c[ j ] ) {
725                                                 p |= m[ j ];
726         
727                                         } else if ( value[ j ] != '-' ) {
728                                                 return LDAP_OTHER;
729                                         }
730                                 }
731                                 break;
732
733                         default:
734                                 return LDAP_OTHER;
735                         } 
736
737                         *crit = c;
738                         *perms = p;
739
740                         return LDAP_SUCCESS;
741                 }
742         }
743
744         return LDAP_OTHER;
745 }
746 #endif /* LDAP_PF_LOCAL || SLAP_X_LISTENER_MOD */
747
748 /* port = 0 indicates AF_LOCAL */
749 static int slap_get_listener_addresses(
750         const char *host,
751         unsigned short port,
752         struct sockaddr ***sal)
753 {
754         struct sockaddr **sap;
755
756 #ifdef LDAP_PF_LOCAL
757         if ( port == 0 ) {
758                 *sal = ch_malloc(2 * sizeof(void *));
759                 if (*sal == NULL) return -1;
760
761                 sap = *sal;
762                 *sap = ch_malloc(sizeof(struct sockaddr_un));
763                 if (*sap == NULL) goto errexit;
764                 sap[1] = NULL;
765
766                 if ( strlen(host) >
767                         (sizeof(((struct sockaddr_un *)*sap)->sun_path) - 1) )
768                 {
769                         Debug( LDAP_DEBUG_ANY,
770                                 "daemon: domain socket path (%s) too long in URL",
771                                 host, 0, 0);
772                         goto errexit;
773                 }
774
775                 (void)memset( (void *)*sap, '\0', sizeof(struct sockaddr_un) );
776                 (*sap)->sa_family = AF_LOCAL;
777                 strcpy( ((struct sockaddr_un *)*sap)->sun_path, host );
778         } else
779 #endif
780         {
781 #ifdef HAVE_GETADDRINFO
782                 struct addrinfo hints, *res, *sai;
783                 int n, err;
784                 char serv[7];
785
786                 memset( &hints, '\0', sizeof(hints) );
787                 hints.ai_flags = AI_PASSIVE;
788                 hints.ai_socktype = SOCK_STREAM;
789                 hints.ai_family = slap_inet4or6;
790                 snprintf(serv, sizeof serv, "%d", port);
791
792                 if ( (err = getaddrinfo(host, serv, &hints, &res)) ) {
793                         Debug( LDAP_DEBUG_ANY, "daemon: getaddrinfo failed: %s\n",
794                                 AC_GAI_STRERROR(err), 0, 0);
795                         return -1;
796                 }
797
798                 sai = res;
799                 for (n=2; (sai = sai->ai_next) != NULL; n++) {
800                         /* EMPTY */ ;
801                 }
802                 *sal = ch_calloc(n, sizeof(void *));
803                 if (*sal == NULL) return -1;
804
805                 sap = *sal;
806                 *sap = NULL;
807
808                 for ( sai=res; sai; sai=sai->ai_next ) {
809                         if( sai->ai_addr == NULL ) {
810                                 Debug( LDAP_DEBUG_ANY, "slap_get_listener_addresses: "
811                                         "getaddrinfo ai_addr is NULL?\n", 0, 0, 0 );
812                                 freeaddrinfo(res);
813                                 goto errexit;
814                         }
815
816                         switch (sai->ai_family) {
817 #  ifdef LDAP_PF_INET6
818                         case AF_INET6:
819                                 *sap = ch_malloc(sizeof(struct sockaddr_in6));
820                                 if (*sap == NULL) {
821                                         freeaddrinfo(res);
822                                         goto errexit;
823                                 }
824                                 *(struct sockaddr_in6 *)*sap =
825                                         *((struct sockaddr_in6 *)sai->ai_addr);
826                                 break;
827 #  endif
828                         case AF_INET:
829                                 *sap = ch_malloc(sizeof(struct sockaddr_in));
830                                 if (*sap == NULL) {
831                                         freeaddrinfo(res);
832                                         goto errexit;
833                                 }
834                                 *(struct sockaddr_in *)*sap =
835                                         *((struct sockaddr_in *)sai->ai_addr);
836                                 break;
837                         default:
838                                 *sap = NULL;
839                                 break;
840                         }
841
842                         if (*sap != NULL) {
843                                 (*sap)->sa_family = sai->ai_family;
844                                 sap++;
845                                 *sap = NULL;
846                         }
847                 }
848
849                 freeaddrinfo(res);
850 #else
851                 int i, n = 1;
852                 struct in_addr in;
853                 struct hostent *he = NULL;
854
855                 if ( host == NULL ) {
856                         in.s_addr = htonl(INADDR_ANY);
857
858                 } else if ( !inet_aton( host, &in ) ) {
859                         he = gethostbyname( host );
860                         if( he == NULL ) {
861                                 Debug( LDAP_DEBUG_ANY,
862                                         "daemon: invalid host %s", host, 0, 0);
863                                 return -1;
864                         }
865                         for (n = 0; he->h_addr_list[n]; n++) ;
866                 }
867
868                 *sal = ch_malloc((n+1) * sizeof(void *));
869                 if (*sal == NULL) {
870                         return -1;
871                 }
872
873                 sap = *sal;
874                 for ( i = 0; i<n; i++ ) {
875                         sap[i] = ch_malloc(sizeof(struct sockaddr_in));
876                         if (*sap == NULL) goto errexit;
877                         (void)memset( (void *)sap[i], '\0', sizeof(struct sockaddr_in) );
878                         sap[i]->sa_family = AF_INET;
879                         ((struct sockaddr_in *)sap[i])->sin_port = htons(port);
880                         if (he) {
881                                 AC_MEMCPY( &((struct sockaddr_in *)sap[i])->sin_addr,
882                                         he->h_addr_list[i], sizeof(struct in_addr) );
883                         } else {
884                                 AC_MEMCPY( &((struct sockaddr_in *)sap[i])->sin_addr,
885                                         &in, sizeof(struct in_addr) );
886                         }
887                 }
888                 sap[i] = NULL;
889 #endif
890         }
891
892         return 0;
893
894 errexit:
895         slap_free_listener_addresses(*sal);
896         return -1;
897 }
898
899 static int slap_open_listener(
900         const char* url,
901         int *listeners,
902         int *cur
903         )
904 {
905         int     num, tmp, rc;
906         Listener l;
907         Listener *li;
908         LDAPURLDesc *lud;
909         unsigned short port;
910         int err, addrlen = 0;
911         struct sockaddr **sal, **psal;
912         int socktype = SOCK_STREAM;     /* default to COTS */
913
914 #if defined(LDAP_PF_LOCAL) || defined(SLAP_X_LISTENER_MOD)
915         /*
916          * use safe defaults
917          */
918         int     crit = 1;
919 #endif /* LDAP_PF_LOCAL || SLAP_X_LISTENER_MOD */
920
921         rc = ldap_url_parse( url, &lud );
922
923         if( rc != LDAP_URL_SUCCESS ) {
924                 Debug( LDAP_DEBUG_ANY,
925                         "daemon: listen URL \"%s\" parse error=%d\n",
926                         url, rc, 0 );
927                 return rc;
928         }
929
930         l.sl_url.bv_val = NULL;
931         l.sl_is_mute = 0;
932
933 #ifndef HAVE_TLS
934         if( ldap_pvt_url_scheme2tls( lud->lud_scheme ) ) {
935                 Debug( LDAP_DEBUG_ANY,
936                         "daemon: TLS not supported (%s)\n",
937                         url, 0, 0 );
938                 ldap_free_urldesc( lud );
939                 return -1;
940         }
941
942         if(! lud->lud_port ) lud->lud_port = LDAP_PORT;
943
944 #else
945         l.sl_is_tls = ldap_pvt_url_scheme2tls( lud->lud_scheme );
946
947         if(! lud->lud_port ) {
948                 lud->lud_port = l.sl_is_tls ? LDAPS_PORT : LDAP_PORT;
949         }
950 #endif
951
952         port = (unsigned short) lud->lud_port;
953
954         tmp = ldap_pvt_url_scheme2proto(lud->lud_scheme);
955         if ( tmp == LDAP_PROTO_IPC ) {
956 #ifdef LDAP_PF_LOCAL
957                 if ( lud->lud_host == NULL || lud->lud_host[0] == '\0' ) {
958                         err = slap_get_listener_addresses(LDAPI_SOCK, 0, &sal);
959                 } else {
960                         err = slap_get_listener_addresses(lud->lud_host, 0, &sal);
961                 }
962 #else
963
964                 Debug( LDAP_DEBUG_ANY, "daemon: URL scheme not supported: %s",
965                         url, 0, 0);
966                 ldap_free_urldesc( lud );
967                 return -1;
968 #endif
969         } else {
970                 if( lud->lud_host == NULL || lud->lud_host[0] == '\0'
971                         || strcmp(lud->lud_host, "*") == 0 )
972                 {
973                         err = slap_get_listener_addresses(NULL, port, &sal);
974                 } else {
975                         err = slap_get_listener_addresses(lud->lud_host, port, &sal);
976                 }
977         }
978
979 #ifdef LDAP_CONNECTIONLESS
980         l.sl_is_udp = ( tmp == LDAP_PROTO_UDP );
981 #endif
982
983 #if defined(LDAP_PF_LOCAL) || defined(SLAP_X_LISTENER_MOD)
984         if ( lud->lud_exts ) {
985                 err = get_url_perms( lud->lud_exts, &l.sl_perms, &crit );
986         } else {
987                 l.sl_perms = S_IRWXU | S_IRWXO;
988         }
989 #endif /* LDAP_PF_LOCAL || SLAP_X_LISTENER_MOD */
990
991         ldap_free_urldesc( lud );
992         if ( err ) return -1;
993
994         /* If we got more than one address returned, we need to make space
995          * for it in the slap_listeners array.
996          */
997         for ( num=0; sal[num]; num++ ) /* empty */;
998         if ( num > 1 ) {
999                 *listeners += num-1;
1000                 slap_listeners = ch_realloc( slap_listeners,
1001                         (*listeners + 1) * sizeof(Listener *) );
1002         }
1003
1004         psal = sal;
1005         while ( *sal != NULL ) {
1006                 char *af;
1007                 switch( (*sal)->sa_family ) {
1008                 case AF_INET:
1009                         af = "IPv4";
1010                         break;
1011 #ifdef LDAP_PF_INET6
1012                 case AF_INET6:
1013                         af = "IPv6";
1014                         break;
1015 #endif
1016 #ifdef LDAP_PF_LOCAL
1017                 case AF_LOCAL:
1018                         af = "Local";
1019                         break;
1020 #endif
1021                 default:
1022                         sal++;
1023                         continue;
1024                 }
1025
1026 #ifdef LDAP_CONNECTIONLESS
1027                 if( l.sl_is_udp ) socktype = SOCK_DGRAM;
1028 #endif
1029
1030                 l.sl_sd = socket( (*sal)->sa_family, socktype, 0);
1031                 if ( l.sl_sd == AC_SOCKET_INVALID ) {
1032                         int err = sock_errno();
1033                         Debug( LDAP_DEBUG_ANY,
1034                                 "daemon: %s socket() failed errno=%d (%s)\n",
1035                                 af, err, sock_errstr(err) );
1036                         sal++;
1037                         continue;
1038                 }
1039
1040 #ifndef HAVE_WINSOCK
1041                 if ( l.sl_sd >= dtblsize ) {
1042                         Debug( LDAP_DEBUG_ANY,
1043                                 "daemon: listener descriptor %ld is too great %ld\n",
1044                                 (long) l.sl_sd, (long) dtblsize, 0 );
1045                         tcp_close( l.sl_sd );
1046                         sal++;
1047                         continue;
1048                 }
1049 #endif
1050
1051 #ifdef LDAP_PF_LOCAL
1052                 if ( (*sal)->sa_family == AF_LOCAL ) {
1053                         unlink ( ((struct sockaddr_un *)*sal)->sun_path );
1054                 } else
1055 #endif
1056                 {
1057 #ifdef SO_REUSEADDR
1058                         /* enable address reuse */
1059                         tmp = 1;
1060                         rc = setsockopt( l.sl_sd, SOL_SOCKET, SO_REUSEADDR,
1061                                 (char *) &tmp, sizeof(tmp) );
1062                         if ( rc == AC_SOCKET_ERROR ) {
1063                                 int err = sock_errno();
1064                                 Debug( LDAP_DEBUG_ANY, "slapd(%ld): "
1065                                         "setsockopt(SO_REUSEADDR) failed errno=%d (%s)\n",
1066                                         (long) l.sl_sd, err, sock_errstr(err) );
1067                         }
1068 #endif
1069                 }
1070
1071                 switch( (*sal)->sa_family ) {
1072                 case AF_INET:
1073                         addrlen = sizeof(struct sockaddr_in);
1074                         break;
1075 #ifdef LDAP_PF_INET6
1076                 case AF_INET6:
1077 #ifdef IPV6_V6ONLY
1078                         /* Try to use IPv6 sockets for IPv6 only */
1079                         tmp = 1;
1080                         rc = setsockopt( l.sl_sd, IPPROTO_IPV6, IPV6_V6ONLY,
1081                                 (char *) &tmp, sizeof(tmp) );
1082                         if ( rc == AC_SOCKET_ERROR ) {
1083                                 int err = sock_errno();
1084                                 Debug( LDAP_DEBUG_ANY, "slapd(%ld): "
1085                                         "setsockopt(IPV6_V6ONLY) failed errno=%d (%s)\n",
1086                                         (long) l.sl_sd, err, sock_errstr(err) );
1087                         }
1088 #endif
1089                         addrlen = sizeof(struct sockaddr_in6);
1090                         break;
1091 #endif
1092
1093 #ifdef LDAP_PF_LOCAL
1094                 case AF_LOCAL:
1095 #ifdef LOCAL_CREDS
1096                 {
1097                         int one = 1;
1098                         setsockopt(l.sl_sd, 0, LOCAL_CREDS, &one, sizeof one);
1099                 }
1100 #endif
1101                 addrlen = sizeof(struct sockaddr_un);
1102                 break;
1103 #endif
1104                 }
1105
1106                 if (bind(l.sl_sd, *sal, addrlen)) {
1107                         err = sock_errno();
1108                         Debug( LDAP_DEBUG_ANY,
1109                                 "daemon: bind(%ld) failed errno=%d (%s)\n",
1110                                 (long) l.sl_sd, err, sock_errstr(err) );
1111                         tcp_close( l.sl_sd );
1112                         sal++;
1113                         continue;
1114                 }
1115
1116                 switch ( (*sal)->sa_family ) {
1117 #ifdef LDAP_PF_LOCAL
1118                 case AF_LOCAL: {
1119                         char *addr = ((struct sockaddr_un *)*sal)->sun_path;
1120                         l.sl_name.bv_len = strlen(addr) + sizeof("PATH=") - 1;
1121                         l.sl_name.bv_val = ber_memalloc( l.sl_name.bv_len + 1 );
1122                         snprintf( l.sl_name.bv_val, l.sl_name.bv_len + 1, 
1123                                 "PATH=%s", addr );
1124                 } break;
1125 #endif /* LDAP_PF_LOCAL */
1126
1127                 case AF_INET: {
1128                         char *s;
1129 #if defined( HAVE_GETADDRINFO ) && defined( HAVE_INET_NTOP )
1130                         char addr[INET_ADDRSTRLEN];
1131                         inet_ntop( AF_INET, &((struct sockaddr_in *)*sal)->sin_addr,
1132                                 addr, sizeof(addr) );
1133                         s = addr;
1134 #else
1135                         s = inet_ntoa( ((struct sockaddr_in *) *sal)->sin_addr );
1136 #endif
1137                         port = ntohs( ((struct sockaddr_in *)*sal) ->sin_port );
1138                         l.sl_name.bv_val =
1139                                 ber_memalloc( sizeof("IP=255.255.255.255:65535") );
1140                         snprintf( l.sl_name.bv_val, sizeof("IP=255.255.255.255:65535"),
1141                                 "IP=%s:%d",
1142                                  s != NULL ? s : SLAP_STRING_UNKNOWN, port );
1143                         l.sl_name.bv_len = strlen( l.sl_name.bv_val );
1144                 } break;
1145
1146 #ifdef LDAP_PF_INET6
1147                 case AF_INET6: {
1148                         char addr[INET6_ADDRSTRLEN];
1149                         inet_ntop( AF_INET6, &((struct sockaddr_in6 *)*sal)->sin6_addr,
1150                                 addr, sizeof addr);
1151                         port = ntohs( ((struct sockaddr_in6 *)*sal)->sin6_port );
1152                         l.sl_name.bv_len = strlen(addr) + sizeof("IP= 65535");
1153                         l.sl_name.bv_val = ber_memalloc( l.sl_name.bv_len );
1154                         snprintf( l.sl_name.bv_val, l.sl_name.bv_len, "IP=%s %d", 
1155                                 addr, port );
1156                         l.sl_name.bv_len = strlen( l.sl_name.bv_val );
1157                 } break;
1158 #endif /* LDAP_PF_INET6 */
1159
1160                 default:
1161                         Debug( LDAP_DEBUG_ANY, "daemon: unsupported address family (%d)\n",
1162                                 (int) (*sal)->sa_family, 0, 0 );
1163                         break;
1164                 }
1165
1166                 AC_MEMCPY(&l.sl_sa, *sal, addrlen);
1167                 ber_str2bv( url, 0, 1, &l.sl_url);
1168                 li = ch_malloc( sizeof( Listener ) );
1169                 *li = l;
1170                 slap_listeners[*cur] = li;
1171                 (*cur)++;
1172                 sal++;
1173         }
1174
1175         slap_free_listener_addresses(psal);
1176
1177         if ( l.sl_url.bv_val == NULL ) {
1178                 Debug( LDAP_DEBUG_TRACE,
1179                         "slap_open_listener: failed on %s\n", url, 0, 0 );
1180                 return -1;
1181         }
1182
1183         Debug( LDAP_DEBUG_TRACE, "daemon: initialized %s\n",
1184                 l.sl_url.bv_val, 0, 0 );
1185         return 0;
1186 }
1187
1188 static int sockinit(void);
1189 static int sockdestroy(void);
1190
1191 int slapd_daemon_init( const char *urls )
1192 {
1193         int i, j, n, rc;
1194         char **u;
1195
1196         Debug( LDAP_DEBUG_ARGS, "daemon_init: %s\n",
1197                 urls ? urls : "<null>", 0, 0 );
1198         if( (rc = sockinit()) != 0 ) {
1199                 return rc;
1200         }
1201
1202 #ifdef HAVE_SYSCONF
1203         dtblsize = sysconf( _SC_OPEN_MAX );
1204 #elif HAVE_GETDTABLESIZE
1205         dtblsize = getdtablesize();
1206 #else
1207         dtblsize = FD_SETSIZE;
1208 #endif
1209
1210         /* open a pipe (or something equivalent connected to itself).
1211          * we write a byte on this fd whenever we catch a signal. The main
1212          * loop will be select'ing on this socket, and will wake up when
1213          * this byte arrives.
1214          */
1215         if( (rc = lutil_pair( wake_sds )) < 0 ) {
1216                 Debug( LDAP_DEBUG_ANY,
1217                         "daemon: lutil_pair() failed rc=%d\n", rc, 0, 0 );
1218                 return rc;
1219         }
1220
1221         SLAP_SOCK_SET_INIT;
1222
1223         if( urls == NULL ) {
1224                 urls = "ldap:///";
1225         }
1226
1227         u = ldap_str2charray( urls, " " );
1228
1229         if( u == NULL || u[0] == NULL ) {
1230                 Debug( LDAP_DEBUG_ANY, "daemon_init: no urls (%s) provided.\n",
1231                         urls, 0, 0 );
1232                 return -1;
1233         }
1234
1235         for( i=0; u[i] != NULL; i++ ) {
1236                 Debug( LDAP_DEBUG_TRACE, "daemon_init: listen on %s\n",
1237                         u[i], 0, 0 );
1238         }
1239
1240         if( i == 0 ) {
1241                 Debug( LDAP_DEBUG_ANY, "daemon_init: no listeners to open (%s)\n",
1242                         urls, 0, 0 );
1243                 ldap_charray_free( u );
1244                 return -1;
1245         }
1246
1247         Debug( LDAP_DEBUG_TRACE, "daemon_init: %d listeners to open...\n",
1248                 i, 0, 0 );
1249         slap_listeners = ch_malloc( (i+1)*sizeof(Listener *) );
1250
1251         for(n = 0, j = 0; u[n]; n++ ) {
1252                 if ( slap_open_listener( u[n], &i, &j ) ) {
1253                         ldap_charray_free( u );
1254                         return -1;
1255                 }
1256         }
1257         slap_listeners[j] = NULL;
1258
1259         Debug( LDAP_DEBUG_TRACE, "daemon_init: %d listeners opened\n",
1260                 i, 0, 0 );
1261
1262 #ifdef HAVE_SLP
1263         if( slapd_register_slp ) {
1264                 slapd_slp_init( urls );
1265                 slapd_slp_reg();
1266         }
1267 #endif
1268
1269         ldap_charray_free( u );
1270         ldap_pvt_thread_mutex_init( &slap_daemon.sd_mutex );
1271
1272         return !i;
1273 }
1274
1275
1276 int
1277 slapd_daemon_destroy(void)
1278 {
1279         connections_destroy();
1280         tcp_close( wake_sds[1] );
1281         tcp_close( wake_sds[0] );
1282         sockdestroy();
1283
1284 #ifdef HAVE_SLP
1285         if( slapd_register_slp ) {
1286                 slapd_slp_dereg();
1287                 slapd_slp_deinit();
1288         }
1289 #endif
1290
1291         return 0;
1292 }
1293
1294
1295 static void
1296 close_listeners(
1297         int remove )
1298 {
1299         int l;
1300
1301         for ( l = 0; slap_listeners[l] != NULL; l++ ) {
1302                 if ( slap_listeners[l]->sl_sd != AC_SOCKET_INVALID ) {
1303                         if ( remove ) slapd_remove( slap_listeners[l]->sl_sd, 0, 0 );
1304
1305 #ifdef LDAP_PF_LOCAL
1306                         if ( slap_listeners[l]->sl_sa.sa_addr.sa_family == AF_LOCAL ) {
1307                                 unlink( slap_listeners[l]->sl_sa.sa_un_addr.sun_path );
1308                         }
1309 #endif /* LDAP_PF_LOCAL */
1310
1311                         slapd_close( slap_listeners[l]->sl_sd );
1312                 }
1313
1314                 if ( slap_listeners[l]->sl_url.bv_val ) {
1315                         ber_memfree( slap_listeners[l]->sl_url.bv_val );
1316                 }
1317
1318                 if ( slap_listeners[l]->sl_name.bv_val ) {
1319                         ber_memfree( slap_listeners[l]->sl_name.bv_val );
1320                 }
1321
1322                 free ( slap_listeners[l] );
1323                 slap_listeners[l] = NULL;
1324         }
1325 }
1326
1327 static int
1328 slapd_handle_listener(
1329         Listener *sl )
1330 {
1331         Sockaddr                from;
1332
1333         ber_socket_t s;
1334         socklen_t len = sizeof(from);
1335         long id;
1336         slap_ssf_t ssf = 0;
1337         struct berval authid = BER_BVNULL;
1338 #ifdef SLAPD_RLOOKUPS
1339         char hbuf[NI_MAXHOST];
1340 #endif
1341
1342         char    *dnsname = NULL;
1343         char    *peeraddr = NULL;
1344 #ifdef LDAP_PF_LOCAL
1345         char peername[MAXPATHLEN + sizeof("PATH=")];
1346 #elif defined(LDAP_PF_INET6)
1347         char peername[sizeof("IP=ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff 65535")];
1348 #else
1349         char peername[sizeof("IP=255.255.255.255:65336")];
1350 #endif /* LDAP_PF_LOCAL */
1351
1352         peername[0] = '\0';
1353
1354 #ifdef LDAP_CONNECTIONLESS
1355         if ( sl->sl_is_udp ) {
1356                 /* The first time we receive a query, we set this
1357                  * up as a "connection". It remains open for the life
1358                  * of the slapd.
1359                  */
1360                 if ( sl->sl_is_udp < 2 ) {
1361                         id = connection_init( sl->sl_sd, sl, "", "",
1362                                 CONN_IS_UDP, ssf, NULL );
1363                     sl->sl_is_udp++;
1364                 }
1365                 return 1;
1366         }
1367 #endif
1368
1369 #  ifdef LDAP_PF_LOCAL
1370         /* FIXME: apparently accept doesn't fill
1371          * the sun_path sun_path member */
1372         from.sa_un_addr.sun_path[0] = '\0';
1373 #  endif /* LDAP_PF_LOCAL */
1374
1375         s = accept( sl->sl_sd, (struct sockaddr *) &from, &len );
1376 #ifdef SLAP_LIGHTWEIGHT_LISTENER
1377         /*
1378          * As soon as a TCP connection is accepted, the listener FD is resumed
1379          * for concurrent-processing of incoming TCP connections.
1380          */
1381         slapd_resume( sl->sl_sd );
1382 #endif
1383         if ( s == AC_SOCKET_INVALID ) {
1384                 int err = sock_errno();
1385
1386                 if(
1387 #ifdef EMFILE
1388                     err == EMFILE ||
1389 #endif
1390 #ifdef ENFILE
1391                     err == ENFILE ||
1392 #endif
1393                     0 )
1394                 {
1395                         ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
1396                         emfile++;
1397                         /* Stop listening until an existing session closes */
1398                         sl->sl_is_mute = 1;
1399                         ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
1400                 }
1401
1402                 Debug( LDAP_DEBUG_ANY,
1403                         "daemon: accept(%ld) failed errno=%d (%s)\n",
1404                         (long) sl->sl_sd, err,
1405                         sock_errstr(err) );
1406                 ldap_pvt_thread_yield();
1407                 return 0;
1408         }
1409
1410 #ifndef HAVE_WINSOCK
1411         /* make sure descriptor number isn't too great */
1412         if ( s >= dtblsize ) {
1413                 Debug( LDAP_DEBUG_ANY,
1414                         "daemon: %ld beyond descriptor table size %ld\n",
1415                         (long) s, (long) dtblsize, 0 );
1416
1417                 slapd_close(s);
1418                 ldap_pvt_thread_yield();
1419                 return 0;
1420         }
1421 #endif
1422
1423 #ifdef LDAP_DEBUG
1424         ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
1425
1426         /* newly accepted stream should not be in any of the FD SETS */
1427         assert( SLAP_SOCK_NOT_ACTIVE( s ));
1428
1429         ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
1430 #endif
1431
1432 #if defined( SO_KEEPALIVE ) || defined( TCP_NODELAY )
1433 #ifdef LDAP_PF_LOCAL
1434         /* for IPv4 and IPv6 sockets only */
1435         if ( from.sa_addr.sa_family != AF_LOCAL )
1436 #endif /* LDAP_PF_LOCAL */
1437         {
1438                 int rc;
1439                 int tmp;
1440 #ifdef SO_KEEPALIVE
1441                 /* enable keep alives */
1442                 tmp = 1;
1443                 rc = setsockopt( s, SOL_SOCKET, SO_KEEPALIVE,
1444                         (char *) &tmp, sizeof(tmp) );
1445                 if ( rc == AC_SOCKET_ERROR ) {
1446                         int err = sock_errno();
1447                         Debug( LDAP_DEBUG_ANY,
1448                                 "slapd(%ld): setsockopt(SO_KEEPALIVE) failed "
1449                                 "errno=%d (%s)\n", (long) s, err, sock_errstr(err) );
1450                 }
1451 #endif
1452 #ifdef TCP_NODELAY
1453                 /* enable no delay */
1454                 tmp = 1;
1455                 rc = setsockopt( s, IPPROTO_TCP, TCP_NODELAY,
1456                         (char *)&tmp, sizeof(tmp) );
1457                 if ( rc == AC_SOCKET_ERROR ) {
1458                         int err = sock_errno();
1459                         Debug( LDAP_DEBUG_ANY,
1460                                 "slapd(%ld): setsockopt(TCP_NODELAY) failed "
1461                                 "errno=%d (%s)\n", (long) s, err, sock_errstr(err) );
1462                 }
1463 #endif
1464         }
1465 #endif
1466
1467         Debug( LDAP_DEBUG_CONNS, "daemon: new connection on %ld\n",
1468                 (long) s, 0, 0 );
1469         switch ( from.sa_addr.sa_family ) {
1470 #  ifdef LDAP_PF_LOCAL
1471         case AF_LOCAL:
1472                 /* FIXME: apparently accept doesn't fill
1473                  * the sun_path sun_path member */
1474                 if ( from.sa_un_addr.sun_path[0] == '\0' ) {
1475                         AC_MEMCPY( from.sa_un_addr.sun_path,
1476                                         sl->sl_sa.sa_un_addr.sun_path,
1477                                         sizeof( from.sa_un_addr.sun_path ) );
1478                 }
1479
1480                 sprintf( peername, "PATH=%s", from.sa_un_addr.sun_path );
1481                 ssf = local_ssf;
1482                 {
1483                         uid_t uid;
1484                         gid_t gid;
1485
1486                         if( getpeereid( s, &uid, &gid ) == 0 ) {
1487                                 authid.bv_val = ch_malloc(
1488                                         STRLENOF( "gidNumber=4294967295+uidNumber=4294967295,"
1489                                         "cn=peercred,cn=external,cn=auth" ) + 1 );
1490                                 authid.bv_len = sprintf( authid.bv_val,
1491                                         "gidNumber=%d+uidNumber=%d,"
1492                                         "cn=peercred,cn=external,cn=auth",
1493                                         (int) gid, (int) uid );
1494                                 assert( authid.bv_len <=
1495                                         STRLENOF( "gidNumber=4294967295+uidNumber=4294967295,"
1496                                         "cn=peercred,cn=external,cn=auth" ) );
1497                         }
1498                 }
1499                 dnsname = "local";
1500                 break;
1501 #endif /* LDAP_PF_LOCAL */
1502
1503 #  ifdef LDAP_PF_INET6
1504         case AF_INET6:
1505         if ( IN6_IS_ADDR_V4MAPPED(&from.sa_in6_addr.sin6_addr) ) {
1506                 peeraddr = inet_ntoa( *((struct in_addr *)
1507                                         &from.sa_in6_addr.sin6_addr.s6_addr[12]) );
1508                 sprintf( peername, "IP=%s:%d",
1509                          peeraddr != NULL ? peeraddr : SLAP_STRING_UNKNOWN,
1510                          (unsigned) ntohs( from.sa_in6_addr.sin6_port ) );
1511         } else {
1512                 char addr[INET6_ADDRSTRLEN];
1513
1514                 peeraddr = (char *) inet_ntop( AF_INET6,
1515                                       &from.sa_in6_addr.sin6_addr,
1516                                       addr, sizeof addr );
1517                 sprintf( peername, "IP=%s %d",
1518                          peeraddr != NULL ? peeraddr : SLAP_STRING_UNKNOWN,
1519                          (unsigned) ntohs( from.sa_in6_addr.sin6_port ) );
1520         }
1521         break;
1522 #  endif /* LDAP_PF_INET6 */
1523
1524         case AF_INET:
1525         peeraddr = inet_ntoa( from.sa_in_addr.sin_addr );
1526         sprintf( peername, "IP=%s:%d",
1527                 peeraddr != NULL ? peeraddr : SLAP_STRING_UNKNOWN,
1528                 (unsigned) ntohs( from.sa_in_addr.sin_port ) );
1529                 break;
1530
1531         default:
1532                 slapd_close(s);
1533                 return 0;
1534         }
1535
1536         if ( ( from.sa_addr.sa_family == AF_INET )
1537 #ifdef LDAP_PF_INET6
1538                 || ( from.sa_addr.sa_family == AF_INET6 )
1539 #endif
1540                 )
1541         {
1542                 dnsname = NULL;
1543 #ifdef SLAPD_RLOOKUPS
1544                 if ( use_reverse_lookup ) {
1545                         char *herr;
1546                         if (ldap_pvt_get_hname( (const struct sockaddr *)&from, len, hbuf,
1547                                 sizeof(hbuf), &herr ) == 0) {
1548                                 ldap_pvt_str2lower( hbuf );
1549                                 dnsname = hbuf;
1550                         }
1551                 }
1552 #endif /* SLAPD_RLOOKUPS */
1553
1554 #ifdef HAVE_TCPD
1555                 if ( !hosts_ctl("slapd",
1556                         dnsname != NULL ? dnsname : SLAP_STRING_UNKNOWN,
1557                         peeraddr != NULL ? peeraddr : SLAP_STRING_UNKNOWN,
1558                         SLAP_STRING_UNKNOWN ))
1559                 {
1560                         /* DENY ACCESS */
1561                         Statslog( LDAP_DEBUG_STATS,
1562                                 "fd=%ld DENIED from %s (%s)\n",
1563                                 (long) s,
1564                                 dnsname != NULL ? dnsname : SLAP_STRING_UNKNOWN,
1565                                 peeraddr != NULL ? peeraddr : SLAP_STRING_UNKNOWN,
1566                                 0, 0 );
1567                         slapd_close(s);
1568                         return 0;
1569                 }
1570 #endif /* HAVE_TCPD */
1571         }
1572
1573         id = connection_init(s, sl,
1574                 dnsname != NULL ? dnsname : SLAP_STRING_UNKNOWN,
1575                 peername,
1576 #ifdef HAVE_TLS
1577                 sl->sl_is_tls ? CONN_IS_TLS : 0,
1578 #else
1579                 0,
1580 #endif
1581                 ssf,
1582                 authid.bv_val ? &authid : NULL );
1583
1584         if( authid.bv_val ) ch_free(authid.bv_val);
1585
1586         if( id < 0 ) {
1587                 Debug( LDAP_DEBUG_ANY,
1588                         "daemon: connection_init(%ld, %s, %s) failed.\n",
1589                         (long) s, peername, sl->sl_name.bv_val );
1590                 slapd_close(s);
1591                 return 0;
1592         }
1593
1594         Statslog( LDAP_DEBUG_STATS,
1595                 "conn=%ld fd=%ld ACCEPT from %s (%s)\n",
1596                 id, (long) s, peername, sl->sl_name.bv_val,
1597                 0 );
1598
1599         slapd_add( s, 1, NULL );
1600         return 0;
1601 }
1602
1603 #ifdef SLAP_LIGHTWEIGHT_LISTENER
1604 void*
1605 slapd_handle_listener_thread(
1606         void* ctx,
1607         void* ptr )
1608 {
1609         int rc;
1610
1611         rc = slapd_handle_listener( (Listener*)ptr );
1612
1613         if( rc != LDAP_SUCCESS ) {
1614                 Debug( LDAP_DEBUG_ANY,
1615                         "slapd_handle_listener_thread: failed", 0, 0, 0 );
1616         }
1617
1618         return (void*)NULL;
1619 }
1620
1621 static int
1622 new_connection_activate(
1623         Listener* sl )
1624 {
1625         int status;
1626
1627         if( !slapd_suspend( sl->sl_sd ) ) return (0);
1628
1629         status = ldap_pvt_thread_pool_submit( &connection_pool,
1630                 slapd_handle_listener_thread, (void *) sl );
1631
1632         if( status != 0 ) {
1633                 Debug( LDAP_DEBUG_ANY,
1634                         "new_connection_activate: ldap_pvt_thread_pool_submit failed\n",
1635                         0, 0, 0 );
1636                 return (-1);
1637         }
1638
1639         return (0);
1640 }
1641 #endif
1642
1643 static void *
1644 slapd_daemon_task(
1645         void *ptr )
1646 {
1647         int l;
1648         time_t last_idle_check = 0;
1649         struct timeval idle;
1650         int ebadf = 0;
1651
1652 #define SLAPD_IDLE_CHECK_LIMIT 4
1653
1654         if ( global_idletimeout > 0 ) {
1655                 last_idle_check = slap_get_time();
1656                 /* Set the select timeout.
1657                  * Don't just truncate, preserve the fractions of
1658                  * seconds to prevent sleeping for zero time.
1659                  */
1660                 idle.tv_sec = global_idletimeout / SLAPD_IDLE_CHECK_LIMIT;
1661                 idle.tv_usec = global_idletimeout - \
1662                         ( idle.tv_sec * SLAPD_IDLE_CHECK_LIMIT );
1663                 idle.tv_usec *= 1000000 / SLAPD_IDLE_CHECK_LIMIT;
1664         } else {
1665                 idle.tv_sec = 0;
1666                 idle.tv_usec = 0;
1667         }
1668
1669         slapd_add( wake_sds[0], 0, NULL );
1670
1671         for ( l = 0; slap_listeners[l] != NULL; l++ ) {
1672                 if ( slap_listeners[l]->sl_sd == AC_SOCKET_INVALID ) continue;
1673
1674 #ifdef LDAP_CONNECTIONLESS
1675                 /* Since this is connectionless, the data port is the
1676                  * listening port. The listen() and accept() calls
1677                  * are unnecessary.
1678                  */
1679                 if ( slap_listeners[l]->sl_is_udp ) {
1680                         slapd_add( slap_listeners[l]->sl_sd, 1, slap_listeners[l] );
1681                         continue;
1682                 }
1683 #endif
1684
1685                 if ( listen( slap_listeners[l]->sl_sd, SLAPD_LISTEN_BACKLOG ) == -1 ) {
1686                         int err = sock_errno();
1687
1688 #ifdef LDAP_PF_INET6
1689                         /* If error is EADDRINUSE, we are trying to listen to INADDR_ANY and
1690                          * we are already listening to in6addr_any, then we want to ignore
1691                          * this and continue.
1692                          */
1693                         if ( err == EADDRINUSE ) {
1694                                 int i;
1695                                 struct sockaddr_in sa = slap_listeners[l]->sl_sa.sa_in_addr;
1696                                 struct sockaddr_in6 sa6;
1697                                 
1698                                 if ( sa.sin_family == AF_INET &&
1699                                      sa.sin_addr.s_addr == htonl(INADDR_ANY) ) {
1700                                         for ( i = 0 ; i < l; i++ ) {
1701                                                 sa6 = slap_listeners[i]->sl_sa.sa_in6_addr;
1702                                                 if ( sa6.sin6_family == AF_INET6 &&
1703                                                      !memcmp( &sa6.sin6_addr, &in6addr_any,
1704                                                                 sizeof(struct in6_addr) ) )
1705                                                 {
1706                                                         break;
1707                                                 }
1708                                         }
1709
1710                                         if ( i < l ) {
1711                                                 /* We are already listening to in6addr_any */
1712                                                 Debug( LDAP_DEBUG_CONNS,
1713                                                         "daemon: Attempt to listen to 0.0.0.0 failed, "
1714                                                         "already listening on ::, assuming IPv4 included\n",
1715                                                         0, 0, 0 );
1716                                                 slapd_close( slap_listeners[l]->sl_sd );
1717                                                 slap_listeners[l]->sl_sd = AC_SOCKET_INVALID;
1718                                                 continue;
1719                                         }
1720                                 }
1721                         }
1722 #endif                          
1723                         Debug( LDAP_DEBUG_ANY,
1724                                 "daemon: listen(%s, 5) failed errno=%d (%s)\n",
1725                                         slap_listeners[l]->sl_url.bv_val, err,
1726                                         sock_errstr(err) );
1727                         return (void*)-1;
1728                 }
1729
1730 #ifdef SLAP_LIGHTWEIGHT_LISTENER
1731                 /* make the listening socket non-blocking */
1732                 if ( ber_pvt_socket_set_nonblock( slap_listeners[l]->sl_sd, 1 ) < 0 ) {
1733                         Debug( LDAP_DEBUG_ANY, "slapd_daemon_task: "
1734                                 "set nonblocking on a listening socket failed\n",
1735                                 0, 0, 0 );
1736                         slapd_shutdown = 2;
1737                         return (void*)-1;
1738                 }
1739 #endif
1740
1741                 slapd_add( slap_listeners[l]->sl_sd, 0, slap_listeners[l] );
1742         }
1743
1744 #ifdef HAVE_NT_SERVICE_MANAGER
1745         if ( started_event != NULL ) }
1746                 ldap_pvt_thread_cond_signal( &started_event );
1747         }
1748 #endif
1749
1750 #ifdef SLAP_SEM_LOAD_CONTROL
1751         /*
1752          * initialize count and lazyness of a semaphore
1753          */
1754         (void) ldap_lazy_sem_init(
1755                 SLAP_MAX_WORKER_THREADS + 4 /* max workers + margin */,
1756                 4 /* lazyness */ );
1757 #endif
1758
1759         /* initialization complete. Here comes the loop. */
1760
1761         while ( !slapd_shutdown ) {
1762                 ber_socket_t i;
1763                 int ns, nwriters;
1764                 int at;
1765                 ber_socket_t nfds;
1766 #if SLAP_EVENTS_ARE_INDEXED
1767                 ber_socket_t nrfds, nwfds;
1768 #endif
1769 #define SLAPD_EBADF_LIMIT 16
1770
1771                 time_t  now;
1772
1773                 SLAP_EVENT_DECL;
1774
1775                 struct timeval          tv;
1776                 struct timeval          *tvp;
1777
1778                 struct timeval          *cat;
1779                 time_t                          tdelta = 1;
1780                 struct re_s*            rtask;
1781                 now = slap_get_time();
1782
1783                 if( ( global_idletimeout > 0 ) &&
1784                         difftime( last_idle_check +
1785                         global_idletimeout/SLAPD_IDLE_CHECK_LIMIT, now ) < 0 ) {
1786                         connections_timeout_idle( now );
1787                         last_idle_check = now;
1788                 }
1789                 tv = idle;
1790
1791 #ifdef SIGHUP
1792                 if( slapd_gentle_shutdown ) {
1793                         ber_socket_t active;
1794
1795                         if( slapd_gentle_shutdown == 1 ) {
1796                                 Debug( LDAP_DEBUG_ANY, "slapd gentle shutdown\n", 0, 0, 0 );
1797                                 close_listeners( 1 );
1798                                 frontendDB->be_restrictops |= SLAP_RESTRICT_OP_WRITES;
1799                                 slapd_gentle_shutdown = 2;
1800                         }
1801
1802                         ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
1803                         active = slap_daemon.sd_nactives;
1804                         ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
1805                         if( active == 0 ) {
1806                                 slapd_shutdown = 2;
1807                                 break;
1808                         }
1809                 }
1810 #endif
1811
1812                 at = 0;
1813
1814                 ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
1815
1816                 nwriters = slap_daemon.sd_nwriters;
1817                 SLAP_EVENT_INIT;
1818
1819                 for ( l = 0; slap_listeners[l] != NULL; l++ ) {
1820                         if ( slap_listeners[l]->sl_sd == AC_SOCKET_INVALID )
1821                                 continue;
1822                         if ( slap_listeners[l]->sl_is_mute )
1823                                 SLAP_SOCK_SET_MUTE( slap_listeners[l]->sl_sd );
1824                         else
1825                         if ( SLAP_SOCK_IS_MUTE( slap_listeners[l]->sl_sd ))
1826                             SLAP_SOCK_CLR_MUTE( slap_listeners[l]->sl_sd );
1827                 }
1828
1829                 nfds = SLAP_EVENT_MAX;
1830
1831                 if ( global_idletimeout && slap_daemon.sd_nactives ) at = 1;
1832
1833                 ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
1834
1835                 if ( at 
1836 #if defined(HAVE_YIELDING_SELECT) || defined(NO_THREADS)
1837                         &&  ( tv.tv_sec || tv.tv_usec )
1838 #endif
1839                         )
1840                 {
1841                         tvp = &tv;
1842                 } else {
1843                         tvp = NULL;
1844                 }
1845
1846                 ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex );
1847                 rtask = ldap_pvt_runqueue_next_sched( &slapd_rq, &cat );
1848                 while ( cat && cat->tv_sec && cat->tv_sec <= now ) {
1849                         if ( ldap_pvt_runqueue_isrunning( &slapd_rq, rtask )) {
1850                                 ldap_pvt_runqueue_resched( &slapd_rq, rtask, 0 );
1851                         } else {
1852                                 ldap_pvt_runqueue_runtask( &slapd_rq, rtask );
1853                                 ldap_pvt_runqueue_resched( &slapd_rq, rtask, 0 );
1854                                 ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex );
1855                                 ldap_pvt_thread_pool_submit( &connection_pool,
1856                                                                                         rtask->routine, (void *) rtask );
1857                                 ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex );
1858                         }
1859                         rtask = ldap_pvt_runqueue_next_sched( &slapd_rq, &cat );
1860                 }
1861                 ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex );
1862
1863                 if ( cat && cat->tv_sec ) {
1864                         time_t diff = difftime( cat->tv_sec, now );
1865                         if ( diff == 0 ) diff = tdelta;
1866                         if ( tvp == NULL || diff < tv.tv_sec ) {
1867                                 tv.tv_sec = diff;
1868                                 tv.tv_usec = 0;
1869                                 tvp = &tv;
1870                         }
1871                 }
1872
1873                 for ( l = 0; slap_listeners[l] != NULL; l++ ) {
1874                         if ( slap_listeners[l]->sl_sd == AC_SOCKET_INVALID ||
1875                             slap_listeners[l]->sl_is_mute )
1876                         {
1877                                 continue;
1878                         }
1879
1880                         Debug( LDAP_DEBUG_CONNS,
1881                                 "daemon: select: listen=%d active_threads=%d tvp=%s\n",
1882                                 slap_listeners[l]->sl_sd, at,
1883                                 tvp == NULL ? "NULL" : "zero" );
1884                 }
1885
1886                 switch(ns = SLAP_EVENT_WAIT(tvp)) {
1887                 case -1: {      /* failure - try again */
1888                                 int err = sock_errno();
1889
1890                                 if( err == EBADF
1891 #ifdef WSAENOTSOCK
1892                                         /* you'd think this would be EBADF */
1893                                         || err == WSAENOTSOCK
1894 #endif
1895                                 ) {
1896                                         if (++ebadf < SLAPD_EBADF_LIMIT)
1897                                                 continue;
1898                                 }
1899
1900                                 if( err != EINTR ) {
1901                                         Debug( LDAP_DEBUG_CONNS,
1902                                                 "daemon: select failed (%d): %s\n",
1903                                                 err, sock_errstr(err), 0 );
1904                                         slapd_shutdown = 2;
1905                                 }
1906                         }
1907                         continue;
1908
1909                 case 0:         /* timeout - let threads run */
1910                         ebadf = 0;
1911 #ifndef HAVE_YIELDING_SELECT
1912                         Debug( LDAP_DEBUG_CONNS, "daemon: select timeout - yielding\n",
1913                             0, 0, 0 );
1914
1915                         ldap_pvt_thread_yield();
1916 #endif
1917                         continue;
1918
1919                 default:        /* something happened - deal with it */
1920                         if( slapd_shutdown ) continue;
1921
1922                         ebadf = 0;
1923                         Debug( LDAP_DEBUG_CONNS, "daemon: activity on %d descriptors\n",
1924                                 ns, 0, 0 );
1925                         /* FALL THRU */
1926                 }
1927
1928 #if SLAP_EVENTS_ARE_INDEXED
1929                 if ( SLAP_EVENT_IS_READ( wake_sds[0] )) {
1930                         char c[BUFSIZ];
1931                         tcp_read( wake_sds[0], c, sizeof(c) );
1932                         waking = 0;
1933                         ns--;
1934                         SLAP_EVENT_CLR_READ( wake_sds[0] );
1935                         continue;
1936                 }
1937
1938                 /* The event slot equals the descriptor number - this is
1939                  * true for Unix select and poll. We treat Windows select
1940                  * like this too, even though it's a kludge.
1941                  */
1942                 for ( l = 0; slap_listeners[l] != NULL; l++ ) {
1943                         int rc;
1944
1945                         if ( ns <= 0 ) break;
1946                         if ( slap_listeners[l]->sl_sd == AC_SOCKET_INVALID ) continue;
1947                         if ( !SLAP_EVENT_IS_READ( slap_listeners[l]->sl_sd )) continue;
1948                         
1949
1950 #ifdef SLAP_LIGHTWEIGHT_LISTENER
1951                         rc = new_connection_activate(slap_listeners[l]);
1952 #else
1953                         rc = slapd_handle_listener(slap_listeners[l]);
1954 #endif
1955
1956 #ifdef LDAP_CONNECTIONLESS
1957                         /* This is a UDP session, let the data loop process it */
1958                         if ( rc ) continue;
1959 #endif
1960
1961                         ns--;
1962
1963                         /* Don't need to look at this in the data loops */
1964                         SLAP_EVENT_CLR_READ( slap_listeners[l]->sl_sd );
1965                         SLAP_EVENT_CLR_WRITE( slap_listeners[l]->sl_sd );
1966                 }
1967
1968                 /* bypass the following tests if no descriptors left */
1969                 if ( ns <= 0 ) {
1970 #ifndef HAVE_YIELDING_SELECT
1971                         ldap_pvt_thread_yield();
1972 #endif
1973                         continue;
1974                 }
1975
1976                 Debug( LDAP_DEBUG_CONNS, "daemon: activity on:", 0, 0, 0 );
1977 #ifdef HAVE_WINSOCK
1978                 nrfds = readfds.fd_count;
1979                 nwfds = writefds.fd_count;
1980                 for ( i = 0; i < readfds.fd_count; i++ ) {
1981                         Debug( LDAP_DEBUG_CONNS, " %d%s",
1982                                 readfds.fd_array[i], "r", 0 );
1983                 }
1984                 for ( i = 0; i < writefds.fd_count; i++ ) {
1985                         Debug( LDAP_DEBUG_CONNS, " %d%s",
1986                                 writefds.fd_array[i], "w", 0 );
1987                 }
1988
1989 #else
1990                 nrfds = 0;
1991                 nwfds = 0;
1992                 for ( i = 0; i < nfds; i++ ) {
1993                         int     r, w;
1994
1995                         r = SLAP_EVENT_IS_READ( i );
1996                         /* writefds was not initialized if nwriters was zero */
1997                         w = nwriters ? SLAP_EVENT_IS_WRITE( i ) : 0;
1998                         if ( r || w ) {
1999                                 Debug( LDAP_DEBUG_CONNS, " %d%s%s", i,
2000                                     r ? "r" : "", w ? "w" : "" );
2001                                 if ( r ) {
2002                                         nrfds++;
2003                                         ns--;
2004                                 }
2005                                 if ( w ) {
2006                                         nwfds++;
2007                                         ns--;
2008                                 }
2009                         }
2010                         if ( ns <= 0 ) break;
2011                 }
2012 #endif
2013                 Debug( LDAP_DEBUG_CONNS, "\n", 0, 0, 0 );
2014
2015
2016                 /* loop through the writers */
2017                 for ( i = 0; nwfds > 0; i++ )
2018                 {
2019                         ber_socket_t wd;
2020 #ifdef HAVE_WINSOCK
2021                         wd = writefds.fd_array[i];
2022 #else
2023                         if( ! SLAP_EVENT_IS_WRITE( i ) ) {
2024                                 continue;
2025                         }
2026                         wd = i;
2027 #endif
2028                         nwfds--;
2029
2030                         Debug( LDAP_DEBUG_CONNS,
2031                                 "daemon: write active on %d\n",
2032                                 wd, 0, 0 );
2033                         /*
2034                          * NOTE: it is possible that the connection was closed
2035                          * and that the stream is now inactive.
2036                          * connection_write() must valid the stream is still
2037                          * active.
2038                          */
2039
2040                         if ( connection_write( wd ) < 0 ) {
2041                                 if ( SLAP_EVENT_IS_READ( wd )) {
2042                                         SLAP_EVENT_CLR_READ( (unsigned) wd );
2043                                         nrfds--;
2044                                 }
2045                                 slapd_close( wd );
2046                         }
2047                         SLAP_EVENT_CLR_WRITE( wd );
2048                 }
2049
2050                 for ( i = 0; nrfds > 0; i++ )
2051                 {
2052                         ber_socket_t rd;
2053 #ifdef HAVE_WINSOCK
2054                         rd = readfds.fd_array[i];
2055 #else
2056                         if( ! SLAP_EVENT_IS_READ( i ) ) {
2057                                 continue;
2058                         }
2059                         rd = i;
2060 #endif
2061                         nrfds--;
2062
2063                         Debug ( LDAP_DEBUG_CONNS,
2064                                 "daemon: read activity on %d\n", rd, 0, 0 );
2065                         /*
2066                          * NOTE: it is possible that the connection was closed
2067                          * and that the stream is now inactive.
2068                          * connection_read() must valid the stream is still
2069                          * active.
2070                          */
2071
2072 #ifdef SLAP_LIGHTWEIGHT_LISTENER
2073                         connection_processing_activate( rd );
2074 #else
2075                         if ( connection_read( rd ) < 0 ) {
2076                                 slapd_close( rd );
2077                         }
2078 #endif
2079                 }
2080 #else   /* !SLAP_EVENTS_ARE_INDEXED */
2081         /* FIXME */
2082         /* The events are returned in an arbitrary list. This is true
2083          * for /dev/poll, epoll and kqueue. In order to prioritize things
2084          * so that we can handle wake_sds first, listeners second, and then
2085          * all other connections last (as we do for select), we would need
2086          * to use multiple event handles and cascade them.
2087          *
2088          * That seems like a bit of hassle. So the wake_sds check has been
2089          * skipped. For epoll and kqueue we can associate arbitrary data with
2090          * an event, so we could use pointers to the listener structure
2091          * instead of just the file descriptor. For /dev/poll we have to
2092          * search the listeners array for a matching descriptor.
2093          */
2094                 /* if waking is set and we woke up, we'll read whatever
2095                  * we can.
2096                  */
2097                 if ( waking ) {
2098                         char c[BUFSIZ];
2099                         tcp_read( wake_sds[0], c, sizeof(c) );
2100                         waking = 0;
2101                         ns--;
2102                         continue;
2103                 }
2104
2105 #ifdef LDAP_DEBUG
2106                 Debug( LDAP_DEBUG_CONNS, "daemon: activity on:", 0, 0, 0 );
2107
2108                 for (i=0; i<ns; i++) {
2109                         int     r, w;
2110
2111                         if ( SLAP_EVENT_IS_LISTENER(i)
2112 #ifdef LDAP_CONNECTIONLESS
2113                                 && !((SLAP_EVENT_LISTENER(i))->sl_is_udp)
2114 #endif
2115                                 )
2116                         {
2117                                 continue;
2118                         }
2119
2120                         /* Don't log internal wake events */
2121                         if ( SLAP_EVENT_FD( i ) == wake_sds[0] ) continue;
2122
2123                         r = SLAP_EVENT_IS_READ( i );
2124                         w = SLAP_EVENT_IS_WRITE( i );
2125                         if ( r || w ) {
2126                                 Debug( LDAP_DEBUG_CONNS, " %d%s%s", SLAP_EVENT_FD(i),
2127                                     r ? "r" : "", w ? "w" : "" );
2128                         }
2129                 }
2130 #endif
2131
2132                 for (i=0; i<ns; i++) {
2133                         int rc = 1, fd;
2134
2135                         if ( SLAP_EVENT_IS_LISTENER(i) ) {
2136 #ifdef SLAP_LIGHTWEIGHT_LISTENER
2137                                 rc = new_connection_activate( SLAP_EVENT_LISTENER( i ));
2138 #else
2139                                 rc = slapd_handle_listener( SLAP_EVENT_LISTENER( i ));
2140 #endif
2141                         }
2142                         /* If we found a regular listener, rc is now zero, and we
2143                          * can skip the data portion. But if it was a UDP listener
2144                          * then rc is still 1, and we want to handle the data.
2145                          */
2146                         if ( rc ) {
2147                                 fd = SLAP_EVENT_FD( i );
2148
2149                                 /* Ignore wake events, they were handled above */
2150                                 if ( fd == wake_sds[0] ) continue;
2151
2152                                 if( SLAP_EVENT_IS_WRITE( i ) ) {
2153                                         Debug( LDAP_DEBUG_CONNS,
2154                                                 "daemon: write active on %d\n",
2155                                                 fd, 0, 0 );
2156                                         /*
2157                                          * NOTE: it is possible that the connection was closed
2158                                          * and that the stream is now inactive.
2159                                          * connection_write() must valid the stream is still
2160                                          * active.
2161                                          */
2162
2163                                         if ( connection_write( fd ) < 0 ) {
2164                                                 slapd_close( fd );
2165                                                 continue;
2166                                         }
2167                                 }
2168                                 if( SLAP_EVENT_IS_READ( i ) ) {
2169                                         Debug( LDAP_DEBUG_CONNS,
2170                                                 "daemon: read active on %d\n",
2171                                                 fd, 0, 0 );
2172                                         /*
2173                                          * NOTE: it is possible that the connection was closed
2174                                          * and that the stream is now inactive.
2175                                          * connection_read() must valid the stream is still
2176                                          * active.
2177                                          */
2178
2179 #ifdef SLAP_LIGHTWEIGHT_LISTENER
2180                                         if ( fd != wake_sds[0] ) {
2181                                                 connection_processing_activate( fd );
2182                                         }
2183 #else
2184                                         if ( connection_read( fd ) < 0 ) slapd_close( fd );
2185 #endif
2186                                 }
2187                         }
2188                 }
2189 #endif  /* SLAP_EVENTS_ARE_INDEXED */
2190
2191 #ifndef HAVE_YIELDING_SELECT
2192                 ldap_pvt_thread_yield();
2193 #endif
2194         }
2195
2196         if( slapd_shutdown == 1 ) {
2197                 Debug( LDAP_DEBUG_ANY,
2198                         "daemon: shutdown requested and initiated.\n",
2199                         0, 0, 0 );
2200
2201         } else if ( slapd_shutdown == 2 ) {
2202 #ifdef HAVE_NT_SERVICE_MANAGER
2203                         Debug( LDAP_DEBUG_ANY,
2204                                "daemon: shutdown initiated by Service Manager.\n",
2205                                0, 0, 0);
2206 #else /* !HAVE_NT_SERVICE_MANAGER */
2207                         Debug( LDAP_DEBUG_ANY,
2208                                "daemon: abnormal condition, shutdown initiated.\n",
2209                                0, 0, 0 );
2210 #endif /* !HAVE_NT_SERVICE_MANAGER */
2211         } else {
2212                 Debug( LDAP_DEBUG_ANY,
2213                        "daemon: no active streams, shutdown initiated.\n",
2214                        0, 0, 0 );
2215         }
2216
2217         if( slapd_gentle_shutdown != 2 ) close_listeners ( 0 );
2218
2219         if( !slapd_gentle_shutdown ) {
2220                 slapd_abrupt_shutdown = 1;
2221                 connections_shutdown();
2222         }
2223
2224         Debug( LDAP_DEBUG_ANY,
2225             "slapd shutdown: waiting for %d threads to terminate\n",
2226             ldap_pvt_thread_pool_backload(&connection_pool), 0, 0 );
2227         ldap_pvt_thread_pool_destroy(&connection_pool, 1);
2228
2229         free ( slap_listeners );
2230         slap_listeners = NULL;
2231
2232         return NULL;
2233 }
2234
2235
2236 int slapd_daemon( void )
2237 {
2238         int rc;
2239
2240         connections_init();
2241
2242 #define SLAPD_LISTENER_THREAD 1
2243 #if defined( SLAPD_LISTENER_THREAD )
2244         {
2245                 ldap_pvt_thread_t       listener_tid;
2246
2247                 /* listener as a separate THREAD */
2248                 rc = ldap_pvt_thread_create( &listener_tid,
2249                         0, slapd_daemon_task, NULL );
2250
2251                 if ( rc != 0 ) {
2252                         Debug( LDAP_DEBUG_ANY,
2253                         "listener ldap_pvt_thread_create failed (%d)\n", rc, 0, 0 );
2254                         return rc;
2255                 }
2256  
2257                 /* wait for the listener thread to complete */
2258                 ldap_pvt_thread_join( listener_tid, (void *) NULL );
2259         }
2260 #else
2261         /* experimental code */
2262         slapd_daemon_task( NULL );
2263 #endif
2264
2265         return 0;
2266
2267 }
2268
2269 static int sockinit(void)
2270 {
2271 #if defined( HAVE_WINSOCK2 )
2272     WORD wVersionRequested;
2273         WSADATA wsaData;
2274         int err;
2275
2276         wVersionRequested = MAKEWORD( 2, 0 );
2277
2278         err = WSAStartup( wVersionRequested, &wsaData );
2279         if ( err != 0 ) {
2280                 /* Tell the user that we couldn't find a usable */
2281                 /* WinSock DLL.                                  */
2282                 return -1;
2283         }
2284
2285         /* Confirm that the WinSock DLL supports 2.0.*/
2286         /* Note that if the DLL supports versions greater    */
2287         /* than 2.0 in addition to 2.0, it will still return */
2288         /* 2.0 in wVersion since that is the version we      */
2289         /* requested.                                        */
2290
2291         if ( LOBYTE( wsaData.wVersion ) != 2 ||
2292                 HIBYTE( wsaData.wVersion ) != 0 )
2293         {
2294             /* Tell the user that we couldn't find a usable */
2295             /* WinSock DLL.                                  */
2296             WSACleanup();
2297             return -1;
2298         }
2299
2300         /* The WinSock DLL is acceptable. Proceed. */
2301 #elif defined( HAVE_WINSOCK )
2302         WSADATA wsaData;
2303         if ( WSAStartup( 0x0101, &wsaData ) != 0 ) return -1;
2304 #endif
2305
2306         return 0;
2307 }
2308
2309 static int sockdestroy(void)
2310 {
2311 #if defined( HAVE_WINSOCK2 ) || defined( HAVE_WINSOCK )
2312         WSACleanup();
2313 #endif
2314         return 0;
2315 }
2316
2317 RETSIGTYPE
2318 slap_sig_shutdown( int sig )
2319 {
2320 #if 0
2321         Debug(LDAP_DEBUG_TRACE, "slap_sig_shutdown: signal %d\n", sig, 0, 0);
2322 #endif
2323
2324         /*
2325          * If the NT Service Manager is controlling the server, we don't
2326          * want SIGBREAK to kill the server. For some strange reason,
2327          * SIGBREAK is generated when a user logs out.
2328          */
2329
2330 #if HAVE_NT_SERVICE_MANAGER && SIGBREAK
2331         if (is_NT_Service && sig == SIGBREAK) {
2332                 /* empty */;
2333         } else
2334 #endif
2335 #ifdef SIGHUP
2336         if (sig == SIGHUP && global_gentlehup && slapd_gentle_shutdown == 0) {
2337                 slapd_gentle_shutdown = 1;
2338         } else
2339 #endif
2340         {
2341                 slapd_shutdown = 1;
2342         }
2343
2344         WAKE_LISTENER(1);
2345
2346         /* reinstall self */
2347         (void) SIGNAL_REINSTALL( sig, slap_sig_shutdown );
2348 }
2349
2350 RETSIGTYPE
2351 slap_sig_wake( int sig )
2352 {
2353         WAKE_LISTENER(1);
2354
2355         /* reinstall self */
2356         (void) SIGNAL_REINSTALL( sig, slap_sig_wake );
2357 }
2358
2359
2360 void slapd_add_internal(ber_socket_t s, int isactive) {
2361         slapd_add(s, isactive, NULL);
2362 }
2363
2364 Listener ** slapd_get_listeners(void) {
2365         return slap_listeners;
2366 }
2367
2368 void slap_wake_listener() {
2369         WAKE_LISTENER(1);
2370 }