]> git.sur5r.net Git - openldap/blob - servers/slapd/matchedValues.c
fix negative counters; prepare for imrpved count of sent data
[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 {
66         ValuesReturnFilter *vrf;
67         int             rc = LDAP_SUCCESS;
68
69         Debug( LDAP_DEBUG_FILTER, "=> filter_matched_values\n", 0, 0, 0 );
70
71         for ( vrf = op->o_vrFilter; vrf != NULL; vrf = vrf->vrf_next ) {
72                 switch ( vrf->vrf_choice ) {
73                 case SLAPD_FILTER_COMPUTED:
74                         Debug( LDAP_DEBUG_FILTER, "     COMPUTED %s (%d)\n",
75                                 vrf->vrf_result == LDAP_COMPARE_FALSE ? "false" :
76                                 vrf->vrf_result == LDAP_COMPARE_TRUE ? "true" :
77                                 vrf->vrf_result == SLAPD_COMPARE_UNDEFINED ? "undefined" : "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 ) {
88                                 return rc;
89                         }
90                         break;
91
92                 case LDAP_FILTER_SUBSTRINGS:
93                         Debug( LDAP_DEBUG_FILTER, "     SUBSTRINGS\n", 0, 0, 0 );
94
95                         rc = test_substrings_vrFilter( op, a,
96                                 vrf, e_flags );
97                         if( rc == -1 ) {
98                                 return rc;
99                         }
100                         break;
101
102                 case LDAP_FILTER_PRESENT:
103                         Debug( LDAP_DEBUG_FILTER, "     PRESENT\n", 0, 0, 0 );
104                         rc = test_presence_vrFilter( op, a,
105                                 vrf->vrf_desc, e_flags );
106                         if( rc == -1 ) {
107                                 return rc;
108                         }
109                         break;
110
111                 case LDAP_FILTER_GE:
112                         rc = test_ava_vrFilter( op, a, vrf->vrf_ava,
113                                 LDAP_FILTER_GE, e_flags );
114                         if( rc == -1 ) {
115                                 return rc;
116                         }
117                         break;
118
119                 case LDAP_FILTER_LE:
120                         rc = test_ava_vrFilter( op, a, vrf->vrf_ava,
121                                 LDAP_FILTER_LE, e_flags );
122                         if( rc == -1 ) {
123                                 return rc;
124                         }
125                         break;
126
127                 case LDAP_FILTER_EXT:
128                         Debug( LDAP_DEBUG_FILTER, "     EXT\n", 0, 0, 0 );
129                         rc = test_mra_vrFilter( op, a,
130                                 vrf->vrf_mra, e_flags );
131                         if( rc == -1 ) {
132                                 return rc;
133                         }
134                         break;
135
136                 default:
137                         Debug( LDAP_DEBUG_ANY, "        unknown filter type %lu\n",
138                                 vrf->vrf_choice, 0, 0 );
139                         rc = LDAP_PROTOCOL_ERROR;
140                 } 
141         }
142
143         Debug( LDAP_DEBUG_FILTER, "<= filter_matched_values %d\n", rc, 0, 0 );
144         return( rc );
145 }
146
147 static int
148 test_ava_vrFilter(
149         Operation       *op,
150         Attribute       *a,
151         AttributeAssertion *ava,
152         int             type,
153         char            ***e_flags
154 )
155 {
156         int             i, j;
157
158         for ( i=0; a != NULL; a = a->a_next, i++ ) {
159
160                 MatchingRule *mr;
161                 struct berval *bv;
162         
163                 if ( !is_ad_subtype( a->a_desc, ava->aa_desc ) ) {
164                         continue;
165                 }
166
167                 switch ( type ) {
168                 case LDAP_FILTER_APPROX:
169                         mr = a->a_desc->ad_type->sat_approx;
170                         if( mr != NULL ) break;
171                         /* use EQUALITY matching rule if no APPROX rule */
172
173                 case LDAP_FILTER_EQUALITY:
174                         mr = a->a_desc->ad_type->sat_equality;
175                         break;
176                 
177                 case LDAP_FILTER_GE:
178                 case LDAP_FILTER_LE:
179                         mr = a->a_desc->ad_type->sat_ordering;
180                         break;
181
182                 default:
183                         mr = NULL;
184                 }
185
186                 if( mr == NULL ) continue;
187
188                 bv = a->a_nvals;
189                 for ( j=0; bv->bv_val != NULL; bv++, j++ ) {
190                         int ret;
191                         int rc;
192                         const char *text;
193
194                         rc = value_match( &ret, a->a_desc, mr, 0,
195                                 bv, &ava->aa_value, &text );
196                         if( rc != LDAP_SUCCESS ) {
197                                 return rc;
198                         }
199
200                         switch ( type ) {
201                         case LDAP_FILTER_EQUALITY:
202                         case LDAP_FILTER_APPROX:
203                                 if ( ret == 0 ) {
204                                         (*e_flags)[i][j] = 1;
205                                 }
206                                 break;
207         
208                         case LDAP_FILTER_GE:
209                                 if ( ret >= 0 ) {
210                                         (*e_flags)[i][j] = 1;
211                                 }
212                                 break;
213         
214                         case LDAP_FILTER_LE:
215                                 if ( ret <= 0 ) {
216                                         (*e_flags)[i][j] = 1;
217                                 }
218                                 break;
219                         }
220                 }
221         }
222         return( LDAP_SUCCESS );
223 }
224
225 static int
226 test_presence_vrFilter(
227         Operation       *op,
228         Attribute       *a,
229         AttributeDescription *desc,
230         char            ***e_flags
231 )
232 {
233         int i, j;
234
235         for ( i=0; a != NULL; a = a->a_next, i++ ) {
236                 struct berval *bv;
237
238                 if ( !is_ad_subtype( a->a_desc, desc ) ) {
239                         continue;
240                 }
241
242                 for ( bv = a->a_vals, j=0; bv->bv_val != NULL; bv++, j++ );
243                 memset( (*e_flags)[i], 1, j);
244         }
245
246         return( LDAP_SUCCESS );
247 }
248
249 static int
250 test_substrings_vrFilter(
251         Operation       *op,
252         Attribute       *a,
253         ValuesReturnFilter *vrf,
254         char            ***e_flags
255 )
256 {
257         int i, j;
258
259         for ( i=0; a != NULL; a = a->a_next, i++ ) {
260                 MatchingRule *mr = a->a_desc->ad_type->sat_substr;
261                 struct berval *bv;
262
263                 if ( !is_ad_subtype( a->a_desc, vrf->vrf_sub_desc ) ) {
264                         continue;
265                 }
266
267                 if( mr == NULL ) {
268                         continue;
269                 }
270
271                 bv = a->a_nvals;
272                 for ( j = 0; bv->bv_val != NULL; bv++, j++ ) {
273                         int ret;
274                         int rc;
275                         const char *text;
276
277                         rc = value_match( &ret, a->a_desc, mr, 0,
278                                 bv, vrf->vrf_sub, &text );
279
280                         if( rc != LDAP_SUCCESS ) {
281                                 return rc;
282                         }
283
284                         if ( ret == 0 ) {
285                                 (*e_flags)[i][j] = 1;
286                         }
287                 }
288         }
289
290         return LDAP_SUCCESS;
291 }
292
293 static int
294 test_mra_vrFilter(
295         Operation       *op,
296         Attribute       *a,
297         MatchingRuleAssertion *mra,
298         char            ***e_flags
299 )
300 {
301         int i, j;
302
303         for ( i=0; a != NULL; a = a->a_next, i++ ) {
304                 struct berval *bv, assertedValue;
305
306                 if ( mra->ma_desc ) {
307                         if ( !is_ad_subtype( a->a_desc, mra->ma_desc ) ) {
308                                 continue;
309                         }
310                         assertedValue = mra->ma_value;
311
312                 } else {
313                         int rc;
314                         const char      *text = NULL;
315
316                         /* check if matching is appropriate */
317                         if ( !mr_usable_with_at( mra->ma_rule, a->a_desc->ad_type ) ) {
318                                 continue;
319                         }
320
321                         rc = asserted_value_validate_normalize( a->a_desc, mra->ma_rule,
322                                 SLAP_MR_EXT|SLAP_MR_VALUE_OF_ASSERTION_SYNTAX,
323                                 &mra->ma_value, &assertedValue, &text, op->o_tmpmemctx );
324
325                         if( rc != LDAP_SUCCESS ) continue;
326                 }
327
328                 /* check match */
329                 if (mra->ma_rule == a->a_desc->ad_type->sat_equality) {
330                         bv = a->a_nvals;
331                 } else {
332                         bv = a->a_vals;
333                 }
334                                         
335                 for ( j = 0; bv->bv_val != NULL; bv++, j++ ) {
336                         int ret;
337                         int rc;
338                         const char *text;
339
340                         rc = value_match( &ret, a->a_desc, mra->ma_rule, 0,
341                                 bv, &assertedValue, &text );
342                         if( rc != LDAP_SUCCESS ) {
343                                 return rc;
344                         }
345
346                         if ( ret == 0 ) {
347                                 (*e_flags)[i][j] = 1;
348                         }
349                 }
350         }
351
352         return LDAP_SUCCESS;
353 }
354