]> git.sur5r.net Git - openldap/blob - servers/slapd/value.c
NVALUES: fix a couple of value_find_ex() calls
[openldap] / servers / slapd / value.c
1 /* value.c - routines for dealing with values */
2 /* $OpenLDAP$ */
3 /*
4  * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
5  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
6  */
7
8 #include "portable.h"
9
10 #include <stdio.h>
11
12 #include <ac/ctype.h>
13 #include <ac/socket.h>
14 #include <ac/string.h>
15 #include <ac/time.h>
16
17 #include <sys/stat.h>
18
19 #include "slap.h"
20
21 int
22 value_add( 
23     BerVarray *vals,
24     BerVarray addvals
25 )
26 {
27         int     n, nn;
28         BerVarray v2;
29
30         for ( nn = 0; addvals != NULL && addvals[nn].bv_val != NULL; nn++ )
31                 ;       /* NULL */
32
33         if ( *vals == NULL ) {
34                 *vals = (BerVarray) SLAP_MALLOC( (nn + 1)
35                     * sizeof(struct berval) );
36                 if( *vals == NULL ) {
37 #ifdef NEW_LOGGING
38                          LDAP_LOG( OPERATION, ERR,
39                       "value_add: SLAP_MALLOC failed.\n", 0, 0, 0 );
40 #else
41                         Debug(LDAP_DEBUG_TRACE,
42                       "value_add: SLAP_MALLOC failed.\n", 0, 0, 0 );
43 #endif
44                         return LBER_ERROR_MEMORY;
45                 }
46                 n = 0;
47         } else {
48                 for ( n = 0; (*vals)[n].bv_val != NULL; n++ ) {
49                         ;       /* Empty */
50                 }
51                 *vals = (BerVarray) SLAP_REALLOC( (char *) *vals,
52                     (n + nn + 1) * sizeof(struct berval) );
53                 if( *vals == NULL ) {
54 #ifdef NEW_LOGGING
55                          LDAP_LOG( OPERATION, ERR,
56                       "value_add: SLAP_MALLOC failed.\n", 0, 0, 0 );
57 #else
58                         Debug(LDAP_DEBUG_TRACE,
59                       "value_add: SLAP_MALLOC failed.\n", 0, 0, 0 );
60 #endif
61                         return LBER_ERROR_MEMORY;
62                 }
63         }
64
65         v2 = *vals + n;
66         for ( ; addvals->bv_val; v2++, addvals++ ) {
67                 ber_dupbv(v2, addvals);
68                 if (v2->bv_val == NULL) break;
69         }
70         v2->bv_val = NULL;
71         v2->bv_len = 0;
72
73         return LDAP_SUCCESS;
74 }
75
76 int
77 value_add_one( 
78     BerVarray *vals,
79     struct berval *addval
80 )
81 {
82         int     n;
83         BerVarray v2;
84
85         if ( *vals == NULL ) {
86                 *vals = (BerVarray) SLAP_MALLOC( 2 * sizeof(struct berval) );
87                 if( *vals == NULL ) {
88 #ifdef NEW_LOGGING
89                          LDAP_LOG( OPERATION, ERR,
90                       "value_add_one: SLAP_MALLOC failed.\n", 0, 0, 0 );
91 #else
92                         Debug(LDAP_DEBUG_TRACE,
93                       "value_add_one: SLAP_MALLOC failed.\n", 0, 0, 0 );
94 #endif
95                         return LBER_ERROR_MEMORY;
96                 }
97                 n = 0;
98         } else {
99                 for ( n = 0; (*vals)[n].bv_val != NULL; n++ ) {
100                         ;       /* Empty */
101                 }
102                 *vals = (BerVarray) SLAP_REALLOC( (char *) *vals,
103                     (n + 2) * sizeof(struct berval) );
104                 if( *vals == NULL ) {
105 #ifdef NEW_LOGGING
106                          LDAP_LOG( OPERATION, ERR,
107                       "value_add_one: SLAP_MALLOC failed.\n", 0, 0, 0 );
108 #else
109                         Debug(LDAP_DEBUG_TRACE,
110                       "value_add_one: SLAP_MALLOC failed.\n", 0, 0, 0 );
111 #endif
112                         return LBER_ERROR_MEMORY;
113                 }
114         }
115
116         v2 = *vals + n;
117         ber_dupbv(v2, addval);
118
119         v2++;
120         v2->bv_val = NULL;
121         v2->bv_len = 0;
122
123         return LDAP_SUCCESS;
124 }
125
126 #ifdef SLAP_NVALUES
127 int asserted_value_validate_normalize( 
128         AttributeDescription *ad,
129         MatchingRule *mr,
130         unsigned usage,
131         struct berval *in,
132         struct berval *out,
133         const char ** text )
134 {
135         int rc;
136
137         /* we expect the value to be in the assertion syntax */
138         assert( !SLAP_MR_IS_VALUE_OF_ATTRIBUTE_SYNTAX(usage) );
139
140         if( mr == NULL ) {
141                 *text = "inappropriate matching request";
142                 return LDAP_INAPPROPRIATE_MATCHING;
143         }
144
145         if( !mr->smr_match ) {
146                 *text = "requested matching rule not supported";
147                 return LDAP_INAPPROPRIATE_MATCHING;
148         }
149
150         rc = (mr->smr_syntax->ssyn_validate)( mr->smr_syntax, in );
151
152         if( rc != LDAP_SUCCESS ) {
153                 *text = "value does not conform to assertion syntax";
154                 return LDAP_INVALID_SYNTAX;
155         }
156
157         if( mr->smr_normalize ) {
158                 rc = (mr->smr_normalize)( usage,
159                         ad ? ad->ad_type->sat_syntax : NULL,
160                         mr, in, out );
161
162                 if( rc != LDAP_SUCCESS ) {
163                         *text = "unable to normalize value for matching";
164                         return LDAP_INVALID_SYNTAX;
165                 }
166
167         } else {
168                 ber_dupbv( out, in );
169         }
170 }
171
172 #else
173 int
174 value_validate(
175         MatchingRule *mr,
176         struct berval *in,
177         const char **text )
178 {
179         int rc;
180
181         if( mr == NULL ) {
182                 *text = "inappropriate matching request";
183                 return LDAP_INAPPROPRIATE_MATCHING;
184         }
185
186         if( mr->smr_syntax == NULL ) {
187                 *text = "no assertion syntax";
188                 return LDAP_INVALID_SYNTAX;
189         }
190
191         if( ! mr->smr_syntax->ssyn_validate ) {
192                 *text = "no syntax validator";
193                 return LDAP_INVALID_SYNTAX;
194         }
195
196         rc = (mr->smr_syntax->ssyn_validate)( mr->smr_syntax, in );
197
198         if( rc != LDAP_SUCCESS ) {
199                 *text = "value is invalid";
200                 return LDAP_INVALID_SYNTAX;
201         }
202
203         return LDAP_SUCCESS;
204 }
205
206 int
207 value_normalize(
208         AttributeDescription *ad,
209         unsigned usage,
210         struct berval *in,
211         struct berval *out,
212         const char **text )
213 {
214         int rc;
215         MatchingRule *mr = ad_mr( ad, usage );
216
217         if( mr == NULL ) {
218                 *text = "inappropriate matching request";
219                 return LDAP_INAPPROPRIATE_MATCHING;
220         }
221
222         /* we only support equality matching of binary attributes */
223         /* This is suspect, flexible certificate matching will hit this */
224         if( slap_ad_is_binary( ad ) && usage != SLAP_MR_EQUALITY ) {
225                 *text = "inappropriate binary matching";
226                 return LDAP_INAPPROPRIATE_MATCHING;
227         }
228
229         if( mr->smr_normalize ) {
230                 rc = (mr->smr_normalize)( usage,
231                         ad->ad_type->sat_syntax,
232                         mr, in, out );
233
234                 if( rc != LDAP_SUCCESS ) {
235                         *text = "unable to normalize value";
236                         return LDAP_INVALID_SYNTAX;
237                 }
238
239         } else if ( mr->smr_syntax->ssyn_normalize ) {
240                 rc = (mr->smr_syntax->ssyn_normalize)(
241                         ad->ad_type->sat_syntax,
242                         in, out );
243
244                 if( rc != LDAP_SUCCESS ) {
245                         *text = "unable to normalize value";
246                         return LDAP_INVALID_SYNTAX;
247                 }
248
249         } else {
250                 ber_dupbv( out, in );
251         }
252
253         return LDAP_SUCCESS;
254 }
255
256 int
257 value_validate_normalize(
258         AttributeDescription *ad,
259         unsigned usage,
260         struct berval *in,
261         struct berval *out,
262         const char **text )
263 {
264         int rc;
265         MatchingRule *mr = ad_mr( ad, usage );
266
267         if( mr == NULL ) {
268                 *text = "inappropriate matching request";
269                 return LDAP_INAPPROPRIATE_MATCHING;
270         }
271
272         if( mr->smr_syntax == NULL ) {
273                 *text = "no assertion syntax";
274                 return LDAP_INVALID_SYNTAX;
275         }
276
277         if( ! mr->smr_syntax->ssyn_validate ) {
278                 *text = "no syntax validator";
279                 return LDAP_INVALID_SYNTAX;
280         }
281
282         rc = (mr->smr_syntax->ssyn_validate)( mr->smr_syntax, in );
283
284         if( rc != LDAP_SUCCESS ) {
285                 *text = "value is invalid";
286                 return LDAP_INVALID_SYNTAX;
287         }
288
289         /* we only support equality matching of binary attributes */
290         /* This is suspect, flexible certificate matching will hit this */
291         if( slap_ad_is_binary( ad ) && usage != SLAP_MR_EQUALITY ) {
292                 *text = "inappropriate binary matching";
293                 return LDAP_INAPPROPRIATE_MATCHING;
294         }
295
296         if( mr->smr_normalize ) {
297                 rc = (mr->smr_normalize)( usage,
298                         ad->ad_type->sat_syntax,
299                         mr, in, out );
300
301                 if( rc != LDAP_SUCCESS ) {
302                         *text = "unable to normalize value";
303                         return LDAP_INVALID_SYNTAX;
304                 }
305
306         } else if ( mr->smr_syntax->ssyn_normalize ) {
307                 rc = (mr->smr_syntax->ssyn_normalize)(
308                         ad->ad_type->sat_syntax,
309                         in, out );
310
311                 if( rc != LDAP_SUCCESS ) {
312                         *text = "unable to normalize value";
313                         return LDAP_INVALID_SYNTAX;
314                 }
315
316         } else {
317                 ber_dupbv( out, in );
318         }
319
320         return LDAP_SUCCESS;
321 }
322 #endif
323
324 int
325 value_match(
326         int *match,
327         AttributeDescription *ad,
328         MatchingRule *mr,
329         unsigned flags,
330         struct berval *v1, /* stored value */
331         void *v2, /* assertion */
332         const char ** text )
333 {
334         int rc;
335         struct berval nv1 = { 0, NULL };
336         struct berval nv2 = { 0, NULL };
337
338         assert( mr != NULL );
339
340         if( !mr->smr_match ) {
341                 return LDAP_INAPPROPRIATE_MATCHING;
342         }
343
344 #ifndef SLAP_NVALUES
345         if( ad->ad_type->sat_syntax->ssyn_normalize ) {
346                 rc = ad->ad_type->sat_syntax->ssyn_normalize(
347                         ad->ad_type->sat_syntax, v1, &nv1 );
348
349                 if( rc != LDAP_SUCCESS ) {
350                         return LDAP_INAPPROPRIATE_MATCHING;
351                 }
352         }
353
354         if ( SLAP_IS_MR_ATTRIBUTE_SYNTAX_NONCONVERTED_MATCH( flags ) &&
355                 mr->smr_convert )
356         {
357                 rc = (mr->smr_convert)( v2, &nv2 );
358                 if ( rc != LDAP_SUCCESS ) {
359                         return LDAP_INVALID_SYNTAX;
360                 }
361
362                 /* let smr_match know we've converted the value */
363                 flags |= SLAP_MR_ATTRIBUTE_SYNTAX_CONVERTED_MATCH;
364         }
365 #endif
366
367         rc = (mr->smr_match)( match, flags,
368                 ad->ad_type->sat_syntax,
369                 mr,
370                 nv1.bv_val != NULL ? &nv1 : v1,
371                 nv2.bv_val != NULL ? &nv2 : v2 );
372         
373         if (nv1.bv_val ) free( nv1.bv_val );
374         if (nv2.bv_val ) free( nv2.bv_val );
375         return rc;
376 }
377
378 int value_find_ex(
379         AttributeDescription *ad,
380         unsigned flags,
381         BerVarray vals,
382         struct berval *val )
383 {
384         int     i;
385         int rc;
386         struct berval nval = { 0, NULL };
387         MatchingRule *mr = ad->ad_type->sat_equality;
388
389         if( mr == NULL || !mr->smr_match ) {
390                 return LDAP_INAPPROPRIATE_MATCHING;
391         }
392
393 #ifdef SLAP_NVALUES
394         assert(SLAP_IS_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH( flags ));
395
396         if( !SLAP_IS_MR_ASSERTED_VALUE_NORMALIZED_MATCH( flags ) &&
397                 mr->smr_normalize )
398         {
399                 rc = (mr->smr_normalize)(
400                         flags & SLAP_MR_TYPE_MASK|SLAP_MR_SUBTYPE_MASK,
401                         ad ? ad->ad_type->sat_syntax : NULL,
402                         mr, val, &nval );
403
404                 if( rc != LDAP_SUCCESS ) {
405                         return LDAP_INVALID_SYNTAX;
406                 }
407         }
408 #else
409
410         /* Take care of this here or ssyn_normalize later will hurt */
411         if ( SLAP_IS_MR_ATTRIBUTE_SYNTAX_NONCONVERTED_MATCH( flags )
412                 && mr->smr_convert )
413         {
414                 rc = (mr->smr_convert)( val, &nval );
415                 if ( rc != LDAP_SUCCESS ) {
416                         return LDAP_INVALID_SYNTAX;
417                 }
418
419                 /* let value_match know we've done the version */
420                 flags |= SLAP_MR_ATTRIBUTE_SYNTAX_CONVERTED_MATCH;
421         }
422
423         if( !(flags & SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH) &&
424                 mr->smr_syntax->ssyn_normalize )
425         {
426                 struct berval nval_tmp = { 0, NULL };
427
428                 rc = mr->smr_syntax->ssyn_normalize(
429                         mr->smr_syntax,
430                         nval.bv_val == NULL ? val : &nval, &nval_tmp );
431
432                 free(nval.bv_val);
433                 nval = nval_tmp;
434                 if( rc != LDAP_SUCCESS ) {
435                         free(nval.bv_val);
436                         return LDAP_INAPPROPRIATE_MATCHING;
437                 }
438         }
439 #endif
440
441         for ( i = 0; vals[i].bv_val != NULL; i++ ) {
442                 int match;
443                 const char *text;
444
445                 rc = value_match( &match, ad, mr, flags,
446                         &vals[i], nval.bv_val == NULL ? val : &nval, &text );
447
448                 if( rc == LDAP_SUCCESS && match == 0 ) {
449                         free( nval.bv_val );
450                         return LDAP_SUCCESS;
451                 }
452         }
453
454         free( nval.bv_val );
455         return LDAP_NO_SUCH_ATTRIBUTE;
456 }