]> git.sur5r.net Git - openldap/blob - servers/slapd/value.c
SLAP_NVALUES: more fixes
[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         return LDAP_SUCCESS;
172 }
173
174 #else
175 int
176 value_validate(
177         MatchingRule *mr,
178         struct berval *in,
179         const char **text )
180 {
181         int rc;
182
183         if( mr == NULL ) {
184                 *text = "inappropriate matching request";
185                 return LDAP_INAPPROPRIATE_MATCHING;
186         }
187
188         if( mr->smr_syntax == NULL ) {
189                 *text = "no assertion syntax";
190                 return LDAP_INVALID_SYNTAX;
191         }
192
193         if( ! mr->smr_syntax->ssyn_validate ) {
194                 *text = "no syntax validator";
195                 return LDAP_INVALID_SYNTAX;
196         }
197
198         rc = (mr->smr_syntax->ssyn_validate)( mr->smr_syntax, in );
199
200         if( rc != LDAP_SUCCESS ) {
201                 *text = "value is invalid";
202                 return LDAP_INVALID_SYNTAX;
203         }
204
205         return LDAP_SUCCESS;
206 }
207
208 int
209 value_normalize(
210         AttributeDescription *ad,
211         unsigned usage,
212         struct berval *in,
213         struct berval *out,
214         const char **text )
215 {
216         int rc;
217         MatchingRule *mr = ad_mr( ad, usage );
218
219         if( mr == NULL ) {
220                 *text = "inappropriate matching request";
221                 return LDAP_INAPPROPRIATE_MATCHING;
222         }
223
224         /* we only support equality matching of binary attributes */
225         /* This is suspect, flexible certificate matching will hit this */
226         if( slap_ad_is_binary( ad ) && usage != SLAP_MR_EQUALITY ) {
227                 *text = "inappropriate binary matching";
228                 return LDAP_INAPPROPRIATE_MATCHING;
229         }
230
231         if( mr->smr_normalize ) {
232                 rc = (mr->smr_normalize)( usage,
233                         ad->ad_type->sat_syntax,
234                         mr, in, out );
235
236                 if( rc != LDAP_SUCCESS ) {
237                         *text = "unable to normalize value";
238                         return LDAP_INVALID_SYNTAX;
239                 }
240
241         } else if ( mr->smr_syntax->ssyn_normalize ) {
242                 rc = (mr->smr_syntax->ssyn_normalize)(
243                         ad->ad_type->sat_syntax,
244                         in, out );
245
246                 if( rc != LDAP_SUCCESS ) {
247                         *text = "unable to normalize value";
248                         return LDAP_INVALID_SYNTAX;
249                 }
250
251         } else {
252                 ber_dupbv( out, in );
253         }
254
255         return LDAP_SUCCESS;
256 }
257
258 int
259 value_validate_normalize(
260         AttributeDescription *ad,
261         unsigned usage,
262         struct berval *in,
263         struct berval *out,
264         const char **text )
265 {
266         int rc;
267         MatchingRule *mr = ad_mr( ad, usage );
268
269         if( mr == NULL ) {
270                 *text = "inappropriate matching request";
271                 return LDAP_INAPPROPRIATE_MATCHING;
272         }
273
274         if( mr->smr_syntax == NULL ) {
275                 *text = "no assertion syntax";
276                 return LDAP_INVALID_SYNTAX;
277         }
278
279         if( ! mr->smr_syntax->ssyn_validate ) {
280                 *text = "no syntax validator";
281                 return LDAP_INVALID_SYNTAX;
282         }
283
284         rc = (mr->smr_syntax->ssyn_validate)( mr->smr_syntax, in );
285
286         if( rc != LDAP_SUCCESS ) {
287                 *text = "value is invalid";
288                 return LDAP_INVALID_SYNTAX;
289         }
290
291         /* we only support equality matching of binary attributes */
292         /* This is suspect, flexible certificate matching will hit this */
293         if( slap_ad_is_binary( ad ) && usage != SLAP_MR_EQUALITY ) {
294                 *text = "inappropriate binary matching";
295                 return LDAP_INAPPROPRIATE_MATCHING;
296         }
297
298         if( mr->smr_normalize ) {
299                 rc = (mr->smr_normalize)( usage,
300                         ad->ad_type->sat_syntax,
301                         mr, in, out );
302
303                 if( rc != LDAP_SUCCESS ) {
304                         *text = "unable to normalize value";
305                         return LDAP_INVALID_SYNTAX;
306                 }
307
308         } else if ( mr->smr_syntax->ssyn_normalize ) {
309                 rc = (mr->smr_syntax->ssyn_normalize)(
310                         ad->ad_type->sat_syntax,
311                         in, out );
312
313                 if( rc != LDAP_SUCCESS ) {
314                         *text = "unable to normalize value";
315                         return LDAP_INVALID_SYNTAX;
316                 }
317
318         } else {
319                 ber_dupbv( out, in );
320         }
321
322         return LDAP_SUCCESS;
323 }
324 #endif
325
326 int
327 value_match(
328         int *match,
329         AttributeDescription *ad,
330         MatchingRule *mr,
331         unsigned flags,
332         struct berval *v1, /* stored value */
333         void *v2, /* assertion */
334         const char ** text )
335 {
336         int rc;
337         struct berval nv1 = { 0, NULL };
338         struct berval nv2 = { 0, NULL };
339
340         assert( mr != NULL );
341
342         if( !mr->smr_match ) {
343                 return LDAP_INAPPROPRIATE_MATCHING;
344         }
345
346 #ifndef SLAP_NVALUES
347         if( ad->ad_type->sat_syntax->ssyn_normalize ) {
348                 rc = ad->ad_type->sat_syntax->ssyn_normalize(
349                         ad->ad_type->sat_syntax, v1, &nv1 );
350
351                 if( rc != LDAP_SUCCESS ) {
352                         return LDAP_INAPPROPRIATE_MATCHING;
353                 }
354         }
355
356         if ( SLAP_IS_MR_ATTRIBUTE_SYNTAX_NONCONVERTED_MATCH( flags ) &&
357                 mr->smr_convert )
358         {
359                 rc = (mr->smr_convert)( v2, &nv2 );
360                 if ( rc != LDAP_SUCCESS ) {
361                         return LDAP_INVALID_SYNTAX;
362                 }
363
364                 /* let smr_match know we've converted the value */
365                 flags |= SLAP_MR_ATTRIBUTE_SYNTAX_CONVERTED_MATCH;
366         }
367 #endif
368
369         rc = (mr->smr_match)( match, flags,
370                 ad->ad_type->sat_syntax,
371                 mr,
372                 nv1.bv_val != NULL ? &nv1 : v1,
373                 nv2.bv_val != NULL ? &nv2 : v2 );
374         
375         if (nv1.bv_val ) free( nv1.bv_val );
376         if (nv2.bv_val ) free( nv2.bv_val );
377         return rc;
378 }
379
380 int value_find_ex(
381         AttributeDescription *ad,
382         unsigned flags,
383         BerVarray vals,
384         struct berval *val )
385 {
386         int     i;
387         int rc;
388         struct berval nval = { 0, NULL };
389         MatchingRule *mr = ad->ad_type->sat_equality;
390
391         if( mr == NULL || !mr->smr_match ) {
392                 return LDAP_INAPPROPRIATE_MATCHING;
393         }
394
395 #ifdef SLAP_NVALUES
396         assert(SLAP_IS_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH( flags ));
397
398         if( !SLAP_IS_MR_ASSERTED_VALUE_NORMALIZED_MATCH( flags ) &&
399                 mr->smr_normalize )
400         {
401                 rc = (mr->smr_normalize)(
402                         flags & SLAP_MR_TYPE_MASK|SLAP_MR_SUBTYPE_MASK,
403                         ad ? ad->ad_type->sat_syntax : NULL,
404                         mr, val, &nval );
405
406                 if( rc != LDAP_SUCCESS ) {
407                         return LDAP_INVALID_SYNTAX;
408                 }
409         }
410 #else
411
412         /* Take care of this here or ssyn_normalize later will hurt */
413         if ( SLAP_IS_MR_ATTRIBUTE_SYNTAX_NONCONVERTED_MATCH( flags )
414                 && mr->smr_convert )
415         {
416                 rc = (mr->smr_convert)( val, &nval );
417                 if ( rc != LDAP_SUCCESS ) {
418                         return LDAP_INVALID_SYNTAX;
419                 }
420
421                 /* let value_match know we've done the version */
422                 flags |= SLAP_MR_ATTRIBUTE_SYNTAX_CONVERTED_MATCH;
423         }
424
425         if( !(flags & SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH) &&
426                 mr->smr_syntax->ssyn_normalize )
427         {
428                 struct berval nval_tmp = { 0, NULL };
429
430                 rc = mr->smr_syntax->ssyn_normalize(
431                         mr->smr_syntax,
432                         nval.bv_val == NULL ? val : &nval, &nval_tmp );
433
434                 free(nval.bv_val);
435                 nval = nval_tmp;
436                 if( rc != LDAP_SUCCESS ) {
437                         free(nval.bv_val);
438                         return LDAP_INAPPROPRIATE_MATCHING;
439                 }
440         }
441 #endif
442
443         for ( i = 0; vals[i].bv_val != NULL; i++ ) {
444                 int match;
445                 const char *text;
446
447                 rc = value_match( &match, ad, mr, flags,
448                         &vals[i], nval.bv_val == NULL ? val : &nval, &text );
449
450                 if( rc == LDAP_SUCCESS && match == 0 ) {
451                         free( nval.bv_val );
452                         return LDAP_SUCCESS;
453                 }
454         }
455
456         free( nval.bv_val );
457         return LDAP_NO_SUCH_ATTRIBUTE;
458 }