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