1 /* mra.c - routines for dealing with extensible matching rule assertions */
2 /* $OpenLDAP: pkg/ldap/servers/slapd/mra.c,v 1.45.2.3 2008/02/11 23:26:44 kurt Exp $ */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5 * Copyright 1998-2008 The OpenLDAP Foundation.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted only as authorized by the OpenLDAP
12 * A copy of this license is available in the file LICENSE in the
13 * top-level directory of the distribution or, alternatively, at
14 * <http://www.OpenLDAP.org/license.html>.
21 #include <ac/string.h>
22 #include <ac/socket.h>
26 #ifdef LDAP_COMP_MATCH
27 #include "component.h"
33 MatchingRuleAssertion
*mra
,
36 #ifdef LDAP_COMP_MATCH
37 /* free component assertion */
38 if ( mra
->ma_rule
->smr_usage
& SLAP_MR_COMPONENT
&& mra
->ma_cf
) {
39 component_free( mra
->ma_cf
);
42 /* op->o_tmpfree( mra->ma_value.bv_val, op->o_tmpmemctx ); */
43 ch_free( mra
->ma_value
.bv_val
);
44 if ( mra
->ma_desc
&& mra
->ma_desc
->ad_flags
& SLAP_DESC_TEMPORARY
)
45 op
->o_tmpfree( mra
->ma_desc
, op
->o_tmpmemctx
);
46 if ( freeit
) op
->o_tmpfree( (char *) mra
, op
->o_tmpmemctx
);
59 struct berval type
= BER_BVNULL
;
60 struct berval value
= BER_BVNULL
;
61 struct berval rule_text
= BER_BVNULL
;
62 MatchingRuleAssertion ma
= { 0 };
63 #ifdef LDAP_COMP_MATCH
64 AttributeAliasing
* aa
= NULL
;
67 rtag
= ber_scanf( ber
, "{t" /*"}"*/, &tag
);
69 if( rtag
== LBER_ERROR
) {
70 Debug( LDAP_DEBUG_ANY
, " get_mra ber_scanf\n", 0, 0, 0 );
72 *text
= "Error parsing matching rule assertion";
73 return SLAPD_DISCONNECT
;
76 if ( tag
== LDAP_FILTER_EXT_OID
) {
77 rtag
= ber_scanf( ber
, "m", &rule_text
);
78 if ( rtag
== LBER_ERROR
) {
79 Debug( LDAP_DEBUG_ANY
, " get_mra ber_scanf for mr\n", 0, 0, 0 );
81 *text
= "Error parsing matching rule in matching rule assertion";
82 return SLAPD_DISCONNECT
;
85 rtag
= ber_scanf( ber
, "t", &tag
);
86 if( rtag
== LBER_ERROR
) {
87 Debug( LDAP_DEBUG_ANY
, " get_mra ber_scanf\n", 0, 0, 0 );
89 *text
= "Error parsing matching rule assertion";
90 return SLAPD_DISCONNECT
;
94 if ( tag
== LDAP_FILTER_EXT_TYPE
) {
95 rtag
= ber_scanf( ber
, "m", &type
);
96 if ( rtag
== LBER_ERROR
) {
97 Debug( LDAP_DEBUG_ANY
, " get_mra ber_scanf for ad\n", 0, 0, 0 );
99 *text
= "Error parsing attribute description in matching rule assertion";
100 return SLAPD_DISCONNECT
;
103 rtag
= ber_scanf( ber
, "t", &tag
);
104 if( rtag
== LBER_ERROR
) {
105 Debug( LDAP_DEBUG_ANY
, " get_mra ber_scanf\n", 0, 0, 0 );
107 *text
= "Error parsing matching rule assertion";
108 return SLAPD_DISCONNECT
;
112 if ( tag
!= LDAP_FILTER_EXT_VALUE
) {
113 Debug( LDAP_DEBUG_ANY
, " get_mra ber_scanf missing value\n", 0, 0, 0 );
115 *text
= "Missing value in matching rule assertion";
116 return SLAPD_DISCONNECT
;
119 rtag
= ber_scanf( ber
, "m", &value
);
121 if( rtag
== LBER_ERROR
) {
122 Debug( LDAP_DEBUG_ANY
, " get_mra ber_scanf\n", 0, 0, 0 );
124 *text
= "Error decoding value in matching rule assertion";
125 return SLAPD_DISCONNECT
;
128 tag
= ber_peek_tag( ber
, &length
);
130 if ( tag
== LDAP_FILTER_EXT_DNATTRS
) {
131 rtag
= ber_scanf( ber
, /*"{"*/ "b}", &ma
.ma_dnattrs
);
133 rtag
= ber_scanf( ber
, /*"{"*/ "}" );
136 if( rtag
== LBER_ERROR
) {
137 Debug( LDAP_DEBUG_ANY
, " get_mra ber_scanf\n", 0, 0, 0 );
139 *text
= "Error decoding dnattrs matching rule assertion";
140 return SLAPD_DISCONNECT
;
143 if( type
.bv_val
!= NULL
) {
144 rc
= slap_bv2ad( &type
, &ma
.ma_desc
, text
);
145 if( rc
!= LDAP_SUCCESS
) {
146 f
->f_choice
|= SLAPD_FILTER_UNDEFINED
;
147 rc
= slap_bv2undef_ad( &type
, &ma
.ma_desc
, text
,
148 SLAP_AD_PROXIED
|SLAP_AD_NOINSERT
);
150 if( rc
!= LDAP_SUCCESS
) {
151 ma
.ma_desc
= slap_bv2tmp_ad( &type
, op
->o_tmpmemctx
);
157 if( rule_text
.bv_val
!= NULL
) {
158 ma
.ma_rule
= mr_bvfind( &rule_text
);
159 if( ma
.ma_rule
== NULL
) {
160 *text
= "matching rule not recognized";
161 return LDAP_INAPPROPRIATE_MATCHING
;
165 if ( ma
.ma_rule
== NULL
) {
167 * Need either type or rule ...
169 if ( ma
.ma_desc
== NULL
) {
170 *text
= "no matching rule or type";
171 return LDAP_INAPPROPRIATE_MATCHING
;
174 if ( ma
.ma_desc
->ad_type
->sat_equality
!= NULL
&&
175 ma
.ma_desc
->ad_type
->sat_equality
->smr_usage
& SLAP_MR_EXT
)
177 /* no matching rule was provided, use the attribute's
178 equality rule if it supports extensible matching. */
179 ma
.ma_rule
= ma
.ma_desc
->ad_type
->sat_equality
;
182 *text
= "no appropriate rule to use for type";
183 return LDAP_INAPPROPRIATE_MATCHING
;
187 if ( ma
.ma_desc
!= NULL
) {
188 if( !mr_usable_with_at( ma
.ma_rule
, ma
.ma_desc
->ad_type
) ) {
189 *text
= "matching rule use with this attribute not appropriate";
190 return LDAP_INAPPROPRIATE_MATCHING
;
196 * Normalize per matching rule
198 rc
= asserted_value_validate_normalize( ma
.ma_desc
,
200 SLAP_MR_EXT
|SLAP_MR_VALUE_OF_ASSERTION_SYNTAX
,
201 &value
, &ma
.ma_value
, text
, op
->o_tmpmemctx
);
203 if( rc
!= LDAP_SUCCESS
) return rc
;
205 #ifdef LDAP_COMP_MATCH
206 /* Check If this attribute is aliased */
207 if ( is_aliased_attribute
&& ma
.ma_desc
&& ( aa
= is_aliased_attribute ( ma
.ma_desc
) ) ) {
208 rc
= get_aliased_filter ( op
, &ma
, aa
, text
);
209 if ( rc
!= LDAP_SUCCESS
) return rc
;
211 else if ( ma
.ma_rule
&& ma
.ma_rule
->smr_usage
& SLAP_MR_COMPONENT
) {
212 /* Matching Rule for Component Matching */
213 rc
= get_comp_filter( op
, &ma
.ma_value
, &ma
.ma_cf
, text
);
214 if ( rc
!= LDAP_SUCCESS
) return rc
;
219 /* Append rule_text to end of struct */
220 if (rule_text
.bv_val
) length
+= rule_text
.bv_len
+ 1;
221 f
->f_mra
= op
->o_tmpalloc( length
, op
->o_tmpmemctx
);
223 if (rule_text
.bv_val
) {
224 f
->f_mra
->ma_rule_text
.bv_len
= rule_text
.bv_len
;
225 f
->f_mra
->ma_rule_text
.bv_val
= (char *)(f
->f_mra
+1);
226 AC_MEMCPY(f
->f_mra
->ma_rule_text
.bv_val
, rule_text
.bv_val
,