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