]> git.sur5r.net Git - openldap/blob - servers/slapd/mr.c
Import changes from devel
[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 static int
59 mr_insert(
60     MatchingRule        *smr,
61     const char          **err
62 )
63 {
64         MatchingRule            **mrp;
65         struct mindexrec        *mir;
66         char                    **names;
67
68         mrp = &mr_list;
69         while ( *mrp != NULL ) {
70                 mrp = &(*mrp)->smr_next;
71         }
72         *mrp = smr;
73
74         if ( smr->smr_oid ) {
75                 mir = (struct mindexrec *)
76                         ch_calloc( 1, sizeof(struct mindexrec) );
77                 mir->mir_name = smr->smr_oid;
78                 mir->mir_mr = smr;
79                 if ( avl_insert( &mr_index, (caddr_t) mir,
80                                  (AVL_CMP) mr_index_cmp,
81                                  (AVL_DUP) avl_dup_error ) ) {
82                         *err = smr->smr_oid;
83                         ldap_memfree(mir);
84                         return SLAP_SCHERR_DUP_RULE;
85                 }
86                 /* FIX: temporal consistency check */
87                 mr_find(mir->mir_name);
88         }
89         if ( (names = smr->smr_names) ) {
90                 while ( *names ) {
91                         mir = (struct mindexrec *)
92                                 ch_calloc( 1, sizeof(struct mindexrec) );
93                         mir->mir_name = ch_strdup(*names);
94                         mir->mir_mr = smr;
95                         if ( avl_insert( &mr_index, (caddr_t) mir,
96                                          (AVL_CMP) mr_index_cmp,
97                                          (AVL_DUP) avl_dup_error ) ) {
98                                 *err = *names;
99                                 ldap_memfree(mir);
100                                 return SLAP_SCHERR_DUP_RULE;
101                         }
102                         /* FIX: temporal consistency check */
103                         mr_find(mir->mir_name);
104                         names++;
105                 }
106         }
107         return 0;
108 }
109
110 int
111 mr_add(
112     LDAPMatchingRule            *mr,
113         unsigned usage,
114         slap_mr_convert_func *convert,
115         slap_mr_normalize_func *normalize,
116     slap_mr_match_func  *match,
117         slap_mr_indexer_func *indexer,
118     slap_mr_filter_func *filter,
119         MatchingRule    *amr,
120     const char          **err
121 )
122 {
123         MatchingRule    *smr;
124         Syntax          *syn;
125         int             code;
126
127         smr = (MatchingRule *) ch_calloc( 1, sizeof(MatchingRule) );
128         AC_MEMCPY( &smr->smr_mrule, mr, sizeof(LDAPMatchingRule));
129
130         smr->smr_usage = usage;
131         smr->smr_convert = convert;
132         smr->smr_normalize = normalize;
133         smr->smr_match = match;
134         smr->smr_indexer = indexer;
135         smr->smr_filter = filter;
136         smr->smr_associated = amr;
137
138         if ( smr->smr_syntax_oid ) {
139                 if ( (syn = syn_find(smr->smr_syntax_oid)) ) {
140                         smr->smr_syntax = syn;
141                 } else {
142                         *err = smr->smr_syntax_oid;
143                         return SLAP_SCHERR_SYN_NOT_FOUND;
144                 }
145         } else {
146                 *err = "";
147                 return SLAP_SCHERR_MR_INCOMPLETE;
148         }
149         code = mr_insert(smr,err);
150         return code;
151 }
152
153
154 int
155 register_matching_rule(
156         char * desc,
157         unsigned usage,
158         slap_mr_convert_func *convert,
159         slap_mr_normalize_func *normalize,
160         slap_mr_match_func *match,
161         slap_mr_indexer_func *indexer,
162         slap_mr_filter_func *filter,
163         const char* associated )
164 {
165         LDAPMatchingRule *mr;
166         MatchingRule *amr = NULL;
167         int             code;
168         const char      *err;
169
170         if( usage == SLAP_MR_NONE ) {
171                 Debug( LDAP_DEBUG_ANY, "register_matching_rule: not usable %s\n",
172                     desc, 0, 0 );
173                 return -1;
174         }
175
176         if( associated != NULL ) {
177                 amr = mr_find( associated );
178
179 #if 0
180                 /* ignore for now */
181
182                 if( amr == NULL ) {
183                         Debug( LDAP_DEBUG_ANY, "register_matching_rule: could not locate "
184                                 "associated matching rule %s for %s\n",
185                                 associated, desc, 0 );
186                         return -1;
187                 }
188 #endif
189
190         }
191
192         mr = ldap_str2matchingrule( desc, &code, &err, LDAP_SCHEMA_ALLOW_ALL);
193         if ( !mr ) {
194                 Debug( LDAP_DEBUG_ANY, "Error in register_matching_rule: %s before %s in %s\n",
195                     ldap_scherr2str(code), err, desc );
196                 return( -1 );
197         }
198
199         code = mr_add( mr, usage,
200                 convert, normalize, match, indexer, filter, amr,
201                 &err );
202
203         ldap_memfree( mr );
204
205         if ( code ) {
206                 Debug( LDAP_DEBUG_ANY, "Error in register_syntax: %s for %s in %s\n",
207                     scherr2str(code), err, desc );
208                 return( -1 );
209         }
210
211         return( 0 );
212 }
213
214
215 #if defined( SLAPD_SCHEMA_DN )
216
217 int mr_schema_info( Entry *e )
218 {
219         struct berval   val;
220         struct berval   *vals[2];
221         MatchingRule    *mr;
222
223         AttributeDescription *ad_matchingRules = slap_schema.si_ad_matchingRules;
224
225         vals[0] = &val;
226         vals[1] = NULL;
227
228         for ( mr = mr_list; mr; mr = mr->smr_next ) {
229                 val.bv_val = ldap_matchingrule2str( &mr->smr_mrule );
230
231                 if ( val.bv_val == NULL ) {
232                         return -1;
233                 }
234
235                 val.bv_len = strlen( val.bv_val );
236 #if 0
237                 Debug( LDAP_DEBUG_TRACE, "Merging mr [%ld] %s\n",
238                (long) val.bv_len, val.bv_val, 0 );
239 #endif
240                 attr_merge( e, ad_matchingRules, vals );
241                 ldap_memfree( val.bv_val );
242         }
243         return 0;
244 }
245
246 #endif