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