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