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 *)SLAP_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 SLAP_MALLOC( (i + 1) * sizeof(struct berval) );
727 if( nsa->sa_any == NULL ) {
731 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
732 UTF8bvnormalize( &sa->sa_any[i], &nsa->sa_any[i],
734 if( nsa->sa_any[i].bv_val == NULL ) {
738 nsa->sa_any[i].bv_val = NULL;
741 if( sa->sa_final.bv_val != NULL ) {
742 UTF8bvnormalize( &sa->sa_final, &nsa->sa_final, casefold );
743 if( nsa->sa_final.bv_val == NULL ) {
751 if ( nsa->sa_final.bv_val ) free( nsa->sa_final.bv_val );
752 if ( nsa->sa_any ) ber_bvarray_free( nsa->sa_any );
753 if ( nsa->sa_initial.bv_val ) free( nsa->sa_initial.bv_val );
758 #ifndef SLAPD_APPROX_OLDSINGLESTRING
760 #if defined(SLAPD_APPROX_INITIALS)
761 #define SLAPD_APPROX_DELIMITER "._ "
762 #define SLAPD_APPROX_WORDLEN 2
764 #define SLAPD_APPROX_DELIMITER " "
765 #define SLAPD_APPROX_WORDLEN 1
774 struct berval *value,
775 void *assertedValue )
777 struct berval *nval, *assertv;
778 char *val, **values, **words, *c;
779 int i, count, len, nextchunk=0, nextavail=0;
781 /* Yes, this is necessary */
782 nval = UTF8bvnormalize( value, NULL, LDAP_UTF8_APPROX );
788 /* Yes, this is necessary */
789 assertv = UTF8bvnormalize( ((struct berval *)assertedValue),
790 NULL, LDAP_UTF8_APPROX );
791 if( assertv == NULL ) {
797 /* Isolate how many words there are */
798 for ( c = nval->bv_val, count = 1; *c; c++ ) {
799 c = strpbrk( c, SLAPD_APPROX_DELIMITER );
800 if ( c == NULL ) break;
805 /* Get a phonetic copy of each word */
806 words = (char **)ch_malloc( count * sizeof(char *) );
807 values = (char **)ch_malloc( count * sizeof(char *) );
808 for ( c = nval->bv_val, i = 0; i < count; i++, c += strlen(c) + 1 ) {
810 values[i] = phonetic(c);
813 /* Work through the asserted value's words, to see if at least some
814 of the words are there, in the same order. */
816 while ( (ber_len_t) nextchunk < assertv->bv_len ) {
817 len = strcspn( assertv->bv_val + nextchunk, SLAPD_APPROX_DELIMITER);
822 #if defined(SLAPD_APPROX_INITIALS)
823 else if( len == 1 ) {
824 /* Single letter words need to at least match one word's initial */
825 for( i=nextavail; i<count; i++ )
826 if( !strncasecmp( assertv->bv_val + nextchunk, words[i], 1 )) {
833 /* Isolate the next word in the asserted value and phonetic it */
834 assertv->bv_val[nextchunk+len] = '\0';
835 val = phonetic( assertv->bv_val + nextchunk );
837 /* See if this phonetic chunk is in the remaining words of *value */
838 for( i=nextavail; i<count; i++ ){
839 if( !strcmp( val, values[i] ) ){
847 /* This chunk in the asserted value was NOT within the *value. */
853 /* Go on to the next word in the asserted value */
857 /* If some of the words were seen, call it a match */
858 if( nextavail > 0 ) {
866 ber_bvfree( assertv );
867 for( i=0; i<count; i++ ) {
868 ch_free( values[i] );
883 struct berval *prefix,
888 int i,j, len, wordcount, keycount=0;
889 struct berval *newkeys;
892 for( j=0; values[j].bv_val != NULL; j++ ) {
893 struct berval val = { 0, NULL };
894 /* Yes, this is necessary */
895 UTF8bvnormalize( &values[j], &val, LDAP_UTF8_APPROX );
896 assert( val.bv_val != NULL );
898 /* Isolate how many words there are. There will be a key for each */
899 for( wordcount = 0, c = val.bv_val; *c; c++) {
900 len = strcspn(c, SLAPD_APPROX_DELIMITER);
901 if( len >= SLAPD_APPROX_WORDLEN ) wordcount++;
903 if (*c == '\0') break;
907 /* Allocate/increase storage to account for new keys */
908 newkeys = (struct berval *)ch_malloc( (keycount + wordcount + 1)
909 * sizeof(struct berval) );
910 AC_MEMCPY( newkeys, keys, keycount * sizeof(struct berval) );
911 if( keys ) ch_free( keys );
914 /* Get a phonetic copy of each word */
915 for( c = val.bv_val, i = 0; i < wordcount; c += len + 1 ) {
917 if( len < SLAPD_APPROX_WORDLEN ) continue;
918 ber_str2bv( phonetic( c ), 0, 0, &keys[keycount] );
923 ber_memfree( val.bv_val );
925 keys[keycount].bv_val = NULL;
937 struct berval *prefix,
938 void * assertedValue,
946 /* Yes, this is necessary */
947 val = UTF8bvnormalize( ((struct berval *)assertedValue),
948 NULL, LDAP_UTF8_APPROX );
949 if( val == NULL || val->bv_val == NULL ) {
950 keys = (struct berval *)ch_malloc( sizeof(struct berval) );
951 keys[0].bv_val = NULL;
957 /* Isolate how many words there are. There will be a key for each */
958 for( count = 0,c = val->bv_val; *c; c++) {
959 len = strcspn(c, SLAPD_APPROX_DELIMITER);
960 if( len >= SLAPD_APPROX_WORDLEN ) count++;
962 if (*c == '\0') break;
966 /* Allocate storage for new keys */
967 keys = (struct berval *)ch_malloc( (count + 1) * sizeof(struct berval) );
969 /* Get a phonetic copy of each word */
970 for( c = val->bv_val, i = 0; i < count; c += len + 1 ) {
972 if( len < SLAPD_APPROX_WORDLEN ) continue;
973 ber_str2bv( phonetic( c ), 0, 0, &keys[i] );
979 keys[count].bv_val = NULL;
987 /* No other form of Approximate Matching is defined */
995 struct berval *value,
996 void *assertedValue )
998 char *vapprox, *avapprox;
1001 /* Yes, this is necessary */
1002 s = UTF8normalize( value, UTF8_NOCASEFOLD );
1005 return LDAP_SUCCESS;
1008 /* Yes, this is necessary */
1009 t = UTF8normalize( ((struct berval *)assertedValue),
1014 return LDAP_SUCCESS;
1017 vapprox = phonetic( strip8bitChars( s ) );
1018 avapprox = phonetic( strip8bitChars( t ) );
1023 *matchp = strcmp( vapprox, avapprox );
1026 ch_free( avapprox );
1028 return LDAP_SUCCESS;
1037 struct berval *prefix,
1045 for( i=0; values[i].bv_val != NULL; i++ ) {
1046 /* empty - just count them */
1049 /* we should have at least one value at this point */
1052 keys = (struct berval *)ch_malloc( sizeof( struct berval ) * (i+1) );
1054 /* Copy each value and run it through phonetic() */
1055 for( i=0; values[i].bv_val != NULL; i++ ) {
1056 /* Yes, this is necessary */
1057 s = UTF8normalize( &values[i], UTF8_NOCASEFOLD );
1059 /* strip 8-bit chars and run through phonetic() */
1060 ber_str2bv( phonetic( strip8bitChars( s ) ), 0, 0, &keys[i] );
1063 keys[i].bv_val = NULL;
1066 return LDAP_SUCCESS;
1076 struct berval *prefix,
1077 void * assertedValue,
1083 keys = (struct berval *)ch_malloc( sizeof( struct berval * ) * 2 );
1085 /* Yes, this is necessary */
1086 s = UTF8normalize( ((struct berval *)assertedValue),
1091 /* strip 8-bit chars and run through phonetic() */
1092 keys[0] = ber_bvstr( phonetic( strip8bitChars( s ) ) );
1098 return LDAP_SUCCESS;
1109 struct berval *value,
1110 void *assertedValue )
1112 *matchp = UTF8bvnormcmp( value,
1113 (struct berval *) assertedValue,
1114 LDAP_UTF8_NOCASEFOLD );
1115 return LDAP_SUCCESS;
1119 caseExactIgnoreSubstringsMatch(
1124 struct berval *value,
1125 void *assertedValue )
1128 SubstringsAssertion *sub = NULL;
1129 struct berval left = { 0, NULL };
1135 casefold = ( mr != caseExactSubstringsMatchingRule )
1136 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1138 if ( UTF8bvnormalize( value, &left, casefold ) == NULL ) {
1144 sub = UTF8SubstringsassertionNormalize( assertedValue, casefold );
1150 /* Add up asserted input length */
1151 if( sub->sa_initial.bv_val ) {
1152 inlen += sub->sa_initial.bv_len;
1155 for(i=0; sub->sa_any[i].bv_val != NULL; i++) {
1156 inlen += sub->sa_any[i].bv_len;
1159 if( sub->sa_final.bv_val ) {
1160 inlen += sub->sa_final.bv_len;
1163 if( sub->sa_initial.bv_val ) {
1164 if( inlen > left.bv_len ) {
1169 match = memcmp( sub->sa_initial.bv_val, left.bv_val,
1170 sub->sa_initial.bv_len );
1176 left.bv_val += sub->sa_initial.bv_len;
1177 left.bv_len -= sub->sa_initial.bv_len;
1178 inlen -= sub->sa_initial.bv_len;
1181 if( sub->sa_final.bv_val ) {
1182 if( inlen > left.bv_len ) {
1187 match = memcmp( sub->sa_final.bv_val,
1188 &left.bv_val[left.bv_len - sub->sa_final.bv_len],
1189 sub->sa_final.bv_len );
1195 left.bv_len -= sub->sa_final.bv_len;
1196 inlen -= sub->sa_final.bv_len;
1200 for(i=0; sub->sa_any[i].bv_val; i++) {
1205 if( inlen > left.bv_len ) {
1206 /* not enough length */
1211 if( sub->sa_any[i].bv_len == 0 ) {
1215 p = ber_bvchr( &left, *sub->sa_any[i].bv_val );
1221 idx = p - left.bv_val;
1223 if( idx >= left.bv_len ) {
1224 /* this shouldn't happen */
1226 if ( sub->sa_final.bv_val )
1227 ch_free( sub->sa_final.bv_val );
1229 ber_bvarray_free( sub->sa_any );
1230 if ( sub->sa_initial.bv_val )
1231 ch_free( sub->sa_initial.bv_val );
1239 if( sub->sa_any[i].bv_len > left.bv_len ) {
1240 /* not enough left */
1245 match = memcmp( left.bv_val,
1246 sub->sa_any[i].bv_val,
1247 sub->sa_any[i].bv_len );
1255 left.bv_val += sub->sa_any[i].bv_len;
1256 left.bv_len -= sub->sa_any[i].bv_len;
1257 inlen -= sub->sa_any[i].bv_len;
1264 if ( sub->sa_final.bv_val ) free( sub->sa_final.bv_val );
1265 if ( sub->sa_any ) ber_bvarray_free( sub->sa_any );
1266 if ( sub->sa_initial.bv_val ) free( sub->sa_initial.bv_val );
1270 return LDAP_SUCCESS;
1273 /* Index generation function */
1274 static int caseExactIgnoreIndexer(
1279 struct berval *prefix,
1287 HASH_CONTEXT HASHcontext;
1288 unsigned char HASHdigest[HASH_BYTES];
1289 struct berval digest;
1290 digest.bv_val = HASHdigest;
1291 digest.bv_len = sizeof(HASHdigest);
1293 for( i=0; values[i].bv_val != NULL; i++ ) {
1294 /* empty - just count them */
1297 /* we should have at least one value at this point */
1300 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
1302 slen = syntax->ssyn_oidlen;
1303 mlen = mr->smr_oidlen;
1305 casefold = ( mr != caseExactMatchingRule )
1306 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1308 for( i=0; values[i].bv_val != NULL; i++ ) {
1309 struct berval value;
1310 UTF8bvnormalize( &values[i], &value, casefold );
1312 HASH_Init( &HASHcontext );
1313 if( prefix != NULL && prefix->bv_len > 0 ) {
1314 HASH_Update( &HASHcontext,
1315 prefix->bv_val, prefix->bv_len );
1317 HASH_Update( &HASHcontext,
1318 syntax->ssyn_oid, slen );
1319 HASH_Update( &HASHcontext,
1320 mr->smr_oid, mlen );
1321 HASH_Update( &HASHcontext,
1322 value.bv_val, value.bv_len );
1323 HASH_Final( HASHdigest, &HASHcontext );
1325 free( value.bv_val );
1327 ber_dupbv( &keys[i], &digest );
1330 keys[i].bv_val = NULL;
1332 return LDAP_SUCCESS;
1335 /* Index generation function */
1336 static int caseExactIgnoreFilter(
1341 struct berval *prefix,
1342 void * assertedValue,
1348 HASH_CONTEXT HASHcontext;
1349 unsigned char HASHdigest[HASH_BYTES];
1350 struct berval value = { 0, NULL };
1351 struct berval digest;
1353 digest.bv_val = HASHdigest;
1354 digest.bv_len = sizeof(HASHdigest);
1356 slen = syntax->ssyn_oidlen;
1357 mlen = mr->smr_oidlen;
1359 casefold = ( mr != caseExactMatchingRule )
1360 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1362 UTF8bvnormalize( (struct berval *) assertedValue, &value, casefold );
1363 /* This usually happens if filter contains bad UTF8 */
1364 if( value.bv_val == NULL ) {
1365 keys = ch_malloc( sizeof( struct berval ) );
1366 keys[0].bv_val = NULL;
1367 return LDAP_SUCCESS;
1370 keys = ch_malloc( sizeof( struct berval ) * 2 );
1372 HASH_Init( &HASHcontext );
1373 if( prefix != NULL && prefix->bv_len > 0 ) {
1374 HASH_Update( &HASHcontext,
1375 prefix->bv_val, prefix->bv_len );
1377 HASH_Update( &HASHcontext,
1378 syntax->ssyn_oid, slen );
1379 HASH_Update( &HASHcontext,
1380 mr->smr_oid, mlen );
1381 HASH_Update( &HASHcontext,
1382 value.bv_val, value.bv_len );
1383 HASH_Final( HASHdigest, &HASHcontext );
1385 ber_dupbv( keys, &digest );
1386 keys[1].bv_val = NULL;
1388 free( value.bv_val );
1391 return LDAP_SUCCESS;
1394 /* Substrings Index generation function */
1395 static int caseExactIgnoreSubstringsIndexer(
1400 struct berval *prefix,
1410 HASH_CONTEXT HASHcontext;
1411 unsigned char HASHdigest[HASH_BYTES];
1412 struct berval digest;
1413 digest.bv_val = HASHdigest;
1414 digest.bv_len = sizeof(HASHdigest);
1418 for( i=0; values[i].bv_val != NULL; i++ ) {
1419 /* empty - just count them */
1422 /* we should have at least one value at this point */
1425 casefold = ( mr != caseExactSubstringsMatchingRule )
1426 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1428 nvalues = ch_malloc( sizeof( struct berval ) * (i+1) );
1429 for( i=0; values[i].bv_val != NULL; i++ ) {
1430 UTF8bvnormalize( &values[i], &nvalues[i], casefold );
1432 nvalues[i].bv_val = NULL;
1435 for( i=0; values[i].bv_val != NULL; i++ ) {
1436 /* count number of indices to generate */
1437 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
1441 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
1442 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1443 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
1444 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
1446 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
1450 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
1451 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1452 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
1456 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
1457 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1458 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
1459 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
1461 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
1467 /* no keys to generate */
1469 ber_bvarray_free( nvalues );
1470 return LDAP_SUCCESS;
1473 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
1475 slen = syntax->ssyn_oidlen;
1476 mlen = mr->smr_oidlen;
1479 for( i=0; values[i].bv_val != NULL; i++ ) {
1482 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
1484 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
1485 ( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
1487 char pre = SLAP_INDEX_SUBSTR_PREFIX;
1488 max = values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
1490 for( j=0; j<max; j++ ) {
1491 HASH_Init( &HASHcontext );
1492 if( prefix != NULL && prefix->bv_len > 0 ) {
1493 HASH_Update( &HASHcontext,
1494 prefix->bv_val, prefix->bv_len );
1497 HASH_Update( &HASHcontext,
1498 &pre, sizeof( pre ) );
1499 HASH_Update( &HASHcontext,
1500 syntax->ssyn_oid, slen );
1501 HASH_Update( &HASHcontext,
1502 mr->smr_oid, mlen );
1503 HASH_Update( &HASHcontext,
1504 &values[i].bv_val[j],
1505 SLAP_INDEX_SUBSTR_MAXLEN );
1506 HASH_Final( HASHdigest, &HASHcontext );
1508 ber_dupbv( &keys[nkeys++], &digest );
1512 max = SLAP_INDEX_SUBSTR_MAXLEN < values[i].bv_len
1513 ? SLAP_INDEX_SUBSTR_MAXLEN : values[i].bv_len;
1515 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
1518 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
1519 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
1520 HASH_Init( &HASHcontext );
1521 if( prefix != NULL && prefix->bv_len > 0 ) {
1522 HASH_Update( &HASHcontext,
1523 prefix->bv_val, prefix->bv_len );
1525 HASH_Update( &HASHcontext,
1526 &pre, sizeof( pre ) );
1527 HASH_Update( &HASHcontext,
1528 syntax->ssyn_oid, slen );
1529 HASH_Update( &HASHcontext,
1530 mr->smr_oid, mlen );
1531 HASH_Update( &HASHcontext,
1532 values[i].bv_val, j );
1533 HASH_Final( HASHdigest, &HASHcontext );
1535 ber_dupbv( &keys[nkeys++], &digest );
1538 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
1539 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
1540 HASH_Init( &HASHcontext );
1541 if( prefix != NULL && prefix->bv_len > 0 ) {
1542 HASH_Update( &HASHcontext,
1543 prefix->bv_val, prefix->bv_len );
1545 HASH_Update( &HASHcontext,
1546 &pre, sizeof( pre ) );
1547 HASH_Update( &HASHcontext,
1548 syntax->ssyn_oid, slen );
1549 HASH_Update( &HASHcontext,
1550 mr->smr_oid, mlen );
1551 HASH_Update( &HASHcontext,
1552 &values[i].bv_val[values[i].bv_len-j], j );
1553 HASH_Final( HASHdigest, &HASHcontext );
1555 ber_dupbv( &keys[nkeys++], &digest );
1563 keys[nkeys].bv_val = NULL;
1570 ber_bvarray_free( nvalues );
1572 return LDAP_SUCCESS;
1575 static int caseExactIgnoreSubstringsFilter(
1580 struct berval *prefix,
1581 void * assertedValue,
1584 SubstringsAssertion *sa;
1587 ber_len_t nkeys = 0;
1588 size_t slen, mlen, klen;
1590 HASH_CONTEXT HASHcontext;
1591 unsigned char HASHdigest[HASH_BYTES];
1592 struct berval *value;
1593 struct berval digest;
1595 casefold = ( mr != caseExactSubstringsMatchingRule )
1596 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1598 sa = UTF8SubstringsassertionNormalize( assertedValue, casefold );
1601 return LDAP_SUCCESS;
1604 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
1605 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1610 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
1612 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
1613 if( sa->sa_any[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1614 /* don't bother accounting for stepping */
1615 nkeys += sa->sa_any[i].bv_len -
1616 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
1621 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
1622 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1628 if ( sa->sa_final.bv_val ) free( sa->sa_final.bv_val );
1629 if ( sa->sa_any ) ber_bvarray_free( sa->sa_any );
1630 if ( sa->sa_initial.bv_val ) free( sa->sa_initial.bv_val );
1633 return LDAP_SUCCESS;
1636 digest.bv_val = HASHdigest;
1637 digest.bv_len = sizeof(HASHdigest);
1639 slen = syntax->ssyn_oidlen;
1640 mlen = mr->smr_oidlen;
1642 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
1645 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
1646 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1648 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
1649 value = &sa->sa_initial;
1651 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
1652 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
1654 HASH_Init( &HASHcontext );
1655 if( prefix != NULL && prefix->bv_len > 0 ) {
1656 HASH_Update( &HASHcontext,
1657 prefix->bv_val, prefix->bv_len );
1659 HASH_Update( &HASHcontext,
1660 &pre, sizeof( pre ) );
1661 HASH_Update( &HASHcontext,
1662 syntax->ssyn_oid, slen );
1663 HASH_Update( &HASHcontext,
1664 mr->smr_oid, mlen );
1665 HASH_Update( &HASHcontext,
1666 value->bv_val, klen );
1667 HASH_Final( HASHdigest, &HASHcontext );
1669 ber_dupbv( &keys[nkeys++], &digest );
1672 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
1674 pre = SLAP_INDEX_SUBSTR_PREFIX;
1675 klen = SLAP_INDEX_SUBSTR_MAXLEN;
1677 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
1678 if( sa->sa_any[i].bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
1682 value = &sa->sa_any[i];
1685 j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
1686 j += SLAP_INDEX_SUBSTR_STEP )
1688 HASH_Init( &HASHcontext );
1689 if( prefix != NULL && prefix->bv_len > 0 ) {
1690 HASH_Update( &HASHcontext,
1691 prefix->bv_val, prefix->bv_len );
1693 HASH_Update( &HASHcontext,
1694 &pre, sizeof( pre ) );
1695 HASH_Update( &HASHcontext,
1696 syntax->ssyn_oid, slen );
1697 HASH_Update( &HASHcontext,
1698 mr->smr_oid, mlen );
1699 HASH_Update( &HASHcontext,
1700 &value->bv_val[j], klen );
1701 HASH_Final( HASHdigest, &HASHcontext );
1703 ber_dupbv( &keys[nkeys++], &digest );
1709 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
1710 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1712 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
1713 value = &sa->sa_final;
1715 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
1716 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
1718 HASH_Init( &HASHcontext );
1719 if( prefix != NULL && prefix->bv_len > 0 ) {
1720 HASH_Update( &HASHcontext,
1721 prefix->bv_val, prefix->bv_len );
1723 HASH_Update( &HASHcontext,
1724 &pre, sizeof( pre ) );
1725 HASH_Update( &HASHcontext,
1726 syntax->ssyn_oid, slen );
1727 HASH_Update( &HASHcontext,
1728 mr->smr_oid, mlen );
1729 HASH_Update( &HASHcontext,
1730 &value->bv_val[value->bv_len-klen], klen );
1731 HASH_Final( HASHdigest, &HASHcontext );
1733 ber_dupbv( &keys[nkeys++], &digest );
1737 keys[nkeys].bv_val = NULL;
1743 if ( sa->sa_final.bv_val ) free( sa->sa_final.bv_val );
1744 if ( sa->sa_any ) ber_bvarray_free( sa->sa_any );
1745 if ( sa->sa_initial.bv_val ) free( sa->sa_initial.bv_val );
1748 return LDAP_SUCCESS;
1757 struct berval *value,
1758 void *assertedValue )
1760 *matchp = UTF8bvnormcmp( value,
1761 (struct berval *) assertedValue,
1762 LDAP_UTF8_CASEFOLD );
1763 return LDAP_SUCCESS;
1766 /* Remove all spaces and '-' characters */
1768 telephoneNumberNormalize(
1771 struct berval *normalized )
1775 /* validator should have refused an empty string */
1776 assert( val->bv_len );
1778 q = normalized->bv_val = ch_malloc( val->bv_len + 1 );
1780 for( p = val->bv_val; *p; p++ ) {
1781 if ( ! ( ASCII_SPACE( *p ) || *p == '-' )) {
1787 normalized->bv_len = q - normalized->bv_val;
1789 if( normalized->bv_len == 0 ) {
1790 free( normalized->bv_val );
1791 return LDAP_INVALID_SYNTAX;
1794 return LDAP_SUCCESS;
1800 struct berval *val )
1804 if( val->bv_len == 0 ) {
1805 /* disallow empty strings */
1806 return LDAP_INVALID_SYNTAX;
1809 if( OID_LEADCHAR(val->bv_val[0]) ) {
1811 for(i=1; i < val->bv_len; i++) {
1812 if( OID_SEPARATOR( val->bv_val[i] ) ) {
1813 if( dot++ ) return 1;
1814 } else if ( OID_CHAR( val->bv_val[i] ) ) {
1817 return LDAP_INVALID_SYNTAX;
1821 return !dot ? LDAP_SUCCESS : LDAP_INVALID_SYNTAX;
1823 } else if( DESC_LEADCHAR(val->bv_val[0]) ) {
1824 for(i=1; i < val->bv_len; i++) {
1825 if( !DESC_CHAR(val->bv_val[i] ) ) {
1826 return LDAP_INVALID_SYNTAX;
1830 return LDAP_SUCCESS;
1833 return LDAP_INVALID_SYNTAX;
1842 struct berval *value,
1843 void *assertedValue )
1846 int vsign = 1, avsign = 1; /* default sign = '+' */
1847 struct berval *asserted;
1848 ber_len_t vlen, avlen;
1851 /* Skip leading space/sign/zeroes, and get the sign of the *value number */
1853 vlen = value->bv_len;
1854 if( mr == integerFirstComponentMatchingRule ) {
1855 char *tmp = memchr( v, '$', vlen );
1858 while( vlen && ASCII_SPACE( v[vlen-1] ))
1861 for( ; vlen && ( *v < '1' || '9' < *v ); v++, vlen-- ) /* ANSI 2.2.1 */
1867 /* Do the same with the *assertedValue number */
1868 asserted = (struct berval *) assertedValue;
1869 av = asserted->bv_val;
1870 avlen = asserted->bv_len;
1871 for( ; avlen && ( *av < '1' || '9' < *av ); av++, avlen-- )
1877 match = vsign - avsign;
1879 match = (vlen != avlen
1880 ? ( vlen < avlen ? -1 : 1 )
1881 : memcmp( v, av, vlen ));
1887 return LDAP_SUCCESS;
1893 struct berval *val )
1897 if( !val->bv_len ) return LDAP_INVALID_SYNTAX;
1899 if(( val->bv_val[0] == '+' ) || ( val->bv_val[0] == '-' )) {
1900 if( val->bv_len < 2 ) return LDAP_INVALID_SYNTAX;
1901 } else if( !ASCII_DIGIT(val->bv_val[0]) ) {
1902 return LDAP_INVALID_SYNTAX;
1905 for( i=1; i < val->bv_len; i++ ) {
1906 if( !ASCII_DIGIT(val->bv_val[i]) ) return LDAP_INVALID_SYNTAX;
1909 return LDAP_SUCCESS;
1916 struct berval *normalized )
1926 /* Ignore leading spaces */
1927 while ( len && ( *p == ' ' )) {
1934 negative = ( *p == '-' );
1935 if(( *p == '-' ) || ( *p == '+' )) {
1941 /* Ignore leading zeros */
1942 while ( len && ( *p == '0' )) {
1947 /* If there are no non-zero digits left, the number is zero, otherwise
1948 allocate space for the number and copy it into the buffer */
1950 normalized->bv_val = ch_strdup("0");
1951 normalized->bv_len = 1;
1954 normalized->bv_len = len+negative;
1955 normalized->bv_val = ch_malloc( normalized->bv_len + 1 );
1957 normalized->bv_val[0] = '-';
1959 AC_MEMCPY( normalized->bv_val + negative, p, len );
1960 normalized->bv_val[len+negative] = '\0';
1963 return LDAP_SUCCESS;
1966 /* Index generation function */
1967 static int integerIndexer(
1972 struct berval *prefix,
1979 HASH_CONTEXT HASHcontext;
1980 unsigned char HASHdigest[HASH_BYTES];
1981 struct berval digest;
1982 digest.bv_val = HASHdigest;
1983 digest.bv_len = sizeof(HASHdigest);
1985 for( i=0; values[i].bv_val != NULL; i++ ) {
1986 /* empty - just count them */
1989 /* we should have at least one value at this point */
1992 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
1994 slen = syntax->ssyn_oidlen;
1995 mlen = mr->smr_oidlen;
1997 for( i=0; values[i].bv_val != NULL; i++ ) {
1999 integerNormalize( syntax, &values[i], &norm );
2001 HASH_Init( &HASHcontext );
2002 if( prefix != NULL && prefix->bv_len > 0 ) {
2003 HASH_Update( &HASHcontext,
2004 prefix->bv_val, prefix->bv_len );
2006 HASH_Update( &HASHcontext,
2007 syntax->ssyn_oid, slen );
2008 HASH_Update( &HASHcontext,
2009 mr->smr_oid, mlen );
2010 HASH_Update( &HASHcontext,
2011 norm.bv_val, norm.bv_len );
2012 HASH_Final( HASHdigest, &HASHcontext );
2014 ber_dupbv( &keys[i], &digest );
2015 ch_free( norm.bv_val );
2018 keys[i].bv_val = NULL;
2020 return LDAP_SUCCESS;
2023 /* Index generation function */
2024 static int integerFilter(
2029 struct berval *prefix,
2030 void * assertedValue,
2035 HASH_CONTEXT HASHcontext;
2036 unsigned char HASHdigest[HASH_BYTES];
2038 struct berval digest;
2039 digest.bv_val = HASHdigest;
2040 digest.bv_len = sizeof(HASHdigest);
2042 slen = syntax->ssyn_oidlen;
2043 mlen = mr->smr_oidlen;
2045 integerNormalize( syntax, assertedValue, &norm );
2047 keys = ch_malloc( sizeof( struct berval ) * 2 );
2049 HASH_Init( &HASHcontext );
2050 if( prefix != NULL && prefix->bv_len > 0 ) {
2051 HASH_Update( &HASHcontext,
2052 prefix->bv_val, prefix->bv_len );
2054 HASH_Update( &HASHcontext,
2055 syntax->ssyn_oid, slen );
2056 HASH_Update( &HASHcontext,
2057 mr->smr_oid, mlen );
2058 HASH_Update( &HASHcontext,
2059 norm.bv_val, norm.bv_len );
2060 HASH_Final( HASHdigest, &HASHcontext );
2062 ber_dupbv( &keys[0], &digest );
2063 keys[1].bv_val = NULL;
2064 ch_free( norm.bv_val );
2067 return LDAP_SUCCESS;
2072 countryStringValidate(
2074 struct berval *val )
2076 if( val->bv_len != 2 ) return LDAP_INVALID_SYNTAX;
2078 if( !SLAP_PRINTABLE(val->bv_val[0]) ) {
2079 return LDAP_INVALID_SYNTAX;
2081 if( !SLAP_PRINTABLE(val->bv_val[1]) ) {
2082 return LDAP_INVALID_SYNTAX;
2085 return LDAP_SUCCESS;
2089 printableStringValidate(
2091 struct berval *val )
2095 if( val->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
2097 for(i=0; i < val->bv_len; i++) {
2098 if( !SLAP_PRINTABLE(val->bv_val[i]) ) {
2099 return LDAP_INVALID_SYNTAX;
2103 return LDAP_SUCCESS;
2107 printablesStringValidate(
2109 struct berval *val )
2113 if( val->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
2115 for(i=0,len=0; i < val->bv_len; i++) {
2116 int c = val->bv_val[i];
2120 return LDAP_INVALID_SYNTAX;
2124 } else if ( SLAP_PRINTABLE(c) ) {
2127 return LDAP_INVALID_SYNTAX;
2132 return LDAP_INVALID_SYNTAX;
2135 return LDAP_SUCCESS;
2141 struct berval *val )
2145 if( val->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
2147 for(i=0; i < val->bv_len; i++) {
2148 if( !LDAP_ASCII(val->bv_val[i]) ) {
2149 return LDAP_INVALID_SYNTAX;
2153 return LDAP_SUCCESS;
2160 struct berval *normalized )
2164 assert( val->bv_len );
2168 /* Ignore initial whitespace */
2169 while ( ASCII_SPACE( *p ) ) {
2173 normalized->bv_val = ch_strdup( p );
2174 p = q = normalized->bv_val;
2177 if ( ASCII_SPACE( *p ) ) {
2180 /* Ignore the extra whitespace */
2181 while ( ASCII_SPACE( *p ) ) {
2189 assert( normalized->bv_val <= p );
2193 * If the string ended in space, backup the pointer one
2194 * position. One is enough because the above loop collapsed
2195 * all whitespace to a single space.
2198 if ( ASCII_SPACE( q[-1] ) ) {
2202 /* null terminate */
2205 normalized->bv_len = q - normalized->bv_val;
2207 if( normalized->bv_len == 0 ) {
2208 normalized->bv_val = ch_realloc( normalized->bv_val, 2 );
2209 normalized->bv_val[0] = ' ';
2210 normalized->bv_val[1] = '\0';
2211 normalized->bv_len = 1;
2214 return LDAP_SUCCESS;
2223 struct berval *value,
2224 void *assertedValue )
2226 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
2229 match = strncmp( value->bv_val,
2230 ((struct berval *) assertedValue)->bv_val,
2235 return LDAP_SUCCESS;
2239 caseExactIA5SubstringsMatch(
2244 struct berval *value,
2245 void *assertedValue )
2248 SubstringsAssertion *sub = assertedValue;
2249 struct berval left = *value;
2253 /* Add up asserted input length */
2254 if( sub->sa_initial.bv_val ) {
2255 inlen += sub->sa_initial.bv_len;
2258 for(i=0; sub->sa_any[i].bv_val != NULL; i++) {
2259 inlen += sub->sa_any[i].bv_len;
2262 if( sub->sa_final.bv_val ) {
2263 inlen += sub->sa_final.bv_len;
2266 if( sub->sa_initial.bv_val ) {
2267 if( inlen > left.bv_len ) {
2272 match = strncmp( sub->sa_initial.bv_val, left.bv_val,
2273 sub->sa_initial.bv_len );
2279 left.bv_val += sub->sa_initial.bv_len;
2280 left.bv_len -= sub->sa_initial.bv_len;
2281 inlen -= sub->sa_initial.bv_len;
2284 if( sub->sa_final.bv_val ) {
2285 if( inlen > left.bv_len ) {
2290 match = strncmp( sub->sa_final.bv_val,
2291 &left.bv_val[left.bv_len - sub->sa_final.bv_len],
2292 sub->sa_final.bv_len );
2298 left.bv_len -= sub->sa_final.bv_len;
2299 inlen -= sub->sa_final.bv_len;
2303 for(i=0; sub->sa_any[i].bv_val; i++) {
2308 if( inlen > left.bv_len ) {
2309 /* not enough length */
2314 if( sub->sa_any[i].bv_len == 0 ) {
2318 p = strchr( left.bv_val, *sub->sa_any[i].bv_val );
2325 idx = p - left.bv_val;
2327 if( idx >= left.bv_len ) {
2328 /* this shouldn't happen */
2335 if( sub->sa_any[i].bv_len > left.bv_len ) {
2336 /* not enough left */
2341 match = strncmp( left.bv_val,
2342 sub->sa_any[i].bv_val,
2343 sub->sa_any[i].bv_len );
2351 left.bv_val += sub->sa_any[i].bv_len;
2352 left.bv_len -= sub->sa_any[i].bv_len;
2353 inlen -= sub->sa_any[i].bv_len;
2359 return LDAP_SUCCESS;
2362 /* Index generation function */
2363 static int caseExactIA5Indexer(
2368 struct berval *prefix,
2375 HASH_CONTEXT HASHcontext;
2376 unsigned char HASHdigest[HASH_BYTES];
2377 struct berval digest;
2378 digest.bv_val = HASHdigest;
2379 digest.bv_len = sizeof(HASHdigest);
2381 for( i=0; values[i].bv_val != NULL; i++ ) {
2382 /* empty - just count them */
2385 /* we should have at least one value at this point */
2388 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
2390 slen = syntax->ssyn_oidlen;
2391 mlen = mr->smr_oidlen;
2393 for( i=0; values[i].bv_val != NULL; i++ ) {
2394 struct berval *value = &values[i];
2396 HASH_Init( &HASHcontext );
2397 if( prefix != NULL && prefix->bv_len > 0 ) {
2398 HASH_Update( &HASHcontext,
2399 prefix->bv_val, prefix->bv_len );
2401 HASH_Update( &HASHcontext,
2402 syntax->ssyn_oid, slen );
2403 HASH_Update( &HASHcontext,
2404 mr->smr_oid, mlen );
2405 HASH_Update( &HASHcontext,
2406 value->bv_val, value->bv_len );
2407 HASH_Final( HASHdigest, &HASHcontext );
2409 ber_dupbv( &keys[i], &digest );
2412 keys[i].bv_val = NULL;
2414 return LDAP_SUCCESS;
2417 /* Index generation function */
2418 static int caseExactIA5Filter(
2423 struct berval *prefix,
2424 void * assertedValue,
2429 HASH_CONTEXT HASHcontext;
2430 unsigned char HASHdigest[HASH_BYTES];
2431 struct berval *value;
2432 struct berval digest;
2433 digest.bv_val = HASHdigest;
2434 digest.bv_len = sizeof(HASHdigest);
2436 slen = syntax->ssyn_oidlen;
2437 mlen = mr->smr_oidlen;
2439 value = (struct berval *) assertedValue;
2441 keys = ch_malloc( sizeof( struct berval ) * 2 );
2443 HASH_Init( &HASHcontext );
2444 if( prefix != NULL && prefix->bv_len > 0 ) {
2445 HASH_Update( &HASHcontext,
2446 prefix->bv_val, prefix->bv_len );
2448 HASH_Update( &HASHcontext,
2449 syntax->ssyn_oid, slen );
2450 HASH_Update( &HASHcontext,
2451 mr->smr_oid, mlen );
2452 HASH_Update( &HASHcontext,
2453 value->bv_val, value->bv_len );
2454 HASH_Final( HASHdigest, &HASHcontext );
2456 ber_dupbv( &keys[0], &digest );
2457 keys[1].bv_val = NULL;
2460 return LDAP_SUCCESS;
2463 /* Substrings Index generation function */
2464 static int caseExactIA5SubstringsIndexer(
2469 struct berval *prefix,
2476 HASH_CONTEXT HASHcontext;
2477 unsigned char HASHdigest[HASH_BYTES];
2478 struct berval digest;
2479 digest.bv_val = HASHdigest;
2480 digest.bv_len = sizeof(HASHdigest);
2482 /* we should have at least one value at this point */
2483 assert( values != NULL && values[0].bv_val != NULL );
2486 for( i=0; values[i].bv_val != NULL; i++ ) {
2487 /* count number of indices to generate */
2488 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
2492 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
2493 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2494 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2495 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2497 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2501 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
2502 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2503 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
2507 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
2508 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2509 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2510 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2512 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2518 /* no keys to generate */
2520 return LDAP_SUCCESS;
2523 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
2525 slen = syntax->ssyn_oidlen;
2526 mlen = mr->smr_oidlen;
2529 for( i=0; values[i].bv_val != NULL; i++ ) {
2531 struct berval *value;
2534 if( value->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
2536 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
2537 ( value->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
2539 char pre = SLAP_INDEX_SUBSTR_PREFIX;
2540 max = value->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
2542 for( j=0; j<max; j++ ) {
2543 HASH_Init( &HASHcontext );
2544 if( prefix != NULL && prefix->bv_len > 0 ) {
2545 HASH_Update( &HASHcontext,
2546 prefix->bv_val, prefix->bv_len );
2549 HASH_Update( &HASHcontext,
2550 &pre, sizeof( pre ) );
2551 HASH_Update( &HASHcontext,
2552 syntax->ssyn_oid, slen );
2553 HASH_Update( &HASHcontext,
2554 mr->smr_oid, mlen );
2555 HASH_Update( &HASHcontext,
2557 SLAP_INDEX_SUBSTR_MAXLEN );
2558 HASH_Final( HASHdigest, &HASHcontext );
2560 ber_dupbv( &keys[nkeys++], &digest );
2564 max = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2565 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2567 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
2570 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
2571 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
2572 HASH_Init( &HASHcontext );
2573 if( prefix != NULL && prefix->bv_len > 0 ) {
2574 HASH_Update( &HASHcontext,
2575 prefix->bv_val, prefix->bv_len );
2577 HASH_Update( &HASHcontext,
2578 &pre, sizeof( pre ) );
2579 HASH_Update( &HASHcontext,
2580 syntax->ssyn_oid, slen );
2581 HASH_Update( &HASHcontext,
2582 mr->smr_oid, mlen );
2583 HASH_Update( &HASHcontext,
2585 HASH_Final( HASHdigest, &HASHcontext );
2587 ber_dupbv( &keys[nkeys++], &digest );
2590 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
2591 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
2592 HASH_Init( &HASHcontext );
2593 if( prefix != NULL && prefix->bv_len > 0 ) {
2594 HASH_Update( &HASHcontext,
2595 prefix->bv_val, prefix->bv_len );
2597 HASH_Update( &HASHcontext,
2598 &pre, sizeof( pre ) );
2599 HASH_Update( &HASHcontext,
2600 syntax->ssyn_oid, slen );
2601 HASH_Update( &HASHcontext,
2602 mr->smr_oid, mlen );
2603 HASH_Update( &HASHcontext,
2604 &value->bv_val[value->bv_len-j], j );
2605 HASH_Final( HASHdigest, &HASHcontext );
2607 ber_dupbv( &keys[nkeys++], &digest );
2614 keys[nkeys].bv_val = NULL;
2621 return LDAP_SUCCESS;
2624 static int caseExactIA5SubstringsFilter(
2629 struct berval *prefix,
2630 void * assertedValue,
2633 SubstringsAssertion *sa = assertedValue;
2635 ber_len_t nkeys = 0;
2636 size_t slen, mlen, klen;
2638 HASH_CONTEXT HASHcontext;
2639 unsigned char HASHdigest[HASH_BYTES];
2640 struct berval *value;
2641 struct berval digest;
2643 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
2644 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2649 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
2651 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
2652 if( sa->sa_any[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2653 /* don't bother accounting for stepping */
2654 nkeys += sa->sa_any[i].bv_len -
2655 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
2660 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
2661 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2668 return LDAP_SUCCESS;
2671 digest.bv_val = HASHdigest;
2672 digest.bv_len = sizeof(HASHdigest);
2674 slen = syntax->ssyn_oidlen;
2675 mlen = mr->smr_oidlen;
2677 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
2680 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
2681 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2683 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
2684 value = &sa->sa_initial;
2686 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2687 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2689 HASH_Init( &HASHcontext );
2690 if( prefix != NULL && prefix->bv_len > 0 ) {
2691 HASH_Update( &HASHcontext,
2692 prefix->bv_val, prefix->bv_len );
2694 HASH_Update( &HASHcontext,
2695 &pre, sizeof( pre ) );
2696 HASH_Update( &HASHcontext,
2697 syntax->ssyn_oid, slen );
2698 HASH_Update( &HASHcontext,
2699 mr->smr_oid, mlen );
2700 HASH_Update( &HASHcontext,
2701 value->bv_val, klen );
2702 HASH_Final( HASHdigest, &HASHcontext );
2704 ber_dupbv( &keys[nkeys++], &digest );
2707 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
2709 pre = SLAP_INDEX_SUBSTR_PREFIX;
2710 klen = SLAP_INDEX_SUBSTR_MAXLEN;
2712 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
2713 if( sa->sa_any[i].bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
2717 value = &sa->sa_any[i];
2720 j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
2721 j += SLAP_INDEX_SUBSTR_STEP )
2723 HASH_Init( &HASHcontext );
2724 if( prefix != NULL && prefix->bv_len > 0 ) {
2725 HASH_Update( &HASHcontext,
2726 prefix->bv_val, prefix->bv_len );
2728 HASH_Update( &HASHcontext,
2729 &pre, sizeof( pre ) );
2730 HASH_Update( &HASHcontext,
2731 syntax->ssyn_oid, slen );
2732 HASH_Update( &HASHcontext,
2733 mr->smr_oid, mlen );
2734 HASH_Update( &HASHcontext,
2735 &value->bv_val[j], klen );
2736 HASH_Final( HASHdigest, &HASHcontext );
2738 ber_dupbv( &keys[nkeys++], &digest );
2743 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
2744 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2746 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
2747 value = &sa->sa_final;
2749 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2750 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2752 HASH_Init( &HASHcontext );
2753 if( prefix != NULL && prefix->bv_len > 0 ) {
2754 HASH_Update( &HASHcontext,
2755 prefix->bv_val, prefix->bv_len );
2757 HASH_Update( &HASHcontext,
2758 &pre, sizeof( pre ) );
2759 HASH_Update( &HASHcontext,
2760 syntax->ssyn_oid, slen );
2761 HASH_Update( &HASHcontext,
2762 mr->smr_oid, mlen );
2763 HASH_Update( &HASHcontext,
2764 &value->bv_val[value->bv_len-klen], klen );
2765 HASH_Final( HASHdigest, &HASHcontext );
2767 ber_dupbv( &keys[nkeys++], &digest );
2771 keys[nkeys].bv_val = NULL;
2778 return LDAP_SUCCESS;
2787 struct berval *value,
2788 void *assertedValue )
2790 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
2792 if( match == 0 && value->bv_len ) {
2793 match = strncasecmp( value->bv_val,
2794 ((struct berval *) assertedValue)->bv_val,
2799 return LDAP_SUCCESS;
2803 caseIgnoreIA5SubstringsMatch(
2808 struct berval *value,
2809 void *assertedValue )
2812 SubstringsAssertion *sub = assertedValue;
2813 struct berval left = *value;
2817 /* Add up asserted input length */
2818 if( sub->sa_initial.bv_val ) {
2819 inlen += sub->sa_initial.bv_len;
2822 for(i=0; sub->sa_any[i].bv_val != NULL; i++) {
2823 inlen += sub->sa_any[i].bv_len;
2826 if( sub->sa_final.bv_val ) {
2827 inlen += sub->sa_final.bv_len;
2830 if( sub->sa_initial.bv_val ) {
2831 if( inlen > left.bv_len ) {
2836 match = strncasecmp( sub->sa_initial.bv_val, left.bv_val,
2837 sub->sa_initial.bv_len );
2843 left.bv_val += sub->sa_initial.bv_len;
2844 left.bv_len -= sub->sa_initial.bv_len;
2845 inlen -= sub->sa_initial.bv_len;
2848 if( sub->sa_final.bv_val ) {
2849 if( inlen > left.bv_len ) {
2854 match = strncasecmp( sub->sa_final.bv_val,
2855 &left.bv_val[left.bv_len - sub->sa_final.bv_len],
2856 sub->sa_final.bv_len );
2862 left.bv_len -= sub->sa_final.bv_len;
2863 inlen -= sub->sa_final.bv_len;
2867 for(i=0; sub->sa_any[i].bv_val; i++) {
2872 if( inlen > left.bv_len ) {
2873 /* not enough length */
2878 if( sub->sa_any[i].bv_len == 0 ) {
2882 p = bvcasechr( &left, *sub->sa_any[i].bv_val, &idx );
2889 assert( idx < left.bv_len );
2890 if( idx >= left.bv_len ) {
2891 /* this shouldn't happen */
2898 if( sub->sa_any[i].bv_len > left.bv_len ) {
2899 /* not enough left */
2904 match = strncasecmp( left.bv_val,
2905 sub->sa_any[i].bv_val,
2906 sub->sa_any[i].bv_len );
2915 left.bv_val += sub->sa_any[i].bv_len;
2916 left.bv_len -= sub->sa_any[i].bv_len;
2917 inlen -= sub->sa_any[i].bv_len;
2923 return LDAP_SUCCESS;
2926 /* Index generation function */
2927 static int caseIgnoreIA5Indexer(
2932 struct berval *prefix,
2937 int rc = LDAP_SUCCESS;
2940 HASH_CONTEXT HASHcontext;
2941 unsigned char HASHdigest[HASH_BYTES];
2942 struct berval digest;
2943 digest.bv_val = HASHdigest;
2944 digest.bv_len = sizeof(HASHdigest);
2946 /* we should have at least one value at this point */
2947 assert( values != NULL && values[0].bv_val != NULL );
2949 for( i=0; values[i].bv_val != NULL; i++ ) {
2950 /* just count them */
2953 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
2955 slen = syntax->ssyn_oidlen;
2956 mlen = mr->smr_oidlen;
2958 for( i=0; values[i].bv_val != NULL; i++ ) {
2959 struct berval value;
2961 if( mr->smr_normalize ) {
2962 rc = (mr->smr_normalize)( use, syntax, mr, &values[i], &value );
2963 if( rc != LDAP_SUCCESS ) {
2966 } else if ( mr->smr_syntax->ssyn_normalize ) {
2967 rc = (mr->smr_syntax->ssyn_normalize)( syntax, &values[i], &value );
2968 if( rc != LDAP_SUCCESS ) {
2972 ber_dupbv( &value, &values[i] );
2975 ldap_pvt_str2lower( value.bv_val );
2977 HASH_Init( &HASHcontext );
2978 if( prefix != NULL && prefix->bv_len > 0 ) {
2979 HASH_Update( &HASHcontext,
2980 prefix->bv_val, prefix->bv_len );
2982 HASH_Update( &HASHcontext,
2983 syntax->ssyn_oid, slen );
2984 HASH_Update( &HASHcontext,
2985 mr->smr_oid, mlen );
2986 HASH_Update( &HASHcontext,
2987 value.bv_val, value.bv_len );
2988 HASH_Final( HASHdigest, &HASHcontext );
2990 free( value.bv_val );
2992 ber_dupbv( &keys[i], &digest );
2995 keys[i].bv_val = NULL;
2996 if( rc != LDAP_SUCCESS ) {
2997 ber_bvarray_free( keys );
3004 /* Index generation function */
3005 static int caseIgnoreIA5Filter(
3010 struct berval *prefix,
3011 void * assertedValue,
3016 HASH_CONTEXT HASHcontext;
3017 unsigned char HASHdigest[HASH_BYTES];
3018 struct berval value;
3019 struct berval digest;
3020 digest.bv_val = HASHdigest;
3021 digest.bv_len = sizeof(HASHdigest);
3023 slen = syntax->ssyn_oidlen;
3024 mlen = mr->smr_oidlen;
3026 ber_dupbv( &value, (struct berval *) assertedValue );
3027 ldap_pvt_str2lower( value.bv_val );
3029 keys = ch_malloc( sizeof( struct berval ) * 2 );
3031 HASH_Init( &HASHcontext );
3032 if( prefix != NULL && prefix->bv_len > 0 ) {
3033 HASH_Update( &HASHcontext,
3034 prefix->bv_val, prefix->bv_len );
3036 HASH_Update( &HASHcontext,
3037 syntax->ssyn_oid, slen );
3038 HASH_Update( &HASHcontext,
3039 mr->smr_oid, mlen );
3040 HASH_Update( &HASHcontext,
3041 value.bv_val, value.bv_len );
3042 HASH_Final( HASHdigest, &HASHcontext );
3044 ber_dupbv( &keys[0], &digest );
3045 keys[1].bv_val = NULL;
3047 free( value.bv_val );
3051 return LDAP_SUCCESS;
3054 /* Substrings Index generation function */
3055 static int caseIgnoreIA5SubstringsIndexer(
3060 struct berval *prefix,
3067 HASH_CONTEXT HASHcontext;
3068 unsigned char HASHdigest[HASH_BYTES];
3069 struct berval digest;
3070 digest.bv_val = HASHdigest;
3071 digest.bv_len = sizeof(HASHdigest);
3073 /* we should have at least one value at this point */
3074 assert( values != NULL && values[0].bv_val != NULL );
3077 for( i=0; values[i].bv_val != NULL; i++ ) {
3078 /* count number of indices to generate */
3079 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
3083 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
3084 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3085 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
3086 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
3088 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
3092 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
3093 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3094 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
3098 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
3099 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3100 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
3101 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
3103 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
3109 /* no keys to generate */
3111 return LDAP_SUCCESS;
3114 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
3116 slen = syntax->ssyn_oidlen;
3117 mlen = mr->smr_oidlen;
3120 for( i=0; values[i].bv_val != NULL; i++ ) {
3122 struct berval value;
3124 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
3126 ber_dupbv( &value, &values[i] );
3127 ldap_pvt_str2lower( value.bv_val );
3129 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
3130 ( value.bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
3132 char pre = SLAP_INDEX_SUBSTR_PREFIX;
3133 max = value.bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
3135 for( j=0; j<max; j++ ) {
3136 HASH_Init( &HASHcontext );
3137 if( prefix != NULL && prefix->bv_len > 0 ) {
3138 HASH_Update( &HASHcontext,
3139 prefix->bv_val, prefix->bv_len );
3142 HASH_Update( &HASHcontext,
3143 &pre, sizeof( pre ) );
3144 HASH_Update( &HASHcontext,
3145 syntax->ssyn_oid, slen );
3146 HASH_Update( &HASHcontext,
3147 mr->smr_oid, mlen );
3148 HASH_Update( &HASHcontext,
3150 SLAP_INDEX_SUBSTR_MAXLEN );
3151 HASH_Final( HASHdigest, &HASHcontext );
3153 ber_dupbv( &keys[nkeys++], &digest );
3157 max = SLAP_INDEX_SUBSTR_MAXLEN < value.bv_len
3158 ? SLAP_INDEX_SUBSTR_MAXLEN : value.bv_len;
3160 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
3163 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
3164 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
3165 HASH_Init( &HASHcontext );
3166 if( prefix != NULL && prefix->bv_len > 0 ) {
3167 HASH_Update( &HASHcontext,
3168 prefix->bv_val, prefix->bv_len );
3170 HASH_Update( &HASHcontext,
3171 &pre, sizeof( pre ) );
3172 HASH_Update( &HASHcontext,
3173 syntax->ssyn_oid, slen );
3174 HASH_Update( &HASHcontext,
3175 mr->smr_oid, mlen );
3176 HASH_Update( &HASHcontext,
3178 HASH_Final( HASHdigest, &HASHcontext );
3180 ber_dupbv( &keys[nkeys++], &digest );
3183 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
3184 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
3185 HASH_Init( &HASHcontext );
3186 if( prefix != NULL && prefix->bv_len > 0 ) {
3187 HASH_Update( &HASHcontext,
3188 prefix->bv_val, prefix->bv_len );
3190 HASH_Update( &HASHcontext,
3191 &pre, sizeof( pre ) );
3192 HASH_Update( &HASHcontext,
3193 syntax->ssyn_oid, slen );
3194 HASH_Update( &HASHcontext,
3195 mr->smr_oid, mlen );
3196 HASH_Update( &HASHcontext,
3197 &value.bv_val[value.bv_len-j], j );
3198 HASH_Final( HASHdigest, &HASHcontext );
3200 ber_dupbv( &keys[nkeys++], &digest );
3205 free( value.bv_val );
3209 keys[nkeys].bv_val = NULL;
3216 return LDAP_SUCCESS;
3219 static int caseIgnoreIA5SubstringsFilter(
3224 struct berval *prefix,
3225 void * assertedValue,
3228 SubstringsAssertion *sa = assertedValue;
3230 ber_len_t nkeys = 0;
3231 size_t slen, mlen, klen;
3233 HASH_CONTEXT HASHcontext;
3234 unsigned char HASHdigest[HASH_BYTES];
3235 struct berval value;
3236 struct berval digest;
3238 if((flags & SLAP_INDEX_SUBSTR_INITIAL) && sa->sa_initial.bv_val != NULL &&
3239 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3244 if((flags & SLAP_INDEX_SUBSTR_ANY) && sa->sa_any != NULL ) {
3246 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
3247 if( sa->sa_any[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3248 /* don't bother accounting for stepping */
3249 nkeys += sa->sa_any[i].bv_len -
3250 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
3255 if((flags & SLAP_INDEX_SUBSTR_FINAL) && sa->sa_final.bv_val != NULL &&
3256 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3263 return LDAP_SUCCESS;
3266 digest.bv_val = HASHdigest;
3267 digest.bv_len = sizeof(HASHdigest);
3269 slen = syntax->ssyn_oidlen;
3270 mlen = mr->smr_oidlen;
3272 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
3275 if((flags & SLAP_INDEX_SUBSTR_INITIAL) && sa->sa_initial.bv_val != NULL &&
3276 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3278 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
3279 ber_dupbv( &value, &sa->sa_initial );
3280 ldap_pvt_str2lower( value.bv_val );
3282 klen = SLAP_INDEX_SUBSTR_MAXLEN < value.bv_len
3283 ? SLAP_INDEX_SUBSTR_MAXLEN : value.bv_len;
3285 HASH_Init( &HASHcontext );
3286 if( prefix != NULL && prefix->bv_len > 0 ) {
3287 HASH_Update( &HASHcontext,
3288 prefix->bv_val, prefix->bv_len );
3290 HASH_Update( &HASHcontext,
3291 &pre, sizeof( pre ) );
3292 HASH_Update( &HASHcontext,
3293 syntax->ssyn_oid, slen );
3294 HASH_Update( &HASHcontext,
3295 mr->smr_oid, mlen );
3296 HASH_Update( &HASHcontext,
3297 value.bv_val, klen );
3298 HASH_Final( HASHdigest, &HASHcontext );
3300 free( value.bv_val );
3301 ber_dupbv( &keys[nkeys++], &digest );
3304 if((flags & SLAP_INDEX_SUBSTR_ANY) && sa->sa_any != NULL ) {
3306 pre = SLAP_INDEX_SUBSTR_PREFIX;
3307 klen = SLAP_INDEX_SUBSTR_MAXLEN;
3309 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
3310 if( sa->sa_any[i].bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
3314 ber_dupbv( &value, &sa->sa_any[i] );
3315 ldap_pvt_str2lower( value.bv_val );
3318 j <= value.bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
3319 j += SLAP_INDEX_SUBSTR_STEP )
3321 HASH_Init( &HASHcontext );
3322 if( prefix != NULL && prefix->bv_len > 0 ) {
3323 HASH_Update( &HASHcontext,
3324 prefix->bv_val, prefix->bv_len );
3326 HASH_Update( &HASHcontext,
3327 &pre, sizeof( pre ) );
3328 HASH_Update( &HASHcontext,
3329 syntax->ssyn_oid, slen );
3330 HASH_Update( &HASHcontext,
3331 mr->smr_oid, mlen );
3332 HASH_Update( &HASHcontext,
3333 &value.bv_val[j], klen );
3334 HASH_Final( HASHdigest, &HASHcontext );
3336 ber_dupbv( &keys[nkeys++], &digest );
3339 free( value.bv_val );
3343 if((flags & SLAP_INDEX_SUBSTR_FINAL) && sa->sa_final.bv_val != NULL &&
3344 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3346 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
3347 ber_dupbv( &value, &sa->sa_final );
3348 ldap_pvt_str2lower( value.bv_val );
3350 klen = SLAP_INDEX_SUBSTR_MAXLEN < value.bv_len
3351 ? SLAP_INDEX_SUBSTR_MAXLEN : value.bv_len;
3353 HASH_Init( &HASHcontext );
3354 if( prefix != NULL && prefix->bv_len > 0 ) {
3355 HASH_Update( &HASHcontext,
3356 prefix->bv_val, prefix->bv_len );
3358 HASH_Update( &HASHcontext,
3359 &pre, sizeof( pre ) );
3360 HASH_Update( &HASHcontext,
3361 syntax->ssyn_oid, slen );
3362 HASH_Update( &HASHcontext,
3363 mr->smr_oid, mlen );
3364 HASH_Update( &HASHcontext,
3365 &value.bv_val[value.bv_len-klen], klen );
3366 HASH_Final( HASHdigest, &HASHcontext );
3368 free( value.bv_val );
3369 ber_dupbv( &keys[nkeys++], &digest );
3373 keys[nkeys].bv_val = NULL;
3380 return LDAP_SUCCESS;
3384 numericStringValidate(
3390 if( in->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
3392 for(i=0; i < in->bv_len; i++) {
3393 if( !SLAP_NUMERIC(in->bv_val[i]) ) {
3394 return LDAP_INVALID_SYNTAX;
3398 return LDAP_SUCCESS;
3402 numericStringNormalize(
3405 struct berval *normalized )
3407 /* removal all spaces */
3410 assert( val->bv_len );
3412 normalized->bv_val = ch_malloc( val->bv_len + 1 );
3415 q = normalized->bv_val;
3418 if ( ASCII_SPACE( *p ) ) {
3419 /* Ignore whitespace */
3426 /* we should have copied no more then is in val */
3427 assert( (q - normalized->bv_val) <= (p - val->bv_val) );
3429 /* null terminate */
3432 normalized->bv_len = q - normalized->bv_val;
3434 if( normalized->bv_len == 0 ) {
3435 normalized->bv_val = ch_realloc( normalized->bv_val, 2 );
3436 normalized->bv_val[0] = ' ';
3437 normalized->bv_val[1] = '\0';
3438 normalized->bv_len = 1;
3441 return LDAP_SUCCESS;
3445 objectIdentifierFirstComponentMatch(
3450 struct berval *value,
3451 void *assertedValue )
3453 int rc = LDAP_SUCCESS;
3455 struct berval *asserted = (struct berval *) assertedValue;
3459 if( value->bv_len == 0 || value->bv_val[0] != '(' /*')'*/ ) {
3460 return LDAP_INVALID_SYNTAX;
3463 /* trim leading white space */
3464 for( i=1; ASCII_SPACE(value->bv_val[i]) && i < value->bv_len; i++ ) {
3468 /* grab next word */
3469 oid.bv_val = &value->bv_val[i];
3470 oid.bv_len = value->bv_len - i;
3471 for( i=1; ASCII_SPACE(value->bv_val[i]) && i < oid.bv_len; i++ ) {
3476 /* insert attributeTypes, objectclass check here */
3477 if( OID_LEADCHAR(asserted->bv_val[0]) ) {
3478 rc = objectIdentifierMatch( &match, flags, syntax, mr, &oid, asserted );
3481 if ( !strcmp( syntax->ssyn_oid, SLAP_SYNTAX_MATCHINGRULES_OID ) ) {
3482 MatchingRule *asserted_mr = mr_bvfind( asserted );
3483 MatchingRule *stored_mr = mr_bvfind( &oid );
3485 if( asserted_mr == NULL ) {
3486 rc = SLAPD_COMPARE_UNDEFINED;
3488 match = asserted_mr != stored_mr;
3491 } else if ( !strcmp( syntax->ssyn_oid,
3492 SLAP_SYNTAX_ATTRIBUTETYPES_OID ) )
3494 AttributeType *asserted_at = at_bvfind( asserted );
3495 AttributeType *stored_at = at_bvfind( &oid );
3497 if( asserted_at == NULL ) {
3498 rc = SLAPD_COMPARE_UNDEFINED;
3500 match = asserted_at != stored_at;
3503 } else if ( !strcmp( syntax->ssyn_oid,
3504 SLAP_SYNTAX_OBJECTCLASSES_OID ) )
3506 ObjectClass *asserted_oc = oc_bvfind( asserted );
3507 ObjectClass *stored_oc = oc_bvfind( &oid );
3509 if( asserted_oc == NULL ) {
3510 rc = SLAPD_COMPARE_UNDEFINED;
3512 match = asserted_oc != stored_oc;
3518 LDAP_LOG( CONFIG, ENTRY,
3519 "objectIdentifierFirstComponentMatch: %d\n %s\n %s\n",
3520 match, value->bv_val, asserted->bv_val );
3522 Debug( LDAP_DEBUG_ARGS, "objectIdentifierFirstComponentMatch "
3523 "%d\n\t\"%s\"\n\t\"%s\"\n",
3524 match, value->bv_val, asserted->bv_val );
3528 if( rc == LDAP_SUCCESS ) *matchp = match;
3538 struct berval *value,
3539 void *assertedValue )
3541 long lValue, lAssertedValue;
3543 /* safe to assume integers are NUL terminated? */
3544 lValue = strtoul(value->bv_val, NULL, 10);
3545 if(( lValue == LONG_MIN || lValue == LONG_MAX) && errno == ERANGE )
3546 return LDAP_CONSTRAINT_VIOLATION;
3548 lAssertedValue = strtol(((struct berval *)assertedValue)->bv_val, NULL, 10);
3549 if(( lAssertedValue == LONG_MIN || lAssertedValue == LONG_MAX) && errno == ERANGE )
3550 return LDAP_CONSTRAINT_VIOLATION;
3552 *matchp = (lValue & lAssertedValue) ? 0 : 1;
3553 return LDAP_SUCCESS;
3562 struct berval *value,
3563 void *assertedValue )
3565 long lValue, lAssertedValue;
3567 /* safe to assume integers are NUL terminated? */
3568 lValue = strtoul(value->bv_val, NULL, 10);
3569 if(( lValue == LONG_MIN || lValue == LONG_MAX) && errno == ERANGE )
3570 return LDAP_CONSTRAINT_VIOLATION;
3572 lAssertedValue = strtol(((struct berval *)assertedValue)->bv_val, NULL, 10);
3573 if(( lAssertedValue == LONG_MIN || lAssertedValue == LONG_MAX) && errno == ERANGE )
3574 return LDAP_CONSTRAINT_VIOLATION;
3576 *matchp = (lValue | lAssertedValue) ? 0 : -1;
3577 return LDAP_SUCCESS;
3581 #include <openssl/x509.h>
3582 #include <openssl/err.h>
3583 char digit[] = "0123456789";
3586 * Next function returns a string representation of a ASN1_INTEGER.
3587 * It works for unlimited lengths.
3590 static struct berval *
3591 asn1_integer2str(ASN1_INTEGER *a, struct berval *bv)
3596 /* We work backwards, make it fill from the end of buf */
3597 p = buf + sizeof(buf) - 1;
3600 if ( a == NULL || a->length == 0 ) {
3608 /* We want to preserve the original */
3609 copy = ch_malloc(n*sizeof(unsigned int));
3610 for (i = 0; i<n; i++) {
3611 copy[i] = a->data[i];
3615 * base indicates the index of the most significant
3616 * byte that might be nonzero. When it goes off the
3617 * end, we now there is nothing left to do.
3623 for (i = base; i<n; i++ ) {
3624 copy[i] += carry*256;
3625 carry = copy[i] % 10;
3630 * Way too large, we need to leave
3631 * room for sign if negative
3636 *--p = digit[carry];
3637 if (copy[base] == 0)
3643 if ( a->type == V_ASN1_NEG_INTEGER ) {
3647 return ber_str2bv( p, 0, 1, bv );
3651 * Given a certificate in DER format, extract the corresponding
3652 * assertion value for certificateExactMatch
3655 certificateExactConvert(
3657 struct berval * out )
3660 unsigned char *p = in->bv_val;
3661 struct berval serial;
3662 struct berval issuer_dn;
3664 xcert = d2i_X509(NULL, &p, in->bv_len);
3667 LDAP_LOG( CONFIG, ENTRY,
3668 "certificateExactConvert: error parsing cert: %s\n",
3669 ERR_error_string(ERR_get_error(),NULL), 0, 0 );
3671 Debug( LDAP_DEBUG_ARGS, "certificateExactConvert: "
3672 "error parsing cert: %s\n",
3673 ERR_error_string(ERR_get_error(),NULL), NULL, NULL );
3675 return LDAP_INVALID_SYNTAX;
3678 if ( !asn1_integer2str(xcert->cert_info->serialNumber, &serial) ) {
3680 return LDAP_INVALID_SYNTAX;
3682 if ( dnX509normalize(X509_get_issuer_name(xcert), &issuer_dn ) != LDAP_SUCCESS ) {
3684 ber_memfree(serial.bv_val);
3685 return LDAP_INVALID_SYNTAX;
3690 out->bv_len = serial.bv_len + issuer_dn.bv_len + sizeof(" $ ");
3691 out->bv_val = ch_malloc(out->bv_len);
3693 AC_MEMCPY(p, serial.bv_val, serial.bv_len);
3695 AC_MEMCPY(p, " $ ", sizeof(" $ ")-1);
3697 AC_MEMCPY(p, issuer_dn.bv_val, issuer_dn.bv_len);
3698 p += issuer_dn.bv_len;
3702 LDAP_LOG( CONFIG, ARGS,
3703 "certificateExactConvert: \n %s\n", out->bv_val, 0, 0 );
3705 Debug( LDAP_DEBUG_ARGS, "certificateExactConvert "
3707 out->bv_val, NULL, NULL );
3710 ber_memfree(serial.bv_val);
3711 ber_memfree(issuer_dn.bv_val);
3713 return LDAP_SUCCESS;
3717 serial_and_issuer_parse(
3718 struct berval *assertion,
3719 struct berval *serial,
3720 struct berval *issuer_dn
3728 begin = assertion->bv_val;
3729 end = assertion->bv_val+assertion->bv_len-1;
3730 for (p=begin; p<=end && *p != '$'; p++)
3733 return LDAP_INVALID_SYNTAX;
3735 /* p now points at the $ sign, now use begin and end to delimit the
3737 while (ASCII_SPACE(*begin))
3740 while (ASCII_SPACE(*end))
3743 bv.bv_len = end-begin+1;
3745 ber_dupbv(serial, &bv);
3747 /* now extract the issuer, remember p was at the dollar sign */
3750 end = assertion->bv_val+assertion->bv_len-1;
3751 while (ASCII_SPACE(*begin))
3753 /* should we trim spaces at the end too? is it safe always? */
3755 bv.bv_len = end-begin+1;
3757 dnNormalize2( NULL, &bv, issuer_dn );
3760 return LDAP_SUCCESS;
3764 certificateExactMatch(
3769 struct berval *value,
3770 void *assertedValue )
3773 unsigned char *p = value->bv_val;
3774 struct berval serial;
3775 struct berval issuer_dn;
3776 struct berval asserted_serial;
3777 struct berval asserted_issuer_dn;
3780 xcert = d2i_X509(NULL, &p, value->bv_len);
3783 LDAP_LOG( CONFIG, ENTRY,
3784 "certificateExactMatch: error parsing cert: %s\n",
3785 ERR_error_string(ERR_get_error(),NULL), 0, 0 );
3787 Debug( LDAP_DEBUG_ARGS, "certificateExactMatch: "
3788 "error parsing cert: %s\n",
3789 ERR_error_string(ERR_get_error(),NULL), NULL, NULL );
3791 return LDAP_INVALID_SYNTAX;
3794 asn1_integer2str(xcert->cert_info->serialNumber, &serial);
3795 dnX509normalize(X509_get_issuer_name(xcert), &issuer_dn);
3799 serial_and_issuer_parse(assertedValue,
3801 &asserted_issuer_dn);
3806 slap_schema.si_syn_integer,
3807 slap_schema.si_mr_integerMatch,
3810 if ( ret == LDAP_SUCCESS ) {
3811 if ( *matchp == 0 ) {
3812 /* We need to normalize everything for dnMatch */
3816 slap_schema.si_syn_distinguishedName,
3817 slap_schema.si_mr_distinguishedNameMatch,
3819 &asserted_issuer_dn);
3824 LDAP_LOG( CONFIG, ARGS, "certificateExactMatch "
3825 "%d\n\t\"%s $ %s\"\n",
3826 *matchp, serial.bv_val, issuer_dn.bv_val );
3827 LDAP_LOG( CONFIG, ARGS, "\t\"%s $ %s\"\n",
3828 asserted_serial.bv_val, asserted_issuer_dn.bv_val,
3831 Debug( LDAP_DEBUG_ARGS, "certificateExactMatch "
3832 "%d\n\t\"%s $ %s\"\n",
3833 *matchp, serial.bv_val, issuer_dn.bv_val );
3834 Debug( LDAP_DEBUG_ARGS, "\t\"%s $ %s\"\n",
3835 asserted_serial.bv_val, asserted_issuer_dn.bv_val,
3839 ber_memfree(serial.bv_val);
3840 ber_memfree(issuer_dn.bv_val);
3841 ber_memfree(asserted_serial.bv_val);
3842 ber_memfree(asserted_issuer_dn.bv_val);
3848 * Index generation function
3849 * We just index the serials, in most scenarios the issuer DN is one of
3850 * a very small set of values.
3852 static int certificateExactIndexer(
3857 struct berval *prefix,
3865 struct berval serial;
3867 /* we should have at least one value at this point */
3868 assert( values != NULL && values[0].bv_val != NULL );
3870 for( i=0; values[i].bv_val != NULL; i++ ) {
3871 /* empty -- just count them */
3874 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
3876 for( i=0; values[i].bv_val != NULL; i++ ) {
3877 p = values[i].bv_val;
3878 xcert = d2i_X509(NULL, &p, values[i].bv_len);
3881 LDAP_LOG( CONFIG, ENTRY,
3882 "certificateExactIndexer: error parsing cert: %s\n",
3883 ERR_error_string(ERR_get_error(),NULL), 0, 0);
3885 Debug( LDAP_DEBUG_ARGS, "certificateExactIndexer: "
3886 "error parsing cert: %s\n",
3887 ERR_error_string(ERR_get_error(),NULL),
3890 /* Do we leak keys on error? */
3891 return LDAP_INVALID_SYNTAX;
3894 asn1_integer2str(xcert->cert_info->serialNumber, &serial);
3896 integerNormalize( slap_schema.si_syn_integer,
3899 ber_memfree(serial.bv_val);
3901 LDAP_LOG( CONFIG, ENTRY,
3902 "certificateExactIndexer: returning: %s\n", keys[i].bv_val, 0, 0);
3904 Debug( LDAP_DEBUG_ARGS, "certificateExactIndexer: "
3911 keys[i].bv_val = NULL;
3913 return LDAP_SUCCESS;
3916 /* Index generation function */
3917 /* We think this is always called with a value in matching rule syntax */
3918 static int certificateExactFilter(
3923 struct berval *prefix,
3924 void * assertedValue,
3928 struct berval asserted_serial;
3930 serial_and_issuer_parse(assertedValue,
3934 keys = ch_malloc( sizeof( struct berval ) * 2 );
3935 integerNormalize( syntax, &asserted_serial, &keys[0] );
3936 keys[1].bv_val = NULL;
3939 ber_memfree(asserted_serial.bv_val);
3940 return LDAP_SUCCESS;
3945 check_time_syntax (struct berval *val,
3949 static int ceiling[9] = { 99, 99, 11, 30, 23, 59, 59, 12, 59 };
3950 static int mdays[2][12] = {
3951 /* non-leap years */
3952 { 30, 27, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30 },
3954 { 30, 28, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30 }
3957 int part, c, tzoffset, leapyear = 0 ;
3959 if( val->bv_len == 0 ) {
3960 return LDAP_INVALID_SYNTAX;
3963 p = (char *)val->bv_val;
3964 e = p + val->bv_len;
3966 /* Ignore initial whitespace */
3967 while ( ( p < e ) && ASCII_SPACE( *p ) ) {
3971 if (e - p < 13 - (2 * start)) {
3972 return LDAP_INVALID_SYNTAX;
3975 for (part = 0; part < 9; part++) {
3979 for (part = start; part < 7; part++) {
3981 if ((part == 6) && (c == 'Z' || c == '+' || c == '-')) {
3988 return LDAP_INVALID_SYNTAX;
3990 if (c < 0 || c > 9) {
3991 return LDAP_INVALID_SYNTAX;
3997 return LDAP_INVALID_SYNTAX;
3999 if (c < 0 || c > 9) {
4000 return LDAP_INVALID_SYNTAX;
4005 if (part == 2 || part == 3) {
4008 if (parts[part] < 0) {
4009 return LDAP_INVALID_SYNTAX;
4011 if (parts[part] > ceiling[part]) {
4012 return LDAP_INVALID_SYNTAX;
4016 /* leapyear check for the Gregorian calendar (year>1581) */
4017 if (((parts[1] % 4 == 0) && (parts[1] != 0)) ||
4018 ((parts[0] % 4 == 0) && (parts[1] == 0)))
4023 if (parts[3] > mdays[leapyear][parts[2]]) {
4024 return LDAP_INVALID_SYNTAX;
4029 tzoffset = 0; /* UTC */
4030 } else if (c != '+' && c != '-') {
4031 return LDAP_INVALID_SYNTAX;
4035 } else /* c == '+' */ {
4040 return LDAP_INVALID_SYNTAX;
4043 for (part = 7; part < 9; part++) {
4045 if (c < 0 || c > 9) {
4046 return LDAP_INVALID_SYNTAX;
4051 if (c < 0 || c > 9) {
4052 return LDAP_INVALID_SYNTAX;
4056 if (parts[part] < 0 || parts[part] > ceiling[part]) {
4057 return LDAP_INVALID_SYNTAX;
4062 /* Ignore trailing whitespace */
4063 while ( ( p < e ) && ASCII_SPACE( *p ) ) {
4067 return LDAP_INVALID_SYNTAX;
4070 switch ( tzoffset ) {
4071 case -1: /* negativ offset to UTC, ie west of Greenwich */
4072 parts[4] += parts[7];
4073 parts[5] += parts[8];
4074 for (part = 6; --part > 0; ) { /* offset is just hhmm, no seconds */
4078 c = mdays[leapyear][parts[2]];
4080 if (parts[part] > c) {
4081 parts[part] -= c + 1;
4086 case 1: /* positive offset to UTC, ie east of Greenwich */
4087 parts[4] -= parts[7];
4088 parts[5] -= parts[8];
4089 for (part = 6; --part > 0; ) {
4093 /* first arg to % needs to be non negativ */
4094 c = mdays[leapyear][(parts[2] - 1 + 12) % 12];
4096 if (parts[part] < 0) {
4097 parts[part] += c + 1;
4102 case 0: /* already UTC */
4106 return LDAP_SUCCESS;
4109 #ifdef SUPPORT_OBSOLETE_UTC_SYNTAX
4114 struct berval *normalized )
4118 rc = check_time_syntax(val, 1, parts);
4119 if (rc != LDAP_SUCCESS) {
4123 normalized->bv_val = ch_malloc( 14 );
4124 if ( normalized->bv_val == NULL ) {
4125 return LBER_ERROR_MEMORY;
4128 sprintf( normalized->bv_val, "%02d%02d%02d%02d%02d%02dZ",
4129 parts[1], parts[2] + 1, parts[3] + 1,
4130 parts[4], parts[5], parts[6] );
4131 normalized->bv_len = 13;
4133 return LDAP_SUCCESS;
4137 #ifdef SUPPORT_OBSOLETE_UTC_SYNTAX
4145 return check_time_syntax(in, 1, parts);
4150 generalizedTimeValidate(
4156 return check_time_syntax(in, 0, parts);
4160 generalizedTimeNormalize(
4163 struct berval *normalized )
4167 rc = check_time_syntax(val, 0, parts);
4168 if (rc != LDAP_SUCCESS) {
4172 normalized->bv_val = ch_malloc( 16 );
4173 if ( normalized->bv_val == NULL ) {
4174 return LBER_ERROR_MEMORY;
4177 sprintf( normalized->bv_val, "%02d%02d%02d%02d%02d%02d%02dZ",
4178 parts[0], parts[1], parts[2] + 1, parts[3] + 1,
4179 parts[4], parts[5], parts[6] );
4180 normalized->bv_len = 15;
4182 return LDAP_SUCCESS;
4186 nisNetgroupTripleValidate(
4188 struct berval *val )
4193 if ( val->bv_len == 0 ) {
4194 return LDAP_INVALID_SYNTAX;
4197 p = (char *)val->bv_val;
4198 e = p + val->bv_len;
4200 if ( *p != '(' /*')'*/ ) {
4201 return LDAP_INVALID_SYNTAX;
4204 for ( p++; ( p < e ) && ( *p != /*'('*/ ')' ); p++ ) {
4208 return LDAP_INVALID_SYNTAX;
4211 } else if ( !AD_CHAR( *p ) ) {
4212 return LDAP_INVALID_SYNTAX;
4216 if ( ( commas != 2 ) || ( *p != /*'('*/ ')' ) ) {
4217 return LDAP_INVALID_SYNTAX;
4223 return LDAP_INVALID_SYNTAX;
4226 return LDAP_SUCCESS;
4230 bootParameterValidate(
4232 struct berval *val )
4236 if ( val->bv_len == 0 ) {
4237 return LDAP_INVALID_SYNTAX;
4240 p = (char *)val->bv_val;
4241 e = p + val->bv_len;
4244 for (; ( p < e ) && ( *p != '=' ); p++ ) {
4245 if ( !AD_CHAR( *p ) ) {
4246 return LDAP_INVALID_SYNTAX;
4251 return LDAP_INVALID_SYNTAX;
4255 for ( p++; ( p < e ) && ( *p != ':' ); p++ ) {
4256 if ( !AD_CHAR( *p ) ) {
4257 return LDAP_INVALID_SYNTAX;
4262 return LDAP_INVALID_SYNTAX;
4266 for ( p++; p < e; p++ ) {
4267 if ( !SLAP_PRINTABLE( *p ) ) {
4268 return LDAP_INVALID_SYNTAX;
4272 return LDAP_SUCCESS;
4275 #define X_BINARY "X-BINARY-TRANSFER-REQUIRED 'TRUE' "
4276 #define X_NOT_H_R "X-NOT-HUMAN-READABLE 'TRUE' "
4278 static slap_syntax_defs_rec syntax_defs[] = {
4279 {"( 1.3.6.1.4.1.1466.115.121.1.1 DESC 'ACI Item' "
4280 X_BINARY X_NOT_H_R ")",
4281 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, NULL, NULL, NULL},
4282 {"( 1.3.6.1.4.1.1466.115.121.1.2 DESC 'Access Point' " X_NOT_H_R ")",
4283 0, NULL, NULL, NULL},
4284 {"( 1.3.6.1.4.1.1466.115.121.1.3 DESC 'Attribute Type Description' )",
4285 0, NULL, NULL, NULL},
4286 {"( 1.3.6.1.4.1.1466.115.121.1.4 DESC 'Audio' "
4288 SLAP_SYNTAX_BLOB, blobValidate, NULL, NULL},
4289 {"( 1.3.6.1.4.1.1466.115.121.1.5 DESC 'Binary' "
4291 SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4292 {"( 1.3.6.1.4.1.1466.115.121.1.6 DESC 'Bit String' )",
4293 0, bitStringValidate, bitStringNormalize, NULL },
4294 {"( 1.3.6.1.4.1.1466.115.121.1.7 DESC 'Boolean' )",
4295 0, booleanValidate, NULL, NULL},
4296 {"( 1.3.6.1.4.1.1466.115.121.1.8 DESC 'Certificate' "
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.9 DESC 'Certificate List' "
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.10 DESC 'Certificate Pair' "
4303 X_BINARY X_NOT_H_R ")",
4304 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4305 {"( 1.3.6.1.4.1.1466.115.121.1.11 DESC 'Country String' )",
4306 0, countryStringValidate, IA5StringNormalize, NULL},
4307 {"( 1.3.6.1.4.1.1466.115.121.1.12 DESC 'Distinguished Name' )",
4308 0, dnValidate, dnNormalize2, dnPretty2},
4309 {"( 1.3.6.1.4.1.1466.115.121.1.13 DESC 'Data Quality' )",
4310 0, NULL, NULL, NULL},
4311 {"( 1.3.6.1.4.1.1466.115.121.1.14 DESC 'Delivery Method' )",
4312 0, NULL, NULL, NULL},
4313 {"( 1.3.6.1.4.1.1466.115.121.1.15 DESC 'Directory String' )",
4314 0, UTF8StringValidate, UTF8StringNormalize, NULL},
4315 {"( 1.3.6.1.4.1.1466.115.121.1.16 DESC 'DIT Content Rule Description' )",
4316 0, NULL, NULL, NULL},
4317 {"( 1.3.6.1.4.1.1466.115.121.1.17 DESC 'DIT Structure Rule Description' )",
4318 0, NULL, NULL, NULL},
4319 {"( 1.3.6.1.4.1.1466.115.121.1.19 DESC 'DSA Quality' )",
4320 0, NULL, NULL, NULL},
4321 {"( 1.3.6.1.4.1.1466.115.121.1.20 DESC 'DSE Type' )",
4322 0, NULL, NULL, NULL},
4323 {"( 1.3.6.1.4.1.1466.115.121.1.21 DESC 'Enhanced Guide' )",
4324 0, NULL, NULL, NULL},
4325 {"( 1.3.6.1.4.1.1466.115.121.1.22 DESC 'Facsimile Telephone Number' )",
4326 0, printablesStringValidate, telephoneNumberNormalize, NULL},
4327 {"( 1.3.6.1.4.1.1466.115.121.1.23 DESC 'Fax' " X_NOT_H_R ")",
4328 SLAP_SYNTAX_BLOB, NULL, NULL, NULL},
4329 {"( 1.3.6.1.4.1.1466.115.121.1.24 DESC 'Generalized Time' )",
4330 0, generalizedTimeValidate, generalizedTimeNormalize, NULL},
4331 {"( 1.3.6.1.4.1.1466.115.121.1.25 DESC 'Guide' )",
4332 0, NULL, NULL, NULL},
4333 {"( 1.3.6.1.4.1.1466.115.121.1.26 DESC 'IA5 String' )",
4334 0, IA5StringValidate, IA5StringNormalize, NULL},
4335 {"( 1.3.6.1.4.1.1466.115.121.1.27 DESC 'Integer' )",
4336 0, integerValidate, integerNormalize, NULL},
4337 {"( 1.3.6.1.4.1.1466.115.121.1.28 DESC 'JPEG' " X_NOT_H_R ")",
4338 SLAP_SYNTAX_BLOB, blobValidate, NULL, NULL},
4339 {"( 1.3.6.1.4.1.1466.115.121.1.29 DESC 'Master And Shadow Access Points' )",
4340 0, NULL, NULL, NULL},
4341 {"( 1.3.6.1.4.1.1466.115.121.1.30 DESC 'Matching Rule Description' )",
4342 0, NULL, NULL, NULL},
4343 {"( 1.3.6.1.4.1.1466.115.121.1.31 DESC 'Matching Rule Use Description' )",
4344 0, NULL, NULL, NULL},
4345 {"( 1.3.6.1.4.1.1466.115.121.1.32 DESC 'Mail Preference' )",
4346 0, NULL, NULL, NULL},
4347 {"( 1.3.6.1.4.1.1466.115.121.1.33 DESC 'MHS OR Address' )",
4348 0, NULL, NULL, NULL},
4349 {"( 1.3.6.1.4.1.1466.115.121.1.34 DESC 'Name And Optional UID' )",
4350 0, nameUIDValidate, nameUIDNormalize, NULL},
4351 {"( 1.3.6.1.4.1.1466.115.121.1.35 DESC 'Name Form Description' )",
4352 0, NULL, NULL, NULL},
4353 {"( 1.3.6.1.4.1.1466.115.121.1.36 DESC 'Numeric String' )",
4354 0, numericStringValidate, numericStringNormalize, NULL},
4355 {"( 1.3.6.1.4.1.1466.115.121.1.37 DESC 'Object Class Description' )",
4356 0, NULL, NULL, NULL},
4357 {"( 1.3.6.1.4.1.1466.115.121.1.38 DESC 'OID' )",
4358 0, oidValidate, NULL, NULL},
4359 {"( 1.3.6.1.4.1.1466.115.121.1.39 DESC 'Other Mailbox' )",
4360 0, IA5StringValidate, IA5StringNormalize, NULL},
4361 {"( 1.3.6.1.4.1.1466.115.121.1.40 DESC 'Octet String' )",
4362 0, blobValidate, NULL, NULL},
4363 {"( 1.3.6.1.4.1.1466.115.121.1.41 DESC 'Postal Address' )",
4364 0, UTF8StringValidate, UTF8StringNormalize, NULL},
4365 {"( 1.3.6.1.4.1.1466.115.121.1.42 DESC 'Protocol Information' )",
4366 0, NULL, NULL, NULL},
4367 {"( 1.3.6.1.4.1.1466.115.121.1.43 DESC 'Presentation Address' )",
4368 0, NULL, NULL, NULL},
4369 {"( 1.3.6.1.4.1.1466.115.121.1.44 DESC 'Printable String' )",
4370 0, printableStringValidate, IA5StringNormalize, NULL},
4371 {"( 1.3.6.1.4.1.1466.115.121.1.45 DESC 'SubtreeSpecification' "
4372 X_BINARY X_NOT_H_R ")",
4373 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, NULL, NULL, NULL},
4374 {"( 1.3.6.1.4.1.1466.115.121.1.49 DESC 'Supported Algorithm' "
4375 X_BINARY X_NOT_H_R ")",
4376 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4377 {"( 1.3.6.1.4.1.1466.115.121.1.50 DESC 'Telephone Number' )",
4378 0, printableStringValidate, telephoneNumberNormalize, NULL},
4379 {"( 1.3.6.1.4.1.1466.115.121.1.51 DESC 'Teletex Terminal Identifier' )",
4380 0, NULL, NULL, NULL},
4381 {"( 1.3.6.1.4.1.1466.115.121.1.52 DESC 'Telex Number' )",
4382 0, printablesStringValidate, IA5StringNormalize, NULL},
4383 #ifdef SUPPORT_OBSOLETE_UTC_SYNTAX
4384 {"( 1.3.6.1.4.1.1466.115.121.1.53 DESC 'UTC Time' )",
4385 0, utcTimeValidate, utcTimeNormalize, NULL},
4387 {"( 1.3.6.1.4.1.1466.115.121.1.54 DESC 'LDAP Syntax Description' )",
4388 0, NULL, NULL, NULL},
4389 {"( 1.3.6.1.4.1.1466.115.121.1.55 DESC 'Modify Rights' )",
4390 0, NULL, NULL, NULL},
4391 {"( 1.3.6.1.4.1.1466.115.121.1.56 DESC 'LDAP Schema Definition' )",
4392 0, NULL, NULL, NULL},
4393 {"( 1.3.6.1.4.1.1466.115.121.1.57 DESC 'LDAP Schema Description' )",
4394 0, NULL, NULL, NULL},
4395 {"( 1.3.6.1.4.1.1466.115.121.1.58 DESC 'Substring Assertion' )",
4396 0, NULL, NULL, NULL},
4398 /* RFC 2307 NIS Syntaxes */
4399 {"( 1.3.6.1.1.1.0.0 DESC 'RFC2307 NIS Netgroup Triple' )",
4400 0, nisNetgroupTripleValidate, NULL, NULL},
4401 {"( 1.3.6.1.1.1.0.1 DESC 'RFC2307 Boot Parameter' )",
4402 0, bootParameterValidate, NULL, NULL},
4406 /* These OIDs are not published yet, but will be in the next
4407 * I-D for PKIX LDAPv3 schema as have been advanced by David
4408 * Chadwick in private mail.
4410 {"( 1.2.826.0.1.3344810.7.1 DESC 'Serial Number and Issuer' )",
4411 0, NULL, NULL, NULL},
4414 /* OpenLDAP Experimental Syntaxes */
4415 #ifdef SLAPD_ACI_ENABLED
4416 {"( 1.3.6.1.4.1.4203.666.2.1 DESC 'OpenLDAP Experimental ACI' )",
4418 UTF8StringValidate /* THIS WILL CHANGE FOR NEW ACI SYNTAX */,
4422 #ifdef SLAPD_AUTHPASSWD
4423 /* needs updating */
4424 {"( 1.3.6.1.4.1.4203.666.2.2 DESC 'OpenLDAP authPassword' )",
4425 SLAP_SYNTAX_HIDE, NULL, NULL, NULL},
4428 /* OpenLDAP Void Syntax */
4429 {"( 1.3.6.1.4.1.4203.1.1.1 DESC 'OpenLDAP void' )" ,
4430 SLAP_SYNTAX_HIDE, inValidate, NULL, NULL},
4431 {NULL, 0, NULL, NULL, NULL}
4435 char *certificateExactMatchSyntaxes[] = {
4436 "1.3.6.1.4.1.1466.115.121.1.8" /* certificate */,
4440 char *directoryStringSyntaxes[] = {
4441 "1.3.6.1.4.1.1466.115.121.1.44" /* printableString */,
4444 char *integerFirstComponentMatchSyntaxes[] = {
4445 "1.3.6.1.4.1.1466.115.121.1.27" /* INTEGER */,
4446 "1.3.6.1.4.1.1466.115.121.1.17" /* ditStructureRuleDescription */,
4449 char *objectIdentifierFirstComponentMatchSyntaxes[] = {
4450 "1.3.6.1.4.1.1466.115.121.1.38" /* OID */,
4451 "1.3.6.1.4.1.1466.115.121.1.3" /* attributeTypeDescription */,
4452 "1.3.6.1.4.1.1466.115.121.1.16" /* ditContentRuleDescription */,
4453 "1.3.6.1.4.1.1466.115.121.1.54" /* ldapSyntaxDescription */,
4454 "1.3.6.1.4.1.1466.115.121.1.30" /* matchingRuleDescription */,
4455 "1.3.6.1.4.1.1466.115.121.1.31" /* matchingRuleUseDescription */,
4456 "1.3.6.1.4.1.1466.115.121.1.35" /* nameFormDescription */,
4457 "1.3.6.1.4.1.1466.115.121.1.37" /* objectClassDescription */,
4462 * Other matching rules in X.520 that we do not use (yet):
4464 * 2.5.13.9 numericStringOrderingMatch
4465 * 2.5.13.19 octetStringSubstringsMatch
4466 * 2.5.13.25 uTCTimeMatch
4467 * 2.5.13.26 uTCTimeOrderingMatch
4468 * 2.5.13.31 directoryStringFirstComponentMatch
4469 * 2.5.13.32 wordMatch
4470 * 2.5.13.33 keywordMatch
4471 * 2.5.13.35 certificateMatch
4472 * 2.5.13.36 certificatePairExactMatch
4473 * 2.5.13.37 certificatePairMatch
4474 * 2.5.13.38 certificateListExactMatch
4475 * 2.5.13.39 certificateListMatch
4476 * 2.5.13.40 algorithmIdentifierMatch
4477 * 2.5.13.41 storedPrefixMatch
4478 * 2.5.13.42 attributeCertificateMatch
4479 * 2.5.13.43 readerAndKeyIDMatch
4480 * 2.5.13.44 attributeIntegrityMatch
4482 static slap_mrule_defs_rec mrule_defs[] = {
4484 * EQUALITY matching rules must be listed after associated APPROX
4485 * matching rules. So, we list all APPROX matching rules first.
4487 {"( " directoryStringApproxMatchOID " NAME 'directoryStringApproxMatch' "
4488 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4489 SLAP_MR_HIDE | SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT, NULL,
4491 directoryStringApproxMatch,
4492 directoryStringApproxIndexer,
4493 directoryStringApproxFilter,
4496 {"( " IA5StringApproxMatchOID " NAME 'IA5StringApproxMatch' "
4497 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4498 SLAP_MR_HIDE | SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT, NULL,
4500 IA5StringApproxMatch,
4501 IA5StringApproxIndexer,
4502 IA5StringApproxFilter,
4506 * Other matching rules
4509 {"( 2.5.13.0 NAME 'objectIdentifierMatch' "
4510 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
4511 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4513 objectIdentifierMatch, caseIgnoreIA5Indexer, caseIgnoreIA5Filter,
4516 {"( 2.5.13.1 NAME 'distinguishedNameMatch' "
4517 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )",
4518 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4520 dnMatch, dnIndexer, dnFilter,
4523 {"( 2.5.13.2 NAME 'caseIgnoreMatch' "
4524 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4525 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD,
4526 directoryStringSyntaxes,
4528 caseIgnoreMatch, caseExactIgnoreIndexer, caseExactIgnoreFilter,
4529 directoryStringApproxMatchOID },
4531 {"( 2.5.13.3 NAME 'caseIgnoreOrderingMatch' "
4532 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4533 SLAP_MR_ORDERING, directoryStringSyntaxes,
4535 caseIgnoreOrderingMatch, NULL, NULL,
4538 {"( 2.5.13.4 NAME 'caseIgnoreSubstringsMatch' "
4539 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4540 SLAP_MR_SUBSTR, NULL,
4542 caseExactIgnoreSubstringsMatch,
4543 caseExactIgnoreSubstringsIndexer,
4544 caseExactIgnoreSubstringsFilter,
4547 {"( 2.5.13.5 NAME 'caseExactMatch' "
4548 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4549 SLAP_MR_EQUALITY | SLAP_MR_EXT, directoryStringSyntaxes,
4551 caseExactMatch, caseExactIgnoreIndexer, caseExactIgnoreFilter,
4552 directoryStringApproxMatchOID },
4554 {"( 2.5.13.6 NAME 'caseExactOrderingMatch' "
4555 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4556 SLAP_MR_ORDERING, directoryStringSyntaxes,
4558 caseExactOrderingMatch, NULL, NULL,
4561 {"( 2.5.13.7 NAME 'caseExactSubstringsMatch' "
4562 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4563 SLAP_MR_SUBSTR, directoryStringSyntaxes,
4565 caseExactIgnoreSubstringsMatch,
4566 caseExactIgnoreSubstringsIndexer,
4567 caseExactIgnoreSubstringsFilter,
4570 {"( 2.5.13.8 NAME 'numericStringMatch' "
4571 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 )",
4572 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL,
4575 caseIgnoreIA5Indexer,
4576 caseIgnoreIA5Filter,
4579 {"( 2.5.13.10 NAME 'numericStringSubstringsMatch' "
4580 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4581 SLAP_MR_SUBSTR, NULL,
4583 caseIgnoreIA5SubstringsMatch,
4584 caseIgnoreIA5SubstringsIndexer,
4585 caseIgnoreIA5SubstringsFilter,
4588 {"( 2.5.13.11 NAME 'caseIgnoreListMatch' "
4589 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )",
4590 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL,
4592 caseIgnoreListMatch, NULL, NULL,
4595 {"( 2.5.13.12 NAME 'caseIgnoreListSubstringsMatch' "
4596 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4597 SLAP_MR_SUBSTR, NULL,
4599 caseIgnoreListSubstringsMatch, NULL, NULL,
4602 {"( 2.5.13.13 NAME 'booleanMatch' "
4603 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )",
4604 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4606 booleanMatch, NULL, NULL,
4609 {"( 2.5.13.14 NAME 'integerMatch' "
4610 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4611 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4613 integerMatch, integerIndexer, integerFilter,
4616 {"( 2.5.13.15 NAME 'integerOrderingMatch' "
4617 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4618 SLAP_MR_ORDERING, NULL,
4620 integerOrderingMatch, NULL, NULL,
4623 {"( 2.5.13.16 NAME 'bitStringMatch' "
4624 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.6 )",
4625 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4627 bitStringMatch, bitStringIndexer, bitStringFilter,
4630 {"( 2.5.13.17 NAME 'octetStringMatch' "
4631 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
4632 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4634 octetStringMatch, octetStringIndexer, octetStringFilter,
4637 {"( 2.5.13.18 NAME 'octetStringOrderingMatch' "
4638 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
4639 SLAP_MR_ORDERING, NULL,
4641 octetStringOrderingMatch, NULL, NULL,
4644 {"( 2.5.13.20 NAME 'telephoneNumberMatch' "
4645 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 )",
4646 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL,
4648 telephoneNumberMatch,
4649 telephoneNumberIndexer,
4650 telephoneNumberFilter,
4653 {"( 2.5.13.21 NAME 'telephoneNumberSubstringsMatch' "
4654 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4655 SLAP_MR_SUBSTR, NULL,
4657 telephoneNumberSubstringsMatch,
4658 telephoneNumberSubstringsIndexer,
4659 telephoneNumberSubstringsFilter,
4662 {"( 2.5.13.22 NAME 'presentationAddressMatch' "
4663 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.43 )",
4664 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4669 {"( 2.5.13.23 NAME 'uniqueMemberMatch' "
4670 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.34 )",
4671 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4673 uniqueMemberMatch, NULL, NULL,
4676 {"( 2.5.13.24 NAME 'protocolInformationMatch' "
4677 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.42 )",
4678 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4680 protocolInformationMatch, NULL, NULL,
4683 {"( 2.5.13.27 NAME 'generalizedTimeMatch' "
4684 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
4685 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4687 generalizedTimeMatch, NULL, NULL,
4690 {"( 2.5.13.28 NAME 'generalizedTimeOrderingMatch' "
4691 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
4692 SLAP_MR_ORDERING, NULL,
4694 generalizedTimeOrderingMatch, NULL, NULL,
4697 {"( 2.5.13.29 NAME 'integerFirstComponentMatch' "
4698 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4699 SLAP_MR_EQUALITY | SLAP_MR_EXT, integerFirstComponentMatchSyntaxes,
4701 integerFirstComponentMatch, NULL, NULL,
4704 {"( 2.5.13.30 NAME 'objectIdentifierFirstComponentMatch' "
4705 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
4706 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4707 objectIdentifierFirstComponentMatchSyntaxes,
4709 objectIdentifierFirstComponentMatch, NULL, NULL,
4713 {"( 2.5.13.34 NAME 'certificateExactMatch' "
4714 "SYNTAX 1.2.826.0.1.3344810.7.1 )",
4715 SLAP_MR_EQUALITY | SLAP_MR_EXT, certificateExactMatchSyntaxes,
4716 certificateExactConvert, NULL,
4717 certificateExactMatch,
4718 certificateExactIndexer, certificateExactFilter,
4722 {"( 1.3.6.1.4.1.1466.109.114.1 NAME 'caseExactIA5Match' "
4723 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4724 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4726 caseExactIA5Match, caseExactIA5Indexer, caseExactIA5Filter,
4727 IA5StringApproxMatchOID },
4729 {"( 1.3.6.1.4.1.1466.109.114.2 NAME 'caseIgnoreIA5Match' "
4730 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4731 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL,
4733 caseIgnoreIA5Match, caseIgnoreIA5Indexer, caseIgnoreIA5Filter,
4734 IA5StringApproxMatchOID },
4736 {"( 1.3.6.1.4.1.1466.109.114.3 NAME 'caseIgnoreIA5SubstringsMatch' "
4737 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4738 SLAP_MR_SUBSTR, NULL,
4740 caseIgnoreIA5SubstringsMatch,
4741 caseIgnoreIA5SubstringsIndexer,
4742 caseIgnoreIA5SubstringsFilter,
4745 {"( 1.3.6.1.4.1.4203.1.2.1 NAME 'caseExactIA5SubstringsMatch' "
4746 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4747 SLAP_MR_SUBSTR, NULL,
4749 caseExactIA5SubstringsMatch,
4750 caseExactIA5SubstringsIndexer,
4751 caseExactIA5SubstringsFilter,
4754 #ifdef SLAPD_AUTHPASSWD
4755 /* needs updating */
4756 {"( 1.3.6.1.4.1.4203.666.4.1 NAME 'authPasswordMatch' "
4757 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
4758 SLAP_MR_EQUALITY, NULL,
4760 authPasswordMatch, NULL, NULL,
4764 #ifdef SLAPD_ACI_ENABLED
4765 {"( 1.3.6.1.4.1.4203.666.4.2 NAME 'OpenLDAPaciMatch' "
4766 "SYNTAX 1.3.6.1.4.1.4203.666.2.1 )",
4767 SLAP_MR_EQUALITY, NULL,
4769 OpenLDAPaciMatch, NULL, NULL,
4773 {"( 1.2.840.113556.1.4.803 NAME 'integerBitAndMatch' "
4774 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4777 integerBitAndMatch, NULL, NULL,
4780 {"( 1.2.840.113556.1.4.804 NAME 'integerBitOrMatch' "
4781 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4784 integerBitOrMatch, NULL, NULL,
4787 {NULL, SLAP_MR_NONE, NULL,
4788 NULL, NULL, NULL, NULL, NULL,
4793 slap_schema_init( void )
4798 /* we should only be called once (from main) */
4799 assert( schema_init_done == 0 );
4801 for ( i=0; syntax_defs[i].sd_desc != NULL; i++ ) {
4802 res = register_syntax( &syntax_defs[i] );
4805 fprintf( stderr, "slap_schema_init: Error registering syntax %s\n",
4806 syntax_defs[i].sd_desc );
4811 for ( i=0; mrule_defs[i].mrd_desc != NULL; i++ ) {
4812 if( mrule_defs[i].mrd_usage == SLAP_MR_NONE &&
4813 mrule_defs[i].mrd_compat_syntaxes == NULL )
4816 "slap_schema_init: Ingoring unusable matching rule %s\n",
4817 mrule_defs[i].mrd_desc );
4821 res = register_matching_rule( &mrule_defs[i] );
4825 "slap_schema_init: Error registering matching rule %s\n",
4826 mrule_defs[i].mrd_desc );
4831 for ( i=0; i < (int)(sizeof(mr_ptr)/sizeof(mr_ptr[0])); i++ )
4832 *mr_ptr[i].mr = mr_find( mr_ptr[i].oid );
4834 res = slap_schema_load();
4835 schema_init_done = 1;
4840 schema_destroy( void )
4846 for ( i=0; i < (int)(sizeof(mr_ptr)/sizeof(mr_ptr[0])); i++ )
4847 *mr_ptr[i].mr = NULL;