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