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
63 #ifdef LDAP_CLIENT_UPDATE
64 #define octetStringOrderingMatch octetStringMatch
65 #endif /* LDAP_CLIENT_UPDATE */
67 /* unimplemented matching routines */
68 #define caseIgnoreListMatch NULL
69 #define caseIgnoreListSubstringsMatch NULL
70 #define protocolInformationMatch NULL
72 #ifdef SLAPD_ACI_ENABLED
73 #define OpenLDAPaciMatch NULL
75 #ifdef SLAPD_AUTHPASSWD
76 #define authPasswordMatch NULL
79 /* recycled indexing/filtering routines */
80 #define dnIndexer caseExactIgnoreIndexer
81 #define dnFilter caseExactIgnoreFilter
82 #define bitStringFilter octetStringFilter
83 #define bitStringIndexer octetStringIndexer
85 #define telephoneNumberIndexer caseIgnoreIA5Indexer
86 #define telephoneNumberFilter caseIgnoreIA5Filter
87 #define telephoneNumberSubstringsIndexer caseIgnoreIA5SubstringsIndexer
88 #define telephoneNumberSubstringsFilter caseIgnoreIA5SubstringsFilter
90 static MatchingRule *caseExactMatchingRule;
91 static MatchingRule *caseExactSubstringsMatchingRule;
92 static MatchingRule *integerFirstComponentMatchingRule;
94 static const struct MatchingRulePtr {
98 /* must match OIDs below */
99 { "2.5.13.5", &caseExactMatchingRule },
100 { "2.5.13.7", &caseExactSubstringsMatchingRule },
101 { "2.5.13.29", &integerFirstComponentMatchingRule }
105 static char *bvcasechr( struct berval *bv, unsigned char c, ber_len_t *len )
108 char lower = TOLOWER( c );
109 char upper = TOUPPER( c );
111 if( c == 0 ) return NULL;
113 for( i=0; i < bv->bv_len; i++ ) {
114 if( upper == bv->bv_val[i] || lower == bv->bv_val[i] ) {
116 return &bv->bv_val[i];
129 struct berval *value,
130 void *assertedValue )
132 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
135 match = memcmp( value->bv_val,
136 ((struct berval *) assertedValue)->bv_val,
144 /* Index generation function */
145 int octetStringIndexer(
150 struct berval *prefix,
157 HASH_CONTEXT HASHcontext;
158 unsigned char HASHdigest[HASH_BYTES];
159 struct berval digest;
160 digest.bv_val = HASHdigest;
161 digest.bv_len = sizeof(HASHdigest);
163 for( i=0; values[i].bv_val != NULL; i++ ) {
164 /* just count them */
167 /* we should have at least one value at this point */
170 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
172 slen = syntax->ssyn_oidlen;
173 mlen = mr->smr_oidlen;
175 for( i=0; values[i].bv_val != NULL; i++ ) {
176 HASH_Init( &HASHcontext );
177 if( prefix != NULL && prefix->bv_len > 0 ) {
178 HASH_Update( &HASHcontext,
179 prefix->bv_val, prefix->bv_len );
181 HASH_Update( &HASHcontext,
182 syntax->ssyn_oid, slen );
183 HASH_Update( &HASHcontext,
185 HASH_Update( &HASHcontext,
186 values[i].bv_val, values[i].bv_len );
187 HASH_Final( HASHdigest, &HASHcontext );
189 ber_dupbv( &keys[i], &digest );
192 keys[i].bv_val = NULL;
200 /* Index generation function */
201 int octetStringFilter(
206 struct berval *prefix,
207 void * assertedValue,
212 HASH_CONTEXT HASHcontext;
213 unsigned char HASHdigest[HASH_BYTES];
214 struct berval *value = (struct berval *) assertedValue;
215 struct berval digest;
216 digest.bv_val = HASHdigest;
217 digest.bv_len = sizeof(HASHdigest);
219 slen = syntax->ssyn_oidlen;
220 mlen = mr->smr_oidlen;
222 keys = ch_malloc( sizeof( struct berval ) * 2 );
224 HASH_Init( &HASHcontext );
225 if( prefix != NULL && prefix->bv_len > 0 ) {
226 HASH_Update( &HASHcontext,
227 prefix->bv_val, prefix->bv_len );
229 HASH_Update( &HASHcontext,
230 syntax->ssyn_oid, slen );
231 HASH_Update( &HASHcontext,
233 HASH_Update( &HASHcontext,
234 value->bv_val, value->bv_len );
235 HASH_Final( HASHdigest, &HASHcontext );
237 ber_dupbv( keys, &digest );
238 keys[1].bv_val = NULL;
251 /* no value allowed */
252 return LDAP_INVALID_SYNTAX;
260 /* any value allowed */
271 /* very unforgiving validation, requires no normalization
272 * before simplistic matching
274 if( in->bv_len < 3 ) {
275 return LDAP_INVALID_SYNTAX;
279 * rfc 2252 section 6.3 Bit String
280 * bitstring = "'" *binary-digit "'"
281 * binary-digit = "0" / "1"
282 * example: '0101111101'B
285 if( in->bv_val[0] != '\'' ||
286 in->bv_val[in->bv_len-2] != '\'' ||
287 in->bv_val[in->bv_len-1] != 'B' )
289 return LDAP_INVALID_SYNTAX;
292 for( i=in->bv_len-3; i>0; i-- ) {
293 if( in->bv_val[i] != '0' && in->bv_val[i] != '1' ) {
294 return LDAP_INVALID_SYNTAX;
305 struct berval *normalized )
308 * A normalized bitString is has no extaneous (leading) zero bits.
309 * That is, '00010'B is normalized to '10'B
310 * However, as a special case, '0'B requires no normalization.
314 /* start at the first bit */
317 /* Find the first non-zero bit */
318 while ( *p == '0' ) p++;
321 /* no non-zero bits */
322 ber_str2bv( "\'0\'B", sizeof("\'0\'B") - 1, 1, normalized );
326 normalized->bv_val = ch_malloc( val->bv_len + 1 );
328 normalized->bv_val[0] = '\'';
329 normalized->bv_len = 1;
331 for( ; *p != '\0'; p++ ) {
332 normalized->bv_val[normalized->bv_len++] = *p;
335 normalized->bv_val[normalized->bv_len] = '\0';
349 if( in->bv_len == 0 ) return LDAP_SUCCESS;
351 ber_dupbv( &dn, in );
352 if( !dn.bv_val ) return LDAP_OTHER;
354 if( dn.bv_val[dn.bv_len-1] == 'B'
355 && dn.bv_val[dn.bv_len-2] == '\'' )
357 /* assume presence of optional UID */
360 for(i=dn.bv_len-3; i>1; i--) {
361 if( dn.bv_val[i] != '0' && dn.bv_val[i] != '1' ) {
365 if( dn.bv_val[i] != '\'' || dn.bv_val[i-1] != '#' ) {
366 ber_memfree( dn.bv_val );
367 return LDAP_INVALID_SYNTAX;
370 /* trim the UID to allow use of dnValidate */
371 dn.bv_val[i-1] = '\0';
375 rc = dnValidate( NULL, &dn );
377 ber_memfree( dn.bv_val );
385 struct berval *normalized )
390 ber_dupbv( &out, val );
391 if( out.bv_len != 0 ) {
392 struct berval uidin = { 0, NULL };
393 struct berval uidout = { 0, NULL };
395 if( out.bv_val[out.bv_len-1] == 'B'
396 && out.bv_val[out.bv_len-2] == '\'' )
398 /* assume presence of optional UID */
399 uidin.bv_val = strrchr( out.bv_val, '#' );
401 if( uidin.bv_val == NULL ) {
403 return LDAP_INVALID_SYNTAX;
406 uidin.bv_len = out.bv_len - (uidin.bv_val - out.bv_val);
407 out.bv_len -= uidin.bv_len--;
409 /* temporarily trim the UID */
410 *(uidin.bv_val++) = '\0';
412 rc = bitStringNormalize( syntax, &uidin, &uidout );
414 if( rc != LDAP_SUCCESS ) {
416 return LDAP_INVALID_SYNTAX;
420 #ifdef USE_DN_NORMALIZE
421 rc = dnNormalize2( NULL, &out, normalized );
423 rc = dnPretty2( NULL, &out, normalized );
426 if( rc != LDAP_SUCCESS ) {
428 free( uidout.bv_val );
429 return LDAP_INVALID_SYNTAX;
432 if( uidout.bv_len ) {
433 normalized->bv_val = ch_realloc( normalized->bv_val,
434 normalized->bv_len + uidout.bv_len + sizeof("#") );
436 /* insert the separator */
437 normalized->bv_val[normalized->bv_len++] = '#';
440 AC_MEMCPY( &normalized->bv_val[normalized->bv_len],
441 uidout.bv_val, uidout.bv_len );
442 normalized->bv_len += uidout.bv_len;
445 normalized->bv_val[normalized->bv_len] = '\0';
455 * Handling boolean syntax and matching is quite rigid.
456 * A more flexible approach would be to allow a variety
457 * of strings to be normalized and prettied into TRUE
465 /* very unforgiving validation, requires no normalization
466 * before simplistic matching
469 if( in->bv_len == 4 ) {
470 if( !memcmp( in->bv_val, "TRUE", 4 ) ) {
473 } else if( in->bv_len == 5 ) {
474 if( !memcmp( in->bv_val, "FALSE", 5 ) ) {
479 return LDAP_INVALID_SYNTAX;
488 struct berval *value,
489 void *assertedValue )
491 /* simplistic matching allowed by rigid validation */
492 struct berval *asserted = (struct berval *) assertedValue;
493 *matchp = value->bv_len != asserted->bv_len;
497 /*-------------------------------------------------------------------
498 LDAP/X.500 string syntax / matching rules have a few oddities. This
499 comment attempts to detail how slapd(8) treats them.
502 StringSyntax X.500 LDAP Matching
503 DirectoryString CHOICE UTF8 i/e + ignore insignificant spaces
504 PrintableString subset subset i/e + ignore insignificant spaces
505 NumericString subset subset ignore all spaces
506 IA5String ASCII ASCII i/e + ignore insignificant spaces
507 TeletexString T.61 T.61 i/e + ignore insignificant spaces
509 TelephoneNumber subset subset i + ignore all spaces and "-"
511 See draft-ietf-ldapbis-strpro for details (once published).
515 In X.500(93), a directory string can be either a PrintableString,
516 a bmpString, or a UniversalString (e.g., UCS (a subset of Unicode)).
517 In later versions, more CHOICEs were added. In all cases the string
520 In LDAPv3, a directory string is a UTF-8 encoded UCS string.
522 For matching, there are both case ignore and exact rules. Both
523 also require that "insignificant" spaces be ignored.
524 spaces before the first non-space are ignored;
525 spaces after the last non-space are ignored;
526 spaces after a space are ignored.
527 Note: by these rules (and as clarified in X.520), a string of only
528 spaces is to be treated as if held one space, not empty (which
529 would be a syntax error).
532 In ASN.1, numeric string is just a string of digits and spaces
533 and could be empty. However, in X.500, all attribute values of
534 numeric string carry a non-empty constraint. For example:
536 internationalISDNNumber ATTRIBUTE ::= {
537 WITH SYNTAX InternationalISDNNumber
538 EQUALITY MATCHING RULE numericStringMatch
539 SUBSTRINGS MATCHING RULE numericStringSubstringsMatch
540 ID id-at-internationalISDNNumber }
541 InternationalISDNNumber ::=
542 NumericString (SIZE(1..ub-international-isdn-number))
544 Unforunately, some assertion values are don't carry the same
545 constraint (but its unclear how such an assertion could ever
546 be true). In LDAP, there is one syntax (numericString) not two
547 (numericString with constraint, numericString without constraint).
548 This should be treated as numericString with non-empty constraint.
549 Note that while someone may have no ISDN number, there are no ISDN
550 numbers which are zero length.
552 In matching, spaces are ignored.
555 In ASN.1, Printable string is just a string of printable characters
556 and can be empty. In X.500, semantics much like NumericString (see
557 serialNumber for a like example) excepting uses insignificant space
558 handling instead of ignore all spaces.
561 Basically same as PrintableString. There are no examples in X.500,
562 but same logic applies. So we require them to be non-empty as
565 -------------------------------------------------------------------*/
574 unsigned char *u = in->bv_val;
576 if( !in->bv_len ) return LDAP_INVALID_SYNTAX;
578 for( count = in->bv_len; count > 0; count-=len, u+=len ) {
579 /* get the length indicated by the first byte */
580 len = LDAP_UTF8_CHARLEN2( u, len );
582 /* very basic checks */
585 if( (u[5] & 0xC0) != 0x80 ) {
586 return LDAP_INVALID_SYNTAX;
589 if( (u[4] & 0xC0) != 0x80 ) {
590 return LDAP_INVALID_SYNTAX;
593 if( (u[3] & 0xC0) != 0x80 ) {
594 return LDAP_INVALID_SYNTAX;
597 if( (u[2] & 0xC0 )!= 0x80 ) {
598 return LDAP_INVALID_SYNTAX;
601 if( (u[1] & 0xC0) != 0x80 ) {
602 return LDAP_INVALID_SYNTAX;
605 /* CHARLEN already validated it */
608 return LDAP_INVALID_SYNTAX;
611 /* make sure len corresponds with the offset
612 to the next character */
613 if( LDAP_UTF8_OFFSET( u ) != len ) return LDAP_INVALID_SYNTAX;
616 if( count != 0 ) return LDAP_INVALID_SYNTAX;
625 struct berval *normalized )
630 /* validator should have refused an empty string */
631 assert( val->bv_len );
635 /* Ignore initial whitespace */
636 /* All space is ASCII. All ASCII is 1 byte */
637 for ( ; p < val->bv_val + val->bv_len && ASCII_SPACE( p[ 0 ] ); p++ );
639 normalized->bv_len = val->bv_len - (p - val->bv_val);
641 if( !normalized->bv_len ) {
642 ber_mem2bv( " ", 1, 1, normalized );
646 ber_mem2bv( p, normalized->bv_len, 1, normalized );
647 e = normalized->bv_val + normalized->bv_len;
649 assert( normalized->bv_val );
651 p = q = normalized->bv_val;
656 if ( ASCII_SPACE( *p ) ) {
661 /* Ignore the extra whitespace */
662 while ( ASCII_SPACE( *p ) ) {
666 len = LDAP_UTF8_COPY(q,p);
672 assert( normalized->bv_val <= p );
673 assert( q+len <= p );
675 /* cannot start with a space */
676 assert( !ASCII_SPACE( normalized->bv_val[0] ) );
679 * If the string ended in space, backup the pointer one
680 * position. One is enough because the above loop collapsed
681 * all whitespace to a single space.
689 /* cannot end with a space */
690 assert( !ASCII_SPACE( *q ) );
697 normalized->bv_len = q - normalized->bv_val;
702 /* Returns Unicode canonically normalized copy of a substring assertion
703 * Skipping attribute description */
704 static SubstringsAssertion *
705 UTF8SubstringsassertionNormalize(
706 SubstringsAssertion *sa,
709 SubstringsAssertion *nsa;
712 nsa = (SubstringsAssertion *)ch_calloc( 1, sizeof(SubstringsAssertion) );
717 if( sa->sa_initial.bv_val != NULL ) {
718 UTF8bvnormalize( &sa->sa_initial, &nsa->sa_initial, casefold );
719 if( nsa->sa_initial.bv_val == NULL ) {
724 if( sa->sa_any != NULL ) {
725 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
728 nsa->sa_any = (struct berval *)
729 ch_malloc( (i + 1) * sizeof(struct berval) );
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.18 octetStringOrderingMatch
4466 * 2.5.13.19 octetStringSubstringsMatch
4467 * 2.5.13.25 uTCTimeMatch
4468 * 2.5.13.26 uTCTimeOrderingMatch
4469 * 2.5.13.31 directoryStringFirstComponentMatch
4470 * 2.5.13.32 wordMatch
4471 * 2.5.13.33 keywordMatch
4472 * 2.5.13.35 certificateMatch
4473 * 2.5.13.36 certificatePairExactMatch
4474 * 2.5.13.37 certificatePairMatch
4475 * 2.5.13.38 certificateListExactMatch
4476 * 2.5.13.39 certificateListMatch
4477 * 2.5.13.40 algorithmIdentifierMatch
4478 * 2.5.13.41 storedPrefixMatch
4479 * 2.5.13.42 attributeCertificateMatch
4480 * 2.5.13.43 readerAndKeyIDMatch
4481 * 2.5.13.44 attributeIntegrityMatch
4483 static slap_mrule_defs_rec mrule_defs[] = {
4485 * EQUALITY matching rules must be listed after associated APPROX
4486 * matching rules. So, we list all APPROX matching rules first.
4488 {"( " directoryStringApproxMatchOID " NAME 'directoryStringApproxMatch' "
4489 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4490 SLAP_MR_HIDE | SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT, NULL,
4492 directoryStringApproxMatch,
4493 directoryStringApproxIndexer,
4494 directoryStringApproxFilter,
4497 {"( " IA5StringApproxMatchOID " NAME 'IA5StringApproxMatch' "
4498 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4499 SLAP_MR_HIDE | SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT, NULL,
4501 IA5StringApproxMatch,
4502 IA5StringApproxIndexer,
4503 IA5StringApproxFilter,
4507 * Other matching rules
4510 {"( 2.5.13.0 NAME 'objectIdentifierMatch' "
4511 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
4512 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4514 objectIdentifierMatch, caseIgnoreIA5Indexer, caseIgnoreIA5Filter,
4517 {"( 2.5.13.1 NAME 'distinguishedNameMatch' "
4518 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )",
4519 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4521 dnMatch, dnIndexer, dnFilter,
4524 {"( 2.5.13.2 NAME 'caseIgnoreMatch' "
4525 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4526 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD,
4527 directoryStringSyntaxes,
4529 caseIgnoreMatch, caseExactIgnoreIndexer, caseExactIgnoreFilter,
4530 directoryStringApproxMatchOID },
4532 {"( 2.5.13.3 NAME 'caseIgnoreOrderingMatch' "
4533 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4534 SLAP_MR_ORDERING, directoryStringSyntaxes,
4536 caseIgnoreOrderingMatch, NULL, NULL,
4539 {"( 2.5.13.4 NAME 'caseIgnoreSubstringsMatch' "
4540 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4541 SLAP_MR_SUBSTR, NULL,
4543 caseExactIgnoreSubstringsMatch,
4544 caseExactIgnoreSubstringsIndexer,
4545 caseExactIgnoreSubstringsFilter,
4548 {"( 2.5.13.5 NAME 'caseExactMatch' "
4549 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4550 SLAP_MR_EQUALITY | SLAP_MR_EXT, directoryStringSyntaxes,
4552 caseExactMatch, caseExactIgnoreIndexer, caseExactIgnoreFilter,
4553 directoryStringApproxMatchOID },
4555 {"( 2.5.13.6 NAME 'caseExactOrderingMatch' "
4556 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4557 SLAP_MR_ORDERING, directoryStringSyntaxes,
4559 caseExactOrderingMatch, NULL, NULL,
4562 {"( 2.5.13.7 NAME 'caseExactSubstringsMatch' "
4563 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4564 SLAP_MR_SUBSTR, directoryStringSyntaxes,
4566 caseExactIgnoreSubstringsMatch,
4567 caseExactIgnoreSubstringsIndexer,
4568 caseExactIgnoreSubstringsFilter,
4571 {"( 2.5.13.8 NAME 'numericStringMatch' "
4572 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 )",
4573 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL,
4576 caseIgnoreIA5Indexer,
4577 caseIgnoreIA5Filter,
4580 {"( 2.5.13.10 NAME 'numericStringSubstringsMatch' "
4581 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4582 SLAP_MR_SUBSTR, NULL,
4584 caseIgnoreIA5SubstringsMatch,
4585 caseIgnoreIA5SubstringsIndexer,
4586 caseIgnoreIA5SubstringsFilter,
4589 {"( 2.5.13.11 NAME 'caseIgnoreListMatch' "
4590 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )",
4591 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL,
4593 caseIgnoreListMatch, NULL, NULL,
4596 {"( 2.5.13.12 NAME 'caseIgnoreListSubstringsMatch' "
4597 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4598 SLAP_MR_SUBSTR, NULL,
4600 caseIgnoreListSubstringsMatch, NULL, NULL,
4603 {"( 2.5.13.13 NAME 'booleanMatch' "
4604 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )",
4605 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4607 booleanMatch, NULL, NULL,
4610 {"( 2.5.13.14 NAME 'integerMatch' "
4611 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4612 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4614 integerMatch, integerIndexer, integerFilter,
4617 {"( 2.5.13.15 NAME 'integerOrderingMatch' "
4618 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4619 SLAP_MR_ORDERING, NULL,
4621 integerOrderingMatch, NULL, NULL,
4624 {"( 2.5.13.16 NAME 'bitStringMatch' "
4625 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.6 )",
4626 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4628 bitStringMatch, bitStringIndexer, bitStringFilter,
4631 {"( 2.5.13.17 NAME 'octetStringMatch' "
4632 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
4633 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4635 octetStringMatch, octetStringIndexer, octetStringFilter,
4638 #ifdef LDAP_CLIENT_UPDATE
4639 {"( 2.5.13.18 NAME 'octetStringOrderingMatch' "
4640 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
4641 SLAP_MR_ORDERING, NULL,
4643 octetStringOrderingMatch, NULL, NULL,
4645 #endif /* LDAP_CLIENT_UPDATE */
4647 {"( 2.5.13.20 NAME 'telephoneNumberMatch' "
4648 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 )",
4649 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL,
4651 telephoneNumberMatch,
4652 telephoneNumberIndexer,
4653 telephoneNumberFilter,
4656 {"( 2.5.13.21 NAME 'telephoneNumberSubstringsMatch' "
4657 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4658 SLAP_MR_SUBSTR, NULL,
4660 telephoneNumberSubstringsMatch,
4661 telephoneNumberSubstringsIndexer,
4662 telephoneNumberSubstringsFilter,
4665 {"( 2.5.13.22 NAME 'presentationAddressMatch' "
4666 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.43 )",
4667 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4672 {"( 2.5.13.23 NAME 'uniqueMemberMatch' "
4673 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.34 )",
4674 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4676 uniqueMemberMatch, NULL, NULL,
4679 {"( 2.5.13.24 NAME 'protocolInformationMatch' "
4680 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.42 )",
4681 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4683 protocolInformationMatch, NULL, NULL,
4686 {"( 2.5.13.27 NAME 'generalizedTimeMatch' "
4687 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
4688 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4690 generalizedTimeMatch, NULL, NULL,
4693 {"( 2.5.13.28 NAME 'generalizedTimeOrderingMatch' "
4694 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
4695 SLAP_MR_ORDERING, NULL,
4697 generalizedTimeOrderingMatch, NULL, NULL,
4700 {"( 2.5.13.29 NAME 'integerFirstComponentMatch' "
4701 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4702 SLAP_MR_EQUALITY | SLAP_MR_EXT, integerFirstComponentMatchSyntaxes,
4704 integerFirstComponentMatch, NULL, NULL,
4707 {"( 2.5.13.30 NAME 'objectIdentifierFirstComponentMatch' "
4708 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
4709 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4710 objectIdentifierFirstComponentMatchSyntaxes,
4712 objectIdentifierFirstComponentMatch, NULL, NULL,
4716 {"( 2.5.13.34 NAME 'certificateExactMatch' "
4717 "SYNTAX 1.2.826.0.1.3344810.7.1 )",
4718 SLAP_MR_EQUALITY | SLAP_MR_EXT, certificateExactMatchSyntaxes,
4719 certificateExactConvert, NULL,
4720 certificateExactMatch,
4721 certificateExactIndexer, certificateExactFilter,
4725 {"( 1.3.6.1.4.1.1466.109.114.1 NAME 'caseExactIA5Match' "
4726 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4727 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4729 caseExactIA5Match, caseExactIA5Indexer, caseExactIA5Filter,
4730 IA5StringApproxMatchOID },
4732 {"( 1.3.6.1.4.1.1466.109.114.2 NAME 'caseIgnoreIA5Match' "
4733 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4734 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL,
4736 caseIgnoreIA5Match, caseIgnoreIA5Indexer, caseIgnoreIA5Filter,
4737 IA5StringApproxMatchOID },
4739 {"( 1.3.6.1.4.1.1466.109.114.3 NAME 'caseIgnoreIA5SubstringsMatch' "
4740 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4741 SLAP_MR_SUBSTR, NULL,
4743 caseIgnoreIA5SubstringsMatch,
4744 caseIgnoreIA5SubstringsIndexer,
4745 caseIgnoreIA5SubstringsFilter,
4748 {"( 1.3.6.1.4.1.4203.1.2.1 NAME 'caseExactIA5SubstringsMatch' "
4749 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4750 SLAP_MR_SUBSTR, NULL,
4752 caseExactIA5SubstringsMatch,
4753 caseExactIA5SubstringsIndexer,
4754 caseExactIA5SubstringsFilter,
4757 #ifdef SLAPD_AUTHPASSWD
4758 /* needs updating */
4759 {"( 1.3.6.1.4.1.4203.666.4.1 NAME 'authPasswordMatch' "
4760 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
4761 SLAP_MR_EQUALITY, NULL,
4763 authPasswordMatch, NULL, NULL,
4767 #ifdef SLAPD_ACI_ENABLED
4768 {"( 1.3.6.1.4.1.4203.666.4.2 NAME 'OpenLDAPaciMatch' "
4769 "SYNTAX 1.3.6.1.4.1.4203.666.2.1 )",
4770 SLAP_MR_EQUALITY, NULL,
4772 OpenLDAPaciMatch, NULL, NULL,
4776 {"( 1.2.840.113556.1.4.803 NAME 'integerBitAndMatch' "
4777 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4780 integerBitAndMatch, NULL, NULL,
4783 {"( 1.2.840.113556.1.4.804 NAME 'integerBitOrMatch' "
4784 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4787 integerBitOrMatch, NULL, NULL,
4790 {NULL, SLAP_MR_NONE, NULL,
4791 NULL, NULL, NULL, NULL, NULL,
4796 slap_schema_init( void )
4801 /* we should only be called once (from main) */
4802 assert( schema_init_done == 0 );
4804 for ( i=0; syntax_defs[i].sd_desc != NULL; i++ ) {
4805 res = register_syntax( &syntax_defs[i] );
4808 fprintf( stderr, "slap_schema_init: Error registering syntax %s\n",
4809 syntax_defs[i].sd_desc );
4814 for ( i=0; mrule_defs[i].mrd_desc != NULL; i++ ) {
4815 if( mrule_defs[i].mrd_usage == SLAP_MR_NONE &&
4816 mrule_defs[i].mrd_compat_syntaxes == NULL )
4819 "slap_schema_init: Ingoring unusable matching rule %s\n",
4820 mrule_defs[i].mrd_desc );
4824 res = register_matching_rule( &mrule_defs[i] );
4828 "slap_schema_init: Error registering matching rule %s\n",
4829 mrule_defs[i].mrd_desc );
4834 for ( i=0; i < (int)(sizeof(mr_ptr)/sizeof(mr_ptr[0])); i++ )
4835 *mr_ptr[i].mr = mr_find( mr_ptr[i].oid );
4837 res = slap_schema_load();
4838 schema_init_done = 1;
4843 schema_destroy( void )
4849 for ( i=0; i < (int)(sizeof(mr_ptr)/sizeof(mr_ptr[0])); i++ )
4850 *mr_ptr[i].mr = NULL;