]> git.sur5r.net Git - openldap/blob - servers/slapd/matchedValues.c
5617e771126200876bbbd189c25c49dc781b30f4
[openldap] / servers / slapd / matchedValues.c
1 /* $OpenLDAP$ */
2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
3  *
4  * Copyright 1999-2007 The OpenLDAP Foundation.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted only as authorized by the OpenLDAP
9  * Public License.
10  *
11  * A copy of this license is available in the file LICENSE in the
12  * top-level directory of the distribution or, alternatively, at
13  * <http://www.OpenLDAP.org/license.html>.
14  */
15
16 #include "portable.h"
17
18 #include <stdio.h>
19
20 #include <ac/string.h>
21 #include <ac/socket.h>
22
23 #include "slap.h"
24
25 static int
26 test_mra_vrFilter(
27         Operation       *op,
28         Attribute       *a,
29         MatchingRuleAssertion *mra,
30         char            ***e_flags
31 );
32
33 static int
34 test_substrings_vrFilter(
35         Operation       *op,
36         Attribute       *a,
37         ValuesReturnFilter *f,
38         char            ***e_flags
39 );
40
41 static int
42 test_presence_vrFilter(
43         Operation       *op,
44         Attribute       *a,
45         AttributeDescription *desc,
46         char            ***e_flags
47 );
48
49 static int
50 test_ava_vrFilter(
51         Operation       *op,
52         Attribute       *a,
53         AttributeAssertion *ava,
54         int             type,
55         char            ***e_flags
56 );
57
58
59 int
60 filter_matched_values( 
61         Operation       *op,
62         Attribute       *a,
63         char            ***e_flags )
64 {
65         ValuesReturnFilter *vrf;
66         int             rc = LDAP_SUCCESS;
67
68         Debug( LDAP_DEBUG_FILTER, "=> filter_matched_values\n", 0, 0, 0 );
69
70         for ( vrf = op->o_vrFilter; vrf != NULL; vrf = vrf->vrf_next ) {
71                 switch ( vrf->vrf_choice ) {
72                 case SLAPD_FILTER_COMPUTED:
73                         Debug( LDAP_DEBUG_FILTER, "     COMPUTED %s (%d)\n",
74                                 vrf->vrf_result == LDAP_COMPARE_FALSE ? "false"
75                                 : vrf->vrf_result == LDAP_COMPARE_TRUE ? "true"
76                                 : vrf->vrf_result == SLAPD_COMPARE_UNDEFINED ? "undefined"
77                                 : "error",
78                                 vrf->vrf_result, 0 );
79                         /*This type of filter does not affect the result */
80                         rc = LDAP_SUCCESS;
81                 break;
82
83                 case LDAP_FILTER_EQUALITY:
84                         Debug( LDAP_DEBUG_FILTER, "     EQUALITY\n", 0, 0, 0 );
85                         rc = test_ava_vrFilter( op, a, vrf->vrf_ava,
86                                 LDAP_FILTER_EQUALITY, e_flags );
87                         if( rc == -1 ) return rc;
88                         break;
89
90                 case LDAP_FILTER_SUBSTRINGS:
91                         Debug( LDAP_DEBUG_FILTER, "     SUBSTRINGS\n", 0, 0, 0 );
92                         rc = test_substrings_vrFilter( op, a,
93                                 vrf, e_flags );
94                         if( rc == -1 ) return rc;
95                         break;
96
97                 case LDAP_FILTER_PRESENT:
98                         Debug( LDAP_DEBUG_FILTER, "     PRESENT\n", 0, 0, 0 );
99                         rc = test_presence_vrFilter( op, a,
100                                 vrf->vrf_desc, e_flags );
101                         if( rc == -1 ) return rc;
102                         break;
103
104                 case LDAP_FILTER_GE:
105                         rc = test_ava_vrFilter( op, a, vrf->vrf_ava,
106                                 LDAP_FILTER_GE, e_flags );
107                         if( rc == -1 ) return rc;
108                         break;
109
110                 case LDAP_FILTER_LE:
111                         rc = test_ava_vrFilter( op, a, vrf->vrf_ava,
112                                 LDAP_FILTER_LE, e_flags );
113                         if( rc == -1 ) return rc;
114                         break;
115
116                 case LDAP_FILTER_EXT:
117                         Debug( LDAP_DEBUG_FILTER, "     EXT\n", 0, 0, 0 );
118                         rc = test_mra_vrFilter( op, a,
119                                 vrf->vrf_mra, e_flags );
120                         if( rc == -1 ) return rc;
121                         break;
122
123                 default:
124                         Debug( LDAP_DEBUG_ANY, "        unknown filter type %lu\n",
125                                 vrf->vrf_choice, 0, 0 );
126                         rc = LDAP_PROTOCOL_ERROR;
127                 }
128         }
129
130         Debug( LDAP_DEBUG_FILTER, "<= filter_matched_values %d\n", rc, 0, 0 );
131         return( rc );
132 }
133
134 static int
135 test_ava_vrFilter(
136         Operation       *op,
137         Attribute       *a,
138         AttributeAssertion *ava,
139         int             type,
140         char            ***e_flags )
141 {
142         int             i, j;
143
144         for ( i=0; a != NULL; a = a->a_next, i++ ) {
145                 MatchingRule *mr;
146                 struct berval *bv;
147         
148                 if ( !is_ad_subtype( a->a_desc, ava->aa_desc ) ) {
149                         continue;
150                 }
151
152                 switch ( type ) {
153                 case LDAP_FILTER_APPROX:
154                         mr = a->a_desc->ad_type->sat_approx;
155                         if( mr != NULL ) break;
156                         /* use EQUALITY matching rule if no APPROX rule */
157
158                 case LDAP_FILTER_EQUALITY:
159                         mr = a->a_desc->ad_type->sat_equality;
160                         break;
161                 
162                 case LDAP_FILTER_GE:
163                 case LDAP_FILTER_LE:
164                         mr = a->a_desc->ad_type->sat_ordering;
165                         break;
166
167                 default:
168                         mr = NULL;
169                 }
170
171                 if( mr == NULL ) continue;
172
173                 bv = a->a_nvals;
174                 for ( j=0; !BER_BVISNULL( bv ); bv++, j++ ) {
175                         int rc, match;
176                         const char *text;
177
178                         rc = value_match( &match, a->a_desc, mr, 0,
179                                 bv, &ava->aa_value, &text );
180                         if( rc != LDAP_SUCCESS ) return rc;
181
182                         switch ( type ) {
183                         case LDAP_FILTER_EQUALITY:
184                         case LDAP_FILTER_APPROX:
185                                 if ( match == 0 ) {
186                                         (*e_flags)[i][j] = 1;
187                                 }
188                                 break;
189         
190                         case LDAP_FILTER_GE:
191                                 if ( match >= 0 ) {
192                                         (*e_flags)[i][j] = 1;
193                                 }
194                                 break;
195         
196                         case LDAP_FILTER_LE:
197                                 if ( match <= 0 ) {
198                                         (*e_flags)[i][j] = 1;
199                                 }
200                                 break;
201                         }
202                 }
203         }
204         return LDAP_SUCCESS;
205 }
206
207 static int
208 test_presence_vrFilter(
209         Operation       *op,
210         Attribute       *a,
211         AttributeDescription *desc,
212         char            ***e_flags )
213 {
214         int i, j;
215
216         for ( i=0; a != NULL; a = a->a_next, i++ ) {
217                 struct berval *bv;
218
219                 if ( !is_ad_subtype( a->a_desc, desc ) ) continue;
220
221                 for ( bv = a->a_vals, j = 0; !BER_BVISNULL( bv ); bv++, j++ );
222                 memset( (*e_flags)[i], 1, j);
223         }
224
225         return( LDAP_SUCCESS );
226 }
227
228 static int
229 test_substrings_vrFilter(
230         Operation       *op,
231         Attribute       *a,
232         ValuesReturnFilter *vrf,
233         char            ***e_flags )
234 {
235         int i, j;
236
237         for ( i=0; a != NULL; a = a->a_next, i++ ) {
238                 MatchingRule *mr = a->a_desc->ad_type->sat_substr;
239                 struct berval *bv;
240
241                 if ( !is_ad_subtype( a->a_desc, vrf->vrf_sub_desc ) ) {
242                         continue;
243                 }
244
245                 if( mr == NULL ) continue;
246
247                 bv = a->a_nvals;
248                 for ( j = 0; !BER_BVISNULL( bv ); bv++, j++ ) {
249                         int rc, match;
250                         const char *text;
251
252                         rc = value_match( &match, a->a_desc, mr, 0,
253                                 bv, vrf->vrf_sub, &text );
254
255                         if( rc != LDAP_SUCCESS ) return rc;
256
257                         if ( match == 0 ) {
258                                 (*e_flags)[i][j] = 1;
259                         }
260                 }
261         }
262
263         return LDAP_SUCCESS;
264 }
265
266 static int
267 test_mra_vrFilter(
268         Operation       *op,
269         Attribute       *a,
270         MatchingRuleAssertion *mra,
271         char            ***e_flags )
272 {
273         int     i, j;
274
275         for ( i = 0; a != NULL; a = a->a_next, i++ ) {
276                 struct berval   *bv, assertedValue;
277                 int             normalize_attribute = 0;
278
279                 if ( mra->ma_desc ) {
280                         if ( !is_ad_subtype( a->a_desc, mra->ma_desc ) ) {
281                                 continue;
282                         }
283                         assertedValue = mra->ma_value;
284
285                 } else {
286                         int rc;
287                         const char      *text = NULL;
288
289                         /* check if matching is appropriate */
290                         if ( !mr_usable_with_at( mra->ma_rule, a->a_desc->ad_type ) ) {
291                                 continue;
292                         }
293
294                         rc = asserted_value_validate_normalize( a->a_desc, mra->ma_rule,
295                                 SLAP_MR_EXT|SLAP_MR_VALUE_OF_ASSERTION_SYNTAX,
296                                 &mra->ma_value, &assertedValue, &text, op->o_tmpmemctx );
297
298                         if ( rc != LDAP_SUCCESS ) continue;
299                 }
300
301                 /* check match */
302                 if ( mra->ma_rule == a->a_desc->ad_type->sat_equality ) {
303                         bv = a->a_nvals;
304
305                 } else {
306                         bv = a->a_vals;
307                         normalize_attribute = 1;
308                 }
309                                         
310                 for ( j = 0; !BER_BVISNULL( bv ); bv++, j++ ) {
311                         int             rc, match;
312                         const char      *text;
313                         struct berval   nbv = BER_BVNULL;
314
315                         if ( normalize_attribute && mra->ma_rule->smr_normalize ) {
316                                 /* see comment in filterentry.c */
317                                 if ( mra->ma_rule->smr_normalize(
318                                                 SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
319                                                 mra->ma_rule->smr_syntax,
320                                                 mra->ma_rule,
321                                                 bv, &nbv, op->o_tmpmemctx ) != LDAP_SUCCESS )
322                                 {
323                                         /* FIXME: stop processing? */
324                                         continue;
325                                 }
326
327                         } else {
328                                 nbv = *bv;
329                         }
330
331                         rc = value_match( &match, a->a_desc, mra->ma_rule, 0,
332                                 &nbv, &assertedValue, &text );
333
334                         if ( nbv.bv_val != bv->bv_val ) {
335                                 op->o_tmpfree( nbv.bv_val, op->o_tmpmemctx );
336                         }
337
338                         if ( rc != LDAP_SUCCESS ) return rc;
339
340                         if ( match == 0 ) {
341                                 (*e_flags)[i][j] = 1;
342                         }
343                 }
344         }
345
346         return LDAP_SUCCESS;
347 }
348