Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/libs/ldap/libldap/open.c
4394 views
1
/* $OpenLDAP$ */
2
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
3
*
4
* Copyright 1998-2024 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 */
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
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 *
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
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 *
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
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
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
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
if ( async && rc == -2) {
505
/* Need to let the connect complete asynchronously before we continue */
506
return -2;
507
}
508
509
#ifdef HAVE_TLS
510
if ((rc == 0 || rc == -2) && ( ld->ld_options.ldo_tls_mode == LDAP_OPT_X_TLS_HARD ||
511
strcmp( srv->lud_scheme, "ldaps" ) == 0 ))
512
{
513
++conn->lconn_refcnt; /* avoid premature free */
514
515
rc = ldap_int_tls_start( ld, conn, srv );
516
517
--conn->lconn_refcnt;
518
519
if (rc != LDAP_SUCCESS) {
520
/* process connection callbacks */
521
{
522
struct ldapoptions *lo;
523
ldaplist *ll;
524
ldap_conncb *cb;
525
526
lo = &ld->ld_options;
527
LDAP_MUTEX_LOCK( &lo->ldo_mutex );
528
if ( lo->ldo_conn_cbs ) {
529
for ( ll=lo->ldo_conn_cbs; ll; ll=ll->ll_next ) {
530
cb = ll->ll_data;
531
cb->lc_del( ld, conn->lconn_sb, cb );
532
}
533
}
534
LDAP_MUTEX_UNLOCK( &lo->ldo_mutex );
535
lo = LDAP_INT_GLOBAL_OPT();
536
LDAP_MUTEX_LOCK( &lo->ldo_mutex );
537
if ( lo->ldo_conn_cbs ) {
538
for ( ll=lo->ldo_conn_cbs; ll; ll=ll->ll_next ) {
539
cb = ll->ll_data;
540
cb->lc_del( ld, conn->lconn_sb, cb );
541
}
542
}
543
LDAP_MUTEX_UNLOCK( &lo->ldo_mutex );
544
}
545
ber_int_sb_close( conn->lconn_sb );
546
ber_int_sb_destroy( conn->lconn_sb );
547
return -1;
548
}
549
}
550
#endif
551
552
return( 0 );
553
}
554
555
/*
556
* ldap_open_internal_connection - open connection and set file descriptor
557
*
558
* note: ldap_init_fd() may be preferable
559
*/
560
561
int
562
ldap_open_internal_connection( LDAP **ldp, ber_socket_t *fdp )
563
{
564
int rc;
565
LDAPConn *c;
566
LDAPRequest *lr;
567
LDAP *ld;
568
569
rc = ldap_create( &ld );
570
if( rc != LDAP_SUCCESS ) {
571
*ldp = NULL;
572
return( rc );
573
}
574
575
/* Make it appear that a search request, msgid 0, was sent */
576
lr = (LDAPRequest *)LDAP_CALLOC( 1, sizeof( LDAPRequest ));
577
if( lr == NULL ) {
578
ldap_unbind_ext( ld, NULL, NULL );
579
*ldp = NULL;
580
return( LDAP_NO_MEMORY );
581
}
582
memset(lr, 0, sizeof( LDAPRequest ));
583
lr->lr_msgid = 0;
584
lr->lr_status = LDAP_REQST_INPROGRESS;
585
lr->lr_res_errno = LDAP_SUCCESS;
586
/* no mutex lock needed, we just created this ld here */
587
rc = ldap_tavl_insert( &ld->ld_requests, lr, ldap_req_cmp, ldap_avl_dup_error );
588
assert( rc == LDAP_SUCCESS );
589
590
LDAP_MUTEX_LOCK( &ld->ld_conn_mutex );
591
/* Attach the passed socket as the *LDAP's connection */
592
c = ldap_new_connection( ld, NULL, 1, 0, NULL, 0, 0 );
593
if( c == NULL ) {
594
LDAP_MUTEX_UNLOCK( &ld->ld_conn_mutex );
595
ldap_unbind_ext( ld, NULL, NULL );
596
*ldp = NULL;
597
return( LDAP_NO_MEMORY );
598
}
599
ber_sockbuf_ctrl( c->lconn_sb, LBER_SB_OPT_SET_FD, fdp );
600
#ifdef LDAP_DEBUG
601
ber_sockbuf_add_io( c->lconn_sb, &ber_sockbuf_io_debug,
602
LBER_SBIOD_LEVEL_PROVIDER, (void *)"int_" );
603
#endif
604
ber_sockbuf_add_io( c->lconn_sb, &ber_sockbuf_io_tcp,
605
LBER_SBIOD_LEVEL_PROVIDER, NULL );
606
ld->ld_defconn = c;
607
LDAP_MUTEX_UNLOCK( &ld->ld_conn_mutex );
608
609
/* Add the connection to the *LDAP's select pool */
610
ldap_mark_select_read( ld, c->lconn_sb );
611
612
/* Make this connection an LDAP V3 protocol connection */
613
rc = LDAP_VERSION3;
614
ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &rc );
615
*ldp = ld;
616
617
++ld->ld_defconn->lconn_refcnt; /* so it never gets closed/freed */
618
619
return( LDAP_SUCCESS );
620
}
621
622
LDAP *
623
ldap_dup( LDAP *old )
624
{
625
LDAP *ld;
626
627
if ( old == NULL ) {
628
return( NULL );
629
}
630
631
Debug0( LDAP_DEBUG_TRACE, "ldap_dup\n" );
632
633
if ( (ld = (LDAP *) LDAP_CALLOC( 1, sizeof(LDAP) )) == NULL ) {
634
return( NULL );
635
}
636
637
LDAP_MUTEX_LOCK( &old->ld_ldcmutex );
638
ld->ldc = old->ldc;
639
old->ld_ldcrefcnt++;
640
LDAP_MUTEX_UNLOCK( &old->ld_ldcmutex );
641
return ( ld );
642
}
643
644
int
645
ldap_int_check_async_open( LDAP *ld, ber_socket_t sd )
646
{
647
struct timeval tv = { 0 };
648
int rc;
649
650
rc = ldap_int_poll( ld, sd, &tv, 1 );
651
switch ( rc ) {
652
case 0:
653
/* now ready to start tls */
654
ld->ld_defconn->lconn_status = LDAP_CONNST_CONNECTED;
655
break;
656
657
default:
658
ld->ld_errno = LDAP_CONNECT_ERROR;
659
return -1;
660
661
case -2:
662
/* connect not completed yet */
663
ld->ld_errno = LDAP_X_CONNECTING;
664
return rc;
665
}
666
667
#ifdef HAVE_TLS
668
if ( ld->ld_options.ldo_tls_mode == LDAP_OPT_X_TLS_HARD ||
669
!strcmp( ld->ld_defconn->lconn_server->lud_scheme, "ldaps" )) {
670
671
++ld->ld_defconn->lconn_refcnt; /* avoid premature free */
672
673
rc = ldap_int_tls_start( ld, ld->ld_defconn, ld->ld_defconn->lconn_server );
674
675
--ld->ld_defconn->lconn_refcnt;
676
}
677
#endif
678
return rc;
679
}
680
681