1 /* schema_init.c - init builtin schema */
4 * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
5 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
15 #include <ac/string.h>
16 #include <ac/socket.h>
22 #include "ldap_utf8.h"
24 #include "lutil_hash.h"
25 #define HASH_BYTES LUTIL_HASH_BYTES
26 #define HASH_CONTEXT lutil_HASH_CTX
27 #define HASH_Init(c) lutil_HASHInit(c)
28 #define HASH_Update(c,buf,len) lutil_HASHUpdate(c,buf,len)
29 #define HASH_Final(d,c) lutil_HASHFinal(d,c)
33 #define SLAP_MR_DN_FOLD (0)
35 #define SLAP_MR_ASSOCIATED(mr, with) \
36 ((mr) == (with) || (mr)->smr_associated == (with))
38 #define xUTF8StringNormalize NULL
39 #define xIA5StringNormalize NULL
40 #define xtelephoneNumberNormalize NULL
41 #define xgeneralizedTimeNormalize NULL
42 #define xintegerNormalize NULL
43 #define xnumericStringNormalize NULL
44 #define xnameUIDNormalize NULL
45 #define xdnNormalize NULL
47 /* (new) normalization routines */
48 #define caseExactIA5Normalize IA5StringNormalize
49 #define caseIgnoreIA5Normalize IA5StringNormalize
50 #define caseExactNormalize UTF8StringNormalize
51 #define caseIgnoreNormalize UTF8StringNormalize
53 #define integerNormalize NULL
54 #define integerFirstComponentNormalize NULL
55 #define numericStringNormalize NULL
56 #define objectIdentifierNormalize NULL
57 #define objectIdentifierFirstComponentNormalize NULL
58 #define generalizedTimeNormalize NULL
59 #define bitStringNormalize NULL
60 #define telephoneNumberNormalize NULL
62 #define distinguishedNameNormalize dnNormalize
63 #define distinguishedNameMatch dnMatch
64 #define distinguishedNameIndexer octetStringIndexer
65 #define distinguishedNameFilter octetStringFilter
67 #define uniqueMemberMatch dnMatch
69 #define objectIdentifierMatch octetStringMatch
70 #define objectIdentifierIndexer octetStringIndexer
71 #define objectIdentifierFilter octetStringFilter
73 #define OpenLDAPaciMatch NULL
75 #define bitStringMatch octetStringMatch
76 #define bitStringIndexer octetStringIndexer
77 #define bitStringFilter octetStringFilter
79 #define integerMatch NULL
80 #define integerOrderingMatch NULL
81 #define integerIndexer NULL
82 #define integerFilter NULL
84 #define generalizedTimeMatch NULL
85 #define generalizedTimeOrderingMatch NULL
87 #define caseIgnoreMatch octetStringMatch
88 #define caseIgnoreOrderingMatch octetStringOrderingMatch
89 #define caseIgnoreIndexer octetStringIndexer
90 #define caseIgnoreFilter octetStringFilter
92 #define caseIgnoreSubstringsMatch octetStringSubstringsMatch
93 #define caseIgnoreSubstringsIndexer octetStringSubstringsIndexer
94 #define caseIgnoreSubstringsFilter octetStringSubstringsFilter
96 #define caseExactMatch octetStringMatch
97 #define caseExactOrderingMatch octetStringOrderingMatch
98 #define caseExactIndexer octetStringIndexer
99 #define caseExactFilter octetStringFilter
101 #define caseExactSubstringsMatch octetStringSubstringsMatch
102 #define caseExactSubstringsIndexer octetStringSubstringsIndexer
103 #define caseExactSubstringsFilter octetStringSubstringsFilter
105 #define caseExactIA5Match octetStringMatch
106 #define caseExactIA5Indexer octetStringIndexer
107 #define caseExactIA5Filter octetStringFilter
109 #define caseExactIA5SubstringsMatch octetStringSubstringsMatch
110 #define caseExactIA5SubstringsIndexer octetStringSubstringsIndexer
111 #define caseExactIA5SubstringsFilter octetStringSubstringsFilter
113 #define caseIgnoreIA5Match octetStringMatch
114 #define caseIgnoreIA5Indexer octetStringIndexer
115 #define caseIgnoreIA5Filter octetStringFilter
117 #define caseIgnoreIA5SubstringsMatch caseExactIA5SubstringsMatch
118 #define caseIgnoreIA5SubstringsIndexer caseExactIA5SubstringsIndexer
119 #define caseIgnoreIA5SubstringsFilter caseExactIA5SubstringsFilter
121 #define numericStringMatch octetStringMatch
122 #define numericStringIndexer octetStringIndexer
123 #define numericStringFilter octetStringFilter
125 #define numericStringSubstringsMatch caseExactIA5SubstringsMatch
126 #define numericStringSubstringsIndexer caseExactIA5SubstringsIndexer
127 #define numericStringSubstringsFilter caseExactIA5SubstringsFilter
129 #define telephoneNumberMatch octetStringMatch
130 #define telephoneNumberIndexer octetStringIndexer
131 #define telephoneNumberFilter octetStringFilter
133 #define telephoneNumberSubstringsMatch caseExactIA5SubstringsMatch
134 #define telephoneNumberSubstringsIndexer caseExactIA5SubstringsIndexer
135 #define telephoneNumberSubstringsFilter caseExactIA5SubstringsFilter
139 /* validatation routines */
140 #define berValidate blobValidate
142 /* approx matching rules */
144 #define directoryStringApproxMatchOID NULL
145 #define IA5StringApproxMatchOID NULL
147 #define directoryStringApproxMatchOID "1.3.6.1.4.1.4203.666.4.4"
148 #define directoryStringApproxMatch approxMatch
149 #define directoryStringApproxIndexer approxIndexer
150 #define directoryStringApproxFilter approxFilter
151 #define IA5StringApproxMatchOID "1.3.6.1.4.1.4203.666.4.5"
152 #define IA5StringApproxMatch approxMatch
153 #define IA5StringApproxIndexer approxIndexer
154 #define IA5StringApproxFilter approxFilter
159 #define xdnNormalize dnNormalize
161 /* (new) normalization routines */
162 #define caseExactNormalize NULL
163 #define caseExactIA5Normalize NULL
164 #define caseIgnoreNormalize NULL
165 #define caseIgnoreIA5Normalize NULL
166 #define distinguishedNameNormalize NULL
167 #define integerNormalize NULL
168 #define integerFirstComponentNormalize NULL
169 #define numericStringNormalize NULL
170 #define objectIdentifierNormalize NULL
171 #define objectIdentifierFirstComponentNormalize NULL
172 #define generalizedTimeNormalize NULL
173 #define uniqueMemberNormalize NULL
174 #define bitStringNormalize NULL
175 #define telephoneNumberNormalize NULL
178 /* matching routines */
179 #define bitStringMatch octetStringMatch
180 #define bitStringIndexer octetStringIndexer
181 #define bitStringFilter octetStringFilter
183 #define numericStringMatch caseIgnoreIA5Match
184 #define numericStringIndexer NULL
185 #define numericStringFilter NULL
186 #define numericStringSubstringsIndexer NULL
187 #define numericStringSubstringsFilter NULL
189 #define objectIdentifierMatch octetStringMatch
190 #define objectIdentifierIndexer caseIgnoreIA5Indexer
191 #define objectIdentifierFilter caseIgnoreIA5Filter
193 #define octetStringSubstringsMatch NULL
194 #define OpenLDAPaciMatch NULL
196 #define generalizedTimeMatch caseIgnoreIA5Match
197 #define generalizedTimeOrderingMatch caseIgnoreIA5Match
199 #define uniqueMemberMatch dnMatch
200 #define numericStringSubstringsMatch NULL
202 #define caseExactIndexer caseExactIgnoreIndexer
203 #define caseExactFilter caseExactIgnoreFilter
204 #define caseExactOrderingMatch caseExactMatch
205 #define caseExactSubstringsMatch caseExactIgnoreSubstringsMatch
206 #define caseExactSubstringsIndexer caseExactIgnoreSubstringsIndexer
207 #define caseExactSubstringsFilter caseExactIgnoreSubstringsFilter
208 #define caseIgnoreIndexer caseExactIgnoreIndexer
209 #define caseIgnoreFilter caseExactIgnoreFilter
210 #define caseIgnoreOrderingMatch caseIgnoreMatch
211 #define caseIgnoreSubstringsMatch caseExactIgnoreSubstringsMatch
212 #define caseIgnoreSubstringsIndexer caseExactIgnoreSubstringsIndexer
213 #define caseIgnoreSubstringsFilter caseExactIgnoreSubstringsFilter
215 #define integerOrderingMatch integerMatch
216 #define integerFirstComponentMatch integerMatch
218 #define distinguishedNameMatch dnMatch
219 #define distinguishedNameIndexer caseExactIgnoreIndexer
220 #define distinguishedNameFilter caseExactIgnoreFilter
222 #define telephoneNumberMatch caseIgnoreIA5Match
223 #define telephoneNumberSubstringsMatch caseIgnoreIA5SubstringsMatch
224 #define telephoneNumberIndexer caseIgnoreIA5Indexer
225 #define telephoneNumberFilter caseIgnoreIA5Filter
226 #define telephoneNumberSubstringsIndexer caseIgnoreIA5SubstringsIndexer
227 #define telephoneNumberSubstringsFilter caseIgnoreIA5SubstringsFilter
231 static char *bvcasechr( struct berval *bv, unsigned char c, ber_len_t *len )
234 char lower = TOLOWER( c );
235 char upper = TOUPPER( c );
237 if( c == 0 ) return NULL;
239 for( i=0; i < bv->bv_len; i++ ) {
240 if( upper == bv->bv_val[i] || lower == bv->bv_val[i] ) {
242 return &bv->bv_val[i];
255 struct berval *value,
256 void *assertedValue )
258 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
261 match = memcmp( value->bv_val,
262 ((struct berval *) assertedValue)->bv_val,
271 octetStringOrderingMatch(
276 struct berval *value,
277 void *assertedValue )
279 ber_len_t v_len = value->bv_len;
280 ber_len_t av_len = ((struct berval *) assertedValue)->bv_len;
282 int match = memcmp( value->bv_val,
283 ((struct berval *) assertedValue)->bv_val,
284 (v_len < av_len ? v_len : av_len) );
286 if( match == 0 ) match = v_len - av_len;
292 /* Index generation function */
293 int octetStringIndexer(
298 struct berval *prefix,
305 HASH_CONTEXT HASHcontext;
306 unsigned char HASHdigest[HASH_BYTES];
307 struct berval digest;
308 digest.bv_val = HASHdigest;
309 digest.bv_len = sizeof(HASHdigest);
311 for( i=0; values[i].bv_val != NULL; i++ ) {
312 /* just count them */
315 /* we should have at least one value at this point */
318 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
320 slen = syntax->ssyn_oidlen;
321 mlen = mr->smr_oidlen;
323 for( i=0; values[i].bv_val != NULL; i++ ) {
324 HASH_Init( &HASHcontext );
325 if( prefix != NULL && prefix->bv_len > 0 ) {
326 HASH_Update( &HASHcontext,
327 prefix->bv_val, prefix->bv_len );
329 HASH_Update( &HASHcontext,
330 syntax->ssyn_oid, slen );
331 HASH_Update( &HASHcontext,
333 HASH_Update( &HASHcontext,
334 values[i].bv_val, values[i].bv_len );
335 HASH_Final( HASHdigest, &HASHcontext );
337 ber_dupbv( &keys[i], &digest );
340 keys[i].bv_val = NULL;
348 /* Index generation function */
349 int octetStringFilter(
354 struct berval *prefix,
355 void * assertedValue,
360 HASH_CONTEXT HASHcontext;
361 unsigned char HASHdigest[HASH_BYTES];
362 struct berval *value = (struct berval *) assertedValue;
363 struct berval digest;
364 digest.bv_val = HASHdigest;
365 digest.bv_len = sizeof(HASHdigest);
367 slen = syntax->ssyn_oidlen;
368 mlen = mr->smr_oidlen;
370 keys = ch_malloc( sizeof( struct berval ) * 2 );
372 HASH_Init( &HASHcontext );
373 if( prefix != NULL && prefix->bv_len > 0 ) {
374 HASH_Update( &HASHcontext,
375 prefix->bv_val, prefix->bv_len );
377 HASH_Update( &HASHcontext,
378 syntax->ssyn_oid, slen );
379 HASH_Update( &HASHcontext,
381 HASH_Update( &HASHcontext,
382 value->bv_val, value->bv_len );
383 HASH_Final( HASHdigest, &HASHcontext );
385 ber_dupbv( keys, &digest );
386 keys[1].bv_val = NULL;
399 /* no value allowed */
400 return LDAP_INVALID_SYNTAX;
408 /* any value allowed */
419 /* very unforgiving validation, requires no normalization
420 * before simplistic matching
422 if( in->bv_len < 3 ) {
423 return LDAP_INVALID_SYNTAX;
427 * rfc 2252 section 6.3 Bit String
428 * bitstring = "'" *binary-digit "'"
429 * binary-digit = "0" / "1"
430 * example: '0101111101'B
433 if( in->bv_val[0] != '\'' ||
434 in->bv_val[in->bv_len-2] != '\'' ||
435 in->bv_val[in->bv_len-1] != 'B' )
437 return LDAP_INVALID_SYNTAX;
440 for( i=in->bv_len-3; i>0; i-- ) {
441 if( in->bv_val[i] != '0' && in->bv_val[i] != '1' ) {
442 return LDAP_INVALID_SYNTAX;
457 if( in->bv_len == 0 ) return LDAP_SUCCESS;
459 ber_dupbv( &dn, in );
460 if( !dn.bv_val ) return LDAP_OTHER;
462 if( dn.bv_val[dn.bv_len-1] == 'B'
463 && dn.bv_val[dn.bv_len-2] == '\'' )
465 /* assume presence of optional UID */
468 for(i=dn.bv_len-3; i>1; i--) {
469 if( dn.bv_val[i] != '0' && dn.bv_val[i] != '1' ) {
473 if( dn.bv_val[i] != '\'' || dn.bv_val[i-1] != '#' ) {
474 ber_memfree( dn.bv_val );
475 return LDAP_INVALID_SYNTAX;
478 /* trim the UID to allow use of dnValidate */
479 dn.bv_val[i-1] = '\0';
483 rc = dnValidate( NULL, &dn );
485 ber_memfree( dn.bv_val );
491 uniqueMemberNormalize(
496 struct berval *normalized )
502 struct berval *normalized )
508 ber_dupbv( &out, val );
509 if( out.bv_len != 0 ) {
510 struct berval uid = { 0, NULL };
512 if( out.bv_val[out.bv_len-1] == 'B'
513 && out.bv_val[out.bv_len-2] == '\'' )
515 /* assume presence of optional UID */
516 uid.bv_val = strrchr( out.bv_val, '#' );
518 if( uid.bv_val == NULL ) {
520 return LDAP_INVALID_SYNTAX;
523 uid.bv_len = out.bv_len - (uid.bv_val - out.bv_val);
524 out.bv_len -= uid.bv_len--;
526 /* temporarily trim the UID */
527 *(uid.bv_val++) = '\0';
530 rc = dnNormalize2( NULL, &out, normalized );
532 if( rc != LDAP_SUCCESS ) {
534 return LDAP_INVALID_SYNTAX;
538 normalized->bv_val = ch_realloc( normalized->bv_val,
539 normalized->bv_len + uid.bv_len + sizeof("#") );
541 /* insert the separator */
542 normalized->bv_val[normalized->bv_len++] = '#';
545 AC_MEMCPY( &normalized->bv_val[normalized->bv_len],
546 uid.bv_val, uid.bv_len );
547 normalized->bv_len += uid.bv_len;
550 normalized->bv_val[normalized->bv_len] = '\0';
560 * Handling boolean syntax and matching is quite rigid.
561 * A more flexible approach would be to allow a variety
562 * of strings to be normalized and prettied into TRUE
570 /* very unforgiving validation, requires no normalization
571 * before simplistic matching
574 if( in->bv_len == 4 ) {
575 if( !memcmp( in->bv_val, "TRUE", 4 ) ) {
578 } else if( in->bv_len == 5 ) {
579 if( !memcmp( in->bv_val, "FALSE", 5 ) ) {
584 return LDAP_INVALID_SYNTAX;
593 struct berval *value,
594 void *assertedValue )
596 /* simplistic matching allowed by rigid validation */
597 struct berval *asserted = (struct berval *) assertedValue;
598 *matchp = value->bv_len != asserted->bv_len;
602 /*-------------------------------------------------------------------
603 LDAP/X.500 string syntax / matching rules have a few oddities. This
604 comment attempts to detail how slapd(8) treats them.
607 StringSyntax X.500 LDAP Matching/Comments
608 DirectoryString CHOICE UTF8 i/e + ignore insignificant spaces
609 PrintableString subset subset i/e + ignore insignificant spaces
610 PrintableString subset subset i/e + ignore insignificant spaces
611 NumericString subset subset ignore all spaces
612 IA5String ASCII ASCII i/e + ignore insignificant spaces
613 TeletexString T.61 T.61 i/e + ignore insignificant spaces
615 TelephoneNumber subset subset i + ignore all spaces and "-"
617 See draft-ietf-ldapbis-strpro for details (once published).
621 In X.500(93), a directory string can be either a PrintableString,
622 a bmpString, or a UniversalString (e.g., UCS (a subset of Unicode)).
623 In later versions, more CHOICEs were added. In all cases the string
626 In LDAPv3, a directory string is a UTF-8 encoded UCS string.
627 A directory string cannot be zero length.
629 For matching, there are both case ignore and exact rules. Both
630 also require that "insignificant" spaces be ignored.
631 spaces before the first non-space are ignored;
632 spaces after the last non-space are ignored;
633 spaces after a space are ignored.
634 Note: by these rules (and as clarified in X.520), a string of only
635 spaces is to be treated as if held one space, not empty (which
636 would be a syntax error).
639 In ASN.1, numeric string is just a string of digits and spaces
640 and could be empty. However, in X.500, all attribute values of
641 numeric string carry a non-empty constraint. For example:
643 internationalISDNNumber ATTRIBUTE ::= {
644 WITH SYNTAX InternationalISDNNumber
645 EQUALITY MATCHING RULE numericStringMatch
646 SUBSTRINGS MATCHING RULE numericStringSubstringsMatch
647 ID id-at-internationalISDNNumber }
648 InternationalISDNNumber ::=
649 NumericString (SIZE(1..ub-international-isdn-number))
651 Unforunately, some assertion values are don't carry the same
652 constraint (but its unclear how such an assertion could ever
653 be true). In LDAP, there is one syntax (numericString) not two
654 (numericString with constraint, numericString without constraint).
655 This should be treated as numericString with non-empty constraint.
656 Note that while someone may have no ISDN number, there are no ISDN
657 numbers which are zero length.
659 In matching, spaces are ignored.
662 In ASN.1, Printable string is just a string of printable characters
663 and can be empty. In X.500, semantics much like NumericString (see
664 serialNumber for a like example) excepting uses insignificant space
665 handling instead of ignore all spaces.
668 Basically same as PrintableString. There are no examples in X.500,
669 but same logic applies. So we require them to be non-empty as
672 -------------------------------------------------------------------*/
681 unsigned char *u = in->bv_val;
683 if( in->bv_len == 0 && syntax == slap_schema.si_syn_directoryString ) {
684 /* directory strings cannot be empty */
685 return LDAP_INVALID_SYNTAX;
688 for( count = in->bv_len; count > 0; count-=len, u+=len ) {
689 /* get the length indicated by the first byte */
690 len = LDAP_UTF8_CHARLEN2( u, len );
692 /* very basic checks */
695 if( (u[5] & 0xC0) != 0x80 ) {
696 return LDAP_INVALID_SYNTAX;
699 if( (u[4] & 0xC0) != 0x80 ) {
700 return LDAP_INVALID_SYNTAX;
703 if( (u[3] & 0xC0) != 0x80 ) {
704 return LDAP_INVALID_SYNTAX;
707 if( (u[2] & 0xC0 )!= 0x80 ) {
708 return LDAP_INVALID_SYNTAX;
711 if( (u[1] & 0xC0) != 0x80 ) {
712 return LDAP_INVALID_SYNTAX;
715 /* CHARLEN already validated it */
718 return LDAP_INVALID_SYNTAX;
721 /* make sure len corresponds with the offset
722 to the next character */
723 if( LDAP_UTF8_OFFSET( u ) != len ) return LDAP_INVALID_SYNTAX;
727 return LDAP_INVALID_SYNTAX;
740 struct berval *normalized )
742 struct berval tmp, nvalue;
746 if( val->bv_val == NULL ) {
747 /* assume we're dealing with a syntax (e.g., UTF8String)
748 * which allows empty strings
750 normalized->bv_len = 0;
751 normalized->bv_val = NULL;
755 flags = SLAP_MR_ASSOCIATED(mr, slap_schema.si_mr_caseExactMatch )
756 ? LDAP_UTF8_NOCASEFOLD : LDAP_UTF8_CASEFOLD;
757 flags |= ( use & SLAP_MR_EQUALITY_APPROX == SLAP_MR_EQUALITY_APPROX )
758 ? LDAP_UTF8_APPROX : 0;
760 val = UTF8bvnormalize( val, &tmp, flags );
765 /* collapse spaces (in place) */
767 nvalue.bv_val = tmp.bv_val;
769 wasspace=1; /* trim leading spaces */
770 for( i=0; i<tmp.bv_len; i++) {
771 if ( ASCII_SPACE( tmp.bv_val[i] )) {
772 if( wasspace++ == 0 ) {
773 /* trim repeated spaces */
774 nvalue.bv_val[nvalue.bv_len++] = tmp.bv_val[i];
778 nvalue.bv_val[nvalue.bv_len++] = tmp.bv_val[i];
782 if( nvalue.bv_len ) {
784 /* last character was a space, trim it */
787 nvalue.bv_val[nvalue.bv_len] = '\0';
790 /* string of all spaces is treated as one space */
791 nvalue.bv_val[0] = ' ';
792 nvalue.bv_val[1] = '\0';
796 *normalized = nvalue;
802 xUTF8StringNormalize(
805 struct berval *normalized )
810 /* validator should have refused an empty string */
811 assert( val->bv_len );
815 /* Ignore initial whitespace */
816 /* All space is ASCII. All ASCII is 1 byte */
817 for ( ; p < val->bv_val + val->bv_len && ASCII_SPACE( p[ 0 ] ); p++ );
819 normalized->bv_len = val->bv_len - (p - val->bv_val);
821 if( !normalized->bv_len ) {
822 ber_mem2bv( " ", 1, 1, normalized );
826 ber_mem2bv( p, normalized->bv_len, 1, normalized );
827 e = normalized->bv_val + normalized->bv_len;
829 assert( normalized->bv_val );
831 p = q = normalized->bv_val;
836 if ( ASCII_SPACE( *p ) ) {
841 /* Ignore the extra whitespace */
842 while ( ASCII_SPACE( *p ) ) {
846 len = LDAP_UTF8_COPY(q,p);
852 assert( normalized->bv_val <= p );
853 assert( q+len <= p );
855 /* cannot start with a space */
856 assert( !ASCII_SPACE( normalized->bv_val[0] ) );
859 * If the string ended in space, backup the pointer one
860 * position. One is enough because the above loop collapsed
861 * all whitespace to a single space.
869 /* cannot end with a space */
870 assert( !ASCII_SPACE( *q ) );
877 normalized->bv_len = q - normalized->bv_val;
882 /* Returns Unicode canonically normalized copy of a substring assertion
883 * Skipping attribute description */
884 static SubstringsAssertion *
885 UTF8SubstringsAssertionNormalize(
886 SubstringsAssertion *sa,
889 SubstringsAssertion *nsa;
892 nsa = (SubstringsAssertion *)SLAP_CALLOC( 1, sizeof(SubstringsAssertion) );
897 if( sa->sa_initial.bv_val != NULL ) {
898 UTF8bvnormalize( &sa->sa_initial, &nsa->sa_initial, casefold );
899 if( nsa->sa_initial.bv_val == NULL ) {
904 if( sa->sa_any != NULL ) {
905 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
908 nsa->sa_any = (struct berval *)
909 SLAP_MALLOC( (i + 1) * sizeof(struct berval) );
910 if( nsa->sa_any == NULL ) {
914 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
915 UTF8bvnormalize( &sa->sa_any[i], &nsa->sa_any[i],
917 if( nsa->sa_any[i].bv_val == NULL ) {
921 nsa->sa_any[i].bv_val = NULL;
924 if( sa->sa_final.bv_val != NULL ) {
925 UTF8bvnormalize( &sa->sa_final, &nsa->sa_final, casefold );
926 if( nsa->sa_final.bv_val == NULL ) {
934 if ( nsa->sa_final.bv_val ) free( nsa->sa_final.bv_val );
935 if ( nsa->sa_any ) ber_bvarray_free( nsa->sa_any );
936 if ( nsa->sa_initial.bv_val ) free( nsa->sa_initial.bv_val );
941 #ifndef SLAPD_APPROX_OLDSINGLESTRING
943 #if defined(SLAPD_APPROX_INITIALS)
944 #define SLAPD_APPROX_DELIMITER "._ "
945 #define SLAPD_APPROX_WORDLEN 2
947 #define SLAPD_APPROX_DELIMITER " "
948 #define SLAPD_APPROX_WORDLEN 1
957 struct berval *value,
958 void *assertedValue )
960 struct berval *nval, *assertv;
961 char *val, **values, **words, *c;
962 int i, count, len, nextchunk=0, nextavail=0;
964 /* Yes, this is necessary */
965 nval = UTF8bvnormalize( value, NULL, LDAP_UTF8_APPROX );
971 /* Yes, this is necessary */
972 assertv = UTF8bvnormalize( ((struct berval *)assertedValue),
973 NULL, LDAP_UTF8_APPROX );
974 if( assertv == NULL ) {
980 /* Isolate how many words there are */
981 for ( c = nval->bv_val, count = 1; *c; c++ ) {
982 c = strpbrk( c, SLAPD_APPROX_DELIMITER );
983 if ( c == NULL ) break;
988 /* Get a phonetic copy of each word */
989 words = (char **)ch_malloc( count * sizeof(char *) );
990 values = (char **)ch_malloc( count * sizeof(char *) );
991 for ( c = nval->bv_val, i = 0; i < count; i++, c += strlen(c) + 1 ) {
993 values[i] = phonetic(c);
996 /* Work through the asserted value's words, to see if at least some
997 of the words are there, in the same order. */
999 while ( (ber_len_t) nextchunk < assertv->bv_len ) {
1000 len = strcspn( assertv->bv_val + nextchunk, SLAPD_APPROX_DELIMITER);
1005 #if defined(SLAPD_APPROX_INITIALS)
1006 else if( len == 1 ) {
1007 /* Single letter words need to at least match one word's initial */
1008 for( i=nextavail; i<count; i++ )
1009 if( !strncasecmp( assertv->bv_val + nextchunk, words[i], 1 )) {
1016 /* Isolate the next word in the asserted value and phonetic it */
1017 assertv->bv_val[nextchunk+len] = '\0';
1018 val = phonetic( assertv->bv_val + nextchunk );
1020 /* See if this phonetic chunk is in the remaining words of *value */
1021 for( i=nextavail; i<count; i++ ){
1022 if( !strcmp( val, values[i] ) ){
1030 /* This chunk in the asserted value was NOT within the *value. */
1036 /* Go on to the next word in the asserted value */
1040 /* If some of the words were seen, call it a match */
1041 if( nextavail > 0 ) {
1048 /* Cleanup allocs */
1049 ber_bvfree( assertv );
1050 for( i=0; i<count; i++ ) {
1051 ch_free( values[i] );
1057 return LDAP_SUCCESS;
1066 struct berval *prefix,
1071 int i,j, len, wordcount, keycount=0;
1072 struct berval *newkeys;
1073 BerVarray keys=NULL;
1075 for( j=0; values[j].bv_val != NULL; j++ ) {
1076 struct berval val = { 0, NULL };
1077 /* Yes, this is necessary */
1078 UTF8bvnormalize( &values[j], &val, LDAP_UTF8_APPROX );
1079 assert( val.bv_val != NULL );
1081 /* Isolate how many words there are. There will be a key for each */
1082 for( wordcount = 0, c = val.bv_val; *c; c++) {
1083 len = strcspn(c, SLAPD_APPROX_DELIMITER);
1084 if( len >= SLAPD_APPROX_WORDLEN ) wordcount++;
1086 if (*c == '\0') break;
1090 /* Allocate/increase storage to account for new keys */
1091 newkeys = (struct berval *)ch_malloc( (keycount + wordcount + 1)
1092 * sizeof(struct berval) );
1093 AC_MEMCPY( newkeys, keys, keycount * sizeof(struct berval) );
1094 if( keys ) ch_free( keys );
1097 /* Get a phonetic copy of each word */
1098 for( c = val.bv_val, i = 0; i < wordcount; c += len + 1 ) {
1100 if( len < SLAPD_APPROX_WORDLEN ) continue;
1101 ber_str2bv( phonetic( c ), 0, 0, &keys[keycount] );
1106 ber_memfree( val.bv_val );
1108 keys[keycount].bv_val = NULL;
1111 return LDAP_SUCCESS;
1120 struct berval *prefix,
1121 void * assertedValue,
1129 /* Yes, this is necessary */
1130 val = UTF8bvnormalize( ((struct berval *)assertedValue),
1131 NULL, LDAP_UTF8_APPROX );
1132 if( val == NULL || val->bv_val == NULL ) {
1133 keys = (struct berval *)ch_malloc( sizeof(struct berval) );
1134 keys[0].bv_val = NULL;
1137 return LDAP_SUCCESS;
1140 /* Isolate how many words there are. There will be a key for each */
1141 for( count = 0,c = val->bv_val; *c; c++) {
1142 len = strcspn(c, SLAPD_APPROX_DELIMITER);
1143 if( len >= SLAPD_APPROX_WORDLEN ) count++;
1145 if (*c == '\0') break;
1149 /* Allocate storage for new keys */
1150 keys = (struct berval *)ch_malloc( (count + 1) * sizeof(struct berval) );
1152 /* Get a phonetic copy of each word */
1153 for( c = val->bv_val, i = 0; i < count; c += len + 1 ) {
1155 if( len < SLAPD_APPROX_WORDLEN ) continue;
1156 ber_str2bv( phonetic( c ), 0, 0, &keys[i] );
1162 keys[count].bv_val = NULL;
1165 return LDAP_SUCCESS;
1170 /* No other form of Approximate Matching is defined */
1178 struct berval *value,
1179 void *assertedValue )
1181 char *vapprox, *avapprox;
1184 /* Yes, this is necessary */
1185 s = UTF8normalize( value, UTF8_NOCASEFOLD );
1188 return LDAP_SUCCESS;
1191 /* Yes, this is necessary */
1192 t = UTF8normalize( ((struct berval *)assertedValue),
1197 return LDAP_SUCCESS;
1200 vapprox = phonetic( strip8bitChars( s ) );
1201 avapprox = phonetic( strip8bitChars( t ) );
1206 *matchp = strcmp( vapprox, avapprox );
1209 ch_free( avapprox );
1211 return LDAP_SUCCESS;
1220 struct berval *prefix,
1228 for( i=0; values[i].bv_val != NULL; i++ ) {
1229 /* empty - just count them */
1232 /* we should have at least one value at this point */
1235 keys = (struct berval *)ch_malloc( sizeof( struct berval ) * (i+1) );
1237 /* Copy each value and run it through phonetic() */
1238 for( i=0; values[i].bv_val != NULL; i++ ) {
1239 /* Yes, this is necessary */
1240 s = UTF8normalize( &values[i], UTF8_NOCASEFOLD );
1242 /* strip 8-bit chars and run through phonetic() */
1243 ber_str2bv( phonetic( strip8bitChars( s ) ), 0, 0, &keys[i] );
1246 keys[i].bv_val = NULL;
1249 return LDAP_SUCCESS;
1259 struct berval *prefix,
1260 void * assertedValue,
1266 keys = (struct berval *)ch_malloc( sizeof( struct berval * ) * 2 );
1268 /* Yes, this is necessary */
1269 s = UTF8normalize( ((struct berval *)assertedValue),
1274 /* strip 8-bit chars and run through phonetic() */
1275 keys[0] = ber_bvstr( phonetic( strip8bitChars( s ) ) );
1281 return LDAP_SUCCESS;
1292 struct berval *value,
1293 void *assertedValue )
1295 *matchp = UTF8bvnormcmp( value,
1296 (struct berval *) assertedValue,
1297 LDAP_UTF8_NOCASEFOLD );
1298 return LDAP_SUCCESS;
1302 caseExactIgnoreSubstringsMatch(
1307 struct berval *value,
1308 void *assertedValue )
1311 SubstringsAssertion *sub = NULL;
1312 struct berval left = { 0, NULL };
1318 casefold = ( mr != slap_schema.si_mr_caseExactSubstringsMatch )
1319 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1321 if ( UTF8bvnormalize( value, &left, casefold ) == NULL ) {
1327 sub = UTF8SubstringsAssertionNormalize( assertedValue, casefold );
1333 /* Add up asserted input length */
1334 if( sub->sa_initial.bv_val ) {
1335 inlen += sub->sa_initial.bv_len;
1338 for(i=0; sub->sa_any[i].bv_val != NULL; i++) {
1339 inlen += sub->sa_any[i].bv_len;
1342 if( sub->sa_final.bv_val ) {
1343 inlen += sub->sa_final.bv_len;
1346 if( sub->sa_initial.bv_val ) {
1347 if( inlen > left.bv_len ) {
1352 match = memcmp( sub->sa_initial.bv_val, left.bv_val,
1353 sub->sa_initial.bv_len );
1359 left.bv_val += sub->sa_initial.bv_len;
1360 left.bv_len -= sub->sa_initial.bv_len;
1361 inlen -= sub->sa_initial.bv_len;
1364 if( sub->sa_final.bv_val ) {
1365 if( inlen > left.bv_len ) {
1370 match = memcmp( sub->sa_final.bv_val,
1371 &left.bv_val[left.bv_len - sub->sa_final.bv_len],
1372 sub->sa_final.bv_len );
1378 left.bv_len -= sub->sa_final.bv_len;
1379 inlen -= sub->sa_final.bv_len;
1383 for(i=0; sub->sa_any[i].bv_val; i++) {
1388 if( inlen > left.bv_len ) {
1389 /* not enough length */
1394 if( sub->sa_any[i].bv_len == 0 ) {
1398 p = ber_bvchr( &left, *sub->sa_any[i].bv_val );
1404 idx = p - left.bv_val;
1406 if( idx >= left.bv_len ) {
1407 /* this shouldn't happen */
1409 if ( sub->sa_final.bv_val )
1410 ch_free( sub->sa_final.bv_val );
1412 ber_bvarray_free( sub->sa_any );
1413 if ( sub->sa_initial.bv_val )
1414 ch_free( sub->sa_initial.bv_val );
1422 if( sub->sa_any[i].bv_len > left.bv_len ) {
1423 /* not enough left */
1428 match = memcmp( left.bv_val,
1429 sub->sa_any[i].bv_val,
1430 sub->sa_any[i].bv_len );
1438 left.bv_val += sub->sa_any[i].bv_len;
1439 left.bv_len -= sub->sa_any[i].bv_len;
1440 inlen -= sub->sa_any[i].bv_len;
1447 if ( sub->sa_final.bv_val ) free( sub->sa_final.bv_val );
1448 if ( sub->sa_any ) ber_bvarray_free( sub->sa_any );
1449 if ( sub->sa_initial.bv_val ) free( sub->sa_initial.bv_val );
1453 return LDAP_SUCCESS;
1456 /* Index generation function */
1457 static int caseExactIgnoreIndexer(
1462 struct berval *prefix,
1467 unsigned casefold,wasspace;
1470 HASH_CONTEXT HASHcontext;
1471 unsigned char HASHdigest[HASH_BYTES];
1472 struct berval digest;
1473 digest.bv_val = HASHdigest;
1474 digest.bv_len = sizeof(HASHdigest);
1476 for( i=0; values[i].bv_val != NULL; i++ ) {
1477 /* empty - just count them */
1480 /* we should have at least one value at this point */
1483 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
1485 slen = syntax->ssyn_oidlen;
1486 mlen = mr->smr_oidlen;
1488 casefold = ( mr != slap_schema.si_mr_caseExactMatch )
1489 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1491 for( i=0; values[i].bv_val != NULL; i++ ) {
1492 struct berval value, nvalue;
1493 UTF8bvnormalize( &values[i], &value, casefold );
1495 /* collapse spaces (in place) */
1497 nvalue.bv_val = value.bv_val;
1500 for( j=0; j<value.bv_len; j++) {
1501 if ( ASCII_SPACE( value.bv_val[j] )) {
1502 if( wasspace++ == 0 ) {
1503 nvalue.bv_val[nvalue.bv_len++] = value.bv_val[j];
1507 nvalue.bv_val[nvalue.bv_len++] = value.bv_val[j];
1511 if( nvalue.bv_len == 0 ) {
1512 nvalue.bv_val = " ";
1513 nvalue.bv_len = sizeof(" ")-1;
1515 if( wasspace ) --nvalue.bv_len;
1516 nvalue.bv_val[nvalue.bv_len] = '\0';
1519 HASH_Init( &HASHcontext );
1520 if( prefix != NULL && prefix->bv_len > 0 ) {
1521 HASH_Update( &HASHcontext,
1522 prefix->bv_val, prefix->bv_len );
1524 HASH_Update( &HASHcontext,
1525 syntax->ssyn_oid, slen );
1526 HASH_Update( &HASHcontext,
1527 mr->smr_oid, mlen );
1528 HASH_Update( &HASHcontext,
1529 nvalue.bv_val, nvalue.bv_len );
1530 HASH_Final( HASHdigest, &HASHcontext );
1532 free( value.bv_val );
1533 ber_dupbv( &keys[i], &digest );
1536 keys[i].bv_val = NULL;
1538 return LDAP_SUCCESS;
1541 /* Index generation function */
1542 static int caseExactIgnoreFilter(
1547 struct berval *prefix,
1548 void * assertedValue,
1554 HASH_CONTEXT HASHcontext;
1555 unsigned char HASHdigest[HASH_BYTES];
1556 struct berval value = { 0, NULL };
1557 struct berval digest;
1559 digest.bv_val = HASHdigest;
1560 digest.bv_len = sizeof(HASHdigest);
1562 slen = syntax->ssyn_oidlen;
1563 mlen = mr->smr_oidlen;
1565 casefold = ( mr != slap_schema.si_mr_caseExactMatch )
1566 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1568 UTF8bvnormalize( (struct berval *) assertedValue, &value, casefold );
1569 /* This usually happens if filter contains bad UTF8 */
1570 if( value.bv_val == NULL ) {
1571 keys = ch_malloc( sizeof( struct berval ) );
1572 keys[0].bv_val = NULL;
1573 return LDAP_SUCCESS;
1576 keys = ch_malloc( sizeof( struct berval ) * 2 );
1578 HASH_Init( &HASHcontext );
1579 if( prefix != NULL && prefix->bv_len > 0 ) {
1580 HASH_Update( &HASHcontext,
1581 prefix->bv_val, prefix->bv_len );
1583 HASH_Update( &HASHcontext,
1584 syntax->ssyn_oid, slen );
1585 HASH_Update( &HASHcontext,
1586 mr->smr_oid, mlen );
1587 HASH_Update( &HASHcontext,
1588 value.bv_val, value.bv_len );
1589 HASH_Final( HASHdigest, &HASHcontext );
1591 ber_dupbv( keys, &digest );
1592 keys[1].bv_val = NULL;
1594 free( value.bv_val );
1597 return LDAP_SUCCESS;
1601 /* Substrings Index generation function */
1604 octetStringSubstringsIndexer
1606 caseExactIgnoreSubstringsIndexer
1612 struct berval *prefix,
1616 ber_len_t i, j, nkeys;
1619 #ifndef SLAP_NVALUES
1620 BerVarray tvalues, nvalues;
1621 unsigned casefold, wasspace;
1624 HASH_CONTEXT HASHcontext;
1625 unsigned char HASHdigest[HASH_BYTES];
1626 struct berval digest;
1627 digest.bv_val = HASHdigest;
1628 digest.bv_len = sizeof(HASHdigest);
1630 #ifndef SLAP_NVALUES
1631 for( i=0; values[i].bv_val != NULL; i++ ) {
1632 /* empty - just count them */
1635 /* we should have at least one value at this point */
1638 casefold = ( mr != slap_schema.si_mr_caseExactSubstringsMatch )
1639 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1641 tvalues = ch_malloc( sizeof( struct berval ) * (i+1) );
1642 nvalues = ch_malloc( sizeof( struct berval ) * (i+1) );
1644 for( i=0; values[i].bv_val != NULL; i++ ) {
1645 UTF8bvnormalize( &values[i], &tvalues[i], casefold );
1647 /* collapse spaces (in place) */
1648 nvalues[i].bv_len = 0;
1649 nvalues[i].bv_val = tvalues[i].bv_val;
1652 for( j=0; j<tvalues[i].bv_len; j++) {
1653 if ( ASCII_SPACE( tvalues[i].bv_val[j] )) {
1654 if( wasspace++ == 0 ) {
1655 nvalues[i].bv_val[nvalues[i].bv_len++] =
1656 tvalues[i].bv_val[j];
1660 nvalues[i].bv_val[nvalues[i].bv_len++] = tvalues[i].bv_val[j];
1664 if( nvalues[i].bv_len == 0 ) {
1665 nvalues[i].bv_val = " ";
1666 nvalues[i].bv_len = sizeof(" ")-1;
1668 if( wasspace ) --nvalues[i].bv_len;
1669 nvalues[i].bv_val[nvalues[i].bv_len] = '\0';
1673 tvalues[i].bv_val = NULL;
1674 nvalues[i].bv_val = NULL;
1680 for( i=0; values[i].bv_val != NULL; i++ ) {
1681 /* count number of indices to generate */
1682 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
1686 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
1687 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1688 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
1689 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
1691 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
1695 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
1696 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1697 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
1701 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
1702 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1703 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
1704 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
1706 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
1712 /* no keys to generate */
1714 #ifndef SLAP_NVALUES
1715 ber_bvarray_free( tvalues );
1718 return LDAP_SUCCESS;
1721 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
1723 slen = syntax->ssyn_oidlen;
1724 mlen = mr->smr_oidlen;
1727 for( i=0; values[i].bv_val != NULL; i++ ) {
1730 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
1732 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
1733 ( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
1735 char pre = SLAP_INDEX_SUBSTR_PREFIX;
1736 max = values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
1738 for( j=0; j<max; j++ ) {
1739 HASH_Init( &HASHcontext );
1740 if( prefix != NULL && prefix->bv_len > 0 ) {
1741 HASH_Update( &HASHcontext,
1742 prefix->bv_val, prefix->bv_len );
1745 HASH_Update( &HASHcontext,
1746 &pre, sizeof( pre ) );
1747 HASH_Update( &HASHcontext,
1748 syntax->ssyn_oid, slen );
1749 HASH_Update( &HASHcontext,
1750 mr->smr_oid, mlen );
1751 HASH_Update( &HASHcontext,
1752 &values[i].bv_val[j],
1753 SLAP_INDEX_SUBSTR_MAXLEN );
1754 HASH_Final( HASHdigest, &HASHcontext );
1756 ber_dupbv( &keys[nkeys++], &digest );
1760 max = SLAP_INDEX_SUBSTR_MAXLEN < values[i].bv_len
1761 ? SLAP_INDEX_SUBSTR_MAXLEN : values[i].bv_len;
1763 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
1766 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
1767 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
1768 HASH_Init( &HASHcontext );
1769 if( prefix != NULL && prefix->bv_len > 0 ) {
1770 HASH_Update( &HASHcontext,
1771 prefix->bv_val, prefix->bv_len );
1773 HASH_Update( &HASHcontext,
1774 &pre, sizeof( pre ) );
1775 HASH_Update( &HASHcontext,
1776 syntax->ssyn_oid, slen );
1777 HASH_Update( &HASHcontext,
1778 mr->smr_oid, mlen );
1779 HASH_Update( &HASHcontext,
1780 values[i].bv_val, j );
1781 HASH_Final( HASHdigest, &HASHcontext );
1783 ber_dupbv( &keys[nkeys++], &digest );
1786 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
1787 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
1788 HASH_Init( &HASHcontext );
1789 if( prefix != NULL && prefix->bv_len > 0 ) {
1790 HASH_Update( &HASHcontext,
1791 prefix->bv_val, prefix->bv_len );
1793 HASH_Update( &HASHcontext,
1794 &pre, sizeof( pre ) );
1795 HASH_Update( &HASHcontext,
1796 syntax->ssyn_oid, slen );
1797 HASH_Update( &HASHcontext,
1798 mr->smr_oid, mlen );
1799 HASH_Update( &HASHcontext,
1800 &values[i].bv_val[values[i].bv_len-j], j );
1801 HASH_Final( HASHdigest, &HASHcontext );
1803 ber_dupbv( &keys[nkeys++], &digest );
1811 keys[nkeys].bv_val = NULL;
1818 #ifndef SLAP_NVALUES
1819 ber_bvarray_free( tvalues );
1823 return LDAP_SUCCESS;
1828 octetStringSubstringsFilter
1830 caseExactIgnoreSubstringsFilter
1836 struct berval *prefix,
1837 void * assertedValue,
1840 SubstringsAssertion *sa;
1843 ber_len_t nkeys = 0;
1844 size_t slen, mlen, klen;
1846 HASH_CONTEXT HASHcontext;
1847 unsigned char HASHdigest[HASH_BYTES];
1848 struct berval *value;
1849 struct berval digest;
1851 #ifndef SLAP_NVALUES
1852 casefold = ( mr != slap_schema.si_mr_caseExactSubstringsMatch )
1853 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1855 sa = UTF8SubstringsAssertionNormalize( assertedValue, casefold );
1858 return LDAP_SUCCESS;
1861 sa = (SubstringsAssertion *) assertedValue;
1864 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
1865 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1870 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
1872 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
1873 if( sa->sa_any[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1874 /* don't bother accounting for stepping */
1875 nkeys += sa->sa_any[i].bv_len -
1876 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
1881 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
1882 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1888 #ifndef SLAP_NVALUES
1889 if ( sa->sa_final.bv_val ) free( sa->sa_final.bv_val );
1890 if ( sa->sa_any ) ber_bvarray_free( sa->sa_any );
1891 if ( sa->sa_initial.bv_val ) free( sa->sa_initial.bv_val );
1895 return LDAP_SUCCESS;
1898 digest.bv_val = HASHdigest;
1899 digest.bv_len = sizeof(HASHdigest);
1901 slen = syntax->ssyn_oidlen;
1902 mlen = mr->smr_oidlen;
1904 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
1907 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
1908 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1910 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
1911 value = &sa->sa_initial;
1913 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
1914 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
1916 HASH_Init( &HASHcontext );
1917 if( prefix != NULL && prefix->bv_len > 0 ) {
1918 HASH_Update( &HASHcontext,
1919 prefix->bv_val, prefix->bv_len );
1921 HASH_Update( &HASHcontext,
1922 &pre, sizeof( pre ) );
1923 HASH_Update( &HASHcontext,
1924 syntax->ssyn_oid, slen );
1925 HASH_Update( &HASHcontext,
1926 mr->smr_oid, mlen );
1927 HASH_Update( &HASHcontext,
1928 value->bv_val, klen );
1929 HASH_Final( HASHdigest, &HASHcontext );
1931 ber_dupbv( &keys[nkeys++], &digest );
1934 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
1936 pre = SLAP_INDEX_SUBSTR_PREFIX;
1937 klen = SLAP_INDEX_SUBSTR_MAXLEN;
1939 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
1940 if( sa->sa_any[i].bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
1944 value = &sa->sa_any[i];
1947 j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
1948 j += SLAP_INDEX_SUBSTR_STEP )
1950 HASH_Init( &HASHcontext );
1951 if( prefix != NULL && prefix->bv_len > 0 ) {
1952 HASH_Update( &HASHcontext,
1953 prefix->bv_val, prefix->bv_len );
1955 HASH_Update( &HASHcontext,
1956 &pre, sizeof( pre ) );
1957 HASH_Update( &HASHcontext,
1958 syntax->ssyn_oid, slen );
1959 HASH_Update( &HASHcontext,
1960 mr->smr_oid, mlen );
1961 HASH_Update( &HASHcontext,
1962 &value->bv_val[j], klen );
1963 HASH_Final( HASHdigest, &HASHcontext );
1965 ber_dupbv( &keys[nkeys++], &digest );
1971 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
1972 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1974 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
1975 value = &sa->sa_final;
1977 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
1978 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
1980 HASH_Init( &HASHcontext );
1981 if( prefix != NULL && prefix->bv_len > 0 ) {
1982 HASH_Update( &HASHcontext,
1983 prefix->bv_val, prefix->bv_len );
1985 HASH_Update( &HASHcontext,
1986 &pre, sizeof( pre ) );
1987 HASH_Update( &HASHcontext,
1988 syntax->ssyn_oid, slen );
1989 HASH_Update( &HASHcontext,
1990 mr->smr_oid, mlen );
1991 HASH_Update( &HASHcontext,
1992 &value->bv_val[value->bv_len-klen], klen );
1993 HASH_Final( HASHdigest, &HASHcontext );
1995 ber_dupbv( &keys[nkeys++], &digest );
1999 keys[nkeys].bv_val = NULL;
2006 #ifndef SLAP_NVALUES
2007 if ( sa->sa_final.bv_val ) free( sa->sa_final.bv_val );
2008 if ( sa->sa_any ) ber_bvarray_free( sa->sa_any );
2009 if ( sa->sa_initial.bv_val ) free( sa->sa_initial.bv_val );
2013 return LDAP_SUCCESS;
2016 #ifndef SLAP_NVALUES
2024 struct berval *value,
2025 void *assertedValue )
2027 *matchp = UTF8bvnormcmp( value,
2028 (struct berval *) assertedValue,
2029 LDAP_UTF8_CASEFOLD );
2030 return LDAP_SUCCESS;
2033 /* Remove all spaces and '-' characters */
2035 xtelephoneNumberNormalize(
2038 struct berval *normalized )
2042 /* validator should have refused an empty string */
2043 assert( val->bv_len );
2045 q = normalized->bv_val = ch_malloc( val->bv_len + 1 );
2047 for( p = val->bv_val; *p; p++ ) {
2048 if ( ! ( ASCII_SPACE( *p ) || *p == '-' )) {
2054 normalized->bv_len = q - normalized->bv_val;
2056 if( normalized->bv_len == 0 ) {
2057 free( normalized->bv_val );
2058 return LDAP_INVALID_SYNTAX;
2061 return LDAP_SUCCESS;
2068 struct berval *val )
2072 if( val->bv_len == 0 ) {
2073 /* disallow empty strings */
2074 return LDAP_INVALID_SYNTAX;
2077 if( OID_LEADCHAR(val->bv_val[0]) ) {
2079 for(i=1; i < val->bv_len; i++) {
2080 if( OID_SEPARATOR( val->bv_val[i] ) ) {
2081 if( dot++ ) return 1;
2082 } else if ( OID_CHAR( val->bv_val[i] ) ) {
2085 return LDAP_INVALID_SYNTAX;
2089 return !dot ? LDAP_SUCCESS : LDAP_INVALID_SYNTAX;
2091 } else if( DESC_LEADCHAR(val->bv_val[0]) ) {
2092 for(i=1; i < val->bv_len; i++) {
2093 if( !DESC_CHAR(val->bv_val[i] ) ) {
2094 return LDAP_INVALID_SYNTAX;
2098 return LDAP_SUCCESS;
2101 return LDAP_INVALID_SYNTAX;
2104 #ifndef SLAP_NVALUES
2112 struct berval *value,
2113 void *assertedValue )
2116 int vsign = 1, avsign = 1; /* default sign = '+' */
2117 struct berval *asserted;
2118 ber_len_t vlen, avlen;
2121 /* Skip leading space/sign/zeroes, and get the sign of the *value number */
2123 vlen = value->bv_len;
2124 if( mr == slap_schema.si_mr_integerFirstComponentMatch ) {
2125 char *tmp = memchr( v, '$', vlen );
2128 while( vlen && ASCII_SPACE( v[vlen-1] ))
2131 for( ; vlen && ( *v < '1' || '9' < *v ); v++, vlen-- ) /* ANSI 2.2.1 */
2137 /* Do the same with the *assertedValue number */
2138 asserted = (struct berval *) assertedValue;
2139 av = asserted->bv_val;
2140 avlen = asserted->bv_len;
2141 for( ; avlen && ( *av < '1' || '9' < *av ); av++, avlen-- )
2147 match = vsign - avsign;
2149 match = (vlen != avlen
2150 ? ( vlen < avlen ? -1 : 1 )
2151 : memcmp( v, av, vlen ));
2157 return LDAP_SUCCESS;
2164 struct berval *val )
2168 if( !val->bv_len ) return LDAP_INVALID_SYNTAX;
2170 if(( val->bv_val[0] == '+' ) || ( val->bv_val[0] == '-' )) {
2171 if( val->bv_len < 2 ) return LDAP_INVALID_SYNTAX;
2172 } else if( !ASCII_DIGIT(val->bv_val[0]) ) {
2173 return LDAP_INVALID_SYNTAX;
2176 for( i=1; i < val->bv_len; i++ ) {
2177 if( !ASCII_DIGIT(val->bv_val[i]) ) return LDAP_INVALID_SYNTAX;
2180 return LDAP_SUCCESS;
2183 #ifndef SLAP_NVALUES
2188 struct berval *normalized )
2198 /* Ignore leading spaces */
2199 while ( len && ( *p == ' ' )) {
2206 negative = ( *p == '-' );
2207 if(( *p == '-' ) || ( *p == '+' )) {
2213 /* Ignore leading zeros */
2214 while ( len && ( *p == '0' )) {
2219 /* If there are no non-zero digits left, the number is zero, otherwise
2220 allocate space for the number and copy it into the buffer */
2222 normalized->bv_val = ch_strdup("0");
2223 normalized->bv_len = 1;
2226 normalized->bv_len = len+negative;
2227 normalized->bv_val = ch_malloc( normalized->bv_len + 1 );
2229 normalized->bv_val[0] = '-';
2231 AC_MEMCPY( normalized->bv_val + negative, p, len );
2232 normalized->bv_val[len+negative] = '\0';
2235 return LDAP_SUCCESS;
2238 /* Index generation function */
2239 static int integerIndexer(
2244 struct berval *prefix,
2251 HASH_CONTEXT HASHcontext;
2252 unsigned char HASHdigest[HASH_BYTES];
2253 struct berval digest;
2254 digest.bv_val = HASHdigest;
2255 digest.bv_len = sizeof(HASHdigest);
2257 for( i=0; values[i].bv_val != NULL; i++ ) {
2258 /* empty - just count them */
2261 /* we should have at least one value at this point */
2264 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
2266 slen = syntax->ssyn_oidlen;
2267 mlen = mr->smr_oidlen;
2269 for( i=0; values[i].bv_val != NULL; i++ ) {
2271 xintegerNormalize( syntax, &values[i], &norm );
2273 HASH_Init( &HASHcontext );
2274 if( prefix != NULL && prefix->bv_len > 0 ) {
2275 HASH_Update( &HASHcontext,
2276 prefix->bv_val, prefix->bv_len );
2278 HASH_Update( &HASHcontext,
2279 syntax->ssyn_oid, slen );
2280 HASH_Update( &HASHcontext,
2281 mr->smr_oid, mlen );
2282 HASH_Update( &HASHcontext,
2283 norm.bv_val, norm.bv_len );
2284 HASH_Final( HASHdigest, &HASHcontext );
2286 ber_dupbv( &keys[i], &digest );
2287 ch_free( norm.bv_val );
2290 keys[i].bv_val = NULL;
2292 return LDAP_SUCCESS;
2295 /* Index generation function */
2296 static int integerFilter(
2301 struct berval *prefix,
2302 void * assertedValue,
2307 HASH_CONTEXT HASHcontext;
2308 unsigned char HASHdigest[HASH_BYTES];
2310 struct berval digest;
2311 digest.bv_val = HASHdigest;
2312 digest.bv_len = sizeof(HASHdigest);
2314 slen = syntax->ssyn_oidlen;
2315 mlen = mr->smr_oidlen;
2317 xintegerNormalize( syntax, assertedValue, &norm );
2319 keys = ch_malloc( sizeof( struct berval ) * 2 );
2321 HASH_Init( &HASHcontext );
2322 if( prefix != NULL && prefix->bv_len > 0 ) {
2323 HASH_Update( &HASHcontext,
2324 prefix->bv_val, prefix->bv_len );
2326 HASH_Update( &HASHcontext,
2327 syntax->ssyn_oid, slen );
2328 HASH_Update( &HASHcontext,
2329 mr->smr_oid, mlen );
2330 HASH_Update( &HASHcontext,
2331 norm.bv_val, norm.bv_len );
2332 HASH_Final( HASHdigest, &HASHcontext );
2334 ber_dupbv( &keys[0], &digest );
2335 keys[1].bv_val = NULL;
2336 ch_free( norm.bv_val );
2339 return LDAP_SUCCESS;
2345 countryStringValidate(
2347 struct berval *val )
2349 if( val->bv_len != 2 ) return LDAP_INVALID_SYNTAX;
2351 if( !SLAP_PRINTABLE(val->bv_val[0]) ) {
2352 return LDAP_INVALID_SYNTAX;
2354 if( !SLAP_PRINTABLE(val->bv_val[1]) ) {
2355 return LDAP_INVALID_SYNTAX;
2358 return LDAP_SUCCESS;
2362 printableStringValidate(
2364 struct berval *val )
2368 if( val->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
2370 for(i=0; i < val->bv_len; i++) {
2371 if( !SLAP_PRINTABLE(val->bv_val[i]) ) {
2372 return LDAP_INVALID_SYNTAX;
2376 return LDAP_SUCCESS;
2380 printablesStringValidate(
2382 struct berval *val )
2386 if( val->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
2388 for(i=0,len=0; i < val->bv_len; i++) {
2389 int c = val->bv_val[i];
2393 return LDAP_INVALID_SYNTAX;
2397 } else if ( SLAP_PRINTABLE(c) ) {
2400 return LDAP_INVALID_SYNTAX;
2405 return LDAP_INVALID_SYNTAX;
2408 return LDAP_SUCCESS;
2414 struct berval *val )
2418 if( val->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
2420 for(i=0; i < val->bv_len; i++) {
2421 if( !LDAP_ASCII(val->bv_val[i]) ) {
2422 return LDAP_INVALID_SYNTAX;
2426 return LDAP_SUCCESS;
2436 struct berval *normalized )
2439 xIA5StringNormalize(
2442 struct berval *normalized )
2447 int casefold = !SLAP_MR_ASSOCIATED(mr, slap_schema.si_mr_caseExactIA5Match);
2450 assert( val->bv_len );
2454 /* Ignore initial whitespace */
2455 while ( ASCII_SPACE( *p ) ) {
2459 normalized->bv_val = ch_strdup( p );
2460 p = q = normalized->bv_val;
2463 if ( ASCII_SPACE( *p ) ) {
2466 /* Ignore the extra whitespace */
2467 while ( ASCII_SPACE( *p ) ) {
2472 } else if ( casefold ) {
2473 /* Most IA5 rules require casefolding */
2474 *q++ = TOLOWER(*p++);
2482 assert( normalized->bv_val <= p );
2486 * If the string ended in space, backup the pointer one
2487 * position. One is enough because the above loop collapsed
2488 * all whitespace to a single space.
2491 if ( ASCII_SPACE( q[-1] ) ) {
2495 /* null terminate */
2498 normalized->bv_len = q - normalized->bv_val;
2500 if( normalized->bv_len == 0 ) {
2501 normalized->bv_val = ch_realloc( normalized->bv_val, 2 );
2502 normalized->bv_val[0] = ' ';
2503 normalized->bv_val[1] = '\0';
2504 normalized->bv_len = 1;
2507 return LDAP_SUCCESS;
2510 #ifndef SLAP_NVALUES
2518 struct berval *value,
2519 void *assertedValue )
2521 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
2524 match = strncmp( value->bv_val,
2525 ((struct berval *) assertedValue)->bv_val,
2530 return LDAP_SUCCESS;
2534 caseExactIA5SubstringsMatch
2537 octetStringSubstringsMatch
2544 struct berval *value,
2545 void *assertedValue )
2548 SubstringsAssertion *sub = assertedValue;
2549 struct berval left = *value;
2553 /* Add up asserted input length */
2554 if( sub->sa_initial.bv_val ) {
2555 inlen += sub->sa_initial.bv_len;
2558 for(i=0; sub->sa_any[i].bv_val != NULL; i++) {
2559 inlen += sub->sa_any[i].bv_len;
2562 if( sub->sa_final.bv_val ) {
2563 inlen += sub->sa_final.bv_len;
2566 if( sub->sa_initial.bv_val ) {
2567 if( inlen > left.bv_len ) {
2572 match = memcmp( sub->sa_initial.bv_val, left.bv_val,
2573 sub->sa_initial.bv_len );
2579 left.bv_val += sub->sa_initial.bv_len;
2580 left.bv_len -= sub->sa_initial.bv_len;
2581 inlen -= sub->sa_initial.bv_len;
2584 if( sub->sa_final.bv_val ) {
2585 if( inlen > left.bv_len ) {
2590 match = memcmp( sub->sa_final.bv_val,
2591 &left.bv_val[left.bv_len - sub->sa_final.bv_len],
2592 sub->sa_final.bv_len );
2598 left.bv_len -= sub->sa_final.bv_len;
2599 inlen -= sub->sa_final.bv_len;
2603 for(i=0; sub->sa_any[i].bv_val; i++) {
2608 if( inlen > left.bv_len ) {
2609 /* not enough length */
2614 if( sub->sa_any[i].bv_len == 0 ) {
2618 p = memchr( left.bv_val, *sub->sa_any[i].bv_val, left.bv_len );
2625 idx = p - left.bv_val;
2627 if( idx >= left.bv_len ) {
2628 /* this shouldn't happen */
2635 if( sub->sa_any[i].bv_len > left.bv_len ) {
2636 /* not enough left */
2641 match = memcmp( left.bv_val,
2642 sub->sa_any[i].bv_val,
2643 sub->sa_any[i].bv_len );
2651 left.bv_val += sub->sa_any[i].bv_len;
2652 left.bv_len -= sub->sa_any[i].bv_len;
2653 inlen -= sub->sa_any[i].bv_len;
2659 return LDAP_SUCCESS;
2662 #ifndef SLAP_NVALUES
2664 /* Index generation function */
2665 static int caseExactIA5Indexer(
2670 struct berval *prefix,
2677 HASH_CONTEXT HASHcontext;
2678 unsigned char HASHdigest[HASH_BYTES];
2679 struct berval digest;
2680 digest.bv_val = HASHdigest;
2681 digest.bv_len = sizeof(HASHdigest);
2683 for( i=0; values[i].bv_val != NULL; i++ ) {
2684 /* empty - just count them */
2687 /* we should have at least one value at this point */
2690 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
2692 slen = syntax->ssyn_oidlen;
2693 mlen = mr->smr_oidlen;
2695 for( i=0; values[i].bv_val != NULL; i++ ) {
2696 struct berval *value = &values[i];
2698 HASH_Init( &HASHcontext );
2699 if( prefix != NULL && prefix->bv_len > 0 ) {
2700 HASH_Update( &HASHcontext,
2701 prefix->bv_val, prefix->bv_len );
2703 HASH_Update( &HASHcontext,
2704 syntax->ssyn_oid, slen );
2705 HASH_Update( &HASHcontext,
2706 mr->smr_oid, mlen );
2707 HASH_Update( &HASHcontext,
2708 value->bv_val, value->bv_len );
2709 HASH_Final( HASHdigest, &HASHcontext );
2711 ber_dupbv( &keys[i], &digest );
2714 keys[i].bv_val = NULL;
2716 return LDAP_SUCCESS;
2719 /* Index generation function */
2720 static int caseExactIA5Filter(
2725 struct berval *prefix,
2726 void * assertedValue,
2731 HASH_CONTEXT HASHcontext;
2732 unsigned char HASHdigest[HASH_BYTES];
2733 struct berval *value;
2734 struct berval digest;
2735 digest.bv_val = HASHdigest;
2736 digest.bv_len = sizeof(HASHdigest);
2738 slen = syntax->ssyn_oidlen;
2739 mlen = mr->smr_oidlen;
2741 value = (struct berval *) assertedValue;
2743 keys = ch_malloc( sizeof( struct berval ) * 2 );
2745 HASH_Init( &HASHcontext );
2746 if( prefix != NULL && prefix->bv_len > 0 ) {
2747 HASH_Update( &HASHcontext,
2748 prefix->bv_val, prefix->bv_len );
2750 HASH_Update( &HASHcontext,
2751 syntax->ssyn_oid, slen );
2752 HASH_Update( &HASHcontext,
2753 mr->smr_oid, mlen );
2754 HASH_Update( &HASHcontext,
2755 value->bv_val, value->bv_len );
2756 HASH_Final( HASHdigest, &HASHcontext );
2758 ber_dupbv( &keys[0], &digest );
2759 keys[1].bv_val = NULL;
2762 return LDAP_SUCCESS;
2765 /* Substrings Index generation function */
2766 static int caseExactIA5SubstringsIndexer(
2771 struct berval *prefix,
2778 HASH_CONTEXT HASHcontext;
2779 unsigned char HASHdigest[HASH_BYTES];
2780 struct berval digest;
2781 digest.bv_val = HASHdigest;
2782 digest.bv_len = sizeof(HASHdigest);
2784 /* we should have at least one value at this point */
2785 assert( values != NULL && values[0].bv_val != NULL );
2788 for( i=0; values[i].bv_val != NULL; i++ ) {
2789 /* count number of indices to generate */
2790 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
2794 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
2795 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2796 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2797 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2799 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2803 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
2804 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2805 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
2809 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
2810 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2811 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2812 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2814 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2820 /* no keys to generate */
2822 return LDAP_SUCCESS;
2825 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
2827 slen = syntax->ssyn_oidlen;
2828 mlen = mr->smr_oidlen;
2831 for( i=0; values[i].bv_val != NULL; i++ ) {
2833 struct berval *value;
2836 if( value->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
2838 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
2839 ( value->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
2841 char pre = SLAP_INDEX_SUBSTR_PREFIX;
2842 max = value->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
2844 for( j=0; j<max; j++ ) {
2845 HASH_Init( &HASHcontext );
2846 if( prefix != NULL && prefix->bv_len > 0 ) {
2847 HASH_Update( &HASHcontext,
2848 prefix->bv_val, prefix->bv_len );
2851 HASH_Update( &HASHcontext,
2852 &pre, sizeof( pre ) );
2853 HASH_Update( &HASHcontext,
2854 syntax->ssyn_oid, slen );
2855 HASH_Update( &HASHcontext,
2856 mr->smr_oid, mlen );
2857 HASH_Update( &HASHcontext,
2859 SLAP_INDEX_SUBSTR_MAXLEN );
2860 HASH_Final( HASHdigest, &HASHcontext );
2862 ber_dupbv( &keys[nkeys++], &digest );
2866 max = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2867 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2869 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
2872 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
2873 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
2874 HASH_Init( &HASHcontext );
2875 if( prefix != NULL && prefix->bv_len > 0 ) {
2876 HASH_Update( &HASHcontext,
2877 prefix->bv_val, prefix->bv_len );
2879 HASH_Update( &HASHcontext,
2880 &pre, sizeof( pre ) );
2881 HASH_Update( &HASHcontext,
2882 syntax->ssyn_oid, slen );
2883 HASH_Update( &HASHcontext,
2884 mr->smr_oid, mlen );
2885 HASH_Update( &HASHcontext,
2887 HASH_Final( HASHdigest, &HASHcontext );
2889 ber_dupbv( &keys[nkeys++], &digest );
2892 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
2893 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
2894 HASH_Init( &HASHcontext );
2895 if( prefix != NULL && prefix->bv_len > 0 ) {
2896 HASH_Update( &HASHcontext,
2897 prefix->bv_val, prefix->bv_len );
2899 HASH_Update( &HASHcontext,
2900 &pre, sizeof( pre ) );
2901 HASH_Update( &HASHcontext,
2902 syntax->ssyn_oid, slen );
2903 HASH_Update( &HASHcontext,
2904 mr->smr_oid, mlen );
2905 HASH_Update( &HASHcontext,
2906 &value->bv_val[value->bv_len-j], j );
2907 HASH_Final( HASHdigest, &HASHcontext );
2909 ber_dupbv( &keys[nkeys++], &digest );
2916 keys[nkeys].bv_val = NULL;
2923 return LDAP_SUCCESS;
2926 static int caseExactIA5SubstringsFilter(
2931 struct berval *prefix,
2932 void * assertedValue,
2935 SubstringsAssertion *sa = assertedValue;
2937 ber_len_t nkeys = 0;
2938 size_t slen, mlen, klen;
2940 HASH_CONTEXT HASHcontext;
2941 unsigned char HASHdigest[HASH_BYTES];
2942 struct berval *value;
2943 struct berval digest;
2945 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
2946 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2951 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
2953 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
2954 if( sa->sa_any[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2955 /* don't bother accounting for stepping */
2956 nkeys += sa->sa_any[i].bv_len -
2957 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
2962 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
2963 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2970 return LDAP_SUCCESS;
2973 digest.bv_val = HASHdigest;
2974 digest.bv_len = sizeof(HASHdigest);
2976 slen = syntax->ssyn_oidlen;
2977 mlen = mr->smr_oidlen;
2979 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
2982 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
2983 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2985 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
2986 value = &sa->sa_initial;
2988 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2989 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2991 HASH_Init( &HASHcontext );
2992 if( prefix != NULL && prefix->bv_len > 0 ) {
2993 HASH_Update( &HASHcontext,
2994 prefix->bv_val, prefix->bv_len );
2996 HASH_Update( &HASHcontext,
2997 &pre, sizeof( pre ) );
2998 HASH_Update( &HASHcontext,
2999 syntax->ssyn_oid, slen );
3000 HASH_Update( &HASHcontext,
3001 mr->smr_oid, mlen );
3002 HASH_Update( &HASHcontext,
3003 value->bv_val, klen );
3004 HASH_Final( HASHdigest, &HASHcontext );
3006 ber_dupbv( &keys[nkeys++], &digest );
3009 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
3011 pre = SLAP_INDEX_SUBSTR_PREFIX;
3012 klen = SLAP_INDEX_SUBSTR_MAXLEN;
3014 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
3015 if( sa->sa_any[i].bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
3019 value = &sa->sa_any[i];
3022 j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
3023 j += SLAP_INDEX_SUBSTR_STEP )
3025 HASH_Init( &HASHcontext );
3026 if( prefix != NULL && prefix->bv_len > 0 ) {
3027 HASH_Update( &HASHcontext,
3028 prefix->bv_val, prefix->bv_len );
3030 HASH_Update( &HASHcontext,
3031 &pre, sizeof( pre ) );
3032 HASH_Update( &HASHcontext,
3033 syntax->ssyn_oid, slen );
3034 HASH_Update( &HASHcontext,
3035 mr->smr_oid, mlen );
3036 HASH_Update( &HASHcontext,
3037 &value->bv_val[j], klen );
3038 HASH_Final( HASHdigest, &HASHcontext );
3040 ber_dupbv( &keys[nkeys++], &digest );
3045 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
3046 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3048 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
3049 value = &sa->sa_final;
3051 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
3052 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
3054 HASH_Init( &HASHcontext );
3055 if( prefix != NULL && prefix->bv_len > 0 ) {
3056 HASH_Update( &HASHcontext,
3057 prefix->bv_val, prefix->bv_len );
3059 HASH_Update( &HASHcontext,
3060 &pre, sizeof( pre ) );
3061 HASH_Update( &HASHcontext,
3062 syntax->ssyn_oid, slen );
3063 HASH_Update( &HASHcontext,
3064 mr->smr_oid, mlen );
3065 HASH_Update( &HASHcontext,
3066 &value->bv_val[value->bv_len-klen], klen );
3067 HASH_Final( HASHdigest, &HASHcontext );
3069 ber_dupbv( &keys[nkeys++], &digest );
3073 keys[nkeys].bv_val = NULL;
3080 return LDAP_SUCCESS;
3089 struct berval *value,
3090 void *assertedValue )
3092 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
3094 if( match == 0 && value->bv_len ) {
3095 match = strncasecmp( value->bv_val,
3096 ((struct berval *) assertedValue)->bv_val,
3101 return LDAP_SUCCESS;
3105 caseIgnoreIA5SubstringsMatch(
3110 struct berval *value,
3111 void *assertedValue )
3114 SubstringsAssertion *sub = assertedValue;
3115 struct berval left = *value;
3119 /* Add up asserted input length */
3120 if( sub->sa_initial.bv_val ) {
3121 inlen += sub->sa_initial.bv_len;
3124 for(i=0; sub->sa_any[i].bv_val != NULL; i++) {
3125 inlen += sub->sa_any[i].bv_len;
3128 if( sub->sa_final.bv_val ) {
3129 inlen += sub->sa_final.bv_len;
3132 if( sub->sa_initial.bv_val ) {
3133 if( inlen > left.bv_len ) {
3138 match = strncasecmp( sub->sa_initial.bv_val, left.bv_val,
3139 sub->sa_initial.bv_len );
3145 left.bv_val += sub->sa_initial.bv_len;
3146 left.bv_len -= sub->sa_initial.bv_len;
3147 inlen -= sub->sa_initial.bv_len;
3150 if( sub->sa_final.bv_val ) {
3151 if( inlen > left.bv_len ) {
3156 match = strncasecmp( sub->sa_final.bv_val,
3157 &left.bv_val[left.bv_len - sub->sa_final.bv_len],
3158 sub->sa_final.bv_len );
3164 left.bv_len -= sub->sa_final.bv_len;
3165 inlen -= sub->sa_final.bv_len;
3169 for(i=0; sub->sa_any[i].bv_val; i++) {
3174 if( inlen > left.bv_len ) {
3175 /* not enough length */
3180 if( sub->sa_any[i].bv_len == 0 ) {
3184 p = bvcasechr( &left, *sub->sa_any[i].bv_val, &idx );
3191 assert( idx < left.bv_len );
3192 if( idx >= left.bv_len ) {
3193 /* this shouldn't happen */
3200 if( sub->sa_any[i].bv_len > left.bv_len ) {
3201 /* not enough left */
3206 match = strncasecmp( left.bv_val,
3207 sub->sa_any[i].bv_val,
3208 sub->sa_any[i].bv_len );
3217 left.bv_val += sub->sa_any[i].bv_len;
3218 left.bv_len -= sub->sa_any[i].bv_len;
3219 inlen -= sub->sa_any[i].bv_len;
3225 return LDAP_SUCCESS;
3228 /* Index generation function */
3229 static int caseIgnoreIA5Indexer(
3234 struct berval *prefix,
3239 int rc = LDAP_SUCCESS;
3242 HASH_CONTEXT HASHcontext;
3243 unsigned char HASHdigest[HASH_BYTES];
3244 struct berval digest;
3245 digest.bv_val = HASHdigest;
3246 digest.bv_len = sizeof(HASHdigest);
3248 /* we should have at least one value at this point */
3249 assert( values != NULL && values[0].bv_val != NULL );
3251 for( i=0; values[i].bv_val != NULL; i++ ) {
3252 /* just count them */
3255 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
3257 slen = syntax->ssyn_oidlen;
3258 mlen = mr->smr_oidlen;
3260 for( i=0; values[i].bv_val != NULL; i++ ) {
3261 struct berval value;
3263 if( mr->smr_normalize ) {
3264 rc = (mr->smr_normalize)( use, syntax, mr, &values[i], &value );
3265 if( rc != LDAP_SUCCESS ) {
3268 #ifndef SLAP_NVALUES
3269 } else if ( mr->smr_syntax->ssyn_normalize ) {
3270 rc = (mr->smr_syntax->ssyn_normalize)( syntax, &values[i], &value );
3271 if( rc != LDAP_SUCCESS ) {
3276 ber_dupbv( &value, &values[i] );
3279 ldap_pvt_str2lower( value.bv_val );
3281 HASH_Init( &HASHcontext );
3282 if( prefix != NULL && prefix->bv_len > 0 ) {
3283 HASH_Update( &HASHcontext,
3284 prefix->bv_val, prefix->bv_len );
3286 HASH_Update( &HASHcontext,
3287 syntax->ssyn_oid, slen );
3288 HASH_Update( &HASHcontext,
3289 mr->smr_oid, mlen );
3290 HASH_Update( &HASHcontext,
3291 value.bv_val, value.bv_len );
3292 HASH_Final( HASHdigest, &HASHcontext );
3294 free( value.bv_val );
3296 ber_dupbv( &keys[i], &digest );
3299 keys[i].bv_val = NULL;
3300 if( rc != LDAP_SUCCESS ) {
3301 ber_bvarray_free( keys );
3308 /* Index generation function */
3309 static int caseIgnoreIA5Filter(
3314 struct berval *prefix,
3315 void * assertedValue,
3320 HASH_CONTEXT HASHcontext;
3321 unsigned char HASHdigest[HASH_BYTES];
3322 struct berval value;
3323 struct berval digest;
3324 digest.bv_val = HASHdigest;
3325 digest.bv_len = sizeof(HASHdigest);
3327 slen = syntax->ssyn_oidlen;
3328 mlen = mr->smr_oidlen;
3330 ber_dupbv( &value, (struct berval *) assertedValue );
3331 ldap_pvt_str2lower( value.bv_val );
3333 keys = ch_malloc( sizeof( struct berval ) * 2 );
3335 HASH_Init( &HASHcontext );
3336 if( prefix != NULL && prefix->bv_len > 0 ) {
3337 HASH_Update( &HASHcontext,
3338 prefix->bv_val, prefix->bv_len );
3340 HASH_Update( &HASHcontext,
3341 syntax->ssyn_oid, slen );
3342 HASH_Update( &HASHcontext,
3343 mr->smr_oid, mlen );
3344 HASH_Update( &HASHcontext,
3345 value.bv_val, value.bv_len );
3346 HASH_Final( HASHdigest, &HASHcontext );
3348 ber_dupbv( &keys[0], &digest );
3349 keys[1].bv_val = NULL;
3351 free( value.bv_val );
3355 return LDAP_SUCCESS;
3358 /* Substrings Index generation function */
3359 static int caseIgnoreIA5SubstringsIndexer(
3364 struct berval *prefix,
3371 HASH_CONTEXT HASHcontext;
3372 unsigned char HASHdigest[HASH_BYTES];
3373 struct berval digest;
3374 digest.bv_val = HASHdigest;
3375 digest.bv_len = sizeof(HASHdigest);
3377 /* we should have at least one value at this point */
3378 assert( values != NULL && values[0].bv_val != NULL );
3381 for( i=0; values[i].bv_val != NULL; i++ ) {
3382 /* count number of indices to generate */
3383 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
3387 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
3388 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3389 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
3390 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
3392 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
3396 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
3397 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3398 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
3402 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
3403 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3404 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
3405 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
3407 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
3413 /* no keys to generate */
3415 return LDAP_SUCCESS;
3418 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
3420 slen = syntax->ssyn_oidlen;
3421 mlen = mr->smr_oidlen;
3424 for( i=0; values[i].bv_val != NULL; i++ ) {
3426 struct berval value;
3428 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
3430 ber_dupbv( &value, &values[i] );
3431 ldap_pvt_str2lower( value.bv_val );
3433 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
3434 ( value.bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
3436 char pre = SLAP_INDEX_SUBSTR_PREFIX;
3437 max = value.bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
3439 for( j=0; j<max; j++ ) {
3440 HASH_Init( &HASHcontext );
3441 if( prefix != NULL && prefix->bv_len > 0 ) {
3442 HASH_Update( &HASHcontext,
3443 prefix->bv_val, prefix->bv_len );
3446 HASH_Update( &HASHcontext,
3447 &pre, sizeof( pre ) );
3448 HASH_Update( &HASHcontext,
3449 syntax->ssyn_oid, slen );
3450 HASH_Update( &HASHcontext,
3451 mr->smr_oid, mlen );
3452 HASH_Update( &HASHcontext,
3454 SLAP_INDEX_SUBSTR_MAXLEN );
3455 HASH_Final( HASHdigest, &HASHcontext );
3457 ber_dupbv( &keys[nkeys++], &digest );
3461 max = SLAP_INDEX_SUBSTR_MAXLEN < value.bv_len
3462 ? SLAP_INDEX_SUBSTR_MAXLEN : value.bv_len;
3464 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
3467 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
3468 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
3469 HASH_Init( &HASHcontext );
3470 if( prefix != NULL && prefix->bv_len > 0 ) {
3471 HASH_Update( &HASHcontext,
3472 prefix->bv_val, prefix->bv_len );
3474 HASH_Update( &HASHcontext,
3475 &pre, sizeof( pre ) );
3476 HASH_Update( &HASHcontext,
3477 syntax->ssyn_oid, slen );
3478 HASH_Update( &HASHcontext,
3479 mr->smr_oid, mlen );
3480 HASH_Update( &HASHcontext,
3482 HASH_Final( HASHdigest, &HASHcontext );
3484 ber_dupbv( &keys[nkeys++], &digest );
3487 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
3488 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
3489 HASH_Init( &HASHcontext );
3490 if( prefix != NULL && prefix->bv_len > 0 ) {
3491 HASH_Update( &HASHcontext,
3492 prefix->bv_val, prefix->bv_len );
3494 HASH_Update( &HASHcontext,
3495 &pre, sizeof( pre ) );
3496 HASH_Update( &HASHcontext,
3497 syntax->ssyn_oid, slen );
3498 HASH_Update( &HASHcontext,
3499 mr->smr_oid, mlen );
3500 HASH_Update( &HASHcontext,
3501 &value.bv_val[value.bv_len-j], j );
3502 HASH_Final( HASHdigest, &HASHcontext );
3504 ber_dupbv( &keys[nkeys++], &digest );
3509 free( value.bv_val );
3513 keys[nkeys].bv_val = NULL;
3520 return LDAP_SUCCESS;
3523 static int caseIgnoreIA5SubstringsFilter(
3528 struct berval *prefix,
3529 void * assertedValue,
3532 SubstringsAssertion *sa = assertedValue;
3534 ber_len_t nkeys = 0;
3535 size_t slen, mlen, klen;
3537 HASH_CONTEXT HASHcontext;
3538 unsigned char HASHdigest[HASH_BYTES];
3539 struct berval value;
3540 struct berval digest;
3542 if((flags & SLAP_INDEX_SUBSTR_INITIAL) && sa->sa_initial.bv_val != NULL &&
3543 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3548 if((flags & SLAP_INDEX_SUBSTR_ANY) && sa->sa_any != NULL ) {
3550 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
3551 if( sa->sa_any[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3552 /* don't bother accounting for stepping */
3553 nkeys += sa->sa_any[i].bv_len -
3554 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
3559 if((flags & SLAP_INDEX_SUBSTR_FINAL) && sa->sa_final.bv_val != NULL &&
3560 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3567 return LDAP_SUCCESS;
3570 digest.bv_val = HASHdigest;
3571 digest.bv_len = sizeof(HASHdigest);
3573 slen = syntax->ssyn_oidlen;
3574 mlen = mr->smr_oidlen;
3576 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
3579 if((flags & SLAP_INDEX_SUBSTR_INITIAL) && sa->sa_initial.bv_val != NULL &&
3580 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3582 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
3583 ber_dupbv( &value, &sa->sa_initial );
3584 ldap_pvt_str2lower( value.bv_val );
3586 klen = SLAP_INDEX_SUBSTR_MAXLEN < value.bv_len
3587 ? SLAP_INDEX_SUBSTR_MAXLEN : value.bv_len;
3589 HASH_Init( &HASHcontext );
3590 if( prefix != NULL && prefix->bv_len > 0 ) {
3591 HASH_Update( &HASHcontext,
3592 prefix->bv_val, prefix->bv_len );
3594 HASH_Update( &HASHcontext,
3595 &pre, sizeof( pre ) );
3596 HASH_Update( &HASHcontext,
3597 syntax->ssyn_oid, slen );
3598 HASH_Update( &HASHcontext,
3599 mr->smr_oid, mlen );
3600 HASH_Update( &HASHcontext,
3601 value.bv_val, klen );
3602 HASH_Final( HASHdigest, &HASHcontext );
3604 free( value.bv_val );
3605 ber_dupbv( &keys[nkeys++], &digest );
3608 if((flags & SLAP_INDEX_SUBSTR_ANY) && sa->sa_any != NULL ) {
3610 pre = SLAP_INDEX_SUBSTR_PREFIX;
3611 klen = SLAP_INDEX_SUBSTR_MAXLEN;
3613 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
3614 if( sa->sa_any[i].bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
3618 ber_dupbv( &value, &sa->sa_any[i] );
3619 ldap_pvt_str2lower( value.bv_val );
3622 j <= value.bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
3623 j += SLAP_INDEX_SUBSTR_STEP )
3625 HASH_Init( &HASHcontext );
3626 if( prefix != NULL && prefix->bv_len > 0 ) {
3627 HASH_Update( &HASHcontext,
3628 prefix->bv_val, prefix->bv_len );
3630 HASH_Update( &HASHcontext,
3631 &pre, sizeof( pre ) );
3632 HASH_Update( &HASHcontext,
3633 syntax->ssyn_oid, slen );
3634 HASH_Update( &HASHcontext,
3635 mr->smr_oid, mlen );
3636 HASH_Update( &HASHcontext,
3637 &value.bv_val[j], klen );
3638 HASH_Final( HASHdigest, &HASHcontext );
3640 ber_dupbv( &keys[nkeys++], &digest );
3643 free( value.bv_val );
3647 if((flags & SLAP_INDEX_SUBSTR_FINAL) && sa->sa_final.bv_val != NULL &&
3648 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3650 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
3651 ber_dupbv( &value, &sa->sa_final );
3652 ldap_pvt_str2lower( value.bv_val );
3654 klen = SLAP_INDEX_SUBSTR_MAXLEN < value.bv_len
3655 ? SLAP_INDEX_SUBSTR_MAXLEN : value.bv_len;
3657 HASH_Init( &HASHcontext );
3658 if( prefix != NULL && prefix->bv_len > 0 ) {
3659 HASH_Update( &HASHcontext,
3660 prefix->bv_val, prefix->bv_len );
3662 HASH_Update( &HASHcontext,
3663 &pre, sizeof( pre ) );
3664 HASH_Update( &HASHcontext,
3665 syntax->ssyn_oid, slen );
3666 HASH_Update( &HASHcontext,
3667 mr->smr_oid, mlen );
3668 HASH_Update( &HASHcontext,
3669 &value.bv_val[value.bv_len-klen], klen );
3670 HASH_Final( HASHdigest, &HASHcontext );
3672 free( value.bv_val );
3673 ber_dupbv( &keys[nkeys++], &digest );
3677 keys[nkeys].bv_val = NULL;
3684 return LDAP_SUCCESS;
3690 numericStringValidate(
3696 if( in->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
3698 for(i=0; i < in->bv_len; i++) {
3699 if( !SLAP_NUMERIC(in->bv_val[i]) ) {
3700 return LDAP_INVALID_SYNTAX;
3704 return LDAP_SUCCESS;
3707 #ifndef SLAP_NVALUES
3710 xnumericStringNormalize(
3713 struct berval *normalized )
3715 /* removal all spaces */
3718 assert( val->bv_len );
3720 normalized->bv_val = ch_malloc( val->bv_len + 1 );
3723 q = normalized->bv_val;
3726 if ( ASCII_SPACE( *p ) ) {
3727 /* Ignore whitespace */
3734 /* we should have copied no more then is in val */
3735 assert( (q - normalized->bv_val) <= (p - val->bv_val) );
3737 /* null terminate */
3740 normalized->bv_len = q - normalized->bv_val;
3742 if( normalized->bv_len == 0 ) {
3743 normalized->bv_val = ch_realloc( normalized->bv_val, 2 );
3744 normalized->bv_val[0] = ' ';
3745 normalized->bv_val[1] = '\0';
3746 normalized->bv_len = 1;
3749 return LDAP_SUCCESS;
3753 objectIdentifierFirstComponentMatch(
3758 struct berval *value,
3759 void *assertedValue )
3761 int rc = LDAP_SUCCESS;
3763 struct berval *asserted = (struct berval *) assertedValue;
3767 if( value->bv_len == 0 || value->bv_val[0] != '(' /*')'*/ ) {
3768 return LDAP_INVALID_SYNTAX;
3771 /* trim leading white space */
3772 for( i=1; ASCII_SPACE(value->bv_val[i]) && i < value->bv_len; i++ ) {
3776 /* grab next word */
3777 oid.bv_val = &value->bv_val[i];
3778 j = value->bv_len - i;
3779 for( i=0; !ASCII_SPACE(oid.bv_val[i]) && i < j; i++ ) {
3784 /* insert attributeTypes, objectclass check here */
3785 if( OID_LEADCHAR(asserted->bv_val[0]) ) {
3786 rc = objectIdentifierMatch( &match, flags, syntax, mr, &oid, asserted );
3789 if ( !strcmp( syntax->ssyn_oid, SLAP_SYNTAX_MATCHINGRULES_OID ) ) {
3790 MatchingRule *asserted_mr = mr_bvfind( asserted );
3791 MatchingRule *stored_mr = mr_bvfind( &oid );
3793 if( asserted_mr == NULL ) {
3794 rc = SLAPD_COMPARE_UNDEFINED;
3796 match = asserted_mr != stored_mr;
3799 } else if ( !strcmp( syntax->ssyn_oid,
3800 SLAP_SYNTAX_ATTRIBUTETYPES_OID ) )
3802 AttributeType *asserted_at = at_bvfind( asserted );
3803 AttributeType *stored_at = at_bvfind( &oid );
3805 if( asserted_at == NULL ) {
3806 rc = SLAPD_COMPARE_UNDEFINED;
3808 match = asserted_at != stored_at;
3811 } else if ( !strcmp( syntax->ssyn_oid,
3812 SLAP_SYNTAX_OBJECTCLASSES_OID ) )
3814 ObjectClass *asserted_oc = oc_bvfind( asserted );
3815 ObjectClass *stored_oc = oc_bvfind( &oid );
3817 if( asserted_oc == NULL ) {
3818 rc = SLAPD_COMPARE_UNDEFINED;
3820 match = asserted_oc != stored_oc;
3826 LDAP_LOG( CONFIG, ENTRY,
3827 "objectIdentifierFirstComponentMatch: %d\n %s\n %s\n",
3828 match, value->bv_val, asserted->bv_val );
3830 Debug( LDAP_DEBUG_ARGS, "objectIdentifierFirstComponentMatch "
3831 "%d\n\t\"%s\"\n\t\"%s\"\n",
3832 match, value->bv_val, asserted->bv_val );
3835 if( rc == LDAP_SUCCESS ) *matchp = match;
3847 struct berval *value,
3848 void *assertedValue )
3850 long lValue, lAssertedValue;
3852 /* safe to assume integers are NUL terminated? */
3853 lValue = strtol(value->bv_val, NULL, 10);
3854 if(( lValue == LONG_MIN || lValue == LONG_MAX) && errno == ERANGE ) {
3855 return LDAP_CONSTRAINT_VIOLATION;
3858 lAssertedValue = strtol(((struct berval *)assertedValue)->bv_val, NULL, 10);
3859 if(( lAssertedValue == LONG_MIN || lAssertedValue == LONG_MAX)
3860 && errno == ERANGE )
3862 return LDAP_CONSTRAINT_VIOLATION;
3865 *matchp = (lValue & lAssertedValue) ? 0 : 1;
3866 return LDAP_SUCCESS;
3875 struct berval *value,
3876 void *assertedValue )
3878 long lValue, lAssertedValue;
3880 /* safe to assume integers are NUL terminated? */
3881 lValue = strtol(value->bv_val, NULL, 10);
3882 if(( lValue == LONG_MIN || lValue == LONG_MAX) && errno == ERANGE ) {
3883 return LDAP_CONSTRAINT_VIOLATION;
3886 lAssertedValue = strtol(((struct berval *)assertedValue)->bv_val, NULL, 10);
3887 if(( lAssertedValue == LONG_MIN || lAssertedValue == LONG_MAX)
3888 && errno == ERANGE )
3890 return LDAP_CONSTRAINT_VIOLATION;
3893 *matchp = (lValue | lAssertedValue) ? 0 : -1;
3894 return LDAP_SUCCESS;
3897 #ifndef SLAP_NVALUES
3900 #include <openssl/x509.h>
3901 #include <openssl/err.h>
3904 * Next function returns a string representation of a ASN1_INTEGER.
3905 * It works for unlimited lengths.
3908 static struct berval *
3909 asn1_integer2str(ASN1_INTEGER *a, struct berval *bv)
3913 static char digit[] = "0123456789";
3915 /* We work backwards, make it fill from the end of buf */
3916 p = buf + sizeof(buf) - 1;
3919 if ( a == NULL || a->length == 0 ) {
3927 /* We want to preserve the original */
3928 copy = ch_malloc(n*sizeof(unsigned int));
3929 for (i = 0; i<n; i++) {
3930 copy[i] = a->data[i];
3934 * base indicates the index of the most significant
3935 * byte that might be nonzero. When it goes off the
3936 * end, we now there is nothing left to do.
3942 for (i = base; i<n; i++ ) {
3943 copy[i] += carry*256;
3944 carry = copy[i] % 10;
3949 * Way too large, we need to leave
3950 * room for sign if negative
3955 *--p = digit[carry];
3957 if (copy[base] == 0) base++;
3962 if ( a->type == V_ASN1_NEG_INTEGER ) {
3966 return ber_str2bv( p, 0, 1, bv );
3970 * Given a certificate in DER format, extract the corresponding
3971 * assertion value for certificateExactMatch
3974 certificateExactConvert(
3976 struct berval * out )
3979 unsigned char *p = in->bv_val;
3980 struct berval serial;
3981 struct berval issuer_dn;
3983 xcert = d2i_X509(NULL, &p, in->bv_len);
3986 LDAP_LOG( CONFIG, ENTRY,
3987 "certificateExactConvert: error parsing cert: %s\n",
3988 ERR_error_string(ERR_get_error(),NULL), 0, 0 );
3990 Debug( LDAP_DEBUG_ARGS, "certificateExactConvert: "
3991 "error parsing cert: %s\n",
3992 ERR_error_string(ERR_get_error(),NULL), NULL, NULL );
3994 return LDAP_INVALID_SYNTAX;
3997 if ( !asn1_integer2str(xcert->cert_info->serialNumber, &serial) ) {
3999 return LDAP_INVALID_SYNTAX;
4001 if ( dnX509normalize(X509_get_issuer_name(xcert), &issuer_dn )
4005 ber_memfree(serial.bv_val);
4006 return LDAP_INVALID_SYNTAX;
4011 out->bv_len = serial.bv_len + issuer_dn.bv_len + sizeof(" $ ");
4012 out->bv_val = ch_malloc(out->bv_len);
4014 AC_MEMCPY(p, serial.bv_val, serial.bv_len);
4016 AC_MEMCPY(p, " $ ", sizeof(" $ ")-1);
4018 AC_MEMCPY(p, issuer_dn.bv_val, issuer_dn.bv_len);
4019 p += issuer_dn.bv_len;
4023 LDAP_LOG( CONFIG, ARGS,
4024 "certificateExactConvert: \n %s\n", out->bv_val, 0, 0 );
4026 Debug( LDAP_DEBUG_ARGS, "certificateExactConvert "
4028 out->bv_val, NULL, NULL );
4031 ber_memfree(serial.bv_val);
4032 ber_memfree(issuer_dn.bv_val);
4034 return LDAP_SUCCESS;
4038 serial_and_issuer_parse(
4039 struct berval *assertion,
4040 struct berval *serial,
4041 struct berval *issuer_dn
4049 begin = assertion->bv_val;
4050 end = assertion->bv_val+assertion->bv_len-1;
4051 for (p=begin; p<=end && *p != '$'; p++) /* empty */ ;
4052 if ( p > end ) return LDAP_INVALID_SYNTAX;
4054 /* p now points at the $ sign, now use
4055 * begin and end to delimit the serial number
4057 while (ASCII_SPACE(*begin)) begin++;
4059 while (ASCII_SPACE(*end)) end--;
4061 if( end <= begin ) return LDAP_INVALID_SYNTAX;
4063 bv.bv_len = end-begin+1;
4065 ber_dupbv(serial, &bv);
4067 /* now extract the issuer, remember p was at the dollar sign */
4069 end = assertion->bv_val+assertion->bv_len-1;
4070 while (ASCII_SPACE(*begin)) begin++;
4071 /* should we trim spaces at the end too? is it safe always? no, no */
4073 if( end <= begin ) return LDAP_INVALID_SYNTAX;
4076 bv.bv_len = end-begin+1;
4079 dnNormalize2( NULL, &bv, issuer_dn );
4082 return LDAP_SUCCESS;
4086 certificateExactMatch(
4091 struct berval *value,
4092 void *assertedValue )
4095 unsigned char *p = value->bv_val;
4096 struct berval serial;
4097 struct berval issuer_dn;
4098 struct berval asserted_serial;
4099 struct berval asserted_issuer_dn;
4102 xcert = d2i_X509(NULL, &p, value->bv_len);
4105 LDAP_LOG( CONFIG, ENTRY,
4106 "certificateExactMatch: error parsing cert: %s\n",
4107 ERR_error_string(ERR_get_error(),NULL), 0, 0 );
4109 Debug( LDAP_DEBUG_ARGS, "certificateExactMatch: "
4110 "error parsing cert: %s\n",
4111 ERR_error_string(ERR_get_error(),NULL), NULL, NULL );
4113 return LDAP_INVALID_SYNTAX;
4116 asn1_integer2str(xcert->cert_info->serialNumber, &serial);
4117 dnX509normalize(X509_get_issuer_name(xcert), &issuer_dn);
4121 serial_and_issuer_parse(assertedValue,
4122 &asserted_serial, &asserted_issuer_dn);
4127 slap_schema.si_syn_integer,
4128 slap_schema.si_mr_integerMatch,
4131 if ( ret == LDAP_SUCCESS ) {
4132 if ( *matchp == 0 ) {
4133 /* We need to normalize everything for dnMatch */
4137 slap_schema.si_syn_distinguishedName,
4138 slap_schema.si_mr_distinguishedNameMatch,
4140 &asserted_issuer_dn);
4145 LDAP_LOG( CONFIG, ARGS, "certificateExactMatch "
4146 "%d\n\t\"%s $ %s\"\n",
4147 *matchp, serial.bv_val, issuer_dn.bv_val );
4148 LDAP_LOG( CONFIG, ARGS, "\t\"%s $ %s\"\n",
4149 asserted_serial.bv_val, asserted_issuer_dn.bv_val,
4152 Debug( LDAP_DEBUG_ARGS, "certificateExactMatch "
4153 "%d\n\t\"%s $ %s\"\n",
4154 *matchp, serial.bv_val, issuer_dn.bv_val );
4155 Debug( LDAP_DEBUG_ARGS, "\t\"%s $ %s\"\n",
4156 asserted_serial.bv_val, asserted_issuer_dn.bv_val,
4160 ber_memfree(serial.bv_val);
4161 ber_memfree(issuer_dn.bv_val);
4162 ber_memfree(asserted_serial.bv_val);
4163 ber_memfree(asserted_issuer_dn.bv_val);
4169 * Index generation function
4170 * We just index the serials, in most scenarios the issuer DN is one of
4171 * a very small set of values.
4173 static int certificateExactIndexer(
4178 struct berval *prefix,
4186 struct berval serial;
4188 /* we should have at least one value at this point */
4189 assert( values != NULL && values[0].bv_val != NULL );
4191 for( i=0; values[i].bv_val != NULL; i++ ) {
4192 /* empty -- just count them */
4195 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
4197 for( i=0; values[i].bv_val != NULL; i++ ) {
4198 p = values[i].bv_val;
4199 xcert = d2i_X509(NULL, &p, values[i].bv_len);
4202 LDAP_LOG( CONFIG, ENTRY,
4203 "certificateExactIndexer: error parsing cert: %s\n",
4204 ERR_error_string(ERR_get_error(),NULL), 0, 0);
4206 Debug( LDAP_DEBUG_ARGS, "certificateExactIndexer: "
4207 "error parsing cert: %s\n",
4208 ERR_error_string(ERR_get_error(),NULL),
4211 /* Do we leak keys on error? */
4212 return LDAP_INVALID_SYNTAX;
4215 asn1_integer2str(xcert->cert_info->serialNumber, &serial);
4217 xintegerNormalize( slap_schema.si_syn_integer,
4218 &serial, &keys[i] );
4219 ber_memfree(serial.bv_val);
4221 LDAP_LOG( CONFIG, ENTRY,
4222 "certificateExactIndexer: returning: %s\n", keys[i].bv_val, 0, 0);
4224 Debug( LDAP_DEBUG_ARGS, "certificateExactIndexer: "
4231 keys[i].bv_val = NULL;
4233 return LDAP_SUCCESS;
4236 /* Index generation function */
4237 /* We think this is always called with a value in matching rule syntax */
4238 static int certificateExactFilter(
4243 struct berval *prefix,
4244 void * assertedValue,
4248 struct berval asserted_serial;
4251 ret = serial_and_issuer_parse( assertedValue, &asserted_serial, NULL );
4252 if( ret != LDAP_SUCCESS ) return ret;
4254 keys = ch_malloc( sizeof( struct berval ) * 2 );
4255 xintegerNormalize( syntax, &asserted_serial, &keys[0] );
4256 keys[1].bv_val = NULL;
4259 ber_memfree(asserted_serial.bv_val);
4260 return LDAP_SUCCESS;
4266 check_time_syntax (struct berval *val,
4270 static int ceiling[9] = { 99, 99, 11, 30, 23, 59, 59, 12, 59 };
4271 static int mdays[2][12] = {
4272 /* non-leap years */
4273 { 30, 27, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30 },
4275 { 30, 28, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30 }
4278 int part, c, tzoffset, leapyear = 0 ;
4280 if( val->bv_len == 0 ) {
4281 return LDAP_INVALID_SYNTAX;
4284 p = (char *)val->bv_val;
4285 e = p + val->bv_len;
4287 /* Ignore initial whitespace */
4288 while ( ( p < e ) && ASCII_SPACE( *p ) ) {
4292 if (e - p < 13 - (2 * start)) {
4293 return LDAP_INVALID_SYNTAX;
4296 for (part = 0; part < 9; part++) {
4300 for (part = start; part < 7; part++) {
4302 if ((part == 6) && (c == 'Z' || c == '+' || c == '-')) {
4309 return LDAP_INVALID_SYNTAX;
4311 if (c < 0 || c > 9) {
4312 return LDAP_INVALID_SYNTAX;
4318 return LDAP_INVALID_SYNTAX;
4320 if (c < 0 || c > 9) {
4321 return LDAP_INVALID_SYNTAX;
4326 if (part == 2 || part == 3) {
4329 if (parts[part] < 0) {
4330 return LDAP_INVALID_SYNTAX;
4332 if (parts[part] > ceiling[part]) {
4333 return LDAP_INVALID_SYNTAX;
4337 /* leapyear check for the Gregorian calendar (year>1581) */
4338 if (((parts[1] % 4 == 0) && (parts[1] != 0)) ||
4339 ((parts[0] % 4 == 0) && (parts[1] == 0)))
4344 if (parts[3] > mdays[leapyear][parts[2]]) {
4345 return LDAP_INVALID_SYNTAX;
4350 tzoffset = 0; /* UTC */
4351 } else if (c != '+' && c != '-') {
4352 return LDAP_INVALID_SYNTAX;
4356 } else /* c == '+' */ {
4361 return LDAP_INVALID_SYNTAX;
4364 for (part = 7; part < 9; part++) {
4366 if (c < 0 || c > 9) {
4367 return LDAP_INVALID_SYNTAX;
4372 if (c < 0 || c > 9) {
4373 return LDAP_INVALID_SYNTAX;
4377 if (parts[part] < 0 || parts[part] > ceiling[part]) {
4378 return LDAP_INVALID_SYNTAX;
4383 /* Ignore trailing whitespace */
4384 while ( ( p < e ) && ASCII_SPACE( *p ) ) {
4388 return LDAP_INVALID_SYNTAX;
4391 switch ( tzoffset ) {
4392 case -1: /* negativ offset to UTC, ie west of Greenwich */
4393 parts[4] += parts[7];
4394 parts[5] += parts[8];
4395 for (part = 6; --part > 0; ) { /* offset is just hhmm, no seconds */
4399 c = mdays[leapyear][parts[2]];
4401 if (parts[part] > c) {
4402 parts[part] -= c + 1;
4407 case 1: /* positive offset to UTC, ie east of Greenwich */
4408 parts[4] -= parts[7];
4409 parts[5] -= parts[8];
4410 for (part = 6; --part > 0; ) {
4414 /* first arg to % needs to be non negativ */
4415 c = mdays[leapyear][(parts[2] - 1 + 12) % 12];
4417 if (parts[part] < 0) {
4418 parts[part] += c + 1;
4423 case 0: /* already UTC */
4427 return LDAP_SUCCESS;
4430 #ifdef SUPPORT_OBSOLETE_UTC_SYNTAX
4435 struct berval *normalized )
4439 rc = check_time_syntax(val, 1, parts);
4440 if (rc != LDAP_SUCCESS) {
4444 normalized->bv_val = ch_malloc( 14 );
4445 if ( normalized->bv_val == NULL ) {
4446 return LBER_ERROR_MEMORY;
4449 sprintf( normalized->bv_val, "%02d%02d%02d%02d%02d%02dZ",
4450 parts[1], parts[2] + 1, parts[3] + 1,
4451 parts[4], parts[5], parts[6] );
4452 normalized->bv_len = 13;
4454 return LDAP_SUCCESS;
4458 #ifdef SUPPORT_OBSOLETE_UTC_SYNTAX
4466 return check_time_syntax(in, 1, parts);
4471 generalizedTimeValidate(
4477 return check_time_syntax(in, 0, parts);
4480 #ifndef SLAP_NVALUES
4483 xgeneralizedTimeNormalize(
4486 struct berval *normalized )
4490 rc = check_time_syntax(val, 0, parts);
4491 if (rc != LDAP_SUCCESS) {
4495 normalized->bv_val = ch_malloc( 16 );
4496 if ( normalized->bv_val == NULL ) {
4497 return LBER_ERROR_MEMORY;
4500 sprintf( normalized->bv_val, "%02d%02d%02d%02d%02d%02d%02dZ",
4501 parts[0], parts[1], parts[2] + 1, parts[3] + 1,
4502 parts[4], parts[5], parts[6] );
4503 normalized->bv_len = 15;
4505 return LDAP_SUCCESS;
4510 nisNetgroupTripleValidate(
4512 struct berval *val )
4517 if ( val->bv_len == 0 ) {
4518 return LDAP_INVALID_SYNTAX;
4521 p = (char *)val->bv_val;
4522 e = p + val->bv_len;
4524 if ( *p != '(' /*')'*/ ) {
4525 return LDAP_INVALID_SYNTAX;
4528 for ( p++; ( p < e ) && ( *p != /*'('*/ ')' ); p++ ) {
4532 return LDAP_INVALID_SYNTAX;
4535 } else if ( !AD_CHAR( *p ) ) {
4536 return LDAP_INVALID_SYNTAX;
4540 if ( ( commas != 2 ) || ( *p != /*'('*/ ')' ) ) {
4541 return LDAP_INVALID_SYNTAX;
4547 return LDAP_INVALID_SYNTAX;
4550 return LDAP_SUCCESS;
4554 bootParameterValidate(
4556 struct berval *val )
4560 if ( val->bv_len == 0 ) {
4561 return LDAP_INVALID_SYNTAX;
4564 p = (char *)val->bv_val;
4565 e = p + val->bv_len;
4568 for (; ( p < e ) && ( *p != '=' ); p++ ) {
4569 if ( !AD_CHAR( *p ) ) {
4570 return LDAP_INVALID_SYNTAX;
4575 return LDAP_INVALID_SYNTAX;
4579 for ( p++; ( p < e ) && ( *p != ':' ); p++ ) {
4580 if ( !AD_CHAR( *p ) ) {
4581 return LDAP_INVALID_SYNTAX;
4586 return LDAP_INVALID_SYNTAX;
4590 for ( p++; p < e; p++ ) {
4591 if ( !SLAP_PRINTABLE( *p ) ) {
4592 return LDAP_INVALID_SYNTAX;
4596 return LDAP_SUCCESS;
4599 #define X_BINARY "X-BINARY-TRANSFER-REQUIRED 'TRUE' "
4600 #define X_NOT_H_R "X-NOT-HUMAN-READABLE 'TRUE' "
4602 static slap_syntax_defs_rec syntax_defs[] = {
4603 {"( 1.3.6.1.4.1.1466.115.121.1.1 DESC 'ACI Item' "
4604 X_BINARY X_NOT_H_R ")",
4605 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, NULL, NULL, NULL},
4606 {"( 1.3.6.1.4.1.1466.115.121.1.2 DESC 'Access Point' " X_NOT_H_R ")",
4607 0, NULL, NULL, NULL},
4608 {"( 1.3.6.1.4.1.1466.115.121.1.3 DESC 'Attribute Type Description' )",
4609 0, NULL, NULL, NULL},
4610 {"( 1.3.6.1.4.1.1466.115.121.1.4 DESC 'Audio' "
4612 SLAP_SYNTAX_BLOB, blobValidate, NULL, NULL},
4613 {"( 1.3.6.1.4.1.1466.115.121.1.5 DESC 'Binary' "
4615 SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4616 {"( 1.3.6.1.4.1.1466.115.121.1.6 DESC 'Bit String' )",
4617 0, bitStringValidate, NULL, NULL },
4618 {"( 1.3.6.1.4.1.1466.115.121.1.7 DESC 'Boolean' )",
4619 0, booleanValidate, NULL, NULL},
4620 {"( 1.3.6.1.4.1.1466.115.121.1.8 DESC 'Certificate' "
4621 X_BINARY X_NOT_H_R ")",
4622 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4623 {"( 1.3.6.1.4.1.1466.115.121.1.9 DESC 'Certificate List' "
4624 X_BINARY X_NOT_H_R ")",
4625 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4626 {"( 1.3.6.1.4.1.1466.115.121.1.10 DESC 'Certificate Pair' "
4627 X_BINARY X_NOT_H_R ")",
4628 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4629 {"( 1.3.6.1.4.1.1466.115.121.1.11 DESC 'Country String' )",
4630 0, countryStringValidate, xIA5StringNormalize, NULL},
4631 {"( 1.3.6.1.4.1.1466.115.121.1.12 DESC 'Distinguished Name' )",
4632 0, dnValidate, xdnNormalize, dnPretty2},
4633 {"( 1.3.6.1.4.1.1466.115.121.1.13 DESC 'Data Quality' )",
4634 0, NULL, NULL, NULL},
4635 {"( 1.3.6.1.4.1.1466.115.121.1.14 DESC 'Delivery Method' )",
4636 0, NULL, NULL, NULL},
4637 {"( 1.3.6.1.4.1.1466.115.121.1.15 DESC 'Directory String' )",
4638 0, UTF8StringValidate, xUTF8StringNormalize, NULL},
4639 {"( 1.3.6.1.4.1.1466.115.121.1.16 DESC 'DIT Content Rule Description' )",
4640 0, NULL, NULL, NULL},
4641 {"( 1.3.6.1.4.1.1466.115.121.1.17 DESC 'DIT Structure Rule Description' )",
4642 0, NULL, NULL, NULL},
4643 {"( 1.3.6.1.4.1.1466.115.121.1.19 DESC 'DSA Quality' )",
4644 0, NULL, NULL, NULL},
4645 {"( 1.3.6.1.4.1.1466.115.121.1.20 DESC 'DSE Type' )",
4646 0, NULL, NULL, NULL},
4647 {"( 1.3.6.1.4.1.1466.115.121.1.21 DESC 'Enhanced Guide' )",
4648 0, NULL, NULL, NULL},
4649 {"( 1.3.6.1.4.1.1466.115.121.1.22 DESC 'Facsimile Telephone Number' )",
4650 0, printablesStringValidate, xtelephoneNumberNormalize, NULL},
4651 {"( 1.3.6.1.4.1.1466.115.121.1.23 DESC 'Fax' " X_NOT_H_R ")",
4652 SLAP_SYNTAX_BLOB, NULL, NULL, NULL},
4653 {"( 1.3.6.1.4.1.1466.115.121.1.24 DESC 'Generalized Time' )",
4654 0, generalizedTimeValidate, xgeneralizedTimeNormalize, NULL},
4655 {"( 1.3.6.1.4.1.1466.115.121.1.25 DESC 'Guide' )",
4656 0, NULL, NULL, NULL},
4657 {"( 1.3.6.1.4.1.1466.115.121.1.26 DESC 'IA5 String' )",
4658 0, IA5StringValidate, xIA5StringNormalize, NULL},
4659 {"( 1.3.6.1.4.1.1466.115.121.1.27 DESC 'Integer' )",
4660 0, integerValidate, xintegerNormalize, NULL},
4661 {"( 1.3.6.1.4.1.1466.115.121.1.28 DESC 'JPEG' " X_NOT_H_R ")",
4662 SLAP_SYNTAX_BLOB, blobValidate, NULL, NULL},
4663 {"( 1.3.6.1.4.1.1466.115.121.1.29 DESC 'Master And Shadow Access Points' )",
4664 0, NULL, NULL, NULL},
4665 {"( 1.3.6.1.4.1.1466.115.121.1.30 DESC 'Matching Rule Description' )",
4666 0, NULL, NULL, NULL},
4667 {"( 1.3.6.1.4.1.1466.115.121.1.31 DESC 'Matching Rule Use Description' )",
4668 0, NULL, NULL, NULL},
4669 {"( 1.3.6.1.4.1.1466.115.121.1.32 DESC 'Mail Preference' )",
4670 0, NULL, NULL, NULL},
4671 {"( 1.3.6.1.4.1.1466.115.121.1.33 DESC 'MHS OR Address' )",
4672 0, NULL, NULL, NULL},
4673 {"( 1.3.6.1.4.1.1466.115.121.1.34 DESC 'Name And Optional UID' )",
4674 0, nameUIDValidate, xnameUIDNormalize, NULL},
4675 {"( 1.3.6.1.4.1.1466.115.121.1.35 DESC 'Name Form Description' )",
4676 0, NULL, NULL, NULL},
4677 {"( 1.3.6.1.4.1.1466.115.121.1.36 DESC 'Numeric String' )",
4678 0, numericStringValidate, xnumericStringNormalize, NULL},
4679 {"( 1.3.6.1.4.1.1466.115.121.1.37 DESC 'Object Class Description' )",
4680 0, NULL, NULL, NULL},
4681 {"( 1.3.6.1.4.1.1466.115.121.1.38 DESC 'OID' )",
4682 0, oidValidate, NULL, NULL},
4683 {"( 1.3.6.1.4.1.1466.115.121.1.39 DESC 'Other Mailbox' )",
4684 0, IA5StringValidate, xIA5StringNormalize, NULL},
4685 {"( 1.3.6.1.4.1.1466.115.121.1.40 DESC 'Octet String' )",
4686 0, blobValidate, NULL, NULL},
4687 {"( 1.3.6.1.4.1.1466.115.121.1.41 DESC 'Postal Address' )",
4688 0, UTF8StringValidate, xUTF8StringNormalize, NULL},
4689 {"( 1.3.6.1.4.1.1466.115.121.1.42 DESC 'Protocol Information' )",
4690 0, NULL, NULL, NULL},
4691 {"( 1.3.6.1.4.1.1466.115.121.1.43 DESC 'Presentation Address' )",
4692 0, NULL, NULL, NULL},
4693 {"( 1.3.6.1.4.1.1466.115.121.1.44 DESC 'Printable String' )",
4694 0, printableStringValidate, xIA5StringNormalize, NULL},
4695 {"( 1.3.6.1.4.1.1466.115.121.1.45 DESC 'SubtreeSpecification' "
4696 X_BINARY X_NOT_H_R ")",
4697 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, NULL, NULL, NULL},
4698 {"( 1.3.6.1.4.1.1466.115.121.1.49 DESC 'Supported Algorithm' "
4699 X_BINARY X_NOT_H_R ")",
4700 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4701 {"( 1.3.6.1.4.1.1466.115.121.1.50 DESC 'Telephone Number' )",
4702 0, printableStringValidate, xtelephoneNumberNormalize, NULL},
4703 {"( 1.3.6.1.4.1.1466.115.121.1.51 DESC 'Teletex Terminal Identifier' )",
4704 0, NULL, NULL, NULL},
4705 {"( 1.3.6.1.4.1.1466.115.121.1.52 DESC 'Telex Number' )",
4706 0, printablesStringValidate, xIA5StringNormalize, NULL},
4707 #ifdef SUPPORT_OBSOLETE_UTC_SYNTAX
4708 {"( 1.3.6.1.4.1.1466.115.121.1.53 DESC 'UTC Time' )",
4709 0, utcTimeValidate, xutcTimeNormalize, NULL},
4711 {"( 1.3.6.1.4.1.1466.115.121.1.54 DESC 'LDAP Syntax Description' )",
4712 0, NULL, NULL, NULL},
4713 {"( 1.3.6.1.4.1.1466.115.121.1.55 DESC 'Modify Rights' )",
4714 0, NULL, NULL, NULL},
4715 {"( 1.3.6.1.4.1.1466.115.121.1.56 DESC 'LDAP Schema Definition' )",
4716 0, NULL, NULL, NULL},
4717 {"( 1.3.6.1.4.1.1466.115.121.1.57 DESC 'LDAP Schema Description' )",
4718 0, NULL, NULL, NULL},
4719 {"( 1.3.6.1.4.1.1466.115.121.1.58 DESC 'Substring Assertion' )",
4720 0, NULL, NULL, NULL},
4722 /* RFC 2307 NIS Syntaxes */
4723 {"( 1.3.6.1.1.1.0.0 DESC 'RFC2307 NIS Netgroup Triple' )",
4724 0, nisNetgroupTripleValidate, NULL, NULL},
4725 {"( 1.3.6.1.1.1.0.1 DESC 'RFC2307 Boot Parameter' )",
4726 0, bootParameterValidate, NULL, NULL},
4730 /* These OIDs are not published yet, but will be in the next
4731 * I-D for PKIX LDAPv3 schema as have been advanced by David
4732 * Chadwick in private mail.
4734 {"( 1.2.826.0.1.3344810.7.1 DESC 'Serial Number and Issuer' )",
4735 0, UTF8StringValidate, NULL, NULL},
4738 /* OpenLDAP Experimental Syntaxes */
4739 #ifdef SLAPD_ACI_ENABLED
4740 {"( 1.3.6.1.4.1.4203.666.2.1 DESC 'OpenLDAP Experimental ACI' )",
4742 UTF8StringValidate /* THIS WILL CHANGE FOR NEW ACI SYNTAX */,
4746 #ifdef SLAPD_AUTHPASSWD
4747 /* needs updating */
4748 {"( 1.3.6.1.4.1.4203.666.2.2 DESC 'OpenLDAP authPassword' )",
4749 SLAP_SYNTAX_HIDE, NULL, NULL, NULL},
4752 /* OpenLDAP Void Syntax */
4753 {"( 1.3.6.1.4.1.4203.1.1.1 DESC 'OpenLDAP void' )" ,
4754 SLAP_SYNTAX_HIDE, inValidate, NULL, NULL},
4755 {NULL, 0, NULL, NULL, NULL}
4759 char *certificateExactMatchSyntaxes[] = {
4760 "1.3.6.1.4.1.1466.115.121.1.8" /* certificate */,
4764 char *directoryStringSyntaxes[] = {
4765 "1.3.6.1.4.1.1466.115.121.1.44" /* printableString */,
4768 char *integerFirstComponentMatchSyntaxes[] = {
4769 "1.3.6.1.4.1.1466.115.121.1.27" /* INTEGER */,
4770 "1.3.6.1.4.1.1466.115.121.1.17" /* ditStructureRuleDescription */,
4773 char *objectIdentifierFirstComponentMatchSyntaxes[] = {
4774 "1.3.6.1.4.1.1466.115.121.1.38" /* OID */,
4775 "1.3.6.1.4.1.1466.115.121.1.3" /* attributeTypeDescription */,
4776 "1.3.6.1.4.1.1466.115.121.1.16" /* ditContentRuleDescription */,
4777 "1.3.6.1.4.1.1466.115.121.1.54" /* ldapSyntaxDescription */,
4778 "1.3.6.1.4.1.1466.115.121.1.30" /* matchingRuleDescription */,
4779 "1.3.6.1.4.1.1466.115.121.1.31" /* matchingRuleUseDescription */,
4780 "1.3.6.1.4.1.1466.115.121.1.35" /* nameFormDescription */,
4781 "1.3.6.1.4.1.1466.115.121.1.37" /* objectClassDescription */,
4786 * Other matching rules in X.520 that we do not use (yet):
4788 * 2.5.13.9 numericStringOrderingMatch
4789 * 2.5.13.25 uTCTimeMatch
4790 * 2.5.13.26 uTCTimeOrderingMatch
4791 * 2.5.13.31 directoryStringFirstComponentMatch
4792 * 2.5.13.32 wordMatch
4793 * 2.5.13.33 keywordMatch
4794 * 2.5.13.35 certificateMatch
4795 * 2.5.13.36 certificatePairExactMatch
4796 * 2.5.13.37 certificatePairMatch
4797 * 2.5.13.38 certificateListExactMatch
4798 * 2.5.13.39 certificateListMatch
4799 * 2.5.13.40 algorithmIdentifierMatch
4800 * 2.5.13.41 storedPrefixMatch
4801 * 2.5.13.42 attributeCertificateMatch
4802 * 2.5.13.43 readerAndKeyIDMatch
4803 * 2.5.13.44 attributeIntegrityMatch
4805 static slap_mrule_defs_rec mrule_defs[] = {
4807 * EQUALITY matching rules must be listed after associated APPROX
4808 * matching rules. So, we list all APPROX matching rules first.
4810 #ifndef SLAP_NVALUES
4811 {"( " directoryStringApproxMatchOID " NAME 'directoryStringApproxMatch' "
4812 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4813 SLAP_MR_HIDE | SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT, NULL,
4814 NULL, NULL, directoryStringApproxMatch,
4815 directoryStringApproxIndexer, directoryStringApproxFilter,
4818 {"( " IA5StringApproxMatchOID " NAME 'IA5StringApproxMatch' "
4819 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4820 SLAP_MR_HIDE | SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT, NULL,
4821 NULL, NULL, IA5StringApproxMatch,
4822 IA5StringApproxIndexer, IA5StringApproxFilter,
4827 * Other matching rules
4830 {"( 2.5.13.0 NAME 'objectIdentifierMatch' "
4831 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
4832 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4834 objectIdentifierNormalize, objectIdentifierMatch,
4835 objectIdentifierIndexer, objectIdentifierFilter,
4838 {"( 2.5.13.1 NAME 'distinguishedNameMatch' "
4839 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )",
4840 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4842 distinguishedNameNormalize, distinguishedNameMatch,
4843 distinguishedNameIndexer, distinguishedNameFilter,
4846 {"( 2.5.13.2 NAME 'caseIgnoreMatch' "
4847 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4848 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD,
4849 directoryStringSyntaxes,
4851 caseIgnoreNormalize, caseIgnoreMatch,
4852 caseIgnoreIndexer, caseIgnoreFilter,
4853 directoryStringApproxMatchOID },
4855 {"( 2.5.13.3 NAME 'caseIgnoreOrderingMatch' "
4856 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4857 SLAP_MR_ORDERING, directoryStringSyntaxes,
4858 NULL, caseIgnoreNormalize, caseIgnoreOrderingMatch,
4861 {"( 2.5.13.4 NAME 'caseIgnoreSubstringsMatch' "
4862 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4863 SLAP_MR_SUBSTR, NULL,
4865 caseIgnoreSubstringsMatch,
4866 caseIgnoreSubstringsIndexer, caseIgnoreSubstringsFilter,
4869 {"( 2.5.13.5 NAME 'caseExactMatch' "
4870 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4871 SLAP_MR_EQUALITY | SLAP_MR_EXT, directoryStringSyntaxes,
4873 caseExactNormalize, caseExactMatch,
4874 caseExactIndexer, caseExactFilter,
4875 directoryStringApproxMatchOID },
4877 {"( 2.5.13.6 NAME 'caseExactOrderingMatch' "
4878 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4879 SLAP_MR_ORDERING, directoryStringSyntaxes,
4880 NULL, caseExactNormalize, caseExactOrderingMatch,
4883 {"( 2.5.13.7 NAME 'caseExactSubstringsMatch' "
4884 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4885 SLAP_MR_SUBSTR, directoryStringSyntaxes,
4887 NULL, caseExactSubstringsMatch,
4888 caseExactSubstringsIndexer, caseExactSubstringsFilter,
4891 {"( 2.5.13.8 NAME 'numericStringMatch' "
4892 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 )",
4893 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL,
4895 numericStringNormalize, numericStringMatch,
4896 numericStringIndexer, numericStringFilter,
4899 {"( 2.5.13.10 NAME 'numericStringSubstringsMatch' "
4900 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4901 SLAP_MR_SUBSTR, NULL,
4903 NULL, numericStringSubstringsMatch,
4904 numericStringSubstringsIndexer, numericStringSubstringsFilter,
4907 {"( 2.5.13.11 NAME 'caseIgnoreListMatch' "
4908 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )",
4909 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL,
4910 NULL, NULL, NULL, NULL, NULL, NULL},
4912 {"( 2.5.13.12 NAME 'caseIgnoreListSubstringsMatch' "
4913 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4914 SLAP_MR_SUBSTR, NULL,
4915 NULL, NULL, NULL, NULL, NULL, NULL},
4917 {"( 2.5.13.13 NAME 'booleanMatch' "
4918 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )",
4919 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4920 NULL, NULL, booleanMatch, NULL, NULL, NULL},
4922 {"( 2.5.13.14 NAME 'integerMatch' "
4923 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4924 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4926 integerNormalize, integerMatch,
4927 integerIndexer, integerFilter,
4930 {"( 2.5.13.15 NAME 'integerOrderingMatch' "
4931 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4932 SLAP_MR_ORDERING, NULL, NULL,
4933 integerNormalize, integerOrderingMatch,
4934 integerIndexer, integerFilter,
4937 {"( 2.5.13.16 NAME 'bitStringMatch' "
4938 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.6 )",
4939 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4941 bitStringNormalize, bitStringMatch,
4942 bitStringIndexer, bitStringFilter,
4945 {"( 2.5.13.17 NAME 'octetStringMatch' "
4946 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
4947 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4949 octetStringMatch, octetStringIndexer, octetStringFilter,
4952 {"( 2.5.13.18 NAME 'octetStringOrderingMatch' "
4953 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
4954 SLAP_MR_ORDERING, NULL,
4956 octetStringOrderingMatch, NULL, NULL,
4959 {"( 2.5.13.19 NAME 'octetStringSubstringsMatch' "
4960 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
4961 SLAP_MR_SUBSTR, NULL,
4963 octetStringSubstringsMatch, NULL, NULL,
4966 {"( 2.5.13.20 NAME 'telephoneNumberMatch' "
4967 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 )",
4968 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL,
4970 telephoneNumberNormalize, telephoneNumberMatch,
4971 telephoneNumberIndexer, telephoneNumberFilter,
4974 {"( 2.5.13.21 NAME 'telephoneNumberSubstringsMatch' "
4975 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4976 SLAP_MR_SUBSTR, NULL,
4977 NULL, NULL, telephoneNumberSubstringsMatch,
4978 telephoneNumberSubstringsIndexer, telephoneNumberSubstringsFilter,
4981 {"( 2.5.13.22 NAME 'presentationAddressMatch' "
4982 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.43 )",
4983 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4988 {"( 2.5.13.23 NAME 'uniqueMemberMatch' "
4989 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.34 )",
4990 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4992 uniqueMemberNormalize, uniqueMemberMatch,
4996 {"( 2.5.13.24 NAME 'protocolInformationMatch' "
4997 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.42 )",
4998 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4999 NULL, NULL, NULL, NULL, NULL, NULL},
5001 {"( 2.5.13.27 NAME 'generalizedTimeMatch' "
5002 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
5003 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
5005 generalizedTimeNormalize, generalizedTimeMatch,
5009 {"( 2.5.13.28 NAME 'generalizedTimeOrderingMatch' "
5010 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
5011 SLAP_MR_ORDERING, NULL,
5013 generalizedTimeNormalize, generalizedTimeOrderingMatch,
5017 {"( 2.5.13.29 NAME 'integerFirstComponentMatch' "
5018 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
5019 SLAP_MR_EQUALITY | SLAP_MR_EXT, integerFirstComponentMatchSyntaxes,
5021 integerFirstComponentNormalize, integerMatch,
5025 {"( 2.5.13.30 NAME 'objectIdentifierFirstComponentMatch' "
5026 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
5027 SLAP_MR_EQUALITY | SLAP_MR_EXT,
5028 objectIdentifierFirstComponentMatchSyntaxes,
5030 objectIdentifierFirstComponentNormalize, objectIdentifierMatch,
5034 #ifndef SLAP_NVALUES
5036 {"( 2.5.13.34 NAME 'certificateExactMatch' "
5037 "SYNTAX 1.2.826.0.1.3344810.7.1 )",
5038 SLAP_MR_EQUALITY | SLAP_MR_EXT, certificateExactMatchSyntaxes,
5039 certificateExactConvert, NULL,
5040 certificateExactMatch,
5041 certificateExactIndexer, certificateExactFilter,
5046 {"( 1.3.6.1.4.1.1466.109.114.1 NAME 'caseExactIA5Match' "
5047 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
5048 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
5050 caseExactIA5Normalize, caseExactIA5Match,
5051 caseExactIA5Indexer, caseExactIA5Filter,
5052 IA5StringApproxMatchOID },
5054 {"( 1.3.6.1.4.1.1466.109.114.2 NAME 'caseIgnoreIA5Match' "
5055 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
5056 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL,
5058 NULL, caseIgnoreIA5Match,
5059 caseIgnoreIA5Indexer, caseIgnoreIA5Filter,
5060 IA5StringApproxMatchOID },
5062 {"( 1.3.6.1.4.1.1466.109.114.3 NAME 'caseIgnoreIA5SubstringsMatch' "
5063 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
5064 SLAP_MR_SUBSTR, NULL,
5066 NULL, caseIgnoreIA5SubstringsMatch,
5067 caseIgnoreIA5SubstringsIndexer, caseIgnoreIA5SubstringsFilter,
5070 {"( 1.3.6.1.4.1.4203.1.2.1 NAME 'caseExactIA5SubstringsMatch' "
5071 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
5072 SLAP_MR_SUBSTR, NULL,
5074 NULL, caseExactIA5SubstringsMatch,
5075 caseExactIA5SubstringsIndexer, caseExactIA5SubstringsFilter,
5078 #ifdef SLAPD_AUTHPASSWD
5079 /* needs updating */
5080 {"( 1.3.6.1.4.1.4203.666.4.1 NAME 'authPasswordMatch' "
5081 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
5082 SLAP_MR_EQUALITY, NULL,
5084 authPasswordMatch, NULL, NULL,
5088 #ifdef SLAPD_ACI_ENABLED
5089 {"( 1.3.6.1.4.1.4203.666.4.2 NAME 'OpenLDAPaciMatch' "
5090 "SYNTAX 1.3.6.1.4.1.4203.666.2.1 )",
5091 SLAP_MR_EQUALITY, NULL,
5093 OpenLDAPaciMatch, NULL, NULL,
5097 {"( 1.2.840.113556.1.4.803 NAME 'integerBitAndMatch' "
5098 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
5101 NULL, integerBitAndMatch, NULL, NULL,
5104 {"( 1.2.840.113556.1.4.804 NAME 'integerBitOrMatch' "
5105 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
5108 NULL, integerBitOrMatch, NULL, NULL,
5111 {NULL, SLAP_MR_NONE, NULL,
5112 NULL, NULL, NULL, NULL, NULL,
5117 slap_schema_init( void )
5122 /* we should only be called once (from main) */
5123 assert( schema_init_done == 0 );
5125 for ( i=0; syntax_defs[i].sd_desc != NULL; i++ ) {
5126 res = register_syntax( &syntax_defs[i] );
5129 fprintf( stderr, "slap_schema_init: Error registering syntax %s\n",
5130 syntax_defs[i].sd_desc );
5135 for ( i=0; mrule_defs[i].mrd_desc != NULL; i++ ) {
5136 if( mrule_defs[i].mrd_usage == SLAP_MR_NONE &&
5137 mrule_defs[i].mrd_compat_syntaxes == NULL )
5140 "slap_schema_init: Ignoring unusable matching rule %s\n",
5141 mrule_defs[i].mrd_desc );
5145 res = register_matching_rule( &mrule_defs[i] );
5149 "slap_schema_init: Error registering matching rule %s\n",
5150 mrule_defs[i].mrd_desc );
5155 res = slap_schema_load();
5156 schema_init_done = 1;
5161 schema_destroy( void )