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