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