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