]> git.sur5r.net Git - openldap/blob - servers/slapd/mra.c
sync with HEAD
[openldap] / servers / slapd / mra.c
1 /* $OpenLDAP$ */
2 /*
3  * Copyright 1998-2002 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( ma->ma_dnattrs ) {
174                 *text = "matching with \":dn\" not supported";
175                 return LDAP_INAPPROPRIATE_MATCHING;
176         }
177
178         if( type.bv_val != NULL ) {
179                 rc = slap_bv2ad( &type, &ma->ma_desc, text );
180                 if( rc != LDAP_SUCCESS ) {
181                         mra_free( ma, 1 );
182                         return rc;
183                 }
184
185         } else {
186                 *text = "matching without attribute description rule not supported";
187                 return LDAP_INAPPROPRIATE_MATCHING;
188         }
189
190         if( ma->ma_rule_text.bv_val != NULL ) {
191                 ma->ma_rule = mr_bvfind( &ma->ma_rule_text );
192                 if( ma->ma_rule == NULL ) {
193                         mra_free( ma, 1 );
194                         *text = "matching rule not recognized";
195                         return LDAP_INAPPROPRIATE_MATCHING;
196                 }
197         }
198
199         if( ma->ma_desc != NULL &&
200                 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                 mra_free( ma, 1 );
209                 return LDAP_INAPPROPRIATE_MATCHING;
210         }
211
212         /* check to see if the matching rule is appropriate for
213            the syntax of the attribute.  This check will need
214            to be extended to support other kinds of extensible
215            matching rules */
216         if( strcmp( ma->ma_rule->smr_syntax->ssyn_oid,
217                 ma->ma_desc->ad_type->sat_syntax->ssyn_oid ) != 0 )
218         {
219                 mra_free( ma, 1 );
220                 return LDAP_INAPPROPRIATE_MATCHING;
221         }
222
223         /*
224          * OK, if no matching rule, normalize for equality, otherwise
225          * normalize for the matching rule.
226          */
227         rc = value_validate_normalize( ma->ma_desc, SLAP_MR_EQUALITY,
228                 &value, &ma->ma_value, text );
229
230         if( rc != LDAP_SUCCESS ) {
231                 mra_free( ma, 1 );
232                 return rc;
233         }
234
235         *mra = ma;
236         return LDAP_SUCCESS;
237 }
238