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 if ( sa->sa_final.bv_val ) free( sa->sa_final.bv_val );
1889 if ( sa->sa_any ) ber_bvarray_free( sa->sa_any );
1890 if ( sa->sa_initial.bv_val ) free( sa->sa_initial.bv_val );
1891 #ifndef SLAP_NVALUES
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;
2005 if ( sa->sa_final.bv_val ) free( sa->sa_final.bv_val );
2006 if ( sa->sa_any ) ber_bvarray_free( sa->sa_any );
2007 if ( sa->sa_initial.bv_val ) free( sa->sa_initial.bv_val );
2008 #ifndef SLAP_NVALUES
2012 return LDAP_SUCCESS;
2015 #ifndef SLAP_NVALUES
2023 struct berval *value,
2024 void *assertedValue )
2026 *matchp = UTF8bvnormcmp( value,
2027 (struct berval *) assertedValue,
2028 LDAP_UTF8_CASEFOLD );
2029 return LDAP_SUCCESS;
2032 /* Remove all spaces and '-' characters */
2034 xtelephoneNumberNormalize(
2037 struct berval *normalized )
2041 /* validator should have refused an empty string */
2042 assert( val->bv_len );
2044 q = normalized->bv_val = ch_malloc( val->bv_len + 1 );
2046 for( p = val->bv_val; *p; p++ ) {
2047 if ( ! ( ASCII_SPACE( *p ) || *p == '-' )) {
2053 normalized->bv_len = q - normalized->bv_val;
2055 if( normalized->bv_len == 0 ) {
2056 free( normalized->bv_val );
2057 return LDAP_INVALID_SYNTAX;
2060 return LDAP_SUCCESS;
2067 struct berval *val )
2071 if( val->bv_len == 0 ) {
2072 /* disallow empty strings */
2073 return LDAP_INVALID_SYNTAX;
2076 if( OID_LEADCHAR(val->bv_val[0]) ) {
2078 for(i=1; i < val->bv_len; i++) {
2079 if( OID_SEPARATOR( val->bv_val[i] ) ) {
2080 if( dot++ ) return 1;
2081 } else if ( OID_CHAR( val->bv_val[i] ) ) {
2084 return LDAP_INVALID_SYNTAX;
2088 return !dot ? LDAP_SUCCESS : LDAP_INVALID_SYNTAX;
2090 } else if( DESC_LEADCHAR(val->bv_val[0]) ) {
2091 for(i=1; i < val->bv_len; i++) {
2092 if( !DESC_CHAR(val->bv_val[i] ) ) {
2093 return LDAP_INVALID_SYNTAX;
2097 return LDAP_SUCCESS;
2100 return LDAP_INVALID_SYNTAX;
2103 #ifndef SLAP_NVALUES
2111 struct berval *value,
2112 void *assertedValue )
2115 int vsign = 1, avsign = 1; /* default sign = '+' */
2116 struct berval *asserted;
2117 ber_len_t vlen, avlen;
2120 /* Skip leading space/sign/zeroes, and get the sign of the *value number */
2122 vlen = value->bv_len;
2123 if( mr == slap_schema.si_mr_integerFirstComponentMatch ) {
2124 char *tmp = memchr( v, '$', vlen );
2127 while( vlen && ASCII_SPACE( v[vlen-1] ))
2130 for( ; vlen && ( *v < '1' || '9' < *v ); v++, vlen-- ) /* ANSI 2.2.1 */
2136 /* Do the same with the *assertedValue number */
2137 asserted = (struct berval *) assertedValue;
2138 av = asserted->bv_val;
2139 avlen = asserted->bv_len;
2140 for( ; avlen && ( *av < '1' || '9' < *av ); av++, avlen-- )
2146 match = vsign - avsign;
2148 match = (vlen != avlen
2149 ? ( vlen < avlen ? -1 : 1 )
2150 : memcmp( v, av, vlen ));
2156 return LDAP_SUCCESS;
2163 struct berval *val )
2167 if( !val->bv_len ) return LDAP_INVALID_SYNTAX;
2169 if(( val->bv_val[0] == '+' ) || ( val->bv_val[0] == '-' )) {
2170 if( val->bv_len < 2 ) return LDAP_INVALID_SYNTAX;
2171 } else if( !ASCII_DIGIT(val->bv_val[0]) ) {
2172 return LDAP_INVALID_SYNTAX;
2175 for( i=1; i < val->bv_len; i++ ) {
2176 if( !ASCII_DIGIT(val->bv_val[i]) ) return LDAP_INVALID_SYNTAX;
2179 return LDAP_SUCCESS;
2182 #ifndef SLAP_NVALUES
2187 struct berval *normalized )
2197 /* Ignore leading spaces */
2198 while ( len && ( *p == ' ' )) {
2205 negative = ( *p == '-' );
2206 if(( *p == '-' ) || ( *p == '+' )) {
2212 /* Ignore leading zeros */
2213 while ( len && ( *p == '0' )) {
2218 /* If there are no non-zero digits left, the number is zero, otherwise
2219 allocate space for the number and copy it into the buffer */
2221 normalized->bv_val = ch_strdup("0");
2222 normalized->bv_len = 1;
2225 normalized->bv_len = len+negative;
2226 normalized->bv_val = ch_malloc( normalized->bv_len + 1 );
2228 normalized->bv_val[0] = '-';
2230 AC_MEMCPY( normalized->bv_val + negative, p, len );
2231 normalized->bv_val[len+negative] = '\0';
2234 return LDAP_SUCCESS;
2237 /* Index generation function */
2238 static int integerIndexer(
2243 struct berval *prefix,
2250 HASH_CONTEXT HASHcontext;
2251 unsigned char HASHdigest[HASH_BYTES];
2252 struct berval digest;
2253 digest.bv_val = HASHdigest;
2254 digest.bv_len = sizeof(HASHdigest);
2256 for( i=0; values[i].bv_val != NULL; i++ ) {
2257 /* empty - just count them */
2260 /* we should have at least one value at this point */
2263 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
2265 slen = syntax->ssyn_oidlen;
2266 mlen = mr->smr_oidlen;
2268 for( i=0; values[i].bv_val != NULL; i++ ) {
2270 xintegerNormalize( syntax, &values[i], &norm );
2272 HASH_Init( &HASHcontext );
2273 if( prefix != NULL && prefix->bv_len > 0 ) {
2274 HASH_Update( &HASHcontext,
2275 prefix->bv_val, prefix->bv_len );
2277 HASH_Update( &HASHcontext,
2278 syntax->ssyn_oid, slen );
2279 HASH_Update( &HASHcontext,
2280 mr->smr_oid, mlen );
2281 HASH_Update( &HASHcontext,
2282 norm.bv_val, norm.bv_len );
2283 HASH_Final( HASHdigest, &HASHcontext );
2285 ber_dupbv( &keys[i], &digest );
2286 ch_free( norm.bv_val );
2289 keys[i].bv_val = NULL;
2291 return LDAP_SUCCESS;
2294 /* Index generation function */
2295 static int integerFilter(
2300 struct berval *prefix,
2301 void * assertedValue,
2306 HASH_CONTEXT HASHcontext;
2307 unsigned char HASHdigest[HASH_BYTES];
2309 struct berval digest;
2310 digest.bv_val = HASHdigest;
2311 digest.bv_len = sizeof(HASHdigest);
2313 slen = syntax->ssyn_oidlen;
2314 mlen = mr->smr_oidlen;
2316 xintegerNormalize( syntax, assertedValue, &norm );
2318 keys = ch_malloc( sizeof( struct berval ) * 2 );
2320 HASH_Init( &HASHcontext );
2321 if( prefix != NULL && prefix->bv_len > 0 ) {
2322 HASH_Update( &HASHcontext,
2323 prefix->bv_val, prefix->bv_len );
2325 HASH_Update( &HASHcontext,
2326 syntax->ssyn_oid, slen );
2327 HASH_Update( &HASHcontext,
2328 mr->smr_oid, mlen );
2329 HASH_Update( &HASHcontext,
2330 norm.bv_val, norm.bv_len );
2331 HASH_Final( HASHdigest, &HASHcontext );
2333 ber_dupbv( &keys[0], &digest );
2334 keys[1].bv_val = NULL;
2335 ch_free( norm.bv_val );
2338 return LDAP_SUCCESS;
2344 countryStringValidate(
2346 struct berval *val )
2348 if( val->bv_len != 2 ) return LDAP_INVALID_SYNTAX;
2350 if( !SLAP_PRINTABLE(val->bv_val[0]) ) {
2351 return LDAP_INVALID_SYNTAX;
2353 if( !SLAP_PRINTABLE(val->bv_val[1]) ) {
2354 return LDAP_INVALID_SYNTAX;
2357 return LDAP_SUCCESS;
2361 printableStringValidate(
2363 struct berval *val )
2367 if( val->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
2369 for(i=0; i < val->bv_len; i++) {
2370 if( !SLAP_PRINTABLE(val->bv_val[i]) ) {
2371 return LDAP_INVALID_SYNTAX;
2375 return LDAP_SUCCESS;
2379 printablesStringValidate(
2381 struct berval *val )
2385 if( val->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
2387 for(i=0,len=0; i < val->bv_len; i++) {
2388 int c = val->bv_val[i];
2392 return LDAP_INVALID_SYNTAX;
2396 } else if ( SLAP_PRINTABLE(c) ) {
2399 return LDAP_INVALID_SYNTAX;
2404 return LDAP_INVALID_SYNTAX;
2407 return LDAP_SUCCESS;
2413 struct berval *val )
2417 if( val->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
2419 for(i=0; i < val->bv_len; i++) {
2420 if( !LDAP_ASCII(val->bv_val[i]) ) {
2421 return LDAP_INVALID_SYNTAX;
2425 return LDAP_SUCCESS;
2435 struct berval *normalized )
2438 xIA5StringNormalize(
2441 struct berval *normalized )
2446 int casefold = !SLAP_MR_ASSOCIATED(mr, slap_schema.si_mr_caseExactIA5Match);
2449 assert( val->bv_len );
2453 /* Ignore initial whitespace */
2454 while ( ASCII_SPACE( *p ) ) {
2458 normalized->bv_val = ch_strdup( p );
2459 p = q = normalized->bv_val;
2462 if ( ASCII_SPACE( *p ) ) {
2465 /* Ignore the extra whitespace */
2466 while ( ASCII_SPACE( *p ) ) {
2471 } else if ( casefold ) {
2472 /* Most IA5 rules require casefolding */
2473 *q++ = TOLOWER(*p++);
2481 assert( normalized->bv_val <= p );
2485 * If the string ended in space, backup the pointer one
2486 * position. One is enough because the above loop collapsed
2487 * all whitespace to a single space.
2490 if ( ASCII_SPACE( q[-1] ) ) {
2494 /* null terminate */
2497 normalized->bv_len = q - normalized->bv_val;
2499 if( normalized->bv_len == 0 ) {
2500 normalized->bv_val = ch_realloc( normalized->bv_val, 2 );
2501 normalized->bv_val[0] = ' ';
2502 normalized->bv_val[1] = '\0';
2503 normalized->bv_len = 1;
2506 return LDAP_SUCCESS;
2509 #ifndef SLAP_NVALUES
2517 struct berval *value,
2518 void *assertedValue )
2520 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
2523 match = strncmp( value->bv_val,
2524 ((struct berval *) assertedValue)->bv_val,
2529 return LDAP_SUCCESS;
2533 caseExactIA5SubstringsMatch
2536 octetStringSubstringsMatch
2543 struct berval *value,
2544 void *assertedValue )
2547 SubstringsAssertion *sub = assertedValue;
2548 struct berval left = *value;
2552 /* Add up asserted input length */
2553 if( sub->sa_initial.bv_val ) {
2554 inlen += sub->sa_initial.bv_len;
2557 for(i=0; sub->sa_any[i].bv_val != NULL; i++) {
2558 inlen += sub->sa_any[i].bv_len;
2561 if( sub->sa_final.bv_val ) {
2562 inlen += sub->sa_final.bv_len;
2565 if( sub->sa_initial.bv_val ) {
2566 if( inlen > left.bv_len ) {
2571 match = memcmp( sub->sa_initial.bv_val, left.bv_val,
2572 sub->sa_initial.bv_len );
2578 left.bv_val += sub->sa_initial.bv_len;
2579 left.bv_len -= sub->sa_initial.bv_len;
2580 inlen -= sub->sa_initial.bv_len;
2583 if( sub->sa_final.bv_val ) {
2584 if( inlen > left.bv_len ) {
2589 match = memcmp( sub->sa_final.bv_val,
2590 &left.bv_val[left.bv_len - sub->sa_final.bv_len],
2591 sub->sa_final.bv_len );
2597 left.bv_len -= sub->sa_final.bv_len;
2598 inlen -= sub->sa_final.bv_len;
2602 for(i=0; sub->sa_any[i].bv_val; i++) {
2607 if( inlen > left.bv_len ) {
2608 /* not enough length */
2613 if( sub->sa_any[i].bv_len == 0 ) {
2617 p = memchr( left.bv_val, *sub->sa_any[i].bv_val, left.bv_len );
2624 idx = p - left.bv_val;
2626 if( idx >= left.bv_len ) {
2627 /* this shouldn't happen */
2634 if( sub->sa_any[i].bv_len > left.bv_len ) {
2635 /* not enough left */
2640 match = memcmp( left.bv_val,
2641 sub->sa_any[i].bv_val,
2642 sub->sa_any[i].bv_len );
2650 left.bv_val += sub->sa_any[i].bv_len;
2651 left.bv_len -= sub->sa_any[i].bv_len;
2652 inlen -= sub->sa_any[i].bv_len;
2658 return LDAP_SUCCESS;
2661 #ifndef SLAP_NVALUES
2663 /* Index generation function */
2664 static int caseExactIA5Indexer(
2669 struct berval *prefix,
2676 HASH_CONTEXT HASHcontext;
2677 unsigned char HASHdigest[HASH_BYTES];
2678 struct berval digest;
2679 digest.bv_val = HASHdigest;
2680 digest.bv_len = sizeof(HASHdigest);
2682 for( i=0; values[i].bv_val != NULL; i++ ) {
2683 /* empty - just count them */
2686 /* we should have at least one value at this point */
2689 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
2691 slen = syntax->ssyn_oidlen;
2692 mlen = mr->smr_oidlen;
2694 for( i=0; values[i].bv_val != NULL; i++ ) {
2695 struct berval *value = &values[i];
2697 HASH_Init( &HASHcontext );
2698 if( prefix != NULL && prefix->bv_len > 0 ) {
2699 HASH_Update( &HASHcontext,
2700 prefix->bv_val, prefix->bv_len );
2702 HASH_Update( &HASHcontext,
2703 syntax->ssyn_oid, slen );
2704 HASH_Update( &HASHcontext,
2705 mr->smr_oid, mlen );
2706 HASH_Update( &HASHcontext,
2707 value->bv_val, value->bv_len );
2708 HASH_Final( HASHdigest, &HASHcontext );
2710 ber_dupbv( &keys[i], &digest );
2713 keys[i].bv_val = NULL;
2715 return LDAP_SUCCESS;
2718 /* Index generation function */
2719 static int caseExactIA5Filter(
2724 struct berval *prefix,
2725 void * assertedValue,
2730 HASH_CONTEXT HASHcontext;
2731 unsigned char HASHdigest[HASH_BYTES];
2732 struct berval *value;
2733 struct berval digest;
2734 digest.bv_val = HASHdigest;
2735 digest.bv_len = sizeof(HASHdigest);
2737 slen = syntax->ssyn_oidlen;
2738 mlen = mr->smr_oidlen;
2740 value = (struct berval *) assertedValue;
2742 keys = ch_malloc( sizeof( struct berval ) * 2 );
2744 HASH_Init( &HASHcontext );
2745 if( prefix != NULL && prefix->bv_len > 0 ) {
2746 HASH_Update( &HASHcontext,
2747 prefix->bv_val, prefix->bv_len );
2749 HASH_Update( &HASHcontext,
2750 syntax->ssyn_oid, slen );
2751 HASH_Update( &HASHcontext,
2752 mr->smr_oid, mlen );
2753 HASH_Update( &HASHcontext,
2754 value->bv_val, value->bv_len );
2755 HASH_Final( HASHdigest, &HASHcontext );
2757 ber_dupbv( &keys[0], &digest );
2758 keys[1].bv_val = NULL;
2761 return LDAP_SUCCESS;
2764 /* Substrings Index generation function */
2765 static int caseExactIA5SubstringsIndexer(
2770 struct berval *prefix,
2777 HASH_CONTEXT HASHcontext;
2778 unsigned char HASHdigest[HASH_BYTES];
2779 struct berval digest;
2780 digest.bv_val = HASHdigest;
2781 digest.bv_len = sizeof(HASHdigest);
2783 /* we should have at least one value at this point */
2784 assert( values != NULL && values[0].bv_val != NULL );
2787 for( i=0; values[i].bv_val != NULL; i++ ) {
2788 /* count number of indices to generate */
2789 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
2793 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
2794 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2795 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2796 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2798 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2802 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
2803 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2804 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
2808 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
2809 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2810 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2811 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2813 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2819 /* no keys to generate */
2821 return LDAP_SUCCESS;
2824 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
2826 slen = syntax->ssyn_oidlen;
2827 mlen = mr->smr_oidlen;
2830 for( i=0; values[i].bv_val != NULL; i++ ) {
2832 struct berval *value;
2835 if( value->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
2837 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
2838 ( value->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
2840 char pre = SLAP_INDEX_SUBSTR_PREFIX;
2841 max = value->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
2843 for( j=0; j<max; j++ ) {
2844 HASH_Init( &HASHcontext );
2845 if( prefix != NULL && prefix->bv_len > 0 ) {
2846 HASH_Update( &HASHcontext,
2847 prefix->bv_val, prefix->bv_len );
2850 HASH_Update( &HASHcontext,
2851 &pre, sizeof( pre ) );
2852 HASH_Update( &HASHcontext,
2853 syntax->ssyn_oid, slen );
2854 HASH_Update( &HASHcontext,
2855 mr->smr_oid, mlen );
2856 HASH_Update( &HASHcontext,
2858 SLAP_INDEX_SUBSTR_MAXLEN );
2859 HASH_Final( HASHdigest, &HASHcontext );
2861 ber_dupbv( &keys[nkeys++], &digest );
2865 max = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2866 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2868 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
2871 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
2872 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
2873 HASH_Init( &HASHcontext );
2874 if( prefix != NULL && prefix->bv_len > 0 ) {
2875 HASH_Update( &HASHcontext,
2876 prefix->bv_val, prefix->bv_len );
2878 HASH_Update( &HASHcontext,
2879 &pre, sizeof( pre ) );
2880 HASH_Update( &HASHcontext,
2881 syntax->ssyn_oid, slen );
2882 HASH_Update( &HASHcontext,
2883 mr->smr_oid, mlen );
2884 HASH_Update( &HASHcontext,
2886 HASH_Final( HASHdigest, &HASHcontext );
2888 ber_dupbv( &keys[nkeys++], &digest );
2891 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
2892 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
2893 HASH_Init( &HASHcontext );
2894 if( prefix != NULL && prefix->bv_len > 0 ) {
2895 HASH_Update( &HASHcontext,
2896 prefix->bv_val, prefix->bv_len );
2898 HASH_Update( &HASHcontext,
2899 &pre, sizeof( pre ) );
2900 HASH_Update( &HASHcontext,
2901 syntax->ssyn_oid, slen );
2902 HASH_Update( &HASHcontext,
2903 mr->smr_oid, mlen );
2904 HASH_Update( &HASHcontext,
2905 &value->bv_val[value->bv_len-j], j );
2906 HASH_Final( HASHdigest, &HASHcontext );
2908 ber_dupbv( &keys[nkeys++], &digest );
2915 keys[nkeys].bv_val = NULL;
2922 return LDAP_SUCCESS;
2925 static int caseExactIA5SubstringsFilter(
2930 struct berval *prefix,
2931 void * assertedValue,
2934 SubstringsAssertion *sa = assertedValue;
2936 ber_len_t nkeys = 0;
2937 size_t slen, mlen, klen;
2939 HASH_CONTEXT HASHcontext;
2940 unsigned char HASHdigest[HASH_BYTES];
2941 struct berval *value;
2942 struct berval digest;
2944 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
2945 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2950 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
2952 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
2953 if( sa->sa_any[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2954 /* don't bother accounting for stepping */
2955 nkeys += sa->sa_any[i].bv_len -
2956 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
2961 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
2962 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2969 return LDAP_SUCCESS;
2972 digest.bv_val = HASHdigest;
2973 digest.bv_len = sizeof(HASHdigest);
2975 slen = syntax->ssyn_oidlen;
2976 mlen = mr->smr_oidlen;
2978 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
2981 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
2982 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2984 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
2985 value = &sa->sa_initial;
2987 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2988 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2990 HASH_Init( &HASHcontext );
2991 if( prefix != NULL && prefix->bv_len > 0 ) {
2992 HASH_Update( &HASHcontext,
2993 prefix->bv_val, prefix->bv_len );
2995 HASH_Update( &HASHcontext,
2996 &pre, sizeof( pre ) );
2997 HASH_Update( &HASHcontext,
2998 syntax->ssyn_oid, slen );
2999 HASH_Update( &HASHcontext,
3000 mr->smr_oid, mlen );
3001 HASH_Update( &HASHcontext,
3002 value->bv_val, klen );
3003 HASH_Final( HASHdigest, &HASHcontext );
3005 ber_dupbv( &keys[nkeys++], &digest );
3008 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
3010 pre = SLAP_INDEX_SUBSTR_PREFIX;
3011 klen = SLAP_INDEX_SUBSTR_MAXLEN;
3013 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
3014 if( sa->sa_any[i].bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
3018 value = &sa->sa_any[i];
3021 j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
3022 j += SLAP_INDEX_SUBSTR_STEP )
3024 HASH_Init( &HASHcontext );
3025 if( prefix != NULL && prefix->bv_len > 0 ) {
3026 HASH_Update( &HASHcontext,
3027 prefix->bv_val, prefix->bv_len );
3029 HASH_Update( &HASHcontext,
3030 &pre, sizeof( pre ) );
3031 HASH_Update( &HASHcontext,
3032 syntax->ssyn_oid, slen );
3033 HASH_Update( &HASHcontext,
3034 mr->smr_oid, mlen );
3035 HASH_Update( &HASHcontext,
3036 &value->bv_val[j], klen );
3037 HASH_Final( HASHdigest, &HASHcontext );
3039 ber_dupbv( &keys[nkeys++], &digest );
3044 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
3045 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3047 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
3048 value = &sa->sa_final;
3050 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
3051 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
3053 HASH_Init( &HASHcontext );
3054 if( prefix != NULL && prefix->bv_len > 0 ) {
3055 HASH_Update( &HASHcontext,
3056 prefix->bv_val, prefix->bv_len );
3058 HASH_Update( &HASHcontext,
3059 &pre, sizeof( pre ) );
3060 HASH_Update( &HASHcontext,
3061 syntax->ssyn_oid, slen );
3062 HASH_Update( &HASHcontext,
3063 mr->smr_oid, mlen );
3064 HASH_Update( &HASHcontext,
3065 &value->bv_val[value->bv_len-klen], klen );
3066 HASH_Final( HASHdigest, &HASHcontext );
3068 ber_dupbv( &keys[nkeys++], &digest );
3072 keys[nkeys].bv_val = NULL;
3079 return LDAP_SUCCESS;
3088 struct berval *value,
3089 void *assertedValue )
3091 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
3093 if( match == 0 && value->bv_len ) {
3094 match = strncasecmp( value->bv_val,
3095 ((struct berval *) assertedValue)->bv_val,
3100 return LDAP_SUCCESS;
3104 caseIgnoreIA5SubstringsMatch(
3109 struct berval *value,
3110 void *assertedValue )
3113 SubstringsAssertion *sub = assertedValue;
3114 struct berval left = *value;
3118 /* Add up asserted input length */
3119 if( sub->sa_initial.bv_val ) {
3120 inlen += sub->sa_initial.bv_len;
3123 for(i=0; sub->sa_any[i].bv_val != NULL; i++) {
3124 inlen += sub->sa_any[i].bv_len;
3127 if( sub->sa_final.bv_val ) {
3128 inlen += sub->sa_final.bv_len;
3131 if( sub->sa_initial.bv_val ) {
3132 if( inlen > left.bv_len ) {
3137 match = strncasecmp( sub->sa_initial.bv_val, left.bv_val,
3138 sub->sa_initial.bv_len );
3144 left.bv_val += sub->sa_initial.bv_len;
3145 left.bv_len -= sub->sa_initial.bv_len;
3146 inlen -= sub->sa_initial.bv_len;
3149 if( sub->sa_final.bv_val ) {
3150 if( inlen > left.bv_len ) {
3155 match = strncasecmp( sub->sa_final.bv_val,
3156 &left.bv_val[left.bv_len - sub->sa_final.bv_len],
3157 sub->sa_final.bv_len );
3163 left.bv_len -= sub->sa_final.bv_len;
3164 inlen -= sub->sa_final.bv_len;
3168 for(i=0; sub->sa_any[i].bv_val; i++) {
3173 if( inlen > left.bv_len ) {
3174 /* not enough length */
3179 if( sub->sa_any[i].bv_len == 0 ) {
3183 p = bvcasechr( &left, *sub->sa_any[i].bv_val, &idx );
3190 assert( idx < left.bv_len );
3191 if( idx >= left.bv_len ) {
3192 /* this shouldn't happen */
3199 if( sub->sa_any[i].bv_len > left.bv_len ) {
3200 /* not enough left */
3205 match = strncasecmp( left.bv_val,
3206 sub->sa_any[i].bv_val,
3207 sub->sa_any[i].bv_len );
3216 left.bv_val += sub->sa_any[i].bv_len;
3217 left.bv_len -= sub->sa_any[i].bv_len;
3218 inlen -= sub->sa_any[i].bv_len;
3224 return LDAP_SUCCESS;
3227 /* Index generation function */
3228 static int caseIgnoreIA5Indexer(
3233 struct berval *prefix,
3238 int rc = LDAP_SUCCESS;
3241 HASH_CONTEXT HASHcontext;
3242 unsigned char HASHdigest[HASH_BYTES];
3243 struct berval digest;
3244 digest.bv_val = HASHdigest;
3245 digest.bv_len = sizeof(HASHdigest);
3247 /* we should have at least one value at this point */
3248 assert( values != NULL && values[0].bv_val != NULL );
3250 for( i=0; values[i].bv_val != NULL; i++ ) {
3251 /* just count them */
3254 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
3256 slen = syntax->ssyn_oidlen;
3257 mlen = mr->smr_oidlen;
3259 for( i=0; values[i].bv_val != NULL; i++ ) {
3260 struct berval value;
3262 if( mr->smr_normalize ) {
3263 rc = (mr->smr_normalize)( use, syntax, mr, &values[i], &value );
3264 if( rc != LDAP_SUCCESS ) {
3267 #ifndef SLAP_NVALUES
3268 } else if ( mr->smr_syntax->ssyn_normalize ) {
3269 rc = (mr->smr_syntax->ssyn_normalize)( syntax, &values[i], &value );
3270 if( rc != LDAP_SUCCESS ) {
3275 ber_dupbv( &value, &values[i] );
3278 ldap_pvt_str2lower( value.bv_val );
3280 HASH_Init( &HASHcontext );
3281 if( prefix != NULL && prefix->bv_len > 0 ) {
3282 HASH_Update( &HASHcontext,
3283 prefix->bv_val, prefix->bv_len );
3285 HASH_Update( &HASHcontext,
3286 syntax->ssyn_oid, slen );
3287 HASH_Update( &HASHcontext,
3288 mr->smr_oid, mlen );
3289 HASH_Update( &HASHcontext,
3290 value.bv_val, value.bv_len );
3291 HASH_Final( HASHdigest, &HASHcontext );
3293 free( value.bv_val );
3295 ber_dupbv( &keys[i], &digest );
3298 keys[i].bv_val = NULL;
3299 if( rc != LDAP_SUCCESS ) {
3300 ber_bvarray_free( keys );
3307 /* Index generation function */
3308 static int caseIgnoreIA5Filter(
3313 struct berval *prefix,
3314 void * assertedValue,
3319 HASH_CONTEXT HASHcontext;
3320 unsigned char HASHdigest[HASH_BYTES];
3321 struct berval value;
3322 struct berval digest;
3323 digest.bv_val = HASHdigest;
3324 digest.bv_len = sizeof(HASHdigest);
3326 slen = syntax->ssyn_oidlen;
3327 mlen = mr->smr_oidlen;
3329 ber_dupbv( &value, (struct berval *) assertedValue );
3330 ldap_pvt_str2lower( value.bv_val );
3332 keys = ch_malloc( sizeof( struct berval ) * 2 );
3334 HASH_Init( &HASHcontext );
3335 if( prefix != NULL && prefix->bv_len > 0 ) {
3336 HASH_Update( &HASHcontext,
3337 prefix->bv_val, prefix->bv_len );
3339 HASH_Update( &HASHcontext,
3340 syntax->ssyn_oid, slen );
3341 HASH_Update( &HASHcontext,
3342 mr->smr_oid, mlen );
3343 HASH_Update( &HASHcontext,
3344 value.bv_val, value.bv_len );
3345 HASH_Final( HASHdigest, &HASHcontext );
3347 ber_dupbv( &keys[0], &digest );
3348 keys[1].bv_val = NULL;
3350 free( value.bv_val );
3354 return LDAP_SUCCESS;
3357 /* Substrings Index generation function */
3358 static int caseIgnoreIA5SubstringsIndexer(
3363 struct berval *prefix,
3370 HASH_CONTEXT HASHcontext;
3371 unsigned char HASHdigest[HASH_BYTES];
3372 struct berval digest;
3373 digest.bv_val = HASHdigest;
3374 digest.bv_len = sizeof(HASHdigest);
3376 /* we should have at least one value at this point */
3377 assert( values != NULL && values[0].bv_val != NULL );
3380 for( i=0; values[i].bv_val != NULL; i++ ) {
3381 /* count number of indices to generate */
3382 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
3386 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
3387 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3388 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
3389 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
3391 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
3395 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
3396 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3397 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
3401 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
3402 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3403 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
3404 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
3406 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
3412 /* no keys to generate */
3414 return LDAP_SUCCESS;
3417 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
3419 slen = syntax->ssyn_oidlen;
3420 mlen = mr->smr_oidlen;
3423 for( i=0; values[i].bv_val != NULL; i++ ) {
3425 struct berval value;
3427 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
3429 ber_dupbv( &value, &values[i] );
3430 ldap_pvt_str2lower( value.bv_val );
3432 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
3433 ( value.bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
3435 char pre = SLAP_INDEX_SUBSTR_PREFIX;
3436 max = value.bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
3438 for( j=0; j<max; j++ ) {
3439 HASH_Init( &HASHcontext );
3440 if( prefix != NULL && prefix->bv_len > 0 ) {
3441 HASH_Update( &HASHcontext,
3442 prefix->bv_val, prefix->bv_len );
3445 HASH_Update( &HASHcontext,
3446 &pre, sizeof( pre ) );
3447 HASH_Update( &HASHcontext,
3448 syntax->ssyn_oid, slen );
3449 HASH_Update( &HASHcontext,
3450 mr->smr_oid, mlen );
3451 HASH_Update( &HASHcontext,
3453 SLAP_INDEX_SUBSTR_MAXLEN );
3454 HASH_Final( HASHdigest, &HASHcontext );
3456 ber_dupbv( &keys[nkeys++], &digest );
3460 max = SLAP_INDEX_SUBSTR_MAXLEN < value.bv_len
3461 ? SLAP_INDEX_SUBSTR_MAXLEN : value.bv_len;
3463 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
3466 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
3467 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
3468 HASH_Init( &HASHcontext );
3469 if( prefix != NULL && prefix->bv_len > 0 ) {
3470 HASH_Update( &HASHcontext,
3471 prefix->bv_val, prefix->bv_len );
3473 HASH_Update( &HASHcontext,
3474 &pre, sizeof( pre ) );
3475 HASH_Update( &HASHcontext,
3476 syntax->ssyn_oid, slen );
3477 HASH_Update( &HASHcontext,
3478 mr->smr_oid, mlen );
3479 HASH_Update( &HASHcontext,
3481 HASH_Final( HASHdigest, &HASHcontext );
3483 ber_dupbv( &keys[nkeys++], &digest );
3486 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
3487 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
3488 HASH_Init( &HASHcontext );
3489 if( prefix != NULL && prefix->bv_len > 0 ) {
3490 HASH_Update( &HASHcontext,
3491 prefix->bv_val, prefix->bv_len );
3493 HASH_Update( &HASHcontext,
3494 &pre, sizeof( pre ) );
3495 HASH_Update( &HASHcontext,
3496 syntax->ssyn_oid, slen );
3497 HASH_Update( &HASHcontext,
3498 mr->smr_oid, mlen );
3499 HASH_Update( &HASHcontext,
3500 &value.bv_val[value.bv_len-j], j );
3501 HASH_Final( HASHdigest, &HASHcontext );
3503 ber_dupbv( &keys[nkeys++], &digest );
3508 free( value.bv_val );
3512 keys[nkeys].bv_val = NULL;
3519 return LDAP_SUCCESS;
3522 static int caseIgnoreIA5SubstringsFilter(
3527 struct berval *prefix,
3528 void * assertedValue,
3531 SubstringsAssertion *sa = assertedValue;
3533 ber_len_t nkeys = 0;
3534 size_t slen, mlen, klen;
3536 HASH_CONTEXT HASHcontext;
3537 unsigned char HASHdigest[HASH_BYTES];
3538 struct berval value;
3539 struct berval digest;
3541 if((flags & SLAP_INDEX_SUBSTR_INITIAL) && sa->sa_initial.bv_val != NULL &&
3542 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3547 if((flags & SLAP_INDEX_SUBSTR_ANY) && sa->sa_any != NULL ) {
3549 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
3550 if( sa->sa_any[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3551 /* don't bother accounting for stepping */
3552 nkeys += sa->sa_any[i].bv_len -
3553 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
3558 if((flags & SLAP_INDEX_SUBSTR_FINAL) && sa->sa_final.bv_val != NULL &&
3559 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3566 return LDAP_SUCCESS;
3569 digest.bv_val = HASHdigest;
3570 digest.bv_len = sizeof(HASHdigest);
3572 slen = syntax->ssyn_oidlen;
3573 mlen = mr->smr_oidlen;
3575 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
3578 if((flags & SLAP_INDEX_SUBSTR_INITIAL) && sa->sa_initial.bv_val != NULL &&
3579 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3581 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
3582 ber_dupbv( &value, &sa->sa_initial );
3583 ldap_pvt_str2lower( value.bv_val );
3585 klen = SLAP_INDEX_SUBSTR_MAXLEN < value.bv_len
3586 ? SLAP_INDEX_SUBSTR_MAXLEN : value.bv_len;
3588 HASH_Init( &HASHcontext );
3589 if( prefix != NULL && prefix->bv_len > 0 ) {
3590 HASH_Update( &HASHcontext,
3591 prefix->bv_val, prefix->bv_len );
3593 HASH_Update( &HASHcontext,
3594 &pre, sizeof( pre ) );
3595 HASH_Update( &HASHcontext,
3596 syntax->ssyn_oid, slen );
3597 HASH_Update( &HASHcontext,
3598 mr->smr_oid, mlen );
3599 HASH_Update( &HASHcontext,
3600 value.bv_val, klen );
3601 HASH_Final( HASHdigest, &HASHcontext );
3603 free( value.bv_val );
3604 ber_dupbv( &keys[nkeys++], &digest );
3607 if((flags & SLAP_INDEX_SUBSTR_ANY) && sa->sa_any != NULL ) {
3609 pre = SLAP_INDEX_SUBSTR_PREFIX;
3610 klen = SLAP_INDEX_SUBSTR_MAXLEN;
3612 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
3613 if( sa->sa_any[i].bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
3617 ber_dupbv( &value, &sa->sa_any[i] );
3618 ldap_pvt_str2lower( value.bv_val );
3621 j <= value.bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
3622 j += SLAP_INDEX_SUBSTR_STEP )
3624 HASH_Init( &HASHcontext );
3625 if( prefix != NULL && prefix->bv_len > 0 ) {
3626 HASH_Update( &HASHcontext,
3627 prefix->bv_val, prefix->bv_len );
3629 HASH_Update( &HASHcontext,
3630 &pre, sizeof( pre ) );
3631 HASH_Update( &HASHcontext,
3632 syntax->ssyn_oid, slen );
3633 HASH_Update( &HASHcontext,
3634 mr->smr_oid, mlen );
3635 HASH_Update( &HASHcontext,
3636 &value.bv_val[j], klen );
3637 HASH_Final( HASHdigest, &HASHcontext );
3639 ber_dupbv( &keys[nkeys++], &digest );
3642 free( value.bv_val );
3646 if((flags & SLAP_INDEX_SUBSTR_FINAL) && sa->sa_final.bv_val != NULL &&
3647 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3649 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
3650 ber_dupbv( &value, &sa->sa_final );
3651 ldap_pvt_str2lower( value.bv_val );
3653 klen = SLAP_INDEX_SUBSTR_MAXLEN < value.bv_len
3654 ? SLAP_INDEX_SUBSTR_MAXLEN : value.bv_len;
3656 HASH_Init( &HASHcontext );
3657 if( prefix != NULL && prefix->bv_len > 0 ) {
3658 HASH_Update( &HASHcontext,
3659 prefix->bv_val, prefix->bv_len );
3661 HASH_Update( &HASHcontext,
3662 &pre, sizeof( pre ) );
3663 HASH_Update( &HASHcontext,
3664 syntax->ssyn_oid, slen );
3665 HASH_Update( &HASHcontext,
3666 mr->smr_oid, mlen );
3667 HASH_Update( &HASHcontext,
3668 &value.bv_val[value.bv_len-klen], klen );
3669 HASH_Final( HASHdigest, &HASHcontext );
3671 free( value.bv_val );
3672 ber_dupbv( &keys[nkeys++], &digest );
3676 keys[nkeys].bv_val = NULL;
3683 return LDAP_SUCCESS;
3689 numericStringValidate(
3695 if( in->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
3697 for(i=0; i < in->bv_len; i++) {
3698 if( !SLAP_NUMERIC(in->bv_val[i]) ) {
3699 return LDAP_INVALID_SYNTAX;
3703 return LDAP_SUCCESS;
3706 #ifndef SLAP_NVALUES
3709 xnumericStringNormalize(
3712 struct berval *normalized )
3714 /* removal all spaces */
3717 assert( val->bv_len );
3719 normalized->bv_val = ch_malloc( val->bv_len + 1 );
3722 q = normalized->bv_val;
3725 if ( ASCII_SPACE( *p ) ) {
3726 /* Ignore whitespace */
3733 /* we should have copied no more then is in val */
3734 assert( (q - normalized->bv_val) <= (p - val->bv_val) );
3736 /* null terminate */
3739 normalized->bv_len = q - normalized->bv_val;
3741 if( normalized->bv_len == 0 ) {
3742 normalized->bv_val = ch_realloc( normalized->bv_val, 2 );
3743 normalized->bv_val[0] = ' ';
3744 normalized->bv_val[1] = '\0';
3745 normalized->bv_len = 1;
3748 return LDAP_SUCCESS;
3752 objectIdentifierFirstComponentMatch(
3757 struct berval *value,
3758 void *assertedValue )
3760 int rc = LDAP_SUCCESS;
3762 struct berval *asserted = (struct berval *) assertedValue;
3766 if( value->bv_len == 0 || value->bv_val[0] != '(' /*')'*/ ) {
3767 return LDAP_INVALID_SYNTAX;
3770 /* trim leading white space */
3771 for( i=1; ASCII_SPACE(value->bv_val[i]) && i < value->bv_len; i++ ) {
3775 /* grab next word */
3776 oid.bv_val = &value->bv_val[i];
3777 j = value->bv_len - i;
3778 for( i=0; !ASCII_SPACE(oid.bv_val[i]) && i < j; i++ ) {
3783 /* insert attributeTypes, objectclass check here */
3784 if( OID_LEADCHAR(asserted->bv_val[0]) ) {
3785 rc = objectIdentifierMatch( &match, flags, syntax, mr, &oid, asserted );
3788 if ( !strcmp( syntax->ssyn_oid, SLAP_SYNTAX_MATCHINGRULES_OID ) ) {
3789 MatchingRule *asserted_mr = mr_bvfind( asserted );
3790 MatchingRule *stored_mr = mr_bvfind( &oid );
3792 if( asserted_mr == NULL ) {
3793 rc = SLAPD_COMPARE_UNDEFINED;
3795 match = asserted_mr != stored_mr;
3798 } else if ( !strcmp( syntax->ssyn_oid,
3799 SLAP_SYNTAX_ATTRIBUTETYPES_OID ) )
3801 AttributeType *asserted_at = at_bvfind( asserted );
3802 AttributeType *stored_at = at_bvfind( &oid );
3804 if( asserted_at == NULL ) {
3805 rc = SLAPD_COMPARE_UNDEFINED;
3807 match = asserted_at != stored_at;
3810 } else if ( !strcmp( syntax->ssyn_oid,
3811 SLAP_SYNTAX_OBJECTCLASSES_OID ) )
3813 ObjectClass *asserted_oc = oc_bvfind( asserted );
3814 ObjectClass *stored_oc = oc_bvfind( &oid );
3816 if( asserted_oc == NULL ) {
3817 rc = SLAPD_COMPARE_UNDEFINED;
3819 match = asserted_oc != stored_oc;
3825 LDAP_LOG( CONFIG, ENTRY,
3826 "objectIdentifierFirstComponentMatch: %d\n %s\n %s\n",
3827 match, value->bv_val, asserted->bv_val );
3829 Debug( LDAP_DEBUG_ARGS, "objectIdentifierFirstComponentMatch "
3830 "%d\n\t\"%s\"\n\t\"%s\"\n",
3831 match, value->bv_val, asserted->bv_val );
3834 if( rc == LDAP_SUCCESS ) *matchp = match;
3846 struct berval *value,
3847 void *assertedValue )
3849 long lValue, lAssertedValue;
3851 /* safe to assume integers are NUL terminated? */
3852 lValue = strtol(value->bv_val, NULL, 10);
3853 if(( lValue == LONG_MIN || lValue == LONG_MAX) && errno == ERANGE ) {
3854 return LDAP_CONSTRAINT_VIOLATION;
3857 lAssertedValue = strtol(((struct berval *)assertedValue)->bv_val, NULL, 10);
3858 if(( lAssertedValue == LONG_MIN || lAssertedValue == LONG_MAX)
3859 && errno == ERANGE )
3861 return LDAP_CONSTRAINT_VIOLATION;
3864 *matchp = (lValue & lAssertedValue) ? 0 : 1;
3865 return LDAP_SUCCESS;
3874 struct berval *value,
3875 void *assertedValue )
3877 long lValue, lAssertedValue;
3879 /* safe to assume integers are NUL terminated? */
3880 lValue = strtol(value->bv_val, NULL, 10);
3881 if(( lValue == LONG_MIN || lValue == LONG_MAX) && errno == ERANGE ) {
3882 return LDAP_CONSTRAINT_VIOLATION;
3885 lAssertedValue = strtol(((struct berval *)assertedValue)->bv_val, NULL, 10);
3886 if(( lAssertedValue == LONG_MIN || lAssertedValue == LONG_MAX)
3887 && errno == ERANGE )
3889 return LDAP_CONSTRAINT_VIOLATION;
3892 *matchp = (lValue | lAssertedValue) ? 0 : -1;
3893 return LDAP_SUCCESS;
3896 #ifndef SLAP_NVALUES
3899 #include <openssl/x509.h>
3900 #include <openssl/err.h>
3903 * Next function returns a string representation of a ASN1_INTEGER.
3904 * It works for unlimited lengths.
3907 static struct berval *
3908 asn1_integer2str(ASN1_INTEGER *a, struct berval *bv)
3912 static char digit[] = "0123456789";
3914 /* We work backwards, make it fill from the end of buf */
3915 p = buf + sizeof(buf) - 1;
3918 if ( a == NULL || a->length == 0 ) {
3926 /* We want to preserve the original */
3927 copy = ch_malloc(n*sizeof(unsigned int));
3928 for (i = 0; i<n; i++) {
3929 copy[i] = a->data[i];
3933 * base indicates the index of the most significant
3934 * byte that might be nonzero. When it goes off the
3935 * end, we now there is nothing left to do.
3941 for (i = base; i<n; i++ ) {
3942 copy[i] += carry*256;
3943 carry = copy[i] % 10;
3948 * Way too large, we need to leave
3949 * room for sign if negative
3954 *--p = digit[carry];
3956 if (copy[base] == 0) base++;
3961 if ( a->type == V_ASN1_NEG_INTEGER ) {
3965 return ber_str2bv( p, 0, 1, bv );
3969 * Given a certificate in DER format, extract the corresponding
3970 * assertion value for certificateExactMatch
3973 certificateExactConvert(
3975 struct berval * out )
3978 unsigned char *p = in->bv_val;
3979 struct berval serial;
3980 struct berval issuer_dn;
3982 xcert = d2i_X509(NULL, &p, in->bv_len);
3985 LDAP_LOG( CONFIG, ENTRY,
3986 "certificateExactConvert: error parsing cert: %s\n",
3987 ERR_error_string(ERR_get_error(),NULL), 0, 0 );
3989 Debug( LDAP_DEBUG_ARGS, "certificateExactConvert: "
3990 "error parsing cert: %s\n",
3991 ERR_error_string(ERR_get_error(),NULL), NULL, NULL );
3993 return LDAP_INVALID_SYNTAX;
3996 if ( !asn1_integer2str(xcert->cert_info->serialNumber, &serial) ) {
3998 return LDAP_INVALID_SYNTAX;
4000 if ( dnX509normalize(X509_get_issuer_name(xcert), &issuer_dn )
4004 ber_memfree(serial.bv_val);
4005 return LDAP_INVALID_SYNTAX;
4010 out->bv_len = serial.bv_len + issuer_dn.bv_len + sizeof(" $ ");
4011 out->bv_val = ch_malloc(out->bv_len);
4013 AC_MEMCPY(p, serial.bv_val, serial.bv_len);
4015 AC_MEMCPY(p, " $ ", sizeof(" $ ")-1);
4017 AC_MEMCPY(p, issuer_dn.bv_val, issuer_dn.bv_len);
4018 p += issuer_dn.bv_len;
4022 LDAP_LOG( CONFIG, ARGS,
4023 "certificateExactConvert: \n %s\n", out->bv_val, 0, 0 );
4025 Debug( LDAP_DEBUG_ARGS, "certificateExactConvert "
4027 out->bv_val, NULL, NULL );
4030 ber_memfree(serial.bv_val);
4031 ber_memfree(issuer_dn.bv_val);
4033 return LDAP_SUCCESS;
4037 serial_and_issuer_parse(
4038 struct berval *assertion,
4039 struct berval *serial,
4040 struct berval *issuer_dn
4048 begin = assertion->bv_val;
4049 end = assertion->bv_val+assertion->bv_len-1;
4050 for (p=begin; p<=end && *p != '$'; p++) /* empty */ ;
4051 if ( p > end ) return LDAP_INVALID_SYNTAX;
4053 /* p now points at the $ sign, now use
4054 * begin and end to delimit the serial number
4056 while (ASCII_SPACE(*begin)) begin++;
4058 while (ASCII_SPACE(*end)) end--;
4060 if( end <= begin ) return LDAP_INVALID_SYNTAX;
4062 bv.bv_len = end-begin+1;
4064 ber_dupbv(serial, &bv);
4066 /* now extract the issuer, remember p was at the dollar sign */
4068 end = assertion->bv_val+assertion->bv_len-1;
4069 while (ASCII_SPACE(*begin)) begin++;
4070 /* should we trim spaces at the end too? is it safe always? no, no */
4072 if( end <= begin ) return LDAP_INVALID_SYNTAX;
4075 bv.bv_len = end-begin+1;
4078 dnNormalize2( NULL, &bv, issuer_dn );
4081 return LDAP_SUCCESS;
4085 certificateExactMatch(
4090 struct berval *value,
4091 void *assertedValue )
4094 unsigned char *p = value->bv_val;
4095 struct berval serial;
4096 struct berval issuer_dn;
4097 struct berval asserted_serial;
4098 struct berval asserted_issuer_dn;
4101 xcert = d2i_X509(NULL, &p, value->bv_len);
4104 LDAP_LOG( CONFIG, ENTRY,
4105 "certificateExactMatch: error parsing cert: %s\n",
4106 ERR_error_string(ERR_get_error(),NULL), 0, 0 );
4108 Debug( LDAP_DEBUG_ARGS, "certificateExactMatch: "
4109 "error parsing cert: %s\n",
4110 ERR_error_string(ERR_get_error(),NULL), NULL, NULL );
4112 return LDAP_INVALID_SYNTAX;
4115 asn1_integer2str(xcert->cert_info->serialNumber, &serial);
4116 dnX509normalize(X509_get_issuer_name(xcert), &issuer_dn);
4120 serial_and_issuer_parse(assertedValue,
4121 &asserted_serial, &asserted_issuer_dn);
4126 slap_schema.si_syn_integer,
4127 slap_schema.si_mr_integerMatch,
4130 if ( ret == LDAP_SUCCESS ) {
4131 if ( *matchp == 0 ) {
4132 /* We need to normalize everything for dnMatch */
4136 slap_schema.si_syn_distinguishedName,
4137 slap_schema.si_mr_distinguishedNameMatch,
4139 &asserted_issuer_dn);
4144 LDAP_LOG( CONFIG, ARGS, "certificateExactMatch "
4145 "%d\n\t\"%s $ %s\"\n",
4146 *matchp, serial.bv_val, issuer_dn.bv_val );
4147 LDAP_LOG( CONFIG, ARGS, "\t\"%s $ %s\"\n",
4148 asserted_serial.bv_val, asserted_issuer_dn.bv_val,
4151 Debug( LDAP_DEBUG_ARGS, "certificateExactMatch "
4152 "%d\n\t\"%s $ %s\"\n",
4153 *matchp, serial.bv_val, issuer_dn.bv_val );
4154 Debug( LDAP_DEBUG_ARGS, "\t\"%s $ %s\"\n",
4155 asserted_serial.bv_val, asserted_issuer_dn.bv_val,
4159 ber_memfree(serial.bv_val);
4160 ber_memfree(issuer_dn.bv_val);
4161 ber_memfree(asserted_serial.bv_val);
4162 ber_memfree(asserted_issuer_dn.bv_val);
4168 * Index generation function
4169 * We just index the serials, in most scenarios the issuer DN is one of
4170 * a very small set of values.
4172 static int certificateExactIndexer(
4177 struct berval *prefix,
4185 struct berval serial;
4187 /* we should have at least one value at this point */
4188 assert( values != NULL && values[0].bv_val != NULL );
4190 for( i=0; values[i].bv_val != NULL; i++ ) {
4191 /* empty -- just count them */
4194 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
4196 for( i=0; values[i].bv_val != NULL; i++ ) {
4197 p = values[i].bv_val;
4198 xcert = d2i_X509(NULL, &p, values[i].bv_len);
4201 LDAP_LOG( CONFIG, ENTRY,
4202 "certificateExactIndexer: error parsing cert: %s\n",
4203 ERR_error_string(ERR_get_error(),NULL), 0, 0);
4205 Debug( LDAP_DEBUG_ARGS, "certificateExactIndexer: "
4206 "error parsing cert: %s\n",
4207 ERR_error_string(ERR_get_error(),NULL),
4210 /* Do we leak keys on error? */
4211 return LDAP_INVALID_SYNTAX;
4214 asn1_integer2str(xcert->cert_info->serialNumber, &serial);
4216 xintegerNormalize( slap_schema.si_syn_integer,
4217 &serial, &keys[i] );
4218 ber_memfree(serial.bv_val);
4220 LDAP_LOG( CONFIG, ENTRY,
4221 "certificateExactIndexer: returning: %s\n", keys[i].bv_val, 0, 0);
4223 Debug( LDAP_DEBUG_ARGS, "certificateExactIndexer: "
4230 keys[i].bv_val = NULL;
4232 return LDAP_SUCCESS;
4235 /* Index generation function */
4236 /* We think this is always called with a value in matching rule syntax */
4237 static int certificateExactFilter(
4242 struct berval *prefix,
4243 void * assertedValue,
4247 struct berval asserted_serial;
4250 ret = serial_and_issuer_parse( assertedValue, &asserted_serial, NULL );
4251 if( ret != LDAP_SUCCESS ) return ret;
4253 keys = ch_malloc( sizeof( struct berval ) * 2 );
4254 xintegerNormalize( syntax, &asserted_serial, &keys[0] );
4255 keys[1].bv_val = NULL;
4258 ber_memfree(asserted_serial.bv_val);
4259 return LDAP_SUCCESS;
4265 check_time_syntax (struct berval *val,
4269 static int ceiling[9] = { 99, 99, 11, 30, 23, 59, 59, 12, 59 };
4270 static int mdays[2][12] = {
4271 /* non-leap years */
4272 { 30, 27, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30 },
4274 { 30, 28, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30 }
4277 int part, c, tzoffset, leapyear = 0 ;
4279 if( val->bv_len == 0 ) {
4280 return LDAP_INVALID_SYNTAX;
4283 p = (char *)val->bv_val;
4284 e = p + val->bv_len;
4286 /* Ignore initial whitespace */
4287 while ( ( p < e ) && ASCII_SPACE( *p ) ) {
4291 if (e - p < 13 - (2 * start)) {
4292 return LDAP_INVALID_SYNTAX;
4295 for (part = 0; part < 9; part++) {
4299 for (part = start; part < 7; part++) {
4301 if ((part == 6) && (c == 'Z' || c == '+' || c == '-')) {
4308 return LDAP_INVALID_SYNTAX;
4310 if (c < 0 || c > 9) {
4311 return LDAP_INVALID_SYNTAX;
4317 return LDAP_INVALID_SYNTAX;
4319 if (c < 0 || c > 9) {
4320 return LDAP_INVALID_SYNTAX;
4325 if (part == 2 || part == 3) {
4328 if (parts[part] < 0) {
4329 return LDAP_INVALID_SYNTAX;
4331 if (parts[part] > ceiling[part]) {
4332 return LDAP_INVALID_SYNTAX;
4336 /* leapyear check for the Gregorian calendar (year>1581) */
4337 if (((parts[1] % 4 == 0) && (parts[1] != 0)) ||
4338 ((parts[0] % 4 == 0) && (parts[1] == 0)))
4343 if (parts[3] > mdays[leapyear][parts[2]]) {
4344 return LDAP_INVALID_SYNTAX;
4349 tzoffset = 0; /* UTC */
4350 } else if (c != '+' && c != '-') {
4351 return LDAP_INVALID_SYNTAX;
4355 } else /* c == '+' */ {
4360 return LDAP_INVALID_SYNTAX;
4363 for (part = 7; part < 9; part++) {
4365 if (c < 0 || c > 9) {
4366 return LDAP_INVALID_SYNTAX;
4371 if (c < 0 || c > 9) {
4372 return LDAP_INVALID_SYNTAX;
4376 if (parts[part] < 0 || parts[part] > ceiling[part]) {
4377 return LDAP_INVALID_SYNTAX;
4382 /* Ignore trailing whitespace */
4383 while ( ( p < e ) && ASCII_SPACE( *p ) ) {
4387 return LDAP_INVALID_SYNTAX;
4390 switch ( tzoffset ) {
4391 case -1: /* negativ offset to UTC, ie west of Greenwich */
4392 parts[4] += parts[7];
4393 parts[5] += parts[8];
4394 for (part = 6; --part > 0; ) { /* offset is just hhmm, no seconds */
4398 c = mdays[leapyear][parts[2]];
4400 if (parts[part] > c) {
4401 parts[part] -= c + 1;
4406 case 1: /* positive offset to UTC, ie east of Greenwich */
4407 parts[4] -= parts[7];
4408 parts[5] -= parts[8];
4409 for (part = 6; --part > 0; ) {
4413 /* first arg to % needs to be non negativ */
4414 c = mdays[leapyear][(parts[2] - 1 + 12) % 12];
4416 if (parts[part] < 0) {
4417 parts[part] += c + 1;
4422 case 0: /* already UTC */
4426 return LDAP_SUCCESS;
4429 #ifdef SUPPORT_OBSOLETE_UTC_SYNTAX
4434 struct berval *normalized )
4438 rc = check_time_syntax(val, 1, parts);
4439 if (rc != LDAP_SUCCESS) {
4443 normalized->bv_val = ch_malloc( 14 );
4444 if ( normalized->bv_val == NULL ) {
4445 return LBER_ERROR_MEMORY;
4448 sprintf( normalized->bv_val, "%02d%02d%02d%02d%02d%02dZ",
4449 parts[1], parts[2] + 1, parts[3] + 1,
4450 parts[4], parts[5], parts[6] );
4451 normalized->bv_len = 13;
4453 return LDAP_SUCCESS;
4457 #ifdef SUPPORT_OBSOLETE_UTC_SYNTAX
4465 return check_time_syntax(in, 1, parts);
4470 generalizedTimeValidate(
4476 return check_time_syntax(in, 0, parts);
4479 #ifndef SLAP_NVALUES
4482 xgeneralizedTimeNormalize(
4485 struct berval *normalized )
4489 rc = check_time_syntax(val, 0, parts);
4490 if (rc != LDAP_SUCCESS) {
4494 normalized->bv_val = ch_malloc( 16 );
4495 if ( normalized->bv_val == NULL ) {
4496 return LBER_ERROR_MEMORY;
4499 sprintf( normalized->bv_val, "%02d%02d%02d%02d%02d%02d%02dZ",
4500 parts[0], parts[1], parts[2] + 1, parts[3] + 1,
4501 parts[4], parts[5], parts[6] );
4502 normalized->bv_len = 15;
4504 return LDAP_SUCCESS;
4509 nisNetgroupTripleValidate(
4511 struct berval *val )
4516 if ( val->bv_len == 0 ) {
4517 return LDAP_INVALID_SYNTAX;
4520 p = (char *)val->bv_val;
4521 e = p + val->bv_len;
4523 if ( *p != '(' /*')'*/ ) {
4524 return LDAP_INVALID_SYNTAX;
4527 for ( p++; ( p < e ) && ( *p != /*'('*/ ')' ); p++ ) {
4531 return LDAP_INVALID_SYNTAX;
4534 } else if ( !AD_CHAR( *p ) ) {
4535 return LDAP_INVALID_SYNTAX;
4539 if ( ( commas != 2 ) || ( *p != /*'('*/ ')' ) ) {
4540 return LDAP_INVALID_SYNTAX;
4546 return LDAP_INVALID_SYNTAX;
4549 return LDAP_SUCCESS;
4553 bootParameterValidate(
4555 struct berval *val )
4559 if ( val->bv_len == 0 ) {
4560 return LDAP_INVALID_SYNTAX;
4563 p = (char *)val->bv_val;
4564 e = p + val->bv_len;
4567 for (; ( p < e ) && ( *p != '=' ); p++ ) {
4568 if ( !AD_CHAR( *p ) ) {
4569 return LDAP_INVALID_SYNTAX;
4574 return LDAP_INVALID_SYNTAX;
4578 for ( p++; ( p < e ) && ( *p != ':' ); p++ ) {
4579 if ( !AD_CHAR( *p ) ) {
4580 return LDAP_INVALID_SYNTAX;
4585 return LDAP_INVALID_SYNTAX;
4589 for ( p++; p < e; p++ ) {
4590 if ( !SLAP_PRINTABLE( *p ) ) {
4591 return LDAP_INVALID_SYNTAX;
4595 return LDAP_SUCCESS;
4598 #define X_BINARY "X-BINARY-TRANSFER-REQUIRED 'TRUE' "
4599 #define X_NOT_H_R "X-NOT-HUMAN-READABLE 'TRUE' "
4601 static slap_syntax_defs_rec syntax_defs[] = {
4602 {"( 1.3.6.1.4.1.1466.115.121.1.1 DESC 'ACI Item' "
4603 X_BINARY X_NOT_H_R ")",
4604 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, NULL, NULL, NULL},
4605 {"( 1.3.6.1.4.1.1466.115.121.1.2 DESC 'Access Point' " X_NOT_H_R ")",
4606 0, NULL, NULL, NULL},
4607 {"( 1.3.6.1.4.1.1466.115.121.1.3 DESC 'Attribute Type Description' )",
4608 0, NULL, NULL, NULL},
4609 {"( 1.3.6.1.4.1.1466.115.121.1.4 DESC 'Audio' "
4611 SLAP_SYNTAX_BLOB, blobValidate, NULL, NULL},
4612 {"( 1.3.6.1.4.1.1466.115.121.1.5 DESC 'Binary' "
4614 SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4615 {"( 1.3.6.1.4.1.1466.115.121.1.6 DESC 'Bit String' )",
4616 0, bitStringValidate, NULL, NULL },
4617 {"( 1.3.6.1.4.1.1466.115.121.1.7 DESC 'Boolean' )",
4618 0, booleanValidate, NULL, NULL},
4619 {"( 1.3.6.1.4.1.1466.115.121.1.8 DESC 'Certificate' "
4620 X_BINARY X_NOT_H_R ")",
4621 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4622 {"( 1.3.6.1.4.1.1466.115.121.1.9 DESC 'Certificate List' "
4623 X_BINARY X_NOT_H_R ")",
4624 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4625 {"( 1.3.6.1.4.1.1466.115.121.1.10 DESC 'Certificate Pair' "
4626 X_BINARY X_NOT_H_R ")",
4627 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4628 {"( 1.3.6.1.4.1.1466.115.121.1.11 DESC 'Country String' )",
4629 0, countryStringValidate, xIA5StringNormalize, NULL},
4630 {"( 1.3.6.1.4.1.1466.115.121.1.12 DESC 'Distinguished Name' )",
4631 0, dnValidate, xdnNormalize, dnPretty2},
4632 {"( 1.3.6.1.4.1.1466.115.121.1.13 DESC 'Data Quality' )",
4633 0, NULL, NULL, NULL},
4634 {"( 1.3.6.1.4.1.1466.115.121.1.14 DESC 'Delivery Method' )",
4635 0, NULL, NULL, NULL},
4636 {"( 1.3.6.1.4.1.1466.115.121.1.15 DESC 'Directory String' )",
4637 0, UTF8StringValidate, xUTF8StringNormalize, NULL},
4638 {"( 1.3.6.1.4.1.1466.115.121.1.16 DESC 'DIT Content Rule Description' )",
4639 0, NULL, NULL, NULL},
4640 {"( 1.3.6.1.4.1.1466.115.121.1.17 DESC 'DIT Structure Rule Description' )",
4641 0, NULL, NULL, NULL},
4642 {"( 1.3.6.1.4.1.1466.115.121.1.19 DESC 'DSA Quality' )",
4643 0, NULL, NULL, NULL},
4644 {"( 1.3.6.1.4.1.1466.115.121.1.20 DESC 'DSE Type' )",
4645 0, NULL, NULL, NULL},
4646 {"( 1.3.6.1.4.1.1466.115.121.1.21 DESC 'Enhanced Guide' )",
4647 0, NULL, NULL, NULL},
4648 {"( 1.3.6.1.4.1.1466.115.121.1.22 DESC 'Facsimile Telephone Number' )",
4649 0, printablesStringValidate, xtelephoneNumberNormalize, NULL},
4650 {"( 1.3.6.1.4.1.1466.115.121.1.23 DESC 'Fax' " X_NOT_H_R ")",
4651 SLAP_SYNTAX_BLOB, NULL, NULL, NULL},
4652 {"( 1.3.6.1.4.1.1466.115.121.1.24 DESC 'Generalized Time' )",
4653 0, generalizedTimeValidate, xgeneralizedTimeNormalize, NULL},
4654 {"( 1.3.6.1.4.1.1466.115.121.1.25 DESC 'Guide' )",
4655 0, NULL, NULL, NULL},
4656 {"( 1.3.6.1.4.1.1466.115.121.1.26 DESC 'IA5 String' )",
4657 0, IA5StringValidate, xIA5StringNormalize, NULL},
4658 {"( 1.3.6.1.4.1.1466.115.121.1.27 DESC 'Integer' )",
4659 0, integerValidate, xintegerNormalize, NULL},
4660 {"( 1.3.6.1.4.1.1466.115.121.1.28 DESC 'JPEG' " X_NOT_H_R ")",
4661 SLAP_SYNTAX_BLOB, blobValidate, NULL, NULL},
4662 {"( 1.3.6.1.4.1.1466.115.121.1.29 DESC 'Master And Shadow Access Points' )",
4663 0, NULL, NULL, NULL},
4664 {"( 1.3.6.1.4.1.1466.115.121.1.30 DESC 'Matching Rule Description' )",
4665 0, NULL, NULL, NULL},
4666 {"( 1.3.6.1.4.1.1466.115.121.1.31 DESC 'Matching Rule Use Description' )",
4667 0, NULL, NULL, NULL},
4668 {"( 1.3.6.1.4.1.1466.115.121.1.32 DESC 'Mail Preference' )",
4669 0, NULL, NULL, NULL},
4670 {"( 1.3.6.1.4.1.1466.115.121.1.33 DESC 'MHS OR Address' )",
4671 0, NULL, NULL, NULL},
4672 {"( 1.3.6.1.4.1.1466.115.121.1.34 DESC 'Name And Optional UID' )",
4673 0, nameUIDValidate, xnameUIDNormalize, NULL},
4674 {"( 1.3.6.1.4.1.1466.115.121.1.35 DESC 'Name Form Description' )",
4675 0, NULL, NULL, NULL},
4676 {"( 1.3.6.1.4.1.1466.115.121.1.36 DESC 'Numeric String' )",
4677 0, numericStringValidate, xnumericStringNormalize, NULL},
4678 {"( 1.3.6.1.4.1.1466.115.121.1.37 DESC 'Object Class Description' )",
4679 0, NULL, NULL, NULL},
4680 {"( 1.3.6.1.4.1.1466.115.121.1.38 DESC 'OID' )",
4681 0, oidValidate, NULL, NULL},
4682 {"( 1.3.6.1.4.1.1466.115.121.1.39 DESC 'Other Mailbox' )",
4683 0, IA5StringValidate, xIA5StringNormalize, NULL},
4684 {"( 1.3.6.1.4.1.1466.115.121.1.40 DESC 'Octet String' )",
4685 0, blobValidate, NULL, NULL},
4686 {"( 1.3.6.1.4.1.1466.115.121.1.41 DESC 'Postal Address' )",
4687 0, UTF8StringValidate, xUTF8StringNormalize, NULL},
4688 {"( 1.3.6.1.4.1.1466.115.121.1.42 DESC 'Protocol Information' )",
4689 0, NULL, NULL, NULL},
4690 {"( 1.3.6.1.4.1.1466.115.121.1.43 DESC 'Presentation Address' )",
4691 0, NULL, NULL, NULL},
4692 {"( 1.3.6.1.4.1.1466.115.121.1.44 DESC 'Printable String' )",
4693 0, printableStringValidate, xIA5StringNormalize, NULL},
4694 {"( 1.3.6.1.4.1.1466.115.121.1.45 DESC 'SubtreeSpecification' "
4695 X_BINARY X_NOT_H_R ")",
4696 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, NULL, NULL, NULL},
4697 {"( 1.3.6.1.4.1.1466.115.121.1.49 DESC 'Supported Algorithm' "
4698 X_BINARY X_NOT_H_R ")",
4699 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4700 {"( 1.3.6.1.4.1.1466.115.121.1.50 DESC 'Telephone Number' )",
4701 0, printableStringValidate, xtelephoneNumberNormalize, NULL},
4702 {"( 1.3.6.1.4.1.1466.115.121.1.51 DESC 'Teletex Terminal Identifier' )",
4703 0, NULL, NULL, NULL},
4704 {"( 1.3.6.1.4.1.1466.115.121.1.52 DESC 'Telex Number' )",
4705 0, printablesStringValidate, xIA5StringNormalize, NULL},
4706 #ifdef SUPPORT_OBSOLETE_UTC_SYNTAX
4707 {"( 1.3.6.1.4.1.1466.115.121.1.53 DESC 'UTC Time' )",
4708 0, utcTimeValidate, xutcTimeNormalize, NULL},
4710 {"( 1.3.6.1.4.1.1466.115.121.1.54 DESC 'LDAP Syntax Description' )",
4711 0, NULL, NULL, NULL},
4712 {"( 1.3.6.1.4.1.1466.115.121.1.55 DESC 'Modify Rights' )",
4713 0, NULL, NULL, NULL},
4714 {"( 1.3.6.1.4.1.1466.115.121.1.56 DESC 'LDAP Schema Definition' )",
4715 0, NULL, NULL, NULL},
4716 {"( 1.3.6.1.4.1.1466.115.121.1.57 DESC 'LDAP Schema Description' )",
4717 0, NULL, NULL, NULL},
4718 {"( 1.3.6.1.4.1.1466.115.121.1.58 DESC 'Substring Assertion' )",
4719 0, NULL, NULL, NULL},
4721 /* RFC 2307 NIS Syntaxes */
4722 {"( 1.3.6.1.1.1.0.0 DESC 'RFC2307 NIS Netgroup Triple' )",
4723 0, nisNetgroupTripleValidate, NULL, NULL},
4724 {"( 1.3.6.1.1.1.0.1 DESC 'RFC2307 Boot Parameter' )",
4725 0, bootParameterValidate, NULL, NULL},
4729 /* These OIDs are not published yet, but will be in the next
4730 * I-D for PKIX LDAPv3 schema as have been advanced by David
4731 * Chadwick in private mail.
4733 {"( 1.2.826.0.1.3344810.7.1 DESC 'Serial Number and Issuer' )",
4734 0, UTF8StringValidate, NULL, NULL},
4737 /* OpenLDAP Experimental Syntaxes */
4738 #ifdef SLAPD_ACI_ENABLED
4739 {"( 1.3.6.1.4.1.4203.666.2.1 DESC 'OpenLDAP Experimental ACI' )",
4741 UTF8StringValidate /* THIS WILL CHANGE FOR NEW ACI SYNTAX */,
4745 #ifdef SLAPD_AUTHPASSWD
4746 /* needs updating */
4747 {"( 1.3.6.1.4.1.4203.666.2.2 DESC 'OpenLDAP authPassword' )",
4748 SLAP_SYNTAX_HIDE, NULL, NULL, NULL},
4751 /* OpenLDAP Void Syntax */
4752 {"( 1.3.6.1.4.1.4203.1.1.1 DESC 'OpenLDAP void' )" ,
4753 SLAP_SYNTAX_HIDE, inValidate, NULL, NULL},
4754 {NULL, 0, NULL, NULL, NULL}
4758 char *certificateExactMatchSyntaxes[] = {
4759 "1.3.6.1.4.1.1466.115.121.1.8" /* certificate */,
4763 char *directoryStringSyntaxes[] = {
4764 "1.3.6.1.4.1.1466.115.121.1.44" /* printableString */,
4767 char *integerFirstComponentMatchSyntaxes[] = {
4768 "1.3.6.1.4.1.1466.115.121.1.27" /* INTEGER */,
4769 "1.3.6.1.4.1.1466.115.121.1.17" /* ditStructureRuleDescription */,
4772 char *objectIdentifierFirstComponentMatchSyntaxes[] = {
4773 "1.3.6.1.4.1.1466.115.121.1.38" /* OID */,
4774 "1.3.6.1.4.1.1466.115.121.1.3" /* attributeTypeDescription */,
4775 "1.3.6.1.4.1.1466.115.121.1.16" /* ditContentRuleDescription */,
4776 "1.3.6.1.4.1.1466.115.121.1.54" /* ldapSyntaxDescription */,
4777 "1.3.6.1.4.1.1466.115.121.1.30" /* matchingRuleDescription */,
4778 "1.3.6.1.4.1.1466.115.121.1.31" /* matchingRuleUseDescription */,
4779 "1.3.6.1.4.1.1466.115.121.1.35" /* nameFormDescription */,
4780 "1.3.6.1.4.1.1466.115.121.1.37" /* objectClassDescription */,
4785 * Other matching rules in X.520 that we do not use (yet):
4787 * 2.5.13.9 numericStringOrderingMatch
4788 * 2.5.13.25 uTCTimeMatch
4789 * 2.5.13.26 uTCTimeOrderingMatch
4790 * 2.5.13.31 directoryStringFirstComponentMatch
4791 * 2.5.13.32 wordMatch
4792 * 2.5.13.33 keywordMatch
4793 * 2.5.13.35 certificateMatch
4794 * 2.5.13.36 certificatePairExactMatch
4795 * 2.5.13.37 certificatePairMatch
4796 * 2.5.13.38 certificateListExactMatch
4797 * 2.5.13.39 certificateListMatch
4798 * 2.5.13.40 algorithmIdentifierMatch
4799 * 2.5.13.41 storedPrefixMatch
4800 * 2.5.13.42 attributeCertificateMatch
4801 * 2.5.13.43 readerAndKeyIDMatch
4802 * 2.5.13.44 attributeIntegrityMatch
4804 static slap_mrule_defs_rec mrule_defs[] = {
4806 * EQUALITY matching rules must be listed after associated APPROX
4807 * matching rules. So, we list all APPROX matching rules first.
4809 #ifndef SLAP_NVALUES
4810 {"( " directoryStringApproxMatchOID " NAME 'directoryStringApproxMatch' "
4811 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4812 SLAP_MR_HIDE | SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT, NULL,
4813 NULL, NULL, directoryStringApproxMatch,
4814 directoryStringApproxIndexer, directoryStringApproxFilter,
4817 {"( " IA5StringApproxMatchOID " NAME 'IA5StringApproxMatch' "
4818 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4819 SLAP_MR_HIDE | SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT, NULL,
4820 NULL, NULL, IA5StringApproxMatch,
4821 IA5StringApproxIndexer, IA5StringApproxFilter,
4826 * Other matching rules
4829 {"( 2.5.13.0 NAME 'objectIdentifierMatch' "
4830 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
4831 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4833 objectIdentifierNormalize, objectIdentifierMatch,
4834 objectIdentifierIndexer, objectIdentifierFilter,
4837 {"( 2.5.13.1 NAME 'distinguishedNameMatch' "
4838 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )",
4839 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4841 distinguishedNameNormalize, distinguishedNameMatch,
4842 distinguishedNameIndexer, distinguishedNameFilter,
4845 {"( 2.5.13.2 NAME 'caseIgnoreMatch' "
4846 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4847 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD,
4848 directoryStringSyntaxes,
4850 caseIgnoreNormalize, caseIgnoreMatch,
4851 caseIgnoreIndexer, caseIgnoreFilter,
4852 directoryStringApproxMatchOID },
4854 {"( 2.5.13.3 NAME 'caseIgnoreOrderingMatch' "
4855 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4856 SLAP_MR_ORDERING, directoryStringSyntaxes,
4857 NULL, caseIgnoreNormalize, caseIgnoreOrderingMatch,
4860 {"( 2.5.13.4 NAME 'caseIgnoreSubstringsMatch' "
4861 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4862 SLAP_MR_SUBSTR, NULL,
4864 caseIgnoreSubstringsMatch,
4865 caseIgnoreSubstringsIndexer, caseIgnoreSubstringsFilter,
4868 {"( 2.5.13.5 NAME 'caseExactMatch' "
4869 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4870 SLAP_MR_EQUALITY | SLAP_MR_EXT, directoryStringSyntaxes,
4872 caseExactNormalize, caseExactMatch,
4873 caseExactIndexer, caseExactFilter,
4874 directoryStringApproxMatchOID },
4876 {"( 2.5.13.6 NAME 'caseExactOrderingMatch' "
4877 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4878 SLAP_MR_ORDERING, directoryStringSyntaxes,
4879 NULL, caseExactNormalize, caseExactOrderingMatch,
4882 {"( 2.5.13.7 NAME 'caseExactSubstringsMatch' "
4883 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4884 SLAP_MR_SUBSTR, directoryStringSyntaxes,
4886 NULL, caseExactSubstringsMatch,
4887 caseExactSubstringsIndexer, caseExactSubstringsFilter,
4890 {"( 2.5.13.8 NAME 'numericStringMatch' "
4891 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 )",
4892 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL,
4894 numericStringNormalize, numericStringMatch,
4895 numericStringIndexer, numericStringFilter,
4898 {"( 2.5.13.10 NAME 'numericStringSubstringsMatch' "
4899 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4900 SLAP_MR_SUBSTR, NULL,
4902 NULL, numericStringSubstringsMatch,
4903 numericStringSubstringsIndexer, numericStringSubstringsFilter,
4906 {"( 2.5.13.11 NAME 'caseIgnoreListMatch' "
4907 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )",
4908 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL,
4909 NULL, NULL, NULL, NULL, NULL, NULL},
4911 {"( 2.5.13.12 NAME 'caseIgnoreListSubstringsMatch' "
4912 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4913 SLAP_MR_SUBSTR, NULL,
4914 NULL, NULL, NULL, NULL, NULL, NULL},
4916 {"( 2.5.13.13 NAME 'booleanMatch' "
4917 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )",
4918 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4919 NULL, NULL, booleanMatch, NULL, NULL, NULL},
4921 {"( 2.5.13.14 NAME 'integerMatch' "
4922 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4923 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4925 integerNormalize, integerMatch,
4926 integerIndexer, integerFilter,
4929 {"( 2.5.13.15 NAME 'integerOrderingMatch' "
4930 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4931 SLAP_MR_ORDERING, NULL, NULL,
4932 integerNormalize, integerOrderingMatch,
4933 integerIndexer, integerFilter,
4936 {"( 2.5.13.16 NAME 'bitStringMatch' "
4937 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.6 )",
4938 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4940 bitStringNormalize, bitStringMatch,
4941 bitStringIndexer, bitStringFilter,
4944 {"( 2.5.13.17 NAME 'octetStringMatch' "
4945 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
4946 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4948 octetStringMatch, octetStringIndexer, octetStringFilter,
4951 {"( 2.5.13.18 NAME 'octetStringOrderingMatch' "
4952 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
4953 SLAP_MR_ORDERING, NULL,
4955 octetStringOrderingMatch, NULL, NULL,
4958 {"( 2.5.13.19 NAME 'octetStringSubstringsMatch' "
4959 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
4960 SLAP_MR_SUBSTR, NULL,
4962 octetStringSubstringsMatch, NULL, NULL,
4965 {"( 2.5.13.20 NAME 'telephoneNumberMatch' "
4966 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 )",
4967 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL,
4969 telephoneNumberNormalize, telephoneNumberMatch,
4970 telephoneNumberIndexer, telephoneNumberFilter,
4973 {"( 2.5.13.21 NAME 'telephoneNumberSubstringsMatch' "
4974 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4975 SLAP_MR_SUBSTR, NULL,
4976 NULL, NULL, telephoneNumberSubstringsMatch,
4977 telephoneNumberSubstringsIndexer, telephoneNumberSubstringsFilter,
4980 {"( 2.5.13.22 NAME 'presentationAddressMatch' "
4981 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.43 )",
4982 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4987 {"( 2.5.13.23 NAME 'uniqueMemberMatch' "
4988 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.34 )",
4989 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4991 uniqueMemberNormalize, uniqueMemberMatch,
4995 {"( 2.5.13.24 NAME 'protocolInformationMatch' "
4996 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.42 )",
4997 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4998 NULL, NULL, NULL, NULL, NULL, NULL},
5000 {"( 2.5.13.27 NAME 'generalizedTimeMatch' "
5001 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
5002 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
5004 generalizedTimeNormalize, generalizedTimeMatch,
5008 {"( 2.5.13.28 NAME 'generalizedTimeOrderingMatch' "
5009 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
5010 SLAP_MR_ORDERING, NULL,
5012 generalizedTimeNormalize, generalizedTimeOrderingMatch,
5016 {"( 2.5.13.29 NAME 'integerFirstComponentMatch' "
5017 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
5018 SLAP_MR_EQUALITY | SLAP_MR_EXT, integerFirstComponentMatchSyntaxes,
5020 integerFirstComponentNormalize, integerMatch,
5024 {"( 2.5.13.30 NAME 'objectIdentifierFirstComponentMatch' "
5025 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
5026 SLAP_MR_EQUALITY | SLAP_MR_EXT,
5027 objectIdentifierFirstComponentMatchSyntaxes,
5029 objectIdentifierFirstComponentNormalize, objectIdentifierMatch,
5033 #ifndef SLAP_NVALUES
5035 {"( 2.5.13.34 NAME 'certificateExactMatch' "
5036 "SYNTAX 1.2.826.0.1.3344810.7.1 )",
5037 SLAP_MR_EQUALITY | SLAP_MR_EXT, certificateExactMatchSyntaxes,
5038 certificateExactConvert, NULL,
5039 certificateExactMatch,
5040 certificateExactIndexer, certificateExactFilter,
5045 {"( 1.3.6.1.4.1.1466.109.114.1 NAME 'caseExactIA5Match' "
5046 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
5047 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
5049 caseExactIA5Normalize, caseExactIA5Match,
5050 caseExactIA5Indexer, caseExactIA5Filter,
5051 IA5StringApproxMatchOID },
5053 {"( 1.3.6.1.4.1.1466.109.114.2 NAME 'caseIgnoreIA5Match' "
5054 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
5055 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL,
5057 NULL, caseIgnoreIA5Match,
5058 caseIgnoreIA5Indexer, caseIgnoreIA5Filter,
5059 IA5StringApproxMatchOID },
5061 {"( 1.3.6.1.4.1.1466.109.114.3 NAME 'caseIgnoreIA5SubstringsMatch' "
5062 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
5063 SLAP_MR_SUBSTR, NULL,
5065 NULL, caseIgnoreIA5SubstringsMatch,
5066 caseIgnoreIA5SubstringsIndexer, caseIgnoreIA5SubstringsFilter,
5069 {"( 1.3.6.1.4.1.4203.1.2.1 NAME 'caseExactIA5SubstringsMatch' "
5070 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
5071 SLAP_MR_SUBSTR, NULL,
5073 NULL, caseExactIA5SubstringsMatch,
5074 caseExactIA5SubstringsIndexer, caseExactIA5SubstringsFilter,
5077 #ifdef SLAPD_AUTHPASSWD
5078 /* needs updating */
5079 {"( 1.3.6.1.4.1.4203.666.4.1 NAME 'authPasswordMatch' "
5080 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
5081 SLAP_MR_EQUALITY, NULL,
5083 authPasswordMatch, NULL, NULL,
5087 #ifdef SLAPD_ACI_ENABLED
5088 {"( 1.3.6.1.4.1.4203.666.4.2 NAME 'OpenLDAPaciMatch' "
5089 "SYNTAX 1.3.6.1.4.1.4203.666.2.1 )",
5090 SLAP_MR_EQUALITY, NULL,
5092 OpenLDAPaciMatch, NULL, NULL,
5096 {"( 1.2.840.113556.1.4.803 NAME 'integerBitAndMatch' "
5097 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
5100 NULL, integerBitAndMatch, NULL, NULL,
5103 {"( 1.2.840.113556.1.4.804 NAME 'integerBitOrMatch' "
5104 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
5107 NULL, integerBitOrMatch, NULL, NULL,
5110 {NULL, SLAP_MR_NONE, NULL,
5111 NULL, NULL, NULL, NULL, NULL,
5116 slap_schema_init( void )
5121 /* we should only be called once (from main) */
5122 assert( schema_init_done == 0 );
5124 for ( i=0; syntax_defs[i].sd_desc != NULL; i++ ) {
5125 res = register_syntax( &syntax_defs[i] );
5128 fprintf( stderr, "slap_schema_init: Error registering syntax %s\n",
5129 syntax_defs[i].sd_desc );
5134 for ( i=0; mrule_defs[i].mrd_desc != NULL; i++ ) {
5135 if( mrule_defs[i].mrd_usage == SLAP_MR_NONE &&
5136 mrule_defs[i].mrd_compat_syntaxes == NULL )
5139 "slap_schema_init: Ignoring unusable matching rule %s\n",
5140 mrule_defs[i].mrd_desc );
5144 res = register_matching_rule( &mrule_defs[i] );
5148 "slap_schema_init: Error registering matching rule %s\n",
5149 mrule_defs[i].mrd_desc );
5154 res = slap_schema_load();
5155 schema_init_done = 1;
5160 schema_destroy( void )