1 /* schema_init.c - init builtin schema */
4 * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
5 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
15 #include <ac/string.h>
16 #include <ac/socket.h>
22 #include "ldap_utf8.h"
24 #include "lutil_hash.h"
25 #define HASH_BYTES LUTIL_HASH_BYTES
26 #define HASH_CONTEXT lutil_HASH_CTX
27 #define HASH_Init(c) lutil_HASHInit(c)
28 #define HASH_Update(c,buf,len) lutil_HASHUpdate(c,buf,len)
29 #define HASH_Final(d,c) lutil_HASHFinal(d,c)
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 /* unimplemented matching routines */
64 #define caseIgnoreListMatch NULL
65 #define caseIgnoreListSubstringsMatch NULL
66 #define protocolInformationMatch NULL
68 #ifdef SLAPD_ACI_ENABLED
69 #define OpenLDAPaciMatch NULL
71 #ifdef SLAPD_AUTHPASSWD
72 #define authPasswordMatch NULL
75 /* recycled indexing/filtering routines */
76 #define dnIndexer caseExactIgnoreIndexer
77 #define dnFilter caseExactIgnoreFilter
78 #define bitStringFilter octetStringFilter
79 #define bitStringIndexer octetStringIndexer
81 #define telephoneNumberIndexer caseIgnoreIA5Indexer
82 #define telephoneNumberFilter caseIgnoreIA5Filter
83 #define telephoneNumberSubstringsIndexer caseIgnoreIA5SubstringsIndexer
84 #define telephoneNumberSubstringsFilter caseIgnoreIA5SubstringsFilter
86 static MatchingRule *caseExactMatchingRule;
87 static MatchingRule *caseExactSubstringsMatchingRule;
88 static MatchingRule *integerFirstComponentMatchingRule;
90 static const struct MatchingRulePtr {
94 /* must match OIDs below */
95 { "2.5.13.5", &caseExactMatchingRule },
96 { "2.5.13.7", &caseExactSubstringsMatchingRule },
97 { "2.5.13.29", &integerFirstComponentMatchingRule }
101 static char *bvcasechr( struct berval *bv, unsigned char c, ber_len_t *len )
104 char lower = TOLOWER( c );
105 char upper = TOUPPER( c );
107 if( c == 0 ) return NULL;
109 for( i=0; i < bv->bv_len; i++ ) {
110 if( upper == bv->bv_val[i] || lower == bv->bv_val[i] ) {
112 return &bv->bv_val[i];
125 struct berval *value,
126 void *assertedValue )
128 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
131 match = memcmp( value->bv_val,
132 ((struct berval *) assertedValue)->bv_val,
141 octetStringOrderingMatch(
146 struct berval *value,
147 void *assertedValue )
149 ber_len_t v_len = value->bv_len;
150 ber_len_t av_len = ((struct berval *) assertedValue)->bv_len;
151 int match = memcmp( value->bv_val,
152 ((struct berval *) assertedValue)->bv_val,
153 (v_len < av_len ? v_len : av_len) );
155 match = v_len - av_len;
160 /* Index generation function */
161 int octetStringIndexer(
166 struct berval *prefix,
173 HASH_CONTEXT HASHcontext;
174 unsigned char HASHdigest[HASH_BYTES];
175 struct berval digest;
176 digest.bv_val = HASHdigest;
177 digest.bv_len = sizeof(HASHdigest);
179 for( i=0; values[i].bv_val != NULL; i++ ) {
180 /* just count them */
183 /* we should have at least one value at this point */
186 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
188 slen = syntax->ssyn_oidlen;
189 mlen = mr->smr_oidlen;
191 for( i=0; values[i].bv_val != NULL; i++ ) {
192 HASH_Init( &HASHcontext );
193 if( prefix != NULL && prefix->bv_len > 0 ) {
194 HASH_Update( &HASHcontext,
195 prefix->bv_val, prefix->bv_len );
197 HASH_Update( &HASHcontext,
198 syntax->ssyn_oid, slen );
199 HASH_Update( &HASHcontext,
201 HASH_Update( &HASHcontext,
202 values[i].bv_val, values[i].bv_len );
203 HASH_Final( HASHdigest, &HASHcontext );
205 ber_dupbv( &keys[i], &digest );
208 keys[i].bv_val = NULL;
216 /* Index generation function */
217 int octetStringFilter(
222 struct berval *prefix,
223 void * assertedValue,
228 HASH_CONTEXT HASHcontext;
229 unsigned char HASHdigest[HASH_BYTES];
230 struct berval *value = (struct berval *) assertedValue;
231 struct berval digest;
232 digest.bv_val = HASHdigest;
233 digest.bv_len = sizeof(HASHdigest);
235 slen = syntax->ssyn_oidlen;
236 mlen = mr->smr_oidlen;
238 keys = ch_malloc( sizeof( struct berval ) * 2 );
240 HASH_Init( &HASHcontext );
241 if( prefix != NULL && prefix->bv_len > 0 ) {
242 HASH_Update( &HASHcontext,
243 prefix->bv_val, prefix->bv_len );
245 HASH_Update( &HASHcontext,
246 syntax->ssyn_oid, slen );
247 HASH_Update( &HASHcontext,
249 HASH_Update( &HASHcontext,
250 value->bv_val, value->bv_len );
251 HASH_Final( HASHdigest, &HASHcontext );
253 ber_dupbv( keys, &digest );
254 keys[1].bv_val = NULL;
267 /* no value allowed */
268 return LDAP_INVALID_SYNTAX;
276 /* any value allowed */
287 /* very unforgiving validation, requires no normalization
288 * before simplistic matching
290 if( in->bv_len < 3 ) {
291 return LDAP_INVALID_SYNTAX;
295 * rfc 2252 section 6.3 Bit String
296 * bitstring = "'" *binary-digit "'"
297 * binary-digit = "0" / "1"
298 * example: '0101111101'B
301 if( in->bv_val[0] != '\'' ||
302 in->bv_val[in->bv_len-2] != '\'' ||
303 in->bv_val[in->bv_len-1] != 'B' )
305 return LDAP_INVALID_SYNTAX;
308 for( i=in->bv_len-3; i>0; i-- ) {
309 if( in->bv_val[i] != '0' && in->bv_val[i] != '1' ) {
310 return LDAP_INVALID_SYNTAX;
325 if( in->bv_len == 0 ) return LDAP_SUCCESS;
327 ber_dupbv( &dn, in );
328 if( !dn.bv_val ) return LDAP_OTHER;
330 if( dn.bv_val[dn.bv_len-1] == 'B'
331 && dn.bv_val[dn.bv_len-2] == '\'' )
333 /* assume presence of optional UID */
336 for(i=dn.bv_len-3; i>1; i--) {
337 if( dn.bv_val[i] != '0' && dn.bv_val[i] != '1' ) {
341 if( dn.bv_val[i] != '\'' || dn.bv_val[i-1] != '#' ) {
342 ber_memfree( dn.bv_val );
343 return LDAP_INVALID_SYNTAX;
346 /* trim the UID to allow use of dnValidate */
347 dn.bv_val[i-1] = '\0';
351 rc = dnValidate( NULL, &dn );
353 ber_memfree( dn.bv_val );
361 struct berval *normalized )
366 ber_dupbv( &out, val );
367 if( out.bv_len != 0 ) {
368 struct berval uid = { 0, NULL };
370 if( out.bv_val[out.bv_len-1] == 'B'
371 && out.bv_val[out.bv_len-2] == '\'' )
373 /* assume presence of optional UID */
374 uid.bv_val = strrchr( out.bv_val, '#' );
376 if( uid.bv_val == NULL ) {
378 return LDAP_INVALID_SYNTAX;
381 uid.bv_len = out.bv_len - (uid.bv_val - out.bv_val);
382 out.bv_len -= uid.bv_len--;
384 /* temporarily trim the UID */
385 *(uid.bv_val++) = '\0';
388 rc = dnNormalize2( NULL, &out, normalized );
390 if( rc != LDAP_SUCCESS ) {
392 return LDAP_INVALID_SYNTAX;
396 normalized->bv_val = ch_realloc( normalized->bv_val,
397 normalized->bv_len + uid.bv_len + sizeof("#") );
399 /* insert the separator */
400 normalized->bv_val[normalized->bv_len++] = '#';
403 AC_MEMCPY( &normalized->bv_val[normalized->bv_len],
404 uid.bv_val, uid.bv_len );
405 normalized->bv_len += uid.bv_len;
408 normalized->bv_val[normalized->bv_len] = '\0';
418 * Handling boolean syntax and matching is quite rigid.
419 * A more flexible approach would be to allow a variety
420 * of strings to be normalized and prettied into TRUE
428 /* very unforgiving validation, requires no normalization
429 * before simplistic matching
432 if( in->bv_len == 4 ) {
433 if( !memcmp( in->bv_val, "TRUE", 4 ) ) {
436 } else if( in->bv_len == 5 ) {
437 if( !memcmp( in->bv_val, "FALSE", 5 ) ) {
442 return LDAP_INVALID_SYNTAX;
451 struct berval *value,
452 void *assertedValue )
454 /* simplistic matching allowed by rigid validation */
455 struct berval *asserted = (struct berval *) assertedValue;
456 *matchp = value->bv_len != asserted->bv_len;
460 /*-------------------------------------------------------------------
461 LDAP/X.500 string syntax / matching rules have a few oddities. This
462 comment attempts to detail how slapd(8) treats them.
465 StringSyntax X.500 LDAP Matching
466 DirectoryString CHOICE UTF8 i/e + ignore insignificant spaces
467 PrintableString subset subset i/e + ignore insignificant spaces
468 NumericString subset subset ignore all spaces
469 IA5String ASCII ASCII i/e + ignore insignificant spaces
470 TeletexString T.61 T.61 i/e + ignore insignificant spaces
472 TelephoneNumber subset subset i + ignore all spaces and "-"
474 See draft-ietf-ldapbis-strpro for details (once published).
478 In X.500(93), a directory string can be either a PrintableString,
479 a bmpString, or a UniversalString (e.g., UCS (a subset of Unicode)).
480 In later versions, more CHOICEs were added. In all cases the string
483 In LDAPv3, a directory string is a UTF-8 encoded UCS string.
485 For matching, there are both case ignore and exact rules. Both
486 also require that "insignificant" spaces be ignored.
487 spaces before the first non-space are ignored;
488 spaces after the last non-space are ignored;
489 spaces after a space are ignored.
490 Note: by these rules (and as clarified in X.520), a string of only
491 spaces is to be treated as if held one space, not empty (which
492 would be a syntax error).
495 In ASN.1, numeric string is just a string of digits and spaces
496 and could be empty. However, in X.500, all attribute values of
497 numeric string carry a non-empty constraint. For example:
499 internationalISDNNumber ATTRIBUTE ::= {
500 WITH SYNTAX InternationalISDNNumber
501 EQUALITY MATCHING RULE numericStringMatch
502 SUBSTRINGS MATCHING RULE numericStringSubstringsMatch
503 ID id-at-internationalISDNNumber }
504 InternationalISDNNumber ::=
505 NumericString (SIZE(1..ub-international-isdn-number))
507 Unforunately, some assertion values are don't carry the same
508 constraint (but its unclear how such an assertion could ever
509 be true). In LDAP, there is one syntax (numericString) not two
510 (numericString with constraint, numericString without constraint).
511 This should be treated as numericString with non-empty constraint.
512 Note that while someone may have no ISDN number, there are no ISDN
513 numbers which are zero length.
515 In matching, spaces are ignored.
518 In ASN.1, Printable string is just a string of printable characters
519 and can be empty. In X.500, semantics much like NumericString (see
520 serialNumber for a like example) excepting uses insignificant space
521 handling instead of ignore all spaces.
524 Basically same as PrintableString. There are no examples in X.500,
525 but same logic applies. So we require them to be non-empty as
528 -------------------------------------------------------------------*/
537 unsigned char *u = in->bv_val;
539 if( !in->bv_len ) return LDAP_INVALID_SYNTAX;
541 for( count = in->bv_len; count > 0; count-=len, u+=len ) {
542 /* get the length indicated by the first byte */
543 len = LDAP_UTF8_CHARLEN2( u, len );
545 /* very basic checks */
548 if( (u[5] & 0xC0) != 0x80 ) {
549 return LDAP_INVALID_SYNTAX;
552 if( (u[4] & 0xC0) != 0x80 ) {
553 return LDAP_INVALID_SYNTAX;
556 if( (u[3] & 0xC0) != 0x80 ) {
557 return LDAP_INVALID_SYNTAX;
560 if( (u[2] & 0xC0 )!= 0x80 ) {
561 return LDAP_INVALID_SYNTAX;
564 if( (u[1] & 0xC0) != 0x80 ) {
565 return LDAP_INVALID_SYNTAX;
568 /* CHARLEN already validated it */
571 return LDAP_INVALID_SYNTAX;
574 /* make sure len corresponds with the offset
575 to the next character */
576 if( LDAP_UTF8_OFFSET( u ) != len ) return LDAP_INVALID_SYNTAX;
579 if( count != 0 ) return LDAP_INVALID_SYNTAX;
588 struct berval *normalized )
593 /* validator should have refused an empty string */
594 assert( val->bv_len );
598 /* Ignore initial whitespace */
599 /* All space is ASCII. All ASCII is 1 byte */
600 for ( ; p < val->bv_val + val->bv_len && ASCII_SPACE( p[ 0 ] ); p++ );
602 normalized->bv_len = val->bv_len - (p - val->bv_val);
604 if( !normalized->bv_len ) {
605 ber_mem2bv( " ", 1, 1, normalized );
609 ber_mem2bv( p, normalized->bv_len, 1, normalized );
610 e = normalized->bv_val + normalized->bv_len;
612 assert( normalized->bv_val );
614 p = q = normalized->bv_val;
619 if ( ASCII_SPACE( *p ) ) {
624 /* Ignore the extra whitespace */
625 while ( ASCII_SPACE( *p ) ) {
629 len = LDAP_UTF8_COPY(q,p);
635 assert( normalized->bv_val <= p );
636 assert( q+len <= p );
638 /* cannot start with a space */
639 assert( !ASCII_SPACE( normalized->bv_val[0] ) );
642 * If the string ended in space, backup the pointer one
643 * position. One is enough because the above loop collapsed
644 * all whitespace to a single space.
652 /* cannot end with a space */
653 assert( !ASCII_SPACE( *q ) );
660 normalized->bv_len = q - normalized->bv_val;
665 /* Returns Unicode canonically normalized copy of a substring assertion
666 * Skipping attribute description */
667 static SubstringsAssertion *
668 UTF8SubstringsassertionNormalize(
669 SubstringsAssertion *sa,
672 SubstringsAssertion *nsa;
675 nsa = (SubstringsAssertion *)SLAP_CALLOC( 1, sizeof(SubstringsAssertion) );
680 if( sa->sa_initial.bv_val != NULL ) {
681 UTF8bvnormalize( &sa->sa_initial, &nsa->sa_initial, casefold );
682 if( nsa->sa_initial.bv_val == NULL ) {
687 if( sa->sa_any != NULL ) {
688 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
691 nsa->sa_any = (struct berval *)
692 SLAP_MALLOC( (i + 1) * sizeof(struct berval) );
693 if( nsa->sa_any == NULL ) {
697 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
698 UTF8bvnormalize( &sa->sa_any[i], &nsa->sa_any[i],
700 if( nsa->sa_any[i].bv_val == NULL ) {
704 nsa->sa_any[i].bv_val = NULL;
707 if( sa->sa_final.bv_val != NULL ) {
708 UTF8bvnormalize( &sa->sa_final, &nsa->sa_final, casefold );
709 if( nsa->sa_final.bv_val == NULL ) {
717 if ( nsa->sa_final.bv_val ) free( nsa->sa_final.bv_val );
718 if ( nsa->sa_any ) ber_bvarray_free( nsa->sa_any );
719 if ( nsa->sa_initial.bv_val ) free( nsa->sa_initial.bv_val );
724 #ifndef SLAPD_APPROX_OLDSINGLESTRING
726 #if defined(SLAPD_APPROX_INITIALS)
727 #define SLAPD_APPROX_DELIMITER "._ "
728 #define SLAPD_APPROX_WORDLEN 2
730 #define SLAPD_APPROX_DELIMITER " "
731 #define SLAPD_APPROX_WORDLEN 1
740 struct berval *value,
741 void *assertedValue )
743 struct berval *nval, *assertv;
744 char *val, **values, **words, *c;
745 int i, count, len, nextchunk=0, nextavail=0;
747 /* Yes, this is necessary */
748 nval = UTF8bvnormalize( value, NULL, LDAP_UTF8_APPROX );
754 /* Yes, this is necessary */
755 assertv = UTF8bvnormalize( ((struct berval *)assertedValue),
756 NULL, LDAP_UTF8_APPROX );
757 if( assertv == NULL ) {
763 /* Isolate how many words there are */
764 for ( c = nval->bv_val, count = 1; *c; c++ ) {
765 c = strpbrk( c, SLAPD_APPROX_DELIMITER );
766 if ( c == NULL ) break;
771 /* Get a phonetic copy of each word */
772 words = (char **)ch_malloc( count * sizeof(char *) );
773 values = (char **)ch_malloc( count * sizeof(char *) );
774 for ( c = nval->bv_val, i = 0; i < count; i++, c += strlen(c) + 1 ) {
776 values[i] = phonetic(c);
779 /* Work through the asserted value's words, to see if at least some
780 of the words are there, in the same order. */
782 while ( (ber_len_t) nextchunk < assertv->bv_len ) {
783 len = strcspn( assertv->bv_val + nextchunk, SLAPD_APPROX_DELIMITER);
788 #if defined(SLAPD_APPROX_INITIALS)
789 else if( len == 1 ) {
790 /* Single letter words need to at least match one word's initial */
791 for( i=nextavail; i<count; i++ )
792 if( !strncasecmp( assertv->bv_val + nextchunk, words[i], 1 )) {
799 /* Isolate the next word in the asserted value and phonetic it */
800 assertv->bv_val[nextchunk+len] = '\0';
801 val = phonetic( assertv->bv_val + nextchunk );
803 /* See if this phonetic chunk is in the remaining words of *value */
804 for( i=nextavail; i<count; i++ ){
805 if( !strcmp( val, values[i] ) ){
813 /* This chunk in the asserted value was NOT within the *value. */
819 /* Go on to the next word in the asserted value */
823 /* If some of the words were seen, call it a match */
824 if( nextavail > 0 ) {
832 ber_bvfree( assertv );
833 for( i=0; i<count; i++ ) {
834 ch_free( values[i] );
849 struct berval *prefix,
854 int i,j, len, wordcount, keycount=0;
855 struct berval *newkeys;
858 for( j=0; values[j].bv_val != NULL; j++ ) {
859 struct berval val = { 0, NULL };
860 /* Yes, this is necessary */
861 UTF8bvnormalize( &values[j], &val, LDAP_UTF8_APPROX );
862 assert( val.bv_val != NULL );
864 /* Isolate how many words there are. There will be a key for each */
865 for( wordcount = 0, c = val.bv_val; *c; c++) {
866 len = strcspn(c, SLAPD_APPROX_DELIMITER);
867 if( len >= SLAPD_APPROX_WORDLEN ) wordcount++;
869 if (*c == '\0') break;
873 /* Allocate/increase storage to account for new keys */
874 newkeys = (struct berval *)ch_malloc( (keycount + wordcount + 1)
875 * sizeof(struct berval) );
876 AC_MEMCPY( newkeys, keys, keycount * sizeof(struct berval) );
877 if( keys ) ch_free( keys );
880 /* Get a phonetic copy of each word */
881 for( c = val.bv_val, i = 0; i < wordcount; c += len + 1 ) {
883 if( len < SLAPD_APPROX_WORDLEN ) continue;
884 ber_str2bv( phonetic( c ), 0, 0, &keys[keycount] );
889 ber_memfree( val.bv_val );
891 keys[keycount].bv_val = NULL;
903 struct berval *prefix,
904 void * assertedValue,
912 /* Yes, this is necessary */
913 val = UTF8bvnormalize( ((struct berval *)assertedValue),
914 NULL, LDAP_UTF8_APPROX );
915 if( val == NULL || val->bv_val == NULL ) {
916 keys = (struct berval *)ch_malloc( sizeof(struct berval) );
917 keys[0].bv_val = NULL;
923 /* Isolate how many words there are. There will be a key for each */
924 for( count = 0,c = val->bv_val; *c; c++) {
925 len = strcspn(c, SLAPD_APPROX_DELIMITER);
926 if( len >= SLAPD_APPROX_WORDLEN ) count++;
928 if (*c == '\0') break;
932 /* Allocate storage for new keys */
933 keys = (struct berval *)ch_malloc( (count + 1) * sizeof(struct berval) );
935 /* Get a phonetic copy of each word */
936 for( c = val->bv_val, i = 0; i < count; c += len + 1 ) {
938 if( len < SLAPD_APPROX_WORDLEN ) continue;
939 ber_str2bv( phonetic( c ), 0, 0, &keys[i] );
945 keys[count].bv_val = NULL;
953 /* No other form of Approximate Matching is defined */
961 struct berval *value,
962 void *assertedValue )
964 char *vapprox, *avapprox;
967 /* Yes, this is necessary */
968 s = UTF8normalize( value, UTF8_NOCASEFOLD );
974 /* Yes, this is necessary */
975 t = UTF8normalize( ((struct berval *)assertedValue),
983 vapprox = phonetic( strip8bitChars( s ) );
984 avapprox = phonetic( strip8bitChars( t ) );
989 *matchp = strcmp( vapprox, avapprox );
1003 struct berval *prefix,
1011 for( i=0; values[i].bv_val != NULL; i++ ) {
1012 /* empty - just count them */
1015 /* we should have at least one value at this point */
1018 keys = (struct berval *)ch_malloc( sizeof( struct berval ) * (i+1) );
1020 /* Copy each value and run it through phonetic() */
1021 for( i=0; values[i].bv_val != NULL; i++ ) {
1022 /* Yes, this is necessary */
1023 s = UTF8normalize( &values[i], UTF8_NOCASEFOLD );
1025 /* strip 8-bit chars and run through phonetic() */
1026 ber_str2bv( phonetic( strip8bitChars( s ) ), 0, 0, &keys[i] );
1029 keys[i].bv_val = NULL;
1032 return LDAP_SUCCESS;
1042 struct berval *prefix,
1043 void * assertedValue,
1049 keys = (struct berval *)ch_malloc( sizeof( struct berval * ) * 2 );
1051 /* Yes, this is necessary */
1052 s = UTF8normalize( ((struct berval *)assertedValue),
1057 /* strip 8-bit chars and run through phonetic() */
1058 keys[0] = ber_bvstr( phonetic( strip8bitChars( s ) ) );
1064 return LDAP_SUCCESS;
1075 struct berval *value,
1076 void *assertedValue )
1078 *matchp = UTF8bvnormcmp( value,
1079 (struct berval *) assertedValue,
1080 LDAP_UTF8_NOCASEFOLD );
1081 return LDAP_SUCCESS;
1085 caseExactIgnoreSubstringsMatch(
1090 struct berval *value,
1091 void *assertedValue )
1094 SubstringsAssertion *sub = NULL;
1095 struct berval left = { 0, NULL };
1101 casefold = ( mr != caseExactSubstringsMatchingRule )
1102 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1104 if ( UTF8bvnormalize( value, &left, casefold ) == NULL ) {
1110 sub = UTF8SubstringsassertionNormalize( assertedValue, casefold );
1116 /* Add up asserted input length */
1117 if( sub->sa_initial.bv_val ) {
1118 inlen += sub->sa_initial.bv_len;
1121 for(i=0; sub->sa_any[i].bv_val != NULL; i++) {
1122 inlen += sub->sa_any[i].bv_len;
1125 if( sub->sa_final.bv_val ) {
1126 inlen += sub->sa_final.bv_len;
1129 if( sub->sa_initial.bv_val ) {
1130 if( inlen > left.bv_len ) {
1135 match = memcmp( sub->sa_initial.bv_val, left.bv_val,
1136 sub->sa_initial.bv_len );
1142 left.bv_val += sub->sa_initial.bv_len;
1143 left.bv_len -= sub->sa_initial.bv_len;
1144 inlen -= sub->sa_initial.bv_len;
1147 if( sub->sa_final.bv_val ) {
1148 if( inlen > left.bv_len ) {
1153 match = memcmp( sub->sa_final.bv_val,
1154 &left.bv_val[left.bv_len - sub->sa_final.bv_len],
1155 sub->sa_final.bv_len );
1161 left.bv_len -= sub->sa_final.bv_len;
1162 inlen -= sub->sa_final.bv_len;
1166 for(i=0; sub->sa_any[i].bv_val; i++) {
1171 if( inlen > left.bv_len ) {
1172 /* not enough length */
1177 if( sub->sa_any[i].bv_len == 0 ) {
1181 p = ber_bvchr( &left, *sub->sa_any[i].bv_val );
1187 idx = p - left.bv_val;
1189 if( idx >= left.bv_len ) {
1190 /* this shouldn't happen */
1192 if ( sub->sa_final.bv_val )
1193 ch_free( sub->sa_final.bv_val );
1195 ber_bvarray_free( sub->sa_any );
1196 if ( sub->sa_initial.bv_val )
1197 ch_free( sub->sa_initial.bv_val );
1205 if( sub->sa_any[i].bv_len > left.bv_len ) {
1206 /* not enough left */
1211 match = memcmp( left.bv_val,
1212 sub->sa_any[i].bv_val,
1213 sub->sa_any[i].bv_len );
1221 left.bv_val += sub->sa_any[i].bv_len;
1222 left.bv_len -= sub->sa_any[i].bv_len;
1223 inlen -= sub->sa_any[i].bv_len;
1230 if ( sub->sa_final.bv_val ) free( sub->sa_final.bv_val );
1231 if ( sub->sa_any ) ber_bvarray_free( sub->sa_any );
1232 if ( sub->sa_initial.bv_val ) free( sub->sa_initial.bv_val );
1236 return LDAP_SUCCESS;
1239 /* Index generation function */
1240 static int caseExactIgnoreIndexer(
1245 struct berval *prefix,
1253 HASH_CONTEXT HASHcontext;
1254 unsigned char HASHdigest[HASH_BYTES];
1255 struct berval digest;
1256 digest.bv_val = HASHdigest;
1257 digest.bv_len = sizeof(HASHdigest);
1259 for( i=0; values[i].bv_val != NULL; i++ ) {
1260 /* empty - just count them */
1263 /* we should have at least one value at this point */
1266 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
1268 slen = syntax->ssyn_oidlen;
1269 mlen = mr->smr_oidlen;
1271 casefold = ( mr != caseExactMatchingRule )
1272 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1274 for( i=0; values[i].bv_val != NULL; i++ ) {
1275 struct berval value;
1276 UTF8bvnormalize( &values[i], &value, casefold );
1278 HASH_Init( &HASHcontext );
1279 if( prefix != NULL && prefix->bv_len > 0 ) {
1280 HASH_Update( &HASHcontext,
1281 prefix->bv_val, prefix->bv_len );
1283 HASH_Update( &HASHcontext,
1284 syntax->ssyn_oid, slen );
1285 HASH_Update( &HASHcontext,
1286 mr->smr_oid, mlen );
1287 HASH_Update( &HASHcontext,
1288 value.bv_val, value.bv_len );
1289 HASH_Final( HASHdigest, &HASHcontext );
1291 free( value.bv_val );
1293 ber_dupbv( &keys[i], &digest );
1296 keys[i].bv_val = NULL;
1298 return LDAP_SUCCESS;
1301 /* Index generation function */
1302 static int caseExactIgnoreFilter(
1307 struct berval *prefix,
1308 void * assertedValue,
1314 HASH_CONTEXT HASHcontext;
1315 unsigned char HASHdigest[HASH_BYTES];
1316 struct berval value = { 0, NULL };
1317 struct berval digest;
1319 digest.bv_val = HASHdigest;
1320 digest.bv_len = sizeof(HASHdigest);
1322 slen = syntax->ssyn_oidlen;
1323 mlen = mr->smr_oidlen;
1325 casefold = ( mr != caseExactMatchingRule )
1326 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1328 UTF8bvnormalize( (struct berval *) assertedValue, &value, casefold );
1329 /* This usually happens if filter contains bad UTF8 */
1330 if( value.bv_val == NULL ) {
1331 keys = ch_malloc( sizeof( struct berval ) );
1332 keys[0].bv_val = NULL;
1333 return LDAP_SUCCESS;
1336 keys = ch_malloc( sizeof( struct berval ) * 2 );
1338 HASH_Init( &HASHcontext );
1339 if( prefix != NULL && prefix->bv_len > 0 ) {
1340 HASH_Update( &HASHcontext,
1341 prefix->bv_val, prefix->bv_len );
1343 HASH_Update( &HASHcontext,
1344 syntax->ssyn_oid, slen );
1345 HASH_Update( &HASHcontext,
1346 mr->smr_oid, mlen );
1347 HASH_Update( &HASHcontext,
1348 value.bv_val, value.bv_len );
1349 HASH_Final( HASHdigest, &HASHcontext );
1351 ber_dupbv( keys, &digest );
1352 keys[1].bv_val = NULL;
1354 free( value.bv_val );
1357 return LDAP_SUCCESS;
1360 /* Substrings Index generation function */
1361 static int caseExactIgnoreSubstringsIndexer(
1366 struct berval *prefix,
1376 HASH_CONTEXT HASHcontext;
1377 unsigned char HASHdigest[HASH_BYTES];
1378 struct berval digest;
1379 digest.bv_val = HASHdigest;
1380 digest.bv_len = sizeof(HASHdigest);
1384 for( i=0; values[i].bv_val != NULL; i++ ) {
1385 /* empty - just count them */
1388 /* we should have at least one value at this point */
1391 casefold = ( mr != caseExactSubstringsMatchingRule )
1392 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1394 nvalues = ch_malloc( sizeof( struct berval ) * (i+1) );
1395 for( i=0; values[i].bv_val != NULL; i++ ) {
1396 UTF8bvnormalize( &values[i], &nvalues[i], casefold );
1398 nvalues[i].bv_val = NULL;
1401 for( i=0; values[i].bv_val != NULL; i++ ) {
1402 /* count number of indices to generate */
1403 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
1407 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
1408 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1409 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
1410 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
1412 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
1416 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
1417 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1418 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
1422 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
1423 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1424 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
1425 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
1427 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
1433 /* no keys to generate */
1435 ber_bvarray_free( nvalues );
1436 return LDAP_SUCCESS;
1439 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
1441 slen = syntax->ssyn_oidlen;
1442 mlen = mr->smr_oidlen;
1445 for( i=0; values[i].bv_val != NULL; i++ ) {
1448 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
1450 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
1451 ( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
1453 char pre = SLAP_INDEX_SUBSTR_PREFIX;
1454 max = values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
1456 for( j=0; j<max; j++ ) {
1457 HASH_Init( &HASHcontext );
1458 if( prefix != NULL && prefix->bv_len > 0 ) {
1459 HASH_Update( &HASHcontext,
1460 prefix->bv_val, prefix->bv_len );
1463 HASH_Update( &HASHcontext,
1464 &pre, sizeof( pre ) );
1465 HASH_Update( &HASHcontext,
1466 syntax->ssyn_oid, slen );
1467 HASH_Update( &HASHcontext,
1468 mr->smr_oid, mlen );
1469 HASH_Update( &HASHcontext,
1470 &values[i].bv_val[j],
1471 SLAP_INDEX_SUBSTR_MAXLEN );
1472 HASH_Final( HASHdigest, &HASHcontext );
1474 ber_dupbv( &keys[nkeys++], &digest );
1478 max = SLAP_INDEX_SUBSTR_MAXLEN < values[i].bv_len
1479 ? SLAP_INDEX_SUBSTR_MAXLEN : values[i].bv_len;
1481 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
1484 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
1485 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
1486 HASH_Init( &HASHcontext );
1487 if( prefix != NULL && prefix->bv_len > 0 ) {
1488 HASH_Update( &HASHcontext,
1489 prefix->bv_val, prefix->bv_len );
1491 HASH_Update( &HASHcontext,
1492 &pre, sizeof( pre ) );
1493 HASH_Update( &HASHcontext,
1494 syntax->ssyn_oid, slen );
1495 HASH_Update( &HASHcontext,
1496 mr->smr_oid, mlen );
1497 HASH_Update( &HASHcontext,
1498 values[i].bv_val, j );
1499 HASH_Final( HASHdigest, &HASHcontext );
1501 ber_dupbv( &keys[nkeys++], &digest );
1504 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
1505 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
1506 HASH_Init( &HASHcontext );
1507 if( prefix != NULL && prefix->bv_len > 0 ) {
1508 HASH_Update( &HASHcontext,
1509 prefix->bv_val, prefix->bv_len );
1511 HASH_Update( &HASHcontext,
1512 &pre, sizeof( pre ) );
1513 HASH_Update( &HASHcontext,
1514 syntax->ssyn_oid, slen );
1515 HASH_Update( &HASHcontext,
1516 mr->smr_oid, mlen );
1517 HASH_Update( &HASHcontext,
1518 &values[i].bv_val[values[i].bv_len-j], j );
1519 HASH_Final( HASHdigest, &HASHcontext );
1521 ber_dupbv( &keys[nkeys++], &digest );
1529 keys[nkeys].bv_val = NULL;
1536 ber_bvarray_free( nvalues );
1538 return LDAP_SUCCESS;
1541 static int caseExactIgnoreSubstringsFilter(
1546 struct berval *prefix,
1547 void * assertedValue,
1550 SubstringsAssertion *sa;
1553 ber_len_t nkeys = 0;
1554 size_t slen, mlen, klen;
1556 HASH_CONTEXT HASHcontext;
1557 unsigned char HASHdigest[HASH_BYTES];
1558 struct berval *value;
1559 struct berval digest;
1561 casefold = ( mr != caseExactSubstringsMatchingRule )
1562 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1564 sa = UTF8SubstringsassertionNormalize( assertedValue, casefold );
1567 return LDAP_SUCCESS;
1570 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
1571 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1576 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
1578 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
1579 if( sa->sa_any[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1580 /* don't bother accounting for stepping */
1581 nkeys += sa->sa_any[i].bv_len -
1582 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
1587 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
1588 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1594 if ( sa->sa_final.bv_val ) free( sa->sa_final.bv_val );
1595 if ( sa->sa_any ) ber_bvarray_free( sa->sa_any );
1596 if ( sa->sa_initial.bv_val ) free( sa->sa_initial.bv_val );
1599 return LDAP_SUCCESS;
1602 digest.bv_val = HASHdigest;
1603 digest.bv_len = sizeof(HASHdigest);
1605 slen = syntax->ssyn_oidlen;
1606 mlen = mr->smr_oidlen;
1608 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
1611 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
1612 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1614 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
1615 value = &sa->sa_initial;
1617 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
1618 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
1620 HASH_Init( &HASHcontext );
1621 if( prefix != NULL && prefix->bv_len > 0 ) {
1622 HASH_Update( &HASHcontext,
1623 prefix->bv_val, prefix->bv_len );
1625 HASH_Update( &HASHcontext,
1626 &pre, sizeof( pre ) );
1627 HASH_Update( &HASHcontext,
1628 syntax->ssyn_oid, slen );
1629 HASH_Update( &HASHcontext,
1630 mr->smr_oid, mlen );
1631 HASH_Update( &HASHcontext,
1632 value->bv_val, klen );
1633 HASH_Final( HASHdigest, &HASHcontext );
1635 ber_dupbv( &keys[nkeys++], &digest );
1638 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
1640 pre = SLAP_INDEX_SUBSTR_PREFIX;
1641 klen = SLAP_INDEX_SUBSTR_MAXLEN;
1643 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
1644 if( sa->sa_any[i].bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
1648 value = &sa->sa_any[i];
1651 j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
1652 j += SLAP_INDEX_SUBSTR_STEP )
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[j], klen );
1667 HASH_Final( HASHdigest, &HASHcontext );
1669 ber_dupbv( &keys[nkeys++], &digest );
1675 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
1676 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1678 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
1679 value = &sa->sa_final;
1681 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
1682 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
1684 HASH_Init( &HASHcontext );
1685 if( prefix != NULL && prefix->bv_len > 0 ) {
1686 HASH_Update( &HASHcontext,
1687 prefix->bv_val, prefix->bv_len );
1689 HASH_Update( &HASHcontext,
1690 &pre, sizeof( pre ) );
1691 HASH_Update( &HASHcontext,
1692 syntax->ssyn_oid, slen );
1693 HASH_Update( &HASHcontext,
1694 mr->smr_oid, mlen );
1695 HASH_Update( &HASHcontext,
1696 &value->bv_val[value->bv_len-klen], klen );
1697 HASH_Final( HASHdigest, &HASHcontext );
1699 ber_dupbv( &keys[nkeys++], &digest );
1703 keys[nkeys].bv_val = NULL;
1709 if ( sa->sa_final.bv_val ) free( sa->sa_final.bv_val );
1710 if ( sa->sa_any ) ber_bvarray_free( sa->sa_any );
1711 if ( sa->sa_initial.bv_val ) free( sa->sa_initial.bv_val );
1714 return LDAP_SUCCESS;
1723 struct berval *value,
1724 void *assertedValue )
1726 *matchp = UTF8bvnormcmp( value,
1727 (struct berval *) assertedValue,
1728 LDAP_UTF8_CASEFOLD );
1729 return LDAP_SUCCESS;
1732 /* Remove all spaces and '-' characters */
1734 telephoneNumberNormalize(
1737 struct berval *normalized )
1741 /* validator should have refused an empty string */
1742 assert( val->bv_len );
1744 q = normalized->bv_val = ch_malloc( val->bv_len + 1 );
1746 for( p = val->bv_val; *p; p++ ) {
1747 if ( ! ( ASCII_SPACE( *p ) || *p == '-' )) {
1753 normalized->bv_len = q - normalized->bv_val;
1755 if( normalized->bv_len == 0 ) {
1756 free( normalized->bv_val );
1757 return LDAP_INVALID_SYNTAX;
1760 return LDAP_SUCCESS;
1766 struct berval *val )
1770 if( val->bv_len == 0 ) {
1771 /* disallow empty strings */
1772 return LDAP_INVALID_SYNTAX;
1775 if( OID_LEADCHAR(val->bv_val[0]) ) {
1777 for(i=1; i < val->bv_len; i++) {
1778 if( OID_SEPARATOR( val->bv_val[i] ) ) {
1779 if( dot++ ) return 1;
1780 } else if ( OID_CHAR( val->bv_val[i] ) ) {
1783 return LDAP_INVALID_SYNTAX;
1787 return !dot ? LDAP_SUCCESS : LDAP_INVALID_SYNTAX;
1789 } else if( DESC_LEADCHAR(val->bv_val[0]) ) {
1790 for(i=1; i < val->bv_len; i++) {
1791 if( !DESC_CHAR(val->bv_val[i] ) ) {
1792 return LDAP_INVALID_SYNTAX;
1796 return LDAP_SUCCESS;
1799 return LDAP_INVALID_SYNTAX;
1808 struct berval *value,
1809 void *assertedValue )
1812 int vsign = 1, avsign = 1; /* default sign = '+' */
1813 struct berval *asserted;
1814 ber_len_t vlen, avlen;
1817 /* Skip leading space/sign/zeroes, and get the sign of the *value number */
1819 vlen = value->bv_len;
1820 if( mr == integerFirstComponentMatchingRule ) {
1821 char *tmp = memchr( v, '$', vlen );
1824 while( vlen && ASCII_SPACE( v[vlen-1] ))
1827 for( ; vlen && ( *v < '1' || '9' < *v ); v++, vlen-- ) /* ANSI 2.2.1 */
1833 /* Do the same with the *assertedValue number */
1834 asserted = (struct berval *) assertedValue;
1835 av = asserted->bv_val;
1836 avlen = asserted->bv_len;
1837 for( ; avlen && ( *av < '1' || '9' < *av ); av++, avlen-- )
1843 match = vsign - avsign;
1845 match = (vlen != avlen
1846 ? ( vlen < avlen ? -1 : 1 )
1847 : memcmp( v, av, vlen ));
1853 return LDAP_SUCCESS;
1859 struct berval *val )
1863 if( !val->bv_len ) return LDAP_INVALID_SYNTAX;
1865 if(( val->bv_val[0] == '+' ) || ( val->bv_val[0] == '-' )) {
1866 if( val->bv_len < 2 ) return LDAP_INVALID_SYNTAX;
1867 } else if( !ASCII_DIGIT(val->bv_val[0]) ) {
1868 return LDAP_INVALID_SYNTAX;
1871 for( i=1; i < val->bv_len; i++ ) {
1872 if( !ASCII_DIGIT(val->bv_val[i]) ) return LDAP_INVALID_SYNTAX;
1875 return LDAP_SUCCESS;
1882 struct berval *normalized )
1892 /* Ignore leading spaces */
1893 while ( len && ( *p == ' ' )) {
1900 negative = ( *p == '-' );
1901 if(( *p == '-' ) || ( *p == '+' )) {
1907 /* Ignore leading zeros */
1908 while ( len && ( *p == '0' )) {
1913 /* If there are no non-zero digits left, the number is zero, otherwise
1914 allocate space for the number and copy it into the buffer */
1916 normalized->bv_val = ch_strdup("0");
1917 normalized->bv_len = 1;
1920 normalized->bv_len = len+negative;
1921 normalized->bv_val = ch_malloc( normalized->bv_len + 1 );
1923 normalized->bv_val[0] = '-';
1925 AC_MEMCPY( normalized->bv_val + negative, p, len );
1926 normalized->bv_val[len+negative] = '\0';
1929 return LDAP_SUCCESS;
1932 /* Index generation function */
1933 static int integerIndexer(
1938 struct berval *prefix,
1945 HASH_CONTEXT HASHcontext;
1946 unsigned char HASHdigest[HASH_BYTES];
1947 struct berval digest;
1948 digest.bv_val = HASHdigest;
1949 digest.bv_len = sizeof(HASHdigest);
1951 for( i=0; values[i].bv_val != NULL; i++ ) {
1952 /* empty - just count them */
1955 /* we should have at least one value at this point */
1958 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
1960 slen = syntax->ssyn_oidlen;
1961 mlen = mr->smr_oidlen;
1963 for( i=0; values[i].bv_val != NULL; i++ ) {
1965 integerNormalize( syntax, &values[i], &norm );
1967 HASH_Init( &HASHcontext );
1968 if( prefix != NULL && prefix->bv_len > 0 ) {
1969 HASH_Update( &HASHcontext,
1970 prefix->bv_val, prefix->bv_len );
1972 HASH_Update( &HASHcontext,
1973 syntax->ssyn_oid, slen );
1974 HASH_Update( &HASHcontext,
1975 mr->smr_oid, mlen );
1976 HASH_Update( &HASHcontext,
1977 norm.bv_val, norm.bv_len );
1978 HASH_Final( HASHdigest, &HASHcontext );
1980 ber_dupbv( &keys[i], &digest );
1981 ch_free( norm.bv_val );
1984 keys[i].bv_val = NULL;
1986 return LDAP_SUCCESS;
1989 /* Index generation function */
1990 static int integerFilter(
1995 struct berval *prefix,
1996 void * assertedValue,
2001 HASH_CONTEXT HASHcontext;
2002 unsigned char HASHdigest[HASH_BYTES];
2004 struct berval digest;
2005 digest.bv_val = HASHdigest;
2006 digest.bv_len = sizeof(HASHdigest);
2008 slen = syntax->ssyn_oidlen;
2009 mlen = mr->smr_oidlen;
2011 integerNormalize( syntax, assertedValue, &norm );
2013 keys = ch_malloc( sizeof( struct berval ) * 2 );
2015 HASH_Init( &HASHcontext );
2016 if( prefix != NULL && prefix->bv_len > 0 ) {
2017 HASH_Update( &HASHcontext,
2018 prefix->bv_val, prefix->bv_len );
2020 HASH_Update( &HASHcontext,
2021 syntax->ssyn_oid, slen );
2022 HASH_Update( &HASHcontext,
2023 mr->smr_oid, mlen );
2024 HASH_Update( &HASHcontext,
2025 norm.bv_val, norm.bv_len );
2026 HASH_Final( HASHdigest, &HASHcontext );
2028 ber_dupbv( &keys[0], &digest );
2029 keys[1].bv_val = NULL;
2030 ch_free( norm.bv_val );
2033 return LDAP_SUCCESS;
2038 countryStringValidate(
2040 struct berval *val )
2042 if( val->bv_len != 2 ) return LDAP_INVALID_SYNTAX;
2044 if( !SLAP_PRINTABLE(val->bv_val[0]) ) {
2045 return LDAP_INVALID_SYNTAX;
2047 if( !SLAP_PRINTABLE(val->bv_val[1]) ) {
2048 return LDAP_INVALID_SYNTAX;
2051 return LDAP_SUCCESS;
2055 printableStringValidate(
2057 struct berval *val )
2061 if( val->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
2063 for(i=0; i < val->bv_len; i++) {
2064 if( !SLAP_PRINTABLE(val->bv_val[i]) ) {
2065 return LDAP_INVALID_SYNTAX;
2069 return LDAP_SUCCESS;
2073 printablesStringValidate(
2075 struct berval *val )
2079 if( val->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
2081 for(i=0,len=0; i < val->bv_len; i++) {
2082 int c = val->bv_val[i];
2086 return LDAP_INVALID_SYNTAX;
2090 } else if ( SLAP_PRINTABLE(c) ) {
2093 return LDAP_INVALID_SYNTAX;
2098 return LDAP_INVALID_SYNTAX;
2101 return LDAP_SUCCESS;
2107 struct berval *val )
2111 if( val->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
2113 for(i=0; i < val->bv_len; i++) {
2114 if( !LDAP_ASCII(val->bv_val[i]) ) {
2115 return LDAP_INVALID_SYNTAX;
2119 return LDAP_SUCCESS;
2126 struct berval *normalized )
2130 assert( val->bv_len );
2134 /* Ignore initial whitespace */
2135 while ( ASCII_SPACE( *p ) ) {
2139 normalized->bv_val = ch_strdup( p );
2140 p = q = normalized->bv_val;
2143 if ( ASCII_SPACE( *p ) ) {
2146 /* Ignore the extra whitespace */
2147 while ( ASCII_SPACE( *p ) ) {
2155 assert( normalized->bv_val <= p );
2159 * If the string ended in space, backup the pointer one
2160 * position. One is enough because the above loop collapsed
2161 * all whitespace to a single space.
2164 if ( ASCII_SPACE( q[-1] ) ) {
2168 /* null terminate */
2171 normalized->bv_len = q - normalized->bv_val;
2173 if( normalized->bv_len == 0 ) {
2174 normalized->bv_val = ch_realloc( normalized->bv_val, 2 );
2175 normalized->bv_val[0] = ' ';
2176 normalized->bv_val[1] = '\0';
2177 normalized->bv_len = 1;
2180 return LDAP_SUCCESS;
2189 struct berval *value,
2190 void *assertedValue )
2192 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
2195 match = strncmp( value->bv_val,
2196 ((struct berval *) assertedValue)->bv_val,
2201 return LDAP_SUCCESS;
2205 caseExactIA5SubstringsMatch(
2210 struct berval *value,
2211 void *assertedValue )
2214 SubstringsAssertion *sub = assertedValue;
2215 struct berval left = *value;
2219 /* Add up asserted input length */
2220 if( sub->sa_initial.bv_val ) {
2221 inlen += sub->sa_initial.bv_len;
2224 for(i=0; sub->sa_any[i].bv_val != NULL; i++) {
2225 inlen += sub->sa_any[i].bv_len;
2228 if( sub->sa_final.bv_val ) {
2229 inlen += sub->sa_final.bv_len;
2232 if( sub->sa_initial.bv_val ) {
2233 if( inlen > left.bv_len ) {
2238 match = strncmp( sub->sa_initial.bv_val, left.bv_val,
2239 sub->sa_initial.bv_len );
2245 left.bv_val += sub->sa_initial.bv_len;
2246 left.bv_len -= sub->sa_initial.bv_len;
2247 inlen -= sub->sa_initial.bv_len;
2250 if( sub->sa_final.bv_val ) {
2251 if( inlen > left.bv_len ) {
2256 match = strncmp( sub->sa_final.bv_val,
2257 &left.bv_val[left.bv_len - sub->sa_final.bv_len],
2258 sub->sa_final.bv_len );
2264 left.bv_len -= sub->sa_final.bv_len;
2265 inlen -= sub->sa_final.bv_len;
2269 for(i=0; sub->sa_any[i].bv_val; i++) {
2274 if( inlen > left.bv_len ) {
2275 /* not enough length */
2280 if( sub->sa_any[i].bv_len == 0 ) {
2284 p = strchr( left.bv_val, *sub->sa_any[i].bv_val );
2291 idx = p - left.bv_val;
2293 if( idx >= left.bv_len ) {
2294 /* this shouldn't happen */
2301 if( sub->sa_any[i].bv_len > left.bv_len ) {
2302 /* not enough left */
2307 match = strncmp( left.bv_val,
2308 sub->sa_any[i].bv_val,
2309 sub->sa_any[i].bv_len );
2317 left.bv_val += sub->sa_any[i].bv_len;
2318 left.bv_len -= sub->sa_any[i].bv_len;
2319 inlen -= sub->sa_any[i].bv_len;
2325 return LDAP_SUCCESS;
2328 /* Index generation function */
2329 static int caseExactIA5Indexer(
2334 struct berval *prefix,
2341 HASH_CONTEXT HASHcontext;
2342 unsigned char HASHdigest[HASH_BYTES];
2343 struct berval digest;
2344 digest.bv_val = HASHdigest;
2345 digest.bv_len = sizeof(HASHdigest);
2347 for( i=0; values[i].bv_val != NULL; i++ ) {
2348 /* empty - just count them */
2351 /* we should have at least one value at this point */
2354 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
2356 slen = syntax->ssyn_oidlen;
2357 mlen = mr->smr_oidlen;
2359 for( i=0; values[i].bv_val != NULL; i++ ) {
2360 struct berval *value = &values[i];
2362 HASH_Init( &HASHcontext );
2363 if( prefix != NULL && prefix->bv_len > 0 ) {
2364 HASH_Update( &HASHcontext,
2365 prefix->bv_val, prefix->bv_len );
2367 HASH_Update( &HASHcontext,
2368 syntax->ssyn_oid, slen );
2369 HASH_Update( &HASHcontext,
2370 mr->smr_oid, mlen );
2371 HASH_Update( &HASHcontext,
2372 value->bv_val, value->bv_len );
2373 HASH_Final( HASHdigest, &HASHcontext );
2375 ber_dupbv( &keys[i], &digest );
2378 keys[i].bv_val = NULL;
2380 return LDAP_SUCCESS;
2383 /* Index generation function */
2384 static int caseExactIA5Filter(
2389 struct berval *prefix,
2390 void * assertedValue,
2395 HASH_CONTEXT HASHcontext;
2396 unsigned char HASHdigest[HASH_BYTES];
2397 struct berval *value;
2398 struct berval digest;
2399 digest.bv_val = HASHdigest;
2400 digest.bv_len = sizeof(HASHdigest);
2402 slen = syntax->ssyn_oidlen;
2403 mlen = mr->smr_oidlen;
2405 value = (struct berval *) assertedValue;
2407 keys = ch_malloc( sizeof( struct berval ) * 2 );
2409 HASH_Init( &HASHcontext );
2410 if( prefix != NULL && prefix->bv_len > 0 ) {
2411 HASH_Update( &HASHcontext,
2412 prefix->bv_val, prefix->bv_len );
2414 HASH_Update( &HASHcontext,
2415 syntax->ssyn_oid, slen );
2416 HASH_Update( &HASHcontext,
2417 mr->smr_oid, mlen );
2418 HASH_Update( &HASHcontext,
2419 value->bv_val, value->bv_len );
2420 HASH_Final( HASHdigest, &HASHcontext );
2422 ber_dupbv( &keys[0], &digest );
2423 keys[1].bv_val = NULL;
2426 return LDAP_SUCCESS;
2429 /* Substrings Index generation function */
2430 static int caseExactIA5SubstringsIndexer(
2435 struct berval *prefix,
2442 HASH_CONTEXT HASHcontext;
2443 unsigned char HASHdigest[HASH_BYTES];
2444 struct berval digest;
2445 digest.bv_val = HASHdigest;
2446 digest.bv_len = sizeof(HASHdigest);
2448 /* we should have at least one value at this point */
2449 assert( values != NULL && values[0].bv_val != NULL );
2452 for( i=0; values[i].bv_val != NULL; i++ ) {
2453 /* count number of indices to generate */
2454 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
2458 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
2459 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2460 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2461 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2463 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2467 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
2468 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2469 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
2473 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
2474 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2475 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2476 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2478 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2484 /* no keys to generate */
2486 return LDAP_SUCCESS;
2489 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
2491 slen = syntax->ssyn_oidlen;
2492 mlen = mr->smr_oidlen;
2495 for( i=0; values[i].bv_val != NULL; i++ ) {
2497 struct berval *value;
2500 if( value->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
2502 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
2503 ( value->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
2505 char pre = SLAP_INDEX_SUBSTR_PREFIX;
2506 max = value->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
2508 for( j=0; j<max; j++ ) {
2509 HASH_Init( &HASHcontext );
2510 if( prefix != NULL && prefix->bv_len > 0 ) {
2511 HASH_Update( &HASHcontext,
2512 prefix->bv_val, prefix->bv_len );
2515 HASH_Update( &HASHcontext,
2516 &pre, sizeof( pre ) );
2517 HASH_Update( &HASHcontext,
2518 syntax->ssyn_oid, slen );
2519 HASH_Update( &HASHcontext,
2520 mr->smr_oid, mlen );
2521 HASH_Update( &HASHcontext,
2523 SLAP_INDEX_SUBSTR_MAXLEN );
2524 HASH_Final( HASHdigest, &HASHcontext );
2526 ber_dupbv( &keys[nkeys++], &digest );
2530 max = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2531 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2533 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
2536 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
2537 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
2538 HASH_Init( &HASHcontext );
2539 if( prefix != NULL && prefix->bv_len > 0 ) {
2540 HASH_Update( &HASHcontext,
2541 prefix->bv_val, prefix->bv_len );
2543 HASH_Update( &HASHcontext,
2544 &pre, sizeof( pre ) );
2545 HASH_Update( &HASHcontext,
2546 syntax->ssyn_oid, slen );
2547 HASH_Update( &HASHcontext,
2548 mr->smr_oid, mlen );
2549 HASH_Update( &HASHcontext,
2551 HASH_Final( HASHdigest, &HASHcontext );
2553 ber_dupbv( &keys[nkeys++], &digest );
2556 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
2557 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
2558 HASH_Init( &HASHcontext );
2559 if( prefix != NULL && prefix->bv_len > 0 ) {
2560 HASH_Update( &HASHcontext,
2561 prefix->bv_val, prefix->bv_len );
2563 HASH_Update( &HASHcontext,
2564 &pre, sizeof( pre ) );
2565 HASH_Update( &HASHcontext,
2566 syntax->ssyn_oid, slen );
2567 HASH_Update( &HASHcontext,
2568 mr->smr_oid, mlen );
2569 HASH_Update( &HASHcontext,
2570 &value->bv_val[value->bv_len-j], j );
2571 HASH_Final( HASHdigest, &HASHcontext );
2573 ber_dupbv( &keys[nkeys++], &digest );
2580 keys[nkeys].bv_val = NULL;
2587 return LDAP_SUCCESS;
2590 static int caseExactIA5SubstringsFilter(
2595 struct berval *prefix,
2596 void * assertedValue,
2599 SubstringsAssertion *sa = assertedValue;
2601 ber_len_t nkeys = 0;
2602 size_t slen, mlen, klen;
2604 HASH_CONTEXT HASHcontext;
2605 unsigned char HASHdigest[HASH_BYTES];
2606 struct berval *value;
2607 struct berval digest;
2609 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
2610 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2615 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
2617 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
2618 if( sa->sa_any[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2619 /* don't bother accounting for stepping */
2620 nkeys += sa->sa_any[i].bv_len -
2621 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
2626 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
2627 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2634 return LDAP_SUCCESS;
2637 digest.bv_val = HASHdigest;
2638 digest.bv_len = sizeof(HASHdigest);
2640 slen = syntax->ssyn_oidlen;
2641 mlen = mr->smr_oidlen;
2643 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
2646 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
2647 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2649 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
2650 value = &sa->sa_initial;
2652 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2653 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2655 HASH_Init( &HASHcontext );
2656 if( prefix != NULL && prefix->bv_len > 0 ) {
2657 HASH_Update( &HASHcontext,
2658 prefix->bv_val, prefix->bv_len );
2660 HASH_Update( &HASHcontext,
2661 &pre, sizeof( pre ) );
2662 HASH_Update( &HASHcontext,
2663 syntax->ssyn_oid, slen );
2664 HASH_Update( &HASHcontext,
2665 mr->smr_oid, mlen );
2666 HASH_Update( &HASHcontext,
2667 value->bv_val, klen );
2668 HASH_Final( HASHdigest, &HASHcontext );
2670 ber_dupbv( &keys[nkeys++], &digest );
2673 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
2675 pre = SLAP_INDEX_SUBSTR_PREFIX;
2676 klen = SLAP_INDEX_SUBSTR_MAXLEN;
2678 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
2679 if( sa->sa_any[i].bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
2683 value = &sa->sa_any[i];
2686 j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
2687 j += SLAP_INDEX_SUBSTR_STEP )
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[j], klen );
2702 HASH_Final( HASHdigest, &HASHcontext );
2704 ber_dupbv( &keys[nkeys++], &digest );
2709 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
2710 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2712 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
2713 value = &sa->sa_final;
2715 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2716 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2718 HASH_Init( &HASHcontext );
2719 if( prefix != NULL && prefix->bv_len > 0 ) {
2720 HASH_Update( &HASHcontext,
2721 prefix->bv_val, prefix->bv_len );
2723 HASH_Update( &HASHcontext,
2724 &pre, sizeof( pre ) );
2725 HASH_Update( &HASHcontext,
2726 syntax->ssyn_oid, slen );
2727 HASH_Update( &HASHcontext,
2728 mr->smr_oid, mlen );
2729 HASH_Update( &HASHcontext,
2730 &value->bv_val[value->bv_len-klen], klen );
2731 HASH_Final( HASHdigest, &HASHcontext );
2733 ber_dupbv( &keys[nkeys++], &digest );
2737 keys[nkeys].bv_val = NULL;
2744 return LDAP_SUCCESS;
2753 struct berval *value,
2754 void *assertedValue )
2756 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
2758 if( match == 0 && value->bv_len ) {
2759 match = strncasecmp( value->bv_val,
2760 ((struct berval *) assertedValue)->bv_val,
2765 return LDAP_SUCCESS;
2769 caseIgnoreIA5SubstringsMatch(
2774 struct berval *value,
2775 void *assertedValue )
2778 SubstringsAssertion *sub = assertedValue;
2779 struct berval left = *value;
2783 /* Add up asserted input length */
2784 if( sub->sa_initial.bv_val ) {
2785 inlen += sub->sa_initial.bv_len;
2788 for(i=0; sub->sa_any[i].bv_val != NULL; i++) {
2789 inlen += sub->sa_any[i].bv_len;
2792 if( sub->sa_final.bv_val ) {
2793 inlen += sub->sa_final.bv_len;
2796 if( sub->sa_initial.bv_val ) {
2797 if( inlen > left.bv_len ) {
2802 match = strncasecmp( sub->sa_initial.bv_val, left.bv_val,
2803 sub->sa_initial.bv_len );
2809 left.bv_val += sub->sa_initial.bv_len;
2810 left.bv_len -= sub->sa_initial.bv_len;
2811 inlen -= sub->sa_initial.bv_len;
2814 if( sub->sa_final.bv_val ) {
2815 if( inlen > left.bv_len ) {
2820 match = strncasecmp( sub->sa_final.bv_val,
2821 &left.bv_val[left.bv_len - sub->sa_final.bv_len],
2822 sub->sa_final.bv_len );
2828 left.bv_len -= sub->sa_final.bv_len;
2829 inlen -= sub->sa_final.bv_len;
2833 for(i=0; sub->sa_any[i].bv_val; i++) {
2838 if( inlen > left.bv_len ) {
2839 /* not enough length */
2844 if( sub->sa_any[i].bv_len == 0 ) {
2848 p = bvcasechr( &left, *sub->sa_any[i].bv_val, &idx );
2855 assert( idx < left.bv_len );
2856 if( idx >= left.bv_len ) {
2857 /* this shouldn't happen */
2864 if( sub->sa_any[i].bv_len > left.bv_len ) {
2865 /* not enough left */
2870 match = strncasecmp( left.bv_val,
2871 sub->sa_any[i].bv_val,
2872 sub->sa_any[i].bv_len );
2881 left.bv_val += sub->sa_any[i].bv_len;
2882 left.bv_len -= sub->sa_any[i].bv_len;
2883 inlen -= sub->sa_any[i].bv_len;
2889 return LDAP_SUCCESS;
2892 /* Index generation function */
2893 static int caseIgnoreIA5Indexer(
2898 struct berval *prefix,
2903 int rc = LDAP_SUCCESS;
2906 HASH_CONTEXT HASHcontext;
2907 unsigned char HASHdigest[HASH_BYTES];
2908 struct berval digest;
2909 digest.bv_val = HASHdigest;
2910 digest.bv_len = sizeof(HASHdigest);
2912 /* we should have at least one value at this point */
2913 assert( values != NULL && values[0].bv_val != NULL );
2915 for( i=0; values[i].bv_val != NULL; i++ ) {
2916 /* just count them */
2919 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
2921 slen = syntax->ssyn_oidlen;
2922 mlen = mr->smr_oidlen;
2924 for( i=0; values[i].bv_val != NULL; i++ ) {
2925 struct berval value;
2927 if( mr->smr_normalize ) {
2928 rc = (mr->smr_normalize)( use, syntax, mr, &values[i], &value );
2929 if( rc != LDAP_SUCCESS ) {
2932 } else if ( mr->smr_syntax->ssyn_normalize ) {
2933 rc = (mr->smr_syntax->ssyn_normalize)( syntax, &values[i], &value );
2934 if( rc != LDAP_SUCCESS ) {
2938 ber_dupbv( &value, &values[i] );
2941 ldap_pvt_str2lower( value.bv_val );
2943 HASH_Init( &HASHcontext );
2944 if( prefix != NULL && prefix->bv_len > 0 ) {
2945 HASH_Update( &HASHcontext,
2946 prefix->bv_val, prefix->bv_len );
2948 HASH_Update( &HASHcontext,
2949 syntax->ssyn_oid, slen );
2950 HASH_Update( &HASHcontext,
2951 mr->smr_oid, mlen );
2952 HASH_Update( &HASHcontext,
2953 value.bv_val, value.bv_len );
2954 HASH_Final( HASHdigest, &HASHcontext );
2956 free( value.bv_val );
2958 ber_dupbv( &keys[i], &digest );
2961 keys[i].bv_val = NULL;
2962 if( rc != LDAP_SUCCESS ) {
2963 ber_bvarray_free( keys );
2970 /* Index generation function */
2971 static int caseIgnoreIA5Filter(
2976 struct berval *prefix,
2977 void * assertedValue,
2982 HASH_CONTEXT HASHcontext;
2983 unsigned char HASHdigest[HASH_BYTES];
2984 struct berval value;
2985 struct berval digest;
2986 digest.bv_val = HASHdigest;
2987 digest.bv_len = sizeof(HASHdigest);
2989 slen = syntax->ssyn_oidlen;
2990 mlen = mr->smr_oidlen;
2992 ber_dupbv( &value, (struct berval *) assertedValue );
2993 ldap_pvt_str2lower( value.bv_val );
2995 keys = ch_malloc( sizeof( struct berval ) * 2 );
2997 HASH_Init( &HASHcontext );
2998 if( prefix != NULL && prefix->bv_len > 0 ) {
2999 HASH_Update( &HASHcontext,
3000 prefix->bv_val, prefix->bv_len );
3002 HASH_Update( &HASHcontext,
3003 syntax->ssyn_oid, slen );
3004 HASH_Update( &HASHcontext,
3005 mr->smr_oid, mlen );
3006 HASH_Update( &HASHcontext,
3007 value.bv_val, value.bv_len );
3008 HASH_Final( HASHdigest, &HASHcontext );
3010 ber_dupbv( &keys[0], &digest );
3011 keys[1].bv_val = NULL;
3013 free( value.bv_val );
3017 return LDAP_SUCCESS;
3020 /* Substrings Index generation function */
3021 static int caseIgnoreIA5SubstringsIndexer(
3026 struct berval *prefix,
3033 HASH_CONTEXT HASHcontext;
3034 unsigned char HASHdigest[HASH_BYTES];
3035 struct berval digest;
3036 digest.bv_val = HASHdigest;
3037 digest.bv_len = sizeof(HASHdigest);
3039 /* we should have at least one value at this point */
3040 assert( values != NULL && values[0].bv_val != NULL );
3043 for( i=0; values[i].bv_val != NULL; i++ ) {
3044 /* count number of indices to generate */
3045 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
3049 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
3050 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3051 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
3052 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
3054 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
3058 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
3059 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3060 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
3064 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
3065 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3066 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
3067 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
3069 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
3075 /* no keys to generate */
3077 return LDAP_SUCCESS;
3080 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
3082 slen = syntax->ssyn_oidlen;
3083 mlen = mr->smr_oidlen;
3086 for( i=0; values[i].bv_val != NULL; i++ ) {
3088 struct berval value;
3090 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
3092 ber_dupbv( &value, &values[i] );
3093 ldap_pvt_str2lower( value.bv_val );
3095 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
3096 ( value.bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
3098 char pre = SLAP_INDEX_SUBSTR_PREFIX;
3099 max = value.bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
3101 for( j=0; j<max; j++ ) {
3102 HASH_Init( &HASHcontext );
3103 if( prefix != NULL && prefix->bv_len > 0 ) {
3104 HASH_Update( &HASHcontext,
3105 prefix->bv_val, prefix->bv_len );
3108 HASH_Update( &HASHcontext,
3109 &pre, sizeof( pre ) );
3110 HASH_Update( &HASHcontext,
3111 syntax->ssyn_oid, slen );
3112 HASH_Update( &HASHcontext,
3113 mr->smr_oid, mlen );
3114 HASH_Update( &HASHcontext,
3116 SLAP_INDEX_SUBSTR_MAXLEN );
3117 HASH_Final( HASHdigest, &HASHcontext );
3119 ber_dupbv( &keys[nkeys++], &digest );
3123 max = SLAP_INDEX_SUBSTR_MAXLEN < value.bv_len
3124 ? SLAP_INDEX_SUBSTR_MAXLEN : value.bv_len;
3126 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
3129 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
3130 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
3131 HASH_Init( &HASHcontext );
3132 if( prefix != NULL && prefix->bv_len > 0 ) {
3133 HASH_Update( &HASHcontext,
3134 prefix->bv_val, prefix->bv_len );
3136 HASH_Update( &HASHcontext,
3137 &pre, sizeof( pre ) );
3138 HASH_Update( &HASHcontext,
3139 syntax->ssyn_oid, slen );
3140 HASH_Update( &HASHcontext,
3141 mr->smr_oid, mlen );
3142 HASH_Update( &HASHcontext,
3144 HASH_Final( HASHdigest, &HASHcontext );
3146 ber_dupbv( &keys[nkeys++], &digest );
3149 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
3150 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
3151 HASH_Init( &HASHcontext );
3152 if( prefix != NULL && prefix->bv_len > 0 ) {
3153 HASH_Update( &HASHcontext,
3154 prefix->bv_val, prefix->bv_len );
3156 HASH_Update( &HASHcontext,
3157 &pre, sizeof( pre ) );
3158 HASH_Update( &HASHcontext,
3159 syntax->ssyn_oid, slen );
3160 HASH_Update( &HASHcontext,
3161 mr->smr_oid, mlen );
3162 HASH_Update( &HASHcontext,
3163 &value.bv_val[value.bv_len-j], j );
3164 HASH_Final( HASHdigest, &HASHcontext );
3166 ber_dupbv( &keys[nkeys++], &digest );
3171 free( value.bv_val );
3175 keys[nkeys].bv_val = NULL;
3182 return LDAP_SUCCESS;
3185 static int caseIgnoreIA5SubstringsFilter(
3190 struct berval *prefix,
3191 void * assertedValue,
3194 SubstringsAssertion *sa = assertedValue;
3196 ber_len_t nkeys = 0;
3197 size_t slen, mlen, klen;
3199 HASH_CONTEXT HASHcontext;
3200 unsigned char HASHdigest[HASH_BYTES];
3201 struct berval value;
3202 struct berval digest;
3204 if((flags & SLAP_INDEX_SUBSTR_INITIAL) && sa->sa_initial.bv_val != NULL &&
3205 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3210 if((flags & SLAP_INDEX_SUBSTR_ANY) && sa->sa_any != NULL ) {
3212 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
3213 if( sa->sa_any[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3214 /* don't bother accounting for stepping */
3215 nkeys += sa->sa_any[i].bv_len -
3216 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
3221 if((flags & SLAP_INDEX_SUBSTR_FINAL) && sa->sa_final.bv_val != NULL &&
3222 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3229 return LDAP_SUCCESS;
3232 digest.bv_val = HASHdigest;
3233 digest.bv_len = sizeof(HASHdigest);
3235 slen = syntax->ssyn_oidlen;
3236 mlen = mr->smr_oidlen;
3238 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
3241 if((flags & SLAP_INDEX_SUBSTR_INITIAL) && sa->sa_initial.bv_val != NULL &&
3242 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3244 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
3245 ber_dupbv( &value, &sa->sa_initial );
3246 ldap_pvt_str2lower( value.bv_val );
3248 klen = SLAP_INDEX_SUBSTR_MAXLEN < value.bv_len
3249 ? SLAP_INDEX_SUBSTR_MAXLEN : value.bv_len;
3251 HASH_Init( &HASHcontext );
3252 if( prefix != NULL && prefix->bv_len > 0 ) {
3253 HASH_Update( &HASHcontext,
3254 prefix->bv_val, prefix->bv_len );
3256 HASH_Update( &HASHcontext,
3257 &pre, sizeof( pre ) );
3258 HASH_Update( &HASHcontext,
3259 syntax->ssyn_oid, slen );
3260 HASH_Update( &HASHcontext,
3261 mr->smr_oid, mlen );
3262 HASH_Update( &HASHcontext,
3263 value.bv_val, klen );
3264 HASH_Final( HASHdigest, &HASHcontext );
3266 free( value.bv_val );
3267 ber_dupbv( &keys[nkeys++], &digest );
3270 if((flags & SLAP_INDEX_SUBSTR_ANY) && sa->sa_any != NULL ) {
3272 pre = SLAP_INDEX_SUBSTR_PREFIX;
3273 klen = SLAP_INDEX_SUBSTR_MAXLEN;
3275 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
3276 if( sa->sa_any[i].bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
3280 ber_dupbv( &value, &sa->sa_any[i] );
3281 ldap_pvt_str2lower( value.bv_val );
3284 j <= value.bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
3285 j += SLAP_INDEX_SUBSTR_STEP )
3287 HASH_Init( &HASHcontext );
3288 if( prefix != NULL && prefix->bv_len > 0 ) {
3289 HASH_Update( &HASHcontext,
3290 prefix->bv_val, prefix->bv_len );
3292 HASH_Update( &HASHcontext,
3293 &pre, sizeof( pre ) );
3294 HASH_Update( &HASHcontext,
3295 syntax->ssyn_oid, slen );
3296 HASH_Update( &HASHcontext,
3297 mr->smr_oid, mlen );
3298 HASH_Update( &HASHcontext,
3299 &value.bv_val[j], klen );
3300 HASH_Final( HASHdigest, &HASHcontext );
3302 ber_dupbv( &keys[nkeys++], &digest );
3305 free( value.bv_val );
3309 if((flags & SLAP_INDEX_SUBSTR_FINAL) && sa->sa_final.bv_val != NULL &&
3310 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3312 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
3313 ber_dupbv( &value, &sa->sa_final );
3314 ldap_pvt_str2lower( value.bv_val );
3316 klen = SLAP_INDEX_SUBSTR_MAXLEN < value.bv_len
3317 ? SLAP_INDEX_SUBSTR_MAXLEN : value.bv_len;
3319 HASH_Init( &HASHcontext );
3320 if( prefix != NULL && prefix->bv_len > 0 ) {
3321 HASH_Update( &HASHcontext,
3322 prefix->bv_val, prefix->bv_len );
3324 HASH_Update( &HASHcontext,
3325 &pre, sizeof( pre ) );
3326 HASH_Update( &HASHcontext,
3327 syntax->ssyn_oid, slen );
3328 HASH_Update( &HASHcontext,
3329 mr->smr_oid, mlen );
3330 HASH_Update( &HASHcontext,
3331 &value.bv_val[value.bv_len-klen], klen );
3332 HASH_Final( HASHdigest, &HASHcontext );
3334 free( value.bv_val );
3335 ber_dupbv( &keys[nkeys++], &digest );
3339 keys[nkeys].bv_val = NULL;
3346 return LDAP_SUCCESS;
3350 numericStringValidate(
3356 if( in->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
3358 for(i=0; i < in->bv_len; i++) {
3359 if( !SLAP_NUMERIC(in->bv_val[i]) ) {
3360 return LDAP_INVALID_SYNTAX;
3364 return LDAP_SUCCESS;
3368 numericStringNormalize(
3371 struct berval *normalized )
3373 /* removal all spaces */
3376 assert( val->bv_len );
3378 normalized->bv_val = ch_malloc( val->bv_len + 1 );
3381 q = normalized->bv_val;
3384 if ( ASCII_SPACE( *p ) ) {
3385 /* Ignore whitespace */
3392 /* we should have copied no more then is in val */
3393 assert( (q - normalized->bv_val) <= (p - val->bv_val) );
3395 /* null terminate */
3398 normalized->bv_len = q - normalized->bv_val;
3400 if( normalized->bv_len == 0 ) {
3401 normalized->bv_val = ch_realloc( normalized->bv_val, 2 );
3402 normalized->bv_val[0] = ' ';
3403 normalized->bv_val[1] = '\0';
3404 normalized->bv_len = 1;
3407 return LDAP_SUCCESS;
3411 objectIdentifierFirstComponentMatch(
3416 struct berval *value,
3417 void *assertedValue )
3419 int rc = LDAP_SUCCESS;
3421 struct berval *asserted = (struct berval *) assertedValue;
3425 if( value->bv_len == 0 || value->bv_val[0] != '(' /*')'*/ ) {
3426 return LDAP_INVALID_SYNTAX;
3429 /* trim leading white space */
3430 for( i=1; ASCII_SPACE(value->bv_val[i]) && i < value->bv_len; i++ ) {
3434 /* grab next word */
3435 oid.bv_val = &value->bv_val[i];
3436 j = value->bv_len - i;
3437 for( i=0; !ASCII_SPACE(oid.bv_val[i]) && i < j; i++ ) {
3442 /* insert attributeTypes, objectclass check here */
3443 if( OID_LEADCHAR(asserted->bv_val[0]) ) {
3444 rc = objectIdentifierMatch( &match, flags, syntax, mr, &oid, asserted );
3447 if ( !strcmp( syntax->ssyn_oid, SLAP_SYNTAX_MATCHINGRULES_OID ) ) {
3448 MatchingRule *asserted_mr = mr_bvfind( asserted );
3449 MatchingRule *stored_mr = mr_bvfind( &oid );
3451 if( asserted_mr == NULL ) {
3452 rc = SLAPD_COMPARE_UNDEFINED;
3454 match = asserted_mr != stored_mr;
3457 } else if ( !strcmp( syntax->ssyn_oid,
3458 SLAP_SYNTAX_ATTRIBUTETYPES_OID ) )
3460 AttributeType *asserted_at = at_bvfind( asserted );
3461 AttributeType *stored_at = at_bvfind( &oid );
3463 if( asserted_at == NULL ) {
3464 rc = SLAPD_COMPARE_UNDEFINED;
3466 match = asserted_at != stored_at;
3469 } else if ( !strcmp( syntax->ssyn_oid,
3470 SLAP_SYNTAX_OBJECTCLASSES_OID ) )
3472 ObjectClass *asserted_oc = oc_bvfind( asserted );
3473 ObjectClass *stored_oc = oc_bvfind( &oid );
3475 if( asserted_oc == NULL ) {
3476 rc = SLAPD_COMPARE_UNDEFINED;
3478 match = asserted_oc != stored_oc;
3484 LDAP_LOG( CONFIG, ENTRY,
3485 "objectIdentifierFirstComponentMatch: %d\n %s\n %s\n",
3486 match, value->bv_val, asserted->bv_val );
3488 Debug( LDAP_DEBUG_ARGS, "objectIdentifierFirstComponentMatch "
3489 "%d\n\t\"%s\"\n\t\"%s\"\n",
3490 match, value->bv_val, asserted->bv_val );
3493 if( rc == LDAP_SUCCESS ) *matchp = match;
3503 struct berval *value,
3504 void *assertedValue )
3506 long lValue, lAssertedValue;
3508 /* safe to assume integers are NUL terminated? */
3509 lValue = strtoul(value->bv_val, NULL, 10);
3510 if(( lValue == LONG_MIN || lValue == LONG_MAX) && errno == ERANGE ) {
3511 return LDAP_CONSTRAINT_VIOLATION;
3514 lAssertedValue = strtol(((struct berval *)assertedValue)->bv_val, NULL, 10);
3515 if(( lAssertedValue == LONG_MIN || lAssertedValue == LONG_MAX)
3516 && errno == ERANGE )
3518 return LDAP_CONSTRAINT_VIOLATION;
3521 *matchp = (lValue & lAssertedValue) ? 0 : 1;
3522 return LDAP_SUCCESS;
3531 struct berval *value,
3532 void *assertedValue )
3534 long lValue, lAssertedValue;
3536 /* safe to assume integers are NUL terminated? */
3537 lValue = strtoul(value->bv_val, NULL, 10);
3538 if(( lValue == LONG_MIN || lValue == LONG_MAX) && errno == ERANGE ) {
3539 return LDAP_CONSTRAINT_VIOLATION;
3542 lAssertedValue = strtol(((struct berval *)assertedValue)->bv_val, NULL, 10);
3543 if(( lAssertedValue == LONG_MIN || lAssertedValue == LONG_MAX)
3544 && errno == ERANGE )
3546 return LDAP_CONSTRAINT_VIOLATION;
3549 *matchp = (lValue | lAssertedValue) ? 0 : -1;
3550 return LDAP_SUCCESS;
3554 #include <openssl/x509.h>
3555 #include <openssl/err.h>
3558 * Next function returns a string representation of a ASN1_INTEGER.
3559 * It works for unlimited lengths.
3562 static struct berval *
3563 asn1_integer2str(ASN1_INTEGER *a, struct berval *bv)
3567 static char digit[] = "0123456789";
3569 /* We work backwards, make it fill from the end of buf */
3570 p = buf + sizeof(buf) - 1;
3573 if ( a == NULL || a->length == 0 ) {
3581 /* We want to preserve the original */
3582 copy = ch_malloc(n*sizeof(unsigned int));
3583 for (i = 0; i<n; i++) {
3584 copy[i] = a->data[i];
3588 * base indicates the index of the most significant
3589 * byte that might be nonzero. When it goes off the
3590 * end, we now there is nothing left to do.
3596 for (i = base; i<n; i++ ) {
3597 copy[i] += carry*256;
3598 carry = copy[i] % 10;
3603 * Way too large, we need to leave
3604 * room for sign if negative
3609 *--p = digit[carry];
3611 if (copy[base] == 0) base++;
3616 if ( a->type == V_ASN1_NEG_INTEGER ) {
3620 return ber_str2bv( p, 0, 1, bv );
3624 * Given a certificate in DER format, extract the corresponding
3625 * assertion value for certificateExactMatch
3628 certificateExactConvert(
3630 struct berval * out )
3633 unsigned char *p = in->bv_val;
3634 struct berval serial;
3635 struct berval issuer_dn;
3637 xcert = d2i_X509(NULL, &p, in->bv_len);
3640 LDAP_LOG( CONFIG, ENTRY,
3641 "certificateExactConvert: error parsing cert: %s\n",
3642 ERR_error_string(ERR_get_error(),NULL), 0, 0 );
3644 Debug( LDAP_DEBUG_ARGS, "certificateExactConvert: "
3645 "error parsing cert: %s\n",
3646 ERR_error_string(ERR_get_error(),NULL), NULL, NULL );
3648 return LDAP_INVALID_SYNTAX;
3651 if ( !asn1_integer2str(xcert->cert_info->serialNumber, &serial) ) {
3653 return LDAP_INVALID_SYNTAX;
3655 if ( dnX509normalize(X509_get_issuer_name(xcert), &issuer_dn )
3659 ber_memfree(serial.bv_val);
3660 return LDAP_INVALID_SYNTAX;
3665 out->bv_len = serial.bv_len + issuer_dn.bv_len + sizeof(" $ ");
3666 out->bv_val = ch_malloc(out->bv_len);
3668 AC_MEMCPY(p, serial.bv_val, serial.bv_len);
3670 AC_MEMCPY(p, " $ ", sizeof(" $ ")-1);
3672 AC_MEMCPY(p, issuer_dn.bv_val, issuer_dn.bv_len);
3673 p += issuer_dn.bv_len;
3677 LDAP_LOG( CONFIG, ARGS,
3678 "certificateExactConvert: \n %s\n", out->bv_val, 0, 0 );
3680 Debug( LDAP_DEBUG_ARGS, "certificateExactConvert "
3682 out->bv_val, NULL, NULL );
3685 ber_memfree(serial.bv_val);
3686 ber_memfree(issuer_dn.bv_val);
3688 return LDAP_SUCCESS;
3692 serial_and_issuer_parse(
3693 struct berval *assertion,
3694 struct berval *serial,
3695 struct berval *issuer_dn
3703 begin = assertion->bv_val;
3704 end = assertion->bv_val+assertion->bv_len-1;
3705 for (p=begin; p<=end && *p != '$'; p++) /* empty */ ;
3706 if ( p > end ) return LDAP_INVALID_SYNTAX;
3708 /* p now points at the $ sign, now use
3709 * begin and end to delimit the serial number
3711 while (ASCII_SPACE(*begin)) begin++;
3713 while (ASCII_SPACE(*end)) end--;
3715 if( end <= begin ) return LDAP_INVALID_SYNTAX;
3717 bv.bv_len = end-begin+1;
3719 ber_dupbv(serial, &bv);
3721 /* now extract the issuer, remember p was at the dollar sign */
3723 end = assertion->bv_val+assertion->bv_len-1;
3724 while (ASCII_SPACE(*begin)) begin++;
3725 /* should we trim spaces at the end too? is it safe always? no, no */
3727 if( end <= begin ) return LDAP_INVALID_SYNTAX;
3730 bv.bv_len = end-begin+1;
3733 dnNormalize2( NULL, &bv, issuer_dn );
3736 return LDAP_SUCCESS;
3740 certificateExactMatch(
3745 struct berval *value,
3746 void *assertedValue )
3749 unsigned char *p = value->bv_val;
3750 struct berval serial;
3751 struct berval issuer_dn;
3752 struct berval asserted_serial;
3753 struct berval asserted_issuer_dn;
3756 xcert = d2i_X509(NULL, &p, value->bv_len);
3759 LDAP_LOG( CONFIG, ENTRY,
3760 "certificateExactMatch: error parsing cert: %s\n",
3761 ERR_error_string(ERR_get_error(),NULL), 0, 0 );
3763 Debug( LDAP_DEBUG_ARGS, "certificateExactMatch: "
3764 "error parsing cert: %s\n",
3765 ERR_error_string(ERR_get_error(),NULL), NULL, NULL );
3767 return LDAP_INVALID_SYNTAX;
3770 asn1_integer2str(xcert->cert_info->serialNumber, &serial);
3771 dnX509normalize(X509_get_issuer_name(xcert), &issuer_dn);
3775 serial_and_issuer_parse(assertedValue,
3776 &asserted_serial, &asserted_issuer_dn);
3781 slap_schema.si_syn_integer,
3782 slap_schema.si_mr_integerMatch,
3785 if ( ret == LDAP_SUCCESS ) {
3786 if ( *matchp == 0 ) {
3787 /* We need to normalize everything for dnMatch */
3791 slap_schema.si_syn_distinguishedName,
3792 slap_schema.si_mr_distinguishedNameMatch,
3794 &asserted_issuer_dn);
3799 LDAP_LOG( CONFIG, ARGS, "certificateExactMatch "
3800 "%d\n\t\"%s $ %s\"\n",
3801 *matchp, serial.bv_val, issuer_dn.bv_val );
3802 LDAP_LOG( CONFIG, ARGS, "\t\"%s $ %s\"\n",
3803 asserted_serial.bv_val, asserted_issuer_dn.bv_val,
3806 Debug( LDAP_DEBUG_ARGS, "certificateExactMatch "
3807 "%d\n\t\"%s $ %s\"\n",
3808 *matchp, serial.bv_val, issuer_dn.bv_val );
3809 Debug( LDAP_DEBUG_ARGS, "\t\"%s $ %s\"\n",
3810 asserted_serial.bv_val, asserted_issuer_dn.bv_val,
3814 ber_memfree(serial.bv_val);
3815 ber_memfree(issuer_dn.bv_val);
3816 ber_memfree(asserted_serial.bv_val);
3817 ber_memfree(asserted_issuer_dn.bv_val);
3823 * Index generation function
3824 * We just index the serials, in most scenarios the issuer DN is one of
3825 * a very small set of values.
3827 static int certificateExactIndexer(
3832 struct berval *prefix,
3840 struct berval serial;
3842 /* we should have at least one value at this point */
3843 assert( values != NULL && values[0].bv_val != NULL );
3845 for( i=0; values[i].bv_val != NULL; i++ ) {
3846 /* empty -- just count them */
3849 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
3851 for( i=0; values[i].bv_val != NULL; i++ ) {
3852 p = values[i].bv_val;
3853 xcert = d2i_X509(NULL, &p, values[i].bv_len);
3856 LDAP_LOG( CONFIG, ENTRY,
3857 "certificateExactIndexer: error parsing cert: %s\n",
3858 ERR_error_string(ERR_get_error(),NULL), 0, 0);
3860 Debug( LDAP_DEBUG_ARGS, "certificateExactIndexer: "
3861 "error parsing cert: %s\n",
3862 ERR_error_string(ERR_get_error(),NULL),
3865 /* Do we leak keys on error? */
3866 return LDAP_INVALID_SYNTAX;
3869 asn1_integer2str(xcert->cert_info->serialNumber, &serial);
3871 integerNormalize( slap_schema.si_syn_integer,
3872 &serial, &keys[i] );
3873 ber_memfree(serial.bv_val);
3875 LDAP_LOG( CONFIG, ENTRY,
3876 "certificateExactIndexer: returning: %s\n", keys[i].bv_val, 0, 0);
3878 Debug( LDAP_DEBUG_ARGS, "certificateExactIndexer: "
3885 keys[i].bv_val = NULL;
3887 return LDAP_SUCCESS;
3890 /* Index generation function */
3891 /* We think this is always called with a value in matching rule syntax */
3892 static int certificateExactFilter(
3897 struct berval *prefix,
3898 void * assertedValue,
3902 struct berval asserted_serial;
3905 ret = serial_and_issuer_parse( assertedValue, &asserted_serial, NULL );
3906 if( ret != LDAP_SUCCESS ) return ret;
3908 keys = ch_malloc( sizeof( struct berval ) * 2 );
3909 integerNormalize( syntax, &asserted_serial, &keys[0] );
3910 keys[1].bv_val = NULL;
3913 ber_memfree(asserted_serial.bv_val);
3914 return LDAP_SUCCESS;
3919 check_time_syntax (struct berval *val,
3923 static int ceiling[9] = { 99, 99, 11, 30, 23, 59, 59, 12, 59 };
3924 static int mdays[2][12] = {
3925 /* non-leap years */
3926 { 30, 27, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30 },
3928 { 30, 28, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30 }
3931 int part, c, tzoffset, leapyear = 0 ;
3933 if( val->bv_len == 0 ) {
3934 return LDAP_INVALID_SYNTAX;
3937 p = (char *)val->bv_val;
3938 e = p + val->bv_len;
3940 /* Ignore initial whitespace */
3941 while ( ( p < e ) && ASCII_SPACE( *p ) ) {
3945 if (e - p < 13 - (2 * start)) {
3946 return LDAP_INVALID_SYNTAX;
3949 for (part = 0; part < 9; part++) {
3953 for (part = start; part < 7; part++) {
3955 if ((part == 6) && (c == 'Z' || c == '+' || c == '-')) {
3962 return LDAP_INVALID_SYNTAX;
3964 if (c < 0 || c > 9) {
3965 return LDAP_INVALID_SYNTAX;
3971 return LDAP_INVALID_SYNTAX;
3973 if (c < 0 || c > 9) {
3974 return LDAP_INVALID_SYNTAX;
3979 if (part == 2 || part == 3) {
3982 if (parts[part] < 0) {
3983 return LDAP_INVALID_SYNTAX;
3985 if (parts[part] > ceiling[part]) {
3986 return LDAP_INVALID_SYNTAX;
3990 /* leapyear check for the Gregorian calendar (year>1581) */
3991 if (((parts[1] % 4 == 0) && (parts[1] != 0)) ||
3992 ((parts[0] % 4 == 0) && (parts[1] == 0)))
3997 if (parts[3] > mdays[leapyear][parts[2]]) {
3998 return LDAP_INVALID_SYNTAX;
4003 tzoffset = 0; /* UTC */
4004 } else if (c != '+' && c != '-') {
4005 return LDAP_INVALID_SYNTAX;
4009 } else /* c == '+' */ {
4014 return LDAP_INVALID_SYNTAX;
4017 for (part = 7; part < 9; part++) {
4019 if (c < 0 || c > 9) {
4020 return LDAP_INVALID_SYNTAX;
4025 if (c < 0 || c > 9) {
4026 return LDAP_INVALID_SYNTAX;
4030 if (parts[part] < 0 || parts[part] > ceiling[part]) {
4031 return LDAP_INVALID_SYNTAX;
4036 /* Ignore trailing whitespace */
4037 while ( ( p < e ) && ASCII_SPACE( *p ) ) {
4041 return LDAP_INVALID_SYNTAX;
4044 switch ( tzoffset ) {
4045 case -1: /* negativ offset to UTC, ie west of Greenwich */
4046 parts[4] += parts[7];
4047 parts[5] += parts[8];
4048 for (part = 6; --part > 0; ) { /* offset is just hhmm, no seconds */
4052 c = mdays[leapyear][parts[2]];
4054 if (parts[part] > c) {
4055 parts[part] -= c + 1;
4060 case 1: /* positive offset to UTC, ie east of Greenwich */
4061 parts[4] -= parts[7];
4062 parts[5] -= parts[8];
4063 for (part = 6; --part > 0; ) {
4067 /* first arg to % needs to be non negativ */
4068 c = mdays[leapyear][(parts[2] - 1 + 12) % 12];
4070 if (parts[part] < 0) {
4071 parts[part] += c + 1;
4076 case 0: /* already UTC */
4080 return LDAP_SUCCESS;
4083 #ifdef SUPPORT_OBSOLETE_UTC_SYNTAX
4088 struct berval *normalized )
4092 rc = check_time_syntax(val, 1, parts);
4093 if (rc != LDAP_SUCCESS) {
4097 normalized->bv_val = ch_malloc( 14 );
4098 if ( normalized->bv_val == NULL ) {
4099 return LBER_ERROR_MEMORY;
4102 sprintf( normalized->bv_val, "%02d%02d%02d%02d%02d%02dZ",
4103 parts[1], parts[2] + 1, parts[3] + 1,
4104 parts[4], parts[5], parts[6] );
4105 normalized->bv_len = 13;
4107 return LDAP_SUCCESS;
4111 #ifdef SUPPORT_OBSOLETE_UTC_SYNTAX
4119 return check_time_syntax(in, 1, parts);
4124 generalizedTimeValidate(
4130 return check_time_syntax(in, 0, parts);
4134 generalizedTimeNormalize(
4137 struct berval *normalized )
4141 rc = check_time_syntax(val, 0, parts);
4142 if (rc != LDAP_SUCCESS) {
4146 normalized->bv_val = ch_malloc( 16 );
4147 if ( normalized->bv_val == NULL ) {
4148 return LBER_ERROR_MEMORY;
4151 sprintf( normalized->bv_val, "%02d%02d%02d%02d%02d%02d%02dZ",
4152 parts[0], parts[1], parts[2] + 1, parts[3] + 1,
4153 parts[4], parts[5], parts[6] );
4154 normalized->bv_len = 15;
4156 return LDAP_SUCCESS;
4160 nisNetgroupTripleValidate(
4162 struct berval *val )
4167 if ( val->bv_len == 0 ) {
4168 return LDAP_INVALID_SYNTAX;
4171 p = (char *)val->bv_val;
4172 e = p + val->bv_len;
4174 if ( *p != '(' /*')'*/ ) {
4175 return LDAP_INVALID_SYNTAX;
4178 for ( p++; ( p < e ) && ( *p != /*'('*/ ')' ); p++ ) {
4182 return LDAP_INVALID_SYNTAX;
4185 } else if ( !AD_CHAR( *p ) ) {
4186 return LDAP_INVALID_SYNTAX;
4190 if ( ( commas != 2 ) || ( *p != /*'('*/ ')' ) ) {
4191 return LDAP_INVALID_SYNTAX;
4197 return LDAP_INVALID_SYNTAX;
4200 return LDAP_SUCCESS;
4204 bootParameterValidate(
4206 struct berval *val )
4210 if ( val->bv_len == 0 ) {
4211 return LDAP_INVALID_SYNTAX;
4214 p = (char *)val->bv_val;
4215 e = p + val->bv_len;
4218 for (; ( p < e ) && ( *p != '=' ); p++ ) {
4219 if ( !AD_CHAR( *p ) ) {
4220 return LDAP_INVALID_SYNTAX;
4225 return LDAP_INVALID_SYNTAX;
4229 for ( p++; ( p < e ) && ( *p != ':' ); p++ ) {
4230 if ( !AD_CHAR( *p ) ) {
4231 return LDAP_INVALID_SYNTAX;
4236 return LDAP_INVALID_SYNTAX;
4240 for ( p++; p < e; p++ ) {
4241 if ( !SLAP_PRINTABLE( *p ) ) {
4242 return LDAP_INVALID_SYNTAX;
4246 return LDAP_SUCCESS;
4249 #define X_BINARY "X-BINARY-TRANSFER-REQUIRED 'TRUE' "
4250 #define X_NOT_H_R "X-NOT-HUMAN-READABLE 'TRUE' "
4252 static slap_syntax_defs_rec syntax_defs[] = {
4253 {"( 1.3.6.1.4.1.1466.115.121.1.1 DESC 'ACI Item' "
4254 X_BINARY X_NOT_H_R ")",
4255 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, NULL, NULL, NULL},
4256 {"( 1.3.6.1.4.1.1466.115.121.1.2 DESC 'Access Point' " X_NOT_H_R ")",
4257 0, NULL, NULL, NULL},
4258 {"( 1.3.6.1.4.1.1466.115.121.1.3 DESC 'Attribute Type Description' )",
4259 0, NULL, NULL, NULL},
4260 {"( 1.3.6.1.4.1.1466.115.121.1.4 DESC 'Audio' "
4262 SLAP_SYNTAX_BLOB, blobValidate, NULL, NULL},
4263 {"( 1.3.6.1.4.1.1466.115.121.1.5 DESC 'Binary' "
4265 SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4266 {"( 1.3.6.1.4.1.1466.115.121.1.6 DESC 'Bit String' )",
4267 0, bitStringValidate, NULL, NULL },
4268 {"( 1.3.6.1.4.1.1466.115.121.1.7 DESC 'Boolean' )",
4269 0, booleanValidate, NULL, NULL},
4270 {"( 1.3.6.1.4.1.1466.115.121.1.8 DESC 'Certificate' "
4271 X_BINARY X_NOT_H_R ")",
4272 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4273 {"( 1.3.6.1.4.1.1466.115.121.1.9 DESC 'Certificate List' "
4274 X_BINARY X_NOT_H_R ")",
4275 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4276 {"( 1.3.6.1.4.1.1466.115.121.1.10 DESC 'Certificate Pair' "
4277 X_BINARY X_NOT_H_R ")",
4278 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4279 {"( 1.3.6.1.4.1.1466.115.121.1.11 DESC 'Country String' )",
4280 0, countryStringValidate, IA5StringNormalize, NULL},
4281 {"( 1.3.6.1.4.1.1466.115.121.1.12 DESC 'Distinguished Name' )",
4282 0, dnValidate, dnNormalize2, dnPretty2},
4283 {"( 1.3.6.1.4.1.1466.115.121.1.13 DESC 'Data Quality' )",
4284 0, NULL, NULL, NULL},
4285 {"( 1.3.6.1.4.1.1466.115.121.1.14 DESC 'Delivery Method' )",
4286 0, NULL, NULL, NULL},
4287 {"( 1.3.6.1.4.1.1466.115.121.1.15 DESC 'Directory String' )",
4288 0, UTF8StringValidate, UTF8StringNormalize, NULL},
4289 {"( 1.3.6.1.4.1.1466.115.121.1.16 DESC 'DIT Content Rule Description' )",
4290 0, NULL, NULL, NULL},
4291 {"( 1.3.6.1.4.1.1466.115.121.1.17 DESC 'DIT Structure Rule Description' )",
4292 0, NULL, NULL, NULL},
4293 {"( 1.3.6.1.4.1.1466.115.121.1.19 DESC 'DSA Quality' )",
4294 0, NULL, NULL, NULL},
4295 {"( 1.3.6.1.4.1.1466.115.121.1.20 DESC 'DSE Type' )",
4296 0, NULL, NULL, NULL},
4297 {"( 1.3.6.1.4.1.1466.115.121.1.21 DESC 'Enhanced Guide' )",
4298 0, NULL, NULL, NULL},
4299 {"( 1.3.6.1.4.1.1466.115.121.1.22 DESC 'Facsimile Telephone Number' )",
4300 0, printablesStringValidate, telephoneNumberNormalize, NULL},
4301 {"( 1.3.6.1.4.1.1466.115.121.1.23 DESC 'Fax' " X_NOT_H_R ")",
4302 SLAP_SYNTAX_BLOB, NULL, NULL, NULL},
4303 {"( 1.3.6.1.4.1.1466.115.121.1.24 DESC 'Generalized Time' )",
4304 0, generalizedTimeValidate, generalizedTimeNormalize, NULL},
4305 {"( 1.3.6.1.4.1.1466.115.121.1.25 DESC 'Guide' )",
4306 0, NULL, NULL, NULL},
4307 {"( 1.3.6.1.4.1.1466.115.121.1.26 DESC 'IA5 String' )",
4308 0, IA5StringValidate, IA5StringNormalize, NULL},
4309 {"( 1.3.6.1.4.1.1466.115.121.1.27 DESC 'Integer' )",
4310 0, integerValidate, integerNormalize, NULL},
4311 {"( 1.3.6.1.4.1.1466.115.121.1.28 DESC 'JPEG' " X_NOT_H_R ")",
4312 SLAP_SYNTAX_BLOB, blobValidate, NULL, NULL},
4313 {"( 1.3.6.1.4.1.1466.115.121.1.29 DESC 'Master And Shadow Access Points' )",
4314 0, NULL, NULL, NULL},
4315 {"( 1.3.6.1.4.1.1466.115.121.1.30 DESC 'Matching Rule Description' )",
4316 0, NULL, NULL, NULL},
4317 {"( 1.3.6.1.4.1.1466.115.121.1.31 DESC 'Matching Rule Use Description' )",
4318 0, NULL, NULL, NULL},
4319 {"( 1.3.6.1.4.1.1466.115.121.1.32 DESC 'Mail Preference' )",
4320 0, NULL, NULL, NULL},
4321 {"( 1.3.6.1.4.1.1466.115.121.1.33 DESC 'MHS OR Address' )",
4322 0, NULL, NULL, NULL},
4323 {"( 1.3.6.1.4.1.1466.115.121.1.34 DESC 'Name And Optional UID' )",
4324 0, nameUIDValidate, nameUIDNormalize, NULL},
4325 {"( 1.3.6.1.4.1.1466.115.121.1.35 DESC 'Name Form Description' )",
4326 0, NULL, NULL, NULL},
4327 {"( 1.3.6.1.4.1.1466.115.121.1.36 DESC 'Numeric String' )",
4328 0, numericStringValidate, numericStringNormalize, NULL},
4329 {"( 1.3.6.1.4.1.1466.115.121.1.37 DESC 'Object Class Description' )",
4330 0, NULL, NULL, NULL},
4331 {"( 1.3.6.1.4.1.1466.115.121.1.38 DESC 'OID' )",
4332 0, oidValidate, NULL, NULL},
4333 {"( 1.3.6.1.4.1.1466.115.121.1.39 DESC 'Other Mailbox' )",
4334 0, IA5StringValidate, IA5StringNormalize, NULL},
4335 {"( 1.3.6.1.4.1.1466.115.121.1.40 DESC 'Octet String' )",
4336 0, blobValidate, NULL, NULL},
4337 {"( 1.3.6.1.4.1.1466.115.121.1.41 DESC 'Postal Address' )",
4338 0, UTF8StringValidate, UTF8StringNormalize, NULL},
4339 {"( 1.3.6.1.4.1.1466.115.121.1.42 DESC 'Protocol Information' )",
4340 0, NULL, NULL, NULL},
4341 {"( 1.3.6.1.4.1.1466.115.121.1.43 DESC 'Presentation Address' )",
4342 0, NULL, NULL, NULL},
4343 {"( 1.3.6.1.4.1.1466.115.121.1.44 DESC 'Printable String' )",
4344 0, printableStringValidate, IA5StringNormalize, NULL},
4345 {"( 1.3.6.1.4.1.1466.115.121.1.45 DESC 'SubtreeSpecification' "
4346 X_BINARY X_NOT_H_R ")",
4347 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, NULL, NULL, NULL},
4348 {"( 1.3.6.1.4.1.1466.115.121.1.49 DESC 'Supported Algorithm' "
4349 X_BINARY X_NOT_H_R ")",
4350 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4351 {"( 1.3.6.1.4.1.1466.115.121.1.50 DESC 'Telephone Number' )",
4352 0, printableStringValidate, telephoneNumberNormalize, NULL},
4353 {"( 1.3.6.1.4.1.1466.115.121.1.51 DESC 'Teletex Terminal Identifier' )",
4354 0, NULL, NULL, NULL},
4355 {"( 1.3.6.1.4.1.1466.115.121.1.52 DESC 'Telex Number' )",
4356 0, printablesStringValidate, IA5StringNormalize, NULL},
4357 #ifdef SUPPORT_OBSOLETE_UTC_SYNTAX
4358 {"( 1.3.6.1.4.1.1466.115.121.1.53 DESC 'UTC Time' )",
4359 0, utcTimeValidate, utcTimeNormalize, NULL},
4361 {"( 1.3.6.1.4.1.1466.115.121.1.54 DESC 'LDAP Syntax Description' )",
4362 0, NULL, NULL, NULL},
4363 {"( 1.3.6.1.4.1.1466.115.121.1.55 DESC 'Modify Rights' )",
4364 0, NULL, NULL, NULL},
4365 {"( 1.3.6.1.4.1.1466.115.121.1.56 DESC 'LDAP Schema Definition' )",
4366 0, NULL, NULL, NULL},
4367 {"( 1.3.6.1.4.1.1466.115.121.1.57 DESC 'LDAP Schema Description' )",
4368 0, NULL, NULL, NULL},
4369 {"( 1.3.6.1.4.1.1466.115.121.1.58 DESC 'Substring Assertion' )",
4370 0, NULL, NULL, NULL},
4372 /* RFC 2307 NIS Syntaxes */
4373 {"( 1.3.6.1.1.1.0.0 DESC 'RFC2307 NIS Netgroup Triple' )",
4374 0, nisNetgroupTripleValidate, NULL, NULL},
4375 {"( 1.3.6.1.1.1.0.1 DESC 'RFC2307 Boot Parameter' )",
4376 0, bootParameterValidate, NULL, NULL},
4380 /* These OIDs are not published yet, but will be in the next
4381 * I-D for PKIX LDAPv3 schema as have been advanced by David
4382 * Chadwick in private mail.
4384 {"( 1.2.826.0.1.3344810.7.1 DESC 'Serial Number and Issuer' )",
4385 0, UTF8StringValidate, NULL, NULL},
4388 /* OpenLDAP Experimental Syntaxes */
4389 #ifdef SLAPD_ACI_ENABLED
4390 {"( 1.3.6.1.4.1.4203.666.2.1 DESC 'OpenLDAP Experimental ACI' )",
4392 UTF8StringValidate /* THIS WILL CHANGE FOR NEW ACI SYNTAX */,
4396 #ifdef SLAPD_AUTHPASSWD
4397 /* needs updating */
4398 {"( 1.3.6.1.4.1.4203.666.2.2 DESC 'OpenLDAP authPassword' )",
4399 SLAP_SYNTAX_HIDE, NULL, NULL, NULL},
4402 /* OpenLDAP Void Syntax */
4403 {"( 1.3.6.1.4.1.4203.1.1.1 DESC 'OpenLDAP void' )" ,
4404 SLAP_SYNTAX_HIDE, inValidate, NULL, NULL},
4405 {NULL, 0, NULL, NULL, NULL}
4409 char *certificateExactMatchSyntaxes[] = {
4410 "1.3.6.1.4.1.1466.115.121.1.8" /* certificate */,
4414 char *directoryStringSyntaxes[] = {
4415 "1.3.6.1.4.1.1466.115.121.1.44" /* printableString */,
4418 char *integerFirstComponentMatchSyntaxes[] = {
4419 "1.3.6.1.4.1.1466.115.121.1.27" /* INTEGER */,
4420 "1.3.6.1.4.1.1466.115.121.1.17" /* ditStructureRuleDescription */,
4423 char *objectIdentifierFirstComponentMatchSyntaxes[] = {
4424 "1.3.6.1.4.1.1466.115.121.1.38" /* OID */,
4425 "1.3.6.1.4.1.1466.115.121.1.3" /* attributeTypeDescription */,
4426 "1.3.6.1.4.1.1466.115.121.1.16" /* ditContentRuleDescription */,
4427 "1.3.6.1.4.1.1466.115.121.1.54" /* ldapSyntaxDescription */,
4428 "1.3.6.1.4.1.1466.115.121.1.30" /* matchingRuleDescription */,
4429 "1.3.6.1.4.1.1466.115.121.1.31" /* matchingRuleUseDescription */,
4430 "1.3.6.1.4.1.1466.115.121.1.35" /* nameFormDescription */,
4431 "1.3.6.1.4.1.1466.115.121.1.37" /* objectClassDescription */,
4436 * Other matching rules in X.520 that we do not use (yet):
4438 * 2.5.13.9 numericStringOrderingMatch
4439 * 2.5.13.19 octetStringSubstringsMatch
4440 * 2.5.13.25 uTCTimeMatch
4441 * 2.5.13.26 uTCTimeOrderingMatch
4442 * 2.5.13.31 directoryStringFirstComponentMatch
4443 * 2.5.13.32 wordMatch
4444 * 2.5.13.33 keywordMatch
4445 * 2.5.13.35 certificateMatch
4446 * 2.5.13.36 certificatePairExactMatch
4447 * 2.5.13.37 certificatePairMatch
4448 * 2.5.13.38 certificateListExactMatch
4449 * 2.5.13.39 certificateListMatch
4450 * 2.5.13.40 algorithmIdentifierMatch
4451 * 2.5.13.41 storedPrefixMatch
4452 * 2.5.13.42 attributeCertificateMatch
4453 * 2.5.13.43 readerAndKeyIDMatch
4454 * 2.5.13.44 attributeIntegrityMatch
4456 static slap_mrule_defs_rec mrule_defs[] = {
4458 * EQUALITY matching rules must be listed after associated APPROX
4459 * matching rules. So, we list all APPROX matching rules first.
4461 {"( " directoryStringApproxMatchOID " NAME 'directoryStringApproxMatch' "
4462 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4463 SLAP_MR_HIDE | SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT, NULL,
4465 directoryStringApproxMatch,
4466 directoryStringApproxIndexer,
4467 directoryStringApproxFilter,
4470 {"( " IA5StringApproxMatchOID " NAME 'IA5StringApproxMatch' "
4471 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4472 SLAP_MR_HIDE | SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT, NULL,
4474 IA5StringApproxMatch,
4475 IA5StringApproxIndexer,
4476 IA5StringApproxFilter,
4480 * Other matching rules
4483 {"( 2.5.13.0 NAME 'objectIdentifierMatch' "
4484 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
4485 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4487 objectIdentifierMatch, caseIgnoreIA5Indexer, caseIgnoreIA5Filter,
4490 {"( 2.5.13.1 NAME 'distinguishedNameMatch' "
4491 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )",
4492 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4494 dnMatch, dnIndexer, dnFilter,
4497 {"( 2.5.13.2 NAME 'caseIgnoreMatch' "
4498 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4499 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD,
4500 directoryStringSyntaxes,
4502 caseIgnoreMatch, caseExactIgnoreIndexer, caseExactIgnoreFilter,
4503 directoryStringApproxMatchOID },
4505 {"( 2.5.13.3 NAME 'caseIgnoreOrderingMatch' "
4506 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4507 SLAP_MR_ORDERING, directoryStringSyntaxes,
4509 caseIgnoreOrderingMatch, NULL, NULL,
4512 {"( 2.5.13.4 NAME 'caseIgnoreSubstringsMatch' "
4513 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4514 SLAP_MR_SUBSTR, NULL,
4516 caseExactIgnoreSubstringsMatch,
4517 caseExactIgnoreSubstringsIndexer,
4518 caseExactIgnoreSubstringsFilter,
4521 {"( 2.5.13.5 NAME 'caseExactMatch' "
4522 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4523 SLAP_MR_EQUALITY | SLAP_MR_EXT, directoryStringSyntaxes,
4525 caseExactMatch, caseExactIgnoreIndexer, caseExactIgnoreFilter,
4526 directoryStringApproxMatchOID },
4528 {"( 2.5.13.6 NAME 'caseExactOrderingMatch' "
4529 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4530 SLAP_MR_ORDERING, directoryStringSyntaxes,
4532 caseExactOrderingMatch, NULL, NULL,
4535 {"( 2.5.13.7 NAME 'caseExactSubstringsMatch' "
4536 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4537 SLAP_MR_SUBSTR, directoryStringSyntaxes,
4539 caseExactIgnoreSubstringsMatch,
4540 caseExactIgnoreSubstringsIndexer,
4541 caseExactIgnoreSubstringsFilter,
4544 {"( 2.5.13.8 NAME 'numericStringMatch' "
4545 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 )",
4546 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL,
4549 caseIgnoreIA5Indexer,
4550 caseIgnoreIA5Filter,
4553 {"( 2.5.13.10 NAME 'numericStringSubstringsMatch' "
4554 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4555 SLAP_MR_SUBSTR, NULL,
4557 caseIgnoreIA5SubstringsMatch,
4558 caseIgnoreIA5SubstringsIndexer,
4559 caseIgnoreIA5SubstringsFilter,
4562 {"( 2.5.13.11 NAME 'caseIgnoreListMatch' "
4563 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )",
4564 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL,
4566 caseIgnoreListMatch, NULL, NULL,
4569 {"( 2.5.13.12 NAME 'caseIgnoreListSubstringsMatch' "
4570 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4571 SLAP_MR_SUBSTR, NULL,
4573 caseIgnoreListSubstringsMatch, NULL, NULL,
4576 {"( 2.5.13.13 NAME 'booleanMatch' "
4577 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )",
4578 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4580 booleanMatch, NULL, NULL,
4583 {"( 2.5.13.14 NAME 'integerMatch' "
4584 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4585 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4587 integerMatch, integerIndexer, integerFilter,
4590 {"( 2.5.13.15 NAME 'integerOrderingMatch' "
4591 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4592 SLAP_MR_ORDERING, NULL,
4594 integerOrderingMatch, NULL, NULL,
4597 {"( 2.5.13.16 NAME 'bitStringMatch' "
4598 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.6 )",
4599 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4601 bitStringMatch, bitStringIndexer, bitStringFilter,
4604 {"( 2.5.13.17 NAME 'octetStringMatch' "
4605 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
4606 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4608 octetStringMatch, octetStringIndexer, octetStringFilter,
4611 {"( 2.5.13.18 NAME 'octetStringOrderingMatch' "
4612 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
4613 SLAP_MR_ORDERING, NULL,
4615 octetStringOrderingMatch, NULL, NULL,
4618 {"( 2.5.13.20 NAME 'telephoneNumberMatch' "
4619 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 )",
4620 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL,
4622 telephoneNumberMatch,
4623 telephoneNumberIndexer,
4624 telephoneNumberFilter,
4627 {"( 2.5.13.21 NAME 'telephoneNumberSubstringsMatch' "
4628 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4629 SLAP_MR_SUBSTR, NULL,
4631 telephoneNumberSubstringsMatch,
4632 telephoneNumberSubstringsIndexer,
4633 telephoneNumberSubstringsFilter,
4636 {"( 2.5.13.22 NAME 'presentationAddressMatch' "
4637 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.43 )",
4638 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4643 {"( 2.5.13.23 NAME 'uniqueMemberMatch' "
4644 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.34 )",
4645 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4647 uniqueMemberMatch, NULL, NULL,
4650 {"( 2.5.13.24 NAME 'protocolInformationMatch' "
4651 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.42 )",
4652 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4654 protocolInformationMatch, NULL, NULL,
4657 {"( 2.5.13.27 NAME 'generalizedTimeMatch' "
4658 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
4659 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4661 generalizedTimeMatch, NULL, NULL,
4664 {"( 2.5.13.28 NAME 'generalizedTimeOrderingMatch' "
4665 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
4666 SLAP_MR_ORDERING, NULL,
4668 generalizedTimeOrderingMatch, NULL, NULL,
4671 {"( 2.5.13.29 NAME 'integerFirstComponentMatch' "
4672 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4673 SLAP_MR_EQUALITY | SLAP_MR_EXT, integerFirstComponentMatchSyntaxes,
4675 integerFirstComponentMatch, NULL, NULL,
4678 {"( 2.5.13.30 NAME 'objectIdentifierFirstComponentMatch' "
4679 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
4680 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4681 objectIdentifierFirstComponentMatchSyntaxes,
4683 objectIdentifierFirstComponentMatch, NULL, NULL,
4687 {"( 2.5.13.34 NAME 'certificateExactMatch' "
4688 "SYNTAX 1.2.826.0.1.3344810.7.1 )",
4689 SLAP_MR_EQUALITY | SLAP_MR_EXT, certificateExactMatchSyntaxes,
4690 certificateExactConvert, NULL,
4691 certificateExactMatch,
4692 certificateExactIndexer, certificateExactFilter,
4696 {"( 1.3.6.1.4.1.1466.109.114.1 NAME 'caseExactIA5Match' "
4697 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4698 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4700 caseExactIA5Match, caseExactIA5Indexer, caseExactIA5Filter,
4701 IA5StringApproxMatchOID },
4703 {"( 1.3.6.1.4.1.1466.109.114.2 NAME 'caseIgnoreIA5Match' "
4704 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4705 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL,
4707 caseIgnoreIA5Match, caseIgnoreIA5Indexer, caseIgnoreIA5Filter,
4708 IA5StringApproxMatchOID },
4710 {"( 1.3.6.1.4.1.1466.109.114.3 NAME 'caseIgnoreIA5SubstringsMatch' "
4711 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4712 SLAP_MR_SUBSTR, NULL,
4714 caseIgnoreIA5SubstringsMatch,
4715 caseIgnoreIA5SubstringsIndexer,
4716 caseIgnoreIA5SubstringsFilter,
4719 {"( 1.3.6.1.4.1.4203.1.2.1 NAME 'caseExactIA5SubstringsMatch' "
4720 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4721 SLAP_MR_SUBSTR, NULL,
4723 caseExactIA5SubstringsMatch,
4724 caseExactIA5SubstringsIndexer,
4725 caseExactIA5SubstringsFilter,
4728 #ifdef SLAPD_AUTHPASSWD
4729 /* needs updating */
4730 {"( 1.3.6.1.4.1.4203.666.4.1 NAME 'authPasswordMatch' "
4731 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
4732 SLAP_MR_EQUALITY, NULL,
4734 authPasswordMatch, NULL, NULL,
4738 #ifdef SLAPD_ACI_ENABLED
4739 {"( 1.3.6.1.4.1.4203.666.4.2 NAME 'OpenLDAPaciMatch' "
4740 "SYNTAX 1.3.6.1.4.1.4203.666.2.1 )",
4741 SLAP_MR_EQUALITY, NULL,
4743 OpenLDAPaciMatch, NULL, NULL,
4747 {"( 1.2.840.113556.1.4.803 NAME 'integerBitAndMatch' "
4748 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4751 integerBitAndMatch, NULL, NULL,
4754 {"( 1.2.840.113556.1.4.804 NAME 'integerBitOrMatch' "
4755 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4758 integerBitOrMatch, NULL, NULL,
4761 {NULL, SLAP_MR_NONE, NULL,
4762 NULL, NULL, NULL, NULL, NULL,
4767 slap_schema_init( void )
4772 /* we should only be called once (from main) */
4773 assert( schema_init_done == 0 );
4775 for ( i=0; syntax_defs[i].sd_desc != NULL; i++ ) {
4776 res = register_syntax( &syntax_defs[i] );
4779 fprintf( stderr, "slap_schema_init: Error registering syntax %s\n",
4780 syntax_defs[i].sd_desc );
4785 for ( i=0; mrule_defs[i].mrd_desc != NULL; i++ ) {
4786 if( mrule_defs[i].mrd_usage == SLAP_MR_NONE &&
4787 mrule_defs[i].mrd_compat_syntaxes == NULL )
4790 "slap_schema_init: Ingoring unusable matching rule %s\n",
4791 mrule_defs[i].mrd_desc );
4795 res = register_matching_rule( &mrule_defs[i] );
4799 "slap_schema_init: Error registering matching rule %s\n",
4800 mrule_defs[i].mrd_desc );
4805 for ( i=0; i < (int)(sizeof(mr_ptr)/sizeof(mr_ptr[0])); i++ )
4806 *mr_ptr[i].mr = mr_find( mr_ptr[i].oid );
4808 res = slap_schema_load();
4809 schema_init_done = 1;
4814 schema_destroy( void )
4820 for ( i=0; i < (int)(sizeof(mr_ptr)/sizeof(mr_ptr[0])); i++ )
4821 *mr_ptr[i].mr = NULL;