]> git.sur5r.net Git - openldap/blob - servers/slapd/back-meta/candidates.c
Update copyright statements
[openldap] / servers / slapd / back-meta / candidates.c
1 /*
2  * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
3  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
4  *
5  * Copyright 2001, Pierangelo Masarati, All rights reserved. <ando@sys-net.it>
6  *
7  * This work has been developed to fulfill the requirements
8  * of SysNet s.n.c. <http:www.sys-net.it> and it has been donated
9  * to the OpenLDAP Foundation in the hope that it may be useful
10  * to the Open Source community, but WITHOUT ANY WARRANTY.
11  *
12  * Permission is granted to anyone to use this software for any purpose
13  * on any computer system, and to alter it and redistribute it, subject
14  * to the following restrictions:
15  *
16  * 1. The author and SysNet s.n.c. are not responsible for the consequences
17  *    of use of this software, no matter how awful, even if they arise from 
18  *    flaws in it.
19  *
20  * 2. The origin of this software must not be misrepresented, either by
21  *    explicit claim or by omission.  Since few users ever read sources,
22  *    credits should appear in the documentation.
23  *
24  * 3. Altered versions must be plainly marked as such, and must not be
25  *    misrepresented as being the original software.  Since few users
26  *    ever read sources, credits should appear in the documentation.
27  *    SysNet s.n.c. cannot be responsible for the consequences of the
28  *    alterations.
29  *
30  * 4. This notice may not be removed or altered.
31  *
32  *
33  * This software is based on the backend back-ldap, implemented
34  * by Howard Chu <hyc@highlandsun.com>, and modified by Mark Valence
35  * <kurash@sassafras.com>, Pierangelo Masarati <ando@sys-net.it> and other
36  * contributors. The contribution of the original software to the present
37  * implementation is acknowledged in this copyright statement.
38  *
39  * A special acknowledgement goes to Howard for the overall architecture
40  * (and for borrowing large pieces of code), and to Mark, who implemented
41  * from scratch the attribute/objectclass mapping.
42  *
43  * The original copyright statement follows.
44  *
45  * Copyright 1999, Howard Chu, All rights reserved. <hyc@highlandsun.com>
46  *
47  * Permission is granted to anyone to use this software for any purpose
48  * on any computer system, and to alter it and redistribute it, subject
49  * to the following restrictions:
50  *
51  * 1. The author is not responsible for the consequences of use of this
52  *    software, no matter how awful, even if they arise from flaws in it.
53  *
54  * 2. The origin of this software must not be misrepresented, either by
55  *    explicit claim or by omission.  Since few users ever read sources,
56  *    credits should appear in the documentation.
57  *
58  * 3. Altered versions must be plainly marked as such, and must not be
59  *    misrepresented as being the original software.  Since few users
60  *    ever read sources, credits should appear in the
61  *    documentation.
62  *
63  * 4. This notice may not be removed or altered.
64  *                
65  */
66
67 #include "portable.h"
68
69 #include <stdio.h>
70
71 #include "slap.h"
72 #include "../back-ldap/back-ldap.h"
73 #include "back-meta.h"
74
75 /*
76  * The meta-directory has one suffix, called <suffix>.
77  * It handles a pool of target servers, each with a branch suffix
78  * of the form <branch X>,<suffix>
79  *
80  * When the meta-directory receives a request with a dn that belongs
81  * to a branch, the corresponding target is invoked. When the dn
82  * does not belong to a specific branch, all the targets that
83  * are compatible with the dn are selected as candidates, and
84  * the request is spawned to all the candidate targets
85  *
86  * A request is characterized by a dn. The following cases are handled:
87  *      - the dn is the suffix: <dn> == <suffix>,
88  *              all the targets are candidates (search ...)
89  *      - the dn is a branch suffix: <dn> == <branch X>,<suffix>, or
90  *      - the dn is a subtree of a branch suffix:
91  *              <dn> == <rdn>,<branch X>,<suffix>,
92  *              the target is the only candidate.
93  *
94  * A possible extension will include the handling of multiple suffixes
95  */
96
97 /*
98  * returns 1 if suffix is candidate for dn, otherwise 0
99  *
100  * Note: this function should never be called if dn is the <suffix>.
101  */
102 int 
103 meta_back_is_candidate(
104                 struct berval   *nsuffix,
105                 struct berval   *ndn
106 )
107 {
108         if ( dnIsSuffix( nsuffix, ndn ) || dnIsSuffix( ndn, nsuffix ) ) {
109                 /*
110                  * suffix longer than dn
111                  */
112                 return META_CANDIDATE;
113         }
114
115         return META_NOT_CANDIDATE;
116 }
117
118 /*
119  * meta_back_count_candidates
120  *
121  * returns a count of the possible candidate targets
122  * Note: dn MUST be normalized
123  */
124
125 int
126 meta_back_count_candidates(
127                 struct metainfo         *li,
128                 struct berval           *ndn
129 )
130 {
131         int i, cnt = 0;
132
133         /*
134          * I know assertions should not check run-time values;
135          * at present I didn't find a place for such checks
136          * after config.c
137          */
138         assert( li->targets != NULL );
139         assert( li->ntargets != 0 );
140
141         for ( i = 0; i < li->ntargets; ++i ) {
142                 if ( meta_back_is_candidate( &li->targets[ i ]->suffix, ndn ) ) {
143                         ++cnt;
144                 }
145         }
146
147         return cnt;
148 }
149
150 /*
151  * meta_back_is_candidate_unique
152  *
153  * checks whether a candidate is unique
154  * Note: dn MUST be normalized
155  */
156 int
157 meta_back_is_candidate_unique(
158                 struct metainfo         *li,
159                 struct berval           *ndn
160 )
161 {
162         return ( meta_back_count_candidates( li, ndn ) == 1 );
163 }
164
165 /*
166  * meta_back_select_unique_candidate
167  *
168  * returns the index of the candidate in case it is unique, otherwise -1
169  * Note: dn MUST be normalized.
170  * Note: if defined, the default candidate is returned in case of no match.
171  */
172 int
173 meta_back_select_unique_candidate(
174                 struct metainfo         *li,
175                 struct berval           *ndn
176 )
177 {
178         int i;
179         
180         switch ( meta_back_count_candidates( li, ndn ) ) {
181         case 1:
182                 break;
183         case 0:
184         default:
185                 return ( li->defaulttarget == META_DEFAULT_TARGET_NONE
186                                 ? -1 : li->defaulttarget );
187         }
188
189         for ( i = 0; i < li->ntargets; ++i ) {
190                 if ( meta_back_is_candidate( &li->targets[ i ]->suffix, ndn ) ) {
191                         return i;
192                 }
193         }
194
195         return -1;
196 }
197
198 /*
199  * meta_clear_unused_candidates
200  *
201  * clears all candidates except candidate
202  */
203 int
204 meta_clear_unused_candidates(
205                 struct metainfo         *li,
206                 struct metaconn         *lc,
207                 int                     candidate,
208                 int                     reallyclean
209 )
210 {
211         int i;
212         
213         for ( i = 0; i < li->ntargets; ++i ) {
214                 if ( i == candidate ) {
215                         continue;
216                 }
217                 meta_clear_one_candidate( lc->conns[ i ], reallyclean );
218         }
219
220         return 0;
221 }
222
223 /*
224  * meta_clear_one_candidate
225  *
226  * clears the selected candidate
227  */
228 int
229 meta_clear_one_candidate(
230                 struct metasingleconn   *lsc,
231                 int                     reallyclean
232 )
233 {
234         lsc->candidate = META_NOT_CANDIDATE;
235
236         if ( !reallyclean ) {
237                 return 0;
238         }
239
240         if ( lsc->ld ) {
241                 ldap_unbind( lsc->ld );
242                 lsc->ld = NULL;
243         }
244
245         if ( lsc->bound_dn != NULL ) {
246                 ber_bvfree( lsc->bound_dn );
247                 lsc->bound_dn = NULL;
248         }
249
250         return 0;
251 }
252