1 /* schema_init.c - init builtin schema */
4 * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
5 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
15 #include <ac/string.h>
16 #include <ac/socket.h>
22 #include "ldap_utf8.h"
24 #include "lutil_hash.h"
25 #define HASH_BYTES LUTIL_HASH_BYTES
26 #define HASH_CONTEXT lutil_HASH_CTX
27 #define HASH_Init(c) lutil_HASHInit(c)
28 #define HASH_Update(c,buf,len) lutil_HASHUpdate(c,buf,len)
29 #define HASH_Final(d,c) lutil_HASHFinal(d,c)
33 #define SLAP_MR_DN_FOLD (0)
35 #define SLAP_MR_ASSOCIATED(mr, with) \
36 ((mr) == (with) || (mr)->smr_associated == (with))
38 #define xUTF8StringNormalize NULL
39 #define xIA5StringNormalize NULL
40 #define xtelephoneNumberNormalize NULL
41 #define xgeneralizedTimeNormalize NULL
42 #define xintegerNormalize NULL
43 #define xnumericStringNormalize NULL
44 #define xnameUIDNormalize NULL
45 #define xdnNormalize NULL
47 /* (new) normalization routines */
48 #define caseExactIA5Normalize IA5StringNormalize
49 #define caseIgnoreIA5Normalize IA5StringNormalize
50 #define caseExactNormalize UTF8StringNormalize
51 #define caseIgnoreNormalize UTF8StringNormalize
53 #define integerNormalize NULL
54 #define integerFirstComponentNormalize NULL
55 #define numericStringNormalize NULL
56 #define objectIdentifierNormalize NULL
57 #define objectIdentifierFirstComponentNormalize NULL
58 #define generalizedTimeNormalize NULL
59 #define bitStringNormalize NULL
60 #define telephoneNumberNormalize NULL
62 #define distinguishedNameNormalize dnNormalize
63 #define distinguishedNameMatch dnMatch
64 #define distinguishedNameIndexer octetStringIndexer
65 #define distinguishedNameFilter octetStringFilter
67 #define uniqueMemberMatch dnMatch
69 #define objectIdentifierMatch octetStringMatch
70 #define objectIdentifierIndexer octetStringIndexer
71 #define objectIdentifierFilter octetStringFilter
73 #define OpenLDAPaciMatch NULL
75 #define bitStringMatch octetStringMatch
76 #define bitStringIndexer octetStringIndexer
77 #define bitStringFilter octetStringFilter
79 #define integerMatch NULL
80 #define integerOrderingMatch NULL
81 #define integerIndexer NULL
82 #define integerFilter NULL
84 #define generalizedTimeMatch NULL
85 #define generalizedTimeOrderingMatch NULL
87 #define caseIgnoreMatch octetStringMatch
88 #define caseIgnoreOrderingMatch octetStringOrderingMatch
89 #define caseIgnoreIndexer octetStringIndexer
90 #define caseIgnoreFilter octetStringFilter
92 #define caseIgnoreSubstringsMatch octetStringSubstringsMatch
93 #define caseIgnoreSubstringsIndexer octetStringSubstringsIndexer
94 #define caseIgnoreSubstringsFilter octetStringSubstringsFilter
96 #define caseExactMatch octetStringMatch
97 #define caseExactOrderingMatch octetStringOrderingMatch
98 #define caseExactIndexer octetStringIndexer
99 #define caseExactFilter octetStringFilter
101 #define caseExactSubstringsMatch octetStringSubstringsMatch
102 #define caseExactSubstringsIndexer octetStringSubstringsIndexer
103 #define caseExactSubstringsFilter octetStringSubstringsFilter
105 #define caseExactIA5Match octetStringMatch
106 #define caseExactIA5Indexer octetStringIndexer
107 #define caseExactIA5Filter octetStringFilter
109 #define caseExactIA5SubstringsMatch octetStringSubstringsMatch
110 #define caseExactIA5SubstringsIndexer octetStringSubstringsIndexer
111 #define caseExactIA5SubstringsFilter octetStringSubstringsFilter
113 #define caseIgnoreIA5Match octetStringMatch
114 #define caseIgnoreIA5Indexer octetStringIndexer
115 #define caseIgnoreIA5Filter octetStringFilter
117 #define caseIgnoreIA5SubstringsMatch caseExactIA5SubstringsMatch
118 #define caseIgnoreIA5SubstringsIndexer caseExactIA5SubstringsIndexer
119 #define caseIgnoreIA5SubstringsFilter caseExactIA5SubstringsFilter
121 #define numericStringMatch octetStringMatch
122 #define numericStringIndexer octetStringIndexer
123 #define numericStringFilter octetStringFilter
125 #define numericStringSubstringsMatch caseExactIA5SubstringsMatch
126 #define numericStringSubstringsIndexer caseExactIA5SubstringsIndexer
127 #define numericStringSubstringsFilter caseExactIA5SubstringsFilter
129 #define telephoneNumberMatch octetStringMatch
130 #define telephoneNumberIndexer octetStringIndexer
131 #define telephoneNumberFilter octetStringFilter
133 #define telephoneNumberSubstringsMatch caseExactIA5SubstringsMatch
134 #define telephoneNumberSubstringsIndexer caseExactIA5SubstringsIndexer
135 #define telephoneNumberSubstringsFilter caseExactIA5SubstringsFilter
139 /* validatation routines */
140 #define berValidate blobValidate
142 /* approx matching rules */
144 #define directoryStringApproxMatchOID NULL
145 #define IA5StringApproxMatchOID NULL
147 #define directoryStringApproxMatchOID "1.3.6.1.4.1.4203.666.4.4"
148 #define directoryStringApproxMatch approxMatch
149 #define directoryStringApproxIndexer approxIndexer
150 #define directoryStringApproxFilter approxFilter
151 #define IA5StringApproxMatchOID "1.3.6.1.4.1.4203.666.4.5"
152 #define IA5StringApproxMatch approxMatch
153 #define IA5StringApproxIndexer approxIndexer
154 #define IA5StringApproxFilter approxFilter
159 #define xdnNormalize dnNormalize
161 /* (new) normalization routines */
162 #define caseExactNormalize NULL
163 #define caseExactIA5Normalize NULL
164 #define caseIgnoreNormalize NULL
165 #define caseIgnoreIA5Normalize NULL
166 #define distinguishedNameNormalize NULL
167 #define integerNormalize NULL
168 #define integerFirstComponentNormalize NULL
169 #define numericStringNormalize NULL
170 #define objectIdentifierNormalize NULL
171 #define objectIdentifierFirstComponentNormalize NULL
172 #define generalizedTimeNormalize NULL
173 #define uniqueMemberNormalize NULL
174 #define bitStringNormalize NULL
175 #define telephoneNumberNormalize NULL
178 /* matching routines */
179 #define bitStringMatch octetStringMatch
180 #define bitStringIndexer octetStringIndexer
181 #define bitStringFilter octetStringFilter
183 #define numericStringMatch caseIgnoreIA5Match
184 #define numericStringIndexer NULL
185 #define numericStringFilter NULL
186 #define numericStringSubstringsIndexer NULL
187 #define numericStringSubstringsFilter NULL
189 #define objectIdentifierMatch octetStringMatch
190 #define objectIdentifierIndexer caseIgnoreIA5Indexer
191 #define objectIdentifierFilter caseIgnoreIA5Filter
193 #define octetStringSubstringsMatch NULL
194 #define OpenLDAPaciMatch NULL
196 #define generalizedTimeMatch caseIgnoreIA5Match
197 #define generalizedTimeOrderingMatch caseIgnoreIA5Match
199 #define uniqueMemberMatch dnMatch
200 #define numericStringSubstringsMatch NULL
202 #define caseExactIndexer caseExactIgnoreIndexer
203 #define caseExactFilter caseExactIgnoreFilter
204 #define caseExactOrderingMatch caseExactMatch
205 #define caseExactSubstringsMatch caseExactIgnoreSubstringsMatch
206 #define caseExactSubstringsIndexer caseExactIgnoreSubstringsIndexer
207 #define caseExactSubstringsFilter caseExactIgnoreSubstringsFilter
208 #define caseIgnoreIndexer caseExactIgnoreIndexer
209 #define caseIgnoreFilter caseExactIgnoreFilter
210 #define caseIgnoreOrderingMatch caseIgnoreMatch
211 #define caseIgnoreSubstringsMatch caseExactIgnoreSubstringsMatch
212 #define caseIgnoreSubstringsIndexer caseExactIgnoreSubstringsIndexer
213 #define caseIgnoreSubstringsFilter caseExactIgnoreSubstringsFilter
215 #define integerOrderingMatch integerMatch
216 #define integerFirstComponentMatch integerMatch
218 #define distinguishedNameMatch dnMatch
219 #define distinguishedNameIndexer caseExactIgnoreIndexer
220 #define distinguishedNameFilter caseExactIgnoreFilter
222 #define telephoneNumberMatch caseIgnoreIA5Match
223 #define telephoneNumberSubstringsMatch caseIgnoreIA5SubstringsMatch
224 #define telephoneNumberIndexer caseIgnoreIA5Indexer
225 #define telephoneNumberFilter caseIgnoreIA5Filter
226 #define telephoneNumberSubstringsIndexer caseIgnoreIA5SubstringsIndexer
227 #define telephoneNumberSubstringsFilter caseIgnoreIA5SubstringsFilter
231 static char *bvcasechr( struct berval *bv, unsigned char c, ber_len_t *len )
234 char lower = TOLOWER( c );
235 char upper = TOUPPER( c );
237 if( c == 0 ) return NULL;
239 for( i=0; i < bv->bv_len; i++ ) {
240 if( upper == bv->bv_val[i] || lower == bv->bv_val[i] ) {
242 return &bv->bv_val[i];
255 struct berval *value,
256 void *assertedValue )
258 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
261 match = memcmp( value->bv_val,
262 ((struct berval *) assertedValue)->bv_val,
271 octetStringOrderingMatch(
276 struct berval *value,
277 void *assertedValue )
279 ber_len_t v_len = value->bv_len;
280 ber_len_t av_len = ((struct berval *) assertedValue)->bv_len;
282 int match = memcmp( value->bv_val,
283 ((struct berval *) assertedValue)->bv_val,
284 (v_len < av_len ? v_len : av_len) );
286 if( match == 0 ) match = v_len - av_len;
292 /* Index generation function */
293 int octetStringIndexer(
298 struct berval *prefix,
305 HASH_CONTEXT HASHcontext;
306 unsigned char HASHdigest[HASH_BYTES];
307 struct berval digest;
308 digest.bv_val = HASHdigest;
309 digest.bv_len = sizeof(HASHdigest);
311 for( i=0; values[i].bv_val != NULL; i++ ) {
312 /* just count them */
315 /* we should have at least one value at this point */
318 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
320 slen = syntax->ssyn_oidlen;
321 mlen = mr->smr_oidlen;
323 for( i=0; values[i].bv_val != NULL; i++ ) {
324 HASH_Init( &HASHcontext );
325 if( prefix != NULL && prefix->bv_len > 0 ) {
326 HASH_Update( &HASHcontext,
327 prefix->bv_val, prefix->bv_len );
329 HASH_Update( &HASHcontext,
330 syntax->ssyn_oid, slen );
331 HASH_Update( &HASHcontext,
333 HASH_Update( &HASHcontext,
334 values[i].bv_val, values[i].bv_len );
335 HASH_Final( HASHdigest, &HASHcontext );
337 ber_dupbv( &keys[i], &digest );
340 keys[i].bv_val = NULL;
348 /* Index generation function */
349 int octetStringFilter(
354 struct berval *prefix,
355 void * assertedValue,
360 HASH_CONTEXT HASHcontext;
361 unsigned char HASHdigest[HASH_BYTES];
362 struct berval *value = (struct berval *) assertedValue;
363 struct berval digest;
364 digest.bv_val = HASHdigest;
365 digest.bv_len = sizeof(HASHdigest);
367 slen = syntax->ssyn_oidlen;
368 mlen = mr->smr_oidlen;
370 keys = ch_malloc( sizeof( struct berval ) * 2 );
372 HASH_Init( &HASHcontext );
373 if( prefix != NULL && prefix->bv_len > 0 ) {
374 HASH_Update( &HASHcontext,
375 prefix->bv_val, prefix->bv_len );
377 HASH_Update( &HASHcontext,
378 syntax->ssyn_oid, slen );
379 HASH_Update( &HASHcontext,
381 HASH_Update( &HASHcontext,
382 value->bv_val, value->bv_len );
383 HASH_Final( HASHdigest, &HASHcontext );
385 ber_dupbv( keys, &digest );
386 keys[1].bv_val = NULL;
399 /* no value allowed */
400 return LDAP_INVALID_SYNTAX;
408 /* any value allowed */
419 /* very unforgiving validation, requires no normalization
420 * before simplistic matching
422 if( in->bv_len < 3 ) {
423 return LDAP_INVALID_SYNTAX;
427 * rfc 2252 section 6.3 Bit String
428 * bitstring = "'" *binary-digit "'"
429 * binary-digit = "0" / "1"
430 * example: '0101111101'B
433 if( in->bv_val[0] != '\'' ||
434 in->bv_val[in->bv_len-2] != '\'' ||
435 in->bv_val[in->bv_len-1] != 'B' )
437 return LDAP_INVALID_SYNTAX;
440 for( i=in->bv_len-3; i>0; i-- ) {
441 if( in->bv_val[i] != '0' && in->bv_val[i] != '1' ) {
442 return LDAP_INVALID_SYNTAX;
457 if( in->bv_len == 0 ) return LDAP_SUCCESS;
459 ber_dupbv( &dn, in );
460 if( !dn.bv_val ) return LDAP_OTHER;
462 if( dn.bv_val[dn.bv_len-1] == 'B'
463 && dn.bv_val[dn.bv_len-2] == '\'' )
465 /* assume presence of optional UID */
468 for(i=dn.bv_len-3; i>1; i--) {
469 if( dn.bv_val[i] != '0' && dn.bv_val[i] != '1' ) {
473 if( dn.bv_val[i] != '\'' || dn.bv_val[i-1] != '#' ) {
474 ber_memfree( dn.bv_val );
475 return LDAP_INVALID_SYNTAX;
478 /* trim the UID to allow use of dnValidate */
479 dn.bv_val[i-1] = '\0';
483 rc = dnValidate( NULL, &dn );
485 ber_memfree( dn.bv_val );
491 uniqueMemberNormalize(
496 struct berval *normalized )
502 struct berval *normalized )
508 ber_dupbv( &out, val );
509 if( out.bv_len != 0 ) {
510 struct berval uid = { 0, NULL };
512 if( out.bv_val[out.bv_len-1] == 'B'
513 && out.bv_val[out.bv_len-2] == '\'' )
515 /* assume presence of optional UID */
516 uid.bv_val = strrchr( out.bv_val, '#' );
518 if( uid.bv_val == NULL ) {
520 return LDAP_INVALID_SYNTAX;
523 uid.bv_len = out.bv_len - (uid.bv_val - out.bv_val);
524 out.bv_len -= uid.bv_len--;
526 /* temporarily trim the UID */
527 *(uid.bv_val++) = '\0';
530 rc = dnNormalize2( NULL, &out, normalized );
532 if( rc != LDAP_SUCCESS ) {
534 return LDAP_INVALID_SYNTAX;
538 normalized->bv_val = ch_realloc( normalized->bv_val,
539 normalized->bv_len + uid.bv_len + sizeof("#") );
541 /* insert the separator */
542 normalized->bv_val[normalized->bv_len++] = '#';
545 AC_MEMCPY( &normalized->bv_val[normalized->bv_len],
546 uid.bv_val, uid.bv_len );
547 normalized->bv_len += uid.bv_len;
550 normalized->bv_val[normalized->bv_len] = '\0';
560 * Handling boolean syntax and matching is quite rigid.
561 * A more flexible approach would be to allow a variety
562 * of strings to be normalized and prettied into TRUE
570 /* very unforgiving validation, requires no normalization
571 * before simplistic matching
574 if( in->bv_len == 4 ) {
575 if( !memcmp( in->bv_val, "TRUE", 4 ) ) {
578 } else if( in->bv_len == 5 ) {
579 if( !memcmp( in->bv_val, "FALSE", 5 ) ) {
584 return LDAP_INVALID_SYNTAX;
593 struct berval *value,
594 void *assertedValue )
596 /* simplistic matching allowed by rigid validation */
597 struct berval *asserted = (struct berval *) assertedValue;
598 *matchp = value->bv_len != asserted->bv_len;
602 /*-------------------------------------------------------------------
603 LDAP/X.500 string syntax / matching rules have a few oddities. This
604 comment attempts to detail how slapd(8) treats them.
607 StringSyntax X.500 LDAP Matching/Comments
608 DirectoryString CHOICE UTF8 i/e + ignore insignificant spaces
609 PrintableString subset subset i/e + ignore insignificant spaces
610 PrintableString subset subset i/e + ignore insignificant spaces
611 NumericString subset subset ignore all spaces
612 IA5String ASCII ASCII i/e + ignore insignificant spaces
613 TeletexString T.61 T.61 i/e + ignore insignificant spaces
615 TelephoneNumber subset subset i + ignore all spaces and "-"
617 See draft-ietf-ldapbis-strpro for details (once published).
621 In X.500(93), a directory string can be either a PrintableString,
622 a bmpString, or a UniversalString (e.g., UCS (a subset of Unicode)).
623 In later versions, more CHOICEs were added. In all cases the string
626 In LDAPv3, a directory string is a UTF-8 encoded UCS string.
627 A directory string cannot be zero length.
629 For matching, there are both case ignore and exact rules. Both
630 also require that "insignificant" spaces be ignored.
631 spaces before the first non-space are ignored;
632 spaces after the last non-space are ignored;
633 spaces after a space are ignored.
634 Note: by these rules (and as clarified in X.520), a string of only
635 spaces is to be treated as if held one space, not empty (which
636 would be a syntax error).
639 In ASN.1, numeric string is just a string of digits and spaces
640 and could be empty. However, in X.500, all attribute values of
641 numeric string carry a non-empty constraint. For example:
643 internationalISDNNumber ATTRIBUTE ::= {
644 WITH SYNTAX InternationalISDNNumber
645 EQUALITY MATCHING RULE numericStringMatch
646 SUBSTRINGS MATCHING RULE numericStringSubstringsMatch
647 ID id-at-internationalISDNNumber }
648 InternationalISDNNumber ::=
649 NumericString (SIZE(1..ub-international-isdn-number))
651 Unforunately, some assertion values are don't carry the same
652 constraint (but its unclear how such an assertion could ever
653 be true). In LDAP, there is one syntax (numericString) not two
654 (numericString with constraint, numericString without constraint).
655 This should be treated as numericString with non-empty constraint.
656 Note that while someone may have no ISDN number, there are no ISDN
657 numbers which are zero length.
659 In matching, spaces are ignored.
662 In ASN.1, Printable string is just a string of printable characters
663 and can be empty. In X.500, semantics much like NumericString (see
664 serialNumber for a like example) excepting uses insignificant space
665 handling instead of ignore all spaces.
668 Basically same as PrintableString. There are no examples in X.500,
669 but same logic applies. So we require them to be non-empty as
672 -------------------------------------------------------------------*/
681 unsigned char *u = in->bv_val;
683 if( in->bv_len == 0 && syntax == slap_schema.si_syn_directoryString ) {
684 /* directory strings cannot be empty */
685 return LDAP_INVALID_SYNTAX;
688 for( count = in->bv_len; count > 0; count-=len, u+=len ) {
689 /* get the length indicated by the first byte */
690 len = LDAP_UTF8_CHARLEN2( u, len );
692 /* very basic checks */
695 if( (u[5] & 0xC0) != 0x80 ) {
696 return LDAP_INVALID_SYNTAX;
699 if( (u[4] & 0xC0) != 0x80 ) {
700 return LDAP_INVALID_SYNTAX;
703 if( (u[3] & 0xC0) != 0x80 ) {
704 return LDAP_INVALID_SYNTAX;
707 if( (u[2] & 0xC0 )!= 0x80 ) {
708 return LDAP_INVALID_SYNTAX;
711 if( (u[1] & 0xC0) != 0x80 ) {
712 return LDAP_INVALID_SYNTAX;
715 /* CHARLEN already validated it */
718 return LDAP_INVALID_SYNTAX;
721 /* make sure len corresponds with the offset
722 to the next character */
723 if( LDAP_UTF8_OFFSET( u ) != len ) return LDAP_INVALID_SYNTAX;
727 return LDAP_INVALID_SYNTAX;
740 struct berval *normalized )
742 struct berval tmp, nvalue;
746 if( val->bv_val == NULL ) {
747 /* assume we're dealing with a syntax (e.g., UTF8String)
748 * which allows empty strings
750 normalized->bv_len = 0;
751 normalized->bv_val = NULL;
755 flags = SLAP_MR_ASSOCIATED(mr, slap_schema.si_mr_caseExactMatch )
756 ? LDAP_UTF8_NOCASEFOLD : LDAP_UTF8_CASEFOLD;
757 flags |= ( use & SLAP_MR_EQUALITY_APPROX == SLAP_MR_EQUALITY_APPROX )
758 ? LDAP_UTF8_APPROX : 0;
760 val = UTF8bvnormalize( val, &tmp, flags );
765 /* collapse spaces (in place) */
767 nvalue.bv_val = tmp.bv_val;
769 wasspace=1; /* trim leading spaces */
770 for( i=0; i<tmp.bv_len; i++) {
771 if ( ASCII_SPACE( tmp.bv_val[i] )) {
772 if( wasspace++ == 0 ) {
773 /* trim repeated spaces */
774 nvalue.bv_val[nvalue.bv_len++] = tmp.bv_val[i];
778 nvalue.bv_val[nvalue.bv_len++] = tmp.bv_val[i];
782 if( nvalue.bv_len ) {
784 /* last character was a space, trim it */
787 nvalue.bv_val[nvalue.bv_len] = '\0';
790 /* string of all spaces is treated as one space */
791 nvalue.bv_val[0] = ' ';
792 nvalue.bv_val[1] = '\0';
796 *normalized = nvalue;
802 xUTF8StringNormalize(
805 struct berval *normalized )
810 /* validator should have refused an empty string */
811 assert( val->bv_len );
815 /* Ignore initial whitespace */
816 /* All space is ASCII. All ASCII is 1 byte */
817 for ( ; p < val->bv_val + val->bv_len && ASCII_SPACE( p[ 0 ] ); p++ );
819 normalized->bv_len = val->bv_len - (p - val->bv_val);
821 if( !normalized->bv_len ) {
822 ber_mem2bv( " ", 1, 1, normalized );
826 ber_mem2bv( p, normalized->bv_len, 1, normalized );
827 e = normalized->bv_val + normalized->bv_len;
829 assert( normalized->bv_val );
831 p = q = normalized->bv_val;
836 if ( ASCII_SPACE( *p ) ) {
841 /* Ignore the extra whitespace */
842 while ( ASCII_SPACE( *p ) ) {
846 len = LDAP_UTF8_COPY(q,p);
852 assert( normalized->bv_val <= p );
853 assert( q+len <= p );
855 /* cannot start with a space */
856 assert( !ASCII_SPACE( normalized->bv_val[0] ) );
859 * If the string ended in space, backup the pointer one
860 * position. One is enough because the above loop collapsed
861 * all whitespace to a single space.
869 /* cannot end with a space */
870 assert( !ASCII_SPACE( *q ) );
877 normalized->bv_len = q - normalized->bv_val;
882 /* Returns Unicode canonically normalized copy of a substring assertion
883 * Skipping attribute description */
884 static SubstringsAssertion *
885 UTF8SubstringsAssertionNormalize(
886 SubstringsAssertion *sa,
889 SubstringsAssertion *nsa;
892 nsa = (SubstringsAssertion *)SLAP_CALLOC( 1, sizeof(SubstringsAssertion) );
897 if( sa->sa_initial.bv_val != NULL ) {
898 UTF8bvnormalize( &sa->sa_initial, &nsa->sa_initial, casefold );
899 if( nsa->sa_initial.bv_val == NULL ) {
904 if( sa->sa_any != NULL ) {
905 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
908 nsa->sa_any = (struct berval *)
909 SLAP_MALLOC( (i + 1) * sizeof(struct berval) );
910 if( nsa->sa_any == NULL ) {
914 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
915 UTF8bvnormalize( &sa->sa_any[i], &nsa->sa_any[i],
917 if( nsa->sa_any[i].bv_val == NULL ) {
921 nsa->sa_any[i].bv_val = NULL;
924 if( sa->sa_final.bv_val != NULL ) {
925 UTF8bvnormalize( &sa->sa_final, &nsa->sa_final, casefold );
926 if( nsa->sa_final.bv_val == NULL ) {
934 if ( nsa->sa_final.bv_val ) free( nsa->sa_final.bv_val );
935 if ( nsa->sa_any ) ber_bvarray_free( nsa->sa_any );
936 if ( nsa->sa_initial.bv_val ) free( nsa->sa_initial.bv_val );
941 #ifndef SLAPD_APPROX_OLDSINGLESTRING
943 #if defined(SLAPD_APPROX_INITIALS)
944 #define SLAPD_APPROX_DELIMITER "._ "
945 #define SLAPD_APPROX_WORDLEN 2
947 #define SLAPD_APPROX_DELIMITER " "
948 #define SLAPD_APPROX_WORDLEN 1
957 struct berval *value,
958 void *assertedValue )
960 struct berval *nval, *assertv;
961 char *val, **values, **words, *c;
962 int i, count, len, nextchunk=0, nextavail=0;
964 /* Yes, this is necessary */
965 nval = UTF8bvnormalize( value, NULL, LDAP_UTF8_APPROX );
971 /* Yes, this is necessary */
972 assertv = UTF8bvnormalize( ((struct berval *)assertedValue),
973 NULL, LDAP_UTF8_APPROX );
974 if( assertv == NULL ) {
980 /* Isolate how many words there are */
981 for ( c = nval->bv_val, count = 1; *c; c++ ) {
982 c = strpbrk( c, SLAPD_APPROX_DELIMITER );
983 if ( c == NULL ) break;
988 /* Get a phonetic copy of each word */
989 words = (char **)ch_malloc( count * sizeof(char *) );
990 values = (char **)ch_malloc( count * sizeof(char *) );
991 for ( c = nval->bv_val, i = 0; i < count; i++, c += strlen(c) + 1 ) {
993 values[i] = phonetic(c);
996 /* Work through the asserted value's words, to see if at least some
997 of the words are there, in the same order. */
999 while ( (ber_len_t) nextchunk < assertv->bv_len ) {
1000 len = strcspn( assertv->bv_val + nextchunk, SLAPD_APPROX_DELIMITER);
1005 #if defined(SLAPD_APPROX_INITIALS)
1006 else if( len == 1 ) {
1007 /* Single letter words need to at least match one word's initial */
1008 for( i=nextavail; i<count; i++ )
1009 if( !strncasecmp( assertv->bv_val + nextchunk, words[i], 1 )) {
1016 /* Isolate the next word in the asserted value and phonetic it */
1017 assertv->bv_val[nextchunk+len] = '\0';
1018 val = phonetic( assertv->bv_val + nextchunk );
1020 /* See if this phonetic chunk is in the remaining words of *value */
1021 for( i=nextavail; i<count; i++ ){
1022 if( !strcmp( val, values[i] ) ){
1030 /* This chunk in the asserted value was NOT within the *value. */
1036 /* Go on to the next word in the asserted value */
1040 /* If some of the words were seen, call it a match */
1041 if( nextavail > 0 ) {
1048 /* Cleanup allocs */
1049 ber_bvfree( assertv );
1050 for( i=0; i<count; i++ ) {
1051 ch_free( values[i] );
1057 return LDAP_SUCCESS;
1066 struct berval *prefix,
1071 int i,j, len, wordcount, keycount=0;
1072 struct berval *newkeys;
1073 BerVarray keys=NULL;
1075 for( j=0; values[j].bv_val != NULL; j++ ) {
1076 struct berval val = { 0, NULL };
1077 /* Yes, this is necessary */
1078 UTF8bvnormalize( &values[j], &val, LDAP_UTF8_APPROX );
1079 assert( val.bv_val != NULL );
1081 /* Isolate how many words there are. There will be a key for each */
1082 for( wordcount = 0, c = val.bv_val; *c; c++) {
1083 len = strcspn(c, SLAPD_APPROX_DELIMITER);
1084 if( len >= SLAPD_APPROX_WORDLEN ) wordcount++;
1086 if (*c == '\0') break;
1090 /* Allocate/increase storage to account for new keys */
1091 newkeys = (struct berval *)ch_malloc( (keycount + wordcount + 1)
1092 * sizeof(struct berval) );
1093 AC_MEMCPY( newkeys, keys, keycount * sizeof(struct berval) );
1094 if( keys ) ch_free( keys );
1097 /* Get a phonetic copy of each word */
1098 for( c = val.bv_val, i = 0; i < wordcount; c += len + 1 ) {
1100 if( len < SLAPD_APPROX_WORDLEN ) continue;
1101 ber_str2bv( phonetic( c ), 0, 0, &keys[keycount] );
1106 ber_memfree( val.bv_val );
1108 keys[keycount].bv_val = NULL;
1111 return LDAP_SUCCESS;
1120 struct berval *prefix,
1121 void * assertedValue,
1129 /* Yes, this is necessary */
1130 val = UTF8bvnormalize( ((struct berval *)assertedValue),
1131 NULL, LDAP_UTF8_APPROX );
1132 if( val == NULL || val->bv_val == NULL ) {
1133 keys = (struct berval *)ch_malloc( sizeof(struct berval) );
1134 keys[0].bv_val = NULL;
1137 return LDAP_SUCCESS;
1140 /* Isolate how many words there are. There will be a key for each */
1141 for( count = 0,c = val->bv_val; *c; c++) {
1142 len = strcspn(c, SLAPD_APPROX_DELIMITER);
1143 if( len >= SLAPD_APPROX_WORDLEN ) count++;
1145 if (*c == '\0') break;
1149 /* Allocate storage for new keys */
1150 keys = (struct berval *)ch_malloc( (count + 1) * sizeof(struct berval) );
1152 /* Get a phonetic copy of each word */
1153 for( c = val->bv_val, i = 0; i < count; c += len + 1 ) {
1155 if( len < SLAPD_APPROX_WORDLEN ) continue;
1156 ber_str2bv( phonetic( c ), 0, 0, &keys[i] );
1162 keys[count].bv_val = NULL;
1165 return LDAP_SUCCESS;
1170 /* No other form of Approximate Matching is defined */
1178 struct berval *value,
1179 void *assertedValue )
1181 char *vapprox, *avapprox;
1184 /* Yes, this is necessary */
1185 s = UTF8normalize( value, UTF8_NOCASEFOLD );
1188 return LDAP_SUCCESS;
1191 /* Yes, this is necessary */
1192 t = UTF8normalize( ((struct berval *)assertedValue),
1197 return LDAP_SUCCESS;
1200 vapprox = phonetic( strip8bitChars( s ) );
1201 avapprox = phonetic( strip8bitChars( t ) );
1206 *matchp = strcmp( vapprox, avapprox );
1209 ch_free( avapprox );
1211 return LDAP_SUCCESS;
1220 struct berval *prefix,
1228 for( i=0; values[i].bv_val != NULL; i++ ) {
1229 /* empty - just count them */
1232 /* we should have at least one value at this point */
1235 keys = (struct berval *)ch_malloc( sizeof( struct berval ) * (i+1) );
1237 /* Copy each value and run it through phonetic() */
1238 for( i=0; values[i].bv_val != NULL; i++ ) {
1239 /* Yes, this is necessary */
1240 s = UTF8normalize( &values[i], UTF8_NOCASEFOLD );
1242 /* strip 8-bit chars and run through phonetic() */
1243 ber_str2bv( phonetic( strip8bitChars( s ) ), 0, 0, &keys[i] );
1246 keys[i].bv_val = NULL;
1249 return LDAP_SUCCESS;
1259 struct berval *prefix,
1260 void * assertedValue,
1266 keys = (struct berval *)ch_malloc( sizeof( struct berval * ) * 2 );
1268 /* Yes, this is necessary */
1269 s = UTF8normalize( ((struct berval *)assertedValue),
1274 /* strip 8-bit chars and run through phonetic() */
1275 keys[0] = ber_bvstr( phonetic( strip8bitChars( s ) ) );
1281 return LDAP_SUCCESS;
1292 struct berval *value,
1293 void *assertedValue )
1295 *matchp = UTF8bvnormcmp( value,
1296 (struct berval *) assertedValue,
1297 LDAP_UTF8_NOCASEFOLD );
1298 return LDAP_SUCCESS;
1302 caseExactIgnoreSubstringsMatch(
1307 struct berval *value,
1308 void *assertedValue )
1311 SubstringsAssertion *sub = NULL;
1312 struct berval left = { 0, NULL };
1318 casefold = ( mr != slap_schema.si_mr_caseExactSubstringsMatch )
1319 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1321 if ( UTF8bvnormalize( value, &left, casefold ) == NULL ) {
1327 sub = UTF8SubstringsAssertionNormalize( assertedValue, casefold );
1333 /* Add up asserted input length */
1334 if( sub->sa_initial.bv_val ) {
1335 inlen += sub->sa_initial.bv_len;
1338 for(i=0; sub->sa_any[i].bv_val != NULL; i++) {
1339 inlen += sub->sa_any[i].bv_len;
1342 if( sub->sa_final.bv_val ) {
1343 inlen += sub->sa_final.bv_len;
1346 if( sub->sa_initial.bv_val ) {
1347 if( inlen > left.bv_len ) {
1352 match = memcmp( sub->sa_initial.bv_val, left.bv_val,
1353 sub->sa_initial.bv_len );
1359 left.bv_val += sub->sa_initial.bv_len;
1360 left.bv_len -= sub->sa_initial.bv_len;
1361 inlen -= sub->sa_initial.bv_len;
1364 if( sub->sa_final.bv_val ) {
1365 if( inlen > left.bv_len ) {
1370 match = memcmp( sub->sa_final.bv_val,
1371 &left.bv_val[left.bv_len - sub->sa_final.bv_len],
1372 sub->sa_final.bv_len );
1378 left.bv_len -= sub->sa_final.bv_len;
1379 inlen -= sub->sa_final.bv_len;
1383 for(i=0; sub->sa_any[i].bv_val; i++) {
1388 if( inlen > left.bv_len ) {
1389 /* not enough length */
1394 if( sub->sa_any[i].bv_len == 0 ) {
1398 p = ber_bvchr( &left, *sub->sa_any[i].bv_val );
1404 idx = p - left.bv_val;
1406 if( idx >= left.bv_len ) {
1407 /* this shouldn't happen */
1409 if ( sub->sa_final.bv_val )
1410 ch_free( sub->sa_final.bv_val );
1412 ber_bvarray_free( sub->sa_any );
1413 if ( sub->sa_initial.bv_val )
1414 ch_free( sub->sa_initial.bv_val );
1422 if( sub->sa_any[i].bv_len > left.bv_len ) {
1423 /* not enough left */
1428 match = memcmp( left.bv_val,
1429 sub->sa_any[i].bv_val,
1430 sub->sa_any[i].bv_len );
1438 left.bv_val += sub->sa_any[i].bv_len;
1439 left.bv_len -= sub->sa_any[i].bv_len;
1440 inlen -= sub->sa_any[i].bv_len;
1447 if ( sub->sa_final.bv_val ) free( sub->sa_final.bv_val );
1448 if ( sub->sa_any ) ber_bvarray_free( sub->sa_any );
1449 if ( sub->sa_initial.bv_val ) free( sub->sa_initial.bv_val );
1453 return LDAP_SUCCESS;
1456 /* Index generation function */
1457 static int caseExactIgnoreIndexer(
1462 struct berval *prefix,
1467 unsigned casefold,wasspace;
1470 HASH_CONTEXT HASHcontext;
1471 unsigned char HASHdigest[HASH_BYTES];
1472 struct berval digest;
1473 digest.bv_val = HASHdigest;
1474 digest.bv_len = sizeof(HASHdigest);
1476 for( i=0; values[i].bv_val != NULL; i++ ) {
1477 /* empty - just count them */
1480 /* we should have at least one value at this point */
1483 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
1485 slen = syntax->ssyn_oidlen;
1486 mlen = mr->smr_oidlen;
1488 casefold = ( mr != slap_schema.si_mr_caseExactMatch )
1489 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1491 for( i=0; values[i].bv_val != NULL; i++ ) {
1492 struct berval value, nvalue;
1493 UTF8bvnormalize( &values[i], &value, casefold );
1495 /* collapse spaces (in place) */
1497 nvalue.bv_val = value.bv_val;
1500 for( j=0; j<value.bv_len; j++) {
1501 if ( ASCII_SPACE( value.bv_val[j] )) {
1502 if( wasspace++ == 0 ) {
1503 nvalue.bv_val[nvalue.bv_len++] = value.bv_val[j];
1507 nvalue.bv_val[nvalue.bv_len++] = value.bv_val[j];
1511 if( nvalue.bv_len == 0 ) {
1512 nvalue.bv_val = " ";
1513 nvalue.bv_len = sizeof(" ")-1;
1515 if( wasspace ) --nvalue.bv_len;
1516 nvalue.bv_val[nvalue.bv_len] = '\0';
1519 HASH_Init( &HASHcontext );
1520 if( prefix != NULL && prefix->bv_len > 0 ) {
1521 HASH_Update( &HASHcontext,
1522 prefix->bv_val, prefix->bv_len );
1524 HASH_Update( &HASHcontext,
1525 syntax->ssyn_oid, slen );
1526 HASH_Update( &HASHcontext,
1527 mr->smr_oid, mlen );
1528 HASH_Update( &HASHcontext,
1529 nvalue.bv_val, nvalue.bv_len );
1530 HASH_Final( HASHdigest, &HASHcontext );
1532 free( value.bv_val );
1533 ber_dupbv( &keys[i], &digest );
1536 keys[i].bv_val = NULL;
1538 return LDAP_SUCCESS;
1541 /* Index generation function */
1542 static int caseExactIgnoreFilter(
1547 struct berval *prefix,
1548 void * assertedValue,
1554 HASH_CONTEXT HASHcontext;
1555 unsigned char HASHdigest[HASH_BYTES];
1556 struct berval value = { 0, NULL };
1557 struct berval digest;
1559 digest.bv_val = HASHdigest;
1560 digest.bv_len = sizeof(HASHdigest);
1562 slen = syntax->ssyn_oidlen;
1563 mlen = mr->smr_oidlen;
1565 casefold = ( mr != slap_schema.si_mr_caseExactMatch )
1566 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1568 UTF8bvnormalize( (struct berval *) assertedValue, &value, casefold );
1569 /* This usually happens if filter contains bad UTF8 */
1570 if( value.bv_val == NULL ) {
1571 keys = ch_malloc( sizeof( struct berval ) );
1572 keys[0].bv_val = NULL;
1573 return LDAP_SUCCESS;
1576 keys = ch_malloc( sizeof( struct berval ) * 2 );
1578 HASH_Init( &HASHcontext );
1579 if( prefix != NULL && prefix->bv_len > 0 ) {
1580 HASH_Update( &HASHcontext,
1581 prefix->bv_val, prefix->bv_len );
1583 HASH_Update( &HASHcontext,
1584 syntax->ssyn_oid, slen );
1585 HASH_Update( &HASHcontext,
1586 mr->smr_oid, mlen );
1587 HASH_Update( &HASHcontext,
1588 value.bv_val, value.bv_len );
1589 HASH_Final( HASHdigest, &HASHcontext );
1591 ber_dupbv( keys, &digest );
1592 keys[1].bv_val = NULL;
1594 free( value.bv_val );
1597 return LDAP_SUCCESS;
1601 /* Substrings Index generation function */
1604 octetStringSubstringsIndexer
1606 caseExactIgnoreSubstringsIndexer
1612 struct berval *prefix,
1616 ber_len_t i, j, nkeys;
1619 #ifndef SLAP_NVALUES
1620 BerVarray tvalues, nvalues;
1621 unsigned casefold, wasspace;
1624 HASH_CONTEXT HASHcontext;
1625 unsigned char HASHdigest[HASH_BYTES];
1626 struct berval digest;
1627 digest.bv_val = HASHdigest;
1628 digest.bv_len = sizeof(HASHdigest);
1630 #ifndef SLAP_NVALUES
1631 for( i=0; values[i].bv_val != NULL; i++ ) {
1632 /* empty - just count them */
1635 /* we should have at least one value at this point */
1638 casefold = ( mr != slap_schema.si_mr_caseExactSubstringsMatch )
1639 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1641 tvalues = ch_malloc( sizeof( struct berval ) * (i+1) );
1642 nvalues = ch_malloc( sizeof( struct berval ) * (i+1) );
1644 for( i=0; values[i].bv_val != NULL; i++ ) {
1645 UTF8bvnormalize( &values[i], &tvalues[i], casefold );
1647 /* collapse spaces (in place) */
1648 nvalues[i].bv_len = 0;
1649 nvalues[i].bv_val = tvalues[i].bv_val;
1652 for( j=0; j<tvalues[i].bv_len; j++) {
1653 if ( ASCII_SPACE( tvalues[i].bv_val[j] )) {
1654 if( wasspace++ == 0 ) {
1655 nvalues[i].bv_val[nvalues[i].bv_len++] =
1656 tvalues[i].bv_val[j];
1660 nvalues[i].bv_val[nvalues[i].bv_len++] = tvalues[i].bv_val[j];
1664 if( nvalues[i].bv_len == 0 ) {
1665 nvalues[i].bv_val = " ";
1666 nvalues[i].bv_len = sizeof(" ")-1;
1668 if( wasspace ) --nvalues[i].bv_len;
1669 nvalues[i].bv_val[nvalues[i].bv_len] = '\0';
1673 tvalues[i].bv_val = NULL;
1674 nvalues[i].bv_val = NULL;
1680 for( i=0; values[i].bv_val != NULL; i++ ) {
1681 /* count number of indices to generate */
1682 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
1686 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
1687 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1688 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
1689 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
1691 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
1695 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
1696 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1697 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
1701 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
1702 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1703 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
1704 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
1706 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
1712 /* no keys to generate */
1714 #ifndef SLAP_NVALUES
1715 ber_bvarray_free( tvalues );
1718 return LDAP_SUCCESS;
1721 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
1723 slen = syntax->ssyn_oidlen;
1724 mlen = mr->smr_oidlen;
1727 for( i=0; values[i].bv_val != NULL; i++ ) {
1730 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
1732 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
1733 ( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
1735 char pre = SLAP_INDEX_SUBSTR_PREFIX;
1736 max = values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
1738 for( j=0; j<max; j++ ) {
1739 HASH_Init( &HASHcontext );
1740 if( prefix != NULL && prefix->bv_len > 0 ) {
1741 HASH_Update( &HASHcontext,
1742 prefix->bv_val, prefix->bv_len );
1745 HASH_Update( &HASHcontext,
1746 &pre, sizeof( pre ) );
1747 HASH_Update( &HASHcontext,
1748 syntax->ssyn_oid, slen );
1749 HASH_Update( &HASHcontext,
1750 mr->smr_oid, mlen );
1751 HASH_Update( &HASHcontext,
1752 &values[i].bv_val[j],
1753 SLAP_INDEX_SUBSTR_MAXLEN );
1754 HASH_Final( HASHdigest, &HASHcontext );
1756 ber_dupbv( &keys[nkeys++], &digest );
1760 max = SLAP_INDEX_SUBSTR_MAXLEN < values[i].bv_len
1761 ? SLAP_INDEX_SUBSTR_MAXLEN : values[i].bv_len;
1763 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
1766 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
1767 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
1768 HASH_Init( &HASHcontext );
1769 if( prefix != NULL && prefix->bv_len > 0 ) {
1770 HASH_Update( &HASHcontext,
1771 prefix->bv_val, prefix->bv_len );
1773 HASH_Update( &HASHcontext,
1774 &pre, sizeof( pre ) );
1775 HASH_Update( &HASHcontext,
1776 syntax->ssyn_oid, slen );
1777 HASH_Update( &HASHcontext,
1778 mr->smr_oid, mlen );
1779 HASH_Update( &HASHcontext,
1780 values[i].bv_val, j );
1781 HASH_Final( HASHdigest, &HASHcontext );
1783 ber_dupbv( &keys[nkeys++], &digest );
1786 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
1787 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
1788 HASH_Init( &HASHcontext );
1789 if( prefix != NULL && prefix->bv_len > 0 ) {
1790 HASH_Update( &HASHcontext,
1791 prefix->bv_val, prefix->bv_len );
1793 HASH_Update( &HASHcontext,
1794 &pre, sizeof( pre ) );
1795 HASH_Update( &HASHcontext,
1796 syntax->ssyn_oid, slen );
1797 HASH_Update( &HASHcontext,
1798 mr->smr_oid, mlen );
1799 HASH_Update( &HASHcontext,
1800 &values[i].bv_val[values[i].bv_len-j], j );
1801 HASH_Final( HASHdigest, &HASHcontext );
1803 ber_dupbv( &keys[nkeys++], &digest );
1811 keys[nkeys].bv_val = NULL;
1818 #ifndef SLAP_NVALUES
1819 ber_bvarray_free( tvalues );
1823 return LDAP_SUCCESS;
1828 octetStringSubstringsFilter
1830 caseExactIgnoreSubstringsFilter
1836 struct berval *prefix,
1837 void * assertedValue,
1840 SubstringsAssertion *sa;
1843 ber_len_t nkeys = 0;
1844 size_t slen, mlen, klen;
1846 HASH_CONTEXT HASHcontext;
1847 unsigned char HASHdigest[HASH_BYTES];
1848 struct berval *value;
1849 struct berval digest;
1851 #ifndef SLAP_NVALUES
1852 casefold = ( mr != slap_schema.si_mr_caseExactSubstringsMatch )
1853 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1855 sa = UTF8SubstringsAssertionNormalize( assertedValue, casefold );
1858 return LDAP_SUCCESS;
1861 sa = (SubstringsAssertion *) assertedValue;
1864 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
1865 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1870 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
1872 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
1873 if( sa->sa_any[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1874 /* don't bother accounting for stepping */
1875 nkeys += sa->sa_any[i].bv_len -
1876 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
1881 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
1882 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1888 if ( sa->sa_final.bv_val ) free( sa->sa_final.bv_val );
1889 if ( sa->sa_any ) ber_bvarray_free( sa->sa_any );
1890 if ( sa->sa_initial.bv_val ) free( sa->sa_initial.bv_val );
1893 return LDAP_SUCCESS;
1896 digest.bv_val = HASHdigest;
1897 digest.bv_len = sizeof(HASHdigest);
1899 slen = syntax->ssyn_oidlen;
1900 mlen = mr->smr_oidlen;
1902 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
1905 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
1906 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1908 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
1909 value = &sa->sa_initial;
1911 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
1912 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
1914 HASH_Init( &HASHcontext );
1915 if( prefix != NULL && prefix->bv_len > 0 ) {
1916 HASH_Update( &HASHcontext,
1917 prefix->bv_val, prefix->bv_len );
1919 HASH_Update( &HASHcontext,
1920 &pre, sizeof( pre ) );
1921 HASH_Update( &HASHcontext,
1922 syntax->ssyn_oid, slen );
1923 HASH_Update( &HASHcontext,
1924 mr->smr_oid, mlen );
1925 HASH_Update( &HASHcontext,
1926 value->bv_val, klen );
1927 HASH_Final( HASHdigest, &HASHcontext );
1929 ber_dupbv( &keys[nkeys++], &digest );
1932 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
1934 pre = SLAP_INDEX_SUBSTR_PREFIX;
1935 klen = SLAP_INDEX_SUBSTR_MAXLEN;
1937 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
1938 if( sa->sa_any[i].bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
1942 value = &sa->sa_any[i];
1945 j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
1946 j += SLAP_INDEX_SUBSTR_STEP )
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[j], klen );
1961 HASH_Final( HASHdigest, &HASHcontext );
1963 ber_dupbv( &keys[nkeys++], &digest );
1969 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
1970 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1972 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
1973 value = &sa->sa_final;
1975 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
1976 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
1978 HASH_Init( &HASHcontext );
1979 if( prefix != NULL && prefix->bv_len > 0 ) {
1980 HASH_Update( &HASHcontext,
1981 prefix->bv_val, prefix->bv_len );
1983 HASH_Update( &HASHcontext,
1984 &pre, sizeof( pre ) );
1985 HASH_Update( &HASHcontext,
1986 syntax->ssyn_oid, slen );
1987 HASH_Update( &HASHcontext,
1988 mr->smr_oid, mlen );
1989 HASH_Update( &HASHcontext,
1990 &value->bv_val[value->bv_len-klen], klen );
1991 HASH_Final( HASHdigest, &HASHcontext );
1993 ber_dupbv( &keys[nkeys++], &digest );
1997 keys[nkeys].bv_val = NULL;
2003 if ( sa->sa_final.bv_val ) free( sa->sa_final.bv_val );
2004 if ( sa->sa_any ) ber_bvarray_free( sa->sa_any );
2005 if ( sa->sa_initial.bv_val ) free( sa->sa_initial.bv_val );
2008 return LDAP_SUCCESS;
2011 #ifndef SLAP_NVALUES
2019 struct berval *value,
2020 void *assertedValue )
2022 *matchp = UTF8bvnormcmp( value,
2023 (struct berval *) assertedValue,
2024 LDAP_UTF8_CASEFOLD );
2025 return LDAP_SUCCESS;
2028 /* Remove all spaces and '-' characters */
2030 xtelephoneNumberNormalize(
2033 struct berval *normalized )
2037 /* validator should have refused an empty string */
2038 assert( val->bv_len );
2040 q = normalized->bv_val = ch_malloc( val->bv_len + 1 );
2042 for( p = val->bv_val; *p; p++ ) {
2043 if ( ! ( ASCII_SPACE( *p ) || *p == '-' )) {
2049 normalized->bv_len = q - normalized->bv_val;
2051 if( normalized->bv_len == 0 ) {
2052 free( normalized->bv_val );
2053 return LDAP_INVALID_SYNTAX;
2056 return LDAP_SUCCESS;
2063 struct berval *val )
2067 if( val->bv_len == 0 ) {
2068 /* disallow empty strings */
2069 return LDAP_INVALID_SYNTAX;
2072 if( OID_LEADCHAR(val->bv_val[0]) ) {
2074 for(i=1; i < val->bv_len; i++) {
2075 if( OID_SEPARATOR( val->bv_val[i] ) ) {
2076 if( dot++ ) return 1;
2077 } else if ( OID_CHAR( val->bv_val[i] ) ) {
2080 return LDAP_INVALID_SYNTAX;
2084 return !dot ? LDAP_SUCCESS : LDAP_INVALID_SYNTAX;
2086 } else if( DESC_LEADCHAR(val->bv_val[0]) ) {
2087 for(i=1; i < val->bv_len; i++) {
2088 if( !DESC_CHAR(val->bv_val[i] ) ) {
2089 return LDAP_INVALID_SYNTAX;
2093 return LDAP_SUCCESS;
2096 return LDAP_INVALID_SYNTAX;
2099 #ifndef SLAP_NVALUES
2107 struct berval *value,
2108 void *assertedValue )
2111 int vsign = 1, avsign = 1; /* default sign = '+' */
2112 struct berval *asserted;
2113 ber_len_t vlen, avlen;
2116 /* Skip leading space/sign/zeroes, and get the sign of the *value number */
2118 vlen = value->bv_len;
2119 if( mr == slap_schema.si_mr_integerFirstComponentMatch ) {
2120 char *tmp = memchr( v, '$', vlen );
2123 while( vlen && ASCII_SPACE( v[vlen-1] ))
2126 for( ; vlen && ( *v < '1' || '9' < *v ); v++, vlen-- ) /* ANSI 2.2.1 */
2132 /* Do the same with the *assertedValue number */
2133 asserted = (struct berval *) assertedValue;
2134 av = asserted->bv_val;
2135 avlen = asserted->bv_len;
2136 for( ; avlen && ( *av < '1' || '9' < *av ); av++, avlen-- )
2142 match = vsign - avsign;
2144 match = (vlen != avlen
2145 ? ( vlen < avlen ? -1 : 1 )
2146 : memcmp( v, av, vlen ));
2152 return LDAP_SUCCESS;
2159 struct berval *val )
2163 if( !val->bv_len ) return LDAP_INVALID_SYNTAX;
2165 if(( val->bv_val[0] == '+' ) || ( val->bv_val[0] == '-' )) {
2166 if( val->bv_len < 2 ) return LDAP_INVALID_SYNTAX;
2167 } else if( !ASCII_DIGIT(val->bv_val[0]) ) {
2168 return LDAP_INVALID_SYNTAX;
2171 for( i=1; i < val->bv_len; i++ ) {
2172 if( !ASCII_DIGIT(val->bv_val[i]) ) return LDAP_INVALID_SYNTAX;
2175 return LDAP_SUCCESS;
2178 #ifndef SLAP_NVALUES
2183 struct berval *normalized )
2193 /* Ignore leading spaces */
2194 while ( len && ( *p == ' ' )) {
2201 negative = ( *p == '-' );
2202 if(( *p == '-' ) || ( *p == '+' )) {
2208 /* Ignore leading zeros */
2209 while ( len && ( *p == '0' )) {
2214 /* If there are no non-zero digits left, the number is zero, otherwise
2215 allocate space for the number and copy it into the buffer */
2217 normalized->bv_val = ch_strdup("0");
2218 normalized->bv_len = 1;
2221 normalized->bv_len = len+negative;
2222 normalized->bv_val = ch_malloc( normalized->bv_len + 1 );
2224 normalized->bv_val[0] = '-';
2226 AC_MEMCPY( normalized->bv_val + negative, p, len );
2227 normalized->bv_val[len+negative] = '\0';
2230 return LDAP_SUCCESS;
2233 /* Index generation function */
2234 static int integerIndexer(
2239 struct berval *prefix,
2246 HASH_CONTEXT HASHcontext;
2247 unsigned char HASHdigest[HASH_BYTES];
2248 struct berval digest;
2249 digest.bv_val = HASHdigest;
2250 digest.bv_len = sizeof(HASHdigest);
2252 for( i=0; values[i].bv_val != NULL; i++ ) {
2253 /* empty - just count them */
2256 /* we should have at least one value at this point */
2259 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
2261 slen = syntax->ssyn_oidlen;
2262 mlen = mr->smr_oidlen;
2264 for( i=0; values[i].bv_val != NULL; i++ ) {
2266 xintegerNormalize( syntax, &values[i], &norm );
2268 HASH_Init( &HASHcontext );
2269 if( prefix != NULL && prefix->bv_len > 0 ) {
2270 HASH_Update( &HASHcontext,
2271 prefix->bv_val, prefix->bv_len );
2273 HASH_Update( &HASHcontext,
2274 syntax->ssyn_oid, slen );
2275 HASH_Update( &HASHcontext,
2276 mr->smr_oid, mlen );
2277 HASH_Update( &HASHcontext,
2278 norm.bv_val, norm.bv_len );
2279 HASH_Final( HASHdigest, &HASHcontext );
2281 ber_dupbv( &keys[i], &digest );
2282 ch_free( norm.bv_val );
2285 keys[i].bv_val = NULL;
2287 return LDAP_SUCCESS;
2290 /* Index generation function */
2291 static int integerFilter(
2296 struct berval *prefix,
2297 void * assertedValue,
2302 HASH_CONTEXT HASHcontext;
2303 unsigned char HASHdigest[HASH_BYTES];
2305 struct berval digest;
2306 digest.bv_val = HASHdigest;
2307 digest.bv_len = sizeof(HASHdigest);
2309 slen = syntax->ssyn_oidlen;
2310 mlen = mr->smr_oidlen;
2312 xintegerNormalize( syntax, assertedValue, &norm );
2314 keys = ch_malloc( sizeof( struct berval ) * 2 );
2316 HASH_Init( &HASHcontext );
2317 if( prefix != NULL && prefix->bv_len > 0 ) {
2318 HASH_Update( &HASHcontext,
2319 prefix->bv_val, prefix->bv_len );
2321 HASH_Update( &HASHcontext,
2322 syntax->ssyn_oid, slen );
2323 HASH_Update( &HASHcontext,
2324 mr->smr_oid, mlen );
2325 HASH_Update( &HASHcontext,
2326 norm.bv_val, norm.bv_len );
2327 HASH_Final( HASHdigest, &HASHcontext );
2329 ber_dupbv( &keys[0], &digest );
2330 keys[1].bv_val = NULL;
2331 ch_free( norm.bv_val );
2334 return LDAP_SUCCESS;
2340 countryStringValidate(
2342 struct berval *val )
2344 if( val->bv_len != 2 ) return LDAP_INVALID_SYNTAX;
2346 if( !SLAP_PRINTABLE(val->bv_val[0]) ) {
2347 return LDAP_INVALID_SYNTAX;
2349 if( !SLAP_PRINTABLE(val->bv_val[1]) ) {
2350 return LDAP_INVALID_SYNTAX;
2353 return LDAP_SUCCESS;
2357 printableStringValidate(
2359 struct berval *val )
2363 if( val->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
2365 for(i=0; i < val->bv_len; i++) {
2366 if( !SLAP_PRINTABLE(val->bv_val[i]) ) {
2367 return LDAP_INVALID_SYNTAX;
2371 return LDAP_SUCCESS;
2375 printablesStringValidate(
2377 struct berval *val )
2381 if( val->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
2383 for(i=0,len=0; i < val->bv_len; i++) {
2384 int c = val->bv_val[i];
2388 return LDAP_INVALID_SYNTAX;
2392 } else if ( SLAP_PRINTABLE(c) ) {
2395 return LDAP_INVALID_SYNTAX;
2400 return LDAP_INVALID_SYNTAX;
2403 return LDAP_SUCCESS;
2409 struct berval *val )
2413 if( val->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
2415 for(i=0; i < val->bv_len; i++) {
2416 if( !LDAP_ASCII(val->bv_val[i]) ) {
2417 return LDAP_INVALID_SYNTAX;
2421 return LDAP_SUCCESS;
2431 struct berval *normalized )
2434 xIA5StringNormalize(
2437 struct berval *normalized )
2442 int casefold = !SLAP_MR_ASSOCIATED(mr, slap_schema.si_mr_caseExactIA5Match);
2445 assert( val->bv_len );
2449 /* Ignore initial whitespace */
2450 while ( ASCII_SPACE( *p ) ) {
2454 normalized->bv_val = ch_strdup( p );
2455 p = q = normalized->bv_val;
2458 if ( ASCII_SPACE( *p ) ) {
2461 /* Ignore the extra whitespace */
2462 while ( ASCII_SPACE( *p ) ) {
2467 } else if ( casefold ) {
2468 /* Most IA5 rules require casefolding */
2469 *q++ = TOLOWER(*p++);
2477 assert( normalized->bv_val <= p );
2481 * If the string ended in space, backup the pointer one
2482 * position. One is enough because the above loop collapsed
2483 * all whitespace to a single space.
2486 if ( ASCII_SPACE( q[-1] ) ) {
2490 /* null terminate */
2493 normalized->bv_len = q - normalized->bv_val;
2495 if( normalized->bv_len == 0 ) {
2496 normalized->bv_val = ch_realloc( normalized->bv_val, 2 );
2497 normalized->bv_val[0] = ' ';
2498 normalized->bv_val[1] = '\0';
2499 normalized->bv_len = 1;
2502 return LDAP_SUCCESS;
2505 #ifndef SLAP_NVALUES
2513 struct berval *value,
2514 void *assertedValue )
2516 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
2519 match = strncmp( value->bv_val,
2520 ((struct berval *) assertedValue)->bv_val,
2525 return LDAP_SUCCESS;
2529 caseExactIA5SubstringsMatch
2532 octetStringSubstringsMatch
2539 struct berval *value,
2540 void *assertedValue )
2543 SubstringsAssertion *sub = assertedValue;
2544 struct berval left = *value;
2548 /* Add up asserted input length */
2549 if( sub->sa_initial.bv_val ) {
2550 inlen += sub->sa_initial.bv_len;
2553 for(i=0; sub->sa_any[i].bv_val != NULL; i++) {
2554 inlen += sub->sa_any[i].bv_len;
2557 if( sub->sa_final.bv_val ) {
2558 inlen += sub->sa_final.bv_len;
2561 if( sub->sa_initial.bv_val ) {
2562 if( inlen > left.bv_len ) {
2567 match = memcmp( sub->sa_initial.bv_val, left.bv_val,
2568 sub->sa_initial.bv_len );
2574 left.bv_val += sub->sa_initial.bv_len;
2575 left.bv_len -= sub->sa_initial.bv_len;
2576 inlen -= sub->sa_initial.bv_len;
2579 if( sub->sa_final.bv_val ) {
2580 if( inlen > left.bv_len ) {
2585 match = memcmp( sub->sa_final.bv_val,
2586 &left.bv_val[left.bv_len - sub->sa_final.bv_len],
2587 sub->sa_final.bv_len );
2593 left.bv_len -= sub->sa_final.bv_len;
2594 inlen -= sub->sa_final.bv_len;
2598 for(i=0; sub->sa_any[i].bv_val; i++) {
2603 if( inlen > left.bv_len ) {
2604 /* not enough length */
2609 if( sub->sa_any[i].bv_len == 0 ) {
2613 p = memchr( left.bv_val, *sub->sa_any[i].bv_val, left.bv_len );
2620 idx = p - left.bv_val;
2622 if( idx >= left.bv_len ) {
2623 /* this shouldn't happen */
2630 if( sub->sa_any[i].bv_len > left.bv_len ) {
2631 /* not enough left */
2636 match = memcmp( left.bv_val,
2637 sub->sa_any[i].bv_val,
2638 sub->sa_any[i].bv_len );
2646 left.bv_val += sub->sa_any[i].bv_len;
2647 left.bv_len -= sub->sa_any[i].bv_len;
2648 inlen -= sub->sa_any[i].bv_len;
2654 return LDAP_SUCCESS;
2657 #ifndef SLAP_NVALUES
2659 /* Index generation function */
2660 static int caseExactIA5Indexer(
2665 struct berval *prefix,
2672 HASH_CONTEXT HASHcontext;
2673 unsigned char HASHdigest[HASH_BYTES];
2674 struct berval digest;
2675 digest.bv_val = HASHdigest;
2676 digest.bv_len = sizeof(HASHdigest);
2678 for( i=0; values[i].bv_val != NULL; i++ ) {
2679 /* empty - just count them */
2682 /* we should have at least one value at this point */
2685 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
2687 slen = syntax->ssyn_oidlen;
2688 mlen = mr->smr_oidlen;
2690 for( i=0; values[i].bv_val != NULL; i++ ) {
2691 struct berval *value = &values[i];
2693 HASH_Init( &HASHcontext );
2694 if( prefix != NULL && prefix->bv_len > 0 ) {
2695 HASH_Update( &HASHcontext,
2696 prefix->bv_val, prefix->bv_len );
2698 HASH_Update( &HASHcontext,
2699 syntax->ssyn_oid, slen );
2700 HASH_Update( &HASHcontext,
2701 mr->smr_oid, mlen );
2702 HASH_Update( &HASHcontext,
2703 value->bv_val, value->bv_len );
2704 HASH_Final( HASHdigest, &HASHcontext );
2706 ber_dupbv( &keys[i], &digest );
2709 keys[i].bv_val = NULL;
2711 return LDAP_SUCCESS;
2714 /* Index generation function */
2715 static int caseExactIA5Filter(
2720 struct berval *prefix,
2721 void * assertedValue,
2726 HASH_CONTEXT HASHcontext;
2727 unsigned char HASHdigest[HASH_BYTES];
2728 struct berval *value;
2729 struct berval digest;
2730 digest.bv_val = HASHdigest;
2731 digest.bv_len = sizeof(HASHdigest);
2733 slen = syntax->ssyn_oidlen;
2734 mlen = mr->smr_oidlen;
2736 value = (struct berval *) assertedValue;
2738 keys = ch_malloc( sizeof( struct berval ) * 2 );
2740 HASH_Init( &HASHcontext );
2741 if( prefix != NULL && prefix->bv_len > 0 ) {
2742 HASH_Update( &HASHcontext,
2743 prefix->bv_val, prefix->bv_len );
2745 HASH_Update( &HASHcontext,
2746 syntax->ssyn_oid, slen );
2747 HASH_Update( &HASHcontext,
2748 mr->smr_oid, mlen );
2749 HASH_Update( &HASHcontext,
2750 value->bv_val, value->bv_len );
2751 HASH_Final( HASHdigest, &HASHcontext );
2753 ber_dupbv( &keys[0], &digest );
2754 keys[1].bv_val = NULL;
2757 return LDAP_SUCCESS;
2760 /* Substrings Index generation function */
2761 static int caseExactIA5SubstringsIndexer(
2766 struct berval *prefix,
2773 HASH_CONTEXT HASHcontext;
2774 unsigned char HASHdigest[HASH_BYTES];
2775 struct berval digest;
2776 digest.bv_val = HASHdigest;
2777 digest.bv_len = sizeof(HASHdigest);
2779 /* we should have at least one value at this point */
2780 assert( values != NULL && values[0].bv_val != NULL );
2783 for( i=0; values[i].bv_val != NULL; i++ ) {
2784 /* count number of indices to generate */
2785 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
2789 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
2790 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2791 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2792 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2794 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2798 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
2799 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2800 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
2804 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
2805 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2806 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2807 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2809 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2815 /* no keys to generate */
2817 return LDAP_SUCCESS;
2820 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
2822 slen = syntax->ssyn_oidlen;
2823 mlen = mr->smr_oidlen;
2826 for( i=0; values[i].bv_val != NULL; i++ ) {
2828 struct berval *value;
2831 if( value->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
2833 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
2834 ( value->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
2836 char pre = SLAP_INDEX_SUBSTR_PREFIX;
2837 max = value->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
2839 for( j=0; j<max; j++ ) {
2840 HASH_Init( &HASHcontext );
2841 if( prefix != NULL && prefix->bv_len > 0 ) {
2842 HASH_Update( &HASHcontext,
2843 prefix->bv_val, prefix->bv_len );
2846 HASH_Update( &HASHcontext,
2847 &pre, sizeof( pre ) );
2848 HASH_Update( &HASHcontext,
2849 syntax->ssyn_oid, slen );
2850 HASH_Update( &HASHcontext,
2851 mr->smr_oid, mlen );
2852 HASH_Update( &HASHcontext,
2854 SLAP_INDEX_SUBSTR_MAXLEN );
2855 HASH_Final( HASHdigest, &HASHcontext );
2857 ber_dupbv( &keys[nkeys++], &digest );
2861 max = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2862 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2864 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
2867 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
2868 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
2869 HASH_Init( &HASHcontext );
2870 if( prefix != NULL && prefix->bv_len > 0 ) {
2871 HASH_Update( &HASHcontext,
2872 prefix->bv_val, prefix->bv_len );
2874 HASH_Update( &HASHcontext,
2875 &pre, sizeof( pre ) );
2876 HASH_Update( &HASHcontext,
2877 syntax->ssyn_oid, slen );
2878 HASH_Update( &HASHcontext,
2879 mr->smr_oid, mlen );
2880 HASH_Update( &HASHcontext,
2882 HASH_Final( HASHdigest, &HASHcontext );
2884 ber_dupbv( &keys[nkeys++], &digest );
2887 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
2888 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
2889 HASH_Init( &HASHcontext );
2890 if( prefix != NULL && prefix->bv_len > 0 ) {
2891 HASH_Update( &HASHcontext,
2892 prefix->bv_val, prefix->bv_len );
2894 HASH_Update( &HASHcontext,
2895 &pre, sizeof( pre ) );
2896 HASH_Update( &HASHcontext,
2897 syntax->ssyn_oid, slen );
2898 HASH_Update( &HASHcontext,
2899 mr->smr_oid, mlen );
2900 HASH_Update( &HASHcontext,
2901 &value->bv_val[value->bv_len-j], j );
2902 HASH_Final( HASHdigest, &HASHcontext );
2904 ber_dupbv( &keys[nkeys++], &digest );
2911 keys[nkeys].bv_val = NULL;
2918 return LDAP_SUCCESS;
2921 static int caseExactIA5SubstringsFilter(
2926 struct berval *prefix,
2927 void * assertedValue,
2930 SubstringsAssertion *sa = assertedValue;
2932 ber_len_t nkeys = 0;
2933 size_t slen, mlen, klen;
2935 HASH_CONTEXT HASHcontext;
2936 unsigned char HASHdigest[HASH_BYTES];
2937 struct berval *value;
2938 struct berval digest;
2940 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
2941 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2946 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
2948 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
2949 if( sa->sa_any[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2950 /* don't bother accounting for stepping */
2951 nkeys += sa->sa_any[i].bv_len -
2952 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
2957 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
2958 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2965 return LDAP_SUCCESS;
2968 digest.bv_val = HASHdigest;
2969 digest.bv_len = sizeof(HASHdigest);
2971 slen = syntax->ssyn_oidlen;
2972 mlen = mr->smr_oidlen;
2974 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
2977 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
2978 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2980 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
2981 value = &sa->sa_initial;
2983 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2984 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2986 HASH_Init( &HASHcontext );
2987 if( prefix != NULL && prefix->bv_len > 0 ) {
2988 HASH_Update( &HASHcontext,
2989 prefix->bv_val, prefix->bv_len );
2991 HASH_Update( &HASHcontext,
2992 &pre, sizeof( pre ) );
2993 HASH_Update( &HASHcontext,
2994 syntax->ssyn_oid, slen );
2995 HASH_Update( &HASHcontext,
2996 mr->smr_oid, mlen );
2997 HASH_Update( &HASHcontext,
2998 value->bv_val, klen );
2999 HASH_Final( HASHdigest, &HASHcontext );
3001 ber_dupbv( &keys[nkeys++], &digest );
3004 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
3006 pre = SLAP_INDEX_SUBSTR_PREFIX;
3007 klen = SLAP_INDEX_SUBSTR_MAXLEN;
3009 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
3010 if( sa->sa_any[i].bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
3014 value = &sa->sa_any[i];
3017 j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
3018 j += SLAP_INDEX_SUBSTR_STEP )
3020 HASH_Init( &HASHcontext );
3021 if( prefix != NULL && prefix->bv_len > 0 ) {
3022 HASH_Update( &HASHcontext,
3023 prefix->bv_val, prefix->bv_len );
3025 HASH_Update( &HASHcontext,
3026 &pre, sizeof( pre ) );
3027 HASH_Update( &HASHcontext,
3028 syntax->ssyn_oid, slen );
3029 HASH_Update( &HASHcontext,
3030 mr->smr_oid, mlen );
3031 HASH_Update( &HASHcontext,
3032 &value->bv_val[j], klen );
3033 HASH_Final( HASHdigest, &HASHcontext );
3035 ber_dupbv( &keys[nkeys++], &digest );
3040 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
3041 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3043 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
3044 value = &sa->sa_final;
3046 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
3047 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
3049 HASH_Init( &HASHcontext );
3050 if( prefix != NULL && prefix->bv_len > 0 ) {
3051 HASH_Update( &HASHcontext,
3052 prefix->bv_val, prefix->bv_len );
3054 HASH_Update( &HASHcontext,
3055 &pre, sizeof( pre ) );
3056 HASH_Update( &HASHcontext,
3057 syntax->ssyn_oid, slen );
3058 HASH_Update( &HASHcontext,
3059 mr->smr_oid, mlen );
3060 HASH_Update( &HASHcontext,
3061 &value->bv_val[value->bv_len-klen], klen );
3062 HASH_Final( HASHdigest, &HASHcontext );
3064 ber_dupbv( &keys[nkeys++], &digest );
3068 keys[nkeys].bv_val = NULL;
3075 return LDAP_SUCCESS;
3084 struct berval *value,
3085 void *assertedValue )
3087 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
3089 if( match == 0 && value->bv_len ) {
3090 match = strncasecmp( value->bv_val,
3091 ((struct berval *) assertedValue)->bv_val,
3096 return LDAP_SUCCESS;
3100 caseIgnoreIA5SubstringsMatch(
3105 struct berval *value,
3106 void *assertedValue )
3109 SubstringsAssertion *sub = assertedValue;
3110 struct berval left = *value;
3114 /* Add up asserted input length */
3115 if( sub->sa_initial.bv_val ) {
3116 inlen += sub->sa_initial.bv_len;
3119 for(i=0; sub->sa_any[i].bv_val != NULL; i++) {
3120 inlen += sub->sa_any[i].bv_len;
3123 if( sub->sa_final.bv_val ) {
3124 inlen += sub->sa_final.bv_len;
3127 if( sub->sa_initial.bv_val ) {
3128 if( inlen > left.bv_len ) {
3133 match = strncasecmp( sub->sa_initial.bv_val, left.bv_val,
3134 sub->sa_initial.bv_len );
3140 left.bv_val += sub->sa_initial.bv_len;
3141 left.bv_len -= sub->sa_initial.bv_len;
3142 inlen -= sub->sa_initial.bv_len;
3145 if( sub->sa_final.bv_val ) {
3146 if( inlen > left.bv_len ) {
3151 match = strncasecmp( sub->sa_final.bv_val,
3152 &left.bv_val[left.bv_len - sub->sa_final.bv_len],
3153 sub->sa_final.bv_len );
3159 left.bv_len -= sub->sa_final.bv_len;
3160 inlen -= sub->sa_final.bv_len;
3164 for(i=0; sub->sa_any[i].bv_val; i++) {
3169 if( inlen > left.bv_len ) {
3170 /* not enough length */
3175 if( sub->sa_any[i].bv_len == 0 ) {
3179 p = bvcasechr( &left, *sub->sa_any[i].bv_val, &idx );
3186 assert( idx < left.bv_len );
3187 if( idx >= left.bv_len ) {
3188 /* this shouldn't happen */
3195 if( sub->sa_any[i].bv_len > left.bv_len ) {
3196 /* not enough left */
3201 match = strncasecmp( left.bv_val,
3202 sub->sa_any[i].bv_val,
3203 sub->sa_any[i].bv_len );
3212 left.bv_val += sub->sa_any[i].bv_len;
3213 left.bv_len -= sub->sa_any[i].bv_len;
3214 inlen -= sub->sa_any[i].bv_len;
3220 return LDAP_SUCCESS;
3223 /* Index generation function */
3224 static int caseIgnoreIA5Indexer(
3229 struct berval *prefix,
3234 int rc = LDAP_SUCCESS;
3237 HASH_CONTEXT HASHcontext;
3238 unsigned char HASHdigest[HASH_BYTES];
3239 struct berval digest;
3240 digest.bv_val = HASHdigest;
3241 digest.bv_len = sizeof(HASHdigest);
3243 /* we should have at least one value at this point */
3244 assert( values != NULL && values[0].bv_val != NULL );
3246 for( i=0; values[i].bv_val != NULL; i++ ) {
3247 /* just count them */
3250 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
3252 slen = syntax->ssyn_oidlen;
3253 mlen = mr->smr_oidlen;
3255 for( i=0; values[i].bv_val != NULL; i++ ) {
3256 struct berval value;
3258 if( mr->smr_normalize ) {
3259 rc = (mr->smr_normalize)( use, syntax, mr, &values[i], &value );
3260 if( rc != LDAP_SUCCESS ) {
3263 #ifndef SLAP_NVALUES
3264 } else if ( mr->smr_syntax->ssyn_normalize ) {
3265 rc = (mr->smr_syntax->ssyn_normalize)( syntax, &values[i], &value );
3266 if( rc != LDAP_SUCCESS ) {
3271 ber_dupbv( &value, &values[i] );
3274 ldap_pvt_str2lower( value.bv_val );
3276 HASH_Init( &HASHcontext );
3277 if( prefix != NULL && prefix->bv_len > 0 ) {
3278 HASH_Update( &HASHcontext,
3279 prefix->bv_val, prefix->bv_len );
3281 HASH_Update( &HASHcontext,
3282 syntax->ssyn_oid, slen );
3283 HASH_Update( &HASHcontext,
3284 mr->smr_oid, mlen );
3285 HASH_Update( &HASHcontext,
3286 value.bv_val, value.bv_len );
3287 HASH_Final( HASHdigest, &HASHcontext );
3289 free( value.bv_val );
3291 ber_dupbv( &keys[i], &digest );
3294 keys[i].bv_val = NULL;
3295 if( rc != LDAP_SUCCESS ) {
3296 ber_bvarray_free( keys );
3303 /* Index generation function */
3304 static int caseIgnoreIA5Filter(
3309 struct berval *prefix,
3310 void * assertedValue,
3315 HASH_CONTEXT HASHcontext;
3316 unsigned char HASHdigest[HASH_BYTES];
3317 struct berval value;
3318 struct berval digest;
3319 digest.bv_val = HASHdigest;
3320 digest.bv_len = sizeof(HASHdigest);
3322 slen = syntax->ssyn_oidlen;
3323 mlen = mr->smr_oidlen;
3325 ber_dupbv( &value, (struct berval *) assertedValue );
3326 ldap_pvt_str2lower( value.bv_val );
3328 keys = ch_malloc( sizeof( struct berval ) * 2 );
3330 HASH_Init( &HASHcontext );
3331 if( prefix != NULL && prefix->bv_len > 0 ) {
3332 HASH_Update( &HASHcontext,
3333 prefix->bv_val, prefix->bv_len );
3335 HASH_Update( &HASHcontext,
3336 syntax->ssyn_oid, slen );
3337 HASH_Update( &HASHcontext,
3338 mr->smr_oid, mlen );
3339 HASH_Update( &HASHcontext,
3340 value.bv_val, value.bv_len );
3341 HASH_Final( HASHdigest, &HASHcontext );
3343 ber_dupbv( &keys[0], &digest );
3344 keys[1].bv_val = NULL;
3346 free( value.bv_val );
3350 return LDAP_SUCCESS;
3353 /* Substrings Index generation function */
3354 static int caseIgnoreIA5SubstringsIndexer(
3359 struct berval *prefix,
3366 HASH_CONTEXT HASHcontext;
3367 unsigned char HASHdigest[HASH_BYTES];
3368 struct berval digest;
3369 digest.bv_val = HASHdigest;
3370 digest.bv_len = sizeof(HASHdigest);
3372 /* we should have at least one value at this point */
3373 assert( values != NULL && values[0].bv_val != NULL );
3376 for( i=0; values[i].bv_val != NULL; i++ ) {
3377 /* count number of indices to generate */
3378 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
3382 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
3383 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3384 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
3385 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
3387 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
3391 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
3392 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3393 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
3397 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
3398 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3399 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
3400 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
3402 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
3408 /* no keys to generate */
3410 return LDAP_SUCCESS;
3413 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
3415 slen = syntax->ssyn_oidlen;
3416 mlen = mr->smr_oidlen;
3419 for( i=0; values[i].bv_val != NULL; i++ ) {
3421 struct berval value;
3423 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
3425 ber_dupbv( &value, &values[i] );
3426 ldap_pvt_str2lower( value.bv_val );
3428 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
3429 ( value.bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
3431 char pre = SLAP_INDEX_SUBSTR_PREFIX;
3432 max = value.bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
3434 for( j=0; j<max; j++ ) {
3435 HASH_Init( &HASHcontext );
3436 if( prefix != NULL && prefix->bv_len > 0 ) {
3437 HASH_Update( &HASHcontext,
3438 prefix->bv_val, prefix->bv_len );
3441 HASH_Update( &HASHcontext,
3442 &pre, sizeof( pre ) );
3443 HASH_Update( &HASHcontext,
3444 syntax->ssyn_oid, slen );
3445 HASH_Update( &HASHcontext,
3446 mr->smr_oid, mlen );
3447 HASH_Update( &HASHcontext,
3449 SLAP_INDEX_SUBSTR_MAXLEN );
3450 HASH_Final( HASHdigest, &HASHcontext );
3452 ber_dupbv( &keys[nkeys++], &digest );
3456 max = SLAP_INDEX_SUBSTR_MAXLEN < value.bv_len
3457 ? SLAP_INDEX_SUBSTR_MAXLEN : value.bv_len;
3459 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
3462 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
3463 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
3464 HASH_Init( &HASHcontext );
3465 if( prefix != NULL && prefix->bv_len > 0 ) {
3466 HASH_Update( &HASHcontext,
3467 prefix->bv_val, prefix->bv_len );
3469 HASH_Update( &HASHcontext,
3470 &pre, sizeof( pre ) );
3471 HASH_Update( &HASHcontext,
3472 syntax->ssyn_oid, slen );
3473 HASH_Update( &HASHcontext,
3474 mr->smr_oid, mlen );
3475 HASH_Update( &HASHcontext,
3477 HASH_Final( HASHdigest, &HASHcontext );
3479 ber_dupbv( &keys[nkeys++], &digest );
3482 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
3483 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
3484 HASH_Init( &HASHcontext );
3485 if( prefix != NULL && prefix->bv_len > 0 ) {
3486 HASH_Update( &HASHcontext,
3487 prefix->bv_val, prefix->bv_len );
3489 HASH_Update( &HASHcontext,
3490 &pre, sizeof( pre ) );
3491 HASH_Update( &HASHcontext,
3492 syntax->ssyn_oid, slen );
3493 HASH_Update( &HASHcontext,
3494 mr->smr_oid, mlen );
3495 HASH_Update( &HASHcontext,
3496 &value.bv_val[value.bv_len-j], j );
3497 HASH_Final( HASHdigest, &HASHcontext );
3499 ber_dupbv( &keys[nkeys++], &digest );
3504 free( value.bv_val );
3508 keys[nkeys].bv_val = NULL;
3515 return LDAP_SUCCESS;
3518 static int caseIgnoreIA5SubstringsFilter(
3523 struct berval *prefix,
3524 void * assertedValue,
3527 SubstringsAssertion *sa = assertedValue;
3529 ber_len_t nkeys = 0;
3530 size_t slen, mlen, klen;
3532 HASH_CONTEXT HASHcontext;
3533 unsigned char HASHdigest[HASH_BYTES];
3534 struct berval value;
3535 struct berval digest;
3537 if((flags & SLAP_INDEX_SUBSTR_INITIAL) && sa->sa_initial.bv_val != NULL &&
3538 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3543 if((flags & SLAP_INDEX_SUBSTR_ANY) && sa->sa_any != NULL ) {
3545 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
3546 if( sa->sa_any[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3547 /* don't bother accounting for stepping */
3548 nkeys += sa->sa_any[i].bv_len -
3549 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
3554 if((flags & SLAP_INDEX_SUBSTR_FINAL) && sa->sa_final.bv_val != NULL &&
3555 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3562 return LDAP_SUCCESS;
3565 digest.bv_val = HASHdigest;
3566 digest.bv_len = sizeof(HASHdigest);
3568 slen = syntax->ssyn_oidlen;
3569 mlen = mr->smr_oidlen;
3571 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
3574 if((flags & SLAP_INDEX_SUBSTR_INITIAL) && sa->sa_initial.bv_val != NULL &&
3575 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3577 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
3578 ber_dupbv( &value, &sa->sa_initial );
3579 ldap_pvt_str2lower( value.bv_val );
3581 klen = SLAP_INDEX_SUBSTR_MAXLEN < value.bv_len
3582 ? SLAP_INDEX_SUBSTR_MAXLEN : value.bv_len;
3584 HASH_Init( &HASHcontext );
3585 if( prefix != NULL && prefix->bv_len > 0 ) {
3586 HASH_Update( &HASHcontext,
3587 prefix->bv_val, prefix->bv_len );
3589 HASH_Update( &HASHcontext,
3590 &pre, sizeof( pre ) );
3591 HASH_Update( &HASHcontext,
3592 syntax->ssyn_oid, slen );
3593 HASH_Update( &HASHcontext,
3594 mr->smr_oid, mlen );
3595 HASH_Update( &HASHcontext,
3596 value.bv_val, klen );
3597 HASH_Final( HASHdigest, &HASHcontext );
3599 free( value.bv_val );
3600 ber_dupbv( &keys[nkeys++], &digest );
3603 if((flags & SLAP_INDEX_SUBSTR_ANY) && sa->sa_any != NULL ) {
3605 pre = SLAP_INDEX_SUBSTR_PREFIX;
3606 klen = SLAP_INDEX_SUBSTR_MAXLEN;
3608 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
3609 if( sa->sa_any[i].bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
3613 ber_dupbv( &value, &sa->sa_any[i] );
3614 ldap_pvt_str2lower( value.bv_val );
3617 j <= value.bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
3618 j += SLAP_INDEX_SUBSTR_STEP )
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[j], klen );
3633 HASH_Final( HASHdigest, &HASHcontext );
3635 ber_dupbv( &keys[nkeys++], &digest );
3638 free( value.bv_val );
3642 if((flags & SLAP_INDEX_SUBSTR_FINAL) && sa->sa_final.bv_val != NULL &&
3643 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3645 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
3646 ber_dupbv( &value, &sa->sa_final );
3647 ldap_pvt_str2lower( value.bv_val );
3649 klen = SLAP_INDEX_SUBSTR_MAXLEN < value.bv_len
3650 ? SLAP_INDEX_SUBSTR_MAXLEN : value.bv_len;
3652 HASH_Init( &HASHcontext );
3653 if( prefix != NULL && prefix->bv_len > 0 ) {
3654 HASH_Update( &HASHcontext,
3655 prefix->bv_val, prefix->bv_len );
3657 HASH_Update( &HASHcontext,
3658 &pre, sizeof( pre ) );
3659 HASH_Update( &HASHcontext,
3660 syntax->ssyn_oid, slen );
3661 HASH_Update( &HASHcontext,
3662 mr->smr_oid, mlen );
3663 HASH_Update( &HASHcontext,
3664 &value.bv_val[value.bv_len-klen], klen );
3665 HASH_Final( HASHdigest, &HASHcontext );
3667 free( value.bv_val );
3668 ber_dupbv( &keys[nkeys++], &digest );
3672 keys[nkeys].bv_val = NULL;
3679 return LDAP_SUCCESS;
3685 numericStringValidate(
3691 if( in->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
3693 for(i=0; i < in->bv_len; i++) {
3694 if( !SLAP_NUMERIC(in->bv_val[i]) ) {
3695 return LDAP_INVALID_SYNTAX;
3699 return LDAP_SUCCESS;
3702 #ifndef SLAP_NVALUES
3705 xnumericStringNormalize(
3708 struct berval *normalized )
3710 /* removal all spaces */
3713 assert( val->bv_len );
3715 normalized->bv_val = ch_malloc( val->bv_len + 1 );
3718 q = normalized->bv_val;
3721 if ( ASCII_SPACE( *p ) ) {
3722 /* Ignore whitespace */
3729 /* we should have copied no more then is in val */
3730 assert( (q - normalized->bv_val) <= (p - val->bv_val) );
3732 /* null terminate */
3735 normalized->bv_len = q - normalized->bv_val;
3737 if( normalized->bv_len == 0 ) {
3738 normalized->bv_val = ch_realloc( normalized->bv_val, 2 );
3739 normalized->bv_val[0] = ' ';
3740 normalized->bv_val[1] = '\0';
3741 normalized->bv_len = 1;
3744 return LDAP_SUCCESS;
3748 objectIdentifierFirstComponentMatch(
3753 struct berval *value,
3754 void *assertedValue )
3756 int rc = LDAP_SUCCESS;
3758 struct berval *asserted = (struct berval *) assertedValue;
3762 if( value->bv_len == 0 || value->bv_val[0] != '(' /*')'*/ ) {
3763 return LDAP_INVALID_SYNTAX;
3766 /* trim leading white space */
3767 for( i=1; ASCII_SPACE(value->bv_val[i]) && i < value->bv_len; i++ ) {
3771 /* grab next word */
3772 oid.bv_val = &value->bv_val[i];
3773 j = value->bv_len - i;
3774 for( i=0; !ASCII_SPACE(oid.bv_val[i]) && i < j; i++ ) {
3779 /* insert attributeTypes, objectclass check here */
3780 if( OID_LEADCHAR(asserted->bv_val[0]) ) {
3781 rc = objectIdentifierMatch( &match, flags, syntax, mr, &oid, asserted );
3784 if ( !strcmp( syntax->ssyn_oid, SLAP_SYNTAX_MATCHINGRULES_OID ) ) {
3785 MatchingRule *asserted_mr = mr_bvfind( asserted );
3786 MatchingRule *stored_mr = mr_bvfind( &oid );
3788 if( asserted_mr == NULL ) {
3789 rc = SLAPD_COMPARE_UNDEFINED;
3791 match = asserted_mr != stored_mr;
3794 } else if ( !strcmp( syntax->ssyn_oid,
3795 SLAP_SYNTAX_ATTRIBUTETYPES_OID ) )
3797 AttributeType *asserted_at = at_bvfind( asserted );
3798 AttributeType *stored_at = at_bvfind( &oid );
3800 if( asserted_at == NULL ) {
3801 rc = SLAPD_COMPARE_UNDEFINED;
3803 match = asserted_at != stored_at;
3806 } else if ( !strcmp( syntax->ssyn_oid,
3807 SLAP_SYNTAX_OBJECTCLASSES_OID ) )
3809 ObjectClass *asserted_oc = oc_bvfind( asserted );
3810 ObjectClass *stored_oc = oc_bvfind( &oid );
3812 if( asserted_oc == NULL ) {
3813 rc = SLAPD_COMPARE_UNDEFINED;
3815 match = asserted_oc != stored_oc;
3821 LDAP_LOG( CONFIG, ENTRY,
3822 "objectIdentifierFirstComponentMatch: %d\n %s\n %s\n",
3823 match, value->bv_val, asserted->bv_val );
3825 Debug( LDAP_DEBUG_ARGS, "objectIdentifierFirstComponentMatch "
3826 "%d\n\t\"%s\"\n\t\"%s\"\n",
3827 match, value->bv_val, asserted->bv_val );
3830 if( rc == LDAP_SUCCESS ) *matchp = match;
3842 struct berval *value,
3843 void *assertedValue )
3845 long lValue, lAssertedValue;
3847 /* safe to assume integers are NUL terminated? */
3848 lValue = strtol(value->bv_val, NULL, 10);
3849 if(( lValue == LONG_MIN || lValue == LONG_MAX) && errno == ERANGE ) {
3850 return LDAP_CONSTRAINT_VIOLATION;
3853 lAssertedValue = strtol(((struct berval *)assertedValue)->bv_val, NULL, 10);
3854 if(( lAssertedValue == LONG_MIN || lAssertedValue == LONG_MAX)
3855 && errno == ERANGE )
3857 return LDAP_CONSTRAINT_VIOLATION;
3860 *matchp = (lValue & lAssertedValue) ? 0 : 1;
3861 return LDAP_SUCCESS;
3870 struct berval *value,
3871 void *assertedValue )
3873 long lValue, lAssertedValue;
3875 /* safe to assume integers are NUL terminated? */
3876 lValue = strtol(value->bv_val, NULL, 10);
3877 if(( lValue == LONG_MIN || lValue == LONG_MAX) && errno == ERANGE ) {
3878 return LDAP_CONSTRAINT_VIOLATION;
3881 lAssertedValue = strtol(((struct berval *)assertedValue)->bv_val, NULL, 10);
3882 if(( lAssertedValue == LONG_MIN || lAssertedValue == LONG_MAX)
3883 && errno == ERANGE )
3885 return LDAP_CONSTRAINT_VIOLATION;
3888 *matchp = (lValue | lAssertedValue) ? 0 : -1;
3889 return LDAP_SUCCESS;
3892 #ifndef SLAP_NVALUES
3895 #include <openssl/x509.h>
3896 #include <openssl/err.h>
3899 * Next function returns a string representation of a ASN1_INTEGER.
3900 * It works for unlimited lengths.
3903 static struct berval *
3904 asn1_integer2str(ASN1_INTEGER *a, struct berval *bv)
3908 static char digit[] = "0123456789";
3910 /* We work backwards, make it fill from the end of buf */
3911 p = buf + sizeof(buf) - 1;
3914 if ( a == NULL || a->length == 0 ) {
3922 /* We want to preserve the original */
3923 copy = ch_malloc(n*sizeof(unsigned int));
3924 for (i = 0; i<n; i++) {
3925 copy[i] = a->data[i];
3929 * base indicates the index of the most significant
3930 * byte that might be nonzero. When it goes off the
3931 * end, we now there is nothing left to do.
3937 for (i = base; i<n; i++ ) {
3938 copy[i] += carry*256;
3939 carry = copy[i] % 10;
3944 * Way too large, we need to leave
3945 * room for sign if negative
3950 *--p = digit[carry];
3952 if (copy[base] == 0) base++;
3957 if ( a->type == V_ASN1_NEG_INTEGER ) {
3961 return ber_str2bv( p, 0, 1, bv );
3965 * Given a certificate in DER format, extract the corresponding
3966 * assertion value for certificateExactMatch
3969 certificateExactConvert(
3971 struct berval * out )
3974 unsigned char *p = in->bv_val;
3975 struct berval serial;
3976 struct berval issuer_dn;
3978 xcert = d2i_X509(NULL, &p, in->bv_len);
3981 LDAP_LOG( CONFIG, ENTRY,
3982 "certificateExactConvert: error parsing cert: %s\n",
3983 ERR_error_string(ERR_get_error(),NULL), 0, 0 );
3985 Debug( LDAP_DEBUG_ARGS, "certificateExactConvert: "
3986 "error parsing cert: %s\n",
3987 ERR_error_string(ERR_get_error(),NULL), NULL, NULL );
3989 return LDAP_INVALID_SYNTAX;
3992 if ( !asn1_integer2str(xcert->cert_info->serialNumber, &serial) ) {
3994 return LDAP_INVALID_SYNTAX;
3996 if ( dnX509normalize(X509_get_issuer_name(xcert), &issuer_dn )
4000 ber_memfree(serial.bv_val);
4001 return LDAP_INVALID_SYNTAX;
4006 out->bv_len = serial.bv_len + issuer_dn.bv_len + sizeof(" $ ");
4007 out->bv_val = ch_malloc(out->bv_len);
4009 AC_MEMCPY(p, serial.bv_val, serial.bv_len);
4011 AC_MEMCPY(p, " $ ", sizeof(" $ ")-1);
4013 AC_MEMCPY(p, issuer_dn.bv_val, issuer_dn.bv_len);
4014 p += issuer_dn.bv_len;
4018 LDAP_LOG( CONFIG, ARGS,
4019 "certificateExactConvert: \n %s\n", out->bv_val, 0, 0 );
4021 Debug( LDAP_DEBUG_ARGS, "certificateExactConvert "
4023 out->bv_val, NULL, NULL );
4026 ber_memfree(serial.bv_val);
4027 ber_memfree(issuer_dn.bv_val);
4029 return LDAP_SUCCESS;
4033 serial_and_issuer_parse(
4034 struct berval *assertion,
4035 struct berval *serial,
4036 struct berval *issuer_dn
4044 begin = assertion->bv_val;
4045 end = assertion->bv_val+assertion->bv_len-1;
4046 for (p=begin; p<=end && *p != '$'; p++) /* empty */ ;
4047 if ( p > end ) return LDAP_INVALID_SYNTAX;
4049 /* p now points at the $ sign, now use
4050 * begin and end to delimit the serial number
4052 while (ASCII_SPACE(*begin)) begin++;
4054 while (ASCII_SPACE(*end)) end--;
4056 if( end <= begin ) return LDAP_INVALID_SYNTAX;
4058 bv.bv_len = end-begin+1;
4060 ber_dupbv(serial, &bv);
4062 /* now extract the issuer, remember p was at the dollar sign */
4064 end = assertion->bv_val+assertion->bv_len-1;
4065 while (ASCII_SPACE(*begin)) begin++;
4066 /* should we trim spaces at the end too? is it safe always? no, no */
4068 if( end <= begin ) return LDAP_INVALID_SYNTAX;
4071 bv.bv_len = end-begin+1;
4074 dnNormalize2( NULL, &bv, issuer_dn );
4077 return LDAP_SUCCESS;
4081 certificateExactMatch(
4086 struct berval *value,
4087 void *assertedValue )
4090 unsigned char *p = value->bv_val;
4091 struct berval serial;
4092 struct berval issuer_dn;
4093 struct berval asserted_serial;
4094 struct berval asserted_issuer_dn;
4097 xcert = d2i_X509(NULL, &p, value->bv_len);
4100 LDAP_LOG( CONFIG, ENTRY,
4101 "certificateExactMatch: error parsing cert: %s\n",
4102 ERR_error_string(ERR_get_error(),NULL), 0, 0 );
4104 Debug( LDAP_DEBUG_ARGS, "certificateExactMatch: "
4105 "error parsing cert: %s\n",
4106 ERR_error_string(ERR_get_error(),NULL), NULL, NULL );
4108 return LDAP_INVALID_SYNTAX;
4111 asn1_integer2str(xcert->cert_info->serialNumber, &serial);
4112 dnX509normalize(X509_get_issuer_name(xcert), &issuer_dn);
4116 serial_and_issuer_parse(assertedValue,
4117 &asserted_serial, &asserted_issuer_dn);
4122 slap_schema.si_syn_integer,
4123 slap_schema.si_mr_integerMatch,
4126 if ( ret == LDAP_SUCCESS ) {
4127 if ( *matchp == 0 ) {
4128 /* We need to normalize everything for dnMatch */
4132 slap_schema.si_syn_distinguishedName,
4133 slap_schema.si_mr_distinguishedNameMatch,
4135 &asserted_issuer_dn);
4140 LDAP_LOG( CONFIG, ARGS, "certificateExactMatch "
4141 "%d\n\t\"%s $ %s\"\n",
4142 *matchp, serial.bv_val, issuer_dn.bv_val );
4143 LDAP_LOG( CONFIG, ARGS, "\t\"%s $ %s\"\n",
4144 asserted_serial.bv_val, asserted_issuer_dn.bv_val,
4147 Debug( LDAP_DEBUG_ARGS, "certificateExactMatch "
4148 "%d\n\t\"%s $ %s\"\n",
4149 *matchp, serial.bv_val, issuer_dn.bv_val );
4150 Debug( LDAP_DEBUG_ARGS, "\t\"%s $ %s\"\n",
4151 asserted_serial.bv_val, asserted_issuer_dn.bv_val,
4155 ber_memfree(serial.bv_val);
4156 ber_memfree(issuer_dn.bv_val);
4157 ber_memfree(asserted_serial.bv_val);
4158 ber_memfree(asserted_issuer_dn.bv_val);
4164 * Index generation function
4165 * We just index the serials, in most scenarios the issuer DN is one of
4166 * a very small set of values.
4168 static int certificateExactIndexer(
4173 struct berval *prefix,
4181 struct berval serial;
4183 /* we should have at least one value at this point */
4184 assert( values != NULL && values[0].bv_val != NULL );
4186 for( i=0; values[i].bv_val != NULL; i++ ) {
4187 /* empty -- just count them */
4190 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
4192 for( i=0; values[i].bv_val != NULL; i++ ) {
4193 p = values[i].bv_val;
4194 xcert = d2i_X509(NULL, &p, values[i].bv_len);
4197 LDAP_LOG( CONFIG, ENTRY,
4198 "certificateExactIndexer: error parsing cert: %s\n",
4199 ERR_error_string(ERR_get_error(),NULL), 0, 0);
4201 Debug( LDAP_DEBUG_ARGS, "certificateExactIndexer: "
4202 "error parsing cert: %s\n",
4203 ERR_error_string(ERR_get_error(),NULL),
4206 /* Do we leak keys on error? */
4207 return LDAP_INVALID_SYNTAX;
4210 asn1_integer2str(xcert->cert_info->serialNumber, &serial);
4212 xintegerNormalize( slap_schema.si_syn_integer,
4213 &serial, &keys[i] );
4214 ber_memfree(serial.bv_val);
4216 LDAP_LOG( CONFIG, ENTRY,
4217 "certificateExactIndexer: returning: %s\n", keys[i].bv_val, 0, 0);
4219 Debug( LDAP_DEBUG_ARGS, "certificateExactIndexer: "
4226 keys[i].bv_val = NULL;
4228 return LDAP_SUCCESS;
4231 /* Index generation function */
4232 /* We think this is always called with a value in matching rule syntax */
4233 static int certificateExactFilter(
4238 struct berval *prefix,
4239 void * assertedValue,
4243 struct berval asserted_serial;
4246 ret = serial_and_issuer_parse( assertedValue, &asserted_serial, NULL );
4247 if( ret != LDAP_SUCCESS ) return ret;
4249 keys = ch_malloc( sizeof( struct berval ) * 2 );
4250 xintegerNormalize( syntax, &asserted_serial, &keys[0] );
4251 keys[1].bv_val = NULL;
4254 ber_memfree(asserted_serial.bv_val);
4255 return LDAP_SUCCESS;
4261 check_time_syntax (struct berval *val,
4265 static int ceiling[9] = { 99, 99, 11, 30, 23, 59, 59, 12, 59 };
4266 static int mdays[2][12] = {
4267 /* non-leap years */
4268 { 30, 27, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30 },
4270 { 30, 28, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30 }
4273 int part, c, tzoffset, leapyear = 0 ;
4275 if( val->bv_len == 0 ) {
4276 return LDAP_INVALID_SYNTAX;
4279 p = (char *)val->bv_val;
4280 e = p + val->bv_len;
4282 /* Ignore initial whitespace */
4283 while ( ( p < e ) && ASCII_SPACE( *p ) ) {
4287 if (e - p < 13 - (2 * start)) {
4288 return LDAP_INVALID_SYNTAX;
4291 for (part = 0; part < 9; part++) {
4295 for (part = start; part < 7; part++) {
4297 if ((part == 6) && (c == 'Z' || c == '+' || c == '-')) {
4304 return LDAP_INVALID_SYNTAX;
4306 if (c < 0 || c > 9) {
4307 return LDAP_INVALID_SYNTAX;
4313 return LDAP_INVALID_SYNTAX;
4315 if (c < 0 || c > 9) {
4316 return LDAP_INVALID_SYNTAX;
4321 if (part == 2 || part == 3) {
4324 if (parts[part] < 0) {
4325 return LDAP_INVALID_SYNTAX;
4327 if (parts[part] > ceiling[part]) {
4328 return LDAP_INVALID_SYNTAX;
4332 /* leapyear check for the Gregorian calendar (year>1581) */
4333 if (((parts[1] % 4 == 0) && (parts[1] != 0)) ||
4334 ((parts[0] % 4 == 0) && (parts[1] == 0)))
4339 if (parts[3] > mdays[leapyear][parts[2]]) {
4340 return LDAP_INVALID_SYNTAX;
4345 tzoffset = 0; /* UTC */
4346 } else if (c != '+' && c != '-') {
4347 return LDAP_INVALID_SYNTAX;
4351 } else /* c == '+' */ {
4356 return LDAP_INVALID_SYNTAX;
4359 for (part = 7; part < 9; part++) {
4361 if (c < 0 || c > 9) {
4362 return LDAP_INVALID_SYNTAX;
4367 if (c < 0 || c > 9) {
4368 return LDAP_INVALID_SYNTAX;
4372 if (parts[part] < 0 || parts[part] > ceiling[part]) {
4373 return LDAP_INVALID_SYNTAX;
4378 /* Ignore trailing whitespace */
4379 while ( ( p < e ) && ASCII_SPACE( *p ) ) {
4383 return LDAP_INVALID_SYNTAX;
4386 switch ( tzoffset ) {
4387 case -1: /* negativ offset to UTC, ie west of Greenwich */
4388 parts[4] += parts[7];
4389 parts[5] += parts[8];
4390 for (part = 6; --part > 0; ) { /* offset is just hhmm, no seconds */
4394 c = mdays[leapyear][parts[2]];
4396 if (parts[part] > c) {
4397 parts[part] -= c + 1;
4402 case 1: /* positive offset to UTC, ie east of Greenwich */
4403 parts[4] -= parts[7];
4404 parts[5] -= parts[8];
4405 for (part = 6; --part > 0; ) {
4409 /* first arg to % needs to be non negativ */
4410 c = mdays[leapyear][(parts[2] - 1 + 12) % 12];
4412 if (parts[part] < 0) {
4413 parts[part] += c + 1;
4418 case 0: /* already UTC */
4422 return LDAP_SUCCESS;
4425 #ifdef SUPPORT_OBSOLETE_UTC_SYNTAX
4430 struct berval *normalized )
4434 rc = check_time_syntax(val, 1, parts);
4435 if (rc != LDAP_SUCCESS) {
4439 normalized->bv_val = ch_malloc( 14 );
4440 if ( normalized->bv_val == NULL ) {
4441 return LBER_ERROR_MEMORY;
4444 sprintf( normalized->bv_val, "%02d%02d%02d%02d%02d%02dZ",
4445 parts[1], parts[2] + 1, parts[3] + 1,
4446 parts[4], parts[5], parts[6] );
4447 normalized->bv_len = 13;
4449 return LDAP_SUCCESS;
4453 #ifdef SUPPORT_OBSOLETE_UTC_SYNTAX
4461 return check_time_syntax(in, 1, parts);
4466 generalizedTimeValidate(
4472 return check_time_syntax(in, 0, parts);
4475 #ifndef SLAP_NVALUES
4478 xgeneralizedTimeNormalize(
4481 struct berval *normalized )
4485 rc = check_time_syntax(val, 0, parts);
4486 if (rc != LDAP_SUCCESS) {
4490 normalized->bv_val = ch_malloc( 16 );
4491 if ( normalized->bv_val == NULL ) {
4492 return LBER_ERROR_MEMORY;
4495 sprintf( normalized->bv_val, "%02d%02d%02d%02d%02d%02d%02dZ",
4496 parts[0], parts[1], parts[2] + 1, parts[3] + 1,
4497 parts[4], parts[5], parts[6] );
4498 normalized->bv_len = 15;
4500 return LDAP_SUCCESS;
4505 nisNetgroupTripleValidate(
4507 struct berval *val )
4512 if ( val->bv_len == 0 ) {
4513 return LDAP_INVALID_SYNTAX;
4516 p = (char *)val->bv_val;
4517 e = p + val->bv_len;
4519 if ( *p != '(' /*')'*/ ) {
4520 return LDAP_INVALID_SYNTAX;
4523 for ( p++; ( p < e ) && ( *p != /*'('*/ ')' ); p++ ) {
4527 return LDAP_INVALID_SYNTAX;
4530 } else if ( !AD_CHAR( *p ) ) {
4531 return LDAP_INVALID_SYNTAX;
4535 if ( ( commas != 2 ) || ( *p != /*'('*/ ')' ) ) {
4536 return LDAP_INVALID_SYNTAX;
4542 return LDAP_INVALID_SYNTAX;
4545 return LDAP_SUCCESS;
4549 bootParameterValidate(
4551 struct berval *val )
4555 if ( val->bv_len == 0 ) {
4556 return LDAP_INVALID_SYNTAX;
4559 p = (char *)val->bv_val;
4560 e = p + val->bv_len;
4563 for (; ( p < e ) && ( *p != '=' ); p++ ) {
4564 if ( !AD_CHAR( *p ) ) {
4565 return LDAP_INVALID_SYNTAX;
4570 return LDAP_INVALID_SYNTAX;
4574 for ( p++; ( p < e ) && ( *p != ':' ); p++ ) {
4575 if ( !AD_CHAR( *p ) ) {
4576 return LDAP_INVALID_SYNTAX;
4581 return LDAP_INVALID_SYNTAX;
4585 for ( p++; p < e; p++ ) {
4586 if ( !SLAP_PRINTABLE( *p ) ) {
4587 return LDAP_INVALID_SYNTAX;
4591 return LDAP_SUCCESS;
4594 #define X_BINARY "X-BINARY-TRANSFER-REQUIRED 'TRUE' "
4595 #define X_NOT_H_R "X-NOT-HUMAN-READABLE 'TRUE' "
4597 static slap_syntax_defs_rec syntax_defs[] = {
4598 {"( 1.3.6.1.4.1.1466.115.121.1.1 DESC 'ACI Item' "
4599 X_BINARY X_NOT_H_R ")",
4600 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, NULL, NULL, NULL},
4601 {"( 1.3.6.1.4.1.1466.115.121.1.2 DESC 'Access Point' " X_NOT_H_R ")",
4602 0, NULL, NULL, NULL},
4603 {"( 1.3.6.1.4.1.1466.115.121.1.3 DESC 'Attribute Type Description' )",
4604 0, NULL, NULL, NULL},
4605 {"( 1.3.6.1.4.1.1466.115.121.1.4 DESC 'Audio' "
4607 SLAP_SYNTAX_BLOB, blobValidate, NULL, NULL},
4608 {"( 1.3.6.1.4.1.1466.115.121.1.5 DESC 'Binary' "
4610 SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4611 {"( 1.3.6.1.4.1.1466.115.121.1.6 DESC 'Bit String' )",
4612 0, bitStringValidate, NULL, NULL },
4613 {"( 1.3.6.1.4.1.1466.115.121.1.7 DESC 'Boolean' )",
4614 0, booleanValidate, NULL, NULL},
4615 {"( 1.3.6.1.4.1.1466.115.121.1.8 DESC 'Certificate' "
4616 X_BINARY X_NOT_H_R ")",
4617 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4618 {"( 1.3.6.1.4.1.1466.115.121.1.9 DESC 'Certificate List' "
4619 X_BINARY X_NOT_H_R ")",
4620 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4621 {"( 1.3.6.1.4.1.1466.115.121.1.10 DESC 'Certificate Pair' "
4622 X_BINARY X_NOT_H_R ")",
4623 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4624 {"( 1.3.6.1.4.1.1466.115.121.1.11 DESC 'Country String' )",
4625 0, countryStringValidate, xIA5StringNormalize, NULL},
4626 {"( 1.3.6.1.4.1.1466.115.121.1.12 DESC 'Distinguished Name' )",
4627 0, dnValidate, xdnNormalize, dnPretty2},
4628 {"( 1.3.6.1.4.1.1466.115.121.1.13 DESC 'Data Quality' )",
4629 0, NULL, NULL, NULL},
4630 {"( 1.3.6.1.4.1.1466.115.121.1.14 DESC 'Delivery Method' )",
4631 0, NULL, NULL, NULL},
4632 {"( 1.3.6.1.4.1.1466.115.121.1.15 DESC 'Directory String' )",
4633 0, UTF8StringValidate, xUTF8StringNormalize, NULL},
4634 {"( 1.3.6.1.4.1.1466.115.121.1.16 DESC 'DIT Content Rule Description' )",
4635 0, NULL, NULL, NULL},
4636 {"( 1.3.6.1.4.1.1466.115.121.1.17 DESC 'DIT Structure Rule Description' )",
4637 0, NULL, NULL, NULL},
4638 {"( 1.3.6.1.4.1.1466.115.121.1.19 DESC 'DSA Quality' )",
4639 0, NULL, NULL, NULL},
4640 {"( 1.3.6.1.4.1.1466.115.121.1.20 DESC 'DSE Type' )",
4641 0, NULL, NULL, NULL},
4642 {"( 1.3.6.1.4.1.1466.115.121.1.21 DESC 'Enhanced Guide' )",
4643 0, NULL, NULL, NULL},
4644 {"( 1.3.6.1.4.1.1466.115.121.1.22 DESC 'Facsimile Telephone Number' )",
4645 0, printablesStringValidate, xtelephoneNumberNormalize, NULL},
4646 {"( 1.3.6.1.4.1.1466.115.121.1.23 DESC 'Fax' " X_NOT_H_R ")",
4647 SLAP_SYNTAX_BLOB, NULL, NULL, NULL},
4648 {"( 1.3.6.1.4.1.1466.115.121.1.24 DESC 'Generalized Time' )",
4649 0, generalizedTimeValidate, xgeneralizedTimeNormalize, NULL},
4650 {"( 1.3.6.1.4.1.1466.115.121.1.25 DESC 'Guide' )",
4651 0, NULL, NULL, NULL},
4652 {"( 1.3.6.1.4.1.1466.115.121.1.26 DESC 'IA5 String' )",
4653 0, IA5StringValidate, xIA5StringNormalize, NULL},
4654 {"( 1.3.6.1.4.1.1466.115.121.1.27 DESC 'Integer' )",
4655 0, integerValidate, xintegerNormalize, NULL},
4656 {"( 1.3.6.1.4.1.1466.115.121.1.28 DESC 'JPEG' " X_NOT_H_R ")",
4657 SLAP_SYNTAX_BLOB, blobValidate, NULL, NULL},
4658 {"( 1.3.6.1.4.1.1466.115.121.1.29 DESC 'Master And Shadow Access Points' )",
4659 0, NULL, NULL, NULL},
4660 {"( 1.3.6.1.4.1.1466.115.121.1.30 DESC 'Matching Rule Description' )",
4661 0, NULL, NULL, NULL},
4662 {"( 1.3.6.1.4.1.1466.115.121.1.31 DESC 'Matching Rule Use Description' )",
4663 0, NULL, NULL, NULL},
4664 {"( 1.3.6.1.4.1.1466.115.121.1.32 DESC 'Mail Preference' )",
4665 0, NULL, NULL, NULL},
4666 {"( 1.3.6.1.4.1.1466.115.121.1.33 DESC 'MHS OR Address' )",
4667 0, NULL, NULL, NULL},
4668 {"( 1.3.6.1.4.1.1466.115.121.1.34 DESC 'Name And Optional UID' )",
4669 0, nameUIDValidate, xnameUIDNormalize, NULL},
4670 {"( 1.3.6.1.4.1.1466.115.121.1.35 DESC 'Name Form Description' )",
4671 0, NULL, NULL, NULL},
4672 {"( 1.3.6.1.4.1.1466.115.121.1.36 DESC 'Numeric String' )",
4673 0, numericStringValidate, xnumericStringNormalize, NULL},
4674 {"( 1.3.6.1.4.1.1466.115.121.1.37 DESC 'Object Class Description' )",
4675 0, NULL, NULL, NULL},
4676 {"( 1.3.6.1.4.1.1466.115.121.1.38 DESC 'OID' )",
4677 0, oidValidate, NULL, NULL},
4678 {"( 1.3.6.1.4.1.1466.115.121.1.39 DESC 'Other Mailbox' )",
4679 0, IA5StringValidate, xIA5StringNormalize, NULL},
4680 {"( 1.3.6.1.4.1.1466.115.121.1.40 DESC 'Octet String' )",
4681 0, blobValidate, NULL, NULL},
4682 {"( 1.3.6.1.4.1.1466.115.121.1.41 DESC 'Postal Address' )",
4683 0, UTF8StringValidate, xUTF8StringNormalize, NULL},
4684 {"( 1.3.6.1.4.1.1466.115.121.1.42 DESC 'Protocol Information' )",
4685 0, NULL, NULL, NULL},
4686 {"( 1.3.6.1.4.1.1466.115.121.1.43 DESC 'Presentation Address' )",
4687 0, NULL, NULL, NULL},
4688 {"( 1.3.6.1.4.1.1466.115.121.1.44 DESC 'Printable String' )",
4689 0, printableStringValidate, xIA5StringNormalize, NULL},
4690 {"( 1.3.6.1.4.1.1466.115.121.1.45 DESC 'SubtreeSpecification' "
4691 X_BINARY X_NOT_H_R ")",
4692 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, NULL, NULL, NULL},
4693 {"( 1.3.6.1.4.1.1466.115.121.1.49 DESC 'Supported Algorithm' "
4694 X_BINARY X_NOT_H_R ")",
4695 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4696 {"( 1.3.6.1.4.1.1466.115.121.1.50 DESC 'Telephone Number' )",
4697 0, printableStringValidate, xtelephoneNumberNormalize, NULL},
4698 {"( 1.3.6.1.4.1.1466.115.121.1.51 DESC 'Teletex Terminal Identifier' )",
4699 0, NULL, NULL, NULL},
4700 {"( 1.3.6.1.4.1.1466.115.121.1.52 DESC 'Telex Number' )",
4701 0, printablesStringValidate, xIA5StringNormalize, NULL},
4702 #ifdef SUPPORT_OBSOLETE_UTC_SYNTAX
4703 {"( 1.3.6.1.4.1.1466.115.121.1.53 DESC 'UTC Time' )",
4704 0, utcTimeValidate, xutcTimeNormalize, NULL},
4706 {"( 1.3.6.1.4.1.1466.115.121.1.54 DESC 'LDAP Syntax Description' )",
4707 0, NULL, NULL, NULL},
4708 {"( 1.3.6.1.4.1.1466.115.121.1.55 DESC 'Modify Rights' )",
4709 0, NULL, NULL, NULL},
4710 {"( 1.3.6.1.4.1.1466.115.121.1.56 DESC 'LDAP Schema Definition' )",
4711 0, NULL, NULL, NULL},
4712 {"( 1.3.6.1.4.1.1466.115.121.1.57 DESC 'LDAP Schema Description' )",
4713 0, NULL, NULL, NULL},
4714 {"( 1.3.6.1.4.1.1466.115.121.1.58 DESC 'Substring Assertion' )",
4715 0, NULL, NULL, NULL},
4717 /* RFC 2307 NIS Syntaxes */
4718 {"( 1.3.6.1.1.1.0.0 DESC 'RFC2307 NIS Netgroup Triple' )",
4719 0, nisNetgroupTripleValidate, NULL, NULL},
4720 {"( 1.3.6.1.1.1.0.1 DESC 'RFC2307 Boot Parameter' )",
4721 0, bootParameterValidate, NULL, NULL},
4725 /* These OIDs are not published yet, but will be in the next
4726 * I-D for PKIX LDAPv3 schema as have been advanced by David
4727 * Chadwick in private mail.
4729 {"( 1.2.826.0.1.3344810.7.1 DESC 'Serial Number and Issuer' )",
4730 0, UTF8StringValidate, NULL, NULL},
4733 /* OpenLDAP Experimental Syntaxes */
4734 #ifdef SLAPD_ACI_ENABLED
4735 {"( 1.3.6.1.4.1.4203.666.2.1 DESC 'OpenLDAP Experimental ACI' )",
4737 UTF8StringValidate /* THIS WILL CHANGE FOR NEW ACI SYNTAX */,
4741 #ifdef SLAPD_AUTHPASSWD
4742 /* needs updating */
4743 {"( 1.3.6.1.4.1.4203.666.2.2 DESC 'OpenLDAP authPassword' )",
4744 SLAP_SYNTAX_HIDE, NULL, NULL, NULL},
4747 /* OpenLDAP Void Syntax */
4748 {"( 1.3.6.1.4.1.4203.1.1.1 DESC 'OpenLDAP void' )" ,
4749 SLAP_SYNTAX_HIDE, inValidate, NULL, NULL},
4750 {NULL, 0, NULL, NULL, NULL}
4754 char *certificateExactMatchSyntaxes[] = {
4755 "1.3.6.1.4.1.1466.115.121.1.8" /* certificate */,
4759 char *directoryStringSyntaxes[] = {
4760 "1.3.6.1.4.1.1466.115.121.1.44" /* printableString */,
4763 char *integerFirstComponentMatchSyntaxes[] = {
4764 "1.3.6.1.4.1.1466.115.121.1.27" /* INTEGER */,
4765 "1.3.6.1.4.1.1466.115.121.1.17" /* ditStructureRuleDescription */,
4768 char *objectIdentifierFirstComponentMatchSyntaxes[] = {
4769 "1.3.6.1.4.1.1466.115.121.1.38" /* OID */,
4770 "1.3.6.1.4.1.1466.115.121.1.3" /* attributeTypeDescription */,
4771 "1.3.6.1.4.1.1466.115.121.1.16" /* ditContentRuleDescription */,
4772 "1.3.6.1.4.1.1466.115.121.1.54" /* ldapSyntaxDescription */,
4773 "1.3.6.1.4.1.1466.115.121.1.30" /* matchingRuleDescription */,
4774 "1.3.6.1.4.1.1466.115.121.1.31" /* matchingRuleUseDescription */,
4775 "1.3.6.1.4.1.1466.115.121.1.35" /* nameFormDescription */,
4776 "1.3.6.1.4.1.1466.115.121.1.37" /* objectClassDescription */,
4781 * Other matching rules in X.520 that we do not use (yet):
4783 * 2.5.13.9 numericStringOrderingMatch
4784 * 2.5.13.25 uTCTimeMatch
4785 * 2.5.13.26 uTCTimeOrderingMatch
4786 * 2.5.13.31 directoryStringFirstComponentMatch
4787 * 2.5.13.32 wordMatch
4788 * 2.5.13.33 keywordMatch
4789 * 2.5.13.35 certificateMatch
4790 * 2.5.13.36 certificatePairExactMatch
4791 * 2.5.13.37 certificatePairMatch
4792 * 2.5.13.38 certificateListExactMatch
4793 * 2.5.13.39 certificateListMatch
4794 * 2.5.13.40 algorithmIdentifierMatch
4795 * 2.5.13.41 storedPrefixMatch
4796 * 2.5.13.42 attributeCertificateMatch
4797 * 2.5.13.43 readerAndKeyIDMatch
4798 * 2.5.13.44 attributeIntegrityMatch
4800 static slap_mrule_defs_rec mrule_defs[] = {
4802 * EQUALITY matching rules must be listed after associated APPROX
4803 * matching rules. So, we list all APPROX matching rules first.
4805 #ifndef SLAP_NVALUES
4806 {"( " directoryStringApproxMatchOID " NAME 'directoryStringApproxMatch' "
4807 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4808 SLAP_MR_HIDE | SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT, NULL,
4809 NULL, NULL, directoryStringApproxMatch,
4810 directoryStringApproxIndexer, directoryStringApproxFilter,
4813 {"( " IA5StringApproxMatchOID " NAME 'IA5StringApproxMatch' "
4814 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4815 SLAP_MR_HIDE | SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT, NULL,
4816 NULL, NULL, IA5StringApproxMatch,
4817 IA5StringApproxIndexer, IA5StringApproxFilter,
4822 * Other matching rules
4825 {"( 2.5.13.0 NAME 'objectIdentifierMatch' "
4826 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
4827 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4829 objectIdentifierNormalize, objectIdentifierMatch,
4830 objectIdentifierIndexer, objectIdentifierFilter,
4833 {"( 2.5.13.1 NAME 'distinguishedNameMatch' "
4834 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )",
4835 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4837 distinguishedNameNormalize, distinguishedNameMatch,
4838 distinguishedNameIndexer, distinguishedNameFilter,
4841 {"( 2.5.13.2 NAME 'caseIgnoreMatch' "
4842 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4843 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD,
4844 directoryStringSyntaxes,
4846 caseIgnoreNormalize, caseIgnoreMatch,
4847 caseIgnoreIndexer, caseIgnoreFilter,
4848 directoryStringApproxMatchOID },
4850 {"( 2.5.13.3 NAME 'caseIgnoreOrderingMatch' "
4851 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4852 SLAP_MR_ORDERING, directoryStringSyntaxes,
4853 NULL, caseIgnoreNormalize, caseIgnoreOrderingMatch,
4856 {"( 2.5.13.4 NAME 'caseIgnoreSubstringsMatch' "
4857 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4858 SLAP_MR_SUBSTR, NULL,
4860 caseIgnoreSubstringsMatch,
4861 caseIgnoreSubstringsIndexer, caseIgnoreSubstringsFilter,
4864 {"( 2.5.13.5 NAME 'caseExactMatch' "
4865 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4866 SLAP_MR_EQUALITY | SLAP_MR_EXT, directoryStringSyntaxes,
4868 caseExactNormalize, caseExactMatch,
4869 caseExactIndexer, caseExactFilter,
4870 directoryStringApproxMatchOID },
4872 {"( 2.5.13.6 NAME 'caseExactOrderingMatch' "
4873 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4874 SLAP_MR_ORDERING, directoryStringSyntaxes,
4875 NULL, caseExactNormalize, caseExactOrderingMatch,
4878 {"( 2.5.13.7 NAME 'caseExactSubstringsMatch' "
4879 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4880 SLAP_MR_SUBSTR, directoryStringSyntaxes,
4882 NULL, caseExactSubstringsMatch,
4883 caseExactSubstringsIndexer, caseExactSubstringsFilter,
4886 {"( 2.5.13.8 NAME 'numericStringMatch' "
4887 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 )",
4888 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL,
4890 numericStringNormalize, numericStringMatch,
4891 numericStringIndexer, numericStringFilter,
4894 {"( 2.5.13.10 NAME 'numericStringSubstringsMatch' "
4895 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4896 SLAP_MR_SUBSTR, NULL,
4898 NULL, numericStringSubstringsMatch,
4899 numericStringSubstringsIndexer, numericStringSubstringsFilter,
4902 {"( 2.5.13.11 NAME 'caseIgnoreListMatch' "
4903 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )",
4904 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL,
4905 NULL, NULL, NULL, NULL, NULL, NULL},
4907 {"( 2.5.13.12 NAME 'caseIgnoreListSubstringsMatch' "
4908 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4909 SLAP_MR_SUBSTR, NULL,
4910 NULL, NULL, NULL, NULL, NULL, NULL},
4912 {"( 2.5.13.13 NAME 'booleanMatch' "
4913 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )",
4914 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4915 NULL, NULL, booleanMatch, NULL, NULL, NULL},
4917 {"( 2.5.13.14 NAME 'integerMatch' "
4918 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4919 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4921 integerNormalize, integerMatch,
4922 integerIndexer, integerFilter,
4925 {"( 2.5.13.15 NAME 'integerOrderingMatch' "
4926 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4927 SLAP_MR_ORDERING, NULL, NULL,
4928 integerNormalize, integerOrderingMatch,
4929 integerIndexer, integerFilter,
4932 {"( 2.5.13.16 NAME 'bitStringMatch' "
4933 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.6 )",
4934 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4936 bitStringNormalize, bitStringMatch,
4937 bitStringIndexer, bitStringFilter,
4940 {"( 2.5.13.17 NAME 'octetStringMatch' "
4941 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
4942 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4944 octetStringMatch, octetStringIndexer, octetStringFilter,
4947 {"( 2.5.13.18 NAME 'octetStringOrderingMatch' "
4948 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
4949 SLAP_MR_ORDERING, NULL,
4951 octetStringOrderingMatch, NULL, NULL,
4954 {"( 2.5.13.19 NAME 'octetStringSubstringsMatch' "
4955 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
4956 SLAP_MR_SUBSTR, NULL,
4958 octetStringSubstringsMatch, NULL, NULL,
4961 {"( 2.5.13.20 NAME 'telephoneNumberMatch' "
4962 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 )",
4963 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL,
4965 telephoneNumberNormalize, telephoneNumberMatch,
4966 telephoneNumberIndexer, telephoneNumberFilter,
4969 {"( 2.5.13.21 NAME 'telephoneNumberSubstringsMatch' "
4970 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4971 SLAP_MR_SUBSTR, NULL,
4972 NULL, NULL, telephoneNumberSubstringsMatch,
4973 telephoneNumberSubstringsIndexer, telephoneNumberSubstringsFilter,
4976 {"( 2.5.13.22 NAME 'presentationAddressMatch' "
4977 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.43 )",
4978 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4983 {"( 2.5.13.23 NAME 'uniqueMemberMatch' "
4984 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.34 )",
4985 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4987 uniqueMemberNormalize, uniqueMemberMatch,
4991 {"( 2.5.13.24 NAME 'protocolInformationMatch' "
4992 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.42 )",
4993 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4994 NULL, NULL, NULL, NULL, NULL, NULL},
4996 {"( 2.5.13.27 NAME 'generalizedTimeMatch' "
4997 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
4998 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
5000 generalizedTimeNormalize, generalizedTimeMatch,
5004 {"( 2.5.13.28 NAME 'generalizedTimeOrderingMatch' "
5005 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
5006 SLAP_MR_ORDERING, NULL,
5008 generalizedTimeNormalize, generalizedTimeOrderingMatch,
5012 {"( 2.5.13.29 NAME 'integerFirstComponentMatch' "
5013 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
5014 SLAP_MR_EQUALITY | SLAP_MR_EXT, integerFirstComponentMatchSyntaxes,
5016 integerFirstComponentNormalize, integerMatch,
5020 {"( 2.5.13.30 NAME 'objectIdentifierFirstComponentMatch' "
5021 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
5022 SLAP_MR_EQUALITY | SLAP_MR_EXT,
5023 objectIdentifierFirstComponentMatchSyntaxes,
5025 objectIdentifierFirstComponentNormalize, objectIdentifierMatch,
5029 #ifndef SLAP_NVALUES
5031 {"( 2.5.13.34 NAME 'certificateExactMatch' "
5032 "SYNTAX 1.2.826.0.1.3344810.7.1 )",
5033 SLAP_MR_EQUALITY | SLAP_MR_EXT, certificateExactMatchSyntaxes,
5034 certificateExactConvert, NULL,
5035 certificateExactMatch,
5036 certificateExactIndexer, certificateExactFilter,
5041 {"( 1.3.6.1.4.1.1466.109.114.1 NAME 'caseExactIA5Match' "
5042 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
5043 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
5045 caseExactIA5Normalize, caseExactIA5Match,
5046 caseExactIA5Indexer, caseExactIA5Filter,
5047 IA5StringApproxMatchOID },
5049 {"( 1.3.6.1.4.1.1466.109.114.2 NAME 'caseIgnoreIA5Match' "
5050 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
5051 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL,
5053 NULL, caseIgnoreIA5Match,
5054 caseIgnoreIA5Indexer, caseIgnoreIA5Filter,
5055 IA5StringApproxMatchOID },
5057 {"( 1.3.6.1.4.1.1466.109.114.3 NAME 'caseIgnoreIA5SubstringsMatch' "
5058 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
5059 SLAP_MR_SUBSTR, NULL,
5061 NULL, caseIgnoreIA5SubstringsMatch,
5062 caseIgnoreIA5SubstringsIndexer, caseIgnoreIA5SubstringsFilter,
5065 {"( 1.3.6.1.4.1.4203.1.2.1 NAME 'caseExactIA5SubstringsMatch' "
5066 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
5067 SLAP_MR_SUBSTR, NULL,
5069 NULL, caseExactIA5SubstringsMatch,
5070 caseExactIA5SubstringsIndexer, caseExactIA5SubstringsFilter,
5073 #ifdef SLAPD_AUTHPASSWD
5074 /* needs updating */
5075 {"( 1.3.6.1.4.1.4203.666.4.1 NAME 'authPasswordMatch' "
5076 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
5077 SLAP_MR_EQUALITY, NULL,
5079 authPasswordMatch, NULL, NULL,
5083 #ifdef SLAPD_ACI_ENABLED
5084 {"( 1.3.6.1.4.1.4203.666.4.2 NAME 'OpenLDAPaciMatch' "
5085 "SYNTAX 1.3.6.1.4.1.4203.666.2.1 )",
5086 SLAP_MR_EQUALITY, NULL,
5088 OpenLDAPaciMatch, NULL, NULL,
5092 {"( 1.2.840.113556.1.4.803 NAME 'integerBitAndMatch' "
5093 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
5096 NULL, integerBitAndMatch, NULL, NULL,
5099 {"( 1.2.840.113556.1.4.804 NAME 'integerBitOrMatch' "
5100 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
5103 NULL, integerBitOrMatch, NULL, NULL,
5106 {NULL, SLAP_MR_NONE, NULL,
5107 NULL, NULL, NULL, NULL, NULL,
5112 slap_schema_init( void )
5117 /* we should only be called once (from main) */
5118 assert( schema_init_done == 0 );
5120 for ( i=0; syntax_defs[i].sd_desc != NULL; i++ ) {
5121 res = register_syntax( &syntax_defs[i] );
5124 fprintf( stderr, "slap_schema_init: Error registering syntax %s\n",
5125 syntax_defs[i].sd_desc );
5130 for ( i=0; mrule_defs[i].mrd_desc != NULL; i++ ) {
5131 if( mrule_defs[i].mrd_usage == SLAP_MR_NONE &&
5132 mrule_defs[i].mrd_compat_syntaxes == NULL )
5135 "slap_schema_init: Ignoring unusable matching rule %s\n",
5136 mrule_defs[i].mrd_desc );
5140 res = register_matching_rule( &mrule_defs[i] );
5144 "slap_schema_init: Error registering matching rule %s\n",
5145 mrule_defs[i].mrd_desc );
5150 res = slap_schema_load();
5151 schema_init_done = 1;
5156 schema_destroy( void )