]> git.sur5r.net Git - openldap/blob - servers/slapd/filterentry.c
use auth sockbuf max
[openldap] / servers / slapd / filterentry.c
1 /* filterentry.c - apply a filter to an entry */
2 /* $OpenLDAP$ */
3 /*
4  * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
5  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
6  */
7
8 #include "portable.h"
9
10 #include <stdio.h>
11
12 #include <ac/socket.h>
13 #include <ac/string.h>
14
15
16 #include "slap.h"
17
18 static int      test_filter_and( Backend *be,
19         Connection *conn, Operation *op,
20         Entry *e, Filter *flist );
21 static int      test_filter_or( Backend *be,
22         Connection *conn, Operation *op,
23         Entry *e, Filter *flist );
24 static int      test_substrings_filter( Backend *be,
25         Connection *conn, Operation *op,
26         Entry *e, Filter *f);
27 static int      test_ava_filter( Backend *be,
28         Connection *conn, Operation *op,
29         Entry *e, AttributeAssertion *ava, int type );
30 static int      test_mra_filter( Backend *be,
31         Connection *conn, Operation *op,
32         Entry *e, MatchingRuleAssertion *mra );
33 static int      test_presence_filter( Backend *be,
34         Connection *conn, Operation *op,
35         Entry *e, AttributeDescription *desc );
36
37
38 /*
39  * test_filter - test a filter against a single entry.
40  * returns:
41  *              LDAP_COMPARE_TRUE               filter matched
42  *              LDAP_COMPARE_FALSE              filter did not match
43  *              SLAPD_COMPARE_UNDEFINED filter is undefined
44  *      or an ldap result code indicating error
45  */
46
47 int
48 test_filter(
49     Backend     *be,
50     Connection  *conn,
51     Operation   *op,
52     Entry       *e,
53     Filter      *f
54 )
55 {
56         int     rc;
57
58 #ifdef NEW_LOGGING
59         LDAP_LOG( FILTER, ENTRY, "test_filter: begin\n", 0, 0, 0 );
60 #else
61         Debug( LDAP_DEBUG_FILTER, "=> test_filter\n", 0, 0, 0 );
62 #endif
63
64
65         switch ( f->f_choice ) {
66         case SLAPD_FILTER_COMPUTED:
67 #ifdef NEW_LOGGING
68                 LDAP_LOG( FILTER, DETAIL1,
69                         "test_filter:   COMPUTED %s (%d)\n",
70                         f->f_result == LDAP_COMPARE_FALSE ? "false" :
71                         f->f_result == LDAP_COMPARE_TRUE         ? "true"  :
72                         f->f_result == SLAPD_COMPARE_UNDEFINED ? "undefined" :
73                         "error", f->f_result, 0 );
74 #else
75                 Debug( LDAP_DEBUG_FILTER, "    COMPUTED %s (%d)\n",
76                         f->f_result == LDAP_COMPARE_FALSE ? "false" :
77                         f->f_result == LDAP_COMPARE_TRUE ? "true" :
78                         f->f_result == SLAPD_COMPARE_UNDEFINED ? "undefined" : "error",
79                         f->f_result, 0 );
80 #endif
81
82                 rc = f->f_result;
83                 break;
84
85         case LDAP_FILTER_EQUALITY:
86 #ifdef NEW_LOGGING
87                 LDAP_LOG( FILTER, DETAIL1, "test_filter:   EQUALITY\n", 0, 0, 0 );
88 #else
89                 Debug( LDAP_DEBUG_FILTER, "    EQUALITY\n", 0, 0, 0 );
90 #endif
91
92                 rc = test_ava_filter( be, conn, op, e, f->f_ava,
93                     LDAP_FILTER_EQUALITY );
94                 break;
95
96         case LDAP_FILTER_SUBSTRINGS:
97 #ifdef NEW_LOGGING
98                 LDAP_LOG( FILTER, DETAIL1, "test_filter  SUBSTRINGS\n", 0, 0, 0 );
99 #else
100                 Debug( LDAP_DEBUG_FILTER, "    SUBSTRINGS\n", 0, 0, 0 );
101 #endif
102
103                 rc = test_substrings_filter( be, conn, op, e, f );
104                 break;
105
106         case LDAP_FILTER_GE:
107                 rc = test_ava_filter( be, conn, op, e, f->f_ava,
108                     LDAP_FILTER_GE );
109                 break;
110
111         case LDAP_FILTER_LE:
112                 rc = test_ava_filter( be, conn, op, e, f->f_ava,
113                     LDAP_FILTER_LE );
114                 break;
115
116         case LDAP_FILTER_PRESENT:
117 #ifdef NEW_LOGGING
118                 LDAP_LOG( FILTER, DETAIL1, "test_filter:        PRESENT\n", 0, 0, 0 );
119 #else
120                 Debug( LDAP_DEBUG_FILTER, "    PRESENT\n", 0, 0, 0 );
121 #endif
122
123                 rc = test_presence_filter( be, conn, op, e, f->f_desc );
124                 break;
125
126         case LDAP_FILTER_APPROX:
127 #ifdef NEW_LOGGING
128                 LDAP_LOG( FILTER, DETAIL1, "test_filter: APPROX\n", 0, 0, 0 );
129 #else
130                 Debug( LDAP_DEBUG_FILTER, "    APPROX\n", 0, 0, 0 );
131 #endif
132                 rc = test_ava_filter( be, conn, op, e, f->f_ava,
133                     LDAP_FILTER_APPROX );
134                 break;
135
136         case LDAP_FILTER_AND:
137 #ifdef NEW_LOGGING
138                 LDAP_LOG( FILTER, DETAIL1, "test_filter:  AND\n", 0, 0, 0 );
139 #else
140                 Debug( LDAP_DEBUG_FILTER, "    AND\n", 0, 0, 0 );
141 #endif
142
143                 rc = test_filter_and( be, conn, op, e, f->f_and );
144                 break;
145
146         case LDAP_FILTER_OR:
147 #ifdef NEW_LOGGING
148                 LDAP_LOG( FILTER, DETAIL1, "test_filter:        OR\n", 0, 0, 0 );
149 #else
150                 Debug( LDAP_DEBUG_FILTER, "    OR\n", 0, 0, 0 );
151 #endif
152
153                 rc = test_filter_or( be, conn, op, e, f->f_or );
154                 break;
155
156         case LDAP_FILTER_NOT:
157 #ifdef NEW_LOGGING
158                 LDAP_LOG( FILTER, DETAIL1, "test_filter:        NOT\n", 0, 0, 0 );
159 #else
160                 Debug( LDAP_DEBUG_FILTER, "    NOT\n", 0, 0, 0 );
161 #endif
162
163                 rc = test_filter( be, conn, op, e, f->f_not );
164
165                 /* Flip true to false and false to true
166                  * but leave Undefined alone.
167                  */
168                 switch( rc ) {
169                 case LDAP_COMPARE_TRUE:
170                         rc = LDAP_COMPARE_FALSE;
171                         break;
172                 case LDAP_COMPARE_FALSE:
173                         rc = LDAP_COMPARE_TRUE;
174                         break;
175                 }
176                 break;
177
178         case LDAP_FILTER_EXT:
179 #ifdef NEW_LOGGING
180                 LDAP_LOG( FILTER, DETAIL1, "test_filter:        EXT\n", 0, 0, 0 );
181 #else
182                 Debug( LDAP_DEBUG_FILTER, "    EXT\n", 0, 0, 0 );
183 #endif
184
185                 rc = test_mra_filter( be, conn, op, e, f->f_mra );
186                 break;
187
188         default:
189 #ifdef NEW_LOGGING
190                 LDAP_LOG( FILTER, INFO, 
191                         "test_filter:  unknown filter type %lu\n", f->f_choice, 0, 0 );
192 #else
193                 Debug( LDAP_DEBUG_ANY, "    unknown filter type %lu\n",
194                     f->f_choice, 0, 0 );
195 #endif
196
197                 rc = LDAP_PROTOCOL_ERROR;
198         }
199
200 #ifdef NEW_LOGGING
201         LDAP_LOG( FILTER, RESULTS, "test_filter:  return=%d\n", rc, 0, 0 );
202 #else
203         Debug( LDAP_DEBUG_FILTER, "<= test_filter %d\n", rc, 0, 0 );
204 #endif
205
206         return( rc );
207 }
208
209 static int test_mra_filter(
210         Backend *be,
211         Connection *conn,
212         Operation *op,
213         Entry *e,
214         MatchingRuleAssertion *mra )
215 {
216         Attribute       *a;
217
218         if( !access_allowed( be, conn, op, e,
219                 mra->ma_desc, &mra->ma_value, ACL_SEARCH, NULL ) )
220         {
221                 return LDAP_INSUFFICIENT_ACCESS;
222         }
223
224         for(a = attrs_find( e->e_attrs, mra->ma_desc );
225                 a != NULL;
226                 a = attrs_find( a->a_next, mra->ma_desc ) )
227         {
228                 struct berval *bv;
229                 for ( bv = a->a_vals; bv->bv_val != NULL; bv++ ) {
230                         int ret;
231                         int rc;
232                         const char *text;
233
234                         rc = value_match( &ret, a->a_desc, mra->ma_rule,
235                                 SLAP_MR_ASSERTION_SYNTAX_MATCH,
236                                 bv, &mra->ma_value,
237                                 &text );
238
239                         if( rc != LDAP_SUCCESS ) {
240                                 return rc;
241                         }
242
243                         if ( ret == 0 ) {
244                                 return LDAP_COMPARE_TRUE;
245                         }
246                 }
247         }
248
249         return LDAP_COMPARE_FALSE;
250 }
251
252 static int
253 test_ava_filter(
254     Backend     *be,
255     Connection  *conn,
256     Operation   *op,
257     Entry       *e,
258         AttributeAssertion *ava,
259     int         type
260 )
261 {
262         Attribute       *a;
263
264         if ( !access_allowed( be, conn, op, e,
265                 ava->aa_desc, &ava->aa_value, ACL_SEARCH, NULL ) )
266         {
267                 return LDAP_INSUFFICIENT_ACCESS;
268         }
269
270         for(a = attrs_find( e->e_attrs, ava->aa_desc );
271                 a != NULL;
272                 a = attrs_find( a->a_next, ava->aa_desc ) )
273         {
274                 MatchingRule *mr;
275                 struct berval *bv;
276
277                 switch ( type ) {
278                 case LDAP_FILTER_APPROX:
279                         mr = a->a_desc->ad_type->sat_approx;
280                         if( mr != NULL ) break;
281
282                         /* use EQUALITY matching rule if no APPROX rule */
283
284                 case LDAP_FILTER_EQUALITY:
285                         mr = a->a_desc->ad_type->sat_equality;
286                         break;
287
288                 case LDAP_FILTER_GE:
289                 case LDAP_FILTER_LE:
290                         mr = a->a_desc->ad_type->sat_ordering;
291                         break;
292
293                 default:
294                         mr = NULL;
295                 }
296
297                 if( mr == NULL ) {
298                         continue;
299                 }
300
301                 for ( bv = a->a_vals; bv->bv_val != NULL; bv++ ) {
302                         int ret;
303                         int rc;
304                         const char *text;
305
306                         rc = value_match( &ret, a->a_desc, mr,
307                                 SLAP_MR_ASSERTION_SYNTAX_MATCH,
308                                 bv, &ava->aa_value, &text );
309
310                         if( rc != LDAP_SUCCESS ) {
311                                 return rc;
312                         }
313
314                         switch ( type ) {
315                         case LDAP_FILTER_EQUALITY:
316                         case LDAP_FILTER_APPROX:
317                                 if ( ret == 0 ) {
318                                         return LDAP_COMPARE_TRUE;
319                                 }
320                                 break;
321
322                         case LDAP_FILTER_GE:
323                                 if ( ret >= 0 ) {
324                                         return LDAP_COMPARE_TRUE;
325                                 }
326                                 break;
327
328                         case LDAP_FILTER_LE:
329                                 if ( ret <= 0 ) {
330                                         return LDAP_COMPARE_TRUE;
331                                 }
332                                 break;
333                         }
334                 }
335         }
336
337         return( LDAP_COMPARE_FALSE );
338 }
339
340
341 static int
342 test_presence_filter(
343     Backend     *be,
344     Connection  *conn,
345     Operation   *op,
346     Entry       *e,
347         AttributeDescription *desc
348 )
349 {
350         if ( !access_allowed( be, conn, op, e, desc, NULL, ACL_SEARCH, NULL ) )
351         {
352                 return LDAP_INSUFFICIENT_ACCESS;
353         }
354
355         return attrs_find( e->e_attrs, desc ) != NULL
356                 ? LDAP_COMPARE_TRUE : LDAP_COMPARE_FALSE;
357 }
358
359
360 static int
361 test_filter_and(
362     Backend     *be,
363     Connection  *conn,
364     Operation   *op,
365     Entry       *e,
366     Filter      *flist
367 )
368 {
369         Filter  *f;
370         int rtn = LDAP_COMPARE_TRUE; /* True if empty */
371
372 #ifdef NEW_LOGGING
373         LDAP_LOG( FILTER, ENTRY, "test_filter_and: begin\n", 0, 0, 0 );
374 #else
375         Debug( LDAP_DEBUG_FILTER, "=> test_filter_and\n", 0, 0, 0 );
376 #endif
377
378
379         for ( f = flist; f != NULL; f = f->f_next ) {
380                 int rc = test_filter( be, conn, op, e, f );
381
382                 if ( rc == LDAP_COMPARE_FALSE ) {
383                         /* filter is False */
384                         rtn = rc;
385                         break;
386                 }
387
388                 if ( rc != LDAP_COMPARE_TRUE ) {
389                         /* filter is Undefined unless later elements are False */
390                         rtn = rc;
391                 }
392         }
393
394 #ifdef NEW_LOGGING
395         LDAP_LOG( FILTER, RESULTS, "test_filter_and:  rc=%d\n", rtn, 0, 0 );
396 #else
397         Debug( LDAP_DEBUG_FILTER, "<= test_filter_and %d\n", rtn, 0, 0 );
398 #endif
399
400         return rtn;
401 }
402
403 static int
404 test_filter_or(
405     Backend     *be,
406     Connection  *conn,
407     Operation   *op,
408     Entry       *e,
409     Filter      *flist
410 )
411 {
412         Filter  *f;
413         int rtn = LDAP_COMPARE_FALSE; /* False if empty */
414
415 #ifdef NEW_LOGGING
416         LDAP_LOG( FILTER, ENTRY, "test_filter_or: begin\n", 0, 0, 0 );
417 #else
418         Debug( LDAP_DEBUG_FILTER, "=> test_filter_or\n", 0, 0, 0 );
419 #endif
420
421
422         for ( f = flist; f != NULL; f = f->f_next ) {
423                 int rc = test_filter( be, conn, op, e, f );
424
425                 if ( rc == LDAP_COMPARE_TRUE ) {
426                         /* filter is True */
427                         rtn = rc;
428                         break;
429                 }
430
431                 if ( rc != LDAP_COMPARE_FALSE ) {
432                         /* filter is Undefined unless later elements are True */
433                         rtn = rc;
434                 }
435         }
436
437 #ifdef NEW_LOGGING
438         LDAP_LOG( FILTER, ENTRY, "test_filter_or: result=%d\n", rtn, 0, 0 );
439 #else
440         Debug( LDAP_DEBUG_FILTER, "<= test_filter_or %d\n", rtn, 0, 0 );
441 #endif
442
443         return rtn;
444 }
445
446
447 static int
448 test_substrings_filter(
449     Backend     *be,
450     Connection  *conn,
451     Operation   *op,
452     Entry       *e,
453     Filter      *f
454 )
455 {
456         Attribute       *a;
457
458 #ifdef NEW_LOGGING
459         LDAP_LOG( FILTER, ENTRY, "test_substrings_filter: begin\n", 0, 0, 0 );
460 #else
461         Debug( LDAP_DEBUG_FILTER, "begin test_substrings_filter\n", 0, 0, 0 );
462 #endif
463
464
465         if ( !access_allowed( be, conn, op, e,
466                 f->f_sub_desc, NULL, ACL_SEARCH, NULL ) )
467         {
468                 return LDAP_INSUFFICIENT_ACCESS;
469         }
470
471         for(a = attrs_find( e->e_attrs, f->f_sub_desc );
472                 a != NULL;
473                 a = attrs_find( a->a_next, f->f_sub_desc ) )
474         {
475                 MatchingRule *mr = a->a_desc->ad_type->sat_substr;
476                 struct berval *bv;
477
478                 if( mr == NULL ) {
479                         continue;
480                 }
481
482                 for ( bv = a->a_vals; bv->bv_val != NULL; bv++ ) {
483                         int ret;
484                         int rc;
485                         const char *text;
486
487                         rc = value_match( &ret, a->a_desc, mr,
488                                 SLAP_MR_ASSERTION_SYNTAX_MATCH,
489                                 bv, f->f_sub, &text );
490
491                         if( rc != LDAP_SUCCESS ) {
492                                 return rc;
493                         }
494
495                         if ( ret == 0 ) {
496                                 return LDAP_COMPARE_TRUE;
497                         }
498                 }
499         }
500
501 #ifdef NEW_LOGGING
502         LDAP_LOG( FILTER, ENTRY, "test_substrings_filter: return FALSE\n", 0, 0, 0 );
503 #else
504         Debug( LDAP_DEBUG_FILTER, "end test_substrings_filter 1\n", 0, 0, 0 );
505 #endif
506
507         return LDAP_COMPARE_FALSE;
508 }