]> git.sur5r.net Git - openldap/blob - servers/slapd/mra.c
Not sure why these asserts are failing... too tired to figure it...
[openldap] / servers / slapd / mra.c
1 /* $OpenLDAP$ */
2 /*
3  * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
4  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
5  */
6 /* mra.c - routines for dealing with extensible matching rule assertions */
7
8 #include "portable.h"
9
10 #include <stdio.h>
11
12 #include <ac/string.h>
13 #include <ac/socket.h>
14
15 #include "slap.h"
16
17 void
18 mra_free(
19         MatchingRuleAssertion *mra,
20         int     freeit
21 )
22 {
23         ch_free( mra->ma_value.bv_val );
24         if ( freeit ) {
25                 ch_free( (char *) mra );
26         }
27 }
28
29 int
30 get_mra(
31         BerElement      *ber,
32         MatchingRuleAssertion   **mra,
33         const char **text
34 )
35 {
36         int rc;
37         ber_tag_t tag, rtag;
38         ber_len_t length;
39         struct berval type = { 0, NULL }, value;
40         MatchingRuleAssertion *ma;
41
42         ma = ch_malloc( sizeof( MatchingRuleAssertion ) );
43         ma->ma_rule = NULL;
44         ma->ma_rule_text.bv_len = 0;
45         ma->ma_rule_text.bv_val = NULL;
46         ma->ma_desc = NULL;
47         ma->ma_dnattrs = 0;
48         ma->ma_value.bv_len = 0;
49         ma->ma_value.bv_val = NULL;
50
51         rtag = ber_scanf( ber, "{t", &tag );
52
53         if( rtag == LBER_ERROR ) {
54 #ifdef NEW_LOGGING
55                 LDAP_LOG( OPERATION, ERR, 
56                         "get_mra: ber_scanf (\"{t\") failure\n", 0, 0, 0 );
57 #else
58                 Debug( LDAP_DEBUG_ANY, "  get_mra ber_scanf\n", 0, 0, 0 );
59 #endif
60
61                 *text = "Error parsing matching rule assertion";
62                 mra_free( ma, 1 );
63                 return SLAPD_DISCONNECT;
64         }
65
66         if ( tag == LDAP_FILTER_EXT_OID ) {
67                 rtag = ber_scanf( ber, "m", &ma->ma_rule_text );
68                 if ( rtag == LBER_ERROR ) {
69 #ifdef NEW_LOGGING
70                         LDAP_LOG( OPERATION, ERR,
71                            "get_mra: ber_scanf(\"o\") failure.\n", 0, 0, 0 );
72 #else
73                         Debug( LDAP_DEBUG_ANY, "  get_mra ber_scanf for mr\n", 0, 0, 0 );
74 #endif
75
76                         *text = "Error parsing matching rule in matching rule assertion";
77                         mra_free( ma, 1 );
78                         return SLAPD_DISCONNECT;
79                 }
80
81                 rtag = ber_scanf( ber, "t", &tag );
82                 if( rtag == LBER_ERROR ) {
83 #ifdef NEW_LOGGING
84                         LDAP_LOG( OPERATION, ERR,
85                            "get_mra: ber_scanf (\"t\") failure\n", 0, 0, 0 );
86 #else
87                         Debug( LDAP_DEBUG_ANY, "  get_mra ber_scanf\n", 0, 0, 0 );
88 #endif
89
90                         *text = "Error parsing matching rule assertion";
91                         mra_free( ma, 1 );
92                         return SLAPD_DISCONNECT;
93                 }
94         }
95
96         if ( tag == LDAP_FILTER_EXT_TYPE ) {
97                 rtag = ber_scanf( ber, "m", &type );
98                 if ( rtag == LBER_ERROR ) {
99 #ifdef NEW_LOGGING
100                         LDAP_LOG( OPERATION, ERR,
101                            "get_mra: ber_scanf (\"o\") failure.\n", 0, 0, 0 );
102 #else
103                         Debug( LDAP_DEBUG_ANY, "  get_mra ber_scanf for ad\n", 0, 0, 0 );
104 #endif
105
106                         *text = "Error parsing attribute description in matching rule assertion";
107                         return SLAPD_DISCONNECT;
108                 }
109
110                 rtag = ber_scanf( ber, "t", &tag );
111                 if( rtag == LBER_ERROR ) {
112 #ifdef NEW_LOGGING
113                         LDAP_LOG( OPERATION, ERR,
114                            "get_mra: ber_scanf (\"t\") failure.\n", 0, 0, 0 );
115 #else
116                         Debug( LDAP_DEBUG_ANY, "  get_mra ber_scanf\n", 0, 0, 0 );
117 #endif
118
119                         *text = "Error parsing matching rule assertion";
120                         mra_free( ma, 1 );
121                         return SLAPD_DISCONNECT;
122                 }
123         }
124
125         if ( tag != LDAP_FILTER_EXT_VALUE ) {
126 #ifdef NEW_LOGGING
127                 LDAP_LOG( OPERATION, ERR, 
128                         "get_mra: ber_scanf missing value\n", 0, 0, 0 );
129 #else
130                 Debug( LDAP_DEBUG_ANY, "  get_mra ber_scanf missing value\n", 0, 0, 0 );
131 #endif
132
133                 *text = "Missing value in matching rule assertion";
134                 mra_free( ma, 1 );
135                 return SLAPD_DISCONNECT;
136         }
137
138         rtag = ber_scanf( ber, "m", &value );
139
140         if( rtag == LBER_ERROR ) {
141 #ifdef NEW_LOGGING
142                 LDAP_LOG( OPERATION, ERR, 
143                         "get_mra: ber_scanf (\"o\") failure.\n", 0, 0, 0 );
144 #else
145                 Debug( LDAP_DEBUG_ANY, "  get_mra ber_scanf\n", 0, 0, 0 );
146 #endif
147
148                 *text = "Error decoding value in matching rule assertion";
149                 mra_free( ma, 1 );
150                 return SLAPD_DISCONNECT;
151         }
152
153         tag = ber_peek_tag( ber, &length );
154
155         if ( tag == LDAP_FILTER_EXT_DNATTRS ) {
156                 rtag = ber_scanf( ber, "b}", &ma->ma_dnattrs );
157         } else {
158                 rtag = ber_scanf( ber, "}" );
159         }
160
161         if( rtag == LBER_ERROR ) {
162 #ifdef NEW_LOGGING
163                 LDAP_LOG( OPERATION, ERR, "get_mra: ber_scanf failure\n", 0, 0, 0);
164 #else
165                 Debug( LDAP_DEBUG_ANY, "  get_mra ber_scanf\n", 0, 0, 0 );
166 #endif
167
168                 *text = "Error decoding dnattrs matching rule assertion";
169                 mra_free( ma, 1 );
170                 return SLAPD_DISCONNECT;
171         }
172
173         if( type.bv_val != NULL ) {
174                 rc = slap_bv2ad( &type, &ma->ma_desc, text );
175                 if( rc != LDAP_SUCCESS ) {
176                         mra_free( ma, 1 );
177                         return rc;
178                 }
179         }
180
181         if( ma->ma_rule_text.bv_val != NULL ) {
182                 ma->ma_rule = mr_bvfind( &ma->ma_rule_text );
183                 if( ma->ma_rule == NULL ) {
184                         mra_free( ma, 1 );
185                         *text = "matching rule not recognized";
186                         return LDAP_INAPPROPRIATE_MATCHING;
187                 }
188         }
189
190         if ( ma->ma_rule == NULL ) {
191                 /*
192                  * Need either type or rule ...
193                  */
194                 if ( ma->ma_desc == NULL ) {
195                         mra_free( ma, 1 );
196                         *text = "no matching rule or type";
197                         return LDAP_INAPPROPRIATE_MATCHING;
198                 }
199
200                 if ( ma->ma_desc->ad_type->sat_equality != NULL &&
201                         ma->ma_desc->ad_type->sat_equality->smr_usage & SLAP_MR_EXT )
202                 {
203                         /* no matching rule was provided, use the attribute's
204                            equality rule if it supports extensible matching. */
205                         ma->ma_rule = ma->ma_desc->ad_type->sat_equality;
206
207                 } else {
208                         *text = "no appropriate rule to use for type";
209                         mra_free( ma, 1 );
210                         return LDAP_INAPPROPRIATE_MATCHING;
211                 }
212         }
213
214         if ( ma->ma_desc != NULL ) {
215                 if( !mr_usable_with_at( ma->ma_rule, ma->ma_desc->ad_type ) ) {
216                         mra_free( ma, 1 );
217                         *text = "matching rule use with this attribute not appropriate";
218                         return LDAP_INAPPROPRIATE_MATCHING;
219                 }
220
221 #ifndef SLAP_NVALUES
222                 /*
223                  * OK, if no matching rule, normalize for equality, otherwise
224                  * normalize for the matching rule.
225                  */
226                 rc = value_validate_normalize( ma->ma_desc, SLAP_MR_EQUALITY,
227                         &value, &ma->ma_value, text );
228         } else {
229                 /*
230                  * Need to normalize, but how?
231                  */
232                 rc = value_validate( ma->ma_rule, &value, text );
233                 if ( rc == LDAP_SUCCESS ) {
234                         ber_dupbv( &ma->ma_value, &value );
235                 }
236 #endif
237         }
238
239 #ifdef SLAP_NVALUES
240         /*
241          * Normalize per matching rule
242          */
243         rc = asserted_value_validate_normalize( ma->ma_desc,
244                 ma->ma_rule,
245                 SLAP_MR_EXT|SLAP_MR_VALUE_OF_ASSERTION_SYNTAX,
246                 &ma->ma_value, &value, text );
247         if ( rc == LDAP_SUCCESS ) {
248                 ber_dupbv( &ma->ma_value, &value );
249         } else
250 #else
251         if( rc != LDAP_SUCCESS )
252 #endif
253         {
254                 mra_free( ma, 1 );
255                 return rc;
256         }
257
258         *mra = ma;
259         return LDAP_SUCCESS;
260 }
261