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