Back to index

openldap  2.4.31
mra.c
Go to the documentation of this file.
00001 /* mra.c - routines for dealing with extensible matching rule assertions */
00002 /* $OpenLDAP$ */
00003 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
00004  *
00005  * Copyright 1998-2012 The OpenLDAP Foundation.
00006  * All rights reserved.
00007  *
00008  * Redistribution and use in source and binary forms, with or without
00009  * modification, are permitted only as authorized by the OpenLDAP
00010  * Public License.
00011  *
00012  * A copy of this license is available in the file LICENSE in the
00013  * top-level directory of the distribution or, alternatively, at
00014  * <http://www.OpenLDAP.org/license.html>.
00015  */
00016 
00017 #include "portable.h"
00018 
00019 #include <stdio.h>
00020 
00021 #include <ac/string.h>
00022 #include <ac/socket.h>
00023 
00024 #include "slap.h"
00025 
00026 #ifdef LDAP_COMP_MATCH
00027 #include "component.h"
00028 #endif
00029 
00030 void
00031 mra_free(
00032        Operation *op,
00033        MatchingRuleAssertion *mra,
00034        int    freeit )
00035 {
00036 #ifdef LDAP_COMP_MATCH
00037        /* free component assertion */
00038        if ( mra->ma_rule->smr_usage & SLAP_MR_COMPONENT && mra->ma_cf ) {
00039               component_free( mra->ma_cf );
00040        }
00041 #endif
00042        /* op->o_tmpfree( mra->ma_value.bv_val, op->o_tmpmemctx ); */
00043        ch_free( mra->ma_value.bv_val );
00044        if ( mra->ma_desc && mra->ma_desc->ad_flags & SLAP_DESC_TEMPORARY )
00045               op->o_tmpfree( mra->ma_desc, op->o_tmpmemctx );
00046        if ( freeit ) op->o_tmpfree( (char *) mra, op->o_tmpmemctx );
00047 }
00048 
00049 int
00050 get_mra(
00051        Operation *op,
00052        BerElement    *ber,
00053        Filter *f,
00054        const char **text )
00055 {
00056        int rc;
00057        ber_tag_t tag, rtag;
00058        ber_len_t length;
00059        struct berval type = BER_BVNULL;
00060        struct berval value = BER_BVNULL;
00061        struct berval rule_text = BER_BVNULL;
00062        MatchingRuleAssertion ma = { 0 };
00063 #ifdef LDAP_COMP_MATCH
00064        AttributeAliasing* aa = NULL;
00065 #endif
00066 
00067        rtag = ber_scanf( ber, "{t" /*"}"*/, &tag );
00068 
00069        if( rtag == LBER_ERROR ) {
00070               Debug( LDAP_DEBUG_ANY, "  get_mra ber_scanf\n", 0, 0, 0 );
00071 
00072               *text = "Error parsing matching rule assertion";
00073               return SLAPD_DISCONNECT;
00074        }
00075 
00076        if ( tag == LDAP_FILTER_EXT_OID ) {
00077               rtag = ber_scanf( ber, "m", &rule_text );
00078               if ( rtag == LBER_ERROR ) {
00079                      Debug( LDAP_DEBUG_ANY, "  get_mra ber_scanf for mr\n", 0, 0, 0 );
00080 
00081                      *text = "Error parsing matching rule in matching rule assertion";
00082                      return SLAPD_DISCONNECT;
00083               }
00084 
00085               rtag = ber_scanf( ber, "t", &tag );
00086               if( rtag == LBER_ERROR ) {
00087                      Debug( LDAP_DEBUG_ANY, "  get_mra ber_scanf\n", 0, 0, 0 );
00088 
00089                      *text = "Error parsing matching rule assertion";
00090                      return SLAPD_DISCONNECT;
00091               }
00092        }
00093 
00094        if ( tag == LDAP_FILTER_EXT_TYPE ) {
00095               rtag = ber_scanf( ber, "m", &type );
00096               if ( rtag == LBER_ERROR ) {
00097                      Debug( LDAP_DEBUG_ANY, "  get_mra ber_scanf for ad\n", 0, 0, 0 );
00098 
00099                      *text = "Error parsing attribute description in matching rule assertion";
00100                      return SLAPD_DISCONNECT;
00101               }
00102 
00103               rtag = ber_scanf( ber, "t", &tag );
00104               if( rtag == LBER_ERROR ) {
00105                      Debug( LDAP_DEBUG_ANY, "  get_mra ber_scanf\n", 0, 0, 0 );
00106 
00107                      *text = "Error parsing matching rule assertion";
00108                      return SLAPD_DISCONNECT;
00109               }
00110        }
00111 
00112        if ( tag != LDAP_FILTER_EXT_VALUE ) {
00113               Debug( LDAP_DEBUG_ANY, "  get_mra ber_scanf missing value\n", 0, 0, 0 );
00114 
00115               *text = "Missing value in matching rule assertion";
00116               return SLAPD_DISCONNECT;
00117        }
00118 
00119        rtag = ber_scanf( ber, "m", &value );
00120 
00121        if( rtag == LBER_ERROR ) {
00122               Debug( LDAP_DEBUG_ANY, "  get_mra ber_scanf\n", 0, 0, 0 );
00123 
00124               *text = "Error decoding value in matching rule assertion";
00125               return SLAPD_DISCONNECT;
00126        }
00127 
00128        tag = ber_peek_tag( ber, &length );
00129 
00130        if ( tag == LDAP_FILTER_EXT_DNATTRS ) {
00131               rtag = ber_scanf( ber, /*"{"*/ "b}", &ma.ma_dnattrs );
00132        } else {
00133               rtag = ber_scanf( ber, /*"{"*/ "}" );
00134        }
00135 
00136        if( rtag == LBER_ERROR ) {
00137               Debug( LDAP_DEBUG_ANY, "  get_mra ber_scanf\n", 0, 0, 0 );
00138 
00139               *text = "Error decoding dnattrs matching rule assertion";
00140               return SLAPD_DISCONNECT;
00141        }
00142 
00143        if( type.bv_val != NULL ) {
00144               rc = slap_bv2ad( &type, &ma.ma_desc, text );
00145               if( rc != LDAP_SUCCESS ) {
00146                      f->f_choice |= SLAPD_FILTER_UNDEFINED;
00147                      rc = slap_bv2undef_ad( &type, &ma.ma_desc, text,
00148                             SLAP_AD_PROXIED|SLAP_AD_NOINSERT );
00149 
00150                      if( rc != LDAP_SUCCESS ) {
00151                             ma.ma_desc = slap_bv2tmp_ad( &type, op->o_tmpmemctx );
00152                             rc = LDAP_SUCCESS;
00153                      }
00154               }
00155        }
00156 
00157        if( rule_text.bv_val != NULL ) {
00158               ma.ma_rule = mr_bvfind( &rule_text );
00159               if( ma.ma_rule == NULL ) {
00160                      *text = "matching rule not recognized";
00161                      return LDAP_INAPPROPRIATE_MATCHING;
00162               }
00163        }
00164 
00165        if ( ma.ma_rule == NULL ) {
00166               /*
00167                * Need either type or rule ...
00168                */
00169               if ( ma.ma_desc == NULL ) {
00170                      *text = "no matching rule or type";
00171                      return LDAP_INAPPROPRIATE_MATCHING;
00172               }
00173 
00174               if ( ma.ma_desc->ad_type->sat_equality != NULL &&
00175                      ma.ma_desc->ad_type->sat_equality->smr_usage & SLAP_MR_EXT )
00176               {
00177                      /* no matching rule was provided, use the attribute's
00178                         equality rule if it supports extensible matching. */
00179                      ma.ma_rule = ma.ma_desc->ad_type->sat_equality;
00180 
00181               } else {
00182                      *text = "no appropriate rule to use for type";
00183                      return LDAP_INAPPROPRIATE_MATCHING;
00184               }
00185        }
00186 
00187        if ( ma.ma_desc != NULL ) {
00188               if( !mr_usable_with_at( ma.ma_rule, ma.ma_desc->ad_type ) ) {
00189                      *text = "matching rule use with this attribute not appropriate";
00190                      return LDAP_INAPPROPRIATE_MATCHING;
00191               }
00192 
00193        }
00194 
00195        /*
00196         * Normalize per matching rule
00197         */
00198        rc = asserted_value_validate_normalize( ma.ma_desc,
00199               ma.ma_rule,
00200               SLAP_MR_EXT|SLAP_MR_VALUE_OF_ASSERTION_SYNTAX,
00201               &value, &ma.ma_value, text, op->o_tmpmemctx );
00202 
00203        if( rc != LDAP_SUCCESS ) return rc;
00204 
00205 #ifdef LDAP_COMP_MATCH
00206        /* Check If this attribute is aliased */
00207        if ( is_aliased_attribute && ma.ma_desc && ( aa = is_aliased_attribute ( ma.ma_desc ) ) ) {
00208               rc = get_aliased_filter ( op, &ma, aa, text );
00209               if ( rc != LDAP_SUCCESS ) return rc;
00210        }
00211        else if ( ma.ma_rule && ma.ma_rule->smr_usage & SLAP_MR_COMPONENT ) {
00212               /* Matching Rule for Component Matching */
00213               rc = get_comp_filter( op, &ma.ma_value, &ma.ma_cf, text );
00214               if ( rc != LDAP_SUCCESS ) return rc;
00215        }
00216 #endif
00217 
00218        length = sizeof(ma);
00219        /* Append rule_text to end of struct */
00220        if (rule_text.bv_val) length += rule_text.bv_len + 1;
00221        f->f_mra = op->o_tmpalloc( length, op->o_tmpmemctx );
00222        *f->f_mra = ma;
00223        if (rule_text.bv_val) {
00224               f->f_mra->ma_rule_text.bv_len = rule_text.bv_len;
00225               f->f_mra->ma_rule_text.bv_val = (char *)(f->f_mra+1);
00226               AC_MEMCPY(f->f_mra->ma_rule_text.bv_val, rule_text.bv_val,
00227                      rule_text.bv_len+1);
00228        }
00229 
00230        return LDAP_SUCCESS;
00231 }