]> git.sur5r.net Git - openldap/blob - servers/slapd/matchedValues.c
22a0ad17eeac3a5ac5b4dd1f511d0b64df7fbc1d
[openldap] / servers / slapd / matchedValues.c
1 /* $OpenLDAP$ */
2 /* 
3  * Copyright 1999-2003 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
23 test_mra_vrFilter(
24         Operation       *op,
25         Attribute       *a,
26         MatchingRuleAssertion *mra,
27         char            ***e_flags
28 );
29
30 static int
31 test_substrings_vrFilter(
32         Operation       *op,
33         Attribute       *a,
34         ValuesReturnFilter *f,
35         char            ***e_flags
36 );
37
38 static int
39 test_presence_vrFilter(
40         Operation       *op,
41         Attribute       *a,
42         AttributeDescription *desc,
43         char            ***e_flags
44 );
45
46 static int
47 test_ava_vrFilter(
48         Operation       *op,
49         Attribute       *a,
50         AttributeAssertion *ava,
51         int             type,
52         char            ***e_flags
53 );
54
55
56 int
57 filter_matched_values( 
58         Operation       *op,
59         Attribute       *a,
60         char            ***e_flags
61 )
62 {
63         ValuesReturnFilter *vrf;
64         int             rc = LDAP_SUCCESS;
65
66 #ifdef NEW_LOGGING
67         LDAP_LOG( FILTER, ENTRY, "filter_matched_values: begin\n", 0, 0, 0 );
68 #else
69         Debug( LDAP_DEBUG_FILTER, "=> filter_matched_values\n", 0, 0, 0 );
70 #endif
71
72         for ( vrf = op->vrFilter; vrf != NULL; vrf = vrf->vrf_next ) {
73                 switch ( vrf->vrf_choice ) {
74                 case SLAPD_FILTER_COMPUTED:
75 #ifdef NEW_LOGGING
76                         LDAP_LOG( FILTER, DETAIL1, 
77                                 "test_vrFilter: COMPUTED %s (%d)\n",
78                                 vrf->vrf_result == LDAP_COMPARE_FALSE ? "false" :
79                                 vrf->vrf_result == LDAP_COMPARE_TRUE     ? "true"  :
80                                 vrf->vrf_result == SLAPD_COMPARE_UNDEFINED ? "undefined" :
81                                 "error", vrf->vrf_result, 0 );
82 #else
83                         Debug( LDAP_DEBUG_FILTER, "     COMPUTED %s (%d)\n",
84                                 vrf->vrf_result == LDAP_COMPARE_FALSE ? "false" :
85                                 vrf->vrf_result == LDAP_COMPARE_TRUE ? "true" :
86                                 vrf->vrf_result == SLAPD_COMPARE_UNDEFINED ? "undefined" : "error",
87                                 vrf->vrf_result, 0 );
88 #endif
89                         /*This type of filter does not affect the result */
90                         rc = LDAP_SUCCESS;
91                 break;
92
93                 case LDAP_FILTER_EQUALITY:
94 #ifdef NEW_LOGGING
95                         LDAP_LOG( FILTER, DETAIL1, "test_vrFilter: EQUALITY\n", 0, 0, 0 );
96 #else
97                         Debug( LDAP_DEBUG_FILTER, "     EQUALITY\n", 0, 0, 0 );
98 #endif
99                         rc = test_ava_vrFilter( op, a, vrf->vrf_ava,
100                                 LDAP_FILTER_EQUALITY, e_flags );
101                         if( rc == -1 ) {
102                                 return rc;
103                         }
104                         break;
105
106                 case LDAP_FILTER_SUBSTRINGS:
107 #ifdef NEW_LOGGING
108                         LDAP_LOG( FILTER, DETAIL1, "test_vrFilter  SUBSTRINGS\n", 0, 0, 0 );
109 #else
110                         Debug( LDAP_DEBUG_FILTER, "     SUBSTRINGS\n", 0, 0, 0 );
111 #endif
112
113                         rc = test_substrings_vrFilter( op, a,
114                                 vrf, e_flags );
115                         if( rc == -1 ) {
116                                 return rc;
117                         }
118                         break;
119
120                 case LDAP_FILTER_PRESENT:
121 #ifdef NEW_LOGGING
122                         LDAP_LOG( FILTER, DETAIL1, "test_vrFilter:      PRESENT\n", 0, 0, 0 );
123 #else
124                         Debug( LDAP_DEBUG_FILTER, "     PRESENT\n", 0, 0, 0 );
125 #endif
126                         rc = test_presence_vrFilter( op, a,
127                                 vrf->vrf_desc, e_flags );
128                         if( rc == -1 ) {
129                                 return rc;
130                         }
131                         break;
132
133                 case LDAP_FILTER_GE:
134                         rc = test_ava_vrFilter( op, a, vrf->vrf_ava,
135                                 LDAP_FILTER_GE, e_flags );
136                         if( rc == -1 ) {
137                                 return rc;
138                         }
139                         break;
140
141                 case LDAP_FILTER_LE:
142                         rc = test_ava_vrFilter( op, a, vrf->vrf_ava,
143                                 LDAP_FILTER_LE, e_flags );
144                         if( rc == -1 ) {
145                                 return rc;
146                         }
147                         break;
148
149                 case LDAP_FILTER_EXT:
150 #ifdef NEW_LOGGING
151                         LDAP_LOG( FILTER, DETAIL1, "test_vrFilter:      EXT\n", 0, 0, 0 );
152 #else
153                         Debug( LDAP_DEBUG_FILTER, "     EXT\n", 0, 0, 0 );
154 #endif
155                         rc = test_mra_vrFilter( op, a,
156                                 vrf->vrf_mra, e_flags );
157                         if( rc == -1 ) {
158                                 return rc;
159                         }
160                         break;
161
162                 default:
163 #ifdef NEW_LOGGING
164                         LDAP_LOG( FILTER, INFO, 
165                                 "test_vrFilter:  unknown filter type %lu\n", vrf->vrf_choice, 0, 0 );
166 #else
167                         Debug( LDAP_DEBUG_ANY, "        unknown filter type %lu\n",
168                                 vrf->vrf_choice, 0, 0 );
169 #endif
170                         rc = LDAP_PROTOCOL_ERROR;
171                 } 
172         }
173
174 #ifdef NEW_LOGGING
175         LDAP_LOG( FILTER, ENTRY, "filter_matched_values:  return=%d\n", rc, 0, 0 );
176 #else
177         Debug( LDAP_DEBUG_FILTER, "<= filter_matched_values %d\n", rc, 0, 0 );
178 #endif
179         return( rc );
180 }
181
182 static int
183 test_ava_vrFilter(
184         Operation       *op,
185         Attribute       *a,
186         AttributeAssertion *ava,
187         int             type,
188         char            ***e_flags
189 )
190 {
191         int             i, j;
192
193         for ( i=0; a != NULL; a = a->a_next, i++ ) {
194
195                 MatchingRule *mr;
196                 struct berval *bv;
197         
198                 if ( !is_ad_subtype( a->a_desc, ava->aa_desc ) ) {
199                         continue;
200                 }
201
202                 switch ( type ) {
203                 case LDAP_FILTER_APPROX:
204                         mr = a->a_desc->ad_type->sat_approx;
205                         if( mr != NULL ) break;
206
207                 /* use EQUALITY matching rule if no APPROX rule */
208                 case LDAP_FILTER_EQUALITY:
209                         mr = a->a_desc->ad_type->sat_equality;
210                         break;
211                 
212                 case LDAP_FILTER_GE:
213                 case LDAP_FILTER_LE:
214                         mr = a->a_desc->ad_type->sat_ordering;
215                         break;
216
217                 default:
218                         mr = NULL;
219                 }
220
221                 if( mr == NULL ) {
222                         continue;
223
224                 }
225
226 #ifdef SLAP_NVALUES
227                 bv = a->a_nvals;
228 #else
229                 bv = a->a_vals;
230 #endif
231                 for ( j=0; bv->bv_val != NULL; bv++, j++ ) {
232                         int ret;
233                         int rc;
234                         const char *text;
235
236                         rc = value_match( &ret, a->a_desc, mr, 0,
237                                 bv, &ava->aa_value, &text );
238                         if( rc != LDAP_SUCCESS ) {
239                                 return rc;
240                         }
241
242                         switch ( type ) {
243                         case LDAP_FILTER_EQUALITY:
244                         case LDAP_FILTER_APPROX:
245                                 if ( ret == 0 ) {
246                                         (*e_flags)[i][j] = 1;
247                                 }
248                                 break;
249         
250                         case LDAP_FILTER_GE:
251                                 if ( ret >= 0 ) {
252                                         (*e_flags)[i][j] = 1;
253                                 }
254                                 break;
255         
256                         case LDAP_FILTER_LE:
257                                 if ( ret <= 0 ) {
258                                         (*e_flags)[i][j] = 1;
259                                 }
260                                 break;
261                         }
262                 }
263         }
264         return( LDAP_SUCCESS );
265 }
266
267 static int
268 test_presence_vrFilter(
269         Operation       *op,
270         Attribute       *a,
271         AttributeDescription *desc,
272         char            ***e_flags
273 )
274 {
275         int i, j;
276
277         for ( i=0; a != NULL; a = a->a_next, i++ ) {
278                 struct berval *bv;
279
280                 if ( !is_ad_subtype( a->a_desc, desc ) ) {
281                         continue;
282                 }
283
284                 for ( bv = a->a_vals, j=0; bv->bv_val != NULL; bv++, j++ );
285                 memset( (*e_flags)[i], 1, j);
286         }
287
288         return( LDAP_SUCCESS );
289 }
290
291 static int
292 test_substrings_vrFilter(
293         Operation       *op,
294         Attribute       *a,
295         ValuesReturnFilter *vrf,
296         char            ***e_flags
297 )
298 {
299         int i, j;
300
301         for ( i=0; a != NULL; a = a->a_next, i++ ) {
302                 MatchingRule *mr = a->a_desc->ad_type->sat_substr;
303                 struct berval *bv;
304
305                 if ( !is_ad_subtype( a->a_desc, vrf->vrf_sub_desc ) ) {
306                         continue;
307                 }
308
309                 if( mr == NULL ) {
310                         continue;
311                 }
312
313 #ifdef SLAP_NVALUES
314                 bv = a->a_nvals;
315 #else
316                 bv = a->a_vals;
317 #endif
318                 for ( j = 0; bv->bv_val != NULL; bv++, j++ ) {
319                         int ret;
320                         int rc;
321                         const char *text;
322
323                         rc = value_match( &ret, a->a_desc, mr, 0,
324                                 bv, vrf->vrf_sub, &text );
325
326                         if( rc != LDAP_SUCCESS ) {
327                                 return rc;
328                         }
329
330                         if ( ret == 0 ) {
331                                 (*e_flags)[i][j] = 1;
332                         }
333                 }
334         }
335
336         return LDAP_SUCCESS;
337 }
338
339 static int
340 test_mra_vrFilter(
341         Operation       *op,
342         Attribute       *a,
343         MatchingRuleAssertion *mra,
344         char            ***e_flags
345 )
346 {
347         int i, j;
348
349         for ( i=0; a != NULL; a = a->a_next, i++ ) {
350                 struct berval *bv, value;
351
352                 if ( mra->ma_desc ) {
353                         if ( !is_ad_subtype( a->a_desc, mra->ma_desc ) ) {
354                                 continue;
355                         }
356                         value = mra->ma_value;
357
358                 } else {
359                         int rc;
360                         const char      *text = NULL;
361
362                         /* check if matching is appropriate */
363                         if ( strcmp( mra->ma_rule->smr_syntax->ssyn_oid,
364                                 a->a_desc->ad_type->sat_syntax->ssyn_oid ) != 0 ) {
365                                 continue;
366                         }
367
368 #ifdef SLAP_NVALUES
369                         rc = asserted_value_validate_normalize( a->a_desc, mra->ma_rule,
370                                 SLAP_MR_EXT|SLAP_MR_VALUE_OF_ASSERTION_SYNTAX,
371                                 &mra->ma_value, &value, &text );
372 #else
373                         /* normalize for equality */
374                         rc = value_validate_normalize( a->a_desc, 
375                                 SLAP_MR_EQUALITY,
376                                 &mra->ma_value, &value,
377                                 &text );
378 #endif
379
380                         if( rc != LDAP_SUCCESS ) continue;
381                 }
382
383 #ifdef SLAP_NVALUES
384                 bv = a->a_nvals;
385 #else
386                 bv = a->a_vals;
387 #endif
388                 for ( j = 0; bv->bv_val != NULL; bv++, j++ ) {
389                         int ret;
390                         int rc;
391                         const char *text;
392
393                         rc = value_match( &ret, a->a_desc, mra->ma_rule, 0,
394                                 bv, &value, &text );
395                         if( rc != LDAP_SUCCESS ) {
396                                 return rc;
397                         }
398
399                         if ( ret == 0 ) {
400                                 (*e_flags)[i][j] = 1;
401                         }
402                 }
403         }
404
405         return LDAP_SUCCESS;
406 }