1 /* schema_init.c - init builtin schema */
4 * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
5 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
15 #include <ac/string.h>
16 #include <ac/socket.h>
22 #include "ldap_utf8.h"
24 #include "lutil_hash.h"
25 #define HASH_BYTES LUTIL_HASH_BYTES
26 #define HASH_CONTEXT lutil_HASH_CTX
27 #define HASH_Init(c) lutil_HASHInit(c)
28 #define HASH_Update(c,buf,len) lutil_HASHUpdate(c,buf,len)
29 #define HASH_Final(d,c) lutil_HASHFinal(d,c)
33 #define SLAP_MR_DN_FOLD (0)
35 #define SLAP_MR_ASSOCIATED(mr, with) \
36 ((mr) == (with) || (mr)->smr_associated == (with))
38 #define xUTF8StringNormalize NULL
39 #define xIA5StringNormalize NULL
40 #define xtelephoneNumberNormalize NULL
41 #define xgeneralizedTimeNormalize NULL
42 #define xintegerNormalize NULL
43 #define xnumericStringNormalize NULL
44 #define xnameUIDNormalize NULL
45 #define xdnNormalize NULL
47 /* (new) normalization routines */
48 #define caseExactIA5Normalize IA5StringNormalize
49 #define caseIgnoreIA5Normalize IA5StringNormalize
50 #define caseExactNormalize UTF8StringNormalize
51 #define caseIgnoreNormalize UTF8StringNormalize
53 #define integerFirstComponentNormalize NULL
54 #define objectIdentifierNormalize NULL
55 #define objectIdentifierFirstComponentNormalize NULL
57 #define distinguishedNameNormalize dnNormalize
58 #define distinguishedNameMatch dnMatch
59 #define distinguishedNameIndexer octetStringIndexer
60 #define distinguishedNameFilter octetStringFilter
62 #define integerOrderingMatch integerMatch
63 #define integerFirstComponentMatch NULL
64 #define integerIndexer octetStringIndexer
65 #define integerFilter octetStringFilter
67 #define generalizedTimeMatch caseIgnoreIA5Match
68 #define generalizedTimeOrderingMatch caseIgnoreIA5Match
70 #define uniqueMemberMatch dnMatch /* FIXME! */
72 #define objectIdentifierMatch octetStringMatch
73 #define objectIdentifierIndexer octetStringIndexer
74 #define objectIdentifierFilter octetStringFilter
76 #define OpenLDAPaciMatch NULL
78 #define bitStringMatch octetStringMatch
79 #define bitStringIndexer octetStringIndexer
80 #define bitStringFilter octetStringFilter
82 #define caseIgnoreMatch octetStringMatch
83 #define caseIgnoreOrderingMatch octetStringOrderingMatch
84 #define caseIgnoreIndexer octetStringIndexer
85 #define caseIgnoreFilter octetStringFilter
87 #define caseIgnoreSubstringsMatch octetStringSubstringsMatch
88 #define caseIgnoreSubstringsIndexer octetStringSubstringsIndexer
89 #define caseIgnoreSubstringsFilter octetStringSubstringsFilter
91 #define caseExactMatch octetStringMatch
92 #define caseExactOrderingMatch octetStringOrderingMatch
93 #define caseExactIndexer octetStringIndexer
94 #define caseExactFilter octetStringFilter
96 #define caseExactSubstringsMatch octetStringSubstringsMatch
97 #define caseExactSubstringsIndexer octetStringSubstringsIndexer
98 #define caseExactSubstringsFilter octetStringSubstringsFilter
100 #define caseExactIA5Match octetStringMatch
101 #define caseExactIA5Indexer octetStringIndexer
102 #define caseExactIA5Filter octetStringFilter
104 #define caseExactIA5SubstringsMatch octetStringSubstringsMatch
105 #define caseExactIA5SubstringsIndexer octetStringSubstringsIndexer
106 #define caseExactIA5SubstringsFilter octetStringSubstringsFilter
108 #define caseIgnoreIA5Match octetStringMatch
109 #define caseIgnoreIA5Indexer octetStringIndexer
110 #define caseIgnoreIA5Filter octetStringFilter
112 #define caseIgnoreIA5SubstringsMatch caseExactIA5SubstringsMatch
113 #define caseIgnoreIA5SubstringsIndexer caseExactIA5SubstringsIndexer
114 #define caseIgnoreIA5SubstringsFilter caseExactIA5SubstringsFilter
116 #define numericStringMatch octetStringMatch
117 #define numericStringIndexer octetStringIndexer
118 #define numericStringFilter octetStringFilter
120 #define numericStringSubstringsMatch caseExactIA5SubstringsMatch
121 #define numericStringSubstringsIndexer caseExactIA5SubstringsIndexer
122 #define numericStringSubstringsFilter caseExactIA5SubstringsFilter
124 #define telephoneNumberMatch octetStringMatch
125 #define telephoneNumberIndexer octetStringIndexer
126 #define telephoneNumberFilter octetStringFilter
128 #define telephoneNumberSubstringsMatch caseExactIA5SubstringsMatch
129 #define telephoneNumberSubstringsIndexer caseExactIA5SubstringsIndexer
130 #define telephoneNumberSubstringsFilter caseExactIA5SubstringsFilter
132 #define booleanIndexer octetStringIndexer
133 #define booleanFilter octetStringFilter
136 /* validatation routines */
137 #define berValidate blobValidate
139 /* approx matching rules */
141 #define directoryStringApproxMatchOID NULL
142 #define IA5StringApproxMatchOID NULL
144 #define directoryStringApproxMatchOID "1.3.6.1.4.1.4203.666.4.4"
145 #define directoryStringApproxMatch approxMatch
146 #define directoryStringApproxIndexer approxIndexer
147 #define directoryStringApproxFilter approxFilter
148 #define IA5StringApproxMatchOID "1.3.6.1.4.1.4203.666.4.5"
149 #define IA5StringApproxMatch approxMatch
150 #define IA5StringApproxIndexer approxIndexer
151 #define IA5StringApproxFilter approxFilter
156 #define xdnNormalize dnNormalize
158 /* (new) normalization routines */
159 #define caseExactNormalize NULL
160 #define caseExactIA5Normalize NULL
161 #define caseIgnoreNormalize NULL
162 #define caseIgnoreIA5Normalize NULL
163 #define distinguishedNameNormalize NULL
164 #define integerNormalize NULL
165 #define integerFirstComponentNormalize NULL
166 #define numericStringNormalize NULL
167 #define objectIdentifierNormalize NULL
168 #define objectIdentifierFirstComponentNormalize NULL
169 #define generalizedTimeNormalize NULL
170 #define uniqueMemberNormalize NULL
171 #define telephoneNumberNormalize NULL
174 /* matching routines */
175 #define bitStringMatch octetStringMatch
176 #define bitStringIndexer octetStringIndexer
177 #define bitStringFilter octetStringFilter
179 #define numericStringMatch caseIgnoreIA5Match
180 #define numericStringIndexer NULL
181 #define numericStringFilter NULL
182 #define numericStringSubstringsIndexer NULL
183 #define numericStringSubstringsFilter NULL
185 #define objectIdentifierMatch octetStringMatch
186 #define objectIdentifierIndexer caseIgnoreIA5Indexer
187 #define objectIdentifierFilter caseIgnoreIA5Filter
189 #define octetStringSubstringsMatch NULL
190 #define OpenLDAPaciMatch NULL
192 #define generalizedTimeMatch caseIgnoreIA5Match
193 #define generalizedTimeOrderingMatch caseIgnoreIA5Match
195 #define uniqueMemberMatch dnMatch
196 #define numericStringSubstringsMatch NULL
198 #define caseExactIndexer caseExactIgnoreIndexer
199 #define caseExactFilter caseExactIgnoreFilter
200 #define caseExactOrderingMatch caseExactMatch
201 #define caseExactSubstringsMatch caseExactIgnoreSubstringsMatch
202 #define caseExactSubstringsIndexer caseExactIgnoreSubstringsIndexer
203 #define caseExactSubstringsFilter caseExactIgnoreSubstringsFilter
204 #define caseIgnoreIndexer caseExactIgnoreIndexer
205 #define caseIgnoreFilter caseExactIgnoreFilter
206 #define caseIgnoreOrderingMatch caseIgnoreMatch
207 #define caseIgnoreSubstringsMatch caseExactIgnoreSubstringsMatch
208 #define caseIgnoreSubstringsIndexer caseExactIgnoreSubstringsIndexer
209 #define caseIgnoreSubstringsFilter caseExactIgnoreSubstringsFilter
211 #define integerOrderingMatch integerMatch
212 #define integerFirstComponentMatch integerMatch
214 #define distinguishedNameMatch dnMatch
215 #define distinguishedNameIndexer caseExactIgnoreIndexer
216 #define distinguishedNameFilter caseExactIgnoreFilter
218 #define telephoneNumberMatch caseIgnoreIA5Match
219 #define telephoneNumberSubstringsMatch caseIgnoreIA5SubstringsMatch
220 #define telephoneNumberIndexer caseIgnoreIA5Indexer
221 #define telephoneNumberFilter caseIgnoreIA5Filter
222 #define telephoneNumberSubstringsIndexer caseIgnoreIA5SubstringsIndexer
223 #define telephoneNumberSubstringsFilter caseIgnoreIA5SubstringsFilter
225 #define booleanIndexer octetStringIndexer
226 #define booleanFilter octetStringFilter
230 static char *bvcasechr( struct berval *bv, unsigned char c, ber_len_t *len )
233 char lower = TOLOWER( c );
234 char upper = TOUPPER( c );
236 if( c == 0 ) return NULL;
238 for( i=0; i < bv->bv_len; i++ ) {
239 if( upper == bv->bv_val[i] || lower == bv->bv_val[i] ) {
241 return &bv->bv_val[i];
254 struct berval *value,
255 void *assertedValue )
257 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
260 match = memcmp( value->bv_val,
261 ((struct berval *) assertedValue)->bv_val,
270 octetStringOrderingMatch(
275 struct berval *value,
276 void *assertedValue )
278 ber_len_t v_len = value->bv_len;
279 ber_len_t av_len = ((struct berval *) assertedValue)->bv_len;
281 int match = memcmp( value->bv_val,
282 ((struct berval *) assertedValue)->bv_val,
283 (v_len < av_len ? v_len : av_len) );
285 if( match == 0 ) match = v_len - av_len;
291 /* Index generation function */
292 int octetStringIndexer(
297 struct berval *prefix,
304 HASH_CONTEXT HASHcontext;
305 unsigned char HASHdigest[HASH_BYTES];
306 struct berval digest;
307 digest.bv_val = HASHdigest;
308 digest.bv_len = sizeof(HASHdigest);
310 for( i=0; values[i].bv_val != NULL; i++ ) {
311 /* just count them */
314 /* we should have at least one value at this point */
317 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
319 slen = syntax->ssyn_oidlen;
320 mlen = mr->smr_oidlen;
322 for( i=0; values[i].bv_val != NULL; i++ ) {
323 HASH_Init( &HASHcontext );
324 if( prefix != NULL && prefix->bv_len > 0 ) {
325 HASH_Update( &HASHcontext,
326 prefix->bv_val, prefix->bv_len );
328 HASH_Update( &HASHcontext,
329 syntax->ssyn_oid, slen );
330 HASH_Update( &HASHcontext,
332 HASH_Update( &HASHcontext,
333 values[i].bv_val, values[i].bv_len );
334 HASH_Final( HASHdigest, &HASHcontext );
336 ber_dupbv( &keys[i], &digest );
339 keys[i].bv_val = NULL;
347 /* Index generation function */
348 int octetStringFilter(
353 struct berval *prefix,
354 void * assertedValue,
359 HASH_CONTEXT HASHcontext;
360 unsigned char HASHdigest[HASH_BYTES];
361 struct berval *value = (struct berval *) assertedValue;
362 struct berval digest;
363 digest.bv_val = HASHdigest;
364 digest.bv_len = sizeof(HASHdigest);
366 slen = syntax->ssyn_oidlen;
367 mlen = mr->smr_oidlen;
369 keys = ch_malloc( sizeof( struct berval ) * 2 );
371 HASH_Init( &HASHcontext );
372 if( prefix != NULL && prefix->bv_len > 0 ) {
373 HASH_Update( &HASHcontext,
374 prefix->bv_val, prefix->bv_len );
376 HASH_Update( &HASHcontext,
377 syntax->ssyn_oid, slen );
378 HASH_Update( &HASHcontext,
380 HASH_Update( &HASHcontext,
381 value->bv_val, value->bv_len );
382 HASH_Final( HASHdigest, &HASHcontext );
384 ber_dupbv( keys, &digest );
385 keys[1].bv_val = NULL;
398 /* no value allowed */
399 return LDAP_INVALID_SYNTAX;
407 /* any value allowed */
418 /* very unforgiving validation, requires no normalization
419 * before simplistic matching
421 if( in->bv_len < 3 ) {
422 return LDAP_INVALID_SYNTAX;
426 * rfc 2252 section 6.3 Bit String
427 * bitstring = "'" *binary-digit "'"
428 * binary-digit = "0" / "1"
429 * example: '0101111101'B
432 if( in->bv_val[0] != '\'' ||
433 in->bv_val[in->bv_len-2] != '\'' ||
434 in->bv_val[in->bv_len-1] != 'B' )
436 return LDAP_INVALID_SYNTAX;
439 for( i=in->bv_len-3; i>0; i-- ) {
440 if( in->bv_val[i] != '0' && in->bv_val[i] != '1' ) {
441 return LDAP_INVALID_SYNTAX;
456 if( in->bv_len == 0 ) return LDAP_SUCCESS;
458 ber_dupbv( &dn, in );
459 if( !dn.bv_val ) return LDAP_OTHER;
461 if( dn.bv_val[dn.bv_len-1] == 'B'
462 && dn.bv_val[dn.bv_len-2] == '\'' )
464 /* assume presence of optional UID */
467 for(i=dn.bv_len-3; i>1; i--) {
468 if( dn.bv_val[i] != '0' && dn.bv_val[i] != '1' ) {
472 if( dn.bv_val[i] != '\'' || dn.bv_val[i-1] != '#' ) {
473 ber_memfree( dn.bv_val );
474 return LDAP_INVALID_SYNTAX;
477 /* trim the UID to allow use of dnValidate */
478 dn.bv_val[i-1] = '\0';
482 rc = dnValidate( NULL, &dn );
484 ber_memfree( dn.bv_val );
490 uniqueMemberNormalize(
495 struct berval *normalized )
501 struct berval *normalized )
507 ber_dupbv( &out, val );
508 if( out.bv_len != 0 ) {
509 struct berval uid = { 0, NULL };
511 if( out.bv_val[out.bv_len-1] == 'B'
512 && out.bv_val[out.bv_len-2] == '\'' )
514 /* assume presence of optional UID */
515 uid.bv_val = strrchr( out.bv_val, '#' );
517 if( uid.bv_val == NULL ) {
519 return LDAP_INVALID_SYNTAX;
522 uid.bv_len = out.bv_len - (uid.bv_val - out.bv_val);
523 out.bv_len -= uid.bv_len--;
525 /* temporarily trim the UID */
526 *(uid.bv_val++) = '\0';
529 rc = dnNormalize2( NULL, &out, normalized );
531 if( rc != LDAP_SUCCESS ) {
533 return LDAP_INVALID_SYNTAX;
537 normalized->bv_val = ch_realloc( normalized->bv_val,
538 normalized->bv_len + uid.bv_len + sizeof("#") );
540 /* insert the separator */
541 normalized->bv_val[normalized->bv_len++] = '#';
544 AC_MEMCPY( &normalized->bv_val[normalized->bv_len],
545 uid.bv_val, uid.bv_len );
546 normalized->bv_len += uid.bv_len;
549 normalized->bv_val[normalized->bv_len] = '\0';
559 * Handling boolean syntax and matching is quite rigid.
560 * A more flexible approach would be to allow a variety
561 * of strings to be normalized and prettied into TRUE
569 /* very unforgiving validation, requires no normalization
570 * before simplistic matching
573 if( in->bv_len == 4 ) {
574 if( !memcmp( in->bv_val, "TRUE", 4 ) ) {
577 } else if( in->bv_len == 5 ) {
578 if( !memcmp( in->bv_val, "FALSE", 5 ) ) {
583 return LDAP_INVALID_SYNTAX;
592 struct berval *value,
593 void *assertedValue )
595 /* simplistic matching allowed by rigid validation */
596 struct berval *asserted = (struct berval *) assertedValue;
597 *matchp = value->bv_len != asserted->bv_len;
601 /*-------------------------------------------------------------------
602 LDAP/X.500 string syntax / matching rules have a few oddities. This
603 comment attempts to detail how slapd(8) treats them.
606 StringSyntax X.500 LDAP Matching/Comments
607 DirectoryString CHOICE UTF8 i/e + ignore insignificant spaces
608 PrintableString subset subset i/e + ignore insignificant spaces
609 PrintableString subset subset i/e + ignore insignificant spaces
610 NumericString subset subset ignore all spaces
611 IA5String ASCII ASCII i/e + ignore insignificant spaces
612 TeletexString T.61 T.61 i/e + ignore insignificant spaces
614 TelephoneNumber subset subset i + ignore all spaces and "-"
616 See draft-ietf-ldapbis-strpro for details (once published).
620 In X.500(93), a directory string can be either a PrintableString,
621 a bmpString, or a UniversalString (e.g., UCS (a subset of Unicode)).
622 In later versions, more CHOICEs were added. In all cases the string
625 In LDAPv3, a directory string is a UTF-8 encoded UCS string.
626 A directory string cannot be zero length.
628 For matching, there are both case ignore and exact rules. Both
629 also require that "insignificant" spaces be ignored.
630 spaces before the first non-space are ignored;
631 spaces after the last non-space are ignored;
632 spaces after a space are ignored.
633 Note: by these rules (and as clarified in X.520), a string of only
634 spaces is to be treated as if held one space, not empty (which
635 would be a syntax error).
638 In ASN.1, numeric string is just a string of digits and spaces
639 and could be empty. However, in X.500, all attribute values of
640 numeric string carry a non-empty constraint. For example:
642 internationalISDNNumber ATTRIBUTE ::= {
643 WITH SYNTAX InternationalISDNNumber
644 EQUALITY MATCHING RULE numericStringMatch
645 SUBSTRINGS MATCHING RULE numericStringSubstringsMatch
646 ID id-at-internationalISDNNumber }
647 InternationalISDNNumber ::=
648 NumericString (SIZE(1..ub-international-isdn-number))
650 Unforunately, some assertion values are don't carry the same
651 constraint (but its unclear how such an assertion could ever
652 be true). In LDAP, there is one syntax (numericString) not two
653 (numericString with constraint, numericString without constraint).
654 This should be treated as numericString with non-empty constraint.
655 Note that while someone may have no ISDN number, there are no ISDN
656 numbers which are zero length.
658 In matching, spaces are ignored.
661 In ASN.1, Printable string is just a string of printable characters
662 and can be empty. In X.500, semantics much like NumericString (see
663 serialNumber for a like example) excepting uses insignificant space
664 handling instead of ignore all spaces.
667 Basically same as PrintableString. There are no examples in X.500,
668 but same logic applies. So we require them to be non-empty as
671 -------------------------------------------------------------------*/
680 unsigned char *u = in->bv_val;
682 if( in->bv_len == 0 && syntax == slap_schema.si_syn_directoryString ) {
683 /* directory strings cannot be empty */
684 return LDAP_INVALID_SYNTAX;
687 for( count = in->bv_len; count > 0; count-=len, u+=len ) {
688 /* get the length indicated by the first byte */
689 len = LDAP_UTF8_CHARLEN2( u, len );
691 /* very basic checks */
694 if( (u[5] & 0xC0) != 0x80 ) {
695 return LDAP_INVALID_SYNTAX;
698 if( (u[4] & 0xC0) != 0x80 ) {
699 return LDAP_INVALID_SYNTAX;
702 if( (u[3] & 0xC0) != 0x80 ) {
703 return LDAP_INVALID_SYNTAX;
706 if( (u[2] & 0xC0 )!= 0x80 ) {
707 return LDAP_INVALID_SYNTAX;
710 if( (u[1] & 0xC0) != 0x80 ) {
711 return LDAP_INVALID_SYNTAX;
714 /* CHARLEN already validated it */
717 return LDAP_INVALID_SYNTAX;
720 /* make sure len corresponds with the offset
721 to the next character */
722 if( LDAP_UTF8_OFFSET( u ) != len ) return LDAP_INVALID_SYNTAX;
726 return LDAP_INVALID_SYNTAX;
739 struct berval *normalized )
741 struct berval tmp, nvalue;
745 if( val->bv_val == NULL ) {
746 /* assume we're dealing with a syntax (e.g., UTF8String)
747 * which allows empty strings
749 normalized->bv_len = 0;
750 normalized->bv_val = NULL;
754 flags = SLAP_MR_ASSOCIATED(mr, slap_schema.si_mr_caseExactMatch )
755 ? LDAP_UTF8_NOCASEFOLD : LDAP_UTF8_CASEFOLD;
756 flags |= ( use & SLAP_MR_EQUALITY_APPROX == SLAP_MR_EQUALITY_APPROX )
757 ? LDAP_UTF8_APPROX : 0;
759 val = UTF8bvnormalize( val, &tmp, flags );
764 /* collapse spaces (in place) */
766 nvalue.bv_val = tmp.bv_val;
768 wasspace=1; /* trim leading spaces */
769 for( i=0; i<tmp.bv_len; i++) {
770 if ( ASCII_SPACE( tmp.bv_val[i] )) {
771 if( wasspace++ == 0 ) {
772 /* trim repeated spaces */
773 nvalue.bv_val[nvalue.bv_len++] = tmp.bv_val[i];
777 nvalue.bv_val[nvalue.bv_len++] = tmp.bv_val[i];
781 if( nvalue.bv_len ) {
783 /* last character was a space, trim it */
786 nvalue.bv_val[nvalue.bv_len] = '\0';
789 /* string of all spaces is treated as one space */
790 nvalue.bv_val[0] = ' ';
791 nvalue.bv_val[1] = '\0';
795 *normalized = nvalue;
801 xUTF8StringNormalize(
804 struct berval *normalized )
809 /* validator should have refused an empty string */
810 assert( val->bv_len );
814 /* Ignore initial whitespace */
815 /* All space is ASCII. All ASCII is 1 byte */
816 for ( ; p < val->bv_val + val->bv_len && ASCII_SPACE( p[ 0 ] ); p++ );
818 normalized->bv_len = val->bv_len - (p - val->bv_val);
820 if( !normalized->bv_len ) {
821 ber_mem2bv( " ", 1, 1, normalized );
825 ber_mem2bv( p, normalized->bv_len, 1, normalized );
826 e = normalized->bv_val + normalized->bv_len;
828 assert( normalized->bv_val );
830 p = q = normalized->bv_val;
835 if ( ASCII_SPACE( *p ) ) {
840 /* Ignore the extra whitespace */
841 while ( ASCII_SPACE( *p ) ) {
845 len = LDAP_UTF8_COPY(q,p);
851 assert( normalized->bv_val <= p );
852 assert( q+len <= p );
854 /* cannot start with a space */
855 assert( !ASCII_SPACE( normalized->bv_val[0] ) );
858 * If the string ended in space, backup the pointer one
859 * position. One is enough because the above loop collapsed
860 * all whitespace to a single space.
868 /* cannot end with a space */
869 assert( !ASCII_SPACE( *q ) );
876 normalized->bv_len = q - normalized->bv_val;
881 /* Returns Unicode canonically normalized copy of a substring assertion
882 * Skipping attribute description */
883 static SubstringsAssertion *
884 UTF8SubstringsAssertionNormalize(
885 SubstringsAssertion *sa,
888 SubstringsAssertion *nsa;
891 nsa = (SubstringsAssertion *)SLAP_CALLOC( 1, sizeof(SubstringsAssertion) );
896 if( sa->sa_initial.bv_val != NULL ) {
897 UTF8bvnormalize( &sa->sa_initial, &nsa->sa_initial, casefold );
898 if( nsa->sa_initial.bv_val == NULL ) {
903 if( sa->sa_any != NULL ) {
904 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
907 nsa->sa_any = (struct berval *)
908 SLAP_MALLOC( (i + 1) * sizeof(struct berval) );
909 if( nsa->sa_any == NULL ) {
913 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
914 UTF8bvnormalize( &sa->sa_any[i], &nsa->sa_any[i],
916 if( nsa->sa_any[i].bv_val == NULL ) {
920 nsa->sa_any[i].bv_val = NULL;
923 if( sa->sa_final.bv_val != NULL ) {
924 UTF8bvnormalize( &sa->sa_final, &nsa->sa_final, casefold );
925 if( nsa->sa_final.bv_val == NULL ) {
933 if ( nsa->sa_final.bv_val ) free( nsa->sa_final.bv_val );
934 if ( nsa->sa_any ) ber_bvarray_free( nsa->sa_any );
935 if ( nsa->sa_initial.bv_val ) free( nsa->sa_initial.bv_val );
940 #ifndef SLAPD_APPROX_OLDSINGLESTRING
942 #if defined(SLAPD_APPROX_INITIALS)
943 #define SLAPD_APPROX_DELIMITER "._ "
944 #define SLAPD_APPROX_WORDLEN 2
946 #define SLAPD_APPROX_DELIMITER " "
947 #define SLAPD_APPROX_WORDLEN 1
956 struct berval *value,
957 void *assertedValue )
959 struct berval *nval, *assertv;
960 char *val, **values, **words, *c;
961 int i, count, len, nextchunk=0, nextavail=0;
963 /* Yes, this is necessary */
964 nval = UTF8bvnormalize( value, NULL, LDAP_UTF8_APPROX );
970 /* Yes, this is necessary */
971 assertv = UTF8bvnormalize( ((struct berval *)assertedValue),
972 NULL, LDAP_UTF8_APPROX );
973 if( assertv == NULL ) {
979 /* Isolate how many words there are */
980 for ( c = nval->bv_val, count = 1; *c; c++ ) {
981 c = strpbrk( c, SLAPD_APPROX_DELIMITER );
982 if ( c == NULL ) break;
987 /* Get a phonetic copy of each word */
988 words = (char **)ch_malloc( count * sizeof(char *) );
989 values = (char **)ch_malloc( count * sizeof(char *) );
990 for ( c = nval->bv_val, i = 0; i < count; i++, c += strlen(c) + 1 ) {
992 values[i] = phonetic(c);
995 /* Work through the asserted value's words, to see if at least some
996 of the words are there, in the same order. */
998 while ( (ber_len_t) nextchunk < assertv->bv_len ) {
999 len = strcspn( assertv->bv_val + nextchunk, SLAPD_APPROX_DELIMITER);
1004 #if defined(SLAPD_APPROX_INITIALS)
1005 else if( len == 1 ) {
1006 /* Single letter words need to at least match one word's initial */
1007 for( i=nextavail; i<count; i++ )
1008 if( !strncasecmp( assertv->bv_val + nextchunk, words[i], 1 )) {
1015 /* Isolate the next word in the asserted value and phonetic it */
1016 assertv->bv_val[nextchunk+len] = '\0';
1017 val = phonetic( assertv->bv_val + nextchunk );
1019 /* See if this phonetic chunk is in the remaining words of *value */
1020 for( i=nextavail; i<count; i++ ){
1021 if( !strcmp( val, values[i] ) ){
1029 /* This chunk in the asserted value was NOT within the *value. */
1035 /* Go on to the next word in the asserted value */
1039 /* If some of the words were seen, call it a match */
1040 if( nextavail > 0 ) {
1047 /* Cleanup allocs */
1048 ber_bvfree( assertv );
1049 for( i=0; i<count; i++ ) {
1050 ch_free( values[i] );
1056 return LDAP_SUCCESS;
1065 struct berval *prefix,
1070 int i,j, len, wordcount, keycount=0;
1071 struct berval *newkeys;
1072 BerVarray keys=NULL;
1074 for( j=0; values[j].bv_val != NULL; j++ ) {
1075 struct berval val = { 0, NULL };
1076 /* Yes, this is necessary */
1077 UTF8bvnormalize( &values[j], &val, LDAP_UTF8_APPROX );
1078 assert( val.bv_val != NULL );
1080 /* Isolate how many words there are. There will be a key for each */
1081 for( wordcount = 0, c = val.bv_val; *c; c++) {
1082 len = strcspn(c, SLAPD_APPROX_DELIMITER);
1083 if( len >= SLAPD_APPROX_WORDLEN ) wordcount++;
1085 if (*c == '\0') break;
1089 /* Allocate/increase storage to account for new keys */
1090 newkeys = (struct berval *)ch_malloc( (keycount + wordcount + 1)
1091 * sizeof(struct berval) );
1092 AC_MEMCPY( newkeys, keys, keycount * sizeof(struct berval) );
1093 if( keys ) ch_free( keys );
1096 /* Get a phonetic copy of each word */
1097 for( c = val.bv_val, i = 0; i < wordcount; c += len + 1 ) {
1099 if( len < SLAPD_APPROX_WORDLEN ) continue;
1100 ber_str2bv( phonetic( c ), 0, 0, &keys[keycount] );
1105 ber_memfree( val.bv_val );
1107 keys[keycount].bv_val = NULL;
1110 return LDAP_SUCCESS;
1119 struct berval *prefix,
1120 void * assertedValue,
1128 /* Yes, this is necessary */
1129 val = UTF8bvnormalize( ((struct berval *)assertedValue),
1130 NULL, LDAP_UTF8_APPROX );
1131 if( val == NULL || val->bv_val == NULL ) {
1132 keys = (struct berval *)ch_malloc( sizeof(struct berval) );
1133 keys[0].bv_val = NULL;
1136 return LDAP_SUCCESS;
1139 /* Isolate how many words there are. There will be a key for each */
1140 for( count = 0,c = val->bv_val; *c; c++) {
1141 len = strcspn(c, SLAPD_APPROX_DELIMITER);
1142 if( len >= SLAPD_APPROX_WORDLEN ) count++;
1144 if (*c == '\0') break;
1148 /* Allocate storage for new keys */
1149 keys = (struct berval *)ch_malloc( (count + 1) * sizeof(struct berval) );
1151 /* Get a phonetic copy of each word */
1152 for( c = val->bv_val, i = 0; i < count; c += len + 1 ) {
1154 if( len < SLAPD_APPROX_WORDLEN ) continue;
1155 ber_str2bv( phonetic( c ), 0, 0, &keys[i] );
1161 keys[count].bv_val = NULL;
1164 return LDAP_SUCCESS;
1169 /* No other form of Approximate Matching is defined */
1177 struct berval *value,
1178 void *assertedValue )
1180 char *vapprox, *avapprox;
1183 /* Yes, this is necessary */
1184 s = UTF8normalize( value, UTF8_NOCASEFOLD );
1187 return LDAP_SUCCESS;
1190 /* Yes, this is necessary */
1191 t = UTF8normalize( ((struct berval *)assertedValue),
1196 return LDAP_SUCCESS;
1199 vapprox = phonetic( strip8bitChars( s ) );
1200 avapprox = phonetic( strip8bitChars( t ) );
1205 *matchp = strcmp( vapprox, avapprox );
1208 ch_free( avapprox );
1210 return LDAP_SUCCESS;
1219 struct berval *prefix,
1227 for( i=0; values[i].bv_val != NULL; i++ ) {
1228 /* empty - just count them */
1231 /* we should have at least one value at this point */
1234 keys = (struct berval *)ch_malloc( sizeof( struct berval ) * (i+1) );
1236 /* Copy each value and run it through phonetic() */
1237 for( i=0; values[i].bv_val != NULL; i++ ) {
1238 /* Yes, this is necessary */
1239 s = UTF8normalize( &values[i], UTF8_NOCASEFOLD );
1241 /* strip 8-bit chars and run through phonetic() */
1242 ber_str2bv( phonetic( strip8bitChars( s ) ), 0, 0, &keys[i] );
1245 keys[i].bv_val = NULL;
1248 return LDAP_SUCCESS;
1258 struct berval *prefix,
1259 void * assertedValue,
1265 keys = (struct berval *)ch_malloc( sizeof( struct berval * ) * 2 );
1267 /* Yes, this is necessary */
1268 s = UTF8normalize( ((struct berval *)assertedValue),
1273 /* strip 8-bit chars and run through phonetic() */
1274 keys[0] = ber_bvstr( phonetic( strip8bitChars( s ) ) );
1280 return LDAP_SUCCESS;
1291 struct berval *value,
1292 void *assertedValue )
1294 *matchp = UTF8bvnormcmp( value,
1295 (struct berval *) assertedValue,
1296 LDAP_UTF8_NOCASEFOLD );
1297 return LDAP_SUCCESS;
1301 caseExactIgnoreSubstringsMatch(
1306 struct berval *value,
1307 void *assertedValue )
1310 SubstringsAssertion *sub = NULL;
1311 struct berval left = { 0, NULL };
1317 casefold = ( mr != slap_schema.si_mr_caseExactSubstringsMatch )
1318 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1320 if ( UTF8bvnormalize( value, &left, casefold ) == NULL ) {
1326 sub = UTF8SubstringsAssertionNormalize( assertedValue, casefold );
1332 /* Add up asserted input length */
1333 if( sub->sa_initial.bv_val ) {
1334 inlen += sub->sa_initial.bv_len;
1337 for(i=0; sub->sa_any[i].bv_val != NULL; i++) {
1338 inlen += sub->sa_any[i].bv_len;
1341 if( sub->sa_final.bv_val ) {
1342 inlen += sub->sa_final.bv_len;
1345 if( sub->sa_initial.bv_val ) {
1346 if( inlen > left.bv_len ) {
1351 match = memcmp( sub->sa_initial.bv_val, left.bv_val,
1352 sub->sa_initial.bv_len );
1358 left.bv_val += sub->sa_initial.bv_len;
1359 left.bv_len -= sub->sa_initial.bv_len;
1360 inlen -= sub->sa_initial.bv_len;
1363 if( sub->sa_final.bv_val ) {
1364 if( inlen > left.bv_len ) {
1369 match = memcmp( sub->sa_final.bv_val,
1370 &left.bv_val[left.bv_len - sub->sa_final.bv_len],
1371 sub->sa_final.bv_len );
1377 left.bv_len -= sub->sa_final.bv_len;
1378 inlen -= sub->sa_final.bv_len;
1382 for(i=0; sub->sa_any[i].bv_val; i++) {
1387 if( inlen > left.bv_len ) {
1388 /* not enough length */
1393 if( sub->sa_any[i].bv_len == 0 ) {
1397 p = ber_bvchr( &left, *sub->sa_any[i].bv_val );
1403 idx = p - left.bv_val;
1405 if( idx >= left.bv_len ) {
1406 /* this shouldn't happen */
1408 if ( sub->sa_final.bv_val )
1409 ch_free( sub->sa_final.bv_val );
1411 ber_bvarray_free( sub->sa_any );
1412 if ( sub->sa_initial.bv_val )
1413 ch_free( sub->sa_initial.bv_val );
1421 if( sub->sa_any[i].bv_len > left.bv_len ) {
1422 /* not enough left */
1427 match = memcmp( left.bv_val,
1428 sub->sa_any[i].bv_val,
1429 sub->sa_any[i].bv_len );
1437 left.bv_val += sub->sa_any[i].bv_len;
1438 left.bv_len -= sub->sa_any[i].bv_len;
1439 inlen -= sub->sa_any[i].bv_len;
1446 if ( sub->sa_final.bv_val ) free( sub->sa_final.bv_val );
1447 if ( sub->sa_any ) ber_bvarray_free( sub->sa_any );
1448 if ( sub->sa_initial.bv_val ) free( sub->sa_initial.bv_val );
1452 return LDAP_SUCCESS;
1455 /* Index generation function */
1456 static int caseExactIgnoreIndexer(
1461 struct berval *prefix,
1466 unsigned casefold,wasspace;
1469 HASH_CONTEXT HASHcontext;
1470 unsigned char HASHdigest[HASH_BYTES];
1471 struct berval digest;
1472 digest.bv_val = HASHdigest;
1473 digest.bv_len = sizeof(HASHdigest);
1475 for( i=0; values[i].bv_val != NULL; i++ ) {
1476 /* empty - just count them */
1479 /* we should have at least one value at this point */
1482 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
1484 slen = syntax->ssyn_oidlen;
1485 mlen = mr->smr_oidlen;
1487 casefold = ( mr != slap_schema.si_mr_caseExactMatch )
1488 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1490 for( i=0; values[i].bv_val != NULL; i++ ) {
1491 struct berval value, nvalue;
1492 UTF8bvnormalize( &values[i], &value, casefold );
1494 /* collapse spaces (in place) */
1496 nvalue.bv_val = value.bv_val;
1499 for( j=0; j<value.bv_len; j++) {
1500 if ( ASCII_SPACE( value.bv_val[j] )) {
1501 if( wasspace++ == 0 ) {
1502 nvalue.bv_val[nvalue.bv_len++] = value.bv_val[j];
1506 nvalue.bv_val[nvalue.bv_len++] = value.bv_val[j];
1510 if( nvalue.bv_len == 0 ) {
1511 nvalue.bv_val = " ";
1512 nvalue.bv_len = sizeof(" ")-1;
1514 if( wasspace ) --nvalue.bv_len;
1515 nvalue.bv_val[nvalue.bv_len] = '\0';
1518 HASH_Init( &HASHcontext );
1519 if( prefix != NULL && prefix->bv_len > 0 ) {
1520 HASH_Update( &HASHcontext,
1521 prefix->bv_val, prefix->bv_len );
1523 HASH_Update( &HASHcontext,
1524 syntax->ssyn_oid, slen );
1525 HASH_Update( &HASHcontext,
1526 mr->smr_oid, mlen );
1527 HASH_Update( &HASHcontext,
1528 nvalue.bv_val, nvalue.bv_len );
1529 HASH_Final( HASHdigest, &HASHcontext );
1531 free( value.bv_val );
1532 ber_dupbv( &keys[i], &digest );
1535 keys[i].bv_val = NULL;
1537 return LDAP_SUCCESS;
1540 /* Index generation function */
1541 static int caseExactIgnoreFilter(
1546 struct berval *prefix,
1547 void * assertedValue,
1553 HASH_CONTEXT HASHcontext;
1554 unsigned char HASHdigest[HASH_BYTES];
1555 struct berval value = { 0, NULL };
1556 struct berval digest;
1558 digest.bv_val = HASHdigest;
1559 digest.bv_len = sizeof(HASHdigest);
1561 slen = syntax->ssyn_oidlen;
1562 mlen = mr->smr_oidlen;
1564 casefold = ( mr != slap_schema.si_mr_caseExactMatch )
1565 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1567 UTF8bvnormalize( (struct berval *) assertedValue, &value, casefold );
1568 /* This usually happens if filter contains bad UTF8 */
1569 if( value.bv_val == NULL ) {
1570 keys = ch_malloc( sizeof( struct berval ) );
1571 keys[0].bv_val = NULL;
1572 return LDAP_SUCCESS;
1575 keys = ch_malloc( sizeof( struct berval ) * 2 );
1577 HASH_Init( &HASHcontext );
1578 if( prefix != NULL && prefix->bv_len > 0 ) {
1579 HASH_Update( &HASHcontext,
1580 prefix->bv_val, prefix->bv_len );
1582 HASH_Update( &HASHcontext,
1583 syntax->ssyn_oid, slen );
1584 HASH_Update( &HASHcontext,
1585 mr->smr_oid, mlen );
1586 HASH_Update( &HASHcontext,
1587 value.bv_val, value.bv_len );
1588 HASH_Final( HASHdigest, &HASHcontext );
1590 ber_dupbv( keys, &digest );
1591 keys[1].bv_val = NULL;
1593 free( value.bv_val );
1596 return LDAP_SUCCESS;
1600 /* Substrings Index generation function */
1603 octetStringSubstringsIndexer
1605 caseExactIgnoreSubstringsIndexer
1611 struct berval *prefix,
1615 ber_len_t i, j, nkeys;
1618 #ifndef SLAP_NVALUES
1619 BerVarray tvalues, nvalues;
1620 unsigned casefold, wasspace;
1623 HASH_CONTEXT HASHcontext;
1624 unsigned char HASHdigest[HASH_BYTES];
1625 struct berval digest;
1626 digest.bv_val = HASHdigest;
1627 digest.bv_len = sizeof(HASHdigest);
1629 #ifndef SLAP_NVALUES
1630 for( i=0; values[i].bv_val != NULL; i++ ) {
1631 /* empty - just count them */
1634 /* we should have at least one value at this point */
1637 casefold = ( mr != slap_schema.si_mr_caseExactSubstringsMatch )
1638 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1640 tvalues = ch_malloc( sizeof( struct berval ) * (i+1) );
1641 nvalues = ch_malloc( sizeof( struct berval ) * (i+1) );
1643 for( i=0; values[i].bv_val != NULL; i++ ) {
1644 UTF8bvnormalize( &values[i], &tvalues[i], casefold );
1646 /* collapse spaces (in place) */
1647 nvalues[i].bv_len = 0;
1648 nvalues[i].bv_val = tvalues[i].bv_val;
1651 for( j=0; j<tvalues[i].bv_len; j++) {
1652 if ( ASCII_SPACE( tvalues[i].bv_val[j] )) {
1653 if( wasspace++ == 0 ) {
1654 nvalues[i].bv_val[nvalues[i].bv_len++] =
1655 tvalues[i].bv_val[j];
1659 nvalues[i].bv_val[nvalues[i].bv_len++] = tvalues[i].bv_val[j];
1663 if( nvalues[i].bv_len == 0 ) {
1664 nvalues[i].bv_val = " ";
1665 nvalues[i].bv_len = sizeof(" ")-1;
1667 if( wasspace ) --nvalues[i].bv_len;
1668 nvalues[i].bv_val[nvalues[i].bv_len] = '\0';
1672 tvalues[i].bv_val = NULL;
1673 nvalues[i].bv_val = NULL;
1679 for( i=0; values[i].bv_val != NULL; i++ ) {
1680 /* count number of indices to generate */
1681 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
1685 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
1686 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1687 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
1688 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
1690 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
1694 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
1695 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1696 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
1700 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
1701 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1702 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
1703 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
1705 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
1711 /* no keys to generate */
1713 #ifndef SLAP_NVALUES
1714 ber_bvarray_free( tvalues );
1717 return LDAP_SUCCESS;
1720 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
1722 slen = syntax->ssyn_oidlen;
1723 mlen = mr->smr_oidlen;
1726 for( i=0; values[i].bv_val != NULL; i++ ) {
1729 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
1731 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
1732 ( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
1734 char pre = SLAP_INDEX_SUBSTR_PREFIX;
1735 max = values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
1737 for( j=0; j<max; j++ ) {
1738 HASH_Init( &HASHcontext );
1739 if( prefix != NULL && prefix->bv_len > 0 ) {
1740 HASH_Update( &HASHcontext,
1741 prefix->bv_val, prefix->bv_len );
1744 HASH_Update( &HASHcontext,
1745 &pre, sizeof( pre ) );
1746 HASH_Update( &HASHcontext,
1747 syntax->ssyn_oid, slen );
1748 HASH_Update( &HASHcontext,
1749 mr->smr_oid, mlen );
1750 HASH_Update( &HASHcontext,
1751 &values[i].bv_val[j],
1752 SLAP_INDEX_SUBSTR_MAXLEN );
1753 HASH_Final( HASHdigest, &HASHcontext );
1755 ber_dupbv( &keys[nkeys++], &digest );
1759 max = SLAP_INDEX_SUBSTR_MAXLEN < values[i].bv_len
1760 ? SLAP_INDEX_SUBSTR_MAXLEN : values[i].bv_len;
1762 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
1765 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
1766 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
1767 HASH_Init( &HASHcontext );
1768 if( prefix != NULL && prefix->bv_len > 0 ) {
1769 HASH_Update( &HASHcontext,
1770 prefix->bv_val, prefix->bv_len );
1772 HASH_Update( &HASHcontext,
1773 &pre, sizeof( pre ) );
1774 HASH_Update( &HASHcontext,
1775 syntax->ssyn_oid, slen );
1776 HASH_Update( &HASHcontext,
1777 mr->smr_oid, mlen );
1778 HASH_Update( &HASHcontext,
1779 values[i].bv_val, j );
1780 HASH_Final( HASHdigest, &HASHcontext );
1782 ber_dupbv( &keys[nkeys++], &digest );
1785 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
1786 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
1787 HASH_Init( &HASHcontext );
1788 if( prefix != NULL && prefix->bv_len > 0 ) {
1789 HASH_Update( &HASHcontext,
1790 prefix->bv_val, prefix->bv_len );
1792 HASH_Update( &HASHcontext,
1793 &pre, sizeof( pre ) );
1794 HASH_Update( &HASHcontext,
1795 syntax->ssyn_oid, slen );
1796 HASH_Update( &HASHcontext,
1797 mr->smr_oid, mlen );
1798 HASH_Update( &HASHcontext,
1799 &values[i].bv_val[values[i].bv_len-j], j );
1800 HASH_Final( HASHdigest, &HASHcontext );
1802 ber_dupbv( &keys[nkeys++], &digest );
1810 keys[nkeys].bv_val = NULL;
1817 #ifndef SLAP_NVALUES
1818 ber_bvarray_free( tvalues );
1822 return LDAP_SUCCESS;
1827 octetStringSubstringsFilter
1829 caseExactIgnoreSubstringsFilter
1835 struct berval *prefix,
1836 void * assertedValue,
1839 SubstringsAssertion *sa;
1842 ber_len_t nkeys = 0;
1843 size_t slen, mlen, klen;
1845 HASH_CONTEXT HASHcontext;
1846 unsigned char HASHdigest[HASH_BYTES];
1847 struct berval *value;
1848 struct berval digest;
1850 #ifndef SLAP_NVALUES
1851 casefold = ( mr != slap_schema.si_mr_caseExactSubstringsMatch )
1852 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1854 sa = UTF8SubstringsAssertionNormalize( assertedValue, casefold );
1857 return LDAP_SUCCESS;
1860 sa = (SubstringsAssertion *) assertedValue;
1863 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
1864 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1869 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
1871 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
1872 if( sa->sa_any[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1873 /* don't bother accounting for stepping */
1874 nkeys += sa->sa_any[i].bv_len -
1875 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
1880 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
1881 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1887 #ifndef SLAP_NVALUES
1888 if ( sa->sa_final.bv_val ) free( sa->sa_final.bv_val );
1889 if ( sa->sa_any ) ber_bvarray_free( sa->sa_any );
1890 if ( sa->sa_initial.bv_val ) free( sa->sa_initial.bv_val );
1894 return LDAP_SUCCESS;
1897 digest.bv_val = HASHdigest;
1898 digest.bv_len = sizeof(HASHdigest);
1900 slen = syntax->ssyn_oidlen;
1901 mlen = mr->smr_oidlen;
1903 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
1906 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
1907 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1909 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
1910 value = &sa->sa_initial;
1912 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
1913 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
1915 HASH_Init( &HASHcontext );
1916 if( prefix != NULL && prefix->bv_len > 0 ) {
1917 HASH_Update( &HASHcontext,
1918 prefix->bv_val, prefix->bv_len );
1920 HASH_Update( &HASHcontext,
1921 &pre, sizeof( pre ) );
1922 HASH_Update( &HASHcontext,
1923 syntax->ssyn_oid, slen );
1924 HASH_Update( &HASHcontext,
1925 mr->smr_oid, mlen );
1926 HASH_Update( &HASHcontext,
1927 value->bv_val, klen );
1928 HASH_Final( HASHdigest, &HASHcontext );
1930 ber_dupbv( &keys[nkeys++], &digest );
1933 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
1935 pre = SLAP_INDEX_SUBSTR_PREFIX;
1936 klen = SLAP_INDEX_SUBSTR_MAXLEN;
1938 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
1939 if( sa->sa_any[i].bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
1943 value = &sa->sa_any[i];
1946 j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
1947 j += SLAP_INDEX_SUBSTR_STEP )
1949 HASH_Init( &HASHcontext );
1950 if( prefix != NULL && prefix->bv_len > 0 ) {
1951 HASH_Update( &HASHcontext,
1952 prefix->bv_val, prefix->bv_len );
1954 HASH_Update( &HASHcontext,
1955 &pre, sizeof( pre ) );
1956 HASH_Update( &HASHcontext,
1957 syntax->ssyn_oid, slen );
1958 HASH_Update( &HASHcontext,
1959 mr->smr_oid, mlen );
1960 HASH_Update( &HASHcontext,
1961 &value->bv_val[j], klen );
1962 HASH_Final( HASHdigest, &HASHcontext );
1964 ber_dupbv( &keys[nkeys++], &digest );
1970 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
1971 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1973 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
1974 value = &sa->sa_final;
1976 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
1977 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
1979 HASH_Init( &HASHcontext );
1980 if( prefix != NULL && prefix->bv_len > 0 ) {
1981 HASH_Update( &HASHcontext,
1982 prefix->bv_val, prefix->bv_len );
1984 HASH_Update( &HASHcontext,
1985 &pre, sizeof( pre ) );
1986 HASH_Update( &HASHcontext,
1987 syntax->ssyn_oid, slen );
1988 HASH_Update( &HASHcontext,
1989 mr->smr_oid, mlen );
1990 HASH_Update( &HASHcontext,
1991 &value->bv_val[value->bv_len-klen], klen );
1992 HASH_Final( HASHdigest, &HASHcontext );
1994 ber_dupbv( &keys[nkeys++], &digest );
1998 keys[nkeys].bv_val = NULL;
2005 #ifndef SLAP_NVALUES
2006 if ( sa->sa_final.bv_val ) free( sa->sa_final.bv_val );
2007 if ( sa->sa_any ) ber_bvarray_free( sa->sa_any );
2008 if ( sa->sa_initial.bv_val ) free( sa->sa_initial.bv_val );
2012 return LDAP_SUCCESS;
2014 #ifndef SLAP_NVALUES
2022 struct berval *value,
2023 void *assertedValue )
2025 *matchp = UTF8bvnormcmp( value,
2026 (struct berval *) assertedValue,
2027 LDAP_UTF8_CASEFOLD );
2028 return LDAP_SUCCESS;
2032 /* Remove all spaces and '-' characters */
2035 telephoneNumberNormalize(
2040 struct berval *normalized )
2042 xtelephoneNumberNormalize(
2045 struct berval *normalized )
2050 /* validator should have refused an empty string */
2051 assert( val->bv_len );
2053 q = normalized->bv_val = ch_malloc( val->bv_len + 1 );
2055 for( p = val->bv_val; *p; p++ ) {
2056 if ( ! ( ASCII_SPACE( *p ) || *p == '-' )) {
2062 normalized->bv_len = q - normalized->bv_val;
2064 if( normalized->bv_len == 0 ) {
2065 free( normalized->bv_val );
2066 return LDAP_INVALID_SYNTAX;
2069 return LDAP_SUCCESS;
2075 struct berval *val )
2079 if( val->bv_len == 0 ) {
2080 /* disallow empty strings */
2081 return LDAP_INVALID_SYNTAX;
2084 if( OID_LEADCHAR(val->bv_val[0]) ) {
2086 for(i=1; i < val->bv_len; i++) {
2087 if( OID_SEPARATOR( val->bv_val[i] ) ) {
2088 if( dot++ ) return 1;
2089 } else if ( OID_CHAR( val->bv_val[i] ) ) {
2092 return LDAP_INVALID_SYNTAX;
2096 return !dot ? LDAP_SUCCESS : LDAP_INVALID_SYNTAX;
2098 } else if( DESC_LEADCHAR(val->bv_val[0]) ) {
2099 for(i=1; i < val->bv_len; i++) {
2100 if( !DESC_CHAR(val->bv_val[i] ) ) {
2101 return LDAP_INVALID_SYNTAX;
2105 return LDAP_SUCCESS;
2108 return LDAP_INVALID_SYNTAX;
2117 struct berval *value,
2118 void *assertedValue )
2121 int vsign = 1, avsign = 1; /* default sign = '+' */
2122 struct berval *asserted;
2123 ber_len_t vlen, avlen;
2126 /* Skip leading space/sign/zeroes, and get the sign of the *value number */
2128 vlen = value->bv_len;
2130 #ifndef SLAP_NVALUES
2131 if( mr == slap_schema.si_mr_integerFirstComponentMatch ) {
2132 char *tmp = memchr( v, '$', vlen );
2133 if( tmp ) vlen = tmp - v;
2134 while( vlen && ASCII_SPACE( v[vlen-1] )) vlen--;
2138 for( ; vlen && ( *v < '1' || '9' < *v ); v++, vlen-- ) { /* ANSI 2.2.1 */
2139 if( *v == '-' ) vsign = -1;
2142 if( vlen == 0 ) vsign = 0;
2144 /* Do the same with the *assertedValue number */
2145 asserted = (struct berval *) assertedValue;
2146 av = asserted->bv_val;
2147 avlen = asserted->bv_len;
2148 for( ; avlen && ( *av < '1' || '9' < *av ); av++, avlen-- )
2154 match = vsign - avsign;
2156 match = (vlen != avlen
2157 ? ( vlen < avlen ? -1 : 1 )
2158 : memcmp( v, av, vlen ));
2164 return LDAP_SUCCESS;
2170 struct berval *val )
2174 if( !val->bv_len ) return LDAP_INVALID_SYNTAX;
2176 if(( val->bv_val[0] == '+' ) || ( val->bv_val[0] == '-' )) {
2177 if( val->bv_len < 2 ) return LDAP_INVALID_SYNTAX;
2179 } else if( !ASCII_DIGIT(val->bv_val[0]) ) {
2180 return LDAP_INVALID_SYNTAX;
2183 for( i=1; i < val->bv_len; i++ ) {
2184 if( !ASCII_DIGIT(val->bv_val[i]) ) return LDAP_INVALID_SYNTAX;
2187 return LDAP_SUCCESS;
2197 struct berval *normalized )
2202 struct berval *normalized )
2213 /* Ignore leading spaces */
2214 while ( len && ( *p == ' ' )) {
2221 negative = ( *p == '-' );
2222 if(( *p == '-' ) || ( *p == '+' )) {
2228 /* Ignore leading zeros */
2229 while ( len && ( *p == '0' )) {
2234 /* If there are no non-zero digits left, the number is zero, otherwise
2235 allocate space for the number and copy it into the buffer */
2237 normalized->bv_val = ch_strdup("0");
2238 normalized->bv_len = 1;
2241 normalized->bv_len = len+negative;
2242 normalized->bv_val = ch_malloc( normalized->bv_len + 1 );
2243 if( negative ) normalized->bv_val[0] = '-';
2244 AC_MEMCPY( normalized->bv_val + negative, p, len );
2245 normalized->bv_val[len+negative] = '\0';
2248 return LDAP_SUCCESS;
2251 #ifndef SLAP_NVALUES
2253 /* Index generation function */
2254 static int integerIndexer(
2259 struct berval *prefix,
2266 HASH_CONTEXT HASHcontext;
2267 unsigned char HASHdigest[HASH_BYTES];
2268 struct berval digest;
2269 digest.bv_val = HASHdigest;
2270 digest.bv_len = sizeof(HASHdigest);
2272 for( i=0; values[i].bv_val != NULL; i++ ) {
2273 /* empty - just count them */
2276 /* we should have at least one value at this point */
2279 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
2281 slen = syntax->ssyn_oidlen;
2282 mlen = mr->smr_oidlen;
2284 for( i=0; values[i].bv_val != NULL; i++ ) {
2286 xintegerNormalize( syntax, &values[i], &norm );
2288 HASH_Init( &HASHcontext );
2289 if( prefix != NULL && prefix->bv_len > 0 ) {
2290 HASH_Update( &HASHcontext,
2291 prefix->bv_val, prefix->bv_len );
2293 HASH_Update( &HASHcontext,
2294 syntax->ssyn_oid, slen );
2295 HASH_Update( &HASHcontext,
2296 mr->smr_oid, mlen );
2297 HASH_Update( &HASHcontext,
2298 norm.bv_val, norm.bv_len );
2299 HASH_Final( HASHdigest, &HASHcontext );
2301 ber_dupbv( &keys[i], &digest );
2302 ch_free( norm.bv_val );
2305 keys[i].bv_val = NULL;
2307 return LDAP_SUCCESS;
2310 /* Index generation function */
2311 static int integerFilter(
2316 struct berval *prefix,
2317 void * assertedValue,
2322 HASH_CONTEXT HASHcontext;
2323 unsigned char HASHdigest[HASH_BYTES];
2325 struct berval digest;
2326 digest.bv_val = HASHdigest;
2327 digest.bv_len = sizeof(HASHdigest);
2329 slen = syntax->ssyn_oidlen;
2330 mlen = mr->smr_oidlen;
2332 xintegerNormalize( syntax, assertedValue, &norm );
2334 keys = ch_malloc( sizeof( struct berval ) * 2 );
2336 HASH_Init( &HASHcontext );
2337 if( prefix != NULL && prefix->bv_len > 0 ) {
2338 HASH_Update( &HASHcontext,
2339 prefix->bv_val, prefix->bv_len );
2341 HASH_Update( &HASHcontext,
2342 syntax->ssyn_oid, slen );
2343 HASH_Update( &HASHcontext,
2344 mr->smr_oid, mlen );
2345 HASH_Update( &HASHcontext,
2346 norm.bv_val, norm.bv_len );
2347 HASH_Final( HASHdigest, &HASHcontext );
2349 ber_dupbv( &keys[0], &digest );
2350 keys[1].bv_val = NULL;
2351 ch_free( norm.bv_val );
2354 return LDAP_SUCCESS;
2360 countryStringValidate(
2362 struct berval *val )
2364 if( val->bv_len != 2 ) return LDAP_INVALID_SYNTAX;
2366 if( !SLAP_PRINTABLE(val->bv_val[0]) ) {
2367 return LDAP_INVALID_SYNTAX;
2369 if( !SLAP_PRINTABLE(val->bv_val[1]) ) {
2370 return LDAP_INVALID_SYNTAX;
2373 return LDAP_SUCCESS;
2377 printableStringValidate(
2379 struct berval *val )
2383 if( val->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
2385 for(i=0; i < val->bv_len; i++) {
2386 if( !SLAP_PRINTABLE(val->bv_val[i]) ) {
2387 return LDAP_INVALID_SYNTAX;
2391 return LDAP_SUCCESS;
2395 printablesStringValidate(
2397 struct berval *val )
2401 if( val->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
2403 for(i=0,len=0; i < val->bv_len; i++) {
2404 int c = val->bv_val[i];
2408 return LDAP_INVALID_SYNTAX;
2412 } else if ( SLAP_PRINTABLE(c) ) {
2415 return LDAP_INVALID_SYNTAX;
2420 return LDAP_INVALID_SYNTAX;
2423 return LDAP_SUCCESS;
2429 struct berval *val )
2433 if( val->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
2435 for(i=0; i < val->bv_len; i++) {
2436 if( !LDAP_ASCII(val->bv_val[i]) ) {
2437 return LDAP_INVALID_SYNTAX;
2441 return LDAP_SUCCESS;
2451 struct berval *normalized )
2453 xIA5StringNormalize(
2456 struct berval *normalized )
2461 int casefold = !SLAP_MR_ASSOCIATED(mr, slap_schema.si_mr_caseExactIA5Match);
2464 assert( val->bv_len );
2468 /* Ignore initial whitespace */
2469 while ( ASCII_SPACE( *p ) ) {
2473 normalized->bv_val = ch_strdup( p );
2474 p = q = normalized->bv_val;
2477 if ( ASCII_SPACE( *p ) ) {
2480 /* Ignore the extra whitespace */
2481 while ( ASCII_SPACE( *p ) ) {
2486 } else if ( casefold ) {
2487 /* Most IA5 rules require casefolding */
2488 *q++ = TOLOWER(*p++);
2496 assert( normalized->bv_val <= p );
2500 * If the string ended in space, backup the pointer one
2501 * position. One is enough because the above loop collapsed
2502 * all whitespace to a single space.
2505 if ( ASCII_SPACE( q[-1] ) ) {
2509 /* null terminate */
2512 normalized->bv_len = q - normalized->bv_val;
2514 if( normalized->bv_len == 0 ) {
2515 normalized->bv_val = ch_realloc( normalized->bv_val, 2 );
2516 normalized->bv_val[0] = ' ';
2517 normalized->bv_val[1] = '\0';
2518 normalized->bv_len = 1;
2521 return LDAP_SUCCESS;
2524 #ifndef SLAP_NVALUES
2532 struct berval *value,
2533 void *assertedValue )
2535 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
2538 match = strncmp( value->bv_val,
2539 ((struct berval *) assertedValue)->bv_val,
2544 return LDAP_SUCCESS;
2548 caseExactIA5SubstringsMatch
2551 octetStringSubstringsMatch
2558 struct berval *value,
2559 void *assertedValue )
2562 SubstringsAssertion *sub = assertedValue;
2563 struct berval left = *value;
2567 /* Add up asserted input length */
2568 if( sub->sa_initial.bv_val ) {
2569 inlen += sub->sa_initial.bv_len;
2572 for(i=0; sub->sa_any[i].bv_val != NULL; i++) {
2573 inlen += sub->sa_any[i].bv_len;
2576 if( sub->sa_final.bv_val ) {
2577 inlen += sub->sa_final.bv_len;
2580 if( sub->sa_initial.bv_val ) {
2581 if( inlen > left.bv_len ) {
2586 match = memcmp( sub->sa_initial.bv_val, left.bv_val,
2587 sub->sa_initial.bv_len );
2593 left.bv_val += sub->sa_initial.bv_len;
2594 left.bv_len -= sub->sa_initial.bv_len;
2595 inlen -= sub->sa_initial.bv_len;
2598 if( sub->sa_final.bv_val ) {
2599 if( inlen > left.bv_len ) {
2604 match = memcmp( sub->sa_final.bv_val,
2605 &left.bv_val[left.bv_len - sub->sa_final.bv_len],
2606 sub->sa_final.bv_len );
2612 left.bv_len -= sub->sa_final.bv_len;
2613 inlen -= sub->sa_final.bv_len;
2617 for(i=0; sub->sa_any[i].bv_val; i++) {
2622 if( inlen > left.bv_len ) {
2623 /* not enough length */
2628 if( sub->sa_any[i].bv_len == 0 ) {
2632 p = memchr( left.bv_val, *sub->sa_any[i].bv_val, left.bv_len );
2639 idx = p - left.bv_val;
2641 if( idx >= left.bv_len ) {
2642 /* this shouldn't happen */
2649 if( sub->sa_any[i].bv_len > left.bv_len ) {
2650 /* not enough left */
2655 match = memcmp( left.bv_val,
2656 sub->sa_any[i].bv_val,
2657 sub->sa_any[i].bv_len );
2665 left.bv_val += sub->sa_any[i].bv_len;
2666 left.bv_len -= sub->sa_any[i].bv_len;
2667 inlen -= sub->sa_any[i].bv_len;
2673 return LDAP_SUCCESS;
2676 #ifndef SLAP_NVALUES
2678 /* Index generation function */
2679 static int caseExactIA5Indexer(
2684 struct berval *prefix,
2691 HASH_CONTEXT HASHcontext;
2692 unsigned char HASHdigest[HASH_BYTES];
2693 struct berval digest;
2694 digest.bv_val = HASHdigest;
2695 digest.bv_len = sizeof(HASHdigest);
2697 for( i=0; values[i].bv_val != NULL; i++ ) {
2698 /* empty - just count them */
2701 /* we should have at least one value at this point */
2704 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
2706 slen = syntax->ssyn_oidlen;
2707 mlen = mr->smr_oidlen;
2709 for( i=0; values[i].bv_val != NULL; i++ ) {
2710 struct berval *value = &values[i];
2712 HASH_Init( &HASHcontext );
2713 if( prefix != NULL && prefix->bv_len > 0 ) {
2714 HASH_Update( &HASHcontext,
2715 prefix->bv_val, prefix->bv_len );
2717 HASH_Update( &HASHcontext,
2718 syntax->ssyn_oid, slen );
2719 HASH_Update( &HASHcontext,
2720 mr->smr_oid, mlen );
2721 HASH_Update( &HASHcontext,
2722 value->bv_val, value->bv_len );
2723 HASH_Final( HASHdigest, &HASHcontext );
2725 ber_dupbv( &keys[i], &digest );
2728 keys[i].bv_val = NULL;
2730 return LDAP_SUCCESS;
2733 /* Index generation function */
2734 static int caseExactIA5Filter(
2739 struct berval *prefix,
2740 void * assertedValue,
2745 HASH_CONTEXT HASHcontext;
2746 unsigned char HASHdigest[HASH_BYTES];
2747 struct berval *value;
2748 struct berval digest;
2749 digest.bv_val = HASHdigest;
2750 digest.bv_len = sizeof(HASHdigest);
2752 slen = syntax->ssyn_oidlen;
2753 mlen = mr->smr_oidlen;
2755 value = (struct berval *) assertedValue;
2757 keys = ch_malloc( sizeof( struct berval ) * 2 );
2759 HASH_Init( &HASHcontext );
2760 if( prefix != NULL && prefix->bv_len > 0 ) {
2761 HASH_Update( &HASHcontext,
2762 prefix->bv_val, prefix->bv_len );
2764 HASH_Update( &HASHcontext,
2765 syntax->ssyn_oid, slen );
2766 HASH_Update( &HASHcontext,
2767 mr->smr_oid, mlen );
2768 HASH_Update( &HASHcontext,
2769 value->bv_val, value->bv_len );
2770 HASH_Final( HASHdigest, &HASHcontext );
2772 ber_dupbv( &keys[0], &digest );
2773 keys[1].bv_val = NULL;
2776 return LDAP_SUCCESS;
2779 /* Substrings Index generation function */
2780 static int caseExactIA5SubstringsIndexer(
2785 struct berval *prefix,
2792 HASH_CONTEXT HASHcontext;
2793 unsigned char HASHdigest[HASH_BYTES];
2794 struct berval digest;
2795 digest.bv_val = HASHdigest;
2796 digest.bv_len = sizeof(HASHdigest);
2798 /* we should have at least one value at this point */
2799 assert( values != NULL && values[0].bv_val != NULL );
2802 for( i=0; values[i].bv_val != NULL; i++ ) {
2803 /* count number of indices to generate */
2804 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
2808 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
2809 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2810 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2811 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2813 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2817 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
2818 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2819 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
2823 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
2824 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2825 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2826 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2828 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2834 /* no keys to generate */
2836 return LDAP_SUCCESS;
2839 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
2841 slen = syntax->ssyn_oidlen;
2842 mlen = mr->smr_oidlen;
2845 for( i=0; values[i].bv_val != NULL; i++ ) {
2847 struct berval *value;
2850 if( value->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
2852 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
2853 ( value->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
2855 char pre = SLAP_INDEX_SUBSTR_PREFIX;
2856 max = value->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
2858 for( j=0; j<max; j++ ) {
2859 HASH_Init( &HASHcontext );
2860 if( prefix != NULL && prefix->bv_len > 0 ) {
2861 HASH_Update( &HASHcontext,
2862 prefix->bv_val, prefix->bv_len );
2865 HASH_Update( &HASHcontext,
2866 &pre, sizeof( pre ) );
2867 HASH_Update( &HASHcontext,
2868 syntax->ssyn_oid, slen );
2869 HASH_Update( &HASHcontext,
2870 mr->smr_oid, mlen );
2871 HASH_Update( &HASHcontext,
2873 SLAP_INDEX_SUBSTR_MAXLEN );
2874 HASH_Final( HASHdigest, &HASHcontext );
2876 ber_dupbv( &keys[nkeys++], &digest );
2880 max = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2881 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2883 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
2886 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
2887 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
2888 HASH_Init( &HASHcontext );
2889 if( prefix != NULL && prefix->bv_len > 0 ) {
2890 HASH_Update( &HASHcontext,
2891 prefix->bv_val, prefix->bv_len );
2893 HASH_Update( &HASHcontext,
2894 &pre, sizeof( pre ) );
2895 HASH_Update( &HASHcontext,
2896 syntax->ssyn_oid, slen );
2897 HASH_Update( &HASHcontext,
2898 mr->smr_oid, mlen );
2899 HASH_Update( &HASHcontext,
2901 HASH_Final( HASHdigest, &HASHcontext );
2903 ber_dupbv( &keys[nkeys++], &digest );
2906 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
2907 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
2908 HASH_Init( &HASHcontext );
2909 if( prefix != NULL && prefix->bv_len > 0 ) {
2910 HASH_Update( &HASHcontext,
2911 prefix->bv_val, prefix->bv_len );
2913 HASH_Update( &HASHcontext,
2914 &pre, sizeof( pre ) );
2915 HASH_Update( &HASHcontext,
2916 syntax->ssyn_oid, slen );
2917 HASH_Update( &HASHcontext,
2918 mr->smr_oid, mlen );
2919 HASH_Update( &HASHcontext,
2920 &value->bv_val[value->bv_len-j], j );
2921 HASH_Final( HASHdigest, &HASHcontext );
2923 ber_dupbv( &keys[nkeys++], &digest );
2930 keys[nkeys].bv_val = NULL;
2937 return LDAP_SUCCESS;
2940 static int caseExactIA5SubstringsFilter(
2945 struct berval *prefix,
2946 void * assertedValue,
2949 SubstringsAssertion *sa = assertedValue;
2951 ber_len_t nkeys = 0;
2952 size_t slen, mlen, klen;
2954 HASH_CONTEXT HASHcontext;
2955 unsigned char HASHdigest[HASH_BYTES];
2956 struct berval *value;
2957 struct berval digest;
2959 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
2960 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2965 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
2967 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
2968 if( sa->sa_any[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2969 /* don't bother accounting for stepping */
2970 nkeys += sa->sa_any[i].bv_len -
2971 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
2976 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
2977 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2984 return LDAP_SUCCESS;
2987 digest.bv_val = HASHdigest;
2988 digest.bv_len = sizeof(HASHdigest);
2990 slen = syntax->ssyn_oidlen;
2991 mlen = mr->smr_oidlen;
2993 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
2996 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
2997 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2999 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
3000 value = &sa->sa_initial;
3002 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
3003 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
3005 HASH_Init( &HASHcontext );
3006 if( prefix != NULL && prefix->bv_len > 0 ) {
3007 HASH_Update( &HASHcontext,
3008 prefix->bv_val, prefix->bv_len );
3010 HASH_Update( &HASHcontext,
3011 &pre, sizeof( pre ) );
3012 HASH_Update( &HASHcontext,
3013 syntax->ssyn_oid, slen );
3014 HASH_Update( &HASHcontext,
3015 mr->smr_oid, mlen );
3016 HASH_Update( &HASHcontext,
3017 value->bv_val, klen );
3018 HASH_Final( HASHdigest, &HASHcontext );
3020 ber_dupbv( &keys[nkeys++], &digest );
3023 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
3025 pre = SLAP_INDEX_SUBSTR_PREFIX;
3026 klen = SLAP_INDEX_SUBSTR_MAXLEN;
3028 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
3029 if( sa->sa_any[i].bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
3033 value = &sa->sa_any[i];
3036 j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
3037 j += SLAP_INDEX_SUBSTR_STEP )
3039 HASH_Init( &HASHcontext );
3040 if( prefix != NULL && prefix->bv_len > 0 ) {
3041 HASH_Update( &HASHcontext,
3042 prefix->bv_val, prefix->bv_len );
3044 HASH_Update( &HASHcontext,
3045 &pre, sizeof( pre ) );
3046 HASH_Update( &HASHcontext,
3047 syntax->ssyn_oid, slen );
3048 HASH_Update( &HASHcontext,
3049 mr->smr_oid, mlen );
3050 HASH_Update( &HASHcontext,
3051 &value->bv_val[j], klen );
3052 HASH_Final( HASHdigest, &HASHcontext );
3054 ber_dupbv( &keys[nkeys++], &digest );
3059 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
3060 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3062 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
3063 value = &sa->sa_final;
3065 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
3066 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
3068 HASH_Init( &HASHcontext );
3069 if( prefix != NULL && prefix->bv_len > 0 ) {
3070 HASH_Update( &HASHcontext,
3071 prefix->bv_val, prefix->bv_len );
3073 HASH_Update( &HASHcontext,
3074 &pre, sizeof( pre ) );
3075 HASH_Update( &HASHcontext,
3076 syntax->ssyn_oid, slen );
3077 HASH_Update( &HASHcontext,
3078 mr->smr_oid, mlen );
3079 HASH_Update( &HASHcontext,
3080 &value->bv_val[value->bv_len-klen], klen );
3081 HASH_Final( HASHdigest, &HASHcontext );
3083 ber_dupbv( &keys[nkeys++], &digest );
3087 keys[nkeys].bv_val = NULL;
3094 return LDAP_SUCCESS;
3103 struct berval *value,
3104 void *assertedValue )
3106 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
3108 if( match == 0 && value->bv_len ) {
3109 match = strncasecmp( value->bv_val,
3110 ((struct berval *) assertedValue)->bv_val,
3115 return LDAP_SUCCESS;
3119 caseIgnoreIA5SubstringsMatch(
3124 struct berval *value,
3125 void *assertedValue )
3128 SubstringsAssertion *sub = assertedValue;
3129 struct berval left = *value;
3133 /* Add up asserted input length */
3134 if( sub->sa_initial.bv_val ) {
3135 inlen += sub->sa_initial.bv_len;
3138 for(i=0; sub->sa_any[i].bv_val != NULL; i++) {
3139 inlen += sub->sa_any[i].bv_len;
3142 if( sub->sa_final.bv_val ) {
3143 inlen += sub->sa_final.bv_len;
3146 if( sub->sa_initial.bv_val ) {
3147 if( inlen > left.bv_len ) {
3152 match = strncasecmp( sub->sa_initial.bv_val, left.bv_val,
3153 sub->sa_initial.bv_len );
3159 left.bv_val += sub->sa_initial.bv_len;
3160 left.bv_len -= sub->sa_initial.bv_len;
3161 inlen -= sub->sa_initial.bv_len;
3164 if( sub->sa_final.bv_val ) {
3165 if( inlen > left.bv_len ) {
3170 match = strncasecmp( sub->sa_final.bv_val,
3171 &left.bv_val[left.bv_len - sub->sa_final.bv_len],
3172 sub->sa_final.bv_len );
3178 left.bv_len -= sub->sa_final.bv_len;
3179 inlen -= sub->sa_final.bv_len;
3183 for(i=0; sub->sa_any[i].bv_val; i++) {
3188 if( inlen > left.bv_len ) {
3189 /* not enough length */
3194 if( sub->sa_any[i].bv_len == 0 ) {
3198 p = bvcasechr( &left, *sub->sa_any[i].bv_val, &idx );
3205 assert( idx < left.bv_len );
3206 if( idx >= left.bv_len ) {
3207 /* this shouldn't happen */
3214 if( sub->sa_any[i].bv_len > left.bv_len ) {
3215 /* not enough left */
3220 match = strncasecmp( left.bv_val,
3221 sub->sa_any[i].bv_val,
3222 sub->sa_any[i].bv_len );
3231 left.bv_val += sub->sa_any[i].bv_len;
3232 left.bv_len -= sub->sa_any[i].bv_len;
3233 inlen -= sub->sa_any[i].bv_len;
3239 return LDAP_SUCCESS;
3242 /* Index generation function */
3243 static int caseIgnoreIA5Indexer(
3248 struct berval *prefix,
3253 int rc = LDAP_SUCCESS;
3256 HASH_CONTEXT HASHcontext;
3257 unsigned char HASHdigest[HASH_BYTES];
3258 struct berval digest;
3259 digest.bv_val = HASHdigest;
3260 digest.bv_len = sizeof(HASHdigest);
3262 /* we should have at least one value at this point */
3263 assert( values != NULL && values[0].bv_val != NULL );
3265 for( i=0; values[i].bv_val != NULL; i++ ) {
3266 /* just count them */
3269 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
3271 slen = syntax->ssyn_oidlen;
3272 mlen = mr->smr_oidlen;
3274 for( i=0; values[i].bv_val != NULL; i++ ) {
3275 struct berval value;
3277 if( mr->smr_normalize ) {
3278 rc = (mr->smr_normalize)( use, syntax, mr, &values[i], &value );
3279 if( rc != LDAP_SUCCESS ) {
3282 #ifndef SLAP_NVALUES
3283 } else if ( mr->smr_syntax->ssyn_normalize ) {
3284 rc = (mr->smr_syntax->ssyn_normalize)( syntax, &values[i], &value );
3285 if( rc != LDAP_SUCCESS ) {
3290 ber_dupbv( &value, &values[i] );
3293 ldap_pvt_str2lower( value.bv_val );
3295 HASH_Init( &HASHcontext );
3296 if( prefix != NULL && prefix->bv_len > 0 ) {
3297 HASH_Update( &HASHcontext,
3298 prefix->bv_val, prefix->bv_len );
3300 HASH_Update( &HASHcontext,
3301 syntax->ssyn_oid, slen );
3302 HASH_Update( &HASHcontext,
3303 mr->smr_oid, mlen );
3304 HASH_Update( &HASHcontext,
3305 value.bv_val, value.bv_len );
3306 HASH_Final( HASHdigest, &HASHcontext );
3308 free( value.bv_val );
3310 ber_dupbv( &keys[i], &digest );
3313 keys[i].bv_val = NULL;
3314 if( rc != LDAP_SUCCESS ) {
3315 ber_bvarray_free( keys );
3322 /* Index generation function */
3323 static int caseIgnoreIA5Filter(
3328 struct berval *prefix,
3329 void * assertedValue,
3334 HASH_CONTEXT HASHcontext;
3335 unsigned char HASHdigest[HASH_BYTES];
3336 struct berval value;
3337 struct berval digest;
3338 digest.bv_val = HASHdigest;
3339 digest.bv_len = sizeof(HASHdigest);
3341 slen = syntax->ssyn_oidlen;
3342 mlen = mr->smr_oidlen;
3344 ber_dupbv( &value, (struct berval *) assertedValue );
3345 ldap_pvt_str2lower( value.bv_val );
3347 keys = ch_malloc( sizeof( struct berval ) * 2 );
3349 HASH_Init( &HASHcontext );
3350 if( prefix != NULL && prefix->bv_len > 0 ) {
3351 HASH_Update( &HASHcontext,
3352 prefix->bv_val, prefix->bv_len );
3354 HASH_Update( &HASHcontext,
3355 syntax->ssyn_oid, slen );
3356 HASH_Update( &HASHcontext,
3357 mr->smr_oid, mlen );
3358 HASH_Update( &HASHcontext,
3359 value.bv_val, value.bv_len );
3360 HASH_Final( HASHdigest, &HASHcontext );
3362 ber_dupbv( &keys[0], &digest );
3363 keys[1].bv_val = NULL;
3365 free( value.bv_val );
3369 return LDAP_SUCCESS;
3372 /* Substrings Index generation function */
3373 static int caseIgnoreIA5SubstringsIndexer(
3378 struct berval *prefix,
3385 HASH_CONTEXT HASHcontext;
3386 unsigned char HASHdigest[HASH_BYTES];
3387 struct berval digest;
3388 digest.bv_val = HASHdigest;
3389 digest.bv_len = sizeof(HASHdigest);
3391 /* we should have at least one value at this point */
3392 assert( values != NULL && values[0].bv_val != NULL );
3395 for( i=0; values[i].bv_val != NULL; i++ ) {
3396 /* count number of indices to generate */
3397 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
3401 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
3402 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3403 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
3404 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
3406 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
3410 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
3411 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3412 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
3416 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
3417 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3418 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
3419 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
3421 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
3427 /* no keys to generate */
3429 return LDAP_SUCCESS;
3432 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
3434 slen = syntax->ssyn_oidlen;
3435 mlen = mr->smr_oidlen;
3438 for( i=0; values[i].bv_val != NULL; i++ ) {
3440 struct berval value;
3442 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
3444 ber_dupbv( &value, &values[i] );
3445 ldap_pvt_str2lower( value.bv_val );
3447 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
3448 ( value.bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
3450 char pre = SLAP_INDEX_SUBSTR_PREFIX;
3451 max = value.bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
3453 for( j=0; j<max; j++ ) {
3454 HASH_Init( &HASHcontext );
3455 if( prefix != NULL && prefix->bv_len > 0 ) {
3456 HASH_Update( &HASHcontext,
3457 prefix->bv_val, prefix->bv_len );
3460 HASH_Update( &HASHcontext,
3461 &pre, sizeof( pre ) );
3462 HASH_Update( &HASHcontext,
3463 syntax->ssyn_oid, slen );
3464 HASH_Update( &HASHcontext,
3465 mr->smr_oid, mlen );
3466 HASH_Update( &HASHcontext,
3468 SLAP_INDEX_SUBSTR_MAXLEN );
3469 HASH_Final( HASHdigest, &HASHcontext );
3471 ber_dupbv( &keys[nkeys++], &digest );
3475 max = SLAP_INDEX_SUBSTR_MAXLEN < value.bv_len
3476 ? SLAP_INDEX_SUBSTR_MAXLEN : value.bv_len;
3478 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
3481 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
3482 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
3483 HASH_Init( &HASHcontext );
3484 if( prefix != NULL && prefix->bv_len > 0 ) {
3485 HASH_Update( &HASHcontext,
3486 prefix->bv_val, prefix->bv_len );
3488 HASH_Update( &HASHcontext,
3489 &pre, sizeof( pre ) );
3490 HASH_Update( &HASHcontext,
3491 syntax->ssyn_oid, slen );
3492 HASH_Update( &HASHcontext,
3493 mr->smr_oid, mlen );
3494 HASH_Update( &HASHcontext,
3496 HASH_Final( HASHdigest, &HASHcontext );
3498 ber_dupbv( &keys[nkeys++], &digest );
3501 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
3502 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
3503 HASH_Init( &HASHcontext );
3504 if( prefix != NULL && prefix->bv_len > 0 ) {
3505 HASH_Update( &HASHcontext,
3506 prefix->bv_val, prefix->bv_len );
3508 HASH_Update( &HASHcontext,
3509 &pre, sizeof( pre ) );
3510 HASH_Update( &HASHcontext,
3511 syntax->ssyn_oid, slen );
3512 HASH_Update( &HASHcontext,
3513 mr->smr_oid, mlen );
3514 HASH_Update( &HASHcontext,
3515 &value.bv_val[value.bv_len-j], j );
3516 HASH_Final( HASHdigest, &HASHcontext );
3518 ber_dupbv( &keys[nkeys++], &digest );
3523 free( value.bv_val );
3527 keys[nkeys].bv_val = NULL;
3534 return LDAP_SUCCESS;
3537 static int caseIgnoreIA5SubstringsFilter(
3542 struct berval *prefix,
3543 void * assertedValue,
3546 SubstringsAssertion *sa = assertedValue;
3548 ber_len_t nkeys = 0;
3549 size_t slen, mlen, klen;
3551 HASH_CONTEXT HASHcontext;
3552 unsigned char HASHdigest[HASH_BYTES];
3553 struct berval value;
3554 struct berval digest;
3556 if((flags & SLAP_INDEX_SUBSTR_INITIAL) && sa->sa_initial.bv_val != NULL &&
3557 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3562 if((flags & SLAP_INDEX_SUBSTR_ANY) && sa->sa_any != NULL ) {
3564 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
3565 if( sa->sa_any[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3566 /* don't bother accounting for stepping */
3567 nkeys += sa->sa_any[i].bv_len -
3568 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
3573 if((flags & SLAP_INDEX_SUBSTR_FINAL) && sa->sa_final.bv_val != NULL &&
3574 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3581 return LDAP_SUCCESS;
3584 digest.bv_val = HASHdigest;
3585 digest.bv_len = sizeof(HASHdigest);
3587 slen = syntax->ssyn_oidlen;
3588 mlen = mr->smr_oidlen;
3590 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
3593 if((flags & SLAP_INDEX_SUBSTR_INITIAL) && sa->sa_initial.bv_val != NULL &&
3594 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3596 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
3597 ber_dupbv( &value, &sa->sa_initial );
3598 ldap_pvt_str2lower( value.bv_val );
3600 klen = SLAP_INDEX_SUBSTR_MAXLEN < value.bv_len
3601 ? SLAP_INDEX_SUBSTR_MAXLEN : value.bv_len;
3603 HASH_Init( &HASHcontext );
3604 if( prefix != NULL && prefix->bv_len > 0 ) {
3605 HASH_Update( &HASHcontext,
3606 prefix->bv_val, prefix->bv_len );
3608 HASH_Update( &HASHcontext,
3609 &pre, sizeof( pre ) );
3610 HASH_Update( &HASHcontext,
3611 syntax->ssyn_oid, slen );
3612 HASH_Update( &HASHcontext,
3613 mr->smr_oid, mlen );
3614 HASH_Update( &HASHcontext,
3615 value.bv_val, klen );
3616 HASH_Final( HASHdigest, &HASHcontext );
3618 free( value.bv_val );
3619 ber_dupbv( &keys[nkeys++], &digest );
3622 if((flags & SLAP_INDEX_SUBSTR_ANY) && sa->sa_any != NULL ) {
3624 pre = SLAP_INDEX_SUBSTR_PREFIX;
3625 klen = SLAP_INDEX_SUBSTR_MAXLEN;
3627 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
3628 if( sa->sa_any[i].bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
3632 ber_dupbv( &value, &sa->sa_any[i] );
3633 ldap_pvt_str2lower( value.bv_val );
3636 j <= value.bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
3637 j += SLAP_INDEX_SUBSTR_STEP )
3639 HASH_Init( &HASHcontext );
3640 if( prefix != NULL && prefix->bv_len > 0 ) {
3641 HASH_Update( &HASHcontext,
3642 prefix->bv_val, prefix->bv_len );
3644 HASH_Update( &HASHcontext,
3645 &pre, sizeof( pre ) );
3646 HASH_Update( &HASHcontext,
3647 syntax->ssyn_oid, slen );
3648 HASH_Update( &HASHcontext,
3649 mr->smr_oid, mlen );
3650 HASH_Update( &HASHcontext,
3651 &value.bv_val[j], klen );
3652 HASH_Final( HASHdigest, &HASHcontext );
3654 ber_dupbv( &keys[nkeys++], &digest );
3657 free( value.bv_val );
3661 if((flags & SLAP_INDEX_SUBSTR_FINAL) && sa->sa_final.bv_val != NULL &&
3662 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3664 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
3665 ber_dupbv( &value, &sa->sa_final );
3666 ldap_pvt_str2lower( value.bv_val );
3668 klen = SLAP_INDEX_SUBSTR_MAXLEN < value.bv_len
3669 ? SLAP_INDEX_SUBSTR_MAXLEN : value.bv_len;
3671 HASH_Init( &HASHcontext );
3672 if( prefix != NULL && prefix->bv_len > 0 ) {
3673 HASH_Update( &HASHcontext,
3674 prefix->bv_val, prefix->bv_len );
3676 HASH_Update( &HASHcontext,
3677 &pre, sizeof( pre ) );
3678 HASH_Update( &HASHcontext,
3679 syntax->ssyn_oid, slen );
3680 HASH_Update( &HASHcontext,
3681 mr->smr_oid, mlen );
3682 HASH_Update( &HASHcontext,
3683 &value.bv_val[value.bv_len-klen], klen );
3684 HASH_Final( HASHdigest, &HASHcontext );
3686 free( value.bv_val );
3687 ber_dupbv( &keys[nkeys++], &digest );
3691 keys[nkeys].bv_val = NULL;
3698 return LDAP_SUCCESS;
3704 numericStringValidate(
3710 if( in->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
3712 for(i=0; i < in->bv_len; i++) {
3713 if( !SLAP_NUMERIC(in->bv_val[i]) ) {
3714 return LDAP_INVALID_SYNTAX;
3718 return LDAP_SUCCESS;
3723 numericStringNormalize(
3728 struct berval *normalized )
3730 xnumericStringNormalize(
3733 struct berval *normalized )
3736 /* removal all spaces */
3739 assert( val->bv_len );
3741 normalized->bv_val = ch_malloc( val->bv_len + 1 );
3744 q = normalized->bv_val;
3747 if ( ASCII_SPACE( *p ) ) {
3748 /* Ignore whitespace */
3755 /* we should have copied no more then is in val */
3756 assert( (q - normalized->bv_val) <= (p - val->bv_val) );
3758 /* null terminate */
3761 normalized->bv_len = q - normalized->bv_val;
3763 if( normalized->bv_len == 0 ) {
3764 normalized->bv_val = ch_realloc( normalized->bv_val, 2 );
3765 normalized->bv_val[0] = ' ';
3766 normalized->bv_val[1] = '\0';
3767 normalized->bv_len = 1;
3770 return LDAP_SUCCESS;
3773 #ifndef SLAP_NVALUES
3775 objectIdentifierFirstComponentMatch(
3780 struct berval *value,
3781 void *assertedValue )
3783 int rc = LDAP_SUCCESS;
3785 struct berval *asserted = (struct berval *) assertedValue;
3789 if( value->bv_len == 0 || value->bv_val[0] != '(' /*')'*/ ) {
3790 return LDAP_INVALID_SYNTAX;
3793 /* trim leading white space */
3794 for( i=1; ASCII_SPACE(value->bv_val[i]) && i < value->bv_len; i++ ) {
3798 /* grab next word */
3799 oid.bv_val = &value->bv_val[i];
3800 j = value->bv_len - i;
3801 for( i=0; !ASCII_SPACE(oid.bv_val[i]) && i < j; i++ ) {
3806 /* insert attributeTypes, objectclass check here */
3807 if( OID_LEADCHAR(asserted->bv_val[0]) ) {
3808 rc = objectIdentifierMatch( &match, flags, syntax, mr, &oid, asserted );
3811 if ( !strcmp( syntax->ssyn_oid, SLAP_SYNTAX_MATCHINGRULES_OID ) ) {
3812 MatchingRule *asserted_mr = mr_bvfind( asserted );
3813 MatchingRule *stored_mr = mr_bvfind( &oid );
3815 if( asserted_mr == NULL ) {
3816 rc = SLAPD_COMPARE_UNDEFINED;
3818 match = asserted_mr != stored_mr;
3821 } else if ( !strcmp( syntax->ssyn_oid,
3822 SLAP_SYNTAX_ATTRIBUTETYPES_OID ) )
3824 AttributeType *asserted_at = at_bvfind( asserted );
3825 AttributeType *stored_at = at_bvfind( &oid );
3827 if( asserted_at == NULL ) {
3828 rc = SLAPD_COMPARE_UNDEFINED;
3830 match = asserted_at != stored_at;
3833 } else if ( !strcmp( syntax->ssyn_oid,
3834 SLAP_SYNTAX_OBJECTCLASSES_OID ) )
3836 ObjectClass *asserted_oc = oc_bvfind( asserted );
3837 ObjectClass *stored_oc = oc_bvfind( &oid );
3839 if( asserted_oc == NULL ) {
3840 rc = SLAPD_COMPARE_UNDEFINED;
3842 match = asserted_oc != stored_oc;
3848 LDAP_LOG( CONFIG, ENTRY,
3849 "objectIdentifierFirstComponentMatch: %d\n %s\n %s\n",
3850 match, value->bv_val, asserted->bv_val );
3852 Debug( LDAP_DEBUG_ARGS, "objectIdentifierFirstComponentMatch "
3853 "%d\n\t\"%s\"\n\t\"%s\"\n",
3854 match, value->bv_val, asserted->bv_val );
3857 if( rc == LDAP_SUCCESS ) *matchp = match;
3869 struct berval *value,
3870 void *assertedValue )
3872 long lValue, lAssertedValue;
3874 /* safe to assume integers are NUL terminated? */
3875 lValue = strtol(value->bv_val, NULL, 10);
3876 if(( lValue == LONG_MIN || lValue == LONG_MAX) && errno == ERANGE ) {
3877 return LDAP_CONSTRAINT_VIOLATION;
3880 lAssertedValue = strtol(((struct berval *)assertedValue)->bv_val, NULL, 10);
3881 if(( lAssertedValue == LONG_MIN || lAssertedValue == LONG_MAX)
3882 && errno == ERANGE )
3884 return LDAP_CONSTRAINT_VIOLATION;
3887 *matchp = (lValue & lAssertedValue) ? 0 : 1;
3888 return LDAP_SUCCESS;
3897 struct berval *value,
3898 void *assertedValue )
3900 long lValue, lAssertedValue;
3902 /* safe to assume integers are NUL terminated? */
3903 lValue = strtol(value->bv_val, NULL, 10);
3904 if(( lValue == LONG_MIN || lValue == LONG_MAX) && errno == ERANGE ) {
3905 return LDAP_CONSTRAINT_VIOLATION;
3908 lAssertedValue = strtol(((struct berval *)assertedValue)->bv_val, NULL, 10);
3909 if(( lAssertedValue == LONG_MIN || lAssertedValue == LONG_MAX)
3910 && errno == ERANGE )
3912 return LDAP_CONSTRAINT_VIOLATION;
3915 *matchp = (lValue | lAssertedValue) ? 0 : -1;
3916 return LDAP_SUCCESS;
3919 #ifndef SLAP_NVALUES
3922 #include <openssl/x509.h>
3923 #include <openssl/err.h>
3926 * Next function returns a string representation of a ASN1_INTEGER.
3927 * It works for unlimited lengths.
3930 static struct berval *
3931 asn1_integer2str(ASN1_INTEGER *a, struct berval *bv)
3935 static char digit[] = "0123456789";
3937 /* We work backwards, make it fill from the end of buf */
3938 p = buf + sizeof(buf) - 1;
3941 if ( a == NULL || a->length == 0 ) {
3949 /* We want to preserve the original */
3950 copy = ch_malloc(n*sizeof(unsigned int));
3951 for (i = 0; i<n; i++) {
3952 copy[i] = a->data[i];
3956 * base indicates the index of the most significant
3957 * byte that might be nonzero. When it goes off the
3958 * end, we now there is nothing left to do.
3964 for (i = base; i<n; i++ ) {
3965 copy[i] += carry*256;
3966 carry = copy[i] % 10;
3971 * Way too large, we need to leave
3972 * room for sign if negative
3977 *--p = digit[carry];
3979 if (copy[base] == 0) base++;
3984 if ( a->type == V_ASN1_NEG_INTEGER ) {
3988 return ber_str2bv( p, 0, 1, bv );
3992 * Given a certificate in DER format, extract the corresponding
3993 * assertion value for certificateExactMatch
3996 certificateExactConvert(
3998 struct berval * out )
4001 unsigned char *p = in->bv_val;
4002 struct berval serial;
4003 struct berval issuer_dn;
4005 xcert = d2i_X509(NULL, &p, in->bv_len);
4008 LDAP_LOG( CONFIG, ENTRY,
4009 "certificateExactConvert: error parsing cert: %s\n",
4010 ERR_error_string(ERR_get_error(),NULL), 0, 0 );
4012 Debug( LDAP_DEBUG_ARGS, "certificateExactConvert: "
4013 "error parsing cert: %s\n",
4014 ERR_error_string(ERR_get_error(),NULL), NULL, NULL );
4016 return LDAP_INVALID_SYNTAX;
4019 if ( !asn1_integer2str(xcert->cert_info->serialNumber, &serial) ) {
4021 return LDAP_INVALID_SYNTAX;
4023 if ( dnX509normalize(X509_get_issuer_name(xcert), &issuer_dn )
4027 ber_memfree(serial.bv_val);
4028 return LDAP_INVALID_SYNTAX;
4033 out->bv_len = serial.bv_len + issuer_dn.bv_len + sizeof(" $ ");
4034 out->bv_val = ch_malloc(out->bv_len);
4036 AC_MEMCPY(p, serial.bv_val, serial.bv_len);
4038 AC_MEMCPY(p, " $ ", sizeof(" $ ")-1);
4040 AC_MEMCPY(p, issuer_dn.bv_val, issuer_dn.bv_len);
4041 p += issuer_dn.bv_len;
4045 LDAP_LOG( CONFIG, ARGS,
4046 "certificateExactConvert: \n %s\n", out->bv_val, 0, 0 );
4048 Debug( LDAP_DEBUG_ARGS, "certificateExactConvert "
4050 out->bv_val, NULL, NULL );
4053 ber_memfree(serial.bv_val);
4054 ber_memfree(issuer_dn.bv_val);
4056 return LDAP_SUCCESS;
4060 serial_and_issuer_parse(
4061 struct berval *assertion,
4062 struct berval *serial,
4063 struct berval *issuer_dn
4071 begin = assertion->bv_val;
4072 end = assertion->bv_val+assertion->bv_len-1;
4073 for (p=begin; p<=end && *p != '$'; p++) /* empty */ ;
4074 if ( p > end ) return LDAP_INVALID_SYNTAX;
4076 /* p now points at the $ sign, now use
4077 * begin and end to delimit the serial number
4079 while (ASCII_SPACE(*begin)) begin++;
4081 while (ASCII_SPACE(*end)) end--;
4083 if( end <= begin ) return LDAP_INVALID_SYNTAX;
4085 bv.bv_len = end-begin+1;
4087 ber_dupbv(serial, &bv);
4089 /* now extract the issuer, remember p was at the dollar sign */
4091 end = assertion->bv_val+assertion->bv_len-1;
4092 while (ASCII_SPACE(*begin)) begin++;
4093 /* should we trim spaces at the end too? is it safe always? no, no */
4095 if( end <= begin ) return LDAP_INVALID_SYNTAX;
4098 bv.bv_len = end-begin+1;
4101 dnNormalize2( NULL, &bv, issuer_dn );
4104 return LDAP_SUCCESS;
4108 certificateExactMatch(
4113 struct berval *value,
4114 void *assertedValue )
4117 unsigned char *p = value->bv_val;
4118 struct berval serial;
4119 struct berval issuer_dn;
4120 struct berval asserted_serial;
4121 struct berval asserted_issuer_dn;
4124 xcert = d2i_X509(NULL, &p, value->bv_len);
4127 LDAP_LOG( CONFIG, ENTRY,
4128 "certificateExactMatch: error parsing cert: %s\n",
4129 ERR_error_string(ERR_get_error(),NULL), 0, 0 );
4131 Debug( LDAP_DEBUG_ARGS, "certificateExactMatch: "
4132 "error parsing cert: %s\n",
4133 ERR_error_string(ERR_get_error(),NULL), NULL, NULL );
4135 return LDAP_INVALID_SYNTAX;
4138 asn1_integer2str(xcert->cert_info->serialNumber, &serial);
4139 dnX509normalize(X509_get_issuer_name(xcert), &issuer_dn);
4143 serial_and_issuer_parse(assertedValue,
4144 &asserted_serial, &asserted_issuer_dn);
4149 slap_schema.si_syn_integer,
4150 slap_schema.si_mr_integerMatch,
4153 if ( ret == LDAP_SUCCESS ) {
4154 if ( *matchp == 0 ) {
4155 /* We need to normalize everything for dnMatch */
4159 slap_schema.si_syn_distinguishedName,
4160 slap_schema.si_mr_distinguishedNameMatch,
4162 &asserted_issuer_dn);
4167 LDAP_LOG( CONFIG, ARGS, "certificateExactMatch "
4168 "%d\n\t\"%s $ %s\"\n",
4169 *matchp, serial.bv_val, issuer_dn.bv_val );
4170 LDAP_LOG( CONFIG, ARGS, "\t\"%s $ %s\"\n",
4171 asserted_serial.bv_val, asserted_issuer_dn.bv_val,
4174 Debug( LDAP_DEBUG_ARGS, "certificateExactMatch "
4175 "%d\n\t\"%s $ %s\"\n",
4176 *matchp, serial.bv_val, issuer_dn.bv_val );
4177 Debug( LDAP_DEBUG_ARGS, "\t\"%s $ %s\"\n",
4178 asserted_serial.bv_val, asserted_issuer_dn.bv_val,
4182 ber_memfree(serial.bv_val);
4183 ber_memfree(issuer_dn.bv_val);
4184 ber_memfree(asserted_serial.bv_val);
4185 ber_memfree(asserted_issuer_dn.bv_val);
4191 * Index generation function
4192 * We just index the serials, in most scenarios the issuer DN is one of
4193 * a very small set of values.
4195 static int certificateExactIndexer(
4200 struct berval *prefix,
4208 struct berval serial;
4210 /* we should have at least one value at this point */
4211 assert( values != NULL && values[0].bv_val != NULL );
4213 for( i=0; values[i].bv_val != NULL; i++ ) {
4214 /* empty -- just count them */
4217 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
4219 for( i=0; values[i].bv_val != NULL; i++ ) {
4220 p = values[i].bv_val;
4221 xcert = d2i_X509(NULL, &p, values[i].bv_len);
4224 LDAP_LOG( CONFIG, ENTRY,
4225 "certificateExactIndexer: error parsing cert: %s\n",
4226 ERR_error_string(ERR_get_error(),NULL), 0, 0);
4228 Debug( LDAP_DEBUG_ARGS, "certificateExactIndexer: "
4229 "error parsing cert: %s\n",
4230 ERR_error_string(ERR_get_error(),NULL),
4233 /* Do we leak keys on error? */
4234 return LDAP_INVALID_SYNTAX;
4237 asn1_integer2str(xcert->cert_info->serialNumber, &serial);
4239 xintegerNormalize( slap_schema.si_syn_integer,
4240 &serial, &keys[i] );
4241 ber_memfree(serial.bv_val);
4243 LDAP_LOG( CONFIG, ENTRY,
4244 "certificateExactIndexer: returning: %s\n", keys[i].bv_val, 0, 0);
4246 Debug( LDAP_DEBUG_ARGS, "certificateExactIndexer: "
4253 keys[i].bv_val = NULL;
4255 return LDAP_SUCCESS;
4258 /* Index generation function */
4259 /* We think this is always called with a value in matching rule syntax */
4260 static int certificateExactFilter(
4265 struct berval *prefix,
4266 void * assertedValue,
4270 struct berval asserted_serial;
4273 ret = serial_and_issuer_parse( assertedValue, &asserted_serial, NULL );
4274 if( ret != LDAP_SUCCESS ) return ret;
4276 keys = ch_malloc( sizeof( struct berval ) * 2 );
4277 xintegerNormalize( syntax, &asserted_serial, &keys[0] );
4278 keys[1].bv_val = NULL;
4281 ber_memfree(asserted_serial.bv_val);
4282 return LDAP_SUCCESS;
4288 check_time_syntax (struct berval *val,
4292 static int ceiling[9] = { 99, 99, 11, 30, 23, 59, 59, 12, 59 };
4293 static int mdays[2][12] = {
4294 /* non-leap years */
4295 { 30, 27, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30 },
4297 { 30, 28, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30 }
4300 int part, c, tzoffset, leapyear = 0 ;
4302 if( val->bv_len == 0 ) {
4303 return LDAP_INVALID_SYNTAX;
4306 p = (char *)val->bv_val;
4307 e = p + val->bv_len;
4309 /* Ignore initial whitespace */
4310 while ( ( p < e ) && ASCII_SPACE( *p ) ) {
4314 if (e - p < 13 - (2 * start)) {
4315 return LDAP_INVALID_SYNTAX;
4318 for (part = 0; part < 9; part++) {
4322 for (part = start; part < 7; part++) {
4324 if ((part == 6) && (c == 'Z' || c == '+' || c == '-')) {
4331 return LDAP_INVALID_SYNTAX;
4333 if (c < 0 || c > 9) {
4334 return LDAP_INVALID_SYNTAX;
4340 return LDAP_INVALID_SYNTAX;
4342 if (c < 0 || c > 9) {
4343 return LDAP_INVALID_SYNTAX;
4348 if (part == 2 || part == 3) {
4351 if (parts[part] < 0) {
4352 return LDAP_INVALID_SYNTAX;
4354 if (parts[part] > ceiling[part]) {
4355 return LDAP_INVALID_SYNTAX;
4359 /* leapyear check for the Gregorian calendar (year>1581) */
4360 if (((parts[1] % 4 == 0) && (parts[1] != 0)) ||
4361 ((parts[0] % 4 == 0) && (parts[1] == 0)))
4366 if (parts[3] > mdays[leapyear][parts[2]]) {
4367 return LDAP_INVALID_SYNTAX;
4372 tzoffset = 0; /* UTC */
4373 } else if (c != '+' && c != '-') {
4374 return LDAP_INVALID_SYNTAX;
4378 } else /* c == '+' */ {
4383 return LDAP_INVALID_SYNTAX;
4386 for (part = 7; part < 9; part++) {
4388 if (c < 0 || c > 9) {
4389 return LDAP_INVALID_SYNTAX;
4394 if (c < 0 || c > 9) {
4395 return LDAP_INVALID_SYNTAX;
4399 if (parts[part] < 0 || parts[part] > ceiling[part]) {
4400 return LDAP_INVALID_SYNTAX;
4405 /* Ignore trailing whitespace */
4406 while ( ( p < e ) && ASCII_SPACE( *p ) ) {
4410 return LDAP_INVALID_SYNTAX;
4413 switch ( tzoffset ) {
4414 case -1: /* negativ offset to UTC, ie west of Greenwich */
4415 parts[4] += parts[7];
4416 parts[5] += parts[8];
4417 for (part = 6; --part > 0; ) { /* offset is just hhmm, no seconds */
4421 c = mdays[leapyear][parts[2]];
4423 if (parts[part] > c) {
4424 parts[part] -= c + 1;
4429 case 1: /* positive offset to UTC, ie east of Greenwich */
4430 parts[4] -= parts[7];
4431 parts[5] -= parts[8];
4432 for (part = 6; --part > 0; ) {
4436 /* first arg to % needs to be non negativ */
4437 c = mdays[leapyear][(parts[2] - 1 + 12) % 12];
4439 if (parts[part] < 0) {
4440 parts[part] += c + 1;
4445 case 0: /* already UTC */
4449 return LDAP_SUCCESS;
4452 #ifdef SUPPORT_OBSOLETE_UTC_SYNTAX
4457 struct berval *normalized )
4461 rc = check_time_syntax(val, 1, parts);
4462 if (rc != LDAP_SUCCESS) {
4466 normalized->bv_val = ch_malloc( 14 );
4467 if ( normalized->bv_val == NULL ) {
4468 return LBER_ERROR_MEMORY;
4471 sprintf( normalized->bv_val, "%02d%02d%02d%02d%02d%02dZ",
4472 parts[1], parts[2] + 1, parts[3] + 1,
4473 parts[4], parts[5], parts[6] );
4474 normalized->bv_len = 13;
4476 return LDAP_SUCCESS;
4480 #ifdef SUPPORT_OBSOLETE_UTC_SYNTAX
4488 return check_time_syntax(in, 1, parts);
4493 generalizedTimeValidate(
4499 return check_time_syntax(in, 0, parts);
4504 generalizedTimeNormalize(
4509 struct berval *normalized )
4511 xgeneralizedTimeNormalize(
4514 struct berval *normalized )
4519 rc = check_time_syntax(val, 0, parts);
4520 if (rc != LDAP_SUCCESS) {
4524 normalized->bv_val = ch_malloc( 16 );
4525 if ( normalized->bv_val == NULL ) {
4526 return LBER_ERROR_MEMORY;
4529 sprintf( normalized->bv_val, "%02d%02d%02d%02d%02d%02d%02dZ",
4530 parts[0], parts[1], parts[2] + 1, parts[3] + 1,
4531 parts[4], parts[5], parts[6] );
4532 normalized->bv_len = 15;
4534 return LDAP_SUCCESS;
4538 nisNetgroupTripleValidate(
4540 struct berval *val )
4545 if ( val->bv_len == 0 ) {
4546 return LDAP_INVALID_SYNTAX;
4549 p = (char *)val->bv_val;
4550 e = p + val->bv_len;
4552 if ( *p != '(' /*')'*/ ) {
4553 return LDAP_INVALID_SYNTAX;
4556 for ( p++; ( p < e ) && ( *p != /*'('*/ ')' ); p++ ) {
4560 return LDAP_INVALID_SYNTAX;
4563 } else if ( !AD_CHAR( *p ) ) {
4564 return LDAP_INVALID_SYNTAX;
4568 if ( ( commas != 2 ) || ( *p != /*'('*/ ')' ) ) {
4569 return LDAP_INVALID_SYNTAX;
4575 return LDAP_INVALID_SYNTAX;
4578 return LDAP_SUCCESS;
4582 bootParameterValidate(
4584 struct berval *val )
4588 if ( val->bv_len == 0 ) {
4589 return LDAP_INVALID_SYNTAX;
4592 p = (char *)val->bv_val;
4593 e = p + val->bv_len;
4596 for (; ( p < e ) && ( *p != '=' ); p++ ) {
4597 if ( !AD_CHAR( *p ) ) {
4598 return LDAP_INVALID_SYNTAX;
4603 return LDAP_INVALID_SYNTAX;
4607 for ( p++; ( p < e ) && ( *p != ':' ); p++ ) {
4608 if ( !AD_CHAR( *p ) ) {
4609 return LDAP_INVALID_SYNTAX;
4614 return LDAP_INVALID_SYNTAX;
4618 for ( p++; p < e; p++ ) {
4619 if ( !SLAP_PRINTABLE( *p ) ) {
4620 return LDAP_INVALID_SYNTAX;
4624 return LDAP_SUCCESS;
4627 #define X_BINARY "X-BINARY-TRANSFER-REQUIRED 'TRUE' "
4628 #define X_NOT_H_R "X-NOT-HUMAN-READABLE 'TRUE' "
4630 static slap_syntax_defs_rec syntax_defs[] = {
4631 {"( 1.3.6.1.4.1.1466.115.121.1.1 DESC 'ACI Item' "
4632 X_BINARY X_NOT_H_R ")",
4633 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, NULL, NULL, NULL},
4634 {"( 1.3.6.1.4.1.1466.115.121.1.2 DESC 'Access Point' " X_NOT_H_R ")",
4635 0, NULL, NULL, NULL},
4636 {"( 1.3.6.1.4.1.1466.115.121.1.3 DESC 'Attribute Type Description' )",
4637 0, NULL, NULL, NULL},
4638 {"( 1.3.6.1.4.1.1466.115.121.1.4 DESC 'Audio' "
4640 SLAP_SYNTAX_BLOB, blobValidate, NULL, NULL},
4641 {"( 1.3.6.1.4.1.1466.115.121.1.5 DESC 'Binary' "
4643 SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4644 {"( 1.3.6.1.4.1.1466.115.121.1.6 DESC 'Bit String' )",
4645 0, bitStringValidate, NULL, NULL },
4646 {"( 1.3.6.1.4.1.1466.115.121.1.7 DESC 'Boolean' )",
4647 0, booleanValidate, NULL, NULL},
4648 {"( 1.3.6.1.4.1.1466.115.121.1.8 DESC 'Certificate' "
4649 X_BINARY X_NOT_H_R ")",
4650 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4651 {"( 1.3.6.1.4.1.1466.115.121.1.9 DESC 'Certificate List' "
4652 X_BINARY X_NOT_H_R ")",
4653 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4654 {"( 1.3.6.1.4.1.1466.115.121.1.10 DESC 'Certificate Pair' "
4655 X_BINARY X_NOT_H_R ")",
4656 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4657 {"( 1.3.6.1.4.1.1466.115.121.1.11 DESC 'Country String' )",
4658 0, countryStringValidate, xIA5StringNormalize, NULL},
4659 {"( 1.3.6.1.4.1.1466.115.121.1.12 DESC 'Distinguished Name' )",
4660 0, dnValidate, xdnNormalize, dnPretty2},
4661 {"( 1.3.6.1.4.1.1466.115.121.1.13 DESC 'Data Quality' )",
4662 0, NULL, NULL, NULL},
4663 {"( 1.3.6.1.4.1.1466.115.121.1.14 DESC 'Delivery Method' )",
4664 0, NULL, NULL, NULL},
4665 {"( 1.3.6.1.4.1.1466.115.121.1.15 DESC 'Directory String' )",
4666 0, UTF8StringValidate, xUTF8StringNormalize, NULL},
4667 {"( 1.3.6.1.4.1.1466.115.121.1.16 DESC 'DIT Content Rule Description' )",
4668 0, NULL, NULL, NULL},
4669 {"( 1.3.6.1.4.1.1466.115.121.1.17 DESC 'DIT Structure Rule Description' )",
4670 0, NULL, NULL, NULL},
4671 {"( 1.3.6.1.4.1.1466.115.121.1.19 DESC 'DSA Quality' )",
4672 0, NULL, NULL, NULL},
4673 {"( 1.3.6.1.4.1.1466.115.121.1.20 DESC 'DSE Type' )",
4674 0, NULL, NULL, NULL},
4675 {"( 1.3.6.1.4.1.1466.115.121.1.21 DESC 'Enhanced Guide' )",
4676 0, NULL, NULL, NULL},
4677 {"( 1.3.6.1.4.1.1466.115.121.1.22 DESC 'Facsimile Telephone Number' )",
4678 0, printablesStringValidate, xtelephoneNumberNormalize, NULL},
4679 {"( 1.3.6.1.4.1.1466.115.121.1.23 DESC 'Fax' " X_NOT_H_R ")",
4680 SLAP_SYNTAX_BLOB, NULL, NULL, NULL},
4681 {"( 1.3.6.1.4.1.1466.115.121.1.24 DESC 'Generalized Time' )",
4682 0, generalizedTimeValidate, xgeneralizedTimeNormalize, NULL},
4683 {"( 1.3.6.1.4.1.1466.115.121.1.25 DESC 'Guide' )",
4684 0, NULL, NULL, NULL},
4685 {"( 1.3.6.1.4.1.1466.115.121.1.26 DESC 'IA5 String' )",
4686 0, IA5StringValidate, xIA5StringNormalize, NULL},
4687 {"( 1.3.6.1.4.1.1466.115.121.1.27 DESC 'Integer' )",
4688 0, integerValidate, xintegerNormalize, NULL},
4689 {"( 1.3.6.1.4.1.1466.115.121.1.28 DESC 'JPEG' " X_NOT_H_R ")",
4690 SLAP_SYNTAX_BLOB, blobValidate, NULL, NULL},
4691 {"( 1.3.6.1.4.1.1466.115.121.1.29 DESC 'Master And Shadow Access Points' )",
4692 0, NULL, NULL, NULL},
4693 {"( 1.3.6.1.4.1.1466.115.121.1.30 DESC 'Matching Rule Description' )",
4694 0, NULL, NULL, NULL},
4695 {"( 1.3.6.1.4.1.1466.115.121.1.31 DESC 'Matching Rule Use Description' )",
4696 0, NULL, NULL, NULL},
4697 {"( 1.3.6.1.4.1.1466.115.121.1.32 DESC 'Mail Preference' )",
4698 0, NULL, NULL, NULL},
4699 {"( 1.3.6.1.4.1.1466.115.121.1.33 DESC 'MHS OR Address' )",
4700 0, NULL, NULL, NULL},
4701 {"( 1.3.6.1.4.1.1466.115.121.1.34 DESC 'Name And Optional UID' )",
4702 0, nameUIDValidate, xnameUIDNormalize, NULL},
4703 {"( 1.3.6.1.4.1.1466.115.121.1.35 DESC 'Name Form Description' )",
4704 0, NULL, NULL, NULL},
4705 {"( 1.3.6.1.4.1.1466.115.121.1.36 DESC 'Numeric String' )",
4706 0, numericStringValidate, xnumericStringNormalize, NULL},
4707 {"( 1.3.6.1.4.1.1466.115.121.1.37 DESC 'Object Class Description' )",
4708 0, NULL, NULL, NULL},
4709 {"( 1.3.6.1.4.1.1466.115.121.1.38 DESC 'OID' )",
4710 0, oidValidate, NULL, NULL},
4711 {"( 1.3.6.1.4.1.1466.115.121.1.39 DESC 'Other Mailbox' )",
4712 0, IA5StringValidate, xIA5StringNormalize, NULL},
4713 {"( 1.3.6.1.4.1.1466.115.121.1.40 DESC 'Octet String' )",
4714 0, blobValidate, NULL, NULL},
4715 {"( 1.3.6.1.4.1.1466.115.121.1.41 DESC 'Postal Address' )",
4716 0, UTF8StringValidate, xUTF8StringNormalize, NULL},
4717 {"( 1.3.6.1.4.1.1466.115.121.1.42 DESC 'Protocol Information' )",
4718 0, NULL, NULL, NULL},
4719 {"( 1.3.6.1.4.1.1466.115.121.1.43 DESC 'Presentation Address' )",
4720 0, NULL, NULL, NULL},
4721 {"( 1.3.6.1.4.1.1466.115.121.1.44 DESC 'Printable String' )",
4722 0, printableStringValidate, xIA5StringNormalize, NULL},
4723 {"( 1.3.6.1.4.1.1466.115.121.1.45 DESC 'SubtreeSpecification' "
4724 X_BINARY X_NOT_H_R ")",
4725 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, NULL, NULL, NULL},
4726 {"( 1.3.6.1.4.1.1466.115.121.1.49 DESC 'Supported Algorithm' "
4727 X_BINARY X_NOT_H_R ")",
4728 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4729 {"( 1.3.6.1.4.1.1466.115.121.1.50 DESC 'Telephone Number' )",
4730 0, printableStringValidate, xtelephoneNumberNormalize, NULL},
4731 {"( 1.3.6.1.4.1.1466.115.121.1.51 DESC 'Teletex Terminal Identifier' )",
4732 0, NULL, NULL, NULL},
4733 {"( 1.3.6.1.4.1.1466.115.121.1.52 DESC 'Telex Number' )",
4734 0, printablesStringValidate, xIA5StringNormalize, NULL},
4735 #ifdef SUPPORT_OBSOLETE_UTC_SYNTAX
4736 {"( 1.3.6.1.4.1.1466.115.121.1.53 DESC 'UTC Time' )",
4737 0, utcTimeValidate, xutcTimeNormalize, NULL},
4739 {"( 1.3.6.1.4.1.1466.115.121.1.54 DESC 'LDAP Syntax Description' )",
4740 0, NULL, NULL, NULL},
4741 {"( 1.3.6.1.4.1.1466.115.121.1.55 DESC 'Modify Rights' )",
4742 0, NULL, NULL, NULL},
4743 {"( 1.3.6.1.4.1.1466.115.121.1.56 DESC 'LDAP Schema Definition' )",
4744 0, NULL, NULL, NULL},
4745 {"( 1.3.6.1.4.1.1466.115.121.1.57 DESC 'LDAP Schema Description' )",
4746 0, NULL, NULL, NULL},
4747 {"( 1.3.6.1.4.1.1466.115.121.1.58 DESC 'Substring Assertion' )",
4748 0, NULL, NULL, NULL},
4750 /* RFC 2307 NIS Syntaxes */
4751 {"( 1.3.6.1.1.1.0.0 DESC 'RFC2307 NIS Netgroup Triple' )",
4752 0, nisNetgroupTripleValidate, NULL, NULL},
4753 {"( 1.3.6.1.1.1.0.1 DESC 'RFC2307 Boot Parameter' )",
4754 0, bootParameterValidate, NULL, NULL},
4758 /* These OIDs are not published yet, but will be in the next
4759 * I-D for PKIX LDAPv3 schema as have been advanced by David
4760 * Chadwick in private mail.
4762 {"( 1.2.826.0.1.3344810.7.1 DESC 'Serial Number and Issuer' )",
4763 0, UTF8StringValidate, NULL, NULL},
4766 /* OpenLDAP Experimental Syntaxes */
4767 #ifdef SLAPD_ACI_ENABLED
4768 {"( 1.3.6.1.4.1.4203.666.2.1 DESC 'OpenLDAP Experimental ACI' )",
4770 UTF8StringValidate /* THIS WILL CHANGE FOR NEW ACI SYNTAX */,
4774 #ifdef SLAPD_AUTHPASSWD
4775 /* needs updating */
4776 {"( 1.3.6.1.4.1.4203.666.2.2 DESC 'OpenLDAP authPassword' )",
4777 SLAP_SYNTAX_HIDE, NULL, NULL, NULL},
4780 /* OpenLDAP Void Syntax */
4781 {"( 1.3.6.1.4.1.4203.1.1.1 DESC 'OpenLDAP void' )" ,
4782 SLAP_SYNTAX_HIDE, inValidate, NULL, NULL},
4783 {NULL, 0, NULL, NULL, NULL}
4787 char *certificateExactMatchSyntaxes[] = {
4788 "1.3.6.1.4.1.1466.115.121.1.8" /* certificate */,
4792 char *directoryStringSyntaxes[] = {
4793 "1.3.6.1.4.1.1466.115.121.1.44" /* printableString */,
4796 char *integerFirstComponentMatchSyntaxes[] = {
4797 "1.3.6.1.4.1.1466.115.121.1.27" /* INTEGER */,
4798 "1.3.6.1.4.1.1466.115.121.1.17" /* ditStructureRuleDescription */,
4801 char *objectIdentifierFirstComponentMatchSyntaxes[] = {
4802 "1.3.6.1.4.1.1466.115.121.1.38" /* OID */,
4803 "1.3.6.1.4.1.1466.115.121.1.3" /* attributeTypeDescription */,
4804 "1.3.6.1.4.1.1466.115.121.1.16" /* ditContentRuleDescription */,
4805 "1.3.6.1.4.1.1466.115.121.1.54" /* ldapSyntaxDescription */,
4806 "1.3.6.1.4.1.1466.115.121.1.30" /* matchingRuleDescription */,
4807 "1.3.6.1.4.1.1466.115.121.1.31" /* matchingRuleUseDescription */,
4808 "1.3.6.1.4.1.1466.115.121.1.35" /* nameFormDescription */,
4809 "1.3.6.1.4.1.1466.115.121.1.37" /* objectClassDescription */,
4814 * Other matching rules in X.520 that we do not use (yet):
4816 * 2.5.13.9 numericStringOrderingMatch
4817 * 2.5.13.25 uTCTimeMatch
4818 * 2.5.13.26 uTCTimeOrderingMatch
4819 * 2.5.13.31 directoryStringFirstComponentMatch
4820 * 2.5.13.32 wordMatch
4821 * 2.5.13.33 keywordMatch
4822 * 2.5.13.35 certificateMatch
4823 * 2.5.13.36 certificatePairExactMatch
4824 * 2.5.13.37 certificatePairMatch
4825 * 2.5.13.38 certificateListExactMatch
4826 * 2.5.13.39 certificateListMatch
4827 * 2.5.13.40 algorithmIdentifierMatch
4828 * 2.5.13.41 storedPrefixMatch
4829 * 2.5.13.42 attributeCertificateMatch
4830 * 2.5.13.43 readerAndKeyIDMatch
4831 * 2.5.13.44 attributeIntegrityMatch
4833 static slap_mrule_defs_rec mrule_defs[] = {
4835 * EQUALITY matching rules must be listed after associated APPROX
4836 * matching rules. So, we list all APPROX matching rules first.
4838 #ifndef SLAP_NVALUES
4839 {"( " directoryStringApproxMatchOID " NAME 'directoryStringApproxMatch' "
4840 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4841 SLAP_MR_HIDE | SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT, NULL,
4842 NULL, NULL, directoryStringApproxMatch,
4843 directoryStringApproxIndexer, directoryStringApproxFilter,
4846 {"( " IA5StringApproxMatchOID " NAME 'IA5StringApproxMatch' "
4847 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4848 SLAP_MR_HIDE | SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT, NULL,
4849 NULL, NULL, IA5StringApproxMatch,
4850 IA5StringApproxIndexer, IA5StringApproxFilter,
4855 * Other matching rules
4858 {"( 2.5.13.0 NAME 'objectIdentifierMatch' "
4859 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
4860 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4862 objectIdentifierNormalize, objectIdentifierMatch,
4863 objectIdentifierIndexer, objectIdentifierFilter,
4866 {"( 2.5.13.1 NAME 'distinguishedNameMatch' "
4867 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )",
4868 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4870 distinguishedNameNormalize, distinguishedNameMatch,
4871 distinguishedNameIndexer, distinguishedNameFilter,
4874 {"( 2.5.13.2 NAME 'caseIgnoreMatch' "
4875 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4876 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD,
4877 directoryStringSyntaxes,
4879 caseIgnoreNormalize, caseIgnoreMatch,
4880 caseIgnoreIndexer, caseIgnoreFilter,
4881 directoryStringApproxMatchOID },
4883 {"( 2.5.13.3 NAME 'caseIgnoreOrderingMatch' "
4884 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4885 SLAP_MR_ORDERING, directoryStringSyntaxes,
4886 NULL, caseIgnoreNormalize, caseIgnoreOrderingMatch,
4889 {"( 2.5.13.4 NAME 'caseIgnoreSubstringsMatch' "
4890 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4891 SLAP_MR_SUBSTR, NULL,
4893 caseIgnoreSubstringsMatch,
4894 caseIgnoreSubstringsIndexer, caseIgnoreSubstringsFilter,
4897 {"( 2.5.13.5 NAME 'caseExactMatch' "
4898 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4899 SLAP_MR_EQUALITY | SLAP_MR_EXT, directoryStringSyntaxes,
4901 caseExactNormalize, caseExactMatch,
4902 caseExactIndexer, caseExactFilter,
4903 directoryStringApproxMatchOID },
4905 {"( 2.5.13.6 NAME 'caseExactOrderingMatch' "
4906 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4907 SLAP_MR_ORDERING, directoryStringSyntaxes,
4908 NULL, caseExactNormalize, caseExactOrderingMatch,
4911 {"( 2.5.13.7 NAME 'caseExactSubstringsMatch' "
4912 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4913 SLAP_MR_SUBSTR, directoryStringSyntaxes,
4915 NULL, caseExactSubstringsMatch,
4916 caseExactSubstringsIndexer, caseExactSubstringsFilter,
4919 {"( 2.5.13.8 NAME 'numericStringMatch' "
4920 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 )",
4921 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL,
4923 numericStringNormalize, numericStringMatch,
4924 numericStringIndexer, numericStringFilter,
4927 {"( 2.5.13.10 NAME 'numericStringSubstringsMatch' "
4928 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4929 SLAP_MR_SUBSTR, NULL,
4931 NULL, numericStringSubstringsMatch,
4932 numericStringSubstringsIndexer, numericStringSubstringsFilter,
4935 {"( 2.5.13.11 NAME 'caseIgnoreListMatch' "
4936 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )",
4937 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL,
4938 NULL, NULL, NULL, NULL, NULL, NULL},
4940 {"( 2.5.13.12 NAME 'caseIgnoreListSubstringsMatch' "
4941 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4942 SLAP_MR_SUBSTR, NULL,
4943 NULL, NULL, NULL, NULL, NULL, NULL},
4945 {"( 2.5.13.13 NAME 'booleanMatch' "
4946 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )",
4947 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4950 booleanIndexer, booleanFilter,
4953 {"( 2.5.13.14 NAME 'integerMatch' "
4954 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4955 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4957 integerNormalize, integerMatch,
4958 integerIndexer, integerFilter,
4961 {"( 2.5.13.15 NAME 'integerOrderingMatch' "
4962 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4963 SLAP_MR_ORDERING, NULL, NULL,
4964 integerNormalize, integerOrderingMatch,
4965 integerIndexer, integerFilter,
4968 {"( 2.5.13.16 NAME 'bitStringMatch' "
4969 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.6 )",
4970 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4972 NULL, bitStringMatch,
4973 bitStringIndexer, bitStringFilter,
4976 {"( 2.5.13.17 NAME 'octetStringMatch' "
4977 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
4978 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4980 octetStringMatch, octetStringIndexer, octetStringFilter,
4983 {"( 2.5.13.18 NAME 'octetStringOrderingMatch' "
4984 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
4985 SLAP_MR_ORDERING, NULL,
4987 octetStringOrderingMatch, NULL, NULL,
4990 {"( 2.5.13.19 NAME 'octetStringSubstringsMatch' "
4991 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
4992 SLAP_MR_SUBSTR, NULL,
4994 octetStringSubstringsMatch, NULL, NULL,
4997 {"( 2.5.13.20 NAME 'telephoneNumberMatch' "
4998 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 )",
4999 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL,
5001 telephoneNumberNormalize, telephoneNumberMatch,
5002 telephoneNumberIndexer, telephoneNumberFilter,
5005 {"( 2.5.13.21 NAME 'telephoneNumberSubstringsMatch' "
5006 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
5007 SLAP_MR_SUBSTR, NULL,
5008 NULL, NULL, telephoneNumberSubstringsMatch,
5009 telephoneNumberSubstringsIndexer, telephoneNumberSubstringsFilter,
5012 {"( 2.5.13.22 NAME 'presentationAddressMatch' "
5013 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.43 )",
5014 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
5019 {"( 2.5.13.23 NAME 'uniqueMemberMatch' "
5020 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.34 )",
5021 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
5023 uniqueMemberNormalize, uniqueMemberMatch,
5027 {"( 2.5.13.24 NAME 'protocolInformationMatch' "
5028 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.42 )",
5029 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
5030 NULL, NULL, NULL, NULL, NULL, NULL},
5032 {"( 2.5.13.27 NAME 'generalizedTimeMatch' "
5033 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
5034 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
5036 generalizedTimeNormalize, generalizedTimeMatch,
5040 {"( 2.5.13.28 NAME 'generalizedTimeOrderingMatch' "
5041 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
5042 SLAP_MR_ORDERING, NULL,
5044 generalizedTimeNormalize, generalizedTimeOrderingMatch,
5048 {"( 2.5.13.29 NAME 'integerFirstComponentMatch' "
5049 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
5050 SLAP_MR_EQUALITY | SLAP_MR_EXT, integerFirstComponentMatchSyntaxes,
5052 integerFirstComponentNormalize, integerMatch,
5056 {"( 2.5.13.30 NAME 'objectIdentifierFirstComponentMatch' "
5057 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
5058 SLAP_MR_EQUALITY | SLAP_MR_EXT,
5059 objectIdentifierFirstComponentMatchSyntaxes,
5061 objectIdentifierFirstComponentNormalize, objectIdentifierMatch,
5065 #ifndef SLAP_NVALUES
5067 {"( 2.5.13.34 NAME 'certificateExactMatch' "
5068 "SYNTAX 1.2.826.0.1.3344810.7.1 )",
5069 SLAP_MR_EQUALITY | SLAP_MR_EXT, certificateExactMatchSyntaxes,
5070 certificateExactConvert, NULL,
5071 certificateExactMatch,
5072 certificateExactIndexer, certificateExactFilter,
5077 {"( 1.3.6.1.4.1.1466.109.114.1 NAME 'caseExactIA5Match' "
5078 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
5079 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
5081 caseExactIA5Normalize, caseExactIA5Match,
5082 caseExactIA5Indexer, caseExactIA5Filter,
5083 IA5StringApproxMatchOID },
5085 {"( 1.3.6.1.4.1.1466.109.114.2 NAME 'caseIgnoreIA5Match' "
5086 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
5087 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL,
5089 NULL, caseIgnoreIA5Match,
5090 caseIgnoreIA5Indexer, caseIgnoreIA5Filter,
5091 IA5StringApproxMatchOID },
5093 {"( 1.3.6.1.4.1.1466.109.114.3 NAME 'caseIgnoreIA5SubstringsMatch' "
5094 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
5095 SLAP_MR_SUBSTR, NULL,
5097 NULL, caseIgnoreIA5SubstringsMatch,
5098 caseIgnoreIA5SubstringsIndexer, caseIgnoreIA5SubstringsFilter,
5101 {"( 1.3.6.1.4.1.4203.1.2.1 NAME 'caseExactIA5SubstringsMatch' "
5102 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
5103 SLAP_MR_SUBSTR, NULL,
5105 NULL, caseExactIA5SubstringsMatch,
5106 caseExactIA5SubstringsIndexer, caseExactIA5SubstringsFilter,
5109 #ifdef SLAPD_AUTHPASSWD
5110 /* needs updating */
5111 {"( 1.3.6.1.4.1.4203.666.4.1 NAME 'authPasswordMatch' "
5112 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
5113 SLAP_MR_EQUALITY, NULL,
5115 authPasswordMatch, NULL, NULL,
5119 #ifdef SLAPD_ACI_ENABLED
5120 {"( 1.3.6.1.4.1.4203.666.4.2 NAME 'OpenLDAPaciMatch' "
5121 "SYNTAX 1.3.6.1.4.1.4203.666.2.1 )",
5122 SLAP_MR_EQUALITY, NULL,
5124 OpenLDAPaciMatch, NULL, NULL,
5128 {"( 1.2.840.113556.1.4.803 NAME 'integerBitAndMatch' "
5129 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
5132 NULL, integerBitAndMatch, NULL, NULL,
5135 {"( 1.2.840.113556.1.4.804 NAME 'integerBitOrMatch' "
5136 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
5139 NULL, integerBitOrMatch, NULL, NULL,
5142 {NULL, SLAP_MR_NONE, NULL,
5143 NULL, NULL, NULL, NULL, NULL,
5148 slap_schema_init( void )
5153 /* we should only be called once (from main) */
5154 assert( schema_init_done == 0 );
5156 for ( i=0; syntax_defs[i].sd_desc != NULL; i++ ) {
5157 res = register_syntax( &syntax_defs[i] );
5160 fprintf( stderr, "slap_schema_init: Error registering syntax %s\n",
5161 syntax_defs[i].sd_desc );
5166 for ( i=0; mrule_defs[i].mrd_desc != NULL; i++ ) {
5167 if( mrule_defs[i].mrd_usage == SLAP_MR_NONE &&
5168 mrule_defs[i].mrd_compat_syntaxes == NULL )
5171 "slap_schema_init: Ignoring unusable matching rule %s\n",
5172 mrule_defs[i].mrd_desc );
5176 res = register_matching_rule( &mrule_defs[i] );
5180 "slap_schema_init: Error registering matching rule %s\n",
5181 mrule_defs[i].mrd_desc );
5186 res = slap_schema_load();
5187 schema_init_done = 1;
5192 schema_destroy( void )