]> git.sur5r.net Git - openldap/blob - servers/slapd/mr.c
Import ITS#2007 and ITS#2009 bug fixes from HEAD
[openldap] / servers / slapd / mr.c
1 /* mr.c - routines to manage matching rule definitions */
2 /* $OpenLDAP$ */
3 /*
4  * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
5  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
6  */
7
8 #include "portable.h"
9
10 #include <stdio.h>
11
12 #include <ac/ctype.h>
13 #include <ac/string.h>
14 #include <ac/socket.h>
15
16 #include "slap.h"
17 #include "ldap_pvt.h"
18
19 struct mindexrec {
20         struct berval   mir_name;
21         MatchingRule    *mir_mr;
22 };
23
24 static Avlnode  *mr_index = NULL;
25 static MatchingRule *mr_list = NULL;
26
27 static int
28 mr_index_cmp(
29     struct mindexrec    *mir1,
30     struct mindexrec    *mir2
31 )
32 {
33         int i = mir1->mir_name.bv_len - mir2->mir_name.bv_len;
34         if (i) return i;
35         return (strcmp( mir1->mir_name.bv_val, mir2->mir_name.bv_val ));
36 }
37
38 static int
39 mr_index_name_cmp(
40     struct berval       *name,
41     struct mindexrec    *mir
42 )
43 {
44         int i = name->bv_len - mir->mir_name.bv_len;
45         if (i) return i;
46         return (strncmp( name->bv_val, mir->mir_name.bv_val, name->bv_len ));
47 }
48
49 MatchingRule *
50 mr_find( const char *mrname )
51 {
52         struct berval bv;
53
54         bv.bv_val = (char *)mrname;
55         bv.bv_len = strlen( mrname );
56         return mr_bvfind( &bv );
57 }
58
59 MatchingRule *
60 mr_bvfind( struct berval *mrname )
61 {
62         struct mindexrec        *mir = NULL;
63
64         if ( (mir = (struct mindexrec *) avl_find( mr_index, mrname,
65             (AVL_CMP) mr_index_name_cmp )) != NULL ) {
66                 return( mir->mir_mr );
67         }
68         return( NULL );
69 }
70
71 void
72 mr_destroy( void )
73 {
74         MatchingRule *m, *n;
75
76         avl_free(mr_index, ldap_memfree);
77         for (m=mr_list; m; m=n) {
78                 n = m->smr_next;
79                 ldap_matchingrule_free((LDAPMatchingRule *)m);
80         }
81 }
82
83 static int
84 mr_insert(
85     MatchingRule        *smr,
86     const char          **err
87 )
88 {
89         MatchingRule            **mrp;
90         struct mindexrec        *mir;
91         char                    **names;
92
93         mrp = &mr_list;
94         while ( *mrp != NULL ) {
95                 mrp = &(*mrp)->smr_next;
96         }
97         *mrp = smr;
98
99         if ( smr->smr_oid ) {
100                 mir = (struct mindexrec *)
101                         ch_calloc( 1, sizeof(struct mindexrec) );
102                 mir->mir_name.bv_val = smr->smr_oid;
103                 mir->mir_name.bv_len = strlen( smr->smr_oid );
104                 mir->mir_mr = smr;
105                 if ( avl_insert( &mr_index, (caddr_t) mir,
106                                  (AVL_CMP) mr_index_cmp,
107                                  (AVL_DUP) avl_dup_error ) ) {
108                         *err = smr->smr_oid;
109                         ldap_memfree(mir);
110                         return SLAP_SCHERR_MR_DUP;
111                 }
112                 /* FIX: temporal consistency check */
113                 mr_bvfind(&mir->mir_name);
114         }
115         if ( (names = smr->smr_names) ) {
116                 while ( *names ) {
117                         mir = (struct mindexrec *)
118                                 ch_calloc( 1, sizeof(struct mindexrec) );
119                         mir->mir_name.bv_val = *names;
120                         mir->mir_name.bv_len = strlen( *names );
121                         mir->mir_mr = smr;
122                         if ( avl_insert( &mr_index, (caddr_t) mir,
123                                          (AVL_CMP) mr_index_cmp,
124                                          (AVL_DUP) avl_dup_error ) ) {
125                                 *err = *names;
126                                 ldap_memfree(mir);
127                                 return SLAP_SCHERR_MR_DUP;
128                         }
129                         /* FIX: temporal consistency check */
130                         mr_bvfind(&mir->mir_name);
131                         names++;
132                 }
133         }
134         return 0;
135 }
136
137 int
138 mr_add(
139     LDAPMatchingRule            *mr,
140         unsigned usage,
141         slap_mr_convert_func *convert,
142         slap_mr_normalize_func *normalize,
143     slap_mr_match_func  *match,
144         slap_mr_indexer_func *indexer,
145     slap_mr_filter_func *filter,
146         MatchingRule    *amr,
147     const char          **err
148 )
149 {
150         MatchingRule    *smr;
151         Syntax          *syn;
152         int             code;
153
154         smr = (MatchingRule *) ch_calloc( 1, sizeof(MatchingRule) );
155         AC_MEMCPY( &smr->smr_mrule, mr, sizeof(LDAPMatchingRule));
156
157         smr->smr_oidlen = strlen( mr->mr_oid );
158         smr->smr_usage = usage;
159         smr->smr_convert = convert;
160         smr->smr_normalize = normalize;
161         smr->smr_match = match;
162         smr->smr_indexer = indexer;
163         smr->smr_filter = filter;
164         smr->smr_associated = amr;
165
166         if ( smr->smr_syntax_oid ) {
167                 if ( (syn = syn_find(smr->smr_syntax_oid)) ) {
168                         smr->smr_syntax = syn;
169                 } else {
170                         *err = smr->smr_syntax_oid;
171                         return SLAP_SCHERR_SYN_NOT_FOUND;
172                 }
173         } else {
174                 *err = "";
175                 return SLAP_SCHERR_MR_INCOMPLETE;
176         }
177         code = mr_insert(smr,err);
178         return code;
179 }
180
181
182 int
183 register_matching_rule(
184         const char * desc,
185         unsigned usage,
186         slap_mr_convert_func *convert,
187         slap_mr_normalize_func *normalize,
188         slap_mr_match_func *match,
189         slap_mr_indexer_func *indexer,
190         slap_mr_filter_func *filter,
191         const char* associated )
192 {
193         LDAPMatchingRule *mr;
194         MatchingRule *amr = NULL;
195         int             code;
196         const char      *err;
197
198         if( usage == SLAP_MR_NONE ) {
199 #ifdef NEW_LOGGING
200                 LDAP_LOG( OPERATION, ERR, 
201                         "register_matching_rule: %s not usable\n", desc, 0, 0 );
202 #else
203                 Debug( LDAP_DEBUG_ANY, "register_matching_rule: not usable %s\n",
204                     desc, 0, 0 );
205 #endif
206
207                 return -1;
208         }
209
210         if( associated != NULL ) {
211                 amr = mr_find( associated );
212
213 #if 0
214                 /* ignore for now */
215
216                 if( amr == NULL ) {
217 #ifdef NEW_LOGGING
218                         LDAP_LOG( OPERATION, ERR,
219                            "register_matching_rule: could not locate associated "
220                            "matching rule %s for %s\n",  associated, desc, 0 );
221 #else
222                         Debug( LDAP_DEBUG_ANY, "register_matching_rule: could not locate "
223                                 "associated matching rule %s for %s\n",
224                                 associated, desc, 0 );
225 #endif
226
227                         return -1;
228                 }
229 #endif
230
231         }
232
233         mr = ldap_str2matchingrule( desc, &code, &err, LDAP_SCHEMA_ALLOW_ALL);
234         if ( !mr ) {
235 #ifdef NEW_LOGGING
236                 LDAP_LOG( OPERATION, ERR, 
237                         "register_matching_rule: %s before %s in %s.\n",
238                         ldap_scherr2str(code), err, desc );
239 #else
240                 Debug( LDAP_DEBUG_ANY, "Error in register_matching_rule: %s before %s in %s\n",
241                     ldap_scherr2str(code), err, desc );
242 #endif
243
244                 return( -1 );
245         }
246
247         code = mr_add( mr, usage,
248                 convert, normalize, match, indexer, filter, amr,
249                 &err );
250
251         ldap_memfree( mr );
252
253         if ( code ) {
254 #ifdef NEW_LOGGING
255                 LDAP_LOG( OPERATION, ERR, 
256                         "register_matching_rule: %s for %s in %s.\n",
257                         scherr2str(code), err, desc );
258 #else
259                 Debug( LDAP_DEBUG_ANY, "Error in register_matching_rule: %s for %s in %s\n",
260                     scherr2str(code), err, desc );
261 #endif
262
263                 return( -1 );
264         }
265
266         return( 0 );
267 }
268
269
270 #if defined( SLAPD_SCHEMA_DN )
271
272 int mr_schema_info( Entry *e )
273 {
274         struct berval   vals[2];
275         MatchingRule    *mr;
276
277         AttributeDescription *ad_matchingRules = slap_schema.si_ad_matchingRules;
278
279         vals[1].bv_val = NULL;
280
281         for ( mr = mr_list; mr; mr = mr->smr_next ) {
282                 if ( mr->smr_usage & SLAP_MR_HIDE ) {
283                         /* skip hidden rules */
284                         continue;
285                 }
286
287                 if ( ! mr->smr_match ) {
288                         /* skip rules without matching functions */
289                         continue;
290                 }
291
292                 if ( ldap_matchingrule2bv( &mr->smr_mrule, vals ) == NULL ) {
293                         return -1;
294                 }
295 #if 0
296                 Debug( LDAP_DEBUG_TRACE, "Merging mr [%ld] %s\n",
297                (long) vals[0].bv_len, vals[0].bv_val, 0 );
298 #endif
299                 attr_merge( e, ad_matchingRules, vals );
300                 ldap_memfree( vals[0].bv_val );
301         }
302         return 0;
303 }
304
305 int mru_schema_info( Entry *e )
306 {
307         return 0;
308 }
309
310 #endif