]> git.sur5r.net Git - openldap/blob - servers/slapd/schema_init.c
SLAPD_SCHEMA_NOT_COMPAT: Rework caching of internal schema
[openldap] / servers / slapd / schema_init.c
1 /* schema_init.c - init builtin schema */
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 static int
20 octetStringValidate(
21         Syntax *syntax,
22         struct berval *in )
23 {
24         /* any value allowed */
25         return 0;
26 }
27
28 static int
29 UTF8StringValidate(
30         Syntax *syntax,
31         struct berval *in )
32 {
33         ber_len_t count;
34         int len;
35         unsigned char *u = in->bv_val;
36
37         for( count = in->bv_len; count > 0; count+=len, u+=len ) {
38                 /* get the length indicated by the first byte */
39                 len = LDAP_UTF8_CHARLEN( u );
40
41                 /* should not be zero */
42                 if( len == 0 ) return -1;
43
44                 /* make sure len corresponds with the offset
45                         to the next character */
46                 if( LDAP_UTF8_OFFSET( u ) != len ) return -1;
47         }
48
49         if( count != 0 ) return -1;
50
51         return 0;
52 }
53
54 static int
55 UTF8StringNormalize(
56         unsigned use,
57         Syntax *syntax,
58         MatchingRule *mr,
59         struct berval *val,
60         struct berval **normalized )
61 {
62         struct berval *newval;
63         char *p, *q, *s;
64
65         newval = ch_malloc( sizeof( struct berval ) );
66
67         p = val->bv_val;
68
69         /* Ignore initial whitespace */
70         while ( ldap_utf8_isspace( p ) ) {
71                 LDAP_UTF8_INCR( p );
72         }
73
74         if( *p ) {
75                 ch_free( newval );
76                 return 1;
77         }
78
79         newval->bv_val = ch_strdup( p );
80         p = q = newval->bv_val;
81         s = NULL;
82
83         while ( *p ) {
84                 int len;
85
86                 if ( ldap_utf8_isspace( p ) ) {
87                         len = LDAP_UTF8_COPY(q,p);
88                         s=q;
89                         p+=len;
90                         q+=len;
91
92                         /* Ignore the extra whitespace */
93                         while ( ldap_utf8_isspace( p ) ) {
94                                 LDAP_UTF8_INCR( p );
95                         }
96                 } else {
97                         len = LDAP_UTF8_COPY(q,p);
98                         s=NULL;
99                         p+=len;
100                         q+=len;
101                 }
102         }
103
104         assert( *newval->bv_val );
105         assert( newval->bv_val < p );
106         assert( p <= q );
107
108         /* cannot start with a space */
109         assert( !ldap_utf8_isspace(newval->bv_val) );
110
111         /*
112          * If the string ended in space, backup the pointer one
113          * position.  One is enough because the above loop collapsed
114          * all whitespace to a single space.
115          */
116
117         if ( s != NULL ) {
118                 q = s;
119         }
120
121         /* cannot end with a space */
122         assert( !ldap_utf8_isspace( LDAP_UTF8_PREV(q) ) );
123
124         /* null terminate */
125         *q = '\0';
126
127         newval->bv_len = q - newval->bv_val;
128         normalized = &newval;
129
130         return 0;
131 }
132
133 static int
134 IA5StringValidate(
135         Syntax *syntax,
136         struct berval *val )
137 {
138         ber_len_t i;
139
140         for(i=0; i < val->bv_len; i++) {
141                 if( !isascii(val->bv_val[i]) ) return -1;
142         }
143
144         return 0;
145 }
146
147 static int
148 IA5StringConvert(
149         Syntax *syntax,
150         struct berval *in,
151         struct berval **out )
152 {
153         ber_len_t i;
154         struct berval *bv = ch_malloc( sizeof(struct berval) );
155         bv->bv_len = (in->bv_len+1) * sizeof( ldap_unicode_t );
156         bv->bv_val = ch_malloc( bv->bv_len );
157
158         for(i=0; i < in->bv_len; i++ ) {
159                 /*
160                  * IA5StringValidate should have been called to ensure
161                  * input is limited to IA5.
162                  */
163                 bv->bv_val[i] = in->bv_val[i];
164         }
165
166         *out = bv;
167         return 0;
168 }
169
170 static int
171 IA5StringNormalize(
172         unsigned use,
173         Syntax *syntax,
174         MatchingRule *mr,
175         struct berval *val,
176         struct berval **normalized )
177 {
178         struct berval *newval;
179         char *p, *q;
180
181         newval = ch_malloc( sizeof( struct berval ) );
182
183         p = val->bv_val;
184
185         /* Ignore initial whitespace */
186         while ( isspace( *p++ ) ) {
187                 /* EMPTY */  ;
188         }
189
190         if( *p ) {
191                 ch_free( newval );
192                 return 1;
193         }
194
195         newval->bv_val = ch_strdup( p );
196         p = q = newval->bv_val;
197
198         while ( *p ) {
199                 if ( isspace( *p ) ) {
200                         *q++ = *p++;
201
202                         /* Ignore the extra whitespace */
203                         while ( isspace( *p++ ) ) {
204                                 /* EMPTY */  ;
205                         }
206                 } else {
207                         *q++ = *p++;
208                 }
209         }
210
211         assert( *newval->bv_val );
212         assert( newval->bv_val < p );
213         assert( p <= q );
214
215         /* cannot start with a space */
216         assert( !isspace(*newval->bv_val) );
217
218         /*
219          * If the string ended in space, backup the pointer one
220          * position.  One is enough because the above loop collapsed
221          * all whitespace to a single space.
222          */
223
224         if ( isspace( q[-1] ) ) {
225                 --q;
226         }
227
228         /* cannot end with a space */
229         assert( !isspace( q[-1] ) );
230
231         /* null terminate */
232         *q = '\0';
233
234         newval->bv_len = q - newval->bv_val;
235         normalized = &newval;
236
237         return 0;
238 }
239
240 static int
241 caseExactIA5Match(
242         unsigned use,
243         Syntax *syntax,
244         MatchingRule *mr,
245         struct berval *value,
246         void *assertedValue )
247 {
248         return strcmp( value->bv_val,
249                 ((struct berval *) assertedValue)->bv_val );
250 }
251
252 static int
253 caseIgnoreIA5Match(
254         unsigned use,
255         Syntax *syntax,
256         MatchingRule *mr,
257         struct berval *value,
258         void *assertedValue )
259 {
260         return strcasecmp( value->bv_val,
261                 ((struct berval *) assertedValue)->bv_val );
262 }
263
264 struct syntax_defs_rec {
265         char *sd_desc;
266         int sd_flags;
267         slap_syntax_validate_func *sd_validate;
268         slap_syntax_transform_func *sd_ber2str;
269         slap_syntax_transform_func *sd_str2ber;
270 };
271
272 struct syntax_defs_rec syntax_defs[] = {
273         {"( 1.3.6.1.4.1.1466.115.121.1.3 DESC 'AttributeTypeDescription' )",
274                 0, NULL, NULL, NULL},
275         {"( 1.3.6.1.4.1.1466.115.121.1.4 DESC 'Audio' )",
276                 0, NULL, NULL, NULL},
277         {"( 1.3.6.1.4.1.1466.115.121.1.5 DESC 'Binary' )",
278                 SLAP_SYNTAX_BINARY,
279                 NULL, NULL, NULL},
280         {"( 1.3.6.1.4.1.1466.115.121.1.6 DESC 'BitString' )",
281                 0, NULL, NULL, NULL},
282         {"( 1.3.6.1.4.1.1466.115.121.1.7 DESC 'Boolean' )",
283                 0, NULL, NULL, NULL},
284         {"( 1.3.6.1.4.1.1466.115.121.1.8 DESC 'Certificate' )",
285                 SLAP_SYNTAX_BINARY,
286                 NULL, NULL, NULL},
287         {"( 1.3.6.1.4.1.1466.115.121.1.9 DESC 'CertificateList' )",
288                 SLAP_SYNTAX_BINARY,
289                 NULL, NULL, NULL},
290         {"( 1.3.6.1.4.1.1466.115.121.1.10 DESC 'CertificatePair' )",
291                 SLAP_SYNTAX_BINARY,
292                 NULL, NULL, NULL},
293         {"( 1.3.6.1.4.1.1466.115.121.1.12 DESC 'DN' )",
294                 0, NULL, NULL, NULL},
295         {"( 1.3.6.1.4.1.1466.115.121.1.14 DESC 'DeliveryMethod' )",
296                 0, NULL, NULL, NULL},
297         {"( 1.3.6.1.4.1.1466.115.121.1.15 DESC 'DirectoryString' )",
298                 0, UTF8StringValidate, NULL, NULL},
299         {"( 1.3.6.1.4.1.1466.115.121.1.16 DESC 'DITContentRuleDescription' )",
300                 0, NULL, NULL, NULL},
301         {"( 1.3.6.1.4.1.1466.115.121.1.17 DESC 'DITStructureRuleDescription' )",
302                 0, NULL, NULL, NULL},
303         {"( 1.3.6.1.4.1.1466.115.121.1.21 DESC 'EnhancedGuide' )",
304                 0, NULL, NULL, NULL},
305         {"( 1.3.6.1.4.1.1466.115.121.1.22 DESC 'FacsimileTelephoneNumber' )",
306                 0, NULL, NULL, NULL},
307         {"( 1.3.6.1.4.1.1466.115.121.1.24 DESC 'GeneralizedTime' )",
308                 0, NULL, NULL, NULL},
309         {"( 1.3.6.1.4.1.1466.115.121.1.25 DESC 'Guide' )",
310                 0, NULL, NULL, NULL},
311         {"( 1.3.6.1.4.1.1466.115.121.1.26 DESC 'IA5String' )",
312                 0, IA5StringValidate, NULL, NULL},
313         {"( 1.3.6.1.4.1.1466.115.121.1.27 DESC 'Integer' )",
314                 0, NULL, NULL, NULL},
315         {"( 1.3.6.1.4.1.1466.115.121.1.28 DESC 'JPEG' )",
316                 0, NULL, NULL, NULL},
317         {"( 1.3.6.1.4.1.1466.115.121.1.30 DESC 'MatchingRuleDescription' )",
318                 0, NULL, NULL, NULL},
319         {"( 1.3.6.1.4.1.1466.115.121.1.31 DESC 'MatchingRuleUseDescription' )",
320                 0, NULL, NULL, NULL},
321         {"( 1.3.6.1.4.1.1466.115.121.1.32 DESC 'MailPreference' )",
322                 0, NULL, NULL, NULL},
323         {"( 1.3.6.1.4.1.1466.115.121.1.34 DESC 'NameAndOptionalUID' )",
324                 0, NULL, NULL, NULL},
325         {"( 1.3.6.1.4.1.1466.115.121.1.35 DESC 'NameFormDescription' )",
326                 0, NULL, NULL, NULL},
327         {"( 1.3.6.1.4.1.1466.115.121.1.36 DESC 'NumericString' )",
328                 0, NULL, NULL, NULL},
329         {"( 1.3.6.1.4.1.1466.115.121.1.37 DESC 'ObjectClassDescription' )",
330                 0, NULL, NULL, NULL},
331         {"( 1.3.6.1.4.1.1466.115.121.1.38 DESC 'OID' )",
332                 0, NULL, NULL, NULL},
333         {"( 1.3.6.1.4.1.1466.115.121.1.39 DESC 'OtherMailbox' )",
334                 0, NULL, NULL, NULL},
335         {"( 1.3.6.1.4.1.1466.115.121.1.40 DESC 'OctetString' )",
336                 0, octetStringValidate, NULL, NULL},
337         {"( 1.3.6.1.4.1.1466.115.121.1.41 DESC 'PostalAddress' )",
338                 0, NULL, NULL, NULL},
339         {"( 1.3.6.1.4.1.1466.115.121.1.42 DESC 'ProtocolInformation' )",
340                 0, NULL, NULL, NULL},
341         {"( 1.3.6.1.4.1.1466.115.121.1.43 DESC 'PresentationAddress' )",
342                 0, NULL, NULL, NULL},
343         {"( 1.3.6.1.4.1.1466.115.121.1.44 DESC 'PrintableString' )",
344                 0, NULL, NULL, NULL},
345         {"( 1.3.6.1.4.1.1466.115.121.1.49 DESC 'SupportedAlgorithm' )",
346                 SLAP_SYNTAX_BINARY, NULL, NULL, NULL},
347         {"( 1.3.6.1.4.1.1466.115.121.1.50 DESC 'TelephoneNumber' )",
348                 0, NULL, NULL, NULL},
349         {"( 1.3.6.1.4.1.1466.115.121.1.51 DESC 'TeletexTerminalIdentifier' )",
350                 0, NULL, NULL, NULL},
351         {"( 1.3.6.1.4.1.1466.115.121.1.52 DESC 'TelexNumber' )",
352                 0, NULL, NULL, NULL},
353         {"( 1.3.6.1.4.1.1466.115.121.1.53 DESC 'UTCTime' )",
354                 0, NULL, NULL, NULL},
355         {"( 1.3.6.1.4.1.1466.115.121.1.54 DESC 'LDAPSyntaxDescription' )",
356                 0, NULL, NULL, NULL},
357         {"( 1.3.6.1.4.1.1466.115.121.1.58 DESC 'SubstringAssertion' )",
358                 0, NULL, NULL, NULL},
359
360         /* OpenLDAP Experimental Syntaxes */
361         {"( " SLAPD_OID_ACI_SYNTAX " DESC 'OpenLDAPexperimentalACI' )",
362                 0, NULL, NULL, NULL},
363
364         {NULL, 0, NULL, NULL, NULL}
365 };
366
367 struct mrule_defs_rec {
368         char *                                          mrd_desc;
369         unsigned                                        mrd_usage;
370         slap_mr_convert_func *          mrd_convert;
371         slap_mr_normalize_func *        mrd_normalize;
372         slap_mr_match_func *            mrd_match;
373         slap_mr_indexer_func *          mrd_indexer;
374         slap_mr_filter_func *           mrd_filter;
375 };
376
377 /*
378  * Other matching rules in X.520 that we do not use:
379  *
380  * 2.5.13.9             numericStringOrderingMatch
381  * 2.5.13.12    caseIgnoreListSubstringsMatch
382  * 2.5.13.13    booleanMatch
383  * 2.5.13.15    integerOrderingMatch
384  * 2.5.13.18    octetStringOrderingMatch
385  * 2.5.13.19    octetStringSubstringsMatch
386  * 2.5.13.25    uTCTimeMatch
387  * 2.5.13.26    uTCTimeOrderingMatch
388  * 2.5.13.31    directoryStringFirstComponentMatch
389  * 2.5.13.32    wordMatch
390  * 2.5.13.33    keywordMatch
391  * 2.5.13.34    certificateExactMatch
392  * 2.5.13.35    certificateMatch
393  * 2.5.13.36    certificatePairExactMatch
394  * 2.5.13.37    certificatePairMatch
395  * 2.5.13.38    certificateListExactMatch
396  * 2.5.13.39    certificateListMatch
397  * 2.5.13.40    algorithmIdentifierMatch
398  * 2.5.13.41    storedPrefixMatch
399  * 2.5.13.42    attributeCertificateMatch
400  * 2.5.13.43    readerAndKeyIDMatch
401  * 2.5.13.44    attributeIntegrityMatch
402  */
403
404 /* recycled matching functions */
405 #define caseIgnoreMatch caseIgnoreIA5Match
406 #define caseExactMatch caseExactIA5Match
407
408 /* unimplemented matching functions */
409 #define objectIdentifierMatch NULL
410 #define distinguishedNameMatch NULL
411 #define caseIgnoreOrderingMatch NULL
412 #define caseIgnoreSubstringsMatch NULL
413 #define caseExactOrderingMatch NULL
414 #define caseExactSubstringsMatch NULL
415 #define numericStringMatch NULL
416 #define numericStringSubstringsMatch NULL
417 #define caseIgnoreListMatch NULL
418 #define integerMatch NULL
419 #define bitStringMatch NULL
420 #define octetStringMatch NULL
421 #define telephoneNumberMatch NULL
422 #define telephoneNumberSubstringsMatch NULL
423 #define presentationAddressMatch NULL
424 #define uniqueMemberMatch NULL
425 #define protocolInformationMatch NULL
426 #define generalizedTimeMatch NULL
427 #define generalizedTimeOrderingMatch NULL
428 #define integerFirstComponentMatch NULL
429 #define objectIdentifierFirstComponentMatch NULL
430 #define caseIgnoreIA5SubstringsMatch NULL
431
432 struct mrule_defs_rec mrule_defs[] = {
433         {"( 2.5.13.0 NAME 'objectIdentifierMatch' "
434                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
435                 SLAP_MR_EQUALITY | SLAP_MR_EXT,
436                 NULL, NULL, objectIdentifierMatch, NULL, NULL},
437
438         {"( 2.5.13.1 NAME 'distinguishedNameMatch' "
439                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )",
440                 SLAP_MR_EQUALITY | SLAP_MR_EXT,
441                 NULL, NULL, distinguishedNameMatch, NULL, NULL},
442
443         {"( 2.5.13.2 NAME 'caseIgnoreMatch' "
444                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
445                 SLAP_MR_EQUALITY | SLAP_MR_EXT,
446                 NULL, UTF8StringNormalize, caseIgnoreMatch, NULL, NULL},
447
448         {"( 2.5.13.3 NAME 'caseIgnoreOrderingMatch' "
449                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
450                 SLAP_MR_ORDERING,
451                 NULL, UTF8StringNormalize, caseIgnoreOrderingMatch, NULL, NULL},
452
453         {"( 2.5.13.4 NAME 'caseIgnoreSubstringsMatch' "
454                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
455                 SLAP_MR_SUBSTR | SLAP_MR_EXT,
456                 NULL, UTF8StringNormalize, caseIgnoreSubstringsMatch, NULL, NULL},
457
458         /* Next three are not in the RFC's, but are needed for compatibility */
459         {"( 2.5.13.5 NAME 'caseExactMatch' "
460                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
461                 SLAP_MR_EQUALITY | SLAP_MR_EXT,
462                 NULL, UTF8StringNormalize, caseExactMatch, NULL, NULL},
463
464         {"( 2.5.13.6 NAME 'caseExactOrderingMatch' "
465                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
466                 SLAP_MR_ORDERING,
467                 NULL, UTF8StringNormalize, caseExactOrderingMatch, NULL, NULL},
468
469         {"( 2.5.13.7 NAME 'caseExactSubstringsMatch' "
470                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
471                 SLAP_MR_SUBSTR | SLAP_MR_EXT,
472                 NULL, UTF8StringNormalize, caseExactSubstringsMatch, NULL, NULL},
473
474         {"( 2.5.13.8 NAME 'numericStringMatch' "
475                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 )",
476                 SLAP_MR_EQUALITY | SLAP_MR_EXT,
477                 NULL, NULL, numericStringMatch, NULL, NULL},
478
479         {"( 2.5.13.10 NAME 'numericStringSubstringsMatch' "
480                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
481                 SLAP_MR_SUBSTR | SLAP_MR_EXT,
482                 NULL, NULL, numericStringSubstringsMatch, NULL, NULL},
483
484         {"( 2.5.13.11 NAME 'caseIgnoreListMatch' "
485                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )",
486                 SLAP_MR_EQUALITY | SLAP_MR_EXT,
487                 NULL, NULL, caseIgnoreListMatch, NULL, NULL},
488
489         {"( 2.5.13.14 NAME 'integerMatch' "
490                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
491                 SLAP_MR_NONE | SLAP_MR_EXT,
492                 NULL, NULL, integerMatch, NULL, NULL},
493
494         {"( 2.5.13.16 NAME 'bitStringMatch' "
495                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.6 )",
496                 SLAP_MR_NONE | SLAP_MR_EXT,
497                 NULL, NULL, bitStringMatch, NULL, NULL},
498
499         {"( 2.5.13.17 NAME 'octetStringMatch' "
500                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
501                 SLAP_MR_EQUALITY | SLAP_MR_EXT,
502                 NULL, NULL, octetStringMatch, NULL, NULL},
503
504         {"( 2.5.13.20 NAME 'telephoneNumberMatch' "
505                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 )",
506                 SLAP_MR_EQUALITY | SLAP_MR_EXT,
507                 NULL, NULL, telephoneNumberMatch, NULL, NULL},
508
509         {"( 2.5.13.21 NAME 'telephoneNumberSubstringsMatch' "
510                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
511                 SLAP_MR_SUBSTR | SLAP_MR_EXT,
512                 NULL, NULL, telephoneNumberSubstringsMatch, NULL, NULL},
513
514         {"( 2.5.13.22 NAME 'presentationAddressMatch' "
515                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.43 )",
516                 SLAP_MR_NONE | SLAP_MR_EXT,
517                 NULL, NULL, presentationAddressMatch, NULL, NULL},
518
519         {"( 2.5.13.23 NAME 'uniqueMemberMatch' "
520                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.34 )",
521                 SLAP_MR_NONE | SLAP_MR_EXT,
522                 NULL, NULL, uniqueMemberMatch, NULL, NULL},
523
524         {"( 2.5.13.24 NAME 'protocolInformationMatch' "
525                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.42 )",
526                 SLAP_MR_NONE | SLAP_MR_EXT,
527                 NULL, NULL, protocolInformationMatch, NULL, NULL},
528
529         {"( 2.5.13.27 NAME 'generalizedTimeMatch' "
530                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
531                 SLAP_MR_EQUALITY | SLAP_MR_EXT,
532                 NULL, NULL, generalizedTimeMatch, NULL, NULL},
533
534         {"( 2.5.13.28 NAME 'generalizedTimeOrderingMatch' "
535                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
536                 SLAP_MR_ORDERING,
537                 NULL, NULL, generalizedTimeOrderingMatch, NULL, NULL},
538
539         {"( 2.5.13.29 NAME 'integerFirstComponentMatch' "
540                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
541                 SLAP_MR_EQUALITY | SLAP_MR_EXT,
542                 NULL, NULL, integerFirstComponentMatch, NULL, NULL},
543
544         {"( 2.5.13.30 NAME 'objectIdentifierFirstComponentMatch' "
545                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
546                 SLAP_MR_EQUALITY | SLAP_MR_EXT,
547                 NULL, NULL, objectIdentifierFirstComponentMatch, NULL, NULL},
548
549         {"( 1.3.6.1.4.1.1466.109.114.1 NAME 'caseExactIA5Match' "
550                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
551                 SLAP_MR_EQUALITY | SLAP_MR_EXT,
552                 NULL, IA5StringNormalize, caseExactIA5Match, NULL, NULL},
553
554         {"( 1.3.6.1.4.1.1466.109.114.2 NAME 'caseIgnoreIA5Match' "
555                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
556                 SLAP_MR_EQUALITY | SLAP_MR_EXT,
557                 NULL, IA5StringNormalize, caseIgnoreIA5Match, NULL, NULL},
558
559         {"( 1.3.6.1.4.1.1466.109.114.3 NAME 'caseIgnoreIA5SubstringsMatch' "
560                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
561                 SLAP_MR_SUBSTR,
562                 NULL, IA5StringNormalize, caseIgnoreIA5SubstringsMatch, NULL, NULL},
563
564         {NULL, SLAP_MR_NONE, NULL, NULL, NULL}
565 };
566
567 static int schema_init_done = 0;
568
569 int
570 schema_init( void )
571 {
572         int             res;
573         int             i;
574
575         /* we should only be called once (from main) */
576         assert( schema_init_done == 0 );
577
578         for ( i=0; syntax_defs[i].sd_desc != NULL; i++ ) {
579                 res = register_syntax( syntax_defs[i].sd_desc,
580                     syntax_defs[i].sd_flags,
581                     syntax_defs[i].sd_validate,
582                     syntax_defs[i].sd_ber2str,
583                         syntax_defs[i].sd_str2ber );
584
585                 if ( res ) {
586                         fprintf( stderr, "schema_init: Error registering syntax %s\n",
587                                  syntax_defs[i].sd_desc );
588                         return -1;
589                 }
590         }
591
592         for ( i=0; mrule_defs[i].mrd_desc != NULL; i++ ) {
593                 if( mrule_defs[i].mrd_usage == SLAP_MR_NONE ) {
594                         fprintf( stderr,
595                                 "schema_init: Ingoring unusable matching rule %s\n",
596                                  mrule_defs[i].mrd_desc );
597                         continue;
598                 }
599
600                 res = register_matching_rule(
601                         mrule_defs[i].mrd_desc,
602                         mrule_defs[i].mrd_usage,
603                         mrule_defs[i].mrd_convert,
604                         mrule_defs[i].mrd_normalize,
605                     mrule_defs[i].mrd_match,
606                         mrule_defs[i].mrd_indexer,
607                         mrule_defs[i].mrd_filter );
608
609                 if ( res ) {
610                         fprintf( stderr,
611                                 "schema_init: Error registering matching rule %s\n",
612                                  mrule_defs[i].mrd_desc );
613                         return -1;
614                 }
615         }
616         schema_init_done = 1;
617         return( 0 );
618 }
619
620 #ifdef SLAPD_SCHEMA_NOT_COMPAT
621 struct slap_internal_schema slap_schema;
622
623 struct slap_schema_ad_map {
624         char *ssm_type;
625         size_t ssm_offset;
626 } ad_map[]  = {
627         { "objectClass",
628                 offsetof(struct slap_internal_schema, si_ad_objectClass) },
629
630         { "creatorsName",
631                 offsetof(struct slap_internal_schema, si_ad_creatorsName) },
632         { "createTimestamp",
633                 offsetof(struct slap_internal_schema, si_ad_createTimestamp) },
634         { "modifiersName",
635                 offsetof(struct slap_internal_schema, si_ad_modifiersName) },
636         { "modifyTimestamp",
637                 offsetof(struct slap_internal_schema, si_ad_modifyTimestamp) },
638         { "namingContexts",
639                 offsetof(struct slap_internal_schema, si_ad_namingContexts) },
640         { "supportedControl",
641                 offsetof(struct slap_internal_schema, si_ad_supportedControl) },
642         { "supportedExtension",
643                 offsetof(struct slap_internal_schema, si_ad_supportedExtension) },
644         { "supportedLDAPVersion",
645                 offsetof(struct slap_internal_schema, si_ad_supportedLDAPVersion) },
646         { "supportedSASLMechanisms",
647                 offsetof(struct slap_internal_schema, si_ad_supportedSASLMechanisms) },
648
649         { "ref",
650                 offsetof(struct slap_internal_schema, si_ad_ref) },
651
652         { "entry",
653                 offsetof(struct slap_internal_schema, si_ad_entry) },
654         { "children",
655                 offsetof(struct slap_internal_schema, si_ad_children) },
656         { NULL, NULL }
657 };
658
659 #endif
660
661 int
662 schema_prep( void )
663 {
664 #ifdef SLAPD_SCHEMA_NOT_COMPAT
665         int i;
666         char *text;
667 #endif
668         /* we should only be called once after schema_init() was called */
669         assert( schema_init_done == 1 );
670
671 #ifdef SLAPD_SCHEMA_NOT_COMPAT
672         for( i=0; ad_map[i].ssm_type; i++ ) {
673                 int rc = slap_str2ad( ad_map[i].ssm_type,
674                         (AttributeDescription **)
675                                 &(((char *) &slap_schema)[ad_map[i].ssm_offset]),
676                         &text);
677
678                 if( rc != LDAP_SUCCESS ) {
679                         fprintf( stderr,
680                                 "No attribute \"%s\" defined in schema\n",
681                                 ad_map[i].ssm_type );
682                         return rc;
683                 }
684         }
685 #endif
686
687         ++schema_init_done;
688         return 0;
689 }