]> git.sur5r.net Git - openldap/blob - servers/slapd/value.c
now I remember why I introduced the 'has_ldapinfo_dn_ru' flag
[openldap] / servers / slapd / value.c
1 /* value.c - routines for dealing with values */
2 /* $OpenLDAP$ */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4  *
5  * Copyright 1998-2004 The OpenLDAP Foundation.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted only as authorized by the OpenLDAP
10  * Public License.
11  *
12  * A copy of this license is available in the file LICENSE in the
13  * top-level directory of the distribution or, alternatively, at
14  * <http://www.OpenLDAP.org/license.html>.
15  */
16 /*
17  * Copyright (c) 1995 Regents of the University of Michigan.
18  * All rights reserved.
19  *
20  * Redistribution and use in source and binary forms are permitted
21  * provided that this notice is preserved and that due credit is given
22  * to the University of Michigan at Ann Arbor. The name of the University
23  * may not be used to endorse or promote products derived from this
24  * software without specific prior written permission. This software
25  * is provided ``as is'' without express or implied warranty.
26  */
27
28 #include "portable.h"
29
30 #include <stdio.h>
31
32 #include <ac/ctype.h>
33 #include <ac/socket.h>
34 #include <ac/string.h>
35 #include <ac/time.h>
36
37 #include <sys/stat.h>
38
39 #include "slap.h"
40
41 int
42 value_add( 
43     BerVarray *vals,
44     BerVarray addvals
45 )
46 {
47         int     n, nn;
48         BerVarray v2;
49
50         for ( nn = 0; addvals != NULL && addvals[nn].bv_val != NULL; nn++ )
51                 ;       /* NULL */
52
53         if ( *vals == NULL ) {
54                 *vals = (BerVarray) SLAP_MALLOC( (nn + 1)
55                     * sizeof(struct berval) );
56                 if( *vals == NULL ) {
57 #ifdef NEW_LOGGING
58                          LDAP_LOG( OPERATION, ERR,
59                       "value_add: SLAP_MALLOC failed.\n", 0, 0, 0 );
60 #else
61                         Debug(LDAP_DEBUG_TRACE,
62                       "value_add: SLAP_MALLOC failed.\n", 0, 0, 0 );
63 #endif
64                         return LBER_ERROR_MEMORY;
65                 }
66                 n = 0;
67         } else {
68                 for ( n = 0; (*vals)[n].bv_val != NULL; n++ ) {
69                         ;       /* Empty */
70                 }
71                 *vals = (BerVarray) SLAP_REALLOC( (char *) *vals,
72                     (n + nn + 1) * sizeof(struct berval) );
73                 if( *vals == NULL ) {
74 #ifdef NEW_LOGGING
75                          LDAP_LOG( OPERATION, ERR,
76                       "value_add: SLAP_MALLOC failed.\n", 0, 0, 0 );
77 #else
78                         Debug(LDAP_DEBUG_TRACE,
79                       "value_add: SLAP_MALLOC failed.\n", 0, 0, 0 );
80 #endif
81                         return LBER_ERROR_MEMORY;
82                 }
83         }
84
85         v2 = *vals + n;
86         for ( ; addvals->bv_val; v2++, addvals++ ) {
87                 ber_dupbv(v2, addvals);
88                 if (v2->bv_val == NULL) break;
89         }
90         v2->bv_val = NULL;
91         v2->bv_len = 0;
92
93         return LDAP_SUCCESS;
94 }
95
96 int
97 value_add_one( 
98     BerVarray *vals,
99     struct berval *addval
100 )
101 {
102         int     n;
103         BerVarray v2;
104
105         if ( *vals == NULL ) {
106                 *vals = (BerVarray) SLAP_MALLOC( 2 * sizeof(struct berval) );
107                 if( *vals == NULL ) {
108 #ifdef NEW_LOGGING
109                          LDAP_LOG( OPERATION, ERR,
110                       "value_add_one: SLAP_MALLOC failed.\n", 0, 0, 0 );
111 #else
112                         Debug(LDAP_DEBUG_TRACE,
113                       "value_add_one: SLAP_MALLOC failed.\n", 0, 0, 0 );
114 #endif
115                         return LBER_ERROR_MEMORY;
116                 }
117                 n = 0;
118         } else {
119                 for ( n = 0; (*vals)[n].bv_val != NULL; n++ ) {
120                         ;       /* Empty */
121                 }
122                 *vals = (BerVarray) SLAP_REALLOC( (char *) *vals,
123                     (n + 2) * sizeof(struct berval) );
124                 if( *vals == NULL ) {
125 #ifdef NEW_LOGGING
126                          LDAP_LOG( OPERATION, ERR,
127                       "value_add_one: SLAP_MALLOC failed.\n", 0, 0, 0 );
128 #else
129                         Debug(LDAP_DEBUG_TRACE,
130                       "value_add_one: SLAP_MALLOC failed.\n", 0, 0, 0 );
131 #endif
132                         return LBER_ERROR_MEMORY;
133                 }
134         }
135
136         v2 = *vals + n;
137         ber_dupbv(v2, addval);
138
139         v2++;
140         v2->bv_val = NULL;
141         v2->bv_len = 0;
142
143         return LDAP_SUCCESS;
144 }
145
146 int asserted_value_validate_normalize( 
147         AttributeDescription *ad,
148         MatchingRule *mr,
149         unsigned usage,
150         struct berval *in,
151         struct berval *out,
152         const char ** text,
153         void *ctx )
154 {
155         int rc;
156         struct berval pval;
157         pval.bv_val = NULL;
158
159         /* we expect the value to be in the assertion syntax */
160         assert( !SLAP_MR_IS_VALUE_OF_ATTRIBUTE_SYNTAX(usage) );
161
162         if( mr == NULL ) {
163                 *text = "inappropriate matching request";
164                 return LDAP_INAPPROPRIATE_MATCHING;
165         }
166
167         if( !mr->smr_match ) {
168                 *text = "requested matching rule not supported";
169                 return LDAP_INAPPROPRIATE_MATCHING;
170         }
171
172         if( mr->smr_syntax->ssyn_pretty ) {
173                 rc = (mr->smr_syntax->ssyn_pretty)( mr->smr_syntax, in, &pval, ctx );
174                 in = &pval;
175
176         } else {
177                 rc = (mr->smr_syntax->ssyn_validate)( mr->smr_syntax, in );
178         }
179
180         if( rc != LDAP_SUCCESS ) {
181                 *text = "value does not conform to assertion syntax";
182                 return LDAP_INVALID_SYNTAX;
183         }
184
185         if( mr->smr_normalize ) {
186                 rc = (mr->smr_normalize)(
187                         usage|SLAP_MR_VALUE_OF_ASSERTION_SYNTAX,
188                         ad ? ad->ad_type->sat_syntax : NULL,
189                         mr, in, out, ctx );
190
191                 if( pval.bv_val ) ber_memfree_x( pval.bv_val, ctx );
192
193                 if( rc != LDAP_SUCCESS ) {
194                         *text = "unable to normalize value for matching";
195                         return LDAP_INVALID_SYNTAX;
196                 }
197
198         } else if ( pval.bv_val != NULL ) {
199                 *out = pval;
200
201         } else {
202                 ber_dupbv_x( out, in, ctx );
203         }
204
205         return LDAP_SUCCESS;
206 }
207
208
209 int
210 value_match(
211         int *match,
212         AttributeDescription *ad,
213         MatchingRule *mr,
214         unsigned flags,
215         struct berval *v1, /* stored value */
216         void *v2, /* assertion */
217         const char ** text )
218 {
219         int rc;
220         struct berval nv1 = { 0, NULL };
221         struct berval nv2 = { 0, NULL };
222
223         assert( mr != NULL );
224
225         if( !mr->smr_match ) {
226                 return LDAP_INAPPROPRIATE_MATCHING;
227         }
228
229         rc = (mr->smr_match)( match, flags,
230                 ad->ad_type->sat_syntax,
231                 mr,
232                 nv1.bv_val != NULL ? &nv1 : v1,
233                 nv2.bv_val != NULL ? &nv2 : v2 );
234         
235         if (nv1.bv_val ) free( nv1.bv_val );
236         if (nv2.bv_val ) free( nv2.bv_val );
237         return rc;
238 }
239
240 int value_find_ex(
241         AttributeDescription *ad,
242         unsigned flags,
243         BerVarray vals,
244         struct berval *val,
245         void *ctx )
246 {
247         int     i;
248         int rc;
249         struct berval nval = { 0, NULL };
250         MatchingRule *mr = ad->ad_type->sat_equality;
251
252         if( mr == NULL || !mr->smr_match ) {
253                 return LDAP_INAPPROPRIATE_MATCHING;
254         }
255
256         assert(SLAP_IS_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH( flags ));
257
258         if( !SLAP_IS_MR_ASSERTED_VALUE_NORMALIZED_MATCH( flags ) &&
259                 mr->smr_normalize )
260         {
261                 rc = (mr->smr_normalize)(
262                         flags & (SLAP_MR_TYPE_MASK|SLAP_MR_SUBTYPE_MASK|SLAP_MR_VALUE_OF_SYNTAX),
263                         ad ? ad->ad_type->sat_syntax : NULL,
264                         mr, val, &nval, ctx );
265
266                 if( rc != LDAP_SUCCESS ) {
267                         return LDAP_INVALID_SYNTAX;
268                 }
269         }
270
271         for ( i = 0; vals[i].bv_val != NULL; i++ ) {
272                 int match;
273                 const char *text;
274
275                 rc = value_match( &match, ad, mr, flags,
276                         &vals[i], nval.bv_val == NULL ? val : &nval, &text );
277
278                 if( rc == LDAP_SUCCESS && match == 0 ) {
279                         sl_free( nval.bv_val, ctx );
280                         return rc;
281                 }
282         }
283
284         sl_free( nval.bv_val, ctx );
285         return LDAP_NO_SUCH_ATTRIBUTE;
286 }