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