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