2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4 * Copyright 1999-2003 The OpenLDAP Foundation.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted only as authorized by the OpenLDAP
11 * A copy of this license is available in the file LICENSE in the
12 * top-level directory of the distribution or, alternatively, at
13 * <http://www.OpenLDAP.org/license.html>.
16 * This work was initially developed by the Howard Chu for inclusion
17 * in OpenLDAP Software and subsequently enhanced by Pierangelo
20 /* This is an altered version */
22 * Copyright 2001, Pierangelo Masarati, All rights reserved. <ando@sys-net.it>
24 * This work has been developed to fulfill the requirements
25 * of SysNet s.n.c. <http:www.sys-net.it> and it has been donated
26 * to the OpenLDAP Foundation in the hope that it may be useful
27 * to the Open Source community, but WITHOUT ANY WARRANTY.
29 * Permission is granted to anyone to use this software for any purpose
30 * on any computer system, and to alter it and redistribute it, subject
31 * to the following restrictions:
33 * 1. The author and SysNet s.n.c. are not responsible for the consequences
34 * of use of this software, no matter how awful, even if they arise from
37 * 2. The origin of this software must not be misrepresented, either by
38 * explicit claim or by omission. Since few users ever read sources,
39 * credits should appear in the documentation.
41 * 3. Altered versions must be plainly marked as such, and must not be
42 * misrepresented as being the original software. Since few users
43 * ever read sources, credits should appear in the documentation.
44 * SysNet s.n.c. cannot be responsible for the consequences of the
47 * 4. This notice may not be removed or altered.
50 * This software is based on the backend back-ldap, implemented
51 * by Howard Chu <hyc@highlandsun.com>, and modified by Mark Valence
52 * <kurash@sassafras.com>, Pierangelo Masarati <ando@sys-net.it> and other
53 * contributors. The contribution of the original software to the present
54 * implementation is acknowledged in this copyright statement.
56 * A special acknowledgement goes to Howard for the overall architecture
57 * (and for borrowing large pieces of code), and to Mark, who implemented
58 * from scratch the attribute/objectclass mapping.
60 * The original copyright statement follows.
62 * Copyright 1999, Howard Chu, All rights reserved. <hyc@highlandsun.com>
64 * Permission is granted to anyone to use this software for any purpose
65 * on any computer system, and to alter it and redistribute it, subject
66 * to the following restrictions:
68 * 1. The author is not responsible for the consequences of use of this
69 * software, no matter how awful, even if they arise from flaws in it.
71 * 2. The origin of this software must not be misrepresented, either by
72 * explicit claim or by omission. Since few users ever read sources,
73 * credits should appear in the documentation.
75 * 3. Altered versions must be plainly marked as such, and must not be
76 * misrepresented as being the original software. Since few users
77 * ever read sources, credits should appear in the
80 * 4. This notice may not be removed or altered.
89 #include "../back-ldap/back-ldap.h"
90 #include "back-meta.h"
93 * The meta-directory has one suffix, called <suffix>.
94 * It handles a pool of target servers, each with a branch suffix
95 * of the form <branch X>,<suffix>
97 * When the meta-directory receives a request with a dn that belongs
98 * to a branch, the corresponding target is invoked. When the dn
99 * does not belong to a specific branch, all the targets that
100 * are compatible with the dn are selected as candidates, and
101 * the request is spawned to all the candidate targets
103 * A request is characterized by a dn. The following cases are handled:
104 * - the dn is the suffix: <dn> == <suffix>,
105 * all the targets are candidates (search ...)
106 * - the dn is a branch suffix: <dn> == <branch X>,<suffix>, or
107 * - the dn is a subtree of a branch suffix:
108 * <dn> == <rdn>,<branch X>,<suffix>,
109 * the target is the only candidate.
111 * A possible extension will include the handling of multiple suffixes
115 * returns 1 if suffix is candidate for dn, otherwise 0
117 * Note: this function should never be called if dn is the <suffix>.
120 meta_back_is_candidate(
121 struct berval *nsuffix,
125 if ( dnIsSuffix( nsuffix, ndn ) || dnIsSuffix( ndn, nsuffix ) ) {
127 * suffix longer than dn
129 return META_CANDIDATE;
132 return META_NOT_CANDIDATE;
136 * meta_back_count_candidates
138 * returns a count of the possible candidate targets
139 * Note: dn MUST be normalized
143 meta_back_count_candidates(
151 * I know assertions should not check run-time values;
152 * at present I didn't find a place for such checks
155 assert( li->targets != NULL );
156 assert( li->ntargets != 0 );
158 for ( i = 0; i < li->ntargets; ++i ) {
159 if ( meta_back_is_candidate( &li->targets[ i ]->suffix, ndn ) ) {
168 * meta_back_is_candidate_unique
170 * checks whether a candidate is unique
171 * Note: dn MUST be normalized
174 meta_back_is_candidate_unique(
179 return ( meta_back_count_candidates( li, ndn ) == 1 );
183 * meta_back_select_unique_candidate
185 * returns the index of the candidate in case it is unique, otherwise -1
186 * Note: dn MUST be normalized.
187 * Note: if defined, the default candidate is returned in case of no match.
190 meta_back_select_unique_candidate(
197 switch ( meta_back_count_candidates( li, ndn ) ) {
202 return ( li->defaulttarget == META_DEFAULT_TARGET_NONE
203 ? -1 : li->defaulttarget );
206 for ( i = 0; i < li->ntargets; ++i ) {
207 if ( meta_back_is_candidate( &li->targets[ i ]->suffix, ndn ) ) {
216 * meta_clear_unused_candidates
218 * clears all candidates except candidate
221 meta_clear_unused_candidates(
230 for ( i = 0; i < li->ntargets; ++i ) {
231 if ( i == candidate ) {
234 meta_clear_one_candidate( &lc->conns[ i ], reallyclean );
241 * meta_clear_one_candidate
243 * clears the selected candidate
246 meta_clear_one_candidate(
247 struct metasingleconn *lsc,
251 lsc->candidate = META_NOT_CANDIDATE;
253 if ( !reallyclean ) {
258 ldap_unbind( lsc->ld );
262 if ( lsc->bound_dn.bv_val != NULL ) {
263 ber_memfree( lsc->bound_dn.bv_val );
264 lsc->bound_dn.bv_val = NULL;
265 lsc->bound_dn.bv_len = 0;