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