1 /* $OpenLDAP: pkg/ldap/libraries/libldap/open.c,v 1.110.2.7 2008/02/11 23:56:32 quanah Exp $ */
2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4 * Copyright 1998-2008 The OpenLDAP Foundation.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted only as authorized by the OpenLDAP
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>.
15 /* Portions Copyright (c) 1995 Regents of the University of Michigan.
16 * All rights reserved.
26 #include <ac/stdlib.h>
29 #include <ac/socket.h>
30 #include <ac/string.h>
33 #include <ac/unistd.h>
38 /* Caller should hold the req_mutex if simultaneous accesses are possible */
39 int ldap_open_defconn( LDAP
*ld
)
41 ld
->ld_defconn
= ldap_new_connection( ld
,
42 &ld
->ld_options
.ldo_defludp
, 1, 1, NULL
);
44 if( ld
->ld_defconn
== NULL
) {
45 ld
->ld_errno
= LDAP_SERVER_DOWN
;
49 ++ld
->ld_defconn
->lconn_refcnt
; /* so it never gets closed/freed */
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
60 * ld = ldap_open( hostname, port );
64 ldap_open( LDAP_CONST
char *host
, int port
)
69 Debug( LDAP_DEBUG_TRACE
, "ldap_open(%s, %d)\n",
72 ld
= ldap_init( host
, port
);
77 rc
= ldap_open_defconn( ld
);
80 ldap_ld_free( ld
, 0, NULL
, NULL
);
84 Debug( LDAP_DEBUG_TRACE
, "ldap_open: %s\n",
85 ld
!= NULL
? "succeeded" : "failed", 0, 0 );
93 ldap_create( LDAP
**ldp
)
96 struct ldapoptions
*gopts
;
99 /* Get pointer to global option structure */
100 if ( (gopts
= LDAP_INT_GLOBAL_OPT()) == NULL
) {
101 return LDAP_NO_MEMORY
;
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
;
111 Debug( LDAP_DEBUG_TRACE
, "ldap_create\n", 0, 0, 0 );
113 if ( (ld
= (LDAP
*) LDAP_CALLOC( 1, sizeof(LDAP
) )) == NULL
) {
114 return( LDAP_NO_MEMORY
);
117 /* copy the global options */
118 AC_MEMCPY(&ld
->ld_options
, gopts
, sizeof(ld
->ld_options
));
120 ld
->ld_valid
= LDAP_VALID_SESSION
;
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
;
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
;
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.
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
;
147 if ( gopts
->ldo_defludp
) {
148 ld
->ld_options
.ldo_defludp
= ldap_url_duplist(gopts
->ldo_defludp
);
150 if ( ld
->ld_options
.ldo_defludp
== NULL
) goto nomem
;
153 if (( ld
->ld_selectinfo
= ldap_new_select_info()) == NULL
) goto nomem
;
155 ld
->ld_lberoptions
= LBER_USE_DER
;
157 ld
->ld_sb
= ber_sockbuf_alloc( );
158 if ( ld
->ld_sb
== NULL
) goto nomem
;
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
);
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
);
177 LDAP_FREE( (char *)ld
);
178 return LDAP_NO_MEMORY
;
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
188 * ld = ldap_init( host, port );
191 ldap_init( LDAP_CONST
char *defhost
, int defport
)
196 rc
= ldap_create(&ld
);
197 if ( rc
!= LDAP_SUCCESS
)
201 ld
->ld_options
.ldo_defport
= defport
;
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
);
216 ldap_initialize( LDAP
**ldp
, LDAP_CONST
char *url
)
222 rc
= ldap_create(&ld
);
223 if ( rc
!= LDAP_SUCCESS
)
227 rc
= ldap_set_option(ld
, LDAP_OPT_URI
, url
);
228 if ( rc
!= LDAP_SUCCESS
) {
229 ldap_ld_free(ld
, 1, NULL
, NULL
);
232 #ifdef LDAP_CONNECTIONLESS
233 if (ldap_is_ldapc_url(url
))
246 LDAP_CONST
char *url
,
255 rc
= ldap_create( &ld
);
256 if( rc
!= LDAP_SUCCESS
)
260 rc
= ldap_set_option(ld
, LDAP_OPT_URI
, url
);
261 if ( rc
!= LDAP_SUCCESS
) {
262 ldap_ld_free(ld
, 1, NULL
, NULL
);
267 /* Attach the passed socket as the LDAP's connection */
268 conn
= ldap_new_connection( ld
, NULL
, 1, 0, NULL
);
270 ldap_unbind_ext( ld
, NULL
, NULL
);
271 return( LDAP_NO_MEMORY
);
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 */
280 ber_sockbuf_add_io( conn
->lconn_sb
, &ber_sockbuf_io_debug
,
281 LBER_SBIOD_LEVEL_PROVIDER
, (void *)"tcp_" );
283 ber_sockbuf_add_io( conn
->lconn_sb
, &ber_sockbuf_io_tcp
,
284 LBER_SBIOD_LEVEL_PROVIDER
, NULL
);
287 #ifdef LDAP_CONNECTIONLESS
290 ber_sockbuf_add_io( conn
->lconn_sb
, &ber_sockbuf_io_debug
,
291 LBER_SBIOD_LEVEL_PROVIDER
, (void *)"udp_" );
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
);
298 #endif /* LDAP_CONNECTIONLESS */
302 ber_sockbuf_add_io( conn
->lconn_sb
, &ber_sockbuf_io_debug
,
303 LBER_SBIOD_LEVEL_PROVIDER
, (void *)"ipc_" );
305 ber_sockbuf_add_io( conn
->lconn_sb
, &ber_sockbuf_io_fd
,
306 LBER_SBIOD_LEVEL_PROVIDER
, NULL
);
310 /* caller must supply sockbuf handlers */
314 ldap_unbind_ext( ld
, NULL
, NULL
);
315 return LDAP_PARAM_ERROR
;
319 ber_sockbuf_add_io( conn
->lconn_sb
, &ber_sockbuf_io_debug
,
320 INT_MAX
, (void *)"ldap_" );
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
);
332 ldap_int_open_connection(
342 Debug( LDAP_DEBUG_TRACE
, "ldap_int_open_connection\n", 0, 0, 0 );
344 switch ( proto
= ldap_pvt_url_scheme2proto( srv
->lud_scheme
) ) {
346 port
= srv
->lud_port
;
348 if ( srv
->lud_host
== NULL
|| *srv
->lud_host
== 0 ) {
351 host
= srv
->lud_host
;
355 if( strcmp(srv
->lud_scheme
, "ldaps") == 0 ) {
362 rc
= ldap_connect_to_host( ld
, conn
->lconn_sb
,
363 proto
, host
, port
, async
);
365 if ( rc
== -1 ) return rc
;
368 ber_sockbuf_add_io( conn
->lconn_sb
, &ber_sockbuf_io_debug
,
369 LBER_SBIOD_LEVEL_PROVIDER
, (void *)"tcp_" );
371 ber_sockbuf_add_io( conn
->lconn_sb
, &ber_sockbuf_io_tcp
,
372 LBER_SBIOD_LEVEL_PROVIDER
, NULL
);
376 #ifdef LDAP_CONNECTIONLESS
378 port
= srv
->lud_port
;
380 if ( srv
->lud_host
== NULL
|| *srv
->lud_host
== 0 ) {
383 host
= srv
->lud_host
;
386 if( !port
) port
= LDAP_PORT
;
389 rc
= ldap_connect_to_host( ld
, conn
->lconn_sb
,
390 proto
, host
, port
, async
);
392 if ( rc
== -1 ) return rc
;
394 ber_sockbuf_add_io( conn
->lconn_sb
, &ber_sockbuf_io_debug
,
395 LBER_SBIOD_LEVEL_PROVIDER
, (void *)"udp_" );
397 ber_sockbuf_add_io( conn
->lconn_sb
, &ber_sockbuf_io_udp
,
398 LBER_SBIOD_LEVEL_PROVIDER
, NULL
);
400 ber_sockbuf_add_io( conn
->lconn_sb
, &ber_sockbuf_io_readahead
,
401 LBER_SBIOD_LEVEL_PROVIDER
, NULL
);
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
;
412 ber_sockbuf_add_io( conn
->lconn_sb
, &ber_sockbuf_io_debug
,
413 LBER_SBIOD_LEVEL_PROVIDER
, (void *)"ipc_" );
415 ber_sockbuf_add_io( conn
->lconn_sb
, &ber_sockbuf_io_fd
,
416 LBER_SBIOD_LEVEL_PROVIDER
, NULL
);
419 #endif /* LDAP_PF_LOCAL */
425 conn
->lconn_created
= time( NULL
);
428 ber_sockbuf_add_io( conn
->lconn_sb
, &ber_sockbuf_io_debug
,
429 INT_MAX
, (void *)"ldap_" );
432 #ifdef LDAP_CONNECTIONLESS
433 if( proto
== LDAP_PROTO_UDP
) return 0;
437 if (ld
->ld_options
.ldo_tls_mode
== LDAP_OPT_X_TLS_HARD
||
438 strcmp( srv
->lud_scheme
, "ldaps" ) == 0 )
440 ++conn
->lconn_refcnt
; /* avoid premature free */
442 rc
= ldap_int_tls_start( ld
, conn
, srv
);
444 --conn
->lconn_refcnt
;
446 if (rc
!= LDAP_SUCCESS
) {
457 ldap_open_internal_connection( LDAP
**ldp
, ber_socket_t
*fdp
)
463 rc
= ldap_create( ldp
);
464 if( rc
!= LDAP_SUCCESS
) {
469 /* Make it appear that a search request, msgid 0, was sent */
470 lr
= (LDAPRequest
*)LDAP_CALLOC( 1, sizeof( LDAPRequest
));
472 ldap_unbind_ext( *ldp
, NULL
, NULL
);
474 return( LDAP_NO_MEMORY
);
476 memset(lr
, 0, sizeof( LDAPRequest
));
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
;
483 /* Attach the passed socket as the *LDAP's connection */
484 c
= ldap_new_connection( *ldp
, NULL
, 1, 0, NULL
);
486 ldap_unbind_ext( *ldp
, NULL
, NULL
);
488 return( LDAP_NO_MEMORY
);
490 ber_sockbuf_ctrl( c
->lconn_sb
, LBER_SB_OPT_SET_FD
, fdp
);
492 ber_sockbuf_add_io( c
->lconn_sb
, &ber_sockbuf_io_debug
,
493 LBER_SBIOD_LEVEL_PROVIDER
, (void *)"int_" );
495 ber_sockbuf_add_io( c
->lconn_sb
, &ber_sockbuf_io_tcp
,
496 LBER_SBIOD_LEVEL_PROVIDER
, NULL
);
497 (*ldp
)->ld_defconn
= c
;
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
);
503 /* Make this connection an LDAP V3 protocol connection */
505 ldap_set_option( *ldp
, LDAP_OPT_PROTOCOL_VERSION
, &rc
);
507 return( LDAP_SUCCESS
);