]> git.sur5r.net Git - openldap/blob - servers/slapd/value.c
Use AC_MEMCPY instead of memcpy
[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     BVarray *vals,
24     BVarray addvals
25 )
26 {
27         int     n, nn, i, j;
28         BVarray v2;
29
30         for ( nn = 0; addvals != NULL && addvals[nn].bv_val != NULL; nn++ )
31                 ;       /* NULL */
32
33         if ( *vals == NULL ) {
34                 *vals = (BVarray) ch_malloc( (nn + 1)
35                     * sizeof(struct berval) );
36                 n = 0;
37         } else {
38                 for ( n = 0; (*vals)[n].bv_val != NULL; n++ )
39                         ;       /* NULL */
40                 *vals = (BVarray) ch_realloc( (char *) *vals,
41                     (n + nn + 1) * sizeof(struct berval) );
42         }
43
44         v2 = *vals + n;
45         for ( ; addvals->bv_val; v2++, addvals++ ) {
46                 ber_dupbv(v2, addvals);
47                 if (v2->bv_val == NULL) break;
48         }
49         v2->bv_val = NULL;
50         v2->bv_len = 0;
51
52         return LDAP_SUCCESS;
53 }
54
55
56 int
57 value_normalize(
58         AttributeDescription *ad,
59         unsigned usage,
60         struct berval *in,
61         struct berval *out,
62         const char **text )
63 {
64         int rc;
65         MatchingRule *mr;
66
67         switch( usage & SLAP_MR_TYPE_MASK ) {
68         case SLAP_MR_NONE:
69         case SLAP_MR_EQUALITY:
70                 mr = ad->ad_type->sat_equality;
71                 break;
72         case SLAP_MR_ORDERING:
73                 mr = ad->ad_type->sat_ordering;
74                 break;
75         case SLAP_MR_SUBSTR:
76                 mr = ad->ad_type->sat_substr;
77                 break;
78         case SLAP_MR_EXT:
79         default:
80                 assert( 0 );
81                 *text = "internal error";
82                 return LDAP_OTHER;
83         }
84
85         if( mr == NULL ) {
86                 *text = "inappropriate matching request";
87                 return LDAP_INAPPROPRIATE_MATCHING;
88         }
89
90         /* we only support equality matching of binary attributes */
91         /* This is suspect, flexible certificate matching will hit this */
92         if( slap_ad_is_binary( ad ) && usage != SLAP_MR_EQUALITY ) {
93                 *text = "inappropriate binary matching";
94                 return LDAP_INAPPROPRIATE_MATCHING;
95         }
96
97         if( mr->smr_normalize ) {
98                 rc = (mr->smr_normalize)( usage,
99                         ad->ad_type->sat_syntax,
100                         mr, in, out );
101
102                 if( rc != LDAP_SUCCESS ) {
103                         *text = "unable to normalize value";
104                         return LDAP_INVALID_SYNTAX;
105                 }
106
107         } else if ( mr->smr_syntax->ssyn_normalize ) {
108                 rc = (mr->smr_syntax->ssyn_normalize)(
109                         ad->ad_type->sat_syntax,
110                         in, out );
111
112                 if( rc != LDAP_SUCCESS ) {
113                         *text = "unable to normalize value";
114                         return LDAP_INVALID_SYNTAX;
115                 }
116
117         } else {
118                 ber_dupbv( out, in );
119         }
120
121         return LDAP_SUCCESS;
122 }
123
124
125 int
126 value_match(
127         int *match,
128         AttributeDescription *ad,
129         MatchingRule *mr,
130         unsigned flags,
131         struct berval *v1, /* stored value */
132         void *v2, /* assertion */
133         const char ** text )
134 {
135         int rc;
136         struct berval nv1 = { 0, NULL };
137         struct berval nv2 = { 0, NULL };
138
139         if( !mr->smr_match ) {
140                 return LDAP_INAPPROPRIATE_MATCHING;
141         }
142
143         if( ad->ad_type->sat_syntax->ssyn_normalize ) {
144                 rc = ad->ad_type->sat_syntax->ssyn_normalize(
145                         ad->ad_type->sat_syntax, v1, &nv1 );
146
147                 if( rc != LDAP_SUCCESS ) {
148                         return LDAP_INAPPROPRIATE_MATCHING;
149                 }
150         }
151
152         if ( SLAP_IS_MR_VALUE_SYNTAX_NONCONVERTED_MATCH( flags ) &&
153                 mr->smr_convert )
154         {
155                 rc = (mr->smr_convert)( v2, &nv2 );
156                 if ( rc != LDAP_SUCCESS ) {
157                         return LDAP_INVALID_SYNTAX;
158                 }
159
160                 /* let smr_match know we've converted the value */
161                 flags |= SLAP_MR_VALUE_SYNTAX_CONVERTED_MATCH;
162         }
163
164         rc = (mr->smr_match)( match, flags,
165                 ad->ad_type->sat_syntax,
166                 mr,
167                 nv1.bv_val != NULL ? &nv1 : v1,
168                 nv2.bv_val != NULL ? &nv2 : v2 );
169         
170         if (nv1.bv_val ) free( nv1.bv_val );
171         if (nv2.bv_val ) free( nv2.bv_val );
172         return rc;
173 }
174
175
176 int value_find_ex(
177         AttributeDescription *ad,
178         unsigned flags,
179         BVarray vals,
180         struct berval *val )
181 {
182         int     i;
183         int rc;
184         struct berval nval = { 0, NULL };
185         struct berval nval_tmp;
186         MatchingRule *mr = ad->ad_type->sat_equality;
187
188         if( mr == NULL || !mr->smr_match ) {
189                 return LDAP_INAPPROPRIATE_MATCHING;
190         }
191
192         /* Take care of this here or ssyn_normalize later will hurt */
193         if ( SLAP_IS_MR_VALUE_SYNTAX_NONCONVERTED_MATCH( flags )
194                 && mr->smr_convert )
195         {
196                 rc = (mr->smr_convert)( val, &nval );
197                 if ( rc != LDAP_SUCCESS ) {
198                         return LDAP_INVALID_SYNTAX;
199                 }
200
201                 /* let value_match know we've done the version */
202                 flags |= SLAP_MR_VALUE_SYNTAX_CONVERTED_MATCH;
203         }
204
205         if( mr->smr_syntax->ssyn_normalize ) {
206                 rc = mr->smr_syntax->ssyn_normalize(
207                         mr->smr_syntax, nval.bv_val == NULL ? val : &nval, &nval_tmp );
208
209                 free(nval.bv_val);
210                 nval = nval_tmp;
211                 if( rc != LDAP_SUCCESS ) {
212                         free(nval.bv_val);
213                         return LDAP_INAPPROPRIATE_MATCHING;
214                 }
215         }
216
217         for ( i = 0; vals[i].bv_val != NULL; i++ ) {
218                 int match;
219                 const char *text;
220
221                 rc = value_match( &match, ad, mr, flags,
222                         &vals[i], nval.bv_val == NULL ? val : &nval, &text );
223
224                 if( rc == LDAP_SUCCESS && match == 0 ) {
225                         free( nval.bv_val );
226                         return LDAP_SUCCESS;
227                 }
228         }
229
230         free( nval.bv_val );
231         return LDAP_NO_SUCH_ATTRIBUTE;
232 }