]> git.sur5r.net Git - openldap/blob - servers/slapd/value.c
3391849236fc2711ceb92aec66f20c5185abea4c
[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) ch_malloc( (nn + 1)
35                     * sizeof(struct berval) );
36                 n = 0;
37         } else {
38                 for ( n = 0; (*vals)[n].bv_val != NULL; n++ ) {
39                         ;       /* Empty */
40                 }
41                 *vals = (BerVarray) ch_realloc( (char *) *vals,
42                     (n + nn + 1) * sizeof(struct berval) );
43         }
44
45         v2 = *vals + n;
46         for ( ; addvals->bv_val; v2++, addvals++ ) {
47                 ber_dupbv(v2, addvals);
48                 if (v2->bv_val == NULL) break;
49         }
50         v2->bv_val = NULL;
51         v2->bv_len = 0;
52
53         return LDAP_SUCCESS;
54 }
55
56 int
57 value_validate(
58         MatchingRule *mr,
59         struct berval *in,
60         const char **text )
61 {
62         int rc;
63
64         if( mr == NULL ) {
65                 *text = "inappropriate matching request";
66                 return LDAP_INAPPROPRIATE_MATCHING;
67         }
68
69         if( mr->smr_syntax == NULL ) {
70                 *text = "no assertion syntax";
71                 return LDAP_INVALID_SYNTAX;
72         }
73
74         if( ! mr->smr_syntax->ssyn_validate ) {
75                 *text = "no syntax validator";
76                 return LDAP_INVALID_SYNTAX;
77         }
78
79         rc = (mr->smr_syntax->ssyn_validate)( mr->smr_syntax, in );
80
81         if( rc != LDAP_SUCCESS ) {
82                 *text = "value is invalid";
83                 return LDAP_INVALID_SYNTAX;
84         }
85
86         return LDAP_SUCCESS;
87 }
88
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         /* This is suspect, flexible certificate matching will hit this */
125         if( slap_ad_is_binary( ad ) && usage != SLAP_MR_EQUALITY ) {
126                 *text = "inappropriate binary matching";
127                 return LDAP_INAPPROPRIATE_MATCHING;
128         }
129
130         if( mr->smr_normalize ) {
131                 rc = (mr->smr_normalize)( usage,
132                         ad->ad_type->sat_syntax,
133                         mr, in, out );
134
135                 if( rc != LDAP_SUCCESS ) {
136                         *text = "unable to normalize value";
137                         return LDAP_INVALID_SYNTAX;
138                 }
139
140         } else if ( mr->smr_syntax->ssyn_normalize ) {
141                 rc = (mr->smr_syntax->ssyn_normalize)(
142                         ad->ad_type->sat_syntax,
143                         in, out );
144
145                 if( rc != LDAP_SUCCESS ) {
146                         *text = "unable to normalize value";
147                         return LDAP_INVALID_SYNTAX;
148                 }
149
150         } else {
151                 ber_dupbv( out, in );
152         }
153
154         return LDAP_SUCCESS;
155 }
156
157
158 int
159 value_match(
160         int *match,
161         AttributeDescription *ad,
162         MatchingRule *mr,
163         unsigned flags,
164         struct berval *v1, /* stored value */
165         void *v2, /* assertion */
166         const char ** text )
167 {
168         int rc;
169         struct berval nv1 = { 0, NULL };
170         struct berval nv2 = { 0, NULL };
171
172         if( !mr->smr_match ) {
173                 return LDAP_INAPPROPRIATE_MATCHING;
174         }
175
176         if( ad->ad_type->sat_syntax->ssyn_normalize ) {
177                 rc = ad->ad_type->sat_syntax->ssyn_normalize(
178                         ad->ad_type->sat_syntax, v1, &nv1 );
179
180                 if( rc != LDAP_SUCCESS ) {
181                         return LDAP_INAPPROPRIATE_MATCHING;
182                 }
183         }
184
185         if ( SLAP_IS_MR_VALUE_SYNTAX_NONCONVERTED_MATCH( flags ) &&
186                 mr->smr_convert )
187         {
188                 rc = (mr->smr_convert)( v2, &nv2 );
189                 if ( rc != LDAP_SUCCESS ) {
190                         return LDAP_INVALID_SYNTAX;
191                 }
192
193                 /* let smr_match know we've converted the value */
194                 flags |= SLAP_MR_VALUE_SYNTAX_CONVERTED_MATCH;
195         }
196
197         rc = (mr->smr_match)( match, flags,
198                 ad->ad_type->sat_syntax,
199                 mr,
200                 nv1.bv_val != NULL ? &nv1 : v1,
201                 nv2.bv_val != NULL ? &nv2 : v2 );
202         
203         if (nv1.bv_val ) free( nv1.bv_val );
204         if (nv2.bv_val ) free( nv2.bv_val );
205         return rc;
206 }
207
208
209 int value_find_ex(
210         AttributeDescription *ad,
211         unsigned flags,
212         BerVarray vals,
213         struct berval *val )
214 {
215         int     i;
216         int rc;
217         struct berval nval = { 0, NULL };
218         struct berval nval_tmp;
219         MatchingRule *mr = ad->ad_type->sat_equality;
220
221         if( mr == NULL || !mr->smr_match ) {
222                 return LDAP_INAPPROPRIATE_MATCHING;
223         }
224
225         /* Take care of this here or ssyn_normalize later will hurt */
226         if ( SLAP_IS_MR_VALUE_SYNTAX_NONCONVERTED_MATCH( flags )
227                 && mr->smr_convert )
228         {
229                 rc = (mr->smr_convert)( val, &nval );
230                 if ( rc != LDAP_SUCCESS ) {
231                         return LDAP_INVALID_SYNTAX;
232                 }
233
234                 /* let value_match know we've done the version */
235                 flags |= SLAP_MR_VALUE_SYNTAX_CONVERTED_MATCH;
236         }
237
238         if( mr->smr_syntax->ssyn_normalize ) {
239                 rc = mr->smr_syntax->ssyn_normalize(
240                         mr->smr_syntax, nval.bv_val == NULL ? val : &nval, &nval_tmp );
241
242                 free(nval.bv_val);
243                 nval = nval_tmp;
244                 if( rc != LDAP_SUCCESS ) {
245                         free(nval.bv_val);
246                         return LDAP_INAPPROPRIATE_MATCHING;
247                 }
248         }
249
250         for ( i = 0; vals[i].bv_val != NULL; i++ ) {
251                 int match;
252                 const char *text;
253
254                 rc = value_match( &match, ad, mr, flags,
255                         &vals[i], nval.bv_val == NULL ? val : &nval, &text );
256
257                 if( rc == LDAP_SUCCESS && match == 0 ) {
258                         free( nval.bv_val );
259                         return LDAP_SUCCESS;
260                 }
261         }
262
263         free( nval.bv_val );
264         return LDAP_NO_SUCH_ATTRIBUTE;
265 }