1/* $OpenLDAP$ */
2/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
3 *
4 * Copyright 1999-2011 The OpenLDAP Foundation.
5 * Portions Copyright 2001-2003 Pierangelo Masarati.
6 * Portions Copyright 1999-2003 Howard Chu.
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/* ACKNOWLEDGEMENTS:
18 * This work was initially developed by the Howard Chu for inclusion
19 * in OpenLDAP Software and subsequently enhanced by Pierangelo
20 * Masarati.
21 */
22
23#include "portable.h"
24
25#include <stdio.h>
26
27#include <ac/socket.h>
28#include <ac/string.h>
29#include <ac/time.h>
30
31#include "lutil.h"
32#include "slap.h"
33#include "../back-ldap/back-ldap.h"
34#include "back-meta.h"
35#include "../../../libraries/liblber/lber-int.h"
36
37/* IGNORE means that target does not (no longer) participate
38 * in the search;
39 * NOTREADY means the search on that target has not been initialized yet
40 */
41#define	META_MSGID_IGNORE	(-1)
42#define	META_MSGID_NEED_BIND	(-2)
43#define	META_MSGID_CONNECTING	(-3)
44
45static int
46meta_send_entry(
47	Operation 	*op,
48	SlapReply	*rs,
49	metaconn_t	*mc,
50	int 		i,
51	LDAPMessage 	*e );
52
53typedef enum meta_search_candidate_t {
54	META_SEARCH_UNDEFINED = -2,
55	META_SEARCH_ERR = -1,
56	META_SEARCH_NOT_CANDIDATE,
57	META_SEARCH_CANDIDATE,
58	META_SEARCH_BINDING,
59	META_SEARCH_NEED_BIND,
60	META_SEARCH_CONNECTING
61} meta_search_candidate_t;
62
63/*
64 * meta_search_dobind_init()
65 *
66 * initiates bind for a candidate target of a search.
67 */
68static meta_search_candidate_t
69meta_search_dobind_init(
70	Operation		*op,
71	SlapReply		*rs,
72	metaconn_t		**mcp,
73	int			candidate,
74	SlapReply		*candidates )
75{
76	metaconn_t		*mc = *mcp;
77	metainfo_t		*mi = ( metainfo_t * )op->o_bd->be_private;
78	metatarget_t		*mt = mi->mi_targets[ candidate ];
79	metasingleconn_t	*msc = &mc->mc_conns[ candidate ];
80
81	struct berval		binddn = msc->msc_bound_ndn,
82				cred = msc->msc_cred;
83	int			method;
84
85	int			rc;
86
87	meta_search_candidate_t	retcode;
88
89	Debug( LDAP_DEBUG_TRACE, "%s >>> meta_search_dobind_init[%d]\n",
90		op->o_log_prefix, candidate, 0 );
91
92	/*
93	 * all the targets are already bound as pseudoroot
94	 */
95	if ( mc->mc_authz_target == META_BOUND_ALL ) {
96		return META_SEARCH_CANDIDATE;
97	}
98
99	retcode = META_SEARCH_BINDING;
100	ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex );
101	if ( LDAP_BACK_CONN_ISBOUND( msc ) || LDAP_BACK_CONN_ISANON( msc ) ) {
102		/* already bound (or anonymous) */
103
104#ifdef DEBUG_205
105		char	buf[ SLAP_TEXT_BUFLEN ] = { '\0' };
106		int	bound = 0;
107
108		if ( LDAP_BACK_CONN_ISBOUND( msc ) ) {
109			bound = 1;
110		}
111
112		snprintf( buf, sizeof( buf ), " mc=%p ld=%p%s DN=\"%s\"",
113			(void *)mc, (void *)msc->msc_ld,
114			bound ? " bound" : " anonymous",
115			bound == 0 ? "" : msc->msc_bound_ndn.bv_val );
116		Debug( LDAP_DEBUG_ANY, "### %s meta_search_dobind_init[%d]%s\n",
117			op->o_log_prefix, candidate, buf );
118#endif /* DEBUG_205 */
119
120		retcode = META_SEARCH_CANDIDATE;
121
122	} else if ( META_BACK_CONN_CREATING( msc ) || LDAP_BACK_CONN_BINDING( msc ) ) {
123		/* another thread is binding the target for this conn; wait */
124
125#ifdef DEBUG_205
126		char	buf[ SLAP_TEXT_BUFLEN ] = { '\0' };
127
128		snprintf( buf, sizeof( buf ), " mc=%p ld=%p needbind",
129			(void *)mc, (void *)msc->msc_ld );
130		Debug( LDAP_DEBUG_ANY, "### %s meta_search_dobind_init[%d]%s\n",
131			op->o_log_prefix, candidate, buf );
132#endif /* DEBUG_205 */
133
134		candidates[ candidate ].sr_msgid = META_MSGID_NEED_BIND;
135		retcode = META_SEARCH_NEED_BIND;
136
137	} else {
138		/* we'll need to bind the target for this conn */
139
140#ifdef DEBUG_205
141		char buf[ SLAP_TEXT_BUFLEN ];
142
143		snprintf( buf, sizeof( buf ), " mc=%p ld=%p binding",
144			(void *)mc, (void *)msc->msc_ld );
145		Debug( LDAP_DEBUG_ANY, "### %s meta_search_dobind_init[%d]%s\n",
146			op->o_log_prefix, candidate, buf );
147#endif /* DEBUG_205 */
148
149		if ( msc->msc_ld == NULL ) {
150			/* for some reason (e.g. because formerly in "binding"
151			 * state, with eventual connection expiration or invalidation)
152			 * it was not initialized as expected */
153
154			Debug( LDAP_DEBUG_ANY, "%s meta_search_dobind_init[%d] mc=%p ld=NULL\n",
155				op->o_log_prefix, candidate, (void *)mc );
156
157			rc = meta_back_init_one_conn( op, rs, *mcp, candidate,
158				LDAP_BACK_CONN_ISPRIV( *mcp ), LDAP_BACK_DONTSEND, 0 );
159			switch ( rc ) {
160			case LDAP_SUCCESS:
161				assert( msc->msc_ld != NULL );
162				break;
163
164			case LDAP_SERVER_DOWN:
165			case LDAP_UNAVAILABLE:
166				ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
167				goto down;
168
169			default:
170				ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
171				goto other;
172			}
173		}
174
175		LDAP_BACK_CONN_BINDING_SET( msc );
176	}
177
178	ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
179
180	if ( retcode != META_SEARCH_BINDING ) {
181		return retcode;
182	}
183
184	/* NOTE: this obsoletes pseudorootdn */
185	if ( op->o_conn != NULL &&
186		!op->o_do_not_cache &&
187		( BER_BVISNULL( &msc->msc_bound_ndn ) ||
188			BER_BVISEMPTY( &msc->msc_bound_ndn ) ||
189			( mt->mt_idassert_flags & LDAP_BACK_AUTH_OVERRIDE ) ) )
190	{
191		rc = meta_back_proxy_authz_cred( mc, candidate, op, rs, LDAP_BACK_DONTSEND, &binddn, &cred, &method );
192		switch ( rc ) {
193		case LDAP_SUCCESS:
194			break;
195		case LDAP_UNAVAILABLE:
196			goto down;
197		default:
198			goto other;
199		}
200
201		/* NOTE: we copy things here, even if bind didn't succeed yet,
202		 * because the connection is not shared until bind is over */
203		if ( !BER_BVISNULL( &binddn ) ) {
204			ber_bvreplace( &msc->msc_bound_ndn, &binddn );
205			if ( META_BACK_TGT_SAVECRED( mt ) && !BER_BVISNULL( &cred ) ) {
206				if ( !BER_BVISNULL( &msc->msc_cred ) ) {
207					memset( msc->msc_cred.bv_val, 0,
208						msc->msc_cred.bv_len );
209				}
210				ber_bvreplace( &msc->msc_cred, &cred );
211			}
212		}
213
214		if ( LDAP_BACK_CONN_ISBOUND( msc ) ) {
215			/* apparently, idassert was configured with SASL bind,
216			 * so bind occurred inside meta_back_proxy_authz_cred() */
217			ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex );
218			LDAP_BACK_CONN_BINDING_CLEAR( msc );
219			ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
220			return META_SEARCH_CANDIDATE;
221		}
222
223		/* paranoid */
224		switch ( method ) {
225		case LDAP_AUTH_NONE:
226		case LDAP_AUTH_SIMPLE:
227			/* do a simple bind with binddn, cred */
228			break;
229
230		default:
231			assert( 0 );
232			break;
233		}
234	}
235
236	assert( msc->msc_ld != NULL );
237
238	/* connect must be async only the first time... */
239	ldap_set_option( msc->msc_ld, LDAP_OPT_CONNECT_ASYNC, LDAP_OPT_ON );
240
241retry:;
242	if ( !BER_BVISEMPTY( &binddn ) && BER_BVISEMPTY( &cred ) ) {
243		/* bind anonymously? */
244		Debug( LDAP_DEBUG_ANY, "%s meta_search_dobind_init[%d] mc=%p: "
245			"non-empty dn with empty cred; binding anonymously\n",
246			op->o_log_prefix, candidate, (void *)mc );
247		cred = slap_empty_bv;
248
249	} else if ( BER_BVISEMPTY( &binddn ) && !BER_BVISEMPTY( &cred ) ) {
250		/* error */
251		Debug( LDAP_DEBUG_ANY, "%s meta_search_dobind_init[%d] mc=%p: "
252			"empty dn with non-empty cred: error\n",
253			op->o_log_prefix, candidate, (void *)mc );
254		goto other;
255	}
256
257	rc = ldap_sasl_bind( msc->msc_ld, binddn.bv_val, LDAP_SASL_SIMPLE, &cred,
258			NULL, NULL, &candidates[ candidate ].sr_msgid );
259
260#ifdef DEBUG_205
261	{
262		char buf[ SLAP_TEXT_BUFLEN ];
263
264		snprintf( buf, sizeof( buf ), "meta_search_dobind_init[%d] mc=%p ld=%p rc=%d",
265			candidate, (void *)mc, (void *)mc->mc_conns[ candidate ].msc_ld, rc );
266		Debug( LDAP_DEBUG_ANY, "### %s %s\n",
267			op->o_log_prefix, buf, 0 );
268	}
269#endif /* DEBUG_205 */
270
271	switch ( rc ) {
272	case LDAP_SUCCESS:
273		assert( candidates[ candidate ].sr_msgid >= 0 );
274		META_BINDING_SET( &candidates[ candidate ] );
275		return META_SEARCH_BINDING;
276
277	case LDAP_X_CONNECTING:
278		/* must retry, same conn */
279		candidates[ candidate ].sr_msgid = META_MSGID_CONNECTING;
280		ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex );
281		LDAP_BACK_CONN_BINDING_CLEAR( msc );
282		ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
283		return META_SEARCH_CONNECTING;
284
285	case LDAP_SERVER_DOWN:
286down:;
287		/* This is the worst thing that could happen:
288		 * the search will wait until the retry is over. */
289		if ( !META_IS_RETRYING( &candidates[ candidate ] ) ) {
290			META_RETRYING_SET( &candidates[ candidate ] );
291
292			ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex );
293
294			assert( mc->mc_refcnt > 0 );
295			if ( LogTest( LDAP_DEBUG_ANY ) ) {
296				char	buf[ SLAP_TEXT_BUFLEN ];
297
298				/* this lock is required; however,
299				 * it's invoked only when logging is on */
300				ldap_pvt_thread_mutex_lock( &mt->mt_uri_mutex );
301				snprintf( buf, sizeof( buf ),
302					"retrying URI=\"%s\" DN=\"%s\"",
303					mt->mt_uri,
304					BER_BVISNULL( &msc->msc_bound_ndn ) ?
305						"" : msc->msc_bound_ndn.bv_val );
306				ldap_pvt_thread_mutex_unlock( &mt->mt_uri_mutex );
307
308				Debug( LDAP_DEBUG_ANY,
309					"%s meta_search_dobind_init[%d]: %s.\n",
310					op->o_log_prefix, candidate, buf );
311			}
312
313			meta_clear_one_candidate( op, mc, candidate );
314			LDAP_BACK_CONN_ISBOUND_CLEAR( msc );
315
316			( void )rewrite_session_delete( mt->mt_rwmap.rwm_rw, op->o_conn );
317
318			/* mc here must be the regular mc, reset and ready for init */
319			rc = meta_back_init_one_conn( op, rs, mc, candidate,
320				LDAP_BACK_CONN_ISPRIV( mc ), LDAP_BACK_DONTSEND, 0 );
321
322			if ( rc == LDAP_SUCCESS ) {
323				LDAP_BACK_CONN_BINDING_SET( msc );
324			}
325
326			ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
327
328			if ( rc == LDAP_SUCCESS ) {
329				candidates[ candidate ].sr_msgid = META_MSGID_IGNORE;
330				binddn = msc->msc_bound_ndn;
331				cred = msc->msc_cred;
332				goto retry;
333			}
334		}
335
336		if ( *mcp == NULL ) {
337			retcode = META_SEARCH_ERR;
338			rs->sr_err = LDAP_UNAVAILABLE;
339			candidates[ candidate ].sr_msgid = META_MSGID_IGNORE;
340			break;
341		}
342		/* fall thru */
343
344	default:
345other:;
346		rs->sr_err = rc;
347		rc = slap_map_api2result( rs );
348
349		ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex );
350		meta_clear_one_candidate( op, mc, candidate );
351		candidates[ candidate ].sr_err = rc;
352		if ( META_BACK_ONERR_STOP( mi ) ) {
353			LDAP_BACK_CONN_TAINTED_SET( mc );
354			meta_back_release_conn_lock( mi, mc, 0 );
355			*mcp = NULL;
356			rs->sr_err = rc;
357
358			retcode = META_SEARCH_ERR;
359
360		} else {
361			retcode = META_SEARCH_NOT_CANDIDATE;
362		}
363		candidates[ candidate ].sr_msgid = META_MSGID_IGNORE;
364		ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
365		break;
366	}
367
368	return retcode;
369}
370
371static meta_search_candidate_t
372meta_search_dobind_result(
373	Operation		*op,
374	SlapReply		*rs,
375	metaconn_t		**mcp,
376	int			candidate,
377	SlapReply		*candidates,
378	LDAPMessage		*res )
379{
380	metainfo_t		*mi = ( metainfo_t * )op->o_bd->be_private;
381	metatarget_t		*mt = mi->mi_targets[ candidate ];
382	metaconn_t		*mc = *mcp;
383	metasingleconn_t	*msc = &mc->mc_conns[ candidate ];
384
385	meta_search_candidate_t	retcode = META_SEARCH_NOT_CANDIDATE;
386	int			rc;
387
388	assert( msc->msc_ld != NULL );
389
390	/* FIXME: matched? referrals? response controls? */
391	rc = ldap_parse_result( msc->msc_ld, res,
392		&candidates[ candidate ].sr_err,
393		NULL, NULL, NULL, NULL, 0 );
394	if ( rc != LDAP_SUCCESS ) {
395		candidates[ candidate ].sr_err = rc;
396	}
397	rc = slap_map_api2result( &candidates[ candidate ] );
398
399	ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex );
400	LDAP_BACK_CONN_BINDING_CLEAR( msc );
401	if ( rc != LDAP_SUCCESS ) {
402		meta_clear_one_candidate( op, mc, candidate );
403		candidates[ candidate ].sr_err = rc;
404		if ( META_BACK_ONERR_STOP( mi ) ) {
405	        	LDAP_BACK_CONN_TAINTED_SET( mc );
406			meta_back_release_conn_lock( mi, mc, 0 );
407			*mcp = NULL;
408			retcode = META_SEARCH_ERR;
409			rs->sr_err = rc;
410		}
411
412	} else {
413		/* FIXME: check if bound as idassert authcDN! */
414		if ( BER_BVISNULL( &msc->msc_bound_ndn )
415			|| BER_BVISEMPTY( &msc->msc_bound_ndn ) )
416		{
417			LDAP_BACK_CONN_ISANON_SET( msc );
418
419		} else {
420			if ( META_BACK_TGT_SAVECRED( mt ) &&
421				!BER_BVISNULL( &msc->msc_cred ) &&
422				!BER_BVISEMPTY( &msc->msc_cred ) )
423			{
424				ldap_set_rebind_proc( msc->msc_ld, mt->mt_rebind_f, msc );
425			}
426			LDAP_BACK_CONN_ISBOUND_SET( msc );
427		}
428		retcode = META_SEARCH_CANDIDATE;
429
430		/* connect must be async */
431		ldap_set_option( msc->msc_ld, LDAP_OPT_CONNECT_ASYNC, LDAP_OPT_OFF );
432	}
433
434	candidates[ candidate ].sr_msgid = META_MSGID_IGNORE;
435	META_BINDING_CLEAR( &candidates[ candidate ] );
436
437	ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
438
439	return retcode;
440}
441
442static meta_search_candidate_t
443meta_back_search_start(
444	Operation		*op,
445	SlapReply		*rs,
446	dncookie		*dc,
447	metaconn_t		**mcp,
448	int			candidate,
449	SlapReply		*candidates,
450	struct berval		*prcookie,
451	ber_int_t		prsize )
452{
453	metainfo_t		*mi = ( metainfo_t * )op->o_bd->be_private;
454	metatarget_t		*mt = mi->mi_targets[ candidate ];
455	metasingleconn_t	*msc = &(*mcp)->mc_conns[ candidate ];
456	struct berval		realbase = op->o_req_dn;
457	int			realscope = op->ors_scope;
458	struct berval		mbase = BER_BVNULL;
459	struct berval		mfilter = BER_BVNULL;
460	char			**mapped_attrs = NULL;
461	int			rc;
462	meta_search_candidate_t	retcode;
463	struct timeval		tv, *tvp = NULL;
464	int			nretries = 1;
465	LDAPControl		**ctrls = NULL;
466#ifdef SLAPD_META_CLIENT_PR
467	LDAPControl		**save_ctrls = NULL;
468#endif /* SLAPD_META_CLIENT_PR */
469
470	/* this should not happen; just in case... */
471	if ( msc->msc_ld == NULL ) {
472		Debug( LDAP_DEBUG_ANY,
473			"%s: meta_back_search_start candidate=%d ld=NULL%s.\n",
474			op->o_log_prefix, candidate,
475			META_BACK_ONERR_STOP( mi ) ? "" : " (ignored)" );
476		candidates[ candidate ].sr_err = LDAP_OTHER;
477		if ( META_BACK_ONERR_STOP( mi ) ) {
478			return META_SEARCH_ERR;
479		}
480		candidates[ candidate ].sr_msgid = META_MSGID_IGNORE;
481		return META_SEARCH_NOT_CANDIDATE;
482	}
483
484	Debug( LDAP_DEBUG_TRACE, "%s >>> meta_back_search_start[%d]\n", op->o_log_prefix, candidate, 0 );
485
486	/*
487	 * modifies the base according to the scope, if required
488	 */
489	if ( mt->mt_nsuffix.bv_len > op->o_req_ndn.bv_len ) {
490		switch ( op->ors_scope ) {
491		case LDAP_SCOPE_SUBTREE:
492			/*
493			 * make the target suffix the new base
494			 * FIXME: this is very forgiving, because
495			 * "illegal" searchBases may be turned
496			 * into the suffix of the target; however,
497			 * the requested searchBase already passed
498			 * thru the candidate analyzer...
499			 */
500			if ( dnIsSuffix( &mt->mt_nsuffix, &op->o_req_ndn ) ) {
501				realbase = mt->mt_nsuffix;
502				if ( mt->mt_scope == LDAP_SCOPE_SUBORDINATE ) {
503					realscope = LDAP_SCOPE_SUBORDINATE;
504				}
505
506			} else {
507				/*
508				 * this target is no longer candidate
509				 */
510				retcode = META_SEARCH_NOT_CANDIDATE;
511				goto doreturn;
512			}
513			break;
514
515		case LDAP_SCOPE_SUBORDINATE:
516		case LDAP_SCOPE_ONELEVEL:
517		{
518			struct berval	rdn = mt->mt_nsuffix;
519			rdn.bv_len -= op->o_req_ndn.bv_len + STRLENOF( "," );
520			if ( dnIsOneLevelRDN( &rdn )
521					&& dnIsSuffix( &mt->mt_nsuffix, &op->o_req_ndn ) )
522			{
523				/*
524				 * if there is exactly one level,
525				 * make the target suffix the new
526				 * base, and make scope "base"
527				 */
528				realbase = mt->mt_nsuffix;
529				if ( op->ors_scope == LDAP_SCOPE_SUBORDINATE ) {
530					if ( mt->mt_scope == LDAP_SCOPE_SUBORDINATE ) {
531						realscope = LDAP_SCOPE_SUBORDINATE;
532					} else {
533						realscope = LDAP_SCOPE_SUBTREE;
534					}
535				} else {
536					realscope = LDAP_SCOPE_BASE;
537				}
538				break;
539			} /* else continue with the next case */
540		}
541
542		case LDAP_SCOPE_BASE:
543			/*
544			 * this target is no longer candidate
545			 */
546			retcode = META_SEARCH_NOT_CANDIDATE;
547			goto doreturn;
548		}
549	}
550
551	/* initiate dobind */
552	retcode = meta_search_dobind_init( op, rs, mcp, candidate, candidates );
553
554	Debug( LDAP_DEBUG_TRACE, "%s <<< meta_search_dobind_init[%d]=%d\n", op->o_log_prefix, candidate, retcode );
555
556	if ( retcode != META_SEARCH_CANDIDATE ) {
557		goto doreturn;
558	}
559
560	/*
561	 * Rewrite the search base, if required
562	 */
563	dc->target = mt;
564	dc->ctx = "searchBase";
565	switch ( ldap_back_dn_massage( dc, &realbase, &mbase ) ) {
566	case LDAP_SUCCESS:
567		break;
568
569	case LDAP_UNWILLING_TO_PERFORM:
570		rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
571		rs->sr_text = "Operation not allowed";
572		send_ldap_result( op, rs );
573		retcode = META_SEARCH_ERR;
574		goto doreturn;
575
576	default:
577
578		/*
579		 * this target is no longer candidate
580		 */
581		retcode = META_SEARCH_NOT_CANDIDATE;
582		goto doreturn;
583	}
584
585	/*
586	 * Maps filter
587	 */
588	rc = ldap_back_filter_map_rewrite( dc, op->ors_filter,
589			&mfilter, BACKLDAP_MAP, op->o_tmpmemctx );
590	switch ( rc ) {
591	case LDAP_SUCCESS:
592		break;
593
594	case LDAP_COMPARE_FALSE:
595	default:
596		/*
597		 * this target is no longer candidate
598		 */
599		retcode = META_SEARCH_NOT_CANDIDATE;
600		goto done;
601	}
602
603	/*
604	 * Maps required attributes
605	 */
606	rc = ldap_back_map_attrs( op, &mt->mt_rwmap.rwm_at,
607			op->ors_attrs, BACKLDAP_MAP, &mapped_attrs );
608	if ( rc != LDAP_SUCCESS ) {
609		/*
610		 * this target is no longer candidate
611		 */
612		retcode = META_SEARCH_NOT_CANDIDATE;
613		goto done;
614	}
615
616	if ( op->ors_tlimit != SLAP_NO_LIMIT ) {
617		tv.tv_sec = op->ors_tlimit > 0 ? op->ors_tlimit : 1;
618		tv.tv_usec = 0;
619		tvp = &tv;
620	}
621
622#ifdef SLAPD_META_CLIENT_PR
623	save_ctrls = op->o_ctrls;
624	{
625		LDAPControl *pr_c = NULL;
626		int i = 0, nc = 0;
627
628		if ( save_ctrls ) {
629			for ( ; save_ctrls[i] != NULL; i++ );
630			nc = i;
631			pr_c = ldap_control_find( LDAP_CONTROL_PAGEDRESULTS, save_ctrls, NULL );
632		}
633
634		if ( pr_c != NULL ) nc--;
635		if ( mt->mt_ps > 0 || prcookie != NULL ) nc++;
636
637		if ( mt->mt_ps > 0 || prcookie != NULL || pr_c != NULL ) {
638			int src = 0, dst = 0;
639			BerElementBuffer berbuf;
640			BerElement *ber = (BerElement *)&berbuf;
641			struct berval val = BER_BVNULL;
642			ber_len_t len;
643
644			len = sizeof( LDAPControl * )*( nc + 1 ) + sizeof( LDAPControl );
645
646			if ( mt->mt_ps > 0 || prcookie != NULL ) {
647				struct berval nullcookie = BER_BVNULL;
648				ber_tag_t tag;
649
650				if ( prsize == 0 && mt->mt_ps > 0 ) prsize = mt->mt_ps;
651				if ( prcookie == NULL ) prcookie = &nullcookie;
652
653				ber_init2( ber, NULL, LBER_USE_DER );
654				tag = ber_printf( ber, "{iO}", prsize, prcookie );
655				if ( tag == LBER_ERROR ) {
656					/* error */
657					(void) ber_free_buf( ber );
658					goto done_pr;
659				}
660
661				tag = ber_flatten2( ber, &val, 0 );
662				if ( tag == LBER_ERROR ) {
663					/* error */
664					(void) ber_free_buf( ber );
665					goto done_pr;
666				}
667
668				len += val.bv_len + 1;
669			}
670
671			op->o_ctrls = op->o_tmpalloc( len, op->o_tmpmemctx );
672			if ( save_ctrls ) {
673				for ( ; save_ctrls[ src ] != NULL; src++ ) {
674					if ( save_ctrls[ src ] != pr_c ) {
675						op->o_ctrls[ dst ] = save_ctrls[ src ];
676						dst++;
677					}
678				}
679			}
680
681			if ( mt->mt_ps > 0 || prcookie != NULL ) {
682				op->o_ctrls[ dst ] = (LDAPControl *)&op->o_ctrls[ nc + 1 ];
683
684				op->o_ctrls[ dst ]->ldctl_oid = LDAP_CONTROL_PAGEDRESULTS;
685				op->o_ctrls[ dst ]->ldctl_iscritical = 1;
686
687				op->o_ctrls[ dst ]->ldctl_value.bv_val = (char *)&op->o_ctrls[ dst ][ 1 ];
688				AC_MEMCPY( op->o_ctrls[ dst ]->ldctl_value.bv_val, val.bv_val, val.bv_len + 1 );
689				op->o_ctrls[ dst ]->ldctl_value.bv_len = val.bv_len;
690				dst++;
691
692				(void)ber_free_buf( ber );
693			}
694
695			op->o_ctrls[ dst ] = NULL;
696		}
697done_pr:;
698	}
699#endif /* SLAPD_META_CLIENT_PR */
700
701retry:;
702	ctrls = op->o_ctrls;
703	if ( meta_back_controls_add( op, rs, *mcp, candidate, &ctrls )
704		!= LDAP_SUCCESS )
705	{
706		candidates[ candidate ].sr_msgid = META_MSGID_IGNORE;
707		retcode = META_SEARCH_NOT_CANDIDATE;
708		goto done;
709	}
710
711	/*
712	 * Starts the search
713	 */
714	assert( msc->msc_ld != NULL );
715	rc = ldap_pvt_search( msc->msc_ld,
716			mbase.bv_val, realscope, mfilter.bv_val,
717			mapped_attrs, op->ors_attrsonly,
718			ctrls, NULL, tvp, op->ors_slimit, op->ors_deref,
719			&candidates[ candidate ].sr_msgid );
720	switch ( rc ) {
721	case LDAP_SUCCESS:
722		retcode = META_SEARCH_CANDIDATE;
723		break;
724
725	case LDAP_SERVER_DOWN:
726		if ( nretries && meta_back_retry( op, rs, mcp, candidate, LDAP_BACK_DONTSEND ) ) {
727			nretries = 0;
728			/* if the identity changed, there might be need to re-authz */
729			(void)mi->mi_ldap_extra->controls_free( op, rs, &ctrls );
730			goto retry;
731		}
732
733		if ( *mcp == NULL ) {
734			retcode = META_SEARCH_ERR;
735			candidates[ candidate ].sr_msgid = META_MSGID_IGNORE;
736			break;
737		}
738		/* fall thru */
739
740	default:
741		candidates[ candidate ].sr_msgid = META_MSGID_IGNORE;
742		retcode = META_SEARCH_NOT_CANDIDATE;
743	}
744
745done:;
746	(void)mi->mi_ldap_extra->controls_free( op, rs, &ctrls );
747#ifdef SLAPD_META_CLIENT_PR
748	if ( save_ctrls != op->o_ctrls ) {
749		op->o_tmpfree( op->o_ctrls, op->o_tmpmemctx );
750		op->o_ctrls = save_ctrls;
751	}
752#endif /* SLAPD_META_CLIENT_PR */
753
754	if ( mapped_attrs ) {
755		ber_memfree_x( mapped_attrs, op->o_tmpmemctx );
756	}
757	if ( mfilter.bv_val != op->ors_filterstr.bv_val ) {
758		ber_memfree_x( mfilter.bv_val, op->o_tmpmemctx );
759	}
760	if ( mbase.bv_val != realbase.bv_val ) {
761		free( mbase.bv_val );
762	}
763
764doreturn:;
765	Debug( LDAP_DEBUG_TRACE, "%s <<< meta_back_search_start[%d]=%d\n", op->o_log_prefix, candidate, retcode );
766
767	return retcode;
768}
769
770int
771meta_back_search( Operation *op, SlapReply *rs )
772{
773	metainfo_t	*mi = ( metainfo_t * )op->o_bd->be_private;
774	metaconn_t	*mc;
775	struct timeval	save_tv = { 0, 0 },
776			tv;
777	time_t		stoptime = (time_t)(-1),
778			lastres_time = slap_get_time(),
779			timeout = 0;
780	int		rc = 0, sres = LDAP_SUCCESS;
781	char		*matched = NULL;
782	int		last = 0, ncandidates = 0,
783			initial_candidates = 0, candidate_match = 0,
784			needbind = 0;
785	ldap_back_send_t	sendok = LDAP_BACK_SENDERR;
786	long		i;
787	dncookie	dc;
788	int		is_ok = 0;
789	void		*savepriv;
790	SlapReply	*candidates = NULL;
791	int		do_taint = 0;
792
793	rs_assert_ready( rs );
794	rs->sr_flags &= ~REP_ENTRY_MASK; /* paranoia, we can set rs = non-entry */
795
796	/*
797	 * controls are set in ldap_back_dobind()
798	 *
799	 * FIXME: in case of values return filter, we might want
800	 * to map attrs and maybe rewrite value
801	 */
802getconn:;
803	mc = meta_back_getconn( op, rs, NULL, sendok );
804	if ( !mc ) {
805		return rs->sr_err;
806	}
807
808	dc.conn = op->o_conn;
809	dc.rs = rs;
810
811	if ( candidates == NULL ) candidates = meta_back_candidates_get( op );
812	/*
813	 * Inits searches
814	 */
815	for ( i = 0; i < mi->mi_ntargets; i++ ) {
816		/* reset sr_msgid; it is used in most loops
817		 * to check if that target is still to be considered */
818		candidates[ i ].sr_msgid = META_MSGID_IGNORE;
819
820		/* a target is marked as candidate by meta_back_getconn();
821		 * if for any reason (an error, it's over or so) it is
822		 * no longer active, sr_msgid is set to META_MSGID_IGNORE
823		 * but it remains candidate, which means it has been active
824		 * at some point during the operation.  This allows to
825		 * use its response code and more to compute the final
826		 * response */
827		if ( !META_IS_CANDIDATE( &candidates[ i ] ) ) {
828			continue;
829		}
830
831		candidates[ i ].sr_matched = NULL;
832		candidates[ i ].sr_text = NULL;
833		candidates[ i ].sr_ref = NULL;
834		candidates[ i ].sr_ctrls = NULL;
835		candidates[ i ].sr_nentries = 0;
836
837		/* get largest timeout among candidates */
838		if ( mi->mi_targets[ i ]->mt_timeout[ SLAP_OP_SEARCH ]
839			&& mi->mi_targets[ i ]->mt_timeout[ SLAP_OP_SEARCH ] > timeout )
840		{
841			timeout = mi->mi_targets[ i ]->mt_timeout[ SLAP_OP_SEARCH ];
842		}
843	}
844
845	for ( i = 0; i < mi->mi_ntargets; i++ ) {
846		if ( !META_IS_CANDIDATE( &candidates[ i ] )
847			|| candidates[ i ].sr_err != LDAP_SUCCESS )
848		{
849			continue;
850		}
851
852		switch ( meta_back_search_start( op, rs, &dc, &mc, i, candidates, NULL, 0 ) )
853		{
854		case META_SEARCH_NOT_CANDIDATE:
855			candidates[ i ].sr_msgid = META_MSGID_IGNORE;
856			break;
857
858		case META_SEARCH_NEED_BIND:
859			++needbind;
860			/* fallthru */
861
862		case META_SEARCH_CONNECTING:
863		case META_SEARCH_CANDIDATE:
864		case META_SEARCH_BINDING:
865			candidates[ i ].sr_type = REP_INTERMEDIATE;
866			++ncandidates;
867			break;
868
869		case META_SEARCH_ERR:
870			savepriv = op->o_private;
871			op->o_private = (void *)i;
872			send_ldap_result( op, rs );
873			op->o_private = savepriv;
874			rc = -1;
875			goto finish;
876
877		default:
878			assert( 0 );
879			break;
880		}
881	}
882
883	if ( ncandidates > 0 && needbind == ncandidates ) {
884		/*
885		 * give up the second time...
886		 *
887		 * NOTE: this should not occur the second time, since a fresh
888		 * connection has ben created; however, targets may also
889		 * need bind because the bind timed out or so.
890		 */
891		if ( sendok & LDAP_BACK_BINDING ) {
892			Debug( LDAP_DEBUG_ANY,
893				"%s meta_back_search: unable to initialize conn\n",
894				op->o_log_prefix, 0, 0 );
895			rs->sr_err = LDAP_UNAVAILABLE;
896			rs->sr_text = "unable to initialize connection to remote targets";
897			send_ldap_result( op, rs );
898			rc = -1;
899			goto finish;
900		}
901
902		/* FIXME: better create a separate connection? */
903		sendok |= LDAP_BACK_BINDING;
904
905#ifdef DEBUG_205
906		Debug( LDAP_DEBUG_ANY, "*** %s drop mc=%p create new connection\n",
907			op->o_log_prefix, (void *)mc, 0 );
908#endif /* DEBUG_205 */
909
910		meta_back_release_conn( mi, mc );
911		mc = NULL;
912
913		needbind = 0;
914		ncandidates = 0;
915
916		goto getconn;
917	}
918
919	initial_candidates = ncandidates;
920
921	if ( LogTest( LDAP_DEBUG_TRACE ) ) {
922		char	cnd[ SLAP_TEXT_BUFLEN ];
923		int	c;
924
925		for ( c = 0; c < mi->mi_ntargets; c++ ) {
926			if ( META_IS_CANDIDATE( &candidates[ c ] ) ) {
927				cnd[ c ] = '*';
928			} else {
929				cnd[ c ] = ' ';
930			}
931		}
932		cnd[ c ] = '\0';
933
934		Debug( LDAP_DEBUG_TRACE, "%s meta_back_search: ncandidates=%d "
935			"cnd=\"%s\"\n", op->o_log_prefix, ncandidates, cnd );
936	}
937
938	if ( initial_candidates == 0 ) {
939		/* NOTE: here we are not sending any matchedDN;
940		 * this is intended, because if the back-meta
941		 * is serving this search request, but no valid
942		 * candidate could be looked up, it means that
943		 * there is a hole in the mapping of the targets
944		 * and thus no knowledge of any remote superior
945		 * is available */
946		Debug( LDAP_DEBUG_ANY, "%s meta_back_search: "
947			"base=\"%s\" scope=%d: "
948			"no candidate could be selected\n",
949			op->o_log_prefix, op->o_req_dn.bv_val,
950			op->ors_scope );
951
952		/* FIXME: we're sending the first error we encounter;
953		 * maybe we should pick the worst... */
954		rc = LDAP_NO_SUCH_OBJECT;
955		for ( i = 0; i < mi->mi_ntargets; i++ ) {
956			if ( META_IS_CANDIDATE( &candidates[ i ] )
957				&& candidates[ i ].sr_err != LDAP_SUCCESS )
958			{
959				rc = candidates[ i ].sr_err;
960				break;
961			}
962		}
963
964		send_ldap_error( op, rs, rc, NULL );
965
966		goto finish;
967	}
968
969	/* We pull apart the ber result, stuff it into a slapd entry, and
970	 * let send_search_entry stuff it back into ber format. Slow & ugly,
971	 * but this is necessary for version matching, and for ACL processing.
972	 */
973
974	if ( op->ors_tlimit != SLAP_NO_LIMIT ) {
975		stoptime = op->o_time + op->ors_tlimit;
976	}
977
978	/*
979	 * In case there are no candidates, no cycle takes place...
980	 *
981	 * FIXME: we might use a queue, to better balance the load
982	 * among the candidates
983	 */
984	for ( rc = 0; ncandidates > 0; ) {
985		int	gotit = 0,
986			doabandon = 0,
987			alreadybound = ncandidates;
988
989		/* check timeout */
990		if ( timeout && lastres_time > 0
991			&& ( slap_get_time() - lastres_time ) > timeout )
992		{
993			doabandon = 1;
994			rs->sr_text = "Operation timed out";
995			rc = rs->sr_err = op->o_protocol >= LDAP_VERSION3 ?
996				LDAP_ADMINLIMIT_EXCEEDED : LDAP_OTHER;
997			savepriv = op->o_private;
998			op->o_private = (void *)i;
999			send_ldap_result( op, rs );
1000			op->o_private = savepriv;
1001			goto finish;
1002		}
1003
1004		/* check time limit */
1005		if ( op->ors_tlimit != SLAP_NO_LIMIT
1006				&& slap_get_time() > stoptime )
1007		{
1008			doabandon = 1;
1009			rc = rs->sr_err = LDAP_TIMELIMIT_EXCEEDED;
1010			savepriv = op->o_private;
1011			op->o_private = (void *)i;
1012			send_ldap_result( op, rs );
1013			op->o_private = savepriv;
1014			goto finish;
1015		}
1016
1017		for ( i = 0; i < mi->mi_ntargets; i++ ) {
1018			meta_search_candidate_t	retcode = META_SEARCH_UNDEFINED;
1019			metasingleconn_t	*msc = &mc->mc_conns[ i ];
1020			LDAPMessage		*res = NULL, *msg;
1021
1022			/* if msgid is invalid, don't ldap_result() */
1023			if ( candidates[ i ].sr_msgid == META_MSGID_IGNORE ) {
1024				continue;
1025			}
1026
1027			/* if target still needs bind, retry */
1028			if ( candidates[ i ].sr_msgid == META_MSGID_NEED_BIND
1029				|| candidates[ i ].sr_msgid == META_MSGID_CONNECTING )
1030			{
1031				/* initiate dobind */
1032				retcode = meta_search_dobind_init( op, rs, &mc, i, candidates );
1033
1034				Debug( LDAP_DEBUG_TRACE, "%s <<< meta_search_dobind_init[%ld]=%d\n",
1035					op->o_log_prefix, i, retcode );
1036
1037				switch ( retcode ) {
1038				case META_SEARCH_NEED_BIND:
1039					alreadybound--;
1040					/* fallthru */
1041
1042				case META_SEARCH_CONNECTING:
1043				case META_SEARCH_BINDING:
1044					break;
1045
1046				case META_SEARCH_ERR:
1047					candidates[ i ].sr_err = rs->sr_err;
1048					if ( META_BACK_ONERR_STOP( mi ) ) {
1049						savepriv = op->o_private;
1050						op->o_private = (void *)i;
1051						send_ldap_result( op, rs );
1052						op->o_private = savepriv;
1053						goto finish;
1054					}
1055					/* fallthru */
1056
1057				case META_SEARCH_NOT_CANDIDATE:
1058					/*
1059					 * When no candidates are left,
1060					 * the outer cycle finishes
1061					 */
1062					candidates[ i ].sr_msgid = META_MSGID_IGNORE;
1063					assert( ncandidates > 0 );
1064					--ncandidates;
1065					break;
1066
1067				case META_SEARCH_CANDIDATE:
1068					candidates[ i ].sr_msgid = META_MSGID_IGNORE;
1069					switch ( meta_back_search_start( op, rs, &dc, &mc, i, candidates, NULL, 0 ) )
1070					{
1071					case META_SEARCH_CANDIDATE:
1072						assert( candidates[ i ].sr_msgid >= 0 );
1073						break;
1074
1075					case META_SEARCH_ERR:
1076						candidates[ i ].sr_err = rs->sr_err;
1077						if ( META_BACK_ONERR_STOP( mi ) ) {
1078							savepriv = op->o_private;
1079							op->o_private = (void *)i;
1080							send_ldap_result( op, rs );
1081							op->o_private = savepriv;
1082							goto finish;
1083						}
1084						/* fallthru */
1085
1086					case META_SEARCH_NOT_CANDIDATE:
1087						/* means that meta_back_search_start()
1088						 * failed but onerr == continue */
1089						candidates[ i ].sr_msgid = META_MSGID_IGNORE;
1090						assert( ncandidates > 0 );
1091						--ncandidates;
1092						break;
1093
1094					default:
1095						/* impossible */
1096						assert( 0 );
1097						break;
1098					}
1099					break;
1100
1101				default:
1102					/* impossible */
1103					assert( 0 );
1104					break;
1105				}
1106				continue;
1107			}
1108
1109			/* check for abandon */
1110			if ( op->o_abandon || LDAP_BACK_CONN_ABANDON( mc ) ) {
1111				break;
1112			}
1113
1114#ifdef DEBUG_205
1115			if ( msc->msc_ld == NULL ) {
1116				char	buf[ SLAP_TEXT_BUFLEN ];
1117
1118				ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex );
1119				snprintf( buf, sizeof( buf ),
1120					"%s meta_back_search[%ld] mc=%p msgid=%d%s%s%s\n",
1121					op->o_log_prefix, (long)i, (void *)mc,
1122					candidates[ i ].sr_msgid,
1123					META_IS_BINDING( &candidates[ i ] ) ? " binding" : "",
1124					LDAP_BACK_CONN_BINDING( &mc->mc_conns[ i ] ) ? " connbinding" : "",
1125					META_BACK_CONN_CREATING( &mc->mc_conns[ i ] ) ? " conncreating" : "" );
1126				ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
1127
1128				Debug( LDAP_DEBUG_ANY, "!!! %s\n", buf, 0, 0 );
1129			}
1130#endif /* DEBUG_205 */
1131
1132			/*
1133			 * FIXME: handle time limit as well?
1134			 * Note that target servers are likely
1135			 * to handle it, so at some time we'll
1136			 * get a LDAP_TIMELIMIT_EXCEEDED from
1137			 * one of them ...
1138			 */
1139			tv = save_tv;
1140			rc = ldap_result( msc->msc_ld, candidates[ i ].sr_msgid,
1141					LDAP_MSG_RECEIVED, &tv, &res );
1142			switch ( rc ) {
1143			case 0:
1144				/* FIXME: res should not need to be freed */
1145				assert( res == NULL );
1146				continue;
1147
1148			case -1:
1149really_bad:;
1150				/* something REALLY bad happened! */
1151				if ( candidates[ i ].sr_type == REP_INTERMEDIATE ) {
1152					candidates[ i ].sr_type = REP_RESULT;
1153
1154					if ( meta_back_retry( op, rs, &mc, i, LDAP_BACK_DONTSEND ) ) {
1155						candidates[ i ].sr_msgid = META_MSGID_IGNORE;
1156						switch ( meta_back_search_start( op, rs, &dc, &mc, i, candidates, NULL, 0 ) )
1157						{
1158							/* means that failed but onerr == continue */
1159						case META_SEARCH_NOT_CANDIDATE:
1160							candidates[ i ].sr_msgid = META_MSGID_IGNORE;
1161
1162							assert( ncandidates > 0 );
1163							--ncandidates;
1164
1165							candidates[ i ].sr_err = rs->sr_err;
1166							if ( META_BACK_ONERR_STOP( mi ) ) {
1167								savepriv = op->o_private;
1168								op->o_private = (void *)i;
1169								send_ldap_result( op, rs );
1170								op->o_private = savepriv;
1171								goto finish;
1172							}
1173							/* fall thru */
1174
1175						case META_SEARCH_CANDIDATE:
1176							/* get back into business... */
1177							continue;
1178
1179						case META_SEARCH_BINDING:
1180						case META_SEARCH_CONNECTING:
1181						case META_SEARCH_NEED_BIND:
1182						case META_SEARCH_UNDEFINED:
1183							assert( 0 );
1184
1185						default:
1186							/* unrecoverable error */
1187							candidates[ i ].sr_msgid = META_MSGID_IGNORE;
1188							rc = rs->sr_err = LDAP_OTHER;
1189							goto finish;
1190						}
1191					}
1192
1193					candidates[ i ].sr_err = rs->sr_err;
1194					if ( META_BACK_ONERR_STOP( mi ) ) {
1195						savepriv = op->o_private;
1196						op->o_private = (void *)i;
1197						send_ldap_result( op, rs );
1198						op->o_private = savepriv;
1199						goto finish;
1200					}
1201				}
1202
1203				/*
1204				 * When no candidates are left,
1205				 * the outer cycle finishes
1206				 */
1207				candidates[ i ].sr_msgid = META_MSGID_IGNORE;
1208				assert( ncandidates > 0 );
1209				--ncandidates;
1210				rs->sr_err = candidates[ i ].sr_err;
1211				continue;
1212
1213			default:
1214				lastres_time = slap_get_time();
1215
1216				/* only touch when activity actually took place... */
1217				if ( mi->mi_idle_timeout != 0 && msc->msc_time < lastres_time ) {
1218					msc->msc_time = lastres_time;
1219				}
1220				break;
1221			}
1222
1223			for ( msg = ldap_first_message( msc->msc_ld, res );
1224				msg != NULL;
1225				msg = ldap_next_message( msc->msc_ld, msg ) )
1226			{
1227				rc = ldap_msgtype( msg );
1228				if ( rc == LDAP_RES_SEARCH_ENTRY ) {
1229					LDAPMessage	*e;
1230
1231					if ( candidates[ i ].sr_type == REP_INTERMEDIATE ) {
1232						/* don't retry any more... */
1233						candidates[ i ].sr_type = REP_RESULT;
1234					}
1235
1236					/* count entries returned by target */
1237					candidates[ i ].sr_nentries++;
1238
1239					is_ok++;
1240
1241					e = ldap_first_entry( msc->msc_ld, msg );
1242					savepriv = op->o_private;
1243					op->o_private = (void *)i;
1244					rs->sr_err = meta_send_entry( op, rs, mc, i, e );
1245
1246					switch ( rs->sr_err ) {
1247					case LDAP_SIZELIMIT_EXCEEDED:
1248						savepriv = op->o_private;
1249						op->o_private = (void *)i;
1250						send_ldap_result( op, rs );
1251						op->o_private = savepriv;
1252						rs->sr_err = LDAP_SUCCESS;
1253						ldap_msgfree( res );
1254						res = NULL;
1255						goto finish;
1256
1257					case LDAP_UNAVAILABLE:
1258						rs->sr_err = LDAP_OTHER;
1259						ldap_msgfree( res );
1260						res = NULL;
1261						goto finish;
1262					}
1263					op->o_private = savepriv;
1264
1265					/* don't wait any longer... */
1266					gotit = 1;
1267					save_tv.tv_sec = 0;
1268					save_tv.tv_usec = 0;
1269
1270				} else if ( rc == LDAP_RES_SEARCH_REFERENCE ) {
1271					char		**references = NULL;
1272					int		cnt;
1273
1274					if ( META_BACK_TGT_NOREFS( mi->mi_targets[ i ] ) ) {
1275						continue;
1276					}
1277
1278					if ( candidates[ i ].sr_type == REP_INTERMEDIATE ) {
1279						/* don't retry any more... */
1280						candidates[ i ].sr_type = REP_RESULT;
1281					}
1282
1283					is_ok++;
1284
1285					rc = ldap_parse_reference( msc->msc_ld, msg,
1286							&references, &rs->sr_ctrls, 0 );
1287
1288					if ( rc != LDAP_SUCCESS ) {
1289						continue;
1290					}
1291
1292					if ( references == NULL ) {
1293						continue;
1294					}
1295
1296#ifdef ENABLE_REWRITE
1297					dc.ctx = "referralDN";
1298#else /* ! ENABLE_REWRITE */
1299					dc.tofrom = 0;
1300					dc.normalized = 0;
1301#endif /* ! ENABLE_REWRITE */
1302
1303					/* FIXME: merge all and return at the end */
1304
1305					for ( cnt = 0; references[ cnt ]; cnt++ )
1306						;
1307
1308					rs->sr_ref = ber_memalloc_x( sizeof( struct berval ) * ( cnt + 1 ),
1309						op->o_tmpmemctx );
1310
1311					for ( cnt = 0; references[ cnt ]; cnt++ ) {
1312						ber_str2bv_x( references[ cnt ], 0, 1, &rs->sr_ref[ cnt ],
1313						op->o_tmpmemctx );
1314					}
1315					BER_BVZERO( &rs->sr_ref[ cnt ] );
1316
1317					( void )ldap_back_referral_result_rewrite( &dc, rs->sr_ref,
1318						op->o_tmpmemctx );
1319
1320					if ( rs->sr_ref != NULL && !BER_BVISNULL( &rs->sr_ref[ 0 ] ) ) {
1321						/* ignore return value by now */
1322						savepriv = op->o_private;
1323						op->o_private = (void *)i;
1324						( void )send_search_reference( op, rs );
1325						op->o_private = savepriv;
1326
1327						ber_bvarray_free_x( rs->sr_ref, op->o_tmpmemctx );
1328						rs->sr_ref = NULL;
1329					}
1330
1331					/* cleanup */
1332					if ( references ) {
1333						ber_memvfree( (void **)references );
1334					}
1335
1336					if ( rs->sr_ctrls ) {
1337						ldap_controls_free( rs->sr_ctrls );
1338						rs->sr_ctrls = NULL;
1339					}
1340
1341				} else if ( rc == LDAP_RES_INTERMEDIATE ) {
1342					if ( candidates[ i ].sr_type == REP_INTERMEDIATE ) {
1343						/* don't retry any more... */
1344						candidates[ i ].sr_type = REP_RESULT;
1345					}
1346
1347					/* FIXME: response controls
1348					 * are passed without checks */
1349					rs->sr_err = ldap_parse_intermediate( msc->msc_ld,
1350						msg,
1351						(char **)&rs->sr_rspoid,
1352						&rs->sr_rspdata,
1353						&rs->sr_ctrls,
1354						0 );
1355					if ( rs->sr_err != LDAP_SUCCESS ) {
1356						candidates[ i ].sr_type = REP_RESULT;
1357						ldap_msgfree( res );
1358						res = NULL;
1359						goto really_bad;
1360					}
1361
1362					slap_send_ldap_intermediate( op, rs );
1363
1364					if ( rs->sr_rspoid != NULL ) {
1365						ber_memfree( (char *)rs->sr_rspoid );
1366						rs->sr_rspoid = NULL;
1367					}
1368
1369					if ( rs->sr_rspdata != NULL ) {
1370						ber_bvfree( rs->sr_rspdata );
1371						rs->sr_rspdata = NULL;
1372					}
1373
1374					if ( rs->sr_ctrls != NULL ) {
1375						ldap_controls_free( rs->sr_ctrls );
1376						rs->sr_ctrls = NULL;
1377					}
1378
1379				} else if ( rc == LDAP_RES_SEARCH_RESULT ) {
1380					char		buf[ SLAP_TEXT_BUFLEN ];
1381					char		**references = NULL;
1382					LDAPControl	**ctrls = NULL;
1383
1384					if ( candidates[ i ].sr_type == REP_INTERMEDIATE ) {
1385						/* don't retry any more... */
1386						candidates[ i ].sr_type = REP_RESULT;
1387					}
1388
1389					candidates[ i ].sr_msgid = META_MSGID_IGNORE;
1390
1391					/* NOTE: ignores response controls
1392					 * (and intermediate response controls
1393					 * as well, except for those with search
1394					 * references); this may not be correct,
1395					 * but if they're not ignored then
1396					 * back-meta would need to merge them
1397					 * consistently (think of pagedResults...)
1398					 */
1399					/* FIXME: response controls? */
1400					rs->sr_err = ldap_parse_result( msc->msc_ld,
1401						msg,
1402						&candidates[ i ].sr_err,
1403						(char **)&candidates[ i ].sr_matched,
1404						(char **)&candidates[ i ].sr_text,
1405						&references,
1406						&ctrls /* &candidates[ i ].sr_ctrls (unused) */ ,
1407						0 );
1408					if ( rs->sr_err != LDAP_SUCCESS ) {
1409						candidates[ i ].sr_err = rs->sr_err;
1410						sres = slap_map_api2result( &candidates[ i ] );
1411						candidates[ i ].sr_type = REP_RESULT;
1412						ldap_msgfree( res );
1413						res = NULL;
1414						goto really_bad;
1415					}
1416
1417					rs->sr_err = candidates[ i ].sr_err;
1418
1419					/* massage matchedDN if need be */
1420					if ( candidates[ i ].sr_matched != NULL ) {
1421						struct berval	match, mmatch;
1422
1423						ber_str2bv( candidates[ i ].sr_matched,
1424							0, 0, &match );
1425						candidates[ i ].sr_matched = NULL;
1426
1427						dc.ctx = "matchedDN";
1428						dc.target = mi->mi_targets[ i ];
1429						if ( !ldap_back_dn_massage( &dc, &match, &mmatch ) ) {
1430							if ( mmatch.bv_val == match.bv_val ) {
1431								candidates[ i ].sr_matched
1432									= ch_strdup( mmatch.bv_val );
1433
1434							} else {
1435								candidates[ i ].sr_matched = mmatch.bv_val;
1436							}
1437
1438							candidate_match++;
1439						}
1440						ldap_memfree( match.bv_val );
1441					}
1442
1443					/* add references to array */
1444					/* RFC 4511: referrals can only appear
1445					 * if result code is LDAP_REFERRAL */
1446					if ( references != NULL
1447						&& references[ 0 ] != NULL
1448						&& references[ 0 ][ 0 ] != '\0' )
1449					{
1450						if ( rs->sr_err != LDAP_REFERRAL ) {
1451							Debug( LDAP_DEBUG_ANY,
1452								"%s meta_back_search[%ld]: "
1453								"got referrals with err=%d\n",
1454								op->o_log_prefix,
1455								i, rs->sr_err );
1456
1457						} else {
1458							BerVarray	sr_ref;
1459							int		cnt;
1460
1461							for ( cnt = 0; references[ cnt ]; cnt++ )
1462								;
1463
1464							sr_ref = ber_memalloc_x( sizeof( struct berval ) * ( cnt + 1 ),
1465								op->o_tmpmemctx );
1466
1467							for ( cnt = 0; references[ cnt ]; cnt++ ) {
1468								ber_str2bv_x( references[ cnt ], 0, 1, &sr_ref[ cnt ],
1469									op->o_tmpmemctx );
1470							}
1471							BER_BVZERO( &sr_ref[ cnt ] );
1472
1473							( void )ldap_back_referral_result_rewrite( &dc, sr_ref,
1474								op->o_tmpmemctx );
1475
1476							if ( rs->sr_v2ref == NULL ) {
1477								rs->sr_v2ref = sr_ref;
1478
1479							} else {
1480								for ( cnt = 0; !BER_BVISNULL( &sr_ref[ cnt ] ); cnt++ ) {
1481									ber_bvarray_add_x( &rs->sr_v2ref, &sr_ref[ cnt ],
1482										op->o_tmpmemctx );
1483								}
1484								ber_memfree_x( sr_ref, op->o_tmpmemctx );
1485							}
1486						}
1487
1488					} else if ( rs->sr_err == LDAP_REFERRAL ) {
1489						Debug( LDAP_DEBUG_ANY,
1490							"%s meta_back_search[%ld]: "
1491							"got err=%d with null "
1492							"or empty referrals\n",
1493							op->o_log_prefix,
1494							i, rs->sr_err );
1495
1496						rs->sr_err = LDAP_NO_SUCH_OBJECT;
1497					}
1498
1499					/* cleanup */
1500					ber_memvfree( (void **)references );
1501
1502					sres = slap_map_api2result( rs );
1503
1504					if ( LogTest( LDAP_DEBUG_TRACE | LDAP_DEBUG_ANY ) ) {
1505						snprintf( buf, sizeof( buf ),
1506							"%s meta_back_search[%ld] "
1507							"match=\"%s\" err=%ld",
1508							op->o_log_prefix, i,
1509							candidates[ i ].sr_matched ? candidates[ i ].sr_matched : "",
1510							(long) candidates[ i ].sr_err );
1511						if ( candidates[ i ].sr_err == LDAP_SUCCESS ) {
1512							Debug( LDAP_DEBUG_TRACE, "%s.\n", buf, 0, 0 );
1513
1514						} else {
1515							Debug( LDAP_DEBUG_ANY, "%s (%s).\n",
1516								buf, ldap_err2string( candidates[ i ].sr_err ), 0 );
1517						}
1518					}
1519
1520					switch ( sres ) {
1521					case LDAP_NO_SUCH_OBJECT:
1522						/* is_ok is touched any time a valid
1523						 * (even intermediate) result is
1524						 * returned; as a consequence, if
1525						 * a candidate returns noSuchObject
1526						 * it is ignored and the candidate
1527						 * is simply demoted. */
1528						if ( is_ok ) {
1529							sres = LDAP_SUCCESS;
1530						}
1531						break;
1532
1533					case LDAP_SUCCESS:
1534						if ( ctrls != NULL && ctrls[0] != NULL ) {
1535#ifdef SLAPD_META_CLIENT_PR
1536							LDAPControl *pr_c;
1537
1538							pr_c = ldap_control_find( LDAP_CONTROL_PAGEDRESULTS, ctrls, NULL );
1539							if ( pr_c != NULL ) {
1540								BerElementBuffer berbuf;
1541								BerElement *ber = (BerElement *)&berbuf;
1542								ber_tag_t tag;
1543								ber_int_t prsize;
1544								struct berval prcookie;
1545
1546								/* unsolicited, do not accept */
1547								if ( mi->mi_targets[i]->mt_ps == 0 ) {
1548									rs->sr_err = LDAP_OTHER;
1549									goto err_pr;
1550								}
1551
1552								ber_init2( ber, &pr_c->ldctl_value, LBER_USE_DER );
1553
1554								tag = ber_scanf( ber, "{im}", &prsize, &prcookie );
1555								if ( tag == LBER_ERROR ) {
1556									rs->sr_err = LDAP_OTHER;
1557									goto err_pr;
1558								}
1559
1560								/* more pages? new search request */
1561								if ( !BER_BVISNULL( &prcookie ) && !BER_BVISEMPTY( &prcookie ) ) {
1562									if ( mi->mi_targets[i]->mt_ps > 0 ) {
1563										/* ignore size if specified */
1564										prsize = 0;
1565
1566									} else if ( prsize == 0 ) {
1567										/* guess the page size from the entries returned so far */
1568										prsize = candidates[ i ].sr_nentries;
1569									}
1570
1571									candidates[ i ].sr_nentries = 0;
1572									candidates[ i ].sr_msgid = META_MSGID_IGNORE;
1573									candidates[ i ].sr_type = REP_INTERMEDIATE;
1574
1575									assert( candidates[ i ].sr_matched == NULL );
1576									assert( candidates[ i ].sr_text == NULL );
1577									assert( candidates[ i ].sr_ref == NULL );
1578
1579									switch ( meta_back_search_start( op, rs, &dc, &mc, i, candidates, &prcookie, prsize ) )
1580									{
1581									case META_SEARCH_CANDIDATE:
1582										assert( candidates[ i ].sr_msgid >= 0 );
1583										ldap_controls_free( ctrls );
1584										goto free_message;
1585
1586									case META_SEARCH_ERR:
1587err_pr:;
1588										candidates[ i ].sr_err = rs->sr_err;
1589										if ( META_BACK_ONERR_STOP( mi ) ) {
1590											savepriv = op->o_private;
1591											op->o_private = (void *)i;
1592											send_ldap_result( op, rs );
1593											op->o_private = savepriv;
1594											ldap_controls_free( ctrls );
1595											goto finish;
1596										}
1597										/* fallthru */
1598
1599									case META_SEARCH_NOT_CANDIDATE:
1600										/* means that meta_back_search_start()
1601										 * failed but onerr == continue */
1602										candidates[ i ].sr_msgid = META_MSGID_IGNORE;
1603										assert( ncandidates > 0 );
1604										--ncandidates;
1605										break;
1606
1607									default:
1608										/* impossible */
1609										assert( 0 );
1610										break;
1611									}
1612									break;
1613								}
1614							}
1615#endif /* SLAPD_META_CLIENT_PR */
1616
1617							ldap_controls_free( ctrls );
1618						}
1619						/* fallthru */
1620
1621					case LDAP_REFERRAL:
1622						is_ok++;
1623						break;
1624
1625					case LDAP_SIZELIMIT_EXCEEDED:
1626						/* if a target returned sizelimitExceeded
1627						 * and the entry count is equal to the
1628						 * proxy's limit, the target would have
1629						 * returned more, and the error must be
1630						 * propagated to the client; otherwise,
1631						 * the target enforced a limit lower
1632						 * than what requested by the proxy;
1633						 * ignore it */
1634						candidates[ i ].sr_err = rs->sr_err;
1635						if ( rs->sr_nentries == op->ors_slimit
1636							|| META_BACK_ONERR_STOP( mi ) )
1637						{
1638							const char *save_text = rs->sr_text;
1639							savepriv = op->o_private;
1640							op->o_private = (void *)i;
1641							rs->sr_text = candidates[ i ].sr_text;
1642							send_ldap_result( op, rs );
1643							rs->sr_text = save_text;
1644							op->o_private = savepriv;
1645							ldap_msgfree( res );
1646							res = NULL;
1647							goto finish;
1648						}
1649						break;
1650
1651					default:
1652						candidates[ i ].sr_err = rs->sr_err;
1653						if ( META_BACK_ONERR_STOP( mi ) ) {
1654							const char *save_text = rs->sr_text;
1655							savepriv = op->o_private;
1656							op->o_private = (void *)i;
1657							rs->sr_text = candidates[ i ].sr_text;
1658							send_ldap_result( op, rs );
1659							rs->sr_text = save_text;
1660							op->o_private = savepriv;
1661							ldap_msgfree( res );
1662							res = NULL;
1663							goto finish;
1664						}
1665						break;
1666					}
1667
1668					last = i;
1669					rc = 0;
1670
1671					/*
1672					 * When no candidates are left,
1673					 * the outer cycle finishes
1674					 */
1675					assert( ncandidates > 0 );
1676					--ncandidates;
1677
1678				} else if ( rc == LDAP_RES_BIND ) {
1679					meta_search_candidate_t	retcode;
1680
1681					retcode = meta_search_dobind_result( op, rs, &mc, i, candidates, msg );
1682					if ( retcode == META_SEARCH_CANDIDATE ) {
1683						candidates[ i ].sr_msgid = META_MSGID_IGNORE;
1684						retcode = meta_back_search_start( op, rs, &dc, &mc, i, candidates, NULL, 0 );
1685					}
1686
1687					switch ( retcode ) {
1688					case META_SEARCH_CANDIDATE:
1689						break;
1690
1691						/* means that failed but onerr == continue */
1692					case META_SEARCH_NOT_CANDIDATE:
1693					case META_SEARCH_ERR:
1694						candidates[ i ].sr_msgid = META_MSGID_IGNORE;
1695						assert( ncandidates > 0 );
1696						--ncandidates;
1697
1698						candidates[ i ].sr_err = rs->sr_err;
1699						if ( META_BACK_ONERR_STOP( mi ) ) {
1700							savepriv = op->o_private;
1701							op->o_private = (void *)i;
1702							send_ldap_result( op, rs );
1703							op->o_private = savepriv;
1704							ldap_msgfree( res );
1705							res = NULL;
1706							goto finish;
1707						}
1708						goto free_message;
1709
1710					default:
1711						assert( 0 );
1712						break;
1713					}
1714
1715				} else {
1716					Debug( LDAP_DEBUG_ANY,
1717						"%s meta_back_search[%ld]: "
1718						"unrecognized response message tag=%d\n",
1719						op->o_log_prefix,
1720						i, rc );
1721
1722					ldap_msgfree( res );
1723					res = NULL;
1724					goto really_bad;
1725				}
1726			}
1727
1728free_message:;
1729			ldap_msgfree( res );
1730			res = NULL;
1731		}
1732
1733		/* check for abandon */
1734		if ( op->o_abandon || LDAP_BACK_CONN_ABANDON( mc ) ) {
1735			for ( i = 0; i < mi->mi_ntargets; i++ ) {
1736				if ( candidates[ i ].sr_msgid >= 0
1737					|| candidates[ i ].sr_msgid == META_MSGID_CONNECTING )
1738				{
1739					if ( META_IS_BINDING( &candidates[ i ] )
1740						|| candidates[ i ].sr_msgid == META_MSGID_CONNECTING )
1741					{
1742						ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex );
1743						if ( LDAP_BACK_CONN_BINDING( &mc->mc_conns[ i ] )
1744							|| candidates[ i ].sr_msgid == META_MSGID_CONNECTING )
1745						{
1746							/* if still binding, destroy */
1747
1748#ifdef DEBUG_205
1749							char buf[ SLAP_TEXT_BUFLEN ];
1750
1751							snprintf( buf, sizeof( buf), "%s meta_back_search(abandon) "
1752								"ldap_unbind_ext[%ld] mc=%p ld=%p",
1753								op->o_log_prefix, i, (void *)mc,
1754								(void *)mc->mc_conns[i].msc_ld );
1755
1756							Debug( LDAP_DEBUG_ANY, "### %s\n", buf, 0, 0 );
1757#endif /* DEBUG_205 */
1758
1759							meta_clear_one_candidate( op, mc, i );
1760						}
1761						ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
1762						META_BINDING_CLEAR( &candidates[ i ] );
1763
1764					} else {
1765						(void)meta_back_cancel( mc, op, rs,
1766							candidates[ i ].sr_msgid, i,
1767							LDAP_BACK_DONTSEND );
1768					}
1769
1770					candidates[ i ].sr_msgid = META_MSGID_IGNORE;
1771					assert( ncandidates > 0 );
1772					--ncandidates;
1773				}
1774			}
1775
1776			if ( op->o_abandon ) {
1777				rc = SLAPD_ABANDON;
1778			}
1779
1780			/* let send_ldap_result play cleanup handlers (ITS#4645) */
1781			break;
1782		}
1783
1784		/* if no entry was found during this loop,
1785		 * set a minimal timeout */
1786		if ( ncandidates > 0 && gotit == 0 ) {
1787			if ( save_tv.tv_sec == 0 && save_tv.tv_usec == 0 ) {
1788				save_tv.tv_usec = LDAP_BACK_RESULT_UTIMEOUT/initial_candidates;
1789
1790				/* arbitrarily limit to something between 1 and 2 minutes */
1791			} else if ( ( stoptime == -1 && save_tv.tv_sec < 60 )
1792				|| save_tv.tv_sec < ( stoptime - slap_get_time() ) / ( 2 * ncandidates ) )
1793			{
1794				/* double the timeout */
1795				lutil_timermul( &save_tv, 2, &save_tv );
1796			}
1797
1798			if ( alreadybound == 0 ) {
1799				tv = save_tv;
1800				(void)select( 0, NULL, NULL, NULL, &tv );
1801
1802			} else {
1803				ldap_pvt_thread_yield();
1804			}
1805		}
1806	}
1807
1808	if ( rc == -1 ) {
1809		/*
1810		 * FIXME: need a better strategy to handle errors
1811		 */
1812		if ( mc ) {
1813			rc = meta_back_op_result( mc, op, rs, META_TARGET_NONE,
1814				-1, stoptime != -1 ? (stoptime - slap_get_time()) : 0,
1815				LDAP_BACK_SENDERR );
1816		} else {
1817			rc = rs->sr_err;
1818		}
1819		goto finish;
1820	}
1821
1822	/*
1823	 * Rewrite the matched portion of the search base, if required
1824	 *
1825	 * FIXME: only the last one gets caught!
1826	 */
1827	savepriv = op->o_private;
1828	op->o_private = (void *)(long)mi->mi_ntargets;
1829	if ( candidate_match > 0 ) {
1830		struct berval	pmatched = BER_BVNULL;
1831
1832		/* we use the first one */
1833		for ( i = 0; i < mi->mi_ntargets; i++ ) {
1834			if ( META_IS_CANDIDATE( &candidates[ i ] )
1835					&& candidates[ i ].sr_matched != NULL )
1836			{
1837				struct berval	bv, pbv;
1838				int		rc;
1839
1840				/* if we got success, and this target
1841				 * returned noSuchObject, and its suffix
1842				 * is a superior of the searchBase,
1843				 * ignore the matchedDN */
1844				if ( sres == LDAP_SUCCESS
1845					&& candidates[ i ].sr_err == LDAP_NO_SUCH_OBJECT
1846					&& op->o_req_ndn.bv_len > mi->mi_targets[ i ]->mt_nsuffix.bv_len )
1847				{
1848					free( (char *)candidates[ i ].sr_matched );
1849					candidates[ i ].sr_matched = NULL;
1850					continue;
1851				}
1852
1853				ber_str2bv( candidates[ i ].sr_matched, 0, 0, &bv );
1854				rc = dnPretty( NULL, &bv, &pbv, op->o_tmpmemctx );
1855
1856				if ( rc == LDAP_SUCCESS ) {
1857
1858					/* NOTE: if they all are superiors
1859					 * of the baseDN, the shorter is also
1860					 * superior of the longer... */
1861					if ( pbv.bv_len > pmatched.bv_len ) {
1862						if ( !BER_BVISNULL( &pmatched ) ) {
1863							op->o_tmpfree( pmatched.bv_val, op->o_tmpmemctx );
1864						}
1865						pmatched = pbv;
1866						op->o_private = (void *)i;
1867
1868					} else {
1869						op->o_tmpfree( pbv.bv_val, op->o_tmpmemctx );
1870					}
1871				}
1872
1873				if ( candidates[ i ].sr_matched != NULL ) {
1874					free( (char *)candidates[ i ].sr_matched );
1875					candidates[ i ].sr_matched = NULL;
1876				}
1877			}
1878		}
1879
1880		if ( !BER_BVISNULL( &pmatched ) ) {
1881			matched = pmatched.bv_val;
1882		}
1883
1884	} else if ( sres == LDAP_NO_SUCH_OBJECT ) {
1885		matched = op->o_bd->be_suffix[ 0 ].bv_val;
1886	}
1887
1888	/*
1889	 * In case we returned at least one entry, we return LDAP_SUCCESS
1890	 * otherwise, the latter error code we got
1891	 */
1892
1893	if ( sres == LDAP_SUCCESS ) {
1894		if ( rs->sr_v2ref ) {
1895			sres = LDAP_REFERRAL;
1896		}
1897
1898		if ( META_BACK_ONERR_REPORT( mi ) ) {
1899			/*
1900			 * Report errors, if any
1901			 *
1902			 * FIXME: we should handle error codes and return the more
1903			 * important/reasonable
1904			 */
1905			for ( i = 0; i < mi->mi_ntargets; i++ ) {
1906				if ( !META_IS_CANDIDATE( &candidates[ i ] ) ) {
1907					continue;
1908				}
1909
1910				if ( candidates[ i ].sr_err != LDAP_SUCCESS
1911					&& candidates[ i ].sr_err != LDAP_NO_SUCH_OBJECT )
1912				{
1913					sres = candidates[ i ].sr_err;
1914					break;
1915				}
1916			}
1917		}
1918	}
1919
1920	rs->sr_err = sres;
1921	rs->sr_matched = ( sres == LDAP_SUCCESS ? NULL : matched );
1922	rs->sr_ref = ( sres == LDAP_REFERRAL ? rs->sr_v2ref : NULL );
1923	send_ldap_result( op, rs );
1924	op->o_private = savepriv;
1925	rs->sr_matched = NULL;
1926	rs->sr_ref = NULL;
1927
1928finish:;
1929	if ( matched && matched != op->o_bd->be_suffix[ 0 ].bv_val ) {
1930		op->o_tmpfree( matched, op->o_tmpmemctx );
1931	}
1932
1933	if ( rs->sr_v2ref ) {
1934		ber_bvarray_free_x( rs->sr_v2ref, op->o_tmpmemctx );
1935	}
1936
1937	for ( i = 0; i < mi->mi_ntargets; i++ ) {
1938		if ( !META_IS_CANDIDATE( &candidates[ i ] ) ) {
1939			continue;
1940		}
1941
1942		if ( mc ) {
1943			if ( META_IS_BINDING( &candidates[ i ] )
1944				|| candidates[ i ].sr_msgid == META_MSGID_CONNECTING )
1945			{
1946				ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex );
1947				if ( LDAP_BACK_CONN_BINDING( &mc->mc_conns[ i ] )
1948					|| candidates[ i ].sr_msgid == META_MSGID_CONNECTING )
1949				{
1950					assert( candidates[ i ].sr_msgid >= 0
1951						|| candidates[ i ].sr_msgid == META_MSGID_CONNECTING );
1952					assert( mc->mc_conns[ i ].msc_ld != NULL );
1953
1954#ifdef DEBUG_205
1955					Debug( LDAP_DEBUG_ANY, "### %s meta_back_search(cleanup) "
1956						"ldap_unbind_ext[%ld] ld=%p\n",
1957						op->o_log_prefix, i, (void *)mc->mc_conns[i].msc_ld );
1958#endif /* DEBUG_205 */
1959
1960					/* if still binding, destroy */
1961					meta_clear_one_candidate( op, mc, i );
1962				}
1963				ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
1964				META_BINDING_CLEAR( &candidates[ i ] );
1965
1966			} else if ( candidates[ i ].sr_msgid >= 0 ) {
1967				(void)meta_back_cancel( mc, op, rs,
1968					candidates[ i ].sr_msgid, i,
1969					LDAP_BACK_DONTSEND );
1970			}
1971		}
1972
1973		if ( candidates[ i ].sr_matched ) {
1974			free( (char *)candidates[ i ].sr_matched );
1975			candidates[ i ].sr_matched = NULL;
1976		}
1977
1978		if ( candidates[ i ].sr_text ) {
1979			ldap_memfree( (char *)candidates[ i ].sr_text );
1980			candidates[ i ].sr_text = NULL;
1981		}
1982
1983		if ( candidates[ i ].sr_ref ) {
1984			ber_bvarray_free( candidates[ i ].sr_ref );
1985			candidates[ i ].sr_ref = NULL;
1986		}
1987
1988		if ( candidates[ i ].sr_ctrls ) {
1989			ldap_controls_free( candidates[ i ].sr_ctrls );
1990			candidates[ i ].sr_ctrls = NULL;
1991		}
1992
1993		if ( META_BACK_TGT_QUARANTINE( mi->mi_targets[ i ] ) ) {
1994			meta_back_quarantine( op, &candidates[ i ], i );
1995		}
1996
1997		/* only in case of timelimit exceeded, if the timelimit exceeded because
1998		 * one contacted target never responded, invalidate the connection
1999		 * NOTE: should we quarantine the target as well?  right now, the connection
2000		 * is invalidated; the next time it will be recreated and the target
2001		 * will be quarantined if it cannot be contacted */
2002		if ( mi->mi_idle_timeout != 0
2003			&& rs->sr_err == LDAP_TIMELIMIT_EXCEEDED
2004			&& op->o_time > mc->mc_conns[ i ].msc_time )
2005		{
2006			/* don't let anyone else use this expired connection */
2007			do_taint++;
2008		}
2009	}
2010
2011	if ( mc ) {
2012		ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex );
2013		if ( do_taint ) {
2014			LDAP_BACK_CONN_TAINTED_SET( mc );
2015		}
2016		meta_back_release_conn_lock( mi, mc, 0 );
2017		ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
2018	}
2019
2020	return rs->sr_err;
2021}
2022
2023static int
2024meta_send_entry(
2025	Operation 	*op,
2026	SlapReply	*rs,
2027	metaconn_t	*mc,
2028	int 		target,
2029	LDAPMessage 	*e )
2030{
2031	metainfo_t 		*mi = ( metainfo_t * )op->o_bd->be_private;
2032	struct berval		a, mapped;
2033	int			check_duplicate_attrs = 0;
2034	int			check_sorted_attrs = 0;
2035	Entry 			ent = { 0 };
2036	BerElement 		ber = *ldap_get_message_ber( e );
2037	Attribute 		*attr, **attrp;
2038	struct berval 		bdn,
2039				dn = BER_BVNULL;
2040	const char 		*text;
2041	dncookie		dc;
2042	ber_len_t		len;
2043	int			rc;
2044
2045	if ( ber_scanf( &ber, "l{", &len ) == LBER_ERROR ) {
2046		return LDAP_DECODING_ERROR;
2047	}
2048
2049	if ( ber_set_option( &ber, LBER_OPT_REMAINING_BYTES, &len ) != LBER_OPT_SUCCESS ) {
2050		return LDAP_OTHER;
2051	}
2052
2053	if ( ber_scanf( &ber, "m{", &bdn ) == LBER_ERROR ) {
2054		return LDAP_DECODING_ERROR;
2055	}
2056
2057	/*
2058	 * Rewrite the dn of the result, if needed
2059	 */
2060	dc.target = mi->mi_targets[ target ];
2061	dc.conn = op->o_conn;
2062	dc.rs = rs;
2063	dc.ctx = "searchResult";
2064
2065	rs->sr_err = ldap_back_dn_massage( &dc, &bdn, &dn );
2066	if ( rs->sr_err != LDAP_SUCCESS) {
2067		return rs->sr_err;
2068	}
2069
2070	/*
2071	 * Note: this may fail if the target host(s) schema differs
2072	 * from the one known to the meta, and a DN with unknown
2073	 * attributes is returned.
2074	 *
2075	 * FIXME: should we log anything, or delegate to dnNormalize?
2076	 */
2077	rc = dnPrettyNormal( NULL, &dn, &ent.e_name, &ent.e_nname,
2078		op->o_tmpmemctx );
2079	if ( dn.bv_val != bdn.bv_val ) {
2080		free( dn.bv_val );
2081	}
2082	BER_BVZERO( &dn );
2083
2084	if ( rc != LDAP_SUCCESS ) {
2085		Debug( LDAP_DEBUG_ANY,
2086			"%s meta_send_entry(\"%s\"): "
2087			"invalid DN syntax\n",
2088			op->o_log_prefix, ent.e_name.bv_val, 0 );
2089		rc = LDAP_INVALID_DN_SYNTAX;
2090		goto done;
2091	}
2092
2093	/*
2094	 * cache dn
2095	 */
2096	if ( mi->mi_cache.ttl != META_DNCACHE_DISABLED ) {
2097		( void )meta_dncache_update_entry( &mi->mi_cache,
2098				&ent.e_nname, target );
2099	}
2100
2101	attrp = &ent.e_attrs;
2102
2103	dc.ctx = "searchAttrDN";
2104	while ( ber_scanf( &ber, "{m", &a ) != LBER_ERROR ) {
2105		int				last = 0;
2106		slap_syntax_validate_func	*validate;
2107		slap_syntax_transform_func	*pretty;
2108
2109		if ( ber_pvt_ber_remaining( &ber ) < 0 ) {
2110			Debug( LDAP_DEBUG_ANY,
2111				"%s meta_send_entry(\"%s\"): "
2112				"unable to parse attr \"%s\".\n",
2113				op->o_log_prefix, ent.e_name.bv_val, a.bv_val );
2114
2115			rc = LDAP_OTHER;
2116			goto done;
2117		}
2118
2119		if ( ber_pvt_ber_remaining( &ber ) == 0 ) {
2120			break;
2121		}
2122
2123		ldap_back_map( &mi->mi_targets[ target ]->mt_rwmap.rwm_at,
2124				&a, &mapped, BACKLDAP_REMAP );
2125		if ( BER_BVISNULL( &mapped ) || mapped.bv_val[0] == '\0' ) {
2126			( void )ber_scanf( &ber, "x" /* [W] */ );
2127			continue;
2128		}
2129		if ( mapped.bv_val != a.bv_val ) {
2130			/* will need to check for duplicate attrs */
2131			check_duplicate_attrs++;
2132		}
2133		attr = attr_alloc( NULL );
2134		if ( attr == NULL ) {
2135			rc = LDAP_OTHER;
2136			goto done;
2137		}
2138		if ( slap_bv2ad( &mapped, &attr->a_desc, &text )
2139				!= LDAP_SUCCESS) {
2140			if ( slap_bv2undef_ad( &mapped, &attr->a_desc, &text,
2141				SLAP_AD_PROXIED ) != LDAP_SUCCESS )
2142			{
2143				char	buf[ SLAP_TEXT_BUFLEN ];
2144
2145				snprintf( buf, sizeof( buf ),
2146					"%s meta_send_entry(\"%s\"): "
2147					"slap_bv2undef_ad(%s): %s\n",
2148					op->o_log_prefix, ent.e_name.bv_val,
2149					mapped.bv_val, text );
2150
2151				Debug( LDAP_DEBUG_ANY, "%s", buf, 0, 0 );
2152				( void )ber_scanf( &ber, "x" /* [W] */ );
2153				attr_free( attr );
2154				continue;
2155			}
2156		}
2157
2158		if ( attr->a_desc->ad_type->sat_flags & SLAP_AT_SORTED_VAL )
2159			check_sorted_attrs = 1;
2160
2161		/* no subschemaSubentry */
2162		if ( attr->a_desc == slap_schema.si_ad_subschemaSubentry
2163			|| attr->a_desc == slap_schema.si_ad_entryDN )
2164		{
2165
2166			/*
2167			 * We eat target's subschemaSubentry because
2168			 * a search for this value is likely not
2169			 * to resolve to the appropriate backend;
2170			 * later, the local subschemaSubentry is
2171			 * added.
2172			 *
2173			 * We also eat entryDN because the frontend
2174			 * will reattach it without checking if already
2175			 * present...
2176			 */
2177			( void )ber_scanf( &ber, "x" /* [W] */ );
2178			attr_free(attr);
2179			continue;
2180		}
2181
2182		if ( ber_scanf( &ber, "[W]", &attr->a_vals ) == LBER_ERROR
2183				|| attr->a_vals == NULL )
2184		{
2185			attr->a_vals = (struct berval *)&slap_dummy_bv;
2186
2187		} else {
2188			for ( last = 0; !BER_BVISNULL( &attr->a_vals[ last ] ); ++last )
2189				;
2190		}
2191		attr->a_numvals = last;
2192
2193		validate = attr->a_desc->ad_type->sat_syntax->ssyn_validate;
2194		pretty = attr->a_desc->ad_type->sat_syntax->ssyn_pretty;
2195
2196		if ( !validate && !pretty ) {
2197			attr_free( attr );
2198			goto next_attr;
2199		}
2200
2201		if ( attr->a_desc == slap_schema.si_ad_objectClass
2202				|| attr->a_desc == slap_schema.si_ad_structuralObjectClass )
2203		{
2204			struct berval 	*bv;
2205
2206			for ( bv = attr->a_vals; !BER_BVISNULL( bv ); bv++ ) {
2207				ObjectClass *oc;
2208
2209				ldap_back_map( &mi->mi_targets[ target ]->mt_rwmap.rwm_oc,
2210						bv, &mapped, BACKLDAP_REMAP );
2211				if ( BER_BVISNULL( &mapped ) || mapped.bv_val[0] == '\0') {
2212remove_oc:;
2213					free( bv->bv_val );
2214					BER_BVZERO( bv );
2215					if ( --last < 0 ) {
2216						break;
2217					}
2218					*bv = attr->a_vals[ last ];
2219					BER_BVZERO( &attr->a_vals[ last ] );
2220					bv--;
2221
2222				} else if ( mapped.bv_val != bv->bv_val ) {
2223					int	i;
2224
2225					for ( i = 0; !BER_BVISNULL( &attr->a_vals[ i ] ); i++ ) {
2226						if ( &attr->a_vals[ i ] == bv ) {
2227							continue;
2228						}
2229
2230						if ( ber_bvstrcasecmp( &mapped, &attr->a_vals[ i ] ) == 0 ) {
2231							break;
2232						}
2233					}
2234
2235					if ( !BER_BVISNULL( &attr->a_vals[ i ] ) ) {
2236						goto remove_oc;
2237					}
2238
2239					ber_bvreplace( bv, &mapped );
2240
2241				} else if ( ( oc = oc_bvfind_undef( bv ) ) == NULL ) {
2242					goto remove_oc;
2243
2244				} else {
2245					ber_bvreplace( bv, &oc->soc_cname );
2246				}
2247			}
2248		/*
2249		 * It is necessary to try to rewrite attributes with
2250		 * dn syntax because they might be used in ACLs as
2251		 * members of groups; since ACLs are applied to the
2252		 * rewritten stuff, no dn-based subecj clause could
2253		 * be used at the ldap backend side (see
2254		 * http://www.OpenLDAP.org/faq/data/cache/452.html)
2255		 * The problem can be overcome by moving the dn-based
2256		 * ACLs to the target directory server, and letting
2257		 * everything pass thru the ldap backend.
2258		 */
2259		} else {
2260			int	i;
2261
2262			if ( attr->a_desc->ad_type->sat_syntax ==
2263				slap_schema.si_syn_distinguishedName )
2264			{
2265				ldap_dnattr_result_rewrite( &dc, attr->a_vals );
2266
2267			} else if ( attr->a_desc == slap_schema.si_ad_ref ) {
2268				ldap_back_referral_result_rewrite( &dc, attr->a_vals, NULL );
2269
2270			}
2271
2272			for ( i = 0; i < last; i++ ) {
2273				struct berval	pval;
2274				int		rc;
2275
2276				if ( pretty ) {
2277					rc = ordered_value_pretty( attr->a_desc,
2278						&attr->a_vals[i], &pval, NULL );
2279
2280				} else {
2281					rc = ordered_value_validate( attr->a_desc,
2282						&attr->a_vals[i], 0 );
2283				}
2284
2285				if ( rc ) {
2286					ber_memfree( attr->a_vals[i].bv_val );
2287					if ( --last == i ) {
2288						BER_BVZERO( &attr->a_vals[ i ] );
2289						break;
2290					}
2291					attr->a_vals[i] = attr->a_vals[last];
2292					BER_BVZERO( &attr->a_vals[last] );
2293					i--;
2294					continue;
2295				}
2296
2297				if ( pretty ) {
2298					ber_memfree( attr->a_vals[i].bv_val );
2299					attr->a_vals[i] = pval;
2300				}
2301			}
2302
2303			if ( last == 0 && attr->a_vals != &slap_dummy_bv ) {
2304				attr_free( attr );
2305				goto next_attr;
2306			}
2307		}
2308
2309		if ( last && attr->a_desc->ad_type->sat_equality &&
2310			attr->a_desc->ad_type->sat_equality->smr_normalize )
2311		{
2312			int i;
2313
2314			attr->a_nvals = ch_malloc( ( last + 1 ) * sizeof( struct berval ) );
2315			for ( i = 0; i<last; i++ ) {
2316				/* if normalizer fails, drop this value */
2317				if ( ordered_value_normalize(
2318					SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
2319					attr->a_desc,
2320					attr->a_desc->ad_type->sat_equality,
2321					&attr->a_vals[i], &attr->a_nvals[i],
2322					NULL )) {
2323					ber_memfree( attr->a_vals[i].bv_val );
2324					if ( --last == i ) {
2325						BER_BVZERO( &attr->a_vals[ i ] );
2326						break;
2327					}
2328					attr->a_vals[i] = attr->a_vals[last];
2329					BER_BVZERO( &attr->a_vals[last] );
2330					i--;
2331				}
2332			}
2333			BER_BVZERO( &attr->a_nvals[i] );
2334			if ( last == 0 ) {
2335				attr_free( attr );
2336				goto next_attr;
2337			}
2338
2339		} else {
2340			attr->a_nvals = attr->a_vals;
2341		}
2342
2343		attr->a_numvals = last;
2344		*attrp = attr;
2345		attrp = &attr->a_next;
2346next_attr:;
2347	}
2348
2349	/* only check if some mapping occurred */
2350	if ( check_duplicate_attrs ) {
2351		Attribute	**ap;
2352
2353		for ( ap = &ent.e_attrs; *ap != NULL; ap = &(*ap)->a_next ) {
2354			Attribute	**tap;
2355
2356			for ( tap = &(*ap)->a_next; *tap != NULL; ) {
2357				if ( (*tap)->a_desc == (*ap)->a_desc ) {
2358					Entry		e = { 0 };
2359					Modification	mod = { 0 };
2360					const char	*text = NULL;
2361					char		textbuf[ SLAP_TEXT_BUFLEN ];
2362					Attribute	*next = (*tap)->a_next;
2363
2364					BER_BVSTR( &e.e_name, "" );
2365					BER_BVSTR( &e.e_nname, "" );
2366					e.e_attrs = *ap;
2367					mod.sm_op = LDAP_MOD_ADD;
2368					mod.sm_desc = (*ap)->a_desc;
2369					mod.sm_type = mod.sm_desc->ad_cname;
2370					mod.sm_numvals = (*ap)->a_numvals;
2371					mod.sm_values = (*tap)->a_vals;
2372					if ( (*tap)->a_nvals != (*tap)->a_vals ) {
2373						mod.sm_nvalues = (*tap)->a_nvals;
2374					}
2375
2376					(void)modify_add_values( &e, &mod,
2377						/* permissive */ 1,
2378						&text, textbuf, sizeof( textbuf ) );
2379
2380					/* should not insert new attrs! */
2381					assert( e.e_attrs == *ap );
2382
2383					attr_free( *tap );
2384					*tap = next;
2385
2386				} else {
2387					tap = &(*tap)->a_next;
2388				}
2389			}
2390		}
2391	}
2392
2393	/* Check for sorted attributes */
2394	if ( check_sorted_attrs ) {
2395		for ( attr = ent.e_attrs; attr; attr = attr->a_next ) {
2396			if ( attr->a_desc->ad_type->sat_flags & SLAP_AT_SORTED_VAL ) {
2397				while ( attr->a_numvals > 1 ) {
2398					int i;
2399					int rc = slap_sort_vals( (Modifications *)attr, &text, &i, op->o_tmpmemctx );
2400					if ( rc != LDAP_TYPE_OR_VALUE_EXISTS )
2401						break;
2402
2403					/* Strip duplicate values */
2404					if ( attr->a_nvals != attr->a_vals )
2405						ber_memfree( attr->a_nvals[i].bv_val );
2406					ber_memfree( attr->a_vals[i].bv_val );
2407					attr->a_numvals--;
2408					if ( (unsigned)i < attr->a_numvals ) {
2409						attr->a_vals[i] = attr->a_vals[attr->a_numvals];
2410						if ( attr->a_nvals != attr->a_vals )
2411							attr->a_nvals[i] = attr->a_nvals[attr->a_numvals];
2412					}
2413					BER_BVZERO(&attr->a_vals[attr->a_numvals]);
2414					if ( attr->a_nvals != attr->a_vals )
2415						BER_BVZERO(&attr->a_nvals[attr->a_numvals]);
2416				}
2417				attr->a_flags |= SLAP_ATTR_SORTED_VALS;
2418			}
2419		}
2420	}
2421
2422	ldap_get_entry_controls( mc->mc_conns[target].msc_ld,
2423		e, &rs->sr_ctrls );
2424	rs->sr_entry = &ent;
2425	rs->sr_attrs = op->ors_attrs;
2426	rs->sr_operational_attrs = NULL;
2427	rs->sr_flags = mi->mi_targets[ target ]->mt_rep_flags;
2428	rs->sr_err = LDAP_SUCCESS;
2429	rc = send_search_entry( op, rs );
2430	switch ( rc ) {
2431	case LDAP_UNAVAILABLE:
2432		rc = LDAP_OTHER;
2433		break;
2434	}
2435
2436done:;
2437	rs->sr_entry = NULL;
2438	rs->sr_attrs = NULL;
2439	if ( rs->sr_ctrls != NULL ) {
2440		ldap_controls_free( rs->sr_ctrls );
2441		rs->sr_ctrls = NULL;
2442	}
2443	if ( !BER_BVISNULL( &ent.e_name ) ) {
2444		free( ent.e_name.bv_val );
2445		BER_BVZERO( &ent.e_name );
2446	}
2447	if ( !BER_BVISNULL( &ent.e_nname ) ) {
2448		free( ent.e_nname.bv_val );
2449		BER_BVZERO( &ent.e_nname );
2450	}
2451	entry_clean( &ent );
2452
2453	return rc;
2454}
2455
2456