]> git.sur5r.net Git - openldap/blob - servers/slapd/schema_init.c
Use experimental OID for ACI syntax. Likely need to add
[openldap] / servers / slapd / schema_init.c
1 /* schema_init.c - init builtin schema */
2 /* $OpenLDAP$ */
3 /*
4  * Copyright 1998-1999 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         Syntax *syntax,
57         MatchingRule *mr,
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 ) {
74                 ch_free( newval );
75                 return 1;
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 0;
130 }
131
132 static int
133 IA5StringValidate(
134         Syntax *syntax,
135         struct berval *val )
136 {
137         ber_len_t i;
138
139         for(i=0; i < val->bv_len; i++) {
140                 if( !isascii(val->bv_val[i]) ) return -1;
141         }
142
143         return 0;
144 }
145
146 static int
147 IA5StringConvert(
148         Syntax *syntax,
149         struct berval *in,
150         struct berval **out )
151 {
152         ber_len_t i;
153         struct berval *bv = ch_malloc( sizeof(struct berval) );
154         bv->bv_len = (in->bv_len+1) * sizeof( ldap_unicode_t );
155         bv->bv_val = ch_malloc( bv->bv_len );
156
157         for(i=0; i < in->bv_len; i++ ) {
158                 /*
159                  * IA5StringValidate should have been called to ensure
160                  * input is limited to IA5.
161                  */
162                 bv->bv_val[i] = in->bv_val[i];
163         }
164
165         *out = bv;
166         return 0;
167 }
168
169 static int
170 IA5StringNormalize(
171         Syntax *syntax,
172         MatchingRule *mr,
173         struct berval *val,
174         struct berval **normalized )
175 {
176         struct berval *newval;
177         char *p, *q;
178
179         newval = ch_malloc( sizeof( struct berval ) );
180
181         p = val->bv_val;
182
183         /* Ignore initial whitespace */
184         while ( isspace( *p++ ) ) {
185                 /* EMPTY */  ;
186         }
187
188         if( *p ) {
189                 ch_free( newval );
190                 return 1;
191         }
192
193         newval->bv_val = ch_strdup( p );
194         p = q = newval->bv_val;
195
196         while ( *p ) {
197                 if ( isspace( *p ) ) {
198                         *q++ = *p++;
199
200                         /* Ignore the extra whitespace */
201                         while ( isspace( *p++ ) ) {
202                                 /* EMPTY */  ;
203                         }
204                 } else {
205                         *q++ = *p++;
206                 }
207         }
208
209         assert( *newval->bv_val );
210         assert( newval->bv_val < p );
211         assert( p <= q );
212
213         /* cannot start with a space */
214         assert( !isspace(*newval->bv_val) );
215
216         /*
217          * If the string ended in space, backup the pointer one
218          * position.  One is enough because the above loop collapsed
219          * all whitespace to a single space.
220          */
221
222         if ( isspace( q[-1] ) ) {
223                 --q;
224         }
225
226         /* cannot end with a space */
227         assert( !isspace( q[-1] ) );
228
229         /* null terminate */
230         *q = '\0';
231
232         newval->bv_len = q - newval->bv_val;
233         normalized = &newval;
234
235         return 0;
236 }
237
238 static int
239 caseExactIA5Match(
240         Syntax *syntax,
241         MatchingRule *mr,
242         struct berval *value,
243         struct berval *assertedValue )
244 {
245         return strcmp( value->bv_val, assertedValue->bv_val );
246 }
247
248 static int
249 caseIgnoreIA5Match(
250         Syntax *syntax,
251         MatchingRule *mr,
252         struct berval *value,
253         struct berval *assertedValue )
254 {
255         return strcasecmp( value->bv_val, assertedValue->bv_val );
256 }
257
258 struct syntax_defs_rec {
259         char *sd_desc;
260         int sd_flags;
261         slap_syntax_validate_func *sd_validate;
262         slap_syntax_transform_func *sd_ber2str;
263         slap_syntax_transform_func *sd_str2ber;
264 };
265
266 struct syntax_defs_rec syntax_defs[] = {
267         {"( 1.3.6.1.4.1.1466.115.121.1.3 DESC 'AttributeTypeDescription' )",
268                 0, NULL, NULL, NULL},
269         {"( 1.3.6.1.4.1.1466.115.121.1.4 DESC 'Audio' )",
270                 0, NULL, NULL, NULL},
271         {"( 1.3.6.1.4.1.1466.115.121.1.5 DESC 'Binary' )",
272                 SLAP_SYNTAX_BINARY,
273                 NULL, NULL, NULL},
274         {"( 1.3.6.1.4.1.1466.115.121.1.6 DESC 'BitString' )",
275                 0, NULL, NULL, NULL},
276         {"( 1.3.6.1.4.1.1466.115.121.1.7 DESC 'Boolean' )",
277                 0, NULL, NULL, NULL},
278         {"( 1.3.6.1.4.1.1466.115.121.1.8 DESC 'Certificate' )",
279                 SLAP_SYNTAX_BINARY,
280                 NULL, NULL, NULL},
281         {"( 1.3.6.1.4.1.1466.115.121.1.9 DESC 'CertificateList' )",
282                 SLAP_SYNTAX_BINARY,
283                 NULL, NULL, NULL},
284         {"( 1.3.6.1.4.1.1466.115.121.1.10 DESC 'CertificatePair' )",
285                 SLAP_SYNTAX_BINARY,
286                 NULL, NULL, NULL},
287         {"( 1.3.6.1.4.1.1466.115.121.1.12 DESC 'DN' )",
288                 0, NULL, NULL, NULL},
289         {"( 1.3.6.1.4.1.1466.115.121.1.14 DESC 'DeliveryMethod' )",
290                 0, NULL, NULL, NULL},
291         {"( 1.3.6.1.4.1.1466.115.121.1.15 DESC 'DirectoryString' )",
292                 0, UTF8StringValidate, NULL, NULL},
293         {"( 1.3.6.1.4.1.1466.115.121.1.16 DESC 'DITContentRuleDescription' )",
294                 0, NULL, NULL, NULL},
295         {"( 1.3.6.1.4.1.1466.115.121.1.17 DESC 'DITStructureRuleDescription' )",
296                 0, NULL, NULL, NULL},
297         {"( 1.3.6.1.4.1.1466.115.121.1.21 DESC 'EnhancedGuide' )",
298                 0, NULL, NULL, NULL},
299         {"( 1.3.6.1.4.1.1466.115.121.1.22 DESC 'FacsimileTelephoneNumber' )",
300                 0, NULL, NULL, NULL},
301         {"( 1.3.6.1.4.1.1466.115.121.1.24 DESC 'GeneralizedTime' )",
302                 0, NULL, NULL, NULL},
303         {"( 1.3.6.1.4.1.1466.115.121.1.25 DESC 'Guide' )",
304                 0, NULL, NULL, NULL},
305         {"( 1.3.6.1.4.1.1466.115.121.1.26 DESC 'IA5String' )",
306                 0, IA5StringValidate, NULL, NULL},
307         {"( 1.3.6.1.4.1.1466.115.121.1.27 DESC 'Integer' )",
308                 0, NULL, NULL, NULL},
309         {"( 1.3.6.1.4.1.1466.115.121.1.28 DESC 'JPEG' )",
310                 0, NULL, NULL, NULL},
311         {"( 1.3.6.1.4.1.1466.115.121.1.30 DESC 'MatchingRuleDescription' )",
312                 0, NULL, NULL, NULL},
313         {"( 1.3.6.1.4.1.1466.115.121.1.31 DESC 'MatchingRuleUseDescription' )",
314                 0, NULL, NULL, NULL},
315         {"( 1.3.6.1.4.1.1466.115.121.1.32 DESC 'MailPreference' )",
316                 0, NULL, NULL, NULL},
317         {"( 1.3.6.1.4.1.1466.115.121.1.34 DESC 'NameAndOptionalUID' )",
318                 0, NULL, NULL, NULL},
319         {"( 1.3.6.1.4.1.1466.115.121.1.35 DESC 'NameFormDescription' )",
320                 0, NULL, NULL, NULL},
321         {"( 1.3.6.1.4.1.1466.115.121.1.36 DESC 'NumericString' )",
322                 0, NULL, NULL, NULL},
323         {"( 1.3.6.1.4.1.1466.115.121.1.37 DESC 'ObjectClassDescription' )",
324                 0, NULL, NULL, NULL},
325         {"( 1.3.6.1.4.1.1466.115.121.1.38 DESC 'OID' )",
326                 0, NULL, NULL, NULL},
327         {"( 1.3.6.1.4.1.1466.115.121.1.39 DESC 'OtherMailbox' )",
328                 0, NULL, NULL, NULL},
329         {"( 1.3.6.1.4.1.1466.115.121.1.40 DESC 'OctetString' )",
330                 0, octetStringValidate, NULL, NULL},
331         {"( 1.3.6.1.4.1.1466.115.121.1.41 DESC 'PostalAddress' )",
332                 0, NULL, NULL, NULL},
333         {"( 1.3.6.1.4.1.1466.115.121.1.42 DESC 'ProtocolInformation' )",
334                 0, NULL, NULL, NULL},
335         {"( 1.3.6.1.4.1.1466.115.121.1.43 DESC 'PresentationAddress' )",
336                 0, NULL, NULL, NULL},
337         {"( 1.3.6.1.4.1.1466.115.121.1.44 DESC 'PrintableString' )",
338                 0, NULL, NULL, NULL},
339         {"( 1.3.6.1.4.1.1466.115.121.1.49 DESC 'SupportedAlgorithm' )",
340                 SLAP_SYNTAX_BINARY, NULL, NULL, NULL},
341         {"( 1.3.6.1.4.1.1466.115.121.1.50 DESC 'TelephoneNumber' )",
342                 0, NULL, NULL, NULL},
343         {"( 1.3.6.1.4.1.1466.115.121.1.51 DESC 'TeletexTerminalIdentifier' )",
344                 0, NULL, NULL, NULL},
345         {"( 1.3.6.1.4.1.1466.115.121.1.52 DESC 'TelexNumber' )",
346                 0, NULL, NULL, NULL},
347         {"( 1.3.6.1.4.1.1466.115.121.1.53 DESC 'UTCTime' )",
348                 0, NULL, NULL, NULL},
349         {"( 1.3.6.1.4.1.1466.115.121.1.54 DESC 'LDAPSyntaxDescription' )",
350                 0, NULL, NULL, NULL},
351         {"( 1.3.6.1.4.1.1466.115.121.1.58 DESC 'SubstringAssertion' )",
352                 0, NULL, NULL, NULL},
353
354         /* OpenLDAP Experimental Syntaxes */
355         {"( " SLAPD_OID_ACI_SYNTAX " DESC 'OpenLDAPexperimentalACI' )",
356                 0, NULL, NULL, NULL},
357
358         {NULL, 0, NULL, NULL, NULL}
359 };
360
361 struct mrule_defs_rec {
362         char *                                          mrd_desc;
363         slap_mr_convert_func *          mrd_convert;
364         slap_mr_normalize_func *        mrd_normalize;
365         slap_mr_match_func *            mrd_match;
366         slap_mr_indexer_func *          mrd_indexer;
367         slap_mr_filter_func *           mrd_filter;
368 };
369
370 /*
371  * Other matching rules in X.520 that we do not use:
372  *
373  * 2.5.13.9             numericStringOrderingMatch
374  * 2.5.13.12    caseIgnoreListSubstringsMatch
375  * 2.5.13.13    booleanMatch
376  * 2.5.13.15    integerOrderingMatch
377  * 2.5.13.18    octetStringOrderingMatch
378  * 2.5.13.19    octetStringSubstringsMatch
379  * 2.5.13.25    uTCTimeMatch
380  * 2.5.13.26    uTCTimeOrderingMatch
381  * 2.5.13.31    directoryStringFirstComponentMatch
382  * 2.5.13.32    wordMatch
383  * 2.5.13.33    keywordMatch
384  * 2.5.13.34    certificateExactMatch
385  * 2.5.13.35    certificateMatch
386  * 2.5.13.36    certificatePairExactMatch
387  * 2.5.13.37    certificatePairMatch
388  * 2.5.13.38    certificateListExactMatch
389  * 2.5.13.39    certificateListMatch
390  * 2.5.13.40    algorithmIdentifierMatch
391  * 2.5.13.41    storedPrefixMatch
392  * 2.5.13.42    attributeCertificateMatch
393  * 2.5.13.43    readerAndKeyIDMatch
394  * 2.5.13.44    attributeIntegrityMatch
395  */
396
397 /* recycled matching functions */
398 #define caseIgnoreMatch caseIgnoreIA5Match
399 #define caseExactMatch caseExactIA5Match
400
401 /* unimplemented matching functions */
402 #define objectIdentifierMatch NULL
403 #define distinguishedNameMatch NULL
404 #define caseIgnoreOrderingMatch NULL
405 #define caseIgnoreSubstringsMatch NULL
406 #define caseExactOrderingMatch NULL
407 #define caseExactSubstringsMatch NULL
408 #define numericStringMatch NULL
409 #define numericStringSubstringsMatch NULL
410 #define caseIgnoreListMatch NULL
411 #define integerMatch NULL
412 #define bitStringMatch NULL
413 #define octetStringMatch NULL
414 #define telephoneNumberMatch NULL
415 #define telephoneNumberSubstringsMatch NULL
416 #define presentationAddressMatch NULL
417 #define uniqueMemberMatch NULL
418 #define protocolInformationMatch NULL
419 #define generalizedTimeMatch NULL
420 #define generalizedTimeOrderingMatch NULL
421 #define integerFirstComponentMatch NULL
422 #define objectIdentifierFirstComponentMatch NULL
423 #define caseIgnoreIA5SubstringsMatch NULL
424
425 struct mrule_defs_rec mrule_defs[] = {
426         {"( 2.5.13.0 NAME 'objectIdentifierMatch' "
427                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
428                 NULL, NULL, objectIdentifierMatch, NULL, NULL},
429
430         {"( 2.5.13.1 NAME 'distinguishedNameMatch' "
431                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )",
432                 NULL, NULL, distinguishedNameMatch, NULL, NULL},
433
434         {"( 2.5.13.2 NAME 'caseIgnoreMatch' "
435                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
436                 NULL, UTF8StringNormalize, caseIgnoreMatch, NULL, NULL},
437
438         {"( 2.5.13.3 NAME 'caseIgnoreOrderingMatch' "
439                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
440                 NULL, UTF8StringNormalize, caseIgnoreOrderingMatch, NULL, NULL},
441
442         {"( 2.5.13.4 NAME 'caseIgnoreSubstringsMatch' "
443                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
444                 NULL, UTF8StringNormalize, caseIgnoreSubstringsMatch, NULL, NULL},
445
446         /* Next three are not in the RFC's, but are needed for compatibility */
447         {"( 2.5.13.5 NAME 'caseExactMatch' "
448                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
449                 NULL, UTF8StringNormalize, caseExactMatch, NULL, NULL},
450
451         {"( 2.5.13.6 NAME 'caseExactOrderingMatch' "
452                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
453                 NULL, UTF8StringNormalize, caseExactOrderingMatch, NULL, NULL},
454
455         {"( 2.5.13.7 NAME 'caseExactSubstringsMatch' "
456                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
457                 NULL, UTF8StringNormalize, caseExactSubstringsMatch, NULL, NULL},
458
459         {"( 2.5.13.8 NAME 'numericStringMatch' "
460                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 )",
461                 NULL, NULL, numericStringMatch, NULL, NULL},
462
463         {"( 2.5.13.10 NAME 'numericStringSubstringsMatch' "
464                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
465                 NULL, NULL, numericStringSubstringsMatch, NULL, NULL},
466
467         {"( 2.5.13.11 NAME 'caseIgnoreListMatch' "
468                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )",
469                 NULL, NULL, caseIgnoreListMatch, NULL, NULL},
470
471         {"( 2.5.13.14 NAME 'integerMatch' "
472                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
473                 NULL, NULL, integerMatch, NULL, NULL},
474
475         {"( 2.5.13.16 NAME 'bitStringMatch' "
476                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.6 )",
477                 NULL, NULL, bitStringMatch, NULL, NULL},
478
479         {"( 2.5.13.17 NAME 'octetStringMatch' "
480                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
481                 NULL, NULL, octetStringMatch, NULL, NULL},
482
483         {"( 2.5.13.20 NAME 'telephoneNumberMatch' "
484                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 )",
485                 NULL, NULL, telephoneNumberMatch, NULL, NULL},
486
487         {"( 2.5.13.21 NAME 'telephoneNumberSubstringsMatch' "
488                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
489                 NULL, NULL, telephoneNumberSubstringsMatch, NULL, NULL},
490
491         {"( 2.5.13.22 NAME 'presentationAddressMatch' "
492                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.43 )",
493                 NULL, NULL, presentationAddressMatch, NULL, NULL},
494
495         {"( 2.5.13.23 NAME 'uniqueMemberMatch' "
496                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.34 )",
497                 NULL, NULL, uniqueMemberMatch, NULL, NULL},
498
499         {"( 2.5.13.24 NAME 'protocolInformationMatch' "
500                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.42 )",
501                 NULL, NULL, protocolInformationMatch, NULL, NULL},
502
503         {"( 2.5.13.27 NAME 'generalizedTimeMatch' "
504                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
505                 NULL, NULL, generalizedTimeMatch, NULL, NULL},
506
507         {"( 2.5.13.28 NAME 'generalizedTimeOrderingMatch' "
508                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
509                 NULL, NULL, generalizedTimeOrderingMatch, NULL, NULL},
510
511         {"( 2.5.13.29 NAME 'integerFirstComponentMatch' "
512                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
513                 NULL, NULL, integerFirstComponentMatch, NULL, NULL},
514
515         {"( 2.5.13.30 NAME 'objectIdentifierFirstComponentMatch' "
516                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
517                 NULL, NULL, objectIdentifierFirstComponentMatch, NULL, NULL},
518
519         {"( 1.3.6.1.4.1.1466.109.114.1 NAME 'caseExactIA5Match' "
520                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
521                 NULL, IA5StringNormalize, caseExactIA5Match, NULL, NULL},
522
523         {"( 1.3.6.1.4.1.1466.109.114.2 NAME 'caseIgnoreIA5Match' "
524                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
525                 NULL, IA5StringNormalize, caseIgnoreIA5Match, NULL, NULL},
526
527         {"( 1.3.6.1.4.1.1466.109.114.3 NAME 'caseIgnoreIA5SubstringsMatch' "
528                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
529                 NULL, IA5StringNormalize, caseIgnoreIA5SubstringsMatch, NULL, NULL},
530
531         {NULL, NULL, NULL, NULL}
532 };
533
534 int
535 schema_init( void )
536 {
537         int             res;
538         int             i;
539         static int      schema_init_done = 0;
540
541         /* We are called from read_config that is recursive */
542         if ( schema_init_done )
543                 return( 0 );
544
545         for ( i=0; syntax_defs[i].sd_desc != NULL; i++ ) {
546                 res = register_syntax( syntax_defs[i].sd_desc,
547                     syntax_defs[i].sd_flags,
548                     syntax_defs[i].sd_validate,
549                     syntax_defs[i].sd_ber2str,
550                         syntax_defs[i].sd_str2ber );
551
552                 if ( res ) {
553                         fprintf( stderr, "schema_init: Error registering syntax %s\n",
554                                  syntax_defs[i].sd_desc );
555                         exit( EXIT_FAILURE );
556                 }
557         }
558
559         for ( i=0; mrule_defs[i].mrd_desc != NULL; i++ ) {
560                 res = register_matching_rule(
561                         mrule_defs[i].mrd_desc,
562                         mrule_defs[i].mrd_convert,
563                         mrule_defs[i].mrd_normalize,
564                     mrule_defs[i].mrd_match,
565                         mrule_defs[i].mrd_indexer,
566                         mrule_defs[i].mrd_filter );
567
568                 if ( res ) {
569                         fprintf( stderr,
570                                 "schema_init: Error registering matching rule %s\n",
571                                  mrule_defs[i].mrd_desc );
572                         exit( EXIT_FAILURE );
573                 }
574         }
575         schema_init_done = 1;
576         return( 0 );
577 }