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