]> git.sur5r.net Git - openldap/blob - servers/slapd/mra.c
Fix cursor initialization, scope IDs
[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 };
40         struct berval value = { 0, NULL };
41         struct berval rule_text = { 0, NULL };
42         MatchingRuleAssertion ma;
43
44         memset( &ma, 0, sizeof ma);
45
46         rtag = ber_scanf( ber, "{t" /*"}"*/, &tag );
47
48         if( rtag == LBER_ERROR ) {
49 #ifdef NEW_LOGGING
50                 LDAP_LOG( OPERATION, ERR, 
51                         "get_mra: ber_scanf (\"{t\") failure\n", 0, 0, 0 );
52 #else
53                 Debug( LDAP_DEBUG_ANY, "  get_mra ber_scanf\n", 0, 0, 0 );
54 #endif
55
56                 *text = "Error parsing matching rule assertion";
57                 return SLAPD_DISCONNECT;
58         }
59
60         if ( tag == LDAP_FILTER_EXT_OID ) {
61                 rtag = ber_scanf( ber, "m", &rule_text );
62                 if ( rtag == LBER_ERROR ) {
63 #ifdef NEW_LOGGING
64                         LDAP_LOG( OPERATION, ERR,
65                            "get_mra: ber_scanf(\"o\") failure.\n", 0, 0, 0 );
66 #else
67                         Debug( LDAP_DEBUG_ANY, "  get_mra ber_scanf for mr\n", 0, 0, 0 );
68 #endif
69
70                         *text = "Error parsing matching rule in matching rule assertion";
71                         return SLAPD_DISCONNECT;
72                 }
73
74                 rtag = ber_scanf( ber, "t", &tag );
75                 if( rtag == LBER_ERROR ) {
76 #ifdef NEW_LOGGING
77                         LDAP_LOG( OPERATION, ERR,
78                            "get_mra: ber_scanf (\"t\") failure\n", 0, 0, 0 );
79 #else
80                         Debug( LDAP_DEBUG_ANY, "  get_mra ber_scanf\n", 0, 0, 0 );
81 #endif
82
83                         *text = "Error parsing matching rule assertion";
84                         return SLAPD_DISCONNECT;
85                 }
86         }
87
88         if ( tag == LDAP_FILTER_EXT_TYPE ) {
89                 rtag = ber_scanf( ber, "m", &type );
90                 if ( rtag == LBER_ERROR ) {
91 #ifdef NEW_LOGGING
92                         LDAP_LOG( OPERATION, ERR,
93                            "get_mra: ber_scanf (\"o\") failure.\n", 0, 0, 0 );
94 #else
95                         Debug( LDAP_DEBUG_ANY, "  get_mra ber_scanf for ad\n", 0, 0, 0 );
96 #endif
97
98                         *text = "Error parsing attribute description in matching rule assertion";
99                         return SLAPD_DISCONNECT;
100                 }
101
102                 rtag = ber_scanf( ber, "t", &tag );
103                 if( rtag == LBER_ERROR ) {
104 #ifdef NEW_LOGGING
105                         LDAP_LOG( OPERATION, ERR,
106                            "get_mra: ber_scanf (\"t\") failure.\n", 0, 0, 0 );
107 #else
108                         Debug( LDAP_DEBUG_ANY, "  get_mra ber_scanf\n", 0, 0, 0 );
109 #endif
110
111                         *text = "Error parsing matching rule assertion";
112                         return SLAPD_DISCONNECT;
113                 }
114         }
115
116         if ( tag != LDAP_FILTER_EXT_VALUE ) {
117 #ifdef NEW_LOGGING
118                 LDAP_LOG( OPERATION, ERR, 
119                         "get_mra: ber_scanf missing value\n", 0, 0, 0 );
120 #else
121                 Debug( LDAP_DEBUG_ANY, "  get_mra ber_scanf missing value\n", 0, 0, 0 );
122 #endif
123
124                 *text = "Missing value in matching rule assertion";
125                 return SLAPD_DISCONNECT;
126         }
127
128         rtag = ber_scanf( ber, "m", &value );
129
130         if( rtag == LBER_ERROR ) {
131 #ifdef NEW_LOGGING
132                 LDAP_LOG( OPERATION, ERR, 
133                         "get_mra: ber_scanf (\"o\") failure.\n", 0, 0, 0 );
134 #else
135                 Debug( LDAP_DEBUG_ANY, "  get_mra ber_scanf\n", 0, 0, 0 );
136 #endif
137
138                 *text = "Error decoding value in matching rule assertion";
139                 return SLAPD_DISCONNECT;
140         }
141
142         tag = ber_peek_tag( ber, &length );
143
144         if ( tag == LDAP_FILTER_EXT_DNATTRS ) {
145                 rtag = ber_scanf( ber, /*"{"*/ "b}", &ma.ma_dnattrs );
146         } else {
147                 rtag = ber_scanf( ber, /*"{"*/ "}" );
148         }
149
150         if( rtag == LBER_ERROR ) {
151 #ifdef NEW_LOGGING
152                 LDAP_LOG( OPERATION, ERR, "get_mra: ber_scanf failure\n", 0, 0, 0);
153 #else
154                 Debug( LDAP_DEBUG_ANY, "  get_mra ber_scanf\n", 0, 0, 0 );
155 #endif
156
157                 *text = "Error decoding dnattrs matching rule assertion";
158                 return SLAPD_DISCONNECT;
159         }
160
161         if( type.bv_val != NULL ) {
162                 rc = slap_bv2ad( &type, &ma.ma_desc, text );
163                 if( rc != LDAP_SUCCESS ) {
164                         return rc;
165                 }
166         }
167
168         if( rule_text.bv_val != NULL ) {
169                 ma.ma_rule = mr_bvfind( &rule_text );
170                 if( ma.ma_rule == NULL ) {
171                         *text = "matching rule not recognized";
172                         return LDAP_INAPPROPRIATE_MATCHING;
173                 }
174         }
175
176         if ( ma.ma_rule == NULL ) {
177                 /*
178                  * Need either type or rule ...
179                  */
180                 if ( ma.ma_desc == NULL ) {
181                         *text = "no matching rule or type";
182                         return LDAP_INAPPROPRIATE_MATCHING;
183                 }
184
185                 if ( ma.ma_desc->ad_type->sat_equality != NULL &&
186                         ma.ma_desc->ad_type->sat_equality->smr_usage & SLAP_MR_EXT )
187                 {
188                         /* no matching rule was provided, use the attribute's
189                            equality rule if it supports extensible matching. */
190                         ma.ma_rule = ma.ma_desc->ad_type->sat_equality;
191
192                 } else {
193                         *text = "no appropriate rule to use for type";
194                         return LDAP_INAPPROPRIATE_MATCHING;
195                 }
196         }
197
198         if ( ma.ma_desc != NULL ) {
199                 if( !mr_usable_with_at( ma.ma_rule, ma.ma_desc->ad_type ) ) {
200                         *text = "matching rule use with this attribute not appropriate";
201                         return LDAP_INAPPROPRIATE_MATCHING;
202                 }
203
204         }
205
206         /*
207          * Normalize per matching rule
208          */
209         rc = asserted_value_validate_normalize( ma.ma_desc,
210                 ma.ma_rule,
211                 SLAP_MR_EXT|SLAP_MR_VALUE_OF_ASSERTION_SYNTAX,
212                 &value, &ma.ma_value, text );
213
214         if( rc != LDAP_SUCCESS ) {
215                 return rc;
216         }
217
218         length = sizeof(ma);
219         /* Append rule_text to end of struct */
220         if (rule_text.bv_val) length += rule_text.bv_len + 1;
221         *mra = ch_malloc( length );
222         **mra = ma;
223         if (rule_text.bv_val) {
224                 (*mra)->ma_rule_text.bv_len = rule_text.bv_len;
225                 (*mra)->ma_rule_text.bv_val = (char *)(*mra+1);
226                 AC_MEMCPY((*mra)->ma_rule_text.bv_val, rule_text.bv_val,
227                         rule_text.bv_len+1);
228         }
229
230         return LDAP_SUCCESS;
231 }