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