]> git.sur5r.net Git - openldap/blob - servers/slapd/matchedValues.c
c025d1866ac9e114a913d12be12c424b4e07ba62
[openldap] / servers / slapd / matchedValues.c
1 /* $OpenLDAP$ */
2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
3  *
4  * Copyright 1999-2004 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; bv->bv_val != NULL; bv++, j++ ) {
175                         int ret;
176                         int rc;
177                         const char *text;
178
179                         rc = value_match( &ret, a->a_desc, mr, 0,
180                                 bv, &ava->aa_value, &text );
181                         if( rc != LDAP_SUCCESS ) return rc;
182
183                         switch ( type ) {
184                         case LDAP_FILTER_EQUALITY:
185                         case LDAP_FILTER_APPROX:
186                                 if ( ret == 0 ) {
187                                         (*e_flags)[i][j] = 1;
188                                 }
189                                 break;
190         
191                         case LDAP_FILTER_GE:
192                                 if ( ret >= 0 ) {
193                                         (*e_flags)[i][j] = 1;
194                                 }
195                                 break;
196         
197                         case LDAP_FILTER_LE:
198                                 if ( ret <= 0 ) {
199                                         (*e_flags)[i][j] = 1;
200                                 }
201                                 break;
202                         }
203                 }
204         }
205         return( LDAP_SUCCESS );
206 }
207
208 static int
209 test_presence_vrFilter(
210         Operation       *op,
211         Attribute       *a,
212         AttributeDescription *desc,
213         char            ***e_flags )
214 {
215         int i, j;
216
217         for ( i=0; a != NULL; a = a->a_next, i++ ) {
218                 struct berval *bv;
219
220                 if ( !is_ad_subtype( a->a_desc, desc ) ) continue;
221
222                 for ( bv = a->a_vals, j=0; bv->bv_val != NULL; bv++, j++ );
223                 memset( (*e_flags)[i], 1, j);
224         }
225
226         return( LDAP_SUCCESS );
227 }
228
229 static int
230 test_substrings_vrFilter(
231         Operation       *op,
232         Attribute       *a,
233         ValuesReturnFilter *vrf,
234         char            ***e_flags )
235 {
236         int i, j;
237
238         for ( i=0; a != NULL; a = a->a_next, i++ ) {
239                 MatchingRule *mr = a->a_desc->ad_type->sat_substr;
240                 struct berval *bv;
241
242                 if ( !is_ad_subtype( a->a_desc, vrf->vrf_sub_desc ) ) {
243                         continue;
244                 }
245
246                 if( mr == NULL ) continue;
247
248                 bv = a->a_nvals;
249                 for ( j = 0; bv->bv_val != NULL; bv++, j++ ) {
250                         int ret;
251                         int rc;
252                         const char *text;
253
254                         rc = value_match( &ret, a->a_desc, mr, 0,
255                                 bv, vrf->vrf_sub, &text );
256
257                         if( rc != LDAP_SUCCESS ) {
258                                 return rc;
259                         }
260
261                         if ( ret == 0 ) {
262                                 (*e_flags)[i][j] = 1;
263                         }
264                 }
265         }
266
267         return LDAP_SUCCESS;
268 }
269
270 static int
271 test_mra_vrFilter(
272         Operation       *op,
273         Attribute       *a,
274         MatchingRuleAssertion *mra,
275         char            ***e_flags )
276 {
277         int i, j;
278
279         for ( i=0; a != NULL; a = a->a_next, i++ ) {
280                 struct berval *bv, assertedValue;
281
282                 if ( mra->ma_desc ) {
283                         if ( !is_ad_subtype( a->a_desc, mra->ma_desc ) ) {
284                                 continue;
285                         }
286                         assertedValue = mra->ma_value;
287
288                 } else {
289                         int rc;
290                         const char      *text = NULL;
291
292                         /* check if matching is appropriate */
293                         if ( !mr_usable_with_at( mra->ma_rule, a->a_desc->ad_type ) ) {
294                                 continue;
295                         }
296
297                         rc = asserted_value_validate_normalize( a->a_desc, mra->ma_rule,
298                                 SLAP_MR_EXT|SLAP_MR_VALUE_OF_ASSERTION_SYNTAX,
299                                 &mra->ma_value, &assertedValue, &text, op->o_tmpmemctx );
300
301                         if( rc != LDAP_SUCCESS ) continue;
302                 }
303
304                 /* check match */
305                 if (mra->ma_rule == a->a_desc->ad_type->sat_equality) {
306                         bv = a->a_nvals;
307                 } else {
308                         bv = a->a_vals;
309                 }
310                                         
311                 for ( j = 0; bv->bv_val != NULL; bv++, j++ ) {
312                         int ret;
313                         int rc;
314                         const char *text;
315
316                         rc = value_match( &ret, a->a_desc, mra->ma_rule, 0,
317                                 bv, &assertedValue, &text );
318                         if( rc != LDAP_SUCCESS ) return rc;
319
320                         if ( ret == 0 ) {
321                                 (*e_flags)[i][j] = 1;
322                         }
323                 }
324         }
325
326         return LDAP_SUCCESS;
327 }
328