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