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