]> git.sur5r.net Git - openldap/blob - servers/slapd/matchedValues.c
SLAP_NVALUES:
[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                 for ( bv = a->a_vals, j=0; bv->bv_val != NULL; bv++, j++ ) {
239                         int ret;
240                         int rc;
241                         const char *text;
242
243                         rc = value_match( &ret, a->a_desc, mr, 0,
244                                 bv, &ava->aa_value, &text );
245                         if( rc != LDAP_SUCCESS ) {
246                                 return rc;
247                         }
248
249                         switch ( type ) {
250                         case LDAP_FILTER_EQUALITY:
251                         case LDAP_FILTER_APPROX:
252                                 if ( ret == 0 ) {
253                                         (*e_flags)[i][j] = 1;
254                                 }
255                                 break;
256         
257                         case LDAP_FILTER_GE:
258                                 if ( ret >= 0 ) {
259                                         (*e_flags)[i][j] = 1;
260                                 }
261                                 break;
262         
263                         case LDAP_FILTER_LE:
264                                 if ( ret <= 0 ) {
265                                         (*e_flags)[i][j] = 1;
266                                 }
267                                 break;
268                         }
269                 }
270         }
271         return( LDAP_SUCCESS );
272 }
273
274 static int
275 test_presence_vrFilter(
276         Backend         *be,
277         Connection      *conn,
278         Operation       *op,
279         Attribute       *a,
280         AttributeDescription *desc,
281         char            ***e_flags
282 )
283 {
284         int i, j;
285
286         for ( i=0; a != NULL; a = a->a_next, i++ ) {
287                 struct berval *bv;
288
289                 if ( !is_ad_subtype( a->a_desc, desc ) ) {
290                         continue;
291                 }
292
293                 for ( bv = a->a_vals, j=0; bv->bv_val != NULL; bv++, j++ );
294                 memset( (*e_flags)[i], 1, j);
295         }
296
297         return( LDAP_SUCCESS );
298 }
299
300 static int
301 test_substrings_vrFilter(
302         Backend         *be,
303         Connection      *conn,
304         Operation       *op,
305         Attribute       *a,
306         ValuesReturnFilter *vrf,
307         char            ***e_flags
308 )
309 {
310         int i, j;
311
312         for ( i=0; a != NULL; a = a->a_next, i++ ) {
313                 MatchingRule *mr = a->a_desc->ad_type->sat_substr;
314                 struct berval *bv;
315
316                 if ( !is_ad_subtype( a->a_desc, vrf->vrf_sub_desc ) ) {
317                         continue;
318                 }
319
320                 if( mr == NULL ) {
321                         continue;
322                 }
323
324                 for ( bv = a->a_vals, j = 0; bv->bv_val != NULL; bv++, j++ ) {
325                         int ret;
326                         int rc;
327                         const char *text;
328
329                         rc = value_match( &ret, a->a_desc, mr, 0,
330                                 bv, vrf->vrf_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
346 test_mra_vrFilter(
347         Backend         *be,
348         Connection      *conn,
349         Operation       *op,
350         Attribute       *a,
351         MatchingRuleAssertion *mra,
352         char            ***e_flags
353 )
354 {
355         int i, j;
356
357         for ( i=0; a != NULL; a = a->a_next, i++ ) {
358                 struct berval *bv, value;
359
360                 if ( mra->ma_desc ) {
361                         if ( !is_ad_subtype( a->a_desc, mra->ma_desc ) ) {
362                                 continue;
363                         }
364                         value = mra->ma_value;
365
366                 } else {
367                         int rc;
368                         const char      *text = NULL;
369
370                         /* check if matching is appropriate */
371                         if ( strcmp( mra->ma_rule->smr_syntax->ssyn_oid,
372                                 a->a_desc->ad_type->sat_syntax->ssyn_oid ) != 0 ) {
373                                 continue;
374                         }
375
376 #ifdef SLAP_NVALUES
377                         rc = asserted_value_validate_normalize( a->a_desc, mra->ma_rule,
378                                 SLAP_MR_EXT|SLAP_MR_VALUE_OF_ASSERTION_SYNTAX,
379                                 &mra->ma_value, &value, &text );
380 #else
381                         /* normalize for equality */
382                         rc = value_validate_normalize( a->a_desc, 
383                                 SLAP_MR_EQUALITY,
384                                 &mra->ma_value, &value,
385                                 &text );
386 #endif
387
388                         if( rc != LDAP_SUCCESS ) continue;
389                 }
390
391                 for ( bv = a->a_vals, j = 0; bv->bv_val != NULL; bv++, j++ ) {
392                         int ret;
393                         int rc;
394                         const char *text;
395
396                         rc = value_match( &ret, a->a_desc, mra->ma_rule, 0,
397                                 bv, &value, &text );
398                         if( rc != LDAP_SUCCESS ) {
399                                 return rc;
400                         }
401
402                         if ( ret == 0 ) {
403                                 (*e_flags)[i][j] = 1;
404                         }
405                 }
406         }
407
408         return LDAP_SUCCESS;
409 }