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 uniqueMemberNormalize NULL
60 #define bitStringNormalize NULL
61 #define telephoneNumberNormalize NULL
63 #define distinguishedNameNormalize dnNormalize
64 #define distinguishedNameMatch dnMatch
65 #define distinguishedNameIndexer octetStringIndexer
66 #define distinguishedNameFilter octetStringFilter
68 #define uniqueMemberMatch dnMatch
70 #define objectIdentifierMatch octetStringMatch
71 #define objectIdentifierIndexer octetStringIndexer
72 #define objectIdentifierFilter octetStringFilter
74 #define OpenLDAPaciMatch NULL
76 #define bitStringMatch octetStringMatch
77 #define bitStringIndexer octetStringIndexer
78 #define bitStringFilter octetStringFilter
80 #define integerMatch NULL
81 #define integerOrderingMatch NULL
82 #define integerIndexer NULL
83 #define integerFilter NULL
85 #define generalizedTimeMatch NULL
86 #define generalizedTimeOrderingMatch NULL
88 #define caseIgnoreMatch octetStringMatch
89 #define caseIgnoreOrderingMatch octetStringOrderingMatch
90 #define caseIgnoreIndexer octetStringIndexer
91 #define caseIgnoreFilter octetStringFilter
93 #define caseIgnoreSubstringsMatch SubstringsMatch
94 #define caseIgnoreSubstringsIndexer NULL
95 #define caseIgnoreSubstringsFilter NULL
97 #define caseExactMatch octetStringMatch
98 #define caseExactOrderingMatch octetStringOrderingMatch
99 #define caseExactIndexer octetStringIndexer
100 #define caseExactFilter octetStringFilter
102 #define caseExactSubstringsMatch NULL
103 #define caseExactSubstringsIndexer NULL
104 #define caseExactSubstringsFilter NULL
106 #define caseExactIA5Match octetStringMatch
107 #define caseExactIA5Indexer octetStringIndexer
108 #define caseExactIA5Filter octetStringFilter
110 #define caseExactIA5SubstringsMatch NULL
111 #define caseExactIA5SubstringsIndexer NULL
112 #define caseExactIA5SubstringsFilter NULL
114 #define caseIgnoreIA5Match octetStringMatch
115 #define caseIgnoreIA5Indexer octetStringIndexer
116 #define caseIgnoreIA5Filter octetStringFilter
118 #define caseIgnoreIA5SubstringsMatch caseExactIA5SubstringsMatch
119 #define caseIgnoreIA5SubstringsIndexer caseExactIA5SubstringsIndexer
120 #define caseIgnoreIA5SubstringsFilter caseExactIA5SubstringsFilter
122 #define numericStringMatch octetStringMatch
123 #define numericStringIndexer octetStringIndexer
124 #define numericStringFilter octetStringFilter
126 #define numericStringSubstringsMatch caseExactIA5SubstringsMatch
127 #define numericStringSubstringsIndexer caseExactIA5SubstringsIndexer
128 #define numericStringSubstringsFilter caseExactIA5SubstringsFilter
130 #define telephoneNumberMatch octetStringMatch
131 #define telephoneNumberIndexer octetStringIndexer
132 #define telephoneNumberFilter octetStringFilter
134 #define telephoneNumberSubstringsMatch caseExactIA5SubstringsMatch
135 #define telephoneNumberSubstringsIndexer caseExactIA5SubstringsIndexer
136 #define telephoneNumberSubstringsFilter caseExactIA5SubstringsFilter
140 /* validatation routines */
141 #define berValidate blobValidate
143 /* approx matching rules */
145 #define directoryStringApproxMatchOID NULL
146 #define IA5StringApproxMatchOID NULL
148 #define directoryStringApproxMatchOID "1.3.6.1.4.1.4203.666.4.4"
149 #define directoryStringApproxMatch approxMatch
150 #define directoryStringApproxIndexer approxIndexer
151 #define directoryStringApproxFilter approxFilter
152 #define IA5StringApproxMatchOID "1.3.6.1.4.1.4203.666.4.5"
153 #define IA5StringApproxMatch approxMatch
154 #define IA5StringApproxIndexer approxIndexer
155 #define IA5StringApproxFilter approxFilter
160 #define xdnNormalize dnNormalize
162 /* (new) normalization routines */
163 #define caseExactNormalize NULL
164 #define caseExactIA5Normalize NULL
165 #define caseIgnoreNormalize NULL
166 #define caseIgnoreIA5Normalize NULL
167 #define distinguishedNameNormalize NULL
168 #define integerNormalize NULL
169 #define integerFirstComponentNormalize NULL
170 #define numericStringNormalize NULL
171 #define objectIdentifierNormalize NULL
172 #define objectIdentifierFirstComponentNormalize NULL
173 #define generalizedTimeNormalize NULL
174 #define uniqueMemberNormalize NULL
175 #define bitStringNormalize NULL
176 #define telephoneNumberNormalize NULL
179 /* matching routines */
180 #define bitStringMatch octetStringMatch
181 #define bitStringIndexer octetStringIndexer
182 #define bitStringFilter octetStringFilter
184 #define numericStringMatch caseIgnoreIA5Match
185 #define numericStringIndexer NULL
186 #define numericStringFilter NULL
187 #define numericStringSubstringsIndexer NULL
188 #define numericStringSubstringsFilter NULL
190 #define objectIdentifierMatch octetStringMatch
191 #define objectIdentifierIndexer caseIgnoreIA5Indexer
192 #define objectIdentifierFilter caseIgnoreIA5Filter
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 );
495 struct berval *normalized )
500 ber_dupbv( &out, val );
501 if( out.bv_len != 0 ) {
502 struct berval uid = { 0, NULL };
504 if( out.bv_val[out.bv_len-1] == 'B'
505 && out.bv_val[out.bv_len-2] == '\'' )
507 /* assume presence of optional UID */
508 uid.bv_val = strrchr( out.bv_val, '#' );
510 if( uid.bv_val == NULL ) {
512 return LDAP_INVALID_SYNTAX;
515 uid.bv_len = out.bv_len - (uid.bv_val - out.bv_val);
516 out.bv_len -= uid.bv_len--;
518 /* temporarily trim the UID */
519 *(uid.bv_val++) = '\0';
522 rc = dnNormalize2( NULL, &out, normalized );
524 if( rc != LDAP_SUCCESS ) {
526 return LDAP_INVALID_SYNTAX;
530 normalized->bv_val = ch_realloc( normalized->bv_val,
531 normalized->bv_len + uid.bv_len + sizeof("#") );
533 /* insert the separator */
534 normalized->bv_val[normalized->bv_len++] = '#';
537 AC_MEMCPY( &normalized->bv_val[normalized->bv_len],
538 uid.bv_val, uid.bv_len );
539 normalized->bv_len += uid.bv_len;
542 normalized->bv_val[normalized->bv_len] = '\0';
553 * Handling boolean syntax and matching is quite rigid.
554 * A more flexible approach would be to allow a variety
555 * of strings to be normalized and prettied into TRUE
563 /* very unforgiving validation, requires no normalization
564 * before simplistic matching
567 if( in->bv_len == 4 ) {
568 if( !memcmp( in->bv_val, "TRUE", 4 ) ) {
571 } else if( in->bv_len == 5 ) {
572 if( !memcmp( in->bv_val, "FALSE", 5 ) ) {
577 return LDAP_INVALID_SYNTAX;
586 struct berval *value,
587 void *assertedValue )
589 /* simplistic matching allowed by rigid validation */
590 struct berval *asserted = (struct berval *) assertedValue;
591 *matchp = value->bv_len != asserted->bv_len;
595 /*-------------------------------------------------------------------
596 LDAP/X.500 string syntax / matching rules have a few oddities. This
597 comment attempts to detail how slapd(8) treats them.
600 StringSyntax X.500 LDAP Matching/Comments
601 DirectoryString CHOICE UTF8 i/e + ignore insignificant spaces
602 PrintableString subset subset i/e + ignore insignificant spaces
603 PrintableString subset subset i/e + ignore insignificant spaces
604 NumericString subset subset ignore all spaces
605 IA5String ASCII ASCII i/e + ignore insignificant spaces
606 TeletexString T.61 T.61 i/e + ignore insignificant spaces
608 TelephoneNumber subset subset i + ignore all spaces and "-"
610 See draft-ietf-ldapbis-strpro for details (once published).
614 In X.500(93), a directory string can be either a PrintableString,
615 a bmpString, or a UniversalString (e.g., UCS (a subset of Unicode)).
616 In later versions, more CHOICEs were added. In all cases the string
619 In LDAPv3, a directory string is a UTF-8 encoded UCS string.
620 A directory string cannot be zero length.
622 For matching, there are both case ignore and exact rules. Both
623 also require that "insignificant" spaces be ignored.
624 spaces before the first non-space are ignored;
625 spaces after the last non-space are ignored;
626 spaces after a space are ignored.
627 Note: by these rules (and as clarified in X.520), a string of only
628 spaces is to be treated as if held one space, not empty (which
629 would be a syntax error).
632 In ASN.1, numeric string is just a string of digits and spaces
633 and could be empty. However, in X.500, all attribute values of
634 numeric string carry a non-empty constraint. For example:
636 internationalISDNNumber ATTRIBUTE ::= {
637 WITH SYNTAX InternationalISDNNumber
638 EQUALITY MATCHING RULE numericStringMatch
639 SUBSTRINGS MATCHING RULE numericStringSubstringsMatch
640 ID id-at-internationalISDNNumber }
641 InternationalISDNNumber ::=
642 NumericString (SIZE(1..ub-international-isdn-number))
644 Unforunately, some assertion values are don't carry the same
645 constraint (but its unclear how such an assertion could ever
646 be true). In LDAP, there is one syntax (numericString) not two
647 (numericString with constraint, numericString without constraint).
648 This should be treated as numericString with non-empty constraint.
649 Note that while someone may have no ISDN number, there are no ISDN
650 numbers which are zero length.
652 In matching, spaces are ignored.
655 In ASN.1, Printable string is just a string of printable characters
656 and can be empty. In X.500, semantics much like NumericString (see
657 serialNumber for a like example) excepting uses insignificant space
658 handling instead of ignore all spaces.
661 Basically same as PrintableString. There are no examples in X.500,
662 but same logic applies. So we require them to be non-empty as
665 -------------------------------------------------------------------*/
674 unsigned char *u = in->bv_val;
676 if( in->bv_len == 0 && syntax == slap_schema.si_syn_directoryString ) {
677 /* directory strings cannot be empty */
678 return LDAP_INVALID_SYNTAX;
681 for( count = in->bv_len; count > 0; count-=len, u+=len ) {
682 /* get the length indicated by the first byte */
683 len = LDAP_UTF8_CHARLEN2( u, len );
685 /* very basic checks */
688 if( (u[5] & 0xC0) != 0x80 ) {
689 return LDAP_INVALID_SYNTAX;
692 if( (u[4] & 0xC0) != 0x80 ) {
693 return LDAP_INVALID_SYNTAX;
696 if( (u[3] & 0xC0) != 0x80 ) {
697 return LDAP_INVALID_SYNTAX;
700 if( (u[2] & 0xC0 )!= 0x80 ) {
701 return LDAP_INVALID_SYNTAX;
704 if( (u[1] & 0xC0) != 0x80 ) {
705 return LDAP_INVALID_SYNTAX;
708 /* CHARLEN already validated it */
711 return LDAP_INVALID_SYNTAX;
714 /* make sure len corresponds with the offset
715 to the next character */
716 if( LDAP_UTF8_OFFSET( u ) != len ) return LDAP_INVALID_SYNTAX;
720 return LDAP_INVALID_SYNTAX;
733 struct berval *normalized )
735 struct berval tmp, nvalue;
739 if( val->bv_val == NULL ) {
740 /* assume we're dealing with a syntax (e.g., UTF8String)
741 * which allows empty strings
743 normalized->bv_len = 0;
744 normalized->bv_val = NULL;
748 flags = SLAP_MR_ASSOCIATED(mr, slap_schema.si_mr_caseExactMatch )
749 ? LDAP_UTF8_NOCASEFOLD : LDAP_UTF8_CASEFOLD;
750 flags |= ( use & SLAP_MR_EQUALITY_APPROX == SLAP_MR_EQUALITY_APPROX )
751 ? LDAP_UTF8_APPROX : 0;
753 val = UTF8bvnormalize( val, &tmp, flags );
758 /* collapse spaces (in place) */
760 nvalue.bv_val = tmp.bv_val;
762 wasspace=1; /* trim leading spaces */
763 for( i=0; i<tmp.bv_len; i++) {
764 if ( ASCII_SPACE( tmp.bv_val[i] )) {
765 if( wasspace++ == 0 ) {
766 /* trim repeated spaces */
767 nvalue.bv_val[nvalue.bv_len++] = tmp.bv_val[i];
771 nvalue.bv_val[nvalue.bv_len++] = tmp.bv_val[i];
775 if( nvalue.bv_len ) {
777 /* last character was a space, trim it */
780 nvalue.bv_val[nvalue.bv_len] = '\0';
783 /* string of all spaces is treated as one space */
784 nvalue.bv_val[0] = ' ';
785 nvalue.bv_val[1] = '\0';
789 *normalized = nvalue;
795 xUTF8StringNormalize(
798 struct berval *normalized )
803 /* validator should have refused an empty string */
804 assert( val->bv_len );
808 /* Ignore initial whitespace */
809 /* All space is ASCII. All ASCII is 1 byte */
810 for ( ; p < val->bv_val + val->bv_len && ASCII_SPACE( p[ 0 ] ); p++ );
812 normalized->bv_len = val->bv_len - (p - val->bv_val);
814 if( !normalized->bv_len ) {
815 ber_mem2bv( " ", 1, 1, normalized );
819 ber_mem2bv( p, normalized->bv_len, 1, normalized );
820 e = normalized->bv_val + normalized->bv_len;
822 assert( normalized->bv_val );
824 p = q = normalized->bv_val;
829 if ( ASCII_SPACE( *p ) ) {
834 /* Ignore the extra whitespace */
835 while ( ASCII_SPACE( *p ) ) {
839 len = LDAP_UTF8_COPY(q,p);
845 assert( normalized->bv_val <= p );
846 assert( q+len <= p );
848 /* cannot start with a space */
849 assert( !ASCII_SPACE( normalized->bv_val[0] ) );
852 * If the string ended in space, backup the pointer one
853 * position. One is enough because the above loop collapsed
854 * all whitespace to a single space.
862 /* cannot end with a space */
863 assert( !ASCII_SPACE( *q ) );
870 normalized->bv_len = q - normalized->bv_val;
875 /* Returns Unicode canonically normalized copy of a substring assertion
876 * Skipping attribute description */
877 static SubstringsAssertion *
878 UTF8SubstringsAssertionNormalize(
879 SubstringsAssertion *sa,
882 SubstringsAssertion *nsa;
885 nsa = (SubstringsAssertion *)SLAP_CALLOC( 1, sizeof(SubstringsAssertion) );
890 if( sa->sa_initial.bv_val != NULL ) {
891 UTF8bvnormalize( &sa->sa_initial, &nsa->sa_initial, casefold );
892 if( nsa->sa_initial.bv_val == NULL ) {
897 if( sa->sa_any != NULL ) {
898 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
901 nsa->sa_any = (struct berval *)
902 SLAP_MALLOC( (i + 1) * sizeof(struct berval) );
903 if( nsa->sa_any == NULL ) {
907 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
908 UTF8bvnormalize( &sa->sa_any[i], &nsa->sa_any[i],
910 if( nsa->sa_any[i].bv_val == NULL ) {
914 nsa->sa_any[i].bv_val = NULL;
917 if( sa->sa_final.bv_val != NULL ) {
918 UTF8bvnormalize( &sa->sa_final, &nsa->sa_final, casefold );
919 if( nsa->sa_final.bv_val == NULL ) {
927 if ( nsa->sa_final.bv_val ) free( nsa->sa_final.bv_val );
928 if ( nsa->sa_any ) ber_bvarray_free( nsa->sa_any );
929 if ( nsa->sa_initial.bv_val ) free( nsa->sa_initial.bv_val );
934 #ifndef SLAPD_APPROX_OLDSINGLESTRING
936 #if defined(SLAPD_APPROX_INITIALS)
937 #define SLAPD_APPROX_DELIMITER "._ "
938 #define SLAPD_APPROX_WORDLEN 2
940 #define SLAPD_APPROX_DELIMITER " "
941 #define SLAPD_APPROX_WORDLEN 1
950 struct berval *value,
951 void *assertedValue )
953 struct berval *nval, *assertv;
954 char *val, **values, **words, *c;
955 int i, count, len, nextchunk=0, nextavail=0;
957 /* Yes, this is necessary */
958 nval = UTF8bvnormalize( value, NULL, LDAP_UTF8_APPROX );
964 /* Yes, this is necessary */
965 assertv = UTF8bvnormalize( ((struct berval *)assertedValue),
966 NULL, LDAP_UTF8_APPROX );
967 if( assertv == NULL ) {
973 /* Isolate how many words there are */
974 for ( c = nval->bv_val, count = 1; *c; c++ ) {
975 c = strpbrk( c, SLAPD_APPROX_DELIMITER );
976 if ( c == NULL ) break;
981 /* Get a phonetic copy of each word */
982 words = (char **)ch_malloc( count * sizeof(char *) );
983 values = (char **)ch_malloc( count * sizeof(char *) );
984 for ( c = nval->bv_val, i = 0; i < count; i++, c += strlen(c) + 1 ) {
986 values[i] = phonetic(c);
989 /* Work through the asserted value's words, to see if at least some
990 of the words are there, in the same order. */
992 while ( (ber_len_t) nextchunk < assertv->bv_len ) {
993 len = strcspn( assertv->bv_val + nextchunk, SLAPD_APPROX_DELIMITER);
998 #if defined(SLAPD_APPROX_INITIALS)
999 else if( len == 1 ) {
1000 /* Single letter words need to at least match one word's initial */
1001 for( i=nextavail; i<count; i++ )
1002 if( !strncasecmp( assertv->bv_val + nextchunk, words[i], 1 )) {
1009 /* Isolate the next word in the asserted value and phonetic it */
1010 assertv->bv_val[nextchunk+len] = '\0';
1011 val = phonetic( assertv->bv_val + nextchunk );
1013 /* See if this phonetic chunk is in the remaining words of *value */
1014 for( i=nextavail; i<count; i++ ){
1015 if( !strcmp( val, values[i] ) ){
1023 /* This chunk in the asserted value was NOT within the *value. */
1029 /* Go on to the next word in the asserted value */
1033 /* If some of the words were seen, call it a match */
1034 if( nextavail > 0 ) {
1041 /* Cleanup allocs */
1042 ber_bvfree( assertv );
1043 for( i=0; i<count; i++ ) {
1044 ch_free( values[i] );
1050 return LDAP_SUCCESS;
1059 struct berval *prefix,
1064 int i,j, len, wordcount, keycount=0;
1065 struct berval *newkeys;
1066 BerVarray keys=NULL;
1068 for( j=0; values[j].bv_val != NULL; j++ ) {
1069 struct berval val = { 0, NULL };
1070 /* Yes, this is necessary */
1071 UTF8bvnormalize( &values[j], &val, LDAP_UTF8_APPROX );
1072 assert( val.bv_val != NULL );
1074 /* Isolate how many words there are. There will be a key for each */
1075 for( wordcount = 0, c = val.bv_val; *c; c++) {
1076 len = strcspn(c, SLAPD_APPROX_DELIMITER);
1077 if( len >= SLAPD_APPROX_WORDLEN ) wordcount++;
1079 if (*c == '\0') break;
1083 /* Allocate/increase storage to account for new keys */
1084 newkeys = (struct berval *)ch_malloc( (keycount + wordcount + 1)
1085 * sizeof(struct berval) );
1086 AC_MEMCPY( newkeys, keys, keycount * sizeof(struct berval) );
1087 if( keys ) ch_free( keys );
1090 /* Get a phonetic copy of each word */
1091 for( c = val.bv_val, i = 0; i < wordcount; c += len + 1 ) {
1093 if( len < SLAPD_APPROX_WORDLEN ) continue;
1094 ber_str2bv( phonetic( c ), 0, 0, &keys[keycount] );
1099 ber_memfree( val.bv_val );
1101 keys[keycount].bv_val = NULL;
1104 return LDAP_SUCCESS;
1113 struct berval *prefix,
1114 void * assertedValue,
1122 /* Yes, this is necessary */
1123 val = UTF8bvnormalize( ((struct berval *)assertedValue),
1124 NULL, LDAP_UTF8_APPROX );
1125 if( val == NULL || val->bv_val == NULL ) {
1126 keys = (struct berval *)ch_malloc( sizeof(struct berval) );
1127 keys[0].bv_val = NULL;
1130 return LDAP_SUCCESS;
1133 /* Isolate how many words there are. There will be a key for each */
1134 for( count = 0,c = val->bv_val; *c; c++) {
1135 len = strcspn(c, SLAPD_APPROX_DELIMITER);
1136 if( len >= SLAPD_APPROX_WORDLEN ) count++;
1138 if (*c == '\0') break;
1142 /* Allocate storage for new keys */
1143 keys = (struct berval *)ch_malloc( (count + 1) * sizeof(struct berval) );
1145 /* Get a phonetic copy of each word */
1146 for( c = val->bv_val, i = 0; i < count; c += len + 1 ) {
1148 if( len < SLAPD_APPROX_WORDLEN ) continue;
1149 ber_str2bv( phonetic( c ), 0, 0, &keys[i] );
1155 keys[count].bv_val = NULL;
1158 return LDAP_SUCCESS;
1163 /* No other form of Approximate Matching is defined */
1171 struct berval *value,
1172 void *assertedValue )
1174 char *vapprox, *avapprox;
1177 /* Yes, this is necessary */
1178 s = UTF8normalize( value, UTF8_NOCASEFOLD );
1181 return LDAP_SUCCESS;
1184 /* Yes, this is necessary */
1185 t = UTF8normalize( ((struct berval *)assertedValue),
1190 return LDAP_SUCCESS;
1193 vapprox = phonetic( strip8bitChars( s ) );
1194 avapprox = phonetic( strip8bitChars( t ) );
1199 *matchp = strcmp( vapprox, avapprox );
1202 ch_free( avapprox );
1204 return LDAP_SUCCESS;
1213 struct berval *prefix,
1221 for( i=0; values[i].bv_val != NULL; i++ ) {
1222 /* empty - just count them */
1225 /* we should have at least one value at this point */
1228 keys = (struct berval *)ch_malloc( sizeof( struct berval ) * (i+1) );
1230 /* Copy each value and run it through phonetic() */
1231 for( i=0; values[i].bv_val != NULL; i++ ) {
1232 /* Yes, this is necessary */
1233 s = UTF8normalize( &values[i], UTF8_NOCASEFOLD );
1235 /* strip 8-bit chars and run through phonetic() */
1236 ber_str2bv( phonetic( strip8bitChars( s ) ), 0, 0, &keys[i] );
1239 keys[i].bv_val = NULL;
1242 return LDAP_SUCCESS;
1252 struct berval *prefix,
1253 void * assertedValue,
1259 keys = (struct berval *)ch_malloc( sizeof( struct berval * ) * 2 );
1261 /* Yes, this is necessary */
1262 s = UTF8normalize( ((struct berval *)assertedValue),
1267 /* strip 8-bit chars and run through phonetic() */
1268 keys[0] = ber_bvstr( phonetic( strip8bitChars( s ) ) );
1274 return LDAP_SUCCESS;
1285 struct berval *value,
1286 void *assertedValue )
1288 *matchp = UTF8bvnormcmp( value,
1289 (struct berval *) assertedValue,
1290 LDAP_UTF8_NOCASEFOLD );
1291 return LDAP_SUCCESS;
1295 caseExactIgnoreSubstringsMatch(
1300 struct berval *value,
1301 void *assertedValue )
1304 SubstringsAssertion *sub = NULL;
1305 struct berval left = { 0, NULL };
1311 casefold = ( mr != slap_schema.si_mr_caseExactSubstringsMatch )
1312 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1314 if ( UTF8bvnormalize( value, &left, casefold ) == NULL ) {
1320 sub = UTF8SubstringsAssertionNormalize( assertedValue, casefold );
1326 /* Add up asserted input length */
1327 if( sub->sa_initial.bv_val ) {
1328 inlen += sub->sa_initial.bv_len;
1331 for(i=0; sub->sa_any[i].bv_val != NULL; i++) {
1332 inlen += sub->sa_any[i].bv_len;
1335 if( sub->sa_final.bv_val ) {
1336 inlen += sub->sa_final.bv_len;
1339 if( sub->sa_initial.bv_val ) {
1340 if( inlen > left.bv_len ) {
1345 match = memcmp( sub->sa_initial.bv_val, left.bv_val,
1346 sub->sa_initial.bv_len );
1352 left.bv_val += sub->sa_initial.bv_len;
1353 left.bv_len -= sub->sa_initial.bv_len;
1354 inlen -= sub->sa_initial.bv_len;
1357 if( sub->sa_final.bv_val ) {
1358 if( inlen > left.bv_len ) {
1363 match = memcmp( sub->sa_final.bv_val,
1364 &left.bv_val[left.bv_len - sub->sa_final.bv_len],
1365 sub->sa_final.bv_len );
1371 left.bv_len -= sub->sa_final.bv_len;
1372 inlen -= sub->sa_final.bv_len;
1376 for(i=0; sub->sa_any[i].bv_val; i++) {
1381 if( inlen > left.bv_len ) {
1382 /* not enough length */
1387 if( sub->sa_any[i].bv_len == 0 ) {
1391 p = ber_bvchr( &left, *sub->sa_any[i].bv_val );
1397 idx = p - left.bv_val;
1399 if( idx >= left.bv_len ) {
1400 /* this shouldn't happen */
1402 if ( sub->sa_final.bv_val )
1403 ch_free( sub->sa_final.bv_val );
1405 ber_bvarray_free( sub->sa_any );
1406 if ( sub->sa_initial.bv_val )
1407 ch_free( sub->sa_initial.bv_val );
1415 if( sub->sa_any[i].bv_len > left.bv_len ) {
1416 /* not enough left */
1421 match = memcmp( left.bv_val,
1422 sub->sa_any[i].bv_val,
1423 sub->sa_any[i].bv_len );
1431 left.bv_val += sub->sa_any[i].bv_len;
1432 left.bv_len -= sub->sa_any[i].bv_len;
1433 inlen -= sub->sa_any[i].bv_len;
1440 if ( sub->sa_final.bv_val ) free( sub->sa_final.bv_val );
1441 if ( sub->sa_any ) ber_bvarray_free( sub->sa_any );
1442 if ( sub->sa_initial.bv_val ) free( sub->sa_initial.bv_val );
1446 return LDAP_SUCCESS;
1449 /* Index generation function */
1450 static int caseExactIgnoreIndexer(
1455 struct berval *prefix,
1460 unsigned casefold,wasspace;
1463 HASH_CONTEXT HASHcontext;
1464 unsigned char HASHdigest[HASH_BYTES];
1465 struct berval digest;
1466 digest.bv_val = HASHdigest;
1467 digest.bv_len = sizeof(HASHdigest);
1469 for( i=0; values[i].bv_val != NULL; i++ ) {
1470 /* empty - just count them */
1473 /* we should have at least one value at this point */
1476 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
1478 slen = syntax->ssyn_oidlen;
1479 mlen = mr->smr_oidlen;
1481 casefold = ( mr != slap_schema.si_mr_caseExactMatch )
1482 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1484 for( i=0; values[i].bv_val != NULL; i++ ) {
1485 struct berval value, nvalue;
1486 UTF8bvnormalize( &values[i], &value, casefold );
1488 /* collapse spaces (in place) */
1490 nvalue.bv_val = value.bv_val;
1493 for( j=0; j<value.bv_len; j++) {
1494 if ( ASCII_SPACE( value.bv_val[j] )) {
1495 if( wasspace++ == 0 ) {
1496 nvalue.bv_val[nvalue.bv_len++] = value.bv_val[j];
1500 nvalue.bv_val[nvalue.bv_len++] = value.bv_val[j];
1504 if( nvalue.bv_len == 0 ) {
1505 nvalue.bv_val = " ";
1506 nvalue.bv_len = sizeof(" ")-1;
1508 if( wasspace ) --nvalue.bv_len;
1509 nvalue.bv_val[nvalue.bv_len] = '\0';
1512 HASH_Init( &HASHcontext );
1513 if( prefix != NULL && prefix->bv_len > 0 ) {
1514 HASH_Update( &HASHcontext,
1515 prefix->bv_val, prefix->bv_len );
1517 HASH_Update( &HASHcontext,
1518 syntax->ssyn_oid, slen );
1519 HASH_Update( &HASHcontext,
1520 mr->smr_oid, mlen );
1521 HASH_Update( &HASHcontext,
1522 nvalue.bv_val, nvalue.bv_len );
1523 HASH_Final( HASHdigest, &HASHcontext );
1525 free( value.bv_val );
1526 ber_dupbv( &keys[i], &digest );
1529 keys[i].bv_val = NULL;
1531 return LDAP_SUCCESS;
1534 /* Index generation function */
1535 static int caseExactIgnoreFilter(
1540 struct berval *prefix,
1541 void * assertedValue,
1547 HASH_CONTEXT HASHcontext;
1548 unsigned char HASHdigest[HASH_BYTES];
1549 struct berval value = { 0, NULL };
1550 struct berval digest;
1552 digest.bv_val = HASHdigest;
1553 digest.bv_len = sizeof(HASHdigest);
1555 slen = syntax->ssyn_oidlen;
1556 mlen = mr->smr_oidlen;
1558 casefold = ( mr != slap_schema.si_mr_caseExactMatch )
1559 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1561 UTF8bvnormalize( (struct berval *) assertedValue, &value, casefold );
1562 /* This usually happens if filter contains bad UTF8 */
1563 if( value.bv_val == NULL ) {
1564 keys = ch_malloc( sizeof( struct berval ) );
1565 keys[0].bv_val = NULL;
1566 return LDAP_SUCCESS;
1569 keys = ch_malloc( sizeof( struct berval ) * 2 );
1571 HASH_Init( &HASHcontext );
1572 if( prefix != NULL && prefix->bv_len > 0 ) {
1573 HASH_Update( &HASHcontext,
1574 prefix->bv_val, prefix->bv_len );
1576 HASH_Update( &HASHcontext,
1577 syntax->ssyn_oid, slen );
1578 HASH_Update( &HASHcontext,
1579 mr->smr_oid, mlen );
1580 HASH_Update( &HASHcontext,
1581 value.bv_val, value.bv_len );
1582 HASH_Final( HASHdigest, &HASHcontext );
1584 ber_dupbv( keys, &digest );
1585 keys[1].bv_val = NULL;
1587 free( value.bv_val );
1590 return LDAP_SUCCESS;
1593 /* Substrings Index generation function */
1594 static int caseExactIgnoreSubstringsIndexer(
1599 struct berval *prefix,
1603 unsigned casefold, wasspace;
1604 ber_len_t i, j, nkeys;
1607 BerVarray tvalues, nvalues;
1609 HASH_CONTEXT HASHcontext;
1610 unsigned char HASHdigest[HASH_BYTES];
1611 struct berval digest;
1612 digest.bv_val = HASHdigest;
1613 digest.bv_len = sizeof(HASHdigest);
1617 for( i=0; values[i].bv_val != NULL; i++ ) {
1618 /* empty - just count them */
1621 /* we should have at least one value at this point */
1624 casefold = ( mr != slap_schema.si_mr_caseExactSubstringsMatch )
1625 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1627 tvalues = ch_malloc( sizeof( struct berval ) * (i+1) );
1628 nvalues = ch_malloc( sizeof( struct berval ) * (i+1) );
1630 for( i=0; values[i].bv_val != NULL; i++ ) {
1631 UTF8bvnormalize( &values[i], &tvalues[i], casefold );
1633 /* collapse spaces (in place) */
1634 nvalues[i].bv_len = 0;
1635 nvalues[i].bv_val = tvalues[i].bv_val;
1638 for( j=0; j<tvalues[i].bv_len; j++) {
1639 if ( ASCII_SPACE( tvalues[i].bv_val[j] )) {
1640 if( wasspace++ == 0 ) {
1641 nvalues[i].bv_val[nvalues[i].bv_len++] =
1642 tvalues[i].bv_val[j];
1646 nvalues[i].bv_val[nvalues[i].bv_len++] = tvalues[i].bv_val[j];
1650 if( nvalues[i].bv_len == 0 ) {
1651 nvalues[i].bv_val = " ";
1652 nvalues[i].bv_len = sizeof(" ")-1;
1654 if( wasspace ) --nvalues[i].bv_len;
1655 nvalues[i].bv_val[nvalues[i].bv_len] = '\0';
1659 tvalues[i].bv_val = NULL;
1660 nvalues[i].bv_val = NULL;
1663 for( i=0; values[i].bv_val != NULL; i++ ) {
1664 /* count number of indices to generate */
1665 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
1669 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
1670 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1671 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
1672 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
1674 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
1678 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
1679 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1680 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
1684 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
1685 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1686 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
1687 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
1689 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
1695 /* no keys to generate */
1697 ber_bvarray_free( tvalues );
1699 return LDAP_SUCCESS;
1702 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
1704 slen = syntax->ssyn_oidlen;
1705 mlen = mr->smr_oidlen;
1708 for( i=0; values[i].bv_val != NULL; i++ ) {
1711 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
1713 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
1714 ( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
1716 char pre = SLAP_INDEX_SUBSTR_PREFIX;
1717 max = values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
1719 for( j=0; j<max; j++ ) {
1720 HASH_Init( &HASHcontext );
1721 if( prefix != NULL && prefix->bv_len > 0 ) {
1722 HASH_Update( &HASHcontext,
1723 prefix->bv_val, prefix->bv_len );
1726 HASH_Update( &HASHcontext,
1727 &pre, sizeof( pre ) );
1728 HASH_Update( &HASHcontext,
1729 syntax->ssyn_oid, slen );
1730 HASH_Update( &HASHcontext,
1731 mr->smr_oid, mlen );
1732 HASH_Update( &HASHcontext,
1733 &values[i].bv_val[j],
1734 SLAP_INDEX_SUBSTR_MAXLEN );
1735 HASH_Final( HASHdigest, &HASHcontext );
1737 ber_dupbv( &keys[nkeys++], &digest );
1741 max = SLAP_INDEX_SUBSTR_MAXLEN < values[i].bv_len
1742 ? SLAP_INDEX_SUBSTR_MAXLEN : values[i].bv_len;
1744 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
1747 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
1748 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
1749 HASH_Init( &HASHcontext );
1750 if( prefix != NULL && prefix->bv_len > 0 ) {
1751 HASH_Update( &HASHcontext,
1752 prefix->bv_val, prefix->bv_len );
1754 HASH_Update( &HASHcontext,
1755 &pre, sizeof( pre ) );
1756 HASH_Update( &HASHcontext,
1757 syntax->ssyn_oid, slen );
1758 HASH_Update( &HASHcontext,
1759 mr->smr_oid, mlen );
1760 HASH_Update( &HASHcontext,
1761 values[i].bv_val, j );
1762 HASH_Final( HASHdigest, &HASHcontext );
1764 ber_dupbv( &keys[nkeys++], &digest );
1767 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
1768 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
1769 HASH_Init( &HASHcontext );
1770 if( prefix != NULL && prefix->bv_len > 0 ) {
1771 HASH_Update( &HASHcontext,
1772 prefix->bv_val, prefix->bv_len );
1774 HASH_Update( &HASHcontext,
1775 &pre, sizeof( pre ) );
1776 HASH_Update( &HASHcontext,
1777 syntax->ssyn_oid, slen );
1778 HASH_Update( &HASHcontext,
1779 mr->smr_oid, mlen );
1780 HASH_Update( &HASHcontext,
1781 &values[i].bv_val[values[i].bv_len-j], j );
1782 HASH_Final( HASHdigest, &HASHcontext );
1784 ber_dupbv( &keys[nkeys++], &digest );
1792 keys[nkeys].bv_val = NULL;
1799 ber_bvarray_free( tvalues );
1802 return LDAP_SUCCESS;
1805 static int caseExactIgnoreSubstringsFilter(
1810 struct berval *prefix,
1811 void * assertedValue,
1814 SubstringsAssertion *sa;
1817 ber_len_t nkeys = 0;
1818 size_t slen, mlen, klen;
1820 HASH_CONTEXT HASHcontext;
1821 unsigned char HASHdigest[HASH_BYTES];
1822 struct berval *value;
1823 struct berval digest;
1825 casefold = ( mr != slap_schema.si_mr_caseExactSubstringsMatch )
1826 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1828 sa = UTF8SubstringsAssertionNormalize( assertedValue, casefold );
1831 return LDAP_SUCCESS;
1834 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
1835 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1840 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
1842 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
1843 if( sa->sa_any[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1844 /* don't bother accounting for stepping */
1845 nkeys += sa->sa_any[i].bv_len -
1846 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
1851 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
1852 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1858 if ( sa->sa_final.bv_val ) free( sa->sa_final.bv_val );
1859 if ( sa->sa_any ) ber_bvarray_free( sa->sa_any );
1860 if ( sa->sa_initial.bv_val ) free( sa->sa_initial.bv_val );
1863 return LDAP_SUCCESS;
1866 digest.bv_val = HASHdigest;
1867 digest.bv_len = sizeof(HASHdigest);
1869 slen = syntax->ssyn_oidlen;
1870 mlen = mr->smr_oidlen;
1872 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
1875 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
1876 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1878 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
1879 value = &sa->sa_initial;
1881 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
1882 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
1884 HASH_Init( &HASHcontext );
1885 if( prefix != NULL && prefix->bv_len > 0 ) {
1886 HASH_Update( &HASHcontext,
1887 prefix->bv_val, prefix->bv_len );
1889 HASH_Update( &HASHcontext,
1890 &pre, sizeof( pre ) );
1891 HASH_Update( &HASHcontext,
1892 syntax->ssyn_oid, slen );
1893 HASH_Update( &HASHcontext,
1894 mr->smr_oid, mlen );
1895 HASH_Update( &HASHcontext,
1896 value->bv_val, klen );
1897 HASH_Final( HASHdigest, &HASHcontext );
1899 ber_dupbv( &keys[nkeys++], &digest );
1902 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
1904 pre = SLAP_INDEX_SUBSTR_PREFIX;
1905 klen = SLAP_INDEX_SUBSTR_MAXLEN;
1907 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
1908 if( sa->sa_any[i].bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
1912 value = &sa->sa_any[i];
1915 j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
1916 j += SLAP_INDEX_SUBSTR_STEP )
1918 HASH_Init( &HASHcontext );
1919 if( prefix != NULL && prefix->bv_len > 0 ) {
1920 HASH_Update( &HASHcontext,
1921 prefix->bv_val, prefix->bv_len );
1923 HASH_Update( &HASHcontext,
1924 &pre, sizeof( pre ) );
1925 HASH_Update( &HASHcontext,
1926 syntax->ssyn_oid, slen );
1927 HASH_Update( &HASHcontext,
1928 mr->smr_oid, mlen );
1929 HASH_Update( &HASHcontext,
1930 &value->bv_val[j], klen );
1931 HASH_Final( HASHdigest, &HASHcontext );
1933 ber_dupbv( &keys[nkeys++], &digest );
1939 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
1940 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1942 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
1943 value = &sa->sa_final;
1945 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
1946 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
1948 HASH_Init( &HASHcontext );
1949 if( prefix != NULL && prefix->bv_len > 0 ) {
1950 HASH_Update( &HASHcontext,
1951 prefix->bv_val, prefix->bv_len );
1953 HASH_Update( &HASHcontext,
1954 &pre, sizeof( pre ) );
1955 HASH_Update( &HASHcontext,
1956 syntax->ssyn_oid, slen );
1957 HASH_Update( &HASHcontext,
1958 mr->smr_oid, mlen );
1959 HASH_Update( &HASHcontext,
1960 &value->bv_val[value->bv_len-klen], klen );
1961 HASH_Final( HASHdigest, &HASHcontext );
1963 ber_dupbv( &keys[nkeys++], &digest );
1967 keys[nkeys].bv_val = NULL;
1973 if ( sa->sa_final.bv_val ) free( sa->sa_final.bv_val );
1974 if ( sa->sa_any ) ber_bvarray_free( sa->sa_any );
1975 if ( sa->sa_initial.bv_val ) free( sa->sa_initial.bv_val );
1978 return LDAP_SUCCESS;
1987 struct berval *value,
1988 void *assertedValue )
1990 *matchp = UTF8bvnormcmp( value,
1991 (struct berval *) assertedValue,
1992 LDAP_UTF8_CASEFOLD );
1993 return LDAP_SUCCESS;
1996 /* Remove all spaces and '-' characters */
1998 xtelephoneNumberNormalize(
2001 struct berval *normalized )
2005 /* validator should have refused an empty string */
2006 assert( val->bv_len );
2008 q = normalized->bv_val = ch_malloc( val->bv_len + 1 );
2010 for( p = val->bv_val; *p; p++ ) {
2011 if ( ! ( ASCII_SPACE( *p ) || *p == '-' )) {
2017 normalized->bv_len = q - normalized->bv_val;
2019 if( normalized->bv_len == 0 ) {
2020 free( normalized->bv_val );
2021 return LDAP_INVALID_SYNTAX;
2024 return LDAP_SUCCESS;
2031 struct berval *val )
2035 if( val->bv_len == 0 ) {
2036 /* disallow empty strings */
2037 return LDAP_INVALID_SYNTAX;
2040 if( OID_LEADCHAR(val->bv_val[0]) ) {
2042 for(i=1; i < val->bv_len; i++) {
2043 if( OID_SEPARATOR( val->bv_val[i] ) ) {
2044 if( dot++ ) return 1;
2045 } else if ( OID_CHAR( val->bv_val[i] ) ) {
2048 return LDAP_INVALID_SYNTAX;
2052 return !dot ? LDAP_SUCCESS : LDAP_INVALID_SYNTAX;
2054 } else if( DESC_LEADCHAR(val->bv_val[0]) ) {
2055 for(i=1; i < val->bv_len; i++) {
2056 if( !DESC_CHAR(val->bv_val[i] ) ) {
2057 return LDAP_INVALID_SYNTAX;
2061 return LDAP_SUCCESS;
2064 return LDAP_INVALID_SYNTAX;
2067 #ifndef SLAP_NVALUES
2075 struct berval *value,
2076 void *assertedValue )
2079 int vsign = 1, avsign = 1; /* default sign = '+' */
2080 struct berval *asserted;
2081 ber_len_t vlen, avlen;
2084 /* Skip leading space/sign/zeroes, and get the sign of the *value number */
2086 vlen = value->bv_len;
2087 if( mr == slap_schema.si_mr_integerFirstComponentMatch ) {
2088 char *tmp = memchr( v, '$', vlen );
2091 while( vlen && ASCII_SPACE( v[vlen-1] ))
2094 for( ; vlen && ( *v < '1' || '9' < *v ); v++, vlen-- ) /* ANSI 2.2.1 */
2100 /* Do the same with the *assertedValue number */
2101 asserted = (struct berval *) assertedValue;
2102 av = asserted->bv_val;
2103 avlen = asserted->bv_len;
2104 for( ; avlen && ( *av < '1' || '9' < *av ); av++, avlen-- )
2110 match = vsign - avsign;
2112 match = (vlen != avlen
2113 ? ( vlen < avlen ? -1 : 1 )
2114 : memcmp( v, av, vlen ));
2120 return LDAP_SUCCESS;
2127 struct berval *val )
2131 if( !val->bv_len ) return LDAP_INVALID_SYNTAX;
2133 if(( val->bv_val[0] == '+' ) || ( val->bv_val[0] == '-' )) {
2134 if( val->bv_len < 2 ) return LDAP_INVALID_SYNTAX;
2135 } else if( !ASCII_DIGIT(val->bv_val[0]) ) {
2136 return LDAP_INVALID_SYNTAX;
2139 for( i=1; i < val->bv_len; i++ ) {
2140 if( !ASCII_DIGIT(val->bv_val[i]) ) return LDAP_INVALID_SYNTAX;
2143 return LDAP_SUCCESS;
2146 #ifndef SLAP_NVALUES
2151 struct berval *normalized )
2161 /* Ignore leading spaces */
2162 while ( len && ( *p == ' ' )) {
2169 negative = ( *p == '-' );
2170 if(( *p == '-' ) || ( *p == '+' )) {
2176 /* Ignore leading zeros */
2177 while ( len && ( *p == '0' )) {
2182 /* If there are no non-zero digits left, the number is zero, otherwise
2183 allocate space for the number and copy it into the buffer */
2185 normalized->bv_val = ch_strdup("0");
2186 normalized->bv_len = 1;
2189 normalized->bv_len = len+negative;
2190 normalized->bv_val = ch_malloc( normalized->bv_len + 1 );
2192 normalized->bv_val[0] = '-';
2194 AC_MEMCPY( normalized->bv_val + negative, p, len );
2195 normalized->bv_val[len+negative] = '\0';
2198 return LDAP_SUCCESS;
2201 /* Index generation function */
2202 static int integerIndexer(
2207 struct berval *prefix,
2214 HASH_CONTEXT HASHcontext;
2215 unsigned char HASHdigest[HASH_BYTES];
2216 struct berval digest;
2217 digest.bv_val = HASHdigest;
2218 digest.bv_len = sizeof(HASHdigest);
2220 for( i=0; values[i].bv_val != NULL; i++ ) {
2221 /* empty - just count them */
2224 /* we should have at least one value at this point */
2227 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
2229 slen = syntax->ssyn_oidlen;
2230 mlen = mr->smr_oidlen;
2232 for( i=0; values[i].bv_val != NULL; i++ ) {
2234 xintegerNormalize( syntax, &values[i], &norm );
2236 HASH_Init( &HASHcontext );
2237 if( prefix != NULL && prefix->bv_len > 0 ) {
2238 HASH_Update( &HASHcontext,
2239 prefix->bv_val, prefix->bv_len );
2241 HASH_Update( &HASHcontext,
2242 syntax->ssyn_oid, slen );
2243 HASH_Update( &HASHcontext,
2244 mr->smr_oid, mlen );
2245 HASH_Update( &HASHcontext,
2246 norm.bv_val, norm.bv_len );
2247 HASH_Final( HASHdigest, &HASHcontext );
2249 ber_dupbv( &keys[i], &digest );
2250 ch_free( norm.bv_val );
2253 keys[i].bv_val = NULL;
2255 return LDAP_SUCCESS;
2258 /* Index generation function */
2259 static int integerFilter(
2264 struct berval *prefix,
2265 void * assertedValue,
2270 HASH_CONTEXT HASHcontext;
2271 unsigned char HASHdigest[HASH_BYTES];
2273 struct berval digest;
2274 digest.bv_val = HASHdigest;
2275 digest.bv_len = sizeof(HASHdigest);
2277 slen = syntax->ssyn_oidlen;
2278 mlen = mr->smr_oidlen;
2280 xintegerNormalize( syntax, assertedValue, &norm );
2282 keys = ch_malloc( sizeof( struct berval ) * 2 );
2284 HASH_Init( &HASHcontext );
2285 if( prefix != NULL && prefix->bv_len > 0 ) {
2286 HASH_Update( &HASHcontext,
2287 prefix->bv_val, prefix->bv_len );
2289 HASH_Update( &HASHcontext,
2290 syntax->ssyn_oid, slen );
2291 HASH_Update( &HASHcontext,
2292 mr->smr_oid, mlen );
2293 HASH_Update( &HASHcontext,
2294 norm.bv_val, norm.bv_len );
2295 HASH_Final( HASHdigest, &HASHcontext );
2297 ber_dupbv( &keys[0], &digest );
2298 keys[1].bv_val = NULL;
2299 ch_free( norm.bv_val );
2302 return LDAP_SUCCESS;
2308 countryStringValidate(
2310 struct berval *val )
2312 if( val->bv_len != 2 ) return LDAP_INVALID_SYNTAX;
2314 if( !SLAP_PRINTABLE(val->bv_val[0]) ) {
2315 return LDAP_INVALID_SYNTAX;
2317 if( !SLAP_PRINTABLE(val->bv_val[1]) ) {
2318 return LDAP_INVALID_SYNTAX;
2321 return LDAP_SUCCESS;
2325 printableStringValidate(
2327 struct berval *val )
2331 if( val->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
2333 for(i=0; i < val->bv_len; i++) {
2334 if( !SLAP_PRINTABLE(val->bv_val[i]) ) {
2335 return LDAP_INVALID_SYNTAX;
2339 return LDAP_SUCCESS;
2343 printablesStringValidate(
2345 struct berval *val )
2349 if( val->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
2351 for(i=0,len=0; i < val->bv_len; i++) {
2352 int c = val->bv_val[i];
2356 return LDAP_INVALID_SYNTAX;
2360 } else if ( SLAP_PRINTABLE(c) ) {
2363 return LDAP_INVALID_SYNTAX;
2368 return LDAP_INVALID_SYNTAX;
2371 return LDAP_SUCCESS;
2377 struct berval *val )
2381 if( val->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
2383 for(i=0; i < val->bv_len; i++) {
2384 if( !LDAP_ASCII(val->bv_val[i]) ) {
2385 return LDAP_INVALID_SYNTAX;
2389 return LDAP_SUCCESS;
2399 struct berval *normalized )
2402 xIA5StringNormalize(
2405 struct berval *normalized )
2410 int casefold = !SLAP_MR_ASSOCIATED(mr, slap_schema.si_mr_caseExactIA5Match);
2413 assert( val->bv_len );
2417 /* Ignore initial whitespace */
2418 while ( ASCII_SPACE( *p ) ) {
2422 normalized->bv_val = ch_strdup( p );
2423 p = q = normalized->bv_val;
2426 if ( ASCII_SPACE( *p ) ) {
2429 /* Ignore the extra whitespace */
2430 while ( ASCII_SPACE( *p ) ) {
2435 } else if ( casefold ) {
2436 /* Most IA5 rules require casefolding */
2437 *q++ = TOLOWER(*p++);
2445 assert( normalized->bv_val <= p );
2449 * If the string ended in space, backup the pointer one
2450 * position. One is enough because the above loop collapsed
2451 * all whitespace to a single space.
2454 if ( ASCII_SPACE( q[-1] ) ) {
2458 /* null terminate */
2461 normalized->bv_len = q - normalized->bv_val;
2463 if( normalized->bv_len == 0 ) {
2464 normalized->bv_val = ch_realloc( normalized->bv_val, 2 );
2465 normalized->bv_val[0] = ' ';
2466 normalized->bv_val[1] = '\0';
2467 normalized->bv_len = 1;
2470 return LDAP_SUCCESS;
2473 #ifndef SLAP_NVALUES
2481 struct berval *value,
2482 void *assertedValue )
2484 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
2487 match = strncmp( value->bv_val,
2488 ((struct berval *) assertedValue)->bv_val,
2493 return LDAP_SUCCESS;
2497 caseExactIA5SubstringsMatch
2507 struct berval *value,
2508 void *assertedValue )
2511 SubstringsAssertion *sub = assertedValue;
2512 struct berval left = *value;
2516 /* Add up asserted input length */
2517 if( sub->sa_initial.bv_val ) {
2518 inlen += sub->sa_initial.bv_len;
2521 for(i=0; sub->sa_any[i].bv_val != NULL; i++) {
2522 inlen += sub->sa_any[i].bv_len;
2525 if( sub->sa_final.bv_val ) {
2526 inlen += sub->sa_final.bv_len;
2529 if( sub->sa_initial.bv_val ) {
2530 if( inlen > left.bv_len ) {
2535 match = strncmp( sub->sa_initial.bv_val, left.bv_val,
2536 sub->sa_initial.bv_len );
2542 left.bv_val += sub->sa_initial.bv_len;
2543 left.bv_len -= sub->sa_initial.bv_len;
2544 inlen -= sub->sa_initial.bv_len;
2547 if( sub->sa_final.bv_val ) {
2548 if( inlen > left.bv_len ) {
2553 match = strncmp( sub->sa_final.bv_val,
2554 &left.bv_val[left.bv_len - sub->sa_final.bv_len],
2555 sub->sa_final.bv_len );
2561 left.bv_len -= sub->sa_final.bv_len;
2562 inlen -= sub->sa_final.bv_len;
2566 for(i=0; sub->sa_any[i].bv_val; i++) {
2571 if( inlen > left.bv_len ) {
2572 /* not enough length */
2577 if( sub->sa_any[i].bv_len == 0 ) {
2581 p = strchr( left.bv_val, *sub->sa_any[i].bv_val );
2588 idx = p - left.bv_val;
2590 if( idx >= left.bv_len ) {
2591 /* this shouldn't happen */
2598 if( sub->sa_any[i].bv_len > left.bv_len ) {
2599 /* not enough left */
2604 match = strncmp( left.bv_val,
2605 sub->sa_any[i].bv_val,
2606 sub->sa_any[i].bv_len );
2614 left.bv_val += sub->sa_any[i].bv_len;
2615 left.bv_len -= sub->sa_any[i].bv_len;
2616 inlen -= sub->sa_any[i].bv_len;
2622 return LDAP_SUCCESS;
2625 #ifndef SLAP_NVALUES
2627 /* Index generation function */
2628 static int caseExactIA5Indexer(
2633 struct berval *prefix,
2640 HASH_CONTEXT HASHcontext;
2641 unsigned char HASHdigest[HASH_BYTES];
2642 struct berval digest;
2643 digest.bv_val = HASHdigest;
2644 digest.bv_len = sizeof(HASHdigest);
2646 for( i=0; values[i].bv_val != NULL; i++ ) {
2647 /* empty - just count them */
2650 /* we should have at least one value at this point */
2653 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
2655 slen = syntax->ssyn_oidlen;
2656 mlen = mr->smr_oidlen;
2658 for( i=0; values[i].bv_val != NULL; i++ ) {
2659 struct berval *value = &values[i];
2661 HASH_Init( &HASHcontext );
2662 if( prefix != NULL && prefix->bv_len > 0 ) {
2663 HASH_Update( &HASHcontext,
2664 prefix->bv_val, prefix->bv_len );
2666 HASH_Update( &HASHcontext,
2667 syntax->ssyn_oid, slen );
2668 HASH_Update( &HASHcontext,
2669 mr->smr_oid, mlen );
2670 HASH_Update( &HASHcontext,
2671 value->bv_val, value->bv_len );
2672 HASH_Final( HASHdigest, &HASHcontext );
2674 ber_dupbv( &keys[i], &digest );
2677 keys[i].bv_val = NULL;
2679 return LDAP_SUCCESS;
2682 /* Index generation function */
2683 static int caseExactIA5Filter(
2688 struct berval *prefix,
2689 void * assertedValue,
2694 HASH_CONTEXT HASHcontext;
2695 unsigned char HASHdigest[HASH_BYTES];
2696 struct berval *value;
2697 struct berval digest;
2698 digest.bv_val = HASHdigest;
2699 digest.bv_len = sizeof(HASHdigest);
2701 slen = syntax->ssyn_oidlen;
2702 mlen = mr->smr_oidlen;
2704 value = (struct berval *) assertedValue;
2706 keys = ch_malloc( sizeof( struct berval ) * 2 );
2708 HASH_Init( &HASHcontext );
2709 if( prefix != NULL && prefix->bv_len > 0 ) {
2710 HASH_Update( &HASHcontext,
2711 prefix->bv_val, prefix->bv_len );
2713 HASH_Update( &HASHcontext,
2714 syntax->ssyn_oid, slen );
2715 HASH_Update( &HASHcontext,
2716 mr->smr_oid, mlen );
2717 HASH_Update( &HASHcontext,
2718 value->bv_val, value->bv_len );
2719 HASH_Final( HASHdigest, &HASHcontext );
2721 ber_dupbv( &keys[0], &digest );
2722 keys[1].bv_val = NULL;
2725 return LDAP_SUCCESS;
2728 /* Substrings Index generation function */
2729 static int caseExactIA5SubstringsIndexer(
2734 struct berval *prefix,
2741 HASH_CONTEXT HASHcontext;
2742 unsigned char HASHdigest[HASH_BYTES];
2743 struct berval digest;
2744 digest.bv_val = HASHdigest;
2745 digest.bv_len = sizeof(HASHdigest);
2747 /* we should have at least one value at this point */
2748 assert( values != NULL && values[0].bv_val != NULL );
2751 for( i=0; values[i].bv_val != NULL; i++ ) {
2752 /* count number of indices to generate */
2753 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
2757 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
2758 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2759 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2760 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2762 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2766 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
2767 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2768 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
2772 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
2773 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2774 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2775 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2777 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2783 /* no keys to generate */
2785 return LDAP_SUCCESS;
2788 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
2790 slen = syntax->ssyn_oidlen;
2791 mlen = mr->smr_oidlen;
2794 for( i=0; values[i].bv_val != NULL; i++ ) {
2796 struct berval *value;
2799 if( value->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
2801 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
2802 ( value->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
2804 char pre = SLAP_INDEX_SUBSTR_PREFIX;
2805 max = value->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
2807 for( j=0; j<max; j++ ) {
2808 HASH_Init( &HASHcontext );
2809 if( prefix != NULL && prefix->bv_len > 0 ) {
2810 HASH_Update( &HASHcontext,
2811 prefix->bv_val, prefix->bv_len );
2814 HASH_Update( &HASHcontext,
2815 &pre, sizeof( pre ) );
2816 HASH_Update( &HASHcontext,
2817 syntax->ssyn_oid, slen );
2818 HASH_Update( &HASHcontext,
2819 mr->smr_oid, mlen );
2820 HASH_Update( &HASHcontext,
2822 SLAP_INDEX_SUBSTR_MAXLEN );
2823 HASH_Final( HASHdigest, &HASHcontext );
2825 ber_dupbv( &keys[nkeys++], &digest );
2829 max = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2830 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2832 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
2835 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
2836 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
2837 HASH_Init( &HASHcontext );
2838 if( prefix != NULL && prefix->bv_len > 0 ) {
2839 HASH_Update( &HASHcontext,
2840 prefix->bv_val, prefix->bv_len );
2842 HASH_Update( &HASHcontext,
2843 &pre, sizeof( pre ) );
2844 HASH_Update( &HASHcontext,
2845 syntax->ssyn_oid, slen );
2846 HASH_Update( &HASHcontext,
2847 mr->smr_oid, mlen );
2848 HASH_Update( &HASHcontext,
2850 HASH_Final( HASHdigest, &HASHcontext );
2852 ber_dupbv( &keys[nkeys++], &digest );
2855 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
2856 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
2857 HASH_Init( &HASHcontext );
2858 if( prefix != NULL && prefix->bv_len > 0 ) {
2859 HASH_Update( &HASHcontext,
2860 prefix->bv_val, prefix->bv_len );
2862 HASH_Update( &HASHcontext,
2863 &pre, sizeof( pre ) );
2864 HASH_Update( &HASHcontext,
2865 syntax->ssyn_oid, slen );
2866 HASH_Update( &HASHcontext,
2867 mr->smr_oid, mlen );
2868 HASH_Update( &HASHcontext,
2869 &value->bv_val[value->bv_len-j], j );
2870 HASH_Final( HASHdigest, &HASHcontext );
2872 ber_dupbv( &keys[nkeys++], &digest );
2879 keys[nkeys].bv_val = NULL;
2886 return LDAP_SUCCESS;
2889 static int caseExactIA5SubstringsFilter(
2894 struct berval *prefix,
2895 void * assertedValue,
2898 SubstringsAssertion *sa = assertedValue;
2900 ber_len_t nkeys = 0;
2901 size_t slen, mlen, klen;
2903 HASH_CONTEXT HASHcontext;
2904 unsigned char HASHdigest[HASH_BYTES];
2905 struct berval *value;
2906 struct berval digest;
2908 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
2909 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2914 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
2916 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
2917 if( sa->sa_any[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2918 /* don't bother accounting for stepping */
2919 nkeys += sa->sa_any[i].bv_len -
2920 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
2925 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
2926 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2933 return LDAP_SUCCESS;
2936 digest.bv_val = HASHdigest;
2937 digest.bv_len = sizeof(HASHdigest);
2939 slen = syntax->ssyn_oidlen;
2940 mlen = mr->smr_oidlen;
2942 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
2945 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
2946 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2948 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
2949 value = &sa->sa_initial;
2951 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2952 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2954 HASH_Init( &HASHcontext );
2955 if( prefix != NULL && prefix->bv_len > 0 ) {
2956 HASH_Update( &HASHcontext,
2957 prefix->bv_val, prefix->bv_len );
2959 HASH_Update( &HASHcontext,
2960 &pre, sizeof( pre ) );
2961 HASH_Update( &HASHcontext,
2962 syntax->ssyn_oid, slen );
2963 HASH_Update( &HASHcontext,
2964 mr->smr_oid, mlen );
2965 HASH_Update( &HASHcontext,
2966 value->bv_val, klen );
2967 HASH_Final( HASHdigest, &HASHcontext );
2969 ber_dupbv( &keys[nkeys++], &digest );
2972 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
2974 pre = SLAP_INDEX_SUBSTR_PREFIX;
2975 klen = SLAP_INDEX_SUBSTR_MAXLEN;
2977 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
2978 if( sa->sa_any[i].bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
2982 value = &sa->sa_any[i];
2985 j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
2986 j += SLAP_INDEX_SUBSTR_STEP )
2988 HASH_Init( &HASHcontext );
2989 if( prefix != NULL && prefix->bv_len > 0 ) {
2990 HASH_Update( &HASHcontext,
2991 prefix->bv_val, prefix->bv_len );
2993 HASH_Update( &HASHcontext,
2994 &pre, sizeof( pre ) );
2995 HASH_Update( &HASHcontext,
2996 syntax->ssyn_oid, slen );
2997 HASH_Update( &HASHcontext,
2998 mr->smr_oid, mlen );
2999 HASH_Update( &HASHcontext,
3000 &value->bv_val[j], klen );
3001 HASH_Final( HASHdigest, &HASHcontext );
3003 ber_dupbv( &keys[nkeys++], &digest );
3008 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
3009 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3011 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
3012 value = &sa->sa_final;
3014 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
3015 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
3017 HASH_Init( &HASHcontext );
3018 if( prefix != NULL && prefix->bv_len > 0 ) {
3019 HASH_Update( &HASHcontext,
3020 prefix->bv_val, prefix->bv_len );
3022 HASH_Update( &HASHcontext,
3023 &pre, sizeof( pre ) );
3024 HASH_Update( &HASHcontext,
3025 syntax->ssyn_oid, slen );
3026 HASH_Update( &HASHcontext,
3027 mr->smr_oid, mlen );
3028 HASH_Update( &HASHcontext,
3029 &value->bv_val[value->bv_len-klen], klen );
3030 HASH_Final( HASHdigest, &HASHcontext );
3032 ber_dupbv( &keys[nkeys++], &digest );
3036 keys[nkeys].bv_val = NULL;
3043 return LDAP_SUCCESS;
3052 struct berval *value,
3053 void *assertedValue )
3055 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
3057 if( match == 0 && value->bv_len ) {
3058 match = strncasecmp( value->bv_val,
3059 ((struct berval *) assertedValue)->bv_val,
3064 return LDAP_SUCCESS;
3068 caseIgnoreIA5SubstringsMatch(
3073 struct berval *value,
3074 void *assertedValue )
3077 SubstringsAssertion *sub = assertedValue;
3078 struct berval left = *value;
3082 /* Add up asserted input length */
3083 if( sub->sa_initial.bv_val ) {
3084 inlen += sub->sa_initial.bv_len;
3087 for(i=0; sub->sa_any[i].bv_val != NULL; i++) {
3088 inlen += sub->sa_any[i].bv_len;
3091 if( sub->sa_final.bv_val ) {
3092 inlen += sub->sa_final.bv_len;
3095 if( sub->sa_initial.bv_val ) {
3096 if( inlen > left.bv_len ) {
3101 match = strncasecmp( sub->sa_initial.bv_val, left.bv_val,
3102 sub->sa_initial.bv_len );
3108 left.bv_val += sub->sa_initial.bv_len;
3109 left.bv_len -= sub->sa_initial.bv_len;
3110 inlen -= sub->sa_initial.bv_len;
3113 if( sub->sa_final.bv_val ) {
3114 if( inlen > left.bv_len ) {
3119 match = strncasecmp( sub->sa_final.bv_val,
3120 &left.bv_val[left.bv_len - sub->sa_final.bv_len],
3121 sub->sa_final.bv_len );
3127 left.bv_len -= sub->sa_final.bv_len;
3128 inlen -= sub->sa_final.bv_len;
3132 for(i=0; sub->sa_any[i].bv_val; i++) {
3137 if( inlen > left.bv_len ) {
3138 /* not enough length */
3143 if( sub->sa_any[i].bv_len == 0 ) {
3147 p = bvcasechr( &left, *sub->sa_any[i].bv_val, &idx );
3154 assert( idx < left.bv_len );
3155 if( idx >= left.bv_len ) {
3156 /* this shouldn't happen */
3163 if( sub->sa_any[i].bv_len > left.bv_len ) {
3164 /* not enough left */
3169 match = strncasecmp( left.bv_val,
3170 sub->sa_any[i].bv_val,
3171 sub->sa_any[i].bv_len );
3180 left.bv_val += sub->sa_any[i].bv_len;
3181 left.bv_len -= sub->sa_any[i].bv_len;
3182 inlen -= sub->sa_any[i].bv_len;
3188 return LDAP_SUCCESS;
3191 /* Index generation function */
3192 static int caseIgnoreIA5Indexer(
3197 struct berval *prefix,
3202 int rc = LDAP_SUCCESS;
3205 HASH_CONTEXT HASHcontext;
3206 unsigned char HASHdigest[HASH_BYTES];
3207 struct berval digest;
3208 digest.bv_val = HASHdigest;
3209 digest.bv_len = sizeof(HASHdigest);
3211 /* we should have at least one value at this point */
3212 assert( values != NULL && values[0].bv_val != NULL );
3214 for( i=0; values[i].bv_val != NULL; i++ ) {
3215 /* just count them */
3218 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
3220 slen = syntax->ssyn_oidlen;
3221 mlen = mr->smr_oidlen;
3223 for( i=0; values[i].bv_val != NULL; i++ ) {
3224 struct berval value;
3226 if( mr->smr_normalize ) {
3227 rc = (mr->smr_normalize)( use, syntax, mr, &values[i], &value );
3228 if( rc != LDAP_SUCCESS ) {
3231 #ifndef SLAP_NVALUES
3232 } else if ( mr->smr_syntax->ssyn_normalize ) {
3233 rc = (mr->smr_syntax->ssyn_normalize)( syntax, &values[i], &value );
3234 if( rc != LDAP_SUCCESS ) {
3239 ber_dupbv( &value, &values[i] );
3242 ldap_pvt_str2lower( value.bv_val );
3244 HASH_Init( &HASHcontext );
3245 if( prefix != NULL && prefix->bv_len > 0 ) {
3246 HASH_Update( &HASHcontext,
3247 prefix->bv_val, prefix->bv_len );
3249 HASH_Update( &HASHcontext,
3250 syntax->ssyn_oid, slen );
3251 HASH_Update( &HASHcontext,
3252 mr->smr_oid, mlen );
3253 HASH_Update( &HASHcontext,
3254 value.bv_val, value.bv_len );
3255 HASH_Final( HASHdigest, &HASHcontext );
3257 free( value.bv_val );
3259 ber_dupbv( &keys[i], &digest );
3262 keys[i].bv_val = NULL;
3263 if( rc != LDAP_SUCCESS ) {
3264 ber_bvarray_free( keys );
3271 /* Index generation function */
3272 static int caseIgnoreIA5Filter(
3277 struct berval *prefix,
3278 void * assertedValue,
3283 HASH_CONTEXT HASHcontext;
3284 unsigned char HASHdigest[HASH_BYTES];
3285 struct berval value;
3286 struct berval digest;
3287 digest.bv_val = HASHdigest;
3288 digest.bv_len = sizeof(HASHdigest);
3290 slen = syntax->ssyn_oidlen;
3291 mlen = mr->smr_oidlen;
3293 ber_dupbv( &value, (struct berval *) assertedValue );
3294 ldap_pvt_str2lower( value.bv_val );
3296 keys = ch_malloc( sizeof( struct berval ) * 2 );
3298 HASH_Init( &HASHcontext );
3299 if( prefix != NULL && prefix->bv_len > 0 ) {
3300 HASH_Update( &HASHcontext,
3301 prefix->bv_val, prefix->bv_len );
3303 HASH_Update( &HASHcontext,
3304 syntax->ssyn_oid, slen );
3305 HASH_Update( &HASHcontext,
3306 mr->smr_oid, mlen );
3307 HASH_Update( &HASHcontext,
3308 value.bv_val, value.bv_len );
3309 HASH_Final( HASHdigest, &HASHcontext );
3311 ber_dupbv( &keys[0], &digest );
3312 keys[1].bv_val = NULL;
3314 free( value.bv_val );
3318 return LDAP_SUCCESS;
3321 /* Substrings Index generation function */
3322 static int caseIgnoreIA5SubstringsIndexer(
3327 struct berval *prefix,
3334 HASH_CONTEXT HASHcontext;
3335 unsigned char HASHdigest[HASH_BYTES];
3336 struct berval digest;
3337 digest.bv_val = HASHdigest;
3338 digest.bv_len = sizeof(HASHdigest);
3340 /* we should have at least one value at this point */
3341 assert( values != NULL && values[0].bv_val != NULL );
3344 for( i=0; values[i].bv_val != NULL; i++ ) {
3345 /* count number of indices to generate */
3346 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
3350 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
3351 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3352 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
3353 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
3355 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
3359 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
3360 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3361 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
3365 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
3366 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3367 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
3368 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
3370 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
3376 /* no keys to generate */
3378 return LDAP_SUCCESS;
3381 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
3383 slen = syntax->ssyn_oidlen;
3384 mlen = mr->smr_oidlen;
3387 for( i=0; values[i].bv_val != NULL; i++ ) {
3389 struct berval value;
3391 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
3393 ber_dupbv( &value, &values[i] );
3394 ldap_pvt_str2lower( value.bv_val );
3396 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
3397 ( value.bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
3399 char pre = SLAP_INDEX_SUBSTR_PREFIX;
3400 max = value.bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
3402 for( j=0; j<max; j++ ) {
3403 HASH_Init( &HASHcontext );
3404 if( prefix != NULL && prefix->bv_len > 0 ) {
3405 HASH_Update( &HASHcontext,
3406 prefix->bv_val, prefix->bv_len );
3409 HASH_Update( &HASHcontext,
3410 &pre, sizeof( pre ) );
3411 HASH_Update( &HASHcontext,
3412 syntax->ssyn_oid, slen );
3413 HASH_Update( &HASHcontext,
3414 mr->smr_oid, mlen );
3415 HASH_Update( &HASHcontext,
3417 SLAP_INDEX_SUBSTR_MAXLEN );
3418 HASH_Final( HASHdigest, &HASHcontext );
3420 ber_dupbv( &keys[nkeys++], &digest );
3424 max = SLAP_INDEX_SUBSTR_MAXLEN < value.bv_len
3425 ? SLAP_INDEX_SUBSTR_MAXLEN : value.bv_len;
3427 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
3430 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
3431 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
3432 HASH_Init( &HASHcontext );
3433 if( prefix != NULL && prefix->bv_len > 0 ) {
3434 HASH_Update( &HASHcontext,
3435 prefix->bv_val, prefix->bv_len );
3437 HASH_Update( &HASHcontext,
3438 &pre, sizeof( pre ) );
3439 HASH_Update( &HASHcontext,
3440 syntax->ssyn_oid, slen );
3441 HASH_Update( &HASHcontext,
3442 mr->smr_oid, mlen );
3443 HASH_Update( &HASHcontext,
3445 HASH_Final( HASHdigest, &HASHcontext );
3447 ber_dupbv( &keys[nkeys++], &digest );
3450 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
3451 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
3452 HASH_Init( &HASHcontext );
3453 if( prefix != NULL && prefix->bv_len > 0 ) {
3454 HASH_Update( &HASHcontext,
3455 prefix->bv_val, prefix->bv_len );
3457 HASH_Update( &HASHcontext,
3458 &pre, sizeof( pre ) );
3459 HASH_Update( &HASHcontext,
3460 syntax->ssyn_oid, slen );
3461 HASH_Update( &HASHcontext,
3462 mr->smr_oid, mlen );
3463 HASH_Update( &HASHcontext,
3464 &value.bv_val[value.bv_len-j], j );
3465 HASH_Final( HASHdigest, &HASHcontext );
3467 ber_dupbv( &keys[nkeys++], &digest );
3472 free( value.bv_val );
3476 keys[nkeys].bv_val = NULL;
3483 return LDAP_SUCCESS;
3486 static int caseIgnoreIA5SubstringsFilter(
3491 struct berval *prefix,
3492 void * assertedValue,
3495 SubstringsAssertion *sa = assertedValue;
3497 ber_len_t nkeys = 0;
3498 size_t slen, mlen, klen;
3500 HASH_CONTEXT HASHcontext;
3501 unsigned char HASHdigest[HASH_BYTES];
3502 struct berval value;
3503 struct berval digest;
3505 if((flags & SLAP_INDEX_SUBSTR_INITIAL) && sa->sa_initial.bv_val != NULL &&
3506 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3511 if((flags & SLAP_INDEX_SUBSTR_ANY) && sa->sa_any != NULL ) {
3513 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
3514 if( sa->sa_any[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3515 /* don't bother accounting for stepping */
3516 nkeys += sa->sa_any[i].bv_len -
3517 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
3522 if((flags & SLAP_INDEX_SUBSTR_FINAL) && sa->sa_final.bv_val != NULL &&
3523 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3530 return LDAP_SUCCESS;
3533 digest.bv_val = HASHdigest;
3534 digest.bv_len = sizeof(HASHdigest);
3536 slen = syntax->ssyn_oidlen;
3537 mlen = mr->smr_oidlen;
3539 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
3542 if((flags & SLAP_INDEX_SUBSTR_INITIAL) && sa->sa_initial.bv_val != NULL &&
3543 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3545 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
3546 ber_dupbv( &value, &sa->sa_initial );
3547 ldap_pvt_str2lower( value.bv_val );
3549 klen = SLAP_INDEX_SUBSTR_MAXLEN < value.bv_len
3550 ? SLAP_INDEX_SUBSTR_MAXLEN : value.bv_len;
3552 HASH_Init( &HASHcontext );
3553 if( prefix != NULL && prefix->bv_len > 0 ) {
3554 HASH_Update( &HASHcontext,
3555 prefix->bv_val, prefix->bv_len );
3557 HASH_Update( &HASHcontext,
3558 &pre, sizeof( pre ) );
3559 HASH_Update( &HASHcontext,
3560 syntax->ssyn_oid, slen );
3561 HASH_Update( &HASHcontext,
3562 mr->smr_oid, mlen );
3563 HASH_Update( &HASHcontext,
3564 value.bv_val, klen );
3565 HASH_Final( HASHdigest, &HASHcontext );
3567 free( value.bv_val );
3568 ber_dupbv( &keys[nkeys++], &digest );
3571 if((flags & SLAP_INDEX_SUBSTR_ANY) && sa->sa_any != NULL ) {
3573 pre = SLAP_INDEX_SUBSTR_PREFIX;
3574 klen = SLAP_INDEX_SUBSTR_MAXLEN;
3576 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
3577 if( sa->sa_any[i].bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
3581 ber_dupbv( &value, &sa->sa_any[i] );
3582 ldap_pvt_str2lower( value.bv_val );
3585 j <= value.bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
3586 j += SLAP_INDEX_SUBSTR_STEP )
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[j], klen );
3601 HASH_Final( HASHdigest, &HASHcontext );
3603 ber_dupbv( &keys[nkeys++], &digest );
3606 free( value.bv_val );
3610 if((flags & SLAP_INDEX_SUBSTR_FINAL) && sa->sa_final.bv_val != NULL &&
3611 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3613 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
3614 ber_dupbv( &value, &sa->sa_final );
3615 ldap_pvt_str2lower( value.bv_val );
3617 klen = SLAP_INDEX_SUBSTR_MAXLEN < value.bv_len
3618 ? SLAP_INDEX_SUBSTR_MAXLEN : value.bv_len;
3620 HASH_Init( &HASHcontext );
3621 if( prefix != NULL && prefix->bv_len > 0 ) {
3622 HASH_Update( &HASHcontext,
3623 prefix->bv_val, prefix->bv_len );
3625 HASH_Update( &HASHcontext,
3626 &pre, sizeof( pre ) );
3627 HASH_Update( &HASHcontext,
3628 syntax->ssyn_oid, slen );
3629 HASH_Update( &HASHcontext,
3630 mr->smr_oid, mlen );
3631 HASH_Update( &HASHcontext,
3632 &value.bv_val[value.bv_len-klen], klen );
3633 HASH_Final( HASHdigest, &HASHcontext );
3635 free( value.bv_val );
3636 ber_dupbv( &keys[nkeys++], &digest );
3640 keys[nkeys].bv_val = NULL;
3647 return LDAP_SUCCESS;
3653 numericStringValidate(
3659 if( in->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
3661 for(i=0; i < in->bv_len; i++) {
3662 if( !SLAP_NUMERIC(in->bv_val[i]) ) {
3663 return LDAP_INVALID_SYNTAX;
3667 return LDAP_SUCCESS;
3670 #ifndef SLAP_NVALUES
3673 xnumericStringNormalize(
3676 struct berval *normalized )
3678 /* removal all spaces */
3681 assert( val->bv_len );
3683 normalized->bv_val = ch_malloc( val->bv_len + 1 );
3686 q = normalized->bv_val;
3689 if ( ASCII_SPACE( *p ) ) {
3690 /* Ignore whitespace */
3697 /* we should have copied no more then is in val */
3698 assert( (q - normalized->bv_val) <= (p - val->bv_val) );
3700 /* null terminate */
3703 normalized->bv_len = q - normalized->bv_val;
3705 if( normalized->bv_len == 0 ) {
3706 normalized->bv_val = ch_realloc( normalized->bv_val, 2 );
3707 normalized->bv_val[0] = ' ';
3708 normalized->bv_val[1] = '\0';
3709 normalized->bv_len = 1;
3712 return LDAP_SUCCESS;
3716 objectIdentifierFirstComponentMatch(
3721 struct berval *value,
3722 void *assertedValue )
3724 int rc = LDAP_SUCCESS;
3726 struct berval *asserted = (struct berval *) assertedValue;
3730 if( value->bv_len == 0 || value->bv_val[0] != '(' /*')'*/ ) {
3731 return LDAP_INVALID_SYNTAX;
3734 /* trim leading white space */
3735 for( i=1; ASCII_SPACE(value->bv_val[i]) && i < value->bv_len; i++ ) {
3739 /* grab next word */
3740 oid.bv_val = &value->bv_val[i];
3741 j = value->bv_len - i;
3742 for( i=0; !ASCII_SPACE(oid.bv_val[i]) && i < j; i++ ) {
3747 /* insert attributeTypes, objectclass check here */
3748 if( OID_LEADCHAR(asserted->bv_val[0]) ) {
3749 rc = objectIdentifierMatch( &match, flags, syntax, mr, &oid, asserted );
3752 if ( !strcmp( syntax->ssyn_oid, SLAP_SYNTAX_MATCHINGRULES_OID ) ) {
3753 MatchingRule *asserted_mr = mr_bvfind( asserted );
3754 MatchingRule *stored_mr = mr_bvfind( &oid );
3756 if( asserted_mr == NULL ) {
3757 rc = SLAPD_COMPARE_UNDEFINED;
3759 match = asserted_mr != stored_mr;
3762 } else if ( !strcmp( syntax->ssyn_oid,
3763 SLAP_SYNTAX_ATTRIBUTETYPES_OID ) )
3765 AttributeType *asserted_at = at_bvfind( asserted );
3766 AttributeType *stored_at = at_bvfind( &oid );
3768 if( asserted_at == NULL ) {
3769 rc = SLAPD_COMPARE_UNDEFINED;
3771 match = asserted_at != stored_at;
3774 } else if ( !strcmp( syntax->ssyn_oid,
3775 SLAP_SYNTAX_OBJECTCLASSES_OID ) )
3777 ObjectClass *asserted_oc = oc_bvfind( asserted );
3778 ObjectClass *stored_oc = oc_bvfind( &oid );
3780 if( asserted_oc == NULL ) {
3781 rc = SLAPD_COMPARE_UNDEFINED;
3783 match = asserted_oc != stored_oc;
3789 LDAP_LOG( CONFIG, ENTRY,
3790 "objectIdentifierFirstComponentMatch: %d\n %s\n %s\n",
3791 match, value->bv_val, asserted->bv_val );
3793 Debug( LDAP_DEBUG_ARGS, "objectIdentifierFirstComponentMatch "
3794 "%d\n\t\"%s\"\n\t\"%s\"\n",
3795 match, value->bv_val, asserted->bv_val );
3798 if( rc == LDAP_SUCCESS ) *matchp = match;
3810 struct berval *value,
3811 void *assertedValue )
3813 long lValue, lAssertedValue;
3815 /* safe to assume integers are NUL terminated? */
3816 lValue = strtol(value->bv_val, NULL, 10);
3817 if(( lValue == LONG_MIN || lValue == LONG_MAX) && errno == ERANGE ) {
3818 return LDAP_CONSTRAINT_VIOLATION;
3821 lAssertedValue = strtol(((struct berval *)assertedValue)->bv_val, NULL, 10);
3822 if(( lAssertedValue == LONG_MIN || lAssertedValue == LONG_MAX)
3823 && errno == ERANGE )
3825 return LDAP_CONSTRAINT_VIOLATION;
3828 *matchp = (lValue & lAssertedValue) ? 0 : 1;
3829 return LDAP_SUCCESS;
3838 struct berval *value,
3839 void *assertedValue )
3841 long lValue, lAssertedValue;
3843 /* safe to assume integers are NUL terminated? */
3844 lValue = strtol(value->bv_val, NULL, 10);
3845 if(( lValue == LONG_MIN || lValue == LONG_MAX) && errno == ERANGE ) {
3846 return LDAP_CONSTRAINT_VIOLATION;
3849 lAssertedValue = strtol(((struct berval *)assertedValue)->bv_val, NULL, 10);
3850 if(( lAssertedValue == LONG_MIN || lAssertedValue == LONG_MAX)
3851 && errno == ERANGE )
3853 return LDAP_CONSTRAINT_VIOLATION;
3856 *matchp = (lValue | lAssertedValue) ? 0 : -1;
3857 return LDAP_SUCCESS;
3860 #ifndef SLAP_NVALUES
3863 #include <openssl/x509.h>
3864 #include <openssl/err.h>
3867 * Next function returns a string representation of a ASN1_INTEGER.
3868 * It works for unlimited lengths.
3871 static struct berval *
3872 asn1_integer2str(ASN1_INTEGER *a, struct berval *bv)
3876 static char digit[] = "0123456789";
3878 /* We work backwards, make it fill from the end of buf */
3879 p = buf + sizeof(buf) - 1;
3882 if ( a == NULL || a->length == 0 ) {
3890 /* We want to preserve the original */
3891 copy = ch_malloc(n*sizeof(unsigned int));
3892 for (i = 0; i<n; i++) {
3893 copy[i] = a->data[i];
3897 * base indicates the index of the most significant
3898 * byte that might be nonzero. When it goes off the
3899 * end, we now there is nothing left to do.
3905 for (i = base; i<n; i++ ) {
3906 copy[i] += carry*256;
3907 carry = copy[i] % 10;
3912 * Way too large, we need to leave
3913 * room for sign if negative
3918 *--p = digit[carry];
3920 if (copy[base] == 0) base++;
3925 if ( a->type == V_ASN1_NEG_INTEGER ) {
3929 return ber_str2bv( p, 0, 1, bv );
3933 * Given a certificate in DER format, extract the corresponding
3934 * assertion value for certificateExactMatch
3937 certificateExactConvert(
3939 struct berval * out )
3942 unsigned char *p = in->bv_val;
3943 struct berval serial;
3944 struct berval issuer_dn;
3946 xcert = d2i_X509(NULL, &p, in->bv_len);
3949 LDAP_LOG( CONFIG, ENTRY,
3950 "certificateExactConvert: error parsing cert: %s\n",
3951 ERR_error_string(ERR_get_error(),NULL), 0, 0 );
3953 Debug( LDAP_DEBUG_ARGS, "certificateExactConvert: "
3954 "error parsing cert: %s\n",
3955 ERR_error_string(ERR_get_error(),NULL), NULL, NULL );
3957 return LDAP_INVALID_SYNTAX;
3960 if ( !asn1_integer2str(xcert->cert_info->serialNumber, &serial) ) {
3962 return LDAP_INVALID_SYNTAX;
3964 if ( dnX509normalize(X509_get_issuer_name(xcert), &issuer_dn )
3968 ber_memfree(serial.bv_val);
3969 return LDAP_INVALID_SYNTAX;
3974 out->bv_len = serial.bv_len + issuer_dn.bv_len + sizeof(" $ ");
3975 out->bv_val = ch_malloc(out->bv_len);
3977 AC_MEMCPY(p, serial.bv_val, serial.bv_len);
3979 AC_MEMCPY(p, " $ ", sizeof(" $ ")-1);
3981 AC_MEMCPY(p, issuer_dn.bv_val, issuer_dn.bv_len);
3982 p += issuer_dn.bv_len;
3986 LDAP_LOG( CONFIG, ARGS,
3987 "certificateExactConvert: \n %s\n", out->bv_val, 0, 0 );
3989 Debug( LDAP_DEBUG_ARGS, "certificateExactConvert "
3991 out->bv_val, NULL, NULL );
3994 ber_memfree(serial.bv_val);
3995 ber_memfree(issuer_dn.bv_val);
3997 return LDAP_SUCCESS;
4001 serial_and_issuer_parse(
4002 struct berval *assertion,
4003 struct berval *serial,
4004 struct berval *issuer_dn
4012 begin = assertion->bv_val;
4013 end = assertion->bv_val+assertion->bv_len-1;
4014 for (p=begin; p<=end && *p != '$'; p++) /* empty */ ;
4015 if ( p > end ) return LDAP_INVALID_SYNTAX;
4017 /* p now points at the $ sign, now use
4018 * begin and end to delimit the serial number
4020 while (ASCII_SPACE(*begin)) begin++;
4022 while (ASCII_SPACE(*end)) end--;
4024 if( end <= begin ) return LDAP_INVALID_SYNTAX;
4026 bv.bv_len = end-begin+1;
4028 ber_dupbv(serial, &bv);
4030 /* now extract the issuer, remember p was at the dollar sign */
4032 end = assertion->bv_val+assertion->bv_len-1;
4033 while (ASCII_SPACE(*begin)) begin++;
4034 /* should we trim spaces at the end too? is it safe always? no, no */
4036 if( end <= begin ) return LDAP_INVALID_SYNTAX;
4039 bv.bv_len = end-begin+1;
4042 dnNormalize2( NULL, &bv, issuer_dn );
4045 return LDAP_SUCCESS;
4049 certificateExactMatch(
4054 struct berval *value,
4055 void *assertedValue )
4058 unsigned char *p = value->bv_val;
4059 struct berval serial;
4060 struct berval issuer_dn;
4061 struct berval asserted_serial;
4062 struct berval asserted_issuer_dn;
4065 xcert = d2i_X509(NULL, &p, value->bv_len);
4068 LDAP_LOG( CONFIG, ENTRY,
4069 "certificateExactMatch: error parsing cert: %s\n",
4070 ERR_error_string(ERR_get_error(),NULL), 0, 0 );
4072 Debug( LDAP_DEBUG_ARGS, "certificateExactMatch: "
4073 "error parsing cert: %s\n",
4074 ERR_error_string(ERR_get_error(),NULL), NULL, NULL );
4076 return LDAP_INVALID_SYNTAX;
4079 asn1_integer2str(xcert->cert_info->serialNumber, &serial);
4080 dnX509normalize(X509_get_issuer_name(xcert), &issuer_dn);
4084 serial_and_issuer_parse(assertedValue,
4085 &asserted_serial, &asserted_issuer_dn);
4090 slap_schema.si_syn_integer,
4091 slap_schema.si_mr_integerMatch,
4094 if ( ret == LDAP_SUCCESS ) {
4095 if ( *matchp == 0 ) {
4096 /* We need to normalize everything for dnMatch */
4100 slap_schema.si_syn_distinguishedName,
4101 slap_schema.si_mr_distinguishedNameMatch,
4103 &asserted_issuer_dn);
4108 LDAP_LOG( CONFIG, ARGS, "certificateExactMatch "
4109 "%d\n\t\"%s $ %s\"\n",
4110 *matchp, serial.bv_val, issuer_dn.bv_val );
4111 LDAP_LOG( CONFIG, ARGS, "\t\"%s $ %s\"\n",
4112 asserted_serial.bv_val, asserted_issuer_dn.bv_val,
4115 Debug( LDAP_DEBUG_ARGS, "certificateExactMatch "
4116 "%d\n\t\"%s $ %s\"\n",
4117 *matchp, serial.bv_val, issuer_dn.bv_val );
4118 Debug( LDAP_DEBUG_ARGS, "\t\"%s $ %s\"\n",
4119 asserted_serial.bv_val, asserted_issuer_dn.bv_val,
4123 ber_memfree(serial.bv_val);
4124 ber_memfree(issuer_dn.bv_val);
4125 ber_memfree(asserted_serial.bv_val);
4126 ber_memfree(asserted_issuer_dn.bv_val);
4132 * Index generation function
4133 * We just index the serials, in most scenarios the issuer DN is one of
4134 * a very small set of values.
4136 static int certificateExactIndexer(
4141 struct berval *prefix,
4149 struct berval serial;
4151 /* we should have at least one value at this point */
4152 assert( values != NULL && values[0].bv_val != NULL );
4154 for( i=0; values[i].bv_val != NULL; i++ ) {
4155 /* empty -- just count them */
4158 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
4160 for( i=0; values[i].bv_val != NULL; i++ ) {
4161 p = values[i].bv_val;
4162 xcert = d2i_X509(NULL, &p, values[i].bv_len);
4165 LDAP_LOG( CONFIG, ENTRY,
4166 "certificateExactIndexer: error parsing cert: %s\n",
4167 ERR_error_string(ERR_get_error(),NULL), 0, 0);
4169 Debug( LDAP_DEBUG_ARGS, "certificateExactIndexer: "
4170 "error parsing cert: %s\n",
4171 ERR_error_string(ERR_get_error(),NULL),
4174 /* Do we leak keys on error? */
4175 return LDAP_INVALID_SYNTAX;
4178 asn1_integer2str(xcert->cert_info->serialNumber, &serial);
4180 xintegerNormalize( slap_schema.si_syn_integer,
4181 &serial, &keys[i] );
4182 ber_memfree(serial.bv_val);
4184 LDAP_LOG( CONFIG, ENTRY,
4185 "certificateExactIndexer: returning: %s\n", keys[i].bv_val, 0, 0);
4187 Debug( LDAP_DEBUG_ARGS, "certificateExactIndexer: "
4194 keys[i].bv_val = NULL;
4196 return LDAP_SUCCESS;
4199 /* Index generation function */
4200 /* We think this is always called with a value in matching rule syntax */
4201 static int certificateExactFilter(
4206 struct berval *prefix,
4207 void * assertedValue,
4211 struct berval asserted_serial;
4214 ret = serial_and_issuer_parse( assertedValue, &asserted_serial, NULL );
4215 if( ret != LDAP_SUCCESS ) return ret;
4217 keys = ch_malloc( sizeof( struct berval ) * 2 );
4218 xintegerNormalize( syntax, &asserted_serial, &keys[0] );
4219 keys[1].bv_val = NULL;
4222 ber_memfree(asserted_serial.bv_val);
4223 return LDAP_SUCCESS;
4229 check_time_syntax (struct berval *val,
4233 static int ceiling[9] = { 99, 99, 11, 30, 23, 59, 59, 12, 59 };
4234 static int mdays[2][12] = {
4235 /* non-leap years */
4236 { 30, 27, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30 },
4238 { 30, 28, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30 }
4241 int part, c, tzoffset, leapyear = 0 ;
4243 if( val->bv_len == 0 ) {
4244 return LDAP_INVALID_SYNTAX;
4247 p = (char *)val->bv_val;
4248 e = p + val->bv_len;
4250 /* Ignore initial whitespace */
4251 while ( ( p < e ) && ASCII_SPACE( *p ) ) {
4255 if (e - p < 13 - (2 * start)) {
4256 return LDAP_INVALID_SYNTAX;
4259 for (part = 0; part < 9; part++) {
4263 for (part = start; part < 7; part++) {
4265 if ((part == 6) && (c == 'Z' || c == '+' || c == '-')) {
4272 return LDAP_INVALID_SYNTAX;
4274 if (c < 0 || c > 9) {
4275 return LDAP_INVALID_SYNTAX;
4281 return LDAP_INVALID_SYNTAX;
4283 if (c < 0 || c > 9) {
4284 return LDAP_INVALID_SYNTAX;
4289 if (part == 2 || part == 3) {
4292 if (parts[part] < 0) {
4293 return LDAP_INVALID_SYNTAX;
4295 if (parts[part] > ceiling[part]) {
4296 return LDAP_INVALID_SYNTAX;
4300 /* leapyear check for the Gregorian calendar (year>1581) */
4301 if (((parts[1] % 4 == 0) && (parts[1] != 0)) ||
4302 ((parts[0] % 4 == 0) && (parts[1] == 0)))
4307 if (parts[3] > mdays[leapyear][parts[2]]) {
4308 return LDAP_INVALID_SYNTAX;
4313 tzoffset = 0; /* UTC */
4314 } else if (c != '+' && c != '-') {
4315 return LDAP_INVALID_SYNTAX;
4319 } else /* c == '+' */ {
4324 return LDAP_INVALID_SYNTAX;
4327 for (part = 7; part < 9; part++) {
4329 if (c < 0 || c > 9) {
4330 return LDAP_INVALID_SYNTAX;
4335 if (c < 0 || c > 9) {
4336 return LDAP_INVALID_SYNTAX;
4340 if (parts[part] < 0 || parts[part] > ceiling[part]) {
4341 return LDAP_INVALID_SYNTAX;
4346 /* Ignore trailing whitespace */
4347 while ( ( p < e ) && ASCII_SPACE( *p ) ) {
4351 return LDAP_INVALID_SYNTAX;
4354 switch ( tzoffset ) {
4355 case -1: /* negativ offset to UTC, ie west of Greenwich */
4356 parts[4] += parts[7];
4357 parts[5] += parts[8];
4358 for (part = 6; --part > 0; ) { /* offset is just hhmm, no seconds */
4362 c = mdays[leapyear][parts[2]];
4364 if (parts[part] > c) {
4365 parts[part] -= c + 1;
4370 case 1: /* positive offset to UTC, ie east of Greenwich */
4371 parts[4] -= parts[7];
4372 parts[5] -= parts[8];
4373 for (part = 6; --part > 0; ) {
4377 /* first arg to % needs to be non negativ */
4378 c = mdays[leapyear][(parts[2] - 1 + 12) % 12];
4380 if (parts[part] < 0) {
4381 parts[part] += c + 1;
4386 case 0: /* already UTC */
4390 return LDAP_SUCCESS;
4393 #ifdef SUPPORT_OBSOLETE_UTC_SYNTAX
4398 struct berval *normalized )
4402 rc = check_time_syntax(val, 1, parts);
4403 if (rc != LDAP_SUCCESS) {
4407 normalized->bv_val = ch_malloc( 14 );
4408 if ( normalized->bv_val == NULL ) {
4409 return LBER_ERROR_MEMORY;
4412 sprintf( normalized->bv_val, "%02d%02d%02d%02d%02d%02dZ",
4413 parts[1], parts[2] + 1, parts[3] + 1,
4414 parts[4], parts[5], parts[6] );
4415 normalized->bv_len = 13;
4417 return LDAP_SUCCESS;
4421 #ifdef SUPPORT_OBSOLETE_UTC_SYNTAX
4429 return check_time_syntax(in, 1, parts);
4434 generalizedTimeValidate(
4440 return check_time_syntax(in, 0, parts);
4443 #ifndef SLAP_NVALUES
4446 xgeneralizedTimeNormalize(
4449 struct berval *normalized )
4453 rc = check_time_syntax(val, 0, parts);
4454 if (rc != LDAP_SUCCESS) {
4458 normalized->bv_val = ch_malloc( 16 );
4459 if ( normalized->bv_val == NULL ) {
4460 return LBER_ERROR_MEMORY;
4463 sprintf( normalized->bv_val, "%02d%02d%02d%02d%02d%02d%02dZ",
4464 parts[0], parts[1], parts[2] + 1, parts[3] + 1,
4465 parts[4], parts[5], parts[6] );
4466 normalized->bv_len = 15;
4468 return LDAP_SUCCESS;
4473 nisNetgroupTripleValidate(
4475 struct berval *val )
4480 if ( val->bv_len == 0 ) {
4481 return LDAP_INVALID_SYNTAX;
4484 p = (char *)val->bv_val;
4485 e = p + val->bv_len;
4487 if ( *p != '(' /*')'*/ ) {
4488 return LDAP_INVALID_SYNTAX;
4491 for ( p++; ( p < e ) && ( *p != /*'('*/ ')' ); p++ ) {
4495 return LDAP_INVALID_SYNTAX;
4498 } else if ( !AD_CHAR( *p ) ) {
4499 return LDAP_INVALID_SYNTAX;
4503 if ( ( commas != 2 ) || ( *p != /*'('*/ ')' ) ) {
4504 return LDAP_INVALID_SYNTAX;
4510 return LDAP_INVALID_SYNTAX;
4513 return LDAP_SUCCESS;
4517 bootParameterValidate(
4519 struct berval *val )
4523 if ( val->bv_len == 0 ) {
4524 return LDAP_INVALID_SYNTAX;
4527 p = (char *)val->bv_val;
4528 e = p + val->bv_len;
4531 for (; ( p < e ) && ( *p != '=' ); p++ ) {
4532 if ( !AD_CHAR( *p ) ) {
4533 return LDAP_INVALID_SYNTAX;
4538 return LDAP_INVALID_SYNTAX;
4542 for ( p++; ( p < e ) && ( *p != ':' ); p++ ) {
4543 if ( !AD_CHAR( *p ) ) {
4544 return LDAP_INVALID_SYNTAX;
4549 return LDAP_INVALID_SYNTAX;
4553 for ( p++; p < e; p++ ) {
4554 if ( !SLAP_PRINTABLE( *p ) ) {
4555 return LDAP_INVALID_SYNTAX;
4559 return LDAP_SUCCESS;
4562 #define X_BINARY "X-BINARY-TRANSFER-REQUIRED 'TRUE' "
4563 #define X_NOT_H_R "X-NOT-HUMAN-READABLE 'TRUE' "
4565 static slap_syntax_defs_rec syntax_defs[] = {
4566 {"( 1.3.6.1.4.1.1466.115.121.1.1 DESC 'ACI Item' "
4567 X_BINARY X_NOT_H_R ")",
4568 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, NULL, NULL, NULL},
4569 {"( 1.3.6.1.4.1.1466.115.121.1.2 DESC 'Access Point' " X_NOT_H_R ")",
4570 0, NULL, NULL, NULL},
4571 {"( 1.3.6.1.4.1.1466.115.121.1.3 DESC 'Attribute Type Description' )",
4572 0, NULL, NULL, NULL},
4573 {"( 1.3.6.1.4.1.1466.115.121.1.4 DESC 'Audio' "
4575 SLAP_SYNTAX_BLOB, blobValidate, NULL, NULL},
4576 {"( 1.3.6.1.4.1.1466.115.121.1.5 DESC 'Binary' "
4578 SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4579 {"( 1.3.6.1.4.1.1466.115.121.1.6 DESC 'Bit String' )",
4580 0, bitStringValidate, NULL, NULL },
4581 {"( 1.3.6.1.4.1.1466.115.121.1.7 DESC 'Boolean' )",
4582 0, booleanValidate, NULL, NULL},
4583 {"( 1.3.6.1.4.1.1466.115.121.1.8 DESC 'Certificate' "
4584 X_BINARY X_NOT_H_R ")",
4585 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4586 {"( 1.3.6.1.4.1.1466.115.121.1.9 DESC 'Certificate List' "
4587 X_BINARY X_NOT_H_R ")",
4588 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4589 {"( 1.3.6.1.4.1.1466.115.121.1.10 DESC 'Certificate Pair' "
4590 X_BINARY X_NOT_H_R ")",
4591 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4592 {"( 1.3.6.1.4.1.1466.115.121.1.11 DESC 'Country String' )",
4593 0, countryStringValidate, xIA5StringNormalize, NULL},
4594 {"( 1.3.6.1.4.1.1466.115.121.1.12 DESC 'Distinguished Name' )",
4595 0, dnValidate, xdnNormalize, dnPretty2},
4596 {"( 1.3.6.1.4.1.1466.115.121.1.13 DESC 'Data Quality' )",
4597 0, NULL, NULL, NULL},
4598 {"( 1.3.6.1.4.1.1466.115.121.1.14 DESC 'Delivery Method' )",
4599 0, NULL, NULL, NULL},
4600 {"( 1.3.6.1.4.1.1466.115.121.1.15 DESC 'Directory String' )",
4601 0, UTF8StringValidate, xUTF8StringNormalize, NULL},
4602 {"( 1.3.6.1.4.1.1466.115.121.1.16 DESC 'DIT Content Rule Description' )",
4603 0, NULL, NULL, NULL},
4604 {"( 1.3.6.1.4.1.1466.115.121.1.17 DESC 'DIT Structure Rule Description' )",
4605 0, NULL, NULL, NULL},
4606 {"( 1.3.6.1.4.1.1466.115.121.1.19 DESC 'DSA Quality' )",
4607 0, NULL, NULL, NULL},
4608 {"( 1.3.6.1.4.1.1466.115.121.1.20 DESC 'DSE Type' )",
4609 0, NULL, NULL, NULL},
4610 {"( 1.3.6.1.4.1.1466.115.121.1.21 DESC 'Enhanced Guide' )",
4611 0, NULL, NULL, NULL},
4612 {"( 1.3.6.1.4.1.1466.115.121.1.22 DESC 'Facsimile Telephone Number' )",
4613 0, printablesStringValidate, xtelephoneNumberNormalize, NULL},
4614 {"( 1.3.6.1.4.1.1466.115.121.1.23 DESC 'Fax' " X_NOT_H_R ")",
4615 SLAP_SYNTAX_BLOB, NULL, NULL, NULL},
4616 {"( 1.3.6.1.4.1.1466.115.121.1.24 DESC 'Generalized Time' )",
4617 0, generalizedTimeValidate, xgeneralizedTimeNormalize, NULL},
4618 {"( 1.3.6.1.4.1.1466.115.121.1.25 DESC 'Guide' )",
4619 0, NULL, NULL, NULL},
4620 {"( 1.3.6.1.4.1.1466.115.121.1.26 DESC 'IA5 String' )",
4621 0, IA5StringValidate, xIA5StringNormalize, NULL},
4622 {"( 1.3.6.1.4.1.1466.115.121.1.27 DESC 'Integer' )",
4623 0, integerValidate, xintegerNormalize, NULL},
4624 {"( 1.3.6.1.4.1.1466.115.121.1.28 DESC 'JPEG' " X_NOT_H_R ")",
4625 SLAP_SYNTAX_BLOB, blobValidate, NULL, NULL},
4626 {"( 1.3.6.1.4.1.1466.115.121.1.29 DESC 'Master And Shadow Access Points' )",
4627 0, NULL, NULL, NULL},
4628 {"( 1.3.6.1.4.1.1466.115.121.1.30 DESC 'Matching Rule Description' )",
4629 0, NULL, NULL, NULL},
4630 {"( 1.3.6.1.4.1.1466.115.121.1.31 DESC 'Matching Rule Use Description' )",
4631 0, NULL, NULL, NULL},
4632 {"( 1.3.6.1.4.1.1466.115.121.1.32 DESC 'Mail Preference' )",
4633 0, NULL, NULL, NULL},
4634 {"( 1.3.6.1.4.1.1466.115.121.1.33 DESC 'MHS OR Address' )",
4635 0, NULL, NULL, NULL},
4636 {"( 1.3.6.1.4.1.1466.115.121.1.34 DESC 'Name And Optional UID' )",
4637 0, nameUIDValidate, xnameUIDNormalize, NULL},
4638 {"( 1.3.6.1.4.1.1466.115.121.1.35 DESC 'Name Form Description' )",
4639 0, NULL, NULL, NULL},
4640 {"( 1.3.6.1.4.1.1466.115.121.1.36 DESC 'Numeric String' )",
4641 0, numericStringValidate, xnumericStringNormalize, NULL},
4642 {"( 1.3.6.1.4.1.1466.115.121.1.37 DESC 'Object Class Description' )",
4643 0, NULL, NULL, NULL},
4644 {"( 1.3.6.1.4.1.1466.115.121.1.38 DESC 'OID' )",
4645 0, oidValidate, NULL, NULL},
4646 {"( 1.3.6.1.4.1.1466.115.121.1.39 DESC 'Other Mailbox' )",
4647 0, IA5StringValidate, xIA5StringNormalize, NULL},
4648 {"( 1.3.6.1.4.1.1466.115.121.1.40 DESC 'Octet String' )",
4649 0, blobValidate, NULL, NULL},
4650 {"( 1.3.6.1.4.1.1466.115.121.1.41 DESC 'Postal Address' )",
4651 0, UTF8StringValidate, xUTF8StringNormalize, NULL},
4652 {"( 1.3.6.1.4.1.1466.115.121.1.42 DESC 'Protocol Information' )",
4653 0, NULL, NULL, NULL},
4654 {"( 1.3.6.1.4.1.1466.115.121.1.43 DESC 'Presentation Address' )",
4655 0, NULL, NULL, NULL},
4656 {"( 1.3.6.1.4.1.1466.115.121.1.44 DESC 'Printable String' )",
4657 0, printableStringValidate, xIA5StringNormalize, NULL},
4658 {"( 1.3.6.1.4.1.1466.115.121.1.45 DESC 'SubtreeSpecification' "
4659 X_BINARY X_NOT_H_R ")",
4660 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, NULL, NULL, NULL},
4661 {"( 1.3.6.1.4.1.1466.115.121.1.49 DESC 'Supported Algorithm' "
4662 X_BINARY X_NOT_H_R ")",
4663 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4664 {"( 1.3.6.1.4.1.1466.115.121.1.50 DESC 'Telephone Number' )",
4665 0, printableStringValidate, xtelephoneNumberNormalize, NULL},
4666 {"( 1.3.6.1.4.1.1466.115.121.1.51 DESC 'Teletex Terminal Identifier' )",
4667 0, NULL, NULL, NULL},
4668 {"( 1.3.6.1.4.1.1466.115.121.1.52 DESC 'Telex Number' )",
4669 0, printablesStringValidate, xIA5StringNormalize, NULL},
4670 #ifdef SUPPORT_OBSOLETE_UTC_SYNTAX
4671 {"( 1.3.6.1.4.1.1466.115.121.1.53 DESC 'UTC Time' )",
4672 0, utcTimeValidate, xutcTimeNormalize, NULL},
4674 {"( 1.3.6.1.4.1.1466.115.121.1.54 DESC 'LDAP Syntax Description' )",
4675 0, NULL, NULL, NULL},
4676 {"( 1.3.6.1.4.1.1466.115.121.1.55 DESC 'Modify Rights' )",
4677 0, NULL, NULL, NULL},
4678 {"( 1.3.6.1.4.1.1466.115.121.1.56 DESC 'LDAP Schema Definition' )",
4679 0, NULL, NULL, NULL},
4680 {"( 1.3.6.1.4.1.1466.115.121.1.57 DESC 'LDAP Schema Description' )",
4681 0, NULL, NULL, NULL},
4682 {"( 1.3.6.1.4.1.1466.115.121.1.58 DESC 'Substring Assertion' )",
4683 0, NULL, NULL, NULL},
4685 /* RFC 2307 NIS Syntaxes */
4686 {"( 1.3.6.1.1.1.0.0 DESC 'RFC2307 NIS Netgroup Triple' )",
4687 0, nisNetgroupTripleValidate, NULL, NULL},
4688 {"( 1.3.6.1.1.1.0.1 DESC 'RFC2307 Boot Parameter' )",
4689 0, bootParameterValidate, NULL, NULL},
4693 /* These OIDs are not published yet, but will be in the next
4694 * I-D for PKIX LDAPv3 schema as have been advanced by David
4695 * Chadwick in private mail.
4697 {"( 1.2.826.0.1.3344810.7.1 DESC 'Serial Number and Issuer' )",
4698 0, UTF8StringValidate, NULL, NULL},
4701 /* OpenLDAP Experimental Syntaxes */
4702 #ifdef SLAPD_ACI_ENABLED
4703 {"( 1.3.6.1.4.1.4203.666.2.1 DESC 'OpenLDAP Experimental ACI' )",
4705 UTF8StringValidate /* THIS WILL CHANGE FOR NEW ACI SYNTAX */,
4709 #ifdef SLAPD_AUTHPASSWD
4710 /* needs updating */
4711 {"( 1.3.6.1.4.1.4203.666.2.2 DESC 'OpenLDAP authPassword' )",
4712 SLAP_SYNTAX_HIDE, NULL, NULL, NULL},
4715 /* OpenLDAP Void Syntax */
4716 {"( 1.3.6.1.4.1.4203.1.1.1 DESC 'OpenLDAP void' )" ,
4717 SLAP_SYNTAX_HIDE, inValidate, NULL, NULL},
4718 {NULL, 0, NULL, NULL, NULL}
4722 char *certificateExactMatchSyntaxes[] = {
4723 "1.3.6.1.4.1.1466.115.121.1.8" /* certificate */,
4727 char *directoryStringSyntaxes[] = {
4728 "1.3.6.1.4.1.1466.115.121.1.44" /* printableString */,
4731 char *integerFirstComponentMatchSyntaxes[] = {
4732 "1.3.6.1.4.1.1466.115.121.1.27" /* INTEGER */,
4733 "1.3.6.1.4.1.1466.115.121.1.17" /* ditStructureRuleDescription */,
4736 char *objectIdentifierFirstComponentMatchSyntaxes[] = {
4737 "1.3.6.1.4.1.1466.115.121.1.38" /* OID */,
4738 "1.3.6.1.4.1.1466.115.121.1.3" /* attributeTypeDescription */,
4739 "1.3.6.1.4.1.1466.115.121.1.16" /* ditContentRuleDescription */,
4740 "1.3.6.1.4.1.1466.115.121.1.54" /* ldapSyntaxDescription */,
4741 "1.3.6.1.4.1.1466.115.121.1.30" /* matchingRuleDescription */,
4742 "1.3.6.1.4.1.1466.115.121.1.31" /* matchingRuleUseDescription */,
4743 "1.3.6.1.4.1.1466.115.121.1.35" /* nameFormDescription */,
4744 "1.3.6.1.4.1.1466.115.121.1.37" /* objectClassDescription */,
4749 * Other matching rules in X.520 that we do not use (yet):
4751 * 2.5.13.9 numericStringOrderingMatch
4752 * 2.5.13.19 octetStringSubstringsMatch
4753 * 2.5.13.25 uTCTimeMatch
4754 * 2.5.13.26 uTCTimeOrderingMatch
4755 * 2.5.13.31 directoryStringFirstComponentMatch
4756 * 2.5.13.32 wordMatch
4757 * 2.5.13.33 keywordMatch
4758 * 2.5.13.35 certificateMatch
4759 * 2.5.13.36 certificatePairExactMatch
4760 * 2.5.13.37 certificatePairMatch
4761 * 2.5.13.38 certificateListExactMatch
4762 * 2.5.13.39 certificateListMatch
4763 * 2.5.13.40 algorithmIdentifierMatch
4764 * 2.5.13.41 storedPrefixMatch
4765 * 2.5.13.42 attributeCertificateMatch
4766 * 2.5.13.43 readerAndKeyIDMatch
4767 * 2.5.13.44 attributeIntegrityMatch
4769 static slap_mrule_defs_rec mrule_defs[] = {
4771 * EQUALITY matching rules must be listed after associated APPROX
4772 * matching rules. So, we list all APPROX matching rules first.
4774 #ifndef SLAP_NVALUES
4775 {"( " directoryStringApproxMatchOID " NAME 'directoryStringApproxMatch' "
4776 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4777 SLAP_MR_HIDE | SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT, NULL,
4778 NULL, NULL, directoryStringApproxMatch,
4779 directoryStringApproxIndexer, directoryStringApproxFilter,
4782 {"( " IA5StringApproxMatchOID " NAME 'IA5StringApproxMatch' "
4783 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4784 SLAP_MR_HIDE | SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT, NULL,
4785 NULL, NULL, IA5StringApproxMatch,
4786 IA5StringApproxIndexer, IA5StringApproxFilter,
4791 * Other matching rules
4794 {"( 2.5.13.0 NAME 'objectIdentifierMatch' "
4795 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
4796 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4798 objectIdentifierNormalize, objectIdentifierMatch,
4799 objectIdentifierIndexer, objectIdentifierFilter,
4802 {"( 2.5.13.1 NAME 'distinguishedNameMatch' "
4803 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )",
4804 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4806 distinguishedNameNormalize, distinguishedNameMatch,
4807 distinguishedNameIndexer, distinguishedNameFilter,
4810 {"( 2.5.13.2 NAME 'caseIgnoreMatch' "
4811 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4812 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD,
4813 directoryStringSyntaxes,
4815 caseIgnoreNormalize, caseIgnoreMatch,
4816 caseIgnoreIndexer, caseIgnoreFilter,
4817 directoryStringApproxMatchOID },
4819 {"( 2.5.13.3 NAME 'caseIgnoreOrderingMatch' "
4820 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4821 SLAP_MR_ORDERING, directoryStringSyntaxes,
4822 NULL, caseIgnoreNormalize, caseIgnoreOrderingMatch,
4825 {"( 2.5.13.4 NAME 'caseIgnoreSubstringsMatch' "
4826 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4827 SLAP_MR_SUBSTR, NULL,
4829 caseIgnoreSubstringsMatch,
4830 caseIgnoreSubstringsIndexer, caseIgnoreSubstringsFilter,
4833 {"( 2.5.13.5 NAME 'caseExactMatch' "
4834 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4835 SLAP_MR_EQUALITY | SLAP_MR_EXT, directoryStringSyntaxes,
4837 caseExactNormalize, caseExactMatch,
4838 caseExactIndexer, caseExactFilter,
4839 directoryStringApproxMatchOID },
4841 {"( 2.5.13.6 NAME 'caseExactOrderingMatch' "
4842 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4843 SLAP_MR_ORDERING, directoryStringSyntaxes,
4844 NULL, caseExactNormalize, caseExactOrderingMatch,
4847 {"( 2.5.13.7 NAME 'caseExactSubstringsMatch' "
4848 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4849 SLAP_MR_SUBSTR, directoryStringSyntaxes,
4851 NULL, caseExactSubstringsMatch,
4852 caseExactSubstringsIndexer, caseExactSubstringsFilter,
4855 {"( 2.5.13.8 NAME 'numericStringMatch' "
4856 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 )",
4857 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL,
4859 numericStringNormalize, numericStringMatch,
4860 numericStringIndexer, numericStringFilter,
4863 {"( 2.5.13.10 NAME 'numericStringSubstringsMatch' "
4864 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4865 SLAP_MR_SUBSTR, NULL,
4867 NULL, numericStringSubstringsMatch,
4868 numericStringSubstringsIndexer, numericStringSubstringsFilter,
4871 {"( 2.5.13.11 NAME 'caseIgnoreListMatch' "
4872 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )",
4873 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL,
4874 NULL, NULL, NULL, NULL, NULL, NULL},
4876 {"( 2.5.13.12 NAME 'caseIgnoreListSubstringsMatch' "
4877 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4878 SLAP_MR_SUBSTR, NULL,
4879 NULL, NULL, NULL, NULL, NULL, NULL},
4881 {"( 2.5.13.13 NAME 'booleanMatch' "
4882 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )",
4883 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4884 NULL, NULL, booleanMatch, NULL, NULL, NULL},
4886 {"( 2.5.13.14 NAME 'integerMatch' "
4887 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4888 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4890 integerNormalize, integerMatch,
4891 integerIndexer, integerFilter,
4894 {"( 2.5.13.15 NAME 'integerOrderingMatch' "
4895 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4896 SLAP_MR_ORDERING, NULL, NULL,
4897 integerNormalize, integerOrderingMatch,
4898 integerIndexer, integerFilter,
4901 {"( 2.5.13.16 NAME 'bitStringMatch' "
4902 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.6 )",
4903 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4905 bitStringNormalize, bitStringMatch,
4906 bitStringIndexer, bitStringFilter,
4909 {"( 2.5.13.17 NAME 'octetStringMatch' "
4910 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
4911 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4913 octetStringMatch, octetStringIndexer, octetStringFilter,
4916 {"( 2.5.13.18 NAME 'octetStringOrderingMatch' "
4917 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
4918 SLAP_MR_ORDERING, NULL,
4920 octetStringOrderingMatch, NULL, NULL,
4923 {"( 2.5.13.20 NAME 'telephoneNumberMatch' "
4924 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 )",
4925 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL,
4927 telephoneNumberNormalize, telephoneNumberMatch,
4928 telephoneNumberIndexer, telephoneNumberFilter,
4931 {"( 2.5.13.21 NAME 'telephoneNumberSubstringsMatch' "
4932 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4933 SLAP_MR_SUBSTR, NULL,
4934 NULL, NULL, telephoneNumberSubstringsMatch,
4935 telephoneNumberSubstringsIndexer, telephoneNumberSubstringsFilter,
4938 {"( 2.5.13.22 NAME 'presentationAddressMatch' "
4939 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.43 )",
4940 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4945 {"( 2.5.13.23 NAME 'uniqueMemberMatch' "
4946 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.34 )",
4947 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4949 uniqueMemberNormalize, uniqueMemberMatch,
4953 {"( 2.5.13.24 NAME 'protocolInformationMatch' "
4954 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.42 )",
4955 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4956 NULL, NULL, NULL, NULL, NULL, NULL},
4958 {"( 2.5.13.27 NAME 'generalizedTimeMatch' "
4959 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
4960 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4962 generalizedTimeNormalize, generalizedTimeMatch,
4966 {"( 2.5.13.28 NAME 'generalizedTimeOrderingMatch' "
4967 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
4968 SLAP_MR_ORDERING, NULL,
4970 generalizedTimeNormalize, generalizedTimeOrderingMatch,
4974 {"( 2.5.13.29 NAME 'integerFirstComponentMatch' "
4975 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4976 SLAP_MR_EQUALITY | SLAP_MR_EXT, integerFirstComponentMatchSyntaxes,
4978 integerFirstComponentNormalize, integerMatch,
4982 {"( 2.5.13.30 NAME 'objectIdentifierFirstComponentMatch' "
4983 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
4984 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4985 objectIdentifierFirstComponentMatchSyntaxes,
4987 objectIdentifierFirstComponentNormalize, objectIdentifierMatch,
4991 #ifndef SLAP_NVALUES
4993 {"( 2.5.13.34 NAME 'certificateExactMatch' "
4994 "SYNTAX 1.2.826.0.1.3344810.7.1 )",
4995 SLAP_MR_EQUALITY | SLAP_MR_EXT, certificateExactMatchSyntaxes,
4996 certificateExactConvert, NULL,
4997 certificateExactMatch,
4998 certificateExactIndexer, certificateExactFilter,
5003 {"( 1.3.6.1.4.1.1466.109.114.1 NAME 'caseExactIA5Match' "
5004 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
5005 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
5007 caseExactIA5Normalize, caseExactIA5Match,
5008 caseExactIA5Indexer, caseExactIA5Filter,
5009 IA5StringApproxMatchOID },
5011 {"( 1.3.6.1.4.1.1466.109.114.2 NAME 'caseIgnoreIA5Match' "
5012 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
5013 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL,
5015 NULL, caseIgnoreIA5Match,
5016 caseIgnoreIA5Indexer, caseIgnoreIA5Filter,
5017 IA5StringApproxMatchOID },
5019 {"( 1.3.6.1.4.1.1466.109.114.3 NAME 'caseIgnoreIA5SubstringsMatch' "
5020 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
5021 SLAP_MR_SUBSTR, NULL,
5023 NULL, caseIgnoreIA5SubstringsMatch,
5024 caseIgnoreIA5SubstringsIndexer, caseIgnoreIA5SubstringsFilter,
5027 {"( 1.3.6.1.4.1.4203.1.2.1 NAME 'caseExactIA5SubstringsMatch' "
5028 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
5029 SLAP_MR_SUBSTR, NULL,
5031 NULL, caseExactIA5SubstringsMatch,
5032 caseExactIA5SubstringsIndexer, caseExactIA5SubstringsFilter,
5035 #ifdef SLAPD_AUTHPASSWD
5036 /* needs updating */
5037 {"( 1.3.6.1.4.1.4203.666.4.1 NAME 'authPasswordMatch' "
5038 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
5039 SLAP_MR_EQUALITY, NULL,
5041 authPasswordMatch, NULL, NULL,
5045 #ifdef SLAPD_ACI_ENABLED
5046 {"( 1.3.6.1.4.1.4203.666.4.2 NAME 'OpenLDAPaciMatch' "
5047 "SYNTAX 1.3.6.1.4.1.4203.666.2.1 )",
5048 SLAP_MR_EQUALITY, NULL,
5050 OpenLDAPaciMatch, NULL, NULL,
5054 {"( 1.2.840.113556.1.4.803 NAME 'integerBitAndMatch' "
5055 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
5058 NULL, integerBitAndMatch, NULL, NULL,
5061 {"( 1.2.840.113556.1.4.804 NAME 'integerBitOrMatch' "
5062 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
5065 NULL, integerBitOrMatch, NULL, NULL,
5068 {NULL, SLAP_MR_NONE, NULL,
5069 NULL, NULL, NULL, NULL, NULL,
5074 slap_schema_init( void )
5079 /* we should only be called once (from main) */
5080 assert( schema_init_done == 0 );
5082 for ( i=0; syntax_defs[i].sd_desc != NULL; i++ ) {
5083 res = register_syntax( &syntax_defs[i] );
5086 fprintf( stderr, "slap_schema_init: Error registering syntax %s\n",
5087 syntax_defs[i].sd_desc );
5092 for ( i=0; mrule_defs[i].mrd_desc != NULL; i++ ) {
5093 if( mrule_defs[i].mrd_usage == SLAP_MR_NONE &&
5094 mrule_defs[i].mrd_compat_syntaxes == NULL )
5097 "slap_schema_init: Ignoring unusable matching rule %s\n",
5098 mrule_defs[i].mrd_desc );
5102 res = register_matching_rule( &mrule_defs[i] );
5106 "slap_schema_init: Error registering matching rule %s\n",
5107 mrule_defs[i].mrd_desc );
5112 res = slap_schema_load();
5113 schema_init_done = 1;
5118 schema_destroy( void )