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