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