1 /* schema_init.c - init builtin schema */
4 * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
5 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
13 #include <ac/string.h>
14 #include <ac/socket.h>
18 #include "lutil_md5.h"
20 /* recycled validatation routines */
21 #define berValidate blobValidate
23 /* recycled normalization routines */
24 #define faxNumberNormalize numericStringNormalize
25 #define phoneNumberNormalize numericStringNormalize
26 #define telexNumberNormalize numericStringNormalize
28 /* recycled matching routines */
29 #define caseIgnoreMatch caseIgnoreIA5Match
30 #define caseIgnoreOrderingMatch caseIgnoreMatch
31 #define caseIgnoreSubstringsMatch caseIgnoreIA5SubstringsMatch
32 #define caseExactMatch caseExactIA5Match
33 #define caseExactOrderingMatch caseExactMatch
34 #define caseExactSubstringsMatch caseExactIA5SubstringsMatch
36 #define numericStringMatch caseIgnoreMatch
37 #define objectIdentifierMatch numericStringMatch
38 #define integerMatch numericStringMatch
39 #define telephoneNumberMatch numericStringMatch
40 #define generalizedTimeMatch numericStringMatch
41 #define generalizedTimeOrderingMatch numericStringMatch
43 /* unimplemented matching routines */
44 #define caseIgnoreListMatch NULL
45 #define caseIgnoreListSubstringsMatch NULL
46 #define bitStringMatch NULL
47 #define telephoneNumberSubstringsMatch NULL
48 #define presentationAddressMatch NULL
49 #define uniqueMemberMatch NULL
50 #define protocolInformationMatch NULL
51 #define integerFirstComponentMatch NULL
53 #define OpenLDAPaciMatch NULL
54 #define authPasswordMatch NULL
56 /* unimplied indexer/filter routines */
57 #define dnIndexer NULL
60 /* recycled indexing/filtering routines */
61 #define caseIgnoreIndexer caseIgnoreIA5Indexer
62 #define caseIgnoreFilter caseIgnoreIA5Filter
63 #define caseExactIndexer caseExactIA5Indexer
64 #define caseExactFilter caseExactIA5Filter
65 #define caseExactIA5Indexer caseIgnoreIA5Indexer
66 #define caseExactIA5Filter caseIgnoreIA5Filter
77 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
80 match = memcmp( value->bv_val,
81 ((struct berval *) assertedValue)->bv_val,
89 /* Index generation function */
90 int octetStringIndexer(
94 struct berval *prefix,
95 struct berval **values,
96 struct berval ***keysp )
100 struct berval **keys;
101 lutil_MD5_CTX MD5context;
102 unsigned char MD5digest[16];
103 struct berval digest;
104 digest.bv_val = MD5digest;
105 digest.bv_len = sizeof(MD5digest);
107 for( i=0; values[i] != NULL; i++ ) {
108 /* just count them */
113 keys = ch_malloc( sizeof( struct berval * ) * (i+1) );
115 slen = strlen( syntax->ssyn_oid );
116 mlen = strlen( mr->smr_oid );
118 for( i=0; values[i] != NULL; i++ ) {
119 lutil_MD5Init( &MD5context );
120 if( prefix != NULL && prefix->bv_len > 0 ) {
121 lutil_MD5Update( &MD5context,
122 prefix->bv_val, prefix->bv_len );
124 lutil_MD5Update( &MD5context,
125 syntax->ssyn_oid, slen );
126 lutil_MD5Update( &MD5context,
128 lutil_MD5Update( &MD5context,
129 values[i]->bv_val, values[i]->bv_len );
130 lutil_MD5Final( MD5digest, &MD5context );
132 keys[i] = ber_bvdup( &digest );
142 /* Index generation function */
143 int octetStringFilter(
147 struct berval *prefix,
149 struct berval ***keysp )
152 struct berval **keys;
153 lutil_MD5_CTX MD5context;
154 unsigned char MD5digest[LUTIL_MD5_BYTES];
155 struct berval *value = (struct berval *) assertValue;
156 struct berval digest;
157 digest.bv_val = MD5digest;
158 digest.bv_len = sizeof(MD5digest);
160 slen = strlen( syntax->ssyn_oid );
161 mlen = strlen( mr->smr_oid );
163 keys = ch_malloc( sizeof( struct berval * ) * 2 );
165 lutil_MD5Init( &MD5context );
166 if( prefix != NULL && prefix->bv_len > 0 ) {
167 lutil_MD5Update( &MD5context,
168 prefix->bv_val, prefix->bv_len );
170 lutil_MD5Update( &MD5context,
171 syntax->ssyn_oid, slen );
172 lutil_MD5Update( &MD5context,
174 lutil_MD5Update( &MD5context,
175 value->bv_val, value->bv_len );
176 lutil_MD5Final( MD5digest, &MD5context );
178 keys[0] = ber_bvdup( &digest );
194 if( in->bv_len == 0 ) return LDAP_SUCCESS;
196 dn = ch_strdup( in->bv_val );
198 rc = dn_validate( dn ) == NULL
199 ? LDAP_INVALID_SYNTAX : LDAP_SUCCESS;
209 struct berval **normalized )
211 struct berval *out = ber_bvdup( val );
213 if( out->bv_len != 0 ) {
215 #ifdef USE_DN_NORMALIZE
216 dn = dn_normalize( out->bv_val );
218 dn = dn_validate( out->bv_val );
223 return LDAP_INVALID_SYNTAX;
227 out->bv_len = strlen( dn );
240 struct berval *value,
241 void *assertedValue )
244 struct berval *asserted = (struct berval *) assertedValue;
246 match = value->bv_len - asserted->bv_len;
249 #ifdef USE_DN_NORMALIZE
250 match = strcmp( value->bv_val, asserted->bv_val );
252 match = strcasecmp( value->bv_val, asserted->bv_val );
256 Debug( LDAP_DEBUG_ARGS, "dnMatch %d\n\t\"%s\"\n\t\"%s\"\n",
257 match, value->bv_val, asserted->bv_val );
268 /* any value allowed */
277 /* any value allowed */
288 unsigned char *u = in->bv_val;
290 for( count = in->bv_len; count > 0; count-=len, u+=len ) {
291 /* get the length indicated by the first byte */
292 len = LDAP_UTF8_CHARLEN( u );
294 /* should not be zero */
295 if( len == 0 ) return LDAP_INVALID_SYNTAX;
297 /* make sure len corresponds with the offset
298 to the next character */
299 if( LDAP_UTF8_OFFSET( u ) != len ) return LDAP_INVALID_SYNTAX;
302 if( count != 0 ) return LDAP_INVALID_SYNTAX;
311 struct berval **normalized )
313 struct berval *newval;
316 newval = ch_malloc( sizeof( struct berval ) );
320 /* Ignore initial whitespace */
321 while ( ldap_utf8_isspace( p ) ) {
327 return LDAP_INVALID_SYNTAX;
330 newval->bv_val = ch_strdup( p );
331 p = q = newval->bv_val;
337 if ( ldap_utf8_isspace( p ) ) {
338 len = LDAP_UTF8_COPY(q,p);
343 /* Ignore the extra whitespace */
344 while ( ldap_utf8_isspace( p ) ) {
348 len = LDAP_UTF8_COPY(q,p);
355 assert( *newval->bv_val );
356 assert( newval->bv_val < p );
359 /* cannot start with a space */
360 assert( !ldap_utf8_isspace(newval->bv_val) );
363 * If the string ended in space, backup the pointer one
364 * position. One is enough because the above loop collapsed
365 * all whitespace to a single space.
372 /* cannot end with a space */
373 assert( !ldap_utf8_isspace( LDAP_UTF8_PREV(q) ) );
378 newval->bv_len = q - newval->bv_val;
379 *normalized = newval;
391 if( val->bv_len == 0 ) return 0;
393 if( isdigit(val->bv_val[0]) ) {
395 for(i=1; i < val->bv_len; i++) {
396 if( val->bv_val[i] == '.' ) {
397 if( dot++ ) return 1;
398 } else if ( isdigit(val->bv_val[i]) ) {
401 return LDAP_INVALID_SYNTAX;
405 return !dot ? LDAP_SUCCESS : LDAP_INVALID_SYNTAX;
407 } else if( isalpha(val->bv_val[0]) ) {
408 for(i=1; i < val->bv_len; i++) {
409 if( !isalpha(val->bv_val[i] ) ) {
410 return LDAP_INVALID_SYNTAX;
417 return LDAP_INVALID_SYNTAX;
427 for(i=0; i < val->bv_len; i++) {
428 if( !isdigit(val->bv_val[i]) ) return LDAP_INVALID_SYNTAX;
435 printableStringValidate(
441 for(i=0; i < val->bv_len; i++) {
442 if( !isprint(val->bv_val[i]) ) return LDAP_INVALID_SYNTAX;
455 for(i=0; i < val->bv_len; i++) {
456 if( !isascii(val->bv_val[i]) ) return LDAP_INVALID_SYNTAX;
466 struct berval **out )
469 ber_len_t i, len = in->bv_len;
470 struct berval *bv = ch_malloc( sizeof(struct berval) );
472 bv->bv_len = len * sizeof( ldap_unicode_t );
473 bv->bv_val = (char *) u = ch_malloc( bv->bv_len + sizeof(ldap_unicode_t) );
475 for(i=0; i < len; i++ ) {
477 * IA5StringValidate should have been called to ensure
478 * input is limited to IA5.
480 u[i] = in->bv_val[i];
492 struct berval **normalized )
494 struct berval *newval;
497 newval = ch_malloc( sizeof( struct berval ) );
501 /* Ignore initial whitespace */
502 while ( isspace( *p ) ) {
508 return LDAP_INVALID_SYNTAX;
511 newval->bv_val = ch_strdup( p );
512 p = q = newval->bv_val;
515 if ( isspace( *p ) ) {
518 /* Ignore the extra whitespace */
519 while ( isspace( *p ) ) {
527 assert( *newval->bv_val );
528 assert( newval->bv_val < p );
531 /* cannot start with a space */
532 assert( !isspace(*newval->bv_val) );
535 * If the string ended in space, backup the pointer one
536 * position. One is enough because the above loop collapsed
537 * all whitespace to a single space.
540 if ( isspace( q[-1] ) ) {
544 /* cannot end with a space */
545 assert( !isspace( q[-1] ) );
550 newval->bv_len = q - newval->bv_val;
551 *normalized = newval;
562 struct berval *value,
563 void *assertedValue )
565 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
568 match = strncmp( value->bv_val,
569 ((struct berval *) assertedValue)->bv_val,
578 caseExactIA5SubstringsMatch(
583 struct berval *value,
584 void *assertedValue )
587 SubstringsAssertion *sub = assertedValue;
588 struct berval left = *value;
592 /* Add up asserted input length */
593 if( sub->sa_initial ) {
594 inlen += sub->sa_initial->bv_len;
597 for(i=0; sub->sa_any[i] != NULL; i++) {
598 inlen += sub->sa_any[i]->bv_len;
601 if( sub->sa_final ) {
602 inlen += sub->sa_final->bv_len;
605 if( sub->sa_initial ) {
606 if( inlen > left.bv_len ) {
611 match = strncmp( sub->sa_initial->bv_val, left.bv_val,
612 sub->sa_initial->bv_len );
618 left.bv_val += sub->sa_initial->bv_len;
619 left.bv_len -= sub->sa_initial->bv_len;
620 inlen -= sub->sa_initial->bv_len;
623 if( sub->sa_final ) {
624 if( inlen > left.bv_len ) {
629 match = strncmp( sub->sa_final->bv_val,
630 &left.bv_val[left.bv_len - sub->sa_final->bv_len],
631 sub->sa_final->bv_len );
637 left.bv_len -= sub->sa_final->bv_len;
638 inlen -= sub->sa_final->bv_len;
642 for(i=0; sub->sa_any[i]; i++) {
647 if( inlen > left.bv_len ) {
648 /* not enough length */
653 if( sub->sa_any[i]->bv_len == 0 ) {
657 p = strchr( left.bv_val, *sub->sa_any[i]->bv_val );
664 idx = p - left.bv_val;
665 assert( idx < left.bv_len );
667 if( idx >= left.bv_len ) {
668 /* this shouldn't happen */
675 if( sub->sa_any[i]->bv_len > left.bv_len ) {
676 /* not enough left */
681 match = strncmp( left.bv_val,
682 sub->sa_any[i]->bv_val,
683 sub->sa_any[i]->bv_len );
691 left.bv_val += sub->sa_any[i]->bv_len;
692 left.bv_len -= sub->sa_any[i]->bv_len;
693 inlen -= sub->sa_any[i]->bv_len;
708 struct berval *value,
709 void *assertedValue )
711 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
714 match = strncasecmp( value->bv_val,
715 ((struct berval *) assertedValue)->bv_val,
723 static char *strcasechr( const char *str, int c )
725 char *lower = strchr( str, TOLOWER(c) );
726 char *upper = strchr( str, TOUPPER(c) );
728 if( lower && upper ) {
729 return lower < upper ? lower : upper;
730 } else if ( lower ) {
738 caseIgnoreIA5SubstringsMatch(
743 struct berval *value,
744 void *assertedValue )
747 SubstringsAssertion *sub = assertedValue;
748 struct berval left = *value;
752 /* Add up asserted input length */
753 if( sub->sa_initial ) {
754 inlen += sub->sa_initial->bv_len;
757 for(i=0; sub->sa_any[i] != NULL; i++) {
758 inlen += sub->sa_any[i]->bv_len;
761 if( sub->sa_final ) {
762 inlen += sub->sa_final->bv_len;
765 if( sub->sa_initial ) {
766 if( inlen > left.bv_len ) {
771 match = strncasecmp( sub->sa_initial->bv_val, left.bv_val,
772 sub->sa_initial->bv_len );
778 left.bv_val += sub->sa_initial->bv_len;
779 left.bv_len -= sub->sa_initial->bv_len;
780 inlen -= sub->sa_initial->bv_len;
783 if( sub->sa_final ) {
784 if( inlen > left.bv_len ) {
789 match = strncasecmp( sub->sa_final->bv_val,
790 &left.bv_val[left.bv_len - sub->sa_final->bv_len],
791 sub->sa_final->bv_len );
797 left.bv_len -= sub->sa_final->bv_len;
798 inlen -= sub->sa_final->bv_len;
802 for(i=0; sub->sa_any[i]; i++) {
807 if( inlen > left.bv_len ) {
808 /* not enough length */
813 if( sub->sa_any[i]->bv_len == 0 ) {
817 p = strcasechr( left.bv_val, *sub->sa_any[i]->bv_val );
824 idx = p - left.bv_val;
825 assert( idx < left.bv_len );
827 if( idx >= left.bv_len ) {
828 /* this shouldn't happen */
835 if( sub->sa_any[i]->bv_len > left.bv_len ) {
836 /* not enough left */
841 match = strncasecmp( left.bv_val,
842 sub->sa_any[i]->bv_val,
843 sub->sa_any[i]->bv_len );
852 left.bv_val += sub->sa_any[i]->bv_len;
853 left.bv_len -= sub->sa_any[i]->bv_len;
854 inlen -= sub->sa_any[i]->bv_len;
863 /* Index generation function */
864 int caseIgnoreIA5Indexer(
868 struct berval *prefix,
869 struct berval **values,
870 struct berval ***keysp )
874 struct berval **keys;
875 lutil_MD5_CTX MD5context;
876 unsigned char MD5digest[16];
877 struct berval digest;
878 digest.bv_val = MD5digest;
879 digest.bv_len = sizeof(MD5digest);
881 for( i=0; values[i] != NULL; i++ ) {
882 /* just count them */
887 keys = ch_malloc( sizeof( struct berval * ) * (i+1) );
889 slen = strlen( syntax->ssyn_oid );
890 mlen = strlen( mr->smr_oid );
892 for( i=0; values[i] != NULL; i++ ) {
893 struct berval *value = ber_bvdup( values[i] );
894 ldap_pvt_str2upper( value->bv_val );
896 lutil_MD5Init( &MD5context );
897 if( prefix != NULL && prefix->bv_len > 0 ) {
898 lutil_MD5Update( &MD5context,
899 prefix->bv_val, prefix->bv_len );
901 lutil_MD5Update( &MD5context,
902 syntax->ssyn_oid, slen );
903 lutil_MD5Update( &MD5context,
905 lutil_MD5Update( &MD5context,
906 value->bv_val, value->bv_len );
907 lutil_MD5Final( MD5digest, &MD5context );
911 keys[i] = ber_bvdup( &digest );
919 /* Index generation function */
920 int caseIgnoreIA5Filter(
924 struct berval *prefix,
926 struct berval ***keysp )
929 struct berval **keys;
930 lutil_MD5_CTX MD5context;
931 unsigned char MD5digest[LUTIL_MD5_BYTES];
932 struct berval *value;
933 struct berval digest;
934 digest.bv_val = MD5digest;
935 digest.bv_len = sizeof(MD5digest);
937 slen = strlen( syntax->ssyn_oid );
938 mlen = strlen( mr->smr_oid );
940 value = ber_bvdup( (struct berval *) assertValue );
941 ldap_pvt_str2upper( value->bv_val );
943 keys = ch_malloc( sizeof( struct berval * ) * 2 );
945 lutil_MD5Init( &MD5context );
946 if( prefix != NULL && prefix->bv_len > 0 ) {
947 lutil_MD5Update( &MD5context,
948 prefix->bv_val, prefix->bv_len );
950 lutil_MD5Update( &MD5context,
951 syntax->ssyn_oid, slen );
952 lutil_MD5Update( &MD5context,
954 lutil_MD5Update( &MD5context,
955 value->bv_val, value->bv_len );
956 lutil_MD5Final( MD5digest, &MD5context );
958 keys[0] = ber_bvdup( &digest );
968 numericStringNormalize(
971 struct berval **normalized )
973 /* similiar to IA5StringNormalize except removes all spaces */
974 struct berval *newval;
977 newval = ch_malloc( sizeof( struct berval ) );
981 /* Ignore initial whitespace */
982 while ( isspace( *p ) ) {
988 return LDAP_INVALID_SYNTAX;
991 newval->bv_val = ch_strdup( p );
992 p = q = newval->bv_val;
995 if ( isspace( *p ) ) {
996 /* Ignore whitespace */
1003 assert( *newval->bv_val );
1004 assert( newval->bv_val < p );
1007 /* cannot start with a space */
1008 assert( !isspace(*newval->bv_val) );
1010 /* cannot end with a space */
1011 assert( !isspace( q[-1] ) );
1013 /* null terminate */
1016 newval->bv_len = q - newval->bv_val;
1017 *normalized = newval;
1019 return LDAP_SUCCESS;
1023 objectIdentifierFirstComponentMatch(
1028 struct berval *value,
1029 void *assertedValue )
1031 int rc = LDAP_SUCCESS;
1033 struct berval *asserted = (struct berval *) assertedValue;
1037 if( value->bv_len == 0 || value->bv_val[0] != '(' /*')'*/ ) {
1038 return LDAP_INVALID_SYNTAX;
1041 /* trim leading white space */
1042 for( i=1; isspace(value->bv_val[i]) && i < value->bv_len; i++ ) {
1046 /* grab next word */
1047 oid.bv_val = &value->bv_val[i];
1048 oid.bv_len = value->bv_len - i;
1049 for( i=1; isspace(value->bv_val[i]) && i < oid.bv_len; i++ ) {
1054 /* insert attributeTypes, objectclass check here */
1055 if( isdigit(asserted->bv_val[0]) ) {
1056 rc = objectIdentifierMatch( &match, use, syntax, mr, &oid, asserted );
1059 char *stored = ch_malloc( oid.bv_len + 1 );
1060 memcpy( stored, oid.bv_val, oid.bv_len );
1061 stored[oid.bv_len] = '\0';
1063 if ( !strcmp( syntax->ssyn_oid, SLAP_SYNTAX_MATCHINGRULES_OID ) ) {
1064 MatchingRule *asserted_mr = mr_find( asserted->bv_val );
1065 MatchingRule *stored_mr = mr_find( stored );
1067 if( asserted_mr == NULL ) {
1068 rc = SLAPD_COMPARE_UNDEFINED;
1070 match = asserted_mr != stored_mr;
1073 } else if ( !strcmp( syntax->ssyn_oid,
1074 SLAP_SYNTAX_ATTRIBUTETYPES_OID ) )
1076 AttributeType *asserted_at = at_find( asserted->bv_val );
1077 AttributeType *stored_at = at_find( stored );
1079 if( asserted_at == NULL ) {
1080 rc = SLAPD_COMPARE_UNDEFINED;
1082 match = asserted_at != stored_at;
1085 } else if ( !strcmp( syntax->ssyn_oid,
1086 SLAP_SYNTAX_OBJECTCLASSES_OID ) )
1088 ObjectClass *asserted_oc = oc_find( asserted->bv_val );
1089 ObjectClass *stored_oc = oc_find( stored );
1091 if( asserted_oc == NULL ) {
1092 rc = SLAPD_COMPARE_UNDEFINED;
1094 match = asserted_oc != stored_oc;
1101 Debug( LDAP_DEBUG_ARGS, "objectIdentifierFirstComponentMatch "
1102 "%d\n\t\"%s\"\n\t\"%s\"\n",
1103 match, value->bv_val, asserted->bv_val );
1105 if( rc == LDAP_SUCCESS ) *matchp = match;
1110 check_time_syntax (struct berval *val,
1114 static int ceiling[9] = { 99, 99, 11, 30, 23, 59, 59, 12, 59 };
1115 static int mdays[12] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
1117 int part, c, neg = 0;
1119 if( val->bv_len == 0 )
1120 return LDAP_INVALID_SYNTAX;
1122 p = (char *)val->bv_val;
1123 e = p + val->bv_len;
1125 /* Ignore initial whitespace */
1126 while ( ( p < e ) && isspace( *p ) ) {
1130 if (e - p < 13 - (2 * start))
1131 return LDAP_INVALID_SYNTAX;
1133 for (part = 0; part < 9; part++)
1136 for (part = start; part < 7; part++) {
1149 return LDAP_INVALID_SYNTAX;
1151 return LDAP_INVALID_SYNTAX;
1156 return LDAP_INVALID_SYNTAX;
1158 return LDAP_INVALID_SYNTAX;
1162 if (part == 2 || part == 3)
1164 if (parts[part] < 0)
1165 return LDAP_INVALID_SYNTAX;
1166 if (parts[part] > ceiling[part])
1167 return LDAP_INVALID_SYNTAX;
1169 if (parts[2] == 1) {
1170 if (parts[3] > mdays[parts[2]])
1171 return LDAP_INVALID_SYNTAX;
1172 if (parts[1] & 0x03) {
1173 /* FIXME: This is an incomplete leap-year
1174 * check that fails in 2100, 2200, 2300,
1175 * 2500, 2600, 2700, ...
1177 if (parts[3] > mdays[parts[2]] - 1)
1178 return LDAP_INVALID_SYNTAX;
1184 } else if (c != '+' && c != '-') {
1185 return LDAP_INVALID_SYNTAX;
1190 return LDAP_INVALID_SYNTAX;
1191 for (part = 7; part < 9; part++) {
1194 return LDAP_INVALID_SYNTAX;
1199 return LDAP_INVALID_SYNTAX;
1202 if (parts[part] < 0 || parts[part] > ceiling[part])
1203 return LDAP_INVALID_SYNTAX;
1207 /* Ignore trailing whitespace */
1208 while ( ( p < e ) && isspace( *p ) ) {
1212 return LDAP_INVALID_SYNTAX;
1215 parts[4] += parts[7];
1216 parts[5] += parts[8];
1217 for (part = 7; --part > 0; ) {
1221 /* FIXME: This is an incomplete leap-year
1222 * check that fails in 2100, 2200, 2300,
1223 * 2500, 2600, 2700, ...
1225 c = mdays[parts[2]];
1229 if (parts[part] > c) {
1230 parts[part] -= c + 1;
1235 parts[4] -= parts[7];
1236 parts[5] -= parts[8];
1237 for (part = 7; --part > 0; ) {
1241 /* FIXME: This is an incomplete leap-year
1242 * check that fails in 2100, 2200, 2300,
1243 * 2500, 2600, 2700, ...
1245 c = mdays[(parts[2] - 1) % 12];
1249 if (parts[part] < 0) {
1250 parts[part] += c + 1;
1256 return LDAP_SUCCESS;
1263 struct berval **normalized )
1268 rc = check_time_syntax(val, 1, parts);
1269 if (rc != LDAP_SUCCESS) {
1274 out = ch_malloc( sizeof(struct berval) );
1276 return LBER_ERROR_MEMORY;
1278 out->bv_val = ch_malloc( 14 );
1279 if ( out->bv_val == NULL ) {
1281 return LBER_ERROR_MEMORY;
1284 sprintf( out->bv_val, "%02ld%02ld%02ld%02ld%02ld%02ldZ",
1285 parts[1], parts[2] + 1, parts[3] + 1,
1286 parts[4], parts[5], parts[6] );
1290 return LDAP_SUCCESS;
1300 return check_time_syntax(in, 1, parts);
1304 generalizedTimeNormalize(
1307 struct berval **normalized )
1312 rc = check_time_syntax(val, 0, parts);
1313 if (rc != LDAP_SUCCESS) {
1318 out = ch_malloc( sizeof(struct berval) );
1320 return LBER_ERROR_MEMORY;
1322 out->bv_val = ch_malloc( 16 );
1323 if ( out->bv_val == NULL ) {
1325 return LBER_ERROR_MEMORY;
1328 sprintf( out->bv_val, "%02ld%02ld%02ld%02ld%02ld%02ld%02ldZ",
1329 parts[0], parts[1], parts[2] + 1, parts[3] + 1,
1330 parts[4], parts[5], parts[6] );
1334 return LDAP_SUCCESS;
1338 generalizedTimeValidate(
1344 return check_time_syntax(in, 0, parts);
1347 struct syntax_defs_rec {
1350 slap_syntax_validate_func *sd_validate;
1351 slap_syntax_transform_func *sd_normalize;
1352 slap_syntax_transform_func *sd_pretty;
1353 #ifdef SLAPD_BINARY_CONVERSION
1354 slap_syntax_transform_func *sd_ber2str;
1355 slap_syntax_transform_func *sd_str2ber;
1359 #define X_HIDE "X-HIDE 'TRUE' "
1360 #define X_BINARY "X-BINARY-TRANSFER-REQUIRED 'TRUE' "
1361 #define X_NOT_H_R "X-NOT-HUMAN-READABLE 'TRUE' "
1363 struct syntax_defs_rec syntax_defs[] = {
1364 {"( 1.3.6.1.4.1.1466.115.121.1.1 DESC 'ACI Item' " X_BINARY X_NOT_H_R ")",
1365 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, NULL, NULL, NULL},
1366 {"( 1.3.6.1.4.1.1466.115.121.1.2 DESC 'Access Point' " X_NOT_H_R ")",
1367 0, NULL, NULL, NULL},
1368 {"( 1.3.6.1.4.1.1466.115.121.1.3 DESC 'Attribute Type Description' )",
1369 0, NULL, NULL, NULL},
1370 {"( 1.3.6.1.4.1.1466.115.121.1.4 DESC 'Audio' " X_NOT_H_R ")",
1371 SLAP_SYNTAX_BLOB, blobValidate, NULL, NULL},
1372 {"( 1.3.6.1.4.1.1466.115.121.1.5 DESC 'Binary' " X_BINARY X_NOT_H_R ")",
1373 SLAP_SYNTAX_BER, berValidate, NULL, NULL},
1374 {"( 1.3.6.1.4.1.1466.115.121.1.6 DESC 'Bit String' )",
1375 0, NULL, NULL, NULL},
1376 {"( 1.3.6.1.4.1.1466.115.121.1.7 DESC 'Boolean' )",
1377 0, NULL, NULL, NULL},
1378 {"( 1.3.6.1.4.1.1466.115.121.1.8 DESC 'Certificate' "
1379 X_BINARY X_NOT_H_R ")",
1380 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
1381 {"( 1.3.6.1.4.1.1466.115.121.1.9 DESC 'Certificate List' "
1382 X_BINARY X_NOT_H_R ")",
1383 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
1384 {"( 1.3.6.1.4.1.1466.115.121.1.10 DESC 'Certificate Pair' "
1385 X_BINARY X_NOT_H_R ")",
1386 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
1387 {"( 1.3.6.1.4.1.1466.115.121.1.11 DESC 'Country String' )",
1388 0, NULL, NULL, NULL},
1389 {"( 1.3.6.1.4.1.1466.115.121.1.12 DESC 'Distinguished Name' )",
1390 0, dnValidate, dnNormalize, NULL},
1391 {"( 1.3.6.1.4.1.1466.115.121.1.13 DESC 'Data Quality' )",
1392 0, NULL, NULL, NULL},
1393 {"( 1.3.6.1.4.1.1466.115.121.1.14 DESC 'Delivery Method' )",
1394 0, NULL, NULL, NULL},
1395 {"( 1.3.6.1.4.1.1466.115.121.1.15 DESC 'Directory String' )",
1396 0, UTF8StringValidate, UTF8StringNormalize, NULL},
1397 {"( 1.3.6.1.4.1.1466.115.121.1.16 DESC 'DIT Content Rule Description' )",
1398 0, NULL, NULL, NULL},
1399 {"( 1.3.6.1.4.1.1466.115.121.1.17 DESC 'DIT Structure Rule Description' )",
1400 0, NULL, NULL, NULL},
1401 {"( 1.3.6.1.4.1.1466.115.121.1.19 DESC 'DSA Quality' )",
1402 0, NULL, NULL, NULL},
1403 {"( 1.3.6.1.4.1.1466.115.121.1.20 DESC 'DSE Type' )",
1404 0, NULL, NULL, NULL},
1405 {"( 1.3.6.1.4.1.1466.115.121.1.21 DESC 'Enhanced Guide' )",
1406 0, NULL, NULL, NULL},
1407 {"( 1.3.6.1.4.1.1466.115.121.1.22 DESC 'Facsimile Telephone Number' )",
1408 0, IA5StringValidate, faxNumberNormalize, NULL},
1409 {"( 1.3.6.1.4.1.1466.115.121.1.23 DESC 'Fax' " X_NOT_H_R ")",
1410 SLAP_SYNTAX_BLOB, NULL, NULL, NULL},
1411 {"( 1.3.6.1.4.1.1466.115.121.1.24 DESC 'Generalized Time' )",
1412 0, generalizedTimeValidate, generalizedTimeNormalize, NULL},
1413 {"( 1.3.6.1.4.1.1466.115.121.1.25 DESC 'Guide' )",
1414 0, NULL, NULL, NULL},
1415 {"( 1.3.6.1.4.1.1466.115.121.1.26 DESC 'IA5 String' )",
1416 0, IA5StringValidate, IA5StringNormalize, NULL},
1417 {"( 1.3.6.1.4.1.1466.115.121.1.27 DESC 'Integer' )",
1418 0, integerValidate, NULL, NULL},
1419 {"( 1.3.6.1.4.1.1466.115.121.1.28 DESC 'JPEG' " X_NOT_H_R ")",
1420 SLAP_SYNTAX_BLOB, NULL, NULL, NULL},
1421 {"( 1.3.6.1.4.1.1466.115.121.1.29 DESC 'Master And Shadow Access Points' )",
1422 0, NULL, NULL, NULL},
1423 {"( 1.3.6.1.4.1.1466.115.121.1.30 DESC 'Matching Rule Description' )",
1424 0, NULL, NULL, NULL},
1425 {"( 1.3.6.1.4.1.1466.115.121.1.31 DESC 'Matching Rule Use Description' )",
1426 0, NULL, NULL, NULL},
1427 {"( 1.3.6.1.4.1.1466.115.121.1.32 DESC 'Mail Preference' )",
1428 0, NULL, NULL, NULL},
1429 {"( 1.3.6.1.4.1.1466.115.121.1.33 DESC 'MHS OR Address' )",
1430 0, NULL, NULL, NULL},
1431 {"( 1.3.6.1.4.1.1466.115.121.1.34 DESC 'Name And Optional UID' )",
1432 0, NULL, NULL, NULL},
1433 {"( 1.3.6.1.4.1.1466.115.121.1.35 DESC 'Name Form Description' )",
1434 0, NULL, NULL, NULL},
1435 {"( 1.3.6.1.4.1.1466.115.121.1.36 DESC 'Numeric String' )",
1436 0, IA5StringValidate, numericStringNormalize, NULL},
1437 {"( 1.3.6.1.4.1.1466.115.121.1.37 DESC 'Object Class Description' )",
1438 0, NULL, NULL, NULL},
1439 {"( 1.3.6.1.4.1.1466.115.121.1.38 DESC 'OID' )",
1440 0, oidValidate, NULL, NULL},
1441 {"( 1.3.6.1.4.1.1466.115.121.1.39 DESC 'Other Mailbox' )",
1442 0, NULL, NULL, NULL},
1443 {"( 1.3.6.1.4.1.1466.115.121.1.40 DESC 'Octet String' )",
1444 0, blobValidate, NULL, NULL},
1445 {"( 1.3.6.1.4.1.1466.115.121.1.41 DESC 'Postal Address' )",
1446 0, blobValidate, NULL, NULL},
1447 {"( 1.3.6.1.4.1.1466.115.121.1.42 DESC 'Protocol Information' )",
1448 0, NULL, NULL, NULL},
1449 {"( 1.3.6.1.4.1.1466.115.121.1.43 DESC 'Presentation Address' )",
1450 0, NULL, NULL, NULL},
1451 {"( 1.3.6.1.4.1.1466.115.121.1.44 DESC 'Printable String' )",
1452 0, printableStringValidate, NULL, NULL},
1453 {"( 1.3.6.1.4.1.1466.115.121.1.49 DESC 'Supported Algorithm' "
1454 X_BINARY X_NOT_H_R ")",
1455 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
1456 {"( 1.3.6.1.4.1.1466.115.121.1.50 DESC 'Telephone Number' )",
1457 0, IA5StringValidate, phoneNumberNormalize, NULL},
1458 {"( 1.3.6.1.4.1.1466.115.121.1.51 DESC 'Teletex Terminal Identifier' )",
1459 0, NULL, NULL, NULL},
1460 {"( 1.3.6.1.4.1.1466.115.121.1.52 DESC 'Telex Number' )",
1461 0, IA5StringValidate, telexNumberNormalize, NULL},
1462 {"( 1.3.6.1.4.1.1466.115.121.1.53 DESC 'UTC Time' )",
1463 0, utcTimeValidate, utcTimeNormalize, NULL},
1464 {"( 1.3.6.1.4.1.1466.115.121.1.54 DESC 'LDAP Syntax Description' )",
1465 0, NULL, NULL, NULL},
1466 {"( 1.3.6.1.4.1.1466.115.121.1.55 DESC 'Modify Rights' )",
1467 0, NULL, NULL, NULL},
1468 {"( 1.3.6.1.4.1.1466.115.121.1.56 DESC 'LDAP Schema Definition' )",
1469 0, NULL, NULL, NULL},
1470 {"( 1.3.6.1.4.1.1466.115.121.1.57 DESC 'LDAP Schema Description' )",
1471 0, NULL, NULL, NULL},
1472 {"( 1.3.6.1.4.1.1466.115.121.1.58 DESC 'Substring Assertion' )",
1473 0, NULL, NULL, NULL},
1475 /* OpenLDAP Experimental Syntaxes */
1476 {"( 1.3.6.1.4.1.4203.666.2.1 DESC 'OpenLDAP Experimental ACI' )",
1477 0, IA5StringValidate /* THIS WILL CHANGE FOR NEW ACI SYNTAX */, NULL, NULL},
1478 {"( 1.3.6.1.4.1.4203.666.2.2 DESC 'OpenLDAP authPassword' )",
1479 0, NULL, NULL, NULL},
1480 {"( 1.3.6.1.4.1.4203.666.2.3 DESC 'OpenLDAP void' " X_HIDE ")" ,
1481 SLAP_SYNTAX_HIDE, inValidate, NULL, NULL},
1482 #if 0 /* not needed */
1483 {"( 1.3.6.1.4.1.4203.666.2.4 DESC 'OpenLDAP DN' " X_HIDE ")" ,
1484 SLAP_SYNTAX_HIDE, inValidate, NULL, NULL},
1487 {NULL, 0, NULL, NULL, NULL}
1490 struct mrule_defs_rec {
1493 slap_mr_convert_func * mrd_convert;
1494 slap_mr_normalize_func * mrd_normalize;
1495 slap_mr_match_func * mrd_match;
1496 slap_mr_indexer_func * mrd_indexer;
1497 slap_mr_filter_func * mrd_filter;
1501 * Other matching rules in X.520 that we do not use:
1503 * 2.5.13.9 numericStringOrderingMatch
1504 * 2.5.13.13 booleanMatch
1505 * 2.5.13.15 integerOrderingMatch
1506 * 2.5.13.18 octetStringOrderingMatch
1507 * 2.5.13.19 octetStringSubstringsMatch
1508 * 2.5.13.25 uTCTimeMatch
1509 * 2.5.13.26 uTCTimeOrderingMatch
1510 * 2.5.13.31 directoryStringFirstComponentMatch
1511 * 2.5.13.32 wordMatch
1512 * 2.5.13.33 keywordMatch
1513 * 2.5.13.34 certificateExactMatch
1514 * 2.5.13.35 certificateMatch
1515 * 2.5.13.36 certificatePairExactMatch
1516 * 2.5.13.37 certificatePairMatch
1517 * 2.5.13.38 certificateListExactMatch
1518 * 2.5.13.39 certificateListMatch
1519 * 2.5.13.40 algorithmIdentifierMatch
1520 * 2.5.13.41 storedPrefixMatch
1521 * 2.5.13.42 attributeCertificateMatch
1522 * 2.5.13.43 readerAndKeyIDMatch
1523 * 2.5.13.44 attributeIntegrityMatch
1526 struct mrule_defs_rec mrule_defs[] = {
1527 {"( 2.5.13.0 NAME 'objectIdentifierMatch' "
1528 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
1529 SLAP_MR_EQUALITY | SLAP_MR_EXT,
1530 NULL, NULL, objectIdentifierMatch,
1531 caseIgnoreIA5Indexer, caseIgnoreIA5Filter},
1533 {"( 2.5.13.1 NAME 'distinguishedNameMatch' "
1534 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )",
1535 SLAP_MR_EQUALITY | SLAP_MR_EXT,
1536 NULL, NULL, dnMatch, dnIndexer, dnFilter},
1538 {"( 2.5.13.2 NAME 'caseIgnoreMatch' "
1539 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
1540 SLAP_MR_EQUALITY | SLAP_MR_EXT,
1541 NULL, NULL, caseIgnoreMatch, caseIgnoreIndexer, caseIgnoreFilter},
1543 {"( 2.5.13.3 NAME 'caseIgnoreOrderingMatch' "
1544 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
1546 NULL, NULL, caseIgnoreOrderingMatch, NULL, NULL},
1548 {"( 2.5.13.4 NAME 'caseIgnoreSubstringsMatch' "
1549 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
1550 SLAP_MR_SUBSTR | SLAP_MR_EXT,
1551 NULL, NULL, caseIgnoreSubstringsMatch, NULL, NULL},
1553 /* Next three are not in the RFC's, but are needed for compatibility */
1554 {"( 2.5.13.5 NAME 'caseExactMatch' "
1555 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
1556 SLAP_MR_EQUALITY | SLAP_MR_EXT,
1557 NULL, NULL, caseExactMatch, caseExactIndexer, caseExactFilter},
1559 {"( 2.5.13.6 NAME 'caseExactOrderingMatch' "
1560 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
1562 NULL, NULL, caseExactOrderingMatch, NULL, NULL},
1564 {"( 2.5.13.7 NAME 'caseExactSubstringsMatch' "
1565 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
1566 SLAP_MR_SUBSTR | SLAP_MR_EXT,
1567 NULL, NULL, caseExactSubstringsMatch, NULL, NULL},
1569 {"( 2.5.13.8 NAME 'numericStringMatch' "
1570 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 )",
1571 SLAP_MR_EQUALITY | SLAP_MR_EXT,
1572 NULL, NULL, caseIgnoreIA5Match, NULL, NULL},
1574 {"( 2.5.13.10 NAME 'numericStringSubstringsMatch' "
1575 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
1576 SLAP_MR_SUBSTR | SLAP_MR_EXT,
1577 NULL, NULL, caseIgnoreIA5SubstringsMatch, NULL, NULL},
1579 {"( 2.5.13.11 NAME 'caseIgnoreListMatch' "
1580 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )",
1581 SLAP_MR_EQUALITY | SLAP_MR_EXT,
1582 NULL, NULL, caseIgnoreListMatch, NULL, NULL},
1584 {"( 2.5.13.12 NAME 'caseIgnoreListSubstringsMatch' "
1585 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
1586 SLAP_MR_SUBSTR | SLAP_MR_EXT,
1587 NULL, NULL, caseIgnoreListSubstringsMatch, NULL, NULL},
1589 {"( 2.5.13.14 NAME 'integerMatch' "
1590 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
1591 SLAP_MR_NONE | SLAP_MR_EXT,
1592 NULL, NULL, integerMatch, NULL, NULL},
1594 {"( 2.5.13.16 NAME 'bitStringMatch' "
1595 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.6 )",
1596 SLAP_MR_NONE | SLAP_MR_EXT,
1597 NULL, NULL, bitStringMatch, NULL, NULL},
1599 {"( 2.5.13.17 NAME 'octetStringMatch' "
1600 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
1601 SLAP_MR_EQUALITY | SLAP_MR_EXT,
1602 NULL, NULL, octetStringMatch, octetStringIndexer, octetStringFilter},
1604 {"( 2.5.13.20 NAME 'telephoneNumberMatch' "
1605 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 )",
1606 SLAP_MR_EQUALITY | SLAP_MR_EXT,
1607 NULL, NULL, telephoneNumberMatch, NULL, NULL},
1609 {"( 2.5.13.21 NAME 'telephoneNumberSubstringsMatch' "
1610 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
1611 SLAP_MR_SUBSTR | SLAP_MR_EXT,
1612 NULL, NULL, telephoneNumberSubstringsMatch, NULL, NULL},
1614 {"( 2.5.13.22 NAME 'presentationAddressMatch' "
1615 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.43 )",
1616 SLAP_MR_NONE | SLAP_MR_EXT,
1617 NULL, NULL, presentationAddressMatch, NULL, NULL},
1619 {"( 2.5.13.23 NAME 'uniqueMemberMatch' "
1620 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.34 )",
1621 SLAP_MR_NONE | SLAP_MR_EXT,
1622 NULL, NULL, uniqueMemberMatch, NULL, NULL},
1624 {"( 2.5.13.24 NAME 'protocolInformationMatch' "
1625 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.42 )",
1626 SLAP_MR_NONE | SLAP_MR_EXT,
1627 NULL, NULL, protocolInformationMatch, NULL, NULL},
1629 {"( 2.5.13.27 NAME 'generalizedTimeMatch' "
1630 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
1631 SLAP_MR_EQUALITY | SLAP_MR_EXT,
1632 NULL, NULL, generalizedTimeMatch, NULL, NULL},
1634 {"( 2.5.13.28 NAME 'generalizedTimeOrderingMatch' "
1635 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
1637 NULL, NULL, generalizedTimeOrderingMatch, NULL, NULL},
1639 {"( 2.5.13.29 NAME 'integerFirstComponentMatch' "
1640 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
1641 SLAP_MR_EQUALITY | SLAP_MR_EXT,
1642 NULL, NULL, integerFirstComponentMatch, NULL, NULL},
1644 {"( 2.5.13.30 NAME 'objectIdentifierFirstComponentMatch' "
1645 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
1646 SLAP_MR_EQUALITY | SLAP_MR_EXT,
1647 NULL, NULL, objectIdentifierFirstComponentMatch, NULL, NULL},
1649 {"( 1.3.6.1.4.1.1466.109.114.1 NAME 'caseExactIA5Match' "
1650 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
1651 SLAP_MR_EQUALITY | SLAP_MR_EXT,
1652 NULL, NULL, caseExactIA5Match, caseExactIA5Indexer, caseExactIA5Filter},
1654 {"( 1.3.6.1.4.1.1466.109.114.2 NAME 'caseIgnoreIA5Match' "
1655 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
1656 SLAP_MR_EQUALITY | SLAP_MR_EXT,
1657 NULL, NULL, caseIgnoreIA5Match, caseExactIA5Indexer, caseExactIA5Filter},
1659 {"( 1.3.6.1.4.1.1466.109.114.3 NAME 'caseIgnoreIA5SubstringsMatch' "
1660 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
1662 NULL, NULL, caseIgnoreIA5SubstringsMatch, NULL, NULL},
1664 {"( 1.3.6.1.4.1.4203.666.4.1 NAME 'authPasswordMatch' "
1665 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
1667 NULL, NULL, authPasswordMatch, NULL, NULL},
1669 {"( 1.3.6.1.4.1.4203.666.4.2 NAME 'OpenLDAPaciMatch' "
1670 "SYNTAX 1.3.6.1.4.1.4203.666.2.1 )",
1672 NULL, NULL, OpenLDAPaciMatch, NULL, NULL},
1674 {NULL, SLAP_MR_NONE, NULL, NULL, NULL}
1683 /* we should only be called once (from main) */
1684 assert( schema_init_done == 0 );
1686 for ( i=0; syntax_defs[i].sd_desc != NULL; i++ ) {
1687 res = register_syntax( syntax_defs[i].sd_desc,
1688 syntax_defs[i].sd_flags,
1689 syntax_defs[i].sd_validate,
1690 syntax_defs[i].sd_normalize,
1691 syntax_defs[i].sd_pretty
1692 #ifdef SLAPD_BINARY_CONVERSION
1694 syntax_defs[i].sd_ber2str,
1695 syntax_defs[i].sd_str2ber
1700 fprintf( stderr, "schema_init: Error registering syntax %s\n",
1701 syntax_defs[i].sd_desc );
1706 for ( i=0; mrule_defs[i].mrd_desc != NULL; i++ ) {
1707 if( mrule_defs[i].mrd_usage == SLAP_MR_NONE ) {
1709 "schema_init: Ingoring unusable matching rule %s\n",
1710 mrule_defs[i].mrd_desc );
1714 res = register_matching_rule(
1715 mrule_defs[i].mrd_desc,
1716 mrule_defs[i].mrd_usage,
1717 mrule_defs[i].mrd_convert,
1718 mrule_defs[i].mrd_normalize,
1719 mrule_defs[i].mrd_match,
1720 mrule_defs[i].mrd_indexer,
1721 mrule_defs[i].mrd_filter );
1725 "schema_init: Error registering matching rule %s\n",
1726 mrule_defs[i].mrd_desc );
1730 schema_init_done = 1;
1731 return LDAP_SUCCESS;