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 19#include "portable.h" 20 21#include <stdio.h> 22#ifdef HAVE_LIMITS_H 23#include <limits.h> 24#endif 25 26#include <ac/stdlib.h> 27 28#include <ac/param.h> 29#include <ac/socket.h> 30#include <ac/string.h> 31#include <ac/time.h> 32 33#include <ac/unistd.h> 34 35#include "ldap-int.h" 36#include "ldap_log.h" 37 38#ifdef LDAP_RESPONSE_RB_TREE 39#include "rb_response.h" 40#endif 41 42#if defined(__APPLE__) && defined(LDAP_R_COMPILE) 43#include <pthread.h> 44#endif 45 46/* Caller should hold the req_mutex if simultaneous accesses are possible */ 47int ldap_open_defconn( LDAP *ld ) 48{ 49 ld->ld_defconn = ldap_new_connection( ld, 50 &ld->ld_options.ldo_defludp, 1, 1, NULL, 0, 0 ); 51 52 if( ld->ld_defconn == NULL ) { 53 ld->ld_errno = LDAP_SERVER_DOWN; 54 return -1; 55 } 56 57 ++ld->ld_defconn->lconn_refcnt; /* so it never gets closed/freed */ 58 return 0; 59} 60 61/* 62 * ldap_open - initialize and connect to an ldap server. A magic cookie to 63 * be used for future communication is returned on success, NULL on failure. 64 * "host" may be a space-separated list of hosts or IP addresses 65 * 66 * Example: 67 * LDAP *ld; 68 * ld = ldap_open( hostname, port ); 69 */ 70 71LDAP * 72ldap_open( LDAP_CONST char *host, int port ) 73{ 74 int rc; 75 LDAP *ld; 76 77 Debug( LDAP_DEBUG_TRACE, "ldap_open(%s, %d)\n", 78 host, port, 0 ); 79 80 ld = ldap_init( host, port ); 81 if ( ld == NULL ) { 82 return( NULL ); 83 } 84 85 LDAP_MUTEX_LOCK( &ld->ld_conn_mutex ); 86 rc = ldap_open_defconn( ld ); 87 LDAP_MUTEX_UNLOCK( &ld->ld_conn_mutex ); 88 89 if( rc < 0 ) { 90 ldap_ld_free( ld, 0, NULL, NULL ); 91 ld = NULL; 92 } 93 94 Debug( LDAP_DEBUG_TRACE, "ldap_open: %s\n", 95 ld != NULL ? "succeeded" : "failed", 0, 0 ); 96 97 return ld; 98} 99 100int 101ldap_create( LDAP **ldp ) 102{ 103 LDAP *ld; 104 struct ldapoptions *gopts; 105 106#if defined(__APPLE__) && defined(LDAP_R_COMPILE) 107 /* Init the global options in a nice thread-safe manner. */ 108 dispatch_once_f(&ldap_global_opts_initialized, NULL, ldap_int_init_global_opts); 109#endif 110 111 *ldp = NULL; 112 /* Get pointer to global option structure */ 113 if ( (gopts = LDAP_INT_GLOBAL_OPT()) == NULL) { 114 return LDAP_NO_MEMORY; 115 } 116 117#if defined(__APPLE__) && defined(LDAP_R_COMPILE) 118 /* Global options should have been initialized by pthread_once() */ 119 if( gopts->ldo_valid != LDAP_INITIALIZED ) { 120 return LDAP_LOCAL_ERROR; 121 } 122#else 123 /* Initialize the global options, if not already done. */ 124 if( gopts->ldo_valid != LDAP_INITIALIZED ) { 125 ldap_int_initialize(gopts, NULL); 126 if ( gopts->ldo_valid != LDAP_INITIALIZED ) 127 return LDAP_LOCAL_ERROR; 128 } 129#endif 130 131 Debug( LDAP_DEBUG_TRACE, "ldap_create\n", 0, 0, 0 ); 132 133 if ( (ld = (LDAP *) LDAP_CALLOC( 1, sizeof(LDAP) )) == NULL ) { 134 return( LDAP_NO_MEMORY ); 135 } 136 137 if ( (ld->ldc = (struct ldap_common *) LDAP_CALLOC( 1, 138 sizeof(struct ldap_common) )) == NULL ) { 139 LDAP_FREE( (char *)ld ); 140 return( LDAP_NO_MEMORY ); 141 } 142 /* copy the global options */ 143 LDAP_MUTEX_LOCK( &gopts->ldo_mutex ); 144 AC_MEMCPY(&ld->ld_options, gopts, sizeof(ld->ld_options)); 145#ifdef LDAP_R_COMPILE 146 /* Properly initialize the structs mutex */ 147 ldap_pvt_thread_mutex_init( &(ld->ld_ldopts_mutex) ); 148#endif 149 LDAP_MUTEX_UNLOCK( &gopts->ldo_mutex ); 150 151 ld->ld_valid = LDAP_VALID_SESSION; 152 153 /* but not pointers to malloc'ed items */ 154 ld->ld_options.ldo_sctrls = NULL; 155 ld->ld_options.ldo_cctrls = NULL; 156 ld->ld_options.ldo_defludp = NULL; 157 ld->ld_options.ldo_conn_cbs = NULL; 158 159 ld->ld_options.ldo_noaddr_option = 0; 160 ld->ld_options.ldo_sasl_fqdn = NULL; 161 162#ifdef HAVE_CYRUS_SASL 163 ld->ld_options.ldo_def_sasl_mech = gopts->ldo_def_sasl_mech 164 ? LDAP_STRDUP( gopts->ldo_def_sasl_mech ) : NULL; 165 ld->ld_options.ldo_def_sasl_realm = gopts->ldo_def_sasl_realm 166 ? LDAP_STRDUP( gopts->ldo_def_sasl_realm ) : NULL; 167 ld->ld_options.ldo_def_sasl_authcid = gopts->ldo_def_sasl_authcid 168 ? LDAP_STRDUP( gopts->ldo_def_sasl_authcid ) : NULL; 169 ld->ld_options.ldo_def_sasl_authzid = gopts->ldo_def_sasl_authzid 170 ? LDAP_STRDUP( gopts->ldo_def_sasl_authzid ) : NULL; 171#endif 172 173#ifdef HAVE_TLS 174 /* We explicitly inherit the SSL_CTX, don't need the names/paths. Leave 175 * them empty to allow new SSL_CTX's to be created from scratch. 176 */ 177 memset( &ld->ld_options.ldo_tls_info, 0, 178 sizeof( ld->ld_options.ldo_tls_info )); 179 ld->ld_options.ldo_tls_ctx = NULL; 180#endif 181 182 if ( gopts->ldo_defludp ) { 183 ld->ld_options.ldo_defludp = ldap_url_duplist(gopts->ldo_defludp); 184 185 if ( ld->ld_options.ldo_defludp == NULL ) goto nomem; 186 } 187 188 if (( ld->ld_selectinfo = ldap_new_select_info()) == NULL ) goto nomem; 189 190 ld->ld_lberoptions = LBER_USE_DER; 191 192 ld->ld_sb = ber_sockbuf_alloc( ); 193 if ( ld->ld_sb == NULL ) goto nomem; 194 195#ifdef LDAP_RESPONSE_RB_TREE 196 ldap_resp_rbt_create( ld ); 197 if ( ld->ld_rbt_responses == NULL ) { 198 goto nomem; 199 } 200#endif 201 202#ifdef LDAP_R_COMPILE 203 ldap_pvt_thread_mutex_init( &ld->ld_msgid_mutex ); 204 ldap_pvt_thread_mutex_init( &ld->ld_conn_mutex ); 205 ldap_pvt_thread_mutex_init( &ld->ld_req_mutex ); 206 ldap_pvt_thread_mutex_init( &ld->ld_res_mutex ); 207 ldap_pvt_thread_mutex_init( &ld->ld_abandon_mutex ); 208 ldap_pvt_thread_mutex_init( &ld->ld_ldcmutex ); 209#endif 210 ld->ld_ldcrefcnt = 1; 211 *ldp = ld; 212 return LDAP_SUCCESS; 213 214nomem: 215 ldap_free_select_info( ld->ld_selectinfo ); 216 ldap_free_urllist( ld->ld_options.ldo_defludp ); 217#ifdef HAVE_CYRUS_SASL 218 LDAP_FREE( ld->ld_options.ldo_def_sasl_authzid ); 219 LDAP_FREE( ld->ld_options.ldo_def_sasl_authcid ); 220 LDAP_FREE( ld->ld_options.ldo_def_sasl_realm ); 221 LDAP_FREE( ld->ld_options.ldo_def_sasl_mech ); 222#endif 223 LDAP_FREE( (char *)ld ); 224 return LDAP_NO_MEMORY; 225} 226 227/* 228 * ldap_init - initialize the LDAP library. A magic cookie to be used for 229 * future communication is returned on success, NULL on failure. 230 * "host" may be a space-separated list of hosts or IP addresses 231 * 232 * Example: 233 * LDAP *ld; 234 * ld = ldap_init( host, port ); 235 */ 236LDAP * 237ldap_init( LDAP_CONST char *defhost, int defport ) 238{ 239 LDAP *ld; 240 int rc; 241 242 rc = ldap_create(&ld); 243 if ( rc != LDAP_SUCCESS ) 244 return NULL; 245 246 if (defport != 0) 247 ld->ld_options.ldo_defport = defport; 248 249 if (defhost != NULL) { 250 rc = ldap_set_option(ld, LDAP_OPT_HOST_NAME, defhost); 251 if ( rc != LDAP_SUCCESS ) { 252 ldap_ld_free(ld, 1, NULL, NULL); 253 return NULL; 254 } 255 } 256 257 return( ld ); 258} 259 260 261int 262ldap_initialize( LDAP **ldp, LDAP_CONST char *url ) 263{ 264 int rc; 265 LDAP *ld; 266 267 *ldp = NULL; 268 rc = ldap_create(&ld); 269 if ( rc != LDAP_SUCCESS ) 270 return rc; 271 272 if (url != NULL) { 273 rc = ldap_set_option(ld, LDAP_OPT_URI, url); 274 if ( rc != LDAP_SUCCESS ) { 275 ldap_ld_free(ld, 1, NULL, NULL); 276 return rc; 277 } 278#ifdef LDAP_CONNECTIONLESS 279 if (ldap_is_ldapc_url(url)) 280 LDAP_IS_UDP(ld) = 1; 281#endif 282 } 283 284 *ldp = ld; 285 return LDAP_SUCCESS; 286} 287 288int 289ldap_init_fd( 290 ber_socket_t fd, 291 int proto, 292 LDAP_CONST char *url, 293 LDAP **ldp 294) 295{ 296 int rc; 297 LDAP *ld; 298 LDAPConn *conn; 299 300 *ldp = NULL; 301 rc = ldap_create( &ld ); 302 if( rc != LDAP_SUCCESS ) 303 return( rc ); 304 305 if (url != NULL) { 306 rc = ldap_set_option(ld, LDAP_OPT_URI, url); 307 if ( rc != LDAP_SUCCESS ) { 308 ldap_ld_free(ld, 1, NULL, NULL); 309 return rc; 310 } 311 } 312 313 LDAP_MUTEX_LOCK( &ld->ld_conn_mutex ); 314 /* Attach the passed socket as the LDAP's connection */ 315 conn = ldap_new_connection( ld, NULL, 1, 0, NULL, 0, 0 ); 316 if( conn == NULL ) { 317 ldap_unbind_ext( ld, NULL, NULL ); 318 return( LDAP_NO_MEMORY ); 319 } 320 if( url ) 321 conn->lconn_server = ldap_url_dup( ld->ld_options.ldo_defludp ); 322 ber_sockbuf_ctrl( conn->lconn_sb, LBER_SB_OPT_SET_FD, &fd ); 323 ld->ld_defconn = conn; 324 ++ld->ld_defconn->lconn_refcnt; /* so it never gets closed/freed */ 325 LDAP_MUTEX_UNLOCK( &ld->ld_conn_mutex ); 326 327 switch( proto ) { 328 case LDAP_PROTO_TCP: 329#ifdef LDAP_DEBUG 330 ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_debug, 331 LBER_SBIOD_LEVEL_PROVIDER, (void *)"tcp_" ); 332#endif 333 ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_tcp, 334 LBER_SBIOD_LEVEL_PROVIDER, NULL ); 335 break; 336 337#ifdef LDAP_CONNECTIONLESS 338 case LDAP_PROTO_UDP: 339#ifdef LDAP_DEBUG 340 ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_debug, 341 LBER_SBIOD_LEVEL_PROVIDER, (void *)"udp_" ); 342#endif 343 ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_udp, 344 LBER_SBIOD_LEVEL_PROVIDER, NULL ); 345 ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_readahead, 346 LBER_SBIOD_LEVEL_PROVIDER, NULL ); 347 break; 348#endif /* LDAP_CONNECTIONLESS */ 349 350 case LDAP_PROTO_IPC: 351#ifdef LDAP_DEBUG 352 ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_debug, 353 LBER_SBIOD_LEVEL_PROVIDER, (void *)"ipc_" ); 354#endif 355 ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_fd, 356 LBER_SBIOD_LEVEL_PROVIDER, NULL ); 357 break; 358 359 case LDAP_PROTO_EXT: 360 /* caller must supply sockbuf handlers */ 361 break; 362 363 default: 364 ldap_unbind_ext( ld, NULL, NULL ); 365 return LDAP_PARAM_ERROR; 366 } 367 368#ifdef LDAP_DEBUG 369 ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_debug, 370 INT_MAX, (void *)"ldap_" ); 371#endif 372 373 /* Add the connection to the *LDAP's select pool */ 374 ldap_mark_select_read( ld, conn->lconn_sb ); 375 ldap_mark_select_write( ld, conn->lconn_sb ); 376 377 *ldp = ld; 378 return LDAP_SUCCESS; 379} 380 381/* Protected by ld_conn_mutex */ 382int 383ldap_int_open_connection( 384 LDAP *ld, 385 LDAPConn *conn, 386 LDAPURLDesc *srv, 387 int async ) 388{ 389 int rc = -1; 390 int proto; 391 392 Debug( LDAP_DEBUG_TRACE, "ldap_int_open_connection\n", 0, 0, 0 ); 393 394 switch ( proto = ldap_pvt_url_scheme2proto( srv->lud_scheme ) ) { 395 case LDAP_PROTO_TCP: 396 rc = ldap_connect_to_host( ld, conn->lconn_sb, 397 proto, srv, async ); 398 399 if ( rc == -1 ) return rc; 400#ifdef LDAP_DEBUG 401 ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_debug, 402 LBER_SBIOD_LEVEL_PROVIDER, (void *)"tcp_" ); 403#endif 404 ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_tcp, 405 LBER_SBIOD_LEVEL_PROVIDER, NULL ); 406 407 break; 408 409#ifdef LDAP_CONNECTIONLESS 410 case LDAP_PROTO_UDP: 411 LDAP_IS_UDP(ld) = 1; 412 rc = ldap_connect_to_host( ld, conn->lconn_sb, 413 proto, srv, async ); 414 415 if ( rc == -1 ) return rc; 416#ifdef LDAP_DEBUG 417 ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_debug, 418 LBER_SBIOD_LEVEL_PROVIDER, (void *)"udp_" ); 419#endif 420 ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_udp, 421 LBER_SBIOD_LEVEL_PROVIDER, NULL ); 422 423 ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_readahead, 424 LBER_SBIOD_LEVEL_PROVIDER, NULL ); 425 426 break; 427#endif 428 case LDAP_PROTO_IPC: 429#ifdef LDAP_PF_LOCAL 430 /* only IPC mechanism supported is PF_LOCAL (PF_UNIX) */ 431 rc = ldap_connect_to_path( ld, conn->lconn_sb, 432 srv, async ); 433 if ( rc == -1 ) return rc; 434#ifdef LDAP_DEBUG 435 ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_debug, 436 LBER_SBIOD_LEVEL_PROVIDER, (void *)"ipc_" ); 437#endif 438 ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_fd, 439 LBER_SBIOD_LEVEL_PROVIDER, NULL ); 440 441 break; 442#endif /* LDAP_PF_LOCAL */ 443 default: 444 return -1; 445 break; 446 } 447 448 conn->lconn_created = time( NULL ); 449 450#ifdef LDAP_DEBUG 451 ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_debug, 452 INT_MAX, (void *)"ldap_" ); 453#endif 454 455#ifdef LDAP_CONNECTIONLESS 456 if( proto == LDAP_PROTO_UDP ) return 0; 457#endif 458 459#ifdef HAVE_TLS 460 if (rc == 0 && ( ld->ld_options.ldo_tls_mode == LDAP_OPT_X_TLS_HARD || 461 strcmp( srv->lud_scheme, "ldaps" ) == 0 )) 462 { 463 ++conn->lconn_refcnt; /* avoid premature free */ 464 465 rc = ldap_int_tls_start( ld, conn, srv ); 466 467 --conn->lconn_refcnt; 468 469 if (rc != LDAP_SUCCESS) { 470 return -1; 471 } 472 } 473#endif 474 475 return( 0 ); 476} 477 478/* 479 * ldap_open_internal_connection - open connection and set file descriptor 480 * 481 * note: ldap_init_fd() may be preferable 482 */ 483 484int 485ldap_open_internal_connection( LDAP **ldp, ber_socket_t *fdp ) 486{ 487 int rc; 488 LDAPConn *c; 489 LDAPRequest *lr; 490 LDAP *ld; 491 492 rc = ldap_create( &ld ); 493 if( rc != LDAP_SUCCESS ) { 494 *ldp = NULL; 495 return( rc ); 496 } 497 498 /* Make it appear that a search request, msgid 0, was sent */ 499 lr = (LDAPRequest *)LDAP_CALLOC( 1, sizeof( LDAPRequest )); 500 if( lr == NULL ) { 501 ldap_unbind_ext( ld, NULL, NULL ); 502 *ldp = NULL; 503 return( LDAP_NO_MEMORY ); 504 } 505 memset(lr, 0, sizeof( LDAPRequest )); 506 lr->lr_msgid = 0; 507 lr->lr_status = LDAP_REQST_INPROGRESS; 508 lr->lr_res_errno = LDAP_SUCCESS; 509 /* no mutex lock needed, we just created this ld here */ 510 ld->ld_requests = lr; 511 512 LDAP_MUTEX_LOCK( &ld->ld_conn_mutex ); 513 /* Attach the passed socket as the *LDAP's connection */ 514 c = ldap_new_connection( ld, NULL, 1, 0, NULL, 0, 0 ); 515 if( c == NULL ) { 516 ldap_unbind_ext( ld, NULL, NULL ); 517 *ldp = NULL; 518 LDAP_MUTEX_UNLOCK( &ld->ld_conn_mutex ); 519 return( LDAP_NO_MEMORY ); 520 } 521 ber_sockbuf_ctrl( c->lconn_sb, LBER_SB_OPT_SET_FD, fdp ); 522#ifdef LDAP_DEBUG 523 ber_sockbuf_add_io( c->lconn_sb, &ber_sockbuf_io_debug, 524 LBER_SBIOD_LEVEL_PROVIDER, (void *)"int_" ); 525#endif 526 ber_sockbuf_add_io( c->lconn_sb, &ber_sockbuf_io_tcp, 527 LBER_SBIOD_LEVEL_PROVIDER, NULL ); 528 ld->ld_defconn = c; 529 LDAP_MUTEX_UNLOCK( &ld->ld_conn_mutex ); 530 531 /* Add the connection to the *LDAP's select pool */ 532 ldap_mark_select_read( ld, c->lconn_sb ); 533 ldap_mark_select_write( ld, c->lconn_sb ); 534 535 /* Make this connection an LDAP V3 protocol connection */ 536 rc = LDAP_VERSION3; 537 ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &rc ); 538 *ldp = ld; 539 540 ++ld->ld_defconn->lconn_refcnt; /* so it never gets closed/freed */ 541 542 return( LDAP_SUCCESS ); 543} 544 545LDAP * 546ldap_dup( LDAP *old ) 547{ 548 LDAP *ld; 549 550 if ( old == NULL ) { 551 return( NULL ); 552 } 553 554 Debug( LDAP_DEBUG_TRACE, "ldap_dup\n", 0, 0, 0 ); 555 556 if ( (ld = (LDAP *) LDAP_CALLOC( 1, sizeof(LDAP) )) == NULL ) { 557 return( NULL ); 558 } 559 560 LDAP_MUTEX_LOCK( &old->ld_ldcmutex ); 561 ld->ldc = old->ldc; 562 old->ld_ldcrefcnt++; 563 LDAP_MUTEX_UNLOCK( &old->ld_ldcmutex ); 564 return ( ld ); 565} 566 567int 568ldap_int_check_async_open( LDAP *ld, ber_socket_t sd ) 569{ 570 struct timeval tv = { 0 }; 571 int rc; 572 573 rc = ldap_int_poll( ld, sd, &tv ); 574 switch ( rc ) { 575 case 0: 576 /* now ready to start tls */ 577 ld->ld_defconn->lconn_status = LDAP_CONNST_CONNECTED; 578 break; 579 580 default: 581 ld->ld_errno = LDAP_CONNECT_ERROR; 582 return -1; 583 584 case -2: 585 /* connect not completed yet */ 586 ld->ld_errno = LDAP_X_CONNECTING; 587 return rc; 588 } 589 590#ifdef HAVE_TLS 591 if ( ld->ld_options.ldo_tls_mode == LDAP_OPT_X_TLS_HARD || 592 !strcmp( ld->ld_defconn->lconn_server->lud_scheme, "ldaps" )) { 593 594 ++ld->ld_defconn->lconn_refcnt; /* avoid premature free */ 595 596 rc = ldap_int_tls_start( ld, ld->ld_defconn, ld->ld_defconn->lconn_server ); 597 598 --ld->ld_defconn->lconn_refcnt; 599 } 600#endif 601 return rc; 602} 603