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