]> git.sur5r.net Git - openldap/blob - servers/slapd/value.c
Prepare for unifdef -DSLAPD_SCHEMA_NOT_COMPAT
[openldap] / servers / slapd / value.c
1 /* value.c - routines for dealing with values */
2 /* $OpenLDAP$ */
3 /*
4  * Copyright 1998-2000 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     struct berval       ***vals,
24     struct berval       **addvals
25 )
26 {
27         int     n, nn, i, j;
28
29         for ( nn = 0; addvals != NULL && addvals[nn] != NULL; nn++ )
30                 ;       /* NULL */
31
32         if ( *vals == NULL ) {
33                 *vals = (struct berval **) ch_malloc( (nn + 1)
34                     * sizeof(struct berval *) );
35                 n = 0;
36         } else {
37                 for ( n = 0; (*vals)[n] != NULL; n++ )
38                         ;       /* NULL */
39                 *vals = (struct berval **) ch_realloc( (char *) *vals,
40                     (n + nn + 1) * sizeof(struct berval *) );
41         }
42
43         for ( i = 0, j = 0; i < nn; i++ ) {
44                 if ( addvals[i]->bv_len > 0 ) {
45                         (*vals)[n + j] = ber_bvdup( addvals[i] );
46                         if( (*vals)[n + j++] == NULL ) break;
47                 }
48         }
49         (*vals)[n + j] = NULL;
50
51         return LDAP_SUCCESS;
52 }
53
54 #ifndef SLAPD_SCHEMA_NOT_COMPAT
55 int
56 value_add_fast( 
57     struct berval       ***vals,
58     struct berval       **addvals,
59     int                 nvals,
60     int                 naddvals,
61     int                 *maxvals
62 )
63 {
64         int     need, i, j;
65
66         if ( *maxvals == 0 ) {
67                 *maxvals = 1;
68         }
69         need = nvals + naddvals + 1;
70         while ( *maxvals < need ) {
71                 *maxvals *= 2;
72                 *vals = (struct berval **) ch_realloc( (char *) *vals,
73                     *maxvals * sizeof(struct berval *) );
74         }
75
76         for ( i = 0, j = 0; i < naddvals; i++ ) {
77                 if ( addvals[i]->bv_len > 0 ) {
78                         (*vals)[nvals + j] = ber_bvdup( addvals[i] );
79                         if( (*vals)[nvals + j] != NULL ) j++;
80                 }
81         }
82         (*vals)[nvals + j] = NULL;
83
84         return( 0 );
85 }
86 #endif
87
88 #ifdef SLAPD_SCHEMA_NOT_COMPAT
89 int
90 value_normalize(
91         AttributeDescription *ad,
92         unsigned usage,
93         struct berval *in,
94         struct berval **out,
95         const char **text )
96 {
97         int rc;
98         MatchingRule *mr;
99
100         switch( usage & SLAP_MR_TYPE_MASK ) {
101         case SLAP_MR_NONE:
102         case SLAP_MR_EQUALITY:
103                 mr = ad->ad_type->sat_equality;
104                 break;
105         case SLAP_MR_ORDERING:
106                 mr = ad->ad_type->sat_ordering;
107                 break;
108         case SLAP_MR_SUBSTR:
109                 mr = ad->ad_type->sat_substr;
110                 break;
111         case SLAP_MR_EXT:
112         default:
113                 assert( 0 );
114                 *text = "internal error";
115                 return LDAP_OTHER;
116         }
117
118         if( mr == NULL ) {
119                 *text = "inappropriate matching request";
120                 return LDAP_INAPPROPRIATE_MATCHING;
121         }
122
123         /* we only support equality matching of binary attributes */
124         if( slap_ad_is_binary( ad ) && usage != SLAP_MR_EQUALITY ) {
125                 *text = "inappropriate binary matching";
126                 return LDAP_INAPPROPRIATE_MATCHING;
127         }
128
129         if( mr->smr_normalize ) {
130                 rc = (mr->smr_normalize)( usage,
131                         ad->ad_type->sat_syntax,
132                         mr, in, out );
133
134                 if( rc != LDAP_SUCCESS ) {
135                         *text = "unable to normalize value";
136                         return LDAP_INVALID_SYNTAX;
137                 }
138
139         } else if ( mr->smr_syntax->ssyn_normalize ) {
140                 rc = (mr->smr_syntax->ssyn_normalize)(
141                         ad->ad_type->sat_syntax,
142                         in, out );
143
144                 if( rc != LDAP_SUCCESS ) {
145                         *text = "unable to normalize value";
146                         return LDAP_INVALID_SYNTAX;
147                 }
148
149         } else {
150                 *out = ber_bvdup( in );
151         }
152
153         return LDAP_SUCCESS;
154 }
155
156 #else
157 void
158 value_normalize(
159     char        *s,
160     int         syntax
161 )
162 {
163         char    *d, *save;
164
165         if ( ! (syntax & SYNTAX_CIS) ) {
166                 return;
167         }
168
169         if ( syntax & SYNTAX_DN ) {
170                 (void) dn_normalize( s );
171                 return;
172         }
173
174         save = s;
175         for ( d = s; *s; s++ ) {
176                 if ( (syntax & SYNTAX_TEL) && (*s == ' ' || *s == '-') ) {
177                         continue;
178                 }
179                 *d++ = TOUPPER( (unsigned char) *s );
180         }
181         *d = '\0';
182 }
183 #endif
184
185 #ifdef SLAPD_SCHEMA_NOT_COMPAT
186 int
187 value_match(
188         int *match,
189         AttributeDescription *ad,
190         MatchingRule *mr,
191         struct berval *v1, /* stored value */
192         void *v2, /* assertion */
193         const char ** text )
194 {
195         int rc;
196         int usage = 0;
197         struct berval *nv1 = NULL;
198
199         if( !mr->smr_match ) {
200                 return LDAP_INAPPROPRIATE_MATCHING;
201         }
202
203         if( ad->ad_type->sat_syntax->ssyn_normalize ) {
204                 rc = ad->ad_type->sat_syntax->ssyn_normalize(
205                         ad->ad_type->sat_syntax, v1, &nv1 );
206
207                 if( rc != LDAP_SUCCESS ) {
208                         return LDAP_INAPPROPRIATE_MATCHING;
209                 }
210         }
211
212         rc = (mr->smr_match)( match, usage,
213                 ad->ad_type->sat_syntax,
214                 mr,
215                 nv1 != NULL ? nv1 : v1,
216                 v2 );
217         
218         ber_bvfree( nv1 );
219         return rc;
220 }
221
222 #else
223 int
224 value_cmp(
225     struct berval       *v1,
226     struct berval       *v2,
227     int                 syntax,
228     int                 normalize       /* 1 => arg 1; 2 => arg 2; 3 => both */
229 )
230 {
231         int             rc;
232
233         if ( normalize & 1 ) {
234                 v1 = ber_bvdup( v1 );
235                 value_normalize( v1->bv_val, syntax );
236         }
237         if ( normalize & 2 ) {
238                 v2 = ber_bvdup( v2 );
239                 value_normalize( v2->bv_val, syntax );
240         }
241
242         switch ( syntax ) {
243         case SYNTAX_CIS:
244         case (SYNTAX_CIS | SYNTAX_TEL):
245         case (SYNTAX_CIS | SYNTAX_DN):
246                 rc = strcasecmp( v1->bv_val, v2->bv_val );
247                 break;
248
249         case SYNTAX_CES:
250                 rc = strcmp( v1->bv_val, v2->bv_val );
251                 break;
252
253         default:        /* Unknown syntax */
254         case SYNTAX_BIN:
255                 rc = (v1->bv_len == v2->bv_len
256                       ? memcmp( v1->bv_val, v2->bv_val, v1->bv_len )
257                       : v1->bv_len > v2->bv_len ? 1 : -1);
258                 break;
259         }
260
261         if ( normalize & 1 ) {
262                 ber_bvfree( v1 );
263         }
264         if ( normalize & 2 ) {
265                 ber_bvfree( v2 );
266         }
267
268         return( rc );
269 }
270 #endif
271
272 #ifdef SLAPD_SCHEMA_NOT_COMPAT
273 int value_find(
274         AttributeDescription *ad,
275         struct berval **vals,
276         struct berval *val )
277 #else
278 int
279 value_find(
280     struct berval       **vals,
281     struct berval       *v,
282     int                 syntax,
283     int                 normalize )
284 #endif
285 {
286         int     i;
287 #ifdef SLAPD_SCHEMA_NOT_COMPAT
288         int rc;
289         struct berval *nval = NULL;
290         MatchingRule *mr = ad->ad_type->sat_equality;
291
292         if( mr == NULL || !mr->smr_match ) {
293                 return LDAP_INAPPROPRIATE_MATCHING;
294         }
295
296         if( mr->smr_syntax->ssyn_normalize ) {
297                 rc = mr->smr_syntax->ssyn_normalize(
298                         mr->smr_syntax, val, &nval );
299
300                 if( rc != LDAP_SUCCESS ) {
301                         return LDAP_INAPPROPRIATE_MATCHING;
302                 }
303         }
304 #endif
305
306         for ( i = 0; vals[i] != NULL; i++ ) {
307 #ifdef SLAPD_SCHEMA_NOT_COMPAT
308                 int match;
309                 const char *text;
310
311                 rc = value_match( &match, ad, mr, vals[i],
312                         nval == NULL ? val : nval, &text );
313
314                 if( rc == LDAP_SUCCESS && match == 0 )
315 #else
316                 if ( value_cmp( vals[i], v, syntax, normalize ) == 0 )
317 #endif
318                 {
319                         return LDAP_SUCCESS;
320                 }
321         }
322
323         return LDAP_NO_SUCH_ATTRIBUTE;
324 }