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