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