]> git.sur5r.net Git - openldap/blob - servers/slapd/daemon.c
aca6614a0e5d108d0ead99bb89e73bf45ccfd909
[openldap] / servers / slapd / daemon.c
1 /* $OpenLDAP$ */
2 /*
3  * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
4  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
5  */
6
7 #include "portable.h"
8
9 #include <stdio.h>
10
11 #include <ac/ctype.h>
12 #include <ac/errno.h>
13 #include <ac/signal.h>
14 #include <ac/socket.h>
15 #include <ac/string.h>
16 #include <ac/time.h>
17 #include <ac/unistd.h>
18
19 #include "ldap_pvt.h"
20 #include "ldap_pvt_thread.h"
21 #include "lutil.h"
22 #include "slap.h"
23
24 #ifdef HAVE_TCPD
25 #include <tcpd.h>
26
27 int allow_severity = LOG_INFO;
28 int deny_severity = LOG_NOTICE;
29 #endif /* TCP Wrappers */
30
31 #ifdef LDAP_PF_LOCAL
32 #include <sys/stat.h>
33 /* this should go in <ldap.h> as soon as it is accepted */
34 #define LDAPI_MOD_URLEXT                "x-mod"
35 #endif /* LDAP_PF_LOCAL */
36
37 /* globals */
38 time_t starttime;
39 ber_socket_t dtblsize;
40
41 Listener **slap_listeners = NULL;
42
43 #define SLAPD_LISTEN 10
44
45 static ber_socket_t wake_sds[2];
46
47 #ifdef NO_THREADS
48 static int waking;
49 #define WAKE_LISTENER(w) \
50 ((w && !waking) ? tcp_write( wake_sds[1], "0", 1 ), waking=1 : 0)
51 #else
52 #define WAKE_LISTENER(w) \
53 do { if (w) tcp_write( wake_sds[1], "0", 1 ); } while(0)
54 #endif
55
56 #ifndef HAVE_WINSOCK
57 static
58 #endif
59 volatile sig_atomic_t slapd_shutdown = 0;
60
61 static struct slap_daemon {
62         ldap_pvt_thread_mutex_t sd_mutex;
63
64         int sd_nactives;
65
66 #ifndef HAVE_WINSOCK
67         /* In winsock, accept() returns values higher than dtblsize
68                 so don't bother with this optimization */
69         int sd_nfds;
70 #endif
71
72         fd_set sd_actives;
73         fd_set sd_readers;
74         fd_set sd_writers;
75 } slap_daemon;
76
77
78
79 #ifdef HAVE_SLP
80 /*
81  * SLP related functions
82  */
83 #include <slp.h>
84
85 #define LDAP_SRVTYPE_PREFIX "service:ldap://"
86 #define LDAPS_SRVTYPE_PREFIX "service:ldaps://"
87 static char** slapd_srvurls = NULL;
88 static SLPHandle slapd_hslp = 0;
89
90 void slapd_slp_init( const char* urls ) {
91         int i;
92
93         slapd_srvurls = str2charray( urls, " " );
94
95         if( slapd_srvurls == NULL ) return;
96
97         /* find and expand INADDR_ANY URLs */
98         for( i=0; slapd_srvurls[i] != NULL; i++ ) {
99                 if( strcmp( slapd_srvurls[i], "ldap:///" ) == 0) {
100                         char *host = ldap_pvt_get_fqdn( NULL );
101                         if ( host != NULL ) {
102                                 slapd_srvurls[i] = (char *) realloc( slapd_srvurls[i],
103                                         strlen( host ) +
104                                         sizeof( LDAP_SRVTYPE_PREFIX ) );
105                                 strcpy( slap_strcopy(slapd_srvurls[i],
106                                         LDAP_SRVTYPE_PREFIX ), host );
107
108                                 ch_free( host );
109                         }
110
111                 } else if ( strcmp( slapd_srvurls[i], "ldaps:///" ) == 0) {
112                         char *host = ldap_pvt_get_fqdn( NULL );
113                         if ( host != NULL ) {
114                                 slapd_srvurls[i] = (char *) realloc( slapd_srvurls[i],
115                                         strlen( host ) +
116                                         sizeof( LDAPS_SRVTYPE_PREFIX ) );
117                                 strcpy( slap_strcopy(slapd_srvurls[i],
118                                         LDAPS_SRVTYPE_PREFIX ), host );
119
120                                 ch_free( host );
121                         }
122                 }
123         }
124
125         /* open the SLP handle */
126         SLPOpen( "en", 0, &slapd_hslp );
127 }
128
129 void slapd_slp_deinit() {
130         if( slapd_srvurls == NULL ) return;
131
132         charray_free( slapd_srvurls );
133         slapd_srvurls = NULL;
134
135         /* close the SLP handle */
136         SLPClose( slapd_hslp );
137 }
138
139 void slapd_slp_regreport(
140         SLPHandle hslp,
141         SLPError errcode,
142         void* cookie )
143 {
144         /* empty report */
145 }
146
147 void slapd_slp_reg() {
148         int i;
149
150         for( i=0; slapd_srvurls[i] != NULL; i++ ) {
151                 if( strncmp( slapd_srvurls[i], LDAP_SRVTYPE_PREFIX,
152                                 sizeof( LDAP_SRVTYPE_PREFIX ) - 1 ) == 0 ||
153                     strncmp( slapd_srvurls[i], LDAPS_SRVTYPE_PREFIX,
154                                 sizeof( LDAPS_SRVTYPE_PREFIX ) - 1 ) == 0 )
155                 {
156                         SLPReg( slapd_hslp,
157                                 slapd_srvurls[i],
158                                 SLP_LIFETIME_MAXIMUM,
159                                 "ldap",
160                                 "",
161                                 1,
162                                 slapd_slp_regreport,
163                                 NULL );
164                 }
165         }
166 }
167
168 void slapd_slp_dereg() {
169         int i;
170
171         for( i=0; slapd_srvurls[i] != NULL; i++ ) {
172                 SLPDereg( slapd_hslp,
173                         slapd_srvurls[i],
174                         slapd_slp_regreport,
175                         NULL );
176         }
177 }
178 #endif /* HAVE_SLP */
179
180 /*
181  * Add a descriptor to daemon control
182  */
183 static void slapd_add(ber_socket_t s) {
184         ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
185
186         assert( !FD_ISSET( s, &slap_daemon.sd_actives ));
187         assert( !FD_ISSET( s, &slap_daemon.sd_readers ));
188         assert( !FD_ISSET( s, &slap_daemon.sd_writers ));
189
190 #ifndef HAVE_WINSOCK
191         if (s >= slap_daemon.sd_nfds) {
192                 slap_daemon.sd_nfds = s + 1;
193         }
194 #endif
195
196         FD_SET( s, &slap_daemon.sd_actives );
197         FD_SET( s, &slap_daemon.sd_readers );
198
199 #ifdef NEW_LOGGING
200         LDAP_LOG(( "connection", LDAP_LEVEL_DETAIL1,
201                    "slapd_add: added %ld%s%s\n",
202                    (long)s,
203                    FD_ISSET(s, &slap_daemon.sd_readers) ? "r" : "",
204                    FD_ISSET(s, &slap_daemon.sd_writers) ? "w" : "" ));
205 #else
206         Debug( LDAP_DEBUG_CONNS, "daemon: added %ld%s%s\n",
207                 (long) s,
208             FD_ISSET(s, &slap_daemon.sd_readers) ? "r" : "",
209                 FD_ISSET(s, &slap_daemon.sd_writers) ? "w" : "" );
210 #endif
211         ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
212 }
213
214 /*
215  * Remove the descriptor from daemon control
216  */
217 void slapd_remove(ber_socket_t s, int wake) {
218         ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
219
220 #ifdef NEW_LOGGING
221         LDAP_LOG(( "connection", LDAP_LEVEL_DETAIL1,
222                    "slapd_remove: removing %ld%s%s\n",
223                    (long) s,
224                    FD_ISSET(s, &slap_daemon.sd_readers) ? "r" : "",
225                    FD_ISSET(s, &slap_daemon.sd_writers) ? "w" : ""  ));
226 #else
227         Debug( LDAP_DEBUG_CONNS, "daemon: removing %ld%s%s\n",
228                 (long) s,
229             FD_ISSET(s, &slap_daemon.sd_readers) ? "r" : "",
230                 FD_ISSET(s, &slap_daemon.sd_writers) ? "w" : "" );
231 #endif
232         FD_CLR( s, &slap_daemon.sd_actives );
233         FD_CLR( s, &slap_daemon.sd_readers );
234         FD_CLR( s, &slap_daemon.sd_writers );
235
236         ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
237         WAKE_LISTENER(wake);
238 }
239
240 void slapd_clr_write(ber_socket_t s, int wake) {
241         ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
242
243         assert( FD_ISSET( s, &slap_daemon.sd_actives) );
244         FD_CLR( s, &slap_daemon.sd_writers );
245
246         ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
247         WAKE_LISTENER(wake);
248 }
249
250 void slapd_set_write(ber_socket_t s, int wake) {
251         ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
252
253         assert( FD_ISSET( s, &slap_daemon.sd_actives) );
254         if (!FD_ISSET(s, &slap_daemon.sd_writers))
255             FD_SET( (unsigned) s, &slap_daemon.sd_writers );
256
257         ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
258         WAKE_LISTENER(wake);
259 }
260
261 void slapd_clr_read(ber_socket_t s, int wake) {
262         ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
263
264         assert( FD_ISSET( s, &slap_daemon.sd_actives) );
265         FD_CLR( s, &slap_daemon.sd_readers );
266
267         ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
268         WAKE_LISTENER(wake);
269 }
270
271 void slapd_set_read(ber_socket_t s, int wake) {
272         ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
273
274         assert( FD_ISSET( s, &slap_daemon.sd_actives) );
275         if (!FD_ISSET(s, &slap_daemon.sd_readers))
276             FD_SET( s, &slap_daemon.sd_readers );
277
278         ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
279         WAKE_LISTENER(wake);
280 }
281
282 static void slapd_close(ber_socket_t s) {
283 #ifdef NEW_LOGGING
284         LDAP_LOG(( "connection", LDAP_LEVEL_DETAIL1,
285                    "slapd_close: closing %ld\n", (long)s ));
286 #else
287         Debug( LDAP_DEBUG_CONNS, "daemon: closing %ld\n",
288                 (long) s, 0, 0 );
289 #endif
290         tcp_close(s);
291 }
292
293 static void slap_free_listener_addresses(struct sockaddr **sal)
294 {
295         struct sockaddr **sap;
296
297         if (sal == NULL) {
298                 return;
299         }
300
301         for (sap = sal; *sap != NULL; sap++) {
302                 ch_free(*sap);
303         }
304
305         ch_free(sal);
306 }
307
308 #ifdef LDAP_PF_LOCAL
309 static int get_url_perms(
310         char    **exts,
311         mode_t  *perms,
312         int     *crit )
313 {
314         int     i;
315
316         assert( exts );
317         assert( perms );
318         assert( crit );
319
320         *crit = 0;
321         for ( i = 0; exts[ i ]; i++ ) {
322                 char    *type = exts[ i ];
323                 int     c = 0;
324
325                 if ( type[ 0 ] == '!' ) {
326                         c = 1;
327                         type++;
328                 }
329
330                 if ( strncasecmp( type, LDAPI_MOD_URLEXT "=", sizeof(LDAPI_MOD_URLEXT "=") - 1 ) == 0 ) {
331                         char    *value = type + sizeof(LDAPI_MOD_URLEXT "=") - 1;
332                         mode_t  p = 0;
333
334 #if 0
335                         if ( strlen( value ) != 9 ) {
336                                 return LDAP_OTHER;
337                         }
338
339                         switch ( value[ 0 ] ) {
340                         case 'r':
341                                 p |= S_IRUSR;
342                                 break;
343                         case '-':
344                                 break;
345                         default:
346                                 return LDAP_OTHER;
347                         } 
348
349                         switch ( value[ 1 ] ) {
350                         case 'w':
351                                 p |= S_IWUSR;
352                                 break;
353                         case '-':
354                                 break;
355                         default:
356                                 return LDAP_OTHER;
357                         } 
358
359                         switch ( value[ 2 ] ) {
360                         case 'x':
361                                 p |= S_IXUSR;
362                                 break;
363                         case '-':
364                                 break;
365                         default:
366                                 return LDAP_OTHER;
367                         } 
368
369                         switch ( value[ 3 ] ) {
370                         case 'r':
371                                 p |= S_IRGRP;
372                                 break;
373                         case '-':
374                                 break;
375                         default:
376                                 return LDAP_OTHER;
377                         } 
378
379                         switch ( value[ 4 ] ) {
380                         case 'w':
381                                 p |= S_IWGRP;
382                                 break;
383                         case '-':
384                                 break;
385                         default:
386                                 return LDAP_OTHER;
387                         } 
388
389                         switch ( value[ 5 ] ) {
390                         case 'x':
391                                 p |= S_IXGRP;
392                                 break;
393                         case '-':
394                                 break;
395                         default:
396                                 return LDAP_OTHER;
397                         } 
398
399                         switch ( value[ 6 ] ) {
400                         case 'r':
401                                 p |= S_IROTH;
402                                 break;
403                         case '-':
404                                 break;
405                         default:
406                                 return LDAP_OTHER;
407                         } 
408
409                         switch ( value[ 7 ] ) {
410                         case 'w':
411                                 p |= S_IWOTH;
412                                 break;
413                         case '-':
414                                 break;
415                         default:
416                                 return LDAP_OTHER;
417                         } 
418
419                         switch ( value[ 8 ] ) {
420                         case 'x':
421                                 p |= S_IXOTH;
422                                 break;
423                         case '-':
424                                 break;
425                         default:
426                                 return LDAP_OTHER;
427                         } 
428 #else
429                         if ( strlen(value) != 3 ) {
430                                 return LDAP_OTHER;
431                         } 
432
433                         switch ( value[ 0 ] ) {
434                         case 'w':
435                                 p |= S_IRWXU;
436                                 break;
437                         case '-':
438                                 break;
439                         default:
440                                 return LDAP_OTHER;
441                         } 
442
443                         switch ( value[ 1 ] ) {
444                         case 'w':
445                                 p |= S_IRWXG;
446                                 break;
447                         case '-':
448                                 break;
449                         default:
450                                 return LDAP_OTHER;
451                         } 
452
453                         switch ( value[ 2 ] ) {
454                         case 'w':
455                                 p |= S_IRWXO;
456                                 break;
457                         case '-':
458                                 break;
459                         default:
460                                 return LDAP_OTHER;
461                         } 
462 #endif
463
464                         *crit = c;
465                         *perms = p;
466
467                         return LDAP_SUCCESS;
468                 }
469         }
470 }
471 #endif /* LDAP_PF_LOCAL */
472
473 /* port = 0 indicates AF_LOCAL */
474 static int slap_get_listener_addresses(
475         const char *host,
476         unsigned short port,
477         struct sockaddr ***sal)
478 {
479         struct sockaddr **sap;
480
481 #ifdef LDAP_PF_LOCAL
482         if ( port == 0 ) {
483                 *sal = ch_malloc(2 * sizeof(void *));
484                 if (*sal == NULL) {
485                         return -1;
486                 }
487
488                 sap = *sal;
489                 *sap = ch_malloc(sizeof(struct sockaddr_un));
490                 if (*sap == NULL)
491                         goto errexit;
492                 sap[1] = NULL;
493
494                 if ( strlen(host) >
495                      (sizeof(((struct sockaddr_un *)*sap)->sun_path) - 1) ) {
496 #ifdef NEW_LOGGING
497                         LDAP_LOG(( "connection", LDAP_LEVEL_INFO,
498                                    "slap_get_listener_addresses: domain socket path (%s) too long in URL\n",
499                                    host ));
500 #else
501                         Debug( LDAP_DEBUG_ANY,
502                                "daemon: domain socket path (%s) too long in URL",
503                                host, 0, 0);
504 #endif
505                         goto errexit;
506                 }
507
508                 (void)memset( (void *)*sap, '\0', sizeof(struct sockaddr_un) );
509                 (*sap)->sa_family = AF_LOCAL;
510                 strcpy( ((struct sockaddr_un *)*sap)->sun_path, host );
511         } else
512 #endif
513         {
514 #ifdef HAVE_GETADDRINFO
515                 struct addrinfo hints, *res, *sai;
516                 int n, err;
517                 char serv[7];
518
519                 memset( &hints, '\0', sizeof(hints) );
520                 hints.ai_flags = AI_PASSIVE;
521                 hints.ai_socktype = SOCK_STREAM;
522                 hints.ai_family = AF_UNSPEC;
523                 snprintf(serv, sizeof serv, "%d", port);
524
525                 if ( (err = getaddrinfo(host, serv, &hints, &res)) ) {
526 #ifdef NEW_LOGGING
527                         LDAP_LOG(( "connection", LDAP_LEVEL_INFO,
528                                    "slap_get_listener_addresses: getaddrinfo failed: %s\n",
529                                    AC_GAI_STRERROR(err) ));
530 #else
531                         Debug( LDAP_DEBUG_ANY, "daemon: getaddrinfo failed: %s\n",
532                                 AC_GAI_STRERROR(err), 0, 0);
533 #endif
534                         return -1;
535                 }
536
537                 sai = res;
538                 for (n=2; (sai = sai->ai_next) != NULL; n++) {
539                         /* EMPTY */ ;
540                 }
541                 *sal = ch_calloc(n, sizeof(void *));
542                 if (*sal == NULL) {
543                         return -1;
544                 }
545
546                 sap = *sal;
547                 *sap = NULL;
548
549                 for ( sai=res; sai; sai=sai->ai_next ) {
550                         if( sai->ai_addr == NULL ) {
551 #ifdef NEW_LOGGING
552                                 LDAP_LOG(( "connection", LDAP_LEVEL_INFO,
553                                         "slap_get_listener_addresses: "
554                                         "getaddrinfo ai_addr is NULL?\n" ));
555 #else
556                                 Debug( LDAP_DEBUG_ANY, "slap_get_listener_addresses: "
557                                         "getaddrinfo ai_addr is NULL?\n", 0, 0, 0 );
558 #endif
559                                 freeaddrinfo(res);
560                                 goto errexit;
561                         }
562
563                         switch (sai->ai_family) {
564 #  ifdef LDAP_PF_INET6
565                         case AF_INET6:
566                                 *sap = ch_malloc(sizeof(struct sockaddr_in6));
567                                 if (*sap == NULL) {
568                                         freeaddrinfo(res);
569                                         goto errexit;
570                                 }
571                                 *(struct sockaddr_in6 *)*sap =
572                                         *((struct sockaddr_in6 *)sai->ai_addr);
573                                 break;
574 #  endif
575                         case AF_INET:
576                                 *sap = ch_malloc(sizeof(struct sockaddr_in));
577                                 if (*sap == NULL) {
578                                         freeaddrinfo(res);
579                                         goto errexit;
580                                 }
581                                 *(struct sockaddr_in *)*sap =
582                                         *((struct sockaddr_in *)sai->ai_addr);
583                                 break;
584                         default:
585                                 *sap = NULL;
586                                 break;
587                         }
588
589                         if (*sap != NULL) {
590                                 (*sap)->sa_family = sai->ai_family;
591                                 sap++;
592                                 *sap = NULL;
593                         }
594                 }
595
596                 freeaddrinfo(res);
597 #else
598                 struct in_addr in;
599
600                 if ( host == NULL ) {
601                         in.s_addr = htonl(INADDR_ANY);
602
603                 } else if ( !inet_aton( host, &in ) ) {
604                         struct hostent *he = gethostbyname( host );
605                         if( he == NULL ) {
606 #ifdef NEW_LOGGING
607                                 LDAP_LOG(( "connection", LDAP_LEVEL_INFO,
608                                            "slap_get_listener_addresses: invalid host %s\n",
609                                            host ));
610 #else
611                                 Debug( LDAP_DEBUG_ANY,
612                                        "daemon: invalid host %s", host, 0, 0);
613 #endif
614                                 return -1;
615                         }
616                         AC_MEMCPY( &in, he->h_addr, sizeof( in ) );
617                 }
618
619                 *sal = ch_malloc(2 * sizeof(void *));
620                 if (*sal == NULL) {
621                         return -1;
622                 }
623
624                 sap = *sal;
625                 *sap = ch_malloc(sizeof(struct sockaddr_in));
626                 if (*sap == NULL) {
627                         goto errexit;
628                 }
629                 sap[1] = NULL;
630
631                 (void)memset( (void *)*sap, '\0', sizeof(struct sockaddr_in) );
632                 (*sap)->sa_family = AF_INET;
633                 ((struct sockaddr_in *)*sap)->sin_port = htons(port);
634                 ((struct sockaddr_in *)*sap)->sin_addr = in;
635 #endif
636         }
637
638         return 0;
639
640 errexit:
641         slap_free_listener_addresses(*sal);
642         return -1;
643 }
644
645 static Listener * slap_open_listener(
646         const char* url )
647 {
648         int     tmp, rc;
649         Listener l;
650         Listener *li;
651         LDAPURLDesc *lud;
652         unsigned short port;
653         int err, addrlen = 0;
654         struct sockaddr **sal, **psal;
655         int socktype = SOCK_STREAM;     /* default to COTS */
656 #ifdef LDAP_PF_LOCAL
657         mode_t  perms = S_IRWXU;
658         int     crit = 1;
659 #endif
660
661         rc = ldap_url_parse( url, &lud );
662
663         if( rc != LDAP_URL_SUCCESS ) {
664 #ifdef NEW_LOGGING
665                 LDAP_LOG(( "connection", LDAP_LEVEL_ERR,
666                            "slap_open_listener: listen URL \"%s\" parse error %d\n",
667                            url, rc ));
668 #else
669                 Debug( LDAP_DEBUG_ANY,
670                         "daemon: listen URL \"%s\" parse error=%d\n",
671                         url, rc, 0 );
672 #endif
673                 return NULL;
674         }
675
676 #ifndef HAVE_TLS
677         if( ldap_pvt_url_scheme2tls( lud->lud_scheme ) ) {
678 #ifdef NEW_LOGGING
679                 LDAP_LOG(( "connection", LDAP_LEVEL_INFO,
680                            "slap_open_listener: TLS is not supported (%s)\n",
681                            url ));
682 #else
683                 Debug( LDAP_DEBUG_ANY,
684                         "daemon: TLS not supported (%s)\n",
685                         url, 0, 0 );
686 #endif
687                 ldap_free_urldesc( lud );
688                 return NULL;
689         }
690
691         if(! lud->lud_port ) {
692                 lud->lud_port = LDAP_PORT;
693         }
694
695 #else
696         l.sl_is_tls = ldap_pvt_url_scheme2tls( lud->lud_scheme );
697
698         if(! lud->lud_port ) {
699                 lud->lud_port = l.sl_is_tls ? LDAPS_PORT : LDAP_PORT;
700         }
701 #endif
702
703         port = (unsigned short) lud->lud_port;
704
705         tmp = ldap_pvt_url_scheme2proto(lud->lud_scheme);
706         if ( tmp == LDAP_PROTO_IPC ) {
707 #ifdef LDAP_PF_LOCAL
708                 if ( lud->lud_host == NULL || lud->lud_host[0] == '\0' ) {
709                         err = slap_get_listener_addresses(LDAPI_SOCK, 0, &sal);
710                 } else {
711                         err = slap_get_listener_addresses(lud->lud_host, 0, &sal);
712                 }
713
714                 if ( lud->lud_exts ) {
715                         err = get_url_perms( lud->lud_exts, &perms, &crit );
716                 }
717 #else
718
719 #ifdef NEW_LOGGING
720                 LDAP_LOG(( "connection", LDAP_LEVEL_INFO,
721                            "slap_open_listener: URL scheme is not supported: %s\n",
722                            url ));
723 #else
724                 Debug( LDAP_DEBUG_ANY, "daemon: URL scheme not supported: %s",
725                         url, 0, 0);
726 #endif
727                 ldap_free_urldesc( lud );
728                 return NULL;
729 #endif
730         } else {
731 #ifdef LDAP_CONNECTIONLESS
732                 l.sl_is_udp = ( tmp == LDAP_PROTO_UDP );
733 #endif
734                 if( lud->lud_host == NULL || lud->lud_host[0] == '\0'
735                         || strcmp(lud->lud_host, "*") == 0 )
736                 {
737                         err = slap_get_listener_addresses(NULL, port, &sal);
738                 } else {
739                         err = slap_get_listener_addresses(lud->lud_host, port, &sal);
740                 }
741         }
742
743         ldap_free_urldesc( lud );
744         if ( err ) {
745                 return NULL;
746         }
747
748         psal = sal;
749         while ( *sal != NULL ) {
750                 switch( (*sal)->sa_family ) {
751                 case AF_INET:
752 #ifdef LDAP_PF_INET6
753                 case AF_INET6:
754 #endif
755 #ifdef LDAP_PF_LOCAL
756                 case AF_LOCAL:
757 #endif
758                         break;
759                 default:
760                         sal++;
761                         continue;
762                 }
763 #ifdef LDAP_CONNECTIONLESS
764                 if (l.sl_is_udp)
765                     socktype = SOCK_DGRAM;
766 #endif
767                 l.sl_sd = socket( (*sal)->sa_family, socktype, 0);
768                 if ( l.sl_sd == AC_SOCKET_INVALID ) {
769                         int err = sock_errno();
770 #ifdef NEW_LOGGING
771                         LDAP_LOG(( "connection", LDAP_LEVEL_ERR,
772                                    "slap_open_listener: socket() failed errno=%d (%s)\n",
773                                    err, sock_errstr(err) ));
774 #else
775                         Debug( LDAP_DEBUG_ANY,
776                                 "daemon: socket() failed errno=%d (%s)\n", err,
777                                 sock_errstr(err), 0 );
778 #endif
779                         sal++;
780                         continue;
781                 }
782 #ifndef HAVE_WINSOCK
783                 if ( l.sl_sd >= dtblsize ) {
784 #ifdef NEW_LOGGING
785                         LDAP_LOG(( "connection", LDAP_LEVEL_ERR,
786                                    "slap_open_listener: listener descriptor %ld is too great %ld\n",
787                                    (long)l.sl_sd, (long)dtblsize ));
788 #else
789                         Debug( LDAP_DEBUG_ANY,
790                                "daemon: listener descriptor %ld is too great %ld\n",
791                                (long) l.sl_sd, (long) dtblsize, 0 );
792 #endif
793                         tcp_close( l.sl_sd );
794                         sal++;
795                         continue;
796                 }
797 #endif
798 #ifdef LDAP_PF_LOCAL
799                 if ( (*sal)->sa_family == AF_LOCAL ) {
800                         unlink ( ((struct sockaddr_un *)*sal)->sun_path );
801                 } else
802 #endif
803                 {
804 #ifdef SO_REUSEADDR
805                         /* enable address reuse */
806                         tmp = 1;
807                         rc = setsockopt( l.sl_sd, SOL_SOCKET, SO_REUSEADDR,
808                                          (char *) &tmp, sizeof(tmp) );
809                         if ( rc == AC_SOCKET_ERROR ) {
810                                 int err = sock_errno();
811 #ifdef NEW_LOGGING
812                                 LDAP_LOG(( "connection", LDAP_LEVEL_INFO,
813                                            "slap_open_listener: setsockopt( %ld, SO_REUSEADDR ) failed errno %d (%s)\n",
814                                            (long)l.sl_sd, err, sock_errstr(err) ));
815 #else
816                                 Debug( LDAP_DEBUG_ANY,
817                                        "slapd(%ld): setsockopt(SO_REUSEADDR) failed errno=%d (%s)\n",
818                                        (long) l.sl_sd, err, sock_errstr(err) );
819 #endif
820                         }
821 #endif
822                 }
823
824                 switch( (*sal)->sa_family ) {
825                 case AF_INET:
826                         addrlen = sizeof(struct sockaddr_in);
827                         break;
828 #ifdef LDAP_PF_INET6
829                 case AF_INET6:
830                         addrlen = sizeof(struct sockaddr_in6);
831                         break;
832 #endif
833 #ifdef LDAP_PF_LOCAL
834                 case AF_LOCAL:
835                         addrlen = sizeof(struct sockaddr_un);
836                         break;
837 #endif
838                 }
839
840                 if (!bind(l.sl_sd, *sal, addrlen))
841                         break;
842                 err = sock_errno();
843 #ifdef NEW_LOGGING
844                 LDAP_LOG(( "connection", LDAP_LEVEL_INFO,
845                            "slap_open_listener: bind(%ld) failed errno=%d (%s)\n",
846                            (long)l.sl_sd, err, sock_errstr(err) ));
847 #else
848                 Debug( LDAP_DEBUG_ANY, "daemon: bind(%ld) failed errno=%d (%s)\n",
849                        (long) l.sl_sd, err, sock_errstr(err) );
850 #endif
851                 tcp_close( l.sl_sd );
852                 sal++;
853         } /* while ( *sal != NULL ) */
854
855         if ( *sal == NULL ) {
856 #ifdef NEW_LOGGING
857                 LDAP_LOG(( "connection", LDAP_LEVEL_INFO,
858                            "slap_open_listener: bind(%ld) failed.\n", (long)l.sl_sd ));
859 #else
860                 Debug( LDAP_DEBUG_ANY, "daemon: bind(%ld) failed\n",
861                         (long) l.sl_sd, 0, 0 );
862 #endif
863                 slap_free_listener_addresses(psal);
864                 return NULL;
865         }
866
867         switch ( (*sal)->sa_family ) {
868 #ifdef LDAP_PF_LOCAL
869         case AF_LOCAL: {
870                 char *addr = ((struct sockaddr_un *)*sal)->sun_path;
871                 if ( chmod( addr, perms ) < 0 && crit ) {
872                         int err = sock_errno();
873 #ifdef NEW_LOGGING
874                         LDAP_LOG(( "connection", LDAP_LEVEL_INFO,
875                                    "slap_open_listener: fchmod(%ld) failed errno=%d (%s)\n",
876                                    (long)l.sl_sd, err, sock_errstr(err) ));
877 #else
878                         Debug( LDAP_DEBUG_ANY, "daemon: fchmod(%ld) failed errno=%d (%s)",
879                                (long) l.sl_sd, err, sock_errstr(err) );
880 #endif
881                         tcp_close( l.sl_sd );
882                         slap_free_listener_addresses(psal);
883                         return NULL;
884                 }
885                 l.sl_name = ch_malloc( strlen(addr) + sizeof("PATH=") );
886                 sprintf( l.sl_name, "PATH=%s", addr );
887         } break;
888 #endif /* LDAP_PF_LOCAL */
889
890         case AF_INET: {
891                 char *s;
892 #if defined( HAVE_GETADDRINFO ) && defined( HAVE_INET_NTOP )
893                 char addr[INET_ADDRSTRLEN];
894                 inet_ntop( AF_INET, &((struct sockaddr_in *)*sal)->sin_addr,
895                            addr, sizeof(addr) );
896                 s = addr;
897 #else
898                 s = inet_ntoa( ((struct sockaddr_in *) *sal)->sin_addr );
899 #endif
900                 port = ntohs( ((struct sockaddr_in *)*sal) ->sin_port );
901                 l.sl_name = ch_malloc( sizeof("IP=255.255.255.255:65535") );
902                 sprintf( l.sl_name, "IP=%s:%d",
903                          s != NULL ? s : "unknown" , port );
904         } break;
905
906 #ifdef LDAP_PF_INET6
907         case AF_INET6: {
908                 char addr[INET6_ADDRSTRLEN];
909                 inet_ntop( AF_INET6, &((struct sockaddr_in6 *)*sal)->sin6_addr,
910                            addr, sizeof addr);
911                 port = ntohs( ((struct sockaddr_in6 *)*sal)->sin6_port );
912                 l.sl_name = ch_malloc( strlen(addr) + sizeof("IP= 65535") );
913                 sprintf( l.sl_name, "IP=%s %d", addr, port );
914         } break;
915 #endif /* LDAP_PF_INET6 */
916
917         default:
918 #ifdef NEW_LOGGING
919                 LDAP_LOG(( "connection", LDAP_LEVEL_INFO,
920                            "slap_open_listener: unsupported address family (%d)\n",
921                            (int)(*sal)->sa_family ));
922 #else
923                 Debug( LDAP_DEBUG_ANY, "daemon: unsupported address family (%d)\n",
924                         (int) (*sal)->sa_family, 0, 0 );
925 #endif
926                 break;
927         }
928
929         slap_free_listener_addresses(psal);
930
931         l.sl_url = ch_strdup( url );
932         li = ch_malloc( sizeof( Listener ) );
933         *li = l;
934
935 #ifdef NEW_LOGGING
936         LDAP_LOG(( "connection", LDAP_LEVEL_RESULTS,
937                    "slap_open_listener: daemon initialzed %s\n", l.sl_url ));
938 #else
939         Debug( LDAP_DEBUG_TRACE, "daemon: initialized %s\n",
940                 l.sl_url, 0, 0 );
941 #endif
942         return li;
943 }
944
945 static int sockinit(void);
946 static int sockdestroy(void);
947
948 int slapd_daemon_init( const char *urls )
949 {
950         int i, rc;
951         char **u;
952
953 #ifdef NEW_LOGGING
954         LDAP_LOG(( "connection", LDAP_LEVEL_ARGS,
955                    "slapd_daemon_init: %s\n",
956                    urls ? urls : "<null>" ));
957 #else
958         Debug( LDAP_DEBUG_ARGS, "daemon_init: %s\n",
959                 urls ? urls : "<null>", 0, 0 );
960 #endif
961         if( (rc = sockinit()) != 0 ) {
962                 return rc;
963         }
964
965 #ifdef HAVE_SYSCONF
966         dtblsize = sysconf( _SC_OPEN_MAX );
967 #elif HAVE_GETDTABLESIZE
968         dtblsize = getdtablesize();
969 #else
970         dtblsize = FD_SETSIZE;
971 #endif
972
973 #ifdef FD_SETSIZE
974         if(dtblsize > FD_SETSIZE) {
975                 dtblsize = FD_SETSIZE;
976         }
977 #endif  /* !FD_SETSIZE */
978
979         /* open a pipe (or something equivalent connected to itself).
980          * we write a byte on this fd whenever we catch a signal. The main
981          * loop will be select'ing on this socket, and will wake up when
982          * this byte arrives.
983          */
984         if( (rc = lutil_pair( wake_sds )) < 0 ) {
985 #ifdef NEW_LOGGING
986                 LDAP_LOG(( "connection", LDAP_LEVEL_ERR,
987                            "slap_daemon_init: lutil_pair() failed rc=%d\n", rc ));
988 #else
989                 Debug( LDAP_DEBUG_ANY,
990                         "daemon: lutil_pair() failed rc=%d\n", rc, 0, 0 );
991 #endif
992                 return rc;
993         }
994
995         FD_ZERO( &slap_daemon.sd_readers );
996         FD_ZERO( &slap_daemon.sd_writers );
997
998         if( urls == NULL ) {
999                 urls = "ldap:///";
1000         }
1001
1002         u = str2charray( urls, " " );
1003
1004         if( u == NULL || u[0] == NULL ) {
1005 #ifdef NEW_LOGGING
1006                 LDAP_LOG(( "connection", LDAP_LEVEL_ERR,
1007                            "slap_daemon_init: no urls (%s) provided.\n", urls ));
1008 #else
1009                 Debug( LDAP_DEBUG_ANY, "daemon_init: no urls (%s) provided.\n",
1010                         urls, 0, 0 );
1011 #endif
1012                 return -1;
1013         }
1014
1015         for( i=0; u[i] != NULL; i++ ) {
1016 #ifdef NEW_LOGGING
1017                 LDAP_LOG(( "connection", LDAP_LEVEL_DETAIL1,
1018                            "slap_daemon_init: listen on %s\n.", u[i] ));
1019 #else
1020                 Debug( LDAP_DEBUG_TRACE, "daemon_init: listen on %s\n",
1021                         u[i], 0, 0 );
1022 #endif
1023         }
1024
1025         if( i == 0 ) {
1026 #ifdef NEW_LOGGING
1027                 LDAP_LOG(( "connection", LDAP_LEVEL_INFO,
1028                            "slap_daemon_init: no listeners to open (%s)\n", urls ));
1029 #else
1030                 Debug( LDAP_DEBUG_ANY, "daemon_init: no listeners to open (%s)\n",
1031                         urls, 0, 0 );
1032 #endif
1033                 charray_free( u );
1034                 return -1;
1035         }
1036
1037 #ifdef NEW_LOGGING
1038         LDAP_LOG(( "connection", LDAP_LEVEL_INFO,
1039                    "slap_daemon_init: %d listeners to open...\n", i ));
1040 #else
1041         Debug( LDAP_DEBUG_TRACE, "daemon_init: %d listeners to open...\n",
1042                 i, 0, 0 );
1043 #endif
1044         slap_listeners = ch_malloc( (i+1)*sizeof(Listener *) );
1045
1046         for(i = 0; u[i] != NULL; i++ ) {
1047                 slap_listeners[i] = slap_open_listener( u[i] );
1048
1049                 if( slap_listeners[i] == NULL ) {
1050                         charray_free( u );
1051                         return -1;
1052                 }
1053         }
1054         slap_listeners[i] = NULL;
1055
1056 #ifdef NEW_LOGGING
1057         LDAP_LOG(( "connection", LDAP_LEVEL_DETAIL1,
1058                    "slap_daemon_init: %d listeners opened\n", i ));
1059 #else
1060         Debug( LDAP_DEBUG_TRACE, "daemon_init: %d listeners opened\n",
1061                 i, 0, 0 );
1062 #endif
1063
1064 #ifdef HAVE_SLP
1065         slapd_slp_init( urls );
1066         slapd_slp_reg();
1067 #endif
1068
1069         charray_free( u );
1070         ldap_pvt_thread_mutex_init( &slap_daemon.sd_mutex );
1071         return !i;
1072 }
1073
1074
1075 int
1076 slapd_daemon_destroy(void)
1077 {
1078         connections_destroy();
1079         tcp_close( wake_sds[1] );
1080         tcp_close( wake_sds[0] );
1081         sockdestroy();
1082
1083 #ifdef HAVE_SLP
1084         slapd_slp_dereg();
1085         slapd_slp_deinit();
1086 #endif
1087
1088         return 0;
1089 }
1090
1091
1092 static void *
1093 slapd_daemon_task(
1094         void *ptr
1095 )
1096 {
1097         int l;
1098         time_t  last_idle_check = 0;
1099         time( &starttime );
1100
1101         if ( global_idletimeout > 0 ) {
1102                 last_idle_check = slap_get_time();
1103         }
1104         for ( l = 0; slap_listeners[l] != NULL; l++ ) {
1105                 if ( slap_listeners[l]->sl_sd == AC_SOCKET_INVALID )
1106                         continue;
1107 #ifdef LDAP_CONNECTIONLESS
1108                 /* Since this is connectionless, the data port is the
1109                  * listening port. The listen() and accept() calls
1110                  * are unnecessary.
1111                  */
1112                 if ( slap_listeners[l]->sl_is_udp )
1113                 {
1114                         slapd_add( slap_listeners[l]->sl_sd );
1115                         continue;
1116                 }
1117 #endif
1118
1119                 if ( listen( slap_listeners[l]->sl_sd, SLAPD_LISTEN ) == -1 ) {
1120                         int err = sock_errno();
1121 #ifdef NEW_LOGGING
1122                         LDAP_LOG(( "connection", LDAP_LEVEL_ERR,
1123                                    "slapd_daemon_task: listen( %s, 5 ) failed errno=%d (%s)\n",
1124                                    slap_listeners[l]->sl_url, err, sock_errstr(err) ));
1125 #else
1126                         Debug( LDAP_DEBUG_ANY,
1127                                 "daemon: listen(%s, 5) failed errno=%d (%s)\n",
1128                                         slap_listeners[l]->sl_url, err,
1129                                         sock_errstr(err) );
1130 #endif
1131                         return( (void*)-1 );
1132                 }
1133
1134                 slapd_add( slap_listeners[l]->sl_sd );
1135         }
1136
1137 #ifdef HAVE_NT_SERVICE_MANAGER
1138         if ( started_event != NULL ) {
1139                 ldap_pvt_thread_cond_signal( &started_event );
1140         }
1141 #endif
1142         /* initialization complete. Here comes the loop. */
1143
1144         while ( !slapd_shutdown ) {
1145                 ber_socket_t i;
1146                 int ns;
1147                 int at;
1148                 ber_socket_t nfds;
1149 #define SLAPD_EBADF_LIMIT 16
1150                 int ebadf = 0;
1151                 int emfile = 0;
1152
1153 #define SLAPD_IDLE_CHECK_LIMIT 4
1154                 time_t  now;
1155
1156
1157                 fd_set                  readfds;
1158                 fd_set                  writefds;
1159                 Sockaddr                from;
1160
1161 #if defined(SLAPD_RLOOKUPS)
1162                 struct hostent          *hp;
1163 #endif
1164                 struct timeval          zero;
1165                 struct timeval          *tvp;
1166
1167                 if( emfile ) {
1168                         now = slap_get_time();
1169                         connections_timeout_idle( now );
1170                 }
1171                 else if ( global_idletimeout > 0 ) {
1172                         now = slap_get_time();
1173                         if ( difftime( last_idle_check+global_idletimeout/SLAPD_IDLE_CHECK_LIMIT, now ) < 0 ) {
1174                                 connections_timeout_idle( now );
1175                         }
1176                 }
1177
1178                 FD_ZERO( &writefds );
1179                 FD_ZERO( &readfds );
1180
1181                 zero.tv_sec = 0;
1182                 zero.tv_usec = 0;
1183
1184                 ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
1185
1186 #ifdef FD_SET_MANUAL_COPY
1187                 for( s = 0; s < nfds; s++ ) {
1188                         if(FD_ISSET( &slap_sd_readers, s )) {
1189                                 FD_SET( s, &readfds );
1190                         }
1191                         if(FD_ISSET( &slap_sd_writers, s )) {
1192                                 FD_SET( s, &writefds );
1193                         }
1194                 }
1195 #else
1196                 AC_MEMCPY( &readfds, &slap_daemon.sd_readers, sizeof(fd_set) );
1197                 AC_MEMCPY( &writefds, &slap_daemon.sd_writers, sizeof(fd_set) );
1198 #endif
1199                 assert(!FD_ISSET(wake_sds[0], &readfds));
1200                 FD_SET( wake_sds[0], &readfds );
1201
1202                 for ( l = 0; slap_listeners[l] != NULL; l++ ) {
1203                         if ( slap_listeners[l]->sl_sd == AC_SOCKET_INVALID )
1204                                 continue;
1205                         if (!FD_ISSET(slap_listeners[l]->sl_sd, &readfds))
1206                             FD_SET( slap_listeners[l]->sl_sd, &readfds );
1207                 }
1208
1209 #ifndef HAVE_WINSOCK
1210                 nfds = slap_daemon.sd_nfds;
1211 #else
1212                 nfds = dtblsize;
1213 #endif
1214
1215                 ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
1216
1217                 at = ldap_pvt_thread_pool_backload(&connection_pool);
1218
1219 #if defined( HAVE_YIELDING_SELECT ) || defined( NO_THREADS )
1220                 tvp = NULL;
1221 #else
1222                 tvp = at ? &zero : NULL;
1223 #endif
1224
1225                 for ( l = 0; slap_listeners[l] != NULL; l++ ) {
1226                         if ( slap_listeners[l]->sl_sd == AC_SOCKET_INVALID )
1227                                 continue;
1228
1229 #ifdef NEW_LOGGING
1230                         LDAP_LOG(( "connection", LDAP_LEVEL_DETAIL1,
1231                                    "slapd_daemon_task: select: listen=%d active_threads=%d tvp=%s\n",
1232                                    slap_listeners[l]->sl_sd, at, tvp == NULL ? "NULL" : "zero" ));
1233 #else
1234                         Debug( LDAP_DEBUG_CONNS,
1235                                 "daemon: select: listen=%d active_threads=%d tvp=%s\n",
1236                                         slap_listeners[l]->sl_sd, at,
1237                                         tvp == NULL ? "NULL" : "zero" );
1238 #endif
1239                 }
1240
1241                 switch(ns = select( nfds, &readfds,
1242 #ifdef HAVE_WINSOCK
1243                         /* don't pass empty fd_set */
1244                         ( writefds.fd_count > 0 ? &writefds : NULL ),
1245 #else
1246                         &writefds,
1247 #endif
1248                         NULL, tvp ))
1249                 {
1250                 case -1: {      /* failure - try again */
1251                                 int err = sock_errno();
1252
1253                                 if( err == EBADF
1254 #ifdef WSAENOTSOCK
1255                                         /* you'd think this would be EBADF */
1256                                         || err == WSAENOTSOCK
1257 #endif
1258                                 ) {
1259                                         if (++ebadf < SLAPD_EBADF_LIMIT)
1260                                                 continue;
1261                                 }
1262
1263                                 if( err != EINTR ) {
1264 #ifdef NEW_LOGGING
1265                                         LDAP_LOG(( "connection", LDAP_LEVEL_INFO,
1266                                                    "slapd_daemon_task: select failed (%d): %s\n",
1267                                                    err, sock_errstr(err) ));
1268 #else
1269                                         Debug( LDAP_DEBUG_CONNS,
1270                                                 "daemon: select failed (%d): %s\n",
1271                                                 err, sock_errstr(err), 0 );
1272 #endif
1273                                         slapd_shutdown = -1;
1274                                 }
1275                         }
1276                         continue;
1277
1278                 case 0:         /* timeout - let threads run */
1279                         ebadf = 0;
1280 #ifdef NEW_LOGGING
1281                         LDAP_LOG(( "connection", LDAP_LEVEL_DETAIL2,
1282                                    "slapd_daemon_task: select timeout - yielding\n" ));
1283 #else
1284                         Debug( LDAP_DEBUG_CONNS, "daemon: select timeout - yielding\n",
1285                             0, 0, 0 );
1286 #endif
1287                         ldap_pvt_thread_yield();
1288                         continue;
1289
1290                 default:        /* something happened - deal with it */
1291                         if( slapd_shutdown ) continue;
1292
1293                         ebadf = 0;
1294 #ifdef NEW_LOGGING
1295                         LDAP_LOG(( "connection", LDAP_LEVEL_DETAIL2,
1296                                    "slapd_daemon_task: activity on %d descriptors\n", ns ));
1297 #else
1298                         Debug( LDAP_DEBUG_CONNS, "daemon: activity on %d descriptors\n",
1299                                 ns, 0, 0 );
1300 #endif
1301                         /* FALL THRU */
1302                 }
1303
1304                 if( FD_ISSET( wake_sds[0], &readfds ) ) {
1305                         char c[BUFSIZ];
1306                         tcp_read( wake_sds[0], c, sizeof(c) );
1307 #ifdef NO_THREADS
1308                         waking = 0;
1309 #endif
1310                         continue;
1311                 }
1312
1313                 for ( l = 0; slap_listeners[l] != NULL; l++ ) {
1314                         ber_socket_t s;
1315                         socklen_t len = sizeof(from);
1316                         long id;
1317                         slap_ssf_t ssf = 0;
1318                         char *authid = NULL;
1319
1320                         char    *dnsname = NULL;
1321                         char    *peeraddr;
1322 #ifdef LDAP_PF_LOCAL
1323                         char    peername[MAXPATHLEN + sizeof("PATH=")];
1324 #elif defined(LDAP_PF_INET6)
1325                         char    peername[sizeof("IP=ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff 65535")];
1326 #else
1327                         char    peername[sizeof("IP=255.255.255.255:65336")];
1328 #endif /* LDAP_PF_LOCAL */
1329
1330                         peername[0] = '\0';
1331
1332                         if ( slap_listeners[l]->sl_sd == AC_SOCKET_INVALID )
1333                                 continue;
1334
1335                         if ( !FD_ISSET( slap_listeners[l]->sl_sd, &readfds ) )
1336                                 continue;
1337
1338 #ifdef LDAP_CONNECTIONLESS
1339                         if ( slap_listeners[l]->sl_is_udp )
1340                         {
1341                         /* The first time we receive a query, we set this
1342                          * up as a "connection". It remains open for the life
1343                          * of the slapd.
1344                          */
1345                                 if ( slap_listeners[l]->sl_is_udp < 2 )
1346                                 {
1347                                     id = connection_init(
1348                                         slap_listeners[l]->sl_sd,
1349                                         slap_listeners[l]->sl_url, "", "",
1350                                         slap_listeners[l]->sl_name,
1351                                         2, ssf, authid );
1352                                     slap_listeners[l]->sl_is_udp++;
1353                                 }
1354                                 continue;
1355                         }
1356 #endif
1357
1358                         s = accept( slap_listeners[l]->sl_sd,
1359                                 (struct sockaddr *) &from, &len );
1360                         if ( s == AC_SOCKET_INVALID ) {
1361                                 int err = sock_errno();
1362
1363 #ifdef EMFILE
1364                                 if( err == EMFILE ) {
1365                                         emfile++;
1366                                 } else
1367 #endif
1368 #ifdef ENFILE
1369                                 if( err == ENFILE ) {
1370                                         emfile++;
1371                                 } else 
1372 #endif
1373                                 {
1374                                         emfile=0;
1375                                 }
1376
1377                                 if( emfile < 3 ) {
1378 #ifdef NEW_LOGGING
1379                                         LDAP_LOG(( "connection", LDAP_LEVEL_ERR,
1380                                                 "slapd_daemon_task: accept(%ld) failed errno=%d (%s)\n",
1381                                                 (long)slap_listeners[l]->sl_sd, err, sock_errstr(err) ));
1382 #else
1383                                         Debug( LDAP_DEBUG_ANY,
1384                                             "daemon: accept(%ld) failed errno=%d (%s)\n",
1385                                             (long) slap_listeners[l]->sl_sd, err,
1386                                             sock_errstr(err) );
1387 #endif
1388                                 } else {
1389                                         /* prevent busy loop */
1390 #  ifdef HAVE_USLEEP
1391                                         if( emfile % 4 == 3 ) usleep( 250 );
1392 #  else
1393                                         if( emfile % 8 == 7 ) sleep( 1 );
1394 #  endif
1395                                 }
1396
1397                                 ldap_pvt_thread_yield();
1398                                 continue;
1399                         }
1400                         emfile = 0;
1401
1402 #ifndef HAVE_WINSOCK
1403                         /* make sure descriptor number isn't too great */
1404                         if ( s >= dtblsize ) {
1405 #ifdef NEW_LOGGING
1406                                 LDAP_LOG(( "connection", LDAP_LEVEL_ERR,
1407                                    "slapd_daemon_task: %ld beyond descriptor table size %ld\n",
1408                                    (long)s, (long)dtblsize ));
1409 #else
1410                                 Debug( LDAP_DEBUG_ANY,
1411                                         "daemon: %ld beyond descriptor table size %ld\n",
1412                                         (long) s, (long) dtblsize, 0 );
1413 #endif
1414
1415                                 slapd_close(s);
1416                                 ldap_pvt_thread_yield();
1417                                 continue;
1418                         }
1419 #endif
1420
1421 #ifdef LDAP_DEBUG
1422                         ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
1423
1424                         /* newly accepted stream should not be in any of the FD SETS */
1425                         assert( !FD_ISSET( s, &slap_daemon.sd_actives) );
1426                         assert( !FD_ISSET( s, &slap_daemon.sd_readers) );
1427                         assert( !FD_ISSET( s, &slap_daemon.sd_writers) );
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 #ifdef NEW_LOGGING
1448                                         LDAP_LOG(( "connection", LDAP_LEVEL_ERR,
1449                                                    "slapd_daemon_task: setsockopt( %ld, SO_KEEPALIVE) failed errno=%d (%s)\n",
1450                                                    (long)s, err, sock_errstr(err) ));
1451 #else
1452                                         Debug( LDAP_DEBUG_ANY,
1453                                                 "slapd(%ld): setsockopt(SO_KEEPALIVE) failed "
1454                                                 "errno=%d (%s)\n", (long) s, err, sock_errstr(err) );
1455 #endif
1456                                 }
1457 #endif
1458 #ifdef TCP_NODELAY
1459                                 /* enable no delay */
1460                                 tmp = 1;
1461                                 rc = setsockopt( s, IPPROTO_TCP, TCP_NODELAY,
1462                                         (char *)&tmp, sizeof(tmp) );
1463                                 if ( rc == AC_SOCKET_ERROR ) {
1464                                         int err = sock_errno();
1465 #ifdef NEW_LOGGING
1466                                         LDAP_LOG(( "connection", LDAP_LEVEL_ERR,
1467                                                    "slapd_daemon_task: setsockopt( %ld, TCP_NODELAY) failed errno=%d (%s)\n",
1468                                                    (long)s, err, sock_errstr(err) ));
1469 #else
1470                                         Debug( LDAP_DEBUG_ANY,
1471                                                 "slapd(%ld): setsockopt(TCP_NODELAY) failed "
1472                                                 "errno=%d (%s)\n", (long) s, err, sock_errstr(err) );
1473 #endif
1474                                 }
1475 #endif
1476                         }
1477 #endif
1478
1479 #ifdef NEW_LOGGING
1480                         LDAP_LOG(( "connection", LDAP_LEVEL_DETAIL1,
1481                                    "slapd_daemon_task: new connection on %ld\n", (long)s ));
1482 #else
1483                         Debug( LDAP_DEBUG_CONNS, "daemon: new connection on %ld\n",
1484                                 (long) s, 0, 0 );
1485 #endif
1486                         switch ( from.sa_addr.sa_family ) {
1487 #  ifdef LDAP_PF_LOCAL
1488                         case AF_LOCAL:
1489                                 sprintf( peername, "PATH=%s", from.sa_un_addr.sun_path );
1490                                 ssf = LDAP_PVT_SASL_LOCAL_SSF;
1491                                 dnsname = "local";
1492                                 break;
1493 #endif /* LDAP_PF_LOCAL */
1494
1495 #  ifdef LDAP_PF_INET6
1496                         case AF_INET6:
1497                         if ( IN6_IS_ADDR_V4MAPPED(&from.sa_in6_addr.sin6_addr) ) {
1498                                 peeraddr = inet_ntoa( *((struct in_addr *)
1499                                                         &from.sa_in6_addr.sin6_addr.s6_addr[12]) );
1500                                 sprintf( peername, "IP=%s:%d",
1501                                          peeraddr != NULL ? peeraddr : "unknown",
1502                                          (unsigned) ntohs( from.sa_in6_addr.sin6_port ) );
1503                         } else {
1504                                 char addr[INET6_ADDRSTRLEN];
1505                                 sprintf( peername, "IP=%s %d",
1506                                          inet_ntop( AF_INET6,
1507                                                     &from.sa_in6_addr.sin6_addr,
1508                                                     addr, sizeof addr) ? addr : "unknown",
1509                                          (unsigned) ntohs( from.sa_in6_addr.sin6_port ) );
1510                         }
1511                         break;
1512 #  endif /* LDAP_PF_INET6 */
1513
1514                         case AF_INET:
1515                         peeraddr = inet_ntoa( from.sa_in_addr.sin_addr );
1516                         sprintf( peername, "IP=%s:%d",
1517                                 peeraddr != NULL ? peeraddr : "unknown",
1518                                 (unsigned) ntohs( from.sa_in_addr.sin_port ) );
1519                                 break;
1520
1521                         default:
1522                                 slapd_close(s);
1523                                 continue;
1524                         }
1525
1526                         if ( ( from.sa_addr.sa_family == AF_INET )
1527 #ifdef LDAP_PF_INET6
1528                                 || ( from.sa_addr.sa_family == AF_INET6 )
1529 #endif
1530                         ) {
1531 #ifdef SLAPD_RLOOKUPS
1532 #  ifdef LDAP_PF_INET6
1533                                 if ( from.sa_addr.sa_family == AF_INET6 )
1534                                         hp = gethostbyaddr(
1535                                                 (char *)&(from.sa_in6_addr.sin6_addr),
1536                                                 sizeof(from.sa_in6_addr.sin6_addr),
1537                                                 AF_INET6 );
1538                                 else
1539 #  endif /* LDAP_PF_INET6 */
1540                                 hp = gethostbyaddr(
1541                                         (char *) &(from.sa_in_addr.sin_addr),
1542                                         sizeof(from.sa_in_addr.sin_addr),
1543                                         AF_INET );
1544                                 dnsname = hp ? ldap_pvt_str2lower( hp->h_name ) : NULL;
1545 #else
1546                                 dnsname = NULL;
1547 #endif /* SLAPD_RLOOKUPS */
1548
1549 #ifdef HAVE_TCPD
1550                                 if ( !hosts_ctl("slapd",
1551                                                 dnsname != NULL ? dnsname : STRING_UNKNOWN,
1552                                                 peeraddr != NULL ? peeraddr : STRING_UNKNOWN,
1553                                                 STRING_UNKNOWN ))
1554                                 {
1555                                         /* DENY ACCESS */
1556                                         Statslog( LDAP_DEBUG_ANY,
1557                                                 "fd=%ld host access from %s (%s) denied.\n",
1558                                                 (long) s,
1559                                                 dnsname != NULL ? dnsname : "unknown",
1560                                                 peeraddr != NULL ? peeraddr : "unknown",
1561                                                 0, 0 );
1562                                         slapd_close(s);
1563                                         continue;
1564                                 }
1565 #endif /* HAVE_TCPD */
1566                         }
1567
1568                         id = connection_init(s,
1569                                 slap_listeners[l]->sl_url,
1570                                 dnsname != NULL ? dnsname : "unknown",
1571                                 peername,
1572                                 slap_listeners[l]->sl_name,
1573 #ifdef HAVE_TLS
1574                                 slap_listeners[l]->sl_is_tls,
1575 #else
1576                                 0,
1577 #endif
1578                                 ssf,
1579                                 authid );
1580
1581                         if( authid ) ch_free(authid);
1582
1583                         if( id < 0 ) {
1584 #ifdef NEW_LOGGING
1585                                 LDAP_LOG(( "connection", LDAP_LEVEL_INFO,
1586                                            "slapd_daemon_task: connection_init(%ld, %s, %s) failed.\n",
1587                                            (long)s, peername, slap_listeners[l]->sl_name ));
1588 #else
1589                                 Debug( LDAP_DEBUG_ANY,
1590                                         "daemon: connection_init(%ld, %s, %s) failed.\n",
1591                                         (long) s,
1592                                         peername,
1593                                         slap_listeners[l]->sl_name );
1594 #endif
1595                                 slapd_close(s);
1596                                 continue;
1597                         }
1598
1599                         Statslog( LDAP_DEBUG_STATS,
1600                                 "daemon: conn=%ld fd=%ld connection from %s (%s) accepted.\n",
1601                                 id, (long) s,
1602                                 peername,
1603                                 slap_listeners[l]->sl_name,
1604                                 0 );
1605
1606                         slapd_add( s );
1607                         continue;
1608                 }
1609
1610 #ifdef LDAP_DEBUG
1611 #ifdef NEW_LOGGING
1612                 LDAP_LOG(( "connection", LDAP_LEVEL_DETAIL2,
1613                            "slapd_daemon_task: activity on " ));
1614 #else
1615                 Debug( LDAP_DEBUG_CONNS, "daemon: activity on:", 0, 0, 0 );
1616 #endif
1617 #ifdef HAVE_WINSOCK
1618                 for ( i = 0; i < readfds.fd_count; i++ ) {
1619 #ifdef NEW_LOGGING
1620                         LDAP_LOG(( "connection", LDAP_LEVEL_DETAIL2,
1621                                    " %d%s", readfds.fd_array[i], "r", 0 ));
1622 #else
1623                         Debug( LDAP_DEBUG_CONNS, " %d%s",
1624                                 readfds.fd_array[i], "r", 0 );
1625 #endif
1626                 }
1627                 for ( i = 0; i < writefds.fd_count; i++ ) {
1628 #ifdef NEW_LOGGING
1629                         LDAP_LOG(( "connection", LDAP_LEVEL_DETAIL2,
1630                                    " %d%s", writefds.fd_array[i], "w" ));
1631 #else
1632                         Debug( LDAP_DEBUG_CONNS, " %d%s",
1633                                 writefds.fd_array[i], "w", 0 );
1634 #endif
1635                 }
1636
1637 #else
1638                 for ( i = 0; i < nfds; i++ ) {
1639                         int     r, w;
1640                         int     is_listener = 0;
1641
1642                         for ( l = 0; slap_listeners[l] != NULL; l++ ) {
1643                                 if ( i == slap_listeners[l]->sl_sd ) {
1644 #ifdef LDAP_CONNECTIONLESS
1645                                 /* The listener is the data port. Don't
1646                                  * skip it.
1647                                  */
1648                                         if (slap_listeners[l]->sl_is_udp)
1649                                                 continue;
1650 #endif
1651                                         is_listener = 1;
1652                                         break;
1653                                 }
1654                         }
1655                         if ( is_listener ) {
1656                                 continue;
1657                         }
1658                         r = FD_ISSET( i, &readfds );
1659                         w = FD_ISSET( i, &writefds );
1660                         if ( r || w ) {
1661 #ifdef NEW_LOGGING
1662                                 LDAP_LOG(( "connection", LDAP_LEVEL_DETAIL2,
1663                                            " %d%s%s", i,
1664                                            r ? "r" : "", w ? "w" : "" ));
1665 #else
1666                                 Debug( LDAP_DEBUG_CONNS, " %d%s%s", i,
1667                                     r ? "r" : "", w ? "w" : "" );
1668 #endif
1669                         }
1670                 }
1671 #endif
1672 #ifdef NEW_LOGGING
1673                 LDAP_LOG(( "connection", LDAP_LEVEL_DETAIL2, "\n" ));
1674 #else
1675                 Debug( LDAP_DEBUG_CONNS, "\n", 0, 0, 0 );
1676 #endif
1677
1678 #endif
1679
1680                 /* loop through the writers */
1681 #ifdef HAVE_WINSOCK
1682                 for ( i = 0; i < writefds.fd_count; i++ )
1683 #else
1684                 for ( i = 0; i < nfds; i++ )
1685 #endif
1686                 {
1687                         ber_socket_t wd;
1688                         int is_listener = 0;
1689 #ifdef HAVE_WINSOCK
1690                         wd = writefds.fd_array[i];
1691 #else
1692                         if( ! FD_ISSET( i, &writefds ) ) {
1693                                 continue;
1694                         }
1695                         wd = i;
1696 #endif
1697
1698                         for ( l = 0; slap_listeners[l] != NULL; l++ ) {
1699                                 if ( i == slap_listeners[l]->sl_sd ) {
1700 #ifdef LDAP_CONNECTIONLESS
1701                                         if (slap_listeners[l]->sl_is_udp)
1702                                                 continue;
1703 #endif
1704                                         is_listener = 1;
1705                                         break;
1706                                 }
1707                         }
1708                         if ( is_listener ) {
1709                                 continue;
1710                         }
1711 #ifdef NEW_LOGGING
1712                         LDAP_LOG(( "connection", LDAP_LEVEL_DETAIL2,
1713                                    "slapd_daemon_task: write active on %d\n", wd ));
1714 #else
1715                         Debug( LDAP_DEBUG_CONNS,
1716                                 "daemon: write active on %d\n",
1717                                 wd, 0, 0 );
1718 #endif
1719                         /*
1720                          * NOTE: it is possible that the connection was closed
1721                          * and that the stream is now inactive.
1722                          * connection_write() must valid the stream is still
1723                          * active.
1724                          */
1725
1726                         if ( connection_write( wd ) < 0 ) {
1727                                 FD_CLR( (unsigned) wd, &readfds );
1728                                 slapd_close( wd );
1729                         }
1730                 }
1731
1732 #ifdef HAVE_WINSOCK
1733                 for ( i = 0; i < readfds.fd_count; i++ )
1734 #else
1735                 for ( i = 0; i < nfds; i++ )
1736 #endif
1737                 {
1738                         ber_socket_t rd;
1739                         int is_listener = 0;
1740
1741 #ifdef HAVE_WINSOCK
1742                         rd = readfds.fd_array[i];
1743 #else
1744                         if( ! FD_ISSET( i, &readfds ) ) {
1745                                 continue;
1746                         }
1747                         rd = i;
1748 #endif
1749
1750                         for ( l = 0; slap_listeners[l] != NULL; l++ ) {
1751                                 if ( rd == slap_listeners[l]->sl_sd ) {
1752 #ifdef LDAP_CONNECTIONLESS
1753                                         if (slap_listeners[l]->sl_is_udp)
1754                                                 continue;
1755 #endif
1756                                         is_listener = 1;
1757                                         break;
1758                                 }
1759                         }
1760                         if ( is_listener ) {
1761                                 continue;
1762                         }
1763
1764 #ifdef NEW_LOGGING
1765                         LDAP_LOG(( "connection", LDAP_LEVEL_DETAIL2,
1766                                    "slapd_daemon_task: read activity on %d\n", rd ));
1767 #else
1768                         Debug ( LDAP_DEBUG_CONNS,
1769                                 "daemon: read activity on %d\n", rd, 0, 0 );
1770 #endif
1771                         /*
1772                          * NOTE: it is possible that the connection was closed
1773                          * and that the stream is now inactive.
1774                          * connection_read() must valid the stream is still
1775                          * active.
1776                          */
1777
1778                         if ( connection_read( rd ) < 0 ) {
1779                                 slapd_close( rd );
1780                         }
1781                 }
1782                 ldap_pvt_thread_yield();
1783         }
1784
1785         if( slapd_shutdown > 0 ) {
1786 #ifdef NEW_LOGGING
1787                 LDAP_LOG(( "connection", LDAP_LEVEL_CRIT,
1788                            "slapd_daemon_task: shutdown requested and initiated.\n"));
1789 #else
1790                 Debug( LDAP_DEBUG_TRACE,
1791                         "daemon: shutdown requested and initiated.\n",
1792                         0, 0, 0 );
1793 #endif
1794
1795         } else if ( slapd_shutdown < 0 ) {
1796 #ifdef HAVE_NT_SERVICE_MANAGER
1797                 if (slapd_shutdown == -1)
1798                 {
1799 #ifdef NEW_LOGGING
1800                         LDAP_LOG(( "connection", LDAP_LEVEL_CRIT,
1801                                    "slapd_daemon_task: shutdown initiated by Service Manager.\n"));
1802 #else
1803                         Debug( LDAP_DEBUG_TRACE,
1804                                "daemon: shutdown initiated by Service Manager.\n",
1805                                0, 0, 0);
1806 #endif
1807                 }
1808                 else
1809 #endif
1810                 {
1811 #ifdef NEW_LOGGING
1812                         LDAP_LOG(( "connection", LDAP_LEVEL_CRIT,
1813                                    "slapd_daemon_task: abnormal condition, shutdown initiated.\n" ));
1814 #else
1815                         Debug( LDAP_DEBUG_TRACE,
1816                                "daemon: abnormal condition, shutdown initiated.\n",
1817                                0, 0, 0 );
1818 #endif
1819                 }
1820         } else {
1821 #ifdef NEW_LOGGING
1822                 LDAP_LOG(( "connection", LDAP_LEVEL_CRIT,
1823                            "slapd_daemon_task: no active streams, shutdown initiated.\n" ));
1824 #else
1825                 Debug( LDAP_DEBUG_TRACE,
1826                        "daemon: no active streams, shutdown initiated.\n",
1827                        0, 0, 0 );
1828 #endif
1829         }
1830
1831         for ( l = 0; slap_listeners[l] != NULL; l++ ) {
1832                 if ( slap_listeners[l]->sl_sd != AC_SOCKET_INVALID ) {
1833 #ifdef LDAP_PF_LOCAL
1834                         if ( slap_listeners[l]->sl_sa.sa_addr.sa_family == AF_LOCAL ) {
1835                                 unlink( slap_listeners[l]->sl_sa.sa_un_addr.sun_path );
1836                         }
1837 #endif /* LDAP_PF_LOCAL */
1838                         slapd_close( slap_listeners[l]->sl_sd );
1839                 }
1840                 if ( slap_listeners[l]->sl_url )
1841                         free ( slap_listeners[l]->sl_url );
1842                 if ( slap_listeners[l]->sl_name )
1843                         free ( slap_listeners[l]->sl_name );
1844                 free ( slap_listeners[l] );
1845         }
1846         free ( slap_listeners );
1847         slap_listeners = NULL;
1848
1849 #ifdef NEW_LOGGING
1850         LDAP_LOG(( "connection", LDAP_LEVEL_CRIT,
1851                    "slapd_daemon_task: shutdown waiting for %d threads to terminate.\n",
1852                    ldap_pvt_thread_pool_backload(&connection_pool) ));
1853 #else
1854         Debug( LDAP_DEBUG_ANY,
1855             "slapd shutdown: waiting for %d threads to terminate\n",
1856             ldap_pvt_thread_pool_backload(&connection_pool), 0, 0 );
1857 #endif
1858         ldap_pvt_thread_pool_destroy(&connection_pool, 1);
1859
1860         return NULL;
1861 }
1862
1863
1864 int slapd_daemon( void )
1865 {
1866         int rc;
1867
1868         connections_init();
1869
1870 #define SLAPD_LISTENER_THREAD 1
1871 #if defined( SLAPD_LISTENER_THREAD )
1872         {
1873                 ldap_pvt_thread_t       listener_tid;
1874
1875                 /* listener as a separate THREAD */
1876                 rc = ldap_pvt_thread_create( &listener_tid,
1877                         0, slapd_daemon_task, NULL );
1878
1879                 if ( rc != 0 ) {
1880 #ifdef NEW_LOGGING
1881                         LDAP_LOG(( "connection", LDAP_LEVEL_ERR,
1882                                    "slapd_daemon: listener ldap_pvt_thread_create failed (%d).\n", rc ));
1883 #else
1884                         Debug( LDAP_DEBUG_ANY,
1885                         "listener ldap_pvt_thread_create failed (%d)\n", rc, 0, 0 );
1886 #endif
1887                         return rc;
1888                 }
1889  
1890                 /* wait for the listener thread to complete */
1891                 ldap_pvt_thread_join( listener_tid, (void *) NULL );
1892         }
1893 #else
1894         /* experimental code */
1895         slapd_daemon_task( NULL );
1896 #endif
1897
1898         return 0;
1899
1900 }
1901
1902 int sockinit(void)
1903 {
1904 #if defined( HAVE_WINSOCK2 )
1905     WORD wVersionRequested;
1906         WSADATA wsaData;
1907         int err;
1908
1909         wVersionRequested = MAKEWORD( 2, 0 );
1910
1911         err = WSAStartup( wVersionRequested, &wsaData );
1912         if ( err != 0 ) {
1913                 /* Tell the user that we couldn't find a usable */
1914                 /* WinSock DLL.                                  */
1915                 return -1;
1916         }
1917
1918         /* Confirm that the WinSock DLL supports 2.0.*/
1919         /* Note that if the DLL supports versions greater    */
1920         /* than 2.0 in addition to 2.0, it will still return */
1921         /* 2.0 in wVersion since that is the version we      */
1922         /* requested.                                        */
1923
1924         if ( LOBYTE( wsaData.wVersion ) != 2 ||
1925                 HIBYTE( wsaData.wVersion ) != 0 )
1926         {
1927             /* Tell the user that we couldn't find a usable */
1928             /* WinSock DLL.                                  */
1929             WSACleanup();
1930             return -1;
1931         }
1932
1933         /* The WinSock DLL is acceptable. Proceed. */
1934 #elif defined( HAVE_WINSOCK )
1935         WSADATA wsaData;
1936         if ( WSAStartup( 0x0101, &wsaData ) != 0 ) {
1937             return -1;
1938         }
1939 #endif
1940         return 0;
1941 }
1942
1943 int sockdestroy(void)
1944 {
1945 #if defined( HAVE_WINSOCK2 ) || defined( HAVE_WINSOCK )
1946         WSACleanup();
1947 #endif
1948         return 0;
1949 }
1950
1951 RETSIGTYPE
1952 slap_sig_shutdown( int sig )
1953 {
1954 #ifdef NEW_LOGGING
1955         LDAP_LOG(( "connection", LDAP_LEVEL_CRIT,
1956                    "slap_sig_shutdown: signal %d\n", sig ));
1957 #else
1958         Debug(LDAP_DEBUG_TRACE, "slap_sig_shutdown: signal %d\n", sig, 0, 0);
1959 #endif
1960
1961         /*
1962          * If the NT Service Manager is controlling the server, we don't
1963          * want SIGBREAK to kill the server. For some strange reason,
1964          * SIGBREAK is generated when a user logs out.
1965          */
1966
1967 #if HAVE_NT_SERVICE_MANAGER && SIGBREAK
1968         if (is_NT_Service && sig == SIGBREAK)
1969 #ifdef NEW_LOGGING
1970             LDAP_LOG(( "connection", LDAP_LEVEL_CRIT,
1971                        "slap_sig_shutdown: SIGBREAK ignored.\n" ));
1972 #else
1973             Debug(LDAP_DEBUG_TRACE, "slap_sig_shutdown: SIGBREAK ignored.\n",
1974                   0, 0, 0);
1975 #endif
1976         else
1977 #endif
1978         slapd_shutdown = sig;
1979
1980         WAKE_LISTENER(1);
1981
1982         /* reinstall self */
1983         (void) SIGNAL_REINSTALL( sig, slap_sig_shutdown );
1984 }
1985
1986 RETSIGTYPE
1987 slap_sig_wake( int sig )
1988 {
1989         WAKE_LISTENER(1);
1990
1991         /* reinstall self */
1992         (void) SIGNAL_REINSTALL( sig, slap_sig_wake );
1993 }
1994
1995
1996 void slapd_add_internal(ber_socket_t s) {
1997         slapd_add(s);
1998 }
1999
2000 Listener ** slapd_get_listeners(void) {
2001         return slap_listeners;
2002 }