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