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