1 /* $NetBSD: daemon.c,v 1.2 2020/08/11 13:15:39 christos Exp $ */ 2 3 /* $OpenLDAP$ */ 4 /* This work is part of OpenLDAP Software <http://www.openldap.org/>. 5 * 6 * Copyright 1998-2020 The OpenLDAP Foundation. 7 * Portions Copyright 2007 by Howard Chu, Symas Corporation. 8 * All rights reserved. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted only as authorized by the OpenLDAP 12 * Public License. 13 * 14 * A copy of this license is available in the file LICENSE in the 15 * top-level directory of the distribution or, alternatively, at 16 * <http://www.OpenLDAP.org/license.html>. 17 */ 18 /* Portions Copyright (c) 1995 Regents of the University of Michigan. 19 * All rights reserved. 20 * 21 * Redistribution and use in source and binary forms are permitted 22 * provided that this notice is preserved and that due credit is given 23 * to the University of Michigan at Ann Arbor. The name of the University 24 * may not be used to endorse or promote products derived from this 25 * software without specific prior written permission. This software 26 * is provided ``as is'' without express or implied warranty. 27 */ 28 29 #include <sys/cdefs.h> 30 __RCSID("$NetBSD: daemon.c,v 1.2 2020/08/11 13:15:39 christos Exp $"); 31 32 #include "portable.h" 33 34 #include <stdio.h> 35 36 #include <ac/ctype.h> 37 #include <ac/errno.h> 38 #include <ac/socket.h> 39 #include <ac/string.h> 40 #include <ac/time.h> 41 #include <ac/unistd.h> 42 43 #include "slap.h" 44 #include "ldap_pvt_thread.h" 45 #include "lutil.h" 46 47 #include "ldap_rq.h" 48 49 #if defined(HAVE_SYS_EPOLL_H) && defined(HAVE_EPOLL) 50 # include <sys/epoll.h> 51 #elif defined(SLAP_X_DEVPOLL) && defined(HAVE_SYS_DEVPOLL_H) && defined(HAVE_DEVPOLL) 52 # include <sys/types.h> 53 # include <sys/stat.h> 54 # include <fcntl.h> 55 # include <sys/devpoll.h> 56 #endif /* ! epoll && ! /dev/poll */ 57 58 #ifdef HAVE_TCPD 59 int allow_severity = LOG_INFO; 60 int deny_severity = LOG_NOTICE; 61 #endif /* TCP Wrappers */ 62 63 #ifdef LDAP_PF_LOCAL 64 # include <sys/stat.h> 65 /* this should go in <ldap.h> as soon as it is accepted */ 66 # define LDAPI_MOD_URLEXT "x-mod" 67 #endif /* LDAP_PF_LOCAL */ 68 69 #ifdef LDAP_PF_INET6 70 int slap_inet4or6 = AF_UNSPEC; 71 #else /* ! INETv6 */ 72 int slap_inet4or6 = AF_INET; 73 #endif /* ! INETv6 */ 74 75 /* globals */ 76 time_t starttime; 77 ber_socket_t dtblsize; 78 slap_ssf_t local_ssf = LDAP_PVT_SASL_LOCAL_SSF; 79 struct runqueue_s slapd_rq; 80 81 #ifndef SLAPD_MAX_DAEMON_THREADS 82 #define SLAPD_MAX_DAEMON_THREADS 16 83 #endif 84 int slapd_daemon_threads = 1; 85 int slapd_daemon_mask; 86 87 #ifdef LDAP_TCP_BUFFER 88 int slapd_tcp_rmem; 89 int slapd_tcp_wmem; 90 #endif /* LDAP_TCP_BUFFER */ 91 92 Listener **slap_listeners = NULL; 93 static volatile sig_atomic_t listening = 1; /* 0 when slap_listeners closed */ 94 static ldap_pvt_thread_t *listener_tid; 95 96 #ifndef SLAPD_LISTEN_BACKLOG 97 #define SLAPD_LISTEN_BACKLOG 1024 98 #endif /* ! SLAPD_LISTEN_BACKLOG */ 99 100 #define DAEMON_ID(fd) (fd & slapd_daemon_mask) 101 102 static ber_socket_t wake_sds[SLAPD_MAX_DAEMON_THREADS][2]; 103 static int emfile; 104 105 static time_t chk_writetime; 106 107 static volatile int waking; 108 #ifdef NO_THREADS 109 #define WAKE_LISTENER(l,w) do { \ 110 if ((w) && ++waking < 5) { \ 111 tcp_write( SLAP_FD2SOCK(wake_sds[l][1]), "0", 1 ); \ 112 } \ 113 } while (0) 114 #else /* ! NO_THREADS */ 115 #define WAKE_LISTENER(l,w) do { \ 116 if (w) { \ 117 tcp_write( SLAP_FD2SOCK(wake_sds[l][1]), "0", 1 ); \ 118 } \ 119 } while (0) 120 #endif /* ! NO_THREADS */ 121 122 volatile sig_atomic_t slapd_shutdown = 0; 123 volatile sig_atomic_t slapd_gentle_shutdown = 0; 124 volatile sig_atomic_t slapd_abrupt_shutdown = 0; 125 126 #ifdef HAVE_WINSOCK 127 ldap_pvt_thread_mutex_t slapd_ws_mutex; 128 SOCKET *slapd_ws_sockets; 129 #define SD_READ 1 130 #define SD_WRITE 2 131 #define SD_ACTIVE 4 132 #define SD_LISTENER 8 133 #endif 134 135 #ifdef HAVE_TCPD 136 static ldap_pvt_thread_mutex_t sd_tcpd_mutex; 137 #endif /* TCP Wrappers */ 138 139 typedef struct slap_daemon_st { 140 ldap_pvt_thread_mutex_t sd_mutex; 141 142 ber_socket_t sd_nactives; 143 int sd_nwriters; 144 int sd_nfds; 145 146 #if defined(HAVE_EPOLL) 147 struct epoll_event *sd_epolls; 148 int *sd_index; 149 int sd_epfd; 150 #elif defined(SLAP_X_DEVPOLL) && defined(HAVE_DEVPOLL) 151 /* eXperimental */ 152 struct pollfd *sd_pollfd; 153 int *sd_index; 154 Listener **sd_l; 155 int sd_dpfd; 156 #else /* ! epoll && ! /dev/poll */ 157 #ifdef HAVE_WINSOCK 158 char *sd_flags; 159 char *sd_rflags; 160 #else /* ! HAVE_WINSOCK */ 161 fd_set sd_actives; 162 fd_set sd_readers; 163 fd_set sd_writers; 164 #endif /* ! HAVE_WINSOCK */ 165 #endif /* ! epoll && ! /dev/poll */ 166 } slap_daemon_st; 167 168 static slap_daemon_st slap_daemon[SLAPD_MAX_DAEMON_THREADS]; 169 170 /* 171 * NOTE: naming convention for macros: 172 * 173 * - SLAP_SOCK_* and SLAP_EVENT_* for public interface that deals 174 * with file descriptors and events respectively 175 * 176 * - SLAP_<type>_* for private interface; type by now is one of 177 * EPOLL, DEVPOLL, SELECT 178 * 179 * private interface should not be used in the code. 180 */ 181 #if defined(HAVE_EPOLL) 182 /*************************************** 183 * Use epoll infrastructure - epoll(4) * 184 ***************************************/ 185 # define SLAP_EVENT_FNAME "epoll" 186 # define SLAP_EVENTS_ARE_INDEXED 0 187 # define SLAP_EPOLL_SOCK_IX(t,s) (slap_daemon[t].sd_index[(s)]) 188 # define SLAP_EPOLL_SOCK_EP(t,s) (slap_daemon[t].sd_epolls[SLAP_EPOLL_SOCK_IX(t,s)]) 189 # define SLAP_EPOLL_SOCK_EV(t,s) (SLAP_EPOLL_SOCK_EP(t,s).events) 190 # define SLAP_SOCK_IS_ACTIVE(t,s) (SLAP_EPOLL_SOCK_IX(t,s) != -1) 191 # define SLAP_SOCK_NOT_ACTIVE(t,s) (SLAP_EPOLL_SOCK_IX(t,s) == -1) 192 # define SLAP_EPOLL_SOCK_IS_SET(t,s, mode) (SLAP_EPOLL_SOCK_EV(t,s) & (mode)) 193 194 # define SLAP_SOCK_IS_READ(t,s) SLAP_EPOLL_SOCK_IS_SET(t,(s), EPOLLIN) 195 # define SLAP_SOCK_IS_WRITE(t,s) SLAP_EPOLL_SOCK_IS_SET(t,(s), EPOLLOUT) 196 197 # define SLAP_EPOLL_SOCK_SET(t,s, mode) do { \ 198 if ( (SLAP_EPOLL_SOCK_EV(t,s) & (mode)) != (mode) ) { \ 199 SLAP_EPOLL_SOCK_EV(t,s) |= (mode); \ 200 epoll_ctl( slap_daemon[t].sd_epfd, EPOLL_CTL_MOD, (s), \ 201 &SLAP_EPOLL_SOCK_EP(t,s) ); \ 202 } \ 203 } while (0) 204 205 # define SLAP_EPOLL_SOCK_CLR(t,s, mode) do { \ 206 if ( (SLAP_EPOLL_SOCK_EV(t,s) & (mode)) ) { \ 207 SLAP_EPOLL_SOCK_EV(t,s) &= ~(mode); \ 208 epoll_ctl( slap_daemon[t].sd_epfd, EPOLL_CTL_MOD, s, \ 209 &SLAP_EPOLL_SOCK_EP(t,s) ); \ 210 } \ 211 } while (0) 212 213 # define SLAP_SOCK_SET_READ(t,s) SLAP_EPOLL_SOCK_SET(t,s, EPOLLIN) 214 # define SLAP_SOCK_SET_WRITE(t,s) SLAP_EPOLL_SOCK_SET(t,s, EPOLLOUT) 215 216 # define SLAP_SOCK_CLR_READ(t,s) SLAP_EPOLL_SOCK_CLR(t,(s), EPOLLIN) 217 # define SLAP_SOCK_CLR_WRITE(t,s) SLAP_EPOLL_SOCK_CLR(t,(s), EPOLLOUT) 218 219 # define SLAP_SOCK_SET_SUSPEND(t,s) \ 220 ( slap_daemon[t].sd_suspend[SLAP_EPOLL_SOCK_IX(t,s)] = 1 ) 221 # define SLAP_SOCK_CLR_SUSPEND(t,s) \ 222 ( slap_daemon[t].sd_suspend[SLAP_EPOLL_SOCK_IX(t,s)] = 0 ) 223 # define SLAP_SOCK_IS_SUSPEND(t,s) \ 224 ( slap_daemon[t].sd_suspend[SLAP_EPOLL_SOCK_IX(t,s)] == 1 ) 225 226 # define SLAP_EPOLL_EVENT_CLR(i, mode) (revents[(i)].events &= ~(mode)) 227 228 # define SLAP_EVENT_MAX(t) slap_daemon[t].sd_nfds 229 230 /* If a Listener address is provided, store that as the epoll data. 231 * Otherwise, store the address of this socket's slot in the 232 * index array. If we can't do this add, the system is out of 233 * resources and we need to shutdown. 234 */ 235 # define SLAP_SOCK_ADD(t, s, l) do { \ 236 int rc; \ 237 SLAP_EPOLL_SOCK_IX(t,(s)) = slap_daemon[t].sd_nfds; \ 238 SLAP_EPOLL_SOCK_EP(t,(s)).data.ptr = (l) ? (l) : (void *)(&SLAP_EPOLL_SOCK_IX(t,s)); \ 239 SLAP_EPOLL_SOCK_EV(t,(s)) = EPOLLIN; \ 240 rc = epoll_ctl(slap_daemon[t].sd_epfd, EPOLL_CTL_ADD, \ 241 (s), &SLAP_EPOLL_SOCK_EP(t,(s))); \ 242 if ( rc == 0 ) { \ 243 slap_daemon[t].sd_nfds++; \ 244 } else { \ 245 Debug( LDAP_DEBUG_ANY, \ 246 "daemon: epoll_ctl(ADD,fd=%d) failed, errno=%d, shutting down\n", \ 247 s, errno, 0 ); \ 248 slapd_shutdown = 2; \ 249 } \ 250 } while (0) 251 252 # define SLAP_EPOLL_EV_LISTENER(t,ptr) \ 253 (((int *)(ptr) >= slap_daemon[t].sd_index && \ 254 (int *)(ptr) <= &slap_daemon[t].sd_index[dtblsize]) ? 0 : 1 ) 255 256 # define SLAP_EPOLL_EV_PTRFD(t,ptr) (SLAP_EPOLL_EV_LISTENER(t,ptr) ? \ 257 ((Listener *)ptr)->sl_sd : \ 258 (ber_socket_t) ((int *)(ptr) - slap_daemon[t].sd_index)) 259 260 # define SLAP_SOCK_DEL(t,s) do { \ 261 int fd, rc, index = SLAP_EPOLL_SOCK_IX(t,(s)); \ 262 if ( index < 0 ) break; \ 263 rc = epoll_ctl(slap_daemon[t].sd_epfd, EPOLL_CTL_DEL, \ 264 (s), &SLAP_EPOLL_SOCK_EP(t,(s))); \ 265 slap_daemon[t].sd_epolls[index] = \ 266 slap_daemon[t].sd_epolls[slap_daemon[t].sd_nfds-1]; \ 267 fd = SLAP_EPOLL_EV_PTRFD(t,slap_daemon[t].sd_epolls[index].data.ptr); \ 268 slap_daemon[t].sd_index[fd] = index; \ 269 slap_daemon[t].sd_index[(s)] = -1; \ 270 slap_daemon[t].sd_nfds--; \ 271 } while (0) 272 273 # define SLAP_EVENT_CLR_READ(i) SLAP_EPOLL_EVENT_CLR((i), EPOLLIN) 274 # define SLAP_EVENT_CLR_WRITE(i) SLAP_EPOLL_EVENT_CLR((i), EPOLLOUT) 275 276 # define SLAP_EPOLL_EVENT_CHK(i, mode) (revents[(i)].events & mode) 277 278 # define SLAP_EVENT_IS_READ(i) SLAP_EPOLL_EVENT_CHK((i), EPOLLIN) 279 # define SLAP_EVENT_IS_WRITE(i) SLAP_EPOLL_EVENT_CHK((i), EPOLLOUT) 280 # define SLAP_EVENT_IS_LISTENER(t,i) SLAP_EPOLL_EV_LISTENER(t,revents[(i)].data.ptr) 281 # define SLAP_EVENT_LISTENER(t,i) ((Listener *)(revents[(i)].data.ptr)) 282 283 # define SLAP_EVENT_FD(t,i) SLAP_EPOLL_EV_PTRFD(t,revents[(i)].data.ptr) 284 285 # define SLAP_SOCK_INIT(t) do { \ 286 int j; \ 287 slap_daemon[t].sd_epolls = ch_calloc(1, \ 288 ( sizeof(struct epoll_event) * 2 \ 289 + sizeof(int) ) * dtblsize * 2); \ 290 slap_daemon[t].sd_index = (int *)&slap_daemon[t].sd_epolls[ 2 * dtblsize ]; \ 291 slap_daemon[t].sd_epfd = epoll_create( dtblsize / slapd_daemon_threads ); \ 292 for ( j = 0; j < dtblsize; j++ ) slap_daemon[t].sd_index[j] = -1; \ 293 } while (0) 294 295 # define SLAP_SOCK_DESTROY(t) do { \ 296 if ( slap_daemon[t].sd_epolls != NULL ) { \ 297 ch_free( slap_daemon[t].sd_epolls ); \ 298 slap_daemon[t].sd_epolls = NULL; \ 299 slap_daemon[t].sd_index = NULL; \ 300 close( slap_daemon[t].sd_epfd ); \ 301 } \ 302 } while ( 0 ) 303 304 # define SLAP_EVENT_DECL struct epoll_event *revents 305 306 # define SLAP_EVENT_INIT(t) do { \ 307 revents = slap_daemon[t].sd_epolls + dtblsize; \ 308 } while (0) 309 310 # define SLAP_EVENT_WAIT(t, tvp, nsp) do { \ 311 *(nsp) = epoll_wait( slap_daemon[t].sd_epfd, revents, \ 312 dtblsize, (tvp) ? ((tvp)->tv_sec * 1000 + (tvp)->tv_usec / 1000) : -1 ); \ 313 } while (0) 314 315 #elif defined(SLAP_X_DEVPOLL) && defined(HAVE_DEVPOLL) 316 317 /************************************************************* 318 * Use Solaris' (>= 2.7) /dev/poll infrastructure - poll(7d) * 319 *************************************************************/ 320 # define SLAP_EVENT_FNAME "/dev/poll" 321 # define SLAP_EVENTS_ARE_INDEXED 0 322 /* 323 * - sd_index is used much like with epoll() 324 * - sd_l is maintained as an array containing the address 325 * of the listener; the index is the fd itself 326 * - sd_pollfd is used to keep track of what data has been 327 * registered in /dev/poll 328 */ 329 # define SLAP_DEVPOLL_SOCK_IX(t,s) (slap_daemon[t].sd_index[(s)]) 330 # define SLAP_DEVPOLL_SOCK_LX(t,s) (slap_daemon[t].sd_l[(s)]) 331 # define SLAP_DEVPOLL_SOCK_EP(t,s) (slap_daemon[t].sd_pollfd[SLAP_DEVPOLL_SOCK_IX(t,(s))]) 332 # define SLAP_DEVPOLL_SOCK_FD(t,s) (SLAP_DEVPOLL_SOCK_EP(t,(s)).fd) 333 # define SLAP_DEVPOLL_SOCK_EV(t,s) (SLAP_DEVPOLL_SOCK_EP(t,(s)).events) 334 # define SLAP_SOCK_IS_ACTIVE(t,s) (SLAP_DEVPOLL_SOCK_IX(t,(s)) != -1) 335 # define SLAP_SOCK_NOT_ACTIVE(t,s) (SLAP_DEVPOLL_SOCK_IX(t,(s)) == -1) 336 # define SLAP_SOCK_IS_SET(t,s, mode) (SLAP_DEVPOLL_SOCK_EV(t,(s)) & (mode)) 337 338 # define SLAP_SOCK_IS_READ(t,s) SLAP_SOCK_IS_SET(t,(s), POLLIN) 339 # define SLAP_SOCK_IS_WRITE(t,s) SLAP_SOCK_IS_SET(t,(s), POLLOUT) 340 341 /* as far as I understand, any time we need to communicate with the kernel 342 * about the number and/or properties of a file descriptor we need it to 343 * wait for, we have to rewrite the whole set */ 344 # define SLAP_DEVPOLL_WRITE_POLLFD(t,s, pfd, n, what, shdn) do { \ 345 int rc; \ 346 size_t size = (n) * sizeof( struct pollfd ); \ 347 /* FIXME: use pwrite? */ \ 348 rc = write( slap_daemon[t].sd_dpfd, (pfd), size ); \ 349 if ( rc != size ) { \ 350 Debug( LDAP_DEBUG_ANY, "daemon: " SLAP_EVENT_FNAME ": " \ 351 "%s fd=%d failed errno=%d\n", \ 352 (what), (s), errno ); \ 353 if ( (shdn) ) { \ 354 slapd_shutdown = 2; \ 355 } \ 356 } \ 357 } while (0) 358 359 # define SLAP_DEVPOLL_SOCK_SET(t,s, mode) do { \ 360 Debug( LDAP_DEBUG_CONNS, "SLAP_SOCK_SET_%s(%d)=%d\n", \ 361 (mode) == POLLIN ? "READ" : "WRITE", (s), \ 362 ( (SLAP_DEVPOLL_SOCK_EV(t,(s)) & (mode)) != (mode) ) ); \ 363 if ( (SLAP_DEVPOLL_SOCK_EV(t,(s)) & (mode)) != (mode) ) { \ 364 struct pollfd pfd; \ 365 SLAP_DEVPOLL_SOCK_EV(t,(s)) |= (mode); \ 366 pfd.fd = SLAP_DEVPOLL_SOCK_FD(t,(s)); \ 367 pfd.events = /* (mode) */ SLAP_DEVPOLL_SOCK_EV(t,(s)); \ 368 SLAP_DEVPOLL_WRITE_POLLFD(t,(s), &pfd, 1, "SET", 0); \ 369 } \ 370 } while (0) 371 372 # define SLAP_DEVPOLL_SOCK_CLR(t,s, mode) do { \ 373 Debug( LDAP_DEBUG_CONNS, "SLAP_SOCK_CLR_%s(%d)=%d\n", \ 374 (mode) == POLLIN ? "READ" : "WRITE", (s), \ 375 ( (SLAP_DEVPOLL_SOCK_EV(t,(s)) & (mode)) == (mode) ) ); \ 376 if ((SLAP_DEVPOLL_SOCK_EV(t,(s)) & (mode)) == (mode) ) { \ 377 struct pollfd pfd[2]; \ 378 SLAP_DEVPOLL_SOCK_EV(t,(s)) &= ~(mode); \ 379 pfd[0].fd = SLAP_DEVPOLL_SOCK_FD(t,(s)); \ 380 pfd[0].events = POLLREMOVE; \ 381 pfd[1] = SLAP_DEVPOLL_SOCK_EP(t,(s)); \ 382 SLAP_DEVPOLL_WRITE_POLLFD(t,(s), &pfd[0], 2, "CLR", 0); \ 383 } \ 384 } while (0) 385 386 # define SLAP_SOCK_SET_READ(t,s) SLAP_DEVPOLL_SOCK_SET(t,s, POLLIN) 387 # define SLAP_SOCK_SET_WRITE(t,s) SLAP_DEVPOLL_SOCK_SET(t,s, POLLOUT) 388 389 # define SLAP_SOCK_CLR_READ(t,s) SLAP_DEVPOLL_SOCK_CLR(t,(s), POLLIN) 390 # define SLAP_SOCK_CLR_WRITE(t,s) SLAP_DEVPOLL_SOCK_CLR(t,(s), POLLOUT) 391 392 # define SLAP_SOCK_SET_SUSPEND(t,s) \ 393 ( slap_daemon[t].sd_suspend[SLAP_DEVPOLL_SOCK_IX(t,(s))] = 1 ) 394 # define SLAP_SOCK_CLR_SUSPEND(t,s) \ 395 ( slap_daemon[t].sd_suspend[SLAP_DEVPOLL_SOCK_IX(t,(s))] = 0 ) 396 # define SLAP_SOCK_IS_SUSPEND(t,s) \ 397 ( slap_daemon[t].sd_suspend[SLAP_DEVPOLL_SOCK_IX(t,(s))] == 1 ) 398 399 # define SLAP_DEVPOLL_EVENT_CLR(i, mode) (revents[(i)].events &= ~(mode)) 400 401 # define SLAP_EVENT_MAX(t) slap_daemon[t].sd_nfds 402 403 /* If a Listener address is provided, store that in the sd_l array. 404 * If we can't do this add, the system is out of resources and we 405 * need to shutdown. 406 */ 407 # define SLAP_SOCK_ADD(t, s, l) do { \ 408 Debug( LDAP_DEBUG_CONNS, "SLAP_SOCK_ADD(%d, %p)\n", (s), (l), 0 ); \ 409 SLAP_DEVPOLL_SOCK_IX(t,(s)) = slap_daemon[t].sd_nfds; \ 410 SLAP_DEVPOLL_SOCK_LX(t,(s)) = (l); \ 411 SLAP_DEVPOLL_SOCK_FD(t,(s)) = (s); \ 412 SLAP_DEVPOLL_SOCK_EV(t,(s)) = POLLIN; \ 413 SLAP_DEVPOLL_WRITE_POLLFD(t,(s), &SLAP_DEVPOLL_SOCK_EP((s)), 1, "ADD", 1); \ 414 slap_daemon[t].sd_nfds++; \ 415 } while (0) 416 417 # define SLAP_DEVPOLL_EV_LISTENER(ptr) ((ptr) != NULL) 418 419 # define SLAP_SOCK_DEL(t,s) do { \ 420 int fd, index = SLAP_DEVPOLL_SOCK_IX(t,(s)); \ 421 Debug( LDAP_DEBUG_CONNS, "SLAP_SOCK_DEL(%d)\n", (s), 0, 0 ); \ 422 if ( index < 0 ) break; \ 423 if ( index < slap_daemon[t].sd_nfds - 1 ) { \ 424 struct pollfd pfd = slap_daemon[t].sd_pollfd[index]; \ 425 fd = slap_daemon[t].sd_pollfd[slap_daemon[t].sd_nfds - 1].fd; \ 426 slap_daemon[t].sd_pollfd[index] = slap_daemon[t].sd_pollfd[slap_daemon[t].sd_nfds - 1]; \ 427 slap_daemon[t].sd_pollfd[slap_daemon[t].sd_nfds - 1] = pfd; \ 428 slap_daemon[t].sd_index[fd] = index; \ 429 } \ 430 slap_daemon[t].sd_index[(s)] = -1; \ 431 slap_daemon[t].sd_pollfd[slap_daemon[t].sd_nfds - 1].events = POLLREMOVE; \ 432 SLAP_DEVPOLL_WRITE_POLLFD(t,(s), &slap_daemon[t].sd_pollfd[slap_daemon[t].sd_nfds - 1], 1, "DEL", 0); \ 433 slap_daemon[t].sd_pollfd[slap_daemon[t].sd_nfds - 1].events = 0; \ 434 slap_daemon[t].sd_nfds--; \ 435 } while (0) 436 437 # define SLAP_EVENT_CLR_READ(i) SLAP_DEVPOLL_EVENT_CLR((i), POLLIN) 438 # define SLAP_EVENT_CLR_WRITE(i) SLAP_DEVPOLL_EVENT_CLR((i), POLLOUT) 439 440 # define SLAP_DEVPOLL_EVENT_CHK(i, mode) (revents[(i)].events & (mode)) 441 442 # define SLAP_EVENT_FD(t,i) (revents[(i)].fd) 443 444 # define SLAP_EVENT_IS_READ(i) SLAP_DEVPOLL_EVENT_CHK((i), POLLIN) 445 # define SLAP_EVENT_IS_WRITE(i) SLAP_DEVPOLL_EVENT_CHK((i), POLLOUT) 446 # define SLAP_EVENT_IS_LISTENER(t,i) SLAP_DEVPOLL_EV_LISTENER(SLAP_DEVPOLL_SOCK_LX(SLAP_EVENT_FD(t,(i)))) 447 # define SLAP_EVENT_LISTENER(t,i) SLAP_DEVPOLL_SOCK_LX(SLAP_EVENT_FD(t,(i))) 448 449 # define SLAP_SOCK_INIT(t) do { \ 450 slap_daemon[t].sd_pollfd = ch_calloc( 1, \ 451 ( sizeof(struct pollfd) * 2 \ 452 + sizeof( int ) \ 453 + sizeof( Listener * ) ) * dtblsize ); \ 454 slap_daemon[t].sd_index = (int *)&slap_daemon[t].sd_pollfd[ 2 * dtblsize ]; \ 455 slap_daemon[t].sd_l = (Listener **)&slap_daemon[t].sd_index[ dtblsize ]; \ 456 slap_daemon[t].sd_dpfd = open( SLAP_EVENT_FNAME, O_RDWR ); \ 457 if ( slap_daemon[t].sd_dpfd == -1 ) { \ 458 Debug( LDAP_DEBUG_ANY, "daemon: " SLAP_EVENT_FNAME ": " \ 459 "open(\"" SLAP_EVENT_FNAME "\") failed errno=%d\n", \ 460 errno, 0, 0 ); \ 461 SLAP_SOCK_DESTROY; \ 462 return -1; \ 463 } \ 464 for ( i = 0; i < dtblsize; i++ ) { \ 465 slap_daemon[t].sd_pollfd[i].fd = -1; \ 466 slap_daemon[t].sd_index[i] = -1; \ 467 } \ 468 } while (0) 469 470 # define SLAP_SOCK_DESTROY(t) do { \ 471 if ( slap_daemon[t].sd_pollfd != NULL ) { \ 472 ch_free( slap_daemon[t].sd_pollfd ); \ 473 slap_daemon[t].sd_pollfd = NULL; \ 474 slap_daemon[t].sd_index = NULL; \ 475 slap_daemon[t].sd_l = NULL; \ 476 close( slap_daemon[t].sd_dpfd ); \ 477 } \ 478 } while ( 0 ) 479 480 # define SLAP_EVENT_DECL struct pollfd *revents 481 482 # define SLAP_EVENT_INIT(t) do { \ 483 revents = &slap_daemon[t].sd_pollfd[ dtblsize ]; \ 484 } while (0) 485 486 # define SLAP_EVENT_WAIT(t, tvp, nsp) do { \ 487 struct dvpoll sd_dvpoll; \ 488 sd_dvpoll.dp_timeout = (tvp) ? ((tvp)->tv_sec * 1000 + (tvp)->tv_usec / 1000) : -1; \ 489 sd_dvpoll.dp_nfds = dtblsize; \ 490 sd_dvpoll.dp_fds = revents; \ 491 *(nsp) = ioctl( slap_daemon[t].sd_dpfd, DP_POLL, &sd_dvpoll ); \ 492 } while (0) 493 494 #else /* ! epoll && ! /dev/poll */ 495 # ifdef HAVE_WINSOCK 496 # define SLAP_EVENT_FNAME "WSselect" 497 /* Winsock provides a "select" function but its fd_sets are 498 * actually arrays of sockets. Since these sockets are handles 499 * and not a contiguous range of small integers, we manage our 500 * own "fd" table of socket handles and use their indices as 501 * descriptors. 502 * 503 * All of our listener/connection structures use fds; the actual 504 * I/O functions use sockets. The SLAP_FD2SOCK macro in proto-slap.h 505 * handles the mapping. 506 * 507 * Despite the mapping overhead, this is about 45% more efficient 508 * than just using Winsock's select and FD_ISSET directly. 509 * 510 * Unfortunately Winsock's select implementation doesn't scale well 511 * as the number of connections increases. This probably needs to be 512 * rewritten to use the Winsock overlapped/asynchronous I/O functions. 513 */ 514 # define SLAP_EVENTS_ARE_INDEXED 1 515 # define SLAP_EVENT_DECL fd_set readfds, writefds; char *rflags 516 # define SLAP_EVENT_INIT(t) do { \ 517 int i; \ 518 FD_ZERO( &readfds ); \ 519 FD_ZERO( &writefds ); \ 520 rflags = slap_daemon[t].sd_rflags; \ 521 memset( rflags, 0, slap_daemon[t].sd_nfds ); \ 522 for ( i=0; i<slap_daemon[t].sd_nfds; i++ ) { \ 523 if ( slap_daemon[t].sd_flags[i] & SD_READ ) \ 524 FD_SET( slapd_ws_sockets[i], &readfds );\ 525 if ( slap_daemon[t].sd_flags[i] & SD_WRITE ) \ 526 FD_SET( slapd_ws_sockets[i], &writefds ); \ 527 } } while ( 0 ) 528 529 # define SLAP_EVENT_MAX(t) slap_daemon[t].sd_nfds 530 531 # define SLAP_EVENT_WAIT(t, tvp, nsp) do { \ 532 int i; \ 533 *(nsp) = select( SLAP_EVENT_MAX(t), &readfds, \ 534 nwriters > 0 ? &writefds : NULL, NULL, (tvp) ); \ 535 for ( i=0; i<readfds.fd_count; i++) { \ 536 int fd = slapd_sock2fd(readfds.fd_array[i]); \ 537 if ( fd >= 0 ) { \ 538 slap_daemon[t].sd_rflags[fd] = SD_READ; \ 539 if ( fd >= *(nsp)) *(nsp) = fd+1; \ 540 } \ 541 } \ 542 for ( i=0; i<writefds.fd_count; i++) { \ 543 int fd = slapd_sock2fd(writefds.fd_array[i]); \ 544 if ( fd >= 0 ) { \ 545 slap_daemon[t].sd_rflags[fd] = SD_WRITE; \ 546 if ( fd >= *(nsp)) *(nsp) = fd+1; \ 547 } \ 548 } \ 549 } while (0) 550 551 # define SLAP_EVENT_IS_READ(fd) (rflags[fd] & SD_READ) 552 # define SLAP_EVENT_IS_WRITE(fd) (rflags[fd] & SD_WRITE) 553 554 # define SLAP_EVENT_CLR_READ(fd) rflags[fd] &= ~SD_READ 555 # define SLAP_EVENT_CLR_WRITE(fd) rflags[fd] &= ~SD_WRITE 556 557 # define SLAP_SOCK_INIT(t) do { \ 558 if (!t) { \ 559 ldap_pvt_thread_mutex_init( &slapd_ws_mutex ); \ 560 slapd_ws_sockets = ch_malloc( dtblsize * ( sizeof(SOCKET) + 2)); \ 561 memset( slapd_ws_sockets, -1, dtblsize * sizeof(SOCKET) ); \ 562 } \ 563 slap_daemon[t].sd_flags = (char *)(slapd_ws_sockets + dtblsize); \ 564 slap_daemon[t].sd_rflags = slap_daemon[t].sd_flags + dtblsize; \ 565 memset( slap_daemon[t].sd_flags, 0, dtblsize ); \ 566 slapd_ws_sockets[t*2] = wake_sds[t][0]; \ 567 slapd_ws_sockets[t*2+1] = wake_sds[t][1]; \ 568 wake_sds[t][0] = t*2; \ 569 wake_sds[t][1] = t*2+1; \ 570 slap_daemon[t].sd_nfds = t*2 + 2; \ 571 } while ( 0 ) 572 573 # define SLAP_SOCK_DESTROY(t) do { \ 574 ch_free( slapd_ws_sockets ); slapd_ws_sockets = NULL; \ 575 slap_daemon[t].sd_flags = NULL; \ 576 slap_daemon[t].sd_rflags = NULL; \ 577 ldap_pvt_thread_mutex_destroy( &slapd_ws_mutex ); \ 578 } while ( 0 ) 579 580 # define SLAP_SOCK_IS_ACTIVE(t,fd) ( slap_daemon[t].sd_flags[fd] & SD_ACTIVE ) 581 # define SLAP_SOCK_IS_READ(t,fd) ( slap_daemon[t].sd_flags[fd] & SD_READ ) 582 # define SLAP_SOCK_IS_WRITE(t,fd) ( slap_daemon[t].sd_flags[fd] & SD_WRITE ) 583 # define SLAP_SOCK_NOT_ACTIVE(t,fd) (!slap_daemon[t].sd_flags[fd]) 584 585 # define SLAP_SOCK_SET_READ(t,fd) ( slap_daemon[t].sd_flags[fd] |= SD_READ ) 586 # define SLAP_SOCK_SET_WRITE(t,fd) ( slap_daemon[t].sd_flags[fd] |= SD_WRITE ) 587 588 # define SLAP_SELECT_ADDTEST(t,s) do { \ 589 if ((s) >= slap_daemon[t].sd_nfds) slap_daemon[t].sd_nfds = (s)+1; \ 590 } while (0) 591 592 # define SLAP_SOCK_CLR_READ(t,fd) ( slap_daemon[t].sd_flags[fd] &= ~SD_READ ) 593 # define SLAP_SOCK_CLR_WRITE(t,fd) ( slap_daemon[t].sd_flags[fd] &= ~SD_WRITE ) 594 595 # define SLAP_SOCK_ADD(t,s, l) do { \ 596 SLAP_SELECT_ADDTEST(t,(s)); \ 597 slap_daemon[t].sd_flags[s] = SD_ACTIVE|SD_READ; \ 598 } while ( 0 ) 599 600 # define SLAP_SOCK_DEL(t,s) do { \ 601 slap_daemon[t].sd_flags[s] = 0; \ 602 slapd_sockdel( s ); \ 603 } while ( 0 ) 604 605 # else /* !HAVE_WINSOCK */ 606 607 /************************************** 608 * Use select system call - select(2) * 609 **************************************/ 610 # define SLAP_EVENT_FNAME "select" 611 /* select */ 612 # define SLAP_EVENTS_ARE_INDEXED 1 613 # define SLAP_EVENT_DECL fd_set readfds, writefds 614 615 # define SLAP_EVENT_INIT(t) do { \ 616 AC_MEMCPY( &readfds, &slap_daemon[t].sd_readers, sizeof(fd_set) ); \ 617 if ( nwriters ) { \ 618 AC_MEMCPY( &writefds, &slap_daemon[t].sd_writers, sizeof(fd_set) ); \ 619 } else { \ 620 FD_ZERO( &writefds ); \ 621 } \ 622 } while (0) 623 624 # ifdef FD_SETSIZE 625 # define SLAP_SELECT_CHK_SETSIZE do { \ 626 if (dtblsize > FD_SETSIZE) dtblsize = FD_SETSIZE; \ 627 } while (0) 628 # else /* ! FD_SETSIZE */ 629 # define SLAP_SELECT_CHK_SETSIZE do { ; } while (0) 630 # endif /* ! FD_SETSIZE */ 631 632 # define SLAP_SOCK_INIT(t) do { \ 633 SLAP_SELECT_CHK_SETSIZE; \ 634 FD_ZERO(&slap_daemon[t].sd_actives); \ 635 FD_ZERO(&slap_daemon[t].sd_readers); \ 636 FD_ZERO(&slap_daemon[t].sd_writers); \ 637 } while (0) 638 639 # define SLAP_SOCK_DESTROY(t) 640 641 # define SLAP_SOCK_IS_ACTIVE(t,fd) FD_ISSET((fd), &slap_daemon[t].sd_actives) 642 # define SLAP_SOCK_IS_READ(t,fd) FD_ISSET((fd), &slap_daemon[t].sd_readers) 643 # define SLAP_SOCK_IS_WRITE(t,fd) FD_ISSET((fd), &slap_daemon[t].sd_writers) 644 645 # define SLAP_SOCK_NOT_ACTIVE(t,fd) (!SLAP_SOCK_IS_ACTIVE(t,fd) && \ 646 !SLAP_SOCK_IS_READ(t,fd) && !SLAP_SOCK_IS_WRITE(t,fd)) 647 648 # define SLAP_SOCK_SET_READ(t,fd) FD_SET((fd), &slap_daemon[t].sd_readers) 649 # define SLAP_SOCK_SET_WRITE(t,fd) FD_SET((fd), &slap_daemon[t].sd_writers) 650 651 # define SLAP_EVENT_MAX(t) slap_daemon[t].sd_nfds 652 # define SLAP_SELECT_ADDTEST(t,s) do { \ 653 if ((s) >= slap_daemon[t].sd_nfds) slap_daemon[t].sd_nfds = (s)+1; \ 654 } while (0) 655 656 # define SLAP_SOCK_CLR_READ(t,fd) FD_CLR((fd), &slap_daemon[t].sd_readers) 657 # define SLAP_SOCK_CLR_WRITE(t,fd) FD_CLR((fd), &slap_daemon[t].sd_writers) 658 659 # define SLAP_SOCK_ADD(t,s, l) do { \ 660 SLAP_SELECT_ADDTEST(t,(s)); \ 661 FD_SET((s), &slap_daemon[t].sd_actives); \ 662 FD_SET((s), &slap_daemon[t].sd_readers); \ 663 } while (0) 664 665 # define SLAP_SOCK_DEL(t,s) do { \ 666 FD_CLR((s), &slap_daemon[t].sd_actives); \ 667 FD_CLR((s), &slap_daemon[t].sd_readers); \ 668 FD_CLR((s), &slap_daemon[t].sd_writers); \ 669 } while (0) 670 671 # define SLAP_EVENT_IS_READ(fd) FD_ISSET((fd), &readfds) 672 # define SLAP_EVENT_IS_WRITE(fd) FD_ISSET((fd), &writefds) 673 674 # define SLAP_EVENT_CLR_READ(fd) FD_CLR((fd), &readfds) 675 # define SLAP_EVENT_CLR_WRITE(fd) FD_CLR((fd), &writefds) 676 677 # define SLAP_EVENT_WAIT(t, tvp, nsp) do { \ 678 *(nsp) = select( SLAP_EVENT_MAX(t), &readfds, \ 679 nwriters > 0 ? &writefds : NULL, NULL, (tvp) ); \ 680 } while (0) 681 # endif /* !HAVE_WINSOCK */ 682 #endif /* ! epoll && ! /dev/poll */ 683 684 #ifdef HAVE_SLP 685 /* 686 * SLP related functions 687 */ 688 #include <slp.h> 689 690 #define LDAP_SRVTYPE_PREFIX "service:ldap://" 691 #define LDAPS_SRVTYPE_PREFIX "service:ldaps://" 692 static char** slapd_srvurls = NULL; 693 static SLPHandle slapd_hslp = 0; 694 int slapd_register_slp = 0; 695 const char *slapd_slp_attrs = NULL; 696 697 static SLPError slapd_slp_cookie; 698 699 static void 700 slapd_slp_init( const char* urls ) 701 { 702 int i; 703 SLPError err; 704 705 slapd_srvurls = ldap_str2charray( urls, " " ); 706 707 if ( slapd_srvurls == NULL ) return; 708 709 /* find and expand INADDR_ANY URLs */ 710 for ( i = 0; slapd_srvurls[i] != NULL; i++ ) { 711 if ( strcmp( slapd_srvurls[i], "ldap:///" ) == 0 ) { 712 slapd_srvurls[i] = (char *) ch_realloc( slapd_srvurls[i], 713 global_host_bv.bv_len + 714 sizeof( LDAP_SRVTYPE_PREFIX ) ); 715 strcpy( lutil_strcopy(slapd_srvurls[i], 716 LDAP_SRVTYPE_PREFIX ), global_host_bv.bv_val ); 717 } else if ( strcmp( slapd_srvurls[i], "ldaps:///" ) == 0 ) { 718 slapd_srvurls[i] = (char *) ch_realloc( slapd_srvurls[i], 719 global_host_bv.bv_len + 720 sizeof( LDAPS_SRVTYPE_PREFIX ) ); 721 strcpy( lutil_strcopy(slapd_srvurls[i], 722 LDAPS_SRVTYPE_PREFIX ), global_host_bv.bv_val ); 723 } 724 } 725 726 /* open the SLP handle */ 727 err = SLPOpen( "en", 0, &slapd_hslp ); 728 729 if ( err != SLP_OK ) { 730 Debug( LDAP_DEBUG_CONNS, "daemon: SLPOpen() failed with %ld\n", 731 (long)err, 0, 0 ); 732 } 733 } 734 735 static void 736 slapd_slp_deinit( void ) 737 { 738 if ( slapd_srvurls == NULL ) return; 739 740 ldap_charray_free( slapd_srvurls ); 741 slapd_srvurls = NULL; 742 743 /* close the SLP handle */ 744 SLPClose( slapd_hslp ); 745 } 746 747 static void 748 slapd_slp_regreport( 749 SLPHandle hslp, 750 SLPError errcode, 751 void *cookie ) 752 { 753 /* return the error code in the cookie */ 754 *(SLPError*)cookie = errcode; 755 } 756 757 static void 758 slapd_slp_reg() 759 { 760 int i; 761 SLPError err; 762 763 if ( slapd_srvurls == NULL ) return; 764 765 for ( i = 0; slapd_srvurls[i] != NULL; i++ ) { 766 if ( strncmp( slapd_srvurls[i], LDAP_SRVTYPE_PREFIX, 767 sizeof( LDAP_SRVTYPE_PREFIX ) - 1 ) == 0 || 768 strncmp( slapd_srvurls[i], LDAPS_SRVTYPE_PREFIX, 769 sizeof( LDAPS_SRVTYPE_PREFIX ) - 1 ) == 0 ) 770 { 771 err = SLPReg( slapd_hslp, 772 slapd_srvurls[i], 773 SLP_LIFETIME_MAXIMUM, 774 "ldap", 775 (slapd_slp_attrs) ? slapd_slp_attrs : "", 776 SLP_TRUE, 777 slapd_slp_regreport, 778 &slapd_slp_cookie ); 779 780 if ( err != SLP_OK || slapd_slp_cookie != SLP_OK ) { 781 Debug( LDAP_DEBUG_CONNS, 782 "daemon: SLPReg(%s) failed with %ld, cookie = %ld\n", 783 slapd_srvurls[i], (long)err, (long)slapd_slp_cookie ); 784 } 785 } 786 } 787 } 788 789 static void 790 slapd_slp_dereg( void ) 791 { 792 int i; 793 SLPError err; 794 795 if ( slapd_srvurls == NULL ) return; 796 797 for ( i = 0; slapd_srvurls[i] != NULL; i++ ) { 798 err = SLPDereg( slapd_hslp, 799 slapd_srvurls[i], 800 slapd_slp_regreport, 801 &slapd_slp_cookie ); 802 803 if ( err != SLP_OK || slapd_slp_cookie != SLP_OK ) { 804 Debug( LDAP_DEBUG_CONNS, 805 "daemon: SLPDereg(%s) failed with %ld, cookie = %ld\n", 806 slapd_srvurls[i], (long)err, (long)slapd_slp_cookie ); 807 } 808 } 809 } 810 #endif /* HAVE_SLP */ 811 812 #ifdef HAVE_WINSOCK 813 /* Manage the descriptor to socket table */ 814 ber_socket_t 815 slapd_socknew( ber_socket_t s ) 816 { 817 ber_socket_t i; 818 ldap_pvt_thread_mutex_lock( &slapd_ws_mutex ); 819 for ( i = 0; i < dtblsize && slapd_ws_sockets[i] != INVALID_SOCKET; i++ ); 820 if ( i == dtblsize ) { 821 WSASetLastError( WSAEMFILE ); 822 } else { 823 slapd_ws_sockets[i] = s; 824 } 825 ldap_pvt_thread_mutex_unlock( &slapd_ws_mutex ); 826 return i; 827 } 828 829 void 830 slapd_sockdel( ber_socket_t s ) 831 { 832 ldap_pvt_thread_mutex_lock( &slapd_ws_mutex ); 833 slapd_ws_sockets[s] = INVALID_SOCKET; 834 ldap_pvt_thread_mutex_unlock( &slapd_ws_mutex ); 835 } 836 837 ber_socket_t 838 slapd_sock2fd( ber_socket_t s ) 839 { 840 ber_socket_t i; 841 for ( i=0; i<dtblsize && slapd_ws_sockets[i] != s; i++); 842 if ( i == dtblsize ) 843 i = -1; 844 return i; 845 } 846 #endif 847 848 #ifdef DEBUG_CLOSE 849 /* Was used to find a bug causing slapd's descriptors to be closed 850 * out from under it. Tracked it down to a long-standing (from 2009) 851 * bug in Heimdal https://github.com/heimdal/heimdal/issues/431 . 852 * Leaving this here for future use, if necessary. 853 */ 854 #include <dlfcn.h> 855 #ifndef RTLD_NEXT 856 #define RTLD_NEXT (void *)-1L 857 #endif 858 static char *newconns; 859 typedef int (closefunc)(int fd); 860 static closefunc *close_ptr; 861 int close( int s ) 862 { 863 if (newconns) { 864 Debug( LDAP_DEBUG_CONNS, 865 "daemon: close(%ld)\n", s, 0, 0 ); 866 if (s >= 0 && s < dtblsize && newconns[s]) 867 assert(newconns[s] == 2); 868 } 869 return close_ptr ? close_ptr(s) : -1; 870 } 871 872 void slapd_debug_close() 873 { 874 if (dtblsize) 875 newconns = ch_calloc(1, dtblsize); 876 close_ptr = dlsym(RTLD_NEXT, "close"); 877 } 878 879 void slapd_set_close(int fd) 880 { 881 newconns[fd] = 3; 882 } 883 #define SETUP_CLOSE() slapd_debug_close() 884 #define SET_CLOSE(fd) slapd_set_close(fd) 885 #define CLR_CLOSE(fd) if (newconns[fd]) newconns[fd]-- 886 #else 887 #define SETUP_CLOSE(fd) 888 #define SET_CLOSE(fd) 889 #define CLR_CLOSE(fd) 890 #endif 891 892 /* 893 * Add a descriptor to daemon control 894 * 895 * If isactive, the descriptor is a live server session and is subject 896 * to idletimeout control. Otherwise, the descriptor is a passive 897 * listener or an outbound client session, and not subject to 898 * idletimeout. The underlying event handler may record the Listener 899 * argument to differentiate Listener's from real sessions. 900 */ 901 static void 902 slapd_add( ber_socket_t s, int isactive, Listener *sl, int id ) 903 { 904 if (id < 0) 905 id = DAEMON_ID(s); 906 ldap_pvt_thread_mutex_lock( &slap_daemon[id].sd_mutex ); 907 908 assert( SLAP_SOCK_NOT_ACTIVE(id, s) ); 909 910 if ( isactive ) slap_daemon[id].sd_nactives++; 911 912 SLAP_SOCK_ADD(id, s, sl); 913 914 Debug( LDAP_DEBUG_CONNS, "daemon: added %ldr%s listener=%p\n", 915 (long) s, isactive ? " (active)" : "", (void *)sl ); 916 917 ldap_pvt_thread_mutex_unlock( &slap_daemon[id].sd_mutex ); 918 919 WAKE_LISTENER(id,1); 920 } 921 922 /* 923 * Remove the descriptor from daemon control 924 */ 925 void 926 slapd_remove( 927 ber_socket_t s, 928 Sockbuf *sb, 929 int wasactive, 930 int wake, 931 int locked ) 932 { 933 int waswriter; 934 int wasreader; 935 int id = DAEMON_ID(s); 936 937 if ( !locked ) 938 ldap_pvt_thread_mutex_lock( &slap_daemon[id].sd_mutex ); 939 940 assert( SLAP_SOCK_IS_ACTIVE( id, s )); 941 942 if ( wasactive ) slap_daemon[id].sd_nactives--; 943 944 waswriter = SLAP_SOCK_IS_WRITE(id, s); 945 wasreader = SLAP_SOCK_IS_READ(id, s); 946 947 Debug( LDAP_DEBUG_CONNS, "daemon: removing %ld%s%s\n", 948 (long) s, 949 wasreader ? "r" : "", 950 waswriter ? "w" : "" ); 951 952 if ( waswriter ) slap_daemon[id].sd_nwriters--; 953 954 SLAP_SOCK_DEL(id, s); 955 CLR_CLOSE(s); 956 957 if ( sb ) 958 ber_sockbuf_free(sb); 959 960 /* If we ran out of file descriptors, we dropped a listener from 961 * the select() loop. Now that we're removing a session from our 962 * control, we can try to resume a dropped listener to use. 963 */ 964 if ( emfile && listening ) { 965 int i; 966 for ( i = 0; slap_listeners[i] != NULL; i++ ) { 967 Listener *lr = slap_listeners[i]; 968 969 if ( lr->sl_sd == AC_SOCKET_INVALID ) continue; 970 if ( lr->sl_sd == s ) continue; 971 if ( lr->sl_mute ) { 972 lr->sl_mute = 0; 973 emfile--; 974 if ( DAEMON_ID(lr->sl_sd) != id ) 975 WAKE_LISTENER(DAEMON_ID(lr->sl_sd), wake); 976 break; 977 } 978 } 979 /* Walked the entire list without enabling anything; emfile 980 * counter is stale. Reset it. 981 */ 982 if ( slap_listeners[i] == NULL ) emfile = 0; 983 } 984 ldap_pvt_thread_mutex_unlock( &slap_daemon[id].sd_mutex ); 985 WAKE_LISTENER(id, wake || slapd_gentle_shutdown == 2); 986 } 987 988 void 989 slapd_clr_write( ber_socket_t s, int wake ) 990 { 991 int id = DAEMON_ID(s); 992 ldap_pvt_thread_mutex_lock( &slap_daemon[id].sd_mutex ); 993 994 if ( SLAP_SOCK_IS_WRITE( id, s )) { 995 assert( SLAP_SOCK_IS_ACTIVE( id, s )); 996 997 SLAP_SOCK_CLR_WRITE( id, s ); 998 slap_daemon[id].sd_nwriters--; 999 } 1000 1001 ldap_pvt_thread_mutex_unlock( &slap_daemon[id].sd_mutex ); 1002 WAKE_LISTENER(id,wake); 1003 } 1004 1005 void 1006 slapd_set_write( ber_socket_t s, int wake ) 1007 { 1008 int id = DAEMON_ID(s); 1009 ldap_pvt_thread_mutex_lock( &slap_daemon[id].sd_mutex ); 1010 1011 assert( SLAP_SOCK_IS_ACTIVE( id, s )); 1012 1013 if ( !SLAP_SOCK_IS_WRITE( id, s )) { 1014 SLAP_SOCK_SET_WRITE( id, s ); 1015 slap_daemon[id].sd_nwriters++; 1016 } 1017 if (( wake & 2 ) && global_writetimeout && !chk_writetime ) { 1018 if (id) 1019 ldap_pvt_thread_mutex_lock( &slap_daemon[0].sd_mutex ); 1020 if (!chk_writetime) 1021 chk_writetime = slap_get_time(); 1022 if (id) 1023 ldap_pvt_thread_mutex_unlock( &slap_daemon[0].sd_mutex ); 1024 } 1025 1026 ldap_pvt_thread_mutex_unlock( &slap_daemon[id].sd_mutex ); 1027 WAKE_LISTENER(id,wake); 1028 } 1029 1030 int 1031 slapd_clr_read( ber_socket_t s, int wake ) 1032 { 1033 int rc = 1; 1034 int id = DAEMON_ID(s); 1035 ldap_pvt_thread_mutex_lock( &slap_daemon[id].sd_mutex ); 1036 1037 if ( SLAP_SOCK_IS_ACTIVE( id, s )) { 1038 SLAP_SOCK_CLR_READ( id, s ); 1039 rc = 0; 1040 } 1041 ldap_pvt_thread_mutex_unlock( &slap_daemon[id].sd_mutex ); 1042 if ( !rc ) 1043 WAKE_LISTENER(id,wake); 1044 return rc; 1045 } 1046 1047 void 1048 slapd_set_read( ber_socket_t s, int wake ) 1049 { 1050 int do_wake = 1; 1051 int id = DAEMON_ID(s); 1052 ldap_pvt_thread_mutex_lock( &slap_daemon[id].sd_mutex ); 1053 1054 if( SLAP_SOCK_IS_ACTIVE( id, s ) && !SLAP_SOCK_IS_READ( id, s )) { 1055 SLAP_SOCK_SET_READ( id, s ); 1056 } else { 1057 do_wake = 0; 1058 } 1059 ldap_pvt_thread_mutex_unlock( &slap_daemon[id].sd_mutex ); 1060 if ( do_wake ) 1061 WAKE_LISTENER(id,wake); 1062 } 1063 1064 time_t 1065 slapd_get_writetime() 1066 { 1067 time_t cur; 1068 ldap_pvt_thread_mutex_lock( &slap_daemon[0].sd_mutex ); 1069 cur = chk_writetime; 1070 ldap_pvt_thread_mutex_unlock( &slap_daemon[0].sd_mutex ); 1071 return cur; 1072 } 1073 1074 void 1075 slapd_clr_writetime( time_t old ) 1076 { 1077 ldap_pvt_thread_mutex_lock( &slap_daemon[0].sd_mutex ); 1078 if ( chk_writetime == old ) 1079 chk_writetime = 0; 1080 ldap_pvt_thread_mutex_unlock( &slap_daemon[0].sd_mutex ); 1081 } 1082 1083 static void 1084 slapd_close( ber_socket_t s ) 1085 { 1086 Debug( LDAP_DEBUG_CONNS, "daemon: closing %ld\n", 1087 (long) s, 0, 0 ); 1088 CLR_CLOSE( SLAP_FD2SOCK(s) ); 1089 tcp_close( SLAP_FD2SOCK(s) ); 1090 #ifdef HAVE_WINSOCK 1091 slapd_sockdel( s ); 1092 #endif 1093 } 1094 1095 static void 1096 slap_free_listener_addresses( struct sockaddr **sal ) 1097 { 1098 struct sockaddr **sap; 1099 if (sal == NULL) return; 1100 for (sap = sal; *sap != NULL; sap++) ch_free(*sap); 1101 ch_free(sal); 1102 } 1103 1104 #if defined(LDAP_PF_LOCAL) || defined(SLAP_X_LISTENER_MOD) 1105 static int 1106 get_url_perms( 1107 char **exts, 1108 mode_t *perms, 1109 int *crit ) 1110 { 1111 int i; 1112 1113 assert( exts != NULL ); 1114 assert( perms != NULL ); 1115 assert( crit != NULL ); 1116 1117 *crit = 0; 1118 for ( i = 0; exts[ i ]; i++ ) { 1119 char *type = exts[ i ]; 1120 int c = 0; 1121 1122 if ( type[ 0 ] == '!' ) { 1123 c = 1; 1124 type++; 1125 } 1126 1127 if ( strncasecmp( type, LDAPI_MOD_URLEXT "=", 1128 sizeof(LDAPI_MOD_URLEXT "=") - 1 ) == 0 ) 1129 { 1130 char *value = type + ( sizeof(LDAPI_MOD_URLEXT "=") - 1 ); 1131 mode_t p = 0; 1132 int j; 1133 1134 switch (strlen(value)) { 1135 case 4: 1136 /* skip leading '0' */ 1137 if ( value[ 0 ] != '0' ) return LDAP_OTHER; 1138 value++; 1139 1140 case 3: 1141 for ( j = 0; j < 3; j++) { 1142 int v; 1143 1144 v = value[ j ] - '0'; 1145 1146 if ( v < 0 || v > 7 ) return LDAP_OTHER; 1147 1148 p |= v << 3*(2-j); 1149 } 1150 break; 1151 1152 case 10: 1153 for ( j = 1; j < 10; j++ ) { 1154 static mode_t m[] = { 0, 1155 S_IRUSR, S_IWUSR, S_IXUSR, 1156 S_IRGRP, S_IWGRP, S_IXGRP, 1157 S_IROTH, S_IWOTH, S_IXOTH 1158 }; 1159 static const char c[] = "-rwxrwxrwx"; 1160 1161 if ( value[ j ] == c[ j ] ) { 1162 p |= m[ j ]; 1163 1164 } else if ( value[ j ] != '-' ) { 1165 return LDAP_OTHER; 1166 } 1167 } 1168 break; 1169 1170 default: 1171 return LDAP_OTHER; 1172 } 1173 1174 *crit = c; 1175 *perms = p; 1176 1177 return LDAP_SUCCESS; 1178 } 1179 } 1180 1181 return LDAP_OTHER; 1182 } 1183 #endif /* LDAP_PF_LOCAL || SLAP_X_LISTENER_MOD */ 1184 1185 /* port = 0 indicates AF_LOCAL */ 1186 static int 1187 slap_get_listener_addresses( 1188 const char *host, 1189 unsigned short port, 1190 struct sockaddr ***sal ) 1191 { 1192 struct sockaddr **sap; 1193 1194 #ifdef LDAP_PF_LOCAL 1195 if ( port == 0 ) { 1196 *sal = ch_malloc(2 * sizeof(void *)); 1197 if (*sal == NULL) return -1; 1198 1199 sap = *sal; 1200 *sap = ch_malloc(sizeof(struct sockaddr_un)); 1201 if (*sap == NULL) goto errexit; 1202 sap[1] = NULL; 1203 1204 if ( strlen(host) > 1205 (sizeof(((struct sockaddr_un *)*sap)->sun_path) - 1) ) 1206 { 1207 Debug( LDAP_DEBUG_ANY, 1208 "daemon: domain socket path (%s) too long in URL", 1209 host, 0, 0); 1210 goto errexit; 1211 } 1212 1213 (void)memset( (void *)*sap, '\0', sizeof(struct sockaddr_un) ); 1214 (*sap)->sa_family = AF_LOCAL; 1215 strcpy( ((struct sockaddr_un *)*sap)->sun_path, host ); 1216 } else 1217 #endif /* LDAP_PF_LOCAL */ 1218 { 1219 #ifdef HAVE_GETADDRINFO 1220 struct addrinfo hints, *res, *sai; 1221 int n, err; 1222 char serv[7]; 1223 1224 memset( &hints, '\0', sizeof(hints) ); 1225 hints.ai_flags = AI_PASSIVE; 1226 hints.ai_socktype = SOCK_STREAM; 1227 hints.ai_family = slap_inet4or6; 1228 snprintf(serv, sizeof serv, "%d", port); 1229 1230 if ( (err = getaddrinfo(host, serv, &hints, &res)) ) { 1231 Debug( LDAP_DEBUG_ANY, "daemon: getaddrinfo() failed: %s\n", 1232 AC_GAI_STRERROR(err), 0, 0); 1233 return -1; 1234 } 1235 1236 sai = res; 1237 for (n=2; (sai = sai->ai_next) != NULL; n++) { 1238 /* EMPTY */ ; 1239 } 1240 *sal = ch_calloc(n, sizeof(void *)); 1241 if (*sal == NULL) return -1; 1242 1243 sap = *sal; 1244 *sap = NULL; 1245 1246 for ( sai=res; sai; sai=sai->ai_next ) { 1247 if( sai->ai_addr == NULL ) { 1248 Debug( LDAP_DEBUG_ANY, "slap_get_listener_addresses: " 1249 "getaddrinfo ai_addr is NULL?\n", 0, 0, 0 ); 1250 freeaddrinfo(res); 1251 goto errexit; 1252 } 1253 1254 switch (sai->ai_family) { 1255 # ifdef LDAP_PF_INET6 1256 case AF_INET6: 1257 *sap = ch_malloc(sizeof(struct sockaddr_in6)); 1258 if (*sap == NULL) { 1259 freeaddrinfo(res); 1260 goto errexit; 1261 } 1262 *(struct sockaddr_in6 *)*sap = 1263 *((struct sockaddr_in6 *)sai->ai_addr); 1264 break; 1265 # endif /* LDAP_PF_INET6 */ 1266 case AF_INET: 1267 *sap = ch_malloc(sizeof(struct sockaddr_in)); 1268 if (*sap == NULL) { 1269 freeaddrinfo(res); 1270 goto errexit; 1271 } 1272 *(struct sockaddr_in *)*sap = 1273 *((struct sockaddr_in *)sai->ai_addr); 1274 break; 1275 default: 1276 *sap = NULL; 1277 break; 1278 } 1279 1280 if (*sap != NULL) { 1281 (*sap)->sa_family = sai->ai_family; 1282 sap++; 1283 *sap = NULL; 1284 } 1285 } 1286 1287 freeaddrinfo(res); 1288 1289 #else /* ! HAVE_GETADDRINFO */ 1290 int i, n = 1; 1291 struct in_addr in; 1292 struct hostent *he = NULL; 1293 1294 if ( host == NULL ) { 1295 in.s_addr = htonl(INADDR_ANY); 1296 1297 } else if ( !inet_aton( host, &in ) ) { 1298 he = gethostbyname( host ); 1299 if( he == NULL ) { 1300 Debug( LDAP_DEBUG_ANY, 1301 "daemon: invalid host %s", host, 0, 0); 1302 return -1; 1303 } 1304 for (n = 0; he->h_addr_list[n]; n++) /* empty */; 1305 } 1306 1307 *sal = ch_malloc((n+1) * sizeof(void *)); 1308 if (*sal == NULL) return -1; 1309 1310 sap = *sal; 1311 for ( i = 0; i<n; i++ ) { 1312 sap[i] = ch_malloc(sizeof(struct sockaddr_in)); 1313 if (*sap == NULL) goto errexit; 1314 1315 (void)memset( (void *)sap[i], '\0', sizeof(struct sockaddr_in) ); 1316 sap[i]->sa_family = AF_INET; 1317 ((struct sockaddr_in *)sap[i])->sin_port = htons(port); 1318 AC_MEMCPY( &((struct sockaddr_in *)sap[i])->sin_addr, 1319 he ? (struct in_addr *)he->h_addr_list[i] : &in, 1320 sizeof(struct in_addr) ); 1321 } 1322 sap[i] = NULL; 1323 #endif /* ! HAVE_GETADDRINFO */ 1324 } 1325 1326 return 0; 1327 1328 errexit: 1329 slap_free_listener_addresses(*sal); 1330 return -1; 1331 } 1332 1333 static int 1334 slap_open_listener( 1335 const char* url, 1336 int *listeners, 1337 int *cur ) 1338 { 1339 int num, tmp, rc; 1340 Listener l; 1341 Listener *li; 1342 LDAPURLDesc *lud; 1343 unsigned short port; 1344 int err, addrlen = 0; 1345 struct sockaddr **sal = NULL, **psal; 1346 int socktype = SOCK_STREAM; /* default to COTS */ 1347 ber_socket_t s; 1348 1349 #if defined(LDAP_PF_LOCAL) || defined(SLAP_X_LISTENER_MOD) 1350 /* 1351 * use safe defaults 1352 */ 1353 int crit = 1; 1354 #endif /* LDAP_PF_LOCAL || SLAP_X_LISTENER_MOD */ 1355 1356 rc = ldap_url_parse( url, &lud ); 1357 1358 if( rc != LDAP_URL_SUCCESS ) { 1359 Debug( LDAP_DEBUG_ANY, 1360 "daemon: listen URL \"%s\" parse error=%d\n", 1361 url, rc, 0 ); 1362 return rc; 1363 } 1364 1365 l.sl_url.bv_val = NULL; 1366 l.sl_mute = 0; 1367 l.sl_busy = 0; 1368 1369 #ifndef HAVE_TLS 1370 if( ldap_pvt_url_scheme2tls( lud->lud_scheme ) ) { 1371 Debug( LDAP_DEBUG_ANY, "daemon: TLS not supported (%s)\n", 1372 url, 0, 0 ); 1373 ldap_free_urldesc( lud ); 1374 return -1; 1375 } 1376 1377 if(! lud->lud_port ) lud->lud_port = LDAP_PORT; 1378 1379 #else /* HAVE_TLS */ 1380 l.sl_is_tls = ldap_pvt_url_scheme2tls( lud->lud_scheme ); 1381 1382 if(! lud->lud_port ) { 1383 lud->lud_port = l.sl_is_tls ? LDAPS_PORT : LDAP_PORT; 1384 } 1385 #endif /* HAVE_TLS */ 1386 1387 #ifdef LDAP_TCP_BUFFER 1388 l.sl_tcp_rmem = 0; 1389 l.sl_tcp_wmem = 0; 1390 #endif /* LDAP_TCP_BUFFER */ 1391 1392 port = (unsigned short) lud->lud_port; 1393 1394 tmp = ldap_pvt_url_scheme2proto(lud->lud_scheme); 1395 if ( tmp == LDAP_PROTO_IPC ) { 1396 #ifdef LDAP_PF_LOCAL 1397 if ( lud->lud_host == NULL || lud->lud_host[0] == '\0' ) { 1398 err = slap_get_listener_addresses(LDAPI_SOCK, 0, &sal); 1399 } else { 1400 err = slap_get_listener_addresses(lud->lud_host, 0, &sal); 1401 } 1402 #else /* ! LDAP_PF_LOCAL */ 1403 1404 Debug( LDAP_DEBUG_ANY, "daemon: URL scheme not supported: %s", 1405 url, 0, 0); 1406 ldap_free_urldesc( lud ); 1407 return -1; 1408 #endif /* ! LDAP_PF_LOCAL */ 1409 } else { 1410 if( lud->lud_host == NULL || lud->lud_host[0] == '\0' 1411 || strcmp(lud->lud_host, "*") == 0 ) 1412 { 1413 err = slap_get_listener_addresses(NULL, port, &sal); 1414 } else { 1415 err = slap_get_listener_addresses(lud->lud_host, port, &sal); 1416 } 1417 } 1418 1419 #ifdef LDAP_CONNECTIONLESS 1420 l.sl_is_udp = ( tmp == LDAP_PROTO_UDP ); 1421 #endif /* LDAP_CONNECTIONLESS */ 1422 1423 #if defined(LDAP_PF_LOCAL) || defined(SLAP_X_LISTENER_MOD) 1424 if ( lud->lud_exts ) { 1425 err = get_url_perms( lud->lud_exts, &l.sl_perms, &crit ); 1426 } else { 1427 l.sl_perms = S_IRWXU | S_IRWXO; 1428 } 1429 #endif /* LDAP_PF_LOCAL || SLAP_X_LISTENER_MOD */ 1430 1431 ldap_free_urldesc( lud ); 1432 if ( err ) { 1433 slap_free_listener_addresses(sal); 1434 return -1; 1435 } 1436 1437 /* If we got more than one address returned, we need to make space 1438 * for it in the slap_listeners array. 1439 */ 1440 for ( num=0; sal[num]; num++ ) /* empty */; 1441 if ( num > 1 ) { 1442 *listeners += num-1; 1443 slap_listeners = ch_realloc( slap_listeners, 1444 (*listeners + 1) * sizeof(Listener *) ); 1445 } 1446 1447 psal = sal; 1448 while ( *sal != NULL ) { 1449 char *af; 1450 switch( (*sal)->sa_family ) { 1451 case AF_INET: 1452 af = "IPv4"; 1453 break; 1454 #ifdef LDAP_PF_INET6 1455 case AF_INET6: 1456 af = "IPv6"; 1457 break; 1458 #endif /* LDAP_PF_INET6 */ 1459 #ifdef LDAP_PF_LOCAL 1460 case AF_LOCAL: 1461 af = "Local"; 1462 break; 1463 #endif /* LDAP_PF_LOCAL */ 1464 default: 1465 sal++; 1466 continue; 1467 } 1468 1469 #ifdef LDAP_CONNECTIONLESS 1470 if( l.sl_is_udp ) socktype = SOCK_DGRAM; 1471 #endif /* LDAP_CONNECTIONLESS */ 1472 1473 s = socket( (*sal)->sa_family, socktype, 0); 1474 if ( s == AC_SOCKET_INVALID ) { 1475 int err = sock_errno(); 1476 Debug( LDAP_DEBUG_ANY, 1477 "daemon: %s socket() failed errno=%d (%s)\n", 1478 af, err, sock_errstr(err) ); 1479 sal++; 1480 continue; 1481 } 1482 l.sl_sd = SLAP_SOCKNEW( s ); 1483 1484 if ( l.sl_sd >= dtblsize ) { 1485 Debug( LDAP_DEBUG_ANY, 1486 "daemon: listener descriptor %ld is too great %ld\n", 1487 (long) l.sl_sd, (long) dtblsize, 0 ); 1488 tcp_close( s ); 1489 sal++; 1490 continue; 1491 } 1492 1493 #ifdef LDAP_PF_LOCAL 1494 if ( (*sal)->sa_family == AF_LOCAL ) { 1495 unlink( ((struct sockaddr_un *)*sal)->sun_path ); 1496 } else 1497 #endif /* LDAP_PF_LOCAL */ 1498 { 1499 #ifdef SO_REUSEADDR 1500 /* enable address reuse */ 1501 tmp = 1; 1502 rc = setsockopt( s, SOL_SOCKET, SO_REUSEADDR, 1503 (char *) &tmp, sizeof(tmp) ); 1504 if ( rc == AC_SOCKET_ERROR ) { 1505 int err = sock_errno(); 1506 Debug( LDAP_DEBUG_ANY, "slapd(%ld): " 1507 "setsockopt(SO_REUSEADDR) failed errno=%d (%s)\n", 1508 (long) l.sl_sd, err, sock_errstr(err) ); 1509 } 1510 #endif /* SO_REUSEADDR */ 1511 } 1512 1513 switch( (*sal)->sa_family ) { 1514 case AF_INET: 1515 addrlen = sizeof(struct sockaddr_in); 1516 break; 1517 #ifdef LDAP_PF_INET6 1518 case AF_INET6: 1519 #ifdef IPV6_V6ONLY 1520 /* Try to use IPv6 sockets for IPv6 only */ 1521 tmp = 1; 1522 rc = setsockopt( s , IPPROTO_IPV6, IPV6_V6ONLY, 1523 (char *) &tmp, sizeof(tmp) ); 1524 if ( rc == AC_SOCKET_ERROR ) { 1525 int err = sock_errno(); 1526 Debug( LDAP_DEBUG_ANY, "slapd(%ld): " 1527 "setsockopt(IPV6_V6ONLY) failed errno=%d (%s)\n", 1528 (long) l.sl_sd, err, sock_errstr(err) ); 1529 } 1530 #endif /* IPV6_V6ONLY */ 1531 addrlen = sizeof(struct sockaddr_in6); 1532 break; 1533 #endif /* LDAP_PF_INET6 */ 1534 1535 #ifdef LDAP_PF_LOCAL 1536 case AF_LOCAL: 1537 #ifdef LOCAL_CREDS 1538 { 1539 int one = 1; 1540 setsockopt( s, 0, LOCAL_CREDS, &one, sizeof( one ) ); 1541 } 1542 #endif /* LOCAL_CREDS */ 1543 1544 addrlen = sizeof( struct sockaddr_un ); 1545 break; 1546 #endif /* LDAP_PF_LOCAL */ 1547 } 1548 1549 #ifdef LDAP_PF_LOCAL 1550 /* create socket with all permissions set for those systems 1551 * that honor permissions on sockets (e.g. Linux); typically, 1552 * only write is required. To exploit filesystem permissions, 1553 * place the socket in a directory and use directory's 1554 * permissions. Need write perms to the directory to 1555 * create/unlink the socket; likely need exec perms to access 1556 * the socket (ITS#4709) */ 1557 { 1558 mode_t old_umask = 0; 1559 1560 if ( (*sal)->sa_family == AF_LOCAL ) { 1561 old_umask = umask( 0 ); 1562 } 1563 #endif /* LDAP_PF_LOCAL */ 1564 rc = bind( s, *sal, addrlen ); 1565 #ifdef LDAP_PF_LOCAL 1566 if ( old_umask != 0 ) { 1567 umask( old_umask ); 1568 } 1569 } 1570 #endif /* LDAP_PF_LOCAL */ 1571 if ( rc ) { 1572 err = sock_errno(); 1573 Debug( LDAP_DEBUG_ANY, 1574 "daemon: bind(%ld) failed errno=%d (%s)\n", 1575 (long)l.sl_sd, err, sock_errstr( err ) ); 1576 tcp_close( s ); 1577 sal++; 1578 continue; 1579 } 1580 1581 switch ( (*sal)->sa_family ) { 1582 #ifdef LDAP_PF_LOCAL 1583 case AF_LOCAL: { 1584 char *path = ((struct sockaddr_un *)*sal)->sun_path; 1585 l.sl_name.bv_len = strlen(path) + STRLENOF("PATH="); 1586 l.sl_name.bv_val = ber_memalloc( l.sl_name.bv_len + 1 ); 1587 snprintf( l.sl_name.bv_val, l.sl_name.bv_len + 1, 1588 "PATH=%s", path ); 1589 } break; 1590 #endif /* LDAP_PF_LOCAL */ 1591 1592 case AF_INET: { 1593 char addr[INET_ADDRSTRLEN]; 1594 const char *s; 1595 #if defined( HAVE_GETADDRINFO ) && defined( HAVE_INET_NTOP ) 1596 s = inet_ntop( AF_INET, &((struct sockaddr_in *)*sal)->sin_addr, 1597 addr, sizeof(addr) ); 1598 #else /* ! HAVE_GETADDRINFO || ! HAVE_INET_NTOP */ 1599 s = inet_ntoa( ((struct sockaddr_in *) *sal)->sin_addr ); 1600 #endif /* ! HAVE_GETADDRINFO || ! HAVE_INET_NTOP */ 1601 if (!s) s = SLAP_STRING_UNKNOWN; 1602 port = ntohs( ((struct sockaddr_in *)*sal) ->sin_port ); 1603 l.sl_name.bv_val = 1604 ber_memalloc( sizeof("IP=255.255.255.255:65535") ); 1605 snprintf( l.sl_name.bv_val, sizeof("IP=255.255.255.255:65535"), 1606 "IP=%s:%d", s, port ); 1607 l.sl_name.bv_len = strlen( l.sl_name.bv_val ); 1608 } break; 1609 1610 #ifdef LDAP_PF_INET6 1611 case AF_INET6: { 1612 char addr[INET6_ADDRSTRLEN]; 1613 const char *s; 1614 s = inet_ntop( AF_INET6, &((struct sockaddr_in6 *)*sal)->sin6_addr, 1615 addr, sizeof addr); 1616 if (!s) s = SLAP_STRING_UNKNOWN; 1617 port = ntohs( ((struct sockaddr_in6 *)*sal)->sin6_port ); 1618 l.sl_name.bv_len = strlen(s) + sizeof("IP=[]:65535"); 1619 l.sl_name.bv_val = ber_memalloc( l.sl_name.bv_len ); 1620 snprintf( l.sl_name.bv_val, l.sl_name.bv_len, "IP=[%s]:%d", 1621 s, port ); 1622 l.sl_name.bv_len = strlen( l.sl_name.bv_val ); 1623 } break; 1624 #endif /* LDAP_PF_INET6 */ 1625 1626 default: 1627 Debug( LDAP_DEBUG_ANY, "daemon: unsupported address family (%d)\n", 1628 (int) (*sal)->sa_family, 0, 0 ); 1629 break; 1630 } 1631 1632 AC_MEMCPY(&l.sl_sa, *sal, addrlen); 1633 ber_str2bv( url, 0, 1, &l.sl_url); 1634 li = ch_malloc( sizeof( Listener ) ); 1635 *li = l; 1636 slap_listeners[*cur] = li; 1637 (*cur)++; 1638 sal++; 1639 } 1640 1641 slap_free_listener_addresses(psal); 1642 1643 if ( l.sl_url.bv_val == NULL ) { 1644 Debug( LDAP_DEBUG_TRACE, 1645 "slap_open_listener: failed on %s\n", url, 0, 0 ); 1646 return -1; 1647 } 1648 1649 Debug( LDAP_DEBUG_TRACE, "daemon: listener initialized %s\n", 1650 l.sl_url.bv_val, 0, 0 ); 1651 return 0; 1652 } 1653 1654 static int sockinit(void); 1655 static int sockdestroy(void); 1656 1657 static int daemon_inited = 0; 1658 1659 int 1660 slapd_daemon_init( const char *urls ) 1661 { 1662 int i, j, n, rc; 1663 char **u; 1664 1665 Debug( LDAP_DEBUG_ARGS, "daemon_init: %s\n", 1666 urls ? urls : "<null>", 0, 0 ); 1667 1668 for ( i=0; i<SLAPD_MAX_DAEMON_THREADS; i++ ) { 1669 wake_sds[i][0] = AC_SOCKET_INVALID; 1670 wake_sds[i][1] = AC_SOCKET_INVALID; 1671 } 1672 1673 ldap_pvt_thread_mutex_init( &slap_daemon[0].sd_mutex ); 1674 #ifdef HAVE_TCPD 1675 ldap_pvt_thread_mutex_init( &sd_tcpd_mutex ); 1676 #endif /* TCP Wrappers */ 1677 1678 daemon_inited = 1; 1679 1680 if( (rc = sockinit()) != 0 ) return rc; 1681 1682 #ifdef HAVE_SYSCONF 1683 dtblsize = sysconf( _SC_OPEN_MAX ); 1684 #elif defined(HAVE_GETDTABLESIZE) 1685 dtblsize = getdtablesize(); 1686 #else /* ! HAVE_SYSCONF && ! HAVE_GETDTABLESIZE */ 1687 dtblsize = FD_SETSIZE; 1688 #endif /* ! HAVE_SYSCONF && ! HAVE_GETDTABLESIZE */ 1689 1690 SETUP_CLOSE(); 1691 1692 /* open a pipe (or something equivalent connected to itself). 1693 * we write a byte on this fd whenever we catch a signal. The main 1694 * loop will be select'ing on this socket, and will wake up when 1695 * this byte arrives. 1696 */ 1697 if( (rc = lutil_pair( wake_sds[0] )) < 0 ) { 1698 Debug( LDAP_DEBUG_ANY, 1699 "daemon: lutil_pair() failed rc=%d\n", rc, 0, 0 ); 1700 return rc; 1701 } 1702 ber_pvt_socket_set_nonblock( wake_sds[0][1], 1 ); 1703 1704 SLAP_SOCK_INIT(0); 1705 1706 if( urls == NULL ) urls = "ldap:///"; 1707 1708 u = ldap_str2charray( urls, " " ); 1709 1710 if( u == NULL || u[0] == NULL ) { 1711 Debug( LDAP_DEBUG_ANY, "daemon_init: no urls (%s) provided.\n", 1712 urls, 0, 0 ); 1713 if ( u ) 1714 ldap_charray_free( u ); 1715 return -1; 1716 } 1717 1718 for( i=0; u[i] != NULL; i++ ) { 1719 Debug( LDAP_DEBUG_TRACE, "daemon_init: listen on %s\n", 1720 u[i], 0, 0 ); 1721 } 1722 1723 if( i == 0 ) { 1724 Debug( LDAP_DEBUG_ANY, "daemon_init: no listeners to open (%s)\n", 1725 urls, 0, 0 ); 1726 ldap_charray_free( u ); 1727 return -1; 1728 } 1729 1730 Debug( LDAP_DEBUG_TRACE, "daemon_init: %d listeners to open...\n", 1731 i, 0, 0 ); 1732 slap_listeners = ch_malloc( (i+1)*sizeof(Listener *) ); 1733 1734 for(n = 0, j = 0; u[n]; n++ ) { 1735 if ( slap_open_listener( u[n], &i, &j ) ) { 1736 ldap_charray_free( u ); 1737 return -1; 1738 } 1739 } 1740 slap_listeners[j] = NULL; 1741 1742 Debug( LDAP_DEBUG_TRACE, "daemon_init: %d listeners opened\n", 1743 i, 0, 0 ); 1744 1745 1746 #ifdef HAVE_SLP 1747 if( slapd_register_slp ) { 1748 slapd_slp_init( urls ); 1749 slapd_slp_reg(); 1750 } 1751 #endif /* HAVE_SLP */ 1752 1753 ldap_charray_free( u ); 1754 1755 return !i; 1756 } 1757 1758 1759 int 1760 slapd_daemon_destroy( void ) 1761 { 1762 connections_destroy(); 1763 if ( daemon_inited ) { 1764 int i; 1765 1766 for ( i=0; i<slapd_daemon_threads; i++ ) { 1767 #ifdef HAVE_WINSOCK 1768 if ( wake_sds[i][1] != INVALID_SOCKET && 1769 SLAP_FD2SOCK( wake_sds[i][1] ) != SLAP_FD2SOCK( wake_sds[i][0] )) 1770 #endif /* HAVE_WINSOCK */ 1771 tcp_close( SLAP_FD2SOCK(wake_sds[i][1]) ); 1772 #ifdef HAVE_WINSOCK 1773 if ( wake_sds[i][0] != INVALID_SOCKET ) 1774 #endif /* HAVE_WINSOCK */ 1775 tcp_close( SLAP_FD2SOCK(wake_sds[i][0]) ); 1776 ldap_pvt_thread_mutex_destroy( &slap_daemon[i].sd_mutex ); 1777 SLAP_SOCK_DESTROY(i); 1778 } 1779 daemon_inited = 0; 1780 #ifdef HAVE_TCPD 1781 ldap_pvt_thread_mutex_destroy( &sd_tcpd_mutex ); 1782 #endif /* TCP Wrappers */ 1783 } 1784 sockdestroy(); 1785 1786 #ifdef HAVE_SLP 1787 if( slapd_register_slp ) { 1788 slapd_slp_dereg(); 1789 slapd_slp_deinit(); 1790 } 1791 #endif /* HAVE_SLP */ 1792 1793 return 0; 1794 } 1795 1796 1797 static void 1798 close_listeners( 1799 int remove ) 1800 { 1801 int l; 1802 1803 if ( !listening ) 1804 return; 1805 listening = 0; 1806 1807 for ( l = 0; slap_listeners[l] != NULL; l++ ) { 1808 Listener *lr = slap_listeners[l]; 1809 1810 if ( lr->sl_sd != AC_SOCKET_INVALID ) { 1811 int s = lr->sl_sd; 1812 lr->sl_sd = AC_SOCKET_INVALID; 1813 if ( remove ) slapd_remove( s, NULL, 0, 0, 0 ); 1814 1815 #ifdef LDAP_PF_LOCAL 1816 if ( lr->sl_sa.sa_addr.sa_family == AF_LOCAL ) { 1817 unlink( lr->sl_sa.sa_un_addr.sun_path ); 1818 } 1819 #endif /* LDAP_PF_LOCAL */ 1820 1821 slapd_close( s ); 1822 } 1823 } 1824 } 1825 1826 static void 1827 destroy_listeners( void ) 1828 { 1829 Listener *lr, **ll = slap_listeners; 1830 1831 if ( ll == NULL ) 1832 return; 1833 1834 while ( (lr = *ll++) != NULL ) { 1835 if ( lr->sl_url.bv_val ) { 1836 ber_memfree( lr->sl_url.bv_val ); 1837 } 1838 1839 if ( lr->sl_name.bv_val ) { 1840 ber_memfree( lr->sl_name.bv_val ); 1841 } 1842 1843 free( lr ); 1844 } 1845 1846 free( slap_listeners ); 1847 slap_listeners = NULL; 1848 } 1849 1850 static int 1851 slap_listener( 1852 Listener *sl ) 1853 { 1854 Sockaddr from; 1855 1856 ber_socket_t s, sfd; 1857 ber_socklen_t len = sizeof(from); 1858 Connection *c; 1859 slap_ssf_t ssf = 0; 1860 struct berval authid = BER_BVNULL; 1861 #ifdef SLAPD_RLOOKUPS 1862 char hbuf[NI_MAXHOST]; 1863 #endif /* SLAPD_RLOOKUPS */ 1864 1865 char *dnsname = NULL; 1866 const char *peeraddr = NULL; 1867 /* we assume INET6_ADDRSTRLEN > INET_ADDRSTRLEN */ 1868 char addr[INET6_ADDRSTRLEN]; 1869 #ifdef LDAP_PF_LOCAL 1870 char peername[MAXPATHLEN + sizeof("PATH=")]; 1871 #ifdef LDAP_PF_LOCAL_SENDMSG 1872 char peerbuf[8]; 1873 struct berval peerbv = BER_BVNULL; 1874 #endif 1875 #elif defined(LDAP_PF_INET6) 1876 char peername[sizeof("IP=[ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff]:65535")]; 1877 #else /* ! LDAP_PF_LOCAL && ! LDAP_PF_INET6 */ 1878 char peername[sizeof("IP=255.255.255.255:65336")]; 1879 #endif /* LDAP_PF_LOCAL */ 1880 int cflag; 1881 int tid; 1882 1883 Debug( LDAP_DEBUG_TRACE, 1884 ">>> slap_listener(%s)\n", 1885 sl->sl_url.bv_val, 0, 0 ); 1886 1887 peername[0] = '\0'; 1888 1889 #ifdef LDAP_CONNECTIONLESS 1890 if ( sl->sl_is_udp ) return 1; 1891 #endif /* LDAP_CONNECTIONLESS */ 1892 1893 # ifdef LDAP_PF_LOCAL 1894 /* FIXME: apparently accept doesn't fill 1895 * the sun_path sun_path member */ 1896 from.sa_un_addr.sun_path[0] = '\0'; 1897 # endif /* LDAP_PF_LOCAL */ 1898 1899 s = accept( SLAP_FD2SOCK( sl->sl_sd ), (struct sockaddr *) &from, &len ); 1900 if ( s != AC_SOCKET_INVALID ) { 1901 SET_CLOSE(s); 1902 } 1903 Debug( LDAP_DEBUG_CONNS, 1904 "daemon: accept() = %ld\n", s, 0, 0 ); 1905 1906 /* Resume the listener FD to allow concurrent-processing of 1907 * additional incoming connections. 1908 */ 1909 sl->sl_busy = 0; 1910 WAKE_LISTENER(DAEMON_ID(sl->sl_sd),1); 1911 1912 if ( s == AC_SOCKET_INVALID ) { 1913 int err = sock_errno(); 1914 1915 if( 1916 #ifdef EMFILE 1917 err == EMFILE || 1918 #endif /* EMFILE */ 1919 #ifdef ENFILE 1920 err == ENFILE || 1921 #endif /* ENFILE */ 1922 0 ) 1923 { 1924 ldap_pvt_thread_mutex_lock( &slap_daemon[0].sd_mutex ); 1925 emfile++; 1926 /* Stop listening until an existing session closes */ 1927 sl->sl_mute = 1; 1928 ldap_pvt_thread_mutex_unlock( &slap_daemon[0].sd_mutex ); 1929 } 1930 1931 Debug( LDAP_DEBUG_ANY, 1932 "daemon: accept(%ld) failed errno=%d (%s)\n", 1933 (long) sl->sl_sd, err, sock_errstr(err) ); 1934 ldap_pvt_thread_yield(); 1935 return 0; 1936 } 1937 sfd = SLAP_SOCKNEW( s ); 1938 1939 /* make sure descriptor number isn't too great */ 1940 if ( sfd >= dtblsize ) { 1941 Debug( LDAP_DEBUG_ANY, 1942 "daemon: %ld beyond descriptor table size %ld\n", 1943 (long) sfd, (long) dtblsize, 0 ); 1944 1945 tcp_close(s); 1946 ldap_pvt_thread_yield(); 1947 return 0; 1948 } 1949 tid = DAEMON_ID(sfd); 1950 1951 #ifdef LDAP_DEBUG 1952 ldap_pvt_thread_mutex_lock( &slap_daemon[tid].sd_mutex ); 1953 /* newly accepted stream should not be in any of the FD SETS */ 1954 assert( SLAP_SOCK_NOT_ACTIVE( tid, sfd )); 1955 ldap_pvt_thread_mutex_unlock( &slap_daemon[tid].sd_mutex ); 1956 #endif /* LDAP_DEBUG */ 1957 1958 #if defined( SO_KEEPALIVE ) || defined( TCP_NODELAY ) 1959 #ifdef LDAP_PF_LOCAL 1960 /* for IPv4 and IPv6 sockets only */ 1961 if ( from.sa_addr.sa_family != AF_LOCAL ) 1962 #endif /* LDAP_PF_LOCAL */ 1963 { 1964 int rc; 1965 int tmp; 1966 #ifdef SO_KEEPALIVE 1967 /* enable keep alives */ 1968 tmp = 1; 1969 rc = setsockopt( s, SOL_SOCKET, SO_KEEPALIVE, 1970 (char *) &tmp, sizeof(tmp) ); 1971 if ( rc == AC_SOCKET_ERROR ) { 1972 int err = sock_errno(); 1973 Debug( LDAP_DEBUG_ANY, 1974 "slapd(%ld): setsockopt(SO_KEEPALIVE) failed " 1975 "errno=%d (%s)\n", (long) sfd, err, sock_errstr(err) ); 1976 slapd_close(sfd); 1977 return 0; 1978 } 1979 #endif /* SO_KEEPALIVE */ 1980 #ifdef TCP_NODELAY 1981 /* enable no delay */ 1982 tmp = 1; 1983 rc = setsockopt( s, IPPROTO_TCP, TCP_NODELAY, 1984 (char *)&tmp, sizeof(tmp) ); 1985 if ( rc == AC_SOCKET_ERROR ) { 1986 int err = sock_errno(); 1987 Debug( LDAP_DEBUG_ANY, 1988 "slapd(%ld): setsockopt(TCP_NODELAY) failed " 1989 "errno=%d (%s)\n", (long) sfd, err, sock_errstr(err) ); 1990 slapd_close(sfd); 1991 return 0; 1992 } 1993 #endif /* TCP_NODELAY */ 1994 } 1995 #endif /* SO_KEEPALIVE || TCP_NODELAY */ 1996 1997 Debug( LDAP_DEBUG_CONNS, 1998 "daemon: listen=%ld, new connection on %ld\n", 1999 (long) sl->sl_sd, (long) sfd, 0 ); 2000 2001 cflag = 0; 2002 switch ( from.sa_addr.sa_family ) { 2003 # ifdef LDAP_PF_LOCAL 2004 case AF_LOCAL: 2005 cflag |= CONN_IS_IPC; 2006 2007 /* FIXME: apparently accept doesn't fill 2008 * the sun_path sun_path member */ 2009 if ( from.sa_un_addr.sun_path[0] == '\0' ) { 2010 AC_MEMCPY( from.sa_un_addr.sun_path, 2011 sl->sl_sa.sa_un_addr.sun_path, 2012 sizeof( from.sa_un_addr.sun_path ) ); 2013 } 2014 2015 sprintf( peername, "PATH=%s", from.sa_un_addr.sun_path ); 2016 ssf = local_ssf; 2017 { 2018 uid_t uid; 2019 gid_t gid; 2020 2021 #ifdef LDAP_PF_LOCAL_SENDMSG 2022 peerbv.bv_val = peerbuf; 2023 peerbv.bv_len = sizeof( peerbuf ); 2024 #endif 2025 if( LUTIL_GETPEEREID( s, &uid, &gid, &peerbv ) == 0 ) { 2026 authid.bv_val = ch_malloc( 2027 STRLENOF( "gidNumber=4294967295+uidNumber=4294967295," 2028 "cn=peercred,cn=external,cn=auth" ) + 1 ); 2029 authid.bv_len = sprintf( authid.bv_val, 2030 "gidNumber=%d+uidNumber=%d," 2031 "cn=peercred,cn=external,cn=auth", 2032 (int) gid, (int) uid ); 2033 assert( authid.bv_len <= 2034 STRLENOF( "gidNumber=4294967295+uidNumber=4294967295," 2035 "cn=peercred,cn=external,cn=auth" ) ); 2036 } 2037 } 2038 dnsname = "local"; 2039 break; 2040 #endif /* LDAP_PF_LOCAL */ 2041 2042 # ifdef LDAP_PF_INET6 2043 case AF_INET6: 2044 if ( IN6_IS_ADDR_V4MAPPED(&from.sa_in6_addr.sin6_addr) ) { 2045 #if defined( HAVE_GETADDRINFO ) && defined( HAVE_INET_NTOP ) 2046 peeraddr = inet_ntop( AF_INET, 2047 ((struct in_addr *)&from.sa_in6_addr.sin6_addr.s6_addr[12]), 2048 addr, sizeof(addr) ); 2049 #else /* ! HAVE_GETADDRINFO || ! HAVE_INET_NTOP */ 2050 peeraddr = inet_ntoa( *((struct in_addr *) 2051 &from.sa_in6_addr.sin6_addr.s6_addr[12]) ); 2052 #endif /* ! HAVE_GETADDRINFO || ! HAVE_INET_NTOP */ 2053 if ( !peeraddr ) peeraddr = SLAP_STRING_UNKNOWN; 2054 sprintf( peername, "IP=%s:%d", peeraddr, 2055 (unsigned) ntohs( from.sa_in6_addr.sin6_port ) ); 2056 } else { 2057 peeraddr = inet_ntop( AF_INET6, 2058 &from.sa_in6_addr.sin6_addr, 2059 addr, sizeof addr ); 2060 if ( !peeraddr ) peeraddr = SLAP_STRING_UNKNOWN; 2061 sprintf( peername, "IP=[%s]:%d", peeraddr, 2062 (unsigned) ntohs( from.sa_in6_addr.sin6_port ) ); 2063 } 2064 break; 2065 # endif /* LDAP_PF_INET6 */ 2066 2067 case AF_INET: { 2068 #if defined( HAVE_GETADDRINFO ) && defined( HAVE_INET_NTOP ) 2069 peeraddr = inet_ntop( AF_INET, &from.sa_in_addr.sin_addr, 2070 addr, sizeof(addr) ); 2071 #else /* ! HAVE_GETADDRINFO || ! HAVE_INET_NTOP */ 2072 peeraddr = inet_ntoa( from.sa_in_addr.sin_addr ); 2073 #endif /* ! HAVE_GETADDRINFO || ! HAVE_INET_NTOP */ 2074 if ( !peeraddr ) peeraddr = SLAP_STRING_UNKNOWN; 2075 sprintf( peername, "IP=%s:%d", peeraddr, 2076 (unsigned) ntohs( from.sa_in_addr.sin_port ) ); 2077 } break; 2078 2079 default: 2080 slapd_close(sfd); 2081 return 0; 2082 } 2083 2084 if ( ( from.sa_addr.sa_family == AF_INET ) 2085 #ifdef LDAP_PF_INET6 2086 || ( from.sa_addr.sa_family == AF_INET6 ) 2087 #endif /* LDAP_PF_INET6 */ 2088 ) 2089 { 2090 dnsname = NULL; 2091 #ifdef SLAPD_RLOOKUPS 2092 if ( use_reverse_lookup ) { 2093 char *herr; 2094 if (ldap_pvt_get_hname( (const struct sockaddr *)&from, len, hbuf, 2095 sizeof(hbuf), &herr ) == 0) { 2096 ldap_pvt_str2lower( hbuf ); 2097 dnsname = hbuf; 2098 } 2099 } 2100 #endif /* SLAPD_RLOOKUPS */ 2101 2102 #ifdef HAVE_TCPD 2103 { 2104 int rc; 2105 ldap_pvt_thread_mutex_lock( &sd_tcpd_mutex ); 2106 rc = hosts_ctl("slapd", 2107 dnsname != NULL ? dnsname : SLAP_STRING_UNKNOWN, 2108 peeraddr, 2109 SLAP_STRING_UNKNOWN ); 2110 ldap_pvt_thread_mutex_unlock( &sd_tcpd_mutex ); 2111 if ( !rc ) { 2112 /* DENY ACCESS */ 2113 Statslog( LDAP_DEBUG_STATS, 2114 "fd=%ld DENIED from %s (%s)\n", 2115 (long) sfd, 2116 dnsname != NULL ? dnsname : SLAP_STRING_UNKNOWN, 2117 peeraddr, 0, 0 ); 2118 slapd_close(sfd); 2119 return 0; 2120 } 2121 } 2122 #endif /* HAVE_TCPD */ 2123 } 2124 2125 #ifdef HAVE_TLS 2126 if ( sl->sl_is_tls ) cflag |= CONN_IS_TLS; 2127 #endif 2128 c = connection_init(sfd, sl, 2129 dnsname != NULL ? dnsname : SLAP_STRING_UNKNOWN, 2130 peername, cflag, ssf, 2131 authid.bv_val ? &authid : NULL 2132 LDAP_PF_LOCAL_SENDMSG_ARG(&peerbv)); 2133 2134 if( authid.bv_val ) ch_free(authid.bv_val); 2135 2136 if( !c ) { 2137 Debug( LDAP_DEBUG_ANY, 2138 "daemon: connection_init(%ld, %s, %s) failed.\n", 2139 (long) sfd, peername, sl->sl_name.bv_val ); 2140 slapd_close(sfd); 2141 } 2142 2143 return 0; 2144 } 2145 2146 static void* 2147 slap_listener_thread( 2148 void* ctx, 2149 void* ptr ) 2150 { 2151 int rc; 2152 Listener *sl = (Listener *)ptr; 2153 2154 rc = slap_listener( sl ); 2155 2156 if( rc != LDAP_SUCCESS ) { 2157 Debug( LDAP_DEBUG_ANY, 2158 "slap_listener_thread(%s): failed err=%d", 2159 sl->sl_url.bv_val, rc, 0 ); 2160 } 2161 2162 return (void*)NULL; 2163 } 2164 2165 static int 2166 slap_listener_activate( 2167 Listener* sl ) 2168 { 2169 int rc; 2170 2171 Debug( LDAP_DEBUG_TRACE, "slap_listener_activate(%d): %s\n", 2172 sl->sl_sd, sl->sl_busy ? "busy" : "", 0 ); 2173 2174 sl->sl_busy = 1; 2175 2176 rc = ldap_pvt_thread_pool_submit( &connection_pool, 2177 slap_listener_thread, (void *) sl ); 2178 2179 if( rc != 0 ) { 2180 Debug( LDAP_DEBUG_ANY, 2181 "slap_listener_activate(%d): submit failed (%d)\n", 2182 sl->sl_sd, rc, 0 ); 2183 } 2184 return rc; 2185 } 2186 2187 static void * 2188 slapd_daemon_task( 2189 void *ptr ) 2190 { 2191 int l; 2192 time_t last_idle_check = 0; 2193 int ebadf = 0; 2194 int tid = (ldap_pvt_thread_t *) ptr - listener_tid; 2195 2196 #define SLAPD_IDLE_CHECK_LIMIT 4 2197 2198 slapd_add( wake_sds[tid][0], 0, NULL, tid ); 2199 if ( tid ) 2200 goto loop; 2201 2202 /* Init stuff done only by thread 0 */ 2203 2204 last_idle_check = slap_get_time(); 2205 2206 for ( l = 0; slap_listeners[l] != NULL; l++ ) { 2207 if ( slap_listeners[l]->sl_sd == AC_SOCKET_INVALID ) continue; 2208 2209 #ifdef LDAP_CONNECTIONLESS 2210 /* Since this is connectionless, the data port is the 2211 * listening port. The listen() and accept() calls 2212 * are unnecessary. 2213 */ 2214 if ( slap_listeners[l]->sl_is_udp ) 2215 continue; 2216 #endif /* LDAP_CONNECTIONLESS */ 2217 2218 /* FIXME: TCP-only! */ 2219 #ifdef LDAP_TCP_BUFFER 2220 if ( 1 ) { 2221 int origsize, size, realsize, rc; 2222 socklen_t optlen; 2223 char buf[ SLAP_TEXT_BUFLEN ]; 2224 2225 size = 0; 2226 if ( slap_listeners[l]->sl_tcp_rmem > 0 ) { 2227 size = slap_listeners[l]->sl_tcp_rmem; 2228 } else if ( slapd_tcp_rmem > 0 ) { 2229 size = slapd_tcp_rmem; 2230 } 2231 2232 if ( size > 0 ) { 2233 optlen = sizeof( origsize ); 2234 rc = getsockopt( SLAP_FD2SOCK( slap_listeners[l]->sl_sd ), 2235 SOL_SOCKET, 2236 SO_RCVBUF, 2237 (void *)&origsize, 2238 &optlen ); 2239 2240 if ( rc ) { 2241 int err = sock_errno(); 2242 Debug( LDAP_DEBUG_ANY, 2243 "slapd_daemon_task: getsockopt(SO_RCVBUF) failed errno=%d (%s)\n", 2244 err, sock_errstr(err), 0 ); 2245 } 2246 2247 optlen = sizeof( size ); 2248 rc = setsockopt( SLAP_FD2SOCK( slap_listeners[l]->sl_sd ), 2249 SOL_SOCKET, 2250 SO_RCVBUF, 2251 (const void *)&size, 2252 optlen ); 2253 2254 if ( rc ) { 2255 int err = sock_errno(); 2256 Debug( LDAP_DEBUG_ANY, 2257 "slapd_daemon_task: setsockopt(SO_RCVBUF) failed errno=%d (%s)\n", 2258 err, sock_errstr(err), 0 ); 2259 } 2260 2261 optlen = sizeof( realsize ); 2262 rc = getsockopt( SLAP_FD2SOCK( slap_listeners[l]->sl_sd ), 2263 SOL_SOCKET, 2264 SO_RCVBUF, 2265 (void *)&realsize, 2266 &optlen ); 2267 2268 if ( rc ) { 2269 int err = sock_errno(); 2270 Debug( LDAP_DEBUG_ANY, 2271 "slapd_daemon_task: getsockopt(SO_RCVBUF) failed errno=%d (%s)\n", 2272 err, sock_errstr(err), 0 ); 2273 } 2274 2275 snprintf( buf, sizeof( buf ), 2276 "url=%s (#%d) RCVBUF original size=%d requested size=%d real size=%d", 2277 slap_listeners[l]->sl_url.bv_val, l, origsize, size, realsize ); 2278 Debug( LDAP_DEBUG_ANY, 2279 "slapd_daemon_task: %s\n", 2280 buf, 0, 0 ); 2281 } 2282 2283 size = 0; 2284 if ( slap_listeners[l]->sl_tcp_wmem > 0 ) { 2285 size = slap_listeners[l]->sl_tcp_wmem; 2286 } else if ( slapd_tcp_wmem > 0 ) { 2287 size = slapd_tcp_wmem; 2288 } 2289 2290 if ( size > 0 ) { 2291 optlen = sizeof( origsize ); 2292 rc = getsockopt( SLAP_FD2SOCK( slap_listeners[l]->sl_sd ), 2293 SOL_SOCKET, 2294 SO_SNDBUF, 2295 (void *)&origsize, 2296 &optlen ); 2297 2298 if ( rc ) { 2299 int err = sock_errno(); 2300 Debug( LDAP_DEBUG_ANY, 2301 "slapd_daemon_task: getsockopt(SO_SNDBUF) failed errno=%d (%s)\n", 2302 err, sock_errstr(err), 0 ); 2303 } 2304 2305 optlen = sizeof( size ); 2306 rc = setsockopt( SLAP_FD2SOCK( slap_listeners[l]->sl_sd ), 2307 SOL_SOCKET, 2308 SO_SNDBUF, 2309 (const void *)&size, 2310 optlen ); 2311 2312 if ( rc ) { 2313 int err = sock_errno(); 2314 Debug( LDAP_DEBUG_ANY, 2315 "slapd_daemon_task: setsockopt(SO_SNDBUF) failed errno=%d (%s)", 2316 err, sock_errstr(err), 0 ); 2317 } 2318 2319 optlen = sizeof( realsize ); 2320 rc = getsockopt( SLAP_FD2SOCK( slap_listeners[l]->sl_sd ), 2321 SOL_SOCKET, 2322 SO_SNDBUF, 2323 (void *)&realsize, 2324 &optlen ); 2325 2326 if ( rc ) { 2327 int err = sock_errno(); 2328 Debug( LDAP_DEBUG_ANY, 2329 "slapd_daemon_task: getsockopt(SO_SNDBUF) failed errno=%d (%s)\n", 2330 err, sock_errstr(err), 0 ); 2331 } 2332 2333 snprintf( buf, sizeof( buf ), 2334 "url=%s (#%d) SNDBUF original size=%d requested size=%d real size=%d", 2335 slap_listeners[l]->sl_url.bv_val, l, origsize, size, realsize ); 2336 Debug( LDAP_DEBUG_ANY, 2337 "slapd_daemon_task: %s\n", 2338 buf, 0, 0 ); 2339 } 2340 } 2341 #endif /* LDAP_TCP_BUFFER */ 2342 2343 if ( listen( SLAP_FD2SOCK( slap_listeners[l]->sl_sd ), SLAPD_LISTEN_BACKLOG ) == -1 ) { 2344 int err = sock_errno(); 2345 2346 #ifdef LDAP_PF_INET6 2347 /* If error is EADDRINUSE, we are trying to listen to INADDR_ANY and 2348 * we are already listening to in6addr_any, then we want to ignore 2349 * this and continue. 2350 */ 2351 if ( err == EADDRINUSE ) { 2352 int i; 2353 struct sockaddr_in sa = slap_listeners[l]->sl_sa.sa_in_addr; 2354 struct sockaddr_in6 sa6; 2355 2356 if ( sa.sin_family == AF_INET && 2357 sa.sin_addr.s_addr == htonl(INADDR_ANY) ) { 2358 for ( i = 0 ; i < l; i++ ) { 2359 sa6 = slap_listeners[i]->sl_sa.sa_in6_addr; 2360 if ( sa6.sin6_family == AF_INET6 && 2361 !memcmp( &sa6.sin6_addr, &in6addr_any, 2362 sizeof(struct in6_addr) ) ) 2363 { 2364 break; 2365 } 2366 } 2367 2368 if ( i < l ) { 2369 /* We are already listening to in6addr_any */ 2370 Debug( LDAP_DEBUG_CONNS, 2371 "daemon: Attempt to listen to 0.0.0.0 failed, " 2372 "already listening on ::, assuming IPv4 included\n", 2373 0, 0, 0 ); 2374 slapd_close( slap_listeners[l]->sl_sd ); 2375 slap_listeners[l]->sl_sd = AC_SOCKET_INVALID; 2376 continue; 2377 } 2378 } 2379 } 2380 #endif /* LDAP_PF_INET6 */ 2381 Debug( LDAP_DEBUG_ANY, 2382 "daemon: listen(%s, 5) failed errno=%d (%s)\n", 2383 slap_listeners[l]->sl_url.bv_val, err, 2384 sock_errstr(err) ); 2385 return (void*)-1; 2386 } 2387 2388 /* make the listening socket non-blocking */ 2389 if ( ber_pvt_socket_set_nonblock( SLAP_FD2SOCK( slap_listeners[l]->sl_sd ), 1 ) < 0 ) { 2390 Debug( LDAP_DEBUG_ANY, "slapd_daemon_task: " 2391 "set nonblocking on a listening socket failed\n", 2392 0, 0, 0 ); 2393 slapd_shutdown = 2; 2394 return (void*)-1; 2395 } 2396 2397 slapd_add( slap_listeners[l]->sl_sd, 0, slap_listeners[l], -1 ); 2398 } 2399 2400 #ifdef HAVE_NT_SERVICE_MANAGER 2401 if ( started_event != NULL ) { 2402 ldap_pvt_thread_cond_signal( &started_event ); 2403 } 2404 #endif /* HAVE_NT_SERVICE_MANAGER */ 2405 2406 loop: 2407 2408 /* initialization complete. Here comes the loop. */ 2409 2410 while ( !slapd_shutdown ) { 2411 ber_socket_t i; 2412 int ns, nwriters; 2413 int at; 2414 ber_socket_t nfds; 2415 #if SLAP_EVENTS_ARE_INDEXED 2416 ber_socket_t nrfds, nwfds; 2417 #endif /* SLAP_EVENTS_ARE_INDEXED */ 2418 #define SLAPD_EBADF_LIMIT 16 2419 2420 time_t now; 2421 2422 SLAP_EVENT_DECL; 2423 2424 struct timeval tv; 2425 struct timeval *tvp; 2426 2427 struct timeval cat; 2428 time_t tdelta = 1; 2429 struct re_s* rtask; 2430 2431 now = slap_get_time(); 2432 2433 if ( !tid && ( global_idletimeout > 0 || chk_writetime )) { 2434 int check = 0; 2435 /* Set the select timeout. 2436 * Don't just truncate, preserve the fractions of 2437 * seconds to prevent sleeping for zero time. 2438 */ 2439 if ( chk_writetime ) { 2440 tv.tv_sec = global_writetimeout; 2441 tv.tv_usec = 0; 2442 if ( difftime( chk_writetime, now ) < 0 ) 2443 check = 2; 2444 } else { 2445 tv.tv_sec = global_idletimeout / SLAPD_IDLE_CHECK_LIMIT; 2446 tv.tv_usec = global_idletimeout - \ 2447 ( tv.tv_sec * SLAPD_IDLE_CHECK_LIMIT ); 2448 tv.tv_usec *= 1000000 / SLAPD_IDLE_CHECK_LIMIT; 2449 if ( difftime( last_idle_check + 2450 global_idletimeout/SLAPD_IDLE_CHECK_LIMIT, now ) < 0 ) 2451 check = 1; 2452 } 2453 if ( check ) { 2454 connections_timeout_idle( now ); 2455 last_idle_check = now; 2456 } 2457 } else { 2458 tv.tv_sec = 0; 2459 tv.tv_usec = 0; 2460 } 2461 2462 #ifdef SIGHUP 2463 if ( slapd_gentle_shutdown ) { 2464 ber_socket_t active; 2465 2466 if ( !tid && slapd_gentle_shutdown == 1 ) { 2467 BackendDB *be; 2468 Debug( LDAP_DEBUG_ANY, "slapd gentle shutdown\n", 0, 0, 0 ); 2469 close_listeners( 1 ); 2470 frontendDB->be_restrictops |= SLAP_RESTRICT_OP_WRITES; 2471 LDAP_STAILQ_FOREACH(be, &backendDB, be_next) { 2472 be->be_restrictops |= SLAP_RESTRICT_OP_WRITES; 2473 } 2474 slapd_gentle_shutdown = 2; 2475 } 2476 2477 ldap_pvt_thread_mutex_lock( &slap_daemon[tid].sd_mutex ); 2478 active = slap_daemon[tid].sd_nactives; 2479 ldap_pvt_thread_mutex_unlock( &slap_daemon[tid].sd_mutex ); 2480 2481 if ( active == 0 ) { 2482 if ( !tid ) { 2483 for ( l=1; l<slapd_daemon_threads; l++ ) { 2484 ldap_pvt_thread_mutex_lock( &slap_daemon[l].sd_mutex ); 2485 active += slap_daemon[l].sd_nactives; 2486 ldap_pvt_thread_mutex_unlock( &slap_daemon[l].sd_mutex ); 2487 } 2488 if ( !active ) 2489 slapd_shutdown = 1; 2490 } 2491 if ( !active ) 2492 break; 2493 } 2494 } 2495 #endif /* SIGHUP */ 2496 at = 0; 2497 2498 ldap_pvt_thread_mutex_lock( &slap_daemon[tid].sd_mutex ); 2499 2500 nwriters = slap_daemon[tid].sd_nwriters; 2501 2502 if ( listening ) 2503 for ( l = 0; slap_listeners[l] != NULL; l++ ) { 2504 Listener *lr = slap_listeners[l]; 2505 2506 if ( lr->sl_sd == AC_SOCKET_INVALID ) continue; 2507 if ( DAEMON_ID( lr->sl_sd ) != tid ) continue; 2508 2509 if ( lr->sl_mute || lr->sl_busy ) 2510 { 2511 SLAP_SOCK_CLR_READ( tid, lr->sl_sd ); 2512 } else { 2513 SLAP_SOCK_SET_READ( tid, lr->sl_sd ); 2514 } 2515 } 2516 2517 SLAP_EVENT_INIT(tid); 2518 2519 nfds = SLAP_EVENT_MAX(tid); 2520 2521 if (( chk_writetime || global_idletimeout ) && slap_daemon[tid].sd_nactives ) at = 1; 2522 2523 ldap_pvt_thread_mutex_unlock( &slap_daemon[tid].sd_mutex ); 2524 2525 if ( at 2526 #if defined(HAVE_YIELDING_SELECT) || defined(NO_THREADS) 2527 && ( tv.tv_sec || tv.tv_usec ) 2528 #endif /* HAVE_YIELDING_SELECT || NO_THREADS */ 2529 ) 2530 { 2531 tvp = &tv; 2532 } else { 2533 tvp = NULL; 2534 } 2535 2536 /* Only thread 0 handles runqueue */ 2537 if ( !tid ) { 2538 ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex ); 2539 rtask = ldap_pvt_runqueue_next_sched( &slapd_rq, &cat ); 2540 while ( rtask && cat.tv_sec && cat.tv_sec <= now ) { 2541 if ( ldap_pvt_runqueue_isrunning( &slapd_rq, rtask )) { 2542 ldap_pvt_runqueue_resched( &slapd_rq, rtask, 0 ); 2543 } else { 2544 ldap_pvt_runqueue_runtask( &slapd_rq, rtask ); 2545 ldap_pvt_runqueue_resched( &slapd_rq, rtask, 0 ); 2546 ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex ); 2547 ldap_pvt_thread_pool_submit( &connection_pool, 2548 rtask->routine, (void *) rtask ); 2549 ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex ); 2550 } 2551 rtask = ldap_pvt_runqueue_next_sched( &slapd_rq, &cat ); 2552 } 2553 ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex ); 2554 2555 if ( rtask && cat.tv_sec ) { 2556 /* NOTE: diff __should__ always be >= 0, 2557 * AFAI understand; however (ITS#4872), 2558 * time_t might be unsigned in some systems, 2559 * while difftime() returns a double */ 2560 double diff = difftime( cat.tv_sec, now ); 2561 if ( diff <= 0 ) { 2562 diff = tdelta; 2563 } 2564 if ( tvp == NULL || diff < tv.tv_sec ) { 2565 tv.tv_sec = diff; 2566 tv.tv_usec = 0; 2567 tvp = &tv; 2568 } 2569 } 2570 } 2571 2572 for ( l = 0; slap_listeners[l] != NULL; l++ ) { 2573 Listener *lr = slap_listeners[l]; 2574 2575 if ( lr->sl_sd == AC_SOCKET_INVALID ) { 2576 continue; 2577 } 2578 2579 if ( lr->sl_mute ) { 2580 Debug( LDAP_DEBUG_CONNS, 2581 "daemon: " SLAP_EVENT_FNAME ": " 2582 "listen=%d muted\n", 2583 lr->sl_sd, 0, 0 ); 2584 continue; 2585 } 2586 2587 if ( lr->sl_busy ) { 2588 Debug( LDAP_DEBUG_CONNS, 2589 "daemon: " SLAP_EVENT_FNAME ": " 2590 "listen=%d busy\n", 2591 lr->sl_sd, 0, 0 ); 2592 continue; 2593 } 2594 2595 Debug( LDAP_DEBUG_CONNS, 2596 "daemon: " SLAP_EVENT_FNAME ": " 2597 "listen=%d active_threads=%d tvp=%s\n", 2598 lr->sl_sd, at, tvp == NULL ? "NULL" : "zero" ); 2599 } 2600 2601 SLAP_EVENT_WAIT( tid, tvp, &ns ); 2602 switch ( ns ) { 2603 case -1: { /* failure - try again */ 2604 int err = sock_errno(); 2605 2606 if ( err != EINTR ) { 2607 ebadf++; 2608 2609 /* Don't log unless we got it twice in a row */ 2610 if ( !( ebadf & 1 ) ) { 2611 Debug( LDAP_DEBUG_ANY, 2612 "daemon: " 2613 SLAP_EVENT_FNAME 2614 " failed count %d " 2615 "err (%d): %s\n", 2616 ebadf, err, 2617 sock_errstr( err ) ); 2618 } 2619 if ( ebadf >= SLAPD_EBADF_LIMIT ) { 2620 slapd_shutdown = 2; 2621 } 2622 } 2623 } 2624 continue; 2625 2626 case 0: /* timeout - let threads run */ 2627 ebadf = 0; 2628 #ifndef HAVE_YIELDING_SELECT 2629 Debug( LDAP_DEBUG_CONNS, "daemon: " SLAP_EVENT_FNAME 2630 "timeout - yielding\n", 2631 0, 0, 0 ); 2632 2633 ldap_pvt_thread_yield(); 2634 #endif /* ! HAVE_YIELDING_SELECT */ 2635 continue; 2636 2637 default: /* something happened - deal with it */ 2638 if ( slapd_shutdown ) continue; 2639 2640 ebadf = 0; 2641 Debug( LDAP_DEBUG_CONNS, 2642 "daemon: activity on %d descriptor%s\n", 2643 ns, ns != 1 ? "s" : "", 0 ); 2644 /* FALL THRU */ 2645 } 2646 2647 #if SLAP_EVENTS_ARE_INDEXED 2648 if ( SLAP_EVENT_IS_READ( wake_sds[tid][0] ) ) { 2649 char c[BUFSIZ]; 2650 SLAP_EVENT_CLR_READ( wake_sds[tid][0] ); 2651 waking = 0; 2652 tcp_read( SLAP_FD2SOCK(wake_sds[tid][0]), c, sizeof(c) ); 2653 Debug( LDAP_DEBUG_CONNS, "daemon: waked\n", 0, 0, 0 ); 2654 continue; 2655 } 2656 2657 /* The event slot equals the descriptor number - this is 2658 * true for Unix select and poll. We treat Windows select 2659 * like this too, even though it's a kludge. 2660 */ 2661 if ( listening ) 2662 for ( l = 0; slap_listeners[l] != NULL; l++ ) { 2663 int rc; 2664 2665 if ( ns <= 0 ) break; 2666 if ( slap_listeners[l]->sl_sd == AC_SOCKET_INVALID ) continue; 2667 #ifdef LDAP_CONNECTIONLESS 2668 if ( slap_listeners[l]->sl_is_udp ) continue; 2669 #endif /* LDAP_CONNECTIONLESS */ 2670 if ( !SLAP_EVENT_IS_READ( slap_listeners[l]->sl_sd ) ) continue; 2671 2672 /* clear events */ 2673 SLAP_EVENT_CLR_READ( slap_listeners[l]->sl_sd ); 2674 SLAP_EVENT_CLR_WRITE( slap_listeners[l]->sl_sd ); 2675 ns--; 2676 2677 rc = slap_listener_activate( slap_listeners[l] ); 2678 } 2679 2680 /* bypass the following tests if no descriptors left */ 2681 if ( ns <= 0 ) { 2682 #ifndef HAVE_YIELDING_SELECT 2683 ldap_pvt_thread_yield(); 2684 #endif /* HAVE_YIELDING_SELECT */ 2685 continue; 2686 } 2687 2688 Debug( LDAP_DEBUG_CONNS, "daemon: activity on:", 0, 0, 0 ); 2689 nrfds = 0; 2690 nwfds = 0; 2691 for ( i = 0; i < nfds; i++ ) { 2692 int r, w; 2693 2694 r = SLAP_EVENT_IS_READ( i ); 2695 /* writefds was not initialized if nwriters was zero */ 2696 w = nwriters ? SLAP_EVENT_IS_WRITE( i ) : 0; 2697 if ( r || w ) { 2698 Debug( LDAP_DEBUG_CONNS, " %d%s%s", i, 2699 r ? "r" : "", w ? "w" : "" ); 2700 if ( r ) { 2701 nrfds++; 2702 ns--; 2703 } 2704 if ( w ) { 2705 nwfds++; 2706 ns--; 2707 } 2708 } 2709 if ( ns <= 0 ) break; 2710 } 2711 Debug( LDAP_DEBUG_CONNS, "\n", 0, 0, 0 ); 2712 2713 /* loop through the writers */ 2714 for ( i = 0; nwfds > 0; i++ ) { 2715 ber_socket_t wd; 2716 if ( ! SLAP_EVENT_IS_WRITE( i ) ) continue; 2717 wd = i; 2718 2719 SLAP_EVENT_CLR_WRITE( wd ); 2720 nwfds--; 2721 2722 Debug( LDAP_DEBUG_CONNS, 2723 "daemon: write active on %d\n", 2724 wd, 0, 0 ); 2725 2726 /* 2727 * NOTE: it is possible that the connection was closed 2728 * and that the stream is now inactive. 2729 * connection_write() must validate the stream is still 2730 * active. 2731 * 2732 * ITS#4338: if the stream is invalid, there is no need to 2733 * close it here. It has already been closed in connection.c. 2734 */ 2735 if ( connection_write( wd ) < 0 ) { 2736 if ( SLAP_EVENT_IS_READ( wd ) ) { 2737 SLAP_EVENT_CLR_READ( (unsigned) wd ); 2738 nrfds--; 2739 } 2740 } 2741 } 2742 2743 for ( i = 0; nrfds > 0; i++ ) { 2744 ber_socket_t rd; 2745 if ( ! SLAP_EVENT_IS_READ( i ) ) continue; 2746 rd = i; 2747 SLAP_EVENT_CLR_READ( rd ); 2748 nrfds--; 2749 2750 Debug ( LDAP_DEBUG_CONNS, 2751 "daemon: read activity on %d\n", rd, 0, 0 ); 2752 /* 2753 * NOTE: it is possible that the connection was closed 2754 * and that the stream is now inactive. 2755 * connection_read() must valid the stream is still 2756 * active. 2757 */ 2758 2759 connection_read_activate( rd ); 2760 } 2761 #else /* !SLAP_EVENTS_ARE_INDEXED */ 2762 /* FIXME */ 2763 /* The events are returned in an arbitrary list. This is true 2764 * for /dev/poll, epoll and kqueue. In order to prioritize things 2765 * so that we can handle wake_sds first, listeners second, and then 2766 * all other connections last (as we do for select), we would need 2767 * to use multiple event handles and cascade them. 2768 * 2769 * That seems like a bit of hassle. So the wake_sds check has been 2770 * skipped. For epoll and kqueue we can associate arbitrary data with 2771 * an event, so we could use pointers to the listener structure 2772 * instead of just the file descriptor. For /dev/poll we have to 2773 * search the listeners array for a matching descriptor. 2774 * 2775 * We now handle wake events when we see them; they are not given 2776 * higher priority. 2777 */ 2778 #ifdef LDAP_DEBUG 2779 Debug( LDAP_DEBUG_CONNS, "daemon: activity on:", 0, 0, 0 ); 2780 2781 for ( i = 0; i < ns; i++ ) { 2782 int r, w, fd; 2783 2784 /* Don't log listener events */ 2785 if ( SLAP_EVENT_IS_LISTENER( tid, i ) 2786 #ifdef LDAP_CONNECTIONLESS 2787 && !( (SLAP_EVENT_LISTENER( tid, i ))->sl_is_udp ) 2788 #endif /* LDAP_CONNECTIONLESS */ 2789 ) 2790 { 2791 continue; 2792 } 2793 2794 fd = SLAP_EVENT_FD( tid, i ); 2795 /* Don't log internal wake events */ 2796 if ( fd == wake_sds[tid][0] ) continue; 2797 2798 r = SLAP_EVENT_IS_READ( i ); 2799 w = SLAP_EVENT_IS_WRITE( i ); 2800 if ( r || w ) { 2801 Debug( LDAP_DEBUG_CONNS, " %d%s%s", fd, 2802 r ? "r" : "", w ? "w" : "" ); 2803 } 2804 } 2805 Debug( LDAP_DEBUG_CONNS, "\n", 0, 0, 0 ); 2806 #endif /* LDAP_DEBUG */ 2807 2808 for ( i = 0; i < ns; i++ ) { 2809 int rc = 1, fd, w = 0, r = 0; 2810 2811 if ( SLAP_EVENT_IS_LISTENER( tid, i ) ) { 2812 rc = slap_listener_activate( SLAP_EVENT_LISTENER( tid, i ) ); 2813 } 2814 2815 /* If we found a regular listener, rc is now zero, and we 2816 * can skip the data portion. But if it was a UDP listener 2817 * then rc is still 1, and we want to handle the data. 2818 */ 2819 if ( rc ) { 2820 fd = SLAP_EVENT_FD( tid, i ); 2821 2822 /* Handle wake events */ 2823 if ( fd == wake_sds[tid][0] ) { 2824 char c[BUFSIZ]; 2825 waking = 0; 2826 tcp_read( SLAP_FD2SOCK(wake_sds[tid][0]), c, sizeof(c) ); 2827 continue; 2828 } 2829 2830 if ( SLAP_EVENT_IS_WRITE( i ) ) { 2831 Debug( LDAP_DEBUG_CONNS, 2832 "daemon: write active on %d\n", 2833 fd, 0, 0 ); 2834 2835 SLAP_EVENT_CLR_WRITE( i ); 2836 w = 1; 2837 2838 /* 2839 * NOTE: it is possible that the connection was closed 2840 * and that the stream is now inactive. 2841 * connection_write() must valid the stream is still 2842 * active. 2843 */ 2844 if ( connection_write( fd ) < 0 ) { 2845 continue; 2846 } 2847 } 2848 /* If event is a read */ 2849 if ( SLAP_EVENT_IS_READ( i )) { 2850 r = 1; 2851 Debug( LDAP_DEBUG_CONNS, 2852 "daemon: read active on %d\n", 2853 fd, 0, 0 ); 2854 2855 SLAP_EVENT_CLR_READ( i ); 2856 connection_read_activate( fd ); 2857 } else if ( !w ) { 2858 #ifdef HAVE_EPOLL 2859 /* Don't keep reporting the hangup 2860 */ 2861 if ( SLAP_SOCK_IS_ACTIVE( tid, fd )) { 2862 SLAP_EPOLL_SOCK_SET( tid, fd, EPOLLET ); 2863 } 2864 #endif 2865 } 2866 } 2867 } 2868 #endif /* SLAP_EVENTS_ARE_INDEXED */ 2869 2870 #ifndef HAVE_YIELDING_SELECT 2871 ldap_pvt_thread_yield(); 2872 #endif /* ! HAVE_YIELDING_SELECT */ 2873 } 2874 2875 /* Only thread 0 handles shutdown */ 2876 if ( tid ) 2877 return NULL; 2878 2879 if ( slapd_shutdown == 1 ) { 2880 Debug( LDAP_DEBUG_ANY, 2881 "daemon: shutdown requested and initiated.\n", 2882 0, 0, 0 ); 2883 2884 } else if ( slapd_shutdown == 2 ) { 2885 #ifdef HAVE_NT_SERVICE_MANAGER 2886 Debug( LDAP_DEBUG_ANY, 2887 "daemon: shutdown initiated by Service Manager.\n", 2888 0, 0, 0); 2889 #else /* !HAVE_NT_SERVICE_MANAGER */ 2890 Debug( LDAP_DEBUG_ANY, 2891 "daemon: abnormal condition, shutdown initiated.\n", 2892 0, 0, 0 ); 2893 #endif /* !HAVE_NT_SERVICE_MANAGER */ 2894 } else { 2895 Debug( LDAP_DEBUG_ANY, 2896 "daemon: no active streams, shutdown initiated.\n", 2897 0, 0, 0 ); 2898 } 2899 2900 close_listeners( 0 ); 2901 2902 if ( !slapd_gentle_shutdown ) { 2903 slapd_abrupt_shutdown = 1; 2904 connections_shutdown(); 2905 } 2906 2907 if ( LogTest( LDAP_DEBUG_ANY )) { 2908 int t = ldap_pvt_thread_pool_backload( &connection_pool ); 2909 Debug( LDAP_DEBUG_ANY, 2910 "slapd shutdown: waiting for %d operations/tasks to finish\n", 2911 t, 0, 0 ); 2912 } 2913 ldap_pvt_thread_pool_destroy( &connection_pool, 1 ); 2914 2915 return NULL; 2916 } 2917 2918 2919 #ifdef LDAP_CONNECTIONLESS 2920 static int 2921 connectionless_init( void ) 2922 { 2923 int l; 2924 2925 for ( l = 0; slap_listeners[l] != NULL; l++ ) { 2926 Listener *lr = slap_listeners[l]; 2927 Connection *c; 2928 2929 if ( !lr->sl_is_udp ) { 2930 continue; 2931 } 2932 2933 c = connection_init( lr->sl_sd, lr, "", "", 2934 CONN_IS_UDP, (slap_ssf_t) 0, NULL 2935 LDAP_PF_LOCAL_SENDMSG_ARG(NULL)); 2936 2937 if ( !c ) { 2938 Debug( LDAP_DEBUG_TRACE, 2939 "connectionless_init: failed on %s (%d)\n", 2940 lr->sl_url.bv_val, lr->sl_sd, 0 ); 2941 return -1; 2942 } 2943 lr->sl_is_udp++; 2944 } 2945 2946 return 0; 2947 } 2948 #endif /* LDAP_CONNECTIONLESS */ 2949 2950 int 2951 slapd_daemon( void ) 2952 { 2953 int i, rc; 2954 2955 #ifdef LDAP_CONNECTIONLESS 2956 connectionless_init(); 2957 #endif /* LDAP_CONNECTIONLESS */ 2958 2959 if ( slapd_daemon_threads > SLAPD_MAX_DAEMON_THREADS ) 2960 slapd_daemon_threads = SLAPD_MAX_DAEMON_THREADS; 2961 2962 listener_tid = ch_malloc(slapd_daemon_threads * sizeof(ldap_pvt_thread_t)); 2963 2964 /* daemon_init only inits element 0 */ 2965 for ( i=1; i<slapd_daemon_threads; i++ ) 2966 { 2967 ldap_pvt_thread_mutex_init( &slap_daemon[i].sd_mutex ); 2968 2969 if( (rc = lutil_pair( wake_sds[i] )) < 0 ) { 2970 Debug( LDAP_DEBUG_ANY, 2971 "daemon: lutil_pair() failed rc=%d\n", rc, 0, 0 ); 2972 return rc; 2973 } 2974 ber_pvt_socket_set_nonblock( wake_sds[i][1], 1 ); 2975 2976 SLAP_SOCK_INIT(i); 2977 } 2978 2979 for ( i=0; i<slapd_daemon_threads; i++ ) 2980 { 2981 /* listener as a separate THREAD */ 2982 rc = ldap_pvt_thread_create( &listener_tid[i], 2983 0, slapd_daemon_task, &listener_tid[i] ); 2984 2985 if ( rc != 0 ) { 2986 Debug( LDAP_DEBUG_ANY, 2987 "listener ldap_pvt_thread_create failed (%d)\n", rc, 0, 0 ); 2988 return rc; 2989 } 2990 } 2991 2992 /* wait for the listener threads to complete */ 2993 for ( i=0; i<slapd_daemon_threads; i++ ) 2994 ldap_pvt_thread_join( listener_tid[i], (void *)NULL ); 2995 2996 destroy_listeners(); 2997 ch_free( listener_tid ); 2998 listener_tid = NULL; 2999 3000 return 0; 3001 } 3002 3003 static int 3004 sockinit( void ) 3005 { 3006 #if defined( HAVE_WINSOCK2 ) 3007 WORD wVersionRequested; 3008 WSADATA wsaData; 3009 int err; 3010 3011 wVersionRequested = MAKEWORD( 2, 0 ); 3012 3013 err = WSAStartup( wVersionRequested, &wsaData ); 3014 if ( err != 0 ) { 3015 /* Tell the user that we couldn't find a usable */ 3016 /* WinSock DLL. */ 3017 return -1; 3018 } 3019 3020 /* Confirm that the WinSock DLL supports 2.0.*/ 3021 /* Note that if the DLL supports versions greater */ 3022 /* than 2.0 in addition to 2.0, it will still return */ 3023 /* 2.0 in wVersion since that is the version we */ 3024 /* requested. */ 3025 3026 if ( LOBYTE( wsaData.wVersion ) != 2 || 3027 HIBYTE( wsaData.wVersion ) != 0 ) 3028 { 3029 /* Tell the user that we couldn't find a usable */ 3030 /* WinSock DLL. */ 3031 WSACleanup(); 3032 return -1; 3033 } 3034 3035 /* The WinSock DLL is acceptable. Proceed. */ 3036 #elif defined( HAVE_WINSOCK ) 3037 WSADATA wsaData; 3038 if ( WSAStartup( 0x0101, &wsaData ) != 0 ) return -1; 3039 #endif /* ! HAVE_WINSOCK2 && ! HAVE_WINSOCK */ 3040 3041 return 0; 3042 } 3043 3044 static int 3045 sockdestroy( void ) 3046 { 3047 #if defined( HAVE_WINSOCK2 ) || defined( HAVE_WINSOCK ) 3048 WSACleanup(); 3049 #endif /* HAVE_WINSOCK2 || HAVE_WINSOCK */ 3050 3051 return 0; 3052 } 3053 3054 RETSIGTYPE 3055 slap_sig_shutdown( int sig ) 3056 { 3057 int save_errno = errno; 3058 int i; 3059 3060 #if 0 3061 Debug(LDAP_DEBUG_TRACE, "slap_sig_shutdown: signal %d\n", sig, 0, 0); 3062 #endif 3063 3064 /* 3065 * If the NT Service Manager is controlling the server, we don't 3066 * want SIGBREAK to kill the server. For some strange reason, 3067 * SIGBREAK is generated when a user logs out. 3068 */ 3069 3070 #if defined(HAVE_NT_SERVICE_MANAGER) && defined(SIGBREAK) 3071 if (is_NT_Service && sig == SIGBREAK) { 3072 /* empty */; 3073 } else 3074 #endif /* HAVE_NT_SERVICE_MANAGER && SIGBREAK */ 3075 #ifdef SIGHUP 3076 if (sig == SIGHUP && global_gentlehup && slapd_gentle_shutdown == 0) { 3077 slapd_gentle_shutdown = 1; 3078 } else 3079 #endif /* SIGHUP */ 3080 { 3081 slapd_shutdown = 1; 3082 } 3083 3084 for (i=0; i<slapd_daemon_threads; i++) { 3085 WAKE_LISTENER(i,1); 3086 } 3087 3088 /* reinstall self */ 3089 (void) SIGNAL_REINSTALL( sig, slap_sig_shutdown ); 3090 3091 errno = save_errno; 3092 } 3093 3094 RETSIGTYPE 3095 slap_sig_wake( int sig ) 3096 { 3097 int save_errno = errno; 3098 3099 WAKE_LISTENER(0,1); 3100 3101 /* reinstall self */ 3102 (void) SIGNAL_REINSTALL( sig, slap_sig_wake ); 3103 3104 errno = save_errno; 3105 } 3106 3107 3108 void 3109 slapd_add_internal( ber_socket_t s, int isactive ) 3110 { 3111 if (!isactive) { 3112 SET_CLOSE(s); 3113 } 3114 slapd_add( s, isactive, NULL, -1 ); 3115 } 3116 3117 Listener ** 3118 slapd_get_listeners( void ) 3119 { 3120 /* Could return array with no listeners if !listening, but current 3121 * callers mostly look at the URLs. E.g. syncrepl uses this to 3122 * identify the server, which means it wants the startup arguments. 3123 */ 3124 return slap_listeners; 3125 } 3126 3127 /* Reject all incoming requests */ 3128 void 3129 slap_suspend_listeners( void ) 3130 { 3131 int i; 3132 for (i=0; slap_listeners[i]; i++) { 3133 slap_listeners[i]->sl_mute = 1; 3134 listen( slap_listeners[i]->sl_sd, 0 ); 3135 } 3136 } 3137 3138 /* Resume after a suspend */ 3139 void 3140 slap_resume_listeners( void ) 3141 { 3142 int i; 3143 for (i=0; slap_listeners[i]; i++) { 3144 slap_listeners[i]->sl_mute = 0; 3145 listen( slap_listeners[i]->sl_sd, SLAPD_LISTEN_BACKLOG ); 3146 } 3147 } 3148 3149 void 3150 slap_wake_listener() 3151 { 3152 WAKE_LISTENER(0,1); 3153 } 3154