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