1 /*	$NetBSD: matchedValues.c,v 1.1.1.7 2019/08/08 13:31:37 christos Exp $	*/
2 
3 /* $OpenLDAP$ */
4 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5  *
6  * Copyright 1999-2019 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.1.1.7 2019/08/08 13:31:37 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
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", 0, 0, 0 );
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, 0 );
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", 0, 0, 0 );
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", 0, 0, 0 );
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", 0, 0, 0 );
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", 0, 0, 0 );
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, 0, 0 );
131 			rc = LDAP_PROTOCOL_ERROR;
132 		}
133 	}
134 
135 	Debug( LDAP_DEBUG_FILTER, "<= filter_matched_values %d\n", rc, 0, 0 );
136 	return( rc );
137 }
138 
139 static int
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
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
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
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