]> git.sur5r.net Git - openldap/blob - servers/slapd/mra.c
unifdef -UNEW_LOGGING
[openldap] / servers / slapd / mra.c
1 /* mra.c - routines for dealing with extensible matching rule assertions */
2 /* $OpenLDAP$ */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4  *
5  * Copyright 1998-2004 The OpenLDAP Foundation.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted only as authorized by the OpenLDAP
10  * Public License.
11  *
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>.
15  */
16
17 #include "portable.h"
18
19 #include <stdio.h>
20
21 #include <ac/string.h>
22 #include <ac/socket.h>
23
24 #include "slap.h"
25
26 void
27 mra_free(
28         Operation *op,
29         MatchingRuleAssertion *mra,
30         int     freeit )
31 {
32         /* op->o_tmpfree( mra->ma_value.bv_val, op->o_tmpmemctx ); */
33         ch_free( mra->ma_value.bv_val );
34         if ( freeit ) op->o_tmpfree( (char *) mra, op->o_tmpmemctx );
35 }
36
37 int
38 get_mra(
39         Operation *op,
40         BerElement      *ber,
41         MatchingRuleAssertion   **mra,
42         const char **text )
43 {
44         int rc;
45         ber_tag_t tag, rtag;
46         ber_len_t length;
47         struct berval type = BER_BVNULL;
48         struct berval value = BER_BVNULL;
49         struct berval rule_text = BER_BVNULL;
50         MatchingRuleAssertion ma;
51
52         memset( &ma, 0, sizeof ma);
53
54         rtag = ber_scanf( ber, "{t" /*"}"*/, &tag );
55
56         if( rtag == LBER_ERROR ) {
57                 Debug( LDAP_DEBUG_ANY, "  get_mra ber_scanf\n", 0, 0, 0 );
58
59                 *text = "Error parsing matching rule assertion";
60                 return SLAPD_DISCONNECT;
61         }
62
63         if ( tag == LDAP_FILTER_EXT_OID ) {
64                 rtag = ber_scanf( ber, "m", &rule_text );
65                 if ( rtag == LBER_ERROR ) {
66                         Debug( LDAP_DEBUG_ANY, "  get_mra ber_scanf for mr\n", 0, 0, 0 );
67
68                         *text = "Error parsing matching rule in matching rule assertion";
69                         return SLAPD_DISCONNECT;
70                 }
71
72                 rtag = ber_scanf( ber, "t", &tag );
73                 if( rtag == LBER_ERROR ) {
74                         Debug( LDAP_DEBUG_ANY, "  get_mra ber_scanf\n", 0, 0, 0 );
75
76                         *text = "Error parsing matching rule assertion";
77                         return SLAPD_DISCONNECT;
78                 }
79         }
80
81         if ( tag == LDAP_FILTER_EXT_TYPE ) {
82                 rtag = ber_scanf( ber, "m", &type );
83                 if ( rtag == LBER_ERROR ) {
84                         Debug( LDAP_DEBUG_ANY, "  get_mra ber_scanf for ad\n", 0, 0, 0 );
85
86                         *text = "Error parsing attribute description in matching rule assertion";
87                         return SLAPD_DISCONNECT;
88                 }
89
90                 rtag = ber_scanf( ber, "t", &tag );
91                 if( rtag == LBER_ERROR ) {
92                         Debug( LDAP_DEBUG_ANY, "  get_mra ber_scanf\n", 0, 0, 0 );
93
94                         *text = "Error parsing matching rule assertion";
95                         return SLAPD_DISCONNECT;
96                 }
97         }
98
99         if ( tag != LDAP_FILTER_EXT_VALUE ) {
100                 Debug( LDAP_DEBUG_ANY, "  get_mra ber_scanf missing value\n", 0, 0, 0 );
101
102                 *text = "Missing value in matching rule assertion";
103                 return SLAPD_DISCONNECT;
104         }
105
106         rtag = ber_scanf( ber, "m", &value );
107
108         if( rtag == LBER_ERROR ) {
109                 Debug( LDAP_DEBUG_ANY, "  get_mra ber_scanf\n", 0, 0, 0 );
110
111                 *text = "Error decoding value in matching rule assertion";
112                 return SLAPD_DISCONNECT;
113         }
114
115         tag = ber_peek_tag( ber, &length );
116
117         if ( tag == LDAP_FILTER_EXT_DNATTRS ) {
118                 rtag = ber_scanf( ber, /*"{"*/ "b}", &ma.ma_dnattrs );
119         } else {
120                 rtag = ber_scanf( ber, /*"{"*/ "}" );
121         }
122
123         if( rtag == LBER_ERROR ) {
124                 Debug( LDAP_DEBUG_ANY, "  get_mra ber_scanf\n", 0, 0, 0 );
125
126                 *text = "Error decoding dnattrs matching rule assertion";
127                 return SLAPD_DISCONNECT;
128         }
129
130         if( type.bv_val != NULL ) {
131                 rc = slap_bv2ad( &type, &ma.ma_desc, text );
132                 if( rc != LDAP_SUCCESS ) {
133                         return rc;
134                 }
135         }
136
137         if( rule_text.bv_val != NULL ) {
138                 ma.ma_rule = mr_bvfind( &rule_text );
139                 if( ma.ma_rule == NULL ) {
140                         *text = "matching rule not recognized";
141                         return LDAP_INAPPROPRIATE_MATCHING;
142                 }
143         }
144
145         if ( ma.ma_rule == NULL ) {
146                 /*
147                  * Need either type or rule ...
148                  */
149                 if ( ma.ma_desc == NULL ) {
150                         *text = "no matching rule or type";
151                         return LDAP_INAPPROPRIATE_MATCHING;
152                 }
153
154                 if ( ma.ma_desc->ad_type->sat_equality != NULL &&
155                         ma.ma_desc->ad_type->sat_equality->smr_usage & SLAP_MR_EXT )
156                 {
157                         /* no matching rule was provided, use the attribute's
158                            equality rule if it supports extensible matching. */
159                         ma.ma_rule = ma.ma_desc->ad_type->sat_equality;
160
161                 } else {
162                         *text = "no appropriate rule to use for type";
163                         return LDAP_INAPPROPRIATE_MATCHING;
164                 }
165         }
166
167         if ( ma.ma_desc != NULL ) {
168                 if( !mr_usable_with_at( ma.ma_rule, ma.ma_desc->ad_type ) ) {
169                         *text = "matching rule use with this attribute not appropriate";
170                         return LDAP_INAPPROPRIATE_MATCHING;
171                 }
172
173         }
174
175         /*
176          * Normalize per matching rule
177          */
178         rc = asserted_value_validate_normalize( ma.ma_desc,
179                 ma.ma_rule,
180                 SLAP_MR_EXT|SLAP_MR_VALUE_OF_ASSERTION_SYNTAX,
181                 &value, &ma.ma_value, text, op->o_tmpmemctx );
182
183         if( rc != LDAP_SUCCESS ) {
184                 return rc;
185         }
186
187 #ifdef LDAP_COMP_MATCH
188         /* Matching Rule for Component Matching */
189         Debug( LDAP_DEBUG_FILTER, "matchingrule %s\n",ma.ma_rule->smr_mrule.mr_oid,0,0);
190         if( ma.ma_rule && ma.ma_rule->smr_usage & SLAP_MR_COMPONENT )
191                 rc = get_comp_filter( op, &ma.ma_value, &ma.cf, text );
192                 if ( rc != LDAP_SUCCESS ) return rc;
193 #endif
194         length = sizeof(ma);
195         /* Append rule_text to end of struct */
196         if (rule_text.bv_val) length += rule_text.bv_len + 1;
197         *mra = op->o_tmpalloc( length, op->o_tmpmemctx );
198         **mra = ma;
199         if (rule_text.bv_val) {
200                 (*mra)->ma_rule_text.bv_len = rule_text.bv_len;
201                 (*mra)->ma_rule_text.bv_val = (char *)(*mra+1);
202                 AC_MEMCPY((*mra)->ma_rule_text.bv_val, rule_text.bv_val,
203                         rule_text.bv_len+1);
204         }
205
206         return LDAP_SUCCESS;
207 }