1 /* $OpenLDAP$ */
2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
3  *
4  * Copyright 1999-2021 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
filter_matched_values(Operation * op,Attribute * a,char *** e_flags)60 filter_matched_values(
61 	Operation	*op,
62 	Attribute	*a,
63 	char		***e_flags )
64 {
65 	ValuesReturnFilter *vrf;
66 	int		rc = LDAP_SUCCESS;
67 
68 	Debug( LDAP_DEBUG_FILTER, "=> filter_matched_values\n" );
69 
70 	for ( vrf = op->o_vrFilter; vrf != NULL; vrf = vrf->vrf_next ) {
71 		switch ( vrf->vrf_choice ) {
72 		case SLAPD_FILTER_COMPUTED:
73 			Debug( LDAP_DEBUG_FILTER, "	COMPUTED %s (%d)\n",
74 				vrf->vrf_result == LDAP_COMPARE_FALSE ? "false"
75 				: vrf->vrf_result == LDAP_COMPARE_TRUE ? "true"
76 				: vrf->vrf_result == SLAPD_COMPARE_UNDEFINED ? "undefined"
77 				: "error",
78 				vrf->vrf_result );
79 			/*This type of filter does not affect the result */
80 			rc = LDAP_SUCCESS;
81 		break;
82 
83 		case LDAP_FILTER_EQUALITY:
84 			Debug( LDAP_DEBUG_FILTER, "	EQUALITY\n" );
85 			rc = test_ava_vrFilter( op, a, vrf->vrf_ava,
86 				LDAP_FILTER_EQUALITY, e_flags );
87 			if( rc == -1 ) return rc;
88 			break;
89 
90 		case LDAP_FILTER_SUBSTRINGS:
91 			Debug( LDAP_DEBUG_FILTER, "	SUBSTRINGS\n" );
92 			rc = test_substrings_vrFilter( op, a,
93 				vrf, e_flags );
94 			if( rc == -1 ) return rc;
95 			break;
96 
97 		case LDAP_FILTER_PRESENT:
98 			Debug( LDAP_DEBUG_FILTER, "	PRESENT\n" );
99 			rc = test_presence_vrFilter( op, a,
100 				vrf->vrf_desc, e_flags );
101 			if( rc == -1 ) return rc;
102 			break;
103 
104 		case LDAP_FILTER_GE:
105 			rc = test_ava_vrFilter( op, a, vrf->vrf_ava,
106 				LDAP_FILTER_GE, e_flags );
107 			if( rc == -1 ) return rc;
108 			break;
109 
110 		case LDAP_FILTER_LE:
111 			rc = test_ava_vrFilter( op, a, vrf->vrf_ava,
112 				LDAP_FILTER_LE, e_flags );
113 			if( rc == -1 ) return rc;
114 			break;
115 
116 		case LDAP_FILTER_EXT:
117 			Debug( LDAP_DEBUG_FILTER, "	EXT\n" );
118 			rc = test_mra_vrFilter( op, a,
119 				vrf->vrf_mra, e_flags );
120 			if( rc == -1 ) return rc;
121 			break;
122 
123 		default:
124 			Debug( LDAP_DEBUG_ANY, "	unknown filter type %lu\n",
125 				vrf->vrf_choice );
126 			rc = LDAP_PROTOCOL_ERROR;
127 		}
128 	}
129 
130 	Debug( LDAP_DEBUG_FILTER, "<= filter_matched_values %d\n", rc );
131 	return( rc );
132 }
133 
134 static int
test_ava_vrFilter(Operation * op,Attribute * a,AttributeAssertion * ava,int type,char *** e_flags)135 test_ava_vrFilter(
136 	Operation	*op,
137 	Attribute	*a,
138 	AttributeAssertion *ava,
139 	int		type,
140 	char 		***e_flags )
141 {
142 	int 		i, j;
143 
144 	for ( i=0; a != NULL; a = a->a_next, i++ ) {
145 		MatchingRule *mr;
146 		struct berval *bv;
147 
148 		if ( !is_ad_subtype( a->a_desc, ava->aa_desc ) ) {
149 			continue;
150 		}
151 
152 		switch ( type ) {
153 		case LDAP_FILTER_APPROX:
154 			mr = a->a_desc->ad_type->sat_approx;
155 			if( mr != NULL ) break;
156 			/* use EQUALITY matching rule if no APPROX rule */
157 
158 		case LDAP_FILTER_EQUALITY:
159 			mr = a->a_desc->ad_type->sat_equality;
160 			break;
161 
162 		case LDAP_FILTER_GE:
163 		case LDAP_FILTER_LE:
164 			mr = a->a_desc->ad_type->sat_ordering;
165 			break;
166 
167 		default:
168 			mr = NULL;
169 		}
170 
171 		if( mr == NULL ) continue;
172 
173 		bv = a->a_nvals;
174 		for ( j=0; !BER_BVISNULL( bv ); bv++, j++ ) {
175 			int rc, match;
176 			const char *text;
177 
178 			rc = value_match( &match, a->a_desc, mr, 0,
179 				bv, &ava->aa_value, &text );
180 			if( rc != LDAP_SUCCESS ) return rc;
181 
182 			switch ( type ) {
183 			case LDAP_FILTER_EQUALITY:
184 			case LDAP_FILTER_APPROX:
185 				if ( match == 0 ) {
186 					(*e_flags)[i][j] = 1;
187 				}
188 				break;
189 
190 			case LDAP_FILTER_GE:
191 				if ( match >= 0 ) {
192 					(*e_flags)[i][j] = 1;
193 				}
194 				break;
195 
196 			case LDAP_FILTER_LE:
197 				if ( match <= 0 ) {
198 					(*e_flags)[i][j] = 1;
199 				}
200 				break;
201 			}
202 		}
203 	}
204 	return LDAP_SUCCESS;
205 }
206 
207 static int
test_presence_vrFilter(Operation * op,Attribute * a,AttributeDescription * desc,char *** e_flags)208 test_presence_vrFilter(
209 	Operation	*op,
210 	Attribute	*a,
211 	AttributeDescription *desc,
212 	char 		***e_flags )
213 {
214 	int i, j;
215 
216 	for ( i=0; a != NULL; a = a->a_next, i++ ) {
217 		struct berval *bv;
218 
219 		if ( !is_ad_subtype( a->a_desc, desc ) ) continue;
220 
221 		for ( bv = a->a_vals, j = 0; !BER_BVISNULL( bv ); bv++, j++ );
222 		memset( (*e_flags)[i], 1, j);
223 	}
224 
225 	return( LDAP_SUCCESS );
226 }
227 
228 static int
test_substrings_vrFilter(Operation * op,Attribute * a,ValuesReturnFilter * vrf,char *** e_flags)229 test_substrings_vrFilter(
230 	Operation	*op,
231 	Attribute	*a,
232 	ValuesReturnFilter *vrf,
233 	char		***e_flags )
234 {
235 	int i, j;
236 
237 	for ( i=0; a != NULL; a = a->a_next, i++ ) {
238 		MatchingRule *mr = a->a_desc->ad_type->sat_substr;
239 		struct berval *bv;
240 
241 		if ( !is_ad_subtype( a->a_desc, vrf->vrf_sub_desc ) ) {
242 			continue;
243 		}
244 
245 		if( mr == NULL ) continue;
246 
247 		bv = a->a_nvals;
248 		for ( j = 0; !BER_BVISNULL( bv ); bv++, j++ ) {
249 			int rc, match;
250 			const char *text;
251 
252 			rc = value_match( &match, a->a_desc, mr, 0,
253 				bv, vrf->vrf_sub, &text );
254 
255 			if( rc != LDAP_SUCCESS ) return rc;
256 
257 			if ( match == 0 ) {
258 				(*e_flags)[i][j] = 1;
259 			}
260 		}
261 	}
262 
263 	return LDAP_SUCCESS;
264 }
265 
266 static int
test_mra_vrFilter(Operation * op,Attribute * a,MatchingRuleAssertion * mra,char *** e_flags)267 test_mra_vrFilter(
268 	Operation	*op,
269 	Attribute	*a,
270 	MatchingRuleAssertion *mra,
271 	char 		***e_flags )
272 {
273 	int	i, j;
274 
275 	for ( i = 0; a != NULL; a = a->a_next, i++ ) {
276 		struct berval	*bv, assertedValue;
277 		int		normalize_attribute = 0;
278 
279 		if ( mra->ma_desc ) {
280 			if ( !is_ad_subtype( a->a_desc, mra->ma_desc ) ) {
281 				continue;
282 			}
283 			assertedValue = mra->ma_value;
284 
285 		} else {
286 			int rc;
287 			const char	*text = NULL;
288 
289 			/* check if matching is appropriate */
290 			if ( !mr_usable_with_at( mra->ma_rule, a->a_desc->ad_type ) ) {
291 				continue;
292 			}
293 
294 			rc = asserted_value_validate_normalize( a->a_desc, mra->ma_rule,
295 				SLAP_MR_EXT|SLAP_MR_VALUE_OF_ASSERTION_SYNTAX,
296 				&mra->ma_value, &assertedValue, &text, op->o_tmpmemctx );
297 
298 			if ( rc != LDAP_SUCCESS ) continue;
299 		}
300 
301 		/* check match */
302 		if ( mra->ma_rule == a->a_desc->ad_type->sat_equality ) {
303 			bv = a->a_nvals;
304 
305 		} else {
306 			bv = a->a_vals;
307 			normalize_attribute = 1;
308 		}
309 
310 		for ( j = 0; !BER_BVISNULL( bv ); bv++, j++ ) {
311 			int		rc, match;
312 			const char	*text;
313 			struct berval	nbv = BER_BVNULL;
314 
315 			if ( normalize_attribute && mra->ma_rule->smr_normalize ) {
316 				/* see comment in filterentry.c */
317 				if ( mra->ma_rule->smr_normalize(
318 						SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
319 						mra->ma_rule->smr_syntax,
320 						mra->ma_rule,
321 						bv, &nbv, op->o_tmpmemctx ) != LDAP_SUCCESS )
322 				{
323 					/* FIXME: stop processing? */
324 					continue;
325 				}
326 
327 			} else {
328 				nbv = *bv;
329 			}
330 
331 			rc = value_match( &match, a->a_desc, mra->ma_rule, 0,
332 				&nbv, &assertedValue, &text );
333 
334 			if ( nbv.bv_val != bv->bv_val ) {
335 				op->o_tmpfree( nbv.bv_val, op->o_tmpmemctx );
336 			}
337 
338 			if ( rc != LDAP_SUCCESS ) return rc;
339 
340 			if ( match == 0 ) {
341 				(*e_flags)[i][j] = 1;
342 			}
343 		}
344 	}
345 
346 	return LDAP_SUCCESS;
347 }
348 
349