Back to index

openldap  2.4.31
matchedValues.c
Go to the documentation of this file.
00001 /* $OpenLDAP$ */
00002 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
00003  *
00004  * Copyright 1999-2012 The OpenLDAP Foundation.
00005  * All rights reserved.
00006  *
00007  * Redistribution and use in source and binary forms, with or without
00008  * modification, are permitted only as authorized by the OpenLDAP
00009  * Public License.
00010  *
00011  * A copy of this license is available in the file LICENSE in the
00012  * top-level directory of the distribution or, alternatively, at
00013  * <http://www.OpenLDAP.org/license.html>.
00014  */
00015 
00016 #include "portable.h"
00017 
00018 #include <stdio.h>
00019 
00020 #include <ac/string.h>
00021 #include <ac/socket.h>
00022 
00023 #include "slap.h"
00024 
00025 static int
00026 test_mra_vrFilter(
00027        Operation     *op,
00028        Attribute     *a,
00029        MatchingRuleAssertion *mra,
00030        char          ***e_flags
00031 );
00032 
00033 static int
00034 test_substrings_vrFilter(
00035        Operation     *op,
00036        Attribute     *a,
00037        ValuesReturnFilter *f,
00038        char          ***e_flags
00039 );
00040 
00041 static int
00042 test_presence_vrFilter(
00043        Operation     *op,
00044        Attribute     *a,
00045        AttributeDescription *desc,
00046        char          ***e_flags
00047 );
00048 
00049 static int
00050 test_ava_vrFilter(
00051        Operation     *op,
00052        Attribute     *a,
00053        AttributeAssertion *ava,
00054        int           type,
00055        char          ***e_flags
00056 );
00057 
00058 
00059 int
00060 filter_matched_values( 
00061        Operation     *op,
00062        Attribute     *a,
00063        char          ***e_flags )
00064 {
00065        ValuesReturnFilter *vrf;
00066        int           rc = LDAP_SUCCESS;
00067 
00068        Debug( LDAP_DEBUG_FILTER, "=> filter_matched_values\n", 0, 0, 0 );
00069 
00070        for ( vrf = op->o_vrFilter; vrf != NULL; vrf = vrf->vrf_next ) {
00071               switch ( vrf->vrf_choice ) {
00072               case SLAPD_FILTER_COMPUTED:
00073                      Debug( LDAP_DEBUG_FILTER, " COMPUTED %s (%d)\n",
00074                             vrf->vrf_result == LDAP_COMPARE_FALSE ? "false"
00075                             : vrf->vrf_result == LDAP_COMPARE_TRUE ? "true"
00076                             : vrf->vrf_result == SLAPD_COMPARE_UNDEFINED ? "undefined"
00077                             : "error",
00078                             vrf->vrf_result, 0 );
00079                      /*This type of filter does not affect the result */
00080                      rc = LDAP_SUCCESS;
00081               break;
00082 
00083               case LDAP_FILTER_EQUALITY:
00084                      Debug( LDAP_DEBUG_FILTER, " EQUALITY\n", 0, 0, 0 );
00085                      rc = test_ava_vrFilter( op, a, vrf->vrf_ava,
00086                             LDAP_FILTER_EQUALITY, e_flags );
00087                      if( rc == -1 ) return rc;
00088                      break;
00089 
00090               case LDAP_FILTER_SUBSTRINGS:
00091                      Debug( LDAP_DEBUG_FILTER, " SUBSTRINGS\n", 0, 0, 0 );
00092                      rc = test_substrings_vrFilter( op, a,
00093                             vrf, e_flags );
00094                      if( rc == -1 ) return rc;
00095                      break;
00096 
00097               case LDAP_FILTER_PRESENT:
00098                      Debug( LDAP_DEBUG_FILTER, " PRESENT\n", 0, 0, 0 );
00099                      rc = test_presence_vrFilter( op, a,
00100                             vrf->vrf_desc, e_flags );
00101                      if( rc == -1 ) return rc;
00102                      break;
00103 
00104               case LDAP_FILTER_GE:
00105                      rc = test_ava_vrFilter( op, a, vrf->vrf_ava,
00106                             LDAP_FILTER_GE, e_flags );
00107                      if( rc == -1 ) return rc;
00108                      break;
00109 
00110               case LDAP_FILTER_LE:
00111                      rc = test_ava_vrFilter( op, a, vrf->vrf_ava,
00112                             LDAP_FILTER_LE, e_flags );
00113                      if( rc == -1 ) return rc;
00114                      break;
00115 
00116               case LDAP_FILTER_EXT:
00117                      Debug( LDAP_DEBUG_FILTER, " EXT\n", 0, 0, 0 );
00118                      rc = test_mra_vrFilter( op, a,
00119                             vrf->vrf_mra, e_flags );
00120                      if( rc == -1 ) return rc;
00121                      break;
00122 
00123               default:
00124                      Debug( LDAP_DEBUG_ANY, "    unknown filter type %lu\n",
00125                             vrf->vrf_choice, 0, 0 );
00126                      rc = LDAP_PROTOCOL_ERROR;
00127               }
00128        }
00129 
00130        Debug( LDAP_DEBUG_FILTER, "<= filter_matched_values %d\n", rc, 0, 0 );
00131        return( rc );
00132 }
00133 
00134 static int
00135 test_ava_vrFilter(
00136        Operation     *op,
00137        Attribute     *a,
00138        AttributeAssertion *ava,
00139        int           type,
00140        char          ***e_flags )
00141 {
00142        int           i, j;
00143 
00144        for ( i=0; a != NULL; a = a->a_next, i++ ) {
00145               MatchingRule *mr;
00146               struct berval *bv;
00147        
00148               if ( !is_ad_subtype( a->a_desc, ava->aa_desc ) ) {
00149                      continue;
00150               }
00151 
00152               switch ( type ) {
00153               case LDAP_FILTER_APPROX:
00154                      mr = a->a_desc->ad_type->sat_approx;
00155                      if( mr != NULL ) break;
00156                      /* use EQUALITY matching rule if no APPROX rule */
00157 
00158               case LDAP_FILTER_EQUALITY:
00159                      mr = a->a_desc->ad_type->sat_equality;
00160                      break;
00161               
00162               case LDAP_FILTER_GE:
00163               case LDAP_FILTER_LE:
00164                      mr = a->a_desc->ad_type->sat_ordering;
00165                      break;
00166 
00167               default:
00168                      mr = NULL;
00169               }
00170 
00171               if( mr == NULL ) continue;
00172 
00173               bv = a->a_nvals;
00174               for ( j=0; !BER_BVISNULL( bv ); bv++, j++ ) {
00175                      int rc, match;
00176                      const char *text;
00177 
00178                      rc = value_match( &match, a->a_desc, mr, 0,
00179                             bv, &ava->aa_value, &text );
00180                      if( rc != LDAP_SUCCESS ) return rc;
00181 
00182                      switch ( type ) {
00183                      case LDAP_FILTER_EQUALITY:
00184                      case LDAP_FILTER_APPROX:
00185                             if ( match == 0 ) {
00186                                    (*e_flags)[i][j] = 1;
00187                             }
00188                             break;
00189        
00190                      case LDAP_FILTER_GE:
00191                             if ( match >= 0 ) {
00192                                    (*e_flags)[i][j] = 1;
00193                             }
00194                             break;
00195        
00196                      case LDAP_FILTER_LE:
00197                             if ( match <= 0 ) {
00198                                    (*e_flags)[i][j] = 1;
00199                             }
00200                             break;
00201                      }
00202               }
00203        }
00204        return LDAP_SUCCESS;
00205 }
00206 
00207 static int
00208 test_presence_vrFilter(
00209        Operation     *op,
00210        Attribute     *a,
00211        AttributeDescription *desc,
00212        char          ***e_flags )
00213 {
00214        int i, j;
00215 
00216        for ( i=0; a != NULL; a = a->a_next, i++ ) {
00217               struct berval *bv;
00218 
00219               if ( !is_ad_subtype( a->a_desc, desc ) ) continue;
00220 
00221               for ( bv = a->a_vals, j = 0; !BER_BVISNULL( bv ); bv++, j++ );
00222               memset( (*e_flags)[i], 1, j);
00223        }
00224 
00225        return( LDAP_SUCCESS );
00226 }
00227 
00228 static int
00229 test_substrings_vrFilter(
00230        Operation     *op,
00231        Attribute     *a,
00232        ValuesReturnFilter *vrf,
00233        char          ***e_flags )
00234 {
00235        int i, j;
00236 
00237        for ( i=0; a != NULL; a = a->a_next, i++ ) {
00238               MatchingRule *mr = a->a_desc->ad_type->sat_substr;
00239               struct berval *bv;
00240 
00241               if ( !is_ad_subtype( a->a_desc, vrf->vrf_sub_desc ) ) {
00242                      continue;
00243               }
00244 
00245               if( mr == NULL ) continue;
00246 
00247               bv = a->a_nvals;
00248               for ( j = 0; !BER_BVISNULL( bv ); bv++, j++ ) {
00249                      int rc, match;
00250                      const char *text;
00251 
00252                      rc = value_match( &match, a->a_desc, mr, 0,
00253                             bv, vrf->vrf_sub, &text );
00254 
00255                      if( rc != LDAP_SUCCESS ) return rc;
00256 
00257                      if ( match == 0 ) {
00258                             (*e_flags)[i][j] = 1;
00259                      }
00260               }
00261        }
00262 
00263        return LDAP_SUCCESS;
00264 }
00265 
00266 static int
00267 test_mra_vrFilter(
00268        Operation     *op,
00269        Attribute     *a,
00270        MatchingRuleAssertion *mra,
00271        char          ***e_flags )
00272 {
00273        int    i, j;
00274 
00275        for ( i = 0; a != NULL; a = a->a_next, i++ ) {
00276               struct berval *bv, assertedValue;
00277               int           normalize_attribute = 0;
00278 
00279               if ( mra->ma_desc ) {
00280                      if ( !is_ad_subtype( a->a_desc, mra->ma_desc ) ) {
00281                             continue;
00282                      }
00283                      assertedValue = mra->ma_value;
00284 
00285               } else {
00286                      int rc;
00287                      const char    *text = NULL;
00288 
00289                      /* check if matching is appropriate */
00290                      if ( !mr_usable_with_at( mra->ma_rule, a->a_desc->ad_type ) ) {
00291                             continue;
00292                      }
00293 
00294                      rc = asserted_value_validate_normalize( a->a_desc, mra->ma_rule,
00295                             SLAP_MR_EXT|SLAP_MR_VALUE_OF_ASSERTION_SYNTAX,
00296                             &mra->ma_value, &assertedValue, &text, op->o_tmpmemctx );
00297 
00298                      if ( rc != LDAP_SUCCESS ) continue;
00299               }
00300 
00301               /* check match */
00302               if ( mra->ma_rule == a->a_desc->ad_type->sat_equality ) {
00303                      bv = a->a_nvals;
00304 
00305               } else {
00306                      bv = a->a_vals;
00307                      normalize_attribute = 1;
00308               }
00309                                    
00310               for ( j = 0; !BER_BVISNULL( bv ); bv++, j++ ) {
00311                      int           rc, match;
00312                      const char    *text;
00313                      struct berval nbv = BER_BVNULL;
00314 
00315                      if ( normalize_attribute && mra->ma_rule->smr_normalize ) {
00316                             /* see comment in filterentry.c */
00317                             if ( mra->ma_rule->smr_normalize(
00318                                           SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
00319                                           mra->ma_rule->smr_syntax,
00320                                           mra->ma_rule,
00321                                           bv, &nbv, op->o_tmpmemctx ) != LDAP_SUCCESS )
00322                             {
00323                                    /* FIXME: stop processing? */
00324                                    continue;
00325                             }
00326 
00327                      } else {
00328                             nbv = *bv;
00329                      }
00330 
00331                      rc = value_match( &match, a->a_desc, mra->ma_rule, 0,
00332                             &nbv, &assertedValue, &text );
00333 
00334                      if ( nbv.bv_val != bv->bv_val ) {
00335                             op->o_tmpfree( nbv.bv_val, op->o_tmpmemctx );
00336                      }
00337 
00338                      if ( rc != LDAP_SUCCESS ) return rc;
00339 
00340                      if ( match == 0 ) {
00341                             (*e_flags)[i][j] = 1;
00342                      }
00343               }
00344        }
00345 
00346        return LDAP_SUCCESS;
00347 }
00348