]> git.sur5r.net Git - openldap/blob - servers/slapd/value.c
Need to pretty assertion values
[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 int asserted_value_validate_normalize( 
127         AttributeDescription *ad,
128         MatchingRule *mr,
129         unsigned usage,
130         struct berval *in,
131         struct berval *out,
132         const char ** text,
133         void *ctx )
134 {
135         int rc;
136         struct berval pval;
137         pval.bv_val = NULL;
138
139         /* we expect the value to be in the assertion syntax */
140         assert( !SLAP_MR_IS_VALUE_OF_ATTRIBUTE_SYNTAX(usage) );
141
142         if( mr == NULL ) {
143                 *text = "inappropriate matching request";
144                 return LDAP_INAPPROPRIATE_MATCHING;
145         }
146
147         if( !mr->smr_match ) {
148                 *text = "requested matching rule not supported";
149                 return LDAP_INAPPROPRIATE_MATCHING;
150         }
151
152         if( mr->smr_syntax->ssyn_pretty ) {
153                 rc = (mr->smr_syntax->ssyn_pretty)( mr->smr_syntax, in, &pval, ctx );
154                 in = &pval;
155
156         } else {
157                 rc = (mr->smr_syntax->ssyn_validate)( mr->smr_syntax, in );
158         }
159
160         if( rc != LDAP_SUCCESS ) {
161                 *text = "value does not conform to assertion syntax";
162                 return LDAP_INVALID_SYNTAX;
163         }
164
165         if( mr->smr_normalize ) {
166                 rc = (mr->smr_normalize)( usage,
167                         ad ? ad->ad_type->sat_syntax : NULL,
168                         mr, in, out, ctx );
169
170                 if( pval.bv_val ) ber_memfree_x( pval.bv_val, ctx );
171
172                 if( rc != LDAP_SUCCESS ) {
173                         *text = "unable to normalize value for matching";
174                         return LDAP_INVALID_SYNTAX;
175                 }
176
177         } else if ( pval.bv_val != NULL ) {
178                 *out = pval;
179
180         } else {
181                 ber_dupbv_x( out, in, ctx );
182         }
183
184         return LDAP_SUCCESS;
185 }
186
187
188 int
189 value_match(
190         int *match,
191         AttributeDescription *ad,
192         MatchingRule *mr,
193         unsigned flags,
194         struct berval *v1, /* stored value */
195         void *v2, /* assertion */
196         const char ** text )
197 {
198         int rc;
199         struct berval nv1 = { 0, NULL };
200         struct berval nv2 = { 0, NULL };
201
202         assert( mr != NULL );
203
204         if( !mr->smr_match ) {
205                 return LDAP_INAPPROPRIATE_MATCHING;
206         }
207
208
209         rc = (mr->smr_match)( match, flags,
210                 ad->ad_type->sat_syntax,
211                 mr,
212                 nv1.bv_val != NULL ? &nv1 : v1,
213                 nv2.bv_val != NULL ? &nv2 : v2 );
214         
215         if (nv1.bv_val ) free( nv1.bv_val );
216         if (nv2.bv_val ) free( nv2.bv_val );
217         return rc;
218 }
219
220 int value_find_ex(
221         AttributeDescription *ad,
222         unsigned flags,
223         BerVarray vals,
224         struct berval *val,
225         void *ctx )
226 {
227         int     i;
228         int rc;
229         struct berval nval = { 0, NULL };
230         MatchingRule *mr = ad->ad_type->sat_equality;
231
232         if( mr == NULL || !mr->smr_match ) {
233                 return LDAP_INAPPROPRIATE_MATCHING;
234         }
235
236         assert(SLAP_IS_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH( flags ));
237
238         if( !SLAP_IS_MR_ASSERTED_VALUE_NORMALIZED_MATCH( flags ) &&
239                 mr->smr_normalize )
240         {
241                 rc = (mr->smr_normalize)(
242                         flags & (SLAP_MR_TYPE_MASK|SLAP_MR_SUBTYPE_MASK),
243                         ad ? ad->ad_type->sat_syntax : NULL,
244                         mr, val, &nval, ctx );
245
246                 if( rc != LDAP_SUCCESS ) {
247                         return LDAP_INVALID_SYNTAX;
248                 }
249         }
250
251         for ( i = 0; vals[i].bv_val != NULL; i++ ) {
252                 int match;
253                 const char *text;
254
255                 rc = value_match( &match, ad, mr, flags,
256                         &vals[i], nval.bv_val == NULL ? val : &nval, &text );
257
258                 if( rc == LDAP_SUCCESS && match == 0 ) {
259                         sl_free( nval.bv_val, ctx );
260                         return rc;
261                 }
262         }
263
264         sl_free( nval.bv_val, ctx );
265         return LDAP_NO_SUCH_ATTRIBUTE;
266 }