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