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