1 /* $NetBSD: matchedValues.c,v 1.3 2021/08/14 16:14:58 christos Exp $ */
2
3 /* $OpenLDAP$ */
4 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5 *
6 * Copyright 1999-2021 The OpenLDAP Foundation.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted only as authorized by the OpenLDAP
11 * Public License.
12 *
13 * A copy of this license is available in the file LICENSE in the
14 * top-level directory of the distribution or, alternatively, at
15 * <http://www.OpenLDAP.org/license.html>.
16 */
17
18 #include <sys/cdefs.h>
19 __RCSID("$NetBSD: matchedValues.c,v 1.3 2021/08/14 16:14:58 christos Exp $");
20
21 #include "portable.h"
22
23 #include <stdio.h>
24
25 #include <ac/string.h>
26 #include <ac/socket.h>
27
28 #include "slap.h"
29
30 static int
31 test_mra_vrFilter(
32 Operation *op,
33 Attribute *a,
34 MatchingRuleAssertion *mra,
35 char ***e_flags
36 );
37
38 static int
39 test_substrings_vrFilter(
40 Operation *op,
41 Attribute *a,
42 ValuesReturnFilter *f,
43 char ***e_flags
44 );
45
46 static int
47 test_presence_vrFilter(
48 Operation *op,
49 Attribute *a,
50 AttributeDescription *desc,
51 char ***e_flags
52 );
53
54 static int
55 test_ava_vrFilter(
56 Operation *op,
57 Attribute *a,
58 AttributeAssertion *ava,
59 int type,
60 char ***e_flags
61 );
62
63
64 int
filter_matched_values(Operation * op,Attribute * a,char *** e_flags)65 filter_matched_values(
66 Operation *op,
67 Attribute *a,
68 char ***e_flags )
69 {
70 ValuesReturnFilter *vrf;
71 int rc = LDAP_SUCCESS;
72
73 Debug( LDAP_DEBUG_FILTER, "=> filter_matched_values\n" );
74
75 for ( vrf = op->o_vrFilter; vrf != NULL; vrf = vrf->vrf_next ) {
76 switch ( vrf->vrf_choice ) {
77 case SLAPD_FILTER_COMPUTED:
78 Debug( LDAP_DEBUG_FILTER, " COMPUTED %s (%d)\n",
79 vrf->vrf_result == LDAP_COMPARE_FALSE ? "false"
80 : vrf->vrf_result == LDAP_COMPARE_TRUE ? "true"
81 : vrf->vrf_result == SLAPD_COMPARE_UNDEFINED ? "undefined"
82 : "error",
83 vrf->vrf_result );
84 /*This type of filter does not affect the result */
85 rc = LDAP_SUCCESS;
86 break;
87
88 case LDAP_FILTER_EQUALITY:
89 Debug( LDAP_DEBUG_FILTER, " EQUALITY\n" );
90 rc = test_ava_vrFilter( op, a, vrf->vrf_ava,
91 LDAP_FILTER_EQUALITY, e_flags );
92 if( rc == -1 ) return rc;
93 break;
94
95 case LDAP_FILTER_SUBSTRINGS:
96 Debug( LDAP_DEBUG_FILTER, " SUBSTRINGS\n" );
97 rc = test_substrings_vrFilter( op, a,
98 vrf, e_flags );
99 if( rc == -1 ) return rc;
100 break;
101
102 case LDAP_FILTER_PRESENT:
103 Debug( LDAP_DEBUG_FILTER, " PRESENT\n" );
104 rc = test_presence_vrFilter( op, a,
105 vrf->vrf_desc, e_flags );
106 if( rc == -1 ) return rc;
107 break;
108
109 case LDAP_FILTER_GE:
110 rc = test_ava_vrFilter( op, a, vrf->vrf_ava,
111 LDAP_FILTER_GE, e_flags );
112 if( rc == -1 ) return rc;
113 break;
114
115 case LDAP_FILTER_LE:
116 rc = test_ava_vrFilter( op, a, vrf->vrf_ava,
117 LDAP_FILTER_LE, e_flags );
118 if( rc == -1 ) return rc;
119 break;
120
121 case LDAP_FILTER_EXT:
122 Debug( LDAP_DEBUG_FILTER, " EXT\n" );
123 rc = test_mra_vrFilter( op, a,
124 vrf->vrf_mra, e_flags );
125 if( rc == -1 ) return rc;
126 break;
127
128 default:
129 Debug( LDAP_DEBUG_ANY, " unknown filter type %lu\n",
130 vrf->vrf_choice );
131 rc = LDAP_PROTOCOL_ERROR;
132 }
133 }
134
135 Debug( LDAP_DEBUG_FILTER, "<= filter_matched_values %d\n", rc );
136 return( rc );
137 }
138
139 static int
test_ava_vrFilter(Operation * op,Attribute * a,AttributeAssertion * ava,int type,char *** e_flags)140 test_ava_vrFilter(
141 Operation *op,
142 Attribute *a,
143 AttributeAssertion *ava,
144 int type,
145 char ***e_flags )
146 {
147 int i, j;
148
149 for ( i=0; a != NULL; a = a->a_next, i++ ) {
150 MatchingRule *mr;
151 struct berval *bv;
152
153 if ( !is_ad_subtype( a->a_desc, ava->aa_desc ) ) {
154 continue;
155 }
156
157 switch ( type ) {
158 case LDAP_FILTER_APPROX:
159 mr = a->a_desc->ad_type->sat_approx;
160 if( mr != NULL ) break;
161 /* use EQUALITY matching rule if no APPROX rule */
162
163 case LDAP_FILTER_EQUALITY:
164 mr = a->a_desc->ad_type->sat_equality;
165 break;
166
167 case LDAP_FILTER_GE:
168 case LDAP_FILTER_LE:
169 mr = a->a_desc->ad_type->sat_ordering;
170 break;
171
172 default:
173 mr = NULL;
174 }
175
176 if( mr == NULL ) continue;
177
178 bv = a->a_nvals;
179 for ( j=0; !BER_BVISNULL( bv ); bv++, j++ ) {
180 int rc, match;
181 const char *text;
182
183 rc = value_match( &match, a->a_desc, mr, 0,
184 bv, &ava->aa_value, &text );
185 if( rc != LDAP_SUCCESS ) return rc;
186
187 switch ( type ) {
188 case LDAP_FILTER_EQUALITY:
189 case LDAP_FILTER_APPROX:
190 if ( match == 0 ) {
191 (*e_flags)[i][j] = 1;
192 }
193 break;
194
195 case LDAP_FILTER_GE:
196 if ( match >= 0 ) {
197 (*e_flags)[i][j] = 1;
198 }
199 break;
200
201 case LDAP_FILTER_LE:
202 if ( match <= 0 ) {
203 (*e_flags)[i][j] = 1;
204 }
205 break;
206 }
207 }
208 }
209 return LDAP_SUCCESS;
210 }
211
212 static int
test_presence_vrFilter(Operation * op,Attribute * a,AttributeDescription * desc,char *** e_flags)213 test_presence_vrFilter(
214 Operation *op,
215 Attribute *a,
216 AttributeDescription *desc,
217 char ***e_flags )
218 {
219 int i, j;
220
221 for ( i=0; a != NULL; a = a->a_next, i++ ) {
222 struct berval *bv;
223
224 if ( !is_ad_subtype( a->a_desc, desc ) ) continue;
225
226 for ( bv = a->a_vals, j = 0; !BER_BVISNULL( bv ); bv++, j++ );
227 memset( (*e_flags)[i], 1, j);
228 }
229
230 return( LDAP_SUCCESS );
231 }
232
233 static int
test_substrings_vrFilter(Operation * op,Attribute * a,ValuesReturnFilter * vrf,char *** e_flags)234 test_substrings_vrFilter(
235 Operation *op,
236 Attribute *a,
237 ValuesReturnFilter *vrf,
238 char ***e_flags )
239 {
240 int i, j;
241
242 for ( i=0; a != NULL; a = a->a_next, i++ ) {
243 MatchingRule *mr = a->a_desc->ad_type->sat_substr;
244 struct berval *bv;
245
246 if ( !is_ad_subtype( a->a_desc, vrf->vrf_sub_desc ) ) {
247 continue;
248 }
249
250 if( mr == NULL ) continue;
251
252 bv = a->a_nvals;
253 for ( j = 0; !BER_BVISNULL( bv ); bv++, j++ ) {
254 int rc, match;
255 const char *text;
256
257 rc = value_match( &match, a->a_desc, mr, 0,
258 bv, vrf->vrf_sub, &text );
259
260 if( rc != LDAP_SUCCESS ) return rc;
261
262 if ( match == 0 ) {
263 (*e_flags)[i][j] = 1;
264 }
265 }
266 }
267
268 return LDAP_SUCCESS;
269 }
270
271 static int
test_mra_vrFilter(Operation * op,Attribute * a,MatchingRuleAssertion * mra,char *** e_flags)272 test_mra_vrFilter(
273 Operation *op,
274 Attribute *a,
275 MatchingRuleAssertion *mra,
276 char ***e_flags )
277 {
278 int i, j;
279
280 for ( i = 0; a != NULL; a = a->a_next, i++ ) {
281 struct berval *bv, assertedValue;
282 int normalize_attribute = 0;
283
284 if ( mra->ma_desc ) {
285 if ( !is_ad_subtype( a->a_desc, mra->ma_desc ) ) {
286 continue;
287 }
288 assertedValue = mra->ma_value;
289
290 } else {
291 int rc;
292 const char *text = NULL;
293
294 /* check if matching is appropriate */
295 if ( !mr_usable_with_at( mra->ma_rule, a->a_desc->ad_type ) ) {
296 continue;
297 }
298
299 rc = asserted_value_validate_normalize( a->a_desc, mra->ma_rule,
300 SLAP_MR_EXT|SLAP_MR_VALUE_OF_ASSERTION_SYNTAX,
301 &mra->ma_value, &assertedValue, &text, op->o_tmpmemctx );
302
303 if ( rc != LDAP_SUCCESS ) continue;
304 }
305
306 /* check match */
307 if ( mra->ma_rule == a->a_desc->ad_type->sat_equality ) {
308 bv = a->a_nvals;
309
310 } else {
311 bv = a->a_vals;
312 normalize_attribute = 1;
313 }
314
315 for ( j = 0; !BER_BVISNULL( bv ); bv++, j++ ) {
316 int rc, match;
317 const char *text;
318 struct berval nbv = BER_BVNULL;
319
320 if ( normalize_attribute && mra->ma_rule->smr_normalize ) {
321 /* see comment in filterentry.c */
322 if ( mra->ma_rule->smr_normalize(
323 SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
324 mra->ma_rule->smr_syntax,
325 mra->ma_rule,
326 bv, &nbv, op->o_tmpmemctx ) != LDAP_SUCCESS )
327 {
328 /* FIXME: stop processing? */
329 continue;
330 }
331
332 } else {
333 nbv = *bv;
334 }
335
336 rc = value_match( &match, a->a_desc, mra->ma_rule, 0,
337 &nbv, &assertedValue, &text );
338
339 if ( nbv.bv_val != bv->bv_val ) {
340 op->o_tmpfree( nbv.bv_val, op->o_tmpmemctx );
341 }
342
343 if ( rc != LDAP_SUCCESS ) return rc;
344
345 if ( match == 0 ) {
346 (*e_flags)[i][j] = 1;
347 }
348 }
349 }
350
351 return LDAP_SUCCESS;
352 }
353
354