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 objectIdentifierNormalize NULL
56 #define objectIdentifierFirstComponentNormalize NULL
57 #define generalizedTimeNormalize NULL
58 #define bitStringNormalize NULL
60 #define distinguishedNameNormalize dnNormalize
61 #define distinguishedNameMatch dnMatch
62 #define distinguishedNameIndexer octetStringIndexer
63 #define distinguishedNameFilter octetStringFilter
65 #define uniqueMemberMatch dnMatch /* FIXME! */
67 #define objectIdentifierMatch octetStringMatch
68 #define objectIdentifierIndexer octetStringIndexer
69 #define objectIdentifierFilter octetStringFilter
71 #define OpenLDAPaciMatch NULL
73 #define bitStringMatch octetStringMatch
74 #define bitStringIndexer octetStringIndexer
75 #define bitStringFilter octetStringFilter
77 #define integerMatch NULL
78 #define integerOrderingMatch NULL
79 #define integerIndexer NULL
80 #define integerFilter NULL
82 #define generalizedTimeMatch NULL
83 #define generalizedTimeOrderingMatch NULL
85 #define caseIgnoreMatch octetStringMatch
86 #define caseIgnoreOrderingMatch octetStringOrderingMatch
87 #define caseIgnoreIndexer octetStringIndexer
88 #define caseIgnoreFilter octetStringFilter
90 #define caseIgnoreSubstringsMatch octetStringSubstringsMatch
91 #define caseIgnoreSubstringsIndexer octetStringSubstringsIndexer
92 #define caseIgnoreSubstringsFilter octetStringSubstringsFilter
94 #define caseExactMatch octetStringMatch
95 #define caseExactOrderingMatch octetStringOrderingMatch
96 #define caseExactIndexer octetStringIndexer
97 #define caseExactFilter octetStringFilter
99 #define caseExactSubstringsMatch octetStringSubstringsMatch
100 #define caseExactSubstringsIndexer octetStringSubstringsIndexer
101 #define caseExactSubstringsFilter octetStringSubstringsFilter
103 #define caseExactIA5Match octetStringMatch
104 #define caseExactIA5Indexer octetStringIndexer
105 #define caseExactIA5Filter octetStringFilter
107 #define caseExactIA5SubstringsMatch octetStringSubstringsMatch
108 #define caseExactIA5SubstringsIndexer octetStringSubstringsIndexer
109 #define caseExactIA5SubstringsFilter octetStringSubstringsFilter
111 #define caseIgnoreIA5Match octetStringMatch
112 #define caseIgnoreIA5Indexer octetStringIndexer
113 #define caseIgnoreIA5Filter octetStringFilter
115 #define caseIgnoreIA5SubstringsMatch caseExactIA5SubstringsMatch
116 #define caseIgnoreIA5SubstringsIndexer caseExactIA5SubstringsIndexer
117 #define caseIgnoreIA5SubstringsFilter caseExactIA5SubstringsFilter
119 #define numericStringMatch octetStringMatch
120 #define numericStringIndexer octetStringIndexer
121 #define numericStringFilter octetStringFilter
123 #define numericStringSubstringsMatch caseExactIA5SubstringsMatch
124 #define numericStringSubstringsIndexer caseExactIA5SubstringsIndexer
125 #define numericStringSubstringsFilter caseExactIA5SubstringsFilter
127 #define telephoneNumberMatch octetStringMatch
128 #define telephoneNumberIndexer octetStringIndexer
129 #define telephoneNumberFilter octetStringFilter
131 #define telephoneNumberSubstringsMatch caseExactIA5SubstringsMatch
132 #define telephoneNumberSubstringsIndexer caseExactIA5SubstringsIndexer
133 #define telephoneNumberSubstringsFilter caseExactIA5SubstringsFilter
135 #define booleanIndexer octetStringIndexer
136 #define booleanFilter octetStringFilter
139 /* validatation routines */
140 #define berValidate blobValidate
142 /* approx matching rules */
144 #define directoryStringApproxMatchOID NULL
145 #define IA5StringApproxMatchOID NULL
147 #define directoryStringApproxMatchOID "1.3.6.1.4.1.4203.666.4.4"
148 #define directoryStringApproxMatch approxMatch
149 #define directoryStringApproxIndexer approxIndexer
150 #define directoryStringApproxFilter approxFilter
151 #define IA5StringApproxMatchOID "1.3.6.1.4.1.4203.666.4.5"
152 #define IA5StringApproxMatch approxMatch
153 #define IA5StringApproxIndexer approxIndexer
154 #define IA5StringApproxFilter approxFilter
159 #define xdnNormalize dnNormalize
161 /* (new) normalization routines */
162 #define caseExactNormalize NULL
163 #define caseExactIA5Normalize NULL
164 #define caseIgnoreNormalize NULL
165 #define caseIgnoreIA5Normalize NULL
166 #define distinguishedNameNormalize NULL
167 #define integerNormalize NULL
168 #define integerFirstComponentNormalize NULL
169 #define numericStringNormalize NULL
170 #define objectIdentifierNormalize NULL
171 #define objectIdentifierFirstComponentNormalize NULL
172 #define generalizedTimeNormalize NULL
173 #define uniqueMemberNormalize NULL
174 #define bitStringNormalize NULL
175 #define telephoneNumberNormalize NULL
178 /* matching routines */
179 #define bitStringMatch octetStringMatch
180 #define bitStringIndexer octetStringIndexer
181 #define bitStringFilter octetStringFilter
183 #define numericStringMatch caseIgnoreIA5Match
184 #define numericStringIndexer NULL
185 #define numericStringFilter NULL
186 #define numericStringSubstringsIndexer NULL
187 #define numericStringSubstringsFilter NULL
189 #define objectIdentifierMatch octetStringMatch
190 #define objectIdentifierIndexer caseIgnoreIA5Indexer
191 #define objectIdentifierFilter caseIgnoreIA5Filter
193 #define octetStringSubstringsMatch NULL
194 #define OpenLDAPaciMatch NULL
196 #define generalizedTimeMatch caseIgnoreIA5Match
197 #define generalizedTimeOrderingMatch caseIgnoreIA5Match
199 #define uniqueMemberMatch dnMatch
200 #define numericStringSubstringsMatch NULL
202 #define caseExactIndexer caseExactIgnoreIndexer
203 #define caseExactFilter caseExactIgnoreFilter
204 #define caseExactOrderingMatch caseExactMatch
205 #define caseExactSubstringsMatch caseExactIgnoreSubstringsMatch
206 #define caseExactSubstringsIndexer caseExactIgnoreSubstringsIndexer
207 #define caseExactSubstringsFilter caseExactIgnoreSubstringsFilter
208 #define caseIgnoreIndexer caseExactIgnoreIndexer
209 #define caseIgnoreFilter caseExactIgnoreFilter
210 #define caseIgnoreOrderingMatch caseIgnoreMatch
211 #define caseIgnoreSubstringsMatch caseExactIgnoreSubstringsMatch
212 #define caseIgnoreSubstringsIndexer caseExactIgnoreSubstringsIndexer
213 #define caseIgnoreSubstringsFilter caseExactIgnoreSubstringsFilter
215 #define integerOrderingMatch integerMatch
216 #define integerFirstComponentMatch integerMatch
218 #define distinguishedNameMatch dnMatch
219 #define distinguishedNameIndexer caseExactIgnoreIndexer
220 #define distinguishedNameFilter caseExactIgnoreFilter
222 #define telephoneNumberMatch caseIgnoreIA5Match
223 #define telephoneNumberSubstringsMatch caseIgnoreIA5SubstringsMatch
224 #define telephoneNumberIndexer caseIgnoreIA5Indexer
225 #define telephoneNumberFilter caseIgnoreIA5Filter
226 #define telephoneNumberSubstringsIndexer caseIgnoreIA5SubstringsIndexer
227 #define telephoneNumberSubstringsFilter caseIgnoreIA5SubstringsFilter
229 #define booleanIndexer octetStringIndexer
230 #define booleanFilter octetStringFilter
234 static char *bvcasechr( struct berval *bv, unsigned char c, ber_len_t *len )
237 char lower = TOLOWER( c );
238 char upper = TOUPPER( c );
240 if( c == 0 ) return NULL;
242 for( i=0; i < bv->bv_len; i++ ) {
243 if( upper == bv->bv_val[i] || lower == bv->bv_val[i] ) {
245 return &bv->bv_val[i];
258 struct berval *value,
259 void *assertedValue )
261 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
264 match = memcmp( value->bv_val,
265 ((struct berval *) assertedValue)->bv_val,
274 octetStringOrderingMatch(
279 struct berval *value,
280 void *assertedValue )
282 ber_len_t v_len = value->bv_len;
283 ber_len_t av_len = ((struct berval *) assertedValue)->bv_len;
285 int match = memcmp( value->bv_val,
286 ((struct berval *) assertedValue)->bv_val,
287 (v_len < av_len ? v_len : av_len) );
289 if( match == 0 ) match = v_len - av_len;
295 /* Index generation function */
296 int octetStringIndexer(
301 struct berval *prefix,
308 HASH_CONTEXT HASHcontext;
309 unsigned char HASHdigest[HASH_BYTES];
310 struct berval digest;
311 digest.bv_val = HASHdigest;
312 digest.bv_len = sizeof(HASHdigest);
314 for( i=0; values[i].bv_val != NULL; i++ ) {
315 /* just count them */
318 /* we should have at least one value at this point */
321 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
323 slen = syntax->ssyn_oidlen;
324 mlen = mr->smr_oidlen;
326 for( i=0; values[i].bv_val != NULL; i++ ) {
327 HASH_Init( &HASHcontext );
328 if( prefix != NULL && prefix->bv_len > 0 ) {
329 HASH_Update( &HASHcontext,
330 prefix->bv_val, prefix->bv_len );
332 HASH_Update( &HASHcontext,
333 syntax->ssyn_oid, slen );
334 HASH_Update( &HASHcontext,
336 HASH_Update( &HASHcontext,
337 values[i].bv_val, values[i].bv_len );
338 HASH_Final( HASHdigest, &HASHcontext );
340 ber_dupbv( &keys[i], &digest );
343 keys[i].bv_val = NULL;
351 /* Index generation function */
352 int octetStringFilter(
357 struct berval *prefix,
358 void * assertedValue,
363 HASH_CONTEXT HASHcontext;
364 unsigned char HASHdigest[HASH_BYTES];
365 struct berval *value = (struct berval *) assertedValue;
366 struct berval digest;
367 digest.bv_val = HASHdigest;
368 digest.bv_len = sizeof(HASHdigest);
370 slen = syntax->ssyn_oidlen;
371 mlen = mr->smr_oidlen;
373 keys = ch_malloc( sizeof( struct berval ) * 2 );
375 HASH_Init( &HASHcontext );
376 if( prefix != NULL && prefix->bv_len > 0 ) {
377 HASH_Update( &HASHcontext,
378 prefix->bv_val, prefix->bv_len );
380 HASH_Update( &HASHcontext,
381 syntax->ssyn_oid, slen );
382 HASH_Update( &HASHcontext,
384 HASH_Update( &HASHcontext,
385 value->bv_val, value->bv_len );
386 HASH_Final( HASHdigest, &HASHcontext );
388 ber_dupbv( keys, &digest );
389 keys[1].bv_val = NULL;
402 /* no value allowed */
403 return LDAP_INVALID_SYNTAX;
411 /* any value allowed */
422 /* very unforgiving validation, requires no normalization
423 * before simplistic matching
425 if( in->bv_len < 3 ) {
426 return LDAP_INVALID_SYNTAX;
430 * rfc 2252 section 6.3 Bit String
431 * bitstring = "'" *binary-digit "'"
432 * binary-digit = "0" / "1"
433 * example: '0101111101'B
436 if( in->bv_val[0] != '\'' ||
437 in->bv_val[in->bv_len-2] != '\'' ||
438 in->bv_val[in->bv_len-1] != 'B' )
440 return LDAP_INVALID_SYNTAX;
443 for( i=in->bv_len-3; i>0; i-- ) {
444 if( in->bv_val[i] != '0' && in->bv_val[i] != '1' ) {
445 return LDAP_INVALID_SYNTAX;
460 if( in->bv_len == 0 ) return LDAP_SUCCESS;
462 ber_dupbv( &dn, in );
463 if( !dn.bv_val ) return LDAP_OTHER;
465 if( dn.bv_val[dn.bv_len-1] == 'B'
466 && dn.bv_val[dn.bv_len-2] == '\'' )
468 /* assume presence of optional UID */
471 for(i=dn.bv_len-3; i>1; i--) {
472 if( dn.bv_val[i] != '0' && dn.bv_val[i] != '1' ) {
476 if( dn.bv_val[i] != '\'' || dn.bv_val[i-1] != '#' ) {
477 ber_memfree( dn.bv_val );
478 return LDAP_INVALID_SYNTAX;
481 /* trim the UID to allow use of dnValidate */
482 dn.bv_val[i-1] = '\0';
486 rc = dnValidate( NULL, &dn );
488 ber_memfree( dn.bv_val );
494 uniqueMemberNormalize(
499 struct berval *normalized )
505 struct berval *normalized )
511 ber_dupbv( &out, val );
512 if( out.bv_len != 0 ) {
513 struct berval uid = { 0, NULL };
515 if( out.bv_val[out.bv_len-1] == 'B'
516 && out.bv_val[out.bv_len-2] == '\'' )
518 /* assume presence of optional UID */
519 uid.bv_val = strrchr( out.bv_val, '#' );
521 if( uid.bv_val == NULL ) {
523 return LDAP_INVALID_SYNTAX;
526 uid.bv_len = out.bv_len - (uid.bv_val - out.bv_val);
527 out.bv_len -= uid.bv_len--;
529 /* temporarily trim the UID */
530 *(uid.bv_val++) = '\0';
533 rc = dnNormalize2( NULL, &out, normalized );
535 if( rc != LDAP_SUCCESS ) {
537 return LDAP_INVALID_SYNTAX;
541 normalized->bv_val = ch_realloc( normalized->bv_val,
542 normalized->bv_len + uid.bv_len + sizeof("#") );
544 /* insert the separator */
545 normalized->bv_val[normalized->bv_len++] = '#';
548 AC_MEMCPY( &normalized->bv_val[normalized->bv_len],
549 uid.bv_val, uid.bv_len );
550 normalized->bv_len += uid.bv_len;
553 normalized->bv_val[normalized->bv_len] = '\0';
563 * Handling boolean syntax and matching is quite rigid.
564 * A more flexible approach would be to allow a variety
565 * of strings to be normalized and prettied into TRUE
573 /* very unforgiving validation, requires no normalization
574 * before simplistic matching
577 if( in->bv_len == 4 ) {
578 if( !memcmp( in->bv_val, "TRUE", 4 ) ) {
581 } else if( in->bv_len == 5 ) {
582 if( !memcmp( in->bv_val, "FALSE", 5 ) ) {
587 return LDAP_INVALID_SYNTAX;
596 struct berval *value,
597 void *assertedValue )
599 /* simplistic matching allowed by rigid validation */
600 struct berval *asserted = (struct berval *) assertedValue;
601 *matchp = value->bv_len != asserted->bv_len;
605 /*-------------------------------------------------------------------
606 LDAP/X.500 string syntax / matching rules have a few oddities. This
607 comment attempts to detail how slapd(8) treats them.
610 StringSyntax X.500 LDAP Matching/Comments
611 DirectoryString CHOICE UTF8 i/e + ignore insignificant spaces
612 PrintableString subset subset i/e + ignore insignificant spaces
613 PrintableString subset subset i/e + ignore insignificant spaces
614 NumericString subset subset ignore all spaces
615 IA5String ASCII ASCII i/e + ignore insignificant spaces
616 TeletexString T.61 T.61 i/e + ignore insignificant spaces
618 TelephoneNumber subset subset i + ignore all spaces and "-"
620 See draft-ietf-ldapbis-strpro for details (once published).
624 In X.500(93), a directory string can be either a PrintableString,
625 a bmpString, or a UniversalString (e.g., UCS (a subset of Unicode)).
626 In later versions, more CHOICEs were added. In all cases the string
629 In LDAPv3, a directory string is a UTF-8 encoded UCS string.
630 A directory string cannot be zero length.
632 For matching, there are both case ignore and exact rules. Both
633 also require that "insignificant" spaces be ignored.
634 spaces before the first non-space are ignored;
635 spaces after the last non-space are ignored;
636 spaces after a space are ignored.
637 Note: by these rules (and as clarified in X.520), a string of only
638 spaces is to be treated as if held one space, not empty (which
639 would be a syntax error).
642 In ASN.1, numeric string is just a string of digits and spaces
643 and could be empty. However, in X.500, all attribute values of
644 numeric string carry a non-empty constraint. For example:
646 internationalISDNNumber ATTRIBUTE ::= {
647 WITH SYNTAX InternationalISDNNumber
648 EQUALITY MATCHING RULE numericStringMatch
649 SUBSTRINGS MATCHING RULE numericStringSubstringsMatch
650 ID id-at-internationalISDNNumber }
651 InternationalISDNNumber ::=
652 NumericString (SIZE(1..ub-international-isdn-number))
654 Unforunately, some assertion values are don't carry the same
655 constraint (but its unclear how such an assertion could ever
656 be true). In LDAP, there is one syntax (numericString) not two
657 (numericString with constraint, numericString without constraint).
658 This should be treated as numericString with non-empty constraint.
659 Note that while someone may have no ISDN number, there are no ISDN
660 numbers which are zero length.
662 In matching, spaces are ignored.
665 In ASN.1, Printable string is just a string of printable characters
666 and can be empty. In X.500, semantics much like NumericString (see
667 serialNumber for a like example) excepting uses insignificant space
668 handling instead of ignore all spaces.
671 Basically same as PrintableString. There are no examples in X.500,
672 but same logic applies. So we require them to be non-empty as
675 -------------------------------------------------------------------*/
684 unsigned char *u = in->bv_val;
686 if( in->bv_len == 0 && syntax == slap_schema.si_syn_directoryString ) {
687 /* directory strings cannot be empty */
688 return LDAP_INVALID_SYNTAX;
691 for( count = in->bv_len; count > 0; count-=len, u+=len ) {
692 /* get the length indicated by the first byte */
693 len = LDAP_UTF8_CHARLEN2( u, len );
695 /* very basic checks */
698 if( (u[5] & 0xC0) != 0x80 ) {
699 return LDAP_INVALID_SYNTAX;
702 if( (u[4] & 0xC0) != 0x80 ) {
703 return LDAP_INVALID_SYNTAX;
706 if( (u[3] & 0xC0) != 0x80 ) {
707 return LDAP_INVALID_SYNTAX;
710 if( (u[2] & 0xC0 )!= 0x80 ) {
711 return LDAP_INVALID_SYNTAX;
714 if( (u[1] & 0xC0) != 0x80 ) {
715 return LDAP_INVALID_SYNTAX;
718 /* CHARLEN already validated it */
721 return LDAP_INVALID_SYNTAX;
724 /* make sure len corresponds with the offset
725 to the next character */
726 if( LDAP_UTF8_OFFSET( u ) != len ) return LDAP_INVALID_SYNTAX;
730 return LDAP_INVALID_SYNTAX;
743 struct berval *normalized )
745 struct berval tmp, nvalue;
749 if( val->bv_val == NULL ) {
750 /* assume we're dealing with a syntax (e.g., UTF8String)
751 * which allows empty strings
753 normalized->bv_len = 0;
754 normalized->bv_val = NULL;
758 flags = SLAP_MR_ASSOCIATED(mr, slap_schema.si_mr_caseExactMatch )
759 ? LDAP_UTF8_NOCASEFOLD : LDAP_UTF8_CASEFOLD;
760 flags |= ( use & SLAP_MR_EQUALITY_APPROX == SLAP_MR_EQUALITY_APPROX )
761 ? LDAP_UTF8_APPROX : 0;
763 val = UTF8bvnormalize( val, &tmp, flags );
768 /* collapse spaces (in place) */
770 nvalue.bv_val = tmp.bv_val;
772 wasspace=1; /* trim leading spaces */
773 for( i=0; i<tmp.bv_len; i++) {
774 if ( ASCII_SPACE( tmp.bv_val[i] )) {
775 if( wasspace++ == 0 ) {
776 /* trim repeated spaces */
777 nvalue.bv_val[nvalue.bv_len++] = tmp.bv_val[i];
781 nvalue.bv_val[nvalue.bv_len++] = tmp.bv_val[i];
785 if( nvalue.bv_len ) {
787 /* last character was a space, trim it */
790 nvalue.bv_val[nvalue.bv_len] = '\0';
793 /* string of all spaces is treated as one space */
794 nvalue.bv_val[0] = ' ';
795 nvalue.bv_val[1] = '\0';
799 *normalized = nvalue;
805 xUTF8StringNormalize(
808 struct berval *normalized )
813 /* validator should have refused an empty string */
814 assert( val->bv_len );
818 /* Ignore initial whitespace */
819 /* All space is ASCII. All ASCII is 1 byte */
820 for ( ; p < val->bv_val + val->bv_len && ASCII_SPACE( p[ 0 ] ); p++ );
822 normalized->bv_len = val->bv_len - (p - val->bv_val);
824 if( !normalized->bv_len ) {
825 ber_mem2bv( " ", 1, 1, normalized );
829 ber_mem2bv( p, normalized->bv_len, 1, normalized );
830 e = normalized->bv_val + normalized->bv_len;
832 assert( normalized->bv_val );
834 p = q = normalized->bv_val;
839 if ( ASCII_SPACE( *p ) ) {
844 /* Ignore the extra whitespace */
845 while ( ASCII_SPACE( *p ) ) {
849 len = LDAP_UTF8_COPY(q,p);
855 assert( normalized->bv_val <= p );
856 assert( q+len <= p );
858 /* cannot start with a space */
859 assert( !ASCII_SPACE( normalized->bv_val[0] ) );
862 * If the string ended in space, backup the pointer one
863 * position. One is enough because the above loop collapsed
864 * all whitespace to a single space.
872 /* cannot end with a space */
873 assert( !ASCII_SPACE( *q ) );
880 normalized->bv_len = q - normalized->bv_val;
885 /* Returns Unicode canonically normalized copy of a substring assertion
886 * Skipping attribute description */
887 static SubstringsAssertion *
888 UTF8SubstringsAssertionNormalize(
889 SubstringsAssertion *sa,
892 SubstringsAssertion *nsa;
895 nsa = (SubstringsAssertion *)SLAP_CALLOC( 1, sizeof(SubstringsAssertion) );
900 if( sa->sa_initial.bv_val != NULL ) {
901 UTF8bvnormalize( &sa->sa_initial, &nsa->sa_initial, casefold );
902 if( nsa->sa_initial.bv_val == NULL ) {
907 if( sa->sa_any != NULL ) {
908 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
911 nsa->sa_any = (struct berval *)
912 SLAP_MALLOC( (i + 1) * sizeof(struct berval) );
913 if( nsa->sa_any == NULL ) {
917 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
918 UTF8bvnormalize( &sa->sa_any[i], &nsa->sa_any[i],
920 if( nsa->sa_any[i].bv_val == NULL ) {
924 nsa->sa_any[i].bv_val = NULL;
927 if( sa->sa_final.bv_val != NULL ) {
928 UTF8bvnormalize( &sa->sa_final, &nsa->sa_final, casefold );
929 if( nsa->sa_final.bv_val == NULL ) {
937 if ( nsa->sa_final.bv_val ) free( nsa->sa_final.bv_val );
938 if ( nsa->sa_any ) ber_bvarray_free( nsa->sa_any );
939 if ( nsa->sa_initial.bv_val ) free( nsa->sa_initial.bv_val );
944 #ifndef SLAPD_APPROX_OLDSINGLESTRING
946 #if defined(SLAPD_APPROX_INITIALS)
947 #define SLAPD_APPROX_DELIMITER "._ "
948 #define SLAPD_APPROX_WORDLEN 2
950 #define SLAPD_APPROX_DELIMITER " "
951 #define SLAPD_APPROX_WORDLEN 1
960 struct berval *value,
961 void *assertedValue )
963 struct berval *nval, *assertv;
964 char *val, **values, **words, *c;
965 int i, count, len, nextchunk=0, nextavail=0;
967 /* Yes, this is necessary */
968 nval = UTF8bvnormalize( value, NULL, LDAP_UTF8_APPROX );
974 /* Yes, this is necessary */
975 assertv = UTF8bvnormalize( ((struct berval *)assertedValue),
976 NULL, LDAP_UTF8_APPROX );
977 if( assertv == NULL ) {
983 /* Isolate how many words there are */
984 for ( c = nval->bv_val, count = 1; *c; c++ ) {
985 c = strpbrk( c, SLAPD_APPROX_DELIMITER );
986 if ( c == NULL ) break;
991 /* Get a phonetic copy of each word */
992 words = (char **)ch_malloc( count * sizeof(char *) );
993 values = (char **)ch_malloc( count * sizeof(char *) );
994 for ( c = nval->bv_val, i = 0; i < count; i++, c += strlen(c) + 1 ) {
996 values[i] = phonetic(c);
999 /* Work through the asserted value's words, to see if at least some
1000 of the words are there, in the same order. */
1002 while ( (ber_len_t) nextchunk < assertv->bv_len ) {
1003 len = strcspn( assertv->bv_val + nextchunk, SLAPD_APPROX_DELIMITER);
1008 #if defined(SLAPD_APPROX_INITIALS)
1009 else if( len == 1 ) {
1010 /* Single letter words need to at least match one word's initial */
1011 for( i=nextavail; i<count; i++ )
1012 if( !strncasecmp( assertv->bv_val + nextchunk, words[i], 1 )) {
1019 /* Isolate the next word in the asserted value and phonetic it */
1020 assertv->bv_val[nextchunk+len] = '\0';
1021 val = phonetic( assertv->bv_val + nextchunk );
1023 /* See if this phonetic chunk is in the remaining words of *value */
1024 for( i=nextavail; i<count; i++ ){
1025 if( !strcmp( val, values[i] ) ){
1033 /* This chunk in the asserted value was NOT within the *value. */
1039 /* Go on to the next word in the asserted value */
1043 /* If some of the words were seen, call it a match */
1044 if( nextavail > 0 ) {
1051 /* Cleanup allocs */
1052 ber_bvfree( assertv );
1053 for( i=0; i<count; i++ ) {
1054 ch_free( values[i] );
1060 return LDAP_SUCCESS;
1069 struct berval *prefix,
1074 int i,j, len, wordcount, keycount=0;
1075 struct berval *newkeys;
1076 BerVarray keys=NULL;
1078 for( j=0; values[j].bv_val != NULL; j++ ) {
1079 struct berval val = { 0, NULL };
1080 /* Yes, this is necessary */
1081 UTF8bvnormalize( &values[j], &val, LDAP_UTF8_APPROX );
1082 assert( val.bv_val != NULL );
1084 /* Isolate how many words there are. There will be a key for each */
1085 for( wordcount = 0, c = val.bv_val; *c; c++) {
1086 len = strcspn(c, SLAPD_APPROX_DELIMITER);
1087 if( len >= SLAPD_APPROX_WORDLEN ) wordcount++;
1089 if (*c == '\0') break;
1093 /* Allocate/increase storage to account for new keys */
1094 newkeys = (struct berval *)ch_malloc( (keycount + wordcount + 1)
1095 * sizeof(struct berval) );
1096 AC_MEMCPY( newkeys, keys, keycount * sizeof(struct berval) );
1097 if( keys ) ch_free( keys );
1100 /* Get a phonetic copy of each word */
1101 for( c = val.bv_val, i = 0; i < wordcount; c += len + 1 ) {
1103 if( len < SLAPD_APPROX_WORDLEN ) continue;
1104 ber_str2bv( phonetic( c ), 0, 0, &keys[keycount] );
1109 ber_memfree( val.bv_val );
1111 keys[keycount].bv_val = NULL;
1114 return LDAP_SUCCESS;
1123 struct berval *prefix,
1124 void * assertedValue,
1132 /* Yes, this is necessary */
1133 val = UTF8bvnormalize( ((struct berval *)assertedValue),
1134 NULL, LDAP_UTF8_APPROX );
1135 if( val == NULL || val->bv_val == NULL ) {
1136 keys = (struct berval *)ch_malloc( sizeof(struct berval) );
1137 keys[0].bv_val = NULL;
1140 return LDAP_SUCCESS;
1143 /* Isolate how many words there are. There will be a key for each */
1144 for( count = 0,c = val->bv_val; *c; c++) {
1145 len = strcspn(c, SLAPD_APPROX_DELIMITER);
1146 if( len >= SLAPD_APPROX_WORDLEN ) count++;
1148 if (*c == '\0') break;
1152 /* Allocate storage for new keys */
1153 keys = (struct berval *)ch_malloc( (count + 1) * sizeof(struct berval) );
1155 /* Get a phonetic copy of each word */
1156 for( c = val->bv_val, i = 0; i < count; c += len + 1 ) {
1158 if( len < SLAPD_APPROX_WORDLEN ) continue;
1159 ber_str2bv( phonetic( c ), 0, 0, &keys[i] );
1165 keys[count].bv_val = NULL;
1168 return LDAP_SUCCESS;
1173 /* No other form of Approximate Matching is defined */
1181 struct berval *value,
1182 void *assertedValue )
1184 char *vapprox, *avapprox;
1187 /* Yes, this is necessary */
1188 s = UTF8normalize( value, UTF8_NOCASEFOLD );
1191 return LDAP_SUCCESS;
1194 /* Yes, this is necessary */
1195 t = UTF8normalize( ((struct berval *)assertedValue),
1200 return LDAP_SUCCESS;
1203 vapprox = phonetic( strip8bitChars( s ) );
1204 avapprox = phonetic( strip8bitChars( t ) );
1209 *matchp = strcmp( vapprox, avapprox );
1212 ch_free( avapprox );
1214 return LDAP_SUCCESS;
1223 struct berval *prefix,
1231 for( i=0; values[i].bv_val != NULL; i++ ) {
1232 /* empty - just count them */
1235 /* we should have at least one value at this point */
1238 keys = (struct berval *)ch_malloc( sizeof( struct berval ) * (i+1) );
1240 /* Copy each value and run it through phonetic() */
1241 for( i=0; values[i].bv_val != NULL; i++ ) {
1242 /* Yes, this is necessary */
1243 s = UTF8normalize( &values[i], UTF8_NOCASEFOLD );
1245 /* strip 8-bit chars and run through phonetic() */
1246 ber_str2bv( phonetic( strip8bitChars( s ) ), 0, 0, &keys[i] );
1249 keys[i].bv_val = NULL;
1252 return LDAP_SUCCESS;
1262 struct berval *prefix,
1263 void * assertedValue,
1269 keys = (struct berval *)ch_malloc( sizeof( struct berval * ) * 2 );
1271 /* Yes, this is necessary */
1272 s = UTF8normalize( ((struct berval *)assertedValue),
1277 /* strip 8-bit chars and run through phonetic() */
1278 keys[0] = ber_bvstr( phonetic( strip8bitChars( s ) ) );
1284 return LDAP_SUCCESS;
1295 struct berval *value,
1296 void *assertedValue )
1298 *matchp = UTF8bvnormcmp( value,
1299 (struct berval *) assertedValue,
1300 LDAP_UTF8_NOCASEFOLD );
1301 return LDAP_SUCCESS;
1305 caseExactIgnoreSubstringsMatch(
1310 struct berval *value,
1311 void *assertedValue )
1314 SubstringsAssertion *sub = NULL;
1315 struct berval left = { 0, NULL };
1321 casefold = ( mr != slap_schema.si_mr_caseExactSubstringsMatch )
1322 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1324 if ( UTF8bvnormalize( value, &left, casefold ) == NULL ) {
1330 sub = UTF8SubstringsAssertionNormalize( assertedValue, casefold );
1336 /* Add up asserted input length */
1337 if( sub->sa_initial.bv_val ) {
1338 inlen += sub->sa_initial.bv_len;
1341 for(i=0; sub->sa_any[i].bv_val != NULL; i++) {
1342 inlen += sub->sa_any[i].bv_len;
1345 if( sub->sa_final.bv_val ) {
1346 inlen += sub->sa_final.bv_len;
1349 if( sub->sa_initial.bv_val ) {
1350 if( inlen > left.bv_len ) {
1355 match = memcmp( sub->sa_initial.bv_val, left.bv_val,
1356 sub->sa_initial.bv_len );
1362 left.bv_val += sub->sa_initial.bv_len;
1363 left.bv_len -= sub->sa_initial.bv_len;
1364 inlen -= sub->sa_initial.bv_len;
1367 if( sub->sa_final.bv_val ) {
1368 if( inlen > left.bv_len ) {
1373 match = memcmp( sub->sa_final.bv_val,
1374 &left.bv_val[left.bv_len - sub->sa_final.bv_len],
1375 sub->sa_final.bv_len );
1381 left.bv_len -= sub->sa_final.bv_len;
1382 inlen -= sub->sa_final.bv_len;
1386 for(i=0; sub->sa_any[i].bv_val; i++) {
1391 if( inlen > left.bv_len ) {
1392 /* not enough length */
1397 if( sub->sa_any[i].bv_len == 0 ) {
1401 p = ber_bvchr( &left, *sub->sa_any[i].bv_val );
1407 idx = p - left.bv_val;
1409 if( idx >= left.bv_len ) {
1410 /* this shouldn't happen */
1412 if ( sub->sa_final.bv_val )
1413 ch_free( sub->sa_final.bv_val );
1415 ber_bvarray_free( sub->sa_any );
1416 if ( sub->sa_initial.bv_val )
1417 ch_free( sub->sa_initial.bv_val );
1425 if( sub->sa_any[i].bv_len > left.bv_len ) {
1426 /* not enough left */
1431 match = memcmp( left.bv_val,
1432 sub->sa_any[i].bv_val,
1433 sub->sa_any[i].bv_len );
1441 left.bv_val += sub->sa_any[i].bv_len;
1442 left.bv_len -= sub->sa_any[i].bv_len;
1443 inlen -= sub->sa_any[i].bv_len;
1450 if ( sub->sa_final.bv_val ) free( sub->sa_final.bv_val );
1451 if ( sub->sa_any ) ber_bvarray_free( sub->sa_any );
1452 if ( sub->sa_initial.bv_val ) free( sub->sa_initial.bv_val );
1456 return LDAP_SUCCESS;
1459 /* Index generation function */
1460 static int caseExactIgnoreIndexer(
1465 struct berval *prefix,
1470 unsigned casefold,wasspace;
1473 HASH_CONTEXT HASHcontext;
1474 unsigned char HASHdigest[HASH_BYTES];
1475 struct berval digest;
1476 digest.bv_val = HASHdigest;
1477 digest.bv_len = sizeof(HASHdigest);
1479 for( i=0; values[i].bv_val != NULL; i++ ) {
1480 /* empty - just count them */
1483 /* we should have at least one value at this point */
1486 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
1488 slen = syntax->ssyn_oidlen;
1489 mlen = mr->smr_oidlen;
1491 casefold = ( mr != slap_schema.si_mr_caseExactMatch )
1492 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1494 for( i=0; values[i].bv_val != NULL; i++ ) {
1495 struct berval value, nvalue;
1496 UTF8bvnormalize( &values[i], &value, casefold );
1498 /* collapse spaces (in place) */
1500 nvalue.bv_val = value.bv_val;
1503 for( j=0; j<value.bv_len; j++) {
1504 if ( ASCII_SPACE( value.bv_val[j] )) {
1505 if( wasspace++ == 0 ) {
1506 nvalue.bv_val[nvalue.bv_len++] = value.bv_val[j];
1510 nvalue.bv_val[nvalue.bv_len++] = value.bv_val[j];
1514 if( nvalue.bv_len == 0 ) {
1515 nvalue.bv_val = " ";
1516 nvalue.bv_len = sizeof(" ")-1;
1518 if( wasspace ) --nvalue.bv_len;
1519 nvalue.bv_val[nvalue.bv_len] = '\0';
1522 HASH_Init( &HASHcontext );
1523 if( prefix != NULL && prefix->bv_len > 0 ) {
1524 HASH_Update( &HASHcontext,
1525 prefix->bv_val, prefix->bv_len );
1527 HASH_Update( &HASHcontext,
1528 syntax->ssyn_oid, slen );
1529 HASH_Update( &HASHcontext,
1530 mr->smr_oid, mlen );
1531 HASH_Update( &HASHcontext,
1532 nvalue.bv_val, nvalue.bv_len );
1533 HASH_Final( HASHdigest, &HASHcontext );
1535 free( value.bv_val );
1536 ber_dupbv( &keys[i], &digest );
1539 keys[i].bv_val = NULL;
1541 return LDAP_SUCCESS;
1544 /* Index generation function */
1545 static int caseExactIgnoreFilter(
1550 struct berval *prefix,
1551 void * assertedValue,
1557 HASH_CONTEXT HASHcontext;
1558 unsigned char HASHdigest[HASH_BYTES];
1559 struct berval value = { 0, NULL };
1560 struct berval digest;
1562 digest.bv_val = HASHdigest;
1563 digest.bv_len = sizeof(HASHdigest);
1565 slen = syntax->ssyn_oidlen;
1566 mlen = mr->smr_oidlen;
1568 casefold = ( mr != slap_schema.si_mr_caseExactMatch )
1569 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1571 UTF8bvnormalize( (struct berval *) assertedValue, &value, casefold );
1572 /* This usually happens if filter contains bad UTF8 */
1573 if( value.bv_val == NULL ) {
1574 keys = ch_malloc( sizeof( struct berval ) );
1575 keys[0].bv_val = NULL;
1576 return LDAP_SUCCESS;
1579 keys = ch_malloc( sizeof( struct berval ) * 2 );
1581 HASH_Init( &HASHcontext );
1582 if( prefix != NULL && prefix->bv_len > 0 ) {
1583 HASH_Update( &HASHcontext,
1584 prefix->bv_val, prefix->bv_len );
1586 HASH_Update( &HASHcontext,
1587 syntax->ssyn_oid, slen );
1588 HASH_Update( &HASHcontext,
1589 mr->smr_oid, mlen );
1590 HASH_Update( &HASHcontext,
1591 value.bv_val, value.bv_len );
1592 HASH_Final( HASHdigest, &HASHcontext );
1594 ber_dupbv( keys, &digest );
1595 keys[1].bv_val = NULL;
1597 free( value.bv_val );
1600 return LDAP_SUCCESS;
1604 /* Substrings Index generation function */
1607 octetStringSubstringsIndexer
1609 caseExactIgnoreSubstringsIndexer
1615 struct berval *prefix,
1619 ber_len_t i, j, nkeys;
1622 #ifndef SLAP_NVALUES
1623 BerVarray tvalues, nvalues;
1624 unsigned casefold, wasspace;
1627 HASH_CONTEXT HASHcontext;
1628 unsigned char HASHdigest[HASH_BYTES];
1629 struct berval digest;
1630 digest.bv_val = HASHdigest;
1631 digest.bv_len = sizeof(HASHdigest);
1633 #ifndef SLAP_NVALUES
1634 for( i=0; values[i].bv_val != NULL; i++ ) {
1635 /* empty - just count them */
1638 /* we should have at least one value at this point */
1641 casefold = ( mr != slap_schema.si_mr_caseExactSubstringsMatch )
1642 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1644 tvalues = ch_malloc( sizeof( struct berval ) * (i+1) );
1645 nvalues = ch_malloc( sizeof( struct berval ) * (i+1) );
1647 for( i=0; values[i].bv_val != NULL; i++ ) {
1648 UTF8bvnormalize( &values[i], &tvalues[i], casefold );
1650 /* collapse spaces (in place) */
1651 nvalues[i].bv_len = 0;
1652 nvalues[i].bv_val = tvalues[i].bv_val;
1655 for( j=0; j<tvalues[i].bv_len; j++) {
1656 if ( ASCII_SPACE( tvalues[i].bv_val[j] )) {
1657 if( wasspace++ == 0 ) {
1658 nvalues[i].bv_val[nvalues[i].bv_len++] =
1659 tvalues[i].bv_val[j];
1663 nvalues[i].bv_val[nvalues[i].bv_len++] = tvalues[i].bv_val[j];
1667 if( nvalues[i].bv_len == 0 ) {
1668 nvalues[i].bv_val = " ";
1669 nvalues[i].bv_len = sizeof(" ")-1;
1671 if( wasspace ) --nvalues[i].bv_len;
1672 nvalues[i].bv_val[nvalues[i].bv_len] = '\0';
1676 tvalues[i].bv_val = NULL;
1677 nvalues[i].bv_val = NULL;
1683 for( i=0; values[i].bv_val != NULL; i++ ) {
1684 /* count number of indices to generate */
1685 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
1689 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
1690 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1691 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
1692 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
1694 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
1698 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
1699 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1700 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
1704 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
1705 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1706 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
1707 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
1709 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
1715 /* no keys to generate */
1717 #ifndef SLAP_NVALUES
1718 ber_bvarray_free( tvalues );
1721 return LDAP_SUCCESS;
1724 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
1726 slen = syntax->ssyn_oidlen;
1727 mlen = mr->smr_oidlen;
1730 for( i=0; values[i].bv_val != NULL; i++ ) {
1733 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
1735 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
1736 ( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
1738 char pre = SLAP_INDEX_SUBSTR_PREFIX;
1739 max = values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
1741 for( j=0; j<max; j++ ) {
1742 HASH_Init( &HASHcontext );
1743 if( prefix != NULL && prefix->bv_len > 0 ) {
1744 HASH_Update( &HASHcontext,
1745 prefix->bv_val, prefix->bv_len );
1748 HASH_Update( &HASHcontext,
1749 &pre, sizeof( pre ) );
1750 HASH_Update( &HASHcontext,
1751 syntax->ssyn_oid, slen );
1752 HASH_Update( &HASHcontext,
1753 mr->smr_oid, mlen );
1754 HASH_Update( &HASHcontext,
1755 &values[i].bv_val[j],
1756 SLAP_INDEX_SUBSTR_MAXLEN );
1757 HASH_Final( HASHdigest, &HASHcontext );
1759 ber_dupbv( &keys[nkeys++], &digest );
1763 max = SLAP_INDEX_SUBSTR_MAXLEN < values[i].bv_len
1764 ? SLAP_INDEX_SUBSTR_MAXLEN : values[i].bv_len;
1766 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
1769 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
1770 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
1771 HASH_Init( &HASHcontext );
1772 if( prefix != NULL && prefix->bv_len > 0 ) {
1773 HASH_Update( &HASHcontext,
1774 prefix->bv_val, prefix->bv_len );
1776 HASH_Update( &HASHcontext,
1777 &pre, sizeof( pre ) );
1778 HASH_Update( &HASHcontext,
1779 syntax->ssyn_oid, slen );
1780 HASH_Update( &HASHcontext,
1781 mr->smr_oid, mlen );
1782 HASH_Update( &HASHcontext,
1783 values[i].bv_val, j );
1784 HASH_Final( HASHdigest, &HASHcontext );
1786 ber_dupbv( &keys[nkeys++], &digest );
1789 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
1790 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
1791 HASH_Init( &HASHcontext );
1792 if( prefix != NULL && prefix->bv_len > 0 ) {
1793 HASH_Update( &HASHcontext,
1794 prefix->bv_val, prefix->bv_len );
1796 HASH_Update( &HASHcontext,
1797 &pre, sizeof( pre ) );
1798 HASH_Update( &HASHcontext,
1799 syntax->ssyn_oid, slen );
1800 HASH_Update( &HASHcontext,
1801 mr->smr_oid, mlen );
1802 HASH_Update( &HASHcontext,
1803 &values[i].bv_val[values[i].bv_len-j], j );
1804 HASH_Final( HASHdigest, &HASHcontext );
1806 ber_dupbv( &keys[nkeys++], &digest );
1814 keys[nkeys].bv_val = NULL;
1821 #ifndef SLAP_NVALUES
1822 ber_bvarray_free( tvalues );
1826 return LDAP_SUCCESS;
1831 octetStringSubstringsFilter
1833 caseExactIgnoreSubstringsFilter
1839 struct berval *prefix,
1840 void * assertedValue,
1843 SubstringsAssertion *sa;
1846 ber_len_t nkeys = 0;
1847 size_t slen, mlen, klen;
1849 HASH_CONTEXT HASHcontext;
1850 unsigned char HASHdigest[HASH_BYTES];
1851 struct berval *value;
1852 struct berval digest;
1854 #ifndef SLAP_NVALUES
1855 casefold = ( mr != slap_schema.si_mr_caseExactSubstringsMatch )
1856 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1858 sa = UTF8SubstringsAssertionNormalize( assertedValue, casefold );
1861 return LDAP_SUCCESS;
1864 sa = (SubstringsAssertion *) assertedValue;
1867 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
1868 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1873 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
1875 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
1876 if( sa->sa_any[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1877 /* don't bother accounting for stepping */
1878 nkeys += sa->sa_any[i].bv_len -
1879 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
1884 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
1885 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1891 #ifndef SLAP_NVALUES
1892 if ( sa->sa_final.bv_val ) free( sa->sa_final.bv_val );
1893 if ( sa->sa_any ) ber_bvarray_free( sa->sa_any );
1894 if ( sa->sa_initial.bv_val ) free( sa->sa_initial.bv_val );
1898 return LDAP_SUCCESS;
1901 digest.bv_val = HASHdigest;
1902 digest.bv_len = sizeof(HASHdigest);
1904 slen = syntax->ssyn_oidlen;
1905 mlen = mr->smr_oidlen;
1907 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
1910 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
1911 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1913 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
1914 value = &sa->sa_initial;
1916 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
1917 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
1919 HASH_Init( &HASHcontext );
1920 if( prefix != NULL && prefix->bv_len > 0 ) {
1921 HASH_Update( &HASHcontext,
1922 prefix->bv_val, prefix->bv_len );
1924 HASH_Update( &HASHcontext,
1925 &pre, sizeof( pre ) );
1926 HASH_Update( &HASHcontext,
1927 syntax->ssyn_oid, slen );
1928 HASH_Update( &HASHcontext,
1929 mr->smr_oid, mlen );
1930 HASH_Update( &HASHcontext,
1931 value->bv_val, klen );
1932 HASH_Final( HASHdigest, &HASHcontext );
1934 ber_dupbv( &keys[nkeys++], &digest );
1937 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
1939 pre = SLAP_INDEX_SUBSTR_PREFIX;
1940 klen = SLAP_INDEX_SUBSTR_MAXLEN;
1942 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
1943 if( sa->sa_any[i].bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
1947 value = &sa->sa_any[i];
1950 j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
1951 j += SLAP_INDEX_SUBSTR_STEP )
1953 HASH_Init( &HASHcontext );
1954 if( prefix != NULL && prefix->bv_len > 0 ) {
1955 HASH_Update( &HASHcontext,
1956 prefix->bv_val, prefix->bv_len );
1958 HASH_Update( &HASHcontext,
1959 &pre, sizeof( pre ) );
1960 HASH_Update( &HASHcontext,
1961 syntax->ssyn_oid, slen );
1962 HASH_Update( &HASHcontext,
1963 mr->smr_oid, mlen );
1964 HASH_Update( &HASHcontext,
1965 &value->bv_val[j], klen );
1966 HASH_Final( HASHdigest, &HASHcontext );
1968 ber_dupbv( &keys[nkeys++], &digest );
1974 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
1975 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1977 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
1978 value = &sa->sa_final;
1980 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
1981 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
1983 HASH_Init( &HASHcontext );
1984 if( prefix != NULL && prefix->bv_len > 0 ) {
1985 HASH_Update( &HASHcontext,
1986 prefix->bv_val, prefix->bv_len );
1988 HASH_Update( &HASHcontext,
1989 &pre, sizeof( pre ) );
1990 HASH_Update( &HASHcontext,
1991 syntax->ssyn_oid, slen );
1992 HASH_Update( &HASHcontext,
1993 mr->smr_oid, mlen );
1994 HASH_Update( &HASHcontext,
1995 &value->bv_val[value->bv_len-klen], klen );
1996 HASH_Final( HASHdigest, &HASHcontext );
1998 ber_dupbv( &keys[nkeys++], &digest );
2002 keys[nkeys].bv_val = NULL;
2009 #ifndef SLAP_NVALUES
2010 if ( sa->sa_final.bv_val ) free( sa->sa_final.bv_val );
2011 if ( sa->sa_any ) ber_bvarray_free( sa->sa_any );
2012 if ( sa->sa_initial.bv_val ) free( sa->sa_initial.bv_val );
2016 return LDAP_SUCCESS;
2018 #ifndef SLAP_NVALUES
2026 struct berval *value,
2027 void *assertedValue )
2029 *matchp = UTF8bvnormcmp( value,
2030 (struct berval *) assertedValue,
2031 LDAP_UTF8_CASEFOLD );
2032 return LDAP_SUCCESS;
2036 /* Remove all spaces and '-' characters */
2039 telephoneNumberNormalize(
2044 struct berval *normalized )
2046 xtelephoneNumberNormalize(
2049 struct berval *normalized )
2054 /* validator should have refused an empty string */
2055 assert( val->bv_len );
2057 q = normalized->bv_val = ch_malloc( val->bv_len + 1 );
2059 for( p = val->bv_val; *p; p++ ) {
2060 if ( ! ( ASCII_SPACE( *p ) || *p == '-' )) {
2066 normalized->bv_len = q - normalized->bv_val;
2068 if( normalized->bv_len == 0 ) {
2069 free( normalized->bv_val );
2070 return LDAP_INVALID_SYNTAX;
2073 return LDAP_SUCCESS;
2079 struct berval *val )
2083 if( val->bv_len == 0 ) {
2084 /* disallow empty strings */
2085 return LDAP_INVALID_SYNTAX;
2088 if( OID_LEADCHAR(val->bv_val[0]) ) {
2090 for(i=1; i < val->bv_len; i++) {
2091 if( OID_SEPARATOR( val->bv_val[i] ) ) {
2092 if( dot++ ) return 1;
2093 } else if ( OID_CHAR( val->bv_val[i] ) ) {
2096 return LDAP_INVALID_SYNTAX;
2100 return !dot ? LDAP_SUCCESS : LDAP_INVALID_SYNTAX;
2102 } else if( DESC_LEADCHAR(val->bv_val[0]) ) {
2103 for(i=1; i < val->bv_len; i++) {
2104 if( !DESC_CHAR(val->bv_val[i] ) ) {
2105 return LDAP_INVALID_SYNTAX;
2109 return LDAP_SUCCESS;
2112 return LDAP_INVALID_SYNTAX;
2115 #ifndef SLAP_NVALUES
2123 struct berval *value,
2124 void *assertedValue )
2127 int vsign = 1, avsign = 1; /* default sign = '+' */
2128 struct berval *asserted;
2129 ber_len_t vlen, avlen;
2132 /* Skip leading space/sign/zeroes, and get the sign of the *value number */
2134 vlen = value->bv_len;
2135 if( mr == slap_schema.si_mr_integerFirstComponentMatch ) {
2136 char *tmp = memchr( v, '$', vlen );
2139 while( vlen && ASCII_SPACE( v[vlen-1] ))
2142 for( ; vlen && ( *v < '1' || '9' < *v ); v++, vlen-- ) /* ANSI 2.2.1 */
2148 /* Do the same with the *assertedValue number */
2149 asserted = (struct berval *) assertedValue;
2150 av = asserted->bv_val;
2151 avlen = asserted->bv_len;
2152 for( ; avlen && ( *av < '1' || '9' < *av ); av++, avlen-- )
2158 match = vsign - avsign;
2160 match = (vlen != avlen
2161 ? ( vlen < avlen ? -1 : 1 )
2162 : memcmp( v, av, vlen ));
2168 return LDAP_SUCCESS;
2175 struct berval *val )
2179 if( !val->bv_len ) return LDAP_INVALID_SYNTAX;
2181 if(( val->bv_val[0] == '+' ) || ( val->bv_val[0] == '-' )) {
2182 if( val->bv_len < 2 ) return LDAP_INVALID_SYNTAX;
2183 } else if( !ASCII_DIGIT(val->bv_val[0]) ) {
2184 return LDAP_INVALID_SYNTAX;
2187 for( i=1; i < val->bv_len; i++ ) {
2188 if( !ASCII_DIGIT(val->bv_val[i]) ) return LDAP_INVALID_SYNTAX;
2191 return LDAP_SUCCESS;
2194 #ifndef SLAP_NVALUES
2199 struct berval *normalized )
2209 /* Ignore leading spaces */
2210 while ( len && ( *p == ' ' )) {
2217 negative = ( *p == '-' );
2218 if(( *p == '-' ) || ( *p == '+' )) {
2224 /* Ignore leading zeros */
2225 while ( len && ( *p == '0' )) {
2230 /* If there are no non-zero digits left, the number is zero, otherwise
2231 allocate space for the number and copy it into the buffer */
2233 normalized->bv_val = ch_strdup("0");
2234 normalized->bv_len = 1;
2237 normalized->bv_len = len+negative;
2238 normalized->bv_val = ch_malloc( normalized->bv_len + 1 );
2240 normalized->bv_val[0] = '-';
2242 AC_MEMCPY( normalized->bv_val + negative, p, len );
2243 normalized->bv_val[len+negative] = '\0';
2246 return LDAP_SUCCESS;
2249 /* Index generation function */
2250 static int integerIndexer(
2255 struct berval *prefix,
2262 HASH_CONTEXT HASHcontext;
2263 unsigned char HASHdigest[HASH_BYTES];
2264 struct berval digest;
2265 digest.bv_val = HASHdigest;
2266 digest.bv_len = sizeof(HASHdigest);
2268 for( i=0; values[i].bv_val != NULL; i++ ) {
2269 /* empty - just count them */
2272 /* we should have at least one value at this point */
2275 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
2277 slen = syntax->ssyn_oidlen;
2278 mlen = mr->smr_oidlen;
2280 for( i=0; values[i].bv_val != NULL; i++ ) {
2282 xintegerNormalize( syntax, &values[i], &norm );
2284 HASH_Init( &HASHcontext );
2285 if( prefix != NULL && prefix->bv_len > 0 ) {
2286 HASH_Update( &HASHcontext,
2287 prefix->bv_val, prefix->bv_len );
2289 HASH_Update( &HASHcontext,
2290 syntax->ssyn_oid, slen );
2291 HASH_Update( &HASHcontext,
2292 mr->smr_oid, mlen );
2293 HASH_Update( &HASHcontext,
2294 norm.bv_val, norm.bv_len );
2295 HASH_Final( HASHdigest, &HASHcontext );
2297 ber_dupbv( &keys[i], &digest );
2298 ch_free( norm.bv_val );
2301 keys[i].bv_val = NULL;
2303 return LDAP_SUCCESS;
2306 /* Index generation function */
2307 static int integerFilter(
2312 struct berval *prefix,
2313 void * assertedValue,
2318 HASH_CONTEXT HASHcontext;
2319 unsigned char HASHdigest[HASH_BYTES];
2321 struct berval digest;
2322 digest.bv_val = HASHdigest;
2323 digest.bv_len = sizeof(HASHdigest);
2325 slen = syntax->ssyn_oidlen;
2326 mlen = mr->smr_oidlen;
2328 xintegerNormalize( syntax, assertedValue, &norm );
2330 keys = ch_malloc( sizeof( struct berval ) * 2 );
2332 HASH_Init( &HASHcontext );
2333 if( prefix != NULL && prefix->bv_len > 0 ) {
2334 HASH_Update( &HASHcontext,
2335 prefix->bv_val, prefix->bv_len );
2337 HASH_Update( &HASHcontext,
2338 syntax->ssyn_oid, slen );
2339 HASH_Update( &HASHcontext,
2340 mr->smr_oid, mlen );
2341 HASH_Update( &HASHcontext,
2342 norm.bv_val, norm.bv_len );
2343 HASH_Final( HASHdigest, &HASHcontext );
2345 ber_dupbv( &keys[0], &digest );
2346 keys[1].bv_val = NULL;
2347 ch_free( norm.bv_val );
2350 return LDAP_SUCCESS;
2356 countryStringValidate(
2358 struct berval *val )
2360 if( val->bv_len != 2 ) return LDAP_INVALID_SYNTAX;
2362 if( !SLAP_PRINTABLE(val->bv_val[0]) ) {
2363 return LDAP_INVALID_SYNTAX;
2365 if( !SLAP_PRINTABLE(val->bv_val[1]) ) {
2366 return LDAP_INVALID_SYNTAX;
2369 return LDAP_SUCCESS;
2373 printableStringValidate(
2375 struct berval *val )
2379 if( val->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
2381 for(i=0; i < val->bv_len; i++) {
2382 if( !SLAP_PRINTABLE(val->bv_val[i]) ) {
2383 return LDAP_INVALID_SYNTAX;
2387 return LDAP_SUCCESS;
2391 printablesStringValidate(
2393 struct berval *val )
2397 if( val->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
2399 for(i=0,len=0; i < val->bv_len; i++) {
2400 int c = val->bv_val[i];
2404 return LDAP_INVALID_SYNTAX;
2408 } else if ( SLAP_PRINTABLE(c) ) {
2411 return LDAP_INVALID_SYNTAX;
2416 return LDAP_INVALID_SYNTAX;
2419 return LDAP_SUCCESS;
2425 struct berval *val )
2429 if( val->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
2431 for(i=0; i < val->bv_len; i++) {
2432 if( !LDAP_ASCII(val->bv_val[i]) ) {
2433 return LDAP_INVALID_SYNTAX;
2437 return LDAP_SUCCESS;
2447 struct berval *normalized )
2450 xIA5StringNormalize(
2453 struct berval *normalized )
2458 int casefold = !SLAP_MR_ASSOCIATED(mr, slap_schema.si_mr_caseExactIA5Match);
2461 assert( val->bv_len );
2465 /* Ignore initial whitespace */
2466 while ( ASCII_SPACE( *p ) ) {
2470 normalized->bv_val = ch_strdup( p );
2471 p = q = normalized->bv_val;
2474 if ( ASCII_SPACE( *p ) ) {
2477 /* Ignore the extra whitespace */
2478 while ( ASCII_SPACE( *p ) ) {
2483 } else if ( casefold ) {
2484 /* Most IA5 rules require casefolding */
2485 *q++ = TOLOWER(*p++);
2493 assert( normalized->bv_val <= p );
2497 * If the string ended in space, backup the pointer one
2498 * position. One is enough because the above loop collapsed
2499 * all whitespace to a single space.
2502 if ( ASCII_SPACE( q[-1] ) ) {
2506 /* null terminate */
2509 normalized->bv_len = q - normalized->bv_val;
2511 if( normalized->bv_len == 0 ) {
2512 normalized->bv_val = ch_realloc( normalized->bv_val, 2 );
2513 normalized->bv_val[0] = ' ';
2514 normalized->bv_val[1] = '\0';
2515 normalized->bv_len = 1;
2518 return LDAP_SUCCESS;
2521 #ifndef SLAP_NVALUES
2529 struct berval *value,
2530 void *assertedValue )
2532 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
2535 match = strncmp( value->bv_val,
2536 ((struct berval *) assertedValue)->bv_val,
2541 return LDAP_SUCCESS;
2545 caseExactIA5SubstringsMatch
2548 octetStringSubstringsMatch
2555 struct berval *value,
2556 void *assertedValue )
2559 SubstringsAssertion *sub = assertedValue;
2560 struct berval left = *value;
2564 /* Add up asserted input length */
2565 if( sub->sa_initial.bv_val ) {
2566 inlen += sub->sa_initial.bv_len;
2569 for(i=0; sub->sa_any[i].bv_val != NULL; i++) {
2570 inlen += sub->sa_any[i].bv_len;
2573 if( sub->sa_final.bv_val ) {
2574 inlen += sub->sa_final.bv_len;
2577 if( sub->sa_initial.bv_val ) {
2578 if( inlen > left.bv_len ) {
2583 match = memcmp( sub->sa_initial.bv_val, left.bv_val,
2584 sub->sa_initial.bv_len );
2590 left.bv_val += sub->sa_initial.bv_len;
2591 left.bv_len -= sub->sa_initial.bv_len;
2592 inlen -= sub->sa_initial.bv_len;
2595 if( sub->sa_final.bv_val ) {
2596 if( inlen > left.bv_len ) {
2601 match = memcmp( sub->sa_final.bv_val,
2602 &left.bv_val[left.bv_len - sub->sa_final.bv_len],
2603 sub->sa_final.bv_len );
2609 left.bv_len -= sub->sa_final.bv_len;
2610 inlen -= sub->sa_final.bv_len;
2614 for(i=0; sub->sa_any[i].bv_val; i++) {
2619 if( inlen > left.bv_len ) {
2620 /* not enough length */
2625 if( sub->sa_any[i].bv_len == 0 ) {
2629 p = memchr( left.bv_val, *sub->sa_any[i].bv_val, left.bv_len );
2636 idx = p - left.bv_val;
2638 if( idx >= left.bv_len ) {
2639 /* this shouldn't happen */
2646 if( sub->sa_any[i].bv_len > left.bv_len ) {
2647 /* not enough left */
2652 match = memcmp( left.bv_val,
2653 sub->sa_any[i].bv_val,
2654 sub->sa_any[i].bv_len );
2662 left.bv_val += sub->sa_any[i].bv_len;
2663 left.bv_len -= sub->sa_any[i].bv_len;
2664 inlen -= sub->sa_any[i].bv_len;
2670 return LDAP_SUCCESS;
2673 #ifndef SLAP_NVALUES
2675 /* Index generation function */
2676 static int caseExactIA5Indexer(
2681 struct berval *prefix,
2688 HASH_CONTEXT HASHcontext;
2689 unsigned char HASHdigest[HASH_BYTES];
2690 struct berval digest;
2691 digest.bv_val = HASHdigest;
2692 digest.bv_len = sizeof(HASHdigest);
2694 for( i=0; values[i].bv_val != NULL; i++ ) {
2695 /* empty - just count them */
2698 /* we should have at least one value at this point */
2701 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
2703 slen = syntax->ssyn_oidlen;
2704 mlen = mr->smr_oidlen;
2706 for( i=0; values[i].bv_val != NULL; i++ ) {
2707 struct berval *value = &values[i];
2709 HASH_Init( &HASHcontext );
2710 if( prefix != NULL && prefix->bv_len > 0 ) {
2711 HASH_Update( &HASHcontext,
2712 prefix->bv_val, prefix->bv_len );
2714 HASH_Update( &HASHcontext,
2715 syntax->ssyn_oid, slen );
2716 HASH_Update( &HASHcontext,
2717 mr->smr_oid, mlen );
2718 HASH_Update( &HASHcontext,
2719 value->bv_val, value->bv_len );
2720 HASH_Final( HASHdigest, &HASHcontext );
2722 ber_dupbv( &keys[i], &digest );
2725 keys[i].bv_val = NULL;
2727 return LDAP_SUCCESS;
2730 /* Index generation function */
2731 static int caseExactIA5Filter(
2736 struct berval *prefix,
2737 void * assertedValue,
2742 HASH_CONTEXT HASHcontext;
2743 unsigned char HASHdigest[HASH_BYTES];
2744 struct berval *value;
2745 struct berval digest;
2746 digest.bv_val = HASHdigest;
2747 digest.bv_len = sizeof(HASHdigest);
2749 slen = syntax->ssyn_oidlen;
2750 mlen = mr->smr_oidlen;
2752 value = (struct berval *) assertedValue;
2754 keys = ch_malloc( sizeof( struct berval ) * 2 );
2756 HASH_Init( &HASHcontext );
2757 if( prefix != NULL && prefix->bv_len > 0 ) {
2758 HASH_Update( &HASHcontext,
2759 prefix->bv_val, prefix->bv_len );
2761 HASH_Update( &HASHcontext,
2762 syntax->ssyn_oid, slen );
2763 HASH_Update( &HASHcontext,
2764 mr->smr_oid, mlen );
2765 HASH_Update( &HASHcontext,
2766 value->bv_val, value->bv_len );
2767 HASH_Final( HASHdigest, &HASHcontext );
2769 ber_dupbv( &keys[0], &digest );
2770 keys[1].bv_val = NULL;
2773 return LDAP_SUCCESS;
2776 /* Substrings Index generation function */
2777 static int caseExactIA5SubstringsIndexer(
2782 struct berval *prefix,
2789 HASH_CONTEXT HASHcontext;
2790 unsigned char HASHdigest[HASH_BYTES];
2791 struct berval digest;
2792 digest.bv_val = HASHdigest;
2793 digest.bv_len = sizeof(HASHdigest);
2795 /* we should have at least one value at this point */
2796 assert( values != NULL && values[0].bv_val != NULL );
2799 for( i=0; values[i].bv_val != NULL; i++ ) {
2800 /* count number of indices to generate */
2801 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
2805 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
2806 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2807 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2808 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2810 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2814 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
2815 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2816 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
2820 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
2821 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2822 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2823 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2825 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2831 /* no keys to generate */
2833 return LDAP_SUCCESS;
2836 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
2838 slen = syntax->ssyn_oidlen;
2839 mlen = mr->smr_oidlen;
2842 for( i=0; values[i].bv_val != NULL; i++ ) {
2844 struct berval *value;
2847 if( value->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
2849 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
2850 ( value->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
2852 char pre = SLAP_INDEX_SUBSTR_PREFIX;
2853 max = value->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
2855 for( j=0; j<max; j++ ) {
2856 HASH_Init( &HASHcontext );
2857 if( prefix != NULL && prefix->bv_len > 0 ) {
2858 HASH_Update( &HASHcontext,
2859 prefix->bv_val, prefix->bv_len );
2862 HASH_Update( &HASHcontext,
2863 &pre, sizeof( pre ) );
2864 HASH_Update( &HASHcontext,
2865 syntax->ssyn_oid, slen );
2866 HASH_Update( &HASHcontext,
2867 mr->smr_oid, mlen );
2868 HASH_Update( &HASHcontext,
2870 SLAP_INDEX_SUBSTR_MAXLEN );
2871 HASH_Final( HASHdigest, &HASHcontext );
2873 ber_dupbv( &keys[nkeys++], &digest );
2877 max = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2878 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2880 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
2883 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
2884 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
2885 HASH_Init( &HASHcontext );
2886 if( prefix != NULL && prefix->bv_len > 0 ) {
2887 HASH_Update( &HASHcontext,
2888 prefix->bv_val, prefix->bv_len );
2890 HASH_Update( &HASHcontext,
2891 &pre, sizeof( pre ) );
2892 HASH_Update( &HASHcontext,
2893 syntax->ssyn_oid, slen );
2894 HASH_Update( &HASHcontext,
2895 mr->smr_oid, mlen );
2896 HASH_Update( &HASHcontext,
2898 HASH_Final( HASHdigest, &HASHcontext );
2900 ber_dupbv( &keys[nkeys++], &digest );
2903 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
2904 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
2905 HASH_Init( &HASHcontext );
2906 if( prefix != NULL && prefix->bv_len > 0 ) {
2907 HASH_Update( &HASHcontext,
2908 prefix->bv_val, prefix->bv_len );
2910 HASH_Update( &HASHcontext,
2911 &pre, sizeof( pre ) );
2912 HASH_Update( &HASHcontext,
2913 syntax->ssyn_oid, slen );
2914 HASH_Update( &HASHcontext,
2915 mr->smr_oid, mlen );
2916 HASH_Update( &HASHcontext,
2917 &value->bv_val[value->bv_len-j], j );
2918 HASH_Final( HASHdigest, &HASHcontext );
2920 ber_dupbv( &keys[nkeys++], &digest );
2927 keys[nkeys].bv_val = NULL;
2934 return LDAP_SUCCESS;
2937 static int caseExactIA5SubstringsFilter(
2942 struct berval *prefix,
2943 void * assertedValue,
2946 SubstringsAssertion *sa = assertedValue;
2948 ber_len_t nkeys = 0;
2949 size_t slen, mlen, klen;
2951 HASH_CONTEXT HASHcontext;
2952 unsigned char HASHdigest[HASH_BYTES];
2953 struct berval *value;
2954 struct berval digest;
2956 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
2957 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2962 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
2964 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
2965 if( sa->sa_any[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2966 /* don't bother accounting for stepping */
2967 nkeys += sa->sa_any[i].bv_len -
2968 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
2973 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
2974 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2981 return LDAP_SUCCESS;
2984 digest.bv_val = HASHdigest;
2985 digest.bv_len = sizeof(HASHdigest);
2987 slen = syntax->ssyn_oidlen;
2988 mlen = mr->smr_oidlen;
2990 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
2993 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
2994 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2996 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
2997 value = &sa->sa_initial;
2999 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
3000 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
3002 HASH_Init( &HASHcontext );
3003 if( prefix != NULL && prefix->bv_len > 0 ) {
3004 HASH_Update( &HASHcontext,
3005 prefix->bv_val, prefix->bv_len );
3007 HASH_Update( &HASHcontext,
3008 &pre, sizeof( pre ) );
3009 HASH_Update( &HASHcontext,
3010 syntax->ssyn_oid, slen );
3011 HASH_Update( &HASHcontext,
3012 mr->smr_oid, mlen );
3013 HASH_Update( &HASHcontext,
3014 value->bv_val, klen );
3015 HASH_Final( HASHdigest, &HASHcontext );
3017 ber_dupbv( &keys[nkeys++], &digest );
3020 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
3022 pre = SLAP_INDEX_SUBSTR_PREFIX;
3023 klen = SLAP_INDEX_SUBSTR_MAXLEN;
3025 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
3026 if( sa->sa_any[i].bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
3030 value = &sa->sa_any[i];
3033 j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
3034 j += SLAP_INDEX_SUBSTR_STEP )
3036 HASH_Init( &HASHcontext );
3037 if( prefix != NULL && prefix->bv_len > 0 ) {
3038 HASH_Update( &HASHcontext,
3039 prefix->bv_val, prefix->bv_len );
3041 HASH_Update( &HASHcontext,
3042 &pre, sizeof( pre ) );
3043 HASH_Update( &HASHcontext,
3044 syntax->ssyn_oid, slen );
3045 HASH_Update( &HASHcontext,
3046 mr->smr_oid, mlen );
3047 HASH_Update( &HASHcontext,
3048 &value->bv_val[j], klen );
3049 HASH_Final( HASHdigest, &HASHcontext );
3051 ber_dupbv( &keys[nkeys++], &digest );
3056 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
3057 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3059 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
3060 value = &sa->sa_final;
3062 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
3063 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
3065 HASH_Init( &HASHcontext );
3066 if( prefix != NULL && prefix->bv_len > 0 ) {
3067 HASH_Update( &HASHcontext,
3068 prefix->bv_val, prefix->bv_len );
3070 HASH_Update( &HASHcontext,
3071 &pre, sizeof( pre ) );
3072 HASH_Update( &HASHcontext,
3073 syntax->ssyn_oid, slen );
3074 HASH_Update( &HASHcontext,
3075 mr->smr_oid, mlen );
3076 HASH_Update( &HASHcontext,
3077 &value->bv_val[value->bv_len-klen], klen );
3078 HASH_Final( HASHdigest, &HASHcontext );
3080 ber_dupbv( &keys[nkeys++], &digest );
3084 keys[nkeys].bv_val = NULL;
3091 return LDAP_SUCCESS;
3100 struct berval *value,
3101 void *assertedValue )
3103 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
3105 if( match == 0 && value->bv_len ) {
3106 match = strncasecmp( value->bv_val,
3107 ((struct berval *) assertedValue)->bv_val,
3112 return LDAP_SUCCESS;
3116 caseIgnoreIA5SubstringsMatch(
3121 struct berval *value,
3122 void *assertedValue )
3125 SubstringsAssertion *sub = assertedValue;
3126 struct berval left = *value;
3130 /* Add up asserted input length */
3131 if( sub->sa_initial.bv_val ) {
3132 inlen += sub->sa_initial.bv_len;
3135 for(i=0; sub->sa_any[i].bv_val != NULL; i++) {
3136 inlen += sub->sa_any[i].bv_len;
3139 if( sub->sa_final.bv_val ) {
3140 inlen += sub->sa_final.bv_len;
3143 if( sub->sa_initial.bv_val ) {
3144 if( inlen > left.bv_len ) {
3149 match = strncasecmp( sub->sa_initial.bv_val, left.bv_val,
3150 sub->sa_initial.bv_len );
3156 left.bv_val += sub->sa_initial.bv_len;
3157 left.bv_len -= sub->sa_initial.bv_len;
3158 inlen -= sub->sa_initial.bv_len;
3161 if( sub->sa_final.bv_val ) {
3162 if( inlen > left.bv_len ) {
3167 match = strncasecmp( sub->sa_final.bv_val,
3168 &left.bv_val[left.bv_len - sub->sa_final.bv_len],
3169 sub->sa_final.bv_len );
3175 left.bv_len -= sub->sa_final.bv_len;
3176 inlen -= sub->sa_final.bv_len;
3180 for(i=0; sub->sa_any[i].bv_val; i++) {
3185 if( inlen > left.bv_len ) {
3186 /* not enough length */
3191 if( sub->sa_any[i].bv_len == 0 ) {
3195 p = bvcasechr( &left, *sub->sa_any[i].bv_val, &idx );
3202 assert( idx < left.bv_len );
3203 if( idx >= left.bv_len ) {
3204 /* this shouldn't happen */
3211 if( sub->sa_any[i].bv_len > left.bv_len ) {
3212 /* not enough left */
3217 match = strncasecmp( left.bv_val,
3218 sub->sa_any[i].bv_val,
3219 sub->sa_any[i].bv_len );
3228 left.bv_val += sub->sa_any[i].bv_len;
3229 left.bv_len -= sub->sa_any[i].bv_len;
3230 inlen -= sub->sa_any[i].bv_len;
3236 return LDAP_SUCCESS;
3239 /* Index generation function */
3240 static int caseIgnoreIA5Indexer(
3245 struct berval *prefix,
3250 int rc = LDAP_SUCCESS;
3253 HASH_CONTEXT HASHcontext;
3254 unsigned char HASHdigest[HASH_BYTES];
3255 struct berval digest;
3256 digest.bv_val = HASHdigest;
3257 digest.bv_len = sizeof(HASHdigest);
3259 /* we should have at least one value at this point */
3260 assert( values != NULL && values[0].bv_val != NULL );
3262 for( i=0; values[i].bv_val != NULL; i++ ) {
3263 /* just count them */
3266 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
3268 slen = syntax->ssyn_oidlen;
3269 mlen = mr->smr_oidlen;
3271 for( i=0; values[i].bv_val != NULL; i++ ) {
3272 struct berval value;
3274 if( mr->smr_normalize ) {
3275 rc = (mr->smr_normalize)( use, syntax, mr, &values[i], &value );
3276 if( rc != LDAP_SUCCESS ) {
3279 #ifndef SLAP_NVALUES
3280 } else if ( mr->smr_syntax->ssyn_normalize ) {
3281 rc = (mr->smr_syntax->ssyn_normalize)( syntax, &values[i], &value );
3282 if( rc != LDAP_SUCCESS ) {
3287 ber_dupbv( &value, &values[i] );
3290 ldap_pvt_str2lower( value.bv_val );
3292 HASH_Init( &HASHcontext );
3293 if( prefix != NULL && prefix->bv_len > 0 ) {
3294 HASH_Update( &HASHcontext,
3295 prefix->bv_val, prefix->bv_len );
3297 HASH_Update( &HASHcontext,
3298 syntax->ssyn_oid, slen );
3299 HASH_Update( &HASHcontext,
3300 mr->smr_oid, mlen );
3301 HASH_Update( &HASHcontext,
3302 value.bv_val, value.bv_len );
3303 HASH_Final( HASHdigest, &HASHcontext );
3305 free( value.bv_val );
3307 ber_dupbv( &keys[i], &digest );
3310 keys[i].bv_val = NULL;
3311 if( rc != LDAP_SUCCESS ) {
3312 ber_bvarray_free( keys );
3319 /* Index generation function */
3320 static int caseIgnoreIA5Filter(
3325 struct berval *prefix,
3326 void * assertedValue,
3331 HASH_CONTEXT HASHcontext;
3332 unsigned char HASHdigest[HASH_BYTES];
3333 struct berval value;
3334 struct berval digest;
3335 digest.bv_val = HASHdigest;
3336 digest.bv_len = sizeof(HASHdigest);
3338 slen = syntax->ssyn_oidlen;
3339 mlen = mr->smr_oidlen;
3341 ber_dupbv( &value, (struct berval *) assertedValue );
3342 ldap_pvt_str2lower( value.bv_val );
3344 keys = ch_malloc( sizeof( struct berval ) * 2 );
3346 HASH_Init( &HASHcontext );
3347 if( prefix != NULL && prefix->bv_len > 0 ) {
3348 HASH_Update( &HASHcontext,
3349 prefix->bv_val, prefix->bv_len );
3351 HASH_Update( &HASHcontext,
3352 syntax->ssyn_oid, slen );
3353 HASH_Update( &HASHcontext,
3354 mr->smr_oid, mlen );
3355 HASH_Update( &HASHcontext,
3356 value.bv_val, value.bv_len );
3357 HASH_Final( HASHdigest, &HASHcontext );
3359 ber_dupbv( &keys[0], &digest );
3360 keys[1].bv_val = NULL;
3362 free( value.bv_val );
3366 return LDAP_SUCCESS;
3369 /* Substrings Index generation function */
3370 static int caseIgnoreIA5SubstringsIndexer(
3375 struct berval *prefix,
3382 HASH_CONTEXT HASHcontext;
3383 unsigned char HASHdigest[HASH_BYTES];
3384 struct berval digest;
3385 digest.bv_val = HASHdigest;
3386 digest.bv_len = sizeof(HASHdigest);
3388 /* we should have at least one value at this point */
3389 assert( values != NULL && values[0].bv_val != NULL );
3392 for( i=0; values[i].bv_val != NULL; i++ ) {
3393 /* count number of indices to generate */
3394 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
3398 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
3399 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3400 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
3401 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
3403 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
3407 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
3408 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3409 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
3413 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
3414 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3415 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
3416 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
3418 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
3424 /* no keys to generate */
3426 return LDAP_SUCCESS;
3429 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
3431 slen = syntax->ssyn_oidlen;
3432 mlen = mr->smr_oidlen;
3435 for( i=0; values[i].bv_val != NULL; i++ ) {
3437 struct berval value;
3439 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
3441 ber_dupbv( &value, &values[i] );
3442 ldap_pvt_str2lower( value.bv_val );
3444 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
3445 ( value.bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
3447 char pre = SLAP_INDEX_SUBSTR_PREFIX;
3448 max = value.bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
3450 for( j=0; j<max; j++ ) {
3451 HASH_Init( &HASHcontext );
3452 if( prefix != NULL && prefix->bv_len > 0 ) {
3453 HASH_Update( &HASHcontext,
3454 prefix->bv_val, prefix->bv_len );
3457 HASH_Update( &HASHcontext,
3458 &pre, sizeof( pre ) );
3459 HASH_Update( &HASHcontext,
3460 syntax->ssyn_oid, slen );
3461 HASH_Update( &HASHcontext,
3462 mr->smr_oid, mlen );
3463 HASH_Update( &HASHcontext,
3465 SLAP_INDEX_SUBSTR_MAXLEN );
3466 HASH_Final( HASHdigest, &HASHcontext );
3468 ber_dupbv( &keys[nkeys++], &digest );
3472 max = SLAP_INDEX_SUBSTR_MAXLEN < value.bv_len
3473 ? SLAP_INDEX_SUBSTR_MAXLEN : value.bv_len;
3475 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
3478 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
3479 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
3480 HASH_Init( &HASHcontext );
3481 if( prefix != NULL && prefix->bv_len > 0 ) {
3482 HASH_Update( &HASHcontext,
3483 prefix->bv_val, prefix->bv_len );
3485 HASH_Update( &HASHcontext,
3486 &pre, sizeof( pre ) );
3487 HASH_Update( &HASHcontext,
3488 syntax->ssyn_oid, slen );
3489 HASH_Update( &HASHcontext,
3490 mr->smr_oid, mlen );
3491 HASH_Update( &HASHcontext,
3493 HASH_Final( HASHdigest, &HASHcontext );
3495 ber_dupbv( &keys[nkeys++], &digest );
3498 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
3499 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
3500 HASH_Init( &HASHcontext );
3501 if( prefix != NULL && prefix->bv_len > 0 ) {
3502 HASH_Update( &HASHcontext,
3503 prefix->bv_val, prefix->bv_len );
3505 HASH_Update( &HASHcontext,
3506 &pre, sizeof( pre ) );
3507 HASH_Update( &HASHcontext,
3508 syntax->ssyn_oid, slen );
3509 HASH_Update( &HASHcontext,
3510 mr->smr_oid, mlen );
3511 HASH_Update( &HASHcontext,
3512 &value.bv_val[value.bv_len-j], j );
3513 HASH_Final( HASHdigest, &HASHcontext );
3515 ber_dupbv( &keys[nkeys++], &digest );
3520 free( value.bv_val );
3524 keys[nkeys].bv_val = NULL;
3531 return LDAP_SUCCESS;
3534 static int caseIgnoreIA5SubstringsFilter(
3539 struct berval *prefix,
3540 void * assertedValue,
3543 SubstringsAssertion *sa = assertedValue;
3545 ber_len_t nkeys = 0;
3546 size_t slen, mlen, klen;
3548 HASH_CONTEXT HASHcontext;
3549 unsigned char HASHdigest[HASH_BYTES];
3550 struct berval value;
3551 struct berval digest;
3553 if((flags & SLAP_INDEX_SUBSTR_INITIAL) && sa->sa_initial.bv_val != NULL &&
3554 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3559 if((flags & SLAP_INDEX_SUBSTR_ANY) && sa->sa_any != NULL ) {
3561 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
3562 if( sa->sa_any[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3563 /* don't bother accounting for stepping */
3564 nkeys += sa->sa_any[i].bv_len -
3565 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
3570 if((flags & SLAP_INDEX_SUBSTR_FINAL) && sa->sa_final.bv_val != NULL &&
3571 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3578 return LDAP_SUCCESS;
3581 digest.bv_val = HASHdigest;
3582 digest.bv_len = sizeof(HASHdigest);
3584 slen = syntax->ssyn_oidlen;
3585 mlen = mr->smr_oidlen;
3587 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
3590 if((flags & SLAP_INDEX_SUBSTR_INITIAL) && sa->sa_initial.bv_val != NULL &&
3591 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3593 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
3594 ber_dupbv( &value, &sa->sa_initial );
3595 ldap_pvt_str2lower( value.bv_val );
3597 klen = SLAP_INDEX_SUBSTR_MAXLEN < value.bv_len
3598 ? SLAP_INDEX_SUBSTR_MAXLEN : value.bv_len;
3600 HASH_Init( &HASHcontext );
3601 if( prefix != NULL && prefix->bv_len > 0 ) {
3602 HASH_Update( &HASHcontext,
3603 prefix->bv_val, prefix->bv_len );
3605 HASH_Update( &HASHcontext,
3606 &pre, sizeof( pre ) );
3607 HASH_Update( &HASHcontext,
3608 syntax->ssyn_oid, slen );
3609 HASH_Update( &HASHcontext,
3610 mr->smr_oid, mlen );
3611 HASH_Update( &HASHcontext,
3612 value.bv_val, klen );
3613 HASH_Final( HASHdigest, &HASHcontext );
3615 free( value.bv_val );
3616 ber_dupbv( &keys[nkeys++], &digest );
3619 if((flags & SLAP_INDEX_SUBSTR_ANY) && sa->sa_any != NULL ) {
3621 pre = SLAP_INDEX_SUBSTR_PREFIX;
3622 klen = SLAP_INDEX_SUBSTR_MAXLEN;
3624 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
3625 if( sa->sa_any[i].bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
3629 ber_dupbv( &value, &sa->sa_any[i] );
3630 ldap_pvt_str2lower( value.bv_val );
3633 j <= value.bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
3634 j += SLAP_INDEX_SUBSTR_STEP )
3636 HASH_Init( &HASHcontext );
3637 if( prefix != NULL && prefix->bv_len > 0 ) {
3638 HASH_Update( &HASHcontext,
3639 prefix->bv_val, prefix->bv_len );
3641 HASH_Update( &HASHcontext,
3642 &pre, sizeof( pre ) );
3643 HASH_Update( &HASHcontext,
3644 syntax->ssyn_oid, slen );
3645 HASH_Update( &HASHcontext,
3646 mr->smr_oid, mlen );
3647 HASH_Update( &HASHcontext,
3648 &value.bv_val[j], klen );
3649 HASH_Final( HASHdigest, &HASHcontext );
3651 ber_dupbv( &keys[nkeys++], &digest );
3654 free( value.bv_val );
3658 if((flags & SLAP_INDEX_SUBSTR_FINAL) && sa->sa_final.bv_val != NULL &&
3659 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3661 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
3662 ber_dupbv( &value, &sa->sa_final );
3663 ldap_pvt_str2lower( value.bv_val );
3665 klen = SLAP_INDEX_SUBSTR_MAXLEN < value.bv_len
3666 ? SLAP_INDEX_SUBSTR_MAXLEN : value.bv_len;
3668 HASH_Init( &HASHcontext );
3669 if( prefix != NULL && prefix->bv_len > 0 ) {
3670 HASH_Update( &HASHcontext,
3671 prefix->bv_val, prefix->bv_len );
3673 HASH_Update( &HASHcontext,
3674 &pre, sizeof( pre ) );
3675 HASH_Update( &HASHcontext,
3676 syntax->ssyn_oid, slen );
3677 HASH_Update( &HASHcontext,
3678 mr->smr_oid, mlen );
3679 HASH_Update( &HASHcontext,
3680 &value.bv_val[value.bv_len-klen], klen );
3681 HASH_Final( HASHdigest, &HASHcontext );
3683 free( value.bv_val );
3684 ber_dupbv( &keys[nkeys++], &digest );
3688 keys[nkeys].bv_val = NULL;
3695 return LDAP_SUCCESS;
3701 numericStringValidate(
3707 if( in->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
3709 for(i=0; i < in->bv_len; i++) {
3710 if( !SLAP_NUMERIC(in->bv_val[i]) ) {
3711 return LDAP_INVALID_SYNTAX;
3715 return LDAP_SUCCESS;
3720 numericStringNormalize(
3725 struct berval *normalized )
3727 xnumericStringNormalize(
3730 struct berval *normalized )
3733 /* removal all spaces */
3736 assert( val->bv_len );
3738 normalized->bv_val = ch_malloc( val->bv_len + 1 );
3741 q = normalized->bv_val;
3744 if ( ASCII_SPACE( *p ) ) {
3745 /* Ignore whitespace */
3752 /* we should have copied no more then is in val */
3753 assert( (q - normalized->bv_val) <= (p - val->bv_val) );
3755 /* null terminate */
3758 normalized->bv_len = q - normalized->bv_val;
3760 if( normalized->bv_len == 0 ) {
3761 normalized->bv_val = ch_realloc( normalized->bv_val, 2 );
3762 normalized->bv_val[0] = ' ';
3763 normalized->bv_val[1] = '\0';
3764 normalized->bv_len = 1;
3767 return LDAP_SUCCESS;
3770 #ifndef SLAP_NVALUES
3772 objectIdentifierFirstComponentMatch(
3777 struct berval *value,
3778 void *assertedValue )
3780 int rc = LDAP_SUCCESS;
3782 struct berval *asserted = (struct berval *) assertedValue;
3786 if( value->bv_len == 0 || value->bv_val[0] != '(' /*')'*/ ) {
3787 return LDAP_INVALID_SYNTAX;
3790 /* trim leading white space */
3791 for( i=1; ASCII_SPACE(value->bv_val[i]) && i < value->bv_len; i++ ) {
3795 /* grab next word */
3796 oid.bv_val = &value->bv_val[i];
3797 j = value->bv_len - i;
3798 for( i=0; !ASCII_SPACE(oid.bv_val[i]) && i < j; i++ ) {
3803 /* insert attributeTypes, objectclass check here */
3804 if( OID_LEADCHAR(asserted->bv_val[0]) ) {
3805 rc = objectIdentifierMatch( &match, flags, syntax, mr, &oid, asserted );
3808 if ( !strcmp( syntax->ssyn_oid, SLAP_SYNTAX_MATCHINGRULES_OID ) ) {
3809 MatchingRule *asserted_mr = mr_bvfind( asserted );
3810 MatchingRule *stored_mr = mr_bvfind( &oid );
3812 if( asserted_mr == NULL ) {
3813 rc = SLAPD_COMPARE_UNDEFINED;
3815 match = asserted_mr != stored_mr;
3818 } else if ( !strcmp( syntax->ssyn_oid,
3819 SLAP_SYNTAX_ATTRIBUTETYPES_OID ) )
3821 AttributeType *asserted_at = at_bvfind( asserted );
3822 AttributeType *stored_at = at_bvfind( &oid );
3824 if( asserted_at == NULL ) {
3825 rc = SLAPD_COMPARE_UNDEFINED;
3827 match = asserted_at != stored_at;
3830 } else if ( !strcmp( syntax->ssyn_oid,
3831 SLAP_SYNTAX_OBJECTCLASSES_OID ) )
3833 ObjectClass *asserted_oc = oc_bvfind( asserted );
3834 ObjectClass *stored_oc = oc_bvfind( &oid );
3836 if( asserted_oc == NULL ) {
3837 rc = SLAPD_COMPARE_UNDEFINED;
3839 match = asserted_oc != stored_oc;
3845 LDAP_LOG( CONFIG, ENTRY,
3846 "objectIdentifierFirstComponentMatch: %d\n %s\n %s\n",
3847 match, value->bv_val, asserted->bv_val );
3849 Debug( LDAP_DEBUG_ARGS, "objectIdentifierFirstComponentMatch "
3850 "%d\n\t\"%s\"\n\t\"%s\"\n",
3851 match, value->bv_val, asserted->bv_val );
3854 if( rc == LDAP_SUCCESS ) *matchp = match;
3866 struct berval *value,
3867 void *assertedValue )
3869 long lValue, lAssertedValue;
3871 /* safe to assume integers are NUL terminated? */
3872 lValue = strtol(value->bv_val, NULL, 10);
3873 if(( lValue == LONG_MIN || lValue == LONG_MAX) && errno == ERANGE ) {
3874 return LDAP_CONSTRAINT_VIOLATION;
3877 lAssertedValue = strtol(((struct berval *)assertedValue)->bv_val, NULL, 10);
3878 if(( lAssertedValue == LONG_MIN || lAssertedValue == LONG_MAX)
3879 && errno == ERANGE )
3881 return LDAP_CONSTRAINT_VIOLATION;
3884 *matchp = (lValue & lAssertedValue) ? 0 : 1;
3885 return LDAP_SUCCESS;
3894 struct berval *value,
3895 void *assertedValue )
3897 long lValue, lAssertedValue;
3899 /* safe to assume integers are NUL terminated? */
3900 lValue = strtol(value->bv_val, NULL, 10);
3901 if(( lValue == LONG_MIN || lValue == LONG_MAX) && errno == ERANGE ) {
3902 return LDAP_CONSTRAINT_VIOLATION;
3905 lAssertedValue = strtol(((struct berval *)assertedValue)->bv_val, NULL, 10);
3906 if(( lAssertedValue == LONG_MIN || lAssertedValue == LONG_MAX)
3907 && errno == ERANGE )
3909 return LDAP_CONSTRAINT_VIOLATION;
3912 *matchp = (lValue | lAssertedValue) ? 0 : -1;
3913 return LDAP_SUCCESS;
3916 #ifndef SLAP_NVALUES
3919 #include <openssl/x509.h>
3920 #include <openssl/err.h>
3923 * Next function returns a string representation of a ASN1_INTEGER.
3924 * It works for unlimited lengths.
3927 static struct berval *
3928 asn1_integer2str(ASN1_INTEGER *a, struct berval *bv)
3932 static char digit[] = "0123456789";
3934 /* We work backwards, make it fill from the end of buf */
3935 p = buf + sizeof(buf) - 1;
3938 if ( a == NULL || a->length == 0 ) {
3946 /* We want to preserve the original */
3947 copy = ch_malloc(n*sizeof(unsigned int));
3948 for (i = 0; i<n; i++) {
3949 copy[i] = a->data[i];
3953 * base indicates the index of the most significant
3954 * byte that might be nonzero. When it goes off the
3955 * end, we now there is nothing left to do.
3961 for (i = base; i<n; i++ ) {
3962 copy[i] += carry*256;
3963 carry = copy[i] % 10;
3968 * Way too large, we need to leave
3969 * room for sign if negative
3974 *--p = digit[carry];
3976 if (copy[base] == 0) base++;
3981 if ( a->type == V_ASN1_NEG_INTEGER ) {
3985 return ber_str2bv( p, 0, 1, bv );
3989 * Given a certificate in DER format, extract the corresponding
3990 * assertion value for certificateExactMatch
3993 certificateExactConvert(
3995 struct berval * out )
3998 unsigned char *p = in->bv_val;
3999 struct berval serial;
4000 struct berval issuer_dn;
4002 xcert = d2i_X509(NULL, &p, in->bv_len);
4005 LDAP_LOG( CONFIG, ENTRY,
4006 "certificateExactConvert: error parsing cert: %s\n",
4007 ERR_error_string(ERR_get_error(),NULL), 0, 0 );
4009 Debug( LDAP_DEBUG_ARGS, "certificateExactConvert: "
4010 "error parsing cert: %s\n",
4011 ERR_error_string(ERR_get_error(),NULL), NULL, NULL );
4013 return LDAP_INVALID_SYNTAX;
4016 if ( !asn1_integer2str(xcert->cert_info->serialNumber, &serial) ) {
4018 return LDAP_INVALID_SYNTAX;
4020 if ( dnX509normalize(X509_get_issuer_name(xcert), &issuer_dn )
4024 ber_memfree(serial.bv_val);
4025 return LDAP_INVALID_SYNTAX;
4030 out->bv_len = serial.bv_len + issuer_dn.bv_len + sizeof(" $ ");
4031 out->bv_val = ch_malloc(out->bv_len);
4033 AC_MEMCPY(p, serial.bv_val, serial.bv_len);
4035 AC_MEMCPY(p, " $ ", sizeof(" $ ")-1);
4037 AC_MEMCPY(p, issuer_dn.bv_val, issuer_dn.bv_len);
4038 p += issuer_dn.bv_len;
4042 LDAP_LOG( CONFIG, ARGS,
4043 "certificateExactConvert: \n %s\n", out->bv_val, 0, 0 );
4045 Debug( LDAP_DEBUG_ARGS, "certificateExactConvert "
4047 out->bv_val, NULL, NULL );
4050 ber_memfree(serial.bv_val);
4051 ber_memfree(issuer_dn.bv_val);
4053 return LDAP_SUCCESS;
4057 serial_and_issuer_parse(
4058 struct berval *assertion,
4059 struct berval *serial,
4060 struct berval *issuer_dn
4068 begin = assertion->bv_val;
4069 end = assertion->bv_val+assertion->bv_len-1;
4070 for (p=begin; p<=end && *p != '$'; p++) /* empty */ ;
4071 if ( p > end ) return LDAP_INVALID_SYNTAX;
4073 /* p now points at the $ sign, now use
4074 * begin and end to delimit the serial number
4076 while (ASCII_SPACE(*begin)) begin++;
4078 while (ASCII_SPACE(*end)) end--;
4080 if( end <= begin ) return LDAP_INVALID_SYNTAX;
4082 bv.bv_len = end-begin+1;
4084 ber_dupbv(serial, &bv);
4086 /* now extract the issuer, remember p was at the dollar sign */
4088 end = assertion->bv_val+assertion->bv_len-1;
4089 while (ASCII_SPACE(*begin)) begin++;
4090 /* should we trim spaces at the end too? is it safe always? no, no */
4092 if( end <= begin ) return LDAP_INVALID_SYNTAX;
4095 bv.bv_len = end-begin+1;
4098 dnNormalize2( NULL, &bv, issuer_dn );
4101 return LDAP_SUCCESS;
4105 certificateExactMatch(
4110 struct berval *value,
4111 void *assertedValue )
4114 unsigned char *p = value->bv_val;
4115 struct berval serial;
4116 struct berval issuer_dn;
4117 struct berval asserted_serial;
4118 struct berval asserted_issuer_dn;
4121 xcert = d2i_X509(NULL, &p, value->bv_len);
4124 LDAP_LOG( CONFIG, ENTRY,
4125 "certificateExactMatch: error parsing cert: %s\n",
4126 ERR_error_string(ERR_get_error(),NULL), 0, 0 );
4128 Debug( LDAP_DEBUG_ARGS, "certificateExactMatch: "
4129 "error parsing cert: %s\n",
4130 ERR_error_string(ERR_get_error(),NULL), NULL, NULL );
4132 return LDAP_INVALID_SYNTAX;
4135 asn1_integer2str(xcert->cert_info->serialNumber, &serial);
4136 dnX509normalize(X509_get_issuer_name(xcert), &issuer_dn);
4140 serial_and_issuer_parse(assertedValue,
4141 &asserted_serial, &asserted_issuer_dn);
4146 slap_schema.si_syn_integer,
4147 slap_schema.si_mr_integerMatch,
4150 if ( ret == LDAP_SUCCESS ) {
4151 if ( *matchp == 0 ) {
4152 /* We need to normalize everything for dnMatch */
4156 slap_schema.si_syn_distinguishedName,
4157 slap_schema.si_mr_distinguishedNameMatch,
4159 &asserted_issuer_dn);
4164 LDAP_LOG( CONFIG, ARGS, "certificateExactMatch "
4165 "%d\n\t\"%s $ %s\"\n",
4166 *matchp, serial.bv_val, issuer_dn.bv_val );
4167 LDAP_LOG( CONFIG, ARGS, "\t\"%s $ %s\"\n",
4168 asserted_serial.bv_val, asserted_issuer_dn.bv_val,
4171 Debug( LDAP_DEBUG_ARGS, "certificateExactMatch "
4172 "%d\n\t\"%s $ %s\"\n",
4173 *matchp, serial.bv_val, issuer_dn.bv_val );
4174 Debug( LDAP_DEBUG_ARGS, "\t\"%s $ %s\"\n",
4175 asserted_serial.bv_val, asserted_issuer_dn.bv_val,
4179 ber_memfree(serial.bv_val);
4180 ber_memfree(issuer_dn.bv_val);
4181 ber_memfree(asserted_serial.bv_val);
4182 ber_memfree(asserted_issuer_dn.bv_val);
4188 * Index generation function
4189 * We just index the serials, in most scenarios the issuer DN is one of
4190 * a very small set of values.
4192 static int certificateExactIndexer(
4197 struct berval *prefix,
4205 struct berval serial;
4207 /* we should have at least one value at this point */
4208 assert( values != NULL && values[0].bv_val != NULL );
4210 for( i=0; values[i].bv_val != NULL; i++ ) {
4211 /* empty -- just count them */
4214 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
4216 for( i=0; values[i].bv_val != NULL; i++ ) {
4217 p = values[i].bv_val;
4218 xcert = d2i_X509(NULL, &p, values[i].bv_len);
4221 LDAP_LOG( CONFIG, ENTRY,
4222 "certificateExactIndexer: error parsing cert: %s\n",
4223 ERR_error_string(ERR_get_error(),NULL), 0, 0);
4225 Debug( LDAP_DEBUG_ARGS, "certificateExactIndexer: "
4226 "error parsing cert: %s\n",
4227 ERR_error_string(ERR_get_error(),NULL),
4230 /* Do we leak keys on error? */
4231 return LDAP_INVALID_SYNTAX;
4234 asn1_integer2str(xcert->cert_info->serialNumber, &serial);
4236 xintegerNormalize( slap_schema.si_syn_integer,
4237 &serial, &keys[i] );
4238 ber_memfree(serial.bv_val);
4240 LDAP_LOG( CONFIG, ENTRY,
4241 "certificateExactIndexer: returning: %s\n", keys[i].bv_val, 0, 0);
4243 Debug( LDAP_DEBUG_ARGS, "certificateExactIndexer: "
4250 keys[i].bv_val = NULL;
4252 return LDAP_SUCCESS;
4255 /* Index generation function */
4256 /* We think this is always called with a value in matching rule syntax */
4257 static int certificateExactFilter(
4262 struct berval *prefix,
4263 void * assertedValue,
4267 struct berval asserted_serial;
4270 ret = serial_and_issuer_parse( assertedValue, &asserted_serial, NULL );
4271 if( ret != LDAP_SUCCESS ) return ret;
4273 keys = ch_malloc( sizeof( struct berval ) * 2 );
4274 xintegerNormalize( syntax, &asserted_serial, &keys[0] );
4275 keys[1].bv_val = NULL;
4278 ber_memfree(asserted_serial.bv_val);
4279 return LDAP_SUCCESS;
4285 check_time_syntax (struct berval *val,
4289 static int ceiling[9] = { 99, 99, 11, 30, 23, 59, 59, 12, 59 };
4290 static int mdays[2][12] = {
4291 /* non-leap years */
4292 { 30, 27, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30 },
4294 { 30, 28, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30 }
4297 int part, c, tzoffset, leapyear = 0 ;
4299 if( val->bv_len == 0 ) {
4300 return LDAP_INVALID_SYNTAX;
4303 p = (char *)val->bv_val;
4304 e = p + val->bv_len;
4306 /* Ignore initial whitespace */
4307 while ( ( p < e ) && ASCII_SPACE( *p ) ) {
4311 if (e - p < 13 - (2 * start)) {
4312 return LDAP_INVALID_SYNTAX;
4315 for (part = 0; part < 9; part++) {
4319 for (part = start; part < 7; part++) {
4321 if ((part == 6) && (c == 'Z' || c == '+' || c == '-')) {
4328 return LDAP_INVALID_SYNTAX;
4330 if (c < 0 || c > 9) {
4331 return LDAP_INVALID_SYNTAX;
4337 return LDAP_INVALID_SYNTAX;
4339 if (c < 0 || c > 9) {
4340 return LDAP_INVALID_SYNTAX;
4345 if (part == 2 || part == 3) {
4348 if (parts[part] < 0) {
4349 return LDAP_INVALID_SYNTAX;
4351 if (parts[part] > ceiling[part]) {
4352 return LDAP_INVALID_SYNTAX;
4356 /* leapyear check for the Gregorian calendar (year>1581) */
4357 if (((parts[1] % 4 == 0) && (parts[1] != 0)) ||
4358 ((parts[0] % 4 == 0) && (parts[1] == 0)))
4363 if (parts[3] > mdays[leapyear][parts[2]]) {
4364 return LDAP_INVALID_SYNTAX;
4369 tzoffset = 0; /* UTC */
4370 } else if (c != '+' && c != '-') {
4371 return LDAP_INVALID_SYNTAX;
4375 } else /* c == '+' */ {
4380 return LDAP_INVALID_SYNTAX;
4383 for (part = 7; part < 9; part++) {
4385 if (c < 0 || c > 9) {
4386 return LDAP_INVALID_SYNTAX;
4391 if (c < 0 || c > 9) {
4392 return LDAP_INVALID_SYNTAX;
4396 if (parts[part] < 0 || parts[part] > ceiling[part]) {
4397 return LDAP_INVALID_SYNTAX;
4402 /* Ignore trailing whitespace */
4403 while ( ( p < e ) && ASCII_SPACE( *p ) ) {
4407 return LDAP_INVALID_SYNTAX;
4410 switch ( tzoffset ) {
4411 case -1: /* negativ offset to UTC, ie west of Greenwich */
4412 parts[4] += parts[7];
4413 parts[5] += parts[8];
4414 for (part = 6; --part > 0; ) { /* offset is just hhmm, no seconds */
4418 c = mdays[leapyear][parts[2]];
4420 if (parts[part] > c) {
4421 parts[part] -= c + 1;
4426 case 1: /* positive offset to UTC, ie east of Greenwich */
4427 parts[4] -= parts[7];
4428 parts[5] -= parts[8];
4429 for (part = 6; --part > 0; ) {
4433 /* first arg to % needs to be non negativ */
4434 c = mdays[leapyear][(parts[2] - 1 + 12) % 12];
4436 if (parts[part] < 0) {
4437 parts[part] += c + 1;
4442 case 0: /* already UTC */
4446 return LDAP_SUCCESS;
4449 #ifdef SUPPORT_OBSOLETE_UTC_SYNTAX
4454 struct berval *normalized )
4458 rc = check_time_syntax(val, 1, parts);
4459 if (rc != LDAP_SUCCESS) {
4463 normalized->bv_val = ch_malloc( 14 );
4464 if ( normalized->bv_val == NULL ) {
4465 return LBER_ERROR_MEMORY;
4468 sprintf( normalized->bv_val, "%02d%02d%02d%02d%02d%02dZ",
4469 parts[1], parts[2] + 1, parts[3] + 1,
4470 parts[4], parts[5], parts[6] );
4471 normalized->bv_len = 13;
4473 return LDAP_SUCCESS;
4477 #ifdef SUPPORT_OBSOLETE_UTC_SYNTAX
4485 return check_time_syntax(in, 1, parts);
4490 generalizedTimeValidate(
4496 return check_time_syntax(in, 0, parts);
4499 #ifndef SLAP_NVALUES
4502 xgeneralizedTimeNormalize(
4505 struct berval *normalized )
4509 rc = check_time_syntax(val, 0, parts);
4510 if (rc != LDAP_SUCCESS) {
4514 normalized->bv_val = ch_malloc( 16 );
4515 if ( normalized->bv_val == NULL ) {
4516 return LBER_ERROR_MEMORY;
4519 sprintf( normalized->bv_val, "%02d%02d%02d%02d%02d%02d%02dZ",
4520 parts[0], parts[1], parts[2] + 1, parts[3] + 1,
4521 parts[4], parts[5], parts[6] );
4522 normalized->bv_len = 15;
4524 return LDAP_SUCCESS;
4529 nisNetgroupTripleValidate(
4531 struct berval *val )
4536 if ( val->bv_len == 0 ) {
4537 return LDAP_INVALID_SYNTAX;
4540 p = (char *)val->bv_val;
4541 e = p + val->bv_len;
4543 if ( *p != '(' /*')'*/ ) {
4544 return LDAP_INVALID_SYNTAX;
4547 for ( p++; ( p < e ) && ( *p != /*'('*/ ')' ); p++ ) {
4551 return LDAP_INVALID_SYNTAX;
4554 } else if ( !AD_CHAR( *p ) ) {
4555 return LDAP_INVALID_SYNTAX;
4559 if ( ( commas != 2 ) || ( *p != /*'('*/ ')' ) ) {
4560 return LDAP_INVALID_SYNTAX;
4566 return LDAP_INVALID_SYNTAX;
4569 return LDAP_SUCCESS;
4573 bootParameterValidate(
4575 struct berval *val )
4579 if ( val->bv_len == 0 ) {
4580 return LDAP_INVALID_SYNTAX;
4583 p = (char *)val->bv_val;
4584 e = p + val->bv_len;
4587 for (; ( p < e ) && ( *p != '=' ); p++ ) {
4588 if ( !AD_CHAR( *p ) ) {
4589 return LDAP_INVALID_SYNTAX;
4594 return LDAP_INVALID_SYNTAX;
4598 for ( p++; ( p < e ) && ( *p != ':' ); p++ ) {
4599 if ( !AD_CHAR( *p ) ) {
4600 return LDAP_INVALID_SYNTAX;
4605 return LDAP_INVALID_SYNTAX;
4609 for ( p++; p < e; p++ ) {
4610 if ( !SLAP_PRINTABLE( *p ) ) {
4611 return LDAP_INVALID_SYNTAX;
4615 return LDAP_SUCCESS;
4618 #define X_BINARY "X-BINARY-TRANSFER-REQUIRED 'TRUE' "
4619 #define X_NOT_H_R "X-NOT-HUMAN-READABLE 'TRUE' "
4621 static slap_syntax_defs_rec syntax_defs[] = {
4622 {"( 1.3.6.1.4.1.1466.115.121.1.1 DESC 'ACI Item' "
4623 X_BINARY X_NOT_H_R ")",
4624 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, NULL, NULL, NULL},
4625 {"( 1.3.6.1.4.1.1466.115.121.1.2 DESC 'Access Point' " X_NOT_H_R ")",
4626 0, NULL, NULL, NULL},
4627 {"( 1.3.6.1.4.1.1466.115.121.1.3 DESC 'Attribute Type Description' )",
4628 0, NULL, NULL, NULL},
4629 {"( 1.3.6.1.4.1.1466.115.121.1.4 DESC 'Audio' "
4631 SLAP_SYNTAX_BLOB, blobValidate, NULL, NULL},
4632 {"( 1.3.6.1.4.1.1466.115.121.1.5 DESC 'Binary' "
4634 SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4635 {"( 1.3.6.1.4.1.1466.115.121.1.6 DESC 'Bit String' )",
4636 0, bitStringValidate, NULL, NULL },
4637 {"( 1.3.6.1.4.1.1466.115.121.1.7 DESC 'Boolean' )",
4638 0, booleanValidate, NULL, NULL},
4639 {"( 1.3.6.1.4.1.1466.115.121.1.8 DESC 'Certificate' "
4640 X_BINARY X_NOT_H_R ")",
4641 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4642 {"( 1.3.6.1.4.1.1466.115.121.1.9 DESC 'Certificate List' "
4643 X_BINARY X_NOT_H_R ")",
4644 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4645 {"( 1.3.6.1.4.1.1466.115.121.1.10 DESC 'Certificate Pair' "
4646 X_BINARY X_NOT_H_R ")",
4647 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4648 {"( 1.3.6.1.4.1.1466.115.121.1.11 DESC 'Country String' )",
4649 0, countryStringValidate, xIA5StringNormalize, NULL},
4650 {"( 1.3.6.1.4.1.1466.115.121.1.12 DESC 'Distinguished Name' )",
4651 0, dnValidate, xdnNormalize, dnPretty2},
4652 {"( 1.3.6.1.4.1.1466.115.121.1.13 DESC 'Data Quality' )",
4653 0, NULL, NULL, NULL},
4654 {"( 1.3.6.1.4.1.1466.115.121.1.14 DESC 'Delivery Method' )",
4655 0, NULL, NULL, NULL},
4656 {"( 1.3.6.1.4.1.1466.115.121.1.15 DESC 'Directory String' )",
4657 0, UTF8StringValidate, xUTF8StringNormalize, NULL},
4658 {"( 1.3.6.1.4.1.1466.115.121.1.16 DESC 'DIT Content Rule Description' )",
4659 0, NULL, NULL, NULL},
4660 {"( 1.3.6.1.4.1.1466.115.121.1.17 DESC 'DIT Structure Rule Description' )",
4661 0, NULL, NULL, NULL},
4662 {"( 1.3.6.1.4.1.1466.115.121.1.19 DESC 'DSA Quality' )",
4663 0, NULL, NULL, NULL},
4664 {"( 1.3.6.1.4.1.1466.115.121.1.20 DESC 'DSE Type' )",
4665 0, NULL, NULL, NULL},
4666 {"( 1.3.6.1.4.1.1466.115.121.1.21 DESC 'Enhanced Guide' )",
4667 0, NULL, NULL, NULL},
4668 {"( 1.3.6.1.4.1.1466.115.121.1.22 DESC 'Facsimile Telephone Number' )",
4669 0, printablesStringValidate, xtelephoneNumberNormalize, NULL},
4670 {"( 1.3.6.1.4.1.1466.115.121.1.23 DESC 'Fax' " X_NOT_H_R ")",
4671 SLAP_SYNTAX_BLOB, NULL, NULL, NULL},
4672 {"( 1.3.6.1.4.1.1466.115.121.1.24 DESC 'Generalized Time' )",
4673 0, generalizedTimeValidate, xgeneralizedTimeNormalize, NULL},
4674 {"( 1.3.6.1.4.1.1466.115.121.1.25 DESC 'Guide' )",
4675 0, NULL, NULL, NULL},
4676 {"( 1.3.6.1.4.1.1466.115.121.1.26 DESC 'IA5 String' )",
4677 0, IA5StringValidate, xIA5StringNormalize, NULL},
4678 {"( 1.3.6.1.4.1.1466.115.121.1.27 DESC 'Integer' )",
4679 0, integerValidate, xintegerNormalize, NULL},
4680 {"( 1.3.6.1.4.1.1466.115.121.1.28 DESC 'JPEG' " X_NOT_H_R ")",
4681 SLAP_SYNTAX_BLOB, blobValidate, NULL, NULL},
4682 {"( 1.3.6.1.4.1.1466.115.121.1.29 DESC 'Master And Shadow Access Points' )",
4683 0, NULL, NULL, NULL},
4684 {"( 1.3.6.1.4.1.1466.115.121.1.30 DESC 'Matching Rule Description' )",
4685 0, NULL, NULL, NULL},
4686 {"( 1.3.6.1.4.1.1466.115.121.1.31 DESC 'Matching Rule Use Description' )",
4687 0, NULL, NULL, NULL},
4688 {"( 1.3.6.1.4.1.1466.115.121.1.32 DESC 'Mail Preference' )",
4689 0, NULL, NULL, NULL},
4690 {"( 1.3.6.1.4.1.1466.115.121.1.33 DESC 'MHS OR Address' )",
4691 0, NULL, NULL, NULL},
4692 {"( 1.3.6.1.4.1.1466.115.121.1.34 DESC 'Name And Optional UID' )",
4693 0, nameUIDValidate, xnameUIDNormalize, NULL},
4694 {"( 1.3.6.1.4.1.1466.115.121.1.35 DESC 'Name Form Description' )",
4695 0, NULL, NULL, NULL},
4696 {"( 1.3.6.1.4.1.1466.115.121.1.36 DESC 'Numeric String' )",
4697 0, numericStringValidate, xnumericStringNormalize, NULL},
4698 {"( 1.3.6.1.4.1.1466.115.121.1.37 DESC 'Object Class Description' )",
4699 0, NULL, NULL, NULL},
4700 {"( 1.3.6.1.4.1.1466.115.121.1.38 DESC 'OID' )",
4701 0, oidValidate, NULL, NULL},
4702 {"( 1.3.6.1.4.1.1466.115.121.1.39 DESC 'Other Mailbox' )",
4703 0, IA5StringValidate, xIA5StringNormalize, NULL},
4704 {"( 1.3.6.1.4.1.1466.115.121.1.40 DESC 'Octet String' )",
4705 0, blobValidate, NULL, NULL},
4706 {"( 1.3.6.1.4.1.1466.115.121.1.41 DESC 'Postal Address' )",
4707 0, UTF8StringValidate, xUTF8StringNormalize, NULL},
4708 {"( 1.3.6.1.4.1.1466.115.121.1.42 DESC 'Protocol Information' )",
4709 0, NULL, NULL, NULL},
4710 {"( 1.3.6.1.4.1.1466.115.121.1.43 DESC 'Presentation Address' )",
4711 0, NULL, NULL, NULL},
4712 {"( 1.3.6.1.4.1.1466.115.121.1.44 DESC 'Printable String' )",
4713 0, printableStringValidate, xIA5StringNormalize, NULL},
4714 {"( 1.3.6.1.4.1.1466.115.121.1.45 DESC 'SubtreeSpecification' "
4715 X_BINARY X_NOT_H_R ")",
4716 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, NULL, NULL, NULL},
4717 {"( 1.3.6.1.4.1.1466.115.121.1.49 DESC 'Supported Algorithm' "
4718 X_BINARY X_NOT_H_R ")",
4719 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4720 {"( 1.3.6.1.4.1.1466.115.121.1.50 DESC 'Telephone Number' )",
4721 0, printableStringValidate, xtelephoneNumberNormalize, NULL},
4722 {"( 1.3.6.1.4.1.1466.115.121.1.51 DESC 'Teletex Terminal Identifier' )",
4723 0, NULL, NULL, NULL},
4724 {"( 1.3.6.1.4.1.1466.115.121.1.52 DESC 'Telex Number' )",
4725 0, printablesStringValidate, xIA5StringNormalize, NULL},
4726 #ifdef SUPPORT_OBSOLETE_UTC_SYNTAX
4727 {"( 1.3.6.1.4.1.1466.115.121.1.53 DESC 'UTC Time' )",
4728 0, utcTimeValidate, xutcTimeNormalize, NULL},
4730 {"( 1.3.6.1.4.1.1466.115.121.1.54 DESC 'LDAP Syntax Description' )",
4731 0, NULL, NULL, NULL},
4732 {"( 1.3.6.1.4.1.1466.115.121.1.55 DESC 'Modify Rights' )",
4733 0, NULL, NULL, NULL},
4734 {"( 1.3.6.1.4.1.1466.115.121.1.56 DESC 'LDAP Schema Definition' )",
4735 0, NULL, NULL, NULL},
4736 {"( 1.3.6.1.4.1.1466.115.121.1.57 DESC 'LDAP Schema Description' )",
4737 0, NULL, NULL, NULL},
4738 {"( 1.3.6.1.4.1.1466.115.121.1.58 DESC 'Substring Assertion' )",
4739 0, NULL, NULL, NULL},
4741 /* RFC 2307 NIS Syntaxes */
4742 {"( 1.3.6.1.1.1.0.0 DESC 'RFC2307 NIS Netgroup Triple' )",
4743 0, nisNetgroupTripleValidate, NULL, NULL},
4744 {"( 1.3.6.1.1.1.0.1 DESC 'RFC2307 Boot Parameter' )",
4745 0, bootParameterValidate, NULL, NULL},
4749 /* These OIDs are not published yet, but will be in the next
4750 * I-D for PKIX LDAPv3 schema as have been advanced by David
4751 * Chadwick in private mail.
4753 {"( 1.2.826.0.1.3344810.7.1 DESC 'Serial Number and Issuer' )",
4754 0, UTF8StringValidate, NULL, NULL},
4757 /* OpenLDAP Experimental Syntaxes */
4758 #ifdef SLAPD_ACI_ENABLED
4759 {"( 1.3.6.1.4.1.4203.666.2.1 DESC 'OpenLDAP Experimental ACI' )",
4761 UTF8StringValidate /* THIS WILL CHANGE FOR NEW ACI SYNTAX */,
4765 #ifdef SLAPD_AUTHPASSWD
4766 /* needs updating */
4767 {"( 1.3.6.1.4.1.4203.666.2.2 DESC 'OpenLDAP authPassword' )",
4768 SLAP_SYNTAX_HIDE, NULL, NULL, NULL},
4771 /* OpenLDAP Void Syntax */
4772 {"( 1.3.6.1.4.1.4203.1.1.1 DESC 'OpenLDAP void' )" ,
4773 SLAP_SYNTAX_HIDE, inValidate, NULL, NULL},
4774 {NULL, 0, NULL, NULL, NULL}
4778 char *certificateExactMatchSyntaxes[] = {
4779 "1.3.6.1.4.1.1466.115.121.1.8" /* certificate */,
4783 char *directoryStringSyntaxes[] = {
4784 "1.3.6.1.4.1.1466.115.121.1.44" /* printableString */,
4787 char *integerFirstComponentMatchSyntaxes[] = {
4788 "1.3.6.1.4.1.1466.115.121.1.27" /* INTEGER */,
4789 "1.3.6.1.4.1.1466.115.121.1.17" /* ditStructureRuleDescription */,
4792 char *objectIdentifierFirstComponentMatchSyntaxes[] = {
4793 "1.3.6.1.4.1.1466.115.121.1.38" /* OID */,
4794 "1.3.6.1.4.1.1466.115.121.1.3" /* attributeTypeDescription */,
4795 "1.3.6.1.4.1.1466.115.121.1.16" /* ditContentRuleDescription */,
4796 "1.3.6.1.4.1.1466.115.121.1.54" /* ldapSyntaxDescription */,
4797 "1.3.6.1.4.1.1466.115.121.1.30" /* matchingRuleDescription */,
4798 "1.3.6.1.4.1.1466.115.121.1.31" /* matchingRuleUseDescription */,
4799 "1.3.6.1.4.1.1466.115.121.1.35" /* nameFormDescription */,
4800 "1.3.6.1.4.1.1466.115.121.1.37" /* objectClassDescription */,
4805 * Other matching rules in X.520 that we do not use (yet):
4807 * 2.5.13.9 numericStringOrderingMatch
4808 * 2.5.13.25 uTCTimeMatch
4809 * 2.5.13.26 uTCTimeOrderingMatch
4810 * 2.5.13.31 directoryStringFirstComponentMatch
4811 * 2.5.13.32 wordMatch
4812 * 2.5.13.33 keywordMatch
4813 * 2.5.13.35 certificateMatch
4814 * 2.5.13.36 certificatePairExactMatch
4815 * 2.5.13.37 certificatePairMatch
4816 * 2.5.13.38 certificateListExactMatch
4817 * 2.5.13.39 certificateListMatch
4818 * 2.5.13.40 algorithmIdentifierMatch
4819 * 2.5.13.41 storedPrefixMatch
4820 * 2.5.13.42 attributeCertificateMatch
4821 * 2.5.13.43 readerAndKeyIDMatch
4822 * 2.5.13.44 attributeIntegrityMatch
4824 static slap_mrule_defs_rec mrule_defs[] = {
4826 * EQUALITY matching rules must be listed after associated APPROX
4827 * matching rules. So, we list all APPROX matching rules first.
4829 #ifndef SLAP_NVALUES
4830 {"( " directoryStringApproxMatchOID " NAME 'directoryStringApproxMatch' "
4831 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4832 SLAP_MR_HIDE | SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT, NULL,
4833 NULL, NULL, directoryStringApproxMatch,
4834 directoryStringApproxIndexer, directoryStringApproxFilter,
4837 {"( " IA5StringApproxMatchOID " NAME 'IA5StringApproxMatch' "
4838 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4839 SLAP_MR_HIDE | SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT, NULL,
4840 NULL, NULL, IA5StringApproxMatch,
4841 IA5StringApproxIndexer, IA5StringApproxFilter,
4846 * Other matching rules
4849 {"( 2.5.13.0 NAME 'objectIdentifierMatch' "
4850 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
4851 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4853 objectIdentifierNormalize, objectIdentifierMatch,
4854 objectIdentifierIndexer, objectIdentifierFilter,
4857 {"( 2.5.13.1 NAME 'distinguishedNameMatch' "
4858 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )",
4859 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4861 distinguishedNameNormalize, distinguishedNameMatch,
4862 distinguishedNameIndexer, distinguishedNameFilter,
4865 {"( 2.5.13.2 NAME 'caseIgnoreMatch' "
4866 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4867 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD,
4868 directoryStringSyntaxes,
4870 caseIgnoreNormalize, caseIgnoreMatch,
4871 caseIgnoreIndexer, caseIgnoreFilter,
4872 directoryStringApproxMatchOID },
4874 {"( 2.5.13.3 NAME 'caseIgnoreOrderingMatch' "
4875 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4876 SLAP_MR_ORDERING, directoryStringSyntaxes,
4877 NULL, caseIgnoreNormalize, caseIgnoreOrderingMatch,
4880 {"( 2.5.13.4 NAME 'caseIgnoreSubstringsMatch' "
4881 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4882 SLAP_MR_SUBSTR, NULL,
4884 caseIgnoreSubstringsMatch,
4885 caseIgnoreSubstringsIndexer, caseIgnoreSubstringsFilter,
4888 {"( 2.5.13.5 NAME 'caseExactMatch' "
4889 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4890 SLAP_MR_EQUALITY | SLAP_MR_EXT, directoryStringSyntaxes,
4892 caseExactNormalize, caseExactMatch,
4893 caseExactIndexer, caseExactFilter,
4894 directoryStringApproxMatchOID },
4896 {"( 2.5.13.6 NAME 'caseExactOrderingMatch' "
4897 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4898 SLAP_MR_ORDERING, directoryStringSyntaxes,
4899 NULL, caseExactNormalize, caseExactOrderingMatch,
4902 {"( 2.5.13.7 NAME 'caseExactSubstringsMatch' "
4903 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4904 SLAP_MR_SUBSTR, directoryStringSyntaxes,
4906 NULL, caseExactSubstringsMatch,
4907 caseExactSubstringsIndexer, caseExactSubstringsFilter,
4910 {"( 2.5.13.8 NAME 'numericStringMatch' "
4911 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 )",
4912 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL,
4914 numericStringNormalize, numericStringMatch,
4915 numericStringIndexer, numericStringFilter,
4918 {"( 2.5.13.10 NAME 'numericStringSubstringsMatch' "
4919 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4920 SLAP_MR_SUBSTR, NULL,
4922 NULL, numericStringSubstringsMatch,
4923 numericStringSubstringsIndexer, numericStringSubstringsFilter,
4926 {"( 2.5.13.11 NAME 'caseIgnoreListMatch' "
4927 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )",
4928 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL,
4929 NULL, NULL, NULL, NULL, NULL, NULL},
4931 {"( 2.5.13.12 NAME 'caseIgnoreListSubstringsMatch' "
4932 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4933 SLAP_MR_SUBSTR, NULL,
4934 NULL, NULL, NULL, NULL, NULL, NULL},
4936 {"( 2.5.13.13 NAME 'booleanMatch' "
4937 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )",
4938 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4941 booleanIndexer, booleanFilter,
4944 {"( 2.5.13.14 NAME 'integerMatch' "
4945 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4946 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4948 integerNormalize, integerMatch,
4949 integerIndexer, integerFilter,
4952 {"( 2.5.13.15 NAME 'integerOrderingMatch' "
4953 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4954 SLAP_MR_ORDERING, NULL, NULL,
4955 integerNormalize, integerOrderingMatch,
4956 integerIndexer, integerFilter,
4959 {"( 2.5.13.16 NAME 'bitStringMatch' "
4960 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.6 )",
4961 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4963 bitStringNormalize, bitStringMatch,
4964 bitStringIndexer, bitStringFilter,
4967 {"( 2.5.13.17 NAME 'octetStringMatch' "
4968 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
4969 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4971 octetStringMatch, octetStringIndexer, octetStringFilter,
4974 {"( 2.5.13.18 NAME 'octetStringOrderingMatch' "
4975 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
4976 SLAP_MR_ORDERING, NULL,
4978 octetStringOrderingMatch, NULL, NULL,
4981 {"( 2.5.13.19 NAME 'octetStringSubstringsMatch' "
4982 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
4983 SLAP_MR_SUBSTR, NULL,
4985 octetStringSubstringsMatch, NULL, NULL,
4988 {"( 2.5.13.20 NAME 'telephoneNumberMatch' "
4989 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 )",
4990 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL,
4992 telephoneNumberNormalize, telephoneNumberMatch,
4993 telephoneNumberIndexer, telephoneNumberFilter,
4996 {"( 2.5.13.21 NAME 'telephoneNumberSubstringsMatch' "
4997 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4998 SLAP_MR_SUBSTR, NULL,
4999 NULL, NULL, telephoneNumberSubstringsMatch,
5000 telephoneNumberSubstringsIndexer, telephoneNumberSubstringsFilter,
5003 {"( 2.5.13.22 NAME 'presentationAddressMatch' "
5004 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.43 )",
5005 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
5010 {"( 2.5.13.23 NAME 'uniqueMemberMatch' "
5011 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.34 )",
5012 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
5014 uniqueMemberNormalize, uniqueMemberMatch,
5018 {"( 2.5.13.24 NAME 'protocolInformationMatch' "
5019 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.42 )",
5020 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
5021 NULL, NULL, NULL, NULL, NULL, NULL},
5023 {"( 2.5.13.27 NAME 'generalizedTimeMatch' "
5024 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
5025 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
5027 generalizedTimeNormalize, generalizedTimeMatch,
5031 {"( 2.5.13.28 NAME 'generalizedTimeOrderingMatch' "
5032 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
5033 SLAP_MR_ORDERING, NULL,
5035 generalizedTimeNormalize, generalizedTimeOrderingMatch,
5039 {"( 2.5.13.29 NAME 'integerFirstComponentMatch' "
5040 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
5041 SLAP_MR_EQUALITY | SLAP_MR_EXT, integerFirstComponentMatchSyntaxes,
5043 integerFirstComponentNormalize, integerMatch,
5047 {"( 2.5.13.30 NAME 'objectIdentifierFirstComponentMatch' "
5048 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
5049 SLAP_MR_EQUALITY | SLAP_MR_EXT,
5050 objectIdentifierFirstComponentMatchSyntaxes,
5052 objectIdentifierFirstComponentNormalize, objectIdentifierMatch,
5056 #ifndef SLAP_NVALUES
5058 {"( 2.5.13.34 NAME 'certificateExactMatch' "
5059 "SYNTAX 1.2.826.0.1.3344810.7.1 )",
5060 SLAP_MR_EQUALITY | SLAP_MR_EXT, certificateExactMatchSyntaxes,
5061 certificateExactConvert, NULL,
5062 certificateExactMatch,
5063 certificateExactIndexer, certificateExactFilter,
5068 {"( 1.3.6.1.4.1.1466.109.114.1 NAME 'caseExactIA5Match' "
5069 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
5070 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
5072 caseExactIA5Normalize, caseExactIA5Match,
5073 caseExactIA5Indexer, caseExactIA5Filter,
5074 IA5StringApproxMatchOID },
5076 {"( 1.3.6.1.4.1.1466.109.114.2 NAME 'caseIgnoreIA5Match' "
5077 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
5078 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL,
5080 NULL, caseIgnoreIA5Match,
5081 caseIgnoreIA5Indexer, caseIgnoreIA5Filter,
5082 IA5StringApproxMatchOID },
5084 {"( 1.3.6.1.4.1.1466.109.114.3 NAME 'caseIgnoreIA5SubstringsMatch' "
5085 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
5086 SLAP_MR_SUBSTR, NULL,
5088 NULL, caseIgnoreIA5SubstringsMatch,
5089 caseIgnoreIA5SubstringsIndexer, caseIgnoreIA5SubstringsFilter,
5092 {"( 1.3.6.1.4.1.4203.1.2.1 NAME 'caseExactIA5SubstringsMatch' "
5093 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
5094 SLAP_MR_SUBSTR, NULL,
5096 NULL, caseExactIA5SubstringsMatch,
5097 caseExactIA5SubstringsIndexer, caseExactIA5SubstringsFilter,
5100 #ifdef SLAPD_AUTHPASSWD
5101 /* needs updating */
5102 {"( 1.3.6.1.4.1.4203.666.4.1 NAME 'authPasswordMatch' "
5103 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
5104 SLAP_MR_EQUALITY, NULL,
5106 authPasswordMatch, NULL, NULL,
5110 #ifdef SLAPD_ACI_ENABLED
5111 {"( 1.3.6.1.4.1.4203.666.4.2 NAME 'OpenLDAPaciMatch' "
5112 "SYNTAX 1.3.6.1.4.1.4203.666.2.1 )",
5113 SLAP_MR_EQUALITY, NULL,
5115 OpenLDAPaciMatch, NULL, NULL,
5119 {"( 1.2.840.113556.1.4.803 NAME 'integerBitAndMatch' "
5120 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
5123 NULL, integerBitAndMatch, NULL, NULL,
5126 {"( 1.2.840.113556.1.4.804 NAME 'integerBitOrMatch' "
5127 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
5130 NULL, integerBitOrMatch, NULL, NULL,
5133 {NULL, SLAP_MR_NONE, NULL,
5134 NULL, NULL, NULL, NULL, NULL,
5139 slap_schema_init( void )
5144 /* we should only be called once (from main) */
5145 assert( schema_init_done == 0 );
5147 for ( i=0; syntax_defs[i].sd_desc != NULL; i++ ) {
5148 res = register_syntax( &syntax_defs[i] );
5151 fprintf( stderr, "slap_schema_init: Error registering syntax %s\n",
5152 syntax_defs[i].sd_desc );
5157 for ( i=0; mrule_defs[i].mrd_desc != NULL; i++ ) {
5158 if( mrule_defs[i].mrd_usage == SLAP_MR_NONE &&
5159 mrule_defs[i].mrd_compat_syntaxes == NULL )
5162 "slap_schema_init: Ignoring unusable matching rule %s\n",
5163 mrule_defs[i].mrd_desc );
5167 res = register_matching_rule( &mrule_defs[i] );
5171 "slap_schema_init: Error registering matching rule %s\n",
5172 mrule_defs[i].mrd_desc );
5177 res = slap_schema_load();
5178 schema_init_done = 1;
5183 schema_destroy( void )