]> git.sur5r.net Git - openldap/blob - servers/slapd/value.c
First round of changes from HEAD
[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         int             n, nn = 0;
47         BerVarray       v2;
48
49         if ( addvals != NULL ) {
50                 for ( ; !BER_BVISNULL( &addvals[nn] ); nn++ )
51                         ;       /* NULL */
52         }
53
54         if ( *vals == NULL ) {
55                 *vals = (BerVarray) SLAP_MALLOC( (nn + 1)
56                     * sizeof(struct berval) );
57                 if( *vals == NULL ) {
58 #ifdef NEW_LOGGING
59                          LDAP_LOG( OPERATION, ERR,
60                       "value_add: SLAP_MALLOC failed.\n", 0, 0, 0 );
61 #else
62                         Debug(LDAP_DEBUG_TRACE,
63                       "value_add: SLAP_MALLOC failed.\n", 0, 0, 0 );
64 #endif
65                         return LBER_ERROR_MEMORY;
66                 }
67                 n = 0;
68
69         } else {
70                 for ( n = 0; !BER_BVISNULL( &(*vals)[n] ); n++ ) {
71                         ;       /* Empty */
72                 }
73                 *vals = (BerVarray) SLAP_REALLOC( (char *) *vals,
74                     (n + nn + 1) * sizeof(struct berval) );
75                 if( *vals == NULL ) {
76 #ifdef NEW_LOGGING
77                          LDAP_LOG( OPERATION, ERR,
78                       "value_add: SLAP_MALLOC failed.\n", 0, 0, 0 );
79 #else
80                         Debug(LDAP_DEBUG_TRACE,
81                       "value_add: SLAP_MALLOC failed.\n", 0, 0, 0 );
82 #endif
83                         return LBER_ERROR_MEMORY;
84                 }
85         }
86
87         v2 = &(*vals)[n];
88         for ( ; !BER_BVISNULL( addvals ); v2++, addvals++ ) {
89                 ber_dupbv( v2, addvals );
90                 if ( BER_BVISNULL( v2 ) ) break;
91         }
92         BER_BVZERO( v2 );
93
94         return LDAP_SUCCESS;
95 }
96
97 int
98 value_add_one( 
99     BerVarray           *vals,
100     struct berval       *addval )
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
119         } else {
120                 for ( n = 0; !BER_BVISNULL( &(*vals)[n] ); n++ ) {
121                         ;       /* Empty */
122                 }
123                 *vals = (BerVarray) SLAP_REALLOC( (char *) *vals,
124                     (n + 2) * sizeof(struct berval) );
125                 if( *vals == NULL ) {
126 #ifdef NEW_LOGGING
127                          LDAP_LOG( OPERATION, ERR,
128                       "value_add_one: SLAP_MALLOC failed.\n", 0, 0, 0 );
129 #else
130                         Debug(LDAP_DEBUG_TRACE,
131                       "value_add_one: SLAP_MALLOC failed.\n", 0, 0, 0 );
132 #endif
133                         return LBER_ERROR_MEMORY;
134                 }
135         }
136
137         v2 = &(*vals)[n];
138         ber_dupbv(v2, addval);
139
140         v2++;
141         BER_BVZERO( v2 );
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
221         assert( mr != NULL );
222
223         if( !mr->smr_match ) {
224                 return LDAP_INAPPROPRIATE_MATCHING;
225         }
226
227         rc = (mr->smr_match)( match, flags,
228                 ad->ad_type->sat_syntax, mr, v1, v2 );
229         
230         return rc;
231 }
232
233 int value_find_ex(
234         AttributeDescription *ad,
235         unsigned flags,
236         BerVarray vals,
237         struct berval *val,
238         void *ctx )
239 {
240         int     i;
241         int rc;
242         struct berval nval = BER_BVNULL;
243         MatchingRule *mr = ad->ad_type->sat_equality;
244
245         if( mr == NULL || !mr->smr_match ) {
246                 return LDAP_INAPPROPRIATE_MATCHING;
247         }
248
249         assert(SLAP_IS_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH( flags ));
250
251         if( !SLAP_IS_MR_ASSERTED_VALUE_NORMALIZED_MATCH( flags ) &&
252                 mr->smr_normalize )
253         {
254                 rc = (mr->smr_normalize)(
255                         flags & (SLAP_MR_TYPE_MASK|SLAP_MR_SUBTYPE_MASK|SLAP_MR_VALUE_OF_SYNTAX),
256                         ad ? ad->ad_type->sat_syntax : NULL,
257                         mr, val, &nval, ctx );
258
259                 if( rc != LDAP_SUCCESS ) {
260                         return LDAP_INVALID_SYNTAX;
261                 }
262         }
263
264         for ( i = 0; vals[i].bv_val != NULL; i++ ) {
265                 int match;
266                 const char *text;
267
268                 rc = value_match( &match, ad, mr, flags,
269                         &vals[i], nval.bv_val == NULL ? val : &nval, &text );
270
271                 if( rc == LDAP_SUCCESS && match == 0 ) {
272                         sl_free( nval.bv_val, ctx );
273                         return rc;
274                 }
275         }
276
277         sl_free( nval.bv_val, ctx );
278         return LDAP_NO_SUCH_ATTRIBUTE;
279 }