]> git.sur5r.net Git - openldap/blob - servers/slapd/value.c
Misc changes from HEAD
[openldap] / servers / slapd / value.c
1 /* value.c - routines for dealing with values */
2 /* $OpenLDAP$ */
3 /*
4  * Copyright 1998-2002 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 int
127 value_validate(
128         MatchingRule *mr,
129         struct berval *in,
130         const char **text )
131 {
132         int rc;
133
134         if( mr == NULL ) {
135                 *text = "inappropriate matching request";
136                 return LDAP_INAPPROPRIATE_MATCHING;
137         }
138
139         if( mr->smr_syntax == NULL ) {
140                 *text = "no assertion syntax";
141                 return LDAP_INVALID_SYNTAX;
142         }
143
144         if( ! mr->smr_syntax->ssyn_validate ) {
145                 *text = "no syntax validator";
146                 return LDAP_INVALID_SYNTAX;
147         }
148
149         rc = (mr->smr_syntax->ssyn_validate)( mr->smr_syntax, in );
150
151         if( rc != LDAP_SUCCESS ) {
152                 *text = "value is invalid";
153                 return LDAP_INVALID_SYNTAX;
154         }
155
156         return LDAP_SUCCESS;
157 }
158
159 int
160 value_normalize(
161         AttributeDescription *ad,
162         unsigned usage,
163         struct berval *in,
164         struct berval *out,
165         const char **text )
166 {
167         int rc;
168         MatchingRule *mr;
169
170         switch( usage & SLAP_MR_TYPE_MASK ) {
171         case SLAP_MR_NONE:
172         case SLAP_MR_EQUALITY:
173                 mr = ad->ad_type->sat_equality;
174                 break;
175         case SLAP_MR_ORDERING:
176                 mr = ad->ad_type->sat_ordering;
177                 break;
178         case SLAP_MR_SUBSTR:
179                 mr = ad->ad_type->sat_substr;
180                 break;
181         case SLAP_MR_EXT:
182         default:
183                 assert( 0 );
184                 *text = "internal error";
185                 return LDAP_OTHER;
186         }
187
188         if( mr == NULL ) {
189                 *text = "inappropriate matching request";
190                 return LDAP_INAPPROPRIATE_MATCHING;
191         }
192
193         /* we only support equality matching of binary attributes */
194         /* This is suspect, flexible certificate matching will hit this */
195         if( slap_ad_is_binary( ad ) && usage != SLAP_MR_EQUALITY ) {
196                 *text = "inappropriate binary matching";
197                 return LDAP_INAPPROPRIATE_MATCHING;
198         }
199
200         if( mr->smr_normalize ) {
201                 rc = (mr->smr_normalize)( usage,
202                         ad->ad_type->sat_syntax,
203                         mr, in, out );
204
205                 if( rc != LDAP_SUCCESS ) {
206                         *text = "unable to normalize value";
207                         return LDAP_INVALID_SYNTAX;
208                 }
209
210         } else if ( mr->smr_syntax->ssyn_normalize ) {
211                 rc = (mr->smr_syntax->ssyn_normalize)(
212                         ad->ad_type->sat_syntax,
213                         in, out );
214
215                 if( rc != LDAP_SUCCESS ) {
216                         *text = "unable to normalize value";
217                         return LDAP_INVALID_SYNTAX;
218                 }
219
220         } else {
221                 ber_dupbv( out, in );
222         }
223
224         return LDAP_SUCCESS;
225 }
226
227 int
228 value_validate_normalize(
229         AttributeDescription *ad,
230         unsigned usage,
231         struct berval *in,
232         struct berval *out,
233         const char **text )
234 {
235         int rc;
236         MatchingRule *mr;
237
238         switch( usage & SLAP_MR_TYPE_MASK ) {
239         case SLAP_MR_NONE:
240         case SLAP_MR_EQUALITY:
241                 mr = ad->ad_type->sat_equality;
242                 break;
243         case SLAP_MR_ORDERING:
244                 mr = ad->ad_type->sat_ordering;
245                 break;
246         case SLAP_MR_SUBSTR:
247                 mr = ad->ad_type->sat_substr;
248                 break;
249         case SLAP_MR_EXT:
250         default:
251                 assert( 0 );
252                 *text = "internal error";
253                 return LDAP_OTHER;
254         }
255
256         if( mr == NULL ) {
257                 *text = "inappropriate matching request";
258                 return LDAP_INAPPROPRIATE_MATCHING;
259         }
260
261         if( mr->smr_syntax == NULL ) {
262                 *text = "no assertion syntax";
263                 return LDAP_INVALID_SYNTAX;
264         }
265
266         if( ! mr->smr_syntax->ssyn_validate ) {
267                 *text = "no syntax validator";
268                 return LDAP_INVALID_SYNTAX;
269         }
270
271         rc = (mr->smr_syntax->ssyn_validate)( mr->smr_syntax, in );
272
273         if( rc != LDAP_SUCCESS ) {
274                 *text = "value is invalid";
275                 return LDAP_INVALID_SYNTAX;
276         }
277
278         /* we only support equality matching of binary attributes */
279         /* This is suspect, flexible certificate matching will hit this */
280         if( slap_ad_is_binary( ad ) && usage != SLAP_MR_EQUALITY ) {
281                 *text = "inappropriate binary matching";
282                 return LDAP_INAPPROPRIATE_MATCHING;
283         }
284
285         if( mr->smr_normalize ) {
286                 rc = (mr->smr_normalize)( usage,
287                         ad->ad_type->sat_syntax,
288                         mr, in, out );
289
290                 if( rc != LDAP_SUCCESS ) {
291                         *text = "unable to normalize value";
292                         return LDAP_INVALID_SYNTAX;
293                 }
294
295         } else if ( mr->smr_syntax->ssyn_normalize ) {
296                 rc = (mr->smr_syntax->ssyn_normalize)(
297                         ad->ad_type->sat_syntax,
298                         in, out );
299
300                 if( rc != LDAP_SUCCESS ) {
301                         *text = "unable to normalize value";
302                         return LDAP_INVALID_SYNTAX;
303                 }
304
305         } else {
306                 ber_dupbv( out, in );
307         }
308
309         return LDAP_SUCCESS;
310 }
311
312
313 int
314 value_match(
315         int *match,
316         AttributeDescription *ad,
317         MatchingRule *mr,
318         unsigned flags,
319         struct berval *v1, /* stored value */
320         void *v2, /* assertion */
321         const char ** text )
322 {
323         int rc;
324         struct berval nv1 = { 0, NULL };
325         struct berval nv2 = { 0, NULL };
326
327         if( !mr->smr_match ) {
328                 return LDAP_INAPPROPRIATE_MATCHING;
329         }
330
331         if( ad->ad_type->sat_syntax->ssyn_normalize ) {
332                 rc = ad->ad_type->sat_syntax->ssyn_normalize(
333                         ad->ad_type->sat_syntax, v1, &nv1 );
334
335                 if( rc != LDAP_SUCCESS ) {
336                         return LDAP_INAPPROPRIATE_MATCHING;
337                 }
338         }
339
340         if ( SLAP_IS_MR_VALUE_SYNTAX_NONCONVERTED_MATCH( flags ) &&
341                 mr->smr_convert )
342         {
343                 rc = (mr->smr_convert)( v2, &nv2 );
344                 if ( rc != LDAP_SUCCESS ) {
345                         return LDAP_INVALID_SYNTAX;
346                 }
347
348                 /* let smr_match know we've converted the value */
349                 flags |= SLAP_MR_VALUE_SYNTAX_CONVERTED_MATCH;
350         }
351
352         rc = (mr->smr_match)( match, flags,
353                 ad->ad_type->sat_syntax,
354                 mr,
355                 nv1.bv_val != NULL ? &nv1 : v1,
356                 nv2.bv_val != NULL ? &nv2 : v2 );
357         
358         if (nv1.bv_val ) free( nv1.bv_val );
359         if (nv2.bv_val ) free( nv2.bv_val );
360         return rc;
361 }
362
363
364 int value_find_ex(
365         AttributeDescription *ad,
366         unsigned flags,
367         BerVarray vals,
368         struct berval *val )
369 {
370         int     i;
371         int rc;
372         struct berval nval = { 0, NULL };
373         MatchingRule *mr = ad->ad_type->sat_equality;
374
375         if( mr == NULL || !mr->smr_match ) {
376                 return LDAP_INAPPROPRIATE_MATCHING;
377         }
378
379         /* Take care of this here or ssyn_normalize later will hurt */
380         if ( SLAP_IS_MR_VALUE_SYNTAX_NONCONVERTED_MATCH( flags )
381                 && mr->smr_convert )
382         {
383                 rc = (mr->smr_convert)( val, &nval );
384                 if ( rc != LDAP_SUCCESS ) {
385                         return LDAP_INVALID_SYNTAX;
386                 }
387
388                 /* let value_match know we've done the version */
389                 flags |= SLAP_MR_VALUE_SYNTAX_CONVERTED_MATCH;
390         }
391
392         if( mr->smr_syntax->ssyn_normalize ) {
393                 struct berval nval_tmp = { 0, NULL };
394
395                 rc = mr->smr_syntax->ssyn_normalize(
396                         mr->smr_syntax,
397                         nval.bv_val == NULL ? val : &nval, &nval_tmp );
398
399                 free(nval.bv_val);
400                 nval = nval_tmp;
401                 if( rc != LDAP_SUCCESS ) {
402                         free(nval.bv_val);
403                         return LDAP_INAPPROPRIATE_MATCHING;
404                 }
405         }
406
407         for ( i = 0; vals[i].bv_val != NULL; i++ ) {
408                 int match;
409                 const char *text;
410
411                 rc = value_match( &match, ad, mr, flags,
412                         &vals[i], nval.bv_val == NULL ? val : &nval, &text );
413
414                 if( rc == LDAP_SUCCESS && match == 0 ) {
415                         free( nval.bv_val );
416                         return LDAP_SUCCESS;
417                 }
418         }
419
420         free( nval.bv_val );
421         return LDAP_NO_SUCH_ATTRIBUTE;
422 }