1 /* $NetBSD: connection.c,v 1.1.1.6 2018/02/06 01:53:15 christos Exp $ */ 2 3 /* $OpenLDAP$ */ 4 /* This work is part of OpenLDAP Software <http://www.openldap.org/>. 5 * 6 * Copyright 1998-2017 The OpenLDAP Foundation. 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted only as authorized by the OpenLDAP 11 * Public License. 12 * 13 * A copy of this license is available in the file LICENSE in the 14 * top-level directory of the distribution or, alternatively, at 15 * <http://www.OpenLDAP.org/license.html>. 16 */ 17 /* Portions Copyright (c) 1995 Regents of the University of Michigan. 18 * All rights reserved. 19 * 20 * Redistribution and use in source and binary forms are permitted 21 * provided that this notice is preserved and that due credit is given 22 * to the University of Michigan at Ann Arbor. The name of the University 23 * may not be used to endorse or promote products derived from this 24 * software without specific prior written permission. This software 25 * is provided ``as is'' without express or implied warranty. 26 */ 27 28 #include <sys/cdefs.h> 29 __RCSID("$NetBSD: connection.c,v 1.1.1.6 2018/02/06 01:53:15 christos Exp $"); 30 31 #include "portable.h" 32 33 #include <stdio.h> 34 #ifdef HAVE_LIMITS_H 35 #include <limits.h> 36 #endif 37 38 #include <ac/socket.h> 39 #include <ac/errno.h> 40 #include <ac/string.h> 41 #include <ac/time.h> 42 #include <ac/unistd.h> 43 44 #include "lutil.h" 45 #include "slap.h" 46 47 #ifdef LDAP_CONNECTIONLESS 48 #include "../../libraries/liblber/lber-int.h" /* ber_int_sb_read() */ 49 #endif 50 51 #ifdef LDAP_SLAPI 52 #include "slapi/slapi.h" 53 #endif 54 55 /* protected by connections_mutex */ 56 static ldap_pvt_thread_mutex_t connections_mutex; 57 static Connection *connections = NULL; 58 59 static ldap_pvt_thread_mutex_t conn_nextid_mutex; 60 static unsigned long conn_nextid = SLAPD_SYNC_SYNCCONN_OFFSET; 61 62 static const char conn_lost_str[] = "connection lost"; 63 64 const char * 65 connection_state2str( int state ) 66 { 67 switch( state ) { 68 case SLAP_C_INVALID: return "!"; 69 case SLAP_C_INACTIVE: return "|"; 70 case SLAP_C_CLOSING: return "C"; 71 case SLAP_C_ACTIVE: return ""; 72 case SLAP_C_BINDING: return "B"; 73 case SLAP_C_CLIENT: return "L"; 74 } 75 76 return "?"; 77 } 78 79 static Connection* connection_get( ber_socket_t s ); 80 81 typedef struct conn_readinfo { 82 Operation *op; 83 ldap_pvt_thread_start_t *func; 84 void *arg; 85 void *ctx; 86 int nullop; 87 } conn_readinfo; 88 89 static int connection_input( Connection *c, conn_readinfo *cri ); 90 static void connection_close( Connection *c ); 91 92 static int connection_op_activate( Operation *op ); 93 static void connection_op_queue( Operation *op ); 94 static int connection_resched( Connection *conn ); 95 static void connection_abandon( Connection *conn ); 96 static void connection_destroy( Connection *c ); 97 98 static ldap_pvt_thread_start_t connection_operation; 99 100 /* 101 * Initialize connection management infrastructure. 102 */ 103 int connections_init(void) 104 { 105 int i; 106 107 assert( connections == NULL ); 108 109 if( connections != NULL) { 110 Debug( LDAP_DEBUG_ANY, "connections_init: already initialized.\n", 111 0, 0, 0 ); 112 return -1; 113 } 114 115 /* should check return of every call */ 116 ldap_pvt_thread_mutex_init( &connections_mutex ); 117 ldap_pvt_thread_mutex_init( &conn_nextid_mutex ); 118 119 connections = (Connection *) ch_calloc( dtblsize, sizeof(Connection) ); 120 121 if( connections == NULL ) { 122 Debug( LDAP_DEBUG_ANY, "connections_init: " 123 "allocation (%d*%ld) of connection array failed\n", 124 dtblsize, (long) sizeof(Connection), 0 ); 125 return -1; 126 } 127 128 assert( connections[0].c_struct_state == SLAP_C_UNINITIALIZED ); 129 assert( connections[dtblsize-1].c_struct_state == SLAP_C_UNINITIALIZED ); 130 131 for (i=0; i<dtblsize; i++) connections[i].c_conn_idx = i; 132 133 /* 134 * per entry initialization of the Connection array initialization 135 * will be done by connection_init() 136 */ 137 138 return 0; 139 } 140 141 /* 142 * Destroy connection management infrastructure. 143 */ 144 145 int connections_destroy(void) 146 { 147 ber_socket_t i; 148 149 /* should check return of every call */ 150 151 if( connections == NULL) { 152 Debug( LDAP_DEBUG_ANY, "connections_destroy: nothing to destroy.\n", 153 0, 0, 0 ); 154 return -1; 155 } 156 157 for ( i = 0; i < dtblsize; i++ ) { 158 if( connections[i].c_struct_state != SLAP_C_UNINITIALIZED ) { 159 ber_sockbuf_free( connections[i].c_sb ); 160 ldap_pvt_thread_mutex_destroy( &connections[i].c_mutex ); 161 ldap_pvt_thread_mutex_destroy( &connections[i].c_write1_mutex ); 162 ldap_pvt_thread_mutex_destroy( &connections[i].c_write2_mutex ); 163 ldap_pvt_thread_cond_destroy( &connections[i].c_write1_cv ); 164 ldap_pvt_thread_cond_destroy( &connections[i].c_write2_cv ); 165 #ifdef LDAP_SLAPI 166 if ( slapi_plugins_used ) { 167 slapi_int_free_object_extensions( SLAPI_X_EXT_CONNECTION, 168 &connections[i] ); 169 } 170 #endif 171 } 172 } 173 174 free( connections ); 175 connections = NULL; 176 177 ldap_pvt_thread_mutex_destroy( &connections_mutex ); 178 ldap_pvt_thread_mutex_destroy( &conn_nextid_mutex ); 179 return 0; 180 } 181 182 /* 183 * shutdown all connections 184 */ 185 int connections_shutdown(void) 186 { 187 ber_socket_t i; 188 189 for ( i = 0; i < dtblsize; i++ ) { 190 if( connections[i].c_struct_state != SLAP_C_UNINITIALIZED ) { 191 ldap_pvt_thread_mutex_lock( &connections[i].c_mutex ); 192 if( connections[i].c_struct_state == SLAP_C_USED ) { 193 194 /* give persistent clients a chance to cleanup */ 195 if( connections[i].c_conn_state == SLAP_C_CLIENT ) { 196 ldap_pvt_thread_pool_submit( &connection_pool, 197 connections[i].c_clientfunc, connections[i].c_clientarg ); 198 } else { 199 /* c_mutex is locked */ 200 connection_closing( &connections[i], "slapd shutdown" ); 201 connection_close( &connections[i] ); 202 } 203 } 204 ldap_pvt_thread_mutex_unlock( &connections[i].c_mutex ); 205 } 206 } 207 208 return 0; 209 } 210 211 /* 212 * Timeout idle connections. 213 */ 214 int connections_timeout_idle(time_t now) 215 { 216 int i = 0, writers = 0; 217 ber_socket_t connindex; 218 Connection* c; 219 time_t old; 220 221 old = slapd_get_writetime(); 222 223 for( c = connection_first( &connindex ); 224 c != NULL; 225 c = connection_next( c, &connindex ) ) 226 { 227 /* Don't timeout a slow-running request or a persistent 228 * outbound connection. But if it has a writewaiter, see 229 * if the waiter has been there too long. 230 */ 231 if(( c->c_n_ops_executing && !c->c_writewaiter) 232 || c->c_conn_state == SLAP_C_CLIENT ) { 233 continue; 234 } 235 236 if( global_idletimeout && 237 difftime( c->c_activitytime+global_idletimeout, now) < 0 ) { 238 /* close it */ 239 connection_closing( c, "idletimeout" ); 240 connection_close( c ); 241 i++; 242 continue; 243 } 244 if ( c->c_writewaiter && global_writetimeout ) { 245 writers = 1; 246 if( difftime( c->c_activitytime+global_writetimeout, now) < 0 ) { 247 /* close it */ 248 connection_closing( c, "writetimeout" ); 249 connection_close( c ); 250 i++; 251 continue; 252 } 253 } 254 } 255 connection_done( c ); 256 if ( old && !writers ) 257 slapd_clr_writetime( old ); 258 259 return i; 260 } 261 262 /* Drop all client connections */ 263 void connections_drop() 264 { 265 Connection* c; 266 ber_socket_t connindex; 267 268 for( c = connection_first( &connindex ); 269 c != NULL; 270 c = connection_next( c, &connindex ) ) 271 { 272 /* Don't close a slow-running request or a persistent 273 * outbound connection. 274 */ 275 if(( c->c_n_ops_executing && !c->c_writewaiter) 276 || c->c_conn_state == SLAP_C_CLIENT ) { 277 continue; 278 } 279 connection_closing( c, "dropping" ); 280 connection_close( c ); 281 } 282 connection_done( c ); 283 } 284 285 static Connection* connection_get( ber_socket_t s ) 286 { 287 Connection *c; 288 289 Debug( LDAP_DEBUG_ARGS, 290 "connection_get(%ld)\n", 291 (long) s, 0, 0 ); 292 293 assert( connections != NULL ); 294 295 if(s == AC_SOCKET_INVALID) return NULL; 296 297 assert( s < dtblsize ); 298 c = &connections[s]; 299 300 if( c != NULL ) { 301 ldap_pvt_thread_mutex_lock( &c->c_mutex ); 302 303 assert( c->c_struct_state != SLAP_C_UNINITIALIZED ); 304 305 if( c->c_struct_state != SLAP_C_USED ) { 306 /* connection must have been closed due to resched */ 307 308 Debug( LDAP_DEBUG_CONNS, 309 "connection_get(%d): connection not used\n", 310 s, 0, 0 ); 311 assert( c->c_conn_state == SLAP_C_INVALID ); 312 assert( c->c_sd == AC_SOCKET_INVALID ); 313 314 ldap_pvt_thread_mutex_unlock( &c->c_mutex ); 315 return NULL; 316 } 317 318 Debug( LDAP_DEBUG_TRACE, 319 "connection_get(%d): got connid=%lu\n", 320 s, c->c_connid, 0 ); 321 322 c->c_n_get++; 323 324 assert( c->c_struct_state == SLAP_C_USED ); 325 assert( c->c_conn_state != SLAP_C_INVALID ); 326 assert( c->c_sd != AC_SOCKET_INVALID ); 327 328 #ifndef SLAPD_MONITOR 329 if ( global_idletimeout > 0 ) 330 #endif /* ! SLAPD_MONITOR */ 331 { 332 c->c_activitytime = slap_get_time(); 333 } 334 } 335 336 return c; 337 } 338 339 static void connection_return( Connection *c ) 340 { 341 ldap_pvt_thread_mutex_unlock( &c->c_mutex ); 342 } 343 344 Connection * connection_init( 345 ber_socket_t s, 346 Listener *listener, 347 const char* dnsname, 348 const char* peername, 349 int flags, 350 slap_ssf_t ssf, 351 struct berval *authid 352 LDAP_PF_LOCAL_SENDMSG_ARG(struct berval *peerbv)) 353 { 354 unsigned long id; 355 Connection *c; 356 int doinit = 0; 357 ber_socket_t sfd = SLAP_FD2SOCK(s); 358 359 assert( connections != NULL ); 360 361 assert( listener != NULL ); 362 assert( dnsname != NULL ); 363 assert( peername != NULL ); 364 365 #ifndef HAVE_TLS 366 assert( !( flags & CONN_IS_TLS )); 367 #endif 368 369 if( s == AC_SOCKET_INVALID ) { 370 Debug( LDAP_DEBUG_ANY, 371 "connection_init: init of socket %ld invalid.\n", (long)s, 0, 0 ); 372 return NULL; 373 } 374 375 assert( s >= 0 ); 376 assert( s < dtblsize ); 377 c = &connections[s]; 378 if( c->c_struct_state == SLAP_C_UNINITIALIZED ) { 379 doinit = 1; 380 } else { 381 assert( c->c_struct_state == SLAP_C_UNUSED ); 382 } 383 384 if( doinit ) { 385 c->c_send_ldap_result = slap_send_ldap_result; 386 c->c_send_search_entry = slap_send_search_entry; 387 c->c_send_search_reference = slap_send_search_reference; 388 c->c_send_ldap_extended = slap_send_ldap_extended; 389 c->c_send_ldap_intermediate = slap_send_ldap_intermediate; 390 391 BER_BVZERO( &c->c_authmech ); 392 BER_BVZERO( &c->c_dn ); 393 BER_BVZERO( &c->c_ndn ); 394 395 c->c_listener = NULL; 396 BER_BVZERO( &c->c_peer_domain ); 397 BER_BVZERO( &c->c_peer_name ); 398 399 LDAP_STAILQ_INIT(&c->c_ops); 400 LDAP_STAILQ_INIT(&c->c_pending_ops); 401 402 #ifdef LDAP_X_TXN 403 c->c_txn = CONN_TXN_INACTIVE; 404 c->c_txn_backend = NULL; 405 LDAP_STAILQ_INIT(&c->c_txn_ops); 406 #endif 407 408 BER_BVZERO( &c->c_sasl_bind_mech ); 409 c->c_sasl_done = 0; 410 c->c_sasl_authctx = NULL; 411 c->c_sasl_sockctx = NULL; 412 c->c_sasl_extra = NULL; 413 c->c_sasl_bindop = NULL; 414 415 c->c_sb = ber_sockbuf_alloc( ); 416 417 { 418 ber_len_t max = sockbuf_max_incoming; 419 ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_SET_MAX_INCOMING, &max ); 420 } 421 422 c->c_currentber = NULL; 423 424 /* should check status of thread calls */ 425 ldap_pvt_thread_mutex_init( &c->c_mutex ); 426 ldap_pvt_thread_mutex_init( &c->c_write1_mutex ); 427 ldap_pvt_thread_mutex_init( &c->c_write2_mutex ); 428 ldap_pvt_thread_cond_init( &c->c_write1_cv ); 429 ldap_pvt_thread_cond_init( &c->c_write2_cv ); 430 431 #ifdef LDAP_SLAPI 432 if ( slapi_plugins_used ) { 433 slapi_int_create_object_extensions( SLAPI_X_EXT_CONNECTION, c ); 434 } 435 #endif 436 } 437 438 ldap_pvt_thread_mutex_lock( &c->c_mutex ); 439 440 assert( BER_BVISNULL( &c->c_authmech ) ); 441 assert( BER_BVISNULL( &c->c_dn ) ); 442 assert( BER_BVISNULL( &c->c_ndn ) ); 443 assert( c->c_listener == NULL ); 444 assert( BER_BVISNULL( &c->c_peer_domain ) ); 445 assert( BER_BVISNULL( &c->c_peer_name ) ); 446 assert( LDAP_STAILQ_EMPTY(&c->c_ops) ); 447 assert( LDAP_STAILQ_EMPTY(&c->c_pending_ops) ); 448 #ifdef LDAP_X_TXN 449 assert( c->c_txn == CONN_TXN_INACTIVE ); 450 assert( c->c_txn_backend == NULL ); 451 assert( LDAP_STAILQ_EMPTY(&c->c_txn_ops) ); 452 #endif 453 assert( BER_BVISNULL( &c->c_sasl_bind_mech ) ); 454 assert( c->c_sasl_done == 0 ); 455 assert( c->c_sasl_authctx == NULL ); 456 assert( c->c_sasl_sockctx == NULL ); 457 assert( c->c_sasl_extra == NULL ); 458 assert( c->c_sasl_bindop == NULL ); 459 assert( c->c_currentber == NULL ); 460 assert( c->c_writewaiter == 0); 461 assert( c->c_writers == 0); 462 463 c->c_listener = listener; 464 c->c_sd = s; 465 466 if ( flags & CONN_IS_CLIENT ) { 467 c->c_connid = 0; 468 ldap_pvt_thread_mutex_lock( &connections_mutex ); 469 c->c_conn_state = SLAP_C_CLIENT; 470 c->c_struct_state = SLAP_C_USED; 471 ldap_pvt_thread_mutex_unlock( &connections_mutex ); 472 c->c_close_reason = "?"; /* should never be needed */ 473 ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_SET_FD, &sfd ); 474 ldap_pvt_thread_mutex_unlock( &c->c_mutex ); 475 476 return c; 477 } 478 479 ber_str2bv( dnsname, 0, 1, &c->c_peer_domain ); 480 ber_str2bv( peername, 0, 1, &c->c_peer_name ); 481 482 c->c_n_ops_received = 0; 483 c->c_n_ops_executing = 0; 484 c->c_n_ops_pending = 0; 485 c->c_n_ops_completed = 0; 486 487 c->c_n_get = 0; 488 c->c_n_read = 0; 489 c->c_n_write = 0; 490 491 /* set to zero until bind, implies LDAP_VERSION3 */ 492 c->c_protocol = 0; 493 494 #ifndef SLAPD_MONITOR 495 if ( global_idletimeout > 0 ) 496 #endif /* ! SLAPD_MONITOR */ 497 { 498 c->c_activitytime = c->c_starttime = slap_get_time(); 499 } 500 501 #ifdef LDAP_CONNECTIONLESS 502 c->c_is_udp = 0; 503 if( flags & CONN_IS_UDP ) { 504 c->c_is_udp = 1; 505 #ifdef LDAP_DEBUG 506 ber_sockbuf_add_io( c->c_sb, &ber_sockbuf_io_debug, 507 LBER_SBIOD_LEVEL_PROVIDER, (void*)"udp_" ); 508 #endif 509 ber_sockbuf_add_io( c->c_sb, &ber_sockbuf_io_udp, 510 LBER_SBIOD_LEVEL_PROVIDER, (void *)&sfd ); 511 ber_sockbuf_add_io( c->c_sb, &ber_sockbuf_io_readahead, 512 LBER_SBIOD_LEVEL_PROVIDER, NULL ); 513 } else 514 #endif /* LDAP_CONNECTIONLESS */ 515 #ifdef LDAP_PF_LOCAL 516 if ( flags & CONN_IS_IPC ) { 517 #ifdef LDAP_DEBUG 518 ber_sockbuf_add_io( c->c_sb, &ber_sockbuf_io_debug, 519 LBER_SBIOD_LEVEL_PROVIDER, (void*)"ipc_" ); 520 #endif 521 ber_sockbuf_add_io( c->c_sb, &ber_sockbuf_io_fd, 522 LBER_SBIOD_LEVEL_PROVIDER, (void *)&sfd ); 523 #ifdef LDAP_PF_LOCAL_SENDMSG 524 if ( !BER_BVISEMPTY( peerbv )) 525 ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_UNGET_BUF, peerbv ); 526 #endif 527 } else 528 #endif /* LDAP_PF_LOCAL */ 529 { 530 #ifdef LDAP_DEBUG 531 ber_sockbuf_add_io( c->c_sb, &ber_sockbuf_io_debug, 532 LBER_SBIOD_LEVEL_PROVIDER, (void*)"tcp_" ); 533 #endif 534 ber_sockbuf_add_io( c->c_sb, &ber_sockbuf_io_tcp, 535 LBER_SBIOD_LEVEL_PROVIDER, (void *)&sfd ); 536 } 537 538 #ifdef LDAP_DEBUG 539 ber_sockbuf_add_io( c->c_sb, &ber_sockbuf_io_debug, 540 INT_MAX, (void*)"ldap_" ); 541 #endif 542 543 if( ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_SET_NONBLOCK, 544 c /* non-NULL */ ) < 0 ) 545 { 546 Debug( LDAP_DEBUG_ANY, 547 "connection_init(%d, %s): set nonblocking failed\n", 548 s, c->c_peer_name.bv_val, 0 ); 549 } 550 551 ldap_pvt_thread_mutex_lock( &conn_nextid_mutex ); 552 id = c->c_connid = conn_nextid++; 553 ldap_pvt_thread_mutex_unlock( &conn_nextid_mutex ); 554 555 ldap_pvt_thread_mutex_lock( &connections_mutex ); 556 c->c_conn_state = SLAP_C_INACTIVE; 557 c->c_struct_state = SLAP_C_USED; 558 ldap_pvt_thread_mutex_unlock( &connections_mutex ); 559 c->c_close_reason = "?"; /* should never be needed */ 560 561 c->c_ssf = c->c_transport_ssf = ssf; 562 c->c_tls_ssf = 0; 563 564 #ifdef HAVE_TLS 565 if ( flags & CONN_IS_TLS ) { 566 c->c_is_tls = 1; 567 c->c_needs_tls_accept = 1; 568 } else { 569 c->c_is_tls = 0; 570 c->c_needs_tls_accept = 0; 571 } 572 #endif 573 574 slap_sasl_open( c, 0 ); 575 slap_sasl_external( c, ssf, authid ); 576 577 slapd_add_internal( s, 1 ); 578 579 backend_connection_init(c); 580 ldap_pvt_thread_mutex_unlock( &c->c_mutex ); 581 582 if ( !(flags & CONN_IS_UDP )) 583 Statslog( LDAP_DEBUG_STATS, 584 "conn=%ld fd=%ld ACCEPT from %s (%s)\n", 585 id, (long) s, peername, listener->sl_name.bv_val, 0 ); 586 587 return c; 588 } 589 590 void connection2anonymous( Connection *c ) 591 { 592 assert( connections != NULL ); 593 assert( c != NULL ); 594 595 { 596 ber_len_t max = sockbuf_max_incoming; 597 ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_SET_MAX_INCOMING, &max ); 598 } 599 600 if ( !BER_BVISNULL( &c->c_authmech ) ) { 601 ch_free(c->c_authmech.bv_val); 602 } 603 BER_BVZERO( &c->c_authmech ); 604 605 if ( !BER_BVISNULL( &c->c_dn ) ) { 606 ch_free(c->c_dn.bv_val); 607 } 608 BER_BVZERO( &c->c_dn ); 609 610 if ( !BER_BVISNULL( &c->c_ndn ) ) { 611 ch_free(c->c_ndn.bv_val); 612 } 613 BER_BVZERO( &c->c_ndn ); 614 615 if ( !BER_BVISNULL( &c->c_sasl_authz_dn ) ) { 616 ber_memfree_x( c->c_sasl_authz_dn.bv_val, NULL ); 617 } 618 BER_BVZERO( &c->c_sasl_authz_dn ); 619 620 c->c_authz_backend = NULL; 621 } 622 623 static void 624 connection_destroy( Connection *c ) 625 { 626 unsigned long connid; 627 const char *close_reason; 628 Sockbuf *sb; 629 ber_socket_t sd; 630 631 assert( connections != NULL ); 632 assert( c != NULL ); 633 assert( c->c_struct_state != SLAP_C_UNUSED ); 634 assert( c->c_conn_state != SLAP_C_INVALID ); 635 assert( LDAP_STAILQ_EMPTY(&c->c_ops) ); 636 assert( LDAP_STAILQ_EMPTY(&c->c_pending_ops) ); 637 #ifdef LDAP_X_TXN 638 assert( c->c_txn == CONN_TXN_INACTIVE ); 639 assert( c->c_txn_backend == NULL ); 640 assert( LDAP_STAILQ_EMPTY(&c->c_txn_ops) ); 641 #endif 642 assert( c->c_writewaiter == 0); 643 assert( c->c_writers == 0); 644 645 /* only for stats (print -1 as "%lu" may give unexpected results ;) */ 646 connid = c->c_connid; 647 close_reason = c->c_close_reason; 648 649 ldap_pvt_thread_mutex_lock( &connections_mutex ); 650 c->c_struct_state = SLAP_C_PENDING; 651 ldap_pvt_thread_mutex_unlock( &connections_mutex ); 652 653 backend_connection_destroy(c); 654 655 c->c_protocol = 0; 656 c->c_connid = -1; 657 658 c->c_activitytime = c->c_starttime = 0; 659 660 connection2anonymous( c ); 661 c->c_listener = NULL; 662 663 if(c->c_peer_domain.bv_val != NULL) { 664 free(c->c_peer_domain.bv_val); 665 } 666 BER_BVZERO( &c->c_peer_domain ); 667 if(c->c_peer_name.bv_val != NULL) { 668 free(c->c_peer_name.bv_val); 669 } 670 BER_BVZERO( &c->c_peer_name ); 671 672 c->c_sasl_bind_in_progress = 0; 673 if(c->c_sasl_bind_mech.bv_val != NULL) { 674 free(c->c_sasl_bind_mech.bv_val); 675 } 676 BER_BVZERO( &c->c_sasl_bind_mech ); 677 678 slap_sasl_close( c ); 679 680 if ( c->c_currentber != NULL ) { 681 ber_free( c->c_currentber, 1 ); 682 c->c_currentber = NULL; 683 } 684 685 686 #ifdef LDAP_SLAPI 687 /* call destructors, then constructors; avoids unnecessary allocation */ 688 if ( slapi_plugins_used ) { 689 slapi_int_clear_object_extensions( SLAPI_X_EXT_CONNECTION, c ); 690 } 691 #endif 692 693 sd = c->c_sd; 694 c->c_sd = AC_SOCKET_INVALID; 695 c->c_conn_state = SLAP_C_INVALID; 696 c->c_struct_state = SLAP_C_UNUSED; 697 c->c_close_reason = "?"; /* should never be needed */ 698 699 sb = c->c_sb; 700 c->c_sb = ber_sockbuf_alloc( ); 701 { 702 ber_len_t max = sockbuf_max_incoming; 703 ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_SET_MAX_INCOMING, &max ); 704 } 705 706 /* c must be fully reset by this point; when we call slapd_remove 707 * it may get immediately reused by a new connection. 708 */ 709 if ( sd != AC_SOCKET_INVALID ) { 710 slapd_remove( sd, sb, 1, 0, 0 ); 711 712 if ( close_reason == NULL ) { 713 Statslog( LDAP_DEBUG_STATS, "conn=%lu fd=%ld closed\n", 714 connid, (long) sd, 0, 0, 0 ); 715 } else { 716 Statslog( LDAP_DEBUG_STATS, "conn=%lu fd=%ld closed (%s)\n", 717 connid, (long) sd, close_reason, 0, 0 ); 718 } 719 } 720 } 721 722 int connection_valid( Connection *c ) 723 { 724 /* c_mutex must be locked by caller */ 725 726 assert( c != NULL ); 727 728 return c->c_struct_state == SLAP_C_USED && 729 c->c_conn_state >= SLAP_C_ACTIVE && 730 c->c_conn_state <= SLAP_C_CLIENT; 731 } 732 733 static void connection_abandon( Connection *c ) 734 { 735 /* c_mutex must be locked by caller */ 736 737 Operation *o, *next, op = {0}; 738 Opheader ohdr = {0}; 739 740 op.o_hdr = &ohdr; 741 op.o_conn = c; 742 op.o_connid = c->c_connid; 743 op.o_tag = LDAP_REQ_ABANDON; 744 745 for ( o = LDAP_STAILQ_FIRST( &c->c_ops ); o; o=next ) { 746 SlapReply rs = {REP_RESULT}; 747 748 next = LDAP_STAILQ_NEXT( o, o_next ); 749 /* don't abandon an op twice */ 750 if ( o->o_abandon ) 751 continue; 752 op.orn_msgid = o->o_msgid; 753 o->o_abandon = 1; 754 op.o_bd = frontendDB; 755 frontendDB->be_abandon( &op, &rs ); 756 } 757 758 #ifdef LDAP_X_TXN 759 /* remove operations in pending transaction */ 760 while ( (o = LDAP_STAILQ_FIRST( &c->c_txn_ops )) != NULL) { 761 LDAP_STAILQ_REMOVE_HEAD( &c->c_txn_ops, o_next ); 762 LDAP_STAILQ_NEXT(o, o_next) = NULL; 763 slap_op_free( o, NULL ); 764 } 765 766 /* clear transaction */ 767 c->c_txn_backend = NULL; 768 c->c_txn = CONN_TXN_INACTIVE; 769 #endif 770 771 /* remove pending operations */ 772 while ( (o = LDAP_STAILQ_FIRST( &c->c_pending_ops )) != NULL) { 773 LDAP_STAILQ_REMOVE_HEAD( &c->c_pending_ops, o_next ); 774 LDAP_STAILQ_NEXT(o, o_next) = NULL; 775 slap_op_free( o, NULL ); 776 } 777 } 778 779 static void 780 connection_wake_writers( Connection *c ) 781 { 782 /* wake write blocked operations */ 783 ldap_pvt_thread_mutex_lock( &c->c_write1_mutex ); 784 if ( c->c_writers > 0 ) { 785 c->c_writers = -c->c_writers; 786 ldap_pvt_thread_cond_broadcast( &c->c_write1_cv ); 787 ldap_pvt_thread_mutex_unlock( &c->c_write1_mutex ); 788 if ( c->c_writewaiter ) { 789 ldap_pvt_thread_mutex_lock( &c->c_write2_mutex ); 790 ldap_pvt_thread_cond_signal( &c->c_write2_cv ); 791 slapd_clr_write( c->c_sd, 1 ); 792 ldap_pvt_thread_mutex_unlock( &c->c_write2_mutex ); 793 } 794 ldap_pvt_thread_mutex_lock( &c->c_write1_mutex ); 795 while ( c->c_writers ) { 796 ldap_pvt_thread_cond_wait( &c->c_write1_cv, &c->c_write1_mutex ); 797 } 798 ldap_pvt_thread_mutex_unlock( &c->c_write1_mutex ); 799 } else { 800 ldap_pvt_thread_mutex_unlock( &c->c_write1_mutex ); 801 slapd_clr_write( c->c_sd, 1 ); 802 } 803 } 804 805 void connection_closing( Connection *c, const char *why ) 806 { 807 assert( connections != NULL ); 808 assert( c != NULL ); 809 810 if ( c->c_struct_state != SLAP_C_USED ) return; 811 812 assert( c->c_conn_state != SLAP_C_INVALID ); 813 814 /* c_mutex must be locked by caller */ 815 816 if( c->c_conn_state != SLAP_C_CLOSING ) { 817 Debug( LDAP_DEBUG_CONNS, 818 "connection_closing: readying conn=%lu sd=%d for close\n", 819 c->c_connid, c->c_sd, 0 ); 820 /* update state to closing */ 821 c->c_conn_state = SLAP_C_CLOSING; 822 c->c_close_reason = why; 823 824 /* don't listen on this port anymore */ 825 slapd_clr_read( c->c_sd, 0 ); 826 827 /* abandon active operations */ 828 connection_abandon( c ); 829 830 /* wake write blocked operations */ 831 connection_wake_writers( c ); 832 833 } else if( why == NULL && c->c_close_reason == conn_lost_str ) { 834 /* Client closed connection after doing Unbind. */ 835 c->c_close_reason = NULL; 836 } 837 } 838 839 static void 840 connection_close( Connection *c ) 841 { 842 assert( connections != NULL ); 843 assert( c != NULL ); 844 845 if ( c->c_struct_state != SLAP_C_USED ) return; 846 847 assert( c->c_conn_state == SLAP_C_CLOSING ); 848 849 /* NOTE: c_mutex should be locked by caller */ 850 851 if ( !LDAP_STAILQ_EMPTY(&c->c_ops) || 852 !LDAP_STAILQ_EMPTY(&c->c_pending_ops) ) 853 { 854 Debug( LDAP_DEBUG_CONNS, 855 "connection_close: deferring conn=%lu sd=%d\n", 856 c->c_connid, c->c_sd, 0 ); 857 return; 858 } 859 860 Debug( LDAP_DEBUG_TRACE, "connection_close: conn=%lu sd=%d\n", 861 c->c_connid, c->c_sd, 0 ); 862 863 connection_destroy( c ); 864 } 865 866 unsigned long connections_nextid(void) 867 { 868 unsigned long id; 869 assert( connections != NULL ); 870 871 ldap_pvt_thread_mutex_lock( &conn_nextid_mutex ); 872 873 id = conn_nextid; 874 875 ldap_pvt_thread_mutex_unlock( &conn_nextid_mutex ); 876 877 return id; 878 } 879 880 /* 881 * Loop through the connections: 882 * 883 * for (c = connection_first(&i); c; c = connection_next(c, &i)) ...; 884 * connection_done(c); 885 * 886 * 'i' is the cursor, initialized by connection_first(). 887 * 'c_mutex' is locked in the returned connection. The functions must 888 * be passed the previous return value so they can unlock it again. 889 */ 890 891 Connection* connection_first( ber_socket_t *index ) 892 { 893 assert( connections != NULL ); 894 assert( index != NULL ); 895 896 ldap_pvt_thread_mutex_lock( &connections_mutex ); 897 for( *index = 0; *index < dtblsize; (*index)++) { 898 if( connections[*index].c_struct_state != SLAP_C_UNINITIALIZED ) { 899 break; 900 } 901 } 902 ldap_pvt_thread_mutex_unlock( &connections_mutex ); 903 904 return connection_next(NULL, index); 905 } 906 907 /* Next connection in loop, see connection_first() */ 908 Connection* connection_next( Connection *c, ber_socket_t *index ) 909 { 910 assert( connections != NULL ); 911 assert( index != NULL ); 912 assert( *index <= dtblsize ); 913 914 if( c != NULL ) ldap_pvt_thread_mutex_unlock( &c->c_mutex ); 915 916 c = NULL; 917 918 ldap_pvt_thread_mutex_lock( &connections_mutex ); 919 for(; *index < dtblsize; (*index)++) { 920 int c_struct; 921 if( connections[*index].c_struct_state == SLAP_C_UNINITIALIZED ) { 922 /* FIXME: accessing c_conn_state without locking c_mutex */ 923 assert( connections[*index].c_conn_state == SLAP_C_INVALID ); 924 continue; 925 } 926 927 if( connections[*index].c_struct_state == SLAP_C_USED ) { 928 c = &connections[(*index)++]; 929 if ( ldap_pvt_thread_mutex_trylock( &c->c_mutex )) { 930 /* avoid deadlock */ 931 ldap_pvt_thread_mutex_unlock( &connections_mutex ); 932 ldap_pvt_thread_mutex_lock( &c->c_mutex ); 933 ldap_pvt_thread_mutex_lock( &connections_mutex ); 934 if ( c->c_struct_state != SLAP_C_USED ) { 935 ldap_pvt_thread_mutex_unlock( &c->c_mutex ); 936 c = NULL; 937 continue; 938 } 939 } 940 assert( c->c_conn_state != SLAP_C_INVALID ); 941 break; 942 } 943 944 c_struct = connections[*index].c_struct_state; 945 if ( c_struct == SLAP_C_PENDING ) 946 continue; 947 assert( c_struct == SLAP_C_UNUSED ); 948 /* FIXME: accessing c_conn_state without locking c_mutex */ 949 assert( connections[*index].c_conn_state == SLAP_C_INVALID ); 950 } 951 952 ldap_pvt_thread_mutex_unlock( &connections_mutex ); 953 return c; 954 } 955 956 /* End connection loop, see connection_first() */ 957 void connection_done( Connection *c ) 958 { 959 assert( connections != NULL ); 960 961 if( c != NULL ) ldap_pvt_thread_mutex_unlock( &c->c_mutex ); 962 } 963 964 /* 965 * connection_activity - handle the request operation op on connection 966 * conn. This routine figures out what kind of operation it is and 967 * calls the appropriate stub to handle it. 968 */ 969 970 #ifdef SLAPD_MONITOR 971 /* FIXME: returns 0 in case of failure */ 972 #define INCR_OP_INITIATED(index) \ 973 do { \ 974 ldap_pvt_thread_mutex_lock( &op->o_counters->sc_mutex ); \ 975 ldap_pvt_mp_add_ulong(op->o_counters->sc_ops_initiated_[(index)], 1); \ 976 ldap_pvt_thread_mutex_unlock( &op->o_counters->sc_mutex ); \ 977 } while (0) 978 #define INCR_OP_COMPLETED(index) \ 979 do { \ 980 ldap_pvt_thread_mutex_lock( &op->o_counters->sc_mutex ); \ 981 ldap_pvt_mp_add_ulong(op->o_counters->sc_ops_completed, 1); \ 982 ldap_pvt_mp_add_ulong(op->o_counters->sc_ops_completed_[(index)], 1); \ 983 ldap_pvt_thread_mutex_unlock( &op->o_counters->sc_mutex ); \ 984 } while (0) 985 #else /* !SLAPD_MONITOR */ 986 #define INCR_OP_INITIATED(index) do { } while (0) 987 #define INCR_OP_COMPLETED(index) \ 988 do { \ 989 ldap_pvt_thread_mutex_lock( &op->o_counters->sc_mutex ); \ 990 ldap_pvt_mp_add_ulong(op->o_counters->sc_ops_completed, 1); \ 991 ldap_pvt_thread_mutex_unlock( &op->o_counters->sc_mutex ); \ 992 } while (0) 993 #endif /* !SLAPD_MONITOR */ 994 995 /* 996 * NOTE: keep in sync with enum in slapd.h 997 */ 998 static BI_op_func *opfun[] = { 999 do_bind, 1000 do_unbind, 1001 do_search, 1002 do_compare, 1003 do_modify, 1004 do_modrdn, 1005 do_add, 1006 do_delete, 1007 do_abandon, 1008 do_extended, 1009 NULL 1010 }; 1011 1012 /* Counters are per-thread, not per-connection. 1013 */ 1014 static void 1015 conn_counter_destroy( void *key, void *data ) 1016 { 1017 slap_counters_t **prev, *sc; 1018 1019 ldap_pvt_thread_mutex_lock( &slap_counters.sc_mutex ); 1020 for ( prev = &slap_counters.sc_next, sc = slap_counters.sc_next; sc; 1021 prev = &sc->sc_next, sc = sc->sc_next ) { 1022 if ( sc == data ) { 1023 int i; 1024 1025 *prev = sc->sc_next; 1026 /* Copy data to main counter */ 1027 ldap_pvt_mp_add( slap_counters.sc_bytes, sc->sc_bytes ); 1028 ldap_pvt_mp_add( slap_counters.sc_pdu, sc->sc_pdu ); 1029 ldap_pvt_mp_add( slap_counters.sc_entries, sc->sc_entries ); 1030 ldap_pvt_mp_add( slap_counters.sc_refs, sc->sc_refs ); 1031 ldap_pvt_mp_add( slap_counters.sc_ops_initiated, sc->sc_ops_initiated ); 1032 ldap_pvt_mp_add( slap_counters.sc_ops_completed, sc->sc_ops_completed ); 1033 #ifdef SLAPD_MONITOR 1034 for ( i = 0; i < SLAP_OP_LAST; i++ ) { 1035 ldap_pvt_mp_add( slap_counters.sc_ops_initiated_[ i ], sc->sc_ops_initiated_[ i ] ); 1036 ldap_pvt_mp_add( slap_counters.sc_ops_initiated_[ i ], sc->sc_ops_completed_[ i ] ); 1037 } 1038 #endif /* SLAPD_MONITOR */ 1039 slap_counters_destroy( sc ); 1040 ber_memfree_x( data, NULL ); 1041 break; 1042 } 1043 } 1044 ldap_pvt_thread_mutex_unlock( &slap_counters.sc_mutex ); 1045 } 1046 1047 static void 1048 conn_counter_init( Operation *op, void *ctx ) 1049 { 1050 slap_counters_t *sc; 1051 void *vsc = NULL; 1052 1053 if ( ldap_pvt_thread_pool_getkey( 1054 ctx, (void *)conn_counter_init, &vsc, NULL ) || !vsc ) { 1055 vsc = ch_malloc( sizeof( slap_counters_t )); 1056 sc = vsc; 1057 slap_counters_init( sc ); 1058 ldap_pvt_thread_pool_setkey( ctx, (void*)conn_counter_init, vsc, 1059 conn_counter_destroy, NULL, NULL ); 1060 1061 ldap_pvt_thread_mutex_lock( &slap_counters.sc_mutex ); 1062 sc->sc_next = slap_counters.sc_next; 1063 slap_counters.sc_next = sc; 1064 ldap_pvt_thread_mutex_unlock( &slap_counters.sc_mutex ); 1065 } 1066 op->o_counters = vsc; 1067 } 1068 1069 static void * 1070 connection_operation( void *ctx, void *arg_v ) 1071 { 1072 int rc = LDAP_OTHER, cancel; 1073 Operation *op = arg_v; 1074 SlapReply rs = {REP_RESULT}; 1075 ber_tag_t tag = op->o_tag; 1076 slap_op_t opidx = SLAP_OP_LAST; 1077 Connection *conn = op->o_conn; 1078 void *memctx = NULL; 1079 void *memctx_null = NULL; 1080 ber_len_t memsiz; 1081 1082 conn_counter_init( op, ctx ); 1083 ldap_pvt_thread_mutex_lock( &op->o_counters->sc_mutex ); 1084 /* FIXME: returns 0 in case of failure */ 1085 ldap_pvt_mp_add_ulong(op->o_counters->sc_ops_initiated, 1); 1086 ldap_pvt_thread_mutex_unlock( &op->o_counters->sc_mutex ); 1087 1088 op->o_threadctx = ctx; 1089 op->o_tid = ldap_pvt_thread_pool_tid( ctx ); 1090 1091 switch ( tag ) { 1092 case LDAP_REQ_BIND: 1093 case LDAP_REQ_UNBIND: 1094 case LDAP_REQ_ADD: 1095 case LDAP_REQ_DELETE: 1096 case LDAP_REQ_MODDN: 1097 case LDAP_REQ_MODIFY: 1098 case LDAP_REQ_COMPARE: 1099 case LDAP_REQ_SEARCH: 1100 case LDAP_REQ_ABANDON: 1101 case LDAP_REQ_EXTENDED: 1102 break; 1103 default: 1104 Debug( LDAP_DEBUG_ANY, "connection_operation: " 1105 "conn %lu unknown LDAP request 0x%lx\n", 1106 conn->c_connid, tag, 0 ); 1107 op->o_tag = LBER_ERROR; 1108 rs.sr_err = LDAP_PROTOCOL_ERROR; 1109 rs.sr_text = "unknown LDAP request"; 1110 send_ldap_disconnect( op, &rs ); 1111 rc = SLAPD_DISCONNECT; 1112 goto operations_error; 1113 } 1114 1115 if( conn->c_sasl_bind_in_progress && tag != LDAP_REQ_BIND ) { 1116 Debug( LDAP_DEBUG_ANY, "connection_operation: " 1117 "error: SASL bind in progress (tag=%ld).\n", 1118 (long) tag, 0, 0 ); 1119 send_ldap_error( op, &rs, LDAP_OPERATIONS_ERROR, 1120 "SASL bind in progress" ); 1121 rc = LDAP_OPERATIONS_ERROR; 1122 goto operations_error; 1123 } 1124 1125 #ifdef LDAP_X_TXN 1126 if (( conn->c_txn == CONN_TXN_SPECIFY ) && ( 1127 ( tag == LDAP_REQ_ADD ) || 1128 ( tag == LDAP_REQ_DELETE ) || 1129 ( tag == LDAP_REQ_MODIFY ) || 1130 ( tag == LDAP_REQ_MODRDN ))) 1131 { 1132 /* Disable SLAB allocator for all update operations 1133 issued inside of a transaction */ 1134 op->o_tmpmemctx = NULL; 1135 op->o_tmpmfuncs = &ch_mfuncs; 1136 } else 1137 #endif 1138 { 1139 /* We can use Thread-Local storage for most mallocs. We can 1140 * also use TL for ber parsing, but not on Add or Modify. 1141 */ 1142 #if 0 1143 memsiz = ber_len( op->o_ber ) * 64; 1144 if ( SLAP_SLAB_SIZE > memsiz ) memsiz = SLAP_SLAB_SIZE; 1145 #endif 1146 memsiz = SLAP_SLAB_SIZE; 1147 1148 memctx = slap_sl_mem_create( memsiz, SLAP_SLAB_STACK, ctx, 1 ); 1149 op->o_tmpmemctx = memctx; 1150 op->o_tmpmfuncs = &slap_sl_mfuncs; 1151 if ( tag != LDAP_REQ_ADD && tag != LDAP_REQ_MODIFY ) { 1152 /* Note - the ber and its buffer are already allocated from 1153 * regular memory; this only affects subsequent mallocs that 1154 * ber_scanf may invoke. 1155 */ 1156 ber_set_option( op->o_ber, LBER_OPT_BER_MEMCTX, &memctx ); 1157 } 1158 } 1159 1160 opidx = slap_req2op( tag ); 1161 assert( opidx != SLAP_OP_LAST ); 1162 INCR_OP_INITIATED( opidx ); 1163 rc = (*(opfun[opidx]))( op, &rs ); 1164 1165 operations_error: 1166 if ( rc == SLAPD_DISCONNECT ) { 1167 tag = LBER_ERROR; 1168 1169 } else if ( opidx != SLAP_OP_LAST ) { 1170 /* increment completed operations count 1171 * only if operation was initiated 1172 * and rc != SLAPD_DISCONNECT */ 1173 INCR_OP_COMPLETED( opidx ); 1174 } 1175 1176 ldap_pvt_thread_mutex_lock( &conn->c_mutex ); 1177 1178 if ( opidx == SLAP_OP_BIND && conn->c_conn_state == SLAP_C_BINDING ) 1179 conn->c_conn_state = SLAP_C_ACTIVE; 1180 1181 cancel = op->o_cancel; 1182 if ( cancel != SLAP_CANCEL_NONE && cancel != SLAP_CANCEL_DONE ) { 1183 if ( cancel == SLAP_CANCEL_REQ ) { 1184 op->o_cancel = rc == SLAPD_ABANDON 1185 ? SLAP_CANCEL_ACK : LDAP_TOO_LATE; 1186 } 1187 1188 do { 1189 /* Fake a cond_wait with thread_yield, then 1190 * verify the result properly mutex-protected. 1191 */ 1192 ldap_pvt_thread_mutex_unlock( &conn->c_mutex ); 1193 do { 1194 ldap_pvt_thread_yield(); 1195 } while ( (cancel = op->o_cancel) != SLAP_CANCEL_NONE 1196 && cancel != SLAP_CANCEL_DONE ); 1197 ldap_pvt_thread_mutex_lock( &conn->c_mutex ); 1198 } while ( (cancel = op->o_cancel) != SLAP_CANCEL_NONE 1199 && cancel != SLAP_CANCEL_DONE ); 1200 } 1201 1202 ber_set_option( op->o_ber, LBER_OPT_BER_MEMCTX, &memctx_null ); 1203 1204 LDAP_STAILQ_REMOVE( &conn->c_ops, op, Operation, o_next); 1205 LDAP_STAILQ_NEXT(op, o_next) = NULL; 1206 conn->c_n_ops_executing--; 1207 conn->c_n_ops_completed++; 1208 1209 switch( tag ) { 1210 case LBER_ERROR: 1211 case LDAP_REQ_UNBIND: 1212 /* c_mutex is locked */ 1213 connection_closing( conn, 1214 tag == LDAP_REQ_UNBIND ? NULL : "operations error" ); 1215 break; 1216 } 1217 1218 connection_resched( conn ); 1219 ldap_pvt_thread_mutex_unlock( &conn->c_mutex ); 1220 slap_op_free( op, ctx ); 1221 return NULL; 1222 } 1223 1224 static const Listener dummy_list = { BER_BVC(""), BER_BVC("") }; 1225 1226 Connection *connection_client_setup( 1227 ber_socket_t s, 1228 ldap_pvt_thread_start_t *func, 1229 void *arg ) 1230 { 1231 Connection *c; 1232 ber_socket_t sfd = SLAP_SOCKNEW( s ); 1233 1234 c = connection_init( sfd, (Listener *)&dummy_list, "", "", 1235 CONN_IS_CLIENT, 0, NULL 1236 LDAP_PF_LOCAL_SENDMSG_ARG(NULL)); 1237 if ( c ) { 1238 c->c_clientfunc = func; 1239 c->c_clientarg = arg; 1240 1241 slapd_add_internal( sfd, 0 ); 1242 } 1243 return c; 1244 } 1245 1246 void connection_client_enable( 1247 Connection *c ) 1248 { 1249 slapd_set_read( c->c_sd, 1 ); 1250 } 1251 1252 void connection_client_stop( 1253 Connection *c ) 1254 { 1255 Sockbuf *sb; 1256 ber_socket_t s = c->c_sd; 1257 1258 /* get (locked) connection */ 1259 c = connection_get( s ); 1260 1261 assert( c->c_conn_state == SLAP_C_CLIENT ); 1262 1263 c->c_listener = NULL; 1264 c->c_conn_state = SLAP_C_INVALID; 1265 c->c_struct_state = SLAP_C_UNUSED; 1266 c->c_sd = AC_SOCKET_INVALID; 1267 c->c_close_reason = "?"; /* should never be needed */ 1268 sb = c->c_sb; 1269 c->c_sb = ber_sockbuf_alloc( ); 1270 { 1271 ber_len_t max = sockbuf_max_incoming; 1272 ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_SET_MAX_INCOMING, &max ); 1273 } 1274 slapd_remove( s, sb, 0, 1, 0 ); 1275 1276 connection_return( c ); 1277 } 1278 1279 static int connection_read( ber_socket_t s, conn_readinfo *cri ); 1280 1281 static void* connection_read_thread( void* ctx, void* argv ) 1282 { 1283 int rc ; 1284 conn_readinfo cri = { NULL, NULL, NULL, NULL, 0 }; 1285 ber_socket_t s = (long)argv; 1286 1287 /* 1288 * read incoming LDAP requests. If there is more than one, 1289 * the first one is returned with new_op 1290 */ 1291 cri.ctx = ctx; 1292 if( ( rc = connection_read( s, &cri ) ) < 0 ) { 1293 Debug( LDAP_DEBUG_CONNS, "connection_read(%d) error\n", s, 0, 0 ); 1294 return (void*)(long)rc; 1295 } 1296 1297 /* execute a single queued request in the same thread */ 1298 if( cri.op && !cri.nullop ) { 1299 rc = (long)connection_operation( ctx, cri.op ); 1300 } else if ( cri.func ) { 1301 rc = (long)cri.func( ctx, cri.arg ); 1302 } 1303 1304 return (void*)(long)rc; 1305 } 1306 1307 int connection_read_activate( ber_socket_t s ) 1308 { 1309 int rc; 1310 1311 /* 1312 * suspend reading on this file descriptor until a connection processing 1313 * thread reads data on it. Otherwise the listener thread will repeatedly 1314 * submit the same event on it to the pool. 1315 */ 1316 rc = slapd_clr_read( s, 0 ); 1317 if ( rc ) 1318 return rc; 1319 1320 /* Don't let blocked writers block a pause request */ 1321 if ( connections[s].c_writewaiter && 1322 ldap_pvt_thread_pool_pausing( &connection_pool )) 1323 connection_wake_writers( &connections[s] ); 1324 1325 rc = ldap_pvt_thread_pool_submit( &connection_pool, 1326 connection_read_thread, (void *)(long)s ); 1327 1328 if( rc != 0 ) { 1329 Debug( LDAP_DEBUG_ANY, 1330 "connection_read_activate(%d): submit failed (%d)\n", 1331 s, rc, 0 ); 1332 } 1333 1334 return rc; 1335 } 1336 1337 static int 1338 connection_read( ber_socket_t s, conn_readinfo *cri ) 1339 { 1340 int rc = 0; 1341 Connection *c; 1342 1343 assert( connections != NULL ); 1344 1345 /* get (locked) connection */ 1346 c = connection_get( s ); 1347 1348 if( c == NULL ) { 1349 Debug( LDAP_DEBUG_ANY, 1350 "connection_read(%ld): no connection!\n", 1351 (long) s, 0, 0 ); 1352 1353 return -1; 1354 } 1355 1356 c->c_n_read++; 1357 1358 if( c->c_conn_state == SLAP_C_CLOSING ) { 1359 Debug( LDAP_DEBUG_CONNS, 1360 "connection_read(%d): closing, ignoring input for id=%lu\n", 1361 s, c->c_connid, 0 ); 1362 connection_return( c ); 1363 return 0; 1364 } 1365 1366 if ( c->c_conn_state == SLAP_C_CLIENT ) { 1367 cri->func = c->c_clientfunc; 1368 cri->arg = c->c_clientarg; 1369 /* read should already be cleared */ 1370 connection_return( c ); 1371 return 0; 1372 } 1373 1374 Debug( LDAP_DEBUG_TRACE, 1375 "connection_read(%d): checking for input on id=%lu\n", 1376 s, c->c_connid, 0 ); 1377 1378 #ifdef HAVE_TLS 1379 if ( c->c_is_tls && c->c_needs_tls_accept ) { 1380 rc = ldap_pvt_tls_accept( c->c_sb, slap_tls_ctx ); 1381 if ( rc < 0 ) { 1382 Debug( LDAP_DEBUG_TRACE, 1383 "connection_read(%d): TLS accept failure " 1384 "error=%d id=%lu, closing\n", 1385 s, rc, c->c_connid ); 1386 1387 c->c_needs_tls_accept = 0; 1388 /* c_mutex is locked */ 1389 connection_closing( c, "TLS negotiation failure" ); 1390 connection_close( c ); 1391 connection_return( c ); 1392 return 0; 1393 1394 } else if ( rc == 0 ) { 1395 void *ssl; 1396 struct berval authid = BER_BVNULL; 1397 1398 c->c_needs_tls_accept = 0; 1399 1400 /* we need to let SASL know */ 1401 ssl = ldap_pvt_tls_sb_ctx( c->c_sb ); 1402 1403 c->c_tls_ssf = (slap_ssf_t) ldap_pvt_tls_get_strength( ssl ); 1404 if( c->c_tls_ssf > c->c_ssf ) { 1405 c->c_ssf = c->c_tls_ssf; 1406 } 1407 1408 rc = dnX509peerNormalize( ssl, &authid ); 1409 if ( rc != LDAP_SUCCESS ) { 1410 Debug( LDAP_DEBUG_TRACE, "connection_read(%d): " 1411 "unable to get TLS client DN, error=%d id=%lu\n", 1412 s, rc, c->c_connid ); 1413 } 1414 Statslog( LDAP_DEBUG_STATS, 1415 "conn=%lu fd=%d TLS established tls_ssf=%u ssf=%u\n", 1416 c->c_connid, (int) s, c->c_tls_ssf, c->c_ssf, 0 ); 1417 slap_sasl_external( c, c->c_tls_ssf, &authid ); 1418 if ( authid.bv_val ) free( authid.bv_val ); 1419 } else if ( rc == 1 && ber_sockbuf_ctrl( c->c_sb, 1420 LBER_SB_OPT_NEEDS_WRITE, NULL )) { /* need to retry */ 1421 slapd_set_write( s, 1 ); 1422 connection_return( c ); 1423 return 0; 1424 } 1425 1426 /* if success and data is ready, fall thru to data input loop */ 1427 if( !ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_DATA_READY, NULL ) ) 1428 { 1429 slapd_set_read( s, 1 ); 1430 connection_return( c ); 1431 return 0; 1432 } 1433 } 1434 #endif 1435 1436 #ifdef HAVE_CYRUS_SASL 1437 if ( c->c_sasl_layers ) { 1438 /* If previous layer is not removed yet, give up for now */ 1439 if ( !c->c_sasl_sockctx ) { 1440 slapd_set_read( s, 1 ); 1441 connection_return( c ); 1442 return 0; 1443 } 1444 1445 c->c_sasl_layers = 0; 1446 1447 rc = ldap_pvt_sasl_install( c->c_sb, c->c_sasl_sockctx ); 1448 if( rc != LDAP_SUCCESS ) { 1449 Debug( LDAP_DEBUG_TRACE, 1450 "connection_read(%d): SASL install error " 1451 "error=%d id=%lu, closing\n", 1452 s, rc, c->c_connid ); 1453 1454 /* c_mutex is locked */ 1455 connection_closing( c, "SASL layer install failure" ); 1456 connection_close( c ); 1457 connection_return( c ); 1458 return 0; 1459 } 1460 } 1461 #endif 1462 1463 #define CONNECTION_INPUT_LOOP 1 1464 /* #define DATA_READY_LOOP 1 */ 1465 1466 do { 1467 /* How do we do this without getting into a busy loop ? */ 1468 rc = connection_input( c, cri ); 1469 } 1470 #ifdef DATA_READY_LOOP 1471 while( !rc && ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_DATA_READY, NULL )); 1472 #elif defined CONNECTION_INPUT_LOOP 1473 while(!rc); 1474 #else 1475 while(0); 1476 #endif 1477 1478 if( rc < 0 ) { 1479 Debug( LDAP_DEBUG_CONNS, 1480 "connection_read(%d): input error=%d id=%lu, closing.\n", 1481 s, rc, c->c_connid ); 1482 1483 /* c_mutex is locked */ 1484 connection_closing( c, conn_lost_str ); 1485 connection_close( c ); 1486 connection_return( c ); 1487 return 0; 1488 } 1489 1490 if ( ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_NEEDS_WRITE, NULL ) ) { 1491 slapd_set_write( s, 0 ); 1492 } 1493 1494 slapd_set_read( s, 1 ); 1495 connection_return( c ); 1496 1497 return 0; 1498 } 1499 1500 static int 1501 connection_input( Connection *conn , conn_readinfo *cri ) 1502 { 1503 Operation *op; 1504 ber_tag_t tag; 1505 ber_len_t len; 1506 ber_int_t msgid; 1507 BerElement *ber; 1508 int rc; 1509 #ifdef LDAP_CONNECTIONLESS 1510 Sockaddr peeraddr; 1511 char *cdn = NULL; 1512 #endif 1513 char *defer = NULL; 1514 void *ctx; 1515 1516 if ( conn->c_currentber == NULL && 1517 ( conn->c_currentber = ber_alloc()) == NULL ) 1518 { 1519 Debug( LDAP_DEBUG_ANY, "ber_alloc failed\n", 0, 0, 0 ); 1520 return -1; 1521 } 1522 1523 sock_errset(0); 1524 1525 #ifdef LDAP_CONNECTIONLESS 1526 if ( conn->c_is_udp ) { 1527 #if defined(LDAP_PF_INET6) 1528 char peername[sizeof("IP=[ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff]:65535")]; 1529 char addr[INET6_ADDRSTRLEN]; 1530 #else 1531 char peername[sizeof("IP=255.255.255.255:65336")]; 1532 char addr[INET_ADDRSTRLEN]; 1533 #endif 1534 const char *peeraddr_string = NULL; 1535 1536 len = ber_int_sb_read(conn->c_sb, &peeraddr, sizeof(Sockaddr)); 1537 if (len != sizeof(Sockaddr)) return 1; 1538 1539 #if defined(LDAP_PF_INET6) 1540 if (peeraddr.sa_addr.sa_family == AF_INET6) { 1541 if ( IN6_IS_ADDR_V4MAPPED(&peeraddr.sa_in6_addr.sin6_addr) ) { 1542 #if defined( HAVE_GETADDRINFO ) && defined( HAVE_INET_NTOP ) 1543 peeraddr_string = inet_ntop( AF_INET, 1544 ((struct in_addr *)&peeraddr.sa_in6_addr.sin6_addr.s6_addr[12]), 1545 addr, sizeof(addr) ); 1546 #else /* ! HAVE_GETADDRINFO || ! HAVE_INET_NTOP */ 1547 peeraddr_string = inet_ntoa( *((struct in_addr *) 1548 &peeraddr.sa_in6_addr.sin6_addr.s6_addr[12]) ); 1549 #endif /* ! HAVE_GETADDRINFO || ! HAVE_INET_NTOP */ 1550 if ( !peeraddr_string ) peeraddr_string = SLAP_STRING_UNKNOWN; 1551 sprintf( peername, "IP=%s:%d", peeraddr_string, 1552 (unsigned) ntohs( peeraddr.sa_in6_addr.sin6_port ) ); 1553 } else { 1554 peeraddr_string = inet_ntop( AF_INET6, 1555 &peeraddr.sa_in6_addr.sin6_addr, 1556 addr, sizeof addr ); 1557 if ( !peeraddr_string ) peeraddr_string = SLAP_STRING_UNKNOWN; 1558 sprintf( peername, "IP=[%s]:%d", peeraddr_string, 1559 (unsigned) ntohs( peeraddr.sa_in6_addr.sin6_port ) ); 1560 } 1561 } else 1562 #endif 1563 #if defined( HAVE_GETADDRINFO ) && defined( HAVE_INET_NTOP ) 1564 { 1565 peeraddr_string = inet_ntop( AF_INET, &peeraddr.sa_in_addr.sin_addr, 1566 addr, sizeof(addr) ); 1567 #else /* ! HAVE_GETADDRINFO || ! HAVE_INET_NTOP */ 1568 peeraddr_string = inet_ntoa( peeraddr.sa_in_addr.sin_addr ); 1569 #endif /* ! HAVE_GETADDRINFO || ! HAVE_INET_NTOP */ 1570 sprintf( peername, "IP=%s:%d", 1571 peeraddr_string, 1572 (unsigned) ntohs( peeraddr.sa_in_addr.sin_port ) ); 1573 } 1574 Statslog( LDAP_DEBUG_STATS, 1575 "conn=%lu UDP request from %s (%s) accepted.\n", 1576 conn->c_connid, peername, conn->c_sock_name.bv_val, 0, 0 ); 1577 } 1578 #endif 1579 1580 tag = ber_get_next( conn->c_sb, &len, conn->c_currentber ); 1581 if ( tag != LDAP_TAG_MESSAGE ) { 1582 int err = sock_errno(); 1583 1584 if ( err != EWOULDBLOCK && err != EAGAIN ) { 1585 /* log, close and send error */ 1586 Debug( LDAP_DEBUG_TRACE, 1587 "ber_get_next on fd %d failed errno=%d (%s)\n", 1588 conn->c_sd, err, sock_errstr(err) ); 1589 ber_free( conn->c_currentber, 1 ); 1590 conn->c_currentber = NULL; 1591 1592 return -2; 1593 } 1594 return 1; 1595 } 1596 1597 ber = conn->c_currentber; 1598 conn->c_currentber = NULL; 1599 1600 if ( (tag = ber_get_int( ber, &msgid )) != LDAP_TAG_MSGID ) { 1601 /* log, close and send error */ 1602 Debug( LDAP_DEBUG_ANY, "ber_get_int returns 0x%lx\n", tag, 0, 0 ); 1603 ber_free( ber, 1 ); 1604 return -1; 1605 } 1606 1607 if ( (tag = ber_peek_tag( ber, &len )) == LBER_ERROR ) { 1608 /* log, close and send error */ 1609 Debug( LDAP_DEBUG_ANY, "ber_peek_tag returns 0x%lx\n", tag, 0, 0 ); 1610 ber_free( ber, 1 ); 1611 1612 return -1; 1613 } 1614 1615 #ifdef LDAP_CONNECTIONLESS 1616 if( conn->c_is_udp ) { 1617 if( tag == LBER_OCTETSTRING ) { 1618 if ( (tag = ber_get_stringa( ber, &cdn )) != LBER_ERROR ) 1619 tag = ber_peek_tag( ber, &len ); 1620 } 1621 if( tag != LDAP_REQ_ABANDON && tag != LDAP_REQ_SEARCH ) { 1622 Debug( LDAP_DEBUG_ANY, "invalid req for UDP 0x%lx\n", tag, 0, 0 ); 1623 ber_free( ber, 1 ); 1624 return 0; 1625 } 1626 } 1627 #endif 1628 1629 if(tag == LDAP_REQ_BIND) { 1630 /* immediately abandon all existing operations upon BIND */ 1631 connection_abandon( conn ); 1632 } 1633 1634 ctx = cri->ctx; 1635 op = slap_op_alloc( ber, msgid, tag, conn->c_n_ops_received++, ctx ); 1636 1637 Debug( LDAP_DEBUG_TRACE, "op tag 0x%lx, time %ld\n", tag, 1638 (long) op->o_time, 0); 1639 1640 op->o_conn = conn; 1641 /* clear state if the connection is being reused from inactive */ 1642 if ( conn->c_conn_state == SLAP_C_INACTIVE ) { 1643 memset( &conn->c_pagedresults_state, 0, 1644 sizeof( conn->c_pagedresults_state ) ); 1645 } 1646 1647 op->o_res_ber = NULL; 1648 1649 #ifdef LDAP_CONNECTIONLESS 1650 if (conn->c_is_udp) { 1651 if ( cdn ) { 1652 ber_str2bv( cdn, 0, 1, &op->o_dn ); 1653 op->o_protocol = LDAP_VERSION2; 1654 } 1655 op->o_res_ber = ber_alloc_t( LBER_USE_DER ); 1656 if (op->o_res_ber == NULL) return 1; 1657 1658 rc = ber_write( op->o_res_ber, (char *)&peeraddr, 1659 sizeof(struct sockaddr), 0 ); 1660 1661 if (rc != sizeof(struct sockaddr)) { 1662 Debug( LDAP_DEBUG_ANY, "ber_write failed\n", 0, 0, 0 ); 1663 return 1; 1664 } 1665 1666 if (op->o_protocol == LDAP_VERSION2) { 1667 rc = ber_printf(op->o_res_ber, "{is{" /*}}*/, op->o_msgid, ""); 1668 if (rc == -1) { 1669 Debug( LDAP_DEBUG_ANY, "ber_write failed\n", 0, 0, 0 ); 1670 return rc; 1671 } 1672 } 1673 } 1674 #endif /* LDAP_CONNECTIONLESS */ 1675 1676 rc = 0; 1677 1678 /* Don't process requests when the conn is in the middle of a 1679 * Bind, or if it's closing. Also, don't let any single conn 1680 * use up all the available threads, and don't execute if we're 1681 * currently blocked on output. And don't execute if there are 1682 * already pending ops, let them go first. Abandon operations 1683 * get exceptions to some, but not all, cases. 1684 */ 1685 switch( tag ){ 1686 default: 1687 /* Abandon and Unbind are exempt from these checks */ 1688 if (conn->c_conn_state == SLAP_C_CLOSING) { 1689 defer = "closing"; 1690 break; 1691 } else if (conn->c_writewaiter) { 1692 defer = "awaiting write"; 1693 break; 1694 } else if (conn->c_n_ops_pending) { 1695 defer = "pending operations"; 1696 break; 1697 } 1698 /* FALLTHRU */ 1699 case LDAP_REQ_ABANDON: 1700 /* Unbind is exempt from these checks */ 1701 if (conn->c_n_ops_executing >= connection_pool_max/2) { 1702 defer = "too many executing"; 1703 break; 1704 } else if (conn->c_conn_state == SLAP_C_BINDING) { 1705 defer = "binding"; 1706 break; 1707 } 1708 /* FALLTHRU */ 1709 case LDAP_REQ_UNBIND: 1710 break; 1711 } 1712 1713 if( defer ) { 1714 int max = conn->c_dn.bv_len 1715 ? slap_conn_max_pending_auth 1716 : slap_conn_max_pending; 1717 1718 Debug( LDAP_DEBUG_ANY, 1719 "connection_input: conn=%lu deferring operation: %s\n", 1720 conn->c_connid, defer, 0 ); 1721 conn->c_n_ops_pending++; 1722 LDAP_STAILQ_INSERT_TAIL( &conn->c_pending_ops, op, o_next ); 1723 rc = ( conn->c_n_ops_pending > max ) ? -1 : 0; 1724 1725 } else { 1726 conn->c_n_ops_executing++; 1727 1728 /* 1729 * The first op will be processed in the same thread context, 1730 * as long as there is only one op total. 1731 * Subsequent ops will be submitted to the pool by 1732 * calling connection_op_activate() 1733 */ 1734 if ( cri->op == NULL ) { 1735 /* the first incoming request */ 1736 connection_op_queue( op ); 1737 cri->op = op; 1738 } else { 1739 if ( !cri->nullop ) { 1740 cri->nullop = 1; 1741 rc = ldap_pvt_thread_pool_submit( &connection_pool, 1742 connection_operation, (void *) cri->op ); 1743 } 1744 connection_op_activate( op ); 1745 } 1746 } 1747 1748 #ifdef NO_THREADS 1749 if ( conn->c_struct_state != SLAP_C_USED ) { 1750 /* connection must have got closed underneath us */ 1751 return 1; 1752 } 1753 #endif 1754 1755 assert( conn->c_struct_state == SLAP_C_USED ); 1756 return rc; 1757 } 1758 1759 static int 1760 connection_resched( Connection *conn ) 1761 { 1762 Operation *op; 1763 1764 if( conn->c_writewaiter ) 1765 return 0; 1766 1767 if( conn->c_conn_state == SLAP_C_CLOSING ) { 1768 Debug( LDAP_DEBUG_CONNS, "connection_resched: " 1769 "attempting closing conn=%lu sd=%d\n", 1770 conn->c_connid, conn->c_sd, 0 ); 1771 connection_close( conn ); 1772 return 0; 1773 } 1774 1775 if( conn->c_conn_state != SLAP_C_ACTIVE ) { 1776 /* other states need different handling */ 1777 return 0; 1778 } 1779 1780 while ((op = LDAP_STAILQ_FIRST( &conn->c_pending_ops )) != NULL) { 1781 if ( conn->c_n_ops_executing > connection_pool_max/2 ) break; 1782 1783 LDAP_STAILQ_REMOVE_HEAD( &conn->c_pending_ops, o_next ); 1784 LDAP_STAILQ_NEXT(op, o_next) = NULL; 1785 1786 /* pending operations should not be marked for abandonment */ 1787 assert(!op->o_abandon); 1788 1789 conn->c_n_ops_pending--; 1790 conn->c_n_ops_executing++; 1791 1792 connection_op_activate( op ); 1793 1794 if ( conn->c_conn_state == SLAP_C_BINDING ) break; 1795 } 1796 return 0; 1797 } 1798 1799 static void 1800 connection_init_log_prefix( Operation *op ) 1801 { 1802 if ( op->o_connid == (unsigned long)(-1) ) { 1803 snprintf( op->o_log_prefix, sizeof( op->o_log_prefix ), 1804 "conn=-1 op=%lu", op->o_opid ); 1805 1806 } else { 1807 snprintf( op->o_log_prefix, sizeof( op->o_log_prefix ), 1808 "conn=%lu op=%lu", op->o_connid, op->o_opid ); 1809 } 1810 } 1811 1812 static int connection_bind_cleanup_cb( Operation *op, SlapReply *rs ) 1813 { 1814 op->o_conn->c_sasl_bindop = NULL; 1815 1816 ch_free( op->o_callback ); 1817 op->o_callback = NULL; 1818 1819 return SLAP_CB_CONTINUE; 1820 } 1821 1822 static int connection_bind_cb( Operation *op, SlapReply *rs ) 1823 { 1824 ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex ); 1825 op->o_conn->c_sasl_bind_in_progress = 1826 ( rs->sr_err == LDAP_SASL_BIND_IN_PROGRESS ); 1827 1828 /* Moved here from bind.c due to ITS#4158 */ 1829 op->o_conn->c_sasl_bindop = NULL; 1830 if ( op->orb_method == LDAP_AUTH_SASL ) { 1831 if( rs->sr_err == LDAP_SUCCESS ) { 1832 ber_dupbv(&op->o_conn->c_dn, &op->orb_edn); 1833 if( !BER_BVISEMPTY( &op->orb_edn ) ) { 1834 /* edn is always normalized already */ 1835 ber_dupbv( &op->o_conn->c_ndn, &op->o_conn->c_dn ); 1836 } 1837 op->o_tmpfree( op->orb_edn.bv_val, op->o_tmpmemctx ); 1838 BER_BVZERO( &op->orb_edn ); 1839 op->o_conn->c_authmech = op->o_conn->c_sasl_bind_mech; 1840 BER_BVZERO( &op->o_conn->c_sasl_bind_mech ); 1841 1842 op->o_conn->c_sasl_ssf = op->orb_ssf; 1843 if( op->orb_ssf > op->o_conn->c_ssf ) { 1844 op->o_conn->c_ssf = op->orb_ssf; 1845 } 1846 1847 if( !BER_BVISEMPTY( &op->o_conn->c_dn ) ) { 1848 ber_len_t max = sockbuf_max_incoming_auth; 1849 ber_sockbuf_ctrl( op->o_conn->c_sb, 1850 LBER_SB_OPT_SET_MAX_INCOMING, &max ); 1851 } 1852 1853 /* log authorization identity */ 1854 Statslog( LDAP_DEBUG_STATS, 1855 "%s BIND dn=\"%s\" mech=%s sasl_ssf=%d ssf=%d\n", 1856 op->o_log_prefix, 1857 BER_BVISNULL( &op->o_conn->c_dn ) ? "<empty>" : op->o_conn->c_dn.bv_val, 1858 op->o_conn->c_authmech.bv_val, 1859 op->orb_ssf, op->o_conn->c_ssf ); 1860 1861 Debug( LDAP_DEBUG_TRACE, 1862 "do_bind: SASL/%s bind: dn=\"%s\" sasl_ssf=%d\n", 1863 op->o_conn->c_authmech.bv_val, 1864 BER_BVISNULL( &op->o_conn->c_dn ) ? "<empty>" : op->o_conn->c_dn.bv_val, 1865 op->orb_ssf ); 1866 1867 } else if ( rs->sr_err != LDAP_SASL_BIND_IN_PROGRESS ) { 1868 if ( !BER_BVISNULL( &op->o_conn->c_sasl_bind_mech ) ) { 1869 free( op->o_conn->c_sasl_bind_mech.bv_val ); 1870 BER_BVZERO( &op->o_conn->c_sasl_bind_mech ); 1871 } 1872 } 1873 } 1874 ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex ); 1875 1876 ch_free( op->o_callback ); 1877 op->o_callback = NULL; 1878 1879 return SLAP_CB_CONTINUE; 1880 } 1881 1882 static void connection_op_queue( Operation *op ) 1883 { 1884 ber_tag_t tag = op->o_tag; 1885 1886 if (tag == LDAP_REQ_BIND) { 1887 slap_callback *sc = ch_calloc( 1, sizeof( slap_callback )); 1888 sc->sc_response = connection_bind_cb; 1889 sc->sc_cleanup = connection_bind_cleanup_cb; 1890 sc->sc_next = op->o_callback; 1891 op->o_callback = sc; 1892 op->o_conn->c_conn_state = SLAP_C_BINDING; 1893 } 1894 1895 if (!op->o_dn.bv_len) { 1896 op->o_authz = op->o_conn->c_authz; 1897 if ( BER_BVISNULL( &op->o_conn->c_sasl_authz_dn )) { 1898 ber_dupbv( &op->o_dn, &op->o_conn->c_dn ); 1899 ber_dupbv( &op->o_ndn, &op->o_conn->c_ndn ); 1900 } else { 1901 ber_dupbv( &op->o_dn, &op->o_conn->c_sasl_authz_dn ); 1902 ber_dupbv( &op->o_ndn, &op->o_conn->c_sasl_authz_dn ); 1903 } 1904 } 1905 1906 op->o_authtype = op->o_conn->c_authtype; 1907 ber_dupbv( &op->o_authmech, &op->o_conn->c_authmech ); 1908 1909 if (!op->o_protocol) { 1910 op->o_protocol = op->o_conn->c_protocol 1911 ? op->o_conn->c_protocol : LDAP_VERSION3; 1912 } 1913 1914 if (op->o_conn->c_conn_state == SLAP_C_INACTIVE && 1915 op->o_protocol > LDAP_VERSION2) 1916 { 1917 op->o_conn->c_conn_state = SLAP_C_ACTIVE; 1918 } 1919 1920 op->o_connid = op->o_conn->c_connid; 1921 connection_init_log_prefix( op ); 1922 1923 LDAP_STAILQ_INSERT_TAIL( &op->o_conn->c_ops, op, o_next ); 1924 } 1925 1926 static int connection_op_activate( Operation *op ) 1927 { 1928 int rc; 1929 1930 connection_op_queue( op ); 1931 1932 rc = ldap_pvt_thread_pool_submit( &connection_pool, 1933 connection_operation, (void *) op ); 1934 1935 if ( rc != 0 ) { 1936 Debug( LDAP_DEBUG_ANY, 1937 "connection_op_activate: submit failed (%d) for conn=%lu\n", 1938 rc, op->o_connid, 0 ); 1939 /* should move op to pending list */ 1940 } 1941 1942 return rc; 1943 } 1944 1945 int connection_write(ber_socket_t s) 1946 { 1947 Connection *c; 1948 Operation *op; 1949 1950 assert( connections != NULL ); 1951 1952 c = connection_get( s ); 1953 if( c == NULL ) { 1954 Debug( LDAP_DEBUG_ANY, 1955 "connection_write(%ld): no connection!\n", 1956 (long)s, 0, 0 ); 1957 return -1; 1958 } 1959 1960 slapd_clr_write( s, 0 ); 1961 1962 #ifdef HAVE_TLS 1963 if ( c->c_is_tls && c->c_needs_tls_accept ) { 1964 connection_return( c ); 1965 connection_read_activate( s ); 1966 return 0; 1967 } 1968 #endif 1969 1970 c->c_n_write++; 1971 1972 Debug( LDAP_DEBUG_TRACE, 1973 "connection_write(%d): waking output for id=%lu\n", 1974 s, c->c_connid, 0 ); 1975 ldap_pvt_thread_mutex_lock( &c->c_write2_mutex ); 1976 ldap_pvt_thread_cond_signal( &c->c_write2_cv ); 1977 ldap_pvt_thread_mutex_unlock( &c->c_write2_mutex ); 1978 1979 if ( ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_NEEDS_READ, NULL ) ) { 1980 slapd_set_read( s, 1 ); 1981 } 1982 if ( ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_NEEDS_WRITE, NULL ) ) { 1983 slapd_set_write( s, 1 ); 1984 } 1985 1986 /* If there are ops pending because of a writewaiter, 1987 * start one up. 1988 */ 1989 while ((op = LDAP_STAILQ_FIRST( &c->c_pending_ops )) != NULL) { 1990 if ( !c->c_writewaiter ) break; 1991 if ( c->c_n_ops_executing > connection_pool_max/2 ) break; 1992 1993 LDAP_STAILQ_REMOVE_HEAD( &c->c_pending_ops, o_next ); 1994 LDAP_STAILQ_NEXT(op, o_next) = NULL; 1995 1996 /* pending operations should not be marked for abandonment */ 1997 assert(!op->o_abandon); 1998 1999 c->c_n_ops_pending--; 2000 c->c_n_ops_executing++; 2001 2002 connection_op_activate( op ); 2003 2004 break; 2005 } 2006 2007 connection_return( c ); 2008 return 0; 2009 } 2010 2011 #ifdef LDAP_SLAPI 2012 typedef struct conn_fake_extblock { 2013 void *eb_conn; 2014 void *eb_op; 2015 } conn_fake_extblock; 2016 2017 static void 2018 connection_fake_destroy( 2019 void *key, 2020 void *data ) 2021 { 2022 Connection conn = {0}; 2023 Operation op = {0}; 2024 Opheader ohdr = {0}; 2025 2026 conn_fake_extblock *eb = data; 2027 2028 op.o_hdr = &ohdr; 2029 op.o_hdr->oh_extensions = eb->eb_op; 2030 conn.c_extensions = eb->eb_conn; 2031 op.o_conn = &conn; 2032 conn.c_connid = -1; 2033 op.o_connid = -1; 2034 2035 ber_memfree_x( eb, NULL ); 2036 slapi_int_free_object_extensions( SLAPI_X_EXT_OPERATION, &op ); 2037 slapi_int_free_object_extensions( SLAPI_X_EXT_CONNECTION, &conn ); 2038 } 2039 #endif 2040 2041 void 2042 connection_fake_init( 2043 Connection *conn, 2044 OperationBuffer *opbuf, 2045 void *ctx ) 2046 { 2047 connection_fake_init2( conn, opbuf, ctx, 1 ); 2048 } 2049 2050 void 2051 operation_fake_init( 2052 Connection *conn, 2053 Operation *op, 2054 void *ctx, 2055 int newmem ) 2056 { 2057 /* set memory context */ 2058 op->o_tmpmemctx = slap_sl_mem_create(SLAP_SLAB_SIZE, SLAP_SLAB_STACK, ctx, 2059 newmem ); 2060 op->o_tmpmfuncs = &slap_sl_mfuncs; 2061 op->o_threadctx = ctx; 2062 op->o_tid = ldap_pvt_thread_pool_tid( ctx ); 2063 2064 op->o_counters = &slap_counters; 2065 op->o_conn = conn; 2066 op->o_connid = op->o_conn->c_connid; 2067 connection_init_log_prefix( op ); 2068 } 2069 2070 2071 void 2072 connection_fake_init2( 2073 Connection *conn, 2074 OperationBuffer *opbuf, 2075 void *ctx, 2076 int newmem ) 2077 { 2078 Operation *op = (Operation *) opbuf; 2079 2080 conn->c_connid = -1; 2081 conn->c_conn_idx = -1; 2082 conn->c_send_ldap_result = slap_send_ldap_result; 2083 conn->c_send_search_entry = slap_send_search_entry; 2084 conn->c_send_search_reference = slap_send_search_reference; 2085 conn->c_send_ldap_extended = slap_send_ldap_extended; 2086 conn->c_send_ldap_intermediate = slap_send_ldap_intermediate; 2087 conn->c_listener = (Listener *)&dummy_list; 2088 conn->c_peer_domain = slap_empty_bv; 2089 conn->c_peer_name = slap_empty_bv; 2090 2091 memset( opbuf, 0, sizeof( *opbuf )); 2092 op->o_hdr = &opbuf->ob_hdr; 2093 op->o_controls = opbuf->ob_controls; 2094 2095 operation_fake_init( conn, op, ctx, newmem ); 2096 2097 #ifdef LDAP_SLAPI 2098 if ( slapi_plugins_used ) { 2099 conn_fake_extblock *eb; 2100 void *ebx = NULL; 2101 2102 /* Use thread keys to make sure these eventually get cleaned up */ 2103 if ( ldap_pvt_thread_pool_getkey( ctx, (void *)connection_fake_init, 2104 &ebx, NULL )) { 2105 eb = ch_malloc( sizeof( *eb )); 2106 slapi_int_create_object_extensions( SLAPI_X_EXT_CONNECTION, conn ); 2107 slapi_int_create_object_extensions( SLAPI_X_EXT_OPERATION, op ); 2108 eb->eb_conn = conn->c_extensions; 2109 eb->eb_op = op->o_hdr->oh_extensions; 2110 ldap_pvt_thread_pool_setkey( ctx, (void *)connection_fake_init, 2111 eb, connection_fake_destroy, NULL, NULL ); 2112 } else { 2113 eb = ebx; 2114 conn->c_extensions = eb->eb_conn; 2115 op->o_hdr->oh_extensions = eb->eb_op; 2116 } 2117 } 2118 #endif /* LDAP_SLAPI */ 2119 2120 slap_op_time( &op->o_time, &op->o_tincr ); 2121 } 2122 2123 void 2124 connection_assign_nextid( Connection *conn ) 2125 { 2126 ldap_pvt_thread_mutex_lock( &conn_nextid_mutex ); 2127 conn->c_connid = conn_nextid++; 2128 ldap_pvt_thread_mutex_unlock( &conn_nextid_mutex ); 2129 } 2130