]> git.sur5r.net Git - openldap/blob - servers/slapd/schema_init.c
Update pilot schema based upon asid ldapv3-attributes I-D.
[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.13 DESC 'DataQuality' )",
296                 0, NULL, NULL, NULL},
297         {"( 1.3.6.1.4.1.1466.115.121.1.14 DESC 'DeliveryMethod' )",
298                 0, NULL, NULL, NULL},
299         {"( 1.3.6.1.4.1.1466.115.121.1.15 DESC 'DirectoryString' )",
300                 0, UTF8StringValidate, NULL, NULL},
301         {"( 1.3.6.1.4.1.1466.115.121.1.16 DESC 'DITContentRuleDescription' )",
302                 0, NULL, NULL, NULL},
303         {"( 1.3.6.1.4.1.1466.115.121.1.17 DESC 'DITStructureRuleDescription' )",
304                 0, NULL, NULL, NULL},
305         {"( 1.3.6.1.4.1.1466.115.121.1.19 DESC 'DSAQuality' )",
306                 0, NULL, NULL, NULL},
307         {"( 1.3.6.1.4.1.1466.115.121.1.21 DESC 'EnhancedGuide' )",
308                 0, NULL, NULL, NULL},
309         {"( 1.3.6.1.4.1.1466.115.121.1.22 DESC 'FacsimileTelephoneNumber' )",
310                 0, NULL, NULL, NULL},
311         {"( 1.3.6.1.4.1.1466.115.121.1.23 DESC 'Fax' )",
312                 0, NULL, NULL, NULL},
313         {"( 1.3.6.1.4.1.1466.115.121.1.24 DESC 'GeneralizedTime' )",
314                 0, NULL, NULL, NULL},
315         {"( 1.3.6.1.4.1.1466.115.121.1.25 DESC 'Guide' )",
316                 0, NULL, NULL, NULL},
317         {"( 1.3.6.1.4.1.1466.115.121.1.26 DESC 'IA5String' )",
318                 0, IA5StringValidate, NULL, NULL},
319         {"( 1.3.6.1.4.1.1466.115.121.1.27 DESC 'Integer' )",
320                 0, NULL, NULL, NULL},
321         {"( 1.3.6.1.4.1.1466.115.121.1.28 DESC 'JPEG' )",
322                 0, NULL, NULL, NULL},
323         {"( 1.3.6.1.4.1.1466.115.121.1.30 DESC 'MatchingRuleDescription' )",
324                 0, NULL, NULL, NULL},
325         {"( 1.3.6.1.4.1.1466.115.121.1.31 DESC 'MatchingRuleUseDescription' )",
326                 0, NULL, NULL, NULL},
327         {"( 1.3.6.1.4.1.1466.115.121.1.32 DESC 'MailPreference' )",
328                 0, NULL, NULL, NULL},
329         {"( 1.3.6.1.4.1.1466.115.121.1.34 DESC 'NameAndOptionalUID' )",
330                 0, NULL, NULL, NULL},
331         {"( 1.3.6.1.4.1.1466.115.121.1.35 DESC 'NameFormDescription' )",
332                 0, NULL, NULL, NULL},
333         {"( 1.3.6.1.4.1.1466.115.121.1.36 DESC 'NumericString' )",
334                 0, NULL, NULL, NULL},
335         {"( 1.3.6.1.4.1.1466.115.121.1.37 DESC 'ObjectClassDescription' )",
336                 0, NULL, NULL, NULL},
337         {"( 1.3.6.1.4.1.1466.115.121.1.38 DESC 'OID' )",
338                 0, NULL, NULL, NULL},
339         {"( 1.3.6.1.4.1.1466.115.121.1.39 DESC 'OtherMailbox' )",
340                 0, NULL, NULL, NULL},
341         {"( 1.3.6.1.4.1.1466.115.121.1.40 DESC 'OctetString' )",
342                 0, octetStringValidate, NULL, NULL},
343         {"( 1.3.6.1.4.1.1466.115.121.1.41 DESC 'PostalAddress' )",
344                 0, NULL, NULL, NULL},
345         {"( 1.3.6.1.4.1.1466.115.121.1.42 DESC 'ProtocolInformation' )",
346                 0, NULL, NULL, NULL},
347         {"( 1.3.6.1.4.1.1466.115.121.1.43 DESC 'PresentationAddress' )",
348                 0, NULL, NULL, NULL},
349         {"( 1.3.6.1.4.1.1466.115.121.1.44 DESC 'PrintableString' )",
350                 0, NULL, NULL, NULL},
351         {"( 1.3.6.1.4.1.1466.115.121.1.49 DESC 'SupportedAlgorithm' )",
352                 SLAP_SYNTAX_BINARY, NULL, NULL, NULL},
353         {"( 1.3.6.1.4.1.1466.115.121.1.50 DESC 'TelephoneNumber' )",
354                 0, NULL, NULL, NULL},
355         {"( 1.3.6.1.4.1.1466.115.121.1.51 DESC 'TeletexTerminalIdentifier' )",
356                 0, NULL, NULL, NULL},
357         {"( 1.3.6.1.4.1.1466.115.121.1.52 DESC 'TelexNumber' )",
358                 0, NULL, NULL, NULL},
359         {"( 1.3.6.1.4.1.1466.115.121.1.53 DESC 'UTCTime' )",
360                 0, NULL, NULL, NULL},
361         {"( 1.3.6.1.4.1.1466.115.121.1.54 DESC 'LDAPSyntaxDescription' )",
362                 0, NULL, NULL, NULL},
363         {"( 1.3.6.1.4.1.1466.115.121.1.58 DESC 'SubstringAssertion' )",
364                 0, NULL, NULL, NULL},
365
366         /* OpenLDAP Experimental Syntaxes */
367         {"( " SLAPD_OID_ACI_SYNTAX " DESC 'OpenLDAPexperimentalACI' )",
368                 0, NULL, NULL, NULL},
369
370         {NULL, 0, NULL, NULL, NULL}
371 };
372
373 struct mrule_defs_rec {
374         char *                                          mrd_desc;
375         unsigned                                        mrd_usage;
376         slap_mr_convert_func *          mrd_convert;
377         slap_mr_normalize_func *        mrd_normalize;
378         slap_mr_match_func *            mrd_match;
379         slap_mr_indexer_func *          mrd_indexer;
380         slap_mr_filter_func *           mrd_filter;
381 };
382
383 /*
384  * Other matching rules in X.520 that we do not use:
385  *
386  * 2.5.13.9             numericStringOrderingMatch
387  * 2.5.13.13    booleanMatch
388  * 2.5.13.15    integerOrderingMatch
389  * 2.5.13.18    octetStringOrderingMatch
390  * 2.5.13.19    octetStringSubstringsMatch
391  * 2.5.13.25    uTCTimeMatch
392  * 2.5.13.26    uTCTimeOrderingMatch
393  * 2.5.13.31    directoryStringFirstComponentMatch
394  * 2.5.13.32    wordMatch
395  * 2.5.13.33    keywordMatch
396  * 2.5.13.34    certificateExactMatch
397  * 2.5.13.35    certificateMatch
398  * 2.5.13.36    certificatePairExactMatch
399  * 2.5.13.37    certificatePairMatch
400  * 2.5.13.38    certificateListExactMatch
401  * 2.5.13.39    certificateListMatch
402  * 2.5.13.40    algorithmIdentifierMatch
403  * 2.5.13.41    storedPrefixMatch
404  * 2.5.13.42    attributeCertificateMatch
405  * 2.5.13.43    readerAndKeyIDMatch
406  * 2.5.13.44    attributeIntegrityMatch
407  */
408
409 /* recycled matching functions */
410 #define caseIgnoreMatch caseIgnoreIA5Match
411 #define caseExactMatch caseExactIA5Match
412
413 /* unimplemented matching functions */
414 #define objectIdentifierMatch NULL
415 #define distinguishedNameMatch NULL
416 #define caseIgnoreOrderingMatch NULL
417 #define caseIgnoreSubstringsMatch NULL
418 #define caseExactOrderingMatch NULL
419 #define caseExactSubstringsMatch NULL
420 #define numericStringMatch NULL
421 #define numericStringSubstringsMatch NULL
422 #define caseIgnoreListMatch NULL
423 #define caseIgnoreListSubstringsMatch NULL
424 #define integerMatch NULL
425 #define bitStringMatch NULL
426 #define octetStringMatch NULL
427 #define telephoneNumberMatch NULL
428 #define telephoneNumberSubstringsMatch NULL
429 #define presentationAddressMatch NULL
430 #define uniqueMemberMatch NULL
431 #define protocolInformationMatch NULL
432 #define generalizedTimeMatch NULL
433 #define generalizedTimeOrderingMatch NULL
434 #define integerFirstComponentMatch NULL
435 #define objectIdentifierFirstComponentMatch NULL
436 #define caseIgnoreIA5SubstringsMatch NULL
437
438 struct mrule_defs_rec mrule_defs[] = {
439         {"( 2.5.13.0 NAME 'objectIdentifierMatch' "
440                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
441                 SLAP_MR_EQUALITY | SLAP_MR_EXT,
442                 NULL, NULL, objectIdentifierMatch, NULL, NULL},
443
444         {"( 2.5.13.1 NAME 'distinguishedNameMatch' "
445                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )",
446                 SLAP_MR_EQUALITY | SLAP_MR_EXT,
447                 NULL, NULL, distinguishedNameMatch, NULL, NULL},
448
449         {"( 2.5.13.2 NAME 'caseIgnoreMatch' "
450                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
451                 SLAP_MR_EQUALITY | SLAP_MR_EXT,
452                 NULL, UTF8StringNormalize, caseIgnoreMatch, NULL, NULL},
453
454         {"( 2.5.13.3 NAME 'caseIgnoreOrderingMatch' "
455                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
456                 SLAP_MR_ORDERING,
457                 NULL, UTF8StringNormalize, caseIgnoreOrderingMatch, NULL, NULL},
458
459         {"( 2.5.13.4 NAME 'caseIgnoreSubstringsMatch' "
460                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
461                 SLAP_MR_SUBSTR | SLAP_MR_EXT,
462                 NULL, UTF8StringNormalize, caseIgnoreSubstringsMatch, NULL, NULL},
463
464         /* Next three are not in the RFC's, but are needed for compatibility */
465         {"( 2.5.13.5 NAME 'caseExactMatch' "
466                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
467                 SLAP_MR_EQUALITY | SLAP_MR_EXT,
468                 NULL, UTF8StringNormalize, caseExactMatch, NULL, NULL},
469
470         {"( 2.5.13.6 NAME 'caseExactOrderingMatch' "
471                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
472                 SLAP_MR_ORDERING,
473                 NULL, UTF8StringNormalize, caseExactOrderingMatch, NULL, NULL},
474
475         {"( 2.5.13.7 NAME 'caseExactSubstringsMatch' "
476                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
477                 SLAP_MR_SUBSTR | SLAP_MR_EXT,
478                 NULL, UTF8StringNormalize, caseExactSubstringsMatch, NULL, NULL},
479
480         {"( 2.5.13.8 NAME 'numericStringMatch' "
481                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 )",
482                 SLAP_MR_EQUALITY | SLAP_MR_EXT,
483                 NULL, NULL, numericStringMatch, NULL, NULL},
484
485         {"( 2.5.13.10 NAME 'numericStringSubstringsMatch' "
486                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
487                 SLAP_MR_SUBSTR | SLAP_MR_EXT,
488                 NULL, NULL, numericStringSubstringsMatch, NULL, NULL},
489
490         {"( 2.5.13.11 NAME 'caseIgnoreListMatch' "
491                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )",
492                 SLAP_MR_EQUALITY | SLAP_MR_EXT,
493                 NULL, NULL, caseIgnoreListMatch, NULL, NULL},
494
495         {"( 2.5.13.12 NAME 'caseIgnoreListSubstringsMatch' "
496                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
497                 SLAP_MR_SUBSTR | SLAP_MR_EXT,
498                 NULL, NULL, caseIgnoreListSubstringsMatch, NULL, NULL},
499
500         {"( 2.5.13.14 NAME 'integerMatch' "
501                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
502                 SLAP_MR_NONE | SLAP_MR_EXT,
503                 NULL, NULL, integerMatch, NULL, NULL},
504
505         {"( 2.5.13.16 NAME 'bitStringMatch' "
506                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.6 )",
507                 SLAP_MR_NONE | SLAP_MR_EXT,
508                 NULL, NULL, bitStringMatch, NULL, NULL},
509
510         {"( 2.5.13.17 NAME 'octetStringMatch' "
511                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
512                 SLAP_MR_EQUALITY | SLAP_MR_EXT,
513                 NULL, NULL, octetStringMatch, NULL, NULL},
514
515         {"( 2.5.13.20 NAME 'telephoneNumberMatch' "
516                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 )",
517                 SLAP_MR_EQUALITY | SLAP_MR_EXT,
518                 NULL, NULL, telephoneNumberMatch, NULL, NULL},
519
520         {"( 2.5.13.21 NAME 'telephoneNumberSubstringsMatch' "
521                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
522                 SLAP_MR_SUBSTR | SLAP_MR_EXT,
523                 NULL, NULL, telephoneNumberSubstringsMatch, NULL, NULL},
524
525         {"( 2.5.13.22 NAME 'presentationAddressMatch' "
526                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.43 )",
527                 SLAP_MR_NONE | SLAP_MR_EXT,
528                 NULL, NULL, presentationAddressMatch, NULL, NULL},
529
530         {"( 2.5.13.23 NAME 'uniqueMemberMatch' "
531                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.34 )",
532                 SLAP_MR_NONE | SLAP_MR_EXT,
533                 NULL, NULL, uniqueMemberMatch, NULL, NULL},
534
535         {"( 2.5.13.24 NAME 'protocolInformationMatch' "
536                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.42 )",
537                 SLAP_MR_NONE | SLAP_MR_EXT,
538                 NULL, NULL, protocolInformationMatch, NULL, NULL},
539
540         {"( 2.5.13.27 NAME 'generalizedTimeMatch' "
541                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
542                 SLAP_MR_EQUALITY | SLAP_MR_EXT,
543                 NULL, NULL, generalizedTimeMatch, NULL, NULL},
544
545         {"( 2.5.13.28 NAME 'generalizedTimeOrderingMatch' "
546                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
547                 SLAP_MR_ORDERING,
548                 NULL, NULL, generalizedTimeOrderingMatch, NULL, NULL},
549
550         {"( 2.5.13.29 NAME 'integerFirstComponentMatch' "
551                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
552                 SLAP_MR_EQUALITY | SLAP_MR_EXT,
553                 NULL, NULL, integerFirstComponentMatch, NULL, NULL},
554
555         {"( 2.5.13.30 NAME 'objectIdentifierFirstComponentMatch' "
556                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
557                 SLAP_MR_EQUALITY | SLAP_MR_EXT,
558                 NULL, NULL, objectIdentifierFirstComponentMatch, NULL, NULL},
559
560         {"( 1.3.6.1.4.1.1466.109.114.1 NAME 'caseExactIA5Match' "
561                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
562                 SLAP_MR_EQUALITY | SLAP_MR_EXT,
563                 NULL, IA5StringNormalize, caseExactIA5Match, NULL, NULL},
564
565         {"( 1.3.6.1.4.1.1466.109.114.2 NAME 'caseIgnoreIA5Match' "
566                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
567                 SLAP_MR_EQUALITY | SLAP_MR_EXT,
568                 NULL, IA5StringNormalize, caseIgnoreIA5Match, NULL, NULL},
569
570         {"( 1.3.6.1.4.1.1466.109.114.3 NAME 'caseIgnoreIA5SubstringsMatch' "
571                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
572                 SLAP_MR_SUBSTR,
573                 NULL, IA5StringNormalize, caseIgnoreIA5SubstringsMatch, NULL, NULL},
574
575         {NULL, SLAP_MR_NONE, NULL, NULL, NULL}
576 };
577
578 static int schema_init_done = 0;
579
580 int
581 schema_init( void )
582 {
583         int             res;
584         int             i;
585
586         /* we should only be called once (from main) */
587         assert( schema_init_done == 0 );
588
589         for ( i=0; syntax_defs[i].sd_desc != NULL; i++ ) {
590                 res = register_syntax( syntax_defs[i].sd_desc,
591                     syntax_defs[i].sd_flags,
592                     syntax_defs[i].sd_validate,
593                     syntax_defs[i].sd_ber2str,
594                         syntax_defs[i].sd_str2ber );
595
596                 if ( res ) {
597                         fprintf( stderr, "schema_init: Error registering syntax %s\n",
598                                  syntax_defs[i].sd_desc );
599                         return -1;
600                 }
601         }
602
603         for ( i=0; mrule_defs[i].mrd_desc != NULL; i++ ) {
604                 if( mrule_defs[i].mrd_usage == SLAP_MR_NONE ) {
605                         fprintf( stderr,
606                                 "schema_init: Ingoring unusable matching rule %s\n",
607                                  mrule_defs[i].mrd_desc );
608                         continue;
609                 }
610
611                 res = register_matching_rule(
612                         mrule_defs[i].mrd_desc,
613                         mrule_defs[i].mrd_usage,
614                         mrule_defs[i].mrd_convert,
615                         mrule_defs[i].mrd_normalize,
616                     mrule_defs[i].mrd_match,
617                         mrule_defs[i].mrd_indexer,
618                         mrule_defs[i].mrd_filter );
619
620                 if ( res ) {
621                         fprintf( stderr,
622                                 "schema_init: Error registering matching rule %s\n",
623                                  mrule_defs[i].mrd_desc );
624                         return -1;
625                 }
626         }
627         schema_init_done = 1;
628         return( 0 );
629 }
630
631 #ifdef SLAPD_SCHEMA_NOT_COMPAT
632 struct slap_internal_schema slap_schema;
633
634 struct slap_schema_ad_map {
635         char *ssm_type;
636         size_t ssm_offset;
637 } ad_map[]  = {
638         { "objectClass",
639                 offsetof(struct slap_internal_schema, si_ad_objectClass) },
640
641         { "creatorsName",
642                 offsetof(struct slap_internal_schema, si_ad_creatorsName) },
643         { "createTimestamp",
644                 offsetof(struct slap_internal_schema, si_ad_createTimestamp) },
645         { "modifiersName",
646                 offsetof(struct slap_internal_schema, si_ad_modifiersName) },
647         { "modifyTimestamp",
648                 offsetof(struct slap_internal_schema, si_ad_modifyTimestamp) },
649
650         { "subschemaSubentry",
651                 offsetof(struct slap_internal_schema, si_ad_subschemaSubentry) },
652
653         { "namingContexts",
654                 offsetof(struct slap_internal_schema, si_ad_namingContexts) },
655         { "supportedControl",
656                 offsetof(struct slap_internal_schema, si_ad_supportedControl) },
657         { "supportedExtension",
658                 offsetof(struct slap_internal_schema, si_ad_supportedExtension) },
659         { "supportedLDAPVersion",
660                 offsetof(struct slap_internal_schema, si_ad_supportedLDAPVersion) },
661         { "supportedSASLMechanisms",
662                 offsetof(struct slap_internal_schema, si_ad_supportedSASLMechanisms) },
663
664         { "attributeTypes",
665                 offsetof(struct slap_internal_schema, si_ad_attributeTypes) },
666         { "ldapSyntaxes",
667                 offsetof(struct slap_internal_schema, si_ad_ldapSyntaxes) },
668         { "matchingRules",
669                 offsetof(struct slap_internal_schema, si_ad_matchingRules) },
670         { "objectClasses",
671                 offsetof(struct slap_internal_schema, si_ad_objectClasses) },
672
673         { "ref",
674                 offsetof(struct slap_internal_schema, si_ad_ref) },
675
676         { "entry",
677                 offsetof(struct slap_internal_schema, si_ad_entry) },
678         { "children",
679                 offsetof(struct slap_internal_schema, si_ad_children) },
680         { NULL, 0 }
681 };
682
683 #endif
684
685 int
686 schema_prep( void )
687 {
688 #ifdef SLAPD_SCHEMA_NOT_COMPAT
689         int i;
690         char *text;
691 #endif
692         /* we should only be called once after schema_init() was called */
693         assert( schema_init_done == 1 );
694
695 #ifdef SLAPD_SCHEMA_NOT_COMPAT
696         for( i=0; ad_map[i].ssm_type; i++ ) {
697                 int rc;
698
699                 AttributeDescription ** adp = (AttributeDescription **)
700                         &(((char *) &slap_schema)[ad_map[i].ssm_offset]);
701
702                 *adp = NULL;
703
704                 rc = slap_str2ad( ad_map[i].ssm_type, adp, &text );
705
706                 if( rc != LDAP_SUCCESS ) {
707                         fprintf( stderr,
708                                 "No attribute \"%s\" defined in schema\n",
709                                 ad_map[i].ssm_type );
710                         return rc;
711                 }
712         }
713 #endif
714
715         ++schema_init_done;
716         return 0;
717 }