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
45 #define xdnNormalize NULL
47 /* (new) normalization routines */
48 #define caseExactIA5Normalize IA5StringNormalize
49 #define caseIgnoreIA5Normalize IA5StringNormalize
50 #define caseExactNormalize UTF8StringNormalize
51 #define caseIgnoreNormalize UTF8StringNormalize
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 bitStringNormalize NULL
60 #define telephoneNumberNormalize NULL
62 #define distinguishedNameNormalize dnNormalize
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 OpenLDAPaciMatch NULL
75 #define bitStringMatch octetStringMatch
76 #define bitStringIndexer octetStringIndexer
77 #define bitStringFilter octetStringFilter
79 #define integerMatch NULL
80 #define integerOrderingMatch NULL
81 #define integerIndexer NULL
82 #define integerFilter NULL
84 #define generalizedTimeMatch NULL
85 #define generalizedTimeOrderingMatch NULL
87 #define caseIgnoreMatch octetStringMatch
88 #define caseIgnoreOrderingMatch octetStringOrderingMatch
89 #define caseIgnoreIndexer octetStringIndexer
90 #define caseIgnoreFilter octetStringFilter
92 #define caseIgnoreSubstringsMatch octetStringSubstringsMatch
93 #define caseIgnoreSubstringsIndexer octetStringSubstringsIndexer
94 #define caseIgnoreSubstringsFilter octetStringSubstringsFilter
96 #define caseExactMatch octetStringMatch
97 #define caseExactOrderingMatch octetStringOrderingMatch
98 #define caseExactIndexer octetStringIndexer
99 #define caseExactFilter octetStringFilter
101 #define caseExactSubstringsMatch octetStringSubstringsMatch
102 #define caseExactSubstringsIndexer octetStringSubstringsIndexer
103 #define caseExactSubstringsFilter octetStringSubstringsFilter
105 #define caseExactIA5Match octetStringMatch
106 #define caseExactIA5Indexer octetStringIndexer
107 #define caseExactIA5Filter octetStringFilter
109 #define caseExactIA5SubstringsMatch octetStringSubstringsMatch
110 #define caseExactIA5SubstringsIndexer octetStringSubstringsIndexer
111 #define caseExactIA5SubstringsFilter octetStringSubstringsFilter
113 #define caseIgnoreIA5Match octetStringMatch
114 #define caseIgnoreIA5Indexer octetStringIndexer
115 #define caseIgnoreIA5Filter octetStringFilter
117 #define caseIgnoreIA5SubstringsMatch caseExactIA5SubstringsMatch
118 #define caseIgnoreIA5SubstringsIndexer caseExactIA5SubstringsIndexer
119 #define caseIgnoreIA5SubstringsFilter caseExactIA5SubstringsFilter
121 #define numericStringMatch octetStringMatch
122 #define numericStringIndexer octetStringIndexer
123 #define numericStringFilter octetStringFilter
125 #define numericStringSubstringsMatch caseExactIA5SubstringsMatch
126 #define numericStringSubstringsIndexer caseExactIA5SubstringsIndexer
127 #define numericStringSubstringsFilter caseExactIA5SubstringsFilter
129 #define telephoneNumberMatch octetStringMatch
130 #define telephoneNumberIndexer octetStringIndexer
131 #define telephoneNumberFilter octetStringFilter
133 #define telephoneNumberSubstringsMatch caseExactIA5SubstringsMatch
134 #define telephoneNumberSubstringsIndexer caseExactIA5SubstringsIndexer
135 #define telephoneNumberSubstringsFilter caseExactIA5SubstringsFilter
137 #define booleanIndexer octetStringIndexer
138 #define booleanFilter octetStringFilter
141 /* validatation routines */
142 #define berValidate blobValidate
144 /* approx matching rules */
146 #define directoryStringApproxMatchOID NULL
147 #define IA5StringApproxMatchOID NULL
149 #define directoryStringApproxMatchOID "1.3.6.1.4.1.4203.666.4.4"
150 #define directoryStringApproxMatch approxMatch
151 #define directoryStringApproxIndexer approxIndexer
152 #define directoryStringApproxFilter approxFilter
153 #define IA5StringApproxMatchOID "1.3.6.1.4.1.4203.666.4.5"
154 #define IA5StringApproxMatch approxMatch
155 #define IA5StringApproxIndexer approxIndexer
156 #define IA5StringApproxFilter approxFilter
161 #define xdnNormalize dnNormalize
163 /* (new) normalization routines */
164 #define caseExactNormalize NULL
165 #define caseExactIA5Normalize NULL
166 #define caseIgnoreNormalize NULL
167 #define caseIgnoreIA5Normalize NULL
168 #define distinguishedNameNormalize NULL
169 #define integerNormalize NULL
170 #define integerFirstComponentNormalize NULL
171 #define numericStringNormalize NULL
172 #define objectIdentifierNormalize NULL
173 #define objectIdentifierFirstComponentNormalize NULL
174 #define generalizedTimeNormalize NULL
175 #define uniqueMemberNormalize NULL
176 #define bitStringNormalize NULL
177 #define telephoneNumberNormalize NULL
180 /* matching routines */
181 #define bitStringMatch octetStringMatch
182 #define bitStringIndexer octetStringIndexer
183 #define bitStringFilter octetStringFilter
185 #define numericStringMatch caseIgnoreIA5Match
186 #define numericStringIndexer NULL
187 #define numericStringFilter NULL
188 #define numericStringSubstringsIndexer NULL
189 #define numericStringSubstringsFilter NULL
191 #define objectIdentifierMatch octetStringMatch
192 #define objectIdentifierIndexer caseIgnoreIA5Indexer
193 #define objectIdentifierFilter caseIgnoreIA5Filter
195 #define octetStringSubstringsMatch NULL
196 #define OpenLDAPaciMatch NULL
198 #define generalizedTimeMatch caseIgnoreIA5Match
199 #define generalizedTimeOrderingMatch caseIgnoreIA5Match
201 #define uniqueMemberMatch dnMatch
202 #define numericStringSubstringsMatch NULL
204 #define caseExactIndexer caseExactIgnoreIndexer
205 #define caseExactFilter caseExactIgnoreFilter
206 #define caseExactOrderingMatch caseExactMatch
207 #define caseExactSubstringsMatch caseExactIgnoreSubstringsMatch
208 #define caseExactSubstringsIndexer caseExactIgnoreSubstringsIndexer
209 #define caseExactSubstringsFilter caseExactIgnoreSubstringsFilter
210 #define caseIgnoreIndexer caseExactIgnoreIndexer
211 #define caseIgnoreFilter caseExactIgnoreFilter
212 #define caseIgnoreOrderingMatch caseIgnoreMatch
213 #define caseIgnoreSubstringsMatch caseExactIgnoreSubstringsMatch
214 #define caseIgnoreSubstringsIndexer caseExactIgnoreSubstringsIndexer
215 #define caseIgnoreSubstringsFilter caseExactIgnoreSubstringsFilter
217 #define integerOrderingMatch integerMatch
218 #define integerFirstComponentMatch integerMatch
220 #define distinguishedNameMatch dnMatch
221 #define distinguishedNameIndexer caseExactIgnoreIndexer
222 #define distinguishedNameFilter caseExactIgnoreFilter
224 #define telephoneNumberMatch caseIgnoreIA5Match
225 #define telephoneNumberSubstringsMatch caseIgnoreIA5SubstringsMatch
226 #define telephoneNumberIndexer caseIgnoreIA5Indexer
227 #define telephoneNumberFilter caseIgnoreIA5Filter
228 #define telephoneNumberSubstringsIndexer caseIgnoreIA5SubstringsIndexer
229 #define telephoneNumberSubstringsFilter caseIgnoreIA5SubstringsFilter
231 #define booleanIndexer octetStringIndexer
232 #define booleanFilter octetStringFilter
236 static char *bvcasechr( struct berval *bv, unsigned char c, ber_len_t *len )
239 char lower = TOLOWER( c );
240 char upper = TOUPPER( c );
242 if( c == 0 ) return NULL;
244 for( i=0; i < bv->bv_len; i++ ) {
245 if( upper == bv->bv_val[i] || lower == bv->bv_val[i] ) {
247 return &bv->bv_val[i];
260 struct berval *value,
261 void *assertedValue )
263 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
266 match = memcmp( value->bv_val,
267 ((struct berval *) assertedValue)->bv_val,
276 octetStringOrderingMatch(
281 struct berval *value,
282 void *assertedValue )
284 ber_len_t v_len = value->bv_len;
285 ber_len_t av_len = ((struct berval *) assertedValue)->bv_len;
287 int match = memcmp( value->bv_val,
288 ((struct berval *) assertedValue)->bv_val,
289 (v_len < av_len ? v_len : av_len) );
291 if( match == 0 ) match = v_len - av_len;
297 /* Index generation function */
298 int octetStringIndexer(
303 struct berval *prefix,
310 HASH_CONTEXT HASHcontext;
311 unsigned char HASHdigest[HASH_BYTES];
312 struct berval digest;
313 digest.bv_val = HASHdigest;
314 digest.bv_len = sizeof(HASHdigest);
316 for( i=0; values[i].bv_val != NULL; i++ ) {
317 /* just count them */
320 /* we should have at least one value at this point */
323 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
325 slen = syntax->ssyn_oidlen;
326 mlen = mr->smr_oidlen;
328 for( i=0; values[i].bv_val != NULL; i++ ) {
329 HASH_Init( &HASHcontext );
330 if( prefix != NULL && prefix->bv_len > 0 ) {
331 HASH_Update( &HASHcontext,
332 prefix->bv_val, prefix->bv_len );
334 HASH_Update( &HASHcontext,
335 syntax->ssyn_oid, slen );
336 HASH_Update( &HASHcontext,
338 HASH_Update( &HASHcontext,
339 values[i].bv_val, values[i].bv_len );
340 HASH_Final( HASHdigest, &HASHcontext );
342 ber_dupbv( &keys[i], &digest );
345 keys[i].bv_val = NULL;
353 /* Index generation function */
354 int octetStringFilter(
359 struct berval *prefix,
360 void * assertedValue,
365 HASH_CONTEXT HASHcontext;
366 unsigned char HASHdigest[HASH_BYTES];
367 struct berval *value = (struct berval *) assertedValue;
368 struct berval digest;
369 digest.bv_val = HASHdigest;
370 digest.bv_len = sizeof(HASHdigest);
372 slen = syntax->ssyn_oidlen;
373 mlen = mr->smr_oidlen;
375 keys = ch_malloc( sizeof( struct berval ) * 2 );
377 HASH_Init( &HASHcontext );
378 if( prefix != NULL && prefix->bv_len > 0 ) {
379 HASH_Update( &HASHcontext,
380 prefix->bv_val, prefix->bv_len );
382 HASH_Update( &HASHcontext,
383 syntax->ssyn_oid, slen );
384 HASH_Update( &HASHcontext,
386 HASH_Update( &HASHcontext,
387 value->bv_val, value->bv_len );
388 HASH_Final( HASHdigest, &HASHcontext );
390 ber_dupbv( keys, &digest );
391 keys[1].bv_val = NULL;
404 /* no value allowed */
405 return LDAP_INVALID_SYNTAX;
413 /* any value allowed */
424 /* very unforgiving validation, requires no normalization
425 * before simplistic matching
427 if( in->bv_len < 3 ) {
428 return LDAP_INVALID_SYNTAX;
432 * rfc 2252 section 6.3 Bit String
433 * bitstring = "'" *binary-digit "'"
434 * binary-digit = "0" / "1"
435 * example: '0101111101'B
438 if( in->bv_val[0] != '\'' ||
439 in->bv_val[in->bv_len-2] != '\'' ||
440 in->bv_val[in->bv_len-1] != 'B' )
442 return LDAP_INVALID_SYNTAX;
445 for( i=in->bv_len-3; i>0; i-- ) {
446 if( in->bv_val[i] != '0' && in->bv_val[i] != '1' ) {
447 return LDAP_INVALID_SYNTAX;
462 if( in->bv_len == 0 ) return LDAP_SUCCESS;
464 ber_dupbv( &dn, in );
465 if( !dn.bv_val ) return LDAP_OTHER;
467 if( dn.bv_val[dn.bv_len-1] == 'B'
468 && dn.bv_val[dn.bv_len-2] == '\'' )
470 /* assume presence of optional UID */
473 for(i=dn.bv_len-3; i>1; i--) {
474 if( dn.bv_val[i] != '0' && dn.bv_val[i] != '1' ) {
478 if( dn.bv_val[i] != '\'' || dn.bv_val[i-1] != '#' ) {
479 ber_memfree( dn.bv_val );
480 return LDAP_INVALID_SYNTAX;
483 /* trim the UID to allow use of dnValidate */
484 dn.bv_val[i-1] = '\0';
488 rc = dnValidate( NULL, &dn );
490 ber_memfree( dn.bv_val );
496 uniqueMemberNormalize(
501 struct berval *normalized )
507 struct berval *normalized )
513 ber_dupbv( &out, val );
514 if( out.bv_len != 0 ) {
515 struct berval uid = { 0, NULL };
517 if( out.bv_val[out.bv_len-1] == 'B'
518 && out.bv_val[out.bv_len-2] == '\'' )
520 /* assume presence of optional UID */
521 uid.bv_val = strrchr( out.bv_val, '#' );
523 if( uid.bv_val == NULL ) {
525 return LDAP_INVALID_SYNTAX;
528 uid.bv_len = out.bv_len - (uid.bv_val - out.bv_val);
529 out.bv_len -= uid.bv_len--;
531 /* temporarily trim the UID */
532 *(uid.bv_val++) = '\0';
535 rc = dnNormalize2( NULL, &out, normalized );
537 if( rc != LDAP_SUCCESS ) {
539 return LDAP_INVALID_SYNTAX;
543 normalized->bv_val = ch_realloc( normalized->bv_val,
544 normalized->bv_len + uid.bv_len + sizeof("#") );
546 /* insert the separator */
547 normalized->bv_val[normalized->bv_len++] = '#';
550 AC_MEMCPY( &normalized->bv_val[normalized->bv_len],
551 uid.bv_val, uid.bv_len );
552 normalized->bv_len += uid.bv_len;
555 normalized->bv_val[normalized->bv_len] = '\0';
565 * Handling boolean syntax and matching is quite rigid.
566 * A more flexible approach would be to allow a variety
567 * of strings to be normalized and prettied into TRUE
575 /* very unforgiving validation, requires no normalization
576 * before simplistic matching
579 if( in->bv_len == 4 ) {
580 if( !memcmp( in->bv_val, "TRUE", 4 ) ) {
583 } else if( in->bv_len == 5 ) {
584 if( !memcmp( in->bv_val, "FALSE", 5 ) ) {
589 return LDAP_INVALID_SYNTAX;
598 struct berval *value,
599 void *assertedValue )
601 /* simplistic matching allowed by rigid validation */
602 struct berval *asserted = (struct berval *) assertedValue;
603 *matchp = value->bv_len != asserted->bv_len;
607 /*-------------------------------------------------------------------
608 LDAP/X.500 string syntax / matching rules have a few oddities. This
609 comment attempts to detail how slapd(8) treats them.
612 StringSyntax X.500 LDAP Matching/Comments
613 DirectoryString CHOICE UTF8 i/e + ignore insignificant spaces
614 PrintableString subset subset i/e + ignore insignificant spaces
615 PrintableString subset subset i/e + ignore insignificant spaces
616 NumericString subset subset ignore all spaces
617 IA5String ASCII ASCII i/e + ignore insignificant spaces
618 TeletexString T.61 T.61 i/e + ignore insignificant spaces
620 TelephoneNumber subset subset i + ignore all spaces and "-"
622 See draft-ietf-ldapbis-strpro for details (once published).
626 In X.500(93), a directory string can be either a PrintableString,
627 a bmpString, or a UniversalString (e.g., UCS (a subset of Unicode)).
628 In later versions, more CHOICEs were added. In all cases the string
631 In LDAPv3, a directory string is a UTF-8 encoded UCS string.
632 A directory string cannot be zero length.
634 For matching, there are both case ignore and exact rules. Both
635 also require that "insignificant" spaces be ignored.
636 spaces before the first non-space are ignored;
637 spaces after the last non-space are ignored;
638 spaces after a space are ignored.
639 Note: by these rules (and as clarified in X.520), a string of only
640 spaces is to be treated as if held one space, not empty (which
641 would be a syntax error).
644 In ASN.1, numeric string is just a string of digits and spaces
645 and could be empty. However, in X.500, all attribute values of
646 numeric string carry a non-empty constraint. For example:
648 internationalISDNNumber ATTRIBUTE ::= {
649 WITH SYNTAX InternationalISDNNumber
650 EQUALITY MATCHING RULE numericStringMatch
651 SUBSTRINGS MATCHING RULE numericStringSubstringsMatch
652 ID id-at-internationalISDNNumber }
653 InternationalISDNNumber ::=
654 NumericString (SIZE(1..ub-international-isdn-number))
656 Unforunately, some assertion values are don't carry the same
657 constraint (but its unclear how such an assertion could ever
658 be true). In LDAP, there is one syntax (numericString) not two
659 (numericString with constraint, numericString without constraint).
660 This should be treated as numericString with non-empty constraint.
661 Note that while someone may have no ISDN number, there are no ISDN
662 numbers which are zero length.
664 In matching, spaces are ignored.
667 In ASN.1, Printable string is just a string of printable characters
668 and can be empty. In X.500, semantics much like NumericString (see
669 serialNumber for a like example) excepting uses insignificant space
670 handling instead of ignore all spaces.
673 Basically same as PrintableString. There are no examples in X.500,
674 but same logic applies. So we require them to be non-empty as
677 -------------------------------------------------------------------*/
686 unsigned char *u = in->bv_val;
688 if( in->bv_len == 0 && syntax == slap_schema.si_syn_directoryString ) {
689 /* directory strings cannot be empty */
690 return LDAP_INVALID_SYNTAX;
693 for( count = in->bv_len; count > 0; count-=len, u+=len ) {
694 /* get the length indicated by the first byte */
695 len = LDAP_UTF8_CHARLEN2( u, len );
697 /* very basic checks */
700 if( (u[5] & 0xC0) != 0x80 ) {
701 return LDAP_INVALID_SYNTAX;
704 if( (u[4] & 0xC0) != 0x80 ) {
705 return LDAP_INVALID_SYNTAX;
708 if( (u[3] & 0xC0) != 0x80 ) {
709 return LDAP_INVALID_SYNTAX;
712 if( (u[2] & 0xC0 )!= 0x80 ) {
713 return LDAP_INVALID_SYNTAX;
716 if( (u[1] & 0xC0) != 0x80 ) {
717 return LDAP_INVALID_SYNTAX;
720 /* CHARLEN already validated it */
723 return LDAP_INVALID_SYNTAX;
726 /* make sure len corresponds with the offset
727 to the next character */
728 if( LDAP_UTF8_OFFSET( u ) != len ) return LDAP_INVALID_SYNTAX;
732 return LDAP_INVALID_SYNTAX;
745 struct berval *normalized )
747 struct berval tmp, nvalue;
751 if( val->bv_val == NULL ) {
752 /* assume we're dealing with a syntax (e.g., UTF8String)
753 * which allows empty strings
755 normalized->bv_len = 0;
756 normalized->bv_val = NULL;
760 flags = SLAP_MR_ASSOCIATED(mr, slap_schema.si_mr_caseExactMatch )
761 ? LDAP_UTF8_NOCASEFOLD : LDAP_UTF8_CASEFOLD;
762 flags |= ( use & SLAP_MR_EQUALITY_APPROX == SLAP_MR_EQUALITY_APPROX )
763 ? LDAP_UTF8_APPROX : 0;
765 val = UTF8bvnormalize( val, &tmp, flags );
770 /* collapse spaces (in place) */
772 nvalue.bv_val = tmp.bv_val;
774 wasspace=1; /* trim leading spaces */
775 for( i=0; i<tmp.bv_len; i++) {
776 if ( ASCII_SPACE( tmp.bv_val[i] )) {
777 if( wasspace++ == 0 ) {
778 /* trim repeated spaces */
779 nvalue.bv_val[nvalue.bv_len++] = tmp.bv_val[i];
783 nvalue.bv_val[nvalue.bv_len++] = tmp.bv_val[i];
787 if( nvalue.bv_len ) {
789 /* last character was a space, trim it */
792 nvalue.bv_val[nvalue.bv_len] = '\0';
795 /* string of all spaces is treated as one space */
796 nvalue.bv_val[0] = ' ';
797 nvalue.bv_val[1] = '\0';
801 *normalized = nvalue;
807 xUTF8StringNormalize(
810 struct berval *normalized )
815 /* validator should have refused an empty string */
816 assert( val->bv_len );
820 /* Ignore initial whitespace */
821 /* All space is ASCII. All ASCII is 1 byte */
822 for ( ; p < val->bv_val + val->bv_len && ASCII_SPACE( p[ 0 ] ); p++ );
824 normalized->bv_len = val->bv_len - (p - val->bv_val);
826 if( !normalized->bv_len ) {
827 ber_mem2bv( " ", 1, 1, normalized );
831 ber_mem2bv( p, normalized->bv_len, 1, normalized );
832 e = normalized->bv_val + normalized->bv_len;
834 assert( normalized->bv_val );
836 p = q = normalized->bv_val;
841 if ( ASCII_SPACE( *p ) ) {
846 /* Ignore the extra whitespace */
847 while ( ASCII_SPACE( *p ) ) {
851 len = LDAP_UTF8_COPY(q,p);
857 assert( normalized->bv_val <= p );
858 assert( q+len <= p );
860 /* cannot start with a space */
861 assert( !ASCII_SPACE( normalized->bv_val[0] ) );
864 * If the string ended in space, backup the pointer one
865 * position. One is enough because the above loop collapsed
866 * all whitespace to a single space.
874 /* cannot end with a space */
875 assert( !ASCII_SPACE( *q ) );
882 normalized->bv_len = q - normalized->bv_val;
887 /* Returns Unicode canonically normalized copy of a substring assertion
888 * Skipping attribute description */
889 static SubstringsAssertion *
890 UTF8SubstringsAssertionNormalize(
891 SubstringsAssertion *sa,
894 SubstringsAssertion *nsa;
897 nsa = (SubstringsAssertion *)SLAP_CALLOC( 1, sizeof(SubstringsAssertion) );
902 if( sa->sa_initial.bv_val != NULL ) {
903 UTF8bvnormalize( &sa->sa_initial, &nsa->sa_initial, casefold );
904 if( nsa->sa_initial.bv_val == NULL ) {
909 if( sa->sa_any != NULL ) {
910 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
913 nsa->sa_any = (struct berval *)
914 SLAP_MALLOC( (i + 1) * sizeof(struct berval) );
915 if( nsa->sa_any == NULL ) {
919 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
920 UTF8bvnormalize( &sa->sa_any[i], &nsa->sa_any[i],
922 if( nsa->sa_any[i].bv_val == NULL ) {
926 nsa->sa_any[i].bv_val = NULL;
929 if( sa->sa_final.bv_val != NULL ) {
930 UTF8bvnormalize( &sa->sa_final, &nsa->sa_final, casefold );
931 if( nsa->sa_final.bv_val == NULL ) {
939 if ( nsa->sa_final.bv_val ) free( nsa->sa_final.bv_val );
940 if ( nsa->sa_any ) ber_bvarray_free( nsa->sa_any );
941 if ( nsa->sa_initial.bv_val ) free( nsa->sa_initial.bv_val );
946 #ifndef SLAPD_APPROX_OLDSINGLESTRING
948 #if defined(SLAPD_APPROX_INITIALS)
949 #define SLAPD_APPROX_DELIMITER "._ "
950 #define SLAPD_APPROX_WORDLEN 2
952 #define SLAPD_APPROX_DELIMITER " "
953 #define SLAPD_APPROX_WORDLEN 1
962 struct berval *value,
963 void *assertedValue )
965 struct berval *nval, *assertv;
966 char *val, **values, **words, *c;
967 int i, count, len, nextchunk=0, nextavail=0;
969 /* Yes, this is necessary */
970 nval = UTF8bvnormalize( value, NULL, LDAP_UTF8_APPROX );
976 /* Yes, this is necessary */
977 assertv = UTF8bvnormalize( ((struct berval *)assertedValue),
978 NULL, LDAP_UTF8_APPROX );
979 if( assertv == NULL ) {
985 /* Isolate how many words there are */
986 for ( c = nval->bv_val, count = 1; *c; c++ ) {
987 c = strpbrk( c, SLAPD_APPROX_DELIMITER );
988 if ( c == NULL ) break;
993 /* Get a phonetic copy of each word */
994 words = (char **)ch_malloc( count * sizeof(char *) );
995 values = (char **)ch_malloc( count * sizeof(char *) );
996 for ( c = nval->bv_val, i = 0; i < count; i++, c += strlen(c) + 1 ) {
998 values[i] = phonetic(c);
1001 /* Work through the asserted value's words, to see if at least some
1002 of the words are there, in the same order. */
1004 while ( (ber_len_t) nextchunk < assertv->bv_len ) {
1005 len = strcspn( assertv->bv_val + nextchunk, SLAPD_APPROX_DELIMITER);
1010 #if defined(SLAPD_APPROX_INITIALS)
1011 else if( len == 1 ) {
1012 /* Single letter words need to at least match one word's initial */
1013 for( i=nextavail; i<count; i++ )
1014 if( !strncasecmp( assertv->bv_val + nextchunk, words[i], 1 )) {
1021 /* Isolate the next word in the asserted value and phonetic it */
1022 assertv->bv_val[nextchunk+len] = '\0';
1023 val = phonetic( assertv->bv_val + nextchunk );
1025 /* See if this phonetic chunk is in the remaining words of *value */
1026 for( i=nextavail; i<count; i++ ){
1027 if( !strcmp( val, values[i] ) ){
1035 /* This chunk in the asserted value was NOT within the *value. */
1041 /* Go on to the next word in the asserted value */
1045 /* If some of the words were seen, call it a match */
1046 if( nextavail > 0 ) {
1053 /* Cleanup allocs */
1054 ber_bvfree( assertv );
1055 for( i=0; i<count; i++ ) {
1056 ch_free( values[i] );
1062 return LDAP_SUCCESS;
1071 struct berval *prefix,
1076 int i,j, len, wordcount, keycount=0;
1077 struct berval *newkeys;
1078 BerVarray keys=NULL;
1080 for( j=0; values[j].bv_val != NULL; j++ ) {
1081 struct berval val = { 0, NULL };
1082 /* Yes, this is necessary */
1083 UTF8bvnormalize( &values[j], &val, LDAP_UTF8_APPROX );
1084 assert( val.bv_val != NULL );
1086 /* Isolate how many words there are. There will be a key for each */
1087 for( wordcount = 0, c = val.bv_val; *c; c++) {
1088 len = strcspn(c, SLAPD_APPROX_DELIMITER);
1089 if( len >= SLAPD_APPROX_WORDLEN ) wordcount++;
1091 if (*c == '\0') break;
1095 /* Allocate/increase storage to account for new keys */
1096 newkeys = (struct berval *)ch_malloc( (keycount + wordcount + 1)
1097 * sizeof(struct berval) );
1098 AC_MEMCPY( newkeys, keys, keycount * sizeof(struct berval) );
1099 if( keys ) ch_free( keys );
1102 /* Get a phonetic copy of each word */
1103 for( c = val.bv_val, i = 0; i < wordcount; c += len + 1 ) {
1105 if( len < SLAPD_APPROX_WORDLEN ) continue;
1106 ber_str2bv( phonetic( c ), 0, 0, &keys[keycount] );
1111 ber_memfree( val.bv_val );
1113 keys[keycount].bv_val = NULL;
1116 return LDAP_SUCCESS;
1125 struct berval *prefix,
1126 void * assertedValue,
1134 /* Yes, this is necessary */
1135 val = UTF8bvnormalize( ((struct berval *)assertedValue),
1136 NULL, LDAP_UTF8_APPROX );
1137 if( val == NULL || val->bv_val == NULL ) {
1138 keys = (struct berval *)ch_malloc( sizeof(struct berval) );
1139 keys[0].bv_val = NULL;
1142 return LDAP_SUCCESS;
1145 /* Isolate how many words there are. There will be a key for each */
1146 for( count = 0,c = val->bv_val; *c; c++) {
1147 len = strcspn(c, SLAPD_APPROX_DELIMITER);
1148 if( len >= SLAPD_APPROX_WORDLEN ) count++;
1150 if (*c == '\0') break;
1154 /* Allocate storage for new keys */
1155 keys = (struct berval *)ch_malloc( (count + 1) * sizeof(struct berval) );
1157 /* Get a phonetic copy of each word */
1158 for( c = val->bv_val, i = 0; i < count; c += len + 1 ) {
1160 if( len < SLAPD_APPROX_WORDLEN ) continue;
1161 ber_str2bv( phonetic( c ), 0, 0, &keys[i] );
1167 keys[count].bv_val = NULL;
1170 return LDAP_SUCCESS;
1175 /* No other form of Approximate Matching is defined */
1183 struct berval *value,
1184 void *assertedValue )
1186 char *vapprox, *avapprox;
1189 /* Yes, this is necessary */
1190 s = UTF8normalize( value, UTF8_NOCASEFOLD );
1193 return LDAP_SUCCESS;
1196 /* Yes, this is necessary */
1197 t = UTF8normalize( ((struct berval *)assertedValue),
1202 return LDAP_SUCCESS;
1205 vapprox = phonetic( strip8bitChars( s ) );
1206 avapprox = phonetic( strip8bitChars( t ) );
1211 *matchp = strcmp( vapprox, avapprox );
1214 ch_free( avapprox );
1216 return LDAP_SUCCESS;
1225 struct berval *prefix,
1233 for( i=0; values[i].bv_val != NULL; i++ ) {
1234 /* empty - just count them */
1237 /* we should have at least one value at this point */
1240 keys = (struct berval *)ch_malloc( sizeof( struct berval ) * (i+1) );
1242 /* Copy each value and run it through phonetic() */
1243 for( i=0; values[i].bv_val != NULL; i++ ) {
1244 /* Yes, this is necessary */
1245 s = UTF8normalize( &values[i], UTF8_NOCASEFOLD );
1247 /* strip 8-bit chars and run through phonetic() */
1248 ber_str2bv( phonetic( strip8bitChars( s ) ), 0, 0, &keys[i] );
1251 keys[i].bv_val = NULL;
1254 return LDAP_SUCCESS;
1264 struct berval *prefix,
1265 void * assertedValue,
1271 keys = (struct berval *)ch_malloc( sizeof( struct berval * ) * 2 );
1273 /* Yes, this is necessary */
1274 s = UTF8normalize( ((struct berval *)assertedValue),
1279 /* strip 8-bit chars and run through phonetic() */
1280 keys[0] = ber_bvstr( phonetic( strip8bitChars( s ) ) );
1286 return LDAP_SUCCESS;
1297 struct berval *value,
1298 void *assertedValue )
1300 *matchp = UTF8bvnormcmp( value,
1301 (struct berval *) assertedValue,
1302 LDAP_UTF8_NOCASEFOLD );
1303 return LDAP_SUCCESS;
1307 caseExactIgnoreSubstringsMatch(
1312 struct berval *value,
1313 void *assertedValue )
1316 SubstringsAssertion *sub = NULL;
1317 struct berval left = { 0, NULL };
1323 casefold = ( mr != slap_schema.si_mr_caseExactSubstringsMatch )
1324 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1326 if ( UTF8bvnormalize( value, &left, casefold ) == NULL ) {
1332 sub = UTF8SubstringsAssertionNormalize( assertedValue, casefold );
1338 /* Add up asserted input length */
1339 if( sub->sa_initial.bv_val ) {
1340 inlen += sub->sa_initial.bv_len;
1343 for(i=0; sub->sa_any[i].bv_val != NULL; i++) {
1344 inlen += sub->sa_any[i].bv_len;
1347 if( sub->sa_final.bv_val ) {
1348 inlen += sub->sa_final.bv_len;
1351 if( sub->sa_initial.bv_val ) {
1352 if( inlen > left.bv_len ) {
1357 match = memcmp( sub->sa_initial.bv_val, left.bv_val,
1358 sub->sa_initial.bv_len );
1364 left.bv_val += sub->sa_initial.bv_len;
1365 left.bv_len -= sub->sa_initial.bv_len;
1366 inlen -= sub->sa_initial.bv_len;
1369 if( sub->sa_final.bv_val ) {
1370 if( inlen > left.bv_len ) {
1375 match = memcmp( sub->sa_final.bv_val,
1376 &left.bv_val[left.bv_len - sub->sa_final.bv_len],
1377 sub->sa_final.bv_len );
1383 left.bv_len -= sub->sa_final.bv_len;
1384 inlen -= sub->sa_final.bv_len;
1388 for(i=0; sub->sa_any[i].bv_val; i++) {
1393 if( inlen > left.bv_len ) {
1394 /* not enough length */
1399 if( sub->sa_any[i].bv_len == 0 ) {
1403 p = ber_bvchr( &left, *sub->sa_any[i].bv_val );
1409 idx = p - left.bv_val;
1411 if( idx >= left.bv_len ) {
1412 /* this shouldn't happen */
1414 if ( sub->sa_final.bv_val )
1415 ch_free( sub->sa_final.bv_val );
1417 ber_bvarray_free( sub->sa_any );
1418 if ( sub->sa_initial.bv_val )
1419 ch_free( sub->sa_initial.bv_val );
1427 if( sub->sa_any[i].bv_len > left.bv_len ) {
1428 /* not enough left */
1433 match = memcmp( left.bv_val,
1434 sub->sa_any[i].bv_val,
1435 sub->sa_any[i].bv_len );
1443 left.bv_val += sub->sa_any[i].bv_len;
1444 left.bv_len -= sub->sa_any[i].bv_len;
1445 inlen -= sub->sa_any[i].bv_len;
1452 if ( sub->sa_final.bv_val ) free( sub->sa_final.bv_val );
1453 if ( sub->sa_any ) ber_bvarray_free( sub->sa_any );
1454 if ( sub->sa_initial.bv_val ) free( sub->sa_initial.bv_val );
1458 return LDAP_SUCCESS;
1461 /* Index generation function */
1462 static int caseExactIgnoreIndexer(
1467 struct berval *prefix,
1472 unsigned casefold,wasspace;
1475 HASH_CONTEXT HASHcontext;
1476 unsigned char HASHdigest[HASH_BYTES];
1477 struct berval digest;
1478 digest.bv_val = HASHdigest;
1479 digest.bv_len = sizeof(HASHdigest);
1481 for( i=0; values[i].bv_val != NULL; i++ ) {
1482 /* empty - just count them */
1485 /* we should have at least one value at this point */
1488 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
1490 slen = syntax->ssyn_oidlen;
1491 mlen = mr->smr_oidlen;
1493 casefold = ( mr != slap_schema.si_mr_caseExactMatch )
1494 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1496 for( i=0; values[i].bv_val != NULL; i++ ) {
1497 struct berval value, nvalue;
1498 UTF8bvnormalize( &values[i], &value, casefold );
1500 /* collapse spaces (in place) */
1502 nvalue.bv_val = value.bv_val;
1505 for( j=0; j<value.bv_len; j++) {
1506 if ( ASCII_SPACE( value.bv_val[j] )) {
1507 if( wasspace++ == 0 ) {
1508 nvalue.bv_val[nvalue.bv_len++] = value.bv_val[j];
1512 nvalue.bv_val[nvalue.bv_len++] = value.bv_val[j];
1516 if( nvalue.bv_len == 0 ) {
1517 nvalue.bv_val = " ";
1518 nvalue.bv_len = sizeof(" ")-1;
1520 if( wasspace ) --nvalue.bv_len;
1521 nvalue.bv_val[nvalue.bv_len] = '\0';
1524 HASH_Init( &HASHcontext );
1525 if( prefix != NULL && prefix->bv_len > 0 ) {
1526 HASH_Update( &HASHcontext,
1527 prefix->bv_val, prefix->bv_len );
1529 HASH_Update( &HASHcontext,
1530 syntax->ssyn_oid, slen );
1531 HASH_Update( &HASHcontext,
1532 mr->smr_oid, mlen );
1533 HASH_Update( &HASHcontext,
1534 nvalue.bv_val, nvalue.bv_len );
1535 HASH_Final( HASHdigest, &HASHcontext );
1537 free( value.bv_val );
1538 ber_dupbv( &keys[i], &digest );
1541 keys[i].bv_val = NULL;
1543 return LDAP_SUCCESS;
1546 /* Index generation function */
1547 static int caseExactIgnoreFilter(
1552 struct berval *prefix,
1553 void * assertedValue,
1559 HASH_CONTEXT HASHcontext;
1560 unsigned char HASHdigest[HASH_BYTES];
1561 struct berval value = { 0, NULL };
1562 struct berval digest;
1564 digest.bv_val = HASHdigest;
1565 digest.bv_len = sizeof(HASHdigest);
1567 slen = syntax->ssyn_oidlen;
1568 mlen = mr->smr_oidlen;
1570 casefold = ( mr != slap_schema.si_mr_caseExactMatch )
1571 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1573 UTF8bvnormalize( (struct berval *) assertedValue, &value, casefold );
1574 /* This usually happens if filter contains bad UTF8 */
1575 if( value.bv_val == NULL ) {
1576 keys = ch_malloc( sizeof( struct berval ) );
1577 keys[0].bv_val = NULL;
1578 return LDAP_SUCCESS;
1581 keys = ch_malloc( sizeof( struct berval ) * 2 );
1583 HASH_Init( &HASHcontext );
1584 if( prefix != NULL && prefix->bv_len > 0 ) {
1585 HASH_Update( &HASHcontext,
1586 prefix->bv_val, prefix->bv_len );
1588 HASH_Update( &HASHcontext,
1589 syntax->ssyn_oid, slen );
1590 HASH_Update( &HASHcontext,
1591 mr->smr_oid, mlen );
1592 HASH_Update( &HASHcontext,
1593 value.bv_val, value.bv_len );
1594 HASH_Final( HASHdigest, &HASHcontext );
1596 ber_dupbv( keys, &digest );
1597 keys[1].bv_val = NULL;
1599 free( value.bv_val );
1602 return LDAP_SUCCESS;
1606 /* Substrings Index generation function */
1609 octetStringSubstringsIndexer
1611 caseExactIgnoreSubstringsIndexer
1617 struct berval *prefix,
1621 ber_len_t i, j, nkeys;
1624 #ifndef SLAP_NVALUES
1625 BerVarray tvalues, nvalues;
1626 unsigned casefold, wasspace;
1629 HASH_CONTEXT HASHcontext;
1630 unsigned char HASHdigest[HASH_BYTES];
1631 struct berval digest;
1632 digest.bv_val = HASHdigest;
1633 digest.bv_len = sizeof(HASHdigest);
1635 #ifndef SLAP_NVALUES
1636 for( i=0; values[i].bv_val != NULL; i++ ) {
1637 /* empty - just count them */
1640 /* we should have at least one value at this point */
1643 casefold = ( mr != slap_schema.si_mr_caseExactSubstringsMatch )
1644 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1646 tvalues = ch_malloc( sizeof( struct berval ) * (i+1) );
1647 nvalues = ch_malloc( sizeof( struct berval ) * (i+1) );
1649 for( i=0; values[i].bv_val != NULL; i++ ) {
1650 UTF8bvnormalize( &values[i], &tvalues[i], casefold );
1652 /* collapse spaces (in place) */
1653 nvalues[i].bv_len = 0;
1654 nvalues[i].bv_val = tvalues[i].bv_val;
1657 for( j=0; j<tvalues[i].bv_len; j++) {
1658 if ( ASCII_SPACE( tvalues[i].bv_val[j] )) {
1659 if( wasspace++ == 0 ) {
1660 nvalues[i].bv_val[nvalues[i].bv_len++] =
1661 tvalues[i].bv_val[j];
1665 nvalues[i].bv_val[nvalues[i].bv_len++] = tvalues[i].bv_val[j];
1669 if( nvalues[i].bv_len == 0 ) {
1670 nvalues[i].bv_val = " ";
1671 nvalues[i].bv_len = sizeof(" ")-1;
1673 if( wasspace ) --nvalues[i].bv_len;
1674 nvalues[i].bv_val[nvalues[i].bv_len] = '\0';
1678 tvalues[i].bv_val = NULL;
1679 nvalues[i].bv_val = NULL;
1685 for( i=0; values[i].bv_val != NULL; i++ ) {
1686 /* count number of indices to generate */
1687 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
1691 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
1692 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1693 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
1694 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
1696 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
1700 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
1701 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1702 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
1706 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
1707 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1708 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
1709 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
1711 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
1717 /* no keys to generate */
1719 #ifndef SLAP_NVALUES
1720 ber_bvarray_free( tvalues );
1723 return LDAP_SUCCESS;
1726 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
1728 slen = syntax->ssyn_oidlen;
1729 mlen = mr->smr_oidlen;
1732 for( i=0; values[i].bv_val != NULL; i++ ) {
1735 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
1737 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
1738 ( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
1740 char pre = SLAP_INDEX_SUBSTR_PREFIX;
1741 max = values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
1743 for( j=0; j<max; j++ ) {
1744 HASH_Init( &HASHcontext );
1745 if( prefix != NULL && prefix->bv_len > 0 ) {
1746 HASH_Update( &HASHcontext,
1747 prefix->bv_val, prefix->bv_len );
1750 HASH_Update( &HASHcontext,
1751 &pre, sizeof( pre ) );
1752 HASH_Update( &HASHcontext,
1753 syntax->ssyn_oid, slen );
1754 HASH_Update( &HASHcontext,
1755 mr->smr_oid, mlen );
1756 HASH_Update( &HASHcontext,
1757 &values[i].bv_val[j],
1758 SLAP_INDEX_SUBSTR_MAXLEN );
1759 HASH_Final( HASHdigest, &HASHcontext );
1761 ber_dupbv( &keys[nkeys++], &digest );
1765 max = SLAP_INDEX_SUBSTR_MAXLEN < values[i].bv_len
1766 ? SLAP_INDEX_SUBSTR_MAXLEN : values[i].bv_len;
1768 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
1771 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
1772 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
1773 HASH_Init( &HASHcontext );
1774 if( prefix != NULL && prefix->bv_len > 0 ) {
1775 HASH_Update( &HASHcontext,
1776 prefix->bv_val, prefix->bv_len );
1778 HASH_Update( &HASHcontext,
1779 &pre, sizeof( pre ) );
1780 HASH_Update( &HASHcontext,
1781 syntax->ssyn_oid, slen );
1782 HASH_Update( &HASHcontext,
1783 mr->smr_oid, mlen );
1784 HASH_Update( &HASHcontext,
1785 values[i].bv_val, j );
1786 HASH_Final( HASHdigest, &HASHcontext );
1788 ber_dupbv( &keys[nkeys++], &digest );
1791 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
1792 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
1793 HASH_Init( &HASHcontext );
1794 if( prefix != NULL && prefix->bv_len > 0 ) {
1795 HASH_Update( &HASHcontext,
1796 prefix->bv_val, prefix->bv_len );
1798 HASH_Update( &HASHcontext,
1799 &pre, sizeof( pre ) );
1800 HASH_Update( &HASHcontext,
1801 syntax->ssyn_oid, slen );
1802 HASH_Update( &HASHcontext,
1803 mr->smr_oid, mlen );
1804 HASH_Update( &HASHcontext,
1805 &values[i].bv_val[values[i].bv_len-j], j );
1806 HASH_Final( HASHdigest, &HASHcontext );
1808 ber_dupbv( &keys[nkeys++], &digest );
1816 keys[nkeys].bv_val = NULL;
1823 #ifndef SLAP_NVALUES
1824 ber_bvarray_free( tvalues );
1828 return LDAP_SUCCESS;
1833 octetStringSubstringsFilter
1835 caseExactIgnoreSubstringsFilter
1841 struct berval *prefix,
1842 void * assertedValue,
1845 SubstringsAssertion *sa;
1848 ber_len_t nkeys = 0;
1849 size_t slen, mlen, klen;
1851 HASH_CONTEXT HASHcontext;
1852 unsigned char HASHdigest[HASH_BYTES];
1853 struct berval *value;
1854 struct berval digest;
1856 #ifndef SLAP_NVALUES
1857 casefold = ( mr != slap_schema.si_mr_caseExactSubstringsMatch )
1858 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1860 sa = UTF8SubstringsAssertionNormalize( assertedValue, casefold );
1863 return LDAP_SUCCESS;
1866 sa = (SubstringsAssertion *) assertedValue;
1869 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
1870 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1875 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
1877 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
1878 if( sa->sa_any[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1879 /* don't bother accounting for stepping */
1880 nkeys += sa->sa_any[i].bv_len -
1881 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
1886 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
1887 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1893 #ifndef SLAP_NVALUES
1894 if ( sa->sa_final.bv_val ) free( sa->sa_final.bv_val );
1895 if ( sa->sa_any ) ber_bvarray_free( sa->sa_any );
1896 if ( sa->sa_initial.bv_val ) free( sa->sa_initial.bv_val );
1900 return LDAP_SUCCESS;
1903 digest.bv_val = HASHdigest;
1904 digest.bv_len = sizeof(HASHdigest);
1906 slen = syntax->ssyn_oidlen;
1907 mlen = mr->smr_oidlen;
1909 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
1912 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
1913 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1915 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
1916 value = &sa->sa_initial;
1918 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
1919 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
1921 HASH_Init( &HASHcontext );
1922 if( prefix != NULL && prefix->bv_len > 0 ) {
1923 HASH_Update( &HASHcontext,
1924 prefix->bv_val, prefix->bv_len );
1926 HASH_Update( &HASHcontext,
1927 &pre, sizeof( pre ) );
1928 HASH_Update( &HASHcontext,
1929 syntax->ssyn_oid, slen );
1930 HASH_Update( &HASHcontext,
1931 mr->smr_oid, mlen );
1932 HASH_Update( &HASHcontext,
1933 value->bv_val, klen );
1934 HASH_Final( HASHdigest, &HASHcontext );
1936 ber_dupbv( &keys[nkeys++], &digest );
1939 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
1941 pre = SLAP_INDEX_SUBSTR_PREFIX;
1942 klen = SLAP_INDEX_SUBSTR_MAXLEN;
1944 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
1945 if( sa->sa_any[i].bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
1949 value = &sa->sa_any[i];
1952 j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
1953 j += SLAP_INDEX_SUBSTR_STEP )
1955 HASH_Init( &HASHcontext );
1956 if( prefix != NULL && prefix->bv_len > 0 ) {
1957 HASH_Update( &HASHcontext,
1958 prefix->bv_val, prefix->bv_len );
1960 HASH_Update( &HASHcontext,
1961 &pre, sizeof( pre ) );
1962 HASH_Update( &HASHcontext,
1963 syntax->ssyn_oid, slen );
1964 HASH_Update( &HASHcontext,
1965 mr->smr_oid, mlen );
1966 HASH_Update( &HASHcontext,
1967 &value->bv_val[j], klen );
1968 HASH_Final( HASHdigest, &HASHcontext );
1970 ber_dupbv( &keys[nkeys++], &digest );
1976 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
1977 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1979 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
1980 value = &sa->sa_final;
1982 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
1983 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
1985 HASH_Init( &HASHcontext );
1986 if( prefix != NULL && prefix->bv_len > 0 ) {
1987 HASH_Update( &HASHcontext,
1988 prefix->bv_val, prefix->bv_len );
1990 HASH_Update( &HASHcontext,
1991 &pre, sizeof( pre ) );
1992 HASH_Update( &HASHcontext,
1993 syntax->ssyn_oid, slen );
1994 HASH_Update( &HASHcontext,
1995 mr->smr_oid, mlen );
1996 HASH_Update( &HASHcontext,
1997 &value->bv_val[value->bv_len-klen], klen );
1998 HASH_Final( HASHdigest, &HASHcontext );
2000 ber_dupbv( &keys[nkeys++], &digest );
2004 keys[nkeys].bv_val = NULL;
2011 #ifndef SLAP_NVALUES
2012 if ( sa->sa_final.bv_val ) free( sa->sa_final.bv_val );
2013 if ( sa->sa_any ) ber_bvarray_free( sa->sa_any );
2014 if ( sa->sa_initial.bv_val ) free( sa->sa_initial.bv_val );
2018 return LDAP_SUCCESS;
2021 #ifndef SLAP_NVALUES
2029 struct berval *value,
2030 void *assertedValue )
2032 *matchp = UTF8bvnormcmp( value,
2033 (struct berval *) assertedValue,
2034 LDAP_UTF8_CASEFOLD );
2035 return LDAP_SUCCESS;
2038 /* Remove all spaces and '-' characters */
2040 xtelephoneNumberNormalize(
2043 struct berval *normalized )
2047 /* validator should have refused an empty string */
2048 assert( val->bv_len );
2050 q = normalized->bv_val = ch_malloc( val->bv_len + 1 );
2052 for( p = val->bv_val; *p; p++ ) {
2053 if ( ! ( ASCII_SPACE( *p ) || *p == '-' )) {
2059 normalized->bv_len = q - normalized->bv_val;
2061 if( normalized->bv_len == 0 ) {
2062 free( normalized->bv_val );
2063 return LDAP_INVALID_SYNTAX;
2066 return LDAP_SUCCESS;
2073 struct berval *val )
2077 if( val->bv_len == 0 ) {
2078 /* disallow empty strings */
2079 return LDAP_INVALID_SYNTAX;
2082 if( OID_LEADCHAR(val->bv_val[0]) ) {
2084 for(i=1; i < val->bv_len; i++) {
2085 if( OID_SEPARATOR( val->bv_val[i] ) ) {
2086 if( dot++ ) return 1;
2087 } else if ( OID_CHAR( val->bv_val[i] ) ) {
2090 return LDAP_INVALID_SYNTAX;
2094 return !dot ? LDAP_SUCCESS : LDAP_INVALID_SYNTAX;
2096 } else if( DESC_LEADCHAR(val->bv_val[0]) ) {
2097 for(i=1; i < val->bv_len; i++) {
2098 if( !DESC_CHAR(val->bv_val[i] ) ) {
2099 return LDAP_INVALID_SYNTAX;
2103 return LDAP_SUCCESS;
2106 return LDAP_INVALID_SYNTAX;
2109 #ifndef SLAP_NVALUES
2117 struct berval *value,
2118 void *assertedValue )
2121 int vsign = 1, avsign = 1; /* default sign = '+' */
2122 struct berval *asserted;
2123 ber_len_t vlen, avlen;
2126 /* Skip leading space/sign/zeroes, and get the sign of the *value number */
2128 vlen = value->bv_len;
2129 if( mr == slap_schema.si_mr_integerFirstComponentMatch ) {
2130 char *tmp = memchr( v, '$', vlen );
2133 while( vlen && ASCII_SPACE( v[vlen-1] ))
2136 for( ; vlen && ( *v < '1' || '9' < *v ); v++, vlen-- ) /* ANSI 2.2.1 */
2142 /* Do the same with the *assertedValue number */
2143 asserted = (struct berval *) assertedValue;
2144 av = asserted->bv_val;
2145 avlen = asserted->bv_len;
2146 for( ; avlen && ( *av < '1' || '9' < *av ); av++, avlen-- )
2152 match = vsign - avsign;
2154 match = (vlen != avlen
2155 ? ( vlen < avlen ? -1 : 1 )
2156 : memcmp( v, av, vlen ));
2162 return LDAP_SUCCESS;
2169 struct berval *val )
2173 if( !val->bv_len ) return LDAP_INVALID_SYNTAX;
2175 if(( val->bv_val[0] == '+' ) || ( val->bv_val[0] == '-' )) {
2176 if( val->bv_len < 2 ) return LDAP_INVALID_SYNTAX;
2177 } else if( !ASCII_DIGIT(val->bv_val[0]) ) {
2178 return LDAP_INVALID_SYNTAX;
2181 for( i=1; i < val->bv_len; i++ ) {
2182 if( !ASCII_DIGIT(val->bv_val[i]) ) return LDAP_INVALID_SYNTAX;
2185 return LDAP_SUCCESS;
2188 #ifndef SLAP_NVALUES
2193 struct berval *normalized )
2203 /* Ignore leading spaces */
2204 while ( len && ( *p == ' ' )) {
2211 negative = ( *p == '-' );
2212 if(( *p == '-' ) || ( *p == '+' )) {
2218 /* Ignore leading zeros */
2219 while ( len && ( *p == '0' )) {
2224 /* If there are no non-zero digits left, the number is zero, otherwise
2225 allocate space for the number and copy it into the buffer */
2227 normalized->bv_val = ch_strdup("0");
2228 normalized->bv_len = 1;
2231 normalized->bv_len = len+negative;
2232 normalized->bv_val = ch_malloc( normalized->bv_len + 1 );
2234 normalized->bv_val[0] = '-';
2236 AC_MEMCPY( normalized->bv_val + negative, p, len );
2237 normalized->bv_val[len+negative] = '\0';
2240 return LDAP_SUCCESS;
2243 /* Index generation function */
2244 static int integerIndexer(
2249 struct berval *prefix,
2256 HASH_CONTEXT HASHcontext;
2257 unsigned char HASHdigest[HASH_BYTES];
2258 struct berval digest;
2259 digest.bv_val = HASHdigest;
2260 digest.bv_len = sizeof(HASHdigest);
2262 for( i=0; values[i].bv_val != NULL; i++ ) {
2263 /* empty - just count them */
2266 /* we should have at least one value at this point */
2269 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
2271 slen = syntax->ssyn_oidlen;
2272 mlen = mr->smr_oidlen;
2274 for( i=0; values[i].bv_val != NULL; i++ ) {
2276 xintegerNormalize( syntax, &values[i], &norm );
2278 HASH_Init( &HASHcontext );
2279 if( prefix != NULL && prefix->bv_len > 0 ) {
2280 HASH_Update( &HASHcontext,
2281 prefix->bv_val, prefix->bv_len );
2283 HASH_Update( &HASHcontext,
2284 syntax->ssyn_oid, slen );
2285 HASH_Update( &HASHcontext,
2286 mr->smr_oid, mlen );
2287 HASH_Update( &HASHcontext,
2288 norm.bv_val, norm.bv_len );
2289 HASH_Final( HASHdigest, &HASHcontext );
2291 ber_dupbv( &keys[i], &digest );
2292 ch_free( norm.bv_val );
2295 keys[i].bv_val = NULL;
2297 return LDAP_SUCCESS;
2300 /* Index generation function */
2301 static int integerFilter(
2306 struct berval *prefix,
2307 void * assertedValue,
2312 HASH_CONTEXT HASHcontext;
2313 unsigned char HASHdigest[HASH_BYTES];
2315 struct berval digest;
2316 digest.bv_val = HASHdigest;
2317 digest.bv_len = sizeof(HASHdigest);
2319 slen = syntax->ssyn_oidlen;
2320 mlen = mr->smr_oidlen;
2322 xintegerNormalize( syntax, assertedValue, &norm );
2324 keys = ch_malloc( sizeof( struct berval ) * 2 );
2326 HASH_Init( &HASHcontext );
2327 if( prefix != NULL && prefix->bv_len > 0 ) {
2328 HASH_Update( &HASHcontext,
2329 prefix->bv_val, prefix->bv_len );
2331 HASH_Update( &HASHcontext,
2332 syntax->ssyn_oid, slen );
2333 HASH_Update( &HASHcontext,
2334 mr->smr_oid, mlen );
2335 HASH_Update( &HASHcontext,
2336 norm.bv_val, norm.bv_len );
2337 HASH_Final( HASHdigest, &HASHcontext );
2339 ber_dupbv( &keys[0], &digest );
2340 keys[1].bv_val = NULL;
2341 ch_free( norm.bv_val );
2344 return LDAP_SUCCESS;
2350 countryStringValidate(
2352 struct berval *val )
2354 if( val->bv_len != 2 ) return LDAP_INVALID_SYNTAX;
2356 if( !SLAP_PRINTABLE(val->bv_val[0]) ) {
2357 return LDAP_INVALID_SYNTAX;
2359 if( !SLAP_PRINTABLE(val->bv_val[1]) ) {
2360 return LDAP_INVALID_SYNTAX;
2363 return LDAP_SUCCESS;
2367 printableStringValidate(
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( !SLAP_PRINTABLE(val->bv_val[i]) ) {
2377 return LDAP_INVALID_SYNTAX;
2381 return LDAP_SUCCESS;
2385 printablesStringValidate(
2387 struct berval *val )
2391 if( val->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
2393 for(i=0,len=0; i < val->bv_len; i++) {
2394 int c = val->bv_val[i];
2398 return LDAP_INVALID_SYNTAX;
2402 } else if ( SLAP_PRINTABLE(c) ) {
2405 return LDAP_INVALID_SYNTAX;
2410 return LDAP_INVALID_SYNTAX;
2413 return LDAP_SUCCESS;
2419 struct berval *val )
2423 if( val->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
2425 for(i=0; i < val->bv_len; i++) {
2426 if( !LDAP_ASCII(val->bv_val[i]) ) {
2427 return LDAP_INVALID_SYNTAX;
2431 return LDAP_SUCCESS;
2441 struct berval *normalized )
2444 xIA5StringNormalize(
2447 struct berval *normalized )
2452 int casefold = !SLAP_MR_ASSOCIATED(mr, slap_schema.si_mr_caseExactIA5Match);
2455 assert( val->bv_len );
2459 /* Ignore initial whitespace */
2460 while ( ASCII_SPACE( *p ) ) {
2464 normalized->bv_val = ch_strdup( p );
2465 p = q = normalized->bv_val;
2468 if ( ASCII_SPACE( *p ) ) {
2471 /* Ignore the extra whitespace */
2472 while ( ASCII_SPACE( *p ) ) {
2477 } else if ( casefold ) {
2478 /* Most IA5 rules require casefolding */
2479 *q++ = TOLOWER(*p++);
2487 assert( normalized->bv_val <= p );
2491 * If the string ended in space, backup the pointer one
2492 * position. One is enough because the above loop collapsed
2493 * all whitespace to a single space.
2496 if ( ASCII_SPACE( q[-1] ) ) {
2500 /* null terminate */
2503 normalized->bv_len = q - normalized->bv_val;
2505 if( normalized->bv_len == 0 ) {
2506 normalized->bv_val = ch_realloc( normalized->bv_val, 2 );
2507 normalized->bv_val[0] = ' ';
2508 normalized->bv_val[1] = '\0';
2509 normalized->bv_len = 1;
2512 return LDAP_SUCCESS;
2515 #ifndef SLAP_NVALUES
2523 struct berval *value,
2524 void *assertedValue )
2526 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
2529 match = strncmp( value->bv_val,
2530 ((struct berval *) assertedValue)->bv_val,
2535 return LDAP_SUCCESS;
2539 caseExactIA5SubstringsMatch
2542 octetStringSubstringsMatch
2549 struct berval *value,
2550 void *assertedValue )
2553 SubstringsAssertion *sub = assertedValue;
2554 struct berval left = *value;
2558 /* Add up asserted input length */
2559 if( sub->sa_initial.bv_val ) {
2560 inlen += sub->sa_initial.bv_len;
2563 for(i=0; sub->sa_any[i].bv_val != NULL; i++) {
2564 inlen += sub->sa_any[i].bv_len;
2567 if( sub->sa_final.bv_val ) {
2568 inlen += sub->sa_final.bv_len;
2571 if( sub->sa_initial.bv_val ) {
2572 if( inlen > left.bv_len ) {
2577 match = memcmp( sub->sa_initial.bv_val, left.bv_val,
2578 sub->sa_initial.bv_len );
2584 left.bv_val += sub->sa_initial.bv_len;
2585 left.bv_len -= sub->sa_initial.bv_len;
2586 inlen -= sub->sa_initial.bv_len;
2589 if( sub->sa_final.bv_val ) {
2590 if( inlen > left.bv_len ) {
2595 match = memcmp( sub->sa_final.bv_val,
2596 &left.bv_val[left.bv_len - sub->sa_final.bv_len],
2597 sub->sa_final.bv_len );
2603 left.bv_len -= sub->sa_final.bv_len;
2604 inlen -= sub->sa_final.bv_len;
2608 for(i=0; sub->sa_any[i].bv_val; i++) {
2613 if( inlen > left.bv_len ) {
2614 /* not enough length */
2619 if( sub->sa_any[i].bv_len == 0 ) {
2623 p = memchr( left.bv_val, *sub->sa_any[i].bv_val, left.bv_len );
2630 idx = p - left.bv_val;
2632 if( idx >= left.bv_len ) {
2633 /* this shouldn't happen */
2640 if( sub->sa_any[i].bv_len > left.bv_len ) {
2641 /* not enough left */
2646 match = memcmp( left.bv_val,
2647 sub->sa_any[i].bv_val,
2648 sub->sa_any[i].bv_len );
2656 left.bv_val += sub->sa_any[i].bv_len;
2657 left.bv_len -= sub->sa_any[i].bv_len;
2658 inlen -= sub->sa_any[i].bv_len;
2664 return LDAP_SUCCESS;
2667 #ifndef SLAP_NVALUES
2669 /* Index generation function */
2670 static int caseExactIA5Indexer(
2675 struct berval *prefix,
2682 HASH_CONTEXT HASHcontext;
2683 unsigned char HASHdigest[HASH_BYTES];
2684 struct berval digest;
2685 digest.bv_val = HASHdigest;
2686 digest.bv_len = sizeof(HASHdigest);
2688 for( i=0; values[i].bv_val != NULL; i++ ) {
2689 /* empty - just count them */
2692 /* we should have at least one value at this point */
2695 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
2697 slen = syntax->ssyn_oidlen;
2698 mlen = mr->smr_oidlen;
2700 for( i=0; values[i].bv_val != NULL; i++ ) {
2701 struct berval *value = &values[i];
2703 HASH_Init( &HASHcontext );
2704 if( prefix != NULL && prefix->bv_len > 0 ) {
2705 HASH_Update( &HASHcontext,
2706 prefix->bv_val, prefix->bv_len );
2708 HASH_Update( &HASHcontext,
2709 syntax->ssyn_oid, slen );
2710 HASH_Update( &HASHcontext,
2711 mr->smr_oid, mlen );
2712 HASH_Update( &HASHcontext,
2713 value->bv_val, value->bv_len );
2714 HASH_Final( HASHdigest, &HASHcontext );
2716 ber_dupbv( &keys[i], &digest );
2719 keys[i].bv_val = NULL;
2721 return LDAP_SUCCESS;
2724 /* Index generation function */
2725 static int caseExactIA5Filter(
2730 struct berval *prefix,
2731 void * assertedValue,
2736 HASH_CONTEXT HASHcontext;
2737 unsigned char HASHdigest[HASH_BYTES];
2738 struct berval *value;
2739 struct berval digest;
2740 digest.bv_val = HASHdigest;
2741 digest.bv_len = sizeof(HASHdigest);
2743 slen = syntax->ssyn_oidlen;
2744 mlen = mr->smr_oidlen;
2746 value = (struct berval *) assertedValue;
2748 keys = ch_malloc( sizeof( struct berval ) * 2 );
2750 HASH_Init( &HASHcontext );
2751 if( prefix != NULL && prefix->bv_len > 0 ) {
2752 HASH_Update( &HASHcontext,
2753 prefix->bv_val, prefix->bv_len );
2755 HASH_Update( &HASHcontext,
2756 syntax->ssyn_oid, slen );
2757 HASH_Update( &HASHcontext,
2758 mr->smr_oid, mlen );
2759 HASH_Update( &HASHcontext,
2760 value->bv_val, value->bv_len );
2761 HASH_Final( HASHdigest, &HASHcontext );
2763 ber_dupbv( &keys[0], &digest );
2764 keys[1].bv_val = NULL;
2767 return LDAP_SUCCESS;
2770 /* Substrings Index generation function */
2771 static int caseExactIA5SubstringsIndexer(
2776 struct berval *prefix,
2783 HASH_CONTEXT HASHcontext;
2784 unsigned char HASHdigest[HASH_BYTES];
2785 struct berval digest;
2786 digest.bv_val = HASHdigest;
2787 digest.bv_len = sizeof(HASHdigest);
2789 /* we should have at least one value at this point */
2790 assert( values != NULL && values[0].bv_val != NULL );
2793 for( i=0; values[i].bv_val != NULL; i++ ) {
2794 /* count number of indices to generate */
2795 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
2799 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
2800 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2801 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2802 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2804 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2808 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
2809 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2810 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
2814 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
2815 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2816 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2817 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2819 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2825 /* no keys to generate */
2827 return LDAP_SUCCESS;
2830 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
2832 slen = syntax->ssyn_oidlen;
2833 mlen = mr->smr_oidlen;
2836 for( i=0; values[i].bv_val != NULL; i++ ) {
2838 struct berval *value;
2841 if( value->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
2843 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
2844 ( value->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
2846 char pre = SLAP_INDEX_SUBSTR_PREFIX;
2847 max = value->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
2849 for( j=0; j<max; j++ ) {
2850 HASH_Init( &HASHcontext );
2851 if( prefix != NULL && prefix->bv_len > 0 ) {
2852 HASH_Update( &HASHcontext,
2853 prefix->bv_val, prefix->bv_len );
2856 HASH_Update( &HASHcontext,
2857 &pre, sizeof( pre ) );
2858 HASH_Update( &HASHcontext,
2859 syntax->ssyn_oid, slen );
2860 HASH_Update( &HASHcontext,
2861 mr->smr_oid, mlen );
2862 HASH_Update( &HASHcontext,
2864 SLAP_INDEX_SUBSTR_MAXLEN );
2865 HASH_Final( HASHdigest, &HASHcontext );
2867 ber_dupbv( &keys[nkeys++], &digest );
2871 max = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2872 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2874 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
2877 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
2878 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
2879 HASH_Init( &HASHcontext );
2880 if( prefix != NULL && prefix->bv_len > 0 ) {
2881 HASH_Update( &HASHcontext,
2882 prefix->bv_val, prefix->bv_len );
2884 HASH_Update( &HASHcontext,
2885 &pre, sizeof( pre ) );
2886 HASH_Update( &HASHcontext,
2887 syntax->ssyn_oid, slen );
2888 HASH_Update( &HASHcontext,
2889 mr->smr_oid, mlen );
2890 HASH_Update( &HASHcontext,
2892 HASH_Final( HASHdigest, &HASHcontext );
2894 ber_dupbv( &keys[nkeys++], &digest );
2897 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
2898 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
2899 HASH_Init( &HASHcontext );
2900 if( prefix != NULL && prefix->bv_len > 0 ) {
2901 HASH_Update( &HASHcontext,
2902 prefix->bv_val, prefix->bv_len );
2904 HASH_Update( &HASHcontext,
2905 &pre, sizeof( pre ) );
2906 HASH_Update( &HASHcontext,
2907 syntax->ssyn_oid, slen );
2908 HASH_Update( &HASHcontext,
2909 mr->smr_oid, mlen );
2910 HASH_Update( &HASHcontext,
2911 &value->bv_val[value->bv_len-j], j );
2912 HASH_Final( HASHdigest, &HASHcontext );
2914 ber_dupbv( &keys[nkeys++], &digest );
2921 keys[nkeys].bv_val = NULL;
2928 return LDAP_SUCCESS;
2931 static int caseExactIA5SubstringsFilter(
2936 struct berval *prefix,
2937 void * assertedValue,
2940 SubstringsAssertion *sa = assertedValue;
2942 ber_len_t nkeys = 0;
2943 size_t slen, mlen, klen;
2945 HASH_CONTEXT HASHcontext;
2946 unsigned char HASHdigest[HASH_BYTES];
2947 struct berval *value;
2948 struct berval digest;
2950 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
2951 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2956 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
2958 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
2959 if( sa->sa_any[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2960 /* don't bother accounting for stepping */
2961 nkeys += sa->sa_any[i].bv_len -
2962 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
2967 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
2968 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2975 return LDAP_SUCCESS;
2978 digest.bv_val = HASHdigest;
2979 digest.bv_len = sizeof(HASHdigest);
2981 slen = syntax->ssyn_oidlen;
2982 mlen = mr->smr_oidlen;
2984 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
2987 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
2988 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2990 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
2991 value = &sa->sa_initial;
2993 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2994 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2996 HASH_Init( &HASHcontext );
2997 if( prefix != NULL && prefix->bv_len > 0 ) {
2998 HASH_Update( &HASHcontext,
2999 prefix->bv_val, prefix->bv_len );
3001 HASH_Update( &HASHcontext,
3002 &pre, sizeof( pre ) );
3003 HASH_Update( &HASHcontext,
3004 syntax->ssyn_oid, slen );
3005 HASH_Update( &HASHcontext,
3006 mr->smr_oid, mlen );
3007 HASH_Update( &HASHcontext,
3008 value->bv_val, klen );
3009 HASH_Final( HASHdigest, &HASHcontext );
3011 ber_dupbv( &keys[nkeys++], &digest );
3014 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
3016 pre = SLAP_INDEX_SUBSTR_PREFIX;
3017 klen = SLAP_INDEX_SUBSTR_MAXLEN;
3019 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
3020 if( sa->sa_any[i].bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
3024 value = &sa->sa_any[i];
3027 j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
3028 j += SLAP_INDEX_SUBSTR_STEP )
3030 HASH_Init( &HASHcontext );
3031 if( prefix != NULL && prefix->bv_len > 0 ) {
3032 HASH_Update( &HASHcontext,
3033 prefix->bv_val, prefix->bv_len );
3035 HASH_Update( &HASHcontext,
3036 &pre, sizeof( pre ) );
3037 HASH_Update( &HASHcontext,
3038 syntax->ssyn_oid, slen );
3039 HASH_Update( &HASHcontext,
3040 mr->smr_oid, mlen );
3041 HASH_Update( &HASHcontext,
3042 &value->bv_val[j], klen );
3043 HASH_Final( HASHdigest, &HASHcontext );
3045 ber_dupbv( &keys[nkeys++], &digest );
3050 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
3051 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3053 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
3054 value = &sa->sa_final;
3056 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
3057 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
3059 HASH_Init( &HASHcontext );
3060 if( prefix != NULL && prefix->bv_len > 0 ) {
3061 HASH_Update( &HASHcontext,
3062 prefix->bv_val, prefix->bv_len );
3064 HASH_Update( &HASHcontext,
3065 &pre, sizeof( pre ) );
3066 HASH_Update( &HASHcontext,
3067 syntax->ssyn_oid, slen );
3068 HASH_Update( &HASHcontext,
3069 mr->smr_oid, mlen );
3070 HASH_Update( &HASHcontext,
3071 &value->bv_val[value->bv_len-klen], klen );
3072 HASH_Final( HASHdigest, &HASHcontext );
3074 ber_dupbv( &keys[nkeys++], &digest );
3078 keys[nkeys].bv_val = NULL;
3085 return LDAP_SUCCESS;
3094 struct berval *value,
3095 void *assertedValue )
3097 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
3099 if( match == 0 && value->bv_len ) {
3100 match = strncasecmp( value->bv_val,
3101 ((struct berval *) assertedValue)->bv_val,
3106 return LDAP_SUCCESS;
3110 caseIgnoreIA5SubstringsMatch(
3115 struct berval *value,
3116 void *assertedValue )
3119 SubstringsAssertion *sub = assertedValue;
3120 struct berval left = *value;
3124 /* Add up asserted input length */
3125 if( sub->sa_initial.bv_val ) {
3126 inlen += sub->sa_initial.bv_len;
3129 for(i=0; sub->sa_any[i].bv_val != NULL; i++) {
3130 inlen += sub->sa_any[i].bv_len;
3133 if( sub->sa_final.bv_val ) {
3134 inlen += sub->sa_final.bv_len;
3137 if( sub->sa_initial.bv_val ) {
3138 if( inlen > left.bv_len ) {
3143 match = strncasecmp( sub->sa_initial.bv_val, left.bv_val,
3144 sub->sa_initial.bv_len );
3150 left.bv_val += sub->sa_initial.bv_len;
3151 left.bv_len -= sub->sa_initial.bv_len;
3152 inlen -= sub->sa_initial.bv_len;
3155 if( sub->sa_final.bv_val ) {
3156 if( inlen > left.bv_len ) {
3161 match = strncasecmp( sub->sa_final.bv_val,
3162 &left.bv_val[left.bv_len - sub->sa_final.bv_len],
3163 sub->sa_final.bv_len );
3169 left.bv_len -= sub->sa_final.bv_len;
3170 inlen -= sub->sa_final.bv_len;
3174 for(i=0; sub->sa_any[i].bv_val; i++) {
3179 if( inlen > left.bv_len ) {
3180 /* not enough length */
3185 if( sub->sa_any[i].bv_len == 0 ) {
3189 p = bvcasechr( &left, *sub->sa_any[i].bv_val, &idx );
3196 assert( idx < left.bv_len );
3197 if( idx >= left.bv_len ) {
3198 /* this shouldn't happen */
3205 if( sub->sa_any[i].bv_len > left.bv_len ) {
3206 /* not enough left */
3211 match = strncasecmp( left.bv_val,
3212 sub->sa_any[i].bv_val,
3213 sub->sa_any[i].bv_len );
3222 left.bv_val += sub->sa_any[i].bv_len;
3223 left.bv_len -= sub->sa_any[i].bv_len;
3224 inlen -= sub->sa_any[i].bv_len;
3230 return LDAP_SUCCESS;
3233 /* Index generation function */
3234 static int caseIgnoreIA5Indexer(
3239 struct berval *prefix,
3244 int rc = LDAP_SUCCESS;
3247 HASH_CONTEXT HASHcontext;
3248 unsigned char HASHdigest[HASH_BYTES];
3249 struct berval digest;
3250 digest.bv_val = HASHdigest;
3251 digest.bv_len = sizeof(HASHdigest);
3253 /* we should have at least one value at this point */
3254 assert( values != NULL && values[0].bv_val != NULL );
3256 for( i=0; values[i].bv_val != NULL; i++ ) {
3257 /* just count them */
3260 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
3262 slen = syntax->ssyn_oidlen;
3263 mlen = mr->smr_oidlen;
3265 for( i=0; values[i].bv_val != NULL; i++ ) {
3266 struct berval value;
3268 if( mr->smr_normalize ) {
3269 rc = (mr->smr_normalize)( use, syntax, mr, &values[i], &value );
3270 if( rc != LDAP_SUCCESS ) {
3273 #ifndef SLAP_NVALUES
3274 } else if ( mr->smr_syntax->ssyn_normalize ) {
3275 rc = (mr->smr_syntax->ssyn_normalize)( syntax, &values[i], &value );
3276 if( rc != LDAP_SUCCESS ) {
3281 ber_dupbv( &value, &values[i] );
3284 ldap_pvt_str2lower( value.bv_val );
3286 HASH_Init( &HASHcontext );
3287 if( prefix != NULL && prefix->bv_len > 0 ) {
3288 HASH_Update( &HASHcontext,
3289 prefix->bv_val, prefix->bv_len );
3291 HASH_Update( &HASHcontext,
3292 syntax->ssyn_oid, slen );
3293 HASH_Update( &HASHcontext,
3294 mr->smr_oid, mlen );
3295 HASH_Update( &HASHcontext,
3296 value.bv_val, value.bv_len );
3297 HASH_Final( HASHdigest, &HASHcontext );
3299 free( value.bv_val );
3301 ber_dupbv( &keys[i], &digest );
3304 keys[i].bv_val = NULL;
3305 if( rc != LDAP_SUCCESS ) {
3306 ber_bvarray_free( keys );
3313 /* Index generation function */
3314 static int caseIgnoreIA5Filter(
3319 struct berval *prefix,
3320 void * assertedValue,
3325 HASH_CONTEXT HASHcontext;
3326 unsigned char HASHdigest[HASH_BYTES];
3327 struct berval value;
3328 struct berval digest;
3329 digest.bv_val = HASHdigest;
3330 digest.bv_len = sizeof(HASHdigest);
3332 slen = syntax->ssyn_oidlen;
3333 mlen = mr->smr_oidlen;
3335 ber_dupbv( &value, (struct berval *) assertedValue );
3336 ldap_pvt_str2lower( value.bv_val );
3338 keys = ch_malloc( sizeof( struct berval ) * 2 );
3340 HASH_Init( &HASHcontext );
3341 if( prefix != NULL && prefix->bv_len > 0 ) {
3342 HASH_Update( &HASHcontext,
3343 prefix->bv_val, prefix->bv_len );
3345 HASH_Update( &HASHcontext,
3346 syntax->ssyn_oid, slen );
3347 HASH_Update( &HASHcontext,
3348 mr->smr_oid, mlen );
3349 HASH_Update( &HASHcontext,
3350 value.bv_val, value.bv_len );
3351 HASH_Final( HASHdigest, &HASHcontext );
3353 ber_dupbv( &keys[0], &digest );
3354 keys[1].bv_val = NULL;
3356 free( value.bv_val );
3360 return LDAP_SUCCESS;
3363 /* Substrings Index generation function */
3364 static int caseIgnoreIA5SubstringsIndexer(
3369 struct berval *prefix,
3376 HASH_CONTEXT HASHcontext;
3377 unsigned char HASHdigest[HASH_BYTES];
3378 struct berval digest;
3379 digest.bv_val = HASHdigest;
3380 digest.bv_len = sizeof(HASHdigest);
3382 /* we should have at least one value at this point */
3383 assert( values != NULL && values[0].bv_val != NULL );
3386 for( i=0; values[i].bv_val != NULL; i++ ) {
3387 /* count number of indices to generate */
3388 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
3392 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
3393 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3394 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
3395 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
3397 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
3401 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
3402 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3403 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
3407 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
3408 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3409 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
3410 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
3412 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
3418 /* no keys to generate */
3420 return LDAP_SUCCESS;
3423 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
3425 slen = syntax->ssyn_oidlen;
3426 mlen = mr->smr_oidlen;
3429 for( i=0; values[i].bv_val != NULL; i++ ) {
3431 struct berval value;
3433 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
3435 ber_dupbv( &value, &values[i] );
3436 ldap_pvt_str2lower( value.bv_val );
3438 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
3439 ( value.bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
3441 char pre = SLAP_INDEX_SUBSTR_PREFIX;
3442 max = value.bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
3444 for( j=0; j<max; j++ ) {
3445 HASH_Init( &HASHcontext );
3446 if( prefix != NULL && prefix->bv_len > 0 ) {
3447 HASH_Update( &HASHcontext,
3448 prefix->bv_val, prefix->bv_len );
3451 HASH_Update( &HASHcontext,
3452 &pre, sizeof( pre ) );
3453 HASH_Update( &HASHcontext,
3454 syntax->ssyn_oid, slen );
3455 HASH_Update( &HASHcontext,
3456 mr->smr_oid, mlen );
3457 HASH_Update( &HASHcontext,
3459 SLAP_INDEX_SUBSTR_MAXLEN );
3460 HASH_Final( HASHdigest, &HASHcontext );
3462 ber_dupbv( &keys[nkeys++], &digest );
3466 max = SLAP_INDEX_SUBSTR_MAXLEN < value.bv_len
3467 ? SLAP_INDEX_SUBSTR_MAXLEN : value.bv_len;
3469 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
3472 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
3473 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
3474 HASH_Init( &HASHcontext );
3475 if( prefix != NULL && prefix->bv_len > 0 ) {
3476 HASH_Update( &HASHcontext,
3477 prefix->bv_val, prefix->bv_len );
3479 HASH_Update( &HASHcontext,
3480 &pre, sizeof( pre ) );
3481 HASH_Update( &HASHcontext,
3482 syntax->ssyn_oid, slen );
3483 HASH_Update( &HASHcontext,
3484 mr->smr_oid, mlen );
3485 HASH_Update( &HASHcontext,
3487 HASH_Final( HASHdigest, &HASHcontext );
3489 ber_dupbv( &keys[nkeys++], &digest );
3492 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
3493 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
3494 HASH_Init( &HASHcontext );
3495 if( prefix != NULL && prefix->bv_len > 0 ) {
3496 HASH_Update( &HASHcontext,
3497 prefix->bv_val, prefix->bv_len );
3499 HASH_Update( &HASHcontext,
3500 &pre, sizeof( pre ) );
3501 HASH_Update( &HASHcontext,
3502 syntax->ssyn_oid, slen );
3503 HASH_Update( &HASHcontext,
3504 mr->smr_oid, mlen );
3505 HASH_Update( &HASHcontext,
3506 &value.bv_val[value.bv_len-j], j );
3507 HASH_Final( HASHdigest, &HASHcontext );
3509 ber_dupbv( &keys[nkeys++], &digest );
3514 free( value.bv_val );
3518 keys[nkeys].bv_val = NULL;
3525 return LDAP_SUCCESS;
3528 static int caseIgnoreIA5SubstringsFilter(
3533 struct berval *prefix,
3534 void * assertedValue,
3537 SubstringsAssertion *sa = assertedValue;
3539 ber_len_t nkeys = 0;
3540 size_t slen, mlen, klen;
3542 HASH_CONTEXT HASHcontext;
3543 unsigned char HASHdigest[HASH_BYTES];
3544 struct berval value;
3545 struct berval digest;
3547 if((flags & SLAP_INDEX_SUBSTR_INITIAL) && sa->sa_initial.bv_val != NULL &&
3548 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3553 if((flags & SLAP_INDEX_SUBSTR_ANY) && sa->sa_any != NULL ) {
3555 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
3556 if( sa->sa_any[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3557 /* don't bother accounting for stepping */
3558 nkeys += sa->sa_any[i].bv_len -
3559 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
3564 if((flags & SLAP_INDEX_SUBSTR_FINAL) && sa->sa_final.bv_val != NULL &&
3565 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3572 return LDAP_SUCCESS;
3575 digest.bv_val = HASHdigest;
3576 digest.bv_len = sizeof(HASHdigest);
3578 slen = syntax->ssyn_oidlen;
3579 mlen = mr->smr_oidlen;
3581 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
3584 if((flags & SLAP_INDEX_SUBSTR_INITIAL) && sa->sa_initial.bv_val != NULL &&
3585 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3587 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
3588 ber_dupbv( &value, &sa->sa_initial );
3589 ldap_pvt_str2lower( value.bv_val );
3591 klen = SLAP_INDEX_SUBSTR_MAXLEN < value.bv_len
3592 ? SLAP_INDEX_SUBSTR_MAXLEN : value.bv_len;
3594 HASH_Init( &HASHcontext );
3595 if( prefix != NULL && prefix->bv_len > 0 ) {
3596 HASH_Update( &HASHcontext,
3597 prefix->bv_val, prefix->bv_len );
3599 HASH_Update( &HASHcontext,
3600 &pre, sizeof( pre ) );
3601 HASH_Update( &HASHcontext,
3602 syntax->ssyn_oid, slen );
3603 HASH_Update( &HASHcontext,
3604 mr->smr_oid, mlen );
3605 HASH_Update( &HASHcontext,
3606 value.bv_val, klen );
3607 HASH_Final( HASHdigest, &HASHcontext );
3609 free( value.bv_val );
3610 ber_dupbv( &keys[nkeys++], &digest );
3613 if((flags & SLAP_INDEX_SUBSTR_ANY) && sa->sa_any != NULL ) {
3615 pre = SLAP_INDEX_SUBSTR_PREFIX;
3616 klen = SLAP_INDEX_SUBSTR_MAXLEN;
3618 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
3619 if( sa->sa_any[i].bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
3623 ber_dupbv( &value, &sa->sa_any[i] );
3624 ldap_pvt_str2lower( value.bv_val );
3627 j <= value.bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
3628 j += SLAP_INDEX_SUBSTR_STEP )
3630 HASH_Init( &HASHcontext );
3631 if( prefix != NULL && prefix->bv_len > 0 ) {
3632 HASH_Update( &HASHcontext,
3633 prefix->bv_val, prefix->bv_len );
3635 HASH_Update( &HASHcontext,
3636 &pre, sizeof( pre ) );
3637 HASH_Update( &HASHcontext,
3638 syntax->ssyn_oid, slen );
3639 HASH_Update( &HASHcontext,
3640 mr->smr_oid, mlen );
3641 HASH_Update( &HASHcontext,
3642 &value.bv_val[j], klen );
3643 HASH_Final( HASHdigest, &HASHcontext );
3645 ber_dupbv( &keys[nkeys++], &digest );
3648 free( value.bv_val );
3652 if((flags & SLAP_INDEX_SUBSTR_FINAL) && sa->sa_final.bv_val != NULL &&
3653 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3655 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
3656 ber_dupbv( &value, &sa->sa_final );
3657 ldap_pvt_str2lower( value.bv_val );
3659 klen = SLAP_INDEX_SUBSTR_MAXLEN < value.bv_len
3660 ? SLAP_INDEX_SUBSTR_MAXLEN : value.bv_len;
3662 HASH_Init( &HASHcontext );
3663 if( prefix != NULL && prefix->bv_len > 0 ) {
3664 HASH_Update( &HASHcontext,
3665 prefix->bv_val, prefix->bv_len );
3667 HASH_Update( &HASHcontext,
3668 &pre, sizeof( pre ) );
3669 HASH_Update( &HASHcontext,
3670 syntax->ssyn_oid, slen );
3671 HASH_Update( &HASHcontext,
3672 mr->smr_oid, mlen );
3673 HASH_Update( &HASHcontext,
3674 &value.bv_val[value.bv_len-klen], klen );
3675 HASH_Final( HASHdigest, &HASHcontext );
3677 free( value.bv_val );
3678 ber_dupbv( &keys[nkeys++], &digest );
3682 keys[nkeys].bv_val = NULL;
3689 return LDAP_SUCCESS;
3695 numericStringValidate(
3701 if( in->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
3703 for(i=0; i < in->bv_len; i++) {
3704 if( !SLAP_NUMERIC(in->bv_val[i]) ) {
3705 return LDAP_INVALID_SYNTAX;
3709 return LDAP_SUCCESS;
3712 #ifndef SLAP_NVALUES
3715 xnumericStringNormalize(
3718 struct berval *normalized )
3720 /* removal all spaces */
3723 assert( val->bv_len );
3725 normalized->bv_val = ch_malloc( val->bv_len + 1 );
3728 q = normalized->bv_val;
3731 if ( ASCII_SPACE( *p ) ) {
3732 /* Ignore whitespace */
3739 /* we should have copied no more then is in val */
3740 assert( (q - normalized->bv_val) <= (p - val->bv_val) );
3742 /* null terminate */
3745 normalized->bv_len = q - normalized->bv_val;
3747 if( normalized->bv_len == 0 ) {
3748 normalized->bv_val = ch_realloc( normalized->bv_val, 2 );
3749 normalized->bv_val[0] = ' ';
3750 normalized->bv_val[1] = '\0';
3751 normalized->bv_len = 1;
3754 return LDAP_SUCCESS;
3758 objectIdentifierFirstComponentMatch(
3763 struct berval *value,
3764 void *assertedValue )
3766 int rc = LDAP_SUCCESS;
3768 struct berval *asserted = (struct berval *) assertedValue;
3772 if( value->bv_len == 0 || value->bv_val[0] != '(' /*')'*/ ) {
3773 return LDAP_INVALID_SYNTAX;
3776 /* trim leading white space */
3777 for( i=1; ASCII_SPACE(value->bv_val[i]) && i < value->bv_len; i++ ) {
3781 /* grab next word */
3782 oid.bv_val = &value->bv_val[i];
3783 j = value->bv_len - i;
3784 for( i=0; !ASCII_SPACE(oid.bv_val[i]) && i < j; i++ ) {
3789 /* insert attributeTypes, objectclass check here */
3790 if( OID_LEADCHAR(asserted->bv_val[0]) ) {
3791 rc = objectIdentifierMatch( &match, flags, syntax, mr, &oid, asserted );
3794 if ( !strcmp( syntax->ssyn_oid, SLAP_SYNTAX_MATCHINGRULES_OID ) ) {
3795 MatchingRule *asserted_mr = mr_bvfind( asserted );
3796 MatchingRule *stored_mr = mr_bvfind( &oid );
3798 if( asserted_mr == NULL ) {
3799 rc = SLAPD_COMPARE_UNDEFINED;
3801 match = asserted_mr != stored_mr;
3804 } else if ( !strcmp( syntax->ssyn_oid,
3805 SLAP_SYNTAX_ATTRIBUTETYPES_OID ) )
3807 AttributeType *asserted_at = at_bvfind( asserted );
3808 AttributeType *stored_at = at_bvfind( &oid );
3810 if( asserted_at == NULL ) {
3811 rc = SLAPD_COMPARE_UNDEFINED;
3813 match = asserted_at != stored_at;
3816 } else if ( !strcmp( syntax->ssyn_oid,
3817 SLAP_SYNTAX_OBJECTCLASSES_OID ) )
3819 ObjectClass *asserted_oc = oc_bvfind( asserted );
3820 ObjectClass *stored_oc = oc_bvfind( &oid );
3822 if( asserted_oc == NULL ) {
3823 rc = SLAPD_COMPARE_UNDEFINED;
3825 match = asserted_oc != stored_oc;
3831 LDAP_LOG( CONFIG, ENTRY,
3832 "objectIdentifierFirstComponentMatch: %d\n %s\n %s\n",
3833 match, value->bv_val, asserted->bv_val );
3835 Debug( LDAP_DEBUG_ARGS, "objectIdentifierFirstComponentMatch "
3836 "%d\n\t\"%s\"\n\t\"%s\"\n",
3837 match, value->bv_val, asserted->bv_val );
3840 if( rc == LDAP_SUCCESS ) *matchp = match;
3852 struct berval *value,
3853 void *assertedValue )
3855 long lValue, lAssertedValue;
3857 /* safe to assume integers are NUL terminated? */
3858 lValue = strtol(value->bv_val, NULL, 10);
3859 if(( lValue == LONG_MIN || lValue == LONG_MAX) && errno == ERANGE ) {
3860 return LDAP_CONSTRAINT_VIOLATION;
3863 lAssertedValue = strtol(((struct berval *)assertedValue)->bv_val, NULL, 10);
3864 if(( lAssertedValue == LONG_MIN || lAssertedValue == LONG_MAX)
3865 && errno == ERANGE )
3867 return LDAP_CONSTRAINT_VIOLATION;
3870 *matchp = (lValue & lAssertedValue) ? 0 : 1;
3871 return LDAP_SUCCESS;
3880 struct berval *value,
3881 void *assertedValue )
3883 long lValue, lAssertedValue;
3885 /* safe to assume integers are NUL terminated? */
3886 lValue = strtol(value->bv_val, NULL, 10);
3887 if(( lValue == LONG_MIN || lValue == LONG_MAX) && errno == ERANGE ) {
3888 return LDAP_CONSTRAINT_VIOLATION;
3891 lAssertedValue = strtol(((struct berval *)assertedValue)->bv_val, NULL, 10);
3892 if(( lAssertedValue == LONG_MIN || lAssertedValue == LONG_MAX)
3893 && errno == ERANGE )
3895 return LDAP_CONSTRAINT_VIOLATION;
3898 *matchp = (lValue | lAssertedValue) ? 0 : -1;
3899 return LDAP_SUCCESS;
3902 #ifndef SLAP_NVALUES
3905 #include <openssl/x509.h>
3906 #include <openssl/err.h>
3909 * Next function returns a string representation of a ASN1_INTEGER.
3910 * It works for unlimited lengths.
3913 static struct berval *
3914 asn1_integer2str(ASN1_INTEGER *a, struct berval *bv)
3918 static char digit[] = "0123456789";
3920 /* We work backwards, make it fill from the end of buf */
3921 p = buf + sizeof(buf) - 1;
3924 if ( a == NULL || a->length == 0 ) {
3932 /* We want to preserve the original */
3933 copy = ch_malloc(n*sizeof(unsigned int));
3934 for (i = 0; i<n; i++) {
3935 copy[i] = a->data[i];
3939 * base indicates the index of the most significant
3940 * byte that might be nonzero. When it goes off the
3941 * end, we now there is nothing left to do.
3947 for (i = base; i<n; i++ ) {
3948 copy[i] += carry*256;
3949 carry = copy[i] % 10;
3954 * Way too large, we need to leave
3955 * room for sign if negative
3960 *--p = digit[carry];
3962 if (copy[base] == 0) base++;
3967 if ( a->type == V_ASN1_NEG_INTEGER ) {
3971 return ber_str2bv( p, 0, 1, bv );
3975 * Given a certificate in DER format, extract the corresponding
3976 * assertion value for certificateExactMatch
3979 certificateExactConvert(
3981 struct berval * out )
3984 unsigned char *p = in->bv_val;
3985 struct berval serial;
3986 struct berval issuer_dn;
3988 xcert = d2i_X509(NULL, &p, in->bv_len);
3991 LDAP_LOG( CONFIG, ENTRY,
3992 "certificateExactConvert: error parsing cert: %s\n",
3993 ERR_error_string(ERR_get_error(),NULL), 0, 0 );
3995 Debug( LDAP_DEBUG_ARGS, "certificateExactConvert: "
3996 "error parsing cert: %s\n",
3997 ERR_error_string(ERR_get_error(),NULL), NULL, NULL );
3999 return LDAP_INVALID_SYNTAX;
4002 if ( !asn1_integer2str(xcert->cert_info->serialNumber, &serial) ) {
4004 return LDAP_INVALID_SYNTAX;
4006 if ( dnX509normalize(X509_get_issuer_name(xcert), &issuer_dn )
4010 ber_memfree(serial.bv_val);
4011 return LDAP_INVALID_SYNTAX;
4016 out->bv_len = serial.bv_len + issuer_dn.bv_len + sizeof(" $ ");
4017 out->bv_val = ch_malloc(out->bv_len);
4019 AC_MEMCPY(p, serial.bv_val, serial.bv_len);
4021 AC_MEMCPY(p, " $ ", sizeof(" $ ")-1);
4023 AC_MEMCPY(p, issuer_dn.bv_val, issuer_dn.bv_len);
4024 p += issuer_dn.bv_len;
4028 LDAP_LOG( CONFIG, ARGS,
4029 "certificateExactConvert: \n %s\n", out->bv_val, 0, 0 );
4031 Debug( LDAP_DEBUG_ARGS, "certificateExactConvert "
4033 out->bv_val, NULL, NULL );
4036 ber_memfree(serial.bv_val);
4037 ber_memfree(issuer_dn.bv_val);
4039 return LDAP_SUCCESS;
4043 serial_and_issuer_parse(
4044 struct berval *assertion,
4045 struct berval *serial,
4046 struct berval *issuer_dn
4054 begin = assertion->bv_val;
4055 end = assertion->bv_val+assertion->bv_len-1;
4056 for (p=begin; p<=end && *p != '$'; p++) /* empty */ ;
4057 if ( p > end ) return LDAP_INVALID_SYNTAX;
4059 /* p now points at the $ sign, now use
4060 * begin and end to delimit the serial number
4062 while (ASCII_SPACE(*begin)) begin++;
4064 while (ASCII_SPACE(*end)) end--;
4066 if( end <= begin ) return LDAP_INVALID_SYNTAX;
4068 bv.bv_len = end-begin+1;
4070 ber_dupbv(serial, &bv);
4072 /* now extract the issuer, remember p was at the dollar sign */
4074 end = assertion->bv_val+assertion->bv_len-1;
4075 while (ASCII_SPACE(*begin)) begin++;
4076 /* should we trim spaces at the end too? is it safe always? no, no */
4078 if( end <= begin ) return LDAP_INVALID_SYNTAX;
4081 bv.bv_len = end-begin+1;
4084 dnNormalize2( NULL, &bv, issuer_dn );
4087 return LDAP_SUCCESS;
4091 certificateExactMatch(
4096 struct berval *value,
4097 void *assertedValue )
4100 unsigned char *p = value->bv_val;
4101 struct berval serial;
4102 struct berval issuer_dn;
4103 struct berval asserted_serial;
4104 struct berval asserted_issuer_dn;
4107 xcert = d2i_X509(NULL, &p, value->bv_len);
4110 LDAP_LOG( CONFIG, ENTRY,
4111 "certificateExactMatch: error parsing cert: %s\n",
4112 ERR_error_string(ERR_get_error(),NULL), 0, 0 );
4114 Debug( LDAP_DEBUG_ARGS, "certificateExactMatch: "
4115 "error parsing cert: %s\n",
4116 ERR_error_string(ERR_get_error(),NULL), NULL, NULL );
4118 return LDAP_INVALID_SYNTAX;
4121 asn1_integer2str(xcert->cert_info->serialNumber, &serial);
4122 dnX509normalize(X509_get_issuer_name(xcert), &issuer_dn);
4126 serial_and_issuer_parse(assertedValue,
4127 &asserted_serial, &asserted_issuer_dn);
4132 slap_schema.si_syn_integer,
4133 slap_schema.si_mr_integerMatch,
4136 if ( ret == LDAP_SUCCESS ) {
4137 if ( *matchp == 0 ) {
4138 /* We need to normalize everything for dnMatch */
4142 slap_schema.si_syn_distinguishedName,
4143 slap_schema.si_mr_distinguishedNameMatch,
4145 &asserted_issuer_dn);
4150 LDAP_LOG( CONFIG, ARGS, "certificateExactMatch "
4151 "%d\n\t\"%s $ %s\"\n",
4152 *matchp, serial.bv_val, issuer_dn.bv_val );
4153 LDAP_LOG( CONFIG, ARGS, "\t\"%s $ %s\"\n",
4154 asserted_serial.bv_val, asserted_issuer_dn.bv_val,
4157 Debug( LDAP_DEBUG_ARGS, "certificateExactMatch "
4158 "%d\n\t\"%s $ %s\"\n",
4159 *matchp, serial.bv_val, issuer_dn.bv_val );
4160 Debug( LDAP_DEBUG_ARGS, "\t\"%s $ %s\"\n",
4161 asserted_serial.bv_val, asserted_issuer_dn.bv_val,
4165 ber_memfree(serial.bv_val);
4166 ber_memfree(issuer_dn.bv_val);
4167 ber_memfree(asserted_serial.bv_val);
4168 ber_memfree(asserted_issuer_dn.bv_val);
4174 * Index generation function
4175 * We just index the serials, in most scenarios the issuer DN is one of
4176 * a very small set of values.
4178 static int certificateExactIndexer(
4183 struct berval *prefix,
4191 struct berval serial;
4193 /* we should have at least one value at this point */
4194 assert( values != NULL && values[0].bv_val != NULL );
4196 for( i=0; values[i].bv_val != NULL; i++ ) {
4197 /* empty -- just count them */
4200 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
4202 for( i=0; values[i].bv_val != NULL; i++ ) {
4203 p = values[i].bv_val;
4204 xcert = d2i_X509(NULL, &p, values[i].bv_len);
4207 LDAP_LOG( CONFIG, ENTRY,
4208 "certificateExactIndexer: error parsing cert: %s\n",
4209 ERR_error_string(ERR_get_error(),NULL), 0, 0);
4211 Debug( LDAP_DEBUG_ARGS, "certificateExactIndexer: "
4212 "error parsing cert: %s\n",
4213 ERR_error_string(ERR_get_error(),NULL),
4216 /* Do we leak keys on error? */
4217 return LDAP_INVALID_SYNTAX;
4220 asn1_integer2str(xcert->cert_info->serialNumber, &serial);
4222 xintegerNormalize( slap_schema.si_syn_integer,
4223 &serial, &keys[i] );
4224 ber_memfree(serial.bv_val);
4226 LDAP_LOG( CONFIG, ENTRY,
4227 "certificateExactIndexer: returning: %s\n", keys[i].bv_val, 0, 0);
4229 Debug( LDAP_DEBUG_ARGS, "certificateExactIndexer: "
4236 keys[i].bv_val = NULL;
4238 return LDAP_SUCCESS;
4241 /* Index generation function */
4242 /* We think this is always called with a value in matching rule syntax */
4243 static int certificateExactFilter(
4248 struct berval *prefix,
4249 void * assertedValue,
4253 struct berval asserted_serial;
4256 ret = serial_and_issuer_parse( assertedValue, &asserted_serial, NULL );
4257 if( ret != LDAP_SUCCESS ) return ret;
4259 keys = ch_malloc( sizeof( struct berval ) * 2 );
4260 xintegerNormalize( syntax, &asserted_serial, &keys[0] );
4261 keys[1].bv_val = NULL;
4264 ber_memfree(asserted_serial.bv_val);
4265 return LDAP_SUCCESS;
4271 check_time_syntax (struct berval *val,
4275 static int ceiling[9] = { 99, 99, 11, 30, 23, 59, 59, 12, 59 };
4276 static int mdays[2][12] = {
4277 /* non-leap years */
4278 { 30, 27, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30 },
4280 { 30, 28, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30 }
4283 int part, c, tzoffset, leapyear = 0 ;
4285 if( val->bv_len == 0 ) {
4286 return LDAP_INVALID_SYNTAX;
4289 p = (char *)val->bv_val;
4290 e = p + val->bv_len;
4292 /* Ignore initial whitespace */
4293 while ( ( p < e ) && ASCII_SPACE( *p ) ) {
4297 if (e - p < 13 - (2 * start)) {
4298 return LDAP_INVALID_SYNTAX;
4301 for (part = 0; part < 9; part++) {
4305 for (part = start; part < 7; part++) {
4307 if ((part == 6) && (c == 'Z' || c == '+' || c == '-')) {
4314 return LDAP_INVALID_SYNTAX;
4316 if (c < 0 || c > 9) {
4317 return LDAP_INVALID_SYNTAX;
4323 return LDAP_INVALID_SYNTAX;
4325 if (c < 0 || c > 9) {
4326 return LDAP_INVALID_SYNTAX;
4331 if (part == 2 || part == 3) {
4334 if (parts[part] < 0) {
4335 return LDAP_INVALID_SYNTAX;
4337 if (parts[part] > ceiling[part]) {
4338 return LDAP_INVALID_SYNTAX;
4342 /* leapyear check for the Gregorian calendar (year>1581) */
4343 if (((parts[1] % 4 == 0) && (parts[1] != 0)) ||
4344 ((parts[0] % 4 == 0) && (parts[1] == 0)))
4349 if (parts[3] > mdays[leapyear][parts[2]]) {
4350 return LDAP_INVALID_SYNTAX;
4355 tzoffset = 0; /* UTC */
4356 } else if (c != '+' && c != '-') {
4357 return LDAP_INVALID_SYNTAX;
4361 } else /* c == '+' */ {
4366 return LDAP_INVALID_SYNTAX;
4369 for (part = 7; part < 9; part++) {
4371 if (c < 0 || c > 9) {
4372 return LDAP_INVALID_SYNTAX;
4377 if (c < 0 || c > 9) {
4378 return LDAP_INVALID_SYNTAX;
4382 if (parts[part] < 0 || parts[part] > ceiling[part]) {
4383 return LDAP_INVALID_SYNTAX;
4388 /* Ignore trailing whitespace */
4389 while ( ( p < e ) && ASCII_SPACE( *p ) ) {
4393 return LDAP_INVALID_SYNTAX;
4396 switch ( tzoffset ) {
4397 case -1: /* negativ offset to UTC, ie west of Greenwich */
4398 parts[4] += parts[7];
4399 parts[5] += parts[8];
4400 for (part = 6; --part > 0; ) { /* offset is just hhmm, no seconds */
4404 c = mdays[leapyear][parts[2]];
4406 if (parts[part] > c) {
4407 parts[part] -= c + 1;
4412 case 1: /* positive offset to UTC, ie east of Greenwich */
4413 parts[4] -= parts[7];
4414 parts[5] -= parts[8];
4415 for (part = 6; --part > 0; ) {
4419 /* first arg to % needs to be non negativ */
4420 c = mdays[leapyear][(parts[2] - 1 + 12) % 12];
4422 if (parts[part] < 0) {
4423 parts[part] += c + 1;
4428 case 0: /* already UTC */
4432 return LDAP_SUCCESS;
4435 #ifdef SUPPORT_OBSOLETE_UTC_SYNTAX
4440 struct berval *normalized )
4444 rc = check_time_syntax(val, 1, parts);
4445 if (rc != LDAP_SUCCESS) {
4449 normalized->bv_val = ch_malloc( 14 );
4450 if ( normalized->bv_val == NULL ) {
4451 return LBER_ERROR_MEMORY;
4454 sprintf( normalized->bv_val, "%02d%02d%02d%02d%02d%02dZ",
4455 parts[1], parts[2] + 1, parts[3] + 1,
4456 parts[4], parts[5], parts[6] );
4457 normalized->bv_len = 13;
4459 return LDAP_SUCCESS;
4463 #ifdef SUPPORT_OBSOLETE_UTC_SYNTAX
4471 return check_time_syntax(in, 1, parts);
4476 generalizedTimeValidate(
4482 return check_time_syntax(in, 0, parts);
4485 #ifndef SLAP_NVALUES
4488 xgeneralizedTimeNormalize(
4491 struct berval *normalized )
4495 rc = check_time_syntax(val, 0, parts);
4496 if (rc != LDAP_SUCCESS) {
4500 normalized->bv_val = ch_malloc( 16 );
4501 if ( normalized->bv_val == NULL ) {
4502 return LBER_ERROR_MEMORY;
4505 sprintf( normalized->bv_val, "%02d%02d%02d%02d%02d%02d%02dZ",
4506 parts[0], parts[1], parts[2] + 1, parts[3] + 1,
4507 parts[4], parts[5], parts[6] );
4508 normalized->bv_len = 15;
4510 return LDAP_SUCCESS;
4515 nisNetgroupTripleValidate(
4517 struct berval *val )
4522 if ( val->bv_len == 0 ) {
4523 return LDAP_INVALID_SYNTAX;
4526 p = (char *)val->bv_val;
4527 e = p + val->bv_len;
4529 if ( *p != '(' /*')'*/ ) {
4530 return LDAP_INVALID_SYNTAX;
4533 for ( p++; ( p < e ) && ( *p != /*'('*/ ')' ); p++ ) {
4537 return LDAP_INVALID_SYNTAX;
4540 } else if ( !AD_CHAR( *p ) ) {
4541 return LDAP_INVALID_SYNTAX;
4545 if ( ( commas != 2 ) || ( *p != /*'('*/ ')' ) ) {
4546 return LDAP_INVALID_SYNTAX;
4552 return LDAP_INVALID_SYNTAX;
4555 return LDAP_SUCCESS;
4559 bootParameterValidate(
4561 struct berval *val )
4565 if ( val->bv_len == 0 ) {
4566 return LDAP_INVALID_SYNTAX;
4569 p = (char *)val->bv_val;
4570 e = p + val->bv_len;
4573 for (; ( p < e ) && ( *p != '=' ); p++ ) {
4574 if ( !AD_CHAR( *p ) ) {
4575 return LDAP_INVALID_SYNTAX;
4580 return LDAP_INVALID_SYNTAX;
4584 for ( p++; ( p < e ) && ( *p != ':' ); p++ ) {
4585 if ( !AD_CHAR( *p ) ) {
4586 return LDAP_INVALID_SYNTAX;
4591 return LDAP_INVALID_SYNTAX;
4595 for ( p++; p < e; p++ ) {
4596 if ( !SLAP_PRINTABLE( *p ) ) {
4597 return LDAP_INVALID_SYNTAX;
4601 return LDAP_SUCCESS;
4604 #define X_BINARY "X-BINARY-TRANSFER-REQUIRED 'TRUE' "
4605 #define X_NOT_H_R "X-NOT-HUMAN-READABLE 'TRUE' "
4607 static slap_syntax_defs_rec syntax_defs[] = {
4608 {"( 1.3.6.1.4.1.1466.115.121.1.1 DESC 'ACI Item' "
4609 X_BINARY X_NOT_H_R ")",
4610 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, NULL, NULL, NULL},
4611 {"( 1.3.6.1.4.1.1466.115.121.1.2 DESC 'Access Point' " X_NOT_H_R ")",
4612 0, NULL, NULL, NULL},
4613 {"( 1.3.6.1.4.1.1466.115.121.1.3 DESC 'Attribute Type Description' )",
4614 0, NULL, NULL, NULL},
4615 {"( 1.3.6.1.4.1.1466.115.121.1.4 DESC 'Audio' "
4617 SLAP_SYNTAX_BLOB, blobValidate, NULL, NULL},
4618 {"( 1.3.6.1.4.1.1466.115.121.1.5 DESC 'Binary' "
4620 SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4621 {"( 1.3.6.1.4.1.1466.115.121.1.6 DESC 'Bit String' )",
4622 0, bitStringValidate, NULL, NULL },
4623 {"( 1.3.6.1.4.1.1466.115.121.1.7 DESC 'Boolean' )",
4624 0, booleanValidate, NULL, NULL},
4625 {"( 1.3.6.1.4.1.1466.115.121.1.8 DESC 'Certificate' "
4626 X_BINARY X_NOT_H_R ")",
4627 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4628 {"( 1.3.6.1.4.1.1466.115.121.1.9 DESC 'Certificate List' "
4629 X_BINARY X_NOT_H_R ")",
4630 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4631 {"( 1.3.6.1.4.1.1466.115.121.1.10 DESC 'Certificate Pair' "
4632 X_BINARY X_NOT_H_R ")",
4633 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4634 {"( 1.3.6.1.4.1.1466.115.121.1.11 DESC 'Country String' )",
4635 0, countryStringValidate, xIA5StringNormalize, NULL},
4636 {"( 1.3.6.1.4.1.1466.115.121.1.12 DESC 'Distinguished Name' )",
4637 0, dnValidate, xdnNormalize, dnPretty2},
4638 {"( 1.3.6.1.4.1.1466.115.121.1.13 DESC 'Data Quality' )",
4639 0, NULL, NULL, NULL},
4640 {"( 1.3.6.1.4.1.1466.115.121.1.14 DESC 'Delivery Method' )",
4641 0, NULL, NULL, NULL},
4642 {"( 1.3.6.1.4.1.1466.115.121.1.15 DESC 'Directory String' )",
4643 0, UTF8StringValidate, xUTF8StringNormalize, NULL},
4644 {"( 1.3.6.1.4.1.1466.115.121.1.16 DESC 'DIT Content Rule Description' )",
4645 0, NULL, NULL, NULL},
4646 {"( 1.3.6.1.4.1.1466.115.121.1.17 DESC 'DIT Structure Rule Description' )",
4647 0, NULL, NULL, NULL},
4648 {"( 1.3.6.1.4.1.1466.115.121.1.19 DESC 'DSA Quality' )",
4649 0, NULL, NULL, NULL},
4650 {"( 1.3.6.1.4.1.1466.115.121.1.20 DESC 'DSE Type' )",
4651 0, NULL, NULL, NULL},
4652 {"( 1.3.6.1.4.1.1466.115.121.1.21 DESC 'Enhanced Guide' )",
4653 0, NULL, NULL, NULL},
4654 {"( 1.3.6.1.4.1.1466.115.121.1.22 DESC 'Facsimile Telephone Number' )",
4655 0, printablesStringValidate, xtelephoneNumberNormalize, NULL},
4656 {"( 1.3.6.1.4.1.1466.115.121.1.23 DESC 'Fax' " X_NOT_H_R ")",
4657 SLAP_SYNTAX_BLOB, NULL, NULL, NULL},
4658 {"( 1.3.6.1.4.1.1466.115.121.1.24 DESC 'Generalized Time' )",
4659 0, generalizedTimeValidate, xgeneralizedTimeNormalize, NULL},
4660 {"( 1.3.6.1.4.1.1466.115.121.1.25 DESC 'Guide' )",
4661 0, NULL, NULL, NULL},
4662 {"( 1.3.6.1.4.1.1466.115.121.1.26 DESC 'IA5 String' )",
4663 0, IA5StringValidate, xIA5StringNormalize, NULL},
4664 {"( 1.3.6.1.4.1.1466.115.121.1.27 DESC 'Integer' )",
4665 0, integerValidate, xintegerNormalize, NULL},
4666 {"( 1.3.6.1.4.1.1466.115.121.1.28 DESC 'JPEG' " X_NOT_H_R ")",
4667 SLAP_SYNTAX_BLOB, blobValidate, NULL, NULL},
4668 {"( 1.3.6.1.4.1.1466.115.121.1.29 DESC 'Master And Shadow Access Points' )",
4669 0, NULL, NULL, NULL},
4670 {"( 1.3.6.1.4.1.1466.115.121.1.30 DESC 'Matching Rule Description' )",
4671 0, NULL, NULL, NULL},
4672 {"( 1.3.6.1.4.1.1466.115.121.1.31 DESC 'Matching Rule Use Description' )",
4673 0, NULL, NULL, NULL},
4674 {"( 1.3.6.1.4.1.1466.115.121.1.32 DESC 'Mail Preference' )",
4675 0, NULL, NULL, NULL},
4676 {"( 1.3.6.1.4.1.1466.115.121.1.33 DESC 'MHS OR Address' )",
4677 0, NULL, NULL, NULL},
4678 {"( 1.3.6.1.4.1.1466.115.121.1.34 DESC 'Name And Optional UID' )",
4679 0, nameUIDValidate, xnameUIDNormalize, NULL},
4680 {"( 1.3.6.1.4.1.1466.115.121.1.35 DESC 'Name Form Description' )",
4681 0, NULL, NULL, NULL},
4682 {"( 1.3.6.1.4.1.1466.115.121.1.36 DESC 'Numeric String' )",
4683 0, numericStringValidate, xnumericStringNormalize, NULL},
4684 {"( 1.3.6.1.4.1.1466.115.121.1.37 DESC 'Object Class Description' )",
4685 0, NULL, NULL, NULL},
4686 {"( 1.3.6.1.4.1.1466.115.121.1.38 DESC 'OID' )",
4687 0, oidValidate, NULL, NULL},
4688 {"( 1.3.6.1.4.1.1466.115.121.1.39 DESC 'Other Mailbox' )",
4689 0, IA5StringValidate, xIA5StringNormalize, NULL},
4690 {"( 1.3.6.1.4.1.1466.115.121.1.40 DESC 'Octet String' )",
4691 0, blobValidate, NULL, NULL},
4692 {"( 1.3.6.1.4.1.1466.115.121.1.41 DESC 'Postal Address' )",
4693 0, UTF8StringValidate, xUTF8StringNormalize, NULL},
4694 {"( 1.3.6.1.4.1.1466.115.121.1.42 DESC 'Protocol Information' )",
4695 0, NULL, NULL, NULL},
4696 {"( 1.3.6.1.4.1.1466.115.121.1.43 DESC 'Presentation Address' )",
4697 0, NULL, NULL, NULL},
4698 {"( 1.3.6.1.4.1.1466.115.121.1.44 DESC 'Printable String' )",
4699 0, printableStringValidate, xIA5StringNormalize, NULL},
4700 {"( 1.3.6.1.4.1.1466.115.121.1.45 DESC 'SubtreeSpecification' "
4701 X_BINARY X_NOT_H_R ")",
4702 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, NULL, NULL, NULL},
4703 {"( 1.3.6.1.4.1.1466.115.121.1.49 DESC 'Supported Algorithm' "
4704 X_BINARY X_NOT_H_R ")",
4705 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4706 {"( 1.3.6.1.4.1.1466.115.121.1.50 DESC 'Telephone Number' )",
4707 0, printableStringValidate, xtelephoneNumberNormalize, NULL},
4708 {"( 1.3.6.1.4.1.1466.115.121.1.51 DESC 'Teletex Terminal Identifier' )",
4709 0, NULL, NULL, NULL},
4710 {"( 1.3.6.1.4.1.1466.115.121.1.52 DESC 'Telex Number' )",
4711 0, printablesStringValidate, xIA5StringNormalize, NULL},
4712 #ifdef SUPPORT_OBSOLETE_UTC_SYNTAX
4713 {"( 1.3.6.1.4.1.1466.115.121.1.53 DESC 'UTC Time' )",
4714 0, utcTimeValidate, xutcTimeNormalize, NULL},
4716 {"( 1.3.6.1.4.1.1466.115.121.1.54 DESC 'LDAP Syntax Description' )",
4717 0, NULL, NULL, NULL},
4718 {"( 1.3.6.1.4.1.1466.115.121.1.55 DESC 'Modify Rights' )",
4719 0, NULL, NULL, NULL},
4720 {"( 1.3.6.1.4.1.1466.115.121.1.56 DESC 'LDAP Schema Definition' )",
4721 0, NULL, NULL, NULL},
4722 {"( 1.3.6.1.4.1.1466.115.121.1.57 DESC 'LDAP Schema Description' )",
4723 0, NULL, NULL, NULL},
4724 {"( 1.3.6.1.4.1.1466.115.121.1.58 DESC 'Substring Assertion' )",
4725 0, NULL, NULL, NULL},
4727 /* RFC 2307 NIS Syntaxes */
4728 {"( 1.3.6.1.1.1.0.0 DESC 'RFC2307 NIS Netgroup Triple' )",
4729 0, nisNetgroupTripleValidate, NULL, NULL},
4730 {"( 1.3.6.1.1.1.0.1 DESC 'RFC2307 Boot Parameter' )",
4731 0, bootParameterValidate, NULL, NULL},
4735 /* These OIDs are not published yet, but will be in the next
4736 * I-D for PKIX LDAPv3 schema as have been advanced by David
4737 * Chadwick in private mail.
4739 {"( 1.2.826.0.1.3344810.7.1 DESC 'Serial Number and Issuer' )",
4740 0, UTF8StringValidate, NULL, NULL},
4743 /* OpenLDAP Experimental Syntaxes */
4744 #ifdef SLAPD_ACI_ENABLED
4745 {"( 1.3.6.1.4.1.4203.666.2.1 DESC 'OpenLDAP Experimental ACI' )",
4747 UTF8StringValidate /* THIS WILL CHANGE FOR NEW ACI SYNTAX */,
4751 #ifdef SLAPD_AUTHPASSWD
4752 /* needs updating */
4753 {"( 1.3.6.1.4.1.4203.666.2.2 DESC 'OpenLDAP authPassword' )",
4754 SLAP_SYNTAX_HIDE, NULL, NULL, NULL},
4757 /* OpenLDAP Void Syntax */
4758 {"( 1.3.6.1.4.1.4203.1.1.1 DESC 'OpenLDAP void' )" ,
4759 SLAP_SYNTAX_HIDE, inValidate, NULL, NULL},
4760 {NULL, 0, NULL, NULL, NULL}
4764 char *certificateExactMatchSyntaxes[] = {
4765 "1.3.6.1.4.1.1466.115.121.1.8" /* certificate */,
4769 char *directoryStringSyntaxes[] = {
4770 "1.3.6.1.4.1.1466.115.121.1.44" /* printableString */,
4773 char *integerFirstComponentMatchSyntaxes[] = {
4774 "1.3.6.1.4.1.1466.115.121.1.27" /* INTEGER */,
4775 "1.3.6.1.4.1.1466.115.121.1.17" /* ditStructureRuleDescription */,
4778 char *objectIdentifierFirstComponentMatchSyntaxes[] = {
4779 "1.3.6.1.4.1.1466.115.121.1.38" /* OID */,
4780 "1.3.6.1.4.1.1466.115.121.1.3" /* attributeTypeDescription */,
4781 "1.3.6.1.4.1.1466.115.121.1.16" /* ditContentRuleDescription */,
4782 "1.3.6.1.4.1.1466.115.121.1.54" /* ldapSyntaxDescription */,
4783 "1.3.6.1.4.1.1466.115.121.1.30" /* matchingRuleDescription */,
4784 "1.3.6.1.4.1.1466.115.121.1.31" /* matchingRuleUseDescription */,
4785 "1.3.6.1.4.1.1466.115.121.1.35" /* nameFormDescription */,
4786 "1.3.6.1.4.1.1466.115.121.1.37" /* objectClassDescription */,
4791 * Other matching rules in X.520 that we do not use (yet):
4793 * 2.5.13.9 numericStringOrderingMatch
4794 * 2.5.13.25 uTCTimeMatch
4795 * 2.5.13.26 uTCTimeOrderingMatch
4796 * 2.5.13.31 directoryStringFirstComponentMatch
4797 * 2.5.13.32 wordMatch
4798 * 2.5.13.33 keywordMatch
4799 * 2.5.13.35 certificateMatch
4800 * 2.5.13.36 certificatePairExactMatch
4801 * 2.5.13.37 certificatePairMatch
4802 * 2.5.13.38 certificateListExactMatch
4803 * 2.5.13.39 certificateListMatch
4804 * 2.5.13.40 algorithmIdentifierMatch
4805 * 2.5.13.41 storedPrefixMatch
4806 * 2.5.13.42 attributeCertificateMatch
4807 * 2.5.13.43 readerAndKeyIDMatch
4808 * 2.5.13.44 attributeIntegrityMatch
4810 static slap_mrule_defs_rec mrule_defs[] = {
4812 * EQUALITY matching rules must be listed after associated APPROX
4813 * matching rules. So, we list all APPROX matching rules first.
4815 #ifndef SLAP_NVALUES
4816 {"( " directoryStringApproxMatchOID " NAME 'directoryStringApproxMatch' "
4817 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4818 SLAP_MR_HIDE | SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT, NULL,
4819 NULL, NULL, directoryStringApproxMatch,
4820 directoryStringApproxIndexer, directoryStringApproxFilter,
4823 {"( " IA5StringApproxMatchOID " NAME 'IA5StringApproxMatch' "
4824 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4825 SLAP_MR_HIDE | SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT, NULL,
4826 NULL, NULL, IA5StringApproxMatch,
4827 IA5StringApproxIndexer, IA5StringApproxFilter,
4832 * Other matching rules
4835 {"( 2.5.13.0 NAME 'objectIdentifierMatch' "
4836 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
4837 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4839 objectIdentifierNormalize, objectIdentifierMatch,
4840 objectIdentifierIndexer, objectIdentifierFilter,
4843 {"( 2.5.13.1 NAME 'distinguishedNameMatch' "
4844 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )",
4845 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4847 distinguishedNameNormalize, distinguishedNameMatch,
4848 distinguishedNameIndexer, distinguishedNameFilter,
4851 {"( 2.5.13.2 NAME 'caseIgnoreMatch' "
4852 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4853 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD,
4854 directoryStringSyntaxes,
4856 caseIgnoreNormalize, caseIgnoreMatch,
4857 caseIgnoreIndexer, caseIgnoreFilter,
4858 directoryStringApproxMatchOID },
4860 {"( 2.5.13.3 NAME 'caseIgnoreOrderingMatch' "
4861 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4862 SLAP_MR_ORDERING, directoryStringSyntaxes,
4863 NULL, caseIgnoreNormalize, caseIgnoreOrderingMatch,
4866 {"( 2.5.13.4 NAME 'caseIgnoreSubstringsMatch' "
4867 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4868 SLAP_MR_SUBSTR, NULL,
4870 caseIgnoreSubstringsMatch,
4871 caseIgnoreSubstringsIndexer, caseIgnoreSubstringsFilter,
4874 {"( 2.5.13.5 NAME 'caseExactMatch' "
4875 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4876 SLAP_MR_EQUALITY | SLAP_MR_EXT, directoryStringSyntaxes,
4878 caseExactNormalize, caseExactMatch,
4879 caseExactIndexer, caseExactFilter,
4880 directoryStringApproxMatchOID },
4882 {"( 2.5.13.6 NAME 'caseExactOrderingMatch' "
4883 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4884 SLAP_MR_ORDERING, directoryStringSyntaxes,
4885 NULL, caseExactNormalize, caseExactOrderingMatch,
4888 {"( 2.5.13.7 NAME 'caseExactSubstringsMatch' "
4889 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4890 SLAP_MR_SUBSTR, directoryStringSyntaxes,
4892 NULL, caseExactSubstringsMatch,
4893 caseExactSubstringsIndexer, caseExactSubstringsFilter,
4896 {"( 2.5.13.8 NAME 'numericStringMatch' "
4897 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 )",
4898 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL,
4900 numericStringNormalize, numericStringMatch,
4901 numericStringIndexer, numericStringFilter,
4904 {"( 2.5.13.10 NAME 'numericStringSubstringsMatch' "
4905 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4906 SLAP_MR_SUBSTR, NULL,
4908 NULL, numericStringSubstringsMatch,
4909 numericStringSubstringsIndexer, numericStringSubstringsFilter,
4912 {"( 2.5.13.11 NAME 'caseIgnoreListMatch' "
4913 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )",
4914 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL,
4915 NULL, NULL, NULL, NULL, NULL, NULL},
4917 {"( 2.5.13.12 NAME 'caseIgnoreListSubstringsMatch' "
4918 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4919 SLAP_MR_SUBSTR, NULL,
4920 NULL, NULL, NULL, NULL, NULL, NULL},
4922 {"( 2.5.13.13 NAME 'booleanMatch' "
4923 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )",
4924 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4927 booleanIndexer, booleanFilter,
4930 {"( 2.5.13.14 NAME 'integerMatch' "
4931 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4932 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4934 integerNormalize, integerMatch,
4935 integerIndexer, integerFilter,
4938 {"( 2.5.13.15 NAME 'integerOrderingMatch' "
4939 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4940 SLAP_MR_ORDERING, NULL, NULL,
4941 integerNormalize, integerOrderingMatch,
4942 integerIndexer, integerFilter,
4945 {"( 2.5.13.16 NAME 'bitStringMatch' "
4946 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.6 )",
4947 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4949 bitStringNormalize, bitStringMatch,
4950 bitStringIndexer, bitStringFilter,
4953 {"( 2.5.13.17 NAME 'octetStringMatch' "
4954 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
4955 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4957 octetStringMatch, octetStringIndexer, octetStringFilter,
4960 {"( 2.5.13.18 NAME 'octetStringOrderingMatch' "
4961 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
4962 SLAP_MR_ORDERING, NULL,
4964 octetStringOrderingMatch, NULL, NULL,
4967 {"( 2.5.13.19 NAME 'octetStringSubstringsMatch' "
4968 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
4969 SLAP_MR_SUBSTR, NULL,
4971 octetStringSubstringsMatch, NULL, NULL,
4974 {"( 2.5.13.20 NAME 'telephoneNumberMatch' "
4975 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 )",
4976 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL,
4978 telephoneNumberNormalize, telephoneNumberMatch,
4979 telephoneNumberIndexer, telephoneNumberFilter,
4982 {"( 2.5.13.21 NAME 'telephoneNumberSubstringsMatch' "
4983 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4984 SLAP_MR_SUBSTR, NULL,
4985 NULL, NULL, telephoneNumberSubstringsMatch,
4986 telephoneNumberSubstringsIndexer, telephoneNumberSubstringsFilter,
4989 {"( 2.5.13.22 NAME 'presentationAddressMatch' "
4990 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.43 )",
4991 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4996 {"( 2.5.13.23 NAME 'uniqueMemberMatch' "
4997 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.34 )",
4998 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
5000 uniqueMemberNormalize, uniqueMemberMatch,
5004 {"( 2.5.13.24 NAME 'protocolInformationMatch' "
5005 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.42 )",
5006 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
5007 NULL, NULL, NULL, NULL, NULL, NULL},
5009 {"( 2.5.13.27 NAME 'generalizedTimeMatch' "
5010 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
5011 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
5013 generalizedTimeNormalize, generalizedTimeMatch,
5017 {"( 2.5.13.28 NAME 'generalizedTimeOrderingMatch' "
5018 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
5019 SLAP_MR_ORDERING, NULL,
5021 generalizedTimeNormalize, generalizedTimeOrderingMatch,
5025 {"( 2.5.13.29 NAME 'integerFirstComponentMatch' "
5026 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
5027 SLAP_MR_EQUALITY | SLAP_MR_EXT, integerFirstComponentMatchSyntaxes,
5029 integerFirstComponentNormalize, integerMatch,
5033 {"( 2.5.13.30 NAME 'objectIdentifierFirstComponentMatch' "
5034 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
5035 SLAP_MR_EQUALITY | SLAP_MR_EXT,
5036 objectIdentifierFirstComponentMatchSyntaxes,
5038 objectIdentifierFirstComponentNormalize, objectIdentifierMatch,
5042 #ifndef SLAP_NVALUES
5044 {"( 2.5.13.34 NAME 'certificateExactMatch' "
5045 "SYNTAX 1.2.826.0.1.3344810.7.1 )",
5046 SLAP_MR_EQUALITY | SLAP_MR_EXT, certificateExactMatchSyntaxes,
5047 certificateExactConvert, NULL,
5048 certificateExactMatch,
5049 certificateExactIndexer, certificateExactFilter,
5054 {"( 1.3.6.1.4.1.1466.109.114.1 NAME 'caseExactIA5Match' "
5055 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
5056 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
5058 caseExactIA5Normalize, caseExactIA5Match,
5059 caseExactIA5Indexer, caseExactIA5Filter,
5060 IA5StringApproxMatchOID },
5062 {"( 1.3.6.1.4.1.1466.109.114.2 NAME 'caseIgnoreIA5Match' "
5063 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
5064 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL,
5066 NULL, caseIgnoreIA5Match,
5067 caseIgnoreIA5Indexer, caseIgnoreIA5Filter,
5068 IA5StringApproxMatchOID },
5070 {"( 1.3.6.1.4.1.1466.109.114.3 NAME 'caseIgnoreIA5SubstringsMatch' "
5071 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
5072 SLAP_MR_SUBSTR, NULL,
5074 NULL, caseIgnoreIA5SubstringsMatch,
5075 caseIgnoreIA5SubstringsIndexer, caseIgnoreIA5SubstringsFilter,
5078 {"( 1.3.6.1.4.1.4203.1.2.1 NAME 'caseExactIA5SubstringsMatch' "
5079 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
5080 SLAP_MR_SUBSTR, NULL,
5082 NULL, caseExactIA5SubstringsMatch,
5083 caseExactIA5SubstringsIndexer, caseExactIA5SubstringsFilter,
5086 #ifdef SLAPD_AUTHPASSWD
5087 /* needs updating */
5088 {"( 1.3.6.1.4.1.4203.666.4.1 NAME 'authPasswordMatch' "
5089 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
5090 SLAP_MR_EQUALITY, NULL,
5092 authPasswordMatch, NULL, NULL,
5096 #ifdef SLAPD_ACI_ENABLED
5097 {"( 1.3.6.1.4.1.4203.666.4.2 NAME 'OpenLDAPaciMatch' "
5098 "SYNTAX 1.3.6.1.4.1.4203.666.2.1 )",
5099 SLAP_MR_EQUALITY, NULL,
5101 OpenLDAPaciMatch, NULL, NULL,
5105 {"( 1.2.840.113556.1.4.803 NAME 'integerBitAndMatch' "
5106 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
5109 NULL, integerBitAndMatch, NULL, NULL,
5112 {"( 1.2.840.113556.1.4.804 NAME 'integerBitOrMatch' "
5113 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
5116 NULL, integerBitOrMatch, NULL, NULL,
5119 {NULL, SLAP_MR_NONE, NULL,
5120 NULL, NULL, NULL, NULL, NULL,
5125 slap_schema_init( void )
5130 /* we should only be called once (from main) */
5131 assert( schema_init_done == 0 );
5133 for ( i=0; syntax_defs[i].sd_desc != NULL; i++ ) {
5134 res = register_syntax( &syntax_defs[i] );
5137 fprintf( stderr, "slap_schema_init: Error registering syntax %s\n",
5138 syntax_defs[i].sd_desc );
5143 for ( i=0; mrule_defs[i].mrd_desc != NULL; i++ ) {
5144 if( mrule_defs[i].mrd_usage == SLAP_MR_NONE &&
5145 mrule_defs[i].mrd_compat_syntaxes == NULL )
5148 "slap_schema_init: Ignoring unusable matching rule %s\n",
5149 mrule_defs[i].mrd_desc );
5153 res = register_matching_rule( &mrule_defs[i] );
5157 "slap_schema_init: Error registering matching rule %s\n",
5158 mrule_defs[i].mrd_desc );
5163 res = slap_schema_load();
5164 schema_init_done = 1;
5169 schema_destroy( void )