xref: /netbsd-src/external/bsd/openldap/dist/libraries/libldap/open.c (revision 946379e7b37692fc43f68eb0d1c10daa0a7f3b6c)
1 /*	$NetBSD: open.c,v 1.1.1.4 2014/05/28 09:58:41 tron Exp $	*/
2 
3 /* $OpenLDAP$ */
4 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5  *
6  * Copyright 1998-2014 The OpenLDAP Foundation.
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted only as authorized by the OpenLDAP
11  * Public License.
12  *
13  * A copy of this license is available in the file LICENSE in the
14  * top-level directory of the distribution or, alternatively, at
15  * <http://www.OpenLDAP.org/license.html>.
16  */
17 /* Portions Copyright (c) 1995 Regents of the University of Michigan.
18  * All rights reserved.
19  */
20 
21 #include "portable.h"
22 
23 #include <stdio.h>
24 #ifdef HAVE_LIMITS_H
25 #include <limits.h>
26 #endif
27 
28 #include <ac/stdlib.h>
29 
30 #include <ac/param.h>
31 #include <ac/socket.h>
32 #include <ac/string.h>
33 #include <ac/time.h>
34 
35 #include <ac/unistd.h>
36 
37 #include "ldap-int.h"
38 #include "ldap_log.h"
39 
40 /* Caller must hold the conn_mutex since simultaneous accesses are possible */
41 int ldap_open_defconn( LDAP *ld )
42 {
43 	ld->ld_defconn = ldap_new_connection( ld,
44 		&ld->ld_options.ldo_defludp, 1, 1, NULL, 0, 0 );
45 
46 	if( ld->ld_defconn == NULL ) {
47 		ld->ld_errno = LDAP_SERVER_DOWN;
48 		return -1;
49 	}
50 
51 	++ld->ld_defconn->lconn_refcnt;	/* so it never gets closed/freed */
52 	return 0;
53 }
54 
55 /*
56  * ldap_open - initialize and connect to an ldap server.  A magic cookie to
57  * be used for future communication is returned on success, NULL on failure.
58  * "host" may be a space-separated list of hosts or IP addresses
59  *
60  * Example:
61  *	LDAP	*ld;
62  *	ld = ldap_open( hostname, port );
63  */
64 
65 LDAP *
66 ldap_open( LDAP_CONST char *host, int port )
67 {
68 	int rc;
69 	LDAP		*ld;
70 
71 	Debug( LDAP_DEBUG_TRACE, "ldap_open(%s, %d)\n",
72 		host, port, 0 );
73 
74 	ld = ldap_init( host, port );
75 	if ( ld == NULL ) {
76 		return( NULL );
77 	}
78 
79 	LDAP_MUTEX_LOCK( &ld->ld_conn_mutex );
80 	rc = ldap_open_defconn( ld );
81 	LDAP_MUTEX_UNLOCK( &ld->ld_conn_mutex );
82 
83 	if( rc < 0 ) {
84 		ldap_ld_free( ld, 0, NULL, NULL );
85 		ld = NULL;
86 	}
87 
88 	Debug( LDAP_DEBUG_TRACE, "ldap_open: %s\n",
89 		ld != NULL ? "succeeded" : "failed", 0, 0 );
90 
91 	return ld;
92 }
93 
94 
95 
96 int
97 ldap_create( LDAP **ldp )
98 {
99 	LDAP			*ld;
100 	struct ldapoptions	*gopts;
101 
102 	*ldp = NULL;
103 	/* Get pointer to global option structure */
104 	if ( (gopts = LDAP_INT_GLOBAL_OPT()) == NULL) {
105 		return LDAP_NO_MEMORY;
106 	}
107 
108 	/* Initialize the global options, if not already done. */
109 	if( gopts->ldo_valid != LDAP_INITIALIZED ) {
110 		ldap_int_initialize(gopts, NULL);
111 		if ( gopts->ldo_valid != LDAP_INITIALIZED )
112 			return LDAP_LOCAL_ERROR;
113 	}
114 
115 	Debug( LDAP_DEBUG_TRACE, "ldap_create\n", 0, 0, 0 );
116 
117 	if ( (ld = (LDAP *) LDAP_CALLOC( 1, sizeof(LDAP) )) == NULL ) {
118 		return( LDAP_NO_MEMORY );
119 	}
120 
121 	if ( (ld->ldc = (struct ldap_common *) LDAP_CALLOC( 1,
122 			sizeof(struct ldap_common) )) == NULL ) {
123 		LDAP_FREE( (char *)ld );
124 		return( LDAP_NO_MEMORY );
125 	}
126 	/* copy the global options */
127 	LDAP_MUTEX_LOCK( &gopts->ldo_mutex );
128 	AC_MEMCPY(&ld->ld_options, gopts, sizeof(ld->ld_options));
129 #ifdef LDAP_R_COMPILE
130 	/* Properly initialize the structs mutex */
131 	ldap_pvt_thread_mutex_init( &(ld->ld_ldopts_mutex) );
132 #endif
133 	LDAP_MUTEX_UNLOCK( &gopts->ldo_mutex );
134 
135 	ld->ld_valid = LDAP_VALID_SESSION;
136 
137 	/* but not pointers to malloc'ed items */
138 	ld->ld_options.ldo_sctrls = NULL;
139 	ld->ld_options.ldo_cctrls = NULL;
140 	ld->ld_options.ldo_defludp = NULL;
141 	ld->ld_options.ldo_conn_cbs = NULL;
142 
143 #ifdef HAVE_CYRUS_SASL
144 	ld->ld_options.ldo_def_sasl_mech = gopts->ldo_def_sasl_mech
145 		? LDAP_STRDUP( gopts->ldo_def_sasl_mech ) : NULL;
146 	ld->ld_options.ldo_def_sasl_realm = gopts->ldo_def_sasl_realm
147 		? LDAP_STRDUP( gopts->ldo_def_sasl_realm ) : NULL;
148 	ld->ld_options.ldo_def_sasl_authcid = gopts->ldo_def_sasl_authcid
149 		? LDAP_STRDUP( gopts->ldo_def_sasl_authcid ) : NULL;
150 	ld->ld_options.ldo_def_sasl_authzid = gopts->ldo_def_sasl_authzid
151 		? LDAP_STRDUP( gopts->ldo_def_sasl_authzid ) : NULL;
152 #endif
153 
154 #ifdef HAVE_TLS
155 	/* We explicitly inherit the SSL_CTX, don't need the names/paths. Leave
156 	 * them empty to allow new SSL_CTX's to be created from scratch.
157 	 */
158 	memset( &ld->ld_options.ldo_tls_info, 0,
159 		sizeof( ld->ld_options.ldo_tls_info ));
160 	ld->ld_options.ldo_tls_ctx = NULL;
161 #endif
162 
163 	if ( gopts->ldo_defludp ) {
164 		ld->ld_options.ldo_defludp = ldap_url_duplist(gopts->ldo_defludp);
165 
166 		if ( ld->ld_options.ldo_defludp == NULL ) goto nomem;
167 	}
168 
169 	if (( ld->ld_selectinfo = ldap_new_select_info()) == NULL ) goto nomem;
170 
171 	ld->ld_lberoptions = LBER_USE_DER;
172 
173 	ld->ld_sb = ber_sockbuf_alloc( );
174 	if ( ld->ld_sb == NULL ) goto nomem;
175 
176 #ifdef LDAP_R_COMPILE
177 	ldap_pvt_thread_mutex_init( &ld->ld_msgid_mutex );
178 	ldap_pvt_thread_mutex_init( &ld->ld_conn_mutex );
179 	ldap_pvt_thread_mutex_init( &ld->ld_req_mutex );
180 	ldap_pvt_thread_mutex_init( &ld->ld_res_mutex );
181 	ldap_pvt_thread_mutex_init( &ld->ld_abandon_mutex );
182 	ldap_pvt_thread_mutex_init( &ld->ld_ldcmutex );
183 #endif
184 	ld->ld_ldcrefcnt = 1;
185 	*ldp = ld;
186 	return LDAP_SUCCESS;
187 
188 nomem:
189 	ldap_free_select_info( ld->ld_selectinfo );
190 	ldap_free_urllist( ld->ld_options.ldo_defludp );
191 #ifdef HAVE_CYRUS_SASL
192 	LDAP_FREE( ld->ld_options.ldo_def_sasl_authzid );
193 	LDAP_FREE( ld->ld_options.ldo_def_sasl_authcid );
194 	LDAP_FREE( ld->ld_options.ldo_def_sasl_realm );
195 	LDAP_FREE( ld->ld_options.ldo_def_sasl_mech );
196 #endif
197 	LDAP_FREE( (char *)ld );
198 	return LDAP_NO_MEMORY;
199 }
200 
201 /*
202  * ldap_init - initialize the LDAP library.  A magic cookie to be used for
203  * future communication is returned on success, NULL on failure.
204  * "host" may be a space-separated list of hosts or IP addresses
205  *
206  * Example:
207  *	LDAP	*ld;
208  *	ld = ldap_init( host, port );
209  */
210 LDAP *
211 ldap_init( LDAP_CONST char *defhost, int defport )
212 {
213 	LDAP *ld;
214 	int rc;
215 
216 	rc = ldap_create(&ld);
217 	if ( rc != LDAP_SUCCESS )
218 		return NULL;
219 
220 	if (defport != 0)
221 		ld->ld_options.ldo_defport = defport;
222 
223 	if (defhost != NULL) {
224 		rc = ldap_set_option(ld, LDAP_OPT_HOST_NAME, defhost);
225 		if ( rc != LDAP_SUCCESS ) {
226 			ldap_ld_free(ld, 1, NULL, NULL);
227 			return NULL;
228 		}
229 	}
230 
231 	return( ld );
232 }
233 
234 
235 int
236 ldap_initialize( LDAP **ldp, LDAP_CONST char *url )
237 {
238 	int rc;
239 	LDAP *ld;
240 
241 	*ldp = NULL;
242 	rc = ldap_create(&ld);
243 	if ( rc != LDAP_SUCCESS )
244 		return rc;
245 
246 	if (url != NULL) {
247 		rc = ldap_set_option(ld, LDAP_OPT_URI, url);
248 		if ( rc != LDAP_SUCCESS ) {
249 			ldap_ld_free(ld, 1, NULL, NULL);
250 			return rc;
251 		}
252 #ifdef LDAP_CONNECTIONLESS
253 		if (ldap_is_ldapc_url(url))
254 			LDAP_IS_UDP(ld) = 1;
255 #endif
256 	}
257 
258 	*ldp = ld;
259 	return LDAP_SUCCESS;
260 }
261 
262 int
263 ldap_init_fd(
264 	ber_socket_t fd,
265 	int proto,
266 	LDAP_CONST char *url,
267 	LDAP **ldp
268 )
269 {
270 	int rc;
271 	LDAP *ld;
272 	LDAPConn *conn;
273 #ifdef LDAP_CONNECTIONLESS
274 	ber_socklen_t	len;
275 #endif
276 
277 	*ldp = NULL;
278 	rc = ldap_create( &ld );
279 	if( rc != LDAP_SUCCESS )
280 		return( rc );
281 
282 	if (url != NULL) {
283 		rc = ldap_set_option(ld, LDAP_OPT_URI, url);
284 		if ( rc != LDAP_SUCCESS ) {
285 			ldap_ld_free(ld, 1, NULL, NULL);
286 			return rc;
287 		}
288 	}
289 
290 	LDAP_MUTEX_LOCK( &ld->ld_conn_mutex );
291 	/* Attach the passed socket as the LDAP's connection */
292 	conn = ldap_new_connection( ld, NULL, 1, 0, NULL, 0, 0 );
293 	if( conn == NULL ) {
294 		ldap_unbind_ext( ld, NULL, NULL );
295 		return( LDAP_NO_MEMORY );
296 	}
297 	if( url )
298 		conn->lconn_server = ldap_url_dup( ld->ld_options.ldo_defludp );
299 	ber_sockbuf_ctrl( conn->lconn_sb, LBER_SB_OPT_SET_FD, &fd );
300 	ld->ld_defconn = conn;
301 	++ld->ld_defconn->lconn_refcnt;	/* so it never gets closed/freed */
302 	LDAP_MUTEX_UNLOCK( &ld->ld_conn_mutex );
303 
304 	switch( proto ) {
305 	case LDAP_PROTO_TCP:
306 #ifdef LDAP_DEBUG
307 		ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_debug,
308 			LBER_SBIOD_LEVEL_PROVIDER, (void *)"tcp_" );
309 #endif
310 		ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_tcp,
311 			LBER_SBIOD_LEVEL_PROVIDER, NULL );
312 		break;
313 
314 #ifdef LDAP_CONNECTIONLESS
315 	case LDAP_PROTO_UDP:
316 		LDAP_IS_UDP(ld) = 1;
317 		if( ld->ld_options.ldo_peer )
318 			ldap_memfree( ld->ld_options.ldo_peer );
319 		ld->ld_options.ldo_peer = ldap_memcalloc( 1, sizeof( struct sockaddr_storage ) );
320 		len = sizeof( struct sockaddr_storage );
321 		if( getpeername ( fd, ld->ld_options.ldo_peer, &len ) < 0) {
322 			ldap_unbind_ext( ld, NULL, NULL );
323 			return( AC_SOCKET_ERROR );
324 		}
325 #ifdef LDAP_DEBUG
326 		ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_debug,
327 			LBER_SBIOD_LEVEL_PROVIDER, (void *)"udp_" );
328 #endif
329 		ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_udp,
330 			LBER_SBIOD_LEVEL_PROVIDER, NULL );
331 		ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_readahead,
332 			LBER_SBIOD_LEVEL_PROVIDER, NULL );
333 		break;
334 #endif /* LDAP_CONNECTIONLESS */
335 
336 	case LDAP_PROTO_IPC:
337 #ifdef LDAP_DEBUG
338 		ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_debug,
339 			LBER_SBIOD_LEVEL_PROVIDER, (void *)"ipc_" );
340 #endif
341 		ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_fd,
342 			LBER_SBIOD_LEVEL_PROVIDER, NULL );
343 		break;
344 
345 	case LDAP_PROTO_EXT:
346 		/* caller must supply sockbuf handlers */
347 		break;
348 
349 	default:
350 		ldap_unbind_ext( ld, NULL, NULL );
351 		return LDAP_PARAM_ERROR;
352 	}
353 
354 #ifdef LDAP_DEBUG
355 	ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_debug,
356 		INT_MAX, (void *)"ldap_" );
357 #endif
358 
359 	/* Add the connection to the *LDAP's select pool */
360 	ldap_mark_select_read( ld, conn->lconn_sb );
361 
362 	*ldp = ld;
363 	return LDAP_SUCCESS;
364 }
365 
366 /* Protected by ld_conn_mutex */
367 int
368 ldap_int_open_connection(
369 	LDAP *ld,
370 	LDAPConn *conn,
371 	LDAPURLDesc *srv,
372 	int async )
373 {
374 	int rc = -1;
375 	int proto;
376 
377 	Debug( LDAP_DEBUG_TRACE, "ldap_int_open_connection\n", 0, 0, 0 );
378 
379 	switch ( proto = ldap_pvt_url_scheme2proto( srv->lud_scheme ) ) {
380 		case LDAP_PROTO_TCP:
381 			rc = ldap_connect_to_host( ld, conn->lconn_sb,
382 				proto, srv, async );
383 
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 *)"tcp_" );
388 #endif
389 			ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_tcp,
390 				LBER_SBIOD_LEVEL_PROVIDER, NULL );
391 
392 			break;
393 
394 #ifdef LDAP_CONNECTIONLESS
395 		case LDAP_PROTO_UDP:
396 			LDAP_IS_UDP(ld) = 1;
397 			rc = ldap_connect_to_host( ld, conn->lconn_sb,
398 				proto, srv, async );
399 
400 			if ( rc == -1 ) return rc;
401 #ifdef LDAP_DEBUG
402 			ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_debug,
403 				LBER_SBIOD_LEVEL_PROVIDER, (void *)"udp_" );
404 #endif
405 			ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_udp,
406 				LBER_SBIOD_LEVEL_PROVIDER, NULL );
407 
408 			ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_readahead,
409 				LBER_SBIOD_LEVEL_PROVIDER, NULL );
410 
411 			break;
412 #endif
413 		case LDAP_PROTO_IPC:
414 #ifdef LDAP_PF_LOCAL
415 			/* only IPC mechanism supported is PF_LOCAL (PF_UNIX) */
416 			rc = ldap_connect_to_path( ld, conn->lconn_sb,
417 				srv, async );
418 			if ( rc == -1 ) return rc;
419 #ifdef LDAP_DEBUG
420 			ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_debug,
421 				LBER_SBIOD_LEVEL_PROVIDER, (void *)"ipc_" );
422 #endif
423 			ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_fd,
424 				LBER_SBIOD_LEVEL_PROVIDER, NULL );
425 
426 			break;
427 #endif /* LDAP_PF_LOCAL */
428 		default:
429 			return -1;
430 			break;
431 	}
432 
433 	conn->lconn_created = time( NULL );
434 
435 #ifdef LDAP_DEBUG
436 	ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_debug,
437 		INT_MAX, (void *)"ldap_" );
438 #endif
439 
440 #ifdef LDAP_CONNECTIONLESS
441 	if( proto == LDAP_PROTO_UDP ) return 0;
442 #endif
443 
444 #ifdef HAVE_TLS
445 	if (rc == 0 && ( ld->ld_options.ldo_tls_mode == LDAP_OPT_X_TLS_HARD ||
446 		strcmp( srv->lud_scheme, "ldaps" ) == 0 ))
447 	{
448 		++conn->lconn_refcnt;	/* avoid premature free */
449 
450 		rc = ldap_int_tls_start( ld, conn, srv );
451 
452 		--conn->lconn_refcnt;
453 
454 		if (rc != LDAP_SUCCESS) {
455 			return -1;
456 		}
457 	}
458 #endif
459 
460 	return( 0 );
461 }
462 
463 /*
464  * ldap_open_internal_connection - open connection and set file descriptor
465  *
466  * note: ldap_init_fd() may be preferable
467  */
468 
469 int
470 ldap_open_internal_connection( LDAP **ldp, ber_socket_t *fdp )
471 {
472 	int rc;
473 	LDAPConn *c;
474 	LDAPRequest *lr;
475 	LDAP	*ld;
476 
477 	rc = ldap_create( &ld );
478 	if( rc != LDAP_SUCCESS ) {
479 		*ldp = NULL;
480 		return( rc );
481 	}
482 
483 	/* Make it appear that a search request, msgid 0, was sent */
484 	lr = (LDAPRequest *)LDAP_CALLOC( 1, sizeof( LDAPRequest ));
485 	if( lr == NULL ) {
486 		ldap_unbind_ext( ld, NULL, NULL );
487 		*ldp = NULL;
488 		return( LDAP_NO_MEMORY );
489 	}
490 	memset(lr, 0, sizeof( LDAPRequest ));
491 	lr->lr_msgid = 0;
492 	lr->lr_status = LDAP_REQST_INPROGRESS;
493 	lr->lr_res_errno = LDAP_SUCCESS;
494 	/* no mutex lock needed, we just created this ld here */
495 	ld->ld_requests = lr;
496 
497 	LDAP_MUTEX_LOCK( &ld->ld_conn_mutex );
498 	/* Attach the passed socket as the *LDAP's connection */
499 	c = ldap_new_connection( ld, NULL, 1, 0, NULL, 0, 0 );
500 	if( c == NULL ) {
501 		ldap_unbind_ext( ld, NULL, NULL );
502 		*ldp = NULL;
503 		LDAP_MUTEX_UNLOCK( &ld->ld_conn_mutex );
504 		return( LDAP_NO_MEMORY );
505 	}
506 	ber_sockbuf_ctrl( c->lconn_sb, LBER_SB_OPT_SET_FD, fdp );
507 #ifdef LDAP_DEBUG
508 	ber_sockbuf_add_io( c->lconn_sb, &ber_sockbuf_io_debug,
509 		LBER_SBIOD_LEVEL_PROVIDER, (void *)"int_" );
510 #endif
511 	ber_sockbuf_add_io( c->lconn_sb, &ber_sockbuf_io_tcp,
512 	  LBER_SBIOD_LEVEL_PROVIDER, NULL );
513 	ld->ld_defconn = c;
514 	LDAP_MUTEX_UNLOCK( &ld->ld_conn_mutex );
515 
516 	/* Add the connection to the *LDAP's select pool */
517 	ldap_mark_select_read( ld, c->lconn_sb );
518 
519 	/* Make this connection an LDAP V3 protocol connection */
520 	rc = LDAP_VERSION3;
521 	ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &rc );
522 	*ldp = ld;
523 
524 	++ld->ld_defconn->lconn_refcnt;	/* so it never gets closed/freed */
525 
526 	return( LDAP_SUCCESS );
527 }
528 
529 LDAP *
530 ldap_dup( LDAP *old )
531 {
532 	LDAP			*ld;
533 
534 	if ( old == NULL ) {
535 		return( NULL );
536 	}
537 
538 	Debug( LDAP_DEBUG_TRACE, "ldap_dup\n", 0, 0, 0 );
539 
540 	if ( (ld = (LDAP *) LDAP_CALLOC( 1, sizeof(LDAP) )) == NULL ) {
541 		return( NULL );
542 	}
543 
544 	LDAP_MUTEX_LOCK( &old->ld_ldcmutex );
545 	ld->ldc = old->ldc;
546 	old->ld_ldcrefcnt++;
547 	LDAP_MUTEX_UNLOCK( &old->ld_ldcmutex );
548 	return ( ld );
549 }
550 
551 int
552 ldap_int_check_async_open( LDAP *ld, ber_socket_t sd )
553 {
554 	struct timeval tv = { 0 };
555 	int rc;
556 
557 	rc = ldap_int_poll( ld, sd, &tv, 1 );
558 	switch ( rc ) {
559 	case 0:
560 		/* now ready to start tls */
561 		ld->ld_defconn->lconn_status = LDAP_CONNST_CONNECTED;
562 		break;
563 
564 	default:
565 		ld->ld_errno = LDAP_CONNECT_ERROR;
566 		return -1;
567 
568 	case -2:
569 		/* connect not completed yet */
570 		ld->ld_errno = LDAP_X_CONNECTING;
571 		return rc;
572 	}
573 
574 #ifdef HAVE_TLS
575 	if ( ld->ld_options.ldo_tls_mode == LDAP_OPT_X_TLS_HARD ||
576 		!strcmp( ld->ld_defconn->lconn_server->lud_scheme, "ldaps" )) {
577 
578 		++ld->ld_defconn->lconn_refcnt;	/* avoid premature free */
579 
580 		rc = ldap_int_tls_start( ld, ld->ld_defconn, ld->ld_defconn->lconn_server );
581 
582 		--ld->ld_defconn->lconn_refcnt;
583 	}
584 #endif
585 	return rc;
586 }
587