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
46 /* (new) normalization routines */
47 #define caseExactIA5Normalize IA5StringNormalize
48 #define caseIgnoreIA5Normalize IA5StringNormalize
49 #define caseExactNormalize UTF8StringNormalize
50 #define caseIgnoreNormalize UTF8StringNormalize
52 #define distinguishedNameNormalize NULL
53 #define integerNormalize NULL
54 #define integerFirstComponentNormalize NULL
55 #define numericStringNormalize NULL
56 #define objectIdentifierNormalize NULL
57 #define objectIdentifierFirstComponentNormalize NULL
58 #define generalizedTimeNormalize NULL
59 #define uniqueMemberNormalize NULL
60 #define bitStringNormalize NULL
61 #define telephoneNumberNormalize NULL
63 #define 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 NULL
93 #define caseIgnoreSubstringsIndexer NULL
94 #define caseIgnoreSubstringsFilter NULL
96 #define caseExactMatch octetStringMatch
97 #define caseExactOrderingMatch octetStringOrderingMatch
98 #define caseExactIndexer octetStringIndexer
99 #define caseExactFilter octetStringFilter
101 #define caseExactSubstringsMatch NULL
102 #define caseExactSubstringsIndexer NULL
103 #define caseExactSubstringsFilter NULL
105 #define caseExactIA5Match octetStringMatch
106 #define caseExactIA5Indexer octetStringIndexer
107 #define caseExactIA5Filter octetStringFilter
109 #define caseExactIA5SubstringsMatch NULL
110 #define caseExactIA5SubstringsIndexer NULL
111 #define caseExactIA5SubstringsFilter NULL
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 /* (new) normalization routines */
160 #define caseExactNormalize NULL
161 #define caseExactIA5Normalize NULL
162 #define caseIgnoreNormalize NULL
163 #define caseIgnoreIA5Normalize NULL
164 #define distinguishedNameNormalize NULL
165 #define integerNormalize NULL
166 #define integerFirstComponentNormalize NULL
167 #define numericStringNormalize NULL
168 #define objectIdentifierNormalize NULL
169 #define objectIdentifierFirstComponentNormalize NULL
170 #define generalizedTimeNormalize NULL
171 #define uniqueMemberNormalize NULL
172 #define bitStringNormalize NULL
173 #define telephoneNumberNormalize NULL
176 /* matching routines */
177 #define bitStringMatch octetStringMatch
178 #define bitStringIndexer octetStringIndexer
179 #define bitStringFilter octetStringFilter
181 #define numericStringMatch caseIgnoreIA5Match
182 #define numericStringIndexer NULL
183 #define numericStringFilter NULL
184 #define numericStringSubstringsIndexer NULL
185 #define numericStringSubstringsFilter NULL
187 #define objectIdentifierMatch octetStringMatch
188 #define objectIdentifierIndexer caseIgnoreIA5Indexer
189 #define objectIdentifierFilter caseIgnoreIA5Filter
191 #define OpenLDAPaciMatch NULL
193 #define generalizedTimeMatch caseIgnoreIA5Match
194 #define generalizedTimeOrderingMatch caseIgnoreIA5Match
196 #define uniqueMemberMatch dnMatch
197 #define numericStringSubstringsMatch NULL
199 #define caseExactIndexer caseExactIgnoreIndexer
200 #define caseExactFilter caseExactIgnoreFilter
201 #define caseExactOrderingMatch caseExactMatch
202 #define caseExactSubstringsMatch caseExactIgnoreSubstringsMatch
203 #define caseExactSubstringsIndexer caseExactIgnoreSubstringsIndexer
204 #define caseExactSubstringsFilter caseExactIgnoreSubstringsFilter
205 #define caseIgnoreIndexer caseExactIgnoreIndexer
206 #define caseIgnoreFilter caseExactIgnoreFilter
207 #define caseIgnoreOrderingMatch caseIgnoreMatch
208 #define caseIgnoreSubstringsMatch caseExactIgnoreSubstringsMatch
209 #define caseIgnoreSubstringsIndexer caseExactIgnoreSubstringsIndexer
210 #define caseIgnoreSubstringsFilter caseExactIgnoreSubstringsFilter
212 #define integerOrderingMatch integerMatch
213 #define integerFirstComponentMatch integerMatch
215 #define distinguishedNameMatch dnMatch
216 #define distinguishedNameIndexer caseExactIgnoreIndexer
217 #define distinguishedNameFilter caseExactIgnoreFilter
219 #define telephoneNumberMatch caseIgnoreIA5Match
220 #define telephoneNumberSubstringsMatch caseIgnoreIA5SubstringsMatch
221 #define telephoneNumberIndexer caseIgnoreIA5Indexer
222 #define telephoneNumberFilter caseIgnoreIA5Filter
223 #define telephoneNumberSubstringsIndexer caseIgnoreIA5SubstringsIndexer
224 #define telephoneNumberSubstringsFilter caseIgnoreIA5SubstringsFilter
228 static char *bvcasechr( struct berval *bv, unsigned char c, ber_len_t *len )
231 char lower = TOLOWER( c );
232 char upper = TOUPPER( c );
234 if( c == 0 ) return NULL;
236 for( i=0; i < bv->bv_len; i++ ) {
237 if( upper == bv->bv_val[i] || lower == bv->bv_val[i] ) {
239 return &bv->bv_val[i];
252 struct berval *value,
253 void *assertedValue )
255 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
258 match = memcmp( value->bv_val,
259 ((struct berval *) assertedValue)->bv_val,
268 octetStringOrderingMatch(
273 struct berval *value,
274 void *assertedValue )
276 ber_len_t v_len = value->bv_len;
277 ber_len_t av_len = ((struct berval *) assertedValue)->bv_len;
279 int match = memcmp( value->bv_val,
280 ((struct berval *) assertedValue)->bv_val,
281 (v_len < av_len ? v_len : av_len) );
283 if( match == 0 ) match = v_len - av_len;
289 /* Index generation function */
290 int octetStringIndexer(
295 struct berval *prefix,
302 HASH_CONTEXT HASHcontext;
303 unsigned char HASHdigest[HASH_BYTES];
304 struct berval digest;
305 digest.bv_val = HASHdigest;
306 digest.bv_len = sizeof(HASHdigest);
308 for( i=0; values[i].bv_val != NULL; i++ ) {
309 /* just count them */
312 /* we should have at least one value at this point */
315 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
317 slen = syntax->ssyn_oidlen;
318 mlen = mr->smr_oidlen;
320 for( i=0; values[i].bv_val != NULL; i++ ) {
321 HASH_Init( &HASHcontext );
322 if( prefix != NULL && prefix->bv_len > 0 ) {
323 HASH_Update( &HASHcontext,
324 prefix->bv_val, prefix->bv_len );
326 HASH_Update( &HASHcontext,
327 syntax->ssyn_oid, slen );
328 HASH_Update( &HASHcontext,
330 HASH_Update( &HASHcontext,
331 values[i].bv_val, values[i].bv_len );
332 HASH_Final( HASHdigest, &HASHcontext );
334 ber_dupbv( &keys[i], &digest );
337 keys[i].bv_val = NULL;
345 /* Index generation function */
346 int octetStringFilter(
351 struct berval *prefix,
352 void * assertedValue,
357 HASH_CONTEXT HASHcontext;
358 unsigned char HASHdigest[HASH_BYTES];
359 struct berval *value = (struct berval *) assertedValue;
360 struct berval digest;
361 digest.bv_val = HASHdigest;
362 digest.bv_len = sizeof(HASHdigest);
364 slen = syntax->ssyn_oidlen;
365 mlen = mr->smr_oidlen;
367 keys = ch_malloc( sizeof( struct berval ) * 2 );
369 HASH_Init( &HASHcontext );
370 if( prefix != NULL && prefix->bv_len > 0 ) {
371 HASH_Update( &HASHcontext,
372 prefix->bv_val, prefix->bv_len );
374 HASH_Update( &HASHcontext,
375 syntax->ssyn_oid, slen );
376 HASH_Update( &HASHcontext,
378 HASH_Update( &HASHcontext,
379 value->bv_val, value->bv_len );
380 HASH_Final( HASHdigest, &HASHcontext );
382 ber_dupbv( keys, &digest );
383 keys[1].bv_val = NULL;
396 /* no value allowed */
397 return LDAP_INVALID_SYNTAX;
405 /* any value allowed */
416 /* very unforgiving validation, requires no normalization
417 * before simplistic matching
419 if( in->bv_len < 3 ) {
420 return LDAP_INVALID_SYNTAX;
424 * rfc 2252 section 6.3 Bit String
425 * bitstring = "'" *binary-digit "'"
426 * binary-digit = "0" / "1"
427 * example: '0101111101'B
430 if( in->bv_val[0] != '\'' ||
431 in->bv_val[in->bv_len-2] != '\'' ||
432 in->bv_val[in->bv_len-1] != 'B' )
434 return LDAP_INVALID_SYNTAX;
437 for( i=in->bv_len-3; i>0; i-- ) {
438 if( in->bv_val[i] != '0' && in->bv_val[i] != '1' ) {
439 return LDAP_INVALID_SYNTAX;
454 if( in->bv_len == 0 ) return LDAP_SUCCESS;
456 ber_dupbv( &dn, in );
457 if( !dn.bv_val ) return LDAP_OTHER;
459 if( dn.bv_val[dn.bv_len-1] == 'B'
460 && dn.bv_val[dn.bv_len-2] == '\'' )
462 /* assume presence of optional UID */
465 for(i=dn.bv_len-3; i>1; i--) {
466 if( dn.bv_val[i] != '0' && dn.bv_val[i] != '1' ) {
470 if( dn.bv_val[i] != '\'' || dn.bv_val[i-1] != '#' ) {
471 ber_memfree( dn.bv_val );
472 return LDAP_INVALID_SYNTAX;
475 /* trim the UID to allow use of dnValidate */
476 dn.bv_val[i-1] = '\0';
480 rc = dnValidate( NULL, &dn );
482 ber_memfree( dn.bv_val );
492 struct berval *normalized )
497 ber_dupbv( &out, val );
498 if( out.bv_len != 0 ) {
499 struct berval uid = { 0, NULL };
501 if( out.bv_val[out.bv_len-1] == 'B'
502 && out.bv_val[out.bv_len-2] == '\'' )
504 /* assume presence of optional UID */
505 uid.bv_val = strrchr( out.bv_val, '#' );
507 if( uid.bv_val == NULL ) {
509 return LDAP_INVALID_SYNTAX;
512 uid.bv_len = out.bv_len - (uid.bv_val - out.bv_val);
513 out.bv_len -= uid.bv_len--;
515 /* temporarily trim the UID */
516 *(uid.bv_val++) = '\0';
519 rc = dnNormalize2( NULL, &out, normalized );
521 if( rc != LDAP_SUCCESS ) {
523 return LDAP_INVALID_SYNTAX;
527 normalized->bv_val = ch_realloc( normalized->bv_val,
528 normalized->bv_len + uid.bv_len + sizeof("#") );
530 /* insert the separator */
531 normalized->bv_val[normalized->bv_len++] = '#';
534 AC_MEMCPY( &normalized->bv_val[normalized->bv_len],
535 uid.bv_val, uid.bv_len );
536 normalized->bv_len += uid.bv_len;
539 normalized->bv_val[normalized->bv_len] = '\0';
550 * Handling boolean syntax and matching is quite rigid.
551 * A more flexible approach would be to allow a variety
552 * of strings to be normalized and prettied into TRUE
560 /* very unforgiving validation, requires no normalization
561 * before simplistic matching
564 if( in->bv_len == 4 ) {
565 if( !memcmp( in->bv_val, "TRUE", 4 ) ) {
568 } else if( in->bv_len == 5 ) {
569 if( !memcmp( in->bv_val, "FALSE", 5 ) ) {
574 return LDAP_INVALID_SYNTAX;
583 struct berval *value,
584 void *assertedValue )
586 /* simplistic matching allowed by rigid validation */
587 struct berval *asserted = (struct berval *) assertedValue;
588 *matchp = value->bv_len != asserted->bv_len;
592 /*-------------------------------------------------------------------
593 LDAP/X.500 string syntax / matching rules have a few oddities. This
594 comment attempts to detail how slapd(8) treats them.
597 StringSyntax X.500 LDAP Matching/Comments
598 DirectoryString CHOICE UTF8 i/e + ignore insignificant spaces
599 PrintableString subset subset i/e + ignore insignificant spaces
600 PrintableString subset subset i/e + ignore insignificant spaces
601 NumericString subset subset ignore all spaces
602 IA5String ASCII ASCII i/e + ignore insignificant spaces
603 TeletexString T.61 T.61 i/e + ignore insignificant spaces
605 TelephoneNumber subset subset i + ignore all spaces and "-"
607 See draft-ietf-ldapbis-strpro for details (once published).
611 In X.500(93), a directory string can be either a PrintableString,
612 a bmpString, or a UniversalString (e.g., UCS (a subset of Unicode)).
613 In later versions, more CHOICEs were added. In all cases the string
616 In LDAPv3, a directory string is a UTF-8 encoded UCS string.
617 A directory string cannot be zero length.
619 For matching, there are both case ignore and exact rules. Both
620 also require that "insignificant" spaces be ignored.
621 spaces before the first non-space are ignored;
622 spaces after the last non-space are ignored;
623 spaces after a space are ignored.
624 Note: by these rules (and as clarified in X.520), a string of only
625 spaces is to be treated as if held one space, not empty (which
626 would be a syntax error).
629 In ASN.1, numeric string is just a string of digits and spaces
630 and could be empty. However, in X.500, all attribute values of
631 numeric string carry a non-empty constraint. For example:
633 internationalISDNNumber ATTRIBUTE ::= {
634 WITH SYNTAX InternationalISDNNumber
635 EQUALITY MATCHING RULE numericStringMatch
636 SUBSTRINGS MATCHING RULE numericStringSubstringsMatch
637 ID id-at-internationalISDNNumber }
638 InternationalISDNNumber ::=
639 NumericString (SIZE(1..ub-international-isdn-number))
641 Unforunately, some assertion values are don't carry the same
642 constraint (but its unclear how such an assertion could ever
643 be true). In LDAP, there is one syntax (numericString) not two
644 (numericString with constraint, numericString without constraint).
645 This should be treated as numericString with non-empty constraint.
646 Note that while someone may have no ISDN number, there are no ISDN
647 numbers which are zero length.
649 In matching, spaces are ignored.
652 In ASN.1, Printable string is just a string of printable characters
653 and can be empty. In X.500, semantics much like NumericString (see
654 serialNumber for a like example) excepting uses insignificant space
655 handling instead of ignore all spaces.
658 Basically same as PrintableString. There are no examples in X.500,
659 but same logic applies. So we require them to be non-empty as
662 -------------------------------------------------------------------*/
671 unsigned char *u = in->bv_val;
673 if( in->bv_len == 0 && syntax == slap_schema.si_syn_directoryString ) {
674 /* directory strings cannot be empty */
675 return LDAP_INVALID_SYNTAX;
678 for( count = in->bv_len; count > 0; count-=len, u+=len ) {
679 /* get the length indicated by the first byte */
680 len = LDAP_UTF8_CHARLEN2( u, len );
682 /* very basic checks */
685 if( (u[5] & 0xC0) != 0x80 ) {
686 return LDAP_INVALID_SYNTAX;
689 if( (u[4] & 0xC0) != 0x80 ) {
690 return LDAP_INVALID_SYNTAX;
693 if( (u[3] & 0xC0) != 0x80 ) {
694 return LDAP_INVALID_SYNTAX;
697 if( (u[2] & 0xC0 )!= 0x80 ) {
698 return LDAP_INVALID_SYNTAX;
701 if( (u[1] & 0xC0) != 0x80 ) {
702 return LDAP_INVALID_SYNTAX;
705 /* CHARLEN already validated it */
708 return LDAP_INVALID_SYNTAX;
711 /* make sure len corresponds with the offset
712 to the next character */
713 if( LDAP_UTF8_OFFSET( u ) != len ) return LDAP_INVALID_SYNTAX;
717 return LDAP_INVALID_SYNTAX;
730 struct berval *normalized )
732 struct berval tmp, nvalue;
736 if( val->bv_val == NULL ) {
737 /* assume we're dealing with a syntax (e.g., UTF8String)
738 * which allows empty strings
740 normalized->bv_len = 0;
741 normalized->bv_val = NULL;
745 flags = SLAP_MR_ASSOCIATED(mr, slap_schema.si_mr_caseExactMatch )
746 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
747 flags |= ( use & SLAP_MR_EQUALITY_APPROX == SLAP_MR_EQUALITY_APPROX )
748 ? LDAP_UTF8_APPROX : 0;
750 val = UTF8bvnormalize( val, &tmp, flags );
755 /* collapse spaces (in place) */
757 nvalue.bv_val = tmp.bv_val;
759 wasspace=1; /* trim leading spaces */
760 for( i=0; i<tmp.bv_len; i++) {
761 if ( ASCII_SPACE( tmp.bv_val[i] )) {
762 if( wasspace++ == 0 ) {
763 /* trim repeated spaces */
764 nvalue.bv_val[nvalue.bv_len++] = tmp.bv_val[i];
768 nvalue.bv_val[nvalue.bv_len++] = tmp.bv_val[i];
772 if( nvalue.bv_len ) {
774 /* last character was a space, trim it */
777 nvalue.bv_val[nvalue.bv_len] = '\0';
780 /* string of all spaces is treated as one space */
781 nvalue.bv_val[0] = ' ';
782 nvalue.bv_val[1] = '\0';
791 xUTF8StringNormalize(
794 struct berval *normalized )
799 /* validator should have refused an empty string */
800 assert( val->bv_len );
804 /* Ignore initial whitespace */
805 /* All space is ASCII. All ASCII is 1 byte */
806 for ( ; p < val->bv_val + val->bv_len && ASCII_SPACE( p[ 0 ] ); p++ );
808 normalized->bv_len = val->bv_len - (p - val->bv_val);
810 if( !normalized->bv_len ) {
811 ber_mem2bv( " ", 1, 1, normalized );
815 ber_mem2bv( p, normalized->bv_len, 1, normalized );
816 e = normalized->bv_val + normalized->bv_len;
818 assert( normalized->bv_val );
820 p = q = normalized->bv_val;
825 if ( ASCII_SPACE( *p ) ) {
830 /* Ignore the extra whitespace */
831 while ( ASCII_SPACE( *p ) ) {
835 len = LDAP_UTF8_COPY(q,p);
841 assert( normalized->bv_val <= p );
842 assert( q+len <= p );
844 /* cannot start with a space */
845 assert( !ASCII_SPACE( normalized->bv_val[0] ) );
848 * If the string ended in space, backup the pointer one
849 * position. One is enough because the above loop collapsed
850 * all whitespace to a single space.
858 /* cannot end with a space */
859 assert( !ASCII_SPACE( *q ) );
866 normalized->bv_len = q - normalized->bv_val;
871 /* Returns Unicode canonically normalized copy of a substring assertion
872 * Skipping attribute description */
873 static SubstringsAssertion *
874 UTF8SubstringsAssertionNormalize(
875 SubstringsAssertion *sa,
878 SubstringsAssertion *nsa;
881 nsa = (SubstringsAssertion *)SLAP_CALLOC( 1, sizeof(SubstringsAssertion) );
886 if( sa->sa_initial.bv_val != NULL ) {
887 UTF8bvnormalize( &sa->sa_initial, &nsa->sa_initial, casefold );
888 if( nsa->sa_initial.bv_val == NULL ) {
893 if( sa->sa_any != NULL ) {
894 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
897 nsa->sa_any = (struct berval *)
898 SLAP_MALLOC( (i + 1) * sizeof(struct berval) );
899 if( nsa->sa_any == NULL ) {
903 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
904 UTF8bvnormalize( &sa->sa_any[i], &nsa->sa_any[i],
906 if( nsa->sa_any[i].bv_val == NULL ) {
910 nsa->sa_any[i].bv_val = NULL;
913 if( sa->sa_final.bv_val != NULL ) {
914 UTF8bvnormalize( &sa->sa_final, &nsa->sa_final, casefold );
915 if( nsa->sa_final.bv_val == NULL ) {
923 if ( nsa->sa_final.bv_val ) free( nsa->sa_final.bv_val );
924 if ( nsa->sa_any ) ber_bvarray_free( nsa->sa_any );
925 if ( nsa->sa_initial.bv_val ) free( nsa->sa_initial.bv_val );
930 #ifndef SLAPD_APPROX_OLDSINGLESTRING
932 #if defined(SLAPD_APPROX_INITIALS)
933 #define SLAPD_APPROX_DELIMITER "._ "
934 #define SLAPD_APPROX_WORDLEN 2
936 #define SLAPD_APPROX_DELIMITER " "
937 #define SLAPD_APPROX_WORDLEN 1
946 struct berval *value,
947 void *assertedValue )
949 struct berval *nval, *assertv;
950 char *val, **values, **words, *c;
951 int i, count, len, nextchunk=0, nextavail=0;
953 /* Yes, this is necessary */
954 nval = UTF8bvnormalize( value, NULL, LDAP_UTF8_APPROX );
960 /* Yes, this is necessary */
961 assertv = UTF8bvnormalize( ((struct berval *)assertedValue),
962 NULL, LDAP_UTF8_APPROX );
963 if( assertv == NULL ) {
969 /* Isolate how many words there are */
970 for ( c = nval->bv_val, count = 1; *c; c++ ) {
971 c = strpbrk( c, SLAPD_APPROX_DELIMITER );
972 if ( c == NULL ) break;
977 /* Get a phonetic copy of each word */
978 words = (char **)ch_malloc( count * sizeof(char *) );
979 values = (char **)ch_malloc( count * sizeof(char *) );
980 for ( c = nval->bv_val, i = 0; i < count; i++, c += strlen(c) + 1 ) {
982 values[i] = phonetic(c);
985 /* Work through the asserted value's words, to see if at least some
986 of the words are there, in the same order. */
988 while ( (ber_len_t) nextchunk < assertv->bv_len ) {
989 len = strcspn( assertv->bv_val + nextchunk, SLAPD_APPROX_DELIMITER);
994 #if defined(SLAPD_APPROX_INITIALS)
995 else if( len == 1 ) {
996 /* Single letter words need to at least match one word's initial */
997 for( i=nextavail; i<count; i++ )
998 if( !strncasecmp( assertv->bv_val + nextchunk, words[i], 1 )) {
1005 /* Isolate the next word in the asserted value and phonetic it */
1006 assertv->bv_val[nextchunk+len] = '\0';
1007 val = phonetic( assertv->bv_val + nextchunk );
1009 /* See if this phonetic chunk is in the remaining words of *value */
1010 for( i=nextavail; i<count; i++ ){
1011 if( !strcmp( val, values[i] ) ){
1019 /* This chunk in the asserted value was NOT within the *value. */
1025 /* Go on to the next word in the asserted value */
1029 /* If some of the words were seen, call it a match */
1030 if( nextavail > 0 ) {
1037 /* Cleanup allocs */
1038 ber_bvfree( assertv );
1039 for( i=0; i<count; i++ ) {
1040 ch_free( values[i] );
1046 return LDAP_SUCCESS;
1055 struct berval *prefix,
1060 int i,j, len, wordcount, keycount=0;
1061 struct berval *newkeys;
1062 BerVarray keys=NULL;
1064 for( j=0; values[j].bv_val != NULL; j++ ) {
1065 struct berval val = { 0, NULL };
1066 /* Yes, this is necessary */
1067 UTF8bvnormalize( &values[j], &val, LDAP_UTF8_APPROX );
1068 assert( val.bv_val != NULL );
1070 /* Isolate how many words there are. There will be a key for each */
1071 for( wordcount = 0, c = val.bv_val; *c; c++) {
1072 len = strcspn(c, SLAPD_APPROX_DELIMITER);
1073 if( len >= SLAPD_APPROX_WORDLEN ) wordcount++;
1075 if (*c == '\0') break;
1079 /* Allocate/increase storage to account for new keys */
1080 newkeys = (struct berval *)ch_malloc( (keycount + wordcount + 1)
1081 * sizeof(struct berval) );
1082 AC_MEMCPY( newkeys, keys, keycount * sizeof(struct berval) );
1083 if( keys ) ch_free( keys );
1086 /* Get a phonetic copy of each word */
1087 for( c = val.bv_val, i = 0; i < wordcount; c += len + 1 ) {
1089 if( len < SLAPD_APPROX_WORDLEN ) continue;
1090 ber_str2bv( phonetic( c ), 0, 0, &keys[keycount] );
1095 ber_memfree( val.bv_val );
1097 keys[keycount].bv_val = NULL;
1100 return LDAP_SUCCESS;
1109 struct berval *prefix,
1110 void * assertedValue,
1118 /* Yes, this is necessary */
1119 val = UTF8bvnormalize( ((struct berval *)assertedValue),
1120 NULL, LDAP_UTF8_APPROX );
1121 if( val == NULL || val->bv_val == NULL ) {
1122 keys = (struct berval *)ch_malloc( sizeof(struct berval) );
1123 keys[0].bv_val = NULL;
1126 return LDAP_SUCCESS;
1129 /* Isolate how many words there are. There will be a key for each */
1130 for( count = 0,c = val->bv_val; *c; c++) {
1131 len = strcspn(c, SLAPD_APPROX_DELIMITER);
1132 if( len >= SLAPD_APPROX_WORDLEN ) count++;
1134 if (*c == '\0') break;
1138 /* Allocate storage for new keys */
1139 keys = (struct berval *)ch_malloc( (count + 1) * sizeof(struct berval) );
1141 /* Get a phonetic copy of each word */
1142 for( c = val->bv_val, i = 0; i < count; c += len + 1 ) {
1144 if( len < SLAPD_APPROX_WORDLEN ) continue;
1145 ber_str2bv( phonetic( c ), 0, 0, &keys[i] );
1151 keys[count].bv_val = NULL;
1154 return LDAP_SUCCESS;
1159 /* No other form of Approximate Matching is defined */
1167 struct berval *value,
1168 void *assertedValue )
1170 char *vapprox, *avapprox;
1173 /* Yes, this is necessary */
1174 s = UTF8normalize( value, UTF8_NOCASEFOLD );
1177 return LDAP_SUCCESS;
1180 /* Yes, this is necessary */
1181 t = UTF8normalize( ((struct berval *)assertedValue),
1186 return LDAP_SUCCESS;
1189 vapprox = phonetic( strip8bitChars( s ) );
1190 avapprox = phonetic( strip8bitChars( t ) );
1195 *matchp = strcmp( vapprox, avapprox );
1198 ch_free( avapprox );
1200 return LDAP_SUCCESS;
1209 struct berval *prefix,
1217 for( i=0; values[i].bv_val != NULL; i++ ) {
1218 /* empty - just count them */
1221 /* we should have at least one value at this point */
1224 keys = (struct berval *)ch_malloc( sizeof( struct berval ) * (i+1) );
1226 /* Copy each value and run it through phonetic() */
1227 for( i=0; values[i].bv_val != NULL; i++ ) {
1228 /* Yes, this is necessary */
1229 s = UTF8normalize( &values[i], UTF8_NOCASEFOLD );
1231 /* strip 8-bit chars and run through phonetic() */
1232 ber_str2bv( phonetic( strip8bitChars( s ) ), 0, 0, &keys[i] );
1235 keys[i].bv_val = NULL;
1238 return LDAP_SUCCESS;
1248 struct berval *prefix,
1249 void * assertedValue,
1255 keys = (struct berval *)ch_malloc( sizeof( struct berval * ) * 2 );
1257 /* Yes, this is necessary */
1258 s = UTF8normalize( ((struct berval *)assertedValue),
1263 /* strip 8-bit chars and run through phonetic() */
1264 keys[0] = ber_bvstr( phonetic( strip8bitChars( s ) ) );
1270 return LDAP_SUCCESS;
1281 struct berval *value,
1282 void *assertedValue )
1284 *matchp = UTF8bvnormcmp( value,
1285 (struct berval *) assertedValue,
1286 LDAP_UTF8_NOCASEFOLD );
1287 return LDAP_SUCCESS;
1291 caseExactIgnoreSubstringsMatch(
1296 struct berval *value,
1297 void *assertedValue )
1300 SubstringsAssertion *sub = NULL;
1301 struct berval left = { 0, NULL };
1307 casefold = ( mr != slap_schema.si_mr_caseExactSubstringsMatch )
1308 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1310 if ( UTF8bvnormalize( value, &left, casefold ) == NULL ) {
1316 sub = UTF8SubstringsAssertionNormalize( assertedValue, casefold );
1322 /* Add up asserted input length */
1323 if( sub->sa_initial.bv_val ) {
1324 inlen += sub->sa_initial.bv_len;
1327 for(i=0; sub->sa_any[i].bv_val != NULL; i++) {
1328 inlen += sub->sa_any[i].bv_len;
1331 if( sub->sa_final.bv_val ) {
1332 inlen += sub->sa_final.bv_len;
1335 if( sub->sa_initial.bv_val ) {
1336 if( inlen > left.bv_len ) {
1341 match = memcmp( sub->sa_initial.bv_val, left.bv_val,
1342 sub->sa_initial.bv_len );
1348 left.bv_val += sub->sa_initial.bv_len;
1349 left.bv_len -= sub->sa_initial.bv_len;
1350 inlen -= sub->sa_initial.bv_len;
1353 if( sub->sa_final.bv_val ) {
1354 if( inlen > left.bv_len ) {
1359 match = memcmp( sub->sa_final.bv_val,
1360 &left.bv_val[left.bv_len - sub->sa_final.bv_len],
1361 sub->sa_final.bv_len );
1367 left.bv_len -= sub->sa_final.bv_len;
1368 inlen -= sub->sa_final.bv_len;
1372 for(i=0; sub->sa_any[i].bv_val; i++) {
1377 if( inlen > left.bv_len ) {
1378 /* not enough length */
1383 if( sub->sa_any[i].bv_len == 0 ) {
1387 p = ber_bvchr( &left, *sub->sa_any[i].bv_val );
1393 idx = p - left.bv_val;
1395 if( idx >= left.bv_len ) {
1396 /* this shouldn't happen */
1398 if ( sub->sa_final.bv_val )
1399 ch_free( sub->sa_final.bv_val );
1401 ber_bvarray_free( sub->sa_any );
1402 if ( sub->sa_initial.bv_val )
1403 ch_free( sub->sa_initial.bv_val );
1411 if( sub->sa_any[i].bv_len > left.bv_len ) {
1412 /* not enough left */
1417 match = memcmp( left.bv_val,
1418 sub->sa_any[i].bv_val,
1419 sub->sa_any[i].bv_len );
1427 left.bv_val += sub->sa_any[i].bv_len;
1428 left.bv_len -= sub->sa_any[i].bv_len;
1429 inlen -= sub->sa_any[i].bv_len;
1436 if ( sub->sa_final.bv_val ) free( sub->sa_final.bv_val );
1437 if ( sub->sa_any ) ber_bvarray_free( sub->sa_any );
1438 if ( sub->sa_initial.bv_val ) free( sub->sa_initial.bv_val );
1442 return LDAP_SUCCESS;
1445 /* Index generation function */
1446 static int caseExactIgnoreIndexer(
1451 struct berval *prefix,
1456 unsigned casefold,wasspace;
1459 HASH_CONTEXT HASHcontext;
1460 unsigned char HASHdigest[HASH_BYTES];
1461 struct berval digest;
1462 digest.bv_val = HASHdigest;
1463 digest.bv_len = sizeof(HASHdigest);
1465 for( i=0; values[i].bv_val != NULL; i++ ) {
1466 /* empty - just count them */
1469 /* we should have at least one value at this point */
1472 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
1474 slen = syntax->ssyn_oidlen;
1475 mlen = mr->smr_oidlen;
1477 casefold = ( mr != slap_schema.si_mr_caseExactMatch )
1478 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1480 for( i=0; values[i].bv_val != NULL; i++ ) {
1481 struct berval value, nvalue;
1482 UTF8bvnormalize( &values[i], &value, casefold );
1484 /* collapse spaces (in place) */
1486 nvalue.bv_val = value.bv_val;
1489 for( j=0; j<value.bv_len; j++) {
1490 if ( ASCII_SPACE( value.bv_val[j] )) {
1491 if( wasspace++ == 0 ) {
1492 nvalue.bv_val[nvalue.bv_len++] = value.bv_val[j];
1496 nvalue.bv_val[nvalue.bv_len++] = value.bv_val[j];
1500 if( nvalue.bv_len == 0 ) {
1501 nvalue.bv_val = " ";
1502 nvalue.bv_len = sizeof(" ")-1;
1504 if( wasspace ) --nvalue.bv_len;
1505 nvalue.bv_val[nvalue.bv_len] = '\0';
1508 HASH_Init( &HASHcontext );
1509 if( prefix != NULL && prefix->bv_len > 0 ) {
1510 HASH_Update( &HASHcontext,
1511 prefix->bv_val, prefix->bv_len );
1513 HASH_Update( &HASHcontext,
1514 syntax->ssyn_oid, slen );
1515 HASH_Update( &HASHcontext,
1516 mr->smr_oid, mlen );
1517 HASH_Update( &HASHcontext,
1518 nvalue.bv_val, nvalue.bv_len );
1519 HASH_Final( HASHdigest, &HASHcontext );
1521 free( value.bv_val );
1522 ber_dupbv( &keys[i], &digest );
1525 keys[i].bv_val = NULL;
1527 return LDAP_SUCCESS;
1530 /* Index generation function */
1531 static int caseExactIgnoreFilter(
1536 struct berval *prefix,
1537 void * assertedValue,
1543 HASH_CONTEXT HASHcontext;
1544 unsigned char HASHdigest[HASH_BYTES];
1545 struct berval value = { 0, NULL };
1546 struct berval digest;
1548 digest.bv_val = HASHdigest;
1549 digest.bv_len = sizeof(HASHdigest);
1551 slen = syntax->ssyn_oidlen;
1552 mlen = mr->smr_oidlen;
1554 casefold = ( mr != slap_schema.si_mr_caseExactMatch )
1555 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1557 UTF8bvnormalize( (struct berval *) assertedValue, &value, casefold );
1558 /* This usually happens if filter contains bad UTF8 */
1559 if( value.bv_val == NULL ) {
1560 keys = ch_malloc( sizeof( struct berval ) );
1561 keys[0].bv_val = NULL;
1562 return LDAP_SUCCESS;
1565 keys = ch_malloc( sizeof( struct berval ) * 2 );
1567 HASH_Init( &HASHcontext );
1568 if( prefix != NULL && prefix->bv_len > 0 ) {
1569 HASH_Update( &HASHcontext,
1570 prefix->bv_val, prefix->bv_len );
1572 HASH_Update( &HASHcontext,
1573 syntax->ssyn_oid, slen );
1574 HASH_Update( &HASHcontext,
1575 mr->smr_oid, mlen );
1576 HASH_Update( &HASHcontext,
1577 value.bv_val, value.bv_len );
1578 HASH_Final( HASHdigest, &HASHcontext );
1580 ber_dupbv( keys, &digest );
1581 keys[1].bv_val = NULL;
1583 free( value.bv_val );
1586 return LDAP_SUCCESS;
1589 /* Substrings Index generation function */
1590 static int caseExactIgnoreSubstringsIndexer(
1595 struct berval *prefix,
1599 unsigned casefold, wasspace;
1600 ber_len_t i, j, nkeys;
1603 BerVarray tvalues, nvalues;
1605 HASH_CONTEXT HASHcontext;
1606 unsigned char HASHdigest[HASH_BYTES];
1607 struct berval digest;
1608 digest.bv_val = HASHdigest;
1609 digest.bv_len = sizeof(HASHdigest);
1613 for( i=0; values[i].bv_val != NULL; i++ ) {
1614 /* empty - just count them */
1617 /* we should have at least one value at this point */
1620 casefold = ( mr != slap_schema.si_mr_caseExactSubstringsMatch )
1621 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1623 tvalues = ch_malloc( sizeof( struct berval ) * (i+1) );
1624 nvalues = ch_malloc( sizeof( struct berval ) * (i+1) );
1626 for( i=0; values[i].bv_val != NULL; i++ ) {
1627 UTF8bvnormalize( &values[i], &tvalues[i], casefold );
1629 /* collapse spaces (in place) */
1630 nvalues[i].bv_len = 0;
1631 nvalues[i].bv_val = tvalues[i].bv_val;
1634 for( j=0; j<tvalues[i].bv_len; j++) {
1635 if ( ASCII_SPACE( tvalues[i].bv_val[j] )) {
1636 if( wasspace++ == 0 ) {
1637 nvalues[i].bv_val[nvalues[i].bv_len++] =
1638 tvalues[i].bv_val[j];
1642 nvalues[i].bv_val[nvalues[i].bv_len++] = tvalues[i].bv_val[j];
1646 if( nvalues[i].bv_len == 0 ) {
1647 nvalues[i].bv_val = " ";
1648 nvalues[i].bv_len = sizeof(" ")-1;
1650 if( wasspace ) --nvalues[i].bv_len;
1651 nvalues[i].bv_val[nvalues[i].bv_len] = '\0';
1655 tvalues[i].bv_val = NULL;
1656 nvalues[i].bv_val = NULL;
1659 for( i=0; values[i].bv_val != NULL; i++ ) {
1660 /* count number of indices to generate */
1661 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
1665 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
1666 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1667 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
1668 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
1670 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
1674 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
1675 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1676 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
1680 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
1681 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1682 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
1683 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
1685 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
1691 /* no keys to generate */
1693 ber_bvarray_free( tvalues );
1695 return LDAP_SUCCESS;
1698 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
1700 slen = syntax->ssyn_oidlen;
1701 mlen = mr->smr_oidlen;
1704 for( i=0; values[i].bv_val != NULL; i++ ) {
1707 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
1709 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
1710 ( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
1712 char pre = SLAP_INDEX_SUBSTR_PREFIX;
1713 max = values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
1715 for( j=0; j<max; j++ ) {
1716 HASH_Init( &HASHcontext );
1717 if( prefix != NULL && prefix->bv_len > 0 ) {
1718 HASH_Update( &HASHcontext,
1719 prefix->bv_val, prefix->bv_len );
1722 HASH_Update( &HASHcontext,
1723 &pre, sizeof( pre ) );
1724 HASH_Update( &HASHcontext,
1725 syntax->ssyn_oid, slen );
1726 HASH_Update( &HASHcontext,
1727 mr->smr_oid, mlen );
1728 HASH_Update( &HASHcontext,
1729 &values[i].bv_val[j],
1730 SLAP_INDEX_SUBSTR_MAXLEN );
1731 HASH_Final( HASHdigest, &HASHcontext );
1733 ber_dupbv( &keys[nkeys++], &digest );
1737 max = SLAP_INDEX_SUBSTR_MAXLEN < values[i].bv_len
1738 ? SLAP_INDEX_SUBSTR_MAXLEN : values[i].bv_len;
1740 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
1743 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
1744 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
1745 HASH_Init( &HASHcontext );
1746 if( prefix != NULL && prefix->bv_len > 0 ) {
1747 HASH_Update( &HASHcontext,
1748 prefix->bv_val, prefix->bv_len );
1750 HASH_Update( &HASHcontext,
1751 &pre, sizeof( pre ) );
1752 HASH_Update( &HASHcontext,
1753 syntax->ssyn_oid, slen );
1754 HASH_Update( &HASHcontext,
1755 mr->smr_oid, mlen );
1756 HASH_Update( &HASHcontext,
1757 values[i].bv_val, j );
1758 HASH_Final( HASHdigest, &HASHcontext );
1760 ber_dupbv( &keys[nkeys++], &digest );
1763 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
1764 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
1765 HASH_Init( &HASHcontext );
1766 if( prefix != NULL && prefix->bv_len > 0 ) {
1767 HASH_Update( &HASHcontext,
1768 prefix->bv_val, prefix->bv_len );
1770 HASH_Update( &HASHcontext,
1771 &pre, sizeof( pre ) );
1772 HASH_Update( &HASHcontext,
1773 syntax->ssyn_oid, slen );
1774 HASH_Update( &HASHcontext,
1775 mr->smr_oid, mlen );
1776 HASH_Update( &HASHcontext,
1777 &values[i].bv_val[values[i].bv_len-j], j );
1778 HASH_Final( HASHdigest, &HASHcontext );
1780 ber_dupbv( &keys[nkeys++], &digest );
1788 keys[nkeys].bv_val = NULL;
1795 ber_bvarray_free( tvalues );
1798 return LDAP_SUCCESS;
1801 static int caseExactIgnoreSubstringsFilter(
1806 struct berval *prefix,
1807 void * assertedValue,
1810 SubstringsAssertion *sa;
1813 ber_len_t nkeys = 0;
1814 size_t slen, mlen, klen;
1816 HASH_CONTEXT HASHcontext;
1817 unsigned char HASHdigest[HASH_BYTES];
1818 struct berval *value;
1819 struct berval digest;
1821 casefold = ( mr != slap_schema.si_mr_caseExactSubstringsMatch )
1822 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1824 sa = UTF8SubstringsAssertionNormalize( assertedValue, casefold );
1827 return LDAP_SUCCESS;
1830 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
1831 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1836 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
1838 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
1839 if( sa->sa_any[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1840 /* don't bother accounting for stepping */
1841 nkeys += sa->sa_any[i].bv_len -
1842 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
1847 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
1848 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1854 if ( sa->sa_final.bv_val ) free( sa->sa_final.bv_val );
1855 if ( sa->sa_any ) ber_bvarray_free( sa->sa_any );
1856 if ( sa->sa_initial.bv_val ) free( sa->sa_initial.bv_val );
1859 return LDAP_SUCCESS;
1862 digest.bv_val = HASHdigest;
1863 digest.bv_len = sizeof(HASHdigest);
1865 slen = syntax->ssyn_oidlen;
1866 mlen = mr->smr_oidlen;
1868 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
1871 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
1872 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1874 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
1875 value = &sa->sa_initial;
1877 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
1878 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
1880 HASH_Init( &HASHcontext );
1881 if( prefix != NULL && prefix->bv_len > 0 ) {
1882 HASH_Update( &HASHcontext,
1883 prefix->bv_val, prefix->bv_len );
1885 HASH_Update( &HASHcontext,
1886 &pre, sizeof( pre ) );
1887 HASH_Update( &HASHcontext,
1888 syntax->ssyn_oid, slen );
1889 HASH_Update( &HASHcontext,
1890 mr->smr_oid, mlen );
1891 HASH_Update( &HASHcontext,
1892 value->bv_val, klen );
1893 HASH_Final( HASHdigest, &HASHcontext );
1895 ber_dupbv( &keys[nkeys++], &digest );
1898 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
1900 pre = SLAP_INDEX_SUBSTR_PREFIX;
1901 klen = SLAP_INDEX_SUBSTR_MAXLEN;
1903 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
1904 if( sa->sa_any[i].bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
1908 value = &sa->sa_any[i];
1911 j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
1912 j += SLAP_INDEX_SUBSTR_STEP )
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[j], klen );
1927 HASH_Final( HASHdigest, &HASHcontext );
1929 ber_dupbv( &keys[nkeys++], &digest );
1935 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
1936 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1938 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
1939 value = &sa->sa_final;
1941 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
1942 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
1944 HASH_Init( &HASHcontext );
1945 if( prefix != NULL && prefix->bv_len > 0 ) {
1946 HASH_Update( &HASHcontext,
1947 prefix->bv_val, prefix->bv_len );
1949 HASH_Update( &HASHcontext,
1950 &pre, sizeof( pre ) );
1951 HASH_Update( &HASHcontext,
1952 syntax->ssyn_oid, slen );
1953 HASH_Update( &HASHcontext,
1954 mr->smr_oid, mlen );
1955 HASH_Update( &HASHcontext,
1956 &value->bv_val[value->bv_len-klen], klen );
1957 HASH_Final( HASHdigest, &HASHcontext );
1959 ber_dupbv( &keys[nkeys++], &digest );
1963 keys[nkeys].bv_val = NULL;
1969 if ( sa->sa_final.bv_val ) free( sa->sa_final.bv_val );
1970 if ( sa->sa_any ) ber_bvarray_free( sa->sa_any );
1971 if ( sa->sa_initial.bv_val ) free( sa->sa_initial.bv_val );
1974 return LDAP_SUCCESS;
1983 struct berval *value,
1984 void *assertedValue )
1986 *matchp = UTF8bvnormcmp( value,
1987 (struct berval *) assertedValue,
1988 LDAP_UTF8_CASEFOLD );
1989 return LDAP_SUCCESS;
1992 /* Remove all spaces and '-' characters */
1994 xtelephoneNumberNormalize(
1997 struct berval *normalized )
2001 /* validator should have refused an empty string */
2002 assert( val->bv_len );
2004 q = normalized->bv_val = ch_malloc( val->bv_len + 1 );
2006 for( p = val->bv_val; *p; p++ ) {
2007 if ( ! ( ASCII_SPACE( *p ) || *p == '-' )) {
2013 normalized->bv_len = q - normalized->bv_val;
2015 if( normalized->bv_len == 0 ) {
2016 free( normalized->bv_val );
2017 return LDAP_INVALID_SYNTAX;
2020 return LDAP_SUCCESS;
2027 struct berval *val )
2031 if( val->bv_len == 0 ) {
2032 /* disallow empty strings */
2033 return LDAP_INVALID_SYNTAX;
2036 if( OID_LEADCHAR(val->bv_val[0]) ) {
2038 for(i=1; i < val->bv_len; i++) {
2039 if( OID_SEPARATOR( val->bv_val[i] ) ) {
2040 if( dot++ ) return 1;
2041 } else if ( OID_CHAR( val->bv_val[i] ) ) {
2044 return LDAP_INVALID_SYNTAX;
2048 return !dot ? LDAP_SUCCESS : LDAP_INVALID_SYNTAX;
2050 } else if( DESC_LEADCHAR(val->bv_val[0]) ) {
2051 for(i=1; i < val->bv_len; i++) {
2052 if( !DESC_CHAR(val->bv_val[i] ) ) {
2053 return LDAP_INVALID_SYNTAX;
2057 return LDAP_SUCCESS;
2060 return LDAP_INVALID_SYNTAX;
2063 #ifndef SLAP_NVALUES
2071 struct berval *value,
2072 void *assertedValue )
2075 int vsign = 1, avsign = 1; /* default sign = '+' */
2076 struct berval *asserted;
2077 ber_len_t vlen, avlen;
2080 /* Skip leading space/sign/zeroes, and get the sign of the *value number */
2082 vlen = value->bv_len;
2083 if( mr == slap_schema.si_mr_integerFirstComponentMatch ) {
2084 char *tmp = memchr( v, '$', vlen );
2087 while( vlen && ASCII_SPACE( v[vlen-1] ))
2090 for( ; vlen && ( *v < '1' || '9' < *v ); v++, vlen-- ) /* ANSI 2.2.1 */
2096 /* Do the same with the *assertedValue number */
2097 asserted = (struct berval *) assertedValue;
2098 av = asserted->bv_val;
2099 avlen = asserted->bv_len;
2100 for( ; avlen && ( *av < '1' || '9' < *av ); av++, avlen-- )
2106 match = vsign - avsign;
2108 match = (vlen != avlen
2109 ? ( vlen < avlen ? -1 : 1 )
2110 : memcmp( v, av, vlen ));
2116 return LDAP_SUCCESS;
2123 struct berval *val )
2127 if( !val->bv_len ) return LDAP_INVALID_SYNTAX;
2129 if(( val->bv_val[0] == '+' ) || ( val->bv_val[0] == '-' )) {
2130 if( val->bv_len < 2 ) return LDAP_INVALID_SYNTAX;
2131 } else if( !ASCII_DIGIT(val->bv_val[0]) ) {
2132 return LDAP_INVALID_SYNTAX;
2135 for( i=1; i < val->bv_len; i++ ) {
2136 if( !ASCII_DIGIT(val->bv_val[i]) ) return LDAP_INVALID_SYNTAX;
2139 return LDAP_SUCCESS;
2142 #ifndef SLAP_NVALUES
2147 struct berval *normalized )
2157 /* Ignore leading spaces */
2158 while ( len && ( *p == ' ' )) {
2165 negative = ( *p == '-' );
2166 if(( *p == '-' ) || ( *p == '+' )) {
2172 /* Ignore leading zeros */
2173 while ( len && ( *p == '0' )) {
2178 /* If there are no non-zero digits left, the number is zero, otherwise
2179 allocate space for the number and copy it into the buffer */
2181 normalized->bv_val = ch_strdup("0");
2182 normalized->bv_len = 1;
2185 normalized->bv_len = len+negative;
2186 normalized->bv_val = ch_malloc( normalized->bv_len + 1 );
2188 normalized->bv_val[0] = '-';
2190 AC_MEMCPY( normalized->bv_val + negative, p, len );
2191 normalized->bv_val[len+negative] = '\0';
2194 return LDAP_SUCCESS;
2197 /* Index generation function */
2198 static int integerIndexer(
2203 struct berval *prefix,
2210 HASH_CONTEXT HASHcontext;
2211 unsigned char HASHdigest[HASH_BYTES];
2212 struct berval digest;
2213 digest.bv_val = HASHdigest;
2214 digest.bv_len = sizeof(HASHdigest);
2216 for( i=0; values[i].bv_val != NULL; i++ ) {
2217 /* empty - just count them */
2220 /* we should have at least one value at this point */
2223 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
2225 slen = syntax->ssyn_oidlen;
2226 mlen = mr->smr_oidlen;
2228 for( i=0; values[i].bv_val != NULL; i++ ) {
2230 xintegerNormalize( syntax, &values[i], &norm );
2232 HASH_Init( &HASHcontext );
2233 if( prefix != NULL && prefix->bv_len > 0 ) {
2234 HASH_Update( &HASHcontext,
2235 prefix->bv_val, prefix->bv_len );
2237 HASH_Update( &HASHcontext,
2238 syntax->ssyn_oid, slen );
2239 HASH_Update( &HASHcontext,
2240 mr->smr_oid, mlen );
2241 HASH_Update( &HASHcontext,
2242 norm.bv_val, norm.bv_len );
2243 HASH_Final( HASHdigest, &HASHcontext );
2245 ber_dupbv( &keys[i], &digest );
2246 ch_free( norm.bv_val );
2249 keys[i].bv_val = NULL;
2251 return LDAP_SUCCESS;
2254 /* Index generation function */
2255 static int integerFilter(
2260 struct berval *prefix,
2261 void * assertedValue,
2266 HASH_CONTEXT HASHcontext;
2267 unsigned char HASHdigest[HASH_BYTES];
2269 struct berval digest;
2270 digest.bv_val = HASHdigest;
2271 digest.bv_len = sizeof(HASHdigest);
2273 slen = syntax->ssyn_oidlen;
2274 mlen = mr->smr_oidlen;
2276 xintegerNormalize( syntax, assertedValue, &norm );
2278 keys = ch_malloc( sizeof( struct berval ) * 2 );
2280 HASH_Init( &HASHcontext );
2281 if( prefix != NULL && prefix->bv_len > 0 ) {
2282 HASH_Update( &HASHcontext,
2283 prefix->bv_val, prefix->bv_len );
2285 HASH_Update( &HASHcontext,
2286 syntax->ssyn_oid, slen );
2287 HASH_Update( &HASHcontext,
2288 mr->smr_oid, mlen );
2289 HASH_Update( &HASHcontext,
2290 norm.bv_val, norm.bv_len );
2291 HASH_Final( HASHdigest, &HASHcontext );
2293 ber_dupbv( &keys[0], &digest );
2294 keys[1].bv_val = NULL;
2295 ch_free( norm.bv_val );
2298 return LDAP_SUCCESS;
2304 countryStringValidate(
2306 struct berval *val )
2308 if( val->bv_len != 2 ) return LDAP_INVALID_SYNTAX;
2310 if( !SLAP_PRINTABLE(val->bv_val[0]) ) {
2311 return LDAP_INVALID_SYNTAX;
2313 if( !SLAP_PRINTABLE(val->bv_val[1]) ) {
2314 return LDAP_INVALID_SYNTAX;
2317 return LDAP_SUCCESS;
2321 printableStringValidate(
2323 struct berval *val )
2327 if( val->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
2329 for(i=0; i < val->bv_len; i++) {
2330 if( !SLAP_PRINTABLE(val->bv_val[i]) ) {
2331 return LDAP_INVALID_SYNTAX;
2335 return LDAP_SUCCESS;
2339 printablesStringValidate(
2341 struct berval *val )
2345 if( val->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
2347 for(i=0,len=0; i < val->bv_len; i++) {
2348 int c = val->bv_val[i];
2352 return LDAP_INVALID_SYNTAX;
2356 } else if ( SLAP_PRINTABLE(c) ) {
2359 return LDAP_INVALID_SYNTAX;
2364 return LDAP_INVALID_SYNTAX;
2367 return LDAP_SUCCESS;
2373 struct berval *val )
2377 if( val->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
2379 for(i=0; i < val->bv_len; i++) {
2380 if( !LDAP_ASCII(val->bv_val[i]) ) {
2381 return LDAP_INVALID_SYNTAX;
2385 return LDAP_SUCCESS;
2395 struct berval *normalized )
2398 xIA5StringNormalize(
2401 struct berval *normalized )
2406 int casefold = !SLAP_MR_ASSOCIATED(mr, slap_schema.si_mr_caseExactIA5Match);
2409 assert( val->bv_len );
2413 /* Ignore initial whitespace */
2414 while ( ASCII_SPACE( *p ) ) {
2418 normalized->bv_val = ch_strdup( p );
2419 p = q = normalized->bv_val;
2422 if ( ASCII_SPACE( *p ) ) {
2425 /* Ignore the extra whitespace */
2426 while ( ASCII_SPACE( *p ) ) {
2431 } else if ( casefold ) {
2432 /* Most IA5 rules require casefolding */
2433 *q++ = TOLOWER(*p++);
2441 assert( normalized->bv_val <= p );
2445 * If the string ended in space, backup the pointer one
2446 * position. One is enough because the above loop collapsed
2447 * all whitespace to a single space.
2450 if ( ASCII_SPACE( q[-1] ) ) {
2454 /* null terminate */
2457 normalized->bv_len = q - normalized->bv_val;
2459 if( normalized->bv_len == 0 ) {
2460 normalized->bv_val = ch_realloc( normalized->bv_val, 2 );
2461 normalized->bv_val[0] = ' ';
2462 normalized->bv_val[1] = '\0';
2463 normalized->bv_len = 1;
2466 return LDAP_SUCCESS;
2469 #ifndef SLAP_NVALUES
2477 struct berval *value,
2478 void *assertedValue )
2480 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
2483 match = strncmp( value->bv_val,
2484 ((struct berval *) assertedValue)->bv_val,
2489 return LDAP_SUCCESS;
2493 caseExactIA5SubstringsMatch(
2498 struct berval *value,
2499 void *assertedValue )
2502 SubstringsAssertion *sub = assertedValue;
2503 struct berval left = *value;
2507 /* Add up asserted input length */
2508 if( sub->sa_initial.bv_val ) {
2509 inlen += sub->sa_initial.bv_len;
2512 for(i=0; sub->sa_any[i].bv_val != NULL; i++) {
2513 inlen += sub->sa_any[i].bv_len;
2516 if( sub->sa_final.bv_val ) {
2517 inlen += sub->sa_final.bv_len;
2520 if( sub->sa_initial.bv_val ) {
2521 if( inlen > left.bv_len ) {
2526 match = strncmp( sub->sa_initial.bv_val, left.bv_val,
2527 sub->sa_initial.bv_len );
2533 left.bv_val += sub->sa_initial.bv_len;
2534 left.bv_len -= sub->sa_initial.bv_len;
2535 inlen -= sub->sa_initial.bv_len;
2538 if( sub->sa_final.bv_val ) {
2539 if( inlen > left.bv_len ) {
2544 match = strncmp( sub->sa_final.bv_val,
2545 &left.bv_val[left.bv_len - sub->sa_final.bv_len],
2546 sub->sa_final.bv_len );
2552 left.bv_len -= sub->sa_final.bv_len;
2553 inlen -= sub->sa_final.bv_len;
2557 for(i=0; sub->sa_any[i].bv_val; i++) {
2562 if( inlen > left.bv_len ) {
2563 /* not enough length */
2568 if( sub->sa_any[i].bv_len == 0 ) {
2572 p = strchr( left.bv_val, *sub->sa_any[i].bv_val );
2579 idx = p - left.bv_val;
2581 if( idx >= left.bv_len ) {
2582 /* this shouldn't happen */
2589 if( sub->sa_any[i].bv_len > left.bv_len ) {
2590 /* not enough left */
2595 match = strncmp( left.bv_val,
2596 sub->sa_any[i].bv_val,
2597 sub->sa_any[i].bv_len );
2605 left.bv_val += sub->sa_any[i].bv_len;
2606 left.bv_len -= sub->sa_any[i].bv_len;
2607 inlen -= sub->sa_any[i].bv_len;
2613 return LDAP_SUCCESS;
2616 /* Index generation function */
2617 static int caseExactIA5Indexer(
2622 struct berval *prefix,
2629 HASH_CONTEXT HASHcontext;
2630 unsigned char HASHdigest[HASH_BYTES];
2631 struct berval digest;
2632 digest.bv_val = HASHdigest;
2633 digest.bv_len = sizeof(HASHdigest);
2635 for( i=0; values[i].bv_val != NULL; i++ ) {
2636 /* empty - just count them */
2639 /* we should have at least one value at this point */
2642 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
2644 slen = syntax->ssyn_oidlen;
2645 mlen = mr->smr_oidlen;
2647 for( i=0; values[i].bv_val != NULL; i++ ) {
2648 struct berval *value = &values[i];
2650 HASH_Init( &HASHcontext );
2651 if( prefix != NULL && prefix->bv_len > 0 ) {
2652 HASH_Update( &HASHcontext,
2653 prefix->bv_val, prefix->bv_len );
2655 HASH_Update( &HASHcontext,
2656 syntax->ssyn_oid, slen );
2657 HASH_Update( &HASHcontext,
2658 mr->smr_oid, mlen );
2659 HASH_Update( &HASHcontext,
2660 value->bv_val, value->bv_len );
2661 HASH_Final( HASHdigest, &HASHcontext );
2663 ber_dupbv( &keys[i], &digest );
2666 keys[i].bv_val = NULL;
2668 return LDAP_SUCCESS;
2671 /* Index generation function */
2672 static int caseExactIA5Filter(
2677 struct berval *prefix,
2678 void * assertedValue,
2683 HASH_CONTEXT HASHcontext;
2684 unsigned char HASHdigest[HASH_BYTES];
2685 struct berval *value;
2686 struct berval digest;
2687 digest.bv_val = HASHdigest;
2688 digest.bv_len = sizeof(HASHdigest);
2690 slen = syntax->ssyn_oidlen;
2691 mlen = mr->smr_oidlen;
2693 value = (struct berval *) assertedValue;
2695 keys = ch_malloc( sizeof( struct berval ) * 2 );
2697 HASH_Init( &HASHcontext );
2698 if( prefix != NULL && prefix->bv_len > 0 ) {
2699 HASH_Update( &HASHcontext,
2700 prefix->bv_val, prefix->bv_len );
2702 HASH_Update( &HASHcontext,
2703 syntax->ssyn_oid, slen );
2704 HASH_Update( &HASHcontext,
2705 mr->smr_oid, mlen );
2706 HASH_Update( &HASHcontext,
2707 value->bv_val, value->bv_len );
2708 HASH_Final( HASHdigest, &HASHcontext );
2710 ber_dupbv( &keys[0], &digest );
2711 keys[1].bv_val = NULL;
2714 return LDAP_SUCCESS;
2717 /* Substrings Index generation function */
2718 static int caseExactIA5SubstringsIndexer(
2723 struct berval *prefix,
2730 HASH_CONTEXT HASHcontext;
2731 unsigned char HASHdigest[HASH_BYTES];
2732 struct berval digest;
2733 digest.bv_val = HASHdigest;
2734 digest.bv_len = sizeof(HASHdigest);
2736 /* we should have at least one value at this point */
2737 assert( values != NULL && values[0].bv_val != NULL );
2740 for( i=0; values[i].bv_val != NULL; i++ ) {
2741 /* count number of indices to generate */
2742 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
2746 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
2747 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2748 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2749 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2751 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2755 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
2756 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2757 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
2761 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
2762 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2763 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2764 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2766 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2772 /* no keys to generate */
2774 return LDAP_SUCCESS;
2777 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
2779 slen = syntax->ssyn_oidlen;
2780 mlen = mr->smr_oidlen;
2783 for( i=0; values[i].bv_val != NULL; i++ ) {
2785 struct berval *value;
2788 if( value->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
2790 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
2791 ( value->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
2793 char pre = SLAP_INDEX_SUBSTR_PREFIX;
2794 max = value->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
2796 for( j=0; j<max; j++ ) {
2797 HASH_Init( &HASHcontext );
2798 if( prefix != NULL && prefix->bv_len > 0 ) {
2799 HASH_Update( &HASHcontext,
2800 prefix->bv_val, prefix->bv_len );
2803 HASH_Update( &HASHcontext,
2804 &pre, sizeof( pre ) );
2805 HASH_Update( &HASHcontext,
2806 syntax->ssyn_oid, slen );
2807 HASH_Update( &HASHcontext,
2808 mr->smr_oid, mlen );
2809 HASH_Update( &HASHcontext,
2811 SLAP_INDEX_SUBSTR_MAXLEN );
2812 HASH_Final( HASHdigest, &HASHcontext );
2814 ber_dupbv( &keys[nkeys++], &digest );
2818 max = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2819 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2821 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
2824 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
2825 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
2826 HASH_Init( &HASHcontext );
2827 if( prefix != NULL && prefix->bv_len > 0 ) {
2828 HASH_Update( &HASHcontext,
2829 prefix->bv_val, prefix->bv_len );
2831 HASH_Update( &HASHcontext,
2832 &pre, sizeof( pre ) );
2833 HASH_Update( &HASHcontext,
2834 syntax->ssyn_oid, slen );
2835 HASH_Update( &HASHcontext,
2836 mr->smr_oid, mlen );
2837 HASH_Update( &HASHcontext,
2839 HASH_Final( HASHdigest, &HASHcontext );
2841 ber_dupbv( &keys[nkeys++], &digest );
2844 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
2845 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
2846 HASH_Init( &HASHcontext );
2847 if( prefix != NULL && prefix->bv_len > 0 ) {
2848 HASH_Update( &HASHcontext,
2849 prefix->bv_val, prefix->bv_len );
2851 HASH_Update( &HASHcontext,
2852 &pre, sizeof( pre ) );
2853 HASH_Update( &HASHcontext,
2854 syntax->ssyn_oid, slen );
2855 HASH_Update( &HASHcontext,
2856 mr->smr_oid, mlen );
2857 HASH_Update( &HASHcontext,
2858 &value->bv_val[value->bv_len-j], j );
2859 HASH_Final( HASHdigest, &HASHcontext );
2861 ber_dupbv( &keys[nkeys++], &digest );
2868 keys[nkeys].bv_val = NULL;
2875 return LDAP_SUCCESS;
2878 static int caseExactIA5SubstringsFilter(
2883 struct berval *prefix,
2884 void * assertedValue,
2887 SubstringsAssertion *sa = assertedValue;
2889 ber_len_t nkeys = 0;
2890 size_t slen, mlen, klen;
2892 HASH_CONTEXT HASHcontext;
2893 unsigned char HASHdigest[HASH_BYTES];
2894 struct berval *value;
2895 struct berval digest;
2897 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
2898 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2903 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
2905 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
2906 if( sa->sa_any[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2907 /* don't bother accounting for stepping */
2908 nkeys += sa->sa_any[i].bv_len -
2909 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
2914 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
2915 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2922 return LDAP_SUCCESS;
2925 digest.bv_val = HASHdigest;
2926 digest.bv_len = sizeof(HASHdigest);
2928 slen = syntax->ssyn_oidlen;
2929 mlen = mr->smr_oidlen;
2931 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
2934 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
2935 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2937 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
2938 value = &sa->sa_initial;
2940 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2941 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2943 HASH_Init( &HASHcontext );
2944 if( prefix != NULL && prefix->bv_len > 0 ) {
2945 HASH_Update( &HASHcontext,
2946 prefix->bv_val, prefix->bv_len );
2948 HASH_Update( &HASHcontext,
2949 &pre, sizeof( pre ) );
2950 HASH_Update( &HASHcontext,
2951 syntax->ssyn_oid, slen );
2952 HASH_Update( &HASHcontext,
2953 mr->smr_oid, mlen );
2954 HASH_Update( &HASHcontext,
2955 value->bv_val, klen );
2956 HASH_Final( HASHdigest, &HASHcontext );
2958 ber_dupbv( &keys[nkeys++], &digest );
2961 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
2963 pre = SLAP_INDEX_SUBSTR_PREFIX;
2964 klen = SLAP_INDEX_SUBSTR_MAXLEN;
2966 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
2967 if( sa->sa_any[i].bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
2971 value = &sa->sa_any[i];
2974 j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
2975 j += SLAP_INDEX_SUBSTR_STEP )
2977 HASH_Init( &HASHcontext );
2978 if( prefix != NULL && prefix->bv_len > 0 ) {
2979 HASH_Update( &HASHcontext,
2980 prefix->bv_val, prefix->bv_len );
2982 HASH_Update( &HASHcontext,
2983 &pre, sizeof( pre ) );
2984 HASH_Update( &HASHcontext,
2985 syntax->ssyn_oid, slen );
2986 HASH_Update( &HASHcontext,
2987 mr->smr_oid, mlen );
2988 HASH_Update( &HASHcontext,
2989 &value->bv_val[j], klen );
2990 HASH_Final( HASHdigest, &HASHcontext );
2992 ber_dupbv( &keys[nkeys++], &digest );
2997 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
2998 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3000 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
3001 value = &sa->sa_final;
3003 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
3004 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
3006 HASH_Init( &HASHcontext );
3007 if( prefix != NULL && prefix->bv_len > 0 ) {
3008 HASH_Update( &HASHcontext,
3009 prefix->bv_val, prefix->bv_len );
3011 HASH_Update( &HASHcontext,
3012 &pre, sizeof( pre ) );
3013 HASH_Update( &HASHcontext,
3014 syntax->ssyn_oid, slen );
3015 HASH_Update( &HASHcontext,
3016 mr->smr_oid, mlen );
3017 HASH_Update( &HASHcontext,
3018 &value->bv_val[value->bv_len-klen], klen );
3019 HASH_Final( HASHdigest, &HASHcontext );
3021 ber_dupbv( &keys[nkeys++], &digest );
3025 keys[nkeys].bv_val = NULL;
3032 return LDAP_SUCCESS;
3041 struct berval *value,
3042 void *assertedValue )
3044 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
3046 if( match == 0 && value->bv_len ) {
3047 match = strncasecmp( value->bv_val,
3048 ((struct berval *) assertedValue)->bv_val,
3053 return LDAP_SUCCESS;
3057 caseIgnoreIA5SubstringsMatch(
3062 struct berval *value,
3063 void *assertedValue )
3066 SubstringsAssertion *sub = assertedValue;
3067 struct berval left = *value;
3071 /* Add up asserted input length */
3072 if( sub->sa_initial.bv_val ) {
3073 inlen += sub->sa_initial.bv_len;
3076 for(i=0; sub->sa_any[i].bv_val != NULL; i++) {
3077 inlen += sub->sa_any[i].bv_len;
3080 if( sub->sa_final.bv_val ) {
3081 inlen += sub->sa_final.bv_len;
3084 if( sub->sa_initial.bv_val ) {
3085 if( inlen > left.bv_len ) {
3090 match = strncasecmp( sub->sa_initial.bv_val, left.bv_val,
3091 sub->sa_initial.bv_len );
3097 left.bv_val += sub->sa_initial.bv_len;
3098 left.bv_len -= sub->sa_initial.bv_len;
3099 inlen -= sub->sa_initial.bv_len;
3102 if( sub->sa_final.bv_val ) {
3103 if( inlen > left.bv_len ) {
3108 match = strncasecmp( sub->sa_final.bv_val,
3109 &left.bv_val[left.bv_len - sub->sa_final.bv_len],
3110 sub->sa_final.bv_len );
3116 left.bv_len -= sub->sa_final.bv_len;
3117 inlen -= sub->sa_final.bv_len;
3121 for(i=0; sub->sa_any[i].bv_val; i++) {
3126 if( inlen > left.bv_len ) {
3127 /* not enough length */
3132 if( sub->sa_any[i].bv_len == 0 ) {
3136 p = bvcasechr( &left, *sub->sa_any[i].bv_val, &idx );
3143 assert( idx < left.bv_len );
3144 if( idx >= left.bv_len ) {
3145 /* this shouldn't happen */
3152 if( sub->sa_any[i].bv_len > left.bv_len ) {
3153 /* not enough left */
3158 match = strncasecmp( left.bv_val,
3159 sub->sa_any[i].bv_val,
3160 sub->sa_any[i].bv_len );
3169 left.bv_val += sub->sa_any[i].bv_len;
3170 left.bv_len -= sub->sa_any[i].bv_len;
3171 inlen -= sub->sa_any[i].bv_len;
3177 return LDAP_SUCCESS;
3180 /* Index generation function */
3181 static int caseIgnoreIA5Indexer(
3186 struct berval *prefix,
3191 int rc = LDAP_SUCCESS;
3194 HASH_CONTEXT HASHcontext;
3195 unsigned char HASHdigest[HASH_BYTES];
3196 struct berval digest;
3197 digest.bv_val = HASHdigest;
3198 digest.bv_len = sizeof(HASHdigest);
3200 /* we should have at least one value at this point */
3201 assert( values != NULL && values[0].bv_val != NULL );
3203 for( i=0; values[i].bv_val != NULL; i++ ) {
3204 /* just count them */
3207 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
3209 slen = syntax->ssyn_oidlen;
3210 mlen = mr->smr_oidlen;
3212 for( i=0; values[i].bv_val != NULL; i++ ) {
3213 struct berval value;
3215 if( mr->smr_normalize ) {
3216 rc = (mr->smr_normalize)( use, syntax, mr, &values[i], &value );
3217 if( rc != LDAP_SUCCESS ) {
3220 #ifndef SLAP_NVALUES
3221 } else if ( mr->smr_syntax->ssyn_normalize ) {
3222 rc = (mr->smr_syntax->ssyn_normalize)( syntax, &values[i], &value );
3223 if( rc != LDAP_SUCCESS ) {
3228 ber_dupbv( &value, &values[i] );
3231 ldap_pvt_str2lower( value.bv_val );
3233 HASH_Init( &HASHcontext );
3234 if( prefix != NULL && prefix->bv_len > 0 ) {
3235 HASH_Update( &HASHcontext,
3236 prefix->bv_val, prefix->bv_len );
3238 HASH_Update( &HASHcontext,
3239 syntax->ssyn_oid, slen );
3240 HASH_Update( &HASHcontext,
3241 mr->smr_oid, mlen );
3242 HASH_Update( &HASHcontext,
3243 value.bv_val, value.bv_len );
3244 HASH_Final( HASHdigest, &HASHcontext );
3246 free( value.bv_val );
3248 ber_dupbv( &keys[i], &digest );
3251 keys[i].bv_val = NULL;
3252 if( rc != LDAP_SUCCESS ) {
3253 ber_bvarray_free( keys );
3260 /* Index generation function */
3261 static int caseIgnoreIA5Filter(
3266 struct berval *prefix,
3267 void * assertedValue,
3272 HASH_CONTEXT HASHcontext;
3273 unsigned char HASHdigest[HASH_BYTES];
3274 struct berval value;
3275 struct berval digest;
3276 digest.bv_val = HASHdigest;
3277 digest.bv_len = sizeof(HASHdigest);
3279 slen = syntax->ssyn_oidlen;
3280 mlen = mr->smr_oidlen;
3282 ber_dupbv( &value, (struct berval *) assertedValue );
3283 ldap_pvt_str2lower( value.bv_val );
3285 keys = ch_malloc( sizeof( struct berval ) * 2 );
3287 HASH_Init( &HASHcontext );
3288 if( prefix != NULL && prefix->bv_len > 0 ) {
3289 HASH_Update( &HASHcontext,
3290 prefix->bv_val, prefix->bv_len );
3292 HASH_Update( &HASHcontext,
3293 syntax->ssyn_oid, slen );
3294 HASH_Update( &HASHcontext,
3295 mr->smr_oid, mlen );
3296 HASH_Update( &HASHcontext,
3297 value.bv_val, value.bv_len );
3298 HASH_Final( HASHdigest, &HASHcontext );
3300 ber_dupbv( &keys[0], &digest );
3301 keys[1].bv_val = NULL;
3303 free( value.bv_val );
3307 return LDAP_SUCCESS;
3310 /* Substrings Index generation function */
3311 static int caseIgnoreIA5SubstringsIndexer(
3316 struct berval *prefix,
3323 HASH_CONTEXT HASHcontext;
3324 unsigned char HASHdigest[HASH_BYTES];
3325 struct berval digest;
3326 digest.bv_val = HASHdigest;
3327 digest.bv_len = sizeof(HASHdigest);
3329 /* we should have at least one value at this point */
3330 assert( values != NULL && values[0].bv_val != NULL );
3333 for( i=0; values[i].bv_val != NULL; i++ ) {
3334 /* count number of indices to generate */
3335 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
3339 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
3340 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3341 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
3342 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
3344 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
3348 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
3349 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3350 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
3354 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
3355 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3356 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
3357 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
3359 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
3365 /* no keys to generate */
3367 return LDAP_SUCCESS;
3370 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
3372 slen = syntax->ssyn_oidlen;
3373 mlen = mr->smr_oidlen;
3376 for( i=0; values[i].bv_val != NULL; i++ ) {
3378 struct berval value;
3380 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
3382 ber_dupbv( &value, &values[i] );
3383 ldap_pvt_str2lower( value.bv_val );
3385 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
3386 ( value.bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
3388 char pre = SLAP_INDEX_SUBSTR_PREFIX;
3389 max = value.bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
3391 for( j=0; j<max; j++ ) {
3392 HASH_Init( &HASHcontext );
3393 if( prefix != NULL && prefix->bv_len > 0 ) {
3394 HASH_Update( &HASHcontext,
3395 prefix->bv_val, prefix->bv_len );
3398 HASH_Update( &HASHcontext,
3399 &pre, sizeof( pre ) );
3400 HASH_Update( &HASHcontext,
3401 syntax->ssyn_oid, slen );
3402 HASH_Update( &HASHcontext,
3403 mr->smr_oid, mlen );
3404 HASH_Update( &HASHcontext,
3406 SLAP_INDEX_SUBSTR_MAXLEN );
3407 HASH_Final( HASHdigest, &HASHcontext );
3409 ber_dupbv( &keys[nkeys++], &digest );
3413 max = SLAP_INDEX_SUBSTR_MAXLEN < value.bv_len
3414 ? SLAP_INDEX_SUBSTR_MAXLEN : value.bv_len;
3416 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
3419 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
3420 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
3421 HASH_Init( &HASHcontext );
3422 if( prefix != NULL && prefix->bv_len > 0 ) {
3423 HASH_Update( &HASHcontext,
3424 prefix->bv_val, prefix->bv_len );
3426 HASH_Update( &HASHcontext,
3427 &pre, sizeof( pre ) );
3428 HASH_Update( &HASHcontext,
3429 syntax->ssyn_oid, slen );
3430 HASH_Update( &HASHcontext,
3431 mr->smr_oid, mlen );
3432 HASH_Update( &HASHcontext,
3434 HASH_Final( HASHdigest, &HASHcontext );
3436 ber_dupbv( &keys[nkeys++], &digest );
3439 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
3440 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
3441 HASH_Init( &HASHcontext );
3442 if( prefix != NULL && prefix->bv_len > 0 ) {
3443 HASH_Update( &HASHcontext,
3444 prefix->bv_val, prefix->bv_len );
3446 HASH_Update( &HASHcontext,
3447 &pre, sizeof( pre ) );
3448 HASH_Update( &HASHcontext,
3449 syntax->ssyn_oid, slen );
3450 HASH_Update( &HASHcontext,
3451 mr->smr_oid, mlen );
3452 HASH_Update( &HASHcontext,
3453 &value.bv_val[value.bv_len-j], j );
3454 HASH_Final( HASHdigest, &HASHcontext );
3456 ber_dupbv( &keys[nkeys++], &digest );
3461 free( value.bv_val );
3465 keys[nkeys].bv_val = NULL;
3472 return LDAP_SUCCESS;
3475 static int caseIgnoreIA5SubstringsFilter(
3480 struct berval *prefix,
3481 void * assertedValue,
3484 SubstringsAssertion *sa = assertedValue;
3486 ber_len_t nkeys = 0;
3487 size_t slen, mlen, klen;
3489 HASH_CONTEXT HASHcontext;
3490 unsigned char HASHdigest[HASH_BYTES];
3491 struct berval value;
3492 struct berval digest;
3494 if((flags & SLAP_INDEX_SUBSTR_INITIAL) && sa->sa_initial.bv_val != NULL &&
3495 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3500 if((flags & SLAP_INDEX_SUBSTR_ANY) && sa->sa_any != NULL ) {
3502 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
3503 if( sa->sa_any[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3504 /* don't bother accounting for stepping */
3505 nkeys += sa->sa_any[i].bv_len -
3506 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
3511 if((flags & SLAP_INDEX_SUBSTR_FINAL) && sa->sa_final.bv_val != NULL &&
3512 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3519 return LDAP_SUCCESS;
3522 digest.bv_val = HASHdigest;
3523 digest.bv_len = sizeof(HASHdigest);
3525 slen = syntax->ssyn_oidlen;
3526 mlen = mr->smr_oidlen;
3528 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
3531 if((flags & SLAP_INDEX_SUBSTR_INITIAL) && sa->sa_initial.bv_val != NULL &&
3532 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3534 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
3535 ber_dupbv( &value, &sa->sa_initial );
3536 ldap_pvt_str2lower( value.bv_val );
3538 klen = SLAP_INDEX_SUBSTR_MAXLEN < value.bv_len
3539 ? SLAP_INDEX_SUBSTR_MAXLEN : value.bv_len;
3541 HASH_Init( &HASHcontext );
3542 if( prefix != NULL && prefix->bv_len > 0 ) {
3543 HASH_Update( &HASHcontext,
3544 prefix->bv_val, prefix->bv_len );
3546 HASH_Update( &HASHcontext,
3547 &pre, sizeof( pre ) );
3548 HASH_Update( &HASHcontext,
3549 syntax->ssyn_oid, slen );
3550 HASH_Update( &HASHcontext,
3551 mr->smr_oid, mlen );
3552 HASH_Update( &HASHcontext,
3553 value.bv_val, klen );
3554 HASH_Final( HASHdigest, &HASHcontext );
3556 free( value.bv_val );
3557 ber_dupbv( &keys[nkeys++], &digest );
3560 if((flags & SLAP_INDEX_SUBSTR_ANY) && sa->sa_any != NULL ) {
3562 pre = SLAP_INDEX_SUBSTR_PREFIX;
3563 klen = SLAP_INDEX_SUBSTR_MAXLEN;
3565 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
3566 if( sa->sa_any[i].bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
3570 ber_dupbv( &value, &sa->sa_any[i] );
3571 ldap_pvt_str2lower( value.bv_val );
3574 j <= value.bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
3575 j += SLAP_INDEX_SUBSTR_STEP )
3577 HASH_Init( &HASHcontext );
3578 if( prefix != NULL && prefix->bv_len > 0 ) {
3579 HASH_Update( &HASHcontext,
3580 prefix->bv_val, prefix->bv_len );
3582 HASH_Update( &HASHcontext,
3583 &pre, sizeof( pre ) );
3584 HASH_Update( &HASHcontext,
3585 syntax->ssyn_oid, slen );
3586 HASH_Update( &HASHcontext,
3587 mr->smr_oid, mlen );
3588 HASH_Update( &HASHcontext,
3589 &value.bv_val[j], klen );
3590 HASH_Final( HASHdigest, &HASHcontext );
3592 ber_dupbv( &keys[nkeys++], &digest );
3595 free( value.bv_val );
3599 if((flags & SLAP_INDEX_SUBSTR_FINAL) && sa->sa_final.bv_val != NULL &&
3600 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3602 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
3603 ber_dupbv( &value, &sa->sa_final );
3604 ldap_pvt_str2lower( value.bv_val );
3606 klen = SLAP_INDEX_SUBSTR_MAXLEN < value.bv_len
3607 ? SLAP_INDEX_SUBSTR_MAXLEN : value.bv_len;
3609 HASH_Init( &HASHcontext );
3610 if( prefix != NULL && prefix->bv_len > 0 ) {
3611 HASH_Update( &HASHcontext,
3612 prefix->bv_val, prefix->bv_len );
3614 HASH_Update( &HASHcontext,
3615 &pre, sizeof( pre ) );
3616 HASH_Update( &HASHcontext,
3617 syntax->ssyn_oid, slen );
3618 HASH_Update( &HASHcontext,
3619 mr->smr_oid, mlen );
3620 HASH_Update( &HASHcontext,
3621 &value.bv_val[value.bv_len-klen], klen );
3622 HASH_Final( HASHdigest, &HASHcontext );
3624 free( value.bv_val );
3625 ber_dupbv( &keys[nkeys++], &digest );
3629 keys[nkeys].bv_val = NULL;
3636 return LDAP_SUCCESS;
3642 numericStringValidate(
3648 if( in->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
3650 for(i=0; i < in->bv_len; i++) {
3651 if( !SLAP_NUMERIC(in->bv_val[i]) ) {
3652 return LDAP_INVALID_SYNTAX;
3656 return LDAP_SUCCESS;
3659 #ifndef SLAP_NVALUES
3662 xnumericStringNormalize(
3665 struct berval *normalized )
3667 /* removal all spaces */
3670 assert( val->bv_len );
3672 normalized->bv_val = ch_malloc( val->bv_len + 1 );
3675 q = normalized->bv_val;
3678 if ( ASCII_SPACE( *p ) ) {
3679 /* Ignore whitespace */
3686 /* we should have copied no more then is in val */
3687 assert( (q - normalized->bv_val) <= (p - val->bv_val) );
3689 /* null terminate */
3692 normalized->bv_len = q - normalized->bv_val;
3694 if( normalized->bv_len == 0 ) {
3695 normalized->bv_val = ch_realloc( normalized->bv_val, 2 );
3696 normalized->bv_val[0] = ' ';
3697 normalized->bv_val[1] = '\0';
3698 normalized->bv_len = 1;
3701 return LDAP_SUCCESS;
3705 objectIdentifierFirstComponentMatch(
3710 struct berval *value,
3711 void *assertedValue )
3713 int rc = LDAP_SUCCESS;
3715 struct berval *asserted = (struct berval *) assertedValue;
3719 if( value->bv_len == 0 || value->bv_val[0] != '(' /*')'*/ ) {
3720 return LDAP_INVALID_SYNTAX;
3723 /* trim leading white space */
3724 for( i=1; ASCII_SPACE(value->bv_val[i]) && i < value->bv_len; i++ ) {
3728 /* grab next word */
3729 oid.bv_val = &value->bv_val[i];
3730 j = value->bv_len - i;
3731 for( i=0; !ASCII_SPACE(oid.bv_val[i]) && i < j; i++ ) {
3736 /* insert attributeTypes, objectclass check here */
3737 if( OID_LEADCHAR(asserted->bv_val[0]) ) {
3738 rc = objectIdentifierMatch( &match, flags, syntax, mr, &oid, asserted );
3741 if ( !strcmp( syntax->ssyn_oid, SLAP_SYNTAX_MATCHINGRULES_OID ) ) {
3742 MatchingRule *asserted_mr = mr_bvfind( asserted );
3743 MatchingRule *stored_mr = mr_bvfind( &oid );
3745 if( asserted_mr == NULL ) {
3746 rc = SLAPD_COMPARE_UNDEFINED;
3748 match = asserted_mr != stored_mr;
3751 } else if ( !strcmp( syntax->ssyn_oid,
3752 SLAP_SYNTAX_ATTRIBUTETYPES_OID ) )
3754 AttributeType *asserted_at = at_bvfind( asserted );
3755 AttributeType *stored_at = at_bvfind( &oid );
3757 if( asserted_at == NULL ) {
3758 rc = SLAPD_COMPARE_UNDEFINED;
3760 match = asserted_at != stored_at;
3763 } else if ( !strcmp( syntax->ssyn_oid,
3764 SLAP_SYNTAX_OBJECTCLASSES_OID ) )
3766 ObjectClass *asserted_oc = oc_bvfind( asserted );
3767 ObjectClass *stored_oc = oc_bvfind( &oid );
3769 if( asserted_oc == NULL ) {
3770 rc = SLAPD_COMPARE_UNDEFINED;
3772 match = asserted_oc != stored_oc;
3778 LDAP_LOG( CONFIG, ENTRY,
3779 "objectIdentifierFirstComponentMatch: %d\n %s\n %s\n",
3780 match, value->bv_val, asserted->bv_val );
3782 Debug( LDAP_DEBUG_ARGS, "objectIdentifierFirstComponentMatch "
3783 "%d\n\t\"%s\"\n\t\"%s\"\n",
3784 match, value->bv_val, asserted->bv_val );
3787 if( rc == LDAP_SUCCESS ) *matchp = match;
3799 struct berval *value,
3800 void *assertedValue )
3802 long lValue, lAssertedValue;
3804 /* safe to assume integers are NUL terminated? */
3805 lValue = strtol(value->bv_val, NULL, 10);
3806 if(( lValue == LONG_MIN || lValue == LONG_MAX) && errno == ERANGE ) {
3807 return LDAP_CONSTRAINT_VIOLATION;
3810 lAssertedValue = strtol(((struct berval *)assertedValue)->bv_val, NULL, 10);
3811 if(( lAssertedValue == LONG_MIN || lAssertedValue == LONG_MAX)
3812 && errno == ERANGE )
3814 return LDAP_CONSTRAINT_VIOLATION;
3817 *matchp = (lValue & lAssertedValue) ? 0 : 1;
3818 return LDAP_SUCCESS;
3827 struct berval *value,
3828 void *assertedValue )
3830 long lValue, lAssertedValue;
3832 /* safe to assume integers are NUL terminated? */
3833 lValue = strtol(value->bv_val, NULL, 10);
3834 if(( lValue == LONG_MIN || lValue == LONG_MAX) && errno == ERANGE ) {
3835 return LDAP_CONSTRAINT_VIOLATION;
3838 lAssertedValue = strtol(((struct berval *)assertedValue)->bv_val, NULL, 10);
3839 if(( lAssertedValue == LONG_MIN || lAssertedValue == LONG_MAX)
3840 && errno == ERANGE )
3842 return LDAP_CONSTRAINT_VIOLATION;
3845 *matchp = (lValue | lAssertedValue) ? 0 : -1;
3846 return LDAP_SUCCESS;
3849 #ifndef SLAP_NVALUES
3852 #include <openssl/x509.h>
3853 #include <openssl/err.h>
3856 * Next function returns a string representation of a ASN1_INTEGER.
3857 * It works for unlimited lengths.
3860 static struct berval *
3861 asn1_integer2str(ASN1_INTEGER *a, struct berval *bv)
3865 static char digit[] = "0123456789";
3867 /* We work backwards, make it fill from the end of buf */
3868 p = buf + sizeof(buf) - 1;
3871 if ( a == NULL || a->length == 0 ) {
3879 /* We want to preserve the original */
3880 copy = ch_malloc(n*sizeof(unsigned int));
3881 for (i = 0; i<n; i++) {
3882 copy[i] = a->data[i];
3886 * base indicates the index of the most significant
3887 * byte that might be nonzero. When it goes off the
3888 * end, we now there is nothing left to do.
3894 for (i = base; i<n; i++ ) {
3895 copy[i] += carry*256;
3896 carry = copy[i] % 10;
3901 * Way too large, we need to leave
3902 * room for sign if negative
3907 *--p = digit[carry];
3909 if (copy[base] == 0) base++;
3914 if ( a->type == V_ASN1_NEG_INTEGER ) {
3918 return ber_str2bv( p, 0, 1, bv );
3922 * Given a certificate in DER format, extract the corresponding
3923 * assertion value for certificateExactMatch
3926 certificateExactConvert(
3928 struct berval * out )
3931 unsigned char *p = in->bv_val;
3932 struct berval serial;
3933 struct berval issuer_dn;
3935 xcert = d2i_X509(NULL, &p, in->bv_len);
3938 LDAP_LOG( CONFIG, ENTRY,
3939 "certificateExactConvert: error parsing cert: %s\n",
3940 ERR_error_string(ERR_get_error(),NULL), 0, 0 );
3942 Debug( LDAP_DEBUG_ARGS, "certificateExactConvert: "
3943 "error parsing cert: %s\n",
3944 ERR_error_string(ERR_get_error(),NULL), NULL, NULL );
3946 return LDAP_INVALID_SYNTAX;
3949 if ( !asn1_integer2str(xcert->cert_info->serialNumber, &serial) ) {
3951 return LDAP_INVALID_SYNTAX;
3953 if ( dnX509normalize(X509_get_issuer_name(xcert), &issuer_dn )
3957 ber_memfree(serial.bv_val);
3958 return LDAP_INVALID_SYNTAX;
3963 out->bv_len = serial.bv_len + issuer_dn.bv_len + sizeof(" $ ");
3964 out->bv_val = ch_malloc(out->bv_len);
3966 AC_MEMCPY(p, serial.bv_val, serial.bv_len);
3968 AC_MEMCPY(p, " $ ", sizeof(" $ ")-1);
3970 AC_MEMCPY(p, issuer_dn.bv_val, issuer_dn.bv_len);
3971 p += issuer_dn.bv_len;
3975 LDAP_LOG( CONFIG, ARGS,
3976 "certificateExactConvert: \n %s\n", out->bv_val, 0, 0 );
3978 Debug( LDAP_DEBUG_ARGS, "certificateExactConvert "
3980 out->bv_val, NULL, NULL );
3983 ber_memfree(serial.bv_val);
3984 ber_memfree(issuer_dn.bv_val);
3986 return LDAP_SUCCESS;
3990 serial_and_issuer_parse(
3991 struct berval *assertion,
3992 struct berval *serial,
3993 struct berval *issuer_dn
4001 begin = assertion->bv_val;
4002 end = assertion->bv_val+assertion->bv_len-1;
4003 for (p=begin; p<=end && *p != '$'; p++) /* empty */ ;
4004 if ( p > end ) return LDAP_INVALID_SYNTAX;
4006 /* p now points at the $ sign, now use
4007 * begin and end to delimit the serial number
4009 while (ASCII_SPACE(*begin)) begin++;
4011 while (ASCII_SPACE(*end)) end--;
4013 if( end <= begin ) return LDAP_INVALID_SYNTAX;
4015 bv.bv_len = end-begin+1;
4017 ber_dupbv(serial, &bv);
4019 /* now extract the issuer, remember p was at the dollar sign */
4021 end = assertion->bv_val+assertion->bv_len-1;
4022 while (ASCII_SPACE(*begin)) begin++;
4023 /* should we trim spaces at the end too? is it safe always? no, no */
4025 if( end <= begin ) return LDAP_INVALID_SYNTAX;
4028 bv.bv_len = end-begin+1;
4031 dnNormalize2( NULL, &bv, issuer_dn );
4034 return LDAP_SUCCESS;
4038 certificateExactMatch(
4043 struct berval *value,
4044 void *assertedValue )
4047 unsigned char *p = value->bv_val;
4048 struct berval serial;
4049 struct berval issuer_dn;
4050 struct berval asserted_serial;
4051 struct berval asserted_issuer_dn;
4054 xcert = d2i_X509(NULL, &p, value->bv_len);
4057 LDAP_LOG( CONFIG, ENTRY,
4058 "certificateExactMatch: error parsing cert: %s\n",
4059 ERR_error_string(ERR_get_error(),NULL), 0, 0 );
4061 Debug( LDAP_DEBUG_ARGS, "certificateExactMatch: "
4062 "error parsing cert: %s\n",
4063 ERR_error_string(ERR_get_error(),NULL), NULL, NULL );
4065 return LDAP_INVALID_SYNTAX;
4068 asn1_integer2str(xcert->cert_info->serialNumber, &serial);
4069 dnX509normalize(X509_get_issuer_name(xcert), &issuer_dn);
4073 serial_and_issuer_parse(assertedValue,
4074 &asserted_serial, &asserted_issuer_dn);
4079 slap_schema.si_syn_integer,
4080 slap_schema.si_mr_integerMatch,
4083 if ( ret == LDAP_SUCCESS ) {
4084 if ( *matchp == 0 ) {
4085 /* We need to normalize everything for dnMatch */
4089 slap_schema.si_syn_distinguishedName,
4090 slap_schema.si_mr_distinguishedNameMatch,
4092 &asserted_issuer_dn);
4097 LDAP_LOG( CONFIG, ARGS, "certificateExactMatch "
4098 "%d\n\t\"%s $ %s\"\n",
4099 *matchp, serial.bv_val, issuer_dn.bv_val );
4100 LDAP_LOG( CONFIG, ARGS, "\t\"%s $ %s\"\n",
4101 asserted_serial.bv_val, asserted_issuer_dn.bv_val,
4104 Debug( LDAP_DEBUG_ARGS, "certificateExactMatch "
4105 "%d\n\t\"%s $ %s\"\n",
4106 *matchp, serial.bv_val, issuer_dn.bv_val );
4107 Debug( LDAP_DEBUG_ARGS, "\t\"%s $ %s\"\n",
4108 asserted_serial.bv_val, asserted_issuer_dn.bv_val,
4112 ber_memfree(serial.bv_val);
4113 ber_memfree(issuer_dn.bv_val);
4114 ber_memfree(asserted_serial.bv_val);
4115 ber_memfree(asserted_issuer_dn.bv_val);
4121 * Index generation function
4122 * We just index the serials, in most scenarios the issuer DN is one of
4123 * a very small set of values.
4125 static int certificateExactIndexer(
4130 struct berval *prefix,
4138 struct berval serial;
4140 /* we should have at least one value at this point */
4141 assert( values != NULL && values[0].bv_val != NULL );
4143 for( i=0; values[i].bv_val != NULL; i++ ) {
4144 /* empty -- just count them */
4147 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
4149 for( i=0; values[i].bv_val != NULL; i++ ) {
4150 p = values[i].bv_val;
4151 xcert = d2i_X509(NULL, &p, values[i].bv_len);
4154 LDAP_LOG( CONFIG, ENTRY,
4155 "certificateExactIndexer: error parsing cert: %s\n",
4156 ERR_error_string(ERR_get_error(),NULL), 0, 0);
4158 Debug( LDAP_DEBUG_ARGS, "certificateExactIndexer: "
4159 "error parsing cert: %s\n",
4160 ERR_error_string(ERR_get_error(),NULL),
4163 /* Do we leak keys on error? */
4164 return LDAP_INVALID_SYNTAX;
4167 asn1_integer2str(xcert->cert_info->serialNumber, &serial);
4169 xintegerNormalize( slap_schema.si_syn_integer,
4170 &serial, &keys[i] );
4171 ber_memfree(serial.bv_val);
4173 LDAP_LOG( CONFIG, ENTRY,
4174 "certificateExactIndexer: returning: %s\n", keys[i].bv_val, 0, 0);
4176 Debug( LDAP_DEBUG_ARGS, "certificateExactIndexer: "
4183 keys[i].bv_val = NULL;
4185 return LDAP_SUCCESS;
4188 /* Index generation function */
4189 /* We think this is always called with a value in matching rule syntax */
4190 static int certificateExactFilter(
4195 struct berval *prefix,
4196 void * assertedValue,
4200 struct berval asserted_serial;
4203 ret = serial_and_issuer_parse( assertedValue, &asserted_serial, NULL );
4204 if( ret != LDAP_SUCCESS ) return ret;
4206 keys = ch_malloc( sizeof( struct berval ) * 2 );
4207 xintegerNormalize( syntax, &asserted_serial, &keys[0] );
4208 keys[1].bv_val = NULL;
4211 ber_memfree(asserted_serial.bv_val);
4212 return LDAP_SUCCESS;
4218 check_time_syntax (struct berval *val,
4222 static int ceiling[9] = { 99, 99, 11, 30, 23, 59, 59, 12, 59 };
4223 static int mdays[2][12] = {
4224 /* non-leap years */
4225 { 30, 27, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30 },
4227 { 30, 28, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30 }
4230 int part, c, tzoffset, leapyear = 0 ;
4232 if( val->bv_len == 0 ) {
4233 return LDAP_INVALID_SYNTAX;
4236 p = (char *)val->bv_val;
4237 e = p + val->bv_len;
4239 /* Ignore initial whitespace */
4240 while ( ( p < e ) && ASCII_SPACE( *p ) ) {
4244 if (e - p < 13 - (2 * start)) {
4245 return LDAP_INVALID_SYNTAX;
4248 for (part = 0; part < 9; part++) {
4252 for (part = start; part < 7; part++) {
4254 if ((part == 6) && (c == 'Z' || c == '+' || c == '-')) {
4261 return LDAP_INVALID_SYNTAX;
4263 if (c < 0 || c > 9) {
4264 return LDAP_INVALID_SYNTAX;
4270 return LDAP_INVALID_SYNTAX;
4272 if (c < 0 || c > 9) {
4273 return LDAP_INVALID_SYNTAX;
4278 if (part == 2 || part == 3) {
4281 if (parts[part] < 0) {
4282 return LDAP_INVALID_SYNTAX;
4284 if (parts[part] > ceiling[part]) {
4285 return LDAP_INVALID_SYNTAX;
4289 /* leapyear check for the Gregorian calendar (year>1581) */
4290 if (((parts[1] % 4 == 0) && (parts[1] != 0)) ||
4291 ((parts[0] % 4 == 0) && (parts[1] == 0)))
4296 if (parts[3] > mdays[leapyear][parts[2]]) {
4297 return LDAP_INVALID_SYNTAX;
4302 tzoffset = 0; /* UTC */
4303 } else if (c != '+' && c != '-') {
4304 return LDAP_INVALID_SYNTAX;
4308 } else /* c == '+' */ {
4313 return LDAP_INVALID_SYNTAX;
4316 for (part = 7; part < 9; part++) {
4318 if (c < 0 || c > 9) {
4319 return LDAP_INVALID_SYNTAX;
4324 if (c < 0 || c > 9) {
4325 return LDAP_INVALID_SYNTAX;
4329 if (parts[part] < 0 || parts[part] > ceiling[part]) {
4330 return LDAP_INVALID_SYNTAX;
4335 /* Ignore trailing whitespace */
4336 while ( ( p < e ) && ASCII_SPACE( *p ) ) {
4340 return LDAP_INVALID_SYNTAX;
4343 switch ( tzoffset ) {
4344 case -1: /* negativ offset to UTC, ie west of Greenwich */
4345 parts[4] += parts[7];
4346 parts[5] += parts[8];
4347 for (part = 6; --part > 0; ) { /* offset is just hhmm, no seconds */
4351 c = mdays[leapyear][parts[2]];
4353 if (parts[part] > c) {
4354 parts[part] -= c + 1;
4359 case 1: /* positive offset to UTC, ie east of Greenwich */
4360 parts[4] -= parts[7];
4361 parts[5] -= parts[8];
4362 for (part = 6; --part > 0; ) {
4366 /* first arg to % needs to be non negativ */
4367 c = mdays[leapyear][(parts[2] - 1 + 12) % 12];
4369 if (parts[part] < 0) {
4370 parts[part] += c + 1;
4375 case 0: /* already UTC */
4379 return LDAP_SUCCESS;
4382 #ifdef SUPPORT_OBSOLETE_UTC_SYNTAX
4387 struct berval *normalized )
4391 rc = check_time_syntax(val, 1, parts);
4392 if (rc != LDAP_SUCCESS) {
4396 normalized->bv_val = ch_malloc( 14 );
4397 if ( normalized->bv_val == NULL ) {
4398 return LBER_ERROR_MEMORY;
4401 sprintf( normalized->bv_val, "%02d%02d%02d%02d%02d%02dZ",
4402 parts[1], parts[2] + 1, parts[3] + 1,
4403 parts[4], parts[5], parts[6] );
4404 normalized->bv_len = 13;
4406 return LDAP_SUCCESS;
4410 #ifdef SUPPORT_OBSOLETE_UTC_SYNTAX
4418 return check_time_syntax(in, 1, parts);
4423 generalizedTimeValidate(
4429 return check_time_syntax(in, 0, parts);
4432 #ifndef SLAP_NVALUES
4435 xgeneralizedTimeNormalize(
4438 struct berval *normalized )
4442 rc = check_time_syntax(val, 0, parts);
4443 if (rc != LDAP_SUCCESS) {
4447 normalized->bv_val = ch_malloc( 16 );
4448 if ( normalized->bv_val == NULL ) {
4449 return LBER_ERROR_MEMORY;
4452 sprintf( normalized->bv_val, "%02d%02d%02d%02d%02d%02d%02dZ",
4453 parts[0], parts[1], parts[2] + 1, parts[3] + 1,
4454 parts[4], parts[5], parts[6] );
4455 normalized->bv_len = 15;
4457 return LDAP_SUCCESS;
4462 nisNetgroupTripleValidate(
4464 struct berval *val )
4469 if ( val->bv_len == 0 ) {
4470 return LDAP_INVALID_SYNTAX;
4473 p = (char *)val->bv_val;
4474 e = p + val->bv_len;
4476 if ( *p != '(' /*')'*/ ) {
4477 return LDAP_INVALID_SYNTAX;
4480 for ( p++; ( p < e ) && ( *p != /*'('*/ ')' ); p++ ) {
4484 return LDAP_INVALID_SYNTAX;
4487 } else if ( !AD_CHAR( *p ) ) {
4488 return LDAP_INVALID_SYNTAX;
4492 if ( ( commas != 2 ) || ( *p != /*'('*/ ')' ) ) {
4493 return LDAP_INVALID_SYNTAX;
4499 return LDAP_INVALID_SYNTAX;
4502 return LDAP_SUCCESS;
4506 bootParameterValidate(
4508 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;
4520 for (; ( p < e ) && ( *p != '=' ); p++ ) {
4521 if ( !AD_CHAR( *p ) ) {
4522 return LDAP_INVALID_SYNTAX;
4527 return LDAP_INVALID_SYNTAX;
4531 for ( p++; ( p < e ) && ( *p != ':' ); p++ ) {
4532 if ( !AD_CHAR( *p ) ) {
4533 return LDAP_INVALID_SYNTAX;
4538 return LDAP_INVALID_SYNTAX;
4542 for ( p++; p < e; p++ ) {
4543 if ( !SLAP_PRINTABLE( *p ) ) {
4544 return LDAP_INVALID_SYNTAX;
4548 return LDAP_SUCCESS;
4551 #define X_BINARY "X-BINARY-TRANSFER-REQUIRED 'TRUE' "
4552 #define X_NOT_H_R "X-NOT-HUMAN-READABLE 'TRUE' "
4554 static slap_syntax_defs_rec syntax_defs[] = {
4555 {"( 1.3.6.1.4.1.1466.115.121.1.1 DESC 'ACI Item' "
4556 X_BINARY X_NOT_H_R ")",
4557 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, NULL, NULL, NULL},
4558 {"( 1.3.6.1.4.1.1466.115.121.1.2 DESC 'Access Point' " X_NOT_H_R ")",
4559 0, NULL, NULL, NULL},
4560 {"( 1.3.6.1.4.1.1466.115.121.1.3 DESC 'Attribute Type Description' )",
4561 0, NULL, NULL, NULL},
4562 {"( 1.3.6.1.4.1.1466.115.121.1.4 DESC 'Audio' "
4564 SLAP_SYNTAX_BLOB, blobValidate, NULL, NULL},
4565 {"( 1.3.6.1.4.1.1466.115.121.1.5 DESC 'Binary' "
4567 SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4568 {"( 1.3.6.1.4.1.1466.115.121.1.6 DESC 'Bit String' )",
4569 0, bitStringValidate, NULL, NULL },
4570 {"( 1.3.6.1.4.1.1466.115.121.1.7 DESC 'Boolean' )",
4571 0, booleanValidate, NULL, NULL},
4572 {"( 1.3.6.1.4.1.1466.115.121.1.8 DESC 'Certificate' "
4573 X_BINARY X_NOT_H_R ")",
4574 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4575 {"( 1.3.6.1.4.1.1466.115.121.1.9 DESC 'Certificate List' "
4576 X_BINARY X_NOT_H_R ")",
4577 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4578 {"( 1.3.6.1.4.1.1466.115.121.1.10 DESC 'Certificate Pair' "
4579 X_BINARY X_NOT_H_R ")",
4580 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4581 {"( 1.3.6.1.4.1.1466.115.121.1.11 DESC 'Country String' )",
4582 0, countryStringValidate, xIA5StringNormalize, NULL},
4583 {"( 1.3.6.1.4.1.1466.115.121.1.12 DESC 'Distinguished Name' )",
4584 0, dnValidate, dnNormalize2, dnPretty2},
4585 {"( 1.3.6.1.4.1.1466.115.121.1.13 DESC 'Data Quality' )",
4586 0, NULL, NULL, NULL},
4587 {"( 1.3.6.1.4.1.1466.115.121.1.14 DESC 'Delivery Method' )",
4588 0, NULL, NULL, NULL},
4589 {"( 1.3.6.1.4.1.1466.115.121.1.15 DESC 'Directory String' )",
4590 0, UTF8StringValidate, xUTF8StringNormalize, NULL},
4591 {"( 1.3.6.1.4.1.1466.115.121.1.16 DESC 'DIT Content Rule Description' )",
4592 0, NULL, NULL, NULL},
4593 {"( 1.3.6.1.4.1.1466.115.121.1.17 DESC 'DIT Structure Rule Description' )",
4594 0, NULL, NULL, NULL},
4595 {"( 1.3.6.1.4.1.1466.115.121.1.19 DESC 'DSA Quality' )",
4596 0, NULL, NULL, NULL},
4597 {"( 1.3.6.1.4.1.1466.115.121.1.20 DESC 'DSE Type' )",
4598 0, NULL, NULL, NULL},
4599 {"( 1.3.6.1.4.1.1466.115.121.1.21 DESC 'Enhanced Guide' )",
4600 0, NULL, NULL, NULL},
4601 {"( 1.3.6.1.4.1.1466.115.121.1.22 DESC 'Facsimile Telephone Number' )",
4602 0, printablesStringValidate, xtelephoneNumberNormalize, NULL},
4603 {"( 1.3.6.1.4.1.1466.115.121.1.23 DESC 'Fax' " X_NOT_H_R ")",
4604 SLAP_SYNTAX_BLOB, NULL, NULL, NULL},
4605 {"( 1.3.6.1.4.1.1466.115.121.1.24 DESC 'Generalized Time' )",
4606 0, generalizedTimeValidate, xgeneralizedTimeNormalize, NULL},
4607 {"( 1.3.6.1.4.1.1466.115.121.1.25 DESC 'Guide' )",
4608 0, NULL, NULL, NULL},
4609 {"( 1.3.6.1.4.1.1466.115.121.1.26 DESC 'IA5 String' )",
4610 0, IA5StringValidate, xIA5StringNormalize, NULL},
4611 {"( 1.3.6.1.4.1.1466.115.121.1.27 DESC 'Integer' )",
4612 0, integerValidate, xintegerNormalize, NULL},
4613 {"( 1.3.6.1.4.1.1466.115.121.1.28 DESC 'JPEG' " X_NOT_H_R ")",
4614 SLAP_SYNTAX_BLOB, blobValidate, NULL, NULL},
4615 {"( 1.3.6.1.4.1.1466.115.121.1.29 DESC 'Master And Shadow Access Points' )",
4616 0, NULL, NULL, NULL},
4617 {"( 1.3.6.1.4.1.1466.115.121.1.30 DESC 'Matching Rule Description' )",
4618 0, NULL, NULL, NULL},
4619 {"( 1.3.6.1.4.1.1466.115.121.1.31 DESC 'Matching Rule Use Description' )",
4620 0, NULL, NULL, NULL},
4621 {"( 1.3.6.1.4.1.1466.115.121.1.32 DESC 'Mail Preference' )",
4622 0, NULL, NULL, NULL},
4623 {"( 1.3.6.1.4.1.1466.115.121.1.33 DESC 'MHS OR Address' )",
4624 0, NULL, NULL, NULL},
4625 {"( 1.3.6.1.4.1.1466.115.121.1.34 DESC 'Name And Optional UID' )",
4626 0, nameUIDValidate, xnameUIDNormalize, NULL},
4627 {"( 1.3.6.1.4.1.1466.115.121.1.35 DESC 'Name Form Description' )",
4628 0, NULL, NULL, NULL},
4629 {"( 1.3.6.1.4.1.1466.115.121.1.36 DESC 'Numeric String' )",
4630 0, numericStringValidate, xnumericStringNormalize, NULL},
4631 {"( 1.3.6.1.4.1.1466.115.121.1.37 DESC 'Object Class Description' )",
4632 0, NULL, NULL, NULL},
4633 {"( 1.3.6.1.4.1.1466.115.121.1.38 DESC 'OID' )",
4634 0, oidValidate, NULL, NULL},
4635 {"( 1.3.6.1.4.1.1466.115.121.1.39 DESC 'Other Mailbox' )",
4636 0, IA5StringValidate, xIA5StringNormalize, NULL},
4637 {"( 1.3.6.1.4.1.1466.115.121.1.40 DESC 'Octet String' )",
4638 0, blobValidate, NULL, NULL},
4639 {"( 1.3.6.1.4.1.1466.115.121.1.41 DESC 'Postal Address' )",
4640 0, UTF8StringValidate, xUTF8StringNormalize, NULL},
4641 {"( 1.3.6.1.4.1.1466.115.121.1.42 DESC 'Protocol Information' )",
4642 0, NULL, NULL, NULL},
4643 {"( 1.3.6.1.4.1.1466.115.121.1.43 DESC 'Presentation Address' )",
4644 0, NULL, NULL, NULL},
4645 {"( 1.3.6.1.4.1.1466.115.121.1.44 DESC 'Printable String' )",
4646 0, printableStringValidate, xIA5StringNormalize, NULL},
4647 {"( 1.3.6.1.4.1.1466.115.121.1.45 DESC 'SubtreeSpecification' "
4648 X_BINARY X_NOT_H_R ")",
4649 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, NULL, NULL, NULL},
4650 {"( 1.3.6.1.4.1.1466.115.121.1.49 DESC 'Supported Algorithm' "
4651 X_BINARY X_NOT_H_R ")",
4652 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4653 {"( 1.3.6.1.4.1.1466.115.121.1.50 DESC 'Telephone Number' )",
4654 0, printableStringValidate, xtelephoneNumberNormalize, NULL},
4655 {"( 1.3.6.1.4.1.1466.115.121.1.51 DESC 'Teletex Terminal Identifier' )",
4656 0, NULL, NULL, NULL},
4657 {"( 1.3.6.1.4.1.1466.115.121.1.52 DESC 'Telex Number' )",
4658 0, printablesStringValidate, xIA5StringNormalize, NULL},
4659 #ifdef SUPPORT_OBSOLETE_UTC_SYNTAX
4660 {"( 1.3.6.1.4.1.1466.115.121.1.53 DESC 'UTC Time' )",
4661 0, utcTimeValidate, xutcTimeNormalize, NULL},
4663 {"( 1.3.6.1.4.1.1466.115.121.1.54 DESC 'LDAP Syntax Description' )",
4664 0, NULL, NULL, NULL},
4665 {"( 1.3.6.1.4.1.1466.115.121.1.55 DESC 'Modify Rights' )",
4666 0, NULL, NULL, NULL},
4667 {"( 1.3.6.1.4.1.1466.115.121.1.56 DESC 'LDAP Schema Definition' )",
4668 0, NULL, NULL, NULL},
4669 {"( 1.3.6.1.4.1.1466.115.121.1.57 DESC 'LDAP Schema Description' )",
4670 0, NULL, NULL, NULL},
4671 {"( 1.3.6.1.4.1.1466.115.121.1.58 DESC 'Substring Assertion' )",
4672 0, NULL, NULL, NULL},
4674 /* RFC 2307 NIS Syntaxes */
4675 {"( 1.3.6.1.1.1.0.0 DESC 'RFC2307 NIS Netgroup Triple' )",
4676 0, nisNetgroupTripleValidate, NULL, NULL},
4677 {"( 1.3.6.1.1.1.0.1 DESC 'RFC2307 Boot Parameter' )",
4678 0, bootParameterValidate, NULL, NULL},
4682 /* These OIDs are not published yet, but will be in the next
4683 * I-D for PKIX LDAPv3 schema as have been advanced by David
4684 * Chadwick in private mail.
4686 {"( 1.2.826.0.1.3344810.7.1 DESC 'Serial Number and Issuer' )",
4687 0, UTF8StringValidate, NULL, NULL},
4690 /* OpenLDAP Experimental Syntaxes */
4691 #ifdef SLAPD_ACI_ENABLED
4692 {"( 1.3.6.1.4.1.4203.666.2.1 DESC 'OpenLDAP Experimental ACI' )",
4694 UTF8StringValidate /* THIS WILL CHANGE FOR NEW ACI SYNTAX */,
4698 #ifdef SLAPD_AUTHPASSWD
4699 /* needs updating */
4700 {"( 1.3.6.1.4.1.4203.666.2.2 DESC 'OpenLDAP authPassword' )",
4701 SLAP_SYNTAX_HIDE, NULL, NULL, NULL},
4704 /* OpenLDAP Void Syntax */
4705 {"( 1.3.6.1.4.1.4203.1.1.1 DESC 'OpenLDAP void' )" ,
4706 SLAP_SYNTAX_HIDE, inValidate, NULL, NULL},
4707 {NULL, 0, NULL, NULL, NULL}
4711 char *certificateExactMatchSyntaxes[] = {
4712 "1.3.6.1.4.1.1466.115.121.1.8" /* certificate */,
4716 char *directoryStringSyntaxes[] = {
4717 "1.3.6.1.4.1.1466.115.121.1.44" /* printableString */,
4720 char *integerFirstComponentMatchSyntaxes[] = {
4721 "1.3.6.1.4.1.1466.115.121.1.27" /* INTEGER */,
4722 "1.3.6.1.4.1.1466.115.121.1.17" /* ditStructureRuleDescription */,
4725 char *objectIdentifierFirstComponentMatchSyntaxes[] = {
4726 "1.3.6.1.4.1.1466.115.121.1.38" /* OID */,
4727 "1.3.6.1.4.1.1466.115.121.1.3" /* attributeTypeDescription */,
4728 "1.3.6.1.4.1.1466.115.121.1.16" /* ditContentRuleDescription */,
4729 "1.3.6.1.4.1.1466.115.121.1.54" /* ldapSyntaxDescription */,
4730 "1.3.6.1.4.1.1466.115.121.1.30" /* matchingRuleDescription */,
4731 "1.3.6.1.4.1.1466.115.121.1.31" /* matchingRuleUseDescription */,
4732 "1.3.6.1.4.1.1466.115.121.1.35" /* nameFormDescription */,
4733 "1.3.6.1.4.1.1466.115.121.1.37" /* objectClassDescription */,
4738 * Other matching rules in X.520 that we do not use (yet):
4740 * 2.5.13.9 numericStringOrderingMatch
4741 * 2.5.13.19 octetStringSubstringsMatch
4742 * 2.5.13.25 uTCTimeMatch
4743 * 2.5.13.26 uTCTimeOrderingMatch
4744 * 2.5.13.31 directoryStringFirstComponentMatch
4745 * 2.5.13.32 wordMatch
4746 * 2.5.13.33 keywordMatch
4747 * 2.5.13.35 certificateMatch
4748 * 2.5.13.36 certificatePairExactMatch
4749 * 2.5.13.37 certificatePairMatch
4750 * 2.5.13.38 certificateListExactMatch
4751 * 2.5.13.39 certificateListMatch
4752 * 2.5.13.40 algorithmIdentifierMatch
4753 * 2.5.13.41 storedPrefixMatch
4754 * 2.5.13.42 attributeCertificateMatch
4755 * 2.5.13.43 readerAndKeyIDMatch
4756 * 2.5.13.44 attributeIntegrityMatch
4758 static slap_mrule_defs_rec mrule_defs[] = {
4760 * EQUALITY matching rules must be listed after associated APPROX
4761 * matching rules. So, we list all APPROX matching rules first.
4763 #ifndef SLAP_NVALUES
4764 {"( " directoryStringApproxMatchOID " NAME 'directoryStringApproxMatch' "
4765 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4766 SLAP_MR_HIDE | SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT, NULL,
4767 NULL, NULL, directoryStringApproxMatch,
4768 directoryStringApproxIndexer, directoryStringApproxFilter,
4771 {"( " IA5StringApproxMatchOID " NAME 'IA5StringApproxMatch' "
4772 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4773 SLAP_MR_HIDE | SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT, NULL,
4774 NULL, NULL, IA5StringApproxMatch,
4775 IA5StringApproxIndexer, IA5StringApproxFilter,
4780 * Other matching rules
4783 {"( 2.5.13.0 NAME 'objectIdentifierMatch' "
4784 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
4785 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4787 objectIdentifierNormalize, objectIdentifierMatch,
4788 objectIdentifierIndexer, objectIdentifierFilter,
4791 {"( 2.5.13.1 NAME 'distinguishedNameMatch' "
4792 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )",
4793 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4795 distinguishedNameNormalize, distinguishedNameMatch,
4796 distinguishedNameIndexer, distinguishedNameFilter,
4799 {"( 2.5.13.2 NAME 'caseIgnoreMatch' "
4800 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4801 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD,
4802 directoryStringSyntaxes,
4804 caseIgnoreNormalize, caseIgnoreMatch,
4805 caseIgnoreIndexer, caseIgnoreFilter,
4806 directoryStringApproxMatchOID },
4808 {"( 2.5.13.3 NAME 'caseIgnoreOrderingMatch' "
4809 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4810 SLAP_MR_ORDERING, directoryStringSyntaxes,
4811 NULL, caseIgnoreNormalize, caseIgnoreOrderingMatch,
4814 {"( 2.5.13.4 NAME 'caseIgnoreSubstringsMatch' "
4815 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4816 SLAP_MR_SUBSTR, NULL,
4818 caseIgnoreSubstringsMatch,
4819 caseIgnoreSubstringsIndexer, caseIgnoreSubstringsFilter,
4822 {"( 2.5.13.5 NAME 'caseExactMatch' "
4823 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4824 SLAP_MR_EQUALITY | SLAP_MR_EXT, directoryStringSyntaxes,
4826 caseExactNormalize, caseExactMatch,
4827 caseExactIndexer, caseExactFilter,
4828 directoryStringApproxMatchOID },
4830 {"( 2.5.13.6 NAME 'caseExactOrderingMatch' "
4831 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4832 SLAP_MR_ORDERING, directoryStringSyntaxes,
4833 NULL, caseExactNormalize, caseExactOrderingMatch,
4836 {"( 2.5.13.7 NAME 'caseExactSubstringsMatch' "
4837 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4838 SLAP_MR_SUBSTR, directoryStringSyntaxes,
4840 NULL, caseExactSubstringsMatch,
4841 caseExactSubstringsIndexer, caseExactSubstringsFilter,
4844 {"( 2.5.13.8 NAME 'numericStringMatch' "
4845 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 )",
4846 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL,
4848 numericStringNormalize, numericStringMatch,
4849 numericStringIndexer, numericStringFilter,
4852 {"( 2.5.13.10 NAME 'numericStringSubstringsMatch' "
4853 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4854 SLAP_MR_SUBSTR, NULL,
4856 NULL, numericStringSubstringsMatch,
4857 numericStringSubstringsIndexer, numericStringSubstringsFilter,
4860 {"( 2.5.13.11 NAME 'caseIgnoreListMatch' "
4861 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )",
4862 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL,
4863 NULL, NULL, NULL, NULL, NULL, NULL},
4865 {"( 2.5.13.12 NAME 'caseIgnoreListSubstringsMatch' "
4866 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4867 SLAP_MR_SUBSTR, NULL,
4868 NULL, NULL, NULL, NULL, NULL, NULL},
4870 {"( 2.5.13.13 NAME 'booleanMatch' "
4871 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )",
4872 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4873 NULL, NULL, booleanMatch, NULL, NULL, NULL},
4875 {"( 2.5.13.14 NAME 'integerMatch' "
4876 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4877 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4879 integerNormalize, integerMatch,
4880 integerIndexer, integerFilter,
4883 {"( 2.5.13.15 NAME 'integerOrderingMatch' "
4884 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4885 SLAP_MR_ORDERING, NULL, NULL,
4886 integerNormalize, integerOrderingMatch,
4887 integerIndexer, integerFilter,
4890 {"( 2.5.13.16 NAME 'bitStringMatch' "
4891 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.6 )",
4892 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4894 bitStringNormalize, bitStringMatch,
4895 bitStringIndexer, bitStringFilter,
4898 {"( 2.5.13.17 NAME 'octetStringMatch' "
4899 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
4900 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4902 octetStringMatch, octetStringIndexer, octetStringFilter,
4905 {"( 2.5.13.18 NAME 'octetStringOrderingMatch' "
4906 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
4907 SLAP_MR_ORDERING, NULL,
4909 octetStringOrderingMatch, NULL, NULL,
4912 {"( 2.5.13.20 NAME 'telephoneNumberMatch' "
4913 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 )",
4914 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL,
4916 telephoneNumberNormalize, telephoneNumberMatch,
4917 telephoneNumberIndexer, telephoneNumberFilter,
4920 {"( 2.5.13.21 NAME 'telephoneNumberSubstringsMatch' "
4921 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4922 SLAP_MR_SUBSTR, NULL,
4923 NULL, NULL, telephoneNumberSubstringsMatch,
4924 telephoneNumberSubstringsIndexer, telephoneNumberSubstringsFilter,
4927 {"( 2.5.13.22 NAME 'presentationAddressMatch' "
4928 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.43 )",
4929 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4934 {"( 2.5.13.23 NAME 'uniqueMemberMatch' "
4935 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.34 )",
4936 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4938 uniqueMemberNormalize, uniqueMemberMatch,
4942 {"( 2.5.13.24 NAME 'protocolInformationMatch' "
4943 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.42 )",
4944 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4945 NULL, NULL, NULL, NULL, NULL, NULL},
4947 {"( 2.5.13.27 NAME 'generalizedTimeMatch' "
4948 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
4949 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4951 generalizedTimeNormalize, generalizedTimeMatch,
4955 {"( 2.5.13.28 NAME 'generalizedTimeOrderingMatch' "
4956 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
4957 SLAP_MR_ORDERING, NULL,
4959 generalizedTimeNormalize, generalizedTimeOrderingMatch,
4963 {"( 2.5.13.29 NAME 'integerFirstComponentMatch' "
4964 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4965 SLAP_MR_EQUALITY | SLAP_MR_EXT, integerFirstComponentMatchSyntaxes,
4967 integerFirstComponentNormalize, integerMatch,
4971 {"( 2.5.13.30 NAME 'objectIdentifierFirstComponentMatch' "
4972 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
4973 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4974 objectIdentifierFirstComponentMatchSyntaxes,
4976 objectIdentifierFirstComponentNormalize, objectIdentifierMatch,
4980 #ifndef SLAP_NVALUES
4982 {"( 2.5.13.34 NAME 'certificateExactMatch' "
4983 "SYNTAX 1.2.826.0.1.3344810.7.1 )",
4984 SLAP_MR_EQUALITY | SLAP_MR_EXT, certificateExactMatchSyntaxes,
4985 certificateExactConvert, NULL,
4986 certificateExactMatch,
4987 certificateExactIndexer, certificateExactFilter,
4992 {"( 1.3.6.1.4.1.1466.109.114.1 NAME 'caseExactIA5Match' "
4993 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4994 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4996 caseExactIA5Normalize, caseExactIA5Match,
4997 caseExactIA5Indexer, caseExactIA5Filter,
4998 IA5StringApproxMatchOID },
5000 {"( 1.3.6.1.4.1.1466.109.114.2 NAME 'caseIgnoreIA5Match' "
5001 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
5002 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL,
5004 NULL, caseIgnoreIA5Match,
5005 caseIgnoreIA5Indexer, caseIgnoreIA5Filter,
5006 IA5StringApproxMatchOID },
5008 {"( 1.3.6.1.4.1.1466.109.114.3 NAME 'caseIgnoreIA5SubstringsMatch' "
5009 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
5010 SLAP_MR_SUBSTR, NULL,
5012 NULL, caseIgnoreIA5SubstringsMatch,
5013 caseIgnoreIA5SubstringsIndexer, caseIgnoreIA5SubstringsFilter,
5016 {"( 1.3.6.1.4.1.4203.1.2.1 NAME 'caseExactIA5SubstringsMatch' "
5017 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
5018 SLAP_MR_SUBSTR, NULL,
5020 NULL, caseExactIA5SubstringsMatch,
5021 caseExactIA5SubstringsIndexer, caseExactIA5SubstringsFilter,
5024 #ifdef SLAPD_AUTHPASSWD
5025 /* needs updating */
5026 {"( 1.3.6.1.4.1.4203.666.4.1 NAME 'authPasswordMatch' "
5027 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
5028 SLAP_MR_EQUALITY, NULL,
5030 authPasswordMatch, NULL, NULL,
5034 #ifdef SLAPD_ACI_ENABLED
5035 {"( 1.3.6.1.4.1.4203.666.4.2 NAME 'OpenLDAPaciMatch' "
5036 "SYNTAX 1.3.6.1.4.1.4203.666.2.1 )",
5037 SLAP_MR_EQUALITY, NULL,
5039 OpenLDAPaciMatch, NULL, NULL,
5043 {"( 1.2.840.113556.1.4.803 NAME 'integerBitAndMatch' "
5044 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
5047 NULL, integerBitAndMatch, NULL, NULL,
5050 {"( 1.2.840.113556.1.4.804 NAME 'integerBitOrMatch' "
5051 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
5054 NULL, integerBitOrMatch, NULL, NULL,
5057 {NULL, SLAP_MR_NONE, NULL,
5058 NULL, NULL, NULL, NULL, NULL,
5063 slap_schema_init( void )
5068 /* we should only be called once (from main) */
5069 assert( schema_init_done == 0 );
5071 for ( i=0; syntax_defs[i].sd_desc != NULL; i++ ) {
5072 res = register_syntax( &syntax_defs[i] );
5075 fprintf( stderr, "slap_schema_init: Error registering syntax %s\n",
5076 syntax_defs[i].sd_desc );
5081 for ( i=0; mrule_defs[i].mrd_desc != NULL; i++ ) {
5082 if( mrule_defs[i].mrd_usage == SLAP_MR_NONE &&
5083 mrule_defs[i].mrd_compat_syntaxes == NULL )
5086 "slap_schema_init: Ignoring unusable matching rule %s\n",
5087 mrule_defs[i].mrd_desc );
5091 res = register_matching_rule( &mrule_defs[i] );
5095 "slap_schema_init: Error registering matching rule %s\n",
5096 mrule_defs[i].mrd_desc );
5101 res = slap_schema_load();
5102 schema_init_done = 1;
5107 schema_destroy( void )