]> git.sur5r.net Git - openldap/blob - libraries/libldap/open.c
ITS#6625,ITS#5421
[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 int
452 ldap_open_internal_connection( LDAP **ldp, ber_socket_t *fdp )
453 {
454         int rc;
455         LDAPConn *c;
456         LDAPRequest *lr;
457         LDAP    *ld;
458
459         rc = ldap_create( &ld );
460         if( rc != LDAP_SUCCESS ) {
461                 *ldp = NULL;
462                 return( rc );
463         }
464
465         /* Make it appear that a search request, msgid 0, was sent */
466         lr = (LDAPRequest *)LDAP_CALLOC( 1, sizeof( LDAPRequest ));
467         if( lr == NULL ) {
468                 ldap_unbind_ext( ld, NULL, NULL );
469                 *ldp = NULL;
470                 return( LDAP_NO_MEMORY );
471         }
472         memset(lr, 0, sizeof( LDAPRequest ));
473         lr->lr_msgid = 0;
474         lr->lr_status = LDAP_REQST_INPROGRESS;
475         lr->lr_res_errno = LDAP_SUCCESS;
476         /* no mutex lock needed, we just created this ld here */
477         ld->ld_requests = lr;
478
479         LDAP_MUTEX_LOCK( &ld->ld_conn_mutex );
480         /* Attach the passed socket as the *LDAP's connection */
481         c = ldap_new_connection( ld, NULL, 1, 0, NULL, 0, 0 );
482         if( c == NULL ) {
483                 ldap_unbind_ext( ld, NULL, NULL );
484                 *ldp = NULL;
485                 LDAP_MUTEX_UNLOCK( &ld->ld_conn_mutex );
486                 return( LDAP_NO_MEMORY );
487         }
488         ber_sockbuf_ctrl( c->lconn_sb, LBER_SB_OPT_SET_FD, fdp );
489 #ifdef LDAP_DEBUG
490         ber_sockbuf_add_io( c->lconn_sb, &ber_sockbuf_io_debug,
491                 LBER_SBIOD_LEVEL_PROVIDER, (void *)"int_" );
492 #endif
493         ber_sockbuf_add_io( c->lconn_sb, &ber_sockbuf_io_tcp,
494           LBER_SBIOD_LEVEL_PROVIDER, NULL );
495         ld->ld_defconn = c;
496         LDAP_MUTEX_UNLOCK( &ld->ld_conn_mutex );
497
498         /* Add the connection to the *LDAP's select pool */
499         ldap_mark_select_read( ld, c->lconn_sb );
500         ldap_mark_select_write( ld, c->lconn_sb );
501
502         /* Make this connection an LDAP V3 protocol connection */
503         rc = LDAP_VERSION3;
504         ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &rc );
505         *ldp = ld;
506
507         return( LDAP_SUCCESS );
508 }
509
510 LDAP *
511 ldap_dup( LDAP *old )
512 {
513         LDAP                    *ld;
514
515         if ( old == NULL ) {
516                 return( NULL );
517         }
518
519         Debug( LDAP_DEBUG_TRACE, "ldap_dup\n", 0, 0, 0 );
520
521         if ( (ld = (LDAP *) LDAP_CALLOC( 1, sizeof(LDAP) )) == NULL ) {
522                 return( NULL );
523         }
524    
525         LDAP_MUTEX_LOCK( &old->ld_ldcmutex );
526         ld->ldc = old->ldc;
527         old->ld_ldcrefcnt++;
528         LDAP_MUTEX_UNLOCK( &old->ld_ldcmutex );
529         return ( ld );
530 }