1 /* schema_init.c - init builtin schema */
4 * Copyright 1998-2002 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)
31 /* recycled validatation routines */
32 #define berValidate blobValidate
34 /* unimplemented pretters */
35 #define integerPretty NULL
37 /* recycled matching routines */
38 #define bitStringMatch octetStringMatch
39 #define numericStringMatch caseIgnoreIA5Match
40 #define objectIdentifierMatch octetStringMatch
41 #define telephoneNumberMatch caseIgnoreIA5Match
42 #define telephoneNumberSubstringsMatch caseIgnoreIA5SubstringsMatch
43 #define generalizedTimeMatch caseIgnoreIA5Match
44 #define generalizedTimeOrderingMatch caseIgnoreIA5Match
45 #define uniqueMemberMatch dnMatch
46 #define integerFirstComponentMatch integerMatch
48 /* approx matching rules */
49 #define directoryStringApproxMatchOID "1.3.6.1.4.1.4203.666.4.4"
50 #define directoryStringApproxMatch approxMatch
51 #define directoryStringApproxIndexer approxIndexer
52 #define directoryStringApproxFilter approxFilter
53 #define IA5StringApproxMatchOID "1.3.6.1.4.1.4203.666.4.5"
54 #define IA5StringApproxMatch approxMatch
55 #define IA5StringApproxIndexer approxIndexer
56 #define IA5StringApproxFilter approxFilter
58 /* ordering matching rules */
59 #define caseIgnoreOrderingMatch caseIgnoreMatch
60 #define caseExactOrderingMatch caseExactMatch
61 #define integerOrderingMatch integerMatch
62 #define octetStringOrderingMatch octetStringMatch
64 /* unimplemented matching routines */
65 #define caseIgnoreListMatch NULL
66 #define caseIgnoreListSubstringsMatch NULL
67 #define protocolInformationMatch NULL
69 #ifdef SLAPD_ACI_ENABLED
70 #define OpenLDAPaciMatch NULL
72 #ifdef SLAPD_AUTHPASSWD
73 #define authPasswordMatch NULL
76 /* recycled indexing/filtering routines */
77 #define dnIndexer caseExactIgnoreIndexer
78 #define dnFilter caseExactIgnoreFilter
79 #define bitStringFilter octetStringFilter
80 #define bitStringIndexer octetStringIndexer
82 #define telephoneNumberIndexer caseIgnoreIA5Indexer
83 #define telephoneNumberFilter caseIgnoreIA5Filter
84 #define telephoneNumberSubstringsIndexer caseIgnoreIA5SubstringsIndexer
85 #define telephoneNumberSubstringsFilter caseIgnoreIA5SubstringsFilter
87 static MatchingRule *caseExactMatchingRule;
88 static MatchingRule *caseExactSubstringsMatchingRule;
89 static MatchingRule *integerFirstComponentMatchingRule;
91 static const struct MatchingRulePtr {
95 /* must match OIDs below */
96 { "2.5.13.5", &caseExactMatchingRule },
97 { "2.5.13.7", &caseExactSubstringsMatchingRule },
98 { "2.5.13.29", &integerFirstComponentMatchingRule }
102 static char *bvcasechr( struct berval *bv, unsigned char c, ber_len_t *len )
105 char lower = TOLOWER( c );
106 char upper = TOUPPER( c );
108 if( c == 0 ) return NULL;
110 for( i=0; i < bv->bv_len; i++ ) {
111 if( upper == bv->bv_val[i] || lower == bv->bv_val[i] ) {
113 return &bv->bv_val[i];
126 struct berval *value,
127 void *assertedValue )
129 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
132 match = memcmp( value->bv_val,
133 ((struct berval *) assertedValue)->bv_val,
141 /* Index generation function */
142 int octetStringIndexer(
147 struct berval *prefix,
154 HASH_CONTEXT HASHcontext;
155 unsigned char HASHdigest[HASH_BYTES];
156 struct berval digest;
157 digest.bv_val = HASHdigest;
158 digest.bv_len = sizeof(HASHdigest);
160 for( i=0; values[i].bv_val != NULL; i++ ) {
161 /* just count them */
164 /* we should have at least one value at this point */
167 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
169 slen = syntax->ssyn_oidlen;
170 mlen = mr->smr_oidlen;
172 for( i=0; values[i].bv_val != NULL; i++ ) {
173 HASH_Init( &HASHcontext );
174 if( prefix != NULL && prefix->bv_len > 0 ) {
175 HASH_Update( &HASHcontext,
176 prefix->bv_val, prefix->bv_len );
178 HASH_Update( &HASHcontext,
179 syntax->ssyn_oid, slen );
180 HASH_Update( &HASHcontext,
182 HASH_Update( &HASHcontext,
183 values[i].bv_val, values[i].bv_len );
184 HASH_Final( HASHdigest, &HASHcontext );
186 ber_dupbv( &keys[i], &digest );
189 keys[i].bv_val = NULL;
197 /* Index generation function */
198 int octetStringFilter(
203 struct berval *prefix,
204 void * assertedValue,
209 HASH_CONTEXT HASHcontext;
210 unsigned char HASHdigest[HASH_BYTES];
211 struct berval *value = (struct berval *) assertedValue;
212 struct berval digest;
213 digest.bv_val = HASHdigest;
214 digest.bv_len = sizeof(HASHdigest);
216 slen = syntax->ssyn_oidlen;
217 mlen = mr->smr_oidlen;
219 keys = ch_malloc( sizeof( struct berval ) * 2 );
221 HASH_Init( &HASHcontext );
222 if( prefix != NULL && prefix->bv_len > 0 ) {
223 HASH_Update( &HASHcontext,
224 prefix->bv_val, prefix->bv_len );
226 HASH_Update( &HASHcontext,
227 syntax->ssyn_oid, slen );
228 HASH_Update( &HASHcontext,
230 HASH_Update( &HASHcontext,
231 value->bv_val, value->bv_len );
232 HASH_Final( HASHdigest, &HASHcontext );
234 ber_dupbv( keys, &digest );
235 keys[1].bv_val = NULL;
248 /* no value allowed */
249 return LDAP_INVALID_SYNTAX;
257 /* any value allowed */
268 /* very unforgiving validation, requires no normalization
269 * before simplistic matching
271 if( in->bv_len < 3 ) {
272 return LDAP_INVALID_SYNTAX;
276 * rfc 2252 section 6.3 Bit String
277 * bitstring = "'" *binary-digit "'"
278 * binary-digit = "0" / "1"
279 * example: '0101111101'B
282 if( in->bv_val[0] != '\'' ||
283 in->bv_val[in->bv_len-2] != '\'' ||
284 in->bv_val[in->bv_len-1] != 'B' )
286 return LDAP_INVALID_SYNTAX;
289 for( i=in->bv_len-3; i>0; i-- ) {
290 if( in->bv_val[i] != '0' && in->bv_val[i] != '1' ) {
291 return LDAP_INVALID_SYNTAX;
302 struct berval *normalized )
305 * A normalized bitString is has no extaneous (leading) zero bits.
306 * That is, '00010'B is normalized to '10'B
307 * However, as a special case, '0'B requires no normalization.
311 /* start at the first bit */
314 /* Find the first non-zero bit */
315 while ( *p == '0' ) p++;
318 /* no non-zero bits */
319 ber_str2bv( "\'0\'B", sizeof("\'0\'B") - 1, 1, normalized );
323 normalized->bv_val = ch_malloc( val->bv_len + 1 );
325 normalized->bv_val[0] = '\'';
326 normalized->bv_len = 1;
328 for( ; *p != '\0'; p++ ) {
329 normalized->bv_val[normalized->bv_len++] = *p;
332 normalized->bv_val[normalized->bv_len] = '\0';
346 if( in->bv_len == 0 ) return LDAP_SUCCESS;
348 ber_dupbv( &dn, in );
349 if( !dn.bv_val ) return LDAP_OTHER;
351 if( dn.bv_val[dn.bv_len-1] == 'B'
352 && dn.bv_val[dn.bv_len-2] == '\'' )
354 /* assume presence of optional UID */
357 for(i=dn.bv_len-3; i>1; i--) {
358 if( dn.bv_val[i] != '0' && dn.bv_val[i] != '1' ) {
362 if( dn.bv_val[i] != '\'' || dn.bv_val[i-1] != '#' ) {
363 ber_memfree( dn.bv_val );
364 return LDAP_INVALID_SYNTAX;
367 /* trim the UID to allow use of dnValidate */
368 dn.bv_val[i-1] = '\0';
372 rc = dnValidate( NULL, &dn );
374 ber_memfree( dn.bv_val );
382 struct berval *normalized )
387 ber_dupbv( &out, val );
388 if( out.bv_len != 0 ) {
389 struct berval uidin = { 0, NULL };
390 struct berval uidout = { 0, NULL };
392 if( out.bv_val[out.bv_len-1] == 'B'
393 && out.bv_val[out.bv_len-2] == '\'' )
395 /* assume presence of optional UID */
396 uidin.bv_val = strrchr( out.bv_val, '#' );
398 if( uidin.bv_val == NULL ) {
400 return LDAP_INVALID_SYNTAX;
403 uidin.bv_len = out.bv_len - (uidin.bv_val - out.bv_val);
404 out.bv_len -= uidin.bv_len--;
406 /* temporarily trim the UID */
407 *(uidin.bv_val++) = '\0';
409 rc = bitStringNormalize( syntax, &uidin, &uidout );
411 if( rc != LDAP_SUCCESS ) {
413 return LDAP_INVALID_SYNTAX;
417 #ifdef USE_DN_NORMALIZE
418 rc = dnNormalize2( NULL, &out, normalized );
420 rc = dnPretty2( NULL, &out, normalized );
423 if( rc != LDAP_SUCCESS ) {
425 free( uidout.bv_val );
426 return LDAP_INVALID_SYNTAX;
429 if( uidout.bv_len ) {
430 normalized->bv_val = ch_realloc( normalized->bv_val,
431 normalized->bv_len + uidout.bv_len + sizeof("#") );
433 /* insert the separator */
434 normalized->bv_val[normalized->bv_len++] = '#';
437 AC_MEMCPY( &normalized->bv_val[normalized->bv_len],
438 uidout.bv_val, uidout.bv_len );
439 normalized->bv_len += uidout.bv_len;
442 normalized->bv_val[normalized->bv_len] = '\0';
452 * Handling boolean syntax and matching is quite rigid.
453 * A more flexible approach would be to allow a variety
454 * of strings to be normalized and prettied into TRUE
462 /* very unforgiving validation, requires no normalization
463 * before simplistic matching
466 if( in->bv_len == 4 ) {
467 if( !memcmp( in->bv_val, "TRUE", 4 ) ) {
470 } else if( in->bv_len == 5 ) {
471 if( !memcmp( in->bv_val, "FALSE", 5 ) ) {
476 return LDAP_INVALID_SYNTAX;
485 struct berval *value,
486 void *assertedValue )
488 /* simplistic matching allowed by rigid validation */
489 struct berval *asserted = (struct berval *) assertedValue;
490 *matchp = value->bv_len != asserted->bv_len;
494 /*-------------------------------------------------------------------
495 LDAP/X.500 string syntax / matching rules have a few oddities. This
496 comment attempts to detail how slapd(8) treats them.
499 StringSyntax X.500 LDAP Matching
500 DirectoryString CHOICE UTF8 i/e + ignore insignificant spaces
501 PrintableString subset subset i/e + ignore insignificant spaces
502 NumericString subset subset ignore all spaces
503 IA5String ASCII ASCII i/e + ignore insignificant spaces
504 TeletexString T.61 T.61 i/e + ignore insignificant spaces
506 TelephoneNumber subset subset i + ignore all spaces and "-"
508 See draft-ietf-ldapbis-strpro for details (once published).
512 In X.500(93), a directory string can be either a PrintableString,
513 a bmpString, or a UniversalString (e.g., UCS (a subset of Unicode)).
514 In later versions, more CHOICEs were added. In all cases the string
517 In LDAPv3, a directory string is a UTF-8 encoded UCS string.
519 For matching, there are both case ignore and exact rules. Both
520 also require that "insignificant" spaces be ignored.
521 spaces before the first non-space are ignored;
522 spaces after the last non-space are ignored;
523 spaces after a space are ignored.
524 Note: by these rules (and as clarified in X.520), a string of only
525 spaces is to be treated as if held one space, not empty (which
526 would be a syntax error).
529 In ASN.1, numeric string is just a string of digits and spaces
530 and could be empty. However, in X.500, all attribute values of
531 numeric string carry a non-empty constraint. For example:
533 internationalISDNNumber ATTRIBUTE ::= {
534 WITH SYNTAX InternationalISDNNumber
535 EQUALITY MATCHING RULE numericStringMatch
536 SUBSTRINGS MATCHING RULE numericStringSubstringsMatch
537 ID id-at-internationalISDNNumber }
538 InternationalISDNNumber ::=
539 NumericString (SIZE(1..ub-international-isdn-number))
541 Unforunately, some assertion values are don't carry the same
542 constraint (but its unclear how such an assertion could ever
543 be true). In LDAP, there is one syntax (numericString) not two
544 (numericString with constraint, numericString without constraint).
545 This should be treated as numericString with non-empty constraint.
546 Note that while someone may have no ISDN number, there are no ISDN
547 numbers which are zero length.
549 In matching, spaces are ignored.
552 In ASN.1, Printable string is just a string of printable characters
553 and can be empty. In X.500, semantics much like NumericString (see
554 serialNumber for a like example) excepting uses insignificant space
555 handling instead of ignore all spaces.
558 Basically same as PrintableString. There are no examples in X.500,
559 but same logic applies. So we require them to be non-empty as
562 -------------------------------------------------------------------*/
571 unsigned char *u = in->bv_val;
573 if( !in->bv_len ) return LDAP_INVALID_SYNTAX;
575 for( count = in->bv_len; count > 0; count-=len, u+=len ) {
576 /* get the length indicated by the first byte */
577 len = LDAP_UTF8_CHARLEN2( u, len );
579 /* very basic checks */
582 if( (u[5] & 0xC0) != 0x80 ) {
583 return LDAP_INVALID_SYNTAX;
586 if( (u[4] & 0xC0) != 0x80 ) {
587 return LDAP_INVALID_SYNTAX;
590 if( (u[3] & 0xC0) != 0x80 ) {
591 return LDAP_INVALID_SYNTAX;
594 if( (u[2] & 0xC0 )!= 0x80 ) {
595 return LDAP_INVALID_SYNTAX;
598 if( (u[1] & 0xC0) != 0x80 ) {
599 return LDAP_INVALID_SYNTAX;
602 /* CHARLEN already validated it */
605 return LDAP_INVALID_SYNTAX;
608 /* make sure len corresponds with the offset
609 to the next character */
610 if( LDAP_UTF8_OFFSET( u ) != len ) return LDAP_INVALID_SYNTAX;
613 if( count != 0 ) return LDAP_INVALID_SYNTAX;
622 struct berval *normalized )
627 /* validator should have refused an empty string */
628 assert( val->bv_len );
632 /* Ignore initial whitespace */
633 /* All space is ASCII. All ASCII is 1 byte */
634 for ( ; p < val->bv_val + val->bv_len && ASCII_SPACE( p[ 0 ] ); p++ );
636 normalized->bv_len = val->bv_len - (p - val->bv_val);
638 if( !normalized->bv_len ) {
639 ber_mem2bv( " ", 1, 1, normalized );
643 ber_mem2bv( p, normalized->bv_len, 1, normalized );
644 e = normalized->bv_val + normalized->bv_len;
646 assert( normalized->bv_val );
648 p = q = normalized->bv_val;
653 if ( ASCII_SPACE( *p ) ) {
658 /* Ignore the extra whitespace */
659 while ( ASCII_SPACE( *p ) ) {
663 len = LDAP_UTF8_COPY(q,p);
669 assert( normalized->bv_val <= p );
670 assert( q+len <= p );
672 /* cannot start with a space */
673 assert( !ASCII_SPACE( normalized->bv_val[0] ) );
676 * If the string ended in space, backup the pointer one
677 * position. One is enough because the above loop collapsed
678 * all whitespace to a single space.
686 /* cannot end with a space */
687 assert( !ASCII_SPACE( *q ) );
694 normalized->bv_len = q - normalized->bv_val;
699 /* Returns Unicode canonically normalized copy of a substring assertion
700 * Skipping attribute description */
701 static SubstringsAssertion *
702 UTF8SubstringsassertionNormalize(
703 SubstringsAssertion *sa,
706 SubstringsAssertion *nsa;
709 nsa = (SubstringsAssertion *)ch_calloc( 1, sizeof(SubstringsAssertion) );
714 if( sa->sa_initial.bv_val != NULL ) {
715 UTF8bvnormalize( &sa->sa_initial, &nsa->sa_initial, casefold );
716 if( nsa->sa_initial.bv_val == NULL ) {
721 if( sa->sa_any != NULL ) {
722 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
725 nsa->sa_any = (struct berval *)
726 ch_malloc( (i + 1) * sizeof(struct berval) );
728 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
729 UTF8bvnormalize( &sa->sa_any[i], &nsa->sa_any[i],
731 if( nsa->sa_any[i].bv_val == NULL ) {
735 nsa->sa_any[i].bv_val = NULL;
738 if( sa->sa_final.bv_val != NULL ) {
739 UTF8bvnormalize( &sa->sa_final, &nsa->sa_final, casefold );
740 if( nsa->sa_final.bv_val == NULL ) {
748 if ( nsa->sa_final.bv_val ) free( nsa->sa_final.bv_val );
749 if ( nsa->sa_any ) ber_bvarray_free( nsa->sa_any );
750 if ( nsa->sa_initial.bv_val ) free( nsa->sa_initial.bv_val );
755 #ifndef SLAPD_APPROX_OLDSINGLESTRING
757 #if defined(SLAPD_APPROX_INITIALS)
758 #define SLAPD_APPROX_DELIMITER "._ "
759 #define SLAPD_APPROX_WORDLEN 2
761 #define SLAPD_APPROX_DELIMITER " "
762 #define SLAPD_APPROX_WORDLEN 1
771 struct berval *value,
772 void *assertedValue )
774 struct berval *nval, *assertv;
775 char *val, **values, **words, *c;
776 int i, count, len, nextchunk=0, nextavail=0;
778 /* Yes, this is necessary */
779 nval = UTF8bvnormalize( value, NULL, LDAP_UTF8_APPROX );
785 /* Yes, this is necessary */
786 assertv = UTF8bvnormalize( ((struct berval *)assertedValue),
787 NULL, LDAP_UTF8_APPROX );
788 if( assertv == NULL ) {
794 /* Isolate how many words there are */
795 for ( c = nval->bv_val, count = 1; *c; c++ ) {
796 c = strpbrk( c, SLAPD_APPROX_DELIMITER );
797 if ( c == NULL ) break;
802 /* Get a phonetic copy of each word */
803 words = (char **)ch_malloc( count * sizeof(char *) );
804 values = (char **)ch_malloc( count * sizeof(char *) );
805 for ( c = nval->bv_val, i = 0; i < count; i++, c += strlen(c) + 1 ) {
807 values[i] = phonetic(c);
810 /* Work through the asserted value's words, to see if at least some
811 of the words are there, in the same order. */
813 while ( (ber_len_t) nextchunk < assertv->bv_len ) {
814 len = strcspn( assertv->bv_val + nextchunk, SLAPD_APPROX_DELIMITER);
819 #if defined(SLAPD_APPROX_INITIALS)
820 else if( len == 1 ) {
821 /* Single letter words need to at least match one word's initial */
822 for( i=nextavail; i<count; i++ )
823 if( !strncasecmp( assertv->bv_val + nextchunk, words[i], 1 )) {
830 /* Isolate the next word in the asserted value and phonetic it */
831 assertv->bv_val[nextchunk+len] = '\0';
832 val = phonetic( assertv->bv_val + nextchunk );
834 /* See if this phonetic chunk is in the remaining words of *value */
835 for( i=nextavail; i<count; i++ ){
836 if( !strcmp( val, values[i] ) ){
844 /* This chunk in the asserted value was NOT within the *value. */
850 /* Go on to the next word in the asserted value */
854 /* If some of the words were seen, call it a match */
855 if( nextavail > 0 ) {
863 ber_bvfree( assertv );
864 for( i=0; i<count; i++ ) {
865 ch_free( values[i] );
880 struct berval *prefix,
885 int i,j, len, wordcount, keycount=0;
886 struct berval *newkeys;
889 for( j=0; values[j].bv_val != NULL; j++ ) {
890 struct berval val = { 0, NULL };
891 /* Yes, this is necessary */
892 UTF8bvnormalize( &values[j], &val, LDAP_UTF8_APPROX );
893 assert( val.bv_val != NULL );
895 /* Isolate how many words there are. There will be a key for each */
896 for( wordcount = 0, c = val.bv_val; *c; c++) {
897 len = strcspn(c, SLAPD_APPROX_DELIMITER);
898 if( len >= SLAPD_APPROX_WORDLEN ) wordcount++;
900 if (*c == '\0') break;
904 /* Allocate/increase storage to account for new keys */
905 newkeys = (struct berval *)ch_malloc( (keycount + wordcount + 1)
906 * sizeof(struct berval) );
907 AC_MEMCPY( newkeys, keys, keycount * sizeof(struct berval) );
908 if( keys ) ch_free( keys );
911 /* Get a phonetic copy of each word */
912 for( c = val.bv_val, i = 0; i < wordcount; c += len + 1 ) {
914 if( len < SLAPD_APPROX_WORDLEN ) continue;
915 ber_str2bv( phonetic( c ), 0, 0, &keys[keycount] );
920 ber_memfree( val.bv_val );
922 keys[keycount].bv_val = NULL;
934 struct berval *prefix,
935 void * assertedValue,
943 /* Yes, this is necessary */
944 val = UTF8bvnormalize( ((struct berval *)assertedValue),
945 NULL, LDAP_UTF8_APPROX );
946 if( val == NULL || val->bv_val == NULL ) {
947 keys = (struct berval *)ch_malloc( sizeof(struct berval) );
948 keys[0].bv_val = NULL;
954 /* Isolate how many words there are. There will be a key for each */
955 for( count = 0,c = val->bv_val; *c; c++) {
956 len = strcspn(c, SLAPD_APPROX_DELIMITER);
957 if( len >= SLAPD_APPROX_WORDLEN ) count++;
959 if (*c == '\0') break;
963 /* Allocate storage for new keys */
964 keys = (struct berval *)ch_malloc( (count + 1) * sizeof(struct berval) );
966 /* Get a phonetic copy of each word */
967 for( c = val->bv_val, i = 0; i < count; c += len + 1 ) {
969 if( len < SLAPD_APPROX_WORDLEN ) continue;
970 ber_str2bv( phonetic( c ), 0, 0, &keys[i] );
976 keys[count].bv_val = NULL;
984 /* No other form of Approximate Matching is defined */
992 struct berval *value,
993 void *assertedValue )
995 char *vapprox, *avapprox;
998 /* Yes, this is necessary */
999 s = UTF8normalize( value, UTF8_NOCASEFOLD );
1002 return LDAP_SUCCESS;
1005 /* Yes, this is necessary */
1006 t = UTF8normalize( ((struct berval *)assertedValue),
1011 return LDAP_SUCCESS;
1014 vapprox = phonetic( strip8bitChars( s ) );
1015 avapprox = phonetic( strip8bitChars( t ) );
1020 *matchp = strcmp( vapprox, avapprox );
1023 ch_free( avapprox );
1025 return LDAP_SUCCESS;
1034 struct berval *prefix,
1042 for( i=0; values[i].bv_val != NULL; i++ ) {
1043 /* empty - just count them */
1046 /* we should have at least one value at this point */
1049 keys = (struct berval *)ch_malloc( sizeof( struct berval ) * (i+1) );
1051 /* Copy each value and run it through phonetic() */
1052 for( i=0; values[i].bv_val != NULL; i++ ) {
1053 /* Yes, this is necessary */
1054 s = UTF8normalize( &values[i], UTF8_NOCASEFOLD );
1056 /* strip 8-bit chars and run through phonetic() */
1057 ber_str2bv( phonetic( strip8bitChars( s ) ), 0, 0, &keys[i] );
1060 keys[i].bv_val = NULL;
1063 return LDAP_SUCCESS;
1073 struct berval *prefix,
1074 void * assertedValue,
1080 keys = (struct berval *)ch_malloc( sizeof( struct berval * ) * 2 );
1082 /* Yes, this is necessary */
1083 s = UTF8normalize( ((struct berval *)assertedValue),
1088 /* strip 8-bit chars and run through phonetic() */
1089 keys[0] = ber_bvstr( phonetic( strip8bitChars( s ) ) );
1095 return LDAP_SUCCESS;
1106 struct berval *value,
1107 void *assertedValue )
1109 *matchp = UTF8bvnormcmp( value,
1110 (struct berval *) assertedValue,
1111 LDAP_UTF8_NOCASEFOLD );
1112 return LDAP_SUCCESS;
1116 caseExactIgnoreSubstringsMatch(
1121 struct berval *value,
1122 void *assertedValue )
1125 SubstringsAssertion *sub = NULL;
1126 struct berval left = { 0, NULL };
1132 casefold = ( mr != caseExactSubstringsMatchingRule )
1133 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1135 if ( UTF8bvnormalize( value, &left, casefold ) == NULL ) {
1141 sub = UTF8SubstringsassertionNormalize( assertedValue, casefold );
1147 /* Add up asserted input length */
1148 if( sub->sa_initial.bv_val ) {
1149 inlen += sub->sa_initial.bv_len;
1152 for(i=0; sub->sa_any[i].bv_val != NULL; i++) {
1153 inlen += sub->sa_any[i].bv_len;
1156 if( sub->sa_final.bv_val ) {
1157 inlen += sub->sa_final.bv_len;
1160 if( sub->sa_initial.bv_val ) {
1161 if( inlen > left.bv_len ) {
1166 match = memcmp( sub->sa_initial.bv_val, left.bv_val,
1167 sub->sa_initial.bv_len );
1173 left.bv_val += sub->sa_initial.bv_len;
1174 left.bv_len -= sub->sa_initial.bv_len;
1175 inlen -= sub->sa_initial.bv_len;
1178 if( sub->sa_final.bv_val ) {
1179 if( inlen > left.bv_len ) {
1184 match = memcmp( sub->sa_final.bv_val,
1185 &left.bv_val[left.bv_len - sub->sa_final.bv_len],
1186 sub->sa_final.bv_len );
1192 left.bv_len -= sub->sa_final.bv_len;
1193 inlen -= sub->sa_final.bv_len;
1197 for(i=0; sub->sa_any[i].bv_val; i++) {
1202 if( inlen > left.bv_len ) {
1203 /* not enough length */
1208 if( sub->sa_any[i].bv_len == 0 ) {
1212 p = ber_bvchr( &left, *sub->sa_any[i].bv_val );
1218 idx = p - left.bv_val;
1220 if( idx >= left.bv_len ) {
1221 /* this shouldn't happen */
1223 if ( sub->sa_final.bv_val )
1224 ch_free( sub->sa_final.bv_val );
1226 ber_bvarray_free( sub->sa_any );
1227 if ( sub->sa_initial.bv_val )
1228 ch_free( sub->sa_initial.bv_val );
1236 if( sub->sa_any[i].bv_len > left.bv_len ) {
1237 /* not enough left */
1242 match = memcmp( left.bv_val,
1243 sub->sa_any[i].bv_val,
1244 sub->sa_any[i].bv_len );
1252 left.bv_val += sub->sa_any[i].bv_len;
1253 left.bv_len -= sub->sa_any[i].bv_len;
1254 inlen -= sub->sa_any[i].bv_len;
1261 if ( sub->sa_final.bv_val ) free( sub->sa_final.bv_val );
1262 if ( sub->sa_any ) ber_bvarray_free( sub->sa_any );
1263 if ( sub->sa_initial.bv_val ) free( sub->sa_initial.bv_val );
1267 return LDAP_SUCCESS;
1270 /* Index generation function */
1271 static int caseExactIgnoreIndexer(
1276 struct berval *prefix,
1284 HASH_CONTEXT HASHcontext;
1285 unsigned char HASHdigest[HASH_BYTES];
1286 struct berval digest;
1287 digest.bv_val = HASHdigest;
1288 digest.bv_len = sizeof(HASHdigest);
1290 for( i=0; values[i].bv_val != NULL; i++ ) {
1291 /* empty - just count them */
1294 /* we should have at least one value at this point */
1297 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
1299 slen = syntax->ssyn_oidlen;
1300 mlen = mr->smr_oidlen;
1302 casefold = ( mr != caseExactMatchingRule )
1303 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1305 for( i=0; values[i].bv_val != NULL; i++ ) {
1306 struct berval value;
1307 UTF8bvnormalize( &values[i], &value, casefold );
1309 HASH_Init( &HASHcontext );
1310 if( prefix != NULL && prefix->bv_len > 0 ) {
1311 HASH_Update( &HASHcontext,
1312 prefix->bv_val, prefix->bv_len );
1314 HASH_Update( &HASHcontext,
1315 syntax->ssyn_oid, slen );
1316 HASH_Update( &HASHcontext,
1317 mr->smr_oid, mlen );
1318 HASH_Update( &HASHcontext,
1319 value.bv_val, value.bv_len );
1320 HASH_Final( HASHdigest, &HASHcontext );
1322 free( value.bv_val );
1324 ber_dupbv( &keys[i], &digest );
1327 keys[i].bv_val = NULL;
1329 return LDAP_SUCCESS;
1332 /* Index generation function */
1333 static int caseExactIgnoreFilter(
1338 struct berval *prefix,
1339 void * assertedValue,
1345 HASH_CONTEXT HASHcontext;
1346 unsigned char HASHdigest[HASH_BYTES];
1347 struct berval value = { 0, NULL };
1348 struct berval digest;
1350 digest.bv_val = HASHdigest;
1351 digest.bv_len = sizeof(HASHdigest);
1353 slen = syntax->ssyn_oidlen;
1354 mlen = mr->smr_oidlen;
1356 casefold = ( mr != caseExactMatchingRule )
1357 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1359 UTF8bvnormalize( (struct berval *) assertedValue, &value, casefold );
1360 /* This usually happens if filter contains bad UTF8 */
1361 if( value.bv_val == NULL ) {
1362 keys = ch_malloc( sizeof( struct berval ) );
1363 keys[0].bv_val = NULL;
1364 return LDAP_SUCCESS;
1367 keys = ch_malloc( sizeof( struct berval ) * 2 );
1369 HASH_Init( &HASHcontext );
1370 if( prefix != NULL && prefix->bv_len > 0 ) {
1371 HASH_Update( &HASHcontext,
1372 prefix->bv_val, prefix->bv_len );
1374 HASH_Update( &HASHcontext,
1375 syntax->ssyn_oid, slen );
1376 HASH_Update( &HASHcontext,
1377 mr->smr_oid, mlen );
1378 HASH_Update( &HASHcontext,
1379 value.bv_val, value.bv_len );
1380 HASH_Final( HASHdigest, &HASHcontext );
1382 ber_dupbv( keys, &digest );
1383 keys[1].bv_val = NULL;
1385 free( value.bv_val );
1388 return LDAP_SUCCESS;
1391 /* Substrings Index generation function */
1392 static int caseExactIgnoreSubstringsIndexer(
1397 struct berval *prefix,
1407 HASH_CONTEXT HASHcontext;
1408 unsigned char HASHdigest[HASH_BYTES];
1409 struct berval digest;
1410 digest.bv_val = HASHdigest;
1411 digest.bv_len = sizeof(HASHdigest);
1415 for( i=0; values[i].bv_val != NULL; i++ ) {
1416 /* empty - just count them */
1419 /* we should have at least one value at this point */
1422 casefold = ( mr != caseExactSubstringsMatchingRule )
1423 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1425 nvalues = ch_malloc( sizeof( struct berval ) * (i+1) );
1426 for( i=0; values[i].bv_val != NULL; i++ ) {
1427 UTF8bvnormalize( &values[i], &nvalues[i], casefold );
1429 nvalues[i].bv_val = NULL;
1432 for( i=0; values[i].bv_val != NULL; i++ ) {
1433 /* count number of indices to generate */
1434 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
1438 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
1439 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1440 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
1441 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
1443 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
1447 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
1448 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1449 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
1453 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
1454 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1455 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
1456 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
1458 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
1464 /* no keys to generate */
1466 ber_bvarray_free( nvalues );
1467 return LDAP_SUCCESS;
1470 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
1472 slen = syntax->ssyn_oidlen;
1473 mlen = mr->smr_oidlen;
1476 for( i=0; values[i].bv_val != NULL; i++ ) {
1479 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
1481 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
1482 ( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
1484 char pre = SLAP_INDEX_SUBSTR_PREFIX;
1485 max = values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
1487 for( j=0; j<max; j++ ) {
1488 HASH_Init( &HASHcontext );
1489 if( prefix != NULL && prefix->bv_len > 0 ) {
1490 HASH_Update( &HASHcontext,
1491 prefix->bv_val, prefix->bv_len );
1494 HASH_Update( &HASHcontext,
1495 &pre, sizeof( pre ) );
1496 HASH_Update( &HASHcontext,
1497 syntax->ssyn_oid, slen );
1498 HASH_Update( &HASHcontext,
1499 mr->smr_oid, mlen );
1500 HASH_Update( &HASHcontext,
1501 &values[i].bv_val[j],
1502 SLAP_INDEX_SUBSTR_MAXLEN );
1503 HASH_Final( HASHdigest, &HASHcontext );
1505 ber_dupbv( &keys[nkeys++], &digest );
1509 max = SLAP_INDEX_SUBSTR_MAXLEN < values[i].bv_len
1510 ? SLAP_INDEX_SUBSTR_MAXLEN : values[i].bv_len;
1512 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
1515 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
1516 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
1517 HASH_Init( &HASHcontext );
1518 if( prefix != NULL && prefix->bv_len > 0 ) {
1519 HASH_Update( &HASHcontext,
1520 prefix->bv_val, prefix->bv_len );
1522 HASH_Update( &HASHcontext,
1523 &pre, sizeof( pre ) );
1524 HASH_Update( &HASHcontext,
1525 syntax->ssyn_oid, slen );
1526 HASH_Update( &HASHcontext,
1527 mr->smr_oid, mlen );
1528 HASH_Update( &HASHcontext,
1529 values[i].bv_val, j );
1530 HASH_Final( HASHdigest, &HASHcontext );
1532 ber_dupbv( &keys[nkeys++], &digest );
1535 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
1536 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
1537 HASH_Init( &HASHcontext );
1538 if( prefix != NULL && prefix->bv_len > 0 ) {
1539 HASH_Update( &HASHcontext,
1540 prefix->bv_val, prefix->bv_len );
1542 HASH_Update( &HASHcontext,
1543 &pre, sizeof( pre ) );
1544 HASH_Update( &HASHcontext,
1545 syntax->ssyn_oid, slen );
1546 HASH_Update( &HASHcontext,
1547 mr->smr_oid, mlen );
1548 HASH_Update( &HASHcontext,
1549 &values[i].bv_val[values[i].bv_len-j], j );
1550 HASH_Final( HASHdigest, &HASHcontext );
1552 ber_dupbv( &keys[nkeys++], &digest );
1560 keys[nkeys].bv_val = NULL;
1567 ber_bvarray_free( nvalues );
1569 return LDAP_SUCCESS;
1572 static int caseExactIgnoreSubstringsFilter(
1577 struct berval *prefix,
1578 void * assertedValue,
1581 SubstringsAssertion *sa;
1584 ber_len_t nkeys = 0;
1585 size_t slen, mlen, klen;
1587 HASH_CONTEXT HASHcontext;
1588 unsigned char HASHdigest[HASH_BYTES];
1589 struct berval *value;
1590 struct berval digest;
1592 casefold = ( mr != caseExactSubstringsMatchingRule )
1593 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1595 sa = UTF8SubstringsassertionNormalize( assertedValue, casefold );
1598 return LDAP_SUCCESS;
1601 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
1602 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1607 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
1609 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
1610 if( sa->sa_any[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1611 /* don't bother accounting for stepping */
1612 nkeys += sa->sa_any[i].bv_len -
1613 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
1618 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
1619 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1625 if ( sa->sa_final.bv_val ) free( sa->sa_final.bv_val );
1626 if ( sa->sa_any ) ber_bvarray_free( sa->sa_any );
1627 if ( sa->sa_initial.bv_val ) free( sa->sa_initial.bv_val );
1630 return LDAP_SUCCESS;
1633 digest.bv_val = HASHdigest;
1634 digest.bv_len = sizeof(HASHdigest);
1636 slen = syntax->ssyn_oidlen;
1637 mlen = mr->smr_oidlen;
1639 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
1642 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
1643 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1645 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
1646 value = &sa->sa_initial;
1648 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
1649 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
1651 HASH_Init( &HASHcontext );
1652 if( prefix != NULL && prefix->bv_len > 0 ) {
1653 HASH_Update( &HASHcontext,
1654 prefix->bv_val, prefix->bv_len );
1656 HASH_Update( &HASHcontext,
1657 &pre, sizeof( pre ) );
1658 HASH_Update( &HASHcontext,
1659 syntax->ssyn_oid, slen );
1660 HASH_Update( &HASHcontext,
1661 mr->smr_oid, mlen );
1662 HASH_Update( &HASHcontext,
1663 value->bv_val, klen );
1664 HASH_Final( HASHdigest, &HASHcontext );
1666 ber_dupbv( &keys[nkeys++], &digest );
1669 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
1671 pre = SLAP_INDEX_SUBSTR_PREFIX;
1672 klen = SLAP_INDEX_SUBSTR_MAXLEN;
1674 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
1675 if( sa->sa_any[i].bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
1679 value = &sa->sa_any[i];
1682 j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
1683 j += SLAP_INDEX_SUBSTR_STEP )
1685 HASH_Init( &HASHcontext );
1686 if( prefix != NULL && prefix->bv_len > 0 ) {
1687 HASH_Update( &HASHcontext,
1688 prefix->bv_val, prefix->bv_len );
1690 HASH_Update( &HASHcontext,
1691 &pre, sizeof( pre ) );
1692 HASH_Update( &HASHcontext,
1693 syntax->ssyn_oid, slen );
1694 HASH_Update( &HASHcontext,
1695 mr->smr_oid, mlen );
1696 HASH_Update( &HASHcontext,
1697 &value->bv_val[j], klen );
1698 HASH_Final( HASHdigest, &HASHcontext );
1700 ber_dupbv( &keys[nkeys++], &digest );
1706 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
1707 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1709 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
1710 value = &sa->sa_final;
1712 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
1713 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
1715 HASH_Init( &HASHcontext );
1716 if( prefix != NULL && prefix->bv_len > 0 ) {
1717 HASH_Update( &HASHcontext,
1718 prefix->bv_val, prefix->bv_len );
1720 HASH_Update( &HASHcontext,
1721 &pre, sizeof( pre ) );
1722 HASH_Update( &HASHcontext,
1723 syntax->ssyn_oid, slen );
1724 HASH_Update( &HASHcontext,
1725 mr->smr_oid, mlen );
1726 HASH_Update( &HASHcontext,
1727 &value->bv_val[value->bv_len-klen], klen );
1728 HASH_Final( HASHdigest, &HASHcontext );
1730 ber_dupbv( &keys[nkeys++], &digest );
1734 keys[nkeys].bv_val = NULL;
1740 if ( sa->sa_final.bv_val ) free( sa->sa_final.bv_val );
1741 if ( sa->sa_any ) ber_bvarray_free( sa->sa_any );
1742 if ( sa->sa_initial.bv_val ) free( sa->sa_initial.bv_val );
1745 return LDAP_SUCCESS;
1754 struct berval *value,
1755 void *assertedValue )
1757 *matchp = UTF8bvnormcmp( value,
1758 (struct berval *) assertedValue,
1759 LDAP_UTF8_CASEFOLD );
1760 return LDAP_SUCCESS;
1763 /* Remove all spaces and '-' characters */
1765 telephoneNumberNormalize(
1768 struct berval *normalized )
1772 /* validator should have refused an empty string */
1773 assert( val->bv_len );
1775 q = normalized->bv_val = ch_malloc( val->bv_len + 1 );
1777 for( p = val->bv_val; *p; p++ ) {
1778 if ( ! ( ASCII_SPACE( *p ) || *p == '-' )) {
1784 normalized->bv_len = q - normalized->bv_val;
1786 if( normalized->bv_len == 0 ) {
1787 free( normalized->bv_val );
1788 return LDAP_INVALID_SYNTAX;
1791 return LDAP_SUCCESS;
1797 struct berval *val )
1801 if( val->bv_len == 0 ) {
1802 /* disallow empty strings */
1803 return LDAP_INVALID_SYNTAX;
1806 if( OID_LEADCHAR(val->bv_val[0]) ) {
1808 for(i=1; i < val->bv_len; i++) {
1809 if( OID_SEPARATOR( val->bv_val[i] ) ) {
1810 if( dot++ ) return 1;
1811 } else if ( OID_CHAR( val->bv_val[i] ) ) {
1814 return LDAP_INVALID_SYNTAX;
1818 return !dot ? LDAP_SUCCESS : LDAP_INVALID_SYNTAX;
1820 } else if( DESC_LEADCHAR(val->bv_val[0]) ) {
1821 for(i=1; i < val->bv_len; i++) {
1822 if( !DESC_CHAR(val->bv_val[i] ) ) {
1823 return LDAP_INVALID_SYNTAX;
1827 return LDAP_SUCCESS;
1830 return LDAP_INVALID_SYNTAX;
1839 struct berval *value,
1840 void *assertedValue )
1843 int vsign = 1, avsign = 1; /* default sign = '+' */
1844 struct berval *asserted;
1845 ber_len_t vlen, avlen;
1848 /* Skip leading space/sign/zeroes, and get the sign of the *value number */
1850 vlen = value->bv_len;
1851 if( mr == integerFirstComponentMatchingRule ) {
1852 char *tmp = memchr( v, '$', vlen );
1855 while( vlen && ASCII_SPACE( v[vlen-1] ))
1858 for( ; vlen && ( *v < '1' || '9' < *v ); v++, vlen-- ) /* ANSI 2.2.1 */
1864 /* Do the same with the *assertedValue number */
1865 asserted = (struct berval *) assertedValue;
1866 av = asserted->bv_val;
1867 avlen = asserted->bv_len;
1868 for( ; avlen && ( *av < '1' || '9' < *av ); av++, avlen-- )
1874 match = vsign - avsign;
1876 match = (vlen != avlen
1877 ? ( vlen < avlen ? -1 : 1 )
1878 : memcmp( v, av, vlen ));
1884 return LDAP_SUCCESS;
1890 struct berval *val )
1894 if( !val->bv_len ) return LDAP_INVALID_SYNTAX;
1896 if(( val->bv_val[0] == '+' ) || ( val->bv_val[0] == '-' )) {
1897 if( val->bv_len < 2 ) return LDAP_INVALID_SYNTAX;
1898 } else if( !ASCII_DIGIT(val->bv_val[0]) ) {
1899 return LDAP_INVALID_SYNTAX;
1902 for( i=1; i < val->bv_len; i++ ) {
1903 if( !ASCII_DIGIT(val->bv_val[i]) ) return LDAP_INVALID_SYNTAX;
1906 return LDAP_SUCCESS;
1913 struct berval *normalized )
1923 /* Ignore leading spaces */
1924 while ( len && ( *p == ' ' )) {
1931 negative = ( *p == '-' );
1932 if(( *p == '-' ) || ( *p == '+' )) {
1938 /* Ignore leading zeros */
1939 while ( len && ( *p == '0' )) {
1944 /* If there are no non-zero digits left, the number is zero, otherwise
1945 allocate space for the number and copy it into the buffer */
1947 normalized->bv_val = ch_strdup("0");
1948 normalized->bv_len = 1;
1951 normalized->bv_len = len+negative;
1952 normalized->bv_val = ch_malloc( normalized->bv_len + 1 );
1954 normalized->bv_val[0] = '-';
1956 AC_MEMCPY( normalized->bv_val + negative, p, len );
1957 normalized->bv_val[len+negative] = '\0';
1960 return LDAP_SUCCESS;
1963 /* Index generation function */
1964 static int integerIndexer(
1969 struct berval *prefix,
1976 HASH_CONTEXT HASHcontext;
1977 unsigned char HASHdigest[HASH_BYTES];
1978 struct berval digest;
1979 digest.bv_val = HASHdigest;
1980 digest.bv_len = sizeof(HASHdigest);
1982 for( i=0; values[i].bv_val != NULL; i++ ) {
1983 /* empty - just count them */
1986 /* we should have at least one value at this point */
1989 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
1991 slen = syntax->ssyn_oidlen;
1992 mlen = mr->smr_oidlen;
1994 for( i=0; values[i].bv_val != NULL; i++ ) {
1996 integerNormalize( syntax, &values[i], &norm );
1998 HASH_Init( &HASHcontext );
1999 if( prefix != NULL && prefix->bv_len > 0 ) {
2000 HASH_Update( &HASHcontext,
2001 prefix->bv_val, prefix->bv_len );
2003 HASH_Update( &HASHcontext,
2004 syntax->ssyn_oid, slen );
2005 HASH_Update( &HASHcontext,
2006 mr->smr_oid, mlen );
2007 HASH_Update( &HASHcontext,
2008 norm.bv_val, norm.bv_len );
2009 HASH_Final( HASHdigest, &HASHcontext );
2011 ber_dupbv( &keys[i], &digest );
2012 ch_free( norm.bv_val );
2015 keys[i].bv_val = NULL;
2017 return LDAP_SUCCESS;
2020 /* Index generation function */
2021 static int integerFilter(
2026 struct berval *prefix,
2027 void * assertedValue,
2032 HASH_CONTEXT HASHcontext;
2033 unsigned char HASHdigest[HASH_BYTES];
2035 struct berval digest;
2036 digest.bv_val = HASHdigest;
2037 digest.bv_len = sizeof(HASHdigest);
2039 slen = syntax->ssyn_oidlen;
2040 mlen = mr->smr_oidlen;
2042 integerNormalize( syntax, assertedValue, &norm );
2044 keys = ch_malloc( sizeof( struct berval ) * 2 );
2046 HASH_Init( &HASHcontext );
2047 if( prefix != NULL && prefix->bv_len > 0 ) {
2048 HASH_Update( &HASHcontext,
2049 prefix->bv_val, prefix->bv_len );
2051 HASH_Update( &HASHcontext,
2052 syntax->ssyn_oid, slen );
2053 HASH_Update( &HASHcontext,
2054 mr->smr_oid, mlen );
2055 HASH_Update( &HASHcontext,
2056 norm.bv_val, norm.bv_len );
2057 HASH_Final( HASHdigest, &HASHcontext );
2059 ber_dupbv( &keys[0], &digest );
2060 keys[1].bv_val = NULL;
2061 ch_free( norm.bv_val );
2064 return LDAP_SUCCESS;
2069 countryStringValidate(
2071 struct berval *val )
2073 if( val->bv_len != 2 ) return LDAP_INVALID_SYNTAX;
2075 if( !SLAP_PRINTABLE(val->bv_val[0]) ) {
2076 return LDAP_INVALID_SYNTAX;
2078 if( !SLAP_PRINTABLE(val->bv_val[1]) ) {
2079 return LDAP_INVALID_SYNTAX;
2082 return LDAP_SUCCESS;
2086 printableStringValidate(
2088 struct berval *val )
2092 if( val->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
2094 for(i=0; i < val->bv_len; i++) {
2095 if( !SLAP_PRINTABLE(val->bv_val[i]) ) {
2096 return LDAP_INVALID_SYNTAX;
2100 return LDAP_SUCCESS;
2104 printablesStringValidate(
2106 struct berval *val )
2110 if( val->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
2112 for(i=0,len=0; i < val->bv_len; i++) {
2113 int c = val->bv_val[i];
2117 return LDAP_INVALID_SYNTAX;
2121 } else if ( SLAP_PRINTABLE(c) ) {
2124 return LDAP_INVALID_SYNTAX;
2129 return LDAP_INVALID_SYNTAX;
2132 return LDAP_SUCCESS;
2138 struct berval *val )
2142 if( val->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
2144 for(i=0; i < val->bv_len; i++) {
2145 if( !LDAP_ASCII(val->bv_val[i]) ) {
2146 return LDAP_INVALID_SYNTAX;
2150 return LDAP_SUCCESS;
2157 struct berval *normalized )
2161 assert( val->bv_len );
2165 /* Ignore initial whitespace */
2166 while ( ASCII_SPACE( *p ) ) {
2170 normalized->bv_val = ch_strdup( p );
2171 p = q = normalized->bv_val;
2174 if ( ASCII_SPACE( *p ) ) {
2177 /* Ignore the extra whitespace */
2178 while ( ASCII_SPACE( *p ) ) {
2186 assert( normalized->bv_val <= p );
2190 * If the string ended in space, backup the pointer one
2191 * position. One is enough because the above loop collapsed
2192 * all whitespace to a single space.
2195 if ( ASCII_SPACE( q[-1] ) ) {
2199 /* null terminate */
2202 normalized->bv_len = q - normalized->bv_val;
2204 if( normalized->bv_len == 0 ) {
2205 normalized->bv_val = ch_realloc( normalized->bv_val, 2 );
2206 normalized->bv_val[0] = ' ';
2207 normalized->bv_val[1] = '\0';
2208 normalized->bv_len = 1;
2211 return LDAP_SUCCESS;
2220 struct berval *value,
2221 void *assertedValue )
2223 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
2226 match = strncmp( value->bv_val,
2227 ((struct berval *) assertedValue)->bv_val,
2232 return LDAP_SUCCESS;
2236 caseExactIA5SubstringsMatch(
2241 struct berval *value,
2242 void *assertedValue )
2245 SubstringsAssertion *sub = assertedValue;
2246 struct berval left = *value;
2250 /* Add up asserted input length */
2251 if( sub->sa_initial.bv_val ) {
2252 inlen += sub->sa_initial.bv_len;
2255 for(i=0; sub->sa_any[i].bv_val != NULL; i++) {
2256 inlen += sub->sa_any[i].bv_len;
2259 if( sub->sa_final.bv_val ) {
2260 inlen += sub->sa_final.bv_len;
2263 if( sub->sa_initial.bv_val ) {
2264 if( inlen > left.bv_len ) {
2269 match = strncmp( sub->sa_initial.bv_val, left.bv_val,
2270 sub->sa_initial.bv_len );
2276 left.bv_val += sub->sa_initial.bv_len;
2277 left.bv_len -= sub->sa_initial.bv_len;
2278 inlen -= sub->sa_initial.bv_len;
2281 if( sub->sa_final.bv_val ) {
2282 if( inlen > left.bv_len ) {
2287 match = strncmp( sub->sa_final.bv_val,
2288 &left.bv_val[left.bv_len - sub->sa_final.bv_len],
2289 sub->sa_final.bv_len );
2295 left.bv_len -= sub->sa_final.bv_len;
2296 inlen -= sub->sa_final.bv_len;
2300 for(i=0; sub->sa_any[i].bv_val; i++) {
2305 if( inlen > left.bv_len ) {
2306 /* not enough length */
2311 if( sub->sa_any[i].bv_len == 0 ) {
2315 p = strchr( left.bv_val, *sub->sa_any[i].bv_val );
2322 idx = p - left.bv_val;
2324 if( idx >= left.bv_len ) {
2325 /* this shouldn't happen */
2332 if( sub->sa_any[i].bv_len > left.bv_len ) {
2333 /* not enough left */
2338 match = strncmp( left.bv_val,
2339 sub->sa_any[i].bv_val,
2340 sub->sa_any[i].bv_len );
2348 left.bv_val += sub->sa_any[i].bv_len;
2349 left.bv_len -= sub->sa_any[i].bv_len;
2350 inlen -= sub->sa_any[i].bv_len;
2356 return LDAP_SUCCESS;
2359 /* Index generation function */
2360 static int caseExactIA5Indexer(
2365 struct berval *prefix,
2372 HASH_CONTEXT HASHcontext;
2373 unsigned char HASHdigest[HASH_BYTES];
2374 struct berval digest;
2375 digest.bv_val = HASHdigest;
2376 digest.bv_len = sizeof(HASHdigest);
2378 for( i=0; values[i].bv_val != NULL; i++ ) {
2379 /* empty - just count them */
2382 /* we should have at least one value at this point */
2385 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
2387 slen = syntax->ssyn_oidlen;
2388 mlen = mr->smr_oidlen;
2390 for( i=0; values[i].bv_val != NULL; i++ ) {
2391 struct berval *value = &values[i];
2393 HASH_Init( &HASHcontext );
2394 if( prefix != NULL && prefix->bv_len > 0 ) {
2395 HASH_Update( &HASHcontext,
2396 prefix->bv_val, prefix->bv_len );
2398 HASH_Update( &HASHcontext,
2399 syntax->ssyn_oid, slen );
2400 HASH_Update( &HASHcontext,
2401 mr->smr_oid, mlen );
2402 HASH_Update( &HASHcontext,
2403 value->bv_val, value->bv_len );
2404 HASH_Final( HASHdigest, &HASHcontext );
2406 ber_dupbv( &keys[i], &digest );
2409 keys[i].bv_val = NULL;
2411 return LDAP_SUCCESS;
2414 /* Index generation function */
2415 static int caseExactIA5Filter(
2420 struct berval *prefix,
2421 void * assertedValue,
2426 HASH_CONTEXT HASHcontext;
2427 unsigned char HASHdigest[HASH_BYTES];
2428 struct berval *value;
2429 struct berval digest;
2430 digest.bv_val = HASHdigest;
2431 digest.bv_len = sizeof(HASHdigest);
2433 slen = syntax->ssyn_oidlen;
2434 mlen = mr->smr_oidlen;
2436 value = (struct berval *) assertedValue;
2438 keys = ch_malloc( sizeof( struct berval ) * 2 );
2440 HASH_Init( &HASHcontext );
2441 if( prefix != NULL && prefix->bv_len > 0 ) {
2442 HASH_Update( &HASHcontext,
2443 prefix->bv_val, prefix->bv_len );
2445 HASH_Update( &HASHcontext,
2446 syntax->ssyn_oid, slen );
2447 HASH_Update( &HASHcontext,
2448 mr->smr_oid, mlen );
2449 HASH_Update( &HASHcontext,
2450 value->bv_val, value->bv_len );
2451 HASH_Final( HASHdigest, &HASHcontext );
2453 ber_dupbv( &keys[0], &digest );
2454 keys[1].bv_val = NULL;
2457 return LDAP_SUCCESS;
2460 /* Substrings Index generation function */
2461 static int caseExactIA5SubstringsIndexer(
2466 struct berval *prefix,
2473 HASH_CONTEXT HASHcontext;
2474 unsigned char HASHdigest[HASH_BYTES];
2475 struct berval digest;
2476 digest.bv_val = HASHdigest;
2477 digest.bv_len = sizeof(HASHdigest);
2479 /* we should have at least one value at this point */
2480 assert( values != NULL && values[0].bv_val != NULL );
2483 for( i=0; values[i].bv_val != NULL; i++ ) {
2484 /* count number of indices to generate */
2485 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
2489 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
2490 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2491 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2492 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2494 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2498 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
2499 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2500 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
2504 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
2505 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2506 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2507 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2509 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2515 /* no keys to generate */
2517 return LDAP_SUCCESS;
2520 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
2522 slen = syntax->ssyn_oidlen;
2523 mlen = mr->smr_oidlen;
2526 for( i=0; values[i].bv_val != NULL; i++ ) {
2528 struct berval *value;
2531 if( value->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
2533 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
2534 ( value->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
2536 char pre = SLAP_INDEX_SUBSTR_PREFIX;
2537 max = value->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
2539 for( j=0; j<max; j++ ) {
2540 HASH_Init( &HASHcontext );
2541 if( prefix != NULL && prefix->bv_len > 0 ) {
2542 HASH_Update( &HASHcontext,
2543 prefix->bv_val, prefix->bv_len );
2546 HASH_Update( &HASHcontext,
2547 &pre, sizeof( pre ) );
2548 HASH_Update( &HASHcontext,
2549 syntax->ssyn_oid, slen );
2550 HASH_Update( &HASHcontext,
2551 mr->smr_oid, mlen );
2552 HASH_Update( &HASHcontext,
2554 SLAP_INDEX_SUBSTR_MAXLEN );
2555 HASH_Final( HASHdigest, &HASHcontext );
2557 ber_dupbv( &keys[nkeys++], &digest );
2561 max = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2562 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2564 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
2567 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
2568 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
2569 HASH_Init( &HASHcontext );
2570 if( prefix != NULL && prefix->bv_len > 0 ) {
2571 HASH_Update( &HASHcontext,
2572 prefix->bv_val, prefix->bv_len );
2574 HASH_Update( &HASHcontext,
2575 &pre, sizeof( pre ) );
2576 HASH_Update( &HASHcontext,
2577 syntax->ssyn_oid, slen );
2578 HASH_Update( &HASHcontext,
2579 mr->smr_oid, mlen );
2580 HASH_Update( &HASHcontext,
2582 HASH_Final( HASHdigest, &HASHcontext );
2584 ber_dupbv( &keys[nkeys++], &digest );
2587 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
2588 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
2589 HASH_Init( &HASHcontext );
2590 if( prefix != NULL && prefix->bv_len > 0 ) {
2591 HASH_Update( &HASHcontext,
2592 prefix->bv_val, prefix->bv_len );
2594 HASH_Update( &HASHcontext,
2595 &pre, sizeof( pre ) );
2596 HASH_Update( &HASHcontext,
2597 syntax->ssyn_oid, slen );
2598 HASH_Update( &HASHcontext,
2599 mr->smr_oid, mlen );
2600 HASH_Update( &HASHcontext,
2601 &value->bv_val[value->bv_len-j], j );
2602 HASH_Final( HASHdigest, &HASHcontext );
2604 ber_dupbv( &keys[nkeys++], &digest );
2611 keys[nkeys].bv_val = NULL;
2618 return LDAP_SUCCESS;
2621 static int caseExactIA5SubstringsFilter(
2626 struct berval *prefix,
2627 void * assertedValue,
2630 SubstringsAssertion *sa = assertedValue;
2632 ber_len_t nkeys = 0;
2633 size_t slen, mlen, klen;
2635 HASH_CONTEXT HASHcontext;
2636 unsigned char HASHdigest[HASH_BYTES];
2637 struct berval *value;
2638 struct berval digest;
2640 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
2641 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2646 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
2648 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
2649 if( sa->sa_any[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2650 /* don't bother accounting for stepping */
2651 nkeys += sa->sa_any[i].bv_len -
2652 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
2657 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
2658 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2665 return LDAP_SUCCESS;
2668 digest.bv_val = HASHdigest;
2669 digest.bv_len = sizeof(HASHdigest);
2671 slen = syntax->ssyn_oidlen;
2672 mlen = mr->smr_oidlen;
2674 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
2677 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
2678 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2680 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
2681 value = &sa->sa_initial;
2683 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2684 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2686 HASH_Init( &HASHcontext );
2687 if( prefix != NULL && prefix->bv_len > 0 ) {
2688 HASH_Update( &HASHcontext,
2689 prefix->bv_val, prefix->bv_len );
2691 HASH_Update( &HASHcontext,
2692 &pre, sizeof( pre ) );
2693 HASH_Update( &HASHcontext,
2694 syntax->ssyn_oid, slen );
2695 HASH_Update( &HASHcontext,
2696 mr->smr_oid, mlen );
2697 HASH_Update( &HASHcontext,
2698 value->bv_val, klen );
2699 HASH_Final( HASHdigest, &HASHcontext );
2701 ber_dupbv( &keys[nkeys++], &digest );
2704 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
2706 pre = SLAP_INDEX_SUBSTR_PREFIX;
2707 klen = SLAP_INDEX_SUBSTR_MAXLEN;
2709 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
2710 if( sa->sa_any[i].bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
2714 value = &sa->sa_any[i];
2717 j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
2718 j += SLAP_INDEX_SUBSTR_STEP )
2720 HASH_Init( &HASHcontext );
2721 if( prefix != NULL && prefix->bv_len > 0 ) {
2722 HASH_Update( &HASHcontext,
2723 prefix->bv_val, prefix->bv_len );
2725 HASH_Update( &HASHcontext,
2726 &pre, sizeof( pre ) );
2727 HASH_Update( &HASHcontext,
2728 syntax->ssyn_oid, slen );
2729 HASH_Update( &HASHcontext,
2730 mr->smr_oid, mlen );
2731 HASH_Update( &HASHcontext,
2732 &value->bv_val[j], klen );
2733 HASH_Final( HASHdigest, &HASHcontext );
2735 ber_dupbv( &keys[nkeys++], &digest );
2740 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
2741 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2743 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
2744 value = &sa->sa_final;
2746 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2747 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2749 HASH_Init( &HASHcontext );
2750 if( prefix != NULL && prefix->bv_len > 0 ) {
2751 HASH_Update( &HASHcontext,
2752 prefix->bv_val, prefix->bv_len );
2754 HASH_Update( &HASHcontext,
2755 &pre, sizeof( pre ) );
2756 HASH_Update( &HASHcontext,
2757 syntax->ssyn_oid, slen );
2758 HASH_Update( &HASHcontext,
2759 mr->smr_oid, mlen );
2760 HASH_Update( &HASHcontext,
2761 &value->bv_val[value->bv_len-klen], klen );
2762 HASH_Final( HASHdigest, &HASHcontext );
2764 ber_dupbv( &keys[nkeys++], &digest );
2768 keys[nkeys].bv_val = NULL;
2775 return LDAP_SUCCESS;
2784 struct berval *value,
2785 void *assertedValue )
2787 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
2789 if( match == 0 && value->bv_len ) {
2790 match = strncasecmp( value->bv_val,
2791 ((struct berval *) assertedValue)->bv_val,
2796 return LDAP_SUCCESS;
2800 caseIgnoreIA5SubstringsMatch(
2805 struct berval *value,
2806 void *assertedValue )
2809 SubstringsAssertion *sub = assertedValue;
2810 struct berval left = *value;
2814 /* Add up asserted input length */
2815 if( sub->sa_initial.bv_val ) {
2816 inlen += sub->sa_initial.bv_len;
2819 for(i=0; sub->sa_any[i].bv_val != NULL; i++) {
2820 inlen += sub->sa_any[i].bv_len;
2823 if( sub->sa_final.bv_val ) {
2824 inlen += sub->sa_final.bv_len;
2827 if( sub->sa_initial.bv_val ) {
2828 if( inlen > left.bv_len ) {
2833 match = strncasecmp( sub->sa_initial.bv_val, left.bv_val,
2834 sub->sa_initial.bv_len );
2840 left.bv_val += sub->sa_initial.bv_len;
2841 left.bv_len -= sub->sa_initial.bv_len;
2842 inlen -= sub->sa_initial.bv_len;
2845 if( sub->sa_final.bv_val ) {
2846 if( inlen > left.bv_len ) {
2851 match = strncasecmp( sub->sa_final.bv_val,
2852 &left.bv_val[left.bv_len - sub->sa_final.bv_len],
2853 sub->sa_final.bv_len );
2859 left.bv_len -= sub->sa_final.bv_len;
2860 inlen -= sub->sa_final.bv_len;
2864 for(i=0; sub->sa_any[i].bv_val; i++) {
2869 if( inlen > left.bv_len ) {
2870 /* not enough length */
2875 if( sub->sa_any[i].bv_len == 0 ) {
2879 p = bvcasechr( &left, *sub->sa_any[i].bv_val, &idx );
2886 assert( idx < left.bv_len );
2887 if( idx >= left.bv_len ) {
2888 /* this shouldn't happen */
2895 if( sub->sa_any[i].bv_len > left.bv_len ) {
2896 /* not enough left */
2901 match = strncasecmp( left.bv_val,
2902 sub->sa_any[i].bv_val,
2903 sub->sa_any[i].bv_len );
2912 left.bv_val += sub->sa_any[i].bv_len;
2913 left.bv_len -= sub->sa_any[i].bv_len;
2914 inlen -= sub->sa_any[i].bv_len;
2920 return LDAP_SUCCESS;
2923 /* Index generation function */
2924 static int caseIgnoreIA5Indexer(
2929 struct berval *prefix,
2934 int rc = LDAP_SUCCESS;
2937 HASH_CONTEXT HASHcontext;
2938 unsigned char HASHdigest[HASH_BYTES];
2939 struct berval digest;
2940 digest.bv_val = HASHdigest;
2941 digest.bv_len = sizeof(HASHdigest);
2943 /* we should have at least one value at this point */
2944 assert( values != NULL && values[0].bv_val != NULL );
2946 for( i=0; values[i].bv_val != NULL; i++ ) {
2947 /* just count them */
2950 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
2952 slen = syntax->ssyn_oidlen;
2953 mlen = mr->smr_oidlen;
2955 for( i=0; values[i].bv_val != NULL; i++ ) {
2956 struct berval value;
2958 if( mr->smr_normalize ) {
2959 rc = (mr->smr_normalize)( use, syntax, mr, &values[i], &value );
2960 if( rc != LDAP_SUCCESS ) {
2963 } else if ( mr->smr_syntax->ssyn_normalize ) {
2964 rc = (mr->smr_syntax->ssyn_normalize)( syntax, &values[i], &value );
2965 if( rc != LDAP_SUCCESS ) {
2969 ber_dupbv( &value, &values[i] );
2972 ldap_pvt_str2lower( value.bv_val );
2974 HASH_Init( &HASHcontext );
2975 if( prefix != NULL && prefix->bv_len > 0 ) {
2976 HASH_Update( &HASHcontext,
2977 prefix->bv_val, prefix->bv_len );
2979 HASH_Update( &HASHcontext,
2980 syntax->ssyn_oid, slen );
2981 HASH_Update( &HASHcontext,
2982 mr->smr_oid, mlen );
2983 HASH_Update( &HASHcontext,
2984 value.bv_val, value.bv_len );
2985 HASH_Final( HASHdigest, &HASHcontext );
2987 free( value.bv_val );
2989 ber_dupbv( &keys[i], &digest );
2992 keys[i].bv_val = NULL;
2993 if( rc != LDAP_SUCCESS ) {
2994 ber_bvarray_free( keys );
3001 /* Index generation function */
3002 static int caseIgnoreIA5Filter(
3007 struct berval *prefix,
3008 void * assertedValue,
3013 HASH_CONTEXT HASHcontext;
3014 unsigned char HASHdigest[HASH_BYTES];
3015 struct berval value;
3016 struct berval digest;
3017 digest.bv_val = HASHdigest;
3018 digest.bv_len = sizeof(HASHdigest);
3020 slen = syntax->ssyn_oidlen;
3021 mlen = mr->smr_oidlen;
3023 ber_dupbv( &value, (struct berval *) assertedValue );
3024 ldap_pvt_str2lower( value.bv_val );
3026 keys = ch_malloc( sizeof( struct berval ) * 2 );
3028 HASH_Init( &HASHcontext );
3029 if( prefix != NULL && prefix->bv_len > 0 ) {
3030 HASH_Update( &HASHcontext,
3031 prefix->bv_val, prefix->bv_len );
3033 HASH_Update( &HASHcontext,
3034 syntax->ssyn_oid, slen );
3035 HASH_Update( &HASHcontext,
3036 mr->smr_oid, mlen );
3037 HASH_Update( &HASHcontext,
3038 value.bv_val, value.bv_len );
3039 HASH_Final( HASHdigest, &HASHcontext );
3041 ber_dupbv( &keys[0], &digest );
3042 keys[1].bv_val = NULL;
3044 free( value.bv_val );
3048 return LDAP_SUCCESS;
3051 /* Substrings Index generation function */
3052 static int caseIgnoreIA5SubstringsIndexer(
3057 struct berval *prefix,
3064 HASH_CONTEXT HASHcontext;
3065 unsigned char HASHdigest[HASH_BYTES];
3066 struct berval digest;
3067 digest.bv_val = HASHdigest;
3068 digest.bv_len = sizeof(HASHdigest);
3070 /* we should have at least one value at this point */
3071 assert( values != NULL && values[0].bv_val != NULL );
3074 for( i=0; values[i].bv_val != NULL; i++ ) {
3075 /* count number of indices to generate */
3076 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
3080 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
3081 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3082 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
3083 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
3085 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
3089 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
3090 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3091 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
3095 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
3096 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3097 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
3098 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
3100 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
3106 /* no keys to generate */
3108 return LDAP_SUCCESS;
3111 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
3113 slen = syntax->ssyn_oidlen;
3114 mlen = mr->smr_oidlen;
3117 for( i=0; values[i].bv_val != NULL; i++ ) {
3119 struct berval value;
3121 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
3123 ber_dupbv( &value, &values[i] );
3124 ldap_pvt_str2lower( value.bv_val );
3126 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
3127 ( value.bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
3129 char pre = SLAP_INDEX_SUBSTR_PREFIX;
3130 max = value.bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
3132 for( j=0; j<max; j++ ) {
3133 HASH_Init( &HASHcontext );
3134 if( prefix != NULL && prefix->bv_len > 0 ) {
3135 HASH_Update( &HASHcontext,
3136 prefix->bv_val, prefix->bv_len );
3139 HASH_Update( &HASHcontext,
3140 &pre, sizeof( pre ) );
3141 HASH_Update( &HASHcontext,
3142 syntax->ssyn_oid, slen );
3143 HASH_Update( &HASHcontext,
3144 mr->smr_oid, mlen );
3145 HASH_Update( &HASHcontext,
3147 SLAP_INDEX_SUBSTR_MAXLEN );
3148 HASH_Final( HASHdigest, &HASHcontext );
3150 ber_dupbv( &keys[nkeys++], &digest );
3154 max = SLAP_INDEX_SUBSTR_MAXLEN < value.bv_len
3155 ? SLAP_INDEX_SUBSTR_MAXLEN : value.bv_len;
3157 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
3160 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
3161 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
3162 HASH_Init( &HASHcontext );
3163 if( prefix != NULL && prefix->bv_len > 0 ) {
3164 HASH_Update( &HASHcontext,
3165 prefix->bv_val, prefix->bv_len );
3167 HASH_Update( &HASHcontext,
3168 &pre, sizeof( pre ) );
3169 HASH_Update( &HASHcontext,
3170 syntax->ssyn_oid, slen );
3171 HASH_Update( &HASHcontext,
3172 mr->smr_oid, mlen );
3173 HASH_Update( &HASHcontext,
3175 HASH_Final( HASHdigest, &HASHcontext );
3177 ber_dupbv( &keys[nkeys++], &digest );
3180 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
3181 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
3182 HASH_Init( &HASHcontext );
3183 if( prefix != NULL && prefix->bv_len > 0 ) {
3184 HASH_Update( &HASHcontext,
3185 prefix->bv_val, prefix->bv_len );
3187 HASH_Update( &HASHcontext,
3188 &pre, sizeof( pre ) );
3189 HASH_Update( &HASHcontext,
3190 syntax->ssyn_oid, slen );
3191 HASH_Update( &HASHcontext,
3192 mr->smr_oid, mlen );
3193 HASH_Update( &HASHcontext,
3194 &value.bv_val[value.bv_len-j], j );
3195 HASH_Final( HASHdigest, &HASHcontext );
3197 ber_dupbv( &keys[nkeys++], &digest );
3202 free( value.bv_val );
3206 keys[nkeys].bv_val = NULL;
3213 return LDAP_SUCCESS;
3216 static int caseIgnoreIA5SubstringsFilter(
3221 struct berval *prefix,
3222 void * assertedValue,
3225 SubstringsAssertion *sa = assertedValue;
3227 ber_len_t nkeys = 0;
3228 size_t slen, mlen, klen;
3230 HASH_CONTEXT HASHcontext;
3231 unsigned char HASHdigest[HASH_BYTES];
3232 struct berval value;
3233 struct berval digest;
3235 if((flags & SLAP_INDEX_SUBSTR_INITIAL) && sa->sa_initial.bv_val != NULL &&
3236 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3241 if((flags & SLAP_INDEX_SUBSTR_ANY) && sa->sa_any != NULL ) {
3243 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
3244 if( sa->sa_any[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3245 /* don't bother accounting for stepping */
3246 nkeys += sa->sa_any[i].bv_len -
3247 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
3252 if((flags & SLAP_INDEX_SUBSTR_FINAL) && sa->sa_final.bv_val != NULL &&
3253 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3260 return LDAP_SUCCESS;
3263 digest.bv_val = HASHdigest;
3264 digest.bv_len = sizeof(HASHdigest);
3266 slen = syntax->ssyn_oidlen;
3267 mlen = mr->smr_oidlen;
3269 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
3272 if((flags & SLAP_INDEX_SUBSTR_INITIAL) && sa->sa_initial.bv_val != NULL &&
3273 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3275 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
3276 ber_dupbv( &value, &sa->sa_initial );
3277 ldap_pvt_str2lower( value.bv_val );
3279 klen = SLAP_INDEX_SUBSTR_MAXLEN < value.bv_len
3280 ? SLAP_INDEX_SUBSTR_MAXLEN : value.bv_len;
3282 HASH_Init( &HASHcontext );
3283 if( prefix != NULL && prefix->bv_len > 0 ) {
3284 HASH_Update( &HASHcontext,
3285 prefix->bv_val, prefix->bv_len );
3287 HASH_Update( &HASHcontext,
3288 &pre, sizeof( pre ) );
3289 HASH_Update( &HASHcontext,
3290 syntax->ssyn_oid, slen );
3291 HASH_Update( &HASHcontext,
3292 mr->smr_oid, mlen );
3293 HASH_Update( &HASHcontext,
3294 value.bv_val, klen );
3295 HASH_Final( HASHdigest, &HASHcontext );
3297 free( value.bv_val );
3298 ber_dupbv( &keys[nkeys++], &digest );
3301 if((flags & SLAP_INDEX_SUBSTR_ANY) && sa->sa_any != NULL ) {
3303 pre = SLAP_INDEX_SUBSTR_PREFIX;
3304 klen = SLAP_INDEX_SUBSTR_MAXLEN;
3306 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
3307 if( sa->sa_any[i].bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
3311 ber_dupbv( &value, &sa->sa_any[i] );
3312 ldap_pvt_str2lower( value.bv_val );
3315 j <= value.bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
3316 j += SLAP_INDEX_SUBSTR_STEP )
3318 HASH_Init( &HASHcontext );
3319 if( prefix != NULL && prefix->bv_len > 0 ) {
3320 HASH_Update( &HASHcontext,
3321 prefix->bv_val, prefix->bv_len );
3323 HASH_Update( &HASHcontext,
3324 &pre, sizeof( pre ) );
3325 HASH_Update( &HASHcontext,
3326 syntax->ssyn_oid, slen );
3327 HASH_Update( &HASHcontext,
3328 mr->smr_oid, mlen );
3329 HASH_Update( &HASHcontext,
3330 &value.bv_val[j], klen );
3331 HASH_Final( HASHdigest, &HASHcontext );
3333 ber_dupbv( &keys[nkeys++], &digest );
3336 free( value.bv_val );
3340 if((flags & SLAP_INDEX_SUBSTR_FINAL) && sa->sa_final.bv_val != NULL &&
3341 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3343 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
3344 ber_dupbv( &value, &sa->sa_final );
3345 ldap_pvt_str2lower( value.bv_val );
3347 klen = SLAP_INDEX_SUBSTR_MAXLEN < value.bv_len
3348 ? SLAP_INDEX_SUBSTR_MAXLEN : value.bv_len;
3350 HASH_Init( &HASHcontext );
3351 if( prefix != NULL && prefix->bv_len > 0 ) {
3352 HASH_Update( &HASHcontext,
3353 prefix->bv_val, prefix->bv_len );
3355 HASH_Update( &HASHcontext,
3356 &pre, sizeof( pre ) );
3357 HASH_Update( &HASHcontext,
3358 syntax->ssyn_oid, slen );
3359 HASH_Update( &HASHcontext,
3360 mr->smr_oid, mlen );
3361 HASH_Update( &HASHcontext,
3362 &value.bv_val[value.bv_len-klen], klen );
3363 HASH_Final( HASHdigest, &HASHcontext );
3365 free( value.bv_val );
3366 ber_dupbv( &keys[nkeys++], &digest );
3370 keys[nkeys].bv_val = NULL;
3377 return LDAP_SUCCESS;
3381 numericStringValidate(
3387 if( in->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
3389 for(i=0; i < in->bv_len; i++) {
3390 if( !SLAP_NUMERIC(in->bv_val[i]) ) {
3391 return LDAP_INVALID_SYNTAX;
3395 return LDAP_SUCCESS;
3399 numericStringNormalize(
3402 struct berval *normalized )
3404 /* removal all spaces */
3407 assert( val->bv_len );
3409 normalized->bv_val = ch_malloc( val->bv_len + 1 );
3412 q = normalized->bv_val;
3415 if ( ASCII_SPACE( *p ) ) {
3416 /* Ignore whitespace */
3423 /* we should have copied no more then is in val */
3424 assert( (q - normalized->bv_val) <= (p - val->bv_val) );
3426 /* null terminate */
3429 normalized->bv_len = q - normalized->bv_val;
3431 if( normalized->bv_len == 0 ) {
3432 normalized->bv_val = ch_realloc( normalized->bv_val, 2 );
3433 normalized->bv_val[0] = ' ';
3434 normalized->bv_val[1] = '\0';
3435 normalized->bv_len = 1;
3438 return LDAP_SUCCESS;
3442 objectIdentifierFirstComponentMatch(
3447 struct berval *value,
3448 void *assertedValue )
3450 int rc = LDAP_SUCCESS;
3452 struct berval *asserted = (struct berval *) assertedValue;
3456 if( value->bv_len == 0 || value->bv_val[0] != '(' /*')'*/ ) {
3457 return LDAP_INVALID_SYNTAX;
3460 /* trim leading white space */
3461 for( i=1; ASCII_SPACE(value->bv_val[i]) && i < value->bv_len; i++ ) {
3465 /* grab next word */
3466 oid.bv_val = &value->bv_val[i];
3467 oid.bv_len = value->bv_len - i;
3468 for( i=1; ASCII_SPACE(value->bv_val[i]) && i < oid.bv_len; i++ ) {
3473 /* insert attributeTypes, objectclass check here */
3474 if( OID_LEADCHAR(asserted->bv_val[0]) ) {
3475 rc = objectIdentifierMatch( &match, flags, syntax, mr, &oid, asserted );
3478 if ( !strcmp( syntax->ssyn_oid, SLAP_SYNTAX_MATCHINGRULES_OID ) ) {
3479 MatchingRule *asserted_mr = mr_bvfind( asserted );
3480 MatchingRule *stored_mr = mr_bvfind( &oid );
3482 if( asserted_mr == NULL ) {
3483 rc = SLAPD_COMPARE_UNDEFINED;
3485 match = asserted_mr != stored_mr;
3488 } else if ( !strcmp( syntax->ssyn_oid,
3489 SLAP_SYNTAX_ATTRIBUTETYPES_OID ) )
3491 AttributeType *asserted_at = at_bvfind( asserted );
3492 AttributeType *stored_at = at_bvfind( &oid );
3494 if( asserted_at == NULL ) {
3495 rc = SLAPD_COMPARE_UNDEFINED;
3497 match = asserted_at != stored_at;
3500 } else if ( !strcmp( syntax->ssyn_oid,
3501 SLAP_SYNTAX_OBJECTCLASSES_OID ) )
3503 ObjectClass *asserted_oc = oc_bvfind( asserted );
3504 ObjectClass *stored_oc = oc_bvfind( &oid );
3506 if( asserted_oc == NULL ) {
3507 rc = SLAPD_COMPARE_UNDEFINED;
3509 match = asserted_oc != stored_oc;
3515 LDAP_LOG( CONFIG, ENTRY,
3516 "objectIdentifierFirstComponentMatch: %d\n %s\n %s\n",
3517 match, value->bv_val, asserted->bv_val );
3519 Debug( LDAP_DEBUG_ARGS, "objectIdentifierFirstComponentMatch "
3520 "%d\n\t\"%s\"\n\t\"%s\"\n",
3521 match, value->bv_val, asserted->bv_val );
3525 if( rc == LDAP_SUCCESS ) *matchp = match;
3535 struct berval *value,
3536 void *assertedValue )
3538 long lValue, lAssertedValue;
3540 /* safe to assume integers are NUL terminated? */
3541 lValue = strtoul(value->bv_val, NULL, 10);
3542 if(( lValue == LONG_MIN || lValue == LONG_MAX) && errno == ERANGE )
3543 return LDAP_CONSTRAINT_VIOLATION;
3545 lAssertedValue = strtol(((struct berval *)assertedValue)->bv_val, NULL, 10);
3546 if(( lAssertedValue == LONG_MIN || lAssertedValue == LONG_MAX) && errno == ERANGE )
3547 return LDAP_CONSTRAINT_VIOLATION;
3549 *matchp = (lValue & lAssertedValue) ? 0 : 1;
3550 return LDAP_SUCCESS;
3559 struct berval *value,
3560 void *assertedValue )
3562 long lValue, lAssertedValue;
3564 /* safe to assume integers are NUL terminated? */
3565 lValue = strtoul(value->bv_val, NULL, 10);
3566 if(( lValue == LONG_MIN || lValue == LONG_MAX) && errno == ERANGE )
3567 return LDAP_CONSTRAINT_VIOLATION;
3569 lAssertedValue = strtol(((struct berval *)assertedValue)->bv_val, NULL, 10);
3570 if(( lAssertedValue == LONG_MIN || lAssertedValue == LONG_MAX) && errno == ERANGE )
3571 return LDAP_CONSTRAINT_VIOLATION;
3573 *matchp = (lValue | lAssertedValue) ? 0 : -1;
3574 return LDAP_SUCCESS;
3578 #include <openssl/x509.h>
3579 #include <openssl/err.h>
3580 char digit[] = "0123456789";
3583 * Next function returns a string representation of a ASN1_INTEGER.
3584 * It works for unlimited lengths.
3587 static struct berval *
3588 asn1_integer2str(ASN1_INTEGER *a, struct berval *bv)
3593 /* We work backwards, make it fill from the end of buf */
3594 p = buf + sizeof(buf) - 1;
3597 if ( a == NULL || a->length == 0 ) {
3605 /* We want to preserve the original */
3606 copy = ch_malloc(n*sizeof(unsigned int));
3607 for (i = 0; i<n; i++) {
3608 copy[i] = a->data[i];
3612 * base indicates the index of the most significant
3613 * byte that might be nonzero. When it goes off the
3614 * end, we now there is nothing left to do.
3620 for (i = base; i<n; i++ ) {
3621 copy[i] += carry*256;
3622 carry = copy[i] % 10;
3627 * Way too large, we need to leave
3628 * room for sign if negative
3633 *--p = digit[carry];
3634 if (copy[base] == 0)
3640 if ( a->type == V_ASN1_NEG_INTEGER ) {
3644 return ber_str2bv( p, 0, 1, bv );
3648 * Given a certificate in DER format, extract the corresponding
3649 * assertion value for certificateExactMatch
3652 certificateExactConvert(
3654 struct berval * out )
3657 unsigned char *p = in->bv_val;
3658 struct berval serial;
3659 struct berval issuer_dn;
3661 xcert = d2i_X509(NULL, &p, in->bv_len);
3664 LDAP_LOG( CONFIG, ENTRY,
3665 "certificateExactConvert: error parsing cert: %s\n",
3666 ERR_error_string(ERR_get_error(),NULL), 0, 0 );
3668 Debug( LDAP_DEBUG_ARGS, "certificateExactConvert: "
3669 "error parsing cert: %s\n",
3670 ERR_error_string(ERR_get_error(),NULL), NULL, NULL );
3672 return LDAP_INVALID_SYNTAX;
3675 if ( !asn1_integer2str(xcert->cert_info->serialNumber, &serial) ) {
3677 return LDAP_INVALID_SYNTAX;
3679 if ( dnX509normalize(X509_get_issuer_name(xcert), &issuer_dn ) != LDAP_SUCCESS ) {
3681 ber_memfree(serial.bv_val);
3682 return LDAP_INVALID_SYNTAX;
3687 out->bv_len = serial.bv_len + issuer_dn.bv_len + sizeof(" $ ");
3688 out->bv_val = ch_malloc(out->bv_len);
3690 AC_MEMCPY(p, serial.bv_val, serial.bv_len);
3692 AC_MEMCPY(p, " $ ", sizeof(" $ ")-1);
3694 AC_MEMCPY(p, issuer_dn.bv_val, issuer_dn.bv_len);
3695 p += issuer_dn.bv_len;
3699 LDAP_LOG( CONFIG, ARGS,
3700 "certificateExactConvert: \n %s\n", out->bv_val, 0, 0 );
3702 Debug( LDAP_DEBUG_ARGS, "certificateExactConvert "
3704 out->bv_val, NULL, NULL );
3707 ber_memfree(serial.bv_val);
3708 ber_memfree(issuer_dn.bv_val);
3710 return LDAP_SUCCESS;
3714 serial_and_issuer_parse(
3715 struct berval *assertion,
3716 struct berval *serial,
3717 struct berval *issuer_dn
3725 begin = assertion->bv_val;
3726 end = assertion->bv_val+assertion->bv_len-1;
3727 for (p=begin; p<=end && *p != '$'; p++)
3730 return LDAP_INVALID_SYNTAX;
3732 /* p now points at the $ sign, now use begin and end to delimit the
3734 while (ASCII_SPACE(*begin))
3737 while (ASCII_SPACE(*end))
3740 bv.bv_len = end-begin+1;
3742 ber_dupbv(serial, &bv);
3744 /* now extract the issuer, remember p was at the dollar sign */
3747 end = assertion->bv_val+assertion->bv_len-1;
3748 while (ASCII_SPACE(*begin))
3750 /* should we trim spaces at the end too? is it safe always? */
3752 bv.bv_len = end-begin+1;
3754 dnNormalize2( NULL, &bv, issuer_dn );
3757 return LDAP_SUCCESS;
3761 certificateExactMatch(
3766 struct berval *value,
3767 void *assertedValue )
3770 unsigned char *p = value->bv_val;
3771 struct berval serial;
3772 struct berval issuer_dn;
3773 struct berval asserted_serial;
3774 struct berval asserted_issuer_dn;
3777 xcert = d2i_X509(NULL, &p, value->bv_len);
3780 LDAP_LOG( CONFIG, ENTRY,
3781 "certificateExactMatch: error parsing cert: %s\n",
3782 ERR_error_string(ERR_get_error(),NULL), 0, 0 );
3784 Debug( LDAP_DEBUG_ARGS, "certificateExactMatch: "
3785 "error parsing cert: %s\n",
3786 ERR_error_string(ERR_get_error(),NULL), NULL, NULL );
3788 return LDAP_INVALID_SYNTAX;
3791 asn1_integer2str(xcert->cert_info->serialNumber, &serial);
3792 dnX509normalize(X509_get_issuer_name(xcert), &issuer_dn);
3796 serial_and_issuer_parse(assertedValue,
3798 &asserted_issuer_dn);
3803 slap_schema.si_syn_integer,
3804 slap_schema.si_mr_integerMatch,
3807 if ( ret == LDAP_SUCCESS ) {
3808 if ( *matchp == 0 ) {
3809 /* We need to normalize everything for dnMatch */
3813 slap_schema.si_syn_distinguishedName,
3814 slap_schema.si_mr_distinguishedNameMatch,
3816 &asserted_issuer_dn);
3821 LDAP_LOG( CONFIG, ARGS, "certificateExactMatch "
3822 "%d\n\t\"%s $ %s\"\n",
3823 *matchp, serial.bv_val, issuer_dn.bv_val );
3824 LDAP_LOG( CONFIG, ARGS, "\t\"%s $ %s\"\n",
3825 asserted_serial.bv_val, asserted_issuer_dn.bv_val,
3828 Debug( LDAP_DEBUG_ARGS, "certificateExactMatch "
3829 "%d\n\t\"%s $ %s\"\n",
3830 *matchp, serial.bv_val, issuer_dn.bv_val );
3831 Debug( LDAP_DEBUG_ARGS, "\t\"%s $ %s\"\n",
3832 asserted_serial.bv_val, asserted_issuer_dn.bv_val,
3836 ber_memfree(serial.bv_val);
3837 ber_memfree(issuer_dn.bv_val);
3838 ber_memfree(asserted_serial.bv_val);
3839 ber_memfree(asserted_issuer_dn.bv_val);
3845 * Index generation function
3846 * We just index the serials, in most scenarios the issuer DN is one of
3847 * a very small set of values.
3849 static int certificateExactIndexer(
3854 struct berval *prefix,
3862 struct berval serial;
3864 /* we should have at least one value at this point */
3865 assert( values != NULL && values[0].bv_val != NULL );
3867 for( i=0; values[i].bv_val != NULL; i++ ) {
3868 /* empty -- just count them */
3871 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
3873 for( i=0; values[i].bv_val != NULL; i++ ) {
3874 p = values[i].bv_val;
3875 xcert = d2i_X509(NULL, &p, values[i].bv_len);
3878 LDAP_LOG( CONFIG, ENTRY,
3879 "certificateExactIndexer: error parsing cert: %s\n",
3880 ERR_error_string(ERR_get_error(),NULL), 0, 0);
3882 Debug( LDAP_DEBUG_ARGS, "certificateExactIndexer: "
3883 "error parsing cert: %s\n",
3884 ERR_error_string(ERR_get_error(),NULL),
3887 /* Do we leak keys on error? */
3888 return LDAP_INVALID_SYNTAX;
3891 asn1_integer2str(xcert->cert_info->serialNumber, &serial);
3893 integerNormalize( slap_schema.si_syn_integer,
3896 ber_memfree(serial.bv_val);
3898 LDAP_LOG( CONFIG, ENTRY,
3899 "certificateExactIndexer: returning: %s\n", keys[i].bv_val, 0, 0);
3901 Debug( LDAP_DEBUG_ARGS, "certificateExactIndexer: "
3908 keys[i].bv_val = NULL;
3910 return LDAP_SUCCESS;
3913 /* Index generation function */
3914 /* We think this is always called with a value in matching rule syntax */
3915 static int certificateExactFilter(
3920 struct berval *prefix,
3921 void * assertedValue,
3925 struct berval asserted_serial;
3927 serial_and_issuer_parse(assertedValue,
3931 keys = ch_malloc( sizeof( struct berval ) * 2 );
3932 integerNormalize( syntax, &asserted_serial, &keys[0] );
3933 keys[1].bv_val = NULL;
3936 ber_memfree(asserted_serial.bv_val);
3937 return LDAP_SUCCESS;
3942 check_time_syntax (struct berval *val,
3946 static int ceiling[9] = { 99, 99, 11, 30, 23, 59, 59, 12, 59 };
3947 static int mdays[2][12] = {
3948 /* non-leap years */
3949 { 30, 27, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30 },
3951 { 30, 28, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30 }
3954 int part, c, tzoffset, leapyear = 0 ;
3956 if( val->bv_len == 0 ) {
3957 return LDAP_INVALID_SYNTAX;
3960 p = (char *)val->bv_val;
3961 e = p + val->bv_len;
3963 /* Ignore initial whitespace */
3964 while ( ( p < e ) && ASCII_SPACE( *p ) ) {
3968 if (e - p < 13 - (2 * start)) {
3969 return LDAP_INVALID_SYNTAX;
3972 for (part = 0; part < 9; part++) {
3976 for (part = start; part < 7; part++) {
3978 if ((part == 6) && (c == 'Z' || c == '+' || c == '-')) {
3985 return LDAP_INVALID_SYNTAX;
3987 if (c < 0 || c > 9) {
3988 return LDAP_INVALID_SYNTAX;
3994 return LDAP_INVALID_SYNTAX;
3996 if (c < 0 || c > 9) {
3997 return LDAP_INVALID_SYNTAX;
4002 if (part == 2 || part == 3) {
4005 if (parts[part] < 0) {
4006 return LDAP_INVALID_SYNTAX;
4008 if (parts[part] > ceiling[part]) {
4009 return LDAP_INVALID_SYNTAX;
4013 /* leapyear check for the Gregorian calendar (year>1581) */
4014 if (((parts[1] % 4 == 0) && (parts[1] != 0)) ||
4015 ((parts[0] % 4 == 0) && (parts[1] == 0)))
4020 if (parts[3] > mdays[leapyear][parts[2]]) {
4021 return LDAP_INVALID_SYNTAX;
4026 tzoffset = 0; /* UTC */
4027 } else if (c != '+' && c != '-') {
4028 return LDAP_INVALID_SYNTAX;
4032 } else /* c == '+' */ {
4037 return LDAP_INVALID_SYNTAX;
4040 for (part = 7; part < 9; part++) {
4042 if (c < 0 || c > 9) {
4043 return LDAP_INVALID_SYNTAX;
4048 if (c < 0 || c > 9) {
4049 return LDAP_INVALID_SYNTAX;
4053 if (parts[part] < 0 || parts[part] > ceiling[part]) {
4054 return LDAP_INVALID_SYNTAX;
4059 /* Ignore trailing whitespace */
4060 while ( ( p < e ) && ASCII_SPACE( *p ) ) {
4064 return LDAP_INVALID_SYNTAX;
4067 switch ( tzoffset ) {
4068 case -1: /* negativ offset to UTC, ie west of Greenwich */
4069 parts[4] += parts[7];
4070 parts[5] += parts[8];
4071 for (part = 6; --part > 0; ) { /* offset is just hhmm, no seconds */
4075 c = mdays[leapyear][parts[2]];
4077 if (parts[part] > c) {
4078 parts[part] -= c + 1;
4083 case 1: /* positive offset to UTC, ie east of Greenwich */
4084 parts[4] -= parts[7];
4085 parts[5] -= parts[8];
4086 for (part = 6; --part > 0; ) {
4090 /* first arg to % needs to be non negativ */
4091 c = mdays[leapyear][(parts[2] - 1 + 12) % 12];
4093 if (parts[part] < 0) {
4094 parts[part] += c + 1;
4099 case 0: /* already UTC */
4103 return LDAP_SUCCESS;
4106 #ifdef SUPPORT_OBSOLETE_UTC_SYNTAX
4111 struct berval *normalized )
4115 rc = check_time_syntax(val, 1, parts);
4116 if (rc != LDAP_SUCCESS) {
4120 normalized->bv_val = ch_malloc( 14 );
4121 if ( normalized->bv_val == NULL ) {
4122 return LBER_ERROR_MEMORY;
4125 sprintf( normalized->bv_val, "%02d%02d%02d%02d%02d%02dZ",
4126 parts[1], parts[2] + 1, parts[3] + 1,
4127 parts[4], parts[5], parts[6] );
4128 normalized->bv_len = 13;
4130 return LDAP_SUCCESS;
4134 #ifdef SUPPORT_OBSOLETE_UTC_SYNTAX
4142 return check_time_syntax(in, 1, parts);
4147 generalizedTimeValidate(
4153 return check_time_syntax(in, 0, parts);
4157 generalizedTimeNormalize(
4160 struct berval *normalized )
4164 rc = check_time_syntax(val, 0, parts);
4165 if (rc != LDAP_SUCCESS) {
4169 normalized->bv_val = ch_malloc( 16 );
4170 if ( normalized->bv_val == NULL ) {
4171 return LBER_ERROR_MEMORY;
4174 sprintf( normalized->bv_val, "%02d%02d%02d%02d%02d%02d%02dZ",
4175 parts[0], parts[1], parts[2] + 1, parts[3] + 1,
4176 parts[4], parts[5], parts[6] );
4177 normalized->bv_len = 15;
4179 return LDAP_SUCCESS;
4183 nisNetgroupTripleValidate(
4185 struct berval *val )
4190 if ( val->bv_len == 0 ) {
4191 return LDAP_INVALID_SYNTAX;
4194 p = (char *)val->bv_val;
4195 e = p + val->bv_len;
4197 if ( *p != '(' /*')'*/ ) {
4198 return LDAP_INVALID_SYNTAX;
4201 for ( p++; ( p < e ) && ( *p != /*'('*/ ')' ); p++ ) {
4205 return LDAP_INVALID_SYNTAX;
4208 } else if ( !AD_CHAR( *p ) ) {
4209 return LDAP_INVALID_SYNTAX;
4213 if ( ( commas != 2 ) || ( *p != /*'('*/ ')' ) ) {
4214 return LDAP_INVALID_SYNTAX;
4220 return LDAP_INVALID_SYNTAX;
4223 return LDAP_SUCCESS;
4227 bootParameterValidate(
4229 struct berval *val )
4233 if ( val->bv_len == 0 ) {
4234 return LDAP_INVALID_SYNTAX;
4237 p = (char *)val->bv_val;
4238 e = p + val->bv_len;
4241 for (; ( p < e ) && ( *p != '=' ); p++ ) {
4242 if ( !AD_CHAR( *p ) ) {
4243 return LDAP_INVALID_SYNTAX;
4248 return LDAP_INVALID_SYNTAX;
4252 for ( p++; ( p < e ) && ( *p != ':' ); p++ ) {
4253 if ( !AD_CHAR( *p ) ) {
4254 return LDAP_INVALID_SYNTAX;
4259 return LDAP_INVALID_SYNTAX;
4263 for ( p++; p < e; p++ ) {
4264 if ( !SLAP_PRINTABLE( *p ) ) {
4265 return LDAP_INVALID_SYNTAX;
4269 return LDAP_SUCCESS;
4272 #define X_BINARY "X-BINARY-TRANSFER-REQUIRED 'TRUE' "
4273 #define X_NOT_H_R "X-NOT-HUMAN-READABLE 'TRUE' "
4275 static slap_syntax_defs_rec syntax_defs[] = {
4276 {"( 1.3.6.1.4.1.1466.115.121.1.1 DESC 'ACI Item' "
4277 X_BINARY X_NOT_H_R ")",
4278 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, NULL, NULL, NULL},
4279 {"( 1.3.6.1.4.1.1466.115.121.1.2 DESC 'Access Point' " X_NOT_H_R ")",
4280 0, NULL, NULL, NULL},
4281 {"( 1.3.6.1.4.1.1466.115.121.1.3 DESC 'Attribute Type Description' )",
4282 0, NULL, NULL, NULL},
4283 {"( 1.3.6.1.4.1.1466.115.121.1.4 DESC 'Audio' "
4285 SLAP_SYNTAX_BLOB, blobValidate, NULL, NULL},
4286 {"( 1.3.6.1.4.1.1466.115.121.1.5 DESC 'Binary' "
4288 SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4289 {"( 1.3.6.1.4.1.1466.115.121.1.6 DESC 'Bit String' )",
4290 0, bitStringValidate, bitStringNormalize, NULL },
4291 {"( 1.3.6.1.4.1.1466.115.121.1.7 DESC 'Boolean' )",
4292 0, booleanValidate, NULL, NULL},
4293 {"( 1.3.6.1.4.1.1466.115.121.1.8 DESC 'Certificate' "
4294 X_BINARY X_NOT_H_R ")",
4295 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4296 {"( 1.3.6.1.4.1.1466.115.121.1.9 DESC 'Certificate List' "
4297 X_BINARY X_NOT_H_R ")",
4298 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4299 {"( 1.3.6.1.4.1.1466.115.121.1.10 DESC 'Certificate Pair' "
4300 X_BINARY X_NOT_H_R ")",
4301 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4302 {"( 1.3.6.1.4.1.1466.115.121.1.11 DESC 'Country String' )",
4303 0, countryStringValidate, IA5StringNormalize, NULL},
4304 {"( 1.3.6.1.4.1.1466.115.121.1.12 DESC 'Distinguished Name' )",
4305 0, dnValidate, dnNormalize2, dnPretty2},
4306 {"( 1.3.6.1.4.1.1466.115.121.1.13 DESC 'Data Quality' )",
4307 0, NULL, NULL, NULL},
4308 {"( 1.3.6.1.4.1.1466.115.121.1.14 DESC 'Delivery Method' )",
4309 0, NULL, NULL, NULL},
4310 {"( 1.3.6.1.4.1.1466.115.121.1.15 DESC 'Directory String' )",
4311 0, UTF8StringValidate, UTF8StringNormalize, NULL},
4312 {"( 1.3.6.1.4.1.1466.115.121.1.16 DESC 'DIT Content Rule Description' )",
4313 0, NULL, NULL, NULL},
4314 {"( 1.3.6.1.4.1.1466.115.121.1.17 DESC 'DIT Structure Rule Description' )",
4315 0, NULL, NULL, NULL},
4316 {"( 1.3.6.1.4.1.1466.115.121.1.19 DESC 'DSA Quality' )",
4317 0, NULL, NULL, NULL},
4318 {"( 1.3.6.1.4.1.1466.115.121.1.20 DESC 'DSE Type' )",
4319 0, NULL, NULL, NULL},
4320 {"( 1.3.6.1.4.1.1466.115.121.1.21 DESC 'Enhanced Guide' )",
4321 0, NULL, NULL, NULL},
4322 {"( 1.3.6.1.4.1.1466.115.121.1.22 DESC 'Facsimile Telephone Number' )",
4323 0, printablesStringValidate, telephoneNumberNormalize, NULL},
4324 {"( 1.3.6.1.4.1.1466.115.121.1.23 DESC 'Fax' " X_NOT_H_R ")",
4325 SLAP_SYNTAX_BLOB, NULL, NULL, NULL},
4326 {"( 1.3.6.1.4.1.1466.115.121.1.24 DESC 'Generalized Time' )",
4327 0, generalizedTimeValidate, generalizedTimeNormalize, NULL},
4328 {"( 1.3.6.1.4.1.1466.115.121.1.25 DESC 'Guide' )",
4329 0, NULL, NULL, NULL},
4330 {"( 1.3.6.1.4.1.1466.115.121.1.26 DESC 'IA5 String' )",
4331 0, IA5StringValidate, IA5StringNormalize, NULL},
4332 {"( 1.3.6.1.4.1.1466.115.121.1.27 DESC 'Integer' )",
4333 0, integerValidate, integerNormalize, NULL},
4334 {"( 1.3.6.1.4.1.1466.115.121.1.28 DESC 'JPEG' " X_NOT_H_R ")",
4335 SLAP_SYNTAX_BLOB, blobValidate, NULL, NULL},
4336 {"( 1.3.6.1.4.1.1466.115.121.1.29 DESC 'Master And Shadow Access Points' )",
4337 0, NULL, NULL, NULL},
4338 {"( 1.3.6.1.4.1.1466.115.121.1.30 DESC 'Matching Rule Description' )",
4339 0, NULL, NULL, NULL},
4340 {"( 1.3.6.1.4.1.1466.115.121.1.31 DESC 'Matching Rule Use Description' )",
4341 0, NULL, NULL, NULL},
4342 {"( 1.3.6.1.4.1.1466.115.121.1.32 DESC 'Mail Preference' )",
4343 0, NULL, NULL, NULL},
4344 {"( 1.3.6.1.4.1.1466.115.121.1.33 DESC 'MHS OR Address' )",
4345 0, NULL, NULL, NULL},
4346 {"( 1.3.6.1.4.1.1466.115.121.1.34 DESC 'Name And Optional UID' )",
4347 0, nameUIDValidate, nameUIDNormalize, NULL},
4348 {"( 1.3.6.1.4.1.1466.115.121.1.35 DESC 'Name Form Description' )",
4349 0, NULL, NULL, NULL},
4350 {"( 1.3.6.1.4.1.1466.115.121.1.36 DESC 'Numeric String' )",
4351 0, numericStringValidate, numericStringNormalize, NULL},
4352 {"( 1.3.6.1.4.1.1466.115.121.1.37 DESC 'Object Class Description' )",
4353 0, NULL, NULL, NULL},
4354 {"( 1.3.6.1.4.1.1466.115.121.1.38 DESC 'OID' )",
4355 0, oidValidate, NULL, NULL},
4356 {"( 1.3.6.1.4.1.1466.115.121.1.39 DESC 'Other Mailbox' )",
4357 0, IA5StringValidate, IA5StringNormalize, NULL},
4358 {"( 1.3.6.1.4.1.1466.115.121.1.40 DESC 'Octet String' )",
4359 0, blobValidate, NULL, NULL},
4360 {"( 1.3.6.1.4.1.1466.115.121.1.41 DESC 'Postal Address' )",
4361 0, UTF8StringValidate, UTF8StringNormalize, NULL},
4362 {"( 1.3.6.1.4.1.1466.115.121.1.42 DESC 'Protocol Information' )",
4363 0, NULL, NULL, NULL},
4364 {"( 1.3.6.1.4.1.1466.115.121.1.43 DESC 'Presentation Address' )",
4365 0, NULL, NULL, NULL},
4366 {"( 1.3.6.1.4.1.1466.115.121.1.44 DESC 'Printable String' )",
4367 0, printableStringValidate, IA5StringNormalize, NULL},
4368 {"( 1.3.6.1.4.1.1466.115.121.1.45 DESC 'SubtreeSpecification' "
4369 X_BINARY X_NOT_H_R ")",
4370 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, NULL, NULL, NULL},
4371 {"( 1.3.6.1.4.1.1466.115.121.1.49 DESC 'Supported Algorithm' "
4372 X_BINARY X_NOT_H_R ")",
4373 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4374 {"( 1.3.6.1.4.1.1466.115.121.1.50 DESC 'Telephone Number' )",
4375 0, printableStringValidate, telephoneNumberNormalize, NULL},
4376 {"( 1.3.6.1.4.1.1466.115.121.1.51 DESC 'Teletex Terminal Identifier' )",
4377 0, NULL, NULL, NULL},
4378 {"( 1.3.6.1.4.1.1466.115.121.1.52 DESC 'Telex Number' )",
4379 0, printablesStringValidate, IA5StringNormalize, NULL},
4380 #ifdef SUPPORT_OBSOLETE_UTC_SYNTAX
4381 {"( 1.3.6.1.4.1.1466.115.121.1.53 DESC 'UTC Time' )",
4382 0, utcTimeValidate, utcTimeNormalize, NULL},
4384 {"( 1.3.6.1.4.1.1466.115.121.1.54 DESC 'LDAP Syntax Description' )",
4385 0, NULL, NULL, NULL},
4386 {"( 1.3.6.1.4.1.1466.115.121.1.55 DESC 'Modify Rights' )",
4387 0, NULL, NULL, NULL},
4388 {"( 1.3.6.1.4.1.1466.115.121.1.56 DESC 'LDAP Schema Definition' )",
4389 0, NULL, NULL, NULL},
4390 {"( 1.3.6.1.4.1.1466.115.121.1.57 DESC 'LDAP Schema Description' )",
4391 0, NULL, NULL, NULL},
4392 {"( 1.3.6.1.4.1.1466.115.121.1.58 DESC 'Substring Assertion' )",
4393 0, NULL, NULL, NULL},
4395 /* RFC 2307 NIS Syntaxes */
4396 {"( 1.3.6.1.1.1.0.0 DESC 'RFC2307 NIS Netgroup Triple' )",
4397 0, nisNetgroupTripleValidate, NULL, NULL},
4398 {"( 1.3.6.1.1.1.0.1 DESC 'RFC2307 Boot Parameter' )",
4399 0, bootParameterValidate, NULL, NULL},
4403 /* These OIDs are not published yet, but will be in the next
4404 * I-D for PKIX LDAPv3 schema as have been advanced by David
4405 * Chadwick in private mail.
4407 {"( 1.2.826.0.1.3344810.7.1 DESC 'Serial Number and Issuer' )",
4408 0, NULL, NULL, NULL},
4411 /* OpenLDAP Experimental Syntaxes */
4412 #ifdef SLAPD_ACI_ENABLED
4413 {"( 1.3.6.1.4.1.4203.666.2.1 DESC 'OpenLDAP Experimental ACI' )",
4415 UTF8StringValidate /* THIS WILL CHANGE FOR NEW ACI SYNTAX */,
4419 #ifdef SLAPD_AUTHPASSWD
4420 /* needs updating */
4421 {"( 1.3.6.1.4.1.4203.666.2.2 DESC 'OpenLDAP authPassword' )",
4422 SLAP_SYNTAX_HIDE, NULL, NULL, NULL},
4425 /* OpenLDAP Void Syntax */
4426 {"( 1.3.6.1.4.1.4203.1.1.1 DESC 'OpenLDAP void' )" ,
4427 SLAP_SYNTAX_HIDE, inValidate, NULL, NULL},
4428 {NULL, 0, NULL, NULL, NULL}
4432 char *certificateExactMatchSyntaxes[] = {
4433 "1.3.6.1.4.1.1466.115.121.1.8" /* certificate */,
4437 char *directoryStringSyntaxes[] = {
4438 "1.3.6.1.4.1.1466.115.121.1.44" /* printableString */,
4441 char *integerFirstComponentMatchSyntaxes[] = {
4442 "1.3.6.1.4.1.1466.115.121.1.27" /* INTEGER */,
4443 "1.3.6.1.4.1.1466.115.121.1.17" /* ditStructureRuleDescription */,
4446 char *objectIdentifierFirstComponentMatchSyntaxes[] = {
4447 "1.3.6.1.4.1.1466.115.121.1.38" /* OID */,
4448 "1.3.6.1.4.1.1466.115.121.1.3" /* attributeTypeDescription */,
4449 "1.3.6.1.4.1.1466.115.121.1.16" /* ditContentRuleDescription */,
4450 "1.3.6.1.4.1.1466.115.121.1.54" /* ldapSyntaxDescription */,
4451 "1.3.6.1.4.1.1466.115.121.1.30" /* matchingRuleDescription */,
4452 "1.3.6.1.4.1.1466.115.121.1.31" /* matchingRuleUseDescription */,
4453 "1.3.6.1.4.1.1466.115.121.1.35" /* nameFormDescription */,
4454 "1.3.6.1.4.1.1466.115.121.1.37" /* objectClassDescription */,
4459 * Other matching rules in X.520 that we do not use (yet):
4461 * 2.5.13.9 numericStringOrderingMatch
4462 * 2.5.13.19 octetStringSubstringsMatch
4463 * 2.5.13.25 uTCTimeMatch
4464 * 2.5.13.26 uTCTimeOrderingMatch
4465 * 2.5.13.31 directoryStringFirstComponentMatch
4466 * 2.5.13.32 wordMatch
4467 * 2.5.13.33 keywordMatch
4468 * 2.5.13.35 certificateMatch
4469 * 2.5.13.36 certificatePairExactMatch
4470 * 2.5.13.37 certificatePairMatch
4471 * 2.5.13.38 certificateListExactMatch
4472 * 2.5.13.39 certificateListMatch
4473 * 2.5.13.40 algorithmIdentifierMatch
4474 * 2.5.13.41 storedPrefixMatch
4475 * 2.5.13.42 attributeCertificateMatch
4476 * 2.5.13.43 readerAndKeyIDMatch
4477 * 2.5.13.44 attributeIntegrityMatch
4479 static slap_mrule_defs_rec mrule_defs[] = {
4481 * EQUALITY matching rules must be listed after associated APPROX
4482 * matching rules. So, we list all APPROX matching rules first.
4484 {"( " directoryStringApproxMatchOID " NAME 'directoryStringApproxMatch' "
4485 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4486 SLAP_MR_HIDE | SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT, NULL,
4488 directoryStringApproxMatch,
4489 directoryStringApproxIndexer,
4490 directoryStringApproxFilter,
4493 {"( " IA5StringApproxMatchOID " NAME 'IA5StringApproxMatch' "
4494 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4495 SLAP_MR_HIDE | SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT, NULL,
4497 IA5StringApproxMatch,
4498 IA5StringApproxIndexer,
4499 IA5StringApproxFilter,
4503 * Other matching rules
4506 {"( 2.5.13.0 NAME 'objectIdentifierMatch' "
4507 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
4508 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4510 objectIdentifierMatch, caseIgnoreIA5Indexer, caseIgnoreIA5Filter,
4513 {"( 2.5.13.1 NAME 'distinguishedNameMatch' "
4514 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )",
4515 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4517 dnMatch, dnIndexer, dnFilter,
4520 {"( 2.5.13.2 NAME 'caseIgnoreMatch' "
4521 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4522 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD,
4523 directoryStringSyntaxes,
4525 caseIgnoreMatch, caseExactIgnoreIndexer, caseExactIgnoreFilter,
4526 directoryStringApproxMatchOID },
4528 {"( 2.5.13.3 NAME 'caseIgnoreOrderingMatch' "
4529 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4530 SLAP_MR_ORDERING, directoryStringSyntaxes,
4532 caseIgnoreOrderingMatch, NULL, NULL,
4535 {"( 2.5.13.4 NAME 'caseIgnoreSubstringsMatch' "
4536 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4537 SLAP_MR_SUBSTR, NULL,
4539 caseExactIgnoreSubstringsMatch,
4540 caseExactIgnoreSubstringsIndexer,
4541 caseExactIgnoreSubstringsFilter,
4544 {"( 2.5.13.5 NAME 'caseExactMatch' "
4545 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4546 SLAP_MR_EQUALITY | SLAP_MR_EXT, directoryStringSyntaxes,
4548 caseExactMatch, caseExactIgnoreIndexer, caseExactIgnoreFilter,
4549 directoryStringApproxMatchOID },
4551 {"( 2.5.13.6 NAME 'caseExactOrderingMatch' "
4552 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4553 SLAP_MR_ORDERING, directoryStringSyntaxes,
4555 caseExactOrderingMatch, NULL, NULL,
4558 {"( 2.5.13.7 NAME 'caseExactSubstringsMatch' "
4559 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4560 SLAP_MR_SUBSTR, directoryStringSyntaxes,
4562 caseExactIgnoreSubstringsMatch,
4563 caseExactIgnoreSubstringsIndexer,
4564 caseExactIgnoreSubstringsFilter,
4567 {"( 2.5.13.8 NAME 'numericStringMatch' "
4568 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 )",
4569 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL,
4572 caseIgnoreIA5Indexer,
4573 caseIgnoreIA5Filter,
4576 {"( 2.5.13.10 NAME 'numericStringSubstringsMatch' "
4577 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4578 SLAP_MR_SUBSTR, NULL,
4580 caseIgnoreIA5SubstringsMatch,
4581 caseIgnoreIA5SubstringsIndexer,
4582 caseIgnoreIA5SubstringsFilter,
4585 {"( 2.5.13.11 NAME 'caseIgnoreListMatch' "
4586 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )",
4587 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL,
4589 caseIgnoreListMatch, NULL, NULL,
4592 {"( 2.5.13.12 NAME 'caseIgnoreListSubstringsMatch' "
4593 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4594 SLAP_MR_SUBSTR, NULL,
4596 caseIgnoreListSubstringsMatch, NULL, NULL,
4599 {"( 2.5.13.13 NAME 'booleanMatch' "
4600 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )",
4601 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4603 booleanMatch, NULL, NULL,
4606 {"( 2.5.13.14 NAME 'integerMatch' "
4607 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4608 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4610 integerMatch, integerIndexer, integerFilter,
4613 {"( 2.5.13.15 NAME 'integerOrderingMatch' "
4614 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4615 SLAP_MR_ORDERING, NULL,
4617 integerOrderingMatch, NULL, NULL,
4620 {"( 2.5.13.16 NAME 'bitStringMatch' "
4621 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.6 )",
4622 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4624 bitStringMatch, bitStringIndexer, bitStringFilter,
4627 {"( 2.5.13.17 NAME 'octetStringMatch' "
4628 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
4629 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4631 octetStringMatch, octetStringIndexer, octetStringFilter,
4634 {"( 2.5.13.18 NAME 'octetStringOrderingMatch' "
4635 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
4636 SLAP_MR_ORDERING, NULL,
4638 octetStringOrderingMatch, NULL, NULL,
4641 {"( 2.5.13.20 NAME 'telephoneNumberMatch' "
4642 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 )",
4643 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL,
4645 telephoneNumberMatch,
4646 telephoneNumberIndexer,
4647 telephoneNumberFilter,
4650 {"( 2.5.13.21 NAME 'telephoneNumberSubstringsMatch' "
4651 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4652 SLAP_MR_SUBSTR, NULL,
4654 telephoneNumberSubstringsMatch,
4655 telephoneNumberSubstringsIndexer,
4656 telephoneNumberSubstringsFilter,
4659 {"( 2.5.13.22 NAME 'presentationAddressMatch' "
4660 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.43 )",
4661 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4666 {"( 2.5.13.23 NAME 'uniqueMemberMatch' "
4667 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.34 )",
4668 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4670 uniqueMemberMatch, NULL, NULL,
4673 {"( 2.5.13.24 NAME 'protocolInformationMatch' "
4674 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.42 )",
4675 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4677 protocolInformationMatch, NULL, NULL,
4680 {"( 2.5.13.27 NAME 'generalizedTimeMatch' "
4681 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
4682 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4684 generalizedTimeMatch, NULL, NULL,
4687 {"( 2.5.13.28 NAME 'generalizedTimeOrderingMatch' "
4688 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
4689 SLAP_MR_ORDERING, NULL,
4691 generalizedTimeOrderingMatch, NULL, NULL,
4694 {"( 2.5.13.29 NAME 'integerFirstComponentMatch' "
4695 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4696 SLAP_MR_EQUALITY | SLAP_MR_EXT, integerFirstComponentMatchSyntaxes,
4698 integerFirstComponentMatch, NULL, NULL,
4701 {"( 2.5.13.30 NAME 'objectIdentifierFirstComponentMatch' "
4702 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
4703 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4704 objectIdentifierFirstComponentMatchSyntaxes,
4706 objectIdentifierFirstComponentMatch, NULL, NULL,
4710 {"( 2.5.13.34 NAME 'certificateExactMatch' "
4711 "SYNTAX 1.2.826.0.1.3344810.7.1 )",
4712 SLAP_MR_EQUALITY | SLAP_MR_EXT, certificateExactMatchSyntaxes,
4713 certificateExactConvert, NULL,
4714 certificateExactMatch,
4715 certificateExactIndexer, certificateExactFilter,
4719 {"( 1.3.6.1.4.1.1466.109.114.1 NAME 'caseExactIA5Match' "
4720 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4721 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4723 caseExactIA5Match, caseExactIA5Indexer, caseExactIA5Filter,
4724 IA5StringApproxMatchOID },
4726 {"( 1.3.6.1.4.1.1466.109.114.2 NAME 'caseIgnoreIA5Match' "
4727 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4728 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL,
4730 caseIgnoreIA5Match, caseIgnoreIA5Indexer, caseIgnoreIA5Filter,
4731 IA5StringApproxMatchOID },
4733 {"( 1.3.6.1.4.1.1466.109.114.3 NAME 'caseIgnoreIA5SubstringsMatch' "
4734 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4735 SLAP_MR_SUBSTR, NULL,
4737 caseIgnoreIA5SubstringsMatch,
4738 caseIgnoreIA5SubstringsIndexer,
4739 caseIgnoreIA5SubstringsFilter,
4742 {"( 1.3.6.1.4.1.4203.1.2.1 NAME 'caseExactIA5SubstringsMatch' "
4743 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4744 SLAP_MR_SUBSTR, NULL,
4746 caseExactIA5SubstringsMatch,
4747 caseExactIA5SubstringsIndexer,
4748 caseExactIA5SubstringsFilter,
4751 #ifdef SLAPD_AUTHPASSWD
4752 /* needs updating */
4753 {"( 1.3.6.1.4.1.4203.666.4.1 NAME 'authPasswordMatch' "
4754 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
4755 SLAP_MR_EQUALITY, NULL,
4757 authPasswordMatch, NULL, NULL,
4761 #ifdef SLAPD_ACI_ENABLED
4762 {"( 1.3.6.1.4.1.4203.666.4.2 NAME 'OpenLDAPaciMatch' "
4763 "SYNTAX 1.3.6.1.4.1.4203.666.2.1 )",
4764 SLAP_MR_EQUALITY, NULL,
4766 OpenLDAPaciMatch, NULL, NULL,
4770 {"( 1.2.840.113556.1.4.803 NAME 'integerBitAndMatch' "
4771 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4774 integerBitAndMatch, NULL, NULL,
4777 {"( 1.2.840.113556.1.4.804 NAME 'integerBitOrMatch' "
4778 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4781 integerBitOrMatch, NULL, NULL,
4784 {NULL, SLAP_MR_NONE, NULL,
4785 NULL, NULL, NULL, NULL, NULL,
4790 slap_schema_init( void )
4795 /* we should only be called once (from main) */
4796 assert( schema_init_done == 0 );
4798 for ( i=0; syntax_defs[i].sd_desc != NULL; i++ ) {
4799 res = register_syntax( &syntax_defs[i] );
4802 fprintf( stderr, "slap_schema_init: Error registering syntax %s\n",
4803 syntax_defs[i].sd_desc );
4808 for ( i=0; mrule_defs[i].mrd_desc != NULL; i++ ) {
4809 if( mrule_defs[i].mrd_usage == SLAP_MR_NONE &&
4810 mrule_defs[i].mrd_compat_syntaxes == NULL )
4813 "slap_schema_init: Ingoring unusable matching rule %s\n",
4814 mrule_defs[i].mrd_desc );
4818 res = register_matching_rule( &mrule_defs[i] );
4822 "slap_schema_init: Error registering matching rule %s\n",
4823 mrule_defs[i].mrd_desc );
4828 for ( i=0; i < (int)(sizeof(mr_ptr)/sizeof(mr_ptr[0])); i++ )
4829 *mr_ptr[i].mr = mr_find( mr_ptr[i].oid );
4831 res = slap_schema_load();
4832 schema_init_done = 1;
4837 schema_destroy( void )
4843 for ( i=0; i < (int)(sizeof(mr_ptr)/sizeof(mr_ptr[0])); i++ )
4844 *mr_ptr[i].mr = NULL;