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)
31 #define SLAP_NVALUES 1
35 #define SLAP_MR_DN_FOLD (0)
37 #define SLAP_MR_ASSOCIATED(mr, with) \
38 ((mr) == (with) || (mr)->smr_associated == (with))
40 #define xUTF8StringNormalize NULL
41 #define xIA5StringNormalize NULL
42 #define xtelephoneNumberNormalize NULL
43 #define xgeneralizedTimeNormalize NULL
44 #define xintegerNormalize NULL
45 #define xnumericStringNormalize NULL
46 #define xnameUIDNormalize NULL
47 #define xdnNormalize NULL
49 /* (new) normalization routines */
50 #define caseExactIA5Normalize IA5StringNormalize
51 #define caseIgnoreIA5Normalize IA5StringNormalize
52 #define caseExactNormalize UTF8StringNormalize
53 #define caseIgnoreNormalize UTF8StringNormalize
55 #define integerFirstComponentNormalize NULL
56 #define objectIdentifierNormalize NULL
57 #define objectIdentifierFirstComponentNormalize NULL
59 #define distinguishedNameNormalize dnNormalize
60 #define distinguishedNameMatch dnMatch
61 #define distinguishedNameIndexer octetStringIndexer
62 #define distinguishedNameFilter octetStringFilter
64 #define integerOrderingMatch integerMatch
65 #define integerFirstComponentMatch NULL
66 #define integerIndexer octetStringIndexer
67 #define integerFilter octetStringFilter
69 #define generalizedTimeMatch caseIgnoreIA5Match
70 #define generalizedTimeOrderingMatch caseIgnoreIA5Match
72 #define uniqueMemberMatch dnMatch /* FIXME! */
74 #define objectIdentifierMatch octetStringMatch
75 #define objectIdentifierIndexer octetStringIndexer
76 #define objectIdentifierFilter octetStringFilter
78 #define OpenLDAPaciMatch NULL
80 #define bitStringMatch octetStringMatch
81 #define bitStringIndexer octetStringIndexer
82 #define bitStringFilter octetStringFilter
84 #define caseIgnoreMatch octetStringMatch
85 #define caseIgnoreOrderingMatch octetStringOrderingMatch
86 #define caseIgnoreIndexer octetStringIndexer
87 #define caseIgnoreFilter octetStringFilter
89 #define caseIgnoreSubstringsMatch octetStringSubstringsMatch
90 #define caseIgnoreSubstringsIndexer octetStringSubstringsIndexer
91 #define caseIgnoreSubstringsFilter octetStringSubstringsFilter
93 #define caseExactMatch octetStringMatch
94 #define caseExactOrderingMatch octetStringOrderingMatch
95 #define caseExactIndexer octetStringIndexer
96 #define caseExactFilter octetStringFilter
98 #define caseExactSubstringsMatch octetStringSubstringsMatch
99 #define caseExactSubstringsIndexer octetStringSubstringsIndexer
100 #define caseExactSubstringsFilter octetStringSubstringsFilter
102 #define caseExactIA5Match octetStringMatch
103 #define caseExactIA5Indexer octetStringIndexer
104 #define caseExactIA5Filter octetStringFilter
106 #define caseExactIA5SubstringsMatch octetStringSubstringsMatch
107 #define caseExactIA5SubstringsIndexer octetStringSubstringsIndexer
108 #define caseExactIA5SubstringsFilter octetStringSubstringsFilter
110 #define caseIgnoreIA5Match octetStringMatch
111 #define caseIgnoreIA5Indexer octetStringIndexer
112 #define caseIgnoreIA5Filter octetStringFilter
114 #define caseIgnoreIA5SubstringsMatch caseExactIA5SubstringsMatch
115 #define caseIgnoreIA5SubstringsIndexer caseExactIA5SubstringsIndexer
116 #define caseIgnoreIA5SubstringsFilter caseExactIA5SubstringsFilter
118 #define numericStringMatch octetStringMatch
119 #define numericStringIndexer octetStringIndexer
120 #define numericStringFilter octetStringFilter
122 #define numericStringSubstringsMatch caseExactIA5SubstringsMatch
123 #define numericStringSubstringsIndexer caseExactIA5SubstringsIndexer
124 #define numericStringSubstringsFilter caseExactIA5SubstringsFilter
126 #define telephoneNumberMatch octetStringMatch
127 #define telephoneNumberIndexer octetStringIndexer
128 #define telephoneNumberFilter octetStringFilter
130 #define telephoneNumberSubstringsMatch caseExactIA5SubstringsMatch
131 #define telephoneNumberSubstringsIndexer caseExactIA5SubstringsIndexer
132 #define telephoneNumberSubstringsFilter caseExactIA5SubstringsFilter
134 #define booleanIndexer octetStringIndexer
135 #define booleanFilter octetStringFilter
138 /* validatation routines */
139 #define berValidate blobValidate
141 /* approx matching rules */
143 #define directoryStringApproxMatchOID NULL
144 #define IA5StringApproxMatchOID NULL
146 #define directoryStringApproxMatchOID "1.3.6.1.4.1.4203.666.4.4"
147 #define directoryStringApproxMatch approxMatch
148 #define directoryStringApproxIndexer approxIndexer
149 #define directoryStringApproxFilter approxFilter
150 #define IA5StringApproxMatchOID "1.3.6.1.4.1.4203.666.4.5"
151 #define IA5StringApproxMatch approxMatch
152 #define IA5StringApproxIndexer approxIndexer
153 #define IA5StringApproxFilter approxFilter
158 #define xdnNormalize dnNormalize
160 /* (new) normalization routines */
161 #define caseExactNormalize NULL
162 #define caseExactIA5Normalize NULL
163 #define caseIgnoreNormalize NULL
164 #define caseIgnoreIA5Normalize NULL
165 #define distinguishedNameNormalize NULL
166 #define integerNormalize NULL
167 #define integerFirstComponentNormalize NULL
168 #define numericStringNormalize NULL
169 #define objectIdentifierNormalize NULL
170 #define objectIdentifierFirstComponentNormalize NULL
171 #define generalizedTimeNormalize NULL
172 #define uniqueMemberNormalize NULL
173 #define telephoneNumberNormalize NULL
176 /* matching routines */
177 #define bitStringMatch octetStringMatch
178 #define bitStringIndexer octetStringIndexer
179 #define bitStringFilter octetStringFilter
181 #define numericStringMatch caseIgnoreIA5Match
182 #define numericStringIndexer NULL
183 #define numericStringFilter NULL
184 #define numericStringSubstringsIndexer NULL
185 #define numericStringSubstringsFilter NULL
187 #define objectIdentifierMatch octetStringMatch
188 #define objectIdentifierIndexer caseIgnoreIA5Indexer
189 #define objectIdentifierFilter caseIgnoreIA5Filter
191 #define octetStringSubstringsMatch NULL
192 #define OpenLDAPaciMatch NULL
194 #define generalizedTimeMatch caseIgnoreIA5Match
195 #define generalizedTimeOrderingMatch caseIgnoreIA5Match
197 #define uniqueMemberMatch dnMatch
198 #define numericStringSubstringsMatch NULL
200 #define caseExactIndexer caseExactIgnoreIndexer
201 #define caseExactFilter caseExactIgnoreFilter
202 #define caseExactOrderingMatch caseExactMatch
203 #define caseExactSubstringsMatch caseExactIgnoreSubstringsMatch
204 #define caseExactSubstringsIndexer caseExactIgnoreSubstringsIndexer
205 #define caseExactSubstringsFilter caseExactIgnoreSubstringsFilter
206 #define caseIgnoreIndexer caseExactIgnoreIndexer
207 #define caseIgnoreFilter caseExactIgnoreFilter
208 #define caseIgnoreOrderingMatch caseIgnoreMatch
209 #define caseIgnoreSubstringsMatch caseExactIgnoreSubstringsMatch
210 #define caseIgnoreSubstringsIndexer caseExactIgnoreSubstringsIndexer
211 #define caseIgnoreSubstringsFilter caseExactIgnoreSubstringsFilter
213 #define integerOrderingMatch integerMatch
214 #define integerFirstComponentMatch integerMatch
216 #define distinguishedNameMatch dnMatch
217 #define distinguishedNameIndexer caseExactIgnoreIndexer
218 #define distinguishedNameFilter caseExactIgnoreFilter
220 #define telephoneNumberMatch caseIgnoreIA5Match
221 #define telephoneNumberSubstringsMatch caseIgnoreIA5SubstringsMatch
222 #define telephoneNumberIndexer caseIgnoreIA5Indexer
223 #define telephoneNumberFilter caseIgnoreIA5Filter
224 #define telephoneNumberSubstringsIndexer caseIgnoreIA5SubstringsIndexer
225 #define telephoneNumberSubstringsFilter caseIgnoreIA5SubstringsFilter
227 #define booleanIndexer octetStringIndexer
228 #define booleanFilter octetStringFilter
232 static char *bvcasechr( struct berval *bv, unsigned char c, ber_len_t *len )
235 char lower = TOLOWER( c );
236 char upper = TOUPPER( c );
238 if( c == 0 ) return NULL;
240 for( i=0; i < bv->bv_len; i++ ) {
241 if( upper == bv->bv_val[i] || lower == bv->bv_val[i] ) {
243 return &bv->bv_val[i];
256 struct berval *value,
257 void *assertedValue )
259 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
262 match = memcmp( value->bv_val,
263 ((struct berval *) assertedValue)->bv_val,
272 octetStringOrderingMatch(
277 struct berval *value,
278 void *assertedValue )
280 ber_len_t v_len = value->bv_len;
281 ber_len_t av_len = ((struct berval *) assertedValue)->bv_len;
283 int match = memcmp( value->bv_val,
284 ((struct berval *) assertedValue)->bv_val,
285 (v_len < av_len ? v_len : av_len) );
287 if( match == 0 ) match = v_len - av_len;
293 /* Index generation function */
294 int octetStringIndexer(
299 struct berval *prefix,
306 HASH_CONTEXT HASHcontext;
307 unsigned char HASHdigest[HASH_BYTES];
308 struct berval digest;
309 digest.bv_val = HASHdigest;
310 digest.bv_len = sizeof(HASHdigest);
312 for( i=0; values[i].bv_val != NULL; i++ ) {
313 /* just count them */
316 /* we should have at least one value at this point */
319 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
321 slen = syntax->ssyn_oidlen;
322 mlen = mr->smr_oidlen;
324 for( i=0; values[i].bv_val != NULL; i++ ) {
325 HASH_Init( &HASHcontext );
326 if( prefix != NULL && prefix->bv_len > 0 ) {
327 HASH_Update( &HASHcontext,
328 prefix->bv_val, prefix->bv_len );
330 HASH_Update( &HASHcontext,
331 syntax->ssyn_oid, slen );
332 HASH_Update( &HASHcontext,
334 HASH_Update( &HASHcontext,
335 values[i].bv_val, values[i].bv_len );
336 HASH_Final( HASHdigest, &HASHcontext );
338 ber_dupbv( &keys[i], &digest );
341 keys[i].bv_val = NULL;
349 /* Index generation function */
350 int octetStringFilter(
355 struct berval *prefix,
356 void * assertedValue,
361 HASH_CONTEXT HASHcontext;
362 unsigned char HASHdigest[HASH_BYTES];
363 struct berval *value = (struct berval *) assertedValue;
364 struct berval digest;
365 digest.bv_val = HASHdigest;
366 digest.bv_len = sizeof(HASHdigest);
368 slen = syntax->ssyn_oidlen;
369 mlen = mr->smr_oidlen;
371 keys = ch_malloc( sizeof( struct berval ) * 2 );
373 HASH_Init( &HASHcontext );
374 if( prefix != NULL && prefix->bv_len > 0 ) {
375 HASH_Update( &HASHcontext,
376 prefix->bv_val, prefix->bv_len );
378 HASH_Update( &HASHcontext,
379 syntax->ssyn_oid, slen );
380 HASH_Update( &HASHcontext,
382 HASH_Update( &HASHcontext,
383 value->bv_val, value->bv_len );
384 HASH_Final( HASHdigest, &HASHcontext );
386 ber_dupbv( keys, &digest );
387 keys[1].bv_val = NULL;
400 /* no value allowed */
401 return LDAP_INVALID_SYNTAX;
409 /* any value allowed */
420 /* very unforgiving validation, requires no normalization
421 * before simplistic matching
423 if( in->bv_len < 3 ) {
424 return LDAP_INVALID_SYNTAX;
428 * rfc 2252 section 6.3 Bit String
429 * bitstring = "'" *binary-digit "'"
430 * binary-digit = "0" / "1"
431 * example: '0101111101'B
434 if( in->bv_val[0] != '\'' ||
435 in->bv_val[in->bv_len-2] != '\'' ||
436 in->bv_val[in->bv_len-1] != 'B' )
438 return LDAP_INVALID_SYNTAX;
441 for( i=in->bv_len-3; i>0; i-- ) {
442 if( in->bv_val[i] != '0' && in->bv_val[i] != '1' ) {
443 return LDAP_INVALID_SYNTAX;
458 if( in->bv_len == 0 ) return LDAP_SUCCESS;
460 ber_dupbv( &dn, in );
461 if( !dn.bv_val ) return LDAP_OTHER;
463 if( dn.bv_val[dn.bv_len-1] == 'B'
464 && dn.bv_val[dn.bv_len-2] == '\'' )
466 /* assume presence of optional UID */
469 for(i=dn.bv_len-3; i>1; i--) {
470 if( dn.bv_val[i] != '0' && dn.bv_val[i] != '1' ) {
474 if( dn.bv_val[i] != '\'' || dn.bv_val[i-1] != '#' ) {
475 ber_memfree( dn.bv_val );
476 return LDAP_INVALID_SYNTAX;
479 /* trim the UID to allow use of dnValidate */
480 dn.bv_val[i-1] = '\0';
484 rc = dnValidate( NULL, &dn );
486 ber_memfree( dn.bv_val );
492 uniqueMemberNormalize(
497 struct berval *normalized )
503 struct berval *normalized )
509 ber_dupbv( &out, val );
510 if( out.bv_len != 0 ) {
511 struct berval uid = { 0, NULL };
513 if( out.bv_val[out.bv_len-1] == 'B'
514 && out.bv_val[out.bv_len-2] == '\'' )
516 /* assume presence of optional UID */
517 uid.bv_val = strrchr( out.bv_val, '#' );
519 if( uid.bv_val == NULL ) {
521 return LDAP_INVALID_SYNTAX;
524 uid.bv_len = out.bv_len - (uid.bv_val - out.bv_val);
525 out.bv_len -= uid.bv_len--;
527 /* temporarily trim the UID */
528 *(uid.bv_val++) = '\0';
531 rc = dnNormalize2( NULL, &out, normalized );
533 if( rc != LDAP_SUCCESS ) {
535 return LDAP_INVALID_SYNTAX;
539 normalized->bv_val = ch_realloc( normalized->bv_val,
540 normalized->bv_len + uid.bv_len + sizeof("#") );
542 /* insert the separator */
543 normalized->bv_val[normalized->bv_len++] = '#';
546 AC_MEMCPY( &normalized->bv_val[normalized->bv_len],
547 uid.bv_val, uid.bv_len );
548 normalized->bv_len += uid.bv_len;
551 normalized->bv_val[normalized->bv_len] = '\0';
561 * Handling boolean syntax and matching is quite rigid.
562 * A more flexible approach would be to allow a variety
563 * of strings to be normalized and prettied into TRUE
571 /* very unforgiving validation, requires no normalization
572 * before simplistic matching
575 if( in->bv_len == 4 ) {
576 if( !memcmp( in->bv_val, "TRUE", 4 ) ) {
579 } else if( in->bv_len == 5 ) {
580 if( !memcmp( in->bv_val, "FALSE", 5 ) ) {
585 return LDAP_INVALID_SYNTAX;
594 struct berval *value,
595 void *assertedValue )
597 /* simplistic matching allowed by rigid validation */
598 struct berval *asserted = (struct berval *) assertedValue;
599 *matchp = value->bv_len != asserted->bv_len;
603 /*-------------------------------------------------------------------
604 LDAP/X.500 string syntax / matching rules have a few oddities. This
605 comment attempts to detail how slapd(8) treats them.
608 StringSyntax X.500 LDAP Matching/Comments
609 DirectoryString CHOICE UTF8 i/e + ignore insignificant spaces
610 PrintableString subset subset i/e + ignore insignificant spaces
611 PrintableString subset subset i/e + ignore insignificant spaces
612 NumericString subset subset ignore all spaces
613 IA5String ASCII ASCII i/e + ignore insignificant spaces
614 TeletexString T.61 T.61 i/e + ignore insignificant spaces
616 TelephoneNumber subset subset i + ignore all spaces and "-"
618 See draft-ietf-ldapbis-strpro for details (once published).
622 In X.500(93), a directory string can be either a PrintableString,
623 a bmpString, or a UniversalString (e.g., UCS (a subset of Unicode)).
624 In later versions, more CHOICEs were added. In all cases the string
627 In LDAPv3, a directory string is a UTF-8 encoded UCS string.
628 A directory string cannot be zero length.
630 For matching, there are both case ignore and exact rules. Both
631 also require that "insignificant" spaces be ignored.
632 spaces before the first non-space are ignored;
633 spaces after the last non-space are ignored;
634 spaces after a space are ignored.
635 Note: by these rules (and as clarified in X.520), a string of only
636 spaces is to be treated as if held one space, not empty (which
637 would be a syntax error).
640 In ASN.1, numeric string is just a string of digits and spaces
641 and could be empty. However, in X.500, all attribute values of
642 numeric string carry a non-empty constraint. For example:
644 internationalISDNNumber ATTRIBUTE ::= {
645 WITH SYNTAX InternationalISDNNumber
646 EQUALITY MATCHING RULE numericStringMatch
647 SUBSTRINGS MATCHING RULE numericStringSubstringsMatch
648 ID id-at-internationalISDNNumber }
649 InternationalISDNNumber ::=
650 NumericString (SIZE(1..ub-international-isdn-number))
652 Unforunately, some assertion values are don't carry the same
653 constraint (but its unclear how such an assertion could ever
654 be true). In LDAP, there is one syntax (numericString) not two
655 (numericString with constraint, numericString without constraint).
656 This should be treated as numericString with non-empty constraint.
657 Note that while someone may have no ISDN number, there are no ISDN
658 numbers which are zero length.
660 In matching, spaces are ignored.
663 In ASN.1, Printable string is just a string of printable characters
664 and can be empty. In X.500, semantics much like NumericString (see
665 serialNumber for a like example) excepting uses insignificant space
666 handling instead of ignore all spaces.
669 Basically same as PrintableString. There are no examples in X.500,
670 but same logic applies. So we require them to be non-empty as
673 -------------------------------------------------------------------*/
682 unsigned char *u = in->bv_val;
684 if( in->bv_len == 0 && syntax == slap_schema.si_syn_directoryString ) {
685 /* directory strings cannot be empty */
686 return LDAP_INVALID_SYNTAX;
689 for( count = in->bv_len; count > 0; count-=len, u+=len ) {
690 /* get the length indicated by the first byte */
691 len = LDAP_UTF8_CHARLEN2( u, len );
693 /* very basic checks */
696 if( (u[5] & 0xC0) != 0x80 ) {
697 return LDAP_INVALID_SYNTAX;
700 if( (u[4] & 0xC0) != 0x80 ) {
701 return LDAP_INVALID_SYNTAX;
704 if( (u[3] & 0xC0) != 0x80 ) {
705 return LDAP_INVALID_SYNTAX;
708 if( (u[2] & 0xC0 )!= 0x80 ) {
709 return LDAP_INVALID_SYNTAX;
712 if( (u[1] & 0xC0) != 0x80 ) {
713 return LDAP_INVALID_SYNTAX;
716 /* CHARLEN already validated it */
719 return LDAP_INVALID_SYNTAX;
722 /* make sure len corresponds with the offset
723 to the next character */
724 if( LDAP_UTF8_OFFSET( u ) != len ) return LDAP_INVALID_SYNTAX;
728 return LDAP_INVALID_SYNTAX;
741 struct berval *normalized )
743 struct berval tmp, nvalue;
747 if( val->bv_val == NULL ) {
748 /* assume we're dealing with a syntax (e.g., UTF8String)
749 * which allows empty strings
751 normalized->bv_len = 0;
752 normalized->bv_val = NULL;
756 flags = SLAP_MR_ASSOCIATED(mr, slap_schema.si_mr_caseExactMatch )
757 ? LDAP_UTF8_NOCASEFOLD : LDAP_UTF8_CASEFOLD;
758 flags |= ( ( use & SLAP_MR_EQUALITY_APPROX ) == SLAP_MR_EQUALITY_APPROX )
759 ? LDAP_UTF8_APPROX : 0;
761 val = UTF8bvnormalize( val, &tmp, flags );
766 /* collapse spaces (in place) */
768 nvalue.bv_val = tmp.bv_val;
770 wasspace=1; /* trim leading spaces */
771 for( i=0; i<tmp.bv_len; i++) {
772 if ( ASCII_SPACE( tmp.bv_val[i] )) {
773 if( wasspace++ == 0 ) {
774 /* trim repeated spaces */
775 nvalue.bv_val[nvalue.bv_len++] = tmp.bv_val[i];
779 nvalue.bv_val[nvalue.bv_len++] = tmp.bv_val[i];
783 if( nvalue.bv_len ) {
785 /* last character was a space, trim it */
788 nvalue.bv_val[nvalue.bv_len] = '\0';
791 /* string of all spaces is treated as one space */
792 nvalue.bv_val[0] = ' ';
793 nvalue.bv_val[1] = '\0';
797 *normalized = nvalue;
803 xUTF8StringNormalize(
806 struct berval *normalized )
811 /* validator should have refused an empty string */
812 assert( val->bv_len );
816 /* Ignore initial whitespace */
817 /* All space is ASCII. All ASCII is 1 byte */
818 for ( ; p < val->bv_val + val->bv_len && ASCII_SPACE( p[ 0 ] ); p++ );
820 normalized->bv_len = val->bv_len - (p - val->bv_val);
822 if( !normalized->bv_len ) {
823 ber_mem2bv( " ", 1, 1, normalized );
827 ber_mem2bv( p, normalized->bv_len, 1, normalized );
828 e = normalized->bv_val + normalized->bv_len;
830 assert( normalized->bv_val );
832 p = q = normalized->bv_val;
837 if ( ASCII_SPACE( *p ) ) {
842 /* Ignore the extra whitespace */
843 while ( ASCII_SPACE( *p ) ) {
847 len = LDAP_UTF8_COPY(q,p);
853 assert( normalized->bv_val <= p );
854 assert( q+len <= p );
856 /* cannot start with a space */
857 assert( !ASCII_SPACE( normalized->bv_val[0] ) );
860 * If the string ended in space, backup the pointer one
861 * position. One is enough because the above loop collapsed
862 * all whitespace to a single space.
870 /* cannot end with a space */
871 assert( !ASCII_SPACE( *q ) );
878 normalized->bv_len = q - normalized->bv_val;
883 /* Returns Unicode canonically normalized copy of a substring assertion
884 * Skipping attribute description */
885 static SubstringsAssertion *
886 UTF8SubstringsAssertionNormalize(
887 SubstringsAssertion *sa,
890 SubstringsAssertion *nsa;
893 nsa = (SubstringsAssertion *)SLAP_CALLOC( 1, sizeof(SubstringsAssertion) );
898 if( sa->sa_initial.bv_val != NULL ) {
899 UTF8bvnormalize( &sa->sa_initial, &nsa->sa_initial, casefold );
900 if( nsa->sa_initial.bv_val == NULL ) {
905 if( sa->sa_any != NULL ) {
906 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
909 nsa->sa_any = (struct berval *)
910 SLAP_MALLOC( (i + 1) * sizeof(struct berval) );
911 if( nsa->sa_any == NULL ) {
915 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
916 UTF8bvnormalize( &sa->sa_any[i], &nsa->sa_any[i],
918 if( nsa->sa_any[i].bv_val == NULL ) {
922 nsa->sa_any[i].bv_val = NULL;
925 if( sa->sa_final.bv_val != NULL ) {
926 UTF8bvnormalize( &sa->sa_final, &nsa->sa_final, casefold );
927 if( nsa->sa_final.bv_val == NULL ) {
935 if ( nsa->sa_final.bv_val ) free( nsa->sa_final.bv_val );
936 if ( nsa->sa_any ) ber_bvarray_free( nsa->sa_any );
937 if ( nsa->sa_initial.bv_val ) free( nsa->sa_initial.bv_val );
942 #ifndef SLAPD_APPROX_OLDSINGLESTRING
944 #if defined(SLAPD_APPROX_INITIALS)
945 #define SLAPD_APPROX_DELIMITER "._ "
946 #define SLAPD_APPROX_WORDLEN 2
948 #define SLAPD_APPROX_DELIMITER " "
949 #define SLAPD_APPROX_WORDLEN 1
958 struct berval *value,
959 void *assertedValue )
961 struct berval *nval, *assertv;
962 char *val, **values, **words, *c;
963 int i, count, len, nextchunk=0, nextavail=0;
965 /* Yes, this is necessary */
966 nval = UTF8bvnormalize( value, NULL, LDAP_UTF8_APPROX );
972 /* Yes, this is necessary */
973 assertv = UTF8bvnormalize( ((struct berval *)assertedValue),
974 NULL, LDAP_UTF8_APPROX );
975 if( assertv == NULL ) {
981 /* Isolate how many words there are */
982 for ( c = nval->bv_val, count = 1; *c; c++ ) {
983 c = strpbrk( c, SLAPD_APPROX_DELIMITER );
984 if ( c == NULL ) break;
989 /* Get a phonetic copy of each word */
990 words = (char **)ch_malloc( count * sizeof(char *) );
991 values = (char **)ch_malloc( count * sizeof(char *) );
992 for ( c = nval->bv_val, i = 0; i < count; i++, c += strlen(c) + 1 ) {
994 values[i] = phonetic(c);
997 /* Work through the asserted value's words, to see if at least some
998 of the words are there, in the same order. */
1000 while ( (ber_len_t) nextchunk < assertv->bv_len ) {
1001 len = strcspn( assertv->bv_val + nextchunk, SLAPD_APPROX_DELIMITER);
1006 #if defined(SLAPD_APPROX_INITIALS)
1007 else if( len == 1 ) {
1008 /* Single letter words need to at least match one word's initial */
1009 for( i=nextavail; i<count; i++ )
1010 if( !strncasecmp( assertv->bv_val + nextchunk, words[i], 1 )) {
1017 /* Isolate the next word in the asserted value and phonetic it */
1018 assertv->bv_val[nextchunk+len] = '\0';
1019 val = phonetic( assertv->bv_val + nextchunk );
1021 /* See if this phonetic chunk is in the remaining words of *value */
1022 for( i=nextavail; i<count; i++ ){
1023 if( !strcmp( val, values[i] ) ){
1031 /* This chunk in the asserted value was NOT within the *value. */
1037 /* Go on to the next word in the asserted value */
1041 /* If some of the words were seen, call it a match */
1042 if( nextavail > 0 ) {
1049 /* Cleanup allocs */
1050 ber_bvfree( assertv );
1051 for( i=0; i<count; i++ ) {
1052 ch_free( values[i] );
1058 return LDAP_SUCCESS;
1067 struct berval *prefix,
1072 int i,j, len, wordcount, keycount=0;
1073 struct berval *newkeys;
1074 BerVarray keys=NULL;
1076 for( j=0; values[j].bv_val != NULL; j++ ) {
1077 struct berval val = { 0, NULL };
1078 /* Yes, this is necessary */
1079 UTF8bvnormalize( &values[j], &val, LDAP_UTF8_APPROX );
1080 assert( val.bv_val != NULL );
1082 /* Isolate how many words there are. There will be a key for each */
1083 for( wordcount = 0, c = val.bv_val; *c; c++) {
1084 len = strcspn(c, SLAPD_APPROX_DELIMITER);
1085 if( len >= SLAPD_APPROX_WORDLEN ) wordcount++;
1087 if (*c == '\0') break;
1091 /* Allocate/increase storage to account for new keys */
1092 newkeys = (struct berval *)ch_malloc( (keycount + wordcount + 1)
1093 * sizeof(struct berval) );
1094 AC_MEMCPY( newkeys, keys, keycount * sizeof(struct berval) );
1095 if( keys ) ch_free( keys );
1098 /* Get a phonetic copy of each word */
1099 for( c = val.bv_val, i = 0; i < wordcount; c += len + 1 ) {
1101 if( len < SLAPD_APPROX_WORDLEN ) continue;
1102 ber_str2bv( phonetic( c ), 0, 0, &keys[keycount] );
1107 ber_memfree( val.bv_val );
1109 keys[keycount].bv_val = NULL;
1112 return LDAP_SUCCESS;
1121 struct berval *prefix,
1122 void * assertedValue,
1130 /* Yes, this is necessary */
1131 val = UTF8bvnormalize( ((struct berval *)assertedValue),
1132 NULL, LDAP_UTF8_APPROX );
1133 if( val == NULL || val->bv_val == NULL ) {
1134 keys = (struct berval *)ch_malloc( sizeof(struct berval) );
1135 keys[0].bv_val = NULL;
1138 return LDAP_SUCCESS;
1141 /* Isolate how many words there are. There will be a key for each */
1142 for( count = 0,c = val->bv_val; *c; c++) {
1143 len = strcspn(c, SLAPD_APPROX_DELIMITER);
1144 if( len >= SLAPD_APPROX_WORDLEN ) count++;
1146 if (*c == '\0') break;
1150 /* Allocate storage for new keys */
1151 keys = (struct berval *)ch_malloc( (count + 1) * sizeof(struct berval) );
1153 /* Get a phonetic copy of each word */
1154 for( c = val->bv_val, i = 0; i < count; c += len + 1 ) {
1156 if( len < SLAPD_APPROX_WORDLEN ) continue;
1157 ber_str2bv( phonetic( c ), 0, 0, &keys[i] );
1163 keys[count].bv_val = NULL;
1166 return LDAP_SUCCESS;
1171 /* No other form of Approximate Matching is defined */
1179 struct berval *value,
1180 void *assertedValue )
1182 char *vapprox, *avapprox;
1185 /* Yes, this is necessary */
1186 s = UTF8normalize( value, UTF8_NOCASEFOLD );
1189 return LDAP_SUCCESS;
1192 /* Yes, this is necessary */
1193 t = UTF8normalize( ((struct berval *)assertedValue),
1198 return LDAP_SUCCESS;
1201 vapprox = phonetic( strip8bitChars( s ) );
1202 avapprox = phonetic( strip8bitChars( t ) );
1207 *matchp = strcmp( vapprox, avapprox );
1210 ch_free( avapprox );
1212 return LDAP_SUCCESS;
1221 struct berval *prefix,
1229 for( i=0; values[i].bv_val != NULL; i++ ) {
1230 /* empty - just count them */
1233 /* we should have at least one value at this point */
1236 keys = (struct berval *)ch_malloc( sizeof( struct berval ) * (i+1) );
1238 /* Copy each value and run it through phonetic() */
1239 for( i=0; values[i].bv_val != NULL; i++ ) {
1240 /* Yes, this is necessary */
1241 s = UTF8normalize( &values[i], UTF8_NOCASEFOLD );
1243 /* strip 8-bit chars and run through phonetic() */
1244 ber_str2bv( phonetic( strip8bitChars( s ) ), 0, 0, &keys[i] );
1247 keys[i].bv_val = NULL;
1250 return LDAP_SUCCESS;
1260 struct berval *prefix,
1261 void * assertedValue,
1267 keys = (struct berval *)ch_malloc( sizeof( struct berval * ) * 2 );
1269 /* Yes, this is necessary */
1270 s = UTF8normalize( ((struct berval *)assertedValue),
1275 /* strip 8-bit chars and run through phonetic() */
1276 keys[0] = ber_bvstr( phonetic( strip8bitChars( s ) ) );
1282 return LDAP_SUCCESS;
1293 struct berval *value,
1294 void *assertedValue )
1296 *matchp = UTF8bvnormcmp( value,
1297 (struct berval *) assertedValue,
1298 LDAP_UTF8_NOCASEFOLD );
1299 return LDAP_SUCCESS;
1303 caseExactIgnoreSubstringsMatch(
1308 struct berval *value,
1309 void *assertedValue )
1312 SubstringsAssertion *sub = NULL;
1313 struct berval left = { 0, NULL };
1319 casefold = ( mr != slap_schema.si_mr_caseExactSubstringsMatch )
1320 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1322 if ( UTF8bvnormalize( value, &left, casefold ) == NULL ) {
1328 sub = UTF8SubstringsAssertionNormalize( assertedValue, casefold );
1334 /* Add up asserted input length */
1335 if( sub->sa_initial.bv_val ) {
1336 inlen += sub->sa_initial.bv_len;
1339 for(i=0; sub->sa_any[i].bv_val != NULL; i++) {
1340 inlen += sub->sa_any[i].bv_len;
1343 if( sub->sa_final.bv_val ) {
1344 inlen += sub->sa_final.bv_len;
1347 if( sub->sa_initial.bv_val ) {
1348 if( inlen > left.bv_len ) {
1353 match = memcmp( sub->sa_initial.bv_val, left.bv_val,
1354 sub->sa_initial.bv_len );
1360 left.bv_val += sub->sa_initial.bv_len;
1361 left.bv_len -= sub->sa_initial.bv_len;
1362 inlen -= sub->sa_initial.bv_len;
1365 if( sub->sa_final.bv_val ) {
1366 if( inlen > left.bv_len ) {
1371 match = memcmp( sub->sa_final.bv_val,
1372 &left.bv_val[left.bv_len - sub->sa_final.bv_len],
1373 sub->sa_final.bv_len );
1379 left.bv_len -= sub->sa_final.bv_len;
1380 inlen -= sub->sa_final.bv_len;
1384 for(i=0; sub->sa_any[i].bv_val; i++) {
1389 if( inlen > left.bv_len ) {
1390 /* not enough length */
1395 if( sub->sa_any[i].bv_len == 0 ) {
1399 p = ber_bvchr( &left, *sub->sa_any[i].bv_val );
1405 idx = p - left.bv_val;
1407 if( idx >= left.bv_len ) {
1408 /* this shouldn't happen */
1410 if ( sub->sa_final.bv_val )
1411 ch_free( sub->sa_final.bv_val );
1413 ber_bvarray_free( sub->sa_any );
1414 if ( sub->sa_initial.bv_val )
1415 ch_free( sub->sa_initial.bv_val );
1423 if( sub->sa_any[i].bv_len > left.bv_len ) {
1424 /* not enough left */
1429 match = memcmp( left.bv_val,
1430 sub->sa_any[i].bv_val,
1431 sub->sa_any[i].bv_len );
1439 left.bv_val += sub->sa_any[i].bv_len;
1440 left.bv_len -= sub->sa_any[i].bv_len;
1441 inlen -= sub->sa_any[i].bv_len;
1448 if ( sub->sa_final.bv_val ) free( sub->sa_final.bv_val );
1449 if ( sub->sa_any ) ber_bvarray_free( sub->sa_any );
1450 if ( sub->sa_initial.bv_val ) free( sub->sa_initial.bv_val );
1454 return LDAP_SUCCESS;
1457 /* Index generation function */
1458 static int caseExactIgnoreIndexer(
1463 struct berval *prefix,
1468 unsigned casefold,wasspace;
1471 HASH_CONTEXT HASHcontext;
1472 unsigned char HASHdigest[HASH_BYTES];
1473 struct berval digest;
1474 digest.bv_val = HASHdigest;
1475 digest.bv_len = sizeof(HASHdigest);
1477 for( i=0; values[i].bv_val != NULL; i++ ) {
1478 /* empty - just count them */
1481 /* we should have at least one value at this point */
1484 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
1486 slen = syntax->ssyn_oidlen;
1487 mlen = mr->smr_oidlen;
1489 casefold = ( mr != slap_schema.si_mr_caseExactMatch )
1490 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1492 for( i=0; values[i].bv_val != NULL; i++ ) {
1493 struct berval value, nvalue;
1494 UTF8bvnormalize( &values[i], &value, casefold );
1496 /* collapse spaces (in place) */
1498 nvalue.bv_val = value.bv_val;
1501 for( j=0; j<value.bv_len; j++) {
1502 if ( ASCII_SPACE( value.bv_val[j] )) {
1503 if( wasspace++ == 0 ) {
1504 nvalue.bv_val[nvalue.bv_len++] = value.bv_val[j];
1508 nvalue.bv_val[nvalue.bv_len++] = value.bv_val[j];
1512 if( nvalue.bv_len == 0 ) {
1513 nvalue.bv_val = " ";
1514 nvalue.bv_len = sizeof(" ")-1;
1516 if( wasspace ) --nvalue.bv_len;
1517 nvalue.bv_val[nvalue.bv_len] = '\0';
1520 HASH_Init( &HASHcontext );
1521 if( prefix != NULL && prefix->bv_len > 0 ) {
1522 HASH_Update( &HASHcontext,
1523 prefix->bv_val, prefix->bv_len );
1525 HASH_Update( &HASHcontext,
1526 syntax->ssyn_oid, slen );
1527 HASH_Update( &HASHcontext,
1528 mr->smr_oid, mlen );
1529 HASH_Update( &HASHcontext,
1530 nvalue.bv_val, nvalue.bv_len );
1531 HASH_Final( HASHdigest, &HASHcontext );
1533 free( value.bv_val );
1534 ber_dupbv( &keys[i], &digest );
1537 keys[i].bv_val = NULL;
1539 return LDAP_SUCCESS;
1542 /* Index generation function */
1543 static int caseExactIgnoreFilter(
1548 struct berval *prefix,
1549 void * assertedValue,
1555 HASH_CONTEXT HASHcontext;
1556 unsigned char HASHdigest[HASH_BYTES];
1557 struct berval value = { 0, NULL };
1558 struct berval digest;
1560 digest.bv_val = HASHdigest;
1561 digest.bv_len = sizeof(HASHdigest);
1563 slen = syntax->ssyn_oidlen;
1564 mlen = mr->smr_oidlen;
1566 casefold = ( mr != slap_schema.si_mr_caseExactMatch )
1567 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1569 UTF8bvnormalize( (struct berval *) assertedValue, &value, casefold );
1570 /* This usually happens if filter contains bad UTF8 */
1571 if( value.bv_val == NULL ) {
1572 keys = ch_malloc( sizeof( struct berval ) );
1573 keys[0].bv_val = NULL;
1574 return LDAP_SUCCESS;
1577 keys = ch_malloc( sizeof( struct berval ) * 2 );
1579 HASH_Init( &HASHcontext );
1580 if( prefix != NULL && prefix->bv_len > 0 ) {
1581 HASH_Update( &HASHcontext,
1582 prefix->bv_val, prefix->bv_len );
1584 HASH_Update( &HASHcontext,
1585 syntax->ssyn_oid, slen );
1586 HASH_Update( &HASHcontext,
1587 mr->smr_oid, mlen );
1588 HASH_Update( &HASHcontext,
1589 value.bv_val, value.bv_len );
1590 HASH_Final( HASHdigest, &HASHcontext );
1592 ber_dupbv( keys, &digest );
1593 keys[1].bv_val = NULL;
1595 free( value.bv_val );
1598 return LDAP_SUCCESS;
1602 /* Substrings Index generation function */
1605 octetStringSubstringsIndexer
1607 caseExactIgnoreSubstringsIndexer
1613 struct berval *prefix,
1617 ber_len_t i, j, nkeys;
1620 #ifndef SLAP_NVALUES
1621 BerVarray tvalues, nvalues;
1622 unsigned casefold, wasspace;
1625 HASH_CONTEXT HASHcontext;
1626 unsigned char HASHdigest[HASH_BYTES];
1627 struct berval digest;
1628 digest.bv_val = HASHdigest;
1629 digest.bv_len = sizeof(HASHdigest);
1631 #ifndef SLAP_NVALUES
1632 for( i=0; values[i].bv_val != NULL; i++ ) {
1633 /* empty - just count them */
1636 /* we should have at least one value at this point */
1639 casefold = ( mr != slap_schema.si_mr_caseExactSubstringsMatch )
1640 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1642 tvalues = ch_malloc( sizeof( struct berval ) * (i+1) );
1643 nvalues = ch_malloc( sizeof( struct berval ) * (i+1) );
1645 for( i=0; values[i].bv_val != NULL; i++ ) {
1646 UTF8bvnormalize( &values[i], &tvalues[i], casefold );
1648 /* collapse spaces (in place) */
1649 nvalues[i].bv_len = 0;
1650 nvalues[i].bv_val = tvalues[i].bv_val;
1653 for( j=0; j<tvalues[i].bv_len; j++) {
1654 if ( ASCII_SPACE( tvalues[i].bv_val[j] )) {
1655 if( wasspace++ == 0 ) {
1656 nvalues[i].bv_val[nvalues[i].bv_len++] =
1657 tvalues[i].bv_val[j];
1661 nvalues[i].bv_val[nvalues[i].bv_len++] = tvalues[i].bv_val[j];
1665 if( nvalues[i].bv_len == 0 ) {
1666 nvalues[i].bv_val = " ";
1667 nvalues[i].bv_len = sizeof(" ")-1;
1669 if( wasspace ) --nvalues[i].bv_len;
1670 nvalues[i].bv_val[nvalues[i].bv_len] = '\0';
1674 tvalues[i].bv_val = NULL;
1675 nvalues[i].bv_val = NULL;
1681 for( i=0; values[i].bv_val != NULL; i++ ) {
1682 /* count number of indices to generate */
1683 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
1687 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
1688 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1689 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
1690 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
1692 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
1696 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
1697 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1698 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
1702 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
1703 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1704 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
1705 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
1707 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
1713 /* no keys to generate */
1715 #ifndef SLAP_NVALUES
1716 ber_bvarray_free( tvalues );
1719 return LDAP_SUCCESS;
1722 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
1724 slen = syntax->ssyn_oidlen;
1725 mlen = mr->smr_oidlen;
1728 for( i=0; values[i].bv_val != NULL; i++ ) {
1731 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
1733 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
1734 ( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
1736 char pre = SLAP_INDEX_SUBSTR_PREFIX;
1737 max = values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
1739 for( j=0; j<max; j++ ) {
1740 HASH_Init( &HASHcontext );
1741 if( prefix != NULL && prefix->bv_len > 0 ) {
1742 HASH_Update( &HASHcontext,
1743 prefix->bv_val, prefix->bv_len );
1746 HASH_Update( &HASHcontext,
1747 &pre, sizeof( pre ) );
1748 HASH_Update( &HASHcontext,
1749 syntax->ssyn_oid, slen );
1750 HASH_Update( &HASHcontext,
1751 mr->smr_oid, mlen );
1752 HASH_Update( &HASHcontext,
1753 &values[i].bv_val[j],
1754 SLAP_INDEX_SUBSTR_MAXLEN );
1755 HASH_Final( HASHdigest, &HASHcontext );
1757 ber_dupbv( &keys[nkeys++], &digest );
1761 max = SLAP_INDEX_SUBSTR_MAXLEN < values[i].bv_len
1762 ? SLAP_INDEX_SUBSTR_MAXLEN : values[i].bv_len;
1764 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
1767 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
1768 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
1769 HASH_Init( &HASHcontext );
1770 if( prefix != NULL && prefix->bv_len > 0 ) {
1771 HASH_Update( &HASHcontext,
1772 prefix->bv_val, prefix->bv_len );
1774 HASH_Update( &HASHcontext,
1775 &pre, sizeof( pre ) );
1776 HASH_Update( &HASHcontext,
1777 syntax->ssyn_oid, slen );
1778 HASH_Update( &HASHcontext,
1779 mr->smr_oid, mlen );
1780 HASH_Update( &HASHcontext,
1781 values[i].bv_val, j );
1782 HASH_Final( HASHdigest, &HASHcontext );
1784 ber_dupbv( &keys[nkeys++], &digest );
1787 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
1788 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
1789 HASH_Init( &HASHcontext );
1790 if( prefix != NULL && prefix->bv_len > 0 ) {
1791 HASH_Update( &HASHcontext,
1792 prefix->bv_val, prefix->bv_len );
1794 HASH_Update( &HASHcontext,
1795 &pre, sizeof( pre ) );
1796 HASH_Update( &HASHcontext,
1797 syntax->ssyn_oid, slen );
1798 HASH_Update( &HASHcontext,
1799 mr->smr_oid, mlen );
1800 HASH_Update( &HASHcontext,
1801 &values[i].bv_val[values[i].bv_len-j], j );
1802 HASH_Final( HASHdigest, &HASHcontext );
1804 ber_dupbv( &keys[nkeys++], &digest );
1812 keys[nkeys].bv_val = NULL;
1819 #ifndef SLAP_NVALUES
1820 ber_bvarray_free( tvalues );
1824 return LDAP_SUCCESS;
1829 octetStringSubstringsFilter
1831 caseExactIgnoreSubstringsFilter
1837 struct berval *prefix,
1838 void * assertedValue,
1841 SubstringsAssertion *sa;
1844 ber_len_t nkeys = 0;
1845 size_t slen, mlen, klen;
1847 HASH_CONTEXT HASHcontext;
1848 unsigned char HASHdigest[HASH_BYTES];
1849 struct berval *value;
1850 struct berval digest;
1852 #ifndef SLAP_NVALUES
1853 casefold = ( mr != slap_schema.si_mr_caseExactSubstringsMatch )
1854 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1856 sa = UTF8SubstringsAssertionNormalize( assertedValue, casefold );
1859 return LDAP_SUCCESS;
1862 sa = (SubstringsAssertion *) assertedValue;
1865 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
1866 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1871 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
1873 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
1874 if( sa->sa_any[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1875 /* don't bother accounting for stepping */
1876 nkeys += sa->sa_any[i].bv_len -
1877 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
1882 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
1883 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1889 #ifndef SLAP_NVALUES
1890 if ( sa->sa_final.bv_val ) free( sa->sa_final.bv_val );
1891 if ( sa->sa_any ) ber_bvarray_free( sa->sa_any );
1892 if ( sa->sa_initial.bv_val ) free( sa->sa_initial.bv_val );
1896 return LDAP_SUCCESS;
1899 digest.bv_val = HASHdigest;
1900 digest.bv_len = sizeof(HASHdigest);
1902 slen = syntax->ssyn_oidlen;
1903 mlen = mr->smr_oidlen;
1905 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
1908 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
1909 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1911 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
1912 value = &sa->sa_initial;
1914 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
1915 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
1917 HASH_Init( &HASHcontext );
1918 if( prefix != NULL && prefix->bv_len > 0 ) {
1919 HASH_Update( &HASHcontext,
1920 prefix->bv_val, prefix->bv_len );
1922 HASH_Update( &HASHcontext,
1923 &pre, sizeof( pre ) );
1924 HASH_Update( &HASHcontext,
1925 syntax->ssyn_oid, slen );
1926 HASH_Update( &HASHcontext,
1927 mr->smr_oid, mlen );
1928 HASH_Update( &HASHcontext,
1929 value->bv_val, klen );
1930 HASH_Final( HASHdigest, &HASHcontext );
1932 ber_dupbv( &keys[nkeys++], &digest );
1935 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
1937 pre = SLAP_INDEX_SUBSTR_PREFIX;
1938 klen = SLAP_INDEX_SUBSTR_MAXLEN;
1940 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
1941 if( sa->sa_any[i].bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
1945 value = &sa->sa_any[i];
1948 j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
1949 j += SLAP_INDEX_SUBSTR_STEP )
1951 HASH_Init( &HASHcontext );
1952 if( prefix != NULL && prefix->bv_len > 0 ) {
1953 HASH_Update( &HASHcontext,
1954 prefix->bv_val, prefix->bv_len );
1956 HASH_Update( &HASHcontext,
1957 &pre, sizeof( pre ) );
1958 HASH_Update( &HASHcontext,
1959 syntax->ssyn_oid, slen );
1960 HASH_Update( &HASHcontext,
1961 mr->smr_oid, mlen );
1962 HASH_Update( &HASHcontext,
1963 &value->bv_val[j], klen );
1964 HASH_Final( HASHdigest, &HASHcontext );
1966 ber_dupbv( &keys[nkeys++], &digest );
1972 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
1973 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1975 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
1976 value = &sa->sa_final;
1978 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
1979 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
1981 HASH_Init( &HASHcontext );
1982 if( prefix != NULL && prefix->bv_len > 0 ) {
1983 HASH_Update( &HASHcontext,
1984 prefix->bv_val, prefix->bv_len );
1986 HASH_Update( &HASHcontext,
1987 &pre, sizeof( pre ) );
1988 HASH_Update( &HASHcontext,
1989 syntax->ssyn_oid, slen );
1990 HASH_Update( &HASHcontext,
1991 mr->smr_oid, mlen );
1992 HASH_Update( &HASHcontext,
1993 &value->bv_val[value->bv_len-klen], klen );
1994 HASH_Final( HASHdigest, &HASHcontext );
1996 ber_dupbv( &keys[nkeys++], &digest );
2000 keys[nkeys].bv_val = NULL;
2007 #ifndef SLAP_NVALUES
2008 if ( sa->sa_final.bv_val ) free( sa->sa_final.bv_val );
2009 if ( sa->sa_any ) ber_bvarray_free( sa->sa_any );
2010 if ( sa->sa_initial.bv_val ) free( sa->sa_initial.bv_val );
2014 return LDAP_SUCCESS;
2016 #ifndef SLAP_NVALUES
2024 struct berval *value,
2025 void *assertedValue )
2027 *matchp = UTF8bvnormcmp( value,
2028 (struct berval *) assertedValue,
2029 LDAP_UTF8_CASEFOLD );
2030 return LDAP_SUCCESS;
2034 /* Remove all spaces and '-' characters */
2037 telephoneNumberNormalize(
2042 struct berval *normalized )
2044 xtelephoneNumberNormalize(
2047 struct berval *normalized )
2052 /* validator should have refused an empty string */
2053 assert( val->bv_len );
2055 q = normalized->bv_val = ch_malloc( val->bv_len + 1 );
2057 for( p = val->bv_val; *p; p++ ) {
2058 if ( ! ( ASCII_SPACE( *p ) || *p == '-' )) {
2064 normalized->bv_len = q - normalized->bv_val;
2066 if( normalized->bv_len == 0 ) {
2067 free( normalized->bv_val );
2068 return LDAP_INVALID_SYNTAX;
2071 return LDAP_SUCCESS;
2077 struct berval *val )
2081 if( val->bv_len == 0 ) {
2082 /* disallow empty strings */
2083 return LDAP_INVALID_SYNTAX;
2086 if( OID_LEADCHAR(val->bv_val[0]) ) {
2088 for(i=1; i < val->bv_len; i++) {
2089 if( OID_SEPARATOR( val->bv_val[i] ) ) {
2090 if( dot++ ) return 1;
2091 } else if ( OID_CHAR( val->bv_val[i] ) ) {
2094 return LDAP_INVALID_SYNTAX;
2098 return !dot ? LDAP_SUCCESS : LDAP_INVALID_SYNTAX;
2100 } else if( DESC_LEADCHAR(val->bv_val[0]) ) {
2101 for(i=1; i < val->bv_len; i++) {
2102 if( !DESC_CHAR(val->bv_val[i] ) ) {
2103 return LDAP_INVALID_SYNTAX;
2107 return LDAP_SUCCESS;
2110 return LDAP_INVALID_SYNTAX;
2119 struct berval *value,
2120 void *assertedValue )
2123 int vsign = 1, avsign = 1; /* default sign = '+' */
2124 struct berval *asserted;
2125 ber_len_t vlen, avlen;
2128 /* Skip leading space/sign/zeroes, and get the sign of the *value number */
2130 vlen = value->bv_len;
2132 #ifndef SLAP_NVALUES
2133 if( mr == slap_schema.si_mr_integerFirstComponentMatch ) {
2134 char *tmp = memchr( v, '$', vlen );
2135 if( tmp ) vlen = tmp - v;
2136 while( vlen && ASCII_SPACE( v[vlen-1] )) vlen--;
2140 for( ; vlen && ( *v < '1' || '9' < *v ); v++, vlen-- ) { /* ANSI 2.2.1 */
2141 if( *v == '-' ) vsign = -1;
2144 if( vlen == 0 ) vsign = 0;
2146 /* Do the same with the *assertedValue number */
2147 asserted = (struct berval *) assertedValue;
2148 av = asserted->bv_val;
2149 avlen = asserted->bv_len;
2150 for( ; avlen && ( *av < '1' || '9' < *av ); av++, avlen-- )
2156 match = vsign - avsign;
2158 match = (vlen != avlen
2159 ? ( vlen < avlen ? -1 : 1 )
2160 : memcmp( v, av, vlen ));
2166 return LDAP_SUCCESS;
2172 struct berval *val )
2176 if( !val->bv_len ) return LDAP_INVALID_SYNTAX;
2178 if(( val->bv_val[0] == '+' ) || ( val->bv_val[0] == '-' )) {
2179 if( val->bv_len < 2 ) return LDAP_INVALID_SYNTAX;
2181 } else if( !ASCII_DIGIT(val->bv_val[0]) ) {
2182 return LDAP_INVALID_SYNTAX;
2185 for( i=1; i < val->bv_len; i++ ) {
2186 if( !ASCII_DIGIT(val->bv_val[i]) ) return LDAP_INVALID_SYNTAX;
2189 return LDAP_SUCCESS;
2199 struct berval *normalized )
2204 struct berval *normalized )
2215 /* Ignore leading spaces */
2216 while ( len && ( *p == ' ' )) {
2223 negative = ( *p == '-' );
2224 if(( *p == '-' ) || ( *p == '+' )) {
2230 /* Ignore leading zeros */
2231 while ( len && ( *p == '0' )) {
2236 /* If there are no non-zero digits left, the number is zero, otherwise
2237 allocate space for the number and copy it into the buffer */
2239 normalized->bv_val = ch_strdup("0");
2240 normalized->bv_len = 1;
2243 normalized->bv_len = len+negative;
2244 normalized->bv_val = ch_malloc( normalized->bv_len + 1 );
2245 if( negative ) normalized->bv_val[0] = '-';
2246 AC_MEMCPY( normalized->bv_val + negative, p, len );
2247 normalized->bv_val[len+negative] = '\0';
2250 return LDAP_SUCCESS;
2253 #ifndef SLAP_NVALUES
2255 /* Index generation function */
2256 static int integerIndexer(
2261 struct berval *prefix,
2268 HASH_CONTEXT HASHcontext;
2269 unsigned char HASHdigest[HASH_BYTES];
2270 struct berval digest;
2271 digest.bv_val = HASHdigest;
2272 digest.bv_len = sizeof(HASHdigest);
2274 for( i=0; values[i].bv_val != NULL; i++ ) {
2275 /* empty - just count them */
2278 /* we should have at least one value at this point */
2281 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
2283 slen = syntax->ssyn_oidlen;
2284 mlen = mr->smr_oidlen;
2286 for( i=0; values[i].bv_val != NULL; i++ ) {
2288 xintegerNormalize( syntax, &values[i], &norm );
2290 HASH_Init( &HASHcontext );
2291 if( prefix != NULL && prefix->bv_len > 0 ) {
2292 HASH_Update( &HASHcontext,
2293 prefix->bv_val, prefix->bv_len );
2295 HASH_Update( &HASHcontext,
2296 syntax->ssyn_oid, slen );
2297 HASH_Update( &HASHcontext,
2298 mr->smr_oid, mlen );
2299 HASH_Update( &HASHcontext,
2300 norm.bv_val, norm.bv_len );
2301 HASH_Final( HASHdigest, &HASHcontext );
2303 ber_dupbv( &keys[i], &digest );
2304 ch_free( norm.bv_val );
2307 keys[i].bv_val = NULL;
2309 return LDAP_SUCCESS;
2312 /* Index generation function */
2313 static int integerFilter(
2318 struct berval *prefix,
2319 void * assertedValue,
2324 HASH_CONTEXT HASHcontext;
2325 unsigned char HASHdigest[HASH_BYTES];
2327 struct berval digest;
2328 digest.bv_val = HASHdigest;
2329 digest.bv_len = sizeof(HASHdigest);
2331 slen = syntax->ssyn_oidlen;
2332 mlen = mr->smr_oidlen;
2334 xintegerNormalize( syntax, assertedValue, &norm );
2336 keys = ch_malloc( sizeof( struct berval ) * 2 );
2338 HASH_Init( &HASHcontext );
2339 if( prefix != NULL && prefix->bv_len > 0 ) {
2340 HASH_Update( &HASHcontext,
2341 prefix->bv_val, prefix->bv_len );
2343 HASH_Update( &HASHcontext,
2344 syntax->ssyn_oid, slen );
2345 HASH_Update( &HASHcontext,
2346 mr->smr_oid, mlen );
2347 HASH_Update( &HASHcontext,
2348 norm.bv_val, norm.bv_len );
2349 HASH_Final( HASHdigest, &HASHcontext );
2351 ber_dupbv( &keys[0], &digest );
2352 keys[1].bv_val = NULL;
2353 ch_free( norm.bv_val );
2356 return LDAP_SUCCESS;
2362 countryStringValidate(
2364 struct berval *val )
2366 if( val->bv_len != 2 ) return LDAP_INVALID_SYNTAX;
2368 if( !SLAP_PRINTABLE(val->bv_val[0]) ) {
2369 return LDAP_INVALID_SYNTAX;
2371 if( !SLAP_PRINTABLE(val->bv_val[1]) ) {
2372 return LDAP_INVALID_SYNTAX;
2375 return LDAP_SUCCESS;
2379 printableStringValidate(
2381 struct berval *val )
2385 if( val->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
2387 for(i=0; i < val->bv_len; i++) {
2388 if( !SLAP_PRINTABLE(val->bv_val[i]) ) {
2389 return LDAP_INVALID_SYNTAX;
2393 return LDAP_SUCCESS;
2397 printablesStringValidate(
2399 struct berval *val )
2403 if( val->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
2405 for(i=0,len=0; i < val->bv_len; i++) {
2406 int c = val->bv_val[i];
2410 return LDAP_INVALID_SYNTAX;
2414 } else if ( SLAP_PRINTABLE(c) ) {
2417 return LDAP_INVALID_SYNTAX;
2422 return LDAP_INVALID_SYNTAX;
2425 return LDAP_SUCCESS;
2431 struct berval *val )
2435 if( val->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
2437 for(i=0; i < val->bv_len; i++) {
2438 if( !LDAP_ASCII(val->bv_val[i]) ) {
2439 return LDAP_INVALID_SYNTAX;
2443 return LDAP_SUCCESS;
2453 struct berval *normalized )
2455 xIA5StringNormalize(
2458 struct berval *normalized )
2463 int casefold = !SLAP_MR_ASSOCIATED(mr, slap_schema.si_mr_caseExactIA5Match);
2466 assert( val->bv_len );
2470 /* Ignore initial whitespace */
2471 while ( ASCII_SPACE( *p ) ) {
2475 normalized->bv_val = ch_strdup( p );
2476 p = q = normalized->bv_val;
2479 if ( ASCII_SPACE( *p ) ) {
2482 /* Ignore the extra whitespace */
2483 while ( ASCII_SPACE( *p ) ) {
2488 } else if ( casefold ) {
2489 /* Most IA5 rules require casefolding */
2490 *q++ = TOLOWER(*p++);
2498 assert( normalized->bv_val <= p );
2502 * If the string ended in space, backup the pointer one
2503 * position. One is enough because the above loop collapsed
2504 * all whitespace to a single space.
2507 if ( ASCII_SPACE( q[-1] ) ) {
2511 /* null terminate */
2514 normalized->bv_len = q - normalized->bv_val;
2516 if( normalized->bv_len == 0 ) {
2517 normalized->bv_val = ch_realloc( normalized->bv_val, 2 );
2518 normalized->bv_val[0] = ' ';
2519 normalized->bv_val[1] = '\0';
2520 normalized->bv_len = 1;
2523 return LDAP_SUCCESS;
2526 #ifndef SLAP_NVALUES
2534 struct berval *value,
2535 void *assertedValue )
2537 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
2540 match = strncmp( value->bv_val,
2541 ((struct berval *) assertedValue)->bv_val,
2546 return LDAP_SUCCESS;
2550 caseExactIA5SubstringsMatch
2553 octetStringSubstringsMatch
2560 struct berval *value,
2561 void *assertedValue )
2564 SubstringsAssertion *sub = assertedValue;
2565 struct berval left = *value;
2569 /* Add up asserted input length */
2570 if( sub->sa_initial.bv_val ) {
2571 inlen += sub->sa_initial.bv_len;
2574 for(i=0; sub->sa_any[i].bv_val != NULL; i++) {
2575 inlen += sub->sa_any[i].bv_len;
2578 if( sub->sa_final.bv_val ) {
2579 inlen += sub->sa_final.bv_len;
2582 if( sub->sa_initial.bv_val ) {
2583 if( inlen > left.bv_len ) {
2588 match = memcmp( sub->sa_initial.bv_val, left.bv_val,
2589 sub->sa_initial.bv_len );
2595 left.bv_val += sub->sa_initial.bv_len;
2596 left.bv_len -= sub->sa_initial.bv_len;
2597 inlen -= sub->sa_initial.bv_len;
2600 if( sub->sa_final.bv_val ) {
2601 if( inlen > left.bv_len ) {
2606 match = memcmp( sub->sa_final.bv_val,
2607 &left.bv_val[left.bv_len - sub->sa_final.bv_len],
2608 sub->sa_final.bv_len );
2614 left.bv_len -= sub->sa_final.bv_len;
2615 inlen -= sub->sa_final.bv_len;
2619 for(i=0; sub->sa_any[i].bv_val; i++) {
2624 if( inlen > left.bv_len ) {
2625 /* not enough length */
2630 if( sub->sa_any[i].bv_len == 0 ) {
2634 p = memchr( left.bv_val, *sub->sa_any[i].bv_val, left.bv_len );
2641 idx = p - left.bv_val;
2643 if( idx >= left.bv_len ) {
2644 /* this shouldn't happen */
2651 if( sub->sa_any[i].bv_len > left.bv_len ) {
2652 /* not enough left */
2657 match = memcmp( left.bv_val,
2658 sub->sa_any[i].bv_val,
2659 sub->sa_any[i].bv_len );
2667 left.bv_val += sub->sa_any[i].bv_len;
2668 left.bv_len -= sub->sa_any[i].bv_len;
2669 inlen -= sub->sa_any[i].bv_len;
2675 return LDAP_SUCCESS;
2678 #ifndef SLAP_NVALUES
2680 /* Index generation function */
2681 static int caseExactIA5Indexer(
2686 struct berval *prefix,
2693 HASH_CONTEXT HASHcontext;
2694 unsigned char HASHdigest[HASH_BYTES];
2695 struct berval digest;
2696 digest.bv_val = HASHdigest;
2697 digest.bv_len = sizeof(HASHdigest);
2699 for( i=0; values[i].bv_val != NULL; i++ ) {
2700 /* empty - just count them */
2703 /* we should have at least one value at this point */
2706 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
2708 slen = syntax->ssyn_oidlen;
2709 mlen = mr->smr_oidlen;
2711 for( i=0; values[i].bv_val != NULL; i++ ) {
2712 struct berval *value = &values[i];
2714 HASH_Init( &HASHcontext );
2715 if( prefix != NULL && prefix->bv_len > 0 ) {
2716 HASH_Update( &HASHcontext,
2717 prefix->bv_val, prefix->bv_len );
2719 HASH_Update( &HASHcontext,
2720 syntax->ssyn_oid, slen );
2721 HASH_Update( &HASHcontext,
2722 mr->smr_oid, mlen );
2723 HASH_Update( &HASHcontext,
2724 value->bv_val, value->bv_len );
2725 HASH_Final( HASHdigest, &HASHcontext );
2727 ber_dupbv( &keys[i], &digest );
2730 keys[i].bv_val = NULL;
2732 return LDAP_SUCCESS;
2735 /* Index generation function */
2736 static int caseExactIA5Filter(
2741 struct berval *prefix,
2742 void * assertedValue,
2747 HASH_CONTEXT HASHcontext;
2748 unsigned char HASHdigest[HASH_BYTES];
2749 struct berval *value;
2750 struct berval digest;
2751 digest.bv_val = HASHdigest;
2752 digest.bv_len = sizeof(HASHdigest);
2754 slen = syntax->ssyn_oidlen;
2755 mlen = mr->smr_oidlen;
2757 value = (struct berval *) assertedValue;
2759 keys = ch_malloc( sizeof( struct berval ) * 2 );
2761 HASH_Init( &HASHcontext );
2762 if( prefix != NULL && prefix->bv_len > 0 ) {
2763 HASH_Update( &HASHcontext,
2764 prefix->bv_val, prefix->bv_len );
2766 HASH_Update( &HASHcontext,
2767 syntax->ssyn_oid, slen );
2768 HASH_Update( &HASHcontext,
2769 mr->smr_oid, mlen );
2770 HASH_Update( &HASHcontext,
2771 value->bv_val, value->bv_len );
2772 HASH_Final( HASHdigest, &HASHcontext );
2774 ber_dupbv( &keys[0], &digest );
2775 keys[1].bv_val = NULL;
2778 return LDAP_SUCCESS;
2781 /* Substrings Index generation function */
2782 static int caseExactIA5SubstringsIndexer(
2787 struct berval *prefix,
2794 HASH_CONTEXT HASHcontext;
2795 unsigned char HASHdigest[HASH_BYTES];
2796 struct berval digest;
2797 digest.bv_val = HASHdigest;
2798 digest.bv_len = sizeof(HASHdigest);
2800 /* we should have at least one value at this point */
2801 assert( values != NULL && values[0].bv_val != NULL );
2804 for( i=0; values[i].bv_val != NULL; i++ ) {
2805 /* count number of indices to generate */
2806 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
2810 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
2811 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2812 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2813 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2815 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2819 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
2820 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2821 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
2825 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
2826 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2827 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2828 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2830 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2836 /* no keys to generate */
2838 return LDAP_SUCCESS;
2841 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
2843 slen = syntax->ssyn_oidlen;
2844 mlen = mr->smr_oidlen;
2847 for( i=0; values[i].bv_val != NULL; i++ ) {
2849 struct berval *value;
2852 if( value->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
2854 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
2855 ( value->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
2857 char pre = SLAP_INDEX_SUBSTR_PREFIX;
2858 max = value->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
2860 for( j=0; j<max; j++ ) {
2861 HASH_Init( &HASHcontext );
2862 if( prefix != NULL && prefix->bv_len > 0 ) {
2863 HASH_Update( &HASHcontext,
2864 prefix->bv_val, prefix->bv_len );
2867 HASH_Update( &HASHcontext,
2868 &pre, sizeof( pre ) );
2869 HASH_Update( &HASHcontext,
2870 syntax->ssyn_oid, slen );
2871 HASH_Update( &HASHcontext,
2872 mr->smr_oid, mlen );
2873 HASH_Update( &HASHcontext,
2875 SLAP_INDEX_SUBSTR_MAXLEN );
2876 HASH_Final( HASHdigest, &HASHcontext );
2878 ber_dupbv( &keys[nkeys++], &digest );
2882 max = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2883 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2885 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
2888 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
2889 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
2890 HASH_Init( &HASHcontext );
2891 if( prefix != NULL && prefix->bv_len > 0 ) {
2892 HASH_Update( &HASHcontext,
2893 prefix->bv_val, prefix->bv_len );
2895 HASH_Update( &HASHcontext,
2896 &pre, sizeof( pre ) );
2897 HASH_Update( &HASHcontext,
2898 syntax->ssyn_oid, slen );
2899 HASH_Update( &HASHcontext,
2900 mr->smr_oid, mlen );
2901 HASH_Update( &HASHcontext,
2903 HASH_Final( HASHdigest, &HASHcontext );
2905 ber_dupbv( &keys[nkeys++], &digest );
2908 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
2909 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
2910 HASH_Init( &HASHcontext );
2911 if( prefix != NULL && prefix->bv_len > 0 ) {
2912 HASH_Update( &HASHcontext,
2913 prefix->bv_val, prefix->bv_len );
2915 HASH_Update( &HASHcontext,
2916 &pre, sizeof( pre ) );
2917 HASH_Update( &HASHcontext,
2918 syntax->ssyn_oid, slen );
2919 HASH_Update( &HASHcontext,
2920 mr->smr_oid, mlen );
2921 HASH_Update( &HASHcontext,
2922 &value->bv_val[value->bv_len-j], j );
2923 HASH_Final( HASHdigest, &HASHcontext );
2925 ber_dupbv( &keys[nkeys++], &digest );
2932 keys[nkeys].bv_val = NULL;
2939 return LDAP_SUCCESS;
2942 static int caseExactIA5SubstringsFilter(
2947 struct berval *prefix,
2948 void * assertedValue,
2951 SubstringsAssertion *sa = assertedValue;
2953 ber_len_t nkeys = 0;
2954 size_t slen, mlen, klen;
2956 HASH_CONTEXT HASHcontext;
2957 unsigned char HASHdigest[HASH_BYTES];
2958 struct berval *value;
2959 struct berval digest;
2961 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
2962 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2967 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
2969 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
2970 if( sa->sa_any[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2971 /* don't bother accounting for stepping */
2972 nkeys += sa->sa_any[i].bv_len -
2973 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
2978 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
2979 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2986 return LDAP_SUCCESS;
2989 digest.bv_val = HASHdigest;
2990 digest.bv_len = sizeof(HASHdigest);
2992 slen = syntax->ssyn_oidlen;
2993 mlen = mr->smr_oidlen;
2995 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
2998 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
2999 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3001 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
3002 value = &sa->sa_initial;
3004 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
3005 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
3007 HASH_Init( &HASHcontext );
3008 if( prefix != NULL && prefix->bv_len > 0 ) {
3009 HASH_Update( &HASHcontext,
3010 prefix->bv_val, prefix->bv_len );
3012 HASH_Update( &HASHcontext,
3013 &pre, sizeof( pre ) );
3014 HASH_Update( &HASHcontext,
3015 syntax->ssyn_oid, slen );
3016 HASH_Update( &HASHcontext,
3017 mr->smr_oid, mlen );
3018 HASH_Update( &HASHcontext,
3019 value->bv_val, klen );
3020 HASH_Final( HASHdigest, &HASHcontext );
3022 ber_dupbv( &keys[nkeys++], &digest );
3025 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
3027 pre = SLAP_INDEX_SUBSTR_PREFIX;
3028 klen = SLAP_INDEX_SUBSTR_MAXLEN;
3030 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
3031 if( sa->sa_any[i].bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
3035 value = &sa->sa_any[i];
3038 j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
3039 j += SLAP_INDEX_SUBSTR_STEP )
3041 HASH_Init( &HASHcontext );
3042 if( prefix != NULL && prefix->bv_len > 0 ) {
3043 HASH_Update( &HASHcontext,
3044 prefix->bv_val, prefix->bv_len );
3046 HASH_Update( &HASHcontext,
3047 &pre, sizeof( pre ) );
3048 HASH_Update( &HASHcontext,
3049 syntax->ssyn_oid, slen );
3050 HASH_Update( &HASHcontext,
3051 mr->smr_oid, mlen );
3052 HASH_Update( &HASHcontext,
3053 &value->bv_val[j], klen );
3054 HASH_Final( HASHdigest, &HASHcontext );
3056 ber_dupbv( &keys[nkeys++], &digest );
3061 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
3062 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3064 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
3065 value = &sa->sa_final;
3067 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
3068 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
3070 HASH_Init( &HASHcontext );
3071 if( prefix != NULL && prefix->bv_len > 0 ) {
3072 HASH_Update( &HASHcontext,
3073 prefix->bv_val, prefix->bv_len );
3075 HASH_Update( &HASHcontext,
3076 &pre, sizeof( pre ) );
3077 HASH_Update( &HASHcontext,
3078 syntax->ssyn_oid, slen );
3079 HASH_Update( &HASHcontext,
3080 mr->smr_oid, mlen );
3081 HASH_Update( &HASHcontext,
3082 &value->bv_val[value->bv_len-klen], klen );
3083 HASH_Final( HASHdigest, &HASHcontext );
3085 ber_dupbv( &keys[nkeys++], &digest );
3089 keys[nkeys].bv_val = NULL;
3096 return LDAP_SUCCESS;
3105 struct berval *value,
3106 void *assertedValue )
3108 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
3110 if( match == 0 && value->bv_len ) {
3111 match = strncasecmp( value->bv_val,
3112 ((struct berval *) assertedValue)->bv_val,
3117 return LDAP_SUCCESS;
3121 caseIgnoreIA5SubstringsMatch(
3126 struct berval *value,
3127 void *assertedValue )
3130 SubstringsAssertion *sub = assertedValue;
3131 struct berval left = *value;
3135 /* Add up asserted input length */
3136 if( sub->sa_initial.bv_val ) {
3137 inlen += sub->sa_initial.bv_len;
3140 for(i=0; sub->sa_any[i].bv_val != NULL; i++) {
3141 inlen += sub->sa_any[i].bv_len;
3144 if( sub->sa_final.bv_val ) {
3145 inlen += sub->sa_final.bv_len;
3148 if( sub->sa_initial.bv_val ) {
3149 if( inlen > left.bv_len ) {
3154 match = strncasecmp( sub->sa_initial.bv_val, left.bv_val,
3155 sub->sa_initial.bv_len );
3161 left.bv_val += sub->sa_initial.bv_len;
3162 left.bv_len -= sub->sa_initial.bv_len;
3163 inlen -= sub->sa_initial.bv_len;
3166 if( sub->sa_final.bv_val ) {
3167 if( inlen > left.bv_len ) {
3172 match = strncasecmp( sub->sa_final.bv_val,
3173 &left.bv_val[left.bv_len - sub->sa_final.bv_len],
3174 sub->sa_final.bv_len );
3180 left.bv_len -= sub->sa_final.bv_len;
3181 inlen -= sub->sa_final.bv_len;
3185 for(i=0; sub->sa_any[i].bv_val; i++) {
3190 if( inlen > left.bv_len ) {
3191 /* not enough length */
3196 if( sub->sa_any[i].bv_len == 0 ) {
3200 p = bvcasechr( &left, *sub->sa_any[i].bv_val, &idx );
3207 assert( idx < left.bv_len );
3208 if( idx >= left.bv_len ) {
3209 /* this shouldn't happen */
3216 if( sub->sa_any[i].bv_len > left.bv_len ) {
3217 /* not enough left */
3222 match = strncasecmp( left.bv_val,
3223 sub->sa_any[i].bv_val,
3224 sub->sa_any[i].bv_len );
3233 left.bv_val += sub->sa_any[i].bv_len;
3234 left.bv_len -= sub->sa_any[i].bv_len;
3235 inlen -= sub->sa_any[i].bv_len;
3241 return LDAP_SUCCESS;
3244 /* Index generation function */
3245 static int caseIgnoreIA5Indexer(
3250 struct berval *prefix,
3255 int rc = LDAP_SUCCESS;
3258 HASH_CONTEXT HASHcontext;
3259 unsigned char HASHdigest[HASH_BYTES];
3260 struct berval digest;
3261 digest.bv_val = HASHdigest;
3262 digest.bv_len = sizeof(HASHdigest);
3264 /* we should have at least one value at this point */
3265 assert( values != NULL && values[0].bv_val != NULL );
3267 for( i=0; values[i].bv_val != NULL; i++ ) {
3268 /* just count them */
3271 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
3273 slen = syntax->ssyn_oidlen;
3274 mlen = mr->smr_oidlen;
3276 for( i=0; values[i].bv_val != NULL; i++ ) {
3277 struct berval value;
3279 if( mr->smr_normalize ) {
3280 rc = (mr->smr_normalize)( use, syntax, mr, &values[i], &value );
3281 if( rc != LDAP_SUCCESS ) {
3284 #ifndef SLAP_NVALUES
3285 } else if ( mr->smr_syntax->ssyn_normalize ) {
3286 rc = (mr->smr_syntax->ssyn_normalize)( syntax, &values[i], &value );
3287 if( rc != LDAP_SUCCESS ) {
3292 ber_dupbv( &value, &values[i] );
3295 ldap_pvt_str2lower( value.bv_val );
3297 HASH_Init( &HASHcontext );
3298 if( prefix != NULL && prefix->bv_len > 0 ) {
3299 HASH_Update( &HASHcontext,
3300 prefix->bv_val, prefix->bv_len );
3302 HASH_Update( &HASHcontext,
3303 syntax->ssyn_oid, slen );
3304 HASH_Update( &HASHcontext,
3305 mr->smr_oid, mlen );
3306 HASH_Update( &HASHcontext,
3307 value.bv_val, value.bv_len );
3308 HASH_Final( HASHdigest, &HASHcontext );
3310 free( value.bv_val );
3312 ber_dupbv( &keys[i], &digest );
3315 keys[i].bv_val = NULL;
3316 if( rc != LDAP_SUCCESS ) {
3317 ber_bvarray_free( keys );
3324 /* Index generation function */
3325 static int caseIgnoreIA5Filter(
3330 struct berval *prefix,
3331 void * assertedValue,
3336 HASH_CONTEXT HASHcontext;
3337 unsigned char HASHdigest[HASH_BYTES];
3338 struct berval value;
3339 struct berval digest;
3340 digest.bv_val = HASHdigest;
3341 digest.bv_len = sizeof(HASHdigest);
3343 slen = syntax->ssyn_oidlen;
3344 mlen = mr->smr_oidlen;
3346 ber_dupbv( &value, (struct berval *) assertedValue );
3347 ldap_pvt_str2lower( value.bv_val );
3349 keys = ch_malloc( sizeof( struct berval ) * 2 );
3351 HASH_Init( &HASHcontext );
3352 if( prefix != NULL && prefix->bv_len > 0 ) {
3353 HASH_Update( &HASHcontext,
3354 prefix->bv_val, prefix->bv_len );
3356 HASH_Update( &HASHcontext,
3357 syntax->ssyn_oid, slen );
3358 HASH_Update( &HASHcontext,
3359 mr->smr_oid, mlen );
3360 HASH_Update( &HASHcontext,
3361 value.bv_val, value.bv_len );
3362 HASH_Final( HASHdigest, &HASHcontext );
3364 ber_dupbv( &keys[0], &digest );
3365 keys[1].bv_val = NULL;
3367 free( value.bv_val );
3371 return LDAP_SUCCESS;
3374 /* Substrings Index generation function */
3375 static int caseIgnoreIA5SubstringsIndexer(
3380 struct berval *prefix,
3387 HASH_CONTEXT HASHcontext;
3388 unsigned char HASHdigest[HASH_BYTES];
3389 struct berval digest;
3390 digest.bv_val = HASHdigest;
3391 digest.bv_len = sizeof(HASHdigest);
3393 /* we should have at least one value at this point */
3394 assert( values != NULL && values[0].bv_val != NULL );
3397 for( i=0; values[i].bv_val != NULL; i++ ) {
3398 /* count number of indices to generate */
3399 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
3403 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
3404 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3405 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
3406 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
3408 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
3412 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
3413 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3414 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
3418 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
3419 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3420 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
3421 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
3423 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
3429 /* no keys to generate */
3431 return LDAP_SUCCESS;
3434 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
3436 slen = syntax->ssyn_oidlen;
3437 mlen = mr->smr_oidlen;
3440 for( i=0; values[i].bv_val != NULL; i++ ) {
3442 struct berval value;
3444 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
3446 ber_dupbv( &value, &values[i] );
3447 ldap_pvt_str2lower( value.bv_val );
3449 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
3450 ( value.bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
3452 char pre = SLAP_INDEX_SUBSTR_PREFIX;
3453 max = value.bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
3455 for( j=0; j<max; j++ ) {
3456 HASH_Init( &HASHcontext );
3457 if( prefix != NULL && prefix->bv_len > 0 ) {
3458 HASH_Update( &HASHcontext,
3459 prefix->bv_val, prefix->bv_len );
3462 HASH_Update( &HASHcontext,
3463 &pre, sizeof( pre ) );
3464 HASH_Update( &HASHcontext,
3465 syntax->ssyn_oid, slen );
3466 HASH_Update( &HASHcontext,
3467 mr->smr_oid, mlen );
3468 HASH_Update( &HASHcontext,
3470 SLAP_INDEX_SUBSTR_MAXLEN );
3471 HASH_Final( HASHdigest, &HASHcontext );
3473 ber_dupbv( &keys[nkeys++], &digest );
3477 max = SLAP_INDEX_SUBSTR_MAXLEN < value.bv_len
3478 ? SLAP_INDEX_SUBSTR_MAXLEN : value.bv_len;
3480 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
3483 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
3484 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
3485 HASH_Init( &HASHcontext );
3486 if( prefix != NULL && prefix->bv_len > 0 ) {
3487 HASH_Update( &HASHcontext,
3488 prefix->bv_val, prefix->bv_len );
3490 HASH_Update( &HASHcontext,
3491 &pre, sizeof( pre ) );
3492 HASH_Update( &HASHcontext,
3493 syntax->ssyn_oid, slen );
3494 HASH_Update( &HASHcontext,
3495 mr->smr_oid, mlen );
3496 HASH_Update( &HASHcontext,
3498 HASH_Final( HASHdigest, &HASHcontext );
3500 ber_dupbv( &keys[nkeys++], &digest );
3503 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
3504 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
3505 HASH_Init( &HASHcontext );
3506 if( prefix != NULL && prefix->bv_len > 0 ) {
3507 HASH_Update( &HASHcontext,
3508 prefix->bv_val, prefix->bv_len );
3510 HASH_Update( &HASHcontext,
3511 &pre, sizeof( pre ) );
3512 HASH_Update( &HASHcontext,
3513 syntax->ssyn_oid, slen );
3514 HASH_Update( &HASHcontext,
3515 mr->smr_oid, mlen );
3516 HASH_Update( &HASHcontext,
3517 &value.bv_val[value.bv_len-j], j );
3518 HASH_Final( HASHdigest, &HASHcontext );
3520 ber_dupbv( &keys[nkeys++], &digest );
3525 free( value.bv_val );
3529 keys[nkeys].bv_val = NULL;
3536 return LDAP_SUCCESS;
3539 static int caseIgnoreIA5SubstringsFilter(
3544 struct berval *prefix,
3545 void * assertedValue,
3548 SubstringsAssertion *sa = assertedValue;
3550 ber_len_t nkeys = 0;
3551 size_t slen, mlen, klen;
3553 HASH_CONTEXT HASHcontext;
3554 unsigned char HASHdigest[HASH_BYTES];
3555 struct berval value;
3556 struct berval digest;
3558 if((flags & SLAP_INDEX_SUBSTR_INITIAL) && sa->sa_initial.bv_val != NULL &&
3559 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3564 if((flags & SLAP_INDEX_SUBSTR_ANY) && sa->sa_any != NULL ) {
3566 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
3567 if( sa->sa_any[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3568 /* don't bother accounting for stepping */
3569 nkeys += sa->sa_any[i].bv_len -
3570 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
3575 if((flags & SLAP_INDEX_SUBSTR_FINAL) && sa->sa_final.bv_val != NULL &&
3576 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3583 return LDAP_SUCCESS;
3586 digest.bv_val = HASHdigest;
3587 digest.bv_len = sizeof(HASHdigest);
3589 slen = syntax->ssyn_oidlen;
3590 mlen = mr->smr_oidlen;
3592 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
3595 if((flags & SLAP_INDEX_SUBSTR_INITIAL) && sa->sa_initial.bv_val != NULL &&
3596 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3598 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
3599 ber_dupbv( &value, &sa->sa_initial );
3600 ldap_pvt_str2lower( value.bv_val );
3602 klen = SLAP_INDEX_SUBSTR_MAXLEN < value.bv_len
3603 ? SLAP_INDEX_SUBSTR_MAXLEN : value.bv_len;
3605 HASH_Init( &HASHcontext );
3606 if( prefix != NULL && prefix->bv_len > 0 ) {
3607 HASH_Update( &HASHcontext,
3608 prefix->bv_val, prefix->bv_len );
3610 HASH_Update( &HASHcontext,
3611 &pre, sizeof( pre ) );
3612 HASH_Update( &HASHcontext,
3613 syntax->ssyn_oid, slen );
3614 HASH_Update( &HASHcontext,
3615 mr->smr_oid, mlen );
3616 HASH_Update( &HASHcontext,
3617 value.bv_val, klen );
3618 HASH_Final( HASHdigest, &HASHcontext );
3620 free( value.bv_val );
3621 ber_dupbv( &keys[nkeys++], &digest );
3624 if((flags & SLAP_INDEX_SUBSTR_ANY) && sa->sa_any != NULL ) {
3626 pre = SLAP_INDEX_SUBSTR_PREFIX;
3627 klen = SLAP_INDEX_SUBSTR_MAXLEN;
3629 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
3630 if( sa->sa_any[i].bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
3634 ber_dupbv( &value, &sa->sa_any[i] );
3635 ldap_pvt_str2lower( value.bv_val );
3638 j <= value.bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
3639 j += SLAP_INDEX_SUBSTR_STEP )
3641 HASH_Init( &HASHcontext );
3642 if( prefix != NULL && prefix->bv_len > 0 ) {
3643 HASH_Update( &HASHcontext,
3644 prefix->bv_val, prefix->bv_len );
3646 HASH_Update( &HASHcontext,
3647 &pre, sizeof( pre ) );
3648 HASH_Update( &HASHcontext,
3649 syntax->ssyn_oid, slen );
3650 HASH_Update( &HASHcontext,
3651 mr->smr_oid, mlen );
3652 HASH_Update( &HASHcontext,
3653 &value.bv_val[j], klen );
3654 HASH_Final( HASHdigest, &HASHcontext );
3656 ber_dupbv( &keys[nkeys++], &digest );
3659 free( value.bv_val );
3663 if((flags & SLAP_INDEX_SUBSTR_FINAL) && sa->sa_final.bv_val != NULL &&
3664 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3666 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
3667 ber_dupbv( &value, &sa->sa_final );
3668 ldap_pvt_str2lower( value.bv_val );
3670 klen = SLAP_INDEX_SUBSTR_MAXLEN < value.bv_len
3671 ? SLAP_INDEX_SUBSTR_MAXLEN : value.bv_len;
3673 HASH_Init( &HASHcontext );
3674 if( prefix != NULL && prefix->bv_len > 0 ) {
3675 HASH_Update( &HASHcontext,
3676 prefix->bv_val, prefix->bv_len );
3678 HASH_Update( &HASHcontext,
3679 &pre, sizeof( pre ) );
3680 HASH_Update( &HASHcontext,
3681 syntax->ssyn_oid, slen );
3682 HASH_Update( &HASHcontext,
3683 mr->smr_oid, mlen );
3684 HASH_Update( &HASHcontext,
3685 &value.bv_val[value.bv_len-klen], klen );
3686 HASH_Final( HASHdigest, &HASHcontext );
3688 free( value.bv_val );
3689 ber_dupbv( &keys[nkeys++], &digest );
3693 keys[nkeys].bv_val = NULL;
3700 return LDAP_SUCCESS;
3706 numericStringValidate(
3712 if( in->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
3714 for(i=0; i < in->bv_len; i++) {
3715 if( !SLAP_NUMERIC(in->bv_val[i]) ) {
3716 return LDAP_INVALID_SYNTAX;
3720 return LDAP_SUCCESS;
3725 numericStringNormalize(
3730 struct berval *normalized )
3732 xnumericStringNormalize(
3735 struct berval *normalized )
3738 /* removal all spaces */
3741 assert( val->bv_len );
3743 normalized->bv_val = ch_malloc( val->bv_len + 1 );
3746 q = normalized->bv_val;
3749 if ( ASCII_SPACE( *p ) ) {
3750 /* Ignore whitespace */
3757 /* we should have copied no more then is in val */
3758 assert( (q - normalized->bv_val) <= (p - val->bv_val) );
3760 /* null terminate */
3763 normalized->bv_len = q - normalized->bv_val;
3765 if( normalized->bv_len == 0 ) {
3766 normalized->bv_val = ch_realloc( normalized->bv_val, 2 );
3767 normalized->bv_val[0] = ' ';
3768 normalized->bv_val[1] = '\0';
3769 normalized->bv_len = 1;
3772 return LDAP_SUCCESS;
3775 #ifndef SLAP_NVALUES
3777 objectIdentifierFirstComponentMatch(
3782 struct berval *value,
3783 void *assertedValue )
3785 int rc = LDAP_SUCCESS;
3787 struct berval *asserted = (struct berval *) assertedValue;
3791 if( value->bv_len == 0 || value->bv_val[0] != '(' /*')'*/ ) {
3792 return LDAP_INVALID_SYNTAX;
3795 /* trim leading white space */
3796 for( i=1; ASCII_SPACE(value->bv_val[i]) && i < value->bv_len; i++ ) {
3800 /* grab next word */
3801 oid.bv_val = &value->bv_val[i];
3802 j = value->bv_len - i;
3803 for( i=0; !ASCII_SPACE(oid.bv_val[i]) && i < j; i++ ) {
3808 /* insert attributeTypes, objectclass check here */
3809 if( OID_LEADCHAR(asserted->bv_val[0]) ) {
3810 rc = objectIdentifierMatch( &match, flags, syntax, mr, &oid, asserted );
3813 if ( !strcmp( syntax->ssyn_oid, SLAP_SYNTAX_MATCHINGRULES_OID ) ) {
3814 MatchingRule *asserted_mr = mr_bvfind( asserted );
3815 MatchingRule *stored_mr = mr_bvfind( &oid );
3817 if( asserted_mr == NULL ) {
3818 rc = SLAPD_COMPARE_UNDEFINED;
3820 match = asserted_mr != stored_mr;
3823 } else if ( !strcmp( syntax->ssyn_oid,
3824 SLAP_SYNTAX_ATTRIBUTETYPES_OID ) )
3826 AttributeType *asserted_at = at_bvfind( asserted );
3827 AttributeType *stored_at = at_bvfind( &oid );
3829 if( asserted_at == NULL ) {
3830 rc = SLAPD_COMPARE_UNDEFINED;
3832 match = asserted_at != stored_at;
3835 } else if ( !strcmp( syntax->ssyn_oid,
3836 SLAP_SYNTAX_OBJECTCLASSES_OID ) )
3838 ObjectClass *asserted_oc = oc_bvfind( asserted );
3839 ObjectClass *stored_oc = oc_bvfind( &oid );
3841 if( asserted_oc == NULL ) {
3842 rc = SLAPD_COMPARE_UNDEFINED;
3844 match = asserted_oc != stored_oc;
3850 LDAP_LOG( CONFIG, ENTRY,
3851 "objectIdentifierFirstComponentMatch: %d\n %s\n %s\n",
3852 match, value->bv_val, asserted->bv_val );
3854 Debug( LDAP_DEBUG_ARGS, "objectIdentifierFirstComponentMatch "
3855 "%d\n\t\"%s\"\n\t\"%s\"\n",
3856 match, value->bv_val, asserted->bv_val );
3859 if( rc == LDAP_SUCCESS ) *matchp = match;
3871 struct berval *value,
3872 void *assertedValue )
3874 long lValue, lAssertedValue;
3876 /* safe to assume integers are NUL terminated? */
3877 lValue = strtol(value->bv_val, NULL, 10);
3878 if(( lValue == LONG_MIN || lValue == LONG_MAX) && errno == ERANGE ) {
3879 return LDAP_CONSTRAINT_VIOLATION;
3882 lAssertedValue = strtol(((struct berval *)assertedValue)->bv_val, NULL, 10);
3883 if(( lAssertedValue == LONG_MIN || lAssertedValue == LONG_MAX)
3884 && errno == ERANGE )
3886 return LDAP_CONSTRAINT_VIOLATION;
3889 *matchp = (lValue & lAssertedValue) ? 0 : 1;
3890 return LDAP_SUCCESS;
3899 struct berval *value,
3900 void *assertedValue )
3902 long lValue, lAssertedValue;
3904 /* safe to assume integers are NUL terminated? */
3905 lValue = strtol(value->bv_val, NULL, 10);
3906 if(( lValue == LONG_MIN || lValue == LONG_MAX) && errno == ERANGE ) {
3907 return LDAP_CONSTRAINT_VIOLATION;
3910 lAssertedValue = strtol(((struct berval *)assertedValue)->bv_val, NULL, 10);
3911 if(( lAssertedValue == LONG_MIN || lAssertedValue == LONG_MAX)
3912 && errno == ERANGE )
3914 return LDAP_CONSTRAINT_VIOLATION;
3917 *matchp = (lValue | lAssertedValue) ? 0 : -1;
3918 return LDAP_SUCCESS;
3921 #ifndef SLAP_NVALUES
3924 #include <openssl/x509.h>
3925 #include <openssl/err.h>
3928 * Next function returns a string representation of a ASN1_INTEGER.
3929 * It works for unlimited lengths.
3932 static struct berval *
3933 asn1_integer2str(ASN1_INTEGER *a, struct berval *bv)
3937 static char digit[] = "0123456789";
3939 /* We work backwards, make it fill from the end of buf */
3940 p = buf + sizeof(buf) - 1;
3943 if ( a == NULL || a->length == 0 ) {
3951 /* We want to preserve the original */
3952 copy = ch_malloc(n*sizeof(unsigned int));
3953 for (i = 0; i<n; i++) {
3954 copy[i] = a->data[i];
3958 * base indicates the index of the most significant
3959 * byte that might be nonzero. When it goes off the
3960 * end, we now there is nothing left to do.
3966 for (i = base; i<n; i++ ) {
3967 copy[i] += carry*256;
3968 carry = copy[i] % 10;
3973 * Way too large, we need to leave
3974 * room for sign if negative
3979 *--p = digit[carry];
3981 if (copy[base] == 0) base++;
3986 if ( a->type == V_ASN1_NEG_INTEGER ) {
3990 return ber_str2bv( p, 0, 1, bv );
3994 * Given a certificate in DER format, extract the corresponding
3995 * assertion value for certificateExactMatch
3998 certificateExactConvert(
4000 struct berval * out )
4003 unsigned char *p = in->bv_val;
4004 struct berval serial;
4005 struct berval issuer_dn;
4007 xcert = d2i_X509(NULL, &p, in->bv_len);
4010 LDAP_LOG( CONFIG, ENTRY,
4011 "certificateExactConvert: error parsing cert: %s\n",
4012 ERR_error_string(ERR_get_error(),NULL), 0, 0 );
4014 Debug( LDAP_DEBUG_ARGS, "certificateExactConvert: "
4015 "error parsing cert: %s\n",
4016 ERR_error_string(ERR_get_error(),NULL), NULL, NULL );
4018 return LDAP_INVALID_SYNTAX;
4021 if ( !asn1_integer2str(xcert->cert_info->serialNumber, &serial) ) {
4023 return LDAP_INVALID_SYNTAX;
4025 if ( dnX509normalize(X509_get_issuer_name(xcert), &issuer_dn )
4029 ber_memfree(serial.bv_val);
4030 return LDAP_INVALID_SYNTAX;
4035 out->bv_len = serial.bv_len + issuer_dn.bv_len + sizeof(" $ ");
4036 out->bv_val = ch_malloc(out->bv_len);
4038 AC_MEMCPY(p, serial.bv_val, serial.bv_len);
4040 AC_MEMCPY(p, " $ ", sizeof(" $ ")-1);
4042 AC_MEMCPY(p, issuer_dn.bv_val, issuer_dn.bv_len);
4043 p += issuer_dn.bv_len;
4047 LDAP_LOG( CONFIG, ARGS,
4048 "certificateExactConvert: \n %s\n", out->bv_val, 0, 0 );
4050 Debug( LDAP_DEBUG_ARGS, "certificateExactConvert "
4052 out->bv_val, NULL, NULL );
4055 ber_memfree(serial.bv_val);
4056 ber_memfree(issuer_dn.bv_val);
4058 return LDAP_SUCCESS;
4062 serial_and_issuer_parse(
4063 struct berval *assertion,
4064 struct berval *serial,
4065 struct berval *issuer_dn
4073 begin = assertion->bv_val;
4074 end = assertion->bv_val+assertion->bv_len-1;
4075 for (p=begin; p<=end && *p != '$'; p++) /* empty */ ;
4076 if ( p > end ) return LDAP_INVALID_SYNTAX;
4078 /* p now points at the $ sign, now use
4079 * begin and end to delimit the serial number
4081 while (ASCII_SPACE(*begin)) begin++;
4083 while (ASCII_SPACE(*end)) end--;
4085 if( end <= begin ) return LDAP_INVALID_SYNTAX;
4087 bv.bv_len = end-begin+1;
4089 ber_dupbv(serial, &bv);
4091 /* now extract the issuer, remember p was at the dollar sign */
4093 end = assertion->bv_val+assertion->bv_len-1;
4094 while (ASCII_SPACE(*begin)) begin++;
4095 /* should we trim spaces at the end too? is it safe always? no, no */
4097 if( end <= begin ) return LDAP_INVALID_SYNTAX;
4100 bv.bv_len = end-begin+1;
4103 dnNormalize2( NULL, &bv, issuer_dn );
4106 return LDAP_SUCCESS;
4110 certificateExactMatch(
4115 struct berval *value,
4116 void *assertedValue )
4119 unsigned char *p = value->bv_val;
4120 struct berval serial;
4121 struct berval issuer_dn;
4122 struct berval asserted_serial;
4123 struct berval asserted_issuer_dn;
4126 xcert = d2i_X509(NULL, &p, value->bv_len);
4129 LDAP_LOG( CONFIG, ENTRY,
4130 "certificateExactMatch: error parsing cert: %s\n",
4131 ERR_error_string(ERR_get_error(),NULL), 0, 0 );
4133 Debug( LDAP_DEBUG_ARGS, "certificateExactMatch: "
4134 "error parsing cert: %s\n",
4135 ERR_error_string(ERR_get_error(),NULL), NULL, NULL );
4137 return LDAP_INVALID_SYNTAX;
4140 asn1_integer2str(xcert->cert_info->serialNumber, &serial);
4141 dnX509normalize(X509_get_issuer_name(xcert), &issuer_dn);
4145 serial_and_issuer_parse(assertedValue,
4146 &asserted_serial, &asserted_issuer_dn);
4151 slap_schema.si_syn_integer,
4152 slap_schema.si_mr_integerMatch,
4155 if ( ret == LDAP_SUCCESS ) {
4156 if ( *matchp == 0 ) {
4157 /* We need to normalize everything for dnMatch */
4161 slap_schema.si_syn_distinguishedName,
4162 slap_schema.si_mr_distinguishedNameMatch,
4164 &asserted_issuer_dn);
4169 LDAP_LOG( CONFIG, ARGS, "certificateExactMatch "
4170 "%d\n\t\"%s $ %s\"\n",
4171 *matchp, serial.bv_val, issuer_dn.bv_val );
4172 LDAP_LOG( CONFIG, ARGS, "\t\"%s $ %s\"\n",
4173 asserted_serial.bv_val, asserted_issuer_dn.bv_val,
4176 Debug( LDAP_DEBUG_ARGS, "certificateExactMatch "
4177 "%d\n\t\"%s $ %s\"\n",
4178 *matchp, serial.bv_val, issuer_dn.bv_val );
4179 Debug( LDAP_DEBUG_ARGS, "\t\"%s $ %s\"\n",
4180 asserted_serial.bv_val, asserted_issuer_dn.bv_val,
4184 ber_memfree(serial.bv_val);
4185 ber_memfree(issuer_dn.bv_val);
4186 ber_memfree(asserted_serial.bv_val);
4187 ber_memfree(asserted_issuer_dn.bv_val);
4193 * Index generation function
4194 * We just index the serials, in most scenarios the issuer DN is one of
4195 * a very small set of values.
4197 static int certificateExactIndexer(
4202 struct berval *prefix,
4210 struct berval serial;
4212 /* we should have at least one value at this point */
4213 assert( values != NULL && values[0].bv_val != NULL );
4215 for( i=0; values[i].bv_val != NULL; i++ ) {
4216 /* empty -- just count them */
4219 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
4221 for( i=0; values[i].bv_val != NULL; i++ ) {
4222 p = values[i].bv_val;
4223 xcert = d2i_X509(NULL, &p, values[i].bv_len);
4226 LDAP_LOG( CONFIG, ENTRY,
4227 "certificateExactIndexer: error parsing cert: %s\n",
4228 ERR_error_string(ERR_get_error(),NULL), 0, 0);
4230 Debug( LDAP_DEBUG_ARGS, "certificateExactIndexer: "
4231 "error parsing cert: %s\n",
4232 ERR_error_string(ERR_get_error(),NULL),
4235 /* Do we leak keys on error? */
4236 return LDAP_INVALID_SYNTAX;
4239 asn1_integer2str(xcert->cert_info->serialNumber, &serial);
4241 xintegerNormalize( slap_schema.si_syn_integer,
4242 &serial, &keys[i] );
4243 ber_memfree(serial.bv_val);
4245 LDAP_LOG( CONFIG, ENTRY,
4246 "certificateExactIndexer: returning: %s\n", keys[i].bv_val, 0, 0);
4248 Debug( LDAP_DEBUG_ARGS, "certificateExactIndexer: "
4255 keys[i].bv_val = NULL;
4257 return LDAP_SUCCESS;
4260 /* Index generation function */
4261 /* We think this is always called with a value in matching rule syntax */
4262 static int certificateExactFilter(
4267 struct berval *prefix,
4268 void * assertedValue,
4272 struct berval asserted_serial;
4275 ret = serial_and_issuer_parse( assertedValue, &asserted_serial, NULL );
4276 if( ret != LDAP_SUCCESS ) return ret;
4278 keys = ch_malloc( sizeof( struct berval ) * 2 );
4279 xintegerNormalize( syntax, &asserted_serial, &keys[0] );
4280 keys[1].bv_val = NULL;
4283 ber_memfree(asserted_serial.bv_val);
4284 return LDAP_SUCCESS;
4290 check_time_syntax (struct berval *val,
4294 static int ceiling[9] = { 99, 99, 11, 30, 23, 59, 59, 12, 59 };
4295 static int mdays[2][12] = {
4296 /* non-leap years */
4297 { 30, 27, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30 },
4299 { 30, 28, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30 }
4302 int part, c, tzoffset, leapyear = 0 ;
4304 if( val->bv_len == 0 ) {
4305 return LDAP_INVALID_SYNTAX;
4308 p = (char *)val->bv_val;
4309 e = p + val->bv_len;
4311 /* Ignore initial whitespace */
4312 while ( ( p < e ) && ASCII_SPACE( *p ) ) {
4316 if (e - p < 13 - (2 * start)) {
4317 return LDAP_INVALID_SYNTAX;
4320 for (part = 0; part < 9; part++) {
4324 for (part = start; part < 7; part++) {
4326 if ((part == 6) && (c == 'Z' || c == '+' || c == '-')) {
4333 return LDAP_INVALID_SYNTAX;
4335 if (c < 0 || c > 9) {
4336 return LDAP_INVALID_SYNTAX;
4342 return LDAP_INVALID_SYNTAX;
4344 if (c < 0 || c > 9) {
4345 return LDAP_INVALID_SYNTAX;
4350 if (part == 2 || part == 3) {
4353 if (parts[part] < 0) {
4354 return LDAP_INVALID_SYNTAX;
4356 if (parts[part] > ceiling[part]) {
4357 return LDAP_INVALID_SYNTAX;
4361 /* leapyear check for the Gregorian calendar (year>1581) */
4362 if (((parts[1] % 4 == 0) && (parts[1] != 0)) ||
4363 ((parts[0] % 4 == 0) && (parts[1] == 0)))
4368 if (parts[3] > mdays[leapyear][parts[2]]) {
4369 return LDAP_INVALID_SYNTAX;
4374 tzoffset = 0; /* UTC */
4375 } else if (c != '+' && c != '-') {
4376 return LDAP_INVALID_SYNTAX;
4380 } else /* c == '+' */ {
4385 return LDAP_INVALID_SYNTAX;
4388 for (part = 7; part < 9; part++) {
4390 if (c < 0 || c > 9) {
4391 return LDAP_INVALID_SYNTAX;
4396 if (c < 0 || c > 9) {
4397 return LDAP_INVALID_SYNTAX;
4401 if (parts[part] < 0 || parts[part] > ceiling[part]) {
4402 return LDAP_INVALID_SYNTAX;
4407 /* Ignore trailing whitespace */
4408 while ( ( p < e ) && ASCII_SPACE( *p ) ) {
4412 return LDAP_INVALID_SYNTAX;
4415 switch ( tzoffset ) {
4416 case -1: /* negativ offset to UTC, ie west of Greenwich */
4417 parts[4] += parts[7];
4418 parts[5] += parts[8];
4419 for (part = 6; --part > 0; ) { /* offset is just hhmm, no seconds */
4423 c = mdays[leapyear][parts[2]];
4425 if (parts[part] > c) {
4426 parts[part] -= c + 1;
4431 case 1: /* positive offset to UTC, ie east of Greenwich */
4432 parts[4] -= parts[7];
4433 parts[5] -= parts[8];
4434 for (part = 6; --part > 0; ) {
4438 /* first arg to % needs to be non negativ */
4439 c = mdays[leapyear][(parts[2] - 1 + 12) % 12];
4441 if (parts[part] < 0) {
4442 parts[part] += c + 1;
4447 case 0: /* already UTC */
4451 return LDAP_SUCCESS;
4454 #ifdef SUPPORT_OBSOLETE_UTC_SYNTAX
4459 struct berval *normalized )
4463 rc = check_time_syntax(val, 1, parts);
4464 if (rc != LDAP_SUCCESS) {
4468 normalized->bv_val = ch_malloc( 14 );
4469 if ( normalized->bv_val == NULL ) {
4470 return LBER_ERROR_MEMORY;
4473 sprintf( normalized->bv_val, "%02d%02d%02d%02d%02d%02dZ",
4474 parts[1], parts[2] + 1, parts[3] + 1,
4475 parts[4], parts[5], parts[6] );
4476 normalized->bv_len = 13;
4478 return LDAP_SUCCESS;
4482 #ifdef SUPPORT_OBSOLETE_UTC_SYNTAX
4490 return check_time_syntax(in, 1, parts);
4495 generalizedTimeValidate(
4501 return check_time_syntax(in, 0, parts);
4506 generalizedTimeNormalize(
4511 struct berval *normalized )
4513 xgeneralizedTimeNormalize(
4516 struct berval *normalized )
4521 rc = check_time_syntax(val, 0, parts);
4522 if (rc != LDAP_SUCCESS) {
4526 normalized->bv_val = ch_malloc( 16 );
4527 if ( normalized->bv_val == NULL ) {
4528 return LBER_ERROR_MEMORY;
4531 sprintf( normalized->bv_val, "%02d%02d%02d%02d%02d%02d%02dZ",
4532 parts[0], parts[1], parts[2] + 1, parts[3] + 1,
4533 parts[4], parts[5], parts[6] );
4534 normalized->bv_len = 15;
4536 return LDAP_SUCCESS;
4540 nisNetgroupTripleValidate(
4542 struct berval *val )
4547 if ( val->bv_len == 0 ) {
4548 return LDAP_INVALID_SYNTAX;
4551 p = (char *)val->bv_val;
4552 e = p + val->bv_len;
4554 if ( *p != '(' /*')'*/ ) {
4555 return LDAP_INVALID_SYNTAX;
4558 for ( p++; ( p < e ) && ( *p != /*'('*/ ')' ); p++ ) {
4562 return LDAP_INVALID_SYNTAX;
4565 } else if ( !AD_CHAR( *p ) ) {
4566 return LDAP_INVALID_SYNTAX;
4570 if ( ( commas != 2 ) || ( *p != /*'('*/ ')' ) ) {
4571 return LDAP_INVALID_SYNTAX;
4577 return LDAP_INVALID_SYNTAX;
4580 return LDAP_SUCCESS;
4584 bootParameterValidate(
4586 struct berval *val )
4590 if ( val->bv_len == 0 ) {
4591 return LDAP_INVALID_SYNTAX;
4594 p = (char *)val->bv_val;
4595 e = p + val->bv_len;
4598 for (; ( 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 != ':' ); p++ ) {
4610 if ( !AD_CHAR( *p ) ) {
4611 return LDAP_INVALID_SYNTAX;
4616 return LDAP_INVALID_SYNTAX;
4620 for ( p++; p < e; p++ ) {
4621 if ( !SLAP_PRINTABLE( *p ) ) {
4622 return LDAP_INVALID_SYNTAX;
4626 return LDAP_SUCCESS;
4629 #define X_BINARY "X-BINARY-TRANSFER-REQUIRED 'TRUE' "
4630 #define X_NOT_H_R "X-NOT-HUMAN-READABLE 'TRUE' "
4632 static slap_syntax_defs_rec syntax_defs[] = {
4633 {"( 1.3.6.1.4.1.1466.115.121.1.1 DESC 'ACI Item' "
4634 X_BINARY X_NOT_H_R ")",
4635 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, NULL, NULL, NULL},
4636 {"( 1.3.6.1.4.1.1466.115.121.1.2 DESC 'Access Point' " X_NOT_H_R ")",
4637 0, NULL, NULL, NULL},
4638 {"( 1.3.6.1.4.1.1466.115.121.1.3 DESC 'Attribute Type Description' )",
4639 0, NULL, NULL, NULL},
4640 {"( 1.3.6.1.4.1.1466.115.121.1.4 DESC 'Audio' "
4642 SLAP_SYNTAX_BLOB, blobValidate, NULL, NULL},
4643 {"( 1.3.6.1.4.1.1466.115.121.1.5 DESC 'Binary' "
4645 SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4646 {"( 1.3.6.1.4.1.1466.115.121.1.6 DESC 'Bit String' )",
4647 0, bitStringValidate, NULL, NULL },
4648 {"( 1.3.6.1.4.1.1466.115.121.1.7 DESC 'Boolean' )",
4649 0, booleanValidate, NULL, NULL},
4650 {"( 1.3.6.1.4.1.1466.115.121.1.8 DESC 'Certificate' "
4651 X_BINARY X_NOT_H_R ")",
4652 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4653 {"( 1.3.6.1.4.1.1466.115.121.1.9 DESC 'Certificate List' "
4654 X_BINARY X_NOT_H_R ")",
4655 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4656 {"( 1.3.6.1.4.1.1466.115.121.1.10 DESC 'Certificate Pair' "
4657 X_BINARY X_NOT_H_R ")",
4658 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4659 {"( 1.3.6.1.4.1.1466.115.121.1.11 DESC 'Country String' )",
4660 0, countryStringValidate, xIA5StringNormalize, NULL},
4661 {"( 1.3.6.1.4.1.1466.115.121.1.12 DESC 'Distinguished Name' )",
4662 0, dnValidate, xdnNormalize, dnPretty2},
4663 {"( 1.3.6.1.4.1.1466.115.121.1.13 DESC 'Data Quality' )",
4664 0, NULL, NULL, NULL},
4665 {"( 1.3.6.1.4.1.1466.115.121.1.14 DESC 'Delivery Method' )",
4666 0, NULL, NULL, NULL},
4667 {"( 1.3.6.1.4.1.1466.115.121.1.15 DESC 'Directory String' )",
4668 0, UTF8StringValidate, xUTF8StringNormalize, NULL},
4669 {"( 1.3.6.1.4.1.1466.115.121.1.16 DESC 'DIT Content Rule Description' )",
4670 0, NULL, NULL, NULL},
4671 {"( 1.3.6.1.4.1.1466.115.121.1.17 DESC 'DIT Structure Rule Description' )",
4672 0, NULL, NULL, NULL},
4673 {"( 1.3.6.1.4.1.1466.115.121.1.19 DESC 'DSA Quality' )",
4674 0, NULL, NULL, NULL},
4675 {"( 1.3.6.1.4.1.1466.115.121.1.20 DESC 'DSE Type' )",
4676 0, NULL, NULL, NULL},
4677 {"( 1.3.6.1.4.1.1466.115.121.1.21 DESC 'Enhanced Guide' )",
4678 0, NULL, NULL, NULL},
4679 {"( 1.3.6.1.4.1.1466.115.121.1.22 DESC 'Facsimile Telephone Number' )",
4680 0, printablesStringValidate, xtelephoneNumberNormalize, NULL},
4681 {"( 1.3.6.1.4.1.1466.115.121.1.23 DESC 'Fax' " X_NOT_H_R ")",
4682 SLAP_SYNTAX_BLOB, NULL, NULL, NULL},
4683 {"( 1.3.6.1.4.1.1466.115.121.1.24 DESC 'Generalized Time' )",
4684 0, generalizedTimeValidate, xgeneralizedTimeNormalize, NULL},
4685 {"( 1.3.6.1.4.1.1466.115.121.1.25 DESC 'Guide' )",
4686 0, NULL, NULL, NULL},
4687 {"( 1.3.6.1.4.1.1466.115.121.1.26 DESC 'IA5 String' )",
4688 0, IA5StringValidate, xIA5StringNormalize, NULL},
4689 {"( 1.3.6.1.4.1.1466.115.121.1.27 DESC 'Integer' )",
4690 0, integerValidate, xintegerNormalize, NULL},
4691 {"( 1.3.6.1.4.1.1466.115.121.1.28 DESC 'JPEG' " X_NOT_H_R ")",
4692 SLAP_SYNTAX_BLOB, blobValidate, NULL, NULL},
4693 {"( 1.3.6.1.4.1.1466.115.121.1.29 DESC 'Master And Shadow Access Points' )",
4694 0, NULL, NULL, NULL},
4695 {"( 1.3.6.1.4.1.1466.115.121.1.30 DESC 'Matching Rule Description' )",
4696 0, NULL, NULL, NULL},
4697 {"( 1.3.6.1.4.1.1466.115.121.1.31 DESC 'Matching Rule Use Description' )",
4698 0, NULL, NULL, NULL},
4699 {"( 1.3.6.1.4.1.1466.115.121.1.32 DESC 'Mail Preference' )",
4700 0, NULL, NULL, NULL},
4701 {"( 1.3.6.1.4.1.1466.115.121.1.33 DESC 'MHS OR Address' )",
4702 0, NULL, NULL, NULL},
4703 {"( 1.3.6.1.4.1.1466.115.121.1.34 DESC 'Name And Optional UID' )",
4704 0, nameUIDValidate, xnameUIDNormalize, NULL},
4705 {"( 1.3.6.1.4.1.1466.115.121.1.35 DESC 'Name Form Description' )",
4706 0, NULL, NULL, NULL},
4707 {"( 1.3.6.1.4.1.1466.115.121.1.36 DESC 'Numeric String' )",
4708 0, numericStringValidate, xnumericStringNormalize, NULL},
4709 {"( 1.3.6.1.4.1.1466.115.121.1.37 DESC 'Object Class Description' )",
4710 0, NULL, NULL, NULL},
4711 {"( 1.3.6.1.4.1.1466.115.121.1.38 DESC 'OID' )",
4712 0, oidValidate, NULL, NULL},
4713 {"( 1.3.6.1.4.1.1466.115.121.1.39 DESC 'Other Mailbox' )",
4714 0, IA5StringValidate, xIA5StringNormalize, NULL},
4715 {"( 1.3.6.1.4.1.1466.115.121.1.40 DESC 'Octet String' )",
4716 0, blobValidate, NULL, NULL},
4717 {"( 1.3.6.1.4.1.1466.115.121.1.41 DESC 'Postal Address' )",
4718 0, UTF8StringValidate, xUTF8StringNormalize, NULL},
4719 {"( 1.3.6.1.4.1.1466.115.121.1.42 DESC 'Protocol Information' )",
4720 0, NULL, NULL, NULL},
4721 {"( 1.3.6.1.4.1.1466.115.121.1.43 DESC 'Presentation Address' )",
4722 0, NULL, NULL, NULL},
4723 {"( 1.3.6.1.4.1.1466.115.121.1.44 DESC 'Printable String' )",
4724 0, printableStringValidate, xIA5StringNormalize, NULL},
4725 {"( 1.3.6.1.4.1.1466.115.121.1.45 DESC 'SubtreeSpecification' "
4726 X_BINARY X_NOT_H_R ")",
4727 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, NULL, NULL, NULL},
4728 {"( 1.3.6.1.4.1.1466.115.121.1.49 DESC 'Supported Algorithm' "
4729 X_BINARY X_NOT_H_R ")",
4730 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4731 {"( 1.3.6.1.4.1.1466.115.121.1.50 DESC 'Telephone Number' )",
4732 0, printableStringValidate, xtelephoneNumberNormalize, NULL},
4733 {"( 1.3.6.1.4.1.1466.115.121.1.51 DESC 'Teletex Terminal Identifier' )",
4734 0, NULL, NULL, NULL},
4735 {"( 1.3.6.1.4.1.1466.115.121.1.52 DESC 'Telex Number' )",
4736 0, printablesStringValidate, xIA5StringNormalize, NULL},
4737 #ifdef SUPPORT_OBSOLETE_UTC_SYNTAX
4738 {"( 1.3.6.1.4.1.1466.115.121.1.53 DESC 'UTC Time' )",
4739 0, utcTimeValidate, xutcTimeNormalize, NULL},
4741 {"( 1.3.6.1.4.1.1466.115.121.1.54 DESC 'LDAP Syntax Description' )",
4742 0, NULL, NULL, NULL},
4743 {"( 1.3.6.1.4.1.1466.115.121.1.55 DESC 'Modify Rights' )",
4744 0, NULL, NULL, NULL},
4745 {"( 1.3.6.1.4.1.1466.115.121.1.56 DESC 'LDAP Schema Definition' )",
4746 0, NULL, NULL, NULL},
4747 {"( 1.3.6.1.4.1.1466.115.121.1.57 DESC 'LDAP Schema Description' )",
4748 0, NULL, NULL, NULL},
4749 {"( 1.3.6.1.4.1.1466.115.121.1.58 DESC 'Substring Assertion' )",
4750 0, NULL, NULL, NULL},
4752 /* RFC 2307 NIS Syntaxes */
4753 {"( 1.3.6.1.1.1.0.0 DESC 'RFC2307 NIS Netgroup Triple' )",
4754 0, nisNetgroupTripleValidate, NULL, NULL},
4755 {"( 1.3.6.1.1.1.0.1 DESC 'RFC2307 Boot Parameter' )",
4756 0, bootParameterValidate, NULL, NULL},
4760 /* These OIDs are not published yet, but will be in the next
4761 * I-D for PKIX LDAPv3 schema as have been advanced by David
4762 * Chadwick in private mail.
4764 {"( 1.2.826.0.1.3344810.7.1 DESC 'Serial Number and Issuer' )",
4765 0, UTF8StringValidate, NULL, NULL},
4768 /* OpenLDAP Experimental Syntaxes */
4769 #ifdef SLAPD_ACI_ENABLED
4770 {"( 1.3.6.1.4.1.4203.666.2.1 DESC 'OpenLDAP Experimental ACI' )",
4772 UTF8StringValidate /* THIS WILL CHANGE FOR NEW ACI SYNTAX */,
4776 #ifdef SLAPD_AUTHPASSWD
4777 /* needs updating */
4778 {"( 1.3.6.1.4.1.4203.666.2.2 DESC 'OpenLDAP authPassword' )",
4779 SLAP_SYNTAX_HIDE, NULL, NULL, NULL},
4782 /* OpenLDAP Void Syntax */
4783 {"( 1.3.6.1.4.1.4203.1.1.1 DESC 'OpenLDAP void' )" ,
4784 SLAP_SYNTAX_HIDE, inValidate, NULL, NULL},
4785 {NULL, 0, NULL, NULL, NULL}
4789 char *certificateExactMatchSyntaxes[] = {
4790 "1.3.6.1.4.1.1466.115.121.1.8" /* certificate */,
4794 char *directoryStringSyntaxes[] = {
4795 "1.3.6.1.4.1.1466.115.121.1.44" /* printableString */,
4798 char *integerFirstComponentMatchSyntaxes[] = {
4799 "1.3.6.1.4.1.1466.115.121.1.27" /* INTEGER */,
4800 "1.3.6.1.4.1.1466.115.121.1.17" /* ditStructureRuleDescription */,
4803 char *objectIdentifierFirstComponentMatchSyntaxes[] = {
4804 "1.3.6.1.4.1.1466.115.121.1.38" /* OID */,
4805 "1.3.6.1.4.1.1466.115.121.1.3" /* attributeTypeDescription */,
4806 "1.3.6.1.4.1.1466.115.121.1.16" /* ditContentRuleDescription */,
4807 "1.3.6.1.4.1.1466.115.121.1.54" /* ldapSyntaxDescription */,
4808 "1.3.6.1.4.1.1466.115.121.1.30" /* matchingRuleDescription */,
4809 "1.3.6.1.4.1.1466.115.121.1.31" /* matchingRuleUseDescription */,
4810 "1.3.6.1.4.1.1466.115.121.1.35" /* nameFormDescription */,
4811 "1.3.6.1.4.1.1466.115.121.1.37" /* objectClassDescription */,
4816 * Other matching rules in X.520 that we do not use (yet):
4818 * 2.5.13.9 numericStringOrderingMatch
4819 * 2.5.13.25 uTCTimeMatch
4820 * 2.5.13.26 uTCTimeOrderingMatch
4821 * 2.5.13.31 directoryStringFirstComponentMatch
4822 * 2.5.13.32 wordMatch
4823 * 2.5.13.33 keywordMatch
4824 * 2.5.13.35 certificateMatch
4825 * 2.5.13.36 certificatePairExactMatch
4826 * 2.5.13.37 certificatePairMatch
4827 * 2.5.13.38 certificateListExactMatch
4828 * 2.5.13.39 certificateListMatch
4829 * 2.5.13.40 algorithmIdentifierMatch
4830 * 2.5.13.41 storedPrefixMatch
4831 * 2.5.13.42 attributeCertificateMatch
4832 * 2.5.13.43 readerAndKeyIDMatch
4833 * 2.5.13.44 attributeIntegrityMatch
4835 static slap_mrule_defs_rec mrule_defs[] = {
4837 * EQUALITY matching rules must be listed after associated APPROX
4838 * matching rules. So, we list all APPROX matching rules first.
4840 #ifndef SLAP_NVALUES
4841 {"( " directoryStringApproxMatchOID " NAME 'directoryStringApproxMatch' "
4842 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4843 SLAP_MR_HIDE | SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT, NULL,
4844 NULL, NULL, directoryStringApproxMatch,
4845 directoryStringApproxIndexer, directoryStringApproxFilter,
4848 {"( " IA5StringApproxMatchOID " NAME 'IA5StringApproxMatch' "
4849 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4850 SLAP_MR_HIDE | SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT, NULL,
4851 NULL, NULL, IA5StringApproxMatch,
4852 IA5StringApproxIndexer, IA5StringApproxFilter,
4857 * Other matching rules
4860 {"( 2.5.13.0 NAME 'objectIdentifierMatch' "
4861 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
4862 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4864 objectIdentifierNormalize, objectIdentifierMatch,
4865 objectIdentifierIndexer, objectIdentifierFilter,
4868 {"( 2.5.13.1 NAME 'distinguishedNameMatch' "
4869 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )",
4870 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4872 distinguishedNameNormalize, distinguishedNameMatch,
4873 distinguishedNameIndexer, distinguishedNameFilter,
4876 {"( 2.5.13.2 NAME 'caseIgnoreMatch' "
4877 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4878 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD,
4879 directoryStringSyntaxes,
4881 caseIgnoreNormalize, caseIgnoreMatch,
4882 caseIgnoreIndexer, caseIgnoreFilter,
4883 directoryStringApproxMatchOID },
4885 {"( 2.5.13.3 NAME 'caseIgnoreOrderingMatch' "
4886 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4887 SLAP_MR_ORDERING, directoryStringSyntaxes,
4888 NULL, caseIgnoreNormalize, caseIgnoreOrderingMatch,
4891 {"( 2.5.13.4 NAME 'caseIgnoreSubstringsMatch' "
4892 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4893 SLAP_MR_SUBSTR, NULL,
4895 caseIgnoreSubstringsMatch,
4896 caseIgnoreSubstringsIndexer, caseIgnoreSubstringsFilter,
4899 {"( 2.5.13.5 NAME 'caseExactMatch' "
4900 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4901 SLAP_MR_EQUALITY | SLAP_MR_EXT, directoryStringSyntaxes,
4903 caseExactNormalize, caseExactMatch,
4904 caseExactIndexer, caseExactFilter,
4905 directoryStringApproxMatchOID },
4907 {"( 2.5.13.6 NAME 'caseExactOrderingMatch' "
4908 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4909 SLAP_MR_ORDERING, directoryStringSyntaxes,
4910 NULL, caseExactNormalize, caseExactOrderingMatch,
4913 {"( 2.5.13.7 NAME 'caseExactSubstringsMatch' "
4914 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4915 SLAP_MR_SUBSTR, directoryStringSyntaxes,
4917 NULL, caseExactSubstringsMatch,
4918 caseExactSubstringsIndexer, caseExactSubstringsFilter,
4921 {"( 2.5.13.8 NAME 'numericStringMatch' "
4922 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 )",
4923 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL,
4925 numericStringNormalize, numericStringMatch,
4926 numericStringIndexer, numericStringFilter,
4929 {"( 2.5.13.10 NAME 'numericStringSubstringsMatch' "
4930 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4931 SLAP_MR_SUBSTR, NULL,
4933 NULL, numericStringSubstringsMatch,
4934 numericStringSubstringsIndexer, numericStringSubstringsFilter,
4937 {"( 2.5.13.11 NAME 'caseIgnoreListMatch' "
4938 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )",
4939 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL,
4940 NULL, NULL, NULL, NULL, NULL, NULL},
4942 {"( 2.5.13.12 NAME 'caseIgnoreListSubstringsMatch' "
4943 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4944 SLAP_MR_SUBSTR, NULL,
4945 NULL, NULL, NULL, NULL, NULL, NULL},
4947 {"( 2.5.13.13 NAME 'booleanMatch' "
4948 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )",
4949 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4952 booleanIndexer, booleanFilter,
4955 {"( 2.5.13.14 NAME 'integerMatch' "
4956 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4957 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4959 integerNormalize, integerMatch,
4960 integerIndexer, integerFilter,
4963 {"( 2.5.13.15 NAME 'integerOrderingMatch' "
4964 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4965 SLAP_MR_ORDERING, NULL, NULL,
4966 integerNormalize, integerOrderingMatch,
4967 integerIndexer, integerFilter,
4970 {"( 2.5.13.16 NAME 'bitStringMatch' "
4971 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.6 )",
4972 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4974 NULL, bitStringMatch,
4975 bitStringIndexer, bitStringFilter,
4978 {"( 2.5.13.17 NAME 'octetStringMatch' "
4979 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
4980 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4982 octetStringMatch, octetStringIndexer, octetStringFilter,
4985 {"( 2.5.13.18 NAME 'octetStringOrderingMatch' "
4986 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
4987 SLAP_MR_ORDERING, NULL,
4989 octetStringOrderingMatch, NULL, NULL,
4992 {"( 2.5.13.19 NAME 'octetStringSubstringsMatch' "
4993 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
4994 SLAP_MR_SUBSTR, NULL,
4996 octetStringSubstringsMatch, NULL, NULL,
4999 {"( 2.5.13.20 NAME 'telephoneNumberMatch' "
5000 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 )",
5001 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL,
5003 telephoneNumberNormalize, telephoneNumberMatch,
5004 telephoneNumberIndexer, telephoneNumberFilter,
5007 {"( 2.5.13.21 NAME 'telephoneNumberSubstringsMatch' "
5008 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
5009 SLAP_MR_SUBSTR, NULL,
5010 NULL, NULL, telephoneNumberSubstringsMatch,
5011 telephoneNumberSubstringsIndexer, telephoneNumberSubstringsFilter,
5014 {"( 2.5.13.22 NAME 'presentationAddressMatch' "
5015 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.43 )",
5016 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
5021 {"( 2.5.13.23 NAME 'uniqueMemberMatch' "
5022 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.34 )",
5023 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
5025 uniqueMemberNormalize, uniqueMemberMatch,
5029 {"( 2.5.13.24 NAME 'protocolInformationMatch' "
5030 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.42 )",
5031 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
5032 NULL, NULL, NULL, NULL, NULL, NULL},
5034 {"( 2.5.13.27 NAME 'generalizedTimeMatch' "
5035 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
5036 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
5038 generalizedTimeNormalize, generalizedTimeMatch,
5042 {"( 2.5.13.28 NAME 'generalizedTimeOrderingMatch' "
5043 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
5044 SLAP_MR_ORDERING, NULL,
5046 generalizedTimeNormalize, generalizedTimeOrderingMatch,
5050 {"( 2.5.13.29 NAME 'integerFirstComponentMatch' "
5051 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
5052 SLAP_MR_EQUALITY | SLAP_MR_EXT, integerFirstComponentMatchSyntaxes,
5054 integerFirstComponentNormalize, integerMatch,
5058 {"( 2.5.13.30 NAME 'objectIdentifierFirstComponentMatch' "
5059 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
5060 SLAP_MR_EQUALITY | SLAP_MR_EXT,
5061 objectIdentifierFirstComponentMatchSyntaxes,
5063 objectIdentifierFirstComponentNormalize, objectIdentifierMatch,
5067 #ifndef SLAP_NVALUES
5069 {"( 2.5.13.34 NAME 'certificateExactMatch' "
5070 "SYNTAX 1.2.826.0.1.3344810.7.1 )",
5071 SLAP_MR_EQUALITY | SLAP_MR_EXT, certificateExactMatchSyntaxes,
5072 certificateExactConvert, NULL,
5073 certificateExactMatch,
5074 certificateExactIndexer, certificateExactFilter,
5079 {"( 1.3.6.1.4.1.1466.109.114.1 NAME 'caseExactIA5Match' "
5080 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
5081 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
5083 caseExactIA5Normalize, caseExactIA5Match,
5084 caseExactIA5Indexer, caseExactIA5Filter,
5085 IA5StringApproxMatchOID },
5087 {"( 1.3.6.1.4.1.1466.109.114.2 NAME 'caseIgnoreIA5Match' "
5088 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
5089 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL,
5091 NULL, caseIgnoreIA5Match,
5092 caseIgnoreIA5Indexer, caseIgnoreIA5Filter,
5093 IA5StringApproxMatchOID },
5095 {"( 1.3.6.1.4.1.1466.109.114.3 NAME 'caseIgnoreIA5SubstringsMatch' "
5096 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
5097 SLAP_MR_SUBSTR, NULL,
5099 NULL, caseIgnoreIA5SubstringsMatch,
5100 caseIgnoreIA5SubstringsIndexer, caseIgnoreIA5SubstringsFilter,
5103 {"( 1.3.6.1.4.1.4203.1.2.1 NAME 'caseExactIA5SubstringsMatch' "
5104 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
5105 SLAP_MR_SUBSTR, NULL,
5107 NULL, caseExactIA5SubstringsMatch,
5108 caseExactIA5SubstringsIndexer, caseExactIA5SubstringsFilter,
5111 #ifdef SLAPD_AUTHPASSWD
5112 /* needs updating */
5113 {"( 1.3.6.1.4.1.4203.666.4.1 NAME 'authPasswordMatch' "
5114 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
5115 SLAP_MR_EQUALITY, NULL,
5117 authPasswordMatch, NULL, NULL,
5121 #ifdef SLAPD_ACI_ENABLED
5122 {"( 1.3.6.1.4.1.4203.666.4.2 NAME 'OpenLDAPaciMatch' "
5123 "SYNTAX 1.3.6.1.4.1.4203.666.2.1 )",
5124 SLAP_MR_EQUALITY, NULL,
5126 OpenLDAPaciMatch, NULL, NULL,
5130 {"( 1.2.840.113556.1.4.803 NAME 'integerBitAndMatch' "
5131 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
5134 NULL, integerBitAndMatch, NULL, NULL,
5137 {"( 1.2.840.113556.1.4.804 NAME 'integerBitOrMatch' "
5138 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
5141 NULL, integerBitOrMatch, NULL, NULL,
5144 {NULL, SLAP_MR_NONE, NULL,
5145 NULL, NULL, NULL, NULL, NULL,
5150 slap_schema_init( void )
5155 /* we should only be called once (from main) */
5156 assert( schema_init_done == 0 );
5158 for ( i=0; syntax_defs[i].sd_desc != NULL; i++ ) {
5159 res = register_syntax( &syntax_defs[i] );
5162 fprintf( stderr, "slap_schema_init: Error registering syntax %s\n",
5163 syntax_defs[i].sd_desc );
5168 for ( i=0; mrule_defs[i].mrd_desc != NULL; i++ ) {
5169 if( mrule_defs[i].mrd_usage == SLAP_MR_NONE &&
5170 mrule_defs[i].mrd_compat_syntaxes == NULL )
5173 "slap_schema_init: Ignoring unusable matching rule %s\n",
5174 mrule_defs[i].mrd_desc );
5178 res = register_matching_rule( &mrule_defs[i] );
5182 "slap_schema_init: Error registering matching rule %s\n",
5183 mrule_defs[i].mrd_desc );
5188 res = slap_schema_load();
5189 schema_init_done = 1;
5194 schema_destroy( void )