1 /* schema_init.c - init builtin schema */
4 * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
5 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
15 #include <ac/string.h>
16 #include <ac/socket.h>
22 #include "ldap_utf8.h"
24 #include "lutil_hash.h"
25 #define HASH_BYTES LUTIL_HASH_BYTES
26 #define HASH_CONTEXT lutil_HASH_CTX
27 #define HASH_Init(c) lutil_HASHInit(c)
28 #define HASH_Update(c,buf,len) lutil_HASHUpdate(c,buf,len)
29 #define HASH_Final(d,c) lutil_HASHFinal(d,c)
33 #define SLAP_MR_DN_FOLD (0)
35 #define SLAP_MR_ASSOCIATED(mr, with) \
36 ((mr) == (with) || (mr)->smr_associated == (with))
38 #define xUTF8StringNormalize NULL
39 #define xIA5StringNormalize NULL
40 #define xtelephoneNumberNormalize NULL
41 #define xgeneralizedTimeNormalize NULL
42 #define xintegerNormalize NULL
43 #define xnumericStringNormalize NULL
44 #define xnameUIDNormalize NULL
46 /* (new) normalization routines */
47 #define caseExactIA5Normalize IA5StringNormalize
48 #define caseIgnoreIA5Normalize IA5StringNormalize
49 #define caseExactNormalize UTF8StringNormalize
50 #define caseIgnoreNormalize UTF8StringNormalize
52 #define distinguishedNameNormalize NULL
53 #define integerNormalize NULL
54 #define integerFirstComponentNormalize NULL
55 #define numericStringNormalize NULL
56 #define objectIdentifierNormalize NULL
57 #define objectIdentifierFirstComponentNormalize NULL
58 #define generalizedTimeNormalize NULL
59 #define uniqueMemberNormalize NULL
60 #define bitStringNormalize NULL
61 #define telephoneNumberNormalize NULL
63 #define distinguishedNameMatch dnMatch
64 #define distinguishedNameIndexer octetStringIndexer
65 #define distinguishedNameFilter octetStringFilter
67 #define uniqueMemberMatch dnMatch
69 #define objectIdentifierMatch octetStringMatch
70 #define objectIdentifierIndexer octetStringIndexer
71 #define objectIdentifierFilter octetStringFilter
73 #define bitStringMatch octetStringMatch
74 #define bitStringIndexer octetStringIndexer
75 #define bitStringFilter octetStringFilter
77 #define integerMatch NULL
78 #define integerOrderingMatch NULL
79 #define integerIndexer NULL
80 #define integerFilter NULL
82 #define generalizedTimeMatch NULL
83 #define generalizedTimeOrderingMatch NULL
85 #define caseIgnoreMatch octetStringMatch
86 #define caseIgnoreOrderingMatch octetStringOrderingMatch
87 #define caseIgnoreIndexer octetStringIndexer
88 #define caseIgnoreFilter octetStringFilter
90 #define caseIgnoreSubstringsMatch NULL
91 #define caseIgnoreSubstringsIndexer NULL
92 #define caseIgnoreSubstringsFilter NULL
94 #define caseExactMatch octetStringMatch
95 #define caseExactOrderingMatch octetStringOrderingMatch
96 #define caseExactIndexer octetStringIndexer
97 #define caseExactFilter octetStringFilter
99 #define caseExactSubstringsMatch NULL
100 #define caseExactSubstringsIndexer NULL
101 #define caseExactSubstringsFilter NULL
103 #define caseExactIA5Match octetStringMatch
104 #define caseExactIA5Indexer octetStringIndexer
105 #define caseExactIA5Filter octetStringFilter
107 #define caseExactIA5SubstringsMatch NULL
108 #define caseExactIA5SubstringsIndexer NULL
109 #define caseExactIA5SubstringsFilter NULL
111 #define caseIgnoreIA5Match octetStringMatch
112 #define caseIgnoreIA5Indexer octetStringIndexer
113 #define caseIgnoreIA5Filter octetStringFilter
115 #define caseIgnoreIA5SubstringsMatch caseExactIA5SubstringsMatch
116 #define caseIgnoreIA5SubstringsIndexer caseExactIA5SubstringsIndexer
117 #define caseIgnoreIA5SubstringsFilter caseExactIA5SubstringsFilter
119 #define numericStringMatch octetStringMatch
120 #define numericStringIndexer octetStringIndexer
121 #define numericStringFilter octetStringFilter
123 #define numericStringSubstringsMatch caseExactIA5SubstringsMatch
124 #define numericStringSubstringsIndexer caseExactIA5SubstringsIndexer
125 #define numericStringSubstringsFilter caseExactIA5SubstringsFilter
127 #define telephoneNumberMatch octetStringMatch
128 #define telephoneNumberIndexer octetStringIndexer
129 #define telephoneNumberFilter octetStringFilter
131 #define telephoneNumberSubstringsMatch caseExactIA5SubstringsMatch
132 #define telephoneNumberSubstringsIndexer caseExactIA5SubstringsIndexer
133 #define telephoneNumberSubstringsFilter caseExactIA5SubstringsFilter
137 /* validatation routines */
138 #define berValidate blobValidate
140 /* approx matching rules */
142 #define directoryStringApproxMatchOID NULL
143 #define IA5StringApproxMatchOID NULL
145 #define directoryStringApproxMatchOID "1.3.6.1.4.1.4203.666.4.4"
146 #define directoryStringApproxMatch approxMatch
147 #define directoryStringApproxIndexer approxIndexer
148 #define directoryStringApproxFilter approxFilter
149 #define IA5StringApproxMatchOID "1.3.6.1.4.1.4203.666.4.5"
150 #define IA5StringApproxMatch approxMatch
151 #define IA5StringApproxIndexer approxIndexer
152 #define IA5StringApproxFilter approxFilter
157 /* (new) normalization routines */
158 #define caseExactNormalize NULL
159 #define caseExactIA5Normalize NULL
160 #define caseIgnoreNormalize NULL
161 #define caseIgnoreIA5Normalize NULL
162 #define distinguishedNameNormalize NULL
163 #define integerNormalize NULL
164 #define integerFirstComponentNormalize NULL
165 #define numericStringNormalize NULL
166 #define objectIdentifierNormalize NULL
167 #define objectIdentifierFirstComponentNormalize NULL
168 #define generalizedTimeNormalize NULL
169 #define uniqueMemberNormalize NULL
170 #define bitStringNormalize NULL
171 #define telephoneNumberNormalize NULL
174 /* matching routines */
175 #define bitStringMatch octetStringMatch
176 #define bitStringIndexer octetStringIndexer
177 #define bitStringFilter octetStringFilter
179 #define numericStringMatch caseIgnoreIA5Match
180 #define numericStringIndexer NULL
181 #define numericStringFilter NULL
182 #define numericStringSubstringsIndexer NULL
183 #define numericStringSubstringsFilter NULL
185 #define objectIdentifierMatch octetStringMatch
186 #define objectIdentifierIndexer caseIgnoreIA5Indexer
187 #define objectIdentifierFilter caseIgnoreIA5Filter
189 #define generalizedTimeMatch caseIgnoreIA5Match
190 #define generalizedTimeOrderingMatch caseIgnoreIA5Match
192 #define uniqueMemberMatch dnMatch
193 #define numericStringSubstringsMatch NULL
195 #define caseExactIndexer caseExactIgnoreIndexer
196 #define caseExactFilter caseExactIgnoreFilter
197 #define caseExactOrderingMatch caseExactMatch
198 #define caseExactSubstringsMatch caseExactIgnoreSubstringsMatch
199 #define caseExactSubstringsIndexer caseExactIgnoreSubstringsIndexer
200 #define caseExactSubstringsFilter caseExactIgnoreSubstringsFilter
201 #define caseIgnoreIndexer caseExactIgnoreIndexer
202 #define caseIgnoreFilter caseExactIgnoreFilter
203 #define caseIgnoreOrderingMatch caseIgnoreMatch
204 #define caseIgnoreSubstringsMatch caseExactIgnoreSubstringsMatch
205 #define caseIgnoreSubstringsIndexer caseExactIgnoreSubstringsIndexer
206 #define caseIgnoreSubstringsFilter caseExactIgnoreSubstringsFilter
208 #define integerOrderingMatch integerMatch
209 #define integerFirstComponentMatch integerMatch
211 #define distinguishedNameMatch dnMatch
212 #define distinguishedNameIndexer caseExactIgnoreIndexer
213 #define distinguishedNameFilter caseExactIgnoreFilter
215 #define telephoneNumberMatch caseIgnoreIA5Match
216 #define telephoneNumberSubstringsMatch caseIgnoreIA5SubstringsMatch
217 #define telephoneNumberIndexer caseIgnoreIA5Indexer
218 #define telephoneNumberFilter caseIgnoreIA5Filter
219 #define telephoneNumberSubstringsIndexer caseIgnoreIA5SubstringsIndexer
220 #define telephoneNumberSubstringsFilter caseIgnoreIA5SubstringsFilter
224 static char *bvcasechr( struct berval *bv, unsigned char c, ber_len_t *len )
227 char lower = TOLOWER( c );
228 char upper = TOUPPER( c );
230 if( c == 0 ) return NULL;
232 for( i=0; i < bv->bv_len; i++ ) {
233 if( upper == bv->bv_val[i] || lower == bv->bv_val[i] ) {
235 return &bv->bv_val[i];
248 struct berval *value,
249 void *assertedValue )
251 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
254 match = memcmp( value->bv_val,
255 ((struct berval *) assertedValue)->bv_val,
264 octetStringOrderingMatch(
269 struct berval *value,
270 void *assertedValue )
272 ber_len_t v_len = value->bv_len;
273 ber_len_t av_len = ((struct berval *) assertedValue)->bv_len;
275 int match = memcmp( value->bv_val,
276 ((struct berval *) assertedValue)->bv_val,
277 (v_len < av_len ? v_len : av_len) );
279 if( match == 0 ) match = v_len - av_len;
285 /* Index generation function */
286 int octetStringIndexer(
291 struct berval *prefix,
298 HASH_CONTEXT HASHcontext;
299 unsigned char HASHdigest[HASH_BYTES];
300 struct berval digest;
301 digest.bv_val = HASHdigest;
302 digest.bv_len = sizeof(HASHdigest);
304 for( i=0; values[i].bv_val != NULL; i++ ) {
305 /* just count them */
308 /* we should have at least one value at this point */
311 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
313 slen = syntax->ssyn_oidlen;
314 mlen = mr->smr_oidlen;
316 for( i=0; values[i].bv_val != NULL; i++ ) {
317 HASH_Init( &HASHcontext );
318 if( prefix != NULL && prefix->bv_len > 0 ) {
319 HASH_Update( &HASHcontext,
320 prefix->bv_val, prefix->bv_len );
322 HASH_Update( &HASHcontext,
323 syntax->ssyn_oid, slen );
324 HASH_Update( &HASHcontext,
326 HASH_Update( &HASHcontext,
327 values[i].bv_val, values[i].bv_len );
328 HASH_Final( HASHdigest, &HASHcontext );
330 ber_dupbv( &keys[i], &digest );
333 keys[i].bv_val = NULL;
341 /* Index generation function */
342 int octetStringFilter(
347 struct berval *prefix,
348 void * assertedValue,
353 HASH_CONTEXT HASHcontext;
354 unsigned char HASHdigest[HASH_BYTES];
355 struct berval *value = (struct berval *) assertedValue;
356 struct berval digest;
357 digest.bv_val = HASHdigest;
358 digest.bv_len = sizeof(HASHdigest);
360 slen = syntax->ssyn_oidlen;
361 mlen = mr->smr_oidlen;
363 keys = ch_malloc( sizeof( struct berval ) * 2 );
365 HASH_Init( &HASHcontext );
366 if( prefix != NULL && prefix->bv_len > 0 ) {
367 HASH_Update( &HASHcontext,
368 prefix->bv_val, prefix->bv_len );
370 HASH_Update( &HASHcontext,
371 syntax->ssyn_oid, slen );
372 HASH_Update( &HASHcontext,
374 HASH_Update( &HASHcontext,
375 value->bv_val, value->bv_len );
376 HASH_Final( HASHdigest, &HASHcontext );
378 ber_dupbv( keys, &digest );
379 keys[1].bv_val = NULL;
392 /* no value allowed */
393 return LDAP_INVALID_SYNTAX;
401 /* any value allowed */
412 /* very unforgiving validation, requires no normalization
413 * before simplistic matching
415 if( in->bv_len < 3 ) {
416 return LDAP_INVALID_SYNTAX;
420 * rfc 2252 section 6.3 Bit String
421 * bitstring = "'" *binary-digit "'"
422 * binary-digit = "0" / "1"
423 * example: '0101111101'B
426 if( in->bv_val[0] != '\'' ||
427 in->bv_val[in->bv_len-2] != '\'' ||
428 in->bv_val[in->bv_len-1] != 'B' )
430 return LDAP_INVALID_SYNTAX;
433 for( i=in->bv_len-3; i>0; i-- ) {
434 if( in->bv_val[i] != '0' && in->bv_val[i] != '1' ) {
435 return LDAP_INVALID_SYNTAX;
450 if( in->bv_len == 0 ) return LDAP_SUCCESS;
452 ber_dupbv( &dn, in );
453 if( !dn.bv_val ) return LDAP_OTHER;
455 if( dn.bv_val[dn.bv_len-1] == 'B'
456 && dn.bv_val[dn.bv_len-2] == '\'' )
458 /* assume presence of optional UID */
461 for(i=dn.bv_len-3; i>1; i--) {
462 if( dn.bv_val[i] != '0' && dn.bv_val[i] != '1' ) {
466 if( dn.bv_val[i] != '\'' || dn.bv_val[i-1] != '#' ) {
467 ber_memfree( dn.bv_val );
468 return LDAP_INVALID_SYNTAX;
471 /* trim the UID to allow use of dnValidate */
472 dn.bv_val[i-1] = '\0';
476 rc = dnValidate( NULL, &dn );
478 ber_memfree( dn.bv_val );
488 struct berval *normalized )
493 ber_dupbv( &out, val );
494 if( out.bv_len != 0 ) {
495 struct berval uid = { 0, NULL };
497 if( out.bv_val[out.bv_len-1] == 'B'
498 && out.bv_val[out.bv_len-2] == '\'' )
500 /* assume presence of optional UID */
501 uid.bv_val = strrchr( out.bv_val, '#' );
503 if( uid.bv_val == NULL ) {
505 return LDAP_INVALID_SYNTAX;
508 uid.bv_len = out.bv_len - (uid.bv_val - out.bv_val);
509 out.bv_len -= uid.bv_len--;
511 /* temporarily trim the UID */
512 *(uid.bv_val++) = '\0';
515 rc = dnNormalize2( NULL, &out, normalized );
517 if( rc != LDAP_SUCCESS ) {
519 return LDAP_INVALID_SYNTAX;
523 normalized->bv_val = ch_realloc( normalized->bv_val,
524 normalized->bv_len + uid.bv_len + sizeof("#") );
526 /* insert the separator */
527 normalized->bv_val[normalized->bv_len++] = '#';
530 AC_MEMCPY( &normalized->bv_val[normalized->bv_len],
531 uid.bv_val, uid.bv_len );
532 normalized->bv_len += uid.bv_len;
535 normalized->bv_val[normalized->bv_len] = '\0';
546 * Handling boolean syntax and matching is quite rigid.
547 * A more flexible approach would be to allow a variety
548 * of strings to be normalized and prettied into TRUE
556 /* very unforgiving validation, requires no normalization
557 * before simplistic matching
560 if( in->bv_len == 4 ) {
561 if( !memcmp( in->bv_val, "TRUE", 4 ) ) {
564 } else if( in->bv_len == 5 ) {
565 if( !memcmp( in->bv_val, "FALSE", 5 ) ) {
570 return LDAP_INVALID_SYNTAX;
579 struct berval *value,
580 void *assertedValue )
582 /* simplistic matching allowed by rigid validation */
583 struct berval *asserted = (struct berval *) assertedValue;
584 *matchp = value->bv_len != asserted->bv_len;
588 /*-------------------------------------------------------------------
589 LDAP/X.500 string syntax / matching rules have a few oddities. This
590 comment attempts to detail how slapd(8) treats them.
593 StringSyntax X.500 LDAP Matching/Comments
594 DirectoryString CHOICE UTF8 i/e + ignore insignificant spaces
595 PrintableString subset subset i/e + ignore insignificant spaces
596 PrintableString subset subset i/e + ignore insignificant spaces
597 NumericString subset subset ignore all spaces
598 IA5String ASCII ASCII i/e + ignore insignificant spaces
599 TeletexString T.61 T.61 i/e + ignore insignificant spaces
601 TelephoneNumber subset subset i + ignore all spaces and "-"
603 See draft-ietf-ldapbis-strpro for details (once published).
607 In X.500(93), a directory string can be either a PrintableString,
608 a bmpString, or a UniversalString (e.g., UCS (a subset of Unicode)).
609 In later versions, more CHOICEs were added. In all cases the string
612 In LDAPv3, a directory string is a UTF-8 encoded UCS string.
613 A directory string cannot be zero length.
615 For matching, there are both case ignore and exact rules. Both
616 also require that "insignificant" spaces be ignored.
617 spaces before the first non-space are ignored;
618 spaces after the last non-space are ignored;
619 spaces after a space are ignored.
620 Note: by these rules (and as clarified in X.520), a string of only
621 spaces is to be treated as if held one space, not empty (which
622 would be a syntax error).
625 In ASN.1, numeric string is just a string of digits and spaces
626 and could be empty. However, in X.500, all attribute values of
627 numeric string carry a non-empty constraint. For example:
629 internationalISDNNumber ATTRIBUTE ::= {
630 WITH SYNTAX InternationalISDNNumber
631 EQUALITY MATCHING RULE numericStringMatch
632 SUBSTRINGS MATCHING RULE numericStringSubstringsMatch
633 ID id-at-internationalISDNNumber }
634 InternationalISDNNumber ::=
635 NumericString (SIZE(1..ub-international-isdn-number))
637 Unforunately, some assertion values are don't carry the same
638 constraint (but its unclear how such an assertion could ever
639 be true). In LDAP, there is one syntax (numericString) not two
640 (numericString with constraint, numericString without constraint).
641 This should be treated as numericString with non-empty constraint.
642 Note that while someone may have no ISDN number, there are no ISDN
643 numbers which are zero length.
645 In matching, spaces are ignored.
648 In ASN.1, Printable string is just a string of printable characters
649 and can be empty. In X.500, semantics much like NumericString (see
650 serialNumber for a like example) excepting uses insignificant space
651 handling instead of ignore all spaces.
654 Basically same as PrintableString. There are no examples in X.500,
655 but same logic applies. So we require them to be non-empty as
658 -------------------------------------------------------------------*/
667 unsigned char *u = in->bv_val;
669 if( in->bv_len == 0 && syntax == slap_schema.si_syn_directoryString ) {
670 /* directory strings cannot be empty */
671 return LDAP_INVALID_SYNTAX;
674 for( count = in->bv_len; count > 0; count-=len, u+=len ) {
675 /* get the length indicated by the first byte */
676 len = LDAP_UTF8_CHARLEN2( u, len );
678 /* very basic checks */
681 if( (u[5] & 0xC0) != 0x80 ) {
682 return LDAP_INVALID_SYNTAX;
685 if( (u[4] & 0xC0) != 0x80 ) {
686 return LDAP_INVALID_SYNTAX;
689 if( (u[3] & 0xC0) != 0x80 ) {
690 return LDAP_INVALID_SYNTAX;
693 if( (u[2] & 0xC0 )!= 0x80 ) {
694 return LDAP_INVALID_SYNTAX;
697 if( (u[1] & 0xC0) != 0x80 ) {
698 return LDAP_INVALID_SYNTAX;
701 /* CHARLEN already validated it */
704 return LDAP_INVALID_SYNTAX;
707 /* make sure len corresponds with the offset
708 to the next character */
709 if( LDAP_UTF8_OFFSET( u ) != len ) return LDAP_INVALID_SYNTAX;
713 return LDAP_INVALID_SYNTAX;
726 struct berval *normalized )
728 struct berval tmp, nvalue;
732 if( val->bv_val == NULL ) {
733 /* assume we're dealing with a syntax (e.g., UTF8String)
734 * which allows empty strings
736 normalized->bv_len = 0;
737 normalized->bv_val = NULL;
741 flags = SLAP_MR_ASSOCIATED(mr, slap_schema.si_mr_caseExactMatch )
742 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
743 flags |= ( use & SLAP_MR_EQUALITY_APPROX == SLAP_MR_EQUALITY_APPROX )
744 ? LDAP_UTF8_APPROX : 0;
746 val = UTF8bvnormalize( val, &tmp, flags );
751 /* collapse spaces (in place) */
753 nvalue.bv_val = tmp.bv_val;
755 wasspace=1; /* trim leading spaces */
756 for( i=0; i<tmp.bv_len; i++) {
757 if ( ASCII_SPACE( tmp.bv_val[i] )) {
758 if( wasspace++ == 0 ) {
759 /* trim repeated spaces */
760 nvalue.bv_val[nvalue.bv_len++] = tmp.bv_val[i];
764 nvalue.bv_val[nvalue.bv_len++] = tmp.bv_val[i];
768 if( nvalue.bv_len ) {
770 /* last character was a space, trim it */
773 nvalue.bv_val[nvalue.bv_len] = '\0';
776 /* string of all spaces is treated as one space */
777 nvalue.bv_val[0] = ' ';
778 nvalue.bv_val[1] = '\0';
787 xUTF8StringNormalize(
790 struct berval *normalized )
795 /* validator should have refused an empty string */
796 assert( val->bv_len );
800 /* Ignore initial whitespace */
801 /* All space is ASCII. All ASCII is 1 byte */
802 for ( ; p < val->bv_val + val->bv_len && ASCII_SPACE( p[ 0 ] ); p++ );
804 normalized->bv_len = val->bv_len - (p - val->bv_val);
806 if( !normalized->bv_len ) {
807 ber_mem2bv( " ", 1, 1, normalized );
811 ber_mem2bv( p, normalized->bv_len, 1, normalized );
812 e = normalized->bv_val + normalized->bv_len;
814 assert( normalized->bv_val );
816 p = q = normalized->bv_val;
821 if ( ASCII_SPACE( *p ) ) {
826 /* Ignore the extra whitespace */
827 while ( ASCII_SPACE( *p ) ) {
831 len = LDAP_UTF8_COPY(q,p);
837 assert( normalized->bv_val <= p );
838 assert( q+len <= p );
840 /* cannot start with a space */
841 assert( !ASCII_SPACE( normalized->bv_val[0] ) );
844 * If the string ended in space, backup the pointer one
845 * position. One is enough because the above loop collapsed
846 * all whitespace to a single space.
854 /* cannot end with a space */
855 assert( !ASCII_SPACE( *q ) );
862 normalized->bv_len = q - normalized->bv_val;
867 /* Returns Unicode canonically normalized copy of a substring assertion
868 * Skipping attribute description */
869 static SubstringsAssertion *
870 UTF8SubstringsAssertionNormalize(
871 SubstringsAssertion *sa,
874 SubstringsAssertion *nsa;
877 nsa = (SubstringsAssertion *)SLAP_CALLOC( 1, sizeof(SubstringsAssertion) );
882 if( sa->sa_initial.bv_val != NULL ) {
883 UTF8bvnormalize( &sa->sa_initial, &nsa->sa_initial, casefold );
884 if( nsa->sa_initial.bv_val == NULL ) {
889 if( sa->sa_any != NULL ) {
890 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
893 nsa->sa_any = (struct berval *)
894 SLAP_MALLOC( (i + 1) * sizeof(struct berval) );
895 if( nsa->sa_any == NULL ) {
899 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
900 UTF8bvnormalize( &sa->sa_any[i], &nsa->sa_any[i],
902 if( nsa->sa_any[i].bv_val == NULL ) {
906 nsa->sa_any[i].bv_val = NULL;
909 if( sa->sa_final.bv_val != NULL ) {
910 UTF8bvnormalize( &sa->sa_final, &nsa->sa_final, casefold );
911 if( nsa->sa_final.bv_val == NULL ) {
919 if ( nsa->sa_final.bv_val ) free( nsa->sa_final.bv_val );
920 if ( nsa->sa_any ) ber_bvarray_free( nsa->sa_any );
921 if ( nsa->sa_initial.bv_val ) free( nsa->sa_initial.bv_val );
926 #ifndef SLAPD_APPROX_OLDSINGLESTRING
928 #if defined(SLAPD_APPROX_INITIALS)
929 #define SLAPD_APPROX_DELIMITER "._ "
930 #define SLAPD_APPROX_WORDLEN 2
932 #define SLAPD_APPROX_DELIMITER " "
933 #define SLAPD_APPROX_WORDLEN 1
942 struct berval *value,
943 void *assertedValue )
945 struct berval *nval, *assertv;
946 char *val, **values, **words, *c;
947 int i, count, len, nextchunk=0, nextavail=0;
949 /* Yes, this is necessary */
950 nval = UTF8bvnormalize( value, NULL, LDAP_UTF8_APPROX );
956 /* Yes, this is necessary */
957 assertv = UTF8bvnormalize( ((struct berval *)assertedValue),
958 NULL, LDAP_UTF8_APPROX );
959 if( assertv == NULL ) {
965 /* Isolate how many words there are */
966 for ( c = nval->bv_val, count = 1; *c; c++ ) {
967 c = strpbrk( c, SLAPD_APPROX_DELIMITER );
968 if ( c == NULL ) break;
973 /* Get a phonetic copy of each word */
974 words = (char **)ch_malloc( count * sizeof(char *) );
975 values = (char **)ch_malloc( count * sizeof(char *) );
976 for ( c = nval->bv_val, i = 0; i < count; i++, c += strlen(c) + 1 ) {
978 values[i] = phonetic(c);
981 /* Work through the asserted value's words, to see if at least some
982 of the words are there, in the same order. */
984 while ( (ber_len_t) nextchunk < assertv->bv_len ) {
985 len = strcspn( assertv->bv_val + nextchunk, SLAPD_APPROX_DELIMITER);
990 #if defined(SLAPD_APPROX_INITIALS)
991 else if( len == 1 ) {
992 /* Single letter words need to at least match one word's initial */
993 for( i=nextavail; i<count; i++ )
994 if( !strncasecmp( assertv->bv_val + nextchunk, words[i], 1 )) {
1001 /* Isolate the next word in the asserted value and phonetic it */
1002 assertv->bv_val[nextchunk+len] = '\0';
1003 val = phonetic( assertv->bv_val + nextchunk );
1005 /* See if this phonetic chunk is in the remaining words of *value */
1006 for( i=nextavail; i<count; i++ ){
1007 if( !strcmp( val, values[i] ) ){
1015 /* This chunk in the asserted value was NOT within the *value. */
1021 /* Go on to the next word in the asserted value */
1025 /* If some of the words were seen, call it a match */
1026 if( nextavail > 0 ) {
1033 /* Cleanup allocs */
1034 ber_bvfree( assertv );
1035 for( i=0; i<count; i++ ) {
1036 ch_free( values[i] );
1042 return LDAP_SUCCESS;
1051 struct berval *prefix,
1056 int i,j, len, wordcount, keycount=0;
1057 struct berval *newkeys;
1058 BerVarray keys=NULL;
1060 for( j=0; values[j].bv_val != NULL; j++ ) {
1061 struct berval val = { 0, NULL };
1062 /* Yes, this is necessary */
1063 UTF8bvnormalize( &values[j], &val, LDAP_UTF8_APPROX );
1064 assert( val.bv_val != NULL );
1066 /* Isolate how many words there are. There will be a key for each */
1067 for( wordcount = 0, c = val.bv_val; *c; c++) {
1068 len = strcspn(c, SLAPD_APPROX_DELIMITER);
1069 if( len >= SLAPD_APPROX_WORDLEN ) wordcount++;
1071 if (*c == '\0') break;
1075 /* Allocate/increase storage to account for new keys */
1076 newkeys = (struct berval *)ch_malloc( (keycount + wordcount + 1)
1077 * sizeof(struct berval) );
1078 AC_MEMCPY( newkeys, keys, keycount * sizeof(struct berval) );
1079 if( keys ) ch_free( keys );
1082 /* Get a phonetic copy of each word */
1083 for( c = val.bv_val, i = 0; i < wordcount; c += len + 1 ) {
1085 if( len < SLAPD_APPROX_WORDLEN ) continue;
1086 ber_str2bv( phonetic( c ), 0, 0, &keys[keycount] );
1091 ber_memfree( val.bv_val );
1093 keys[keycount].bv_val = NULL;
1096 return LDAP_SUCCESS;
1105 struct berval *prefix,
1106 void * assertedValue,
1114 /* Yes, this is necessary */
1115 val = UTF8bvnormalize( ((struct berval *)assertedValue),
1116 NULL, LDAP_UTF8_APPROX );
1117 if( val == NULL || val->bv_val == NULL ) {
1118 keys = (struct berval *)ch_malloc( sizeof(struct berval) );
1119 keys[0].bv_val = NULL;
1122 return LDAP_SUCCESS;
1125 /* Isolate how many words there are. There will be a key for each */
1126 for( count = 0,c = val->bv_val; *c; c++) {
1127 len = strcspn(c, SLAPD_APPROX_DELIMITER);
1128 if( len >= SLAPD_APPROX_WORDLEN ) count++;
1130 if (*c == '\0') break;
1134 /* Allocate storage for new keys */
1135 keys = (struct berval *)ch_malloc( (count + 1) * sizeof(struct berval) );
1137 /* Get a phonetic copy of each word */
1138 for( c = val->bv_val, i = 0; i < count; c += len + 1 ) {
1140 if( len < SLAPD_APPROX_WORDLEN ) continue;
1141 ber_str2bv( phonetic( c ), 0, 0, &keys[i] );
1147 keys[count].bv_val = NULL;
1150 return LDAP_SUCCESS;
1155 /* No other form of Approximate Matching is defined */
1163 struct berval *value,
1164 void *assertedValue )
1166 char *vapprox, *avapprox;
1169 /* Yes, this is necessary */
1170 s = UTF8normalize( value, UTF8_NOCASEFOLD );
1173 return LDAP_SUCCESS;
1176 /* Yes, this is necessary */
1177 t = UTF8normalize( ((struct berval *)assertedValue),
1182 return LDAP_SUCCESS;
1185 vapprox = phonetic( strip8bitChars( s ) );
1186 avapprox = phonetic( strip8bitChars( t ) );
1191 *matchp = strcmp( vapprox, avapprox );
1194 ch_free( avapprox );
1196 return LDAP_SUCCESS;
1205 struct berval *prefix,
1213 for( i=0; values[i].bv_val != NULL; i++ ) {
1214 /* empty - just count them */
1217 /* we should have at least one value at this point */
1220 keys = (struct berval *)ch_malloc( sizeof( struct berval ) * (i+1) );
1222 /* Copy each value and run it through phonetic() */
1223 for( i=0; values[i].bv_val != NULL; i++ ) {
1224 /* Yes, this is necessary */
1225 s = UTF8normalize( &values[i], UTF8_NOCASEFOLD );
1227 /* strip 8-bit chars and run through phonetic() */
1228 ber_str2bv( phonetic( strip8bitChars( s ) ), 0, 0, &keys[i] );
1231 keys[i].bv_val = NULL;
1234 return LDAP_SUCCESS;
1244 struct berval *prefix,
1245 void * assertedValue,
1251 keys = (struct berval *)ch_malloc( sizeof( struct berval * ) * 2 );
1253 /* Yes, this is necessary */
1254 s = UTF8normalize( ((struct berval *)assertedValue),
1259 /* strip 8-bit chars and run through phonetic() */
1260 keys[0] = ber_bvstr( phonetic( strip8bitChars( s ) ) );
1266 return LDAP_SUCCESS;
1277 struct berval *value,
1278 void *assertedValue )
1280 *matchp = UTF8bvnormcmp( value,
1281 (struct berval *) assertedValue,
1282 LDAP_UTF8_NOCASEFOLD );
1283 return LDAP_SUCCESS;
1287 caseExactIgnoreSubstringsMatch(
1292 struct berval *value,
1293 void *assertedValue )
1296 SubstringsAssertion *sub = NULL;
1297 struct berval left = { 0, NULL };
1303 casefold = ( mr != slap_schema.si_mr_caseExactSubstringsMatch )
1304 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1306 if ( UTF8bvnormalize( value, &left, casefold ) == NULL ) {
1312 sub = UTF8SubstringsAssertionNormalize( assertedValue, casefold );
1318 /* Add up asserted input length */
1319 if( sub->sa_initial.bv_val ) {
1320 inlen += sub->sa_initial.bv_len;
1323 for(i=0; sub->sa_any[i].bv_val != NULL; i++) {
1324 inlen += sub->sa_any[i].bv_len;
1327 if( sub->sa_final.bv_val ) {
1328 inlen += sub->sa_final.bv_len;
1331 if( sub->sa_initial.bv_val ) {
1332 if( inlen > left.bv_len ) {
1337 match = memcmp( sub->sa_initial.bv_val, left.bv_val,
1338 sub->sa_initial.bv_len );
1344 left.bv_val += sub->sa_initial.bv_len;
1345 left.bv_len -= sub->sa_initial.bv_len;
1346 inlen -= sub->sa_initial.bv_len;
1349 if( sub->sa_final.bv_val ) {
1350 if( inlen > left.bv_len ) {
1355 match = memcmp( sub->sa_final.bv_val,
1356 &left.bv_val[left.bv_len - sub->sa_final.bv_len],
1357 sub->sa_final.bv_len );
1363 left.bv_len -= sub->sa_final.bv_len;
1364 inlen -= sub->sa_final.bv_len;
1368 for(i=0; sub->sa_any[i].bv_val; i++) {
1373 if( inlen > left.bv_len ) {
1374 /* not enough length */
1379 if( sub->sa_any[i].bv_len == 0 ) {
1383 p = ber_bvchr( &left, *sub->sa_any[i].bv_val );
1389 idx = p - left.bv_val;
1391 if( idx >= left.bv_len ) {
1392 /* this shouldn't happen */
1394 if ( sub->sa_final.bv_val )
1395 ch_free( sub->sa_final.bv_val );
1397 ber_bvarray_free( sub->sa_any );
1398 if ( sub->sa_initial.bv_val )
1399 ch_free( sub->sa_initial.bv_val );
1407 if( sub->sa_any[i].bv_len > left.bv_len ) {
1408 /* not enough left */
1413 match = memcmp( left.bv_val,
1414 sub->sa_any[i].bv_val,
1415 sub->sa_any[i].bv_len );
1423 left.bv_val += sub->sa_any[i].bv_len;
1424 left.bv_len -= sub->sa_any[i].bv_len;
1425 inlen -= sub->sa_any[i].bv_len;
1432 if ( sub->sa_final.bv_val ) free( sub->sa_final.bv_val );
1433 if ( sub->sa_any ) ber_bvarray_free( sub->sa_any );
1434 if ( sub->sa_initial.bv_val ) free( sub->sa_initial.bv_val );
1438 return LDAP_SUCCESS;
1441 /* Index generation function */
1442 static int caseExactIgnoreIndexer(
1447 struct berval *prefix,
1452 unsigned casefold,wasspace;
1455 HASH_CONTEXT HASHcontext;
1456 unsigned char HASHdigest[HASH_BYTES];
1457 struct berval digest;
1458 digest.bv_val = HASHdigest;
1459 digest.bv_len = sizeof(HASHdigest);
1461 for( i=0; values[i].bv_val != NULL; i++ ) {
1462 /* empty - just count them */
1465 /* we should have at least one value at this point */
1468 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
1470 slen = syntax->ssyn_oidlen;
1471 mlen = mr->smr_oidlen;
1473 casefold = ( mr != slap_schema.si_mr_caseExactMatch )
1474 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1476 for( i=0; values[i].bv_val != NULL; i++ ) {
1477 struct berval value, nvalue;
1478 UTF8bvnormalize( &values[i], &value, casefold );
1480 /* collapse spaces (in place) */
1482 nvalue.bv_val = value.bv_val;
1485 for( j=0; j<value.bv_len; j++) {
1486 if ( ASCII_SPACE( value.bv_val[j] )) {
1487 if( wasspace++ == 0 ) {
1488 nvalue.bv_val[nvalue.bv_len++] = value.bv_val[j];
1492 nvalue.bv_val[nvalue.bv_len++] = value.bv_val[j];
1496 if( nvalue.bv_len == 0 ) {
1497 nvalue.bv_val = " ";
1498 nvalue.bv_len = sizeof(" ")-1;
1500 if( wasspace ) --nvalue.bv_len;
1501 nvalue.bv_val[nvalue.bv_len] = '\0';
1504 HASH_Init( &HASHcontext );
1505 if( prefix != NULL && prefix->bv_len > 0 ) {
1506 HASH_Update( &HASHcontext,
1507 prefix->bv_val, prefix->bv_len );
1509 HASH_Update( &HASHcontext,
1510 syntax->ssyn_oid, slen );
1511 HASH_Update( &HASHcontext,
1512 mr->smr_oid, mlen );
1513 HASH_Update( &HASHcontext,
1514 nvalue.bv_val, nvalue.bv_len );
1515 HASH_Final( HASHdigest, &HASHcontext );
1517 free( value.bv_val );
1518 ber_dupbv( &keys[i], &digest );
1521 keys[i].bv_val = NULL;
1523 return LDAP_SUCCESS;
1526 /* Index generation function */
1527 static int caseExactIgnoreFilter(
1532 struct berval *prefix,
1533 void * assertedValue,
1539 HASH_CONTEXT HASHcontext;
1540 unsigned char HASHdigest[HASH_BYTES];
1541 struct berval value = { 0, NULL };
1542 struct berval digest;
1544 digest.bv_val = HASHdigest;
1545 digest.bv_len = sizeof(HASHdigest);
1547 slen = syntax->ssyn_oidlen;
1548 mlen = mr->smr_oidlen;
1550 casefold = ( mr != slap_schema.si_mr_caseExactMatch )
1551 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1553 UTF8bvnormalize( (struct berval *) assertedValue, &value, casefold );
1554 /* This usually happens if filter contains bad UTF8 */
1555 if( value.bv_val == NULL ) {
1556 keys = ch_malloc( sizeof( struct berval ) );
1557 keys[0].bv_val = NULL;
1558 return LDAP_SUCCESS;
1561 keys = ch_malloc( sizeof( struct berval ) * 2 );
1563 HASH_Init( &HASHcontext );
1564 if( prefix != NULL && prefix->bv_len > 0 ) {
1565 HASH_Update( &HASHcontext,
1566 prefix->bv_val, prefix->bv_len );
1568 HASH_Update( &HASHcontext,
1569 syntax->ssyn_oid, slen );
1570 HASH_Update( &HASHcontext,
1571 mr->smr_oid, mlen );
1572 HASH_Update( &HASHcontext,
1573 value.bv_val, value.bv_len );
1574 HASH_Final( HASHdigest, &HASHcontext );
1576 ber_dupbv( keys, &digest );
1577 keys[1].bv_val = NULL;
1579 free( value.bv_val );
1582 return LDAP_SUCCESS;
1585 /* Substrings Index generation function */
1586 static int caseExactIgnoreSubstringsIndexer(
1591 struct berval *prefix,
1595 unsigned casefold, wasspace;
1596 ber_len_t i, j, nkeys;
1599 BerVarray tvalues, nvalues;
1601 HASH_CONTEXT HASHcontext;
1602 unsigned char HASHdigest[HASH_BYTES];
1603 struct berval digest;
1604 digest.bv_val = HASHdigest;
1605 digest.bv_len = sizeof(HASHdigest);
1609 for( i=0; values[i].bv_val != NULL; i++ ) {
1610 /* empty - just count them */
1613 /* we should have at least one value at this point */
1616 casefold = ( mr != slap_schema.si_mr_caseExactSubstringsMatch )
1617 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1619 tvalues = ch_malloc( sizeof( struct berval ) * (i+1) );
1620 nvalues = ch_malloc( sizeof( struct berval ) * (i+1) );
1622 for( i=0; values[i].bv_val != NULL; i++ ) {
1623 UTF8bvnormalize( &values[i], &tvalues[i], casefold );
1625 /* collapse spaces (in place) */
1626 nvalues[i].bv_len = 0;
1627 nvalues[i].bv_val = tvalues[i].bv_val;
1630 for( j=0; j<tvalues[i].bv_len; j++) {
1631 if ( ASCII_SPACE( tvalues[i].bv_val[j] )) {
1632 if( wasspace++ == 0 ) {
1633 nvalues[i].bv_val[nvalues[i].bv_len++] =
1634 tvalues[i].bv_val[j];
1638 nvalues[i].bv_val[nvalues[i].bv_len++] = tvalues[i].bv_val[j];
1642 if( nvalues[i].bv_len == 0 ) {
1643 nvalues[i].bv_val = " ";
1644 nvalues[i].bv_len = sizeof(" ")-1;
1646 if( wasspace ) --nvalues[i].bv_len;
1647 nvalues[i].bv_val[nvalues[i].bv_len] = '\0';
1651 tvalues[i].bv_val = NULL;
1652 nvalues[i].bv_val = NULL;
1655 for( i=0; values[i].bv_val != NULL; i++ ) {
1656 /* count number of indices to generate */
1657 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
1661 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
1662 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1663 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
1664 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
1666 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
1670 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
1671 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1672 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
1676 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
1677 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1678 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
1679 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
1681 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
1687 /* no keys to generate */
1689 ber_bvarray_free( tvalues );
1691 return LDAP_SUCCESS;
1694 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
1696 slen = syntax->ssyn_oidlen;
1697 mlen = mr->smr_oidlen;
1700 for( i=0; values[i].bv_val != NULL; i++ ) {
1703 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
1705 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
1706 ( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
1708 char pre = SLAP_INDEX_SUBSTR_PREFIX;
1709 max = values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
1711 for( j=0; j<max; j++ ) {
1712 HASH_Init( &HASHcontext );
1713 if( prefix != NULL && prefix->bv_len > 0 ) {
1714 HASH_Update( &HASHcontext,
1715 prefix->bv_val, prefix->bv_len );
1718 HASH_Update( &HASHcontext,
1719 &pre, sizeof( pre ) );
1720 HASH_Update( &HASHcontext,
1721 syntax->ssyn_oid, slen );
1722 HASH_Update( &HASHcontext,
1723 mr->smr_oid, mlen );
1724 HASH_Update( &HASHcontext,
1725 &values[i].bv_val[j],
1726 SLAP_INDEX_SUBSTR_MAXLEN );
1727 HASH_Final( HASHdigest, &HASHcontext );
1729 ber_dupbv( &keys[nkeys++], &digest );
1733 max = SLAP_INDEX_SUBSTR_MAXLEN < values[i].bv_len
1734 ? SLAP_INDEX_SUBSTR_MAXLEN : values[i].bv_len;
1736 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
1739 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
1740 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
1741 HASH_Init( &HASHcontext );
1742 if( prefix != NULL && prefix->bv_len > 0 ) {
1743 HASH_Update( &HASHcontext,
1744 prefix->bv_val, prefix->bv_len );
1746 HASH_Update( &HASHcontext,
1747 &pre, sizeof( pre ) );
1748 HASH_Update( &HASHcontext,
1749 syntax->ssyn_oid, slen );
1750 HASH_Update( &HASHcontext,
1751 mr->smr_oid, mlen );
1752 HASH_Update( &HASHcontext,
1753 values[i].bv_val, j );
1754 HASH_Final( HASHdigest, &HASHcontext );
1756 ber_dupbv( &keys[nkeys++], &digest );
1759 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
1760 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
1761 HASH_Init( &HASHcontext );
1762 if( prefix != NULL && prefix->bv_len > 0 ) {
1763 HASH_Update( &HASHcontext,
1764 prefix->bv_val, prefix->bv_len );
1766 HASH_Update( &HASHcontext,
1767 &pre, sizeof( pre ) );
1768 HASH_Update( &HASHcontext,
1769 syntax->ssyn_oid, slen );
1770 HASH_Update( &HASHcontext,
1771 mr->smr_oid, mlen );
1772 HASH_Update( &HASHcontext,
1773 &values[i].bv_val[values[i].bv_len-j], j );
1774 HASH_Final( HASHdigest, &HASHcontext );
1776 ber_dupbv( &keys[nkeys++], &digest );
1784 keys[nkeys].bv_val = NULL;
1791 ber_bvarray_free( tvalues );
1794 return LDAP_SUCCESS;
1797 static int caseExactIgnoreSubstringsFilter(
1802 struct berval *prefix,
1803 void * assertedValue,
1806 SubstringsAssertion *sa;
1809 ber_len_t nkeys = 0;
1810 size_t slen, mlen, klen;
1812 HASH_CONTEXT HASHcontext;
1813 unsigned char HASHdigest[HASH_BYTES];
1814 struct berval *value;
1815 struct berval digest;
1817 casefold = ( mr != slap_schema.si_mr_caseExactSubstringsMatch )
1818 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1820 sa = UTF8SubstringsAssertionNormalize( assertedValue, casefold );
1823 return LDAP_SUCCESS;
1826 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
1827 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1832 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
1834 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
1835 if( sa->sa_any[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1836 /* don't bother accounting for stepping */
1837 nkeys += sa->sa_any[i].bv_len -
1838 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
1843 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
1844 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1850 if ( sa->sa_final.bv_val ) free( sa->sa_final.bv_val );
1851 if ( sa->sa_any ) ber_bvarray_free( sa->sa_any );
1852 if ( sa->sa_initial.bv_val ) free( sa->sa_initial.bv_val );
1855 return LDAP_SUCCESS;
1858 digest.bv_val = HASHdigest;
1859 digest.bv_len = sizeof(HASHdigest);
1861 slen = syntax->ssyn_oidlen;
1862 mlen = mr->smr_oidlen;
1864 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
1867 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
1868 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1870 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
1871 value = &sa->sa_initial;
1873 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
1874 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
1876 HASH_Init( &HASHcontext );
1877 if( prefix != NULL && prefix->bv_len > 0 ) {
1878 HASH_Update( &HASHcontext,
1879 prefix->bv_val, prefix->bv_len );
1881 HASH_Update( &HASHcontext,
1882 &pre, sizeof( pre ) );
1883 HASH_Update( &HASHcontext,
1884 syntax->ssyn_oid, slen );
1885 HASH_Update( &HASHcontext,
1886 mr->smr_oid, mlen );
1887 HASH_Update( &HASHcontext,
1888 value->bv_val, klen );
1889 HASH_Final( HASHdigest, &HASHcontext );
1891 ber_dupbv( &keys[nkeys++], &digest );
1894 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
1896 pre = SLAP_INDEX_SUBSTR_PREFIX;
1897 klen = SLAP_INDEX_SUBSTR_MAXLEN;
1899 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
1900 if( sa->sa_any[i].bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
1904 value = &sa->sa_any[i];
1907 j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
1908 j += SLAP_INDEX_SUBSTR_STEP )
1910 HASH_Init( &HASHcontext );
1911 if( prefix != NULL && prefix->bv_len > 0 ) {
1912 HASH_Update( &HASHcontext,
1913 prefix->bv_val, prefix->bv_len );
1915 HASH_Update( &HASHcontext,
1916 &pre, sizeof( pre ) );
1917 HASH_Update( &HASHcontext,
1918 syntax->ssyn_oid, slen );
1919 HASH_Update( &HASHcontext,
1920 mr->smr_oid, mlen );
1921 HASH_Update( &HASHcontext,
1922 &value->bv_val[j], klen );
1923 HASH_Final( HASHdigest, &HASHcontext );
1925 ber_dupbv( &keys[nkeys++], &digest );
1931 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
1932 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1934 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
1935 value = &sa->sa_final;
1937 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
1938 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
1940 HASH_Init( &HASHcontext );
1941 if( prefix != NULL && prefix->bv_len > 0 ) {
1942 HASH_Update( &HASHcontext,
1943 prefix->bv_val, prefix->bv_len );
1945 HASH_Update( &HASHcontext,
1946 &pre, sizeof( pre ) );
1947 HASH_Update( &HASHcontext,
1948 syntax->ssyn_oid, slen );
1949 HASH_Update( &HASHcontext,
1950 mr->smr_oid, mlen );
1951 HASH_Update( &HASHcontext,
1952 &value->bv_val[value->bv_len-klen], klen );
1953 HASH_Final( HASHdigest, &HASHcontext );
1955 ber_dupbv( &keys[nkeys++], &digest );
1959 keys[nkeys].bv_val = NULL;
1965 if ( sa->sa_final.bv_val ) free( sa->sa_final.bv_val );
1966 if ( sa->sa_any ) ber_bvarray_free( sa->sa_any );
1967 if ( sa->sa_initial.bv_val ) free( sa->sa_initial.bv_val );
1970 return LDAP_SUCCESS;
1979 struct berval *value,
1980 void *assertedValue )
1982 *matchp = UTF8bvnormcmp( value,
1983 (struct berval *) assertedValue,
1984 LDAP_UTF8_CASEFOLD );
1985 return LDAP_SUCCESS;
1988 /* Remove all spaces and '-' characters */
1990 xtelephoneNumberNormalize(
1993 struct berval *normalized )
1997 /* validator should have refused an empty string */
1998 assert( val->bv_len );
2000 q = normalized->bv_val = ch_malloc( val->bv_len + 1 );
2002 for( p = val->bv_val; *p; p++ ) {
2003 if ( ! ( ASCII_SPACE( *p ) || *p == '-' )) {
2009 normalized->bv_len = q - normalized->bv_val;
2011 if( normalized->bv_len == 0 ) {
2012 free( normalized->bv_val );
2013 return LDAP_INVALID_SYNTAX;
2016 return LDAP_SUCCESS;
2023 struct berval *val )
2027 if( val->bv_len == 0 ) {
2028 /* disallow empty strings */
2029 return LDAP_INVALID_SYNTAX;
2032 if( OID_LEADCHAR(val->bv_val[0]) ) {
2034 for(i=1; i < val->bv_len; i++) {
2035 if( OID_SEPARATOR( val->bv_val[i] ) ) {
2036 if( dot++ ) return 1;
2037 } else if ( OID_CHAR( val->bv_val[i] ) ) {
2040 return LDAP_INVALID_SYNTAX;
2044 return !dot ? LDAP_SUCCESS : LDAP_INVALID_SYNTAX;
2046 } else if( DESC_LEADCHAR(val->bv_val[0]) ) {
2047 for(i=1; i < val->bv_len; i++) {
2048 if( !DESC_CHAR(val->bv_val[i] ) ) {
2049 return LDAP_INVALID_SYNTAX;
2053 return LDAP_SUCCESS;
2056 return LDAP_INVALID_SYNTAX;
2059 #ifndef SLAP_NVALUES
2067 struct berval *value,
2068 void *assertedValue )
2071 int vsign = 1, avsign = 1; /* default sign = '+' */
2072 struct berval *asserted;
2073 ber_len_t vlen, avlen;
2076 /* Skip leading space/sign/zeroes, and get the sign of the *value number */
2078 vlen = value->bv_len;
2079 if( mr == slap_schema.si_mr_integerFirstComponentMatch ) {
2080 char *tmp = memchr( v, '$', vlen );
2083 while( vlen && ASCII_SPACE( v[vlen-1] ))
2086 for( ; vlen && ( *v < '1' || '9' < *v ); v++, vlen-- ) /* ANSI 2.2.1 */
2092 /* Do the same with the *assertedValue number */
2093 asserted = (struct berval *) assertedValue;
2094 av = asserted->bv_val;
2095 avlen = asserted->bv_len;
2096 for( ; avlen && ( *av < '1' || '9' < *av ); av++, avlen-- )
2102 match = vsign - avsign;
2104 match = (vlen != avlen
2105 ? ( vlen < avlen ? -1 : 1 )
2106 : memcmp( v, av, vlen ));
2112 return LDAP_SUCCESS;
2119 struct berval *val )
2123 if( !val->bv_len ) return LDAP_INVALID_SYNTAX;
2125 if(( val->bv_val[0] == '+' ) || ( val->bv_val[0] == '-' )) {
2126 if( val->bv_len < 2 ) return LDAP_INVALID_SYNTAX;
2127 } else if( !ASCII_DIGIT(val->bv_val[0]) ) {
2128 return LDAP_INVALID_SYNTAX;
2131 for( i=1; i < val->bv_len; i++ ) {
2132 if( !ASCII_DIGIT(val->bv_val[i]) ) return LDAP_INVALID_SYNTAX;
2135 return LDAP_SUCCESS;
2138 #ifndef SLAP_NVALUES
2143 struct berval *normalized )
2153 /* Ignore leading spaces */
2154 while ( len && ( *p == ' ' )) {
2161 negative = ( *p == '-' );
2162 if(( *p == '-' ) || ( *p == '+' )) {
2168 /* Ignore leading zeros */
2169 while ( len && ( *p == '0' )) {
2174 /* If there are no non-zero digits left, the number is zero, otherwise
2175 allocate space for the number and copy it into the buffer */
2177 normalized->bv_val = ch_strdup("0");
2178 normalized->bv_len = 1;
2181 normalized->bv_len = len+negative;
2182 normalized->bv_val = ch_malloc( normalized->bv_len + 1 );
2184 normalized->bv_val[0] = '-';
2186 AC_MEMCPY( normalized->bv_val + negative, p, len );
2187 normalized->bv_val[len+negative] = '\0';
2190 return LDAP_SUCCESS;
2193 /* Index generation function */
2194 static int integerIndexer(
2199 struct berval *prefix,
2206 HASH_CONTEXT HASHcontext;
2207 unsigned char HASHdigest[HASH_BYTES];
2208 struct berval digest;
2209 digest.bv_val = HASHdigest;
2210 digest.bv_len = sizeof(HASHdigest);
2212 for( i=0; values[i].bv_val != NULL; i++ ) {
2213 /* empty - just count them */
2216 /* we should have at least one value at this point */
2219 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
2221 slen = syntax->ssyn_oidlen;
2222 mlen = mr->smr_oidlen;
2224 for( i=0; values[i].bv_val != NULL; i++ ) {
2226 xintegerNormalize( syntax, &values[i], &norm );
2228 HASH_Init( &HASHcontext );
2229 if( prefix != NULL && prefix->bv_len > 0 ) {
2230 HASH_Update( &HASHcontext,
2231 prefix->bv_val, prefix->bv_len );
2233 HASH_Update( &HASHcontext,
2234 syntax->ssyn_oid, slen );
2235 HASH_Update( &HASHcontext,
2236 mr->smr_oid, mlen );
2237 HASH_Update( &HASHcontext,
2238 norm.bv_val, norm.bv_len );
2239 HASH_Final( HASHdigest, &HASHcontext );
2241 ber_dupbv( &keys[i], &digest );
2242 ch_free( norm.bv_val );
2245 keys[i].bv_val = NULL;
2247 return LDAP_SUCCESS;
2250 /* Index generation function */
2251 static int integerFilter(
2256 struct berval *prefix,
2257 void * assertedValue,
2262 HASH_CONTEXT HASHcontext;
2263 unsigned char HASHdigest[HASH_BYTES];
2265 struct berval digest;
2266 digest.bv_val = HASHdigest;
2267 digest.bv_len = sizeof(HASHdigest);
2269 slen = syntax->ssyn_oidlen;
2270 mlen = mr->smr_oidlen;
2272 xintegerNormalize( syntax, assertedValue, &norm );
2274 keys = ch_malloc( sizeof( struct berval ) * 2 );
2276 HASH_Init( &HASHcontext );
2277 if( prefix != NULL && prefix->bv_len > 0 ) {
2278 HASH_Update( &HASHcontext,
2279 prefix->bv_val, prefix->bv_len );
2281 HASH_Update( &HASHcontext,
2282 syntax->ssyn_oid, slen );
2283 HASH_Update( &HASHcontext,
2284 mr->smr_oid, mlen );
2285 HASH_Update( &HASHcontext,
2286 norm.bv_val, norm.bv_len );
2287 HASH_Final( HASHdigest, &HASHcontext );
2289 ber_dupbv( &keys[0], &digest );
2290 keys[1].bv_val = NULL;
2291 ch_free( norm.bv_val );
2294 return LDAP_SUCCESS;
2300 countryStringValidate(
2302 struct berval *val )
2304 if( val->bv_len != 2 ) return LDAP_INVALID_SYNTAX;
2306 if( !SLAP_PRINTABLE(val->bv_val[0]) ) {
2307 return LDAP_INVALID_SYNTAX;
2309 if( !SLAP_PRINTABLE(val->bv_val[1]) ) {
2310 return LDAP_INVALID_SYNTAX;
2313 return LDAP_SUCCESS;
2317 printableStringValidate(
2319 struct berval *val )
2323 if( val->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
2325 for(i=0; i < val->bv_len; i++) {
2326 if( !SLAP_PRINTABLE(val->bv_val[i]) ) {
2327 return LDAP_INVALID_SYNTAX;
2331 return LDAP_SUCCESS;
2335 printablesStringValidate(
2337 struct berval *val )
2341 if( val->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
2343 for(i=0,len=0; i < val->bv_len; i++) {
2344 int c = val->bv_val[i];
2348 return LDAP_INVALID_SYNTAX;
2352 } else if ( SLAP_PRINTABLE(c) ) {
2355 return LDAP_INVALID_SYNTAX;
2360 return LDAP_INVALID_SYNTAX;
2363 return LDAP_SUCCESS;
2369 struct berval *val )
2373 if( val->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
2375 for(i=0; i < val->bv_len; i++) {
2376 if( !LDAP_ASCII(val->bv_val[i]) ) {
2377 return LDAP_INVALID_SYNTAX;
2381 return LDAP_SUCCESS;
2391 struct berval *normalized )
2394 xIA5StringNormalize(
2397 struct berval *normalized )
2402 int casefold = !SLAP_MR_ASSOCIATED(mr, slap_schema.si_mr_caseExactIA5Match);
2405 assert( val->bv_len );
2409 /* Ignore initial whitespace */
2410 while ( ASCII_SPACE( *p ) ) {
2414 normalized->bv_val = ch_strdup( p );
2415 p = q = normalized->bv_val;
2418 if ( ASCII_SPACE( *p ) ) {
2421 /* Ignore the extra whitespace */
2422 while ( ASCII_SPACE( *p ) ) {
2427 } else if ( casefold ) {
2428 /* Most IA5 rules require casefolding */
2429 *q++ = TOLOWER(*p++);
2437 assert( normalized->bv_val <= p );
2441 * If the string ended in space, backup the pointer one
2442 * position. One is enough because the above loop collapsed
2443 * all whitespace to a single space.
2446 if ( ASCII_SPACE( q[-1] ) ) {
2450 /* null terminate */
2453 normalized->bv_len = q - normalized->bv_val;
2455 if( normalized->bv_len == 0 ) {
2456 normalized->bv_val = ch_realloc( normalized->bv_val, 2 );
2457 normalized->bv_val[0] = ' ';
2458 normalized->bv_val[1] = '\0';
2459 normalized->bv_len = 1;
2462 return LDAP_SUCCESS;
2465 #ifndef SLAP_NVALUES
2473 struct berval *value,
2474 void *assertedValue )
2476 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
2479 match = strncmp( value->bv_val,
2480 ((struct berval *) assertedValue)->bv_val,
2485 return LDAP_SUCCESS;
2489 caseExactIA5SubstringsMatch(
2494 struct berval *value,
2495 void *assertedValue )
2498 SubstringsAssertion *sub = assertedValue;
2499 struct berval left = *value;
2503 /* Add up asserted input length */
2504 if( sub->sa_initial.bv_val ) {
2505 inlen += sub->sa_initial.bv_len;
2508 for(i=0; sub->sa_any[i].bv_val != NULL; i++) {
2509 inlen += sub->sa_any[i].bv_len;
2512 if( sub->sa_final.bv_val ) {
2513 inlen += sub->sa_final.bv_len;
2516 if( sub->sa_initial.bv_val ) {
2517 if( inlen > left.bv_len ) {
2522 match = strncmp( sub->sa_initial.bv_val, left.bv_val,
2523 sub->sa_initial.bv_len );
2529 left.bv_val += sub->sa_initial.bv_len;
2530 left.bv_len -= sub->sa_initial.bv_len;
2531 inlen -= sub->sa_initial.bv_len;
2534 if( sub->sa_final.bv_val ) {
2535 if( inlen > left.bv_len ) {
2540 match = strncmp( sub->sa_final.bv_val,
2541 &left.bv_val[left.bv_len - sub->sa_final.bv_len],
2542 sub->sa_final.bv_len );
2548 left.bv_len -= sub->sa_final.bv_len;
2549 inlen -= sub->sa_final.bv_len;
2553 for(i=0; sub->sa_any[i].bv_val; i++) {
2558 if( inlen > left.bv_len ) {
2559 /* not enough length */
2564 if( sub->sa_any[i].bv_len == 0 ) {
2568 p = strchr( left.bv_val, *sub->sa_any[i].bv_val );
2575 idx = p - left.bv_val;
2577 if( idx >= left.bv_len ) {
2578 /* this shouldn't happen */
2585 if( sub->sa_any[i].bv_len > left.bv_len ) {
2586 /* not enough left */
2591 match = strncmp( left.bv_val,
2592 sub->sa_any[i].bv_val,
2593 sub->sa_any[i].bv_len );
2601 left.bv_val += sub->sa_any[i].bv_len;
2602 left.bv_len -= sub->sa_any[i].bv_len;
2603 inlen -= sub->sa_any[i].bv_len;
2609 return LDAP_SUCCESS;
2612 /* Index generation function */
2613 static int caseExactIA5Indexer(
2618 struct berval *prefix,
2625 HASH_CONTEXT HASHcontext;
2626 unsigned char HASHdigest[HASH_BYTES];
2627 struct berval digest;
2628 digest.bv_val = HASHdigest;
2629 digest.bv_len = sizeof(HASHdigest);
2631 for( i=0; values[i].bv_val != NULL; i++ ) {
2632 /* empty - just count them */
2635 /* we should have at least one value at this point */
2638 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
2640 slen = syntax->ssyn_oidlen;
2641 mlen = mr->smr_oidlen;
2643 for( i=0; values[i].bv_val != NULL; i++ ) {
2644 struct berval *value = &values[i];
2646 HASH_Init( &HASHcontext );
2647 if( prefix != NULL && prefix->bv_len > 0 ) {
2648 HASH_Update( &HASHcontext,
2649 prefix->bv_val, prefix->bv_len );
2651 HASH_Update( &HASHcontext,
2652 syntax->ssyn_oid, slen );
2653 HASH_Update( &HASHcontext,
2654 mr->smr_oid, mlen );
2655 HASH_Update( &HASHcontext,
2656 value->bv_val, value->bv_len );
2657 HASH_Final( HASHdigest, &HASHcontext );
2659 ber_dupbv( &keys[i], &digest );
2662 keys[i].bv_val = NULL;
2664 return LDAP_SUCCESS;
2667 /* Index generation function */
2668 static int caseExactIA5Filter(
2673 struct berval *prefix,
2674 void * assertedValue,
2679 HASH_CONTEXT HASHcontext;
2680 unsigned char HASHdigest[HASH_BYTES];
2681 struct berval *value;
2682 struct berval digest;
2683 digest.bv_val = HASHdigest;
2684 digest.bv_len = sizeof(HASHdigest);
2686 slen = syntax->ssyn_oidlen;
2687 mlen = mr->smr_oidlen;
2689 value = (struct berval *) assertedValue;
2691 keys = ch_malloc( sizeof( struct berval ) * 2 );
2693 HASH_Init( &HASHcontext );
2694 if( prefix != NULL && prefix->bv_len > 0 ) {
2695 HASH_Update( &HASHcontext,
2696 prefix->bv_val, prefix->bv_len );
2698 HASH_Update( &HASHcontext,
2699 syntax->ssyn_oid, slen );
2700 HASH_Update( &HASHcontext,
2701 mr->smr_oid, mlen );
2702 HASH_Update( &HASHcontext,
2703 value->bv_val, value->bv_len );
2704 HASH_Final( HASHdigest, &HASHcontext );
2706 ber_dupbv( &keys[0], &digest );
2707 keys[1].bv_val = NULL;
2710 return LDAP_SUCCESS;
2713 /* Substrings Index generation function */
2714 static int caseExactIA5SubstringsIndexer(
2719 struct berval *prefix,
2726 HASH_CONTEXT HASHcontext;
2727 unsigned char HASHdigest[HASH_BYTES];
2728 struct berval digest;
2729 digest.bv_val = HASHdigest;
2730 digest.bv_len = sizeof(HASHdigest);
2732 /* we should have at least one value at this point */
2733 assert( values != NULL && values[0].bv_val != NULL );
2736 for( i=0; values[i].bv_val != NULL; i++ ) {
2737 /* count number of indices to generate */
2738 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
2742 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
2743 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2744 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2745 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2747 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2751 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
2752 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2753 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
2757 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
2758 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2759 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2760 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2762 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2768 /* no keys to generate */
2770 return LDAP_SUCCESS;
2773 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
2775 slen = syntax->ssyn_oidlen;
2776 mlen = mr->smr_oidlen;
2779 for( i=0; values[i].bv_val != NULL; i++ ) {
2781 struct berval *value;
2784 if( value->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
2786 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
2787 ( value->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
2789 char pre = SLAP_INDEX_SUBSTR_PREFIX;
2790 max = value->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
2792 for( j=0; j<max; j++ ) {
2793 HASH_Init( &HASHcontext );
2794 if( prefix != NULL && prefix->bv_len > 0 ) {
2795 HASH_Update( &HASHcontext,
2796 prefix->bv_val, prefix->bv_len );
2799 HASH_Update( &HASHcontext,
2800 &pre, sizeof( pre ) );
2801 HASH_Update( &HASHcontext,
2802 syntax->ssyn_oid, slen );
2803 HASH_Update( &HASHcontext,
2804 mr->smr_oid, mlen );
2805 HASH_Update( &HASHcontext,
2807 SLAP_INDEX_SUBSTR_MAXLEN );
2808 HASH_Final( HASHdigest, &HASHcontext );
2810 ber_dupbv( &keys[nkeys++], &digest );
2814 max = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2815 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2817 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
2820 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
2821 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
2822 HASH_Init( &HASHcontext );
2823 if( prefix != NULL && prefix->bv_len > 0 ) {
2824 HASH_Update( &HASHcontext,
2825 prefix->bv_val, prefix->bv_len );
2827 HASH_Update( &HASHcontext,
2828 &pre, sizeof( pre ) );
2829 HASH_Update( &HASHcontext,
2830 syntax->ssyn_oid, slen );
2831 HASH_Update( &HASHcontext,
2832 mr->smr_oid, mlen );
2833 HASH_Update( &HASHcontext,
2835 HASH_Final( HASHdigest, &HASHcontext );
2837 ber_dupbv( &keys[nkeys++], &digest );
2840 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
2841 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
2842 HASH_Init( &HASHcontext );
2843 if( prefix != NULL && prefix->bv_len > 0 ) {
2844 HASH_Update( &HASHcontext,
2845 prefix->bv_val, prefix->bv_len );
2847 HASH_Update( &HASHcontext,
2848 &pre, sizeof( pre ) );
2849 HASH_Update( &HASHcontext,
2850 syntax->ssyn_oid, slen );
2851 HASH_Update( &HASHcontext,
2852 mr->smr_oid, mlen );
2853 HASH_Update( &HASHcontext,
2854 &value->bv_val[value->bv_len-j], j );
2855 HASH_Final( HASHdigest, &HASHcontext );
2857 ber_dupbv( &keys[nkeys++], &digest );
2864 keys[nkeys].bv_val = NULL;
2871 return LDAP_SUCCESS;
2874 static int caseExactIA5SubstringsFilter(
2879 struct berval *prefix,
2880 void * assertedValue,
2883 SubstringsAssertion *sa = assertedValue;
2885 ber_len_t nkeys = 0;
2886 size_t slen, mlen, klen;
2888 HASH_CONTEXT HASHcontext;
2889 unsigned char HASHdigest[HASH_BYTES];
2890 struct berval *value;
2891 struct berval digest;
2893 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
2894 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2899 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
2901 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
2902 if( sa->sa_any[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2903 /* don't bother accounting for stepping */
2904 nkeys += sa->sa_any[i].bv_len -
2905 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
2910 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
2911 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2918 return LDAP_SUCCESS;
2921 digest.bv_val = HASHdigest;
2922 digest.bv_len = sizeof(HASHdigest);
2924 slen = syntax->ssyn_oidlen;
2925 mlen = mr->smr_oidlen;
2927 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
2930 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
2931 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2933 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
2934 value = &sa->sa_initial;
2936 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2937 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2939 HASH_Init( &HASHcontext );
2940 if( prefix != NULL && prefix->bv_len > 0 ) {
2941 HASH_Update( &HASHcontext,
2942 prefix->bv_val, prefix->bv_len );
2944 HASH_Update( &HASHcontext,
2945 &pre, sizeof( pre ) );
2946 HASH_Update( &HASHcontext,
2947 syntax->ssyn_oid, slen );
2948 HASH_Update( &HASHcontext,
2949 mr->smr_oid, mlen );
2950 HASH_Update( &HASHcontext,
2951 value->bv_val, klen );
2952 HASH_Final( HASHdigest, &HASHcontext );
2954 ber_dupbv( &keys[nkeys++], &digest );
2957 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
2959 pre = SLAP_INDEX_SUBSTR_PREFIX;
2960 klen = SLAP_INDEX_SUBSTR_MAXLEN;
2962 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
2963 if( sa->sa_any[i].bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
2967 value = &sa->sa_any[i];
2970 j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
2971 j += SLAP_INDEX_SUBSTR_STEP )
2973 HASH_Init( &HASHcontext );
2974 if( prefix != NULL && prefix->bv_len > 0 ) {
2975 HASH_Update( &HASHcontext,
2976 prefix->bv_val, prefix->bv_len );
2978 HASH_Update( &HASHcontext,
2979 &pre, sizeof( pre ) );
2980 HASH_Update( &HASHcontext,
2981 syntax->ssyn_oid, slen );
2982 HASH_Update( &HASHcontext,
2983 mr->smr_oid, mlen );
2984 HASH_Update( &HASHcontext,
2985 &value->bv_val[j], klen );
2986 HASH_Final( HASHdigest, &HASHcontext );
2988 ber_dupbv( &keys[nkeys++], &digest );
2993 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
2994 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2996 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
2997 value = &sa->sa_final;
2999 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
3000 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
3002 HASH_Init( &HASHcontext );
3003 if( prefix != NULL && prefix->bv_len > 0 ) {
3004 HASH_Update( &HASHcontext,
3005 prefix->bv_val, prefix->bv_len );
3007 HASH_Update( &HASHcontext,
3008 &pre, sizeof( pre ) );
3009 HASH_Update( &HASHcontext,
3010 syntax->ssyn_oid, slen );
3011 HASH_Update( &HASHcontext,
3012 mr->smr_oid, mlen );
3013 HASH_Update( &HASHcontext,
3014 &value->bv_val[value->bv_len-klen], klen );
3015 HASH_Final( HASHdigest, &HASHcontext );
3017 ber_dupbv( &keys[nkeys++], &digest );
3021 keys[nkeys].bv_val = NULL;
3028 return LDAP_SUCCESS;
3037 struct berval *value,
3038 void *assertedValue )
3040 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
3042 if( match == 0 && value->bv_len ) {
3043 match = strncasecmp( value->bv_val,
3044 ((struct berval *) assertedValue)->bv_val,
3049 return LDAP_SUCCESS;
3053 caseIgnoreIA5SubstringsMatch(
3058 struct berval *value,
3059 void *assertedValue )
3062 SubstringsAssertion *sub = assertedValue;
3063 struct berval left = *value;
3067 /* Add up asserted input length */
3068 if( sub->sa_initial.bv_val ) {
3069 inlen += sub->sa_initial.bv_len;
3072 for(i=0; sub->sa_any[i].bv_val != NULL; i++) {
3073 inlen += sub->sa_any[i].bv_len;
3076 if( sub->sa_final.bv_val ) {
3077 inlen += sub->sa_final.bv_len;
3080 if( sub->sa_initial.bv_val ) {
3081 if( inlen > left.bv_len ) {
3086 match = strncasecmp( sub->sa_initial.bv_val, left.bv_val,
3087 sub->sa_initial.bv_len );
3093 left.bv_val += sub->sa_initial.bv_len;
3094 left.bv_len -= sub->sa_initial.bv_len;
3095 inlen -= sub->sa_initial.bv_len;
3098 if( sub->sa_final.bv_val ) {
3099 if( inlen > left.bv_len ) {
3104 match = strncasecmp( sub->sa_final.bv_val,
3105 &left.bv_val[left.bv_len - sub->sa_final.bv_len],
3106 sub->sa_final.bv_len );
3112 left.bv_len -= sub->sa_final.bv_len;
3113 inlen -= sub->sa_final.bv_len;
3117 for(i=0; sub->sa_any[i].bv_val; i++) {
3122 if( inlen > left.bv_len ) {
3123 /* not enough length */
3128 if( sub->sa_any[i].bv_len == 0 ) {
3132 p = bvcasechr( &left, *sub->sa_any[i].bv_val, &idx );
3139 assert( idx < left.bv_len );
3140 if( idx >= left.bv_len ) {
3141 /* this shouldn't happen */
3148 if( sub->sa_any[i].bv_len > left.bv_len ) {
3149 /* not enough left */
3154 match = strncasecmp( left.bv_val,
3155 sub->sa_any[i].bv_val,
3156 sub->sa_any[i].bv_len );
3165 left.bv_val += sub->sa_any[i].bv_len;
3166 left.bv_len -= sub->sa_any[i].bv_len;
3167 inlen -= sub->sa_any[i].bv_len;
3173 return LDAP_SUCCESS;
3176 /* Index generation function */
3177 static int caseIgnoreIA5Indexer(
3182 struct berval *prefix,
3187 int rc = LDAP_SUCCESS;
3190 HASH_CONTEXT HASHcontext;
3191 unsigned char HASHdigest[HASH_BYTES];
3192 struct berval digest;
3193 digest.bv_val = HASHdigest;
3194 digest.bv_len = sizeof(HASHdigest);
3196 /* we should have at least one value at this point */
3197 assert( values != NULL && values[0].bv_val != NULL );
3199 for( i=0; values[i].bv_val != NULL; i++ ) {
3200 /* just count them */
3203 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
3205 slen = syntax->ssyn_oidlen;
3206 mlen = mr->smr_oidlen;
3208 for( i=0; values[i].bv_val != NULL; i++ ) {
3209 struct berval value;
3211 if( mr->smr_normalize ) {
3212 rc = (mr->smr_normalize)( use, syntax, mr, &values[i], &value );
3213 if( rc != LDAP_SUCCESS ) {
3216 #ifndef SLAP_NVALUES
3217 } else if ( mr->smr_syntax->ssyn_normalize ) {
3218 rc = (mr->smr_syntax->ssyn_normalize)( syntax, &values[i], &value );
3219 if( rc != LDAP_SUCCESS ) {
3224 ber_dupbv( &value, &values[i] );
3227 ldap_pvt_str2lower( value.bv_val );
3229 HASH_Init( &HASHcontext );
3230 if( prefix != NULL && prefix->bv_len > 0 ) {
3231 HASH_Update( &HASHcontext,
3232 prefix->bv_val, prefix->bv_len );
3234 HASH_Update( &HASHcontext,
3235 syntax->ssyn_oid, slen );
3236 HASH_Update( &HASHcontext,
3237 mr->smr_oid, mlen );
3238 HASH_Update( &HASHcontext,
3239 value.bv_val, value.bv_len );
3240 HASH_Final( HASHdigest, &HASHcontext );
3242 free( value.bv_val );
3244 ber_dupbv( &keys[i], &digest );
3247 keys[i].bv_val = NULL;
3248 if( rc != LDAP_SUCCESS ) {
3249 ber_bvarray_free( keys );
3256 /* Index generation function */
3257 static int caseIgnoreIA5Filter(
3262 struct berval *prefix,
3263 void * assertedValue,
3268 HASH_CONTEXT HASHcontext;
3269 unsigned char HASHdigest[HASH_BYTES];
3270 struct berval value;
3271 struct berval digest;
3272 digest.bv_val = HASHdigest;
3273 digest.bv_len = sizeof(HASHdigest);
3275 slen = syntax->ssyn_oidlen;
3276 mlen = mr->smr_oidlen;
3278 ber_dupbv( &value, (struct berval *) assertedValue );
3279 ldap_pvt_str2lower( value.bv_val );
3281 keys = ch_malloc( sizeof( struct berval ) * 2 );
3283 HASH_Init( &HASHcontext );
3284 if( prefix != NULL && prefix->bv_len > 0 ) {
3285 HASH_Update( &HASHcontext,
3286 prefix->bv_val, prefix->bv_len );
3288 HASH_Update( &HASHcontext,
3289 syntax->ssyn_oid, slen );
3290 HASH_Update( &HASHcontext,
3291 mr->smr_oid, mlen );
3292 HASH_Update( &HASHcontext,
3293 value.bv_val, value.bv_len );
3294 HASH_Final( HASHdigest, &HASHcontext );
3296 ber_dupbv( &keys[0], &digest );
3297 keys[1].bv_val = NULL;
3299 free( value.bv_val );
3303 return LDAP_SUCCESS;
3306 /* Substrings Index generation function */
3307 static int caseIgnoreIA5SubstringsIndexer(
3312 struct berval *prefix,
3319 HASH_CONTEXT HASHcontext;
3320 unsigned char HASHdigest[HASH_BYTES];
3321 struct berval digest;
3322 digest.bv_val = HASHdigest;
3323 digest.bv_len = sizeof(HASHdigest);
3325 /* we should have at least one value at this point */
3326 assert( values != NULL && values[0].bv_val != NULL );
3329 for( i=0; values[i].bv_val != NULL; i++ ) {
3330 /* count number of indices to generate */
3331 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
3335 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
3336 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3337 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
3338 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
3340 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
3344 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
3345 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3346 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
3350 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
3351 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3352 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
3353 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
3355 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
3361 /* no keys to generate */
3363 return LDAP_SUCCESS;
3366 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
3368 slen = syntax->ssyn_oidlen;
3369 mlen = mr->smr_oidlen;
3372 for( i=0; values[i].bv_val != NULL; i++ ) {
3374 struct berval value;
3376 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
3378 ber_dupbv( &value, &values[i] );
3379 ldap_pvt_str2lower( value.bv_val );
3381 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
3382 ( value.bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
3384 char pre = SLAP_INDEX_SUBSTR_PREFIX;
3385 max = value.bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
3387 for( j=0; j<max; j++ ) {
3388 HASH_Init( &HASHcontext );
3389 if( prefix != NULL && prefix->bv_len > 0 ) {
3390 HASH_Update( &HASHcontext,
3391 prefix->bv_val, prefix->bv_len );
3394 HASH_Update( &HASHcontext,
3395 &pre, sizeof( pre ) );
3396 HASH_Update( &HASHcontext,
3397 syntax->ssyn_oid, slen );
3398 HASH_Update( &HASHcontext,
3399 mr->smr_oid, mlen );
3400 HASH_Update( &HASHcontext,
3402 SLAP_INDEX_SUBSTR_MAXLEN );
3403 HASH_Final( HASHdigest, &HASHcontext );
3405 ber_dupbv( &keys[nkeys++], &digest );
3409 max = SLAP_INDEX_SUBSTR_MAXLEN < value.bv_len
3410 ? SLAP_INDEX_SUBSTR_MAXLEN : value.bv_len;
3412 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
3415 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
3416 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
3417 HASH_Init( &HASHcontext );
3418 if( prefix != NULL && prefix->bv_len > 0 ) {
3419 HASH_Update( &HASHcontext,
3420 prefix->bv_val, prefix->bv_len );
3422 HASH_Update( &HASHcontext,
3423 &pre, sizeof( pre ) );
3424 HASH_Update( &HASHcontext,
3425 syntax->ssyn_oid, slen );
3426 HASH_Update( &HASHcontext,
3427 mr->smr_oid, mlen );
3428 HASH_Update( &HASHcontext,
3430 HASH_Final( HASHdigest, &HASHcontext );
3432 ber_dupbv( &keys[nkeys++], &digest );
3435 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
3436 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
3437 HASH_Init( &HASHcontext );
3438 if( prefix != NULL && prefix->bv_len > 0 ) {
3439 HASH_Update( &HASHcontext,
3440 prefix->bv_val, prefix->bv_len );
3442 HASH_Update( &HASHcontext,
3443 &pre, sizeof( pre ) );
3444 HASH_Update( &HASHcontext,
3445 syntax->ssyn_oid, slen );
3446 HASH_Update( &HASHcontext,
3447 mr->smr_oid, mlen );
3448 HASH_Update( &HASHcontext,
3449 &value.bv_val[value.bv_len-j], j );
3450 HASH_Final( HASHdigest, &HASHcontext );
3452 ber_dupbv( &keys[nkeys++], &digest );
3457 free( value.bv_val );
3461 keys[nkeys].bv_val = NULL;
3468 return LDAP_SUCCESS;
3471 static int caseIgnoreIA5SubstringsFilter(
3476 struct berval *prefix,
3477 void * assertedValue,
3480 SubstringsAssertion *sa = assertedValue;
3482 ber_len_t nkeys = 0;
3483 size_t slen, mlen, klen;
3485 HASH_CONTEXT HASHcontext;
3486 unsigned char HASHdigest[HASH_BYTES];
3487 struct berval value;
3488 struct berval digest;
3490 if((flags & SLAP_INDEX_SUBSTR_INITIAL) && sa->sa_initial.bv_val != NULL &&
3491 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3496 if((flags & SLAP_INDEX_SUBSTR_ANY) && sa->sa_any != NULL ) {
3498 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
3499 if( sa->sa_any[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3500 /* don't bother accounting for stepping */
3501 nkeys += sa->sa_any[i].bv_len -
3502 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
3507 if((flags & SLAP_INDEX_SUBSTR_FINAL) && sa->sa_final.bv_val != NULL &&
3508 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3515 return LDAP_SUCCESS;
3518 digest.bv_val = HASHdigest;
3519 digest.bv_len = sizeof(HASHdigest);
3521 slen = syntax->ssyn_oidlen;
3522 mlen = mr->smr_oidlen;
3524 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
3527 if((flags & SLAP_INDEX_SUBSTR_INITIAL) && sa->sa_initial.bv_val != NULL &&
3528 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3530 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
3531 ber_dupbv( &value, &sa->sa_initial );
3532 ldap_pvt_str2lower( value.bv_val );
3534 klen = SLAP_INDEX_SUBSTR_MAXLEN < value.bv_len
3535 ? SLAP_INDEX_SUBSTR_MAXLEN : value.bv_len;
3537 HASH_Init( &HASHcontext );
3538 if( prefix != NULL && prefix->bv_len > 0 ) {
3539 HASH_Update( &HASHcontext,
3540 prefix->bv_val, prefix->bv_len );
3542 HASH_Update( &HASHcontext,
3543 &pre, sizeof( pre ) );
3544 HASH_Update( &HASHcontext,
3545 syntax->ssyn_oid, slen );
3546 HASH_Update( &HASHcontext,
3547 mr->smr_oid, mlen );
3548 HASH_Update( &HASHcontext,
3549 value.bv_val, klen );
3550 HASH_Final( HASHdigest, &HASHcontext );
3552 free( value.bv_val );
3553 ber_dupbv( &keys[nkeys++], &digest );
3556 if((flags & SLAP_INDEX_SUBSTR_ANY) && sa->sa_any != NULL ) {
3558 pre = SLAP_INDEX_SUBSTR_PREFIX;
3559 klen = SLAP_INDEX_SUBSTR_MAXLEN;
3561 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
3562 if( sa->sa_any[i].bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
3566 ber_dupbv( &value, &sa->sa_any[i] );
3567 ldap_pvt_str2lower( value.bv_val );
3570 j <= value.bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
3571 j += SLAP_INDEX_SUBSTR_STEP )
3573 HASH_Init( &HASHcontext );
3574 if( prefix != NULL && prefix->bv_len > 0 ) {
3575 HASH_Update( &HASHcontext,
3576 prefix->bv_val, prefix->bv_len );
3578 HASH_Update( &HASHcontext,
3579 &pre, sizeof( pre ) );
3580 HASH_Update( &HASHcontext,
3581 syntax->ssyn_oid, slen );
3582 HASH_Update( &HASHcontext,
3583 mr->smr_oid, mlen );
3584 HASH_Update( &HASHcontext,
3585 &value.bv_val[j], klen );
3586 HASH_Final( HASHdigest, &HASHcontext );
3588 ber_dupbv( &keys[nkeys++], &digest );
3591 free( value.bv_val );
3595 if((flags & SLAP_INDEX_SUBSTR_FINAL) && sa->sa_final.bv_val != NULL &&
3596 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3598 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
3599 ber_dupbv( &value, &sa->sa_final );
3600 ldap_pvt_str2lower( value.bv_val );
3602 klen = SLAP_INDEX_SUBSTR_MAXLEN < value.bv_len
3603 ? SLAP_INDEX_SUBSTR_MAXLEN : value.bv_len;
3605 HASH_Init( &HASHcontext );
3606 if( prefix != NULL && prefix->bv_len > 0 ) {
3607 HASH_Update( &HASHcontext,
3608 prefix->bv_val, prefix->bv_len );
3610 HASH_Update( &HASHcontext,
3611 &pre, sizeof( pre ) );
3612 HASH_Update( &HASHcontext,
3613 syntax->ssyn_oid, slen );
3614 HASH_Update( &HASHcontext,
3615 mr->smr_oid, mlen );
3616 HASH_Update( &HASHcontext,
3617 &value.bv_val[value.bv_len-klen], klen );
3618 HASH_Final( HASHdigest, &HASHcontext );
3620 free( value.bv_val );
3621 ber_dupbv( &keys[nkeys++], &digest );
3625 keys[nkeys].bv_val = NULL;
3632 return LDAP_SUCCESS;
3638 numericStringValidate(
3644 if( in->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
3646 for(i=0; i < in->bv_len; i++) {
3647 if( !SLAP_NUMERIC(in->bv_val[i]) ) {
3648 return LDAP_INVALID_SYNTAX;
3652 return LDAP_SUCCESS;
3655 #ifndef SLAP_NVALUES
3658 xnumericStringNormalize(
3661 struct berval *normalized )
3663 /* removal all spaces */
3666 assert( val->bv_len );
3668 normalized->bv_val = ch_malloc( val->bv_len + 1 );
3671 q = normalized->bv_val;
3674 if ( ASCII_SPACE( *p ) ) {
3675 /* Ignore whitespace */
3682 /* we should have copied no more then is in val */
3683 assert( (q - normalized->bv_val) <= (p - val->bv_val) );
3685 /* null terminate */
3688 normalized->bv_len = q - normalized->bv_val;
3690 if( normalized->bv_len == 0 ) {
3691 normalized->bv_val = ch_realloc( normalized->bv_val, 2 );
3692 normalized->bv_val[0] = ' ';
3693 normalized->bv_val[1] = '\0';
3694 normalized->bv_len = 1;
3697 return LDAP_SUCCESS;
3701 objectIdentifierFirstComponentMatch(
3706 struct berval *value,
3707 void *assertedValue )
3709 int rc = LDAP_SUCCESS;
3711 struct berval *asserted = (struct berval *) assertedValue;
3715 if( value->bv_len == 0 || value->bv_val[0] != '(' /*')'*/ ) {
3716 return LDAP_INVALID_SYNTAX;
3719 /* trim leading white space */
3720 for( i=1; ASCII_SPACE(value->bv_val[i]) && i < value->bv_len; i++ ) {
3724 /* grab next word */
3725 oid.bv_val = &value->bv_val[i];
3726 j = value->bv_len - i;
3727 for( i=0; !ASCII_SPACE(oid.bv_val[i]) && i < j; i++ ) {
3732 /* insert attributeTypes, objectclass check here */
3733 if( OID_LEADCHAR(asserted->bv_val[0]) ) {
3734 rc = objectIdentifierMatch( &match, flags, syntax, mr, &oid, asserted );
3737 if ( !strcmp( syntax->ssyn_oid, SLAP_SYNTAX_MATCHINGRULES_OID ) ) {
3738 MatchingRule *asserted_mr = mr_bvfind( asserted );
3739 MatchingRule *stored_mr = mr_bvfind( &oid );
3741 if( asserted_mr == NULL ) {
3742 rc = SLAPD_COMPARE_UNDEFINED;
3744 match = asserted_mr != stored_mr;
3747 } else if ( !strcmp( syntax->ssyn_oid,
3748 SLAP_SYNTAX_ATTRIBUTETYPES_OID ) )
3750 AttributeType *asserted_at = at_bvfind( asserted );
3751 AttributeType *stored_at = at_bvfind( &oid );
3753 if( asserted_at == NULL ) {
3754 rc = SLAPD_COMPARE_UNDEFINED;
3756 match = asserted_at != stored_at;
3759 } else if ( !strcmp( syntax->ssyn_oid,
3760 SLAP_SYNTAX_OBJECTCLASSES_OID ) )
3762 ObjectClass *asserted_oc = oc_bvfind( asserted );
3763 ObjectClass *stored_oc = oc_bvfind( &oid );
3765 if( asserted_oc == NULL ) {
3766 rc = SLAPD_COMPARE_UNDEFINED;
3768 match = asserted_oc != stored_oc;
3774 LDAP_LOG( CONFIG, ENTRY,
3775 "objectIdentifierFirstComponentMatch: %d\n %s\n %s\n",
3776 match, value->bv_val, asserted->bv_val );
3778 Debug( LDAP_DEBUG_ARGS, "objectIdentifierFirstComponentMatch "
3779 "%d\n\t\"%s\"\n\t\"%s\"\n",
3780 match, value->bv_val, asserted->bv_val );
3783 if( rc == LDAP_SUCCESS ) *matchp = match;
3795 struct berval *value,
3796 void *assertedValue )
3798 long lValue, lAssertedValue;
3800 /* safe to assume integers are NUL terminated? */
3801 lValue = strtol(value->bv_val, NULL, 10);
3802 if(( lValue == LONG_MIN || lValue == LONG_MAX) && errno == ERANGE ) {
3803 return LDAP_CONSTRAINT_VIOLATION;
3806 lAssertedValue = strtol(((struct berval *)assertedValue)->bv_val, NULL, 10);
3807 if(( lAssertedValue == LONG_MIN || lAssertedValue == LONG_MAX)
3808 && errno == ERANGE )
3810 return LDAP_CONSTRAINT_VIOLATION;
3813 *matchp = (lValue & lAssertedValue) ? 0 : 1;
3814 return LDAP_SUCCESS;
3823 struct berval *value,
3824 void *assertedValue )
3826 long lValue, lAssertedValue;
3828 /* safe to assume integers are NUL terminated? */
3829 lValue = strtol(value->bv_val, NULL, 10);
3830 if(( lValue == LONG_MIN || lValue == LONG_MAX) && errno == ERANGE ) {
3831 return LDAP_CONSTRAINT_VIOLATION;
3834 lAssertedValue = strtol(((struct berval *)assertedValue)->bv_val, NULL, 10);
3835 if(( lAssertedValue == LONG_MIN || lAssertedValue == LONG_MAX)
3836 && errno == ERANGE )
3838 return LDAP_CONSTRAINT_VIOLATION;
3841 *matchp = (lValue | lAssertedValue) ? 0 : -1;
3842 return LDAP_SUCCESS;
3845 #ifndef SLAP_NVALUES
3848 #include <openssl/x509.h>
3849 #include <openssl/err.h>
3852 * Next function returns a string representation of a ASN1_INTEGER.
3853 * It works for unlimited lengths.
3856 static struct berval *
3857 asn1_integer2str(ASN1_INTEGER *a, struct berval *bv)
3861 static char digit[] = "0123456789";
3863 /* We work backwards, make it fill from the end of buf */
3864 p = buf + sizeof(buf) - 1;
3867 if ( a == NULL || a->length == 0 ) {
3875 /* We want to preserve the original */
3876 copy = ch_malloc(n*sizeof(unsigned int));
3877 for (i = 0; i<n; i++) {
3878 copy[i] = a->data[i];
3882 * base indicates the index of the most significant
3883 * byte that might be nonzero. When it goes off the
3884 * end, we now there is nothing left to do.
3890 for (i = base; i<n; i++ ) {
3891 copy[i] += carry*256;
3892 carry = copy[i] % 10;
3897 * Way too large, we need to leave
3898 * room for sign if negative
3903 *--p = digit[carry];
3905 if (copy[base] == 0) base++;
3910 if ( a->type == V_ASN1_NEG_INTEGER ) {
3914 return ber_str2bv( p, 0, 1, bv );
3918 * Given a certificate in DER format, extract the corresponding
3919 * assertion value for certificateExactMatch
3922 certificateExactConvert(
3924 struct berval * out )
3927 unsigned char *p = in->bv_val;
3928 struct berval serial;
3929 struct berval issuer_dn;
3931 xcert = d2i_X509(NULL, &p, in->bv_len);
3934 LDAP_LOG( CONFIG, ENTRY,
3935 "certificateExactConvert: error parsing cert: %s\n",
3936 ERR_error_string(ERR_get_error(),NULL), 0, 0 );
3938 Debug( LDAP_DEBUG_ARGS, "certificateExactConvert: "
3939 "error parsing cert: %s\n",
3940 ERR_error_string(ERR_get_error(),NULL), NULL, NULL );
3942 return LDAP_INVALID_SYNTAX;
3945 if ( !asn1_integer2str(xcert->cert_info->serialNumber, &serial) ) {
3947 return LDAP_INVALID_SYNTAX;
3949 if ( dnX509normalize(X509_get_issuer_name(xcert), &issuer_dn )
3953 ber_memfree(serial.bv_val);
3954 return LDAP_INVALID_SYNTAX;
3959 out->bv_len = serial.bv_len + issuer_dn.bv_len + sizeof(" $ ");
3960 out->bv_val = ch_malloc(out->bv_len);
3962 AC_MEMCPY(p, serial.bv_val, serial.bv_len);
3964 AC_MEMCPY(p, " $ ", sizeof(" $ ")-1);
3966 AC_MEMCPY(p, issuer_dn.bv_val, issuer_dn.bv_len);
3967 p += issuer_dn.bv_len;
3971 LDAP_LOG( CONFIG, ARGS,
3972 "certificateExactConvert: \n %s\n", out->bv_val, 0, 0 );
3974 Debug( LDAP_DEBUG_ARGS, "certificateExactConvert "
3976 out->bv_val, NULL, NULL );
3979 ber_memfree(serial.bv_val);
3980 ber_memfree(issuer_dn.bv_val);
3982 return LDAP_SUCCESS;
3986 serial_and_issuer_parse(
3987 struct berval *assertion,
3988 struct berval *serial,
3989 struct berval *issuer_dn
3997 begin = assertion->bv_val;
3998 end = assertion->bv_val+assertion->bv_len-1;
3999 for (p=begin; p<=end && *p != '$'; p++) /* empty */ ;
4000 if ( p > end ) return LDAP_INVALID_SYNTAX;
4002 /* p now points at the $ sign, now use
4003 * begin and end to delimit the serial number
4005 while (ASCII_SPACE(*begin)) begin++;
4007 while (ASCII_SPACE(*end)) end--;
4009 if( end <= begin ) return LDAP_INVALID_SYNTAX;
4011 bv.bv_len = end-begin+1;
4013 ber_dupbv(serial, &bv);
4015 /* now extract the issuer, remember p was at the dollar sign */
4017 end = assertion->bv_val+assertion->bv_len-1;
4018 while (ASCII_SPACE(*begin)) begin++;
4019 /* should we trim spaces at the end too? is it safe always? no, no */
4021 if( end <= begin ) return LDAP_INVALID_SYNTAX;
4024 bv.bv_len = end-begin+1;
4027 dnNormalize2( NULL, &bv, issuer_dn );
4030 return LDAP_SUCCESS;
4034 certificateExactMatch(
4039 struct berval *value,
4040 void *assertedValue )
4043 unsigned char *p = value->bv_val;
4044 struct berval serial;
4045 struct berval issuer_dn;
4046 struct berval asserted_serial;
4047 struct berval asserted_issuer_dn;
4050 xcert = d2i_X509(NULL, &p, value->bv_len);
4053 LDAP_LOG( CONFIG, ENTRY,
4054 "certificateExactMatch: error parsing cert: %s\n",
4055 ERR_error_string(ERR_get_error(),NULL), 0, 0 );
4057 Debug( LDAP_DEBUG_ARGS, "certificateExactMatch: "
4058 "error parsing cert: %s\n",
4059 ERR_error_string(ERR_get_error(),NULL), NULL, NULL );
4061 return LDAP_INVALID_SYNTAX;
4064 asn1_integer2str(xcert->cert_info->serialNumber, &serial);
4065 dnX509normalize(X509_get_issuer_name(xcert), &issuer_dn);
4069 serial_and_issuer_parse(assertedValue,
4070 &asserted_serial, &asserted_issuer_dn);
4075 slap_schema.si_syn_integer,
4076 slap_schema.si_mr_integerMatch,
4079 if ( ret == LDAP_SUCCESS ) {
4080 if ( *matchp == 0 ) {
4081 /* We need to normalize everything for dnMatch */
4085 slap_schema.si_syn_distinguishedName,
4086 slap_schema.si_mr_distinguishedNameMatch,
4088 &asserted_issuer_dn);
4093 LDAP_LOG( CONFIG, ARGS, "certificateExactMatch "
4094 "%d\n\t\"%s $ %s\"\n",
4095 *matchp, serial.bv_val, issuer_dn.bv_val );
4096 LDAP_LOG( CONFIG, ARGS, "\t\"%s $ %s\"\n",
4097 asserted_serial.bv_val, asserted_issuer_dn.bv_val,
4100 Debug( LDAP_DEBUG_ARGS, "certificateExactMatch "
4101 "%d\n\t\"%s $ %s\"\n",
4102 *matchp, serial.bv_val, issuer_dn.bv_val );
4103 Debug( LDAP_DEBUG_ARGS, "\t\"%s $ %s\"\n",
4104 asserted_serial.bv_val, asserted_issuer_dn.bv_val,
4108 ber_memfree(serial.bv_val);
4109 ber_memfree(issuer_dn.bv_val);
4110 ber_memfree(asserted_serial.bv_val);
4111 ber_memfree(asserted_issuer_dn.bv_val);
4117 * Index generation function
4118 * We just index the serials, in most scenarios the issuer DN is one of
4119 * a very small set of values.
4121 static int certificateExactIndexer(
4126 struct berval *prefix,
4134 struct berval serial;
4136 /* we should have at least one value at this point */
4137 assert( values != NULL && values[0].bv_val != NULL );
4139 for( i=0; values[i].bv_val != NULL; i++ ) {
4140 /* empty -- just count them */
4143 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
4145 for( i=0; values[i].bv_val != NULL; i++ ) {
4146 p = values[i].bv_val;
4147 xcert = d2i_X509(NULL, &p, values[i].bv_len);
4150 LDAP_LOG( CONFIG, ENTRY,
4151 "certificateExactIndexer: error parsing cert: %s\n",
4152 ERR_error_string(ERR_get_error(),NULL), 0, 0);
4154 Debug( LDAP_DEBUG_ARGS, "certificateExactIndexer: "
4155 "error parsing cert: %s\n",
4156 ERR_error_string(ERR_get_error(),NULL),
4159 /* Do we leak keys on error? */
4160 return LDAP_INVALID_SYNTAX;
4163 asn1_integer2str(xcert->cert_info->serialNumber, &serial);
4165 xintegerNormalize( slap_schema.si_syn_integer,
4166 &serial, &keys[i] );
4167 ber_memfree(serial.bv_val);
4169 LDAP_LOG( CONFIG, ENTRY,
4170 "certificateExactIndexer: returning: %s\n", keys[i].bv_val, 0, 0);
4172 Debug( LDAP_DEBUG_ARGS, "certificateExactIndexer: "
4179 keys[i].bv_val = NULL;
4181 return LDAP_SUCCESS;
4184 /* Index generation function */
4185 /* We think this is always called with a value in matching rule syntax */
4186 static int certificateExactFilter(
4191 struct berval *prefix,
4192 void * assertedValue,
4196 struct berval asserted_serial;
4199 ret = serial_and_issuer_parse( assertedValue, &asserted_serial, NULL );
4200 if( ret != LDAP_SUCCESS ) return ret;
4202 keys = ch_malloc( sizeof( struct berval ) * 2 );
4203 xintegerNormalize( syntax, &asserted_serial, &keys[0] );
4204 keys[1].bv_val = NULL;
4207 ber_memfree(asserted_serial.bv_val);
4208 return LDAP_SUCCESS;
4214 check_time_syntax (struct berval *val,
4218 static int ceiling[9] = { 99, 99, 11, 30, 23, 59, 59, 12, 59 };
4219 static int mdays[2][12] = {
4220 /* non-leap years */
4221 { 30, 27, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30 },
4223 { 30, 28, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30 }
4226 int part, c, tzoffset, leapyear = 0 ;
4228 if( val->bv_len == 0 ) {
4229 return LDAP_INVALID_SYNTAX;
4232 p = (char *)val->bv_val;
4233 e = p + val->bv_len;
4235 /* Ignore initial whitespace */
4236 while ( ( p < e ) && ASCII_SPACE( *p ) ) {
4240 if (e - p < 13 - (2 * start)) {
4241 return LDAP_INVALID_SYNTAX;
4244 for (part = 0; part < 9; part++) {
4248 for (part = start; part < 7; part++) {
4250 if ((part == 6) && (c == 'Z' || c == '+' || c == '-')) {
4257 return LDAP_INVALID_SYNTAX;
4259 if (c < 0 || c > 9) {
4260 return LDAP_INVALID_SYNTAX;
4266 return LDAP_INVALID_SYNTAX;
4268 if (c < 0 || c > 9) {
4269 return LDAP_INVALID_SYNTAX;
4274 if (part == 2 || part == 3) {
4277 if (parts[part] < 0) {
4278 return LDAP_INVALID_SYNTAX;
4280 if (parts[part] > ceiling[part]) {
4281 return LDAP_INVALID_SYNTAX;
4285 /* leapyear check for the Gregorian calendar (year>1581) */
4286 if (((parts[1] % 4 == 0) && (parts[1] != 0)) ||
4287 ((parts[0] % 4 == 0) && (parts[1] == 0)))
4292 if (parts[3] > mdays[leapyear][parts[2]]) {
4293 return LDAP_INVALID_SYNTAX;
4298 tzoffset = 0; /* UTC */
4299 } else if (c != '+' && c != '-') {
4300 return LDAP_INVALID_SYNTAX;
4304 } else /* c == '+' */ {
4309 return LDAP_INVALID_SYNTAX;
4312 for (part = 7; part < 9; part++) {
4314 if (c < 0 || c > 9) {
4315 return LDAP_INVALID_SYNTAX;
4320 if (c < 0 || c > 9) {
4321 return LDAP_INVALID_SYNTAX;
4325 if (parts[part] < 0 || parts[part] > ceiling[part]) {
4326 return LDAP_INVALID_SYNTAX;
4331 /* Ignore trailing whitespace */
4332 while ( ( p < e ) && ASCII_SPACE( *p ) ) {
4336 return LDAP_INVALID_SYNTAX;
4339 switch ( tzoffset ) {
4340 case -1: /* negativ offset to UTC, ie west of Greenwich */
4341 parts[4] += parts[7];
4342 parts[5] += parts[8];
4343 for (part = 6; --part > 0; ) { /* offset is just hhmm, no seconds */
4347 c = mdays[leapyear][parts[2]];
4349 if (parts[part] > c) {
4350 parts[part] -= c + 1;
4355 case 1: /* positive offset to UTC, ie east of Greenwich */
4356 parts[4] -= parts[7];
4357 parts[5] -= parts[8];
4358 for (part = 6; --part > 0; ) {
4362 /* first arg to % needs to be non negativ */
4363 c = mdays[leapyear][(parts[2] - 1 + 12) % 12];
4365 if (parts[part] < 0) {
4366 parts[part] += c + 1;
4371 case 0: /* already UTC */
4375 return LDAP_SUCCESS;
4378 #ifdef SUPPORT_OBSOLETE_UTC_SYNTAX
4383 struct berval *normalized )
4387 rc = check_time_syntax(val, 1, parts);
4388 if (rc != LDAP_SUCCESS) {
4392 normalized->bv_val = ch_malloc( 14 );
4393 if ( normalized->bv_val == NULL ) {
4394 return LBER_ERROR_MEMORY;
4397 sprintf( normalized->bv_val, "%02d%02d%02d%02d%02d%02dZ",
4398 parts[1], parts[2] + 1, parts[3] + 1,
4399 parts[4], parts[5], parts[6] );
4400 normalized->bv_len = 13;
4402 return LDAP_SUCCESS;
4406 #ifdef SUPPORT_OBSOLETE_UTC_SYNTAX
4414 return check_time_syntax(in, 1, parts);
4419 generalizedTimeValidate(
4425 return check_time_syntax(in, 0, parts);
4428 #ifndef SLAP_NVALUES
4431 xgeneralizedTimeNormalize(
4434 struct berval *normalized )
4438 rc = check_time_syntax(val, 0, parts);
4439 if (rc != LDAP_SUCCESS) {
4443 normalized->bv_val = ch_malloc( 16 );
4444 if ( normalized->bv_val == NULL ) {
4445 return LBER_ERROR_MEMORY;
4448 sprintf( normalized->bv_val, "%02d%02d%02d%02d%02d%02d%02dZ",
4449 parts[0], parts[1], parts[2] + 1, parts[3] + 1,
4450 parts[4], parts[5], parts[6] );
4451 normalized->bv_len = 15;
4453 return LDAP_SUCCESS;
4458 nisNetgroupTripleValidate(
4460 struct berval *val )
4465 if ( val->bv_len == 0 ) {
4466 return LDAP_INVALID_SYNTAX;
4469 p = (char *)val->bv_val;
4470 e = p + val->bv_len;
4472 if ( *p != '(' /*')'*/ ) {
4473 return LDAP_INVALID_SYNTAX;
4476 for ( p++; ( p < e ) && ( *p != /*'('*/ ')' ); p++ ) {
4480 return LDAP_INVALID_SYNTAX;
4483 } else if ( !AD_CHAR( *p ) ) {
4484 return LDAP_INVALID_SYNTAX;
4488 if ( ( commas != 2 ) || ( *p != /*'('*/ ')' ) ) {
4489 return LDAP_INVALID_SYNTAX;
4495 return LDAP_INVALID_SYNTAX;
4498 return LDAP_SUCCESS;
4502 bootParameterValidate(
4504 struct berval *val )
4508 if ( val->bv_len == 0 ) {
4509 return LDAP_INVALID_SYNTAX;
4512 p = (char *)val->bv_val;
4513 e = p + val->bv_len;
4516 for (; ( p < e ) && ( *p != '=' ); p++ ) {
4517 if ( !AD_CHAR( *p ) ) {
4518 return LDAP_INVALID_SYNTAX;
4523 return LDAP_INVALID_SYNTAX;
4527 for ( p++; ( p < e ) && ( *p != ':' ); p++ ) {
4528 if ( !AD_CHAR( *p ) ) {
4529 return LDAP_INVALID_SYNTAX;
4534 return LDAP_INVALID_SYNTAX;
4538 for ( p++; p < e; p++ ) {
4539 if ( !SLAP_PRINTABLE( *p ) ) {
4540 return LDAP_INVALID_SYNTAX;
4544 return LDAP_SUCCESS;
4547 #define X_BINARY "X-BINARY-TRANSFER-REQUIRED 'TRUE' "
4548 #define X_NOT_H_R "X-NOT-HUMAN-READABLE 'TRUE' "
4550 static slap_syntax_defs_rec syntax_defs[] = {
4551 {"( 1.3.6.1.4.1.1466.115.121.1.1 DESC 'ACI Item' "
4552 X_BINARY X_NOT_H_R ")",
4553 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, NULL, NULL, NULL},
4554 {"( 1.3.6.1.4.1.1466.115.121.1.2 DESC 'Access Point' " X_NOT_H_R ")",
4555 0, NULL, NULL, NULL},
4556 {"( 1.3.6.1.4.1.1466.115.121.1.3 DESC 'Attribute Type Description' )",
4557 0, NULL, NULL, NULL},
4558 {"( 1.3.6.1.4.1.1466.115.121.1.4 DESC 'Audio' "
4560 SLAP_SYNTAX_BLOB, blobValidate, NULL, NULL},
4561 {"( 1.3.6.1.4.1.1466.115.121.1.5 DESC 'Binary' "
4563 SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4564 {"( 1.3.6.1.4.1.1466.115.121.1.6 DESC 'Bit String' )",
4565 0, bitStringValidate, NULL, NULL },
4566 {"( 1.3.6.1.4.1.1466.115.121.1.7 DESC 'Boolean' )",
4567 0, booleanValidate, NULL, NULL},
4568 {"( 1.3.6.1.4.1.1466.115.121.1.8 DESC 'Certificate' "
4569 X_BINARY X_NOT_H_R ")",
4570 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4571 {"( 1.3.6.1.4.1.1466.115.121.1.9 DESC 'Certificate List' "
4572 X_BINARY X_NOT_H_R ")",
4573 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4574 {"( 1.3.6.1.4.1.1466.115.121.1.10 DESC 'Certificate Pair' "
4575 X_BINARY X_NOT_H_R ")",
4576 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4577 {"( 1.3.6.1.4.1.1466.115.121.1.11 DESC 'Country String' )",
4578 0, countryStringValidate, xIA5StringNormalize, NULL},
4579 {"( 1.3.6.1.4.1.1466.115.121.1.12 DESC 'Distinguished Name' )",
4580 0, dnValidate, dnNormalize2, dnPretty2},
4581 {"( 1.3.6.1.4.1.1466.115.121.1.13 DESC 'Data Quality' )",
4582 0, NULL, NULL, NULL},
4583 {"( 1.3.6.1.4.1.1466.115.121.1.14 DESC 'Delivery Method' )",
4584 0, NULL, NULL, NULL},
4585 {"( 1.3.6.1.4.1.1466.115.121.1.15 DESC 'Directory String' )",
4586 0, UTF8StringValidate, xUTF8StringNormalize, NULL},
4587 {"( 1.3.6.1.4.1.1466.115.121.1.16 DESC 'DIT Content Rule Description' )",
4588 0, NULL, NULL, NULL},
4589 {"( 1.3.6.1.4.1.1466.115.121.1.17 DESC 'DIT Structure Rule Description' )",
4590 0, NULL, NULL, NULL},
4591 {"( 1.3.6.1.4.1.1466.115.121.1.19 DESC 'DSA Quality' )",
4592 0, NULL, NULL, NULL},
4593 {"( 1.3.6.1.4.1.1466.115.121.1.20 DESC 'DSE Type' )",
4594 0, NULL, NULL, NULL},
4595 {"( 1.3.6.1.4.1.1466.115.121.1.21 DESC 'Enhanced Guide' )",
4596 0, NULL, NULL, NULL},
4597 {"( 1.3.6.1.4.1.1466.115.121.1.22 DESC 'Facsimile Telephone Number' )",
4598 0, printablesStringValidate, xtelephoneNumberNormalize, NULL},
4599 {"( 1.3.6.1.4.1.1466.115.121.1.23 DESC 'Fax' " X_NOT_H_R ")",
4600 SLAP_SYNTAX_BLOB, NULL, NULL, NULL},
4601 {"( 1.3.6.1.4.1.1466.115.121.1.24 DESC 'Generalized Time' )",
4602 0, generalizedTimeValidate, xgeneralizedTimeNormalize, NULL},
4603 {"( 1.3.6.1.4.1.1466.115.121.1.25 DESC 'Guide' )",
4604 0, NULL, NULL, NULL},
4605 {"( 1.3.6.1.4.1.1466.115.121.1.26 DESC 'IA5 String' )",
4606 0, IA5StringValidate, xIA5StringNormalize, NULL},
4607 {"( 1.3.6.1.4.1.1466.115.121.1.27 DESC 'Integer' )",
4608 0, integerValidate, xintegerNormalize, NULL},
4609 {"( 1.3.6.1.4.1.1466.115.121.1.28 DESC 'JPEG' " X_NOT_H_R ")",
4610 SLAP_SYNTAX_BLOB, blobValidate, NULL, NULL},
4611 {"( 1.3.6.1.4.1.1466.115.121.1.29 DESC 'Master And Shadow Access Points' )",
4612 0, NULL, NULL, NULL},
4613 {"( 1.3.6.1.4.1.1466.115.121.1.30 DESC 'Matching Rule Description' )",
4614 0, NULL, NULL, NULL},
4615 {"( 1.3.6.1.4.1.1466.115.121.1.31 DESC 'Matching Rule Use Description' )",
4616 0, NULL, NULL, NULL},
4617 {"( 1.3.6.1.4.1.1466.115.121.1.32 DESC 'Mail Preference' )",
4618 0, NULL, NULL, NULL},
4619 {"( 1.3.6.1.4.1.1466.115.121.1.33 DESC 'MHS OR Address' )",
4620 0, NULL, NULL, NULL},
4621 {"( 1.3.6.1.4.1.1466.115.121.1.34 DESC 'Name And Optional UID' )",
4622 0, nameUIDValidate, xnameUIDNormalize, NULL},
4623 {"( 1.3.6.1.4.1.1466.115.121.1.35 DESC 'Name Form Description' )",
4624 0, NULL, NULL, NULL},
4625 {"( 1.3.6.1.4.1.1466.115.121.1.36 DESC 'Numeric String' )",
4626 0, numericStringValidate, xnumericStringNormalize, NULL},
4627 {"( 1.3.6.1.4.1.1466.115.121.1.37 DESC 'Object Class Description' )",
4628 0, NULL, NULL, NULL},
4629 {"( 1.3.6.1.4.1.1466.115.121.1.38 DESC 'OID' )",
4630 0, oidValidate, NULL, NULL},
4631 {"( 1.3.6.1.4.1.1466.115.121.1.39 DESC 'Other Mailbox' )",
4632 0, IA5StringValidate, xIA5StringNormalize, NULL},
4633 {"( 1.3.6.1.4.1.1466.115.121.1.40 DESC 'Octet String' )",
4634 0, blobValidate, NULL, NULL},
4635 {"( 1.3.6.1.4.1.1466.115.121.1.41 DESC 'Postal Address' )",
4636 0, UTF8StringValidate, xUTF8StringNormalize, NULL},
4637 {"( 1.3.6.1.4.1.1466.115.121.1.42 DESC 'Protocol Information' )",
4638 0, NULL, NULL, NULL},
4639 {"( 1.3.6.1.4.1.1466.115.121.1.43 DESC 'Presentation Address' )",
4640 0, NULL, NULL, NULL},
4641 {"( 1.3.6.1.4.1.1466.115.121.1.44 DESC 'Printable String' )",
4642 0, printableStringValidate, xIA5StringNormalize, NULL},
4643 {"( 1.3.6.1.4.1.1466.115.121.1.45 DESC 'SubtreeSpecification' "
4644 X_BINARY X_NOT_H_R ")",
4645 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, NULL, NULL, NULL},
4646 {"( 1.3.6.1.4.1.1466.115.121.1.49 DESC 'Supported Algorithm' "
4647 X_BINARY X_NOT_H_R ")",
4648 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4649 {"( 1.3.6.1.4.1.1466.115.121.1.50 DESC 'Telephone Number' )",
4650 0, printableStringValidate, xtelephoneNumberNormalize, NULL},
4651 {"( 1.3.6.1.4.1.1466.115.121.1.51 DESC 'Teletex Terminal Identifier' )",
4652 0, NULL, NULL, NULL},
4653 {"( 1.3.6.1.4.1.1466.115.121.1.52 DESC 'Telex Number' )",
4654 0, printablesStringValidate, xIA5StringNormalize, NULL},
4655 #ifdef SUPPORT_OBSOLETE_UTC_SYNTAX
4656 {"( 1.3.6.1.4.1.1466.115.121.1.53 DESC 'UTC Time' )",
4657 0, utcTimeValidate, xutcTimeNormalize, NULL},
4659 {"( 1.3.6.1.4.1.1466.115.121.1.54 DESC 'LDAP Syntax Description' )",
4660 0, NULL, NULL, NULL},
4661 {"( 1.3.6.1.4.1.1466.115.121.1.55 DESC 'Modify Rights' )",
4662 0, NULL, NULL, NULL},
4663 {"( 1.3.6.1.4.1.1466.115.121.1.56 DESC 'LDAP Schema Definition' )",
4664 0, NULL, NULL, NULL},
4665 {"( 1.3.6.1.4.1.1466.115.121.1.57 DESC 'LDAP Schema Description' )",
4666 0, NULL, NULL, NULL},
4667 {"( 1.3.6.1.4.1.1466.115.121.1.58 DESC 'Substring Assertion' )",
4668 0, NULL, NULL, NULL},
4670 /* RFC 2307 NIS Syntaxes */
4671 {"( 1.3.6.1.1.1.0.0 DESC 'RFC2307 NIS Netgroup Triple' )",
4672 0, nisNetgroupTripleValidate, NULL, NULL},
4673 {"( 1.3.6.1.1.1.0.1 DESC 'RFC2307 Boot Parameter' )",
4674 0, bootParameterValidate, NULL, NULL},
4678 /* These OIDs are not published yet, but will be in the next
4679 * I-D for PKIX LDAPv3 schema as have been advanced by David
4680 * Chadwick in private mail.
4682 {"( 1.2.826.0.1.3344810.7.1 DESC 'Serial Number and Issuer' )",
4683 0, UTF8StringValidate, NULL, NULL},
4686 /* OpenLDAP Experimental Syntaxes */
4687 #ifdef SLAPD_ACI_ENABLED
4688 {"( 1.3.6.1.4.1.4203.666.2.1 DESC 'OpenLDAP Experimental ACI' )",
4690 UTF8StringValidate /* THIS WILL CHANGE FOR NEW ACI SYNTAX */,
4694 #ifdef SLAPD_AUTHPASSWD
4695 /* needs updating */
4696 {"( 1.3.6.1.4.1.4203.666.2.2 DESC 'OpenLDAP authPassword' )",
4697 SLAP_SYNTAX_HIDE, NULL, NULL, NULL},
4700 /* OpenLDAP Void Syntax */
4701 {"( 1.3.6.1.4.1.4203.1.1.1 DESC 'OpenLDAP void' )" ,
4702 SLAP_SYNTAX_HIDE, inValidate, NULL, NULL},
4703 {NULL, 0, NULL, NULL, NULL}
4707 char *certificateExactMatchSyntaxes[] = {
4708 "1.3.6.1.4.1.1466.115.121.1.8" /* certificate */,
4712 char *directoryStringSyntaxes[] = {
4713 "1.3.6.1.4.1.1466.115.121.1.44" /* printableString */,
4716 char *integerFirstComponentMatchSyntaxes[] = {
4717 "1.3.6.1.4.1.1466.115.121.1.27" /* INTEGER */,
4718 "1.3.6.1.4.1.1466.115.121.1.17" /* ditStructureRuleDescription */,
4721 char *objectIdentifierFirstComponentMatchSyntaxes[] = {
4722 "1.3.6.1.4.1.1466.115.121.1.38" /* OID */,
4723 "1.3.6.1.4.1.1466.115.121.1.3" /* attributeTypeDescription */,
4724 "1.3.6.1.4.1.1466.115.121.1.16" /* ditContentRuleDescription */,
4725 "1.3.6.1.4.1.1466.115.121.1.54" /* ldapSyntaxDescription */,
4726 "1.3.6.1.4.1.1466.115.121.1.30" /* matchingRuleDescription */,
4727 "1.3.6.1.4.1.1466.115.121.1.31" /* matchingRuleUseDescription */,
4728 "1.3.6.1.4.1.1466.115.121.1.35" /* nameFormDescription */,
4729 "1.3.6.1.4.1.1466.115.121.1.37" /* objectClassDescription */,
4734 * Other matching rules in X.520 that we do not use (yet):
4736 * 2.5.13.9 numericStringOrderingMatch
4737 * 2.5.13.19 octetStringSubstringsMatch
4738 * 2.5.13.25 uTCTimeMatch
4739 * 2.5.13.26 uTCTimeOrderingMatch
4740 * 2.5.13.31 directoryStringFirstComponentMatch
4741 * 2.5.13.32 wordMatch
4742 * 2.5.13.33 keywordMatch
4743 * 2.5.13.35 certificateMatch
4744 * 2.5.13.36 certificatePairExactMatch
4745 * 2.5.13.37 certificatePairMatch
4746 * 2.5.13.38 certificateListExactMatch
4747 * 2.5.13.39 certificateListMatch
4748 * 2.5.13.40 algorithmIdentifierMatch
4749 * 2.5.13.41 storedPrefixMatch
4750 * 2.5.13.42 attributeCertificateMatch
4751 * 2.5.13.43 readerAndKeyIDMatch
4752 * 2.5.13.44 attributeIntegrityMatch
4754 static slap_mrule_defs_rec mrule_defs[] = {
4756 * EQUALITY matching rules must be listed after associated APPROX
4757 * matching rules. So, we list all APPROX matching rules first.
4759 #ifndef SLAP_NVALUES
4760 {"( " directoryStringApproxMatchOID " NAME 'directoryStringApproxMatch' "
4761 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4762 SLAP_MR_HIDE | SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT, NULL,
4763 NULL, NULL, directoryStringApproxMatch,
4764 directoryStringApproxIndexer, directoryStringApproxFilter,
4767 {"( " IA5StringApproxMatchOID " NAME 'IA5StringApproxMatch' "
4768 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4769 SLAP_MR_HIDE | SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT, NULL,
4770 NULL, NULL, IA5StringApproxMatch,
4771 IA5StringApproxIndexer, IA5StringApproxFilter,
4776 * Other matching rules
4779 {"( 2.5.13.0 NAME 'objectIdentifierMatch' "
4780 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
4781 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4783 objectIdentifierNormalize, objectIdentifierMatch,
4784 objectIdentifierIndexer, objectIdentifierFilter,
4787 {"( 2.5.13.1 NAME 'distinguishedNameMatch' "
4788 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )",
4789 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4791 distinguishedNameNormalize, distinguishedNameMatch,
4792 distinguishedNameIndexer, distinguishedNameFilter,
4795 {"( 2.5.13.2 NAME 'caseIgnoreMatch' "
4796 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4797 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD,
4798 directoryStringSyntaxes,
4800 caseIgnoreNormalize, caseIgnoreMatch,
4801 caseIgnoreIndexer, caseIgnoreFilter,
4802 directoryStringApproxMatchOID },
4804 {"( 2.5.13.3 NAME 'caseIgnoreOrderingMatch' "
4805 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4806 SLAP_MR_ORDERING, directoryStringSyntaxes,
4807 NULL, caseIgnoreNormalize, caseIgnoreOrderingMatch,
4810 {"( 2.5.13.4 NAME 'caseIgnoreSubstringsMatch' "
4811 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4812 SLAP_MR_SUBSTR, NULL,
4814 caseIgnoreSubstringsMatch,
4815 caseIgnoreSubstringsIndexer, caseIgnoreSubstringsFilter,
4818 {"( 2.5.13.5 NAME 'caseExactMatch' "
4819 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4820 SLAP_MR_EQUALITY | SLAP_MR_EXT, directoryStringSyntaxes,
4822 caseExactNormalize, caseExactMatch,
4823 caseExactIndexer, caseExactFilter,
4824 directoryStringApproxMatchOID },
4826 {"( 2.5.13.6 NAME 'caseExactOrderingMatch' "
4827 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4828 SLAP_MR_ORDERING, directoryStringSyntaxes,
4829 NULL, caseExactNormalize, caseExactOrderingMatch,
4832 {"( 2.5.13.7 NAME 'caseExactSubstringsMatch' "
4833 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4834 SLAP_MR_SUBSTR, directoryStringSyntaxes,
4836 NULL, caseExactSubstringsMatch,
4837 caseExactSubstringsIndexer, caseExactSubstringsFilter,
4840 {"( 2.5.13.8 NAME 'numericStringMatch' "
4841 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 )",
4842 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL,
4844 numericStringNormalize, numericStringMatch,
4845 numericStringIndexer, numericStringFilter,
4848 {"( 2.5.13.10 NAME 'numericStringSubstringsMatch' "
4849 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4850 SLAP_MR_SUBSTR, NULL,
4852 NULL, numericStringSubstringsMatch,
4853 numericStringSubstringsIndexer, numericStringSubstringsFilter,
4856 {"( 2.5.13.11 NAME 'caseIgnoreListMatch' "
4857 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )",
4858 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL,
4859 NULL, NULL, NULL, NULL, NULL, NULL},
4861 {"( 2.5.13.12 NAME 'caseIgnoreListSubstringsMatch' "
4862 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4863 SLAP_MR_SUBSTR, NULL,
4864 NULL, NULL, NULL, NULL, NULL, NULL},
4866 {"( 2.5.13.13 NAME 'booleanMatch' "
4867 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )",
4868 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4869 NULL, NULL, booleanMatch, NULL, NULL, NULL},
4871 {"( 2.5.13.14 NAME 'integerMatch' "
4872 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4873 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4875 integerNormalize, integerMatch,
4876 integerIndexer, integerFilter,
4879 {"( 2.5.13.15 NAME 'integerOrderingMatch' "
4880 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4881 SLAP_MR_ORDERING, NULL, NULL,
4882 integerNormalize, integerOrderingMatch,
4883 integerIndexer, integerFilter,
4886 {"( 2.5.13.16 NAME 'bitStringMatch' "
4887 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.6 )",
4888 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4890 bitStringNormalize, bitStringMatch,
4891 bitStringIndexer, bitStringFilter,
4894 {"( 2.5.13.17 NAME 'octetStringMatch' "
4895 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
4896 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4898 octetStringMatch, octetStringIndexer, octetStringFilter,
4901 {"( 2.5.13.18 NAME 'octetStringOrderingMatch' "
4902 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
4903 SLAP_MR_ORDERING, NULL,
4905 octetStringOrderingMatch, NULL, NULL,
4908 {"( 2.5.13.20 NAME 'telephoneNumberMatch' "
4909 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 )",
4910 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL,
4912 telephoneNumberNormalize, telephoneNumberMatch,
4913 telephoneNumberIndexer, telephoneNumberFilter,
4916 {"( 2.5.13.21 NAME 'telephoneNumberSubstringsMatch' "
4917 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4918 SLAP_MR_SUBSTR, NULL,
4919 NULL, NULL, telephoneNumberSubstringsMatch,
4920 telephoneNumberSubstringsIndexer, telephoneNumberSubstringsFilter,
4923 {"( 2.5.13.22 NAME 'presentationAddressMatch' "
4924 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.43 )",
4925 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4930 {"( 2.5.13.23 NAME 'uniqueMemberMatch' "
4931 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.34 )",
4932 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4934 uniqueMemberNormalize, uniqueMemberMatch,
4938 {"( 2.5.13.24 NAME 'protocolInformationMatch' "
4939 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.42 )",
4940 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4941 NULL, NULL, NULL, NULL, NULL, NULL},
4943 {"( 2.5.13.27 NAME 'generalizedTimeMatch' "
4944 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
4945 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4947 generalizedTimeNormalize, generalizedTimeMatch,
4951 {"( 2.5.13.28 NAME 'generalizedTimeOrderingMatch' "
4952 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
4953 SLAP_MR_ORDERING, NULL,
4955 generalizedTimeNormalize, generalizedTimeOrderingMatch,
4959 {"( 2.5.13.29 NAME 'integerFirstComponentMatch' "
4960 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4961 SLAP_MR_EQUALITY | SLAP_MR_EXT, integerFirstComponentMatchSyntaxes,
4963 integerFirstComponentNormalize, integerMatch,
4967 {"( 2.5.13.30 NAME 'objectIdentifierFirstComponentMatch' "
4968 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
4969 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4970 objectIdentifierFirstComponentMatchSyntaxes,
4972 objectIdentifierFirstComponentNormalize, objectIdentifierMatch,
4976 #ifndef SLAP_NVALUES
4978 {"( 2.5.13.34 NAME 'certificateExactMatch' "
4979 "SYNTAX 1.2.826.0.1.3344810.7.1 )",
4980 SLAP_MR_EQUALITY | SLAP_MR_EXT, certificateExactMatchSyntaxes,
4981 certificateExactConvert, NULL,
4982 certificateExactMatch,
4983 certificateExactIndexer, certificateExactFilter,
4988 {"( 1.3.6.1.4.1.1466.109.114.1 NAME 'caseExactIA5Match' "
4989 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4990 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4992 caseExactIA5Normalize, caseExactIA5Match,
4993 caseExactIA5Indexer, caseExactIA5Filter,
4994 IA5StringApproxMatchOID },
4996 {"( 1.3.6.1.4.1.1466.109.114.2 NAME 'caseIgnoreIA5Match' "
4997 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4998 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL,
5000 NULL, caseIgnoreIA5Match,
5001 caseIgnoreIA5Indexer, caseIgnoreIA5Filter,
5002 IA5StringApproxMatchOID },
5004 {"( 1.3.6.1.4.1.1466.109.114.3 NAME 'caseIgnoreIA5SubstringsMatch' "
5005 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
5006 SLAP_MR_SUBSTR, NULL,
5008 NULL, caseIgnoreIA5SubstringsMatch,
5009 caseIgnoreIA5SubstringsIndexer, caseIgnoreIA5SubstringsFilter,
5012 {"( 1.3.6.1.4.1.4203.1.2.1 NAME 'caseExactIA5SubstringsMatch' "
5013 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
5014 SLAP_MR_SUBSTR, NULL,
5016 NULL, caseExactIA5SubstringsMatch,
5017 caseExactIA5SubstringsIndexer, caseExactIA5SubstringsFilter,
5020 #ifdef SLAPD_AUTHPASSWD
5021 /* needs updating */
5022 {"( 1.3.6.1.4.1.4203.666.4.1 NAME 'authPasswordMatch' "
5023 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
5024 SLAP_MR_EQUALITY, NULL,
5026 authPasswordMatch, NULL, NULL,
5030 #ifdef SLAPD_ACI_ENABLED
5031 {"( 1.3.6.1.4.1.4203.666.4.2 NAME 'OpenLDAPaciMatch' "
5032 "SYNTAX 1.3.6.1.4.1.4203.666.2.1 )",
5033 SLAP_MR_EQUALITY, NULL,
5035 OpenLDAPaciMatch, NULL, NULL,
5039 {"( 1.2.840.113556.1.4.803 NAME 'integerBitAndMatch' "
5040 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
5043 NULL, integerBitAndMatch, NULL, NULL,
5046 {"( 1.2.840.113556.1.4.804 NAME 'integerBitOrMatch' "
5047 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
5050 NULL, integerBitOrMatch, NULL, NULL,
5053 {NULL, SLAP_MR_NONE, NULL,
5054 NULL, NULL, NULL, NULL, NULL,
5059 slap_schema_init( void )
5064 /* we should only be called once (from main) */
5065 assert( schema_init_done == 0 );
5067 for ( i=0; syntax_defs[i].sd_desc != NULL; i++ ) {
5068 res = register_syntax( &syntax_defs[i] );
5071 fprintf( stderr, "slap_schema_init: Error registering syntax %s\n",
5072 syntax_defs[i].sd_desc );
5077 for ( i=0; mrule_defs[i].mrd_desc != NULL; i++ ) {
5078 if( mrule_defs[i].mrd_usage == SLAP_MR_NONE &&
5079 mrule_defs[i].mrd_compat_syntaxes == NULL )
5082 "slap_schema_init: Ignoring unusable matching rule %s\n",
5083 mrule_defs[i].mrd_desc );
5087 res = register_matching_rule( &mrule_defs[i] );
5091 "slap_schema_init: Error registering matching rule %s\n",
5092 mrule_defs[i].mrd_desc );
5097 res = slap_schema_load();
5098 schema_init_done = 1;
5103 schema_destroy( void )