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,
1250 unsigned casefold,wasspace;
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, nvalue;
1276 UTF8bvnormalize( &values[i], &value, casefold );
1278 /* collapse spaces (in place) */
1280 nvalue.bv_val = value.bv_val;
1283 for( j=0; j<value.bv_len; j++) {
1284 if ( ASCII_SPACE( value.bv_val[j] )) {
1285 if( wasspace++ == 0 ) {
1286 nvalue.bv_val[nvalue.bv_len++] = value.bv_val[j];
1290 nvalue.bv_val[nvalue.bv_len++] = value.bv_val[j];
1294 if( nvalue.bv_len == 0 ) {
1295 nvalue.bv_val = " ";
1296 nvalue.bv_len = sizeof(" ")-1;
1298 if( wasspace ) --nvalue.bv_len;
1299 nvalue.bv_val[nvalue.bv_len] = '\0';
1302 HASH_Init( &HASHcontext );
1303 if( prefix != NULL && prefix->bv_len > 0 ) {
1304 HASH_Update( &HASHcontext,
1305 prefix->bv_val, prefix->bv_len );
1307 HASH_Update( &HASHcontext,
1308 syntax->ssyn_oid, slen );
1309 HASH_Update( &HASHcontext,
1310 mr->smr_oid, mlen );
1311 HASH_Update( &HASHcontext,
1312 nvalue.bv_val, nvalue.bv_len );
1313 HASH_Final( HASHdigest, &HASHcontext );
1315 free( value.bv_val );
1316 ber_dupbv( &keys[i], &digest );
1319 keys[i].bv_val = NULL;
1321 return LDAP_SUCCESS;
1324 /* Index generation function */
1325 static int caseExactIgnoreFilter(
1330 struct berval *prefix,
1331 void * assertedValue,
1337 HASH_CONTEXT HASHcontext;
1338 unsigned char HASHdigest[HASH_BYTES];
1339 struct berval value = { 0, NULL };
1340 struct berval digest;
1342 digest.bv_val = HASHdigest;
1343 digest.bv_len = sizeof(HASHdigest);
1345 slen = syntax->ssyn_oidlen;
1346 mlen = mr->smr_oidlen;
1348 casefold = ( mr != caseExactMatchingRule )
1349 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1351 UTF8bvnormalize( (struct berval *) assertedValue, &value, casefold );
1352 /* This usually happens if filter contains bad UTF8 */
1353 if( value.bv_val == NULL ) {
1354 keys = ch_malloc( sizeof( struct berval ) );
1355 keys[0].bv_val = NULL;
1356 return LDAP_SUCCESS;
1359 keys = ch_malloc( sizeof( struct berval ) * 2 );
1361 HASH_Init( &HASHcontext );
1362 if( prefix != NULL && prefix->bv_len > 0 ) {
1363 HASH_Update( &HASHcontext,
1364 prefix->bv_val, prefix->bv_len );
1366 HASH_Update( &HASHcontext,
1367 syntax->ssyn_oid, slen );
1368 HASH_Update( &HASHcontext,
1369 mr->smr_oid, mlen );
1370 HASH_Update( &HASHcontext,
1371 value.bv_val, value.bv_len );
1372 HASH_Final( HASHdigest, &HASHcontext );
1374 ber_dupbv( keys, &digest );
1375 keys[1].bv_val = NULL;
1377 free( value.bv_val );
1380 return LDAP_SUCCESS;
1383 /* Substrings Index generation function */
1384 static int caseExactIgnoreSubstringsIndexer(
1389 struct berval *prefix,
1399 HASH_CONTEXT HASHcontext;
1400 unsigned char HASHdigest[HASH_BYTES];
1401 struct berval digest;
1402 digest.bv_val = HASHdigest;
1403 digest.bv_len = sizeof(HASHdigest);
1407 for( i=0; values[i].bv_val != NULL; i++ ) {
1408 /* empty - just count them */
1411 /* we should have at least one value at this point */
1414 casefold = ( mr != caseExactSubstringsMatchingRule )
1415 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1417 nvalues = ch_malloc( sizeof( struct berval ) * (i+1) );
1418 for( i=0; values[i].bv_val != NULL; i++ ) {
1419 UTF8bvnormalize( &values[i], &nvalues[i], casefold );
1421 nvalues[i].bv_val = NULL;
1424 for( i=0; values[i].bv_val != NULL; i++ ) {
1425 /* count number of indices to generate */
1426 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
1430 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
1431 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1432 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
1433 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
1435 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
1439 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
1440 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1441 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
1445 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
1446 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1447 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
1448 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
1450 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
1456 /* no keys to generate */
1458 ber_bvarray_free( nvalues );
1459 return LDAP_SUCCESS;
1462 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
1464 slen = syntax->ssyn_oidlen;
1465 mlen = mr->smr_oidlen;
1468 for( i=0; values[i].bv_val != NULL; i++ ) {
1471 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
1473 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
1474 ( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
1476 char pre = SLAP_INDEX_SUBSTR_PREFIX;
1477 max = values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
1479 for( j=0; j<max; j++ ) {
1480 HASH_Init( &HASHcontext );
1481 if( prefix != NULL && prefix->bv_len > 0 ) {
1482 HASH_Update( &HASHcontext,
1483 prefix->bv_val, prefix->bv_len );
1486 HASH_Update( &HASHcontext,
1487 &pre, sizeof( pre ) );
1488 HASH_Update( &HASHcontext,
1489 syntax->ssyn_oid, slen );
1490 HASH_Update( &HASHcontext,
1491 mr->smr_oid, mlen );
1492 HASH_Update( &HASHcontext,
1493 &values[i].bv_val[j],
1494 SLAP_INDEX_SUBSTR_MAXLEN );
1495 HASH_Final( HASHdigest, &HASHcontext );
1497 ber_dupbv( &keys[nkeys++], &digest );
1501 max = SLAP_INDEX_SUBSTR_MAXLEN < values[i].bv_len
1502 ? SLAP_INDEX_SUBSTR_MAXLEN : values[i].bv_len;
1504 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
1507 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
1508 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
1509 HASH_Init( &HASHcontext );
1510 if( prefix != NULL && prefix->bv_len > 0 ) {
1511 HASH_Update( &HASHcontext,
1512 prefix->bv_val, prefix->bv_len );
1514 HASH_Update( &HASHcontext,
1515 &pre, sizeof( pre ) );
1516 HASH_Update( &HASHcontext,
1517 syntax->ssyn_oid, slen );
1518 HASH_Update( &HASHcontext,
1519 mr->smr_oid, mlen );
1520 HASH_Update( &HASHcontext,
1521 values[i].bv_val, j );
1522 HASH_Final( HASHdigest, &HASHcontext );
1524 ber_dupbv( &keys[nkeys++], &digest );
1527 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
1528 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
1529 HASH_Init( &HASHcontext );
1530 if( prefix != NULL && prefix->bv_len > 0 ) {
1531 HASH_Update( &HASHcontext,
1532 prefix->bv_val, prefix->bv_len );
1534 HASH_Update( &HASHcontext,
1535 &pre, sizeof( pre ) );
1536 HASH_Update( &HASHcontext,
1537 syntax->ssyn_oid, slen );
1538 HASH_Update( &HASHcontext,
1539 mr->smr_oid, mlen );
1540 HASH_Update( &HASHcontext,
1541 &values[i].bv_val[values[i].bv_len-j], j );
1542 HASH_Final( HASHdigest, &HASHcontext );
1544 ber_dupbv( &keys[nkeys++], &digest );
1552 keys[nkeys].bv_val = NULL;
1559 ber_bvarray_free( nvalues );
1561 return LDAP_SUCCESS;
1564 static int caseExactIgnoreSubstringsFilter(
1569 struct berval *prefix,
1570 void * assertedValue,
1573 SubstringsAssertion *sa;
1576 ber_len_t nkeys = 0;
1577 size_t slen, mlen, klen;
1579 HASH_CONTEXT HASHcontext;
1580 unsigned char HASHdigest[HASH_BYTES];
1581 struct berval *value;
1582 struct berval digest;
1584 casefold = ( mr != caseExactSubstringsMatchingRule )
1585 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1587 sa = UTF8SubstringsassertionNormalize( assertedValue, casefold );
1590 return LDAP_SUCCESS;
1593 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
1594 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1599 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
1601 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
1602 if( sa->sa_any[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1603 /* don't bother accounting for stepping */
1604 nkeys += sa->sa_any[i].bv_len -
1605 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
1610 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
1611 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1617 if ( sa->sa_final.bv_val ) free( sa->sa_final.bv_val );
1618 if ( sa->sa_any ) ber_bvarray_free( sa->sa_any );
1619 if ( sa->sa_initial.bv_val ) free( sa->sa_initial.bv_val );
1622 return LDAP_SUCCESS;
1625 digest.bv_val = HASHdigest;
1626 digest.bv_len = sizeof(HASHdigest);
1628 slen = syntax->ssyn_oidlen;
1629 mlen = mr->smr_oidlen;
1631 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
1634 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
1635 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1637 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
1638 value = &sa->sa_initial;
1640 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
1641 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
1643 HASH_Init( &HASHcontext );
1644 if( prefix != NULL && prefix->bv_len > 0 ) {
1645 HASH_Update( &HASHcontext,
1646 prefix->bv_val, prefix->bv_len );
1648 HASH_Update( &HASHcontext,
1649 &pre, sizeof( pre ) );
1650 HASH_Update( &HASHcontext,
1651 syntax->ssyn_oid, slen );
1652 HASH_Update( &HASHcontext,
1653 mr->smr_oid, mlen );
1654 HASH_Update( &HASHcontext,
1655 value->bv_val, klen );
1656 HASH_Final( HASHdigest, &HASHcontext );
1658 ber_dupbv( &keys[nkeys++], &digest );
1661 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
1663 pre = SLAP_INDEX_SUBSTR_PREFIX;
1664 klen = SLAP_INDEX_SUBSTR_MAXLEN;
1666 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
1667 if( sa->sa_any[i].bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
1671 value = &sa->sa_any[i];
1674 j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
1675 j += SLAP_INDEX_SUBSTR_STEP )
1677 HASH_Init( &HASHcontext );
1678 if( prefix != NULL && prefix->bv_len > 0 ) {
1679 HASH_Update( &HASHcontext,
1680 prefix->bv_val, prefix->bv_len );
1682 HASH_Update( &HASHcontext,
1683 &pre, sizeof( pre ) );
1684 HASH_Update( &HASHcontext,
1685 syntax->ssyn_oid, slen );
1686 HASH_Update( &HASHcontext,
1687 mr->smr_oid, mlen );
1688 HASH_Update( &HASHcontext,
1689 &value->bv_val[j], klen );
1690 HASH_Final( HASHdigest, &HASHcontext );
1692 ber_dupbv( &keys[nkeys++], &digest );
1698 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
1699 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1701 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
1702 value = &sa->sa_final;
1704 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
1705 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
1707 HASH_Init( &HASHcontext );
1708 if( prefix != NULL && prefix->bv_len > 0 ) {
1709 HASH_Update( &HASHcontext,
1710 prefix->bv_val, prefix->bv_len );
1712 HASH_Update( &HASHcontext,
1713 &pre, sizeof( pre ) );
1714 HASH_Update( &HASHcontext,
1715 syntax->ssyn_oid, slen );
1716 HASH_Update( &HASHcontext,
1717 mr->smr_oid, mlen );
1718 HASH_Update( &HASHcontext,
1719 &value->bv_val[value->bv_len-klen], klen );
1720 HASH_Final( HASHdigest, &HASHcontext );
1722 ber_dupbv( &keys[nkeys++], &digest );
1726 keys[nkeys].bv_val = NULL;
1732 if ( sa->sa_final.bv_val ) free( sa->sa_final.bv_val );
1733 if ( sa->sa_any ) ber_bvarray_free( sa->sa_any );
1734 if ( sa->sa_initial.bv_val ) free( sa->sa_initial.bv_val );
1737 return LDAP_SUCCESS;
1746 struct berval *value,
1747 void *assertedValue )
1749 *matchp = UTF8bvnormcmp( value,
1750 (struct berval *) assertedValue,
1751 LDAP_UTF8_CASEFOLD );
1752 return LDAP_SUCCESS;
1755 /* Remove all spaces and '-' characters */
1757 telephoneNumberNormalize(
1760 struct berval *normalized )
1764 /* validator should have refused an empty string */
1765 assert( val->bv_len );
1767 q = normalized->bv_val = ch_malloc( val->bv_len + 1 );
1769 for( p = val->bv_val; *p; p++ ) {
1770 if ( ! ( ASCII_SPACE( *p ) || *p == '-' )) {
1776 normalized->bv_len = q - normalized->bv_val;
1778 if( normalized->bv_len == 0 ) {
1779 free( normalized->bv_val );
1780 return LDAP_INVALID_SYNTAX;
1783 return LDAP_SUCCESS;
1789 struct berval *val )
1793 if( val->bv_len == 0 ) {
1794 /* disallow empty strings */
1795 return LDAP_INVALID_SYNTAX;
1798 if( OID_LEADCHAR(val->bv_val[0]) ) {
1800 for(i=1; i < val->bv_len; i++) {
1801 if( OID_SEPARATOR( val->bv_val[i] ) ) {
1802 if( dot++ ) return 1;
1803 } else if ( OID_CHAR( val->bv_val[i] ) ) {
1806 return LDAP_INVALID_SYNTAX;
1810 return !dot ? LDAP_SUCCESS : LDAP_INVALID_SYNTAX;
1812 } else if( DESC_LEADCHAR(val->bv_val[0]) ) {
1813 for(i=1; i < val->bv_len; i++) {
1814 if( !DESC_CHAR(val->bv_val[i] ) ) {
1815 return LDAP_INVALID_SYNTAX;
1819 return LDAP_SUCCESS;
1822 return LDAP_INVALID_SYNTAX;
1831 struct berval *value,
1832 void *assertedValue )
1835 int vsign = 1, avsign = 1; /* default sign = '+' */
1836 struct berval *asserted;
1837 ber_len_t vlen, avlen;
1840 /* Skip leading space/sign/zeroes, and get the sign of the *value number */
1842 vlen = value->bv_len;
1843 if( mr == integerFirstComponentMatchingRule ) {
1844 char *tmp = memchr( v, '$', vlen );
1847 while( vlen && ASCII_SPACE( v[vlen-1] ))
1850 for( ; vlen && ( *v < '1' || '9' < *v ); v++, vlen-- ) /* ANSI 2.2.1 */
1856 /* Do the same with the *assertedValue number */
1857 asserted = (struct berval *) assertedValue;
1858 av = asserted->bv_val;
1859 avlen = asserted->bv_len;
1860 for( ; avlen && ( *av < '1' || '9' < *av ); av++, avlen-- )
1866 match = vsign - avsign;
1868 match = (vlen != avlen
1869 ? ( vlen < avlen ? -1 : 1 )
1870 : memcmp( v, av, vlen ));
1876 return LDAP_SUCCESS;
1882 struct berval *val )
1886 if( !val->bv_len ) return LDAP_INVALID_SYNTAX;
1888 if(( val->bv_val[0] == '+' ) || ( val->bv_val[0] == '-' )) {
1889 if( val->bv_len < 2 ) return LDAP_INVALID_SYNTAX;
1890 } else if( !ASCII_DIGIT(val->bv_val[0]) ) {
1891 return LDAP_INVALID_SYNTAX;
1894 for( i=1; i < val->bv_len; i++ ) {
1895 if( !ASCII_DIGIT(val->bv_val[i]) ) return LDAP_INVALID_SYNTAX;
1898 return LDAP_SUCCESS;
1905 struct berval *normalized )
1915 /* Ignore leading spaces */
1916 while ( len && ( *p == ' ' )) {
1923 negative = ( *p == '-' );
1924 if(( *p == '-' ) || ( *p == '+' )) {
1930 /* Ignore leading zeros */
1931 while ( len && ( *p == '0' )) {
1936 /* If there are no non-zero digits left, the number is zero, otherwise
1937 allocate space for the number and copy it into the buffer */
1939 normalized->bv_val = ch_strdup("0");
1940 normalized->bv_len = 1;
1943 normalized->bv_len = len+negative;
1944 normalized->bv_val = ch_malloc( normalized->bv_len + 1 );
1946 normalized->bv_val[0] = '-';
1948 AC_MEMCPY( normalized->bv_val + negative, p, len );
1949 normalized->bv_val[len+negative] = '\0';
1952 return LDAP_SUCCESS;
1955 /* Index generation function */
1956 static int integerIndexer(
1961 struct berval *prefix,
1968 HASH_CONTEXT HASHcontext;
1969 unsigned char HASHdigest[HASH_BYTES];
1970 struct berval digest;
1971 digest.bv_val = HASHdigest;
1972 digest.bv_len = sizeof(HASHdigest);
1974 for( i=0; values[i].bv_val != NULL; i++ ) {
1975 /* empty - just count them */
1978 /* we should have at least one value at this point */
1981 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
1983 slen = syntax->ssyn_oidlen;
1984 mlen = mr->smr_oidlen;
1986 for( i=0; values[i].bv_val != NULL; i++ ) {
1988 integerNormalize( syntax, &values[i], &norm );
1990 HASH_Init( &HASHcontext );
1991 if( prefix != NULL && prefix->bv_len > 0 ) {
1992 HASH_Update( &HASHcontext,
1993 prefix->bv_val, prefix->bv_len );
1995 HASH_Update( &HASHcontext,
1996 syntax->ssyn_oid, slen );
1997 HASH_Update( &HASHcontext,
1998 mr->smr_oid, mlen );
1999 HASH_Update( &HASHcontext,
2000 norm.bv_val, norm.bv_len );
2001 HASH_Final( HASHdigest, &HASHcontext );
2003 ber_dupbv( &keys[i], &digest );
2004 ch_free( norm.bv_val );
2007 keys[i].bv_val = NULL;
2009 return LDAP_SUCCESS;
2012 /* Index generation function */
2013 static int integerFilter(
2018 struct berval *prefix,
2019 void * assertedValue,
2024 HASH_CONTEXT HASHcontext;
2025 unsigned char HASHdigest[HASH_BYTES];
2027 struct berval digest;
2028 digest.bv_val = HASHdigest;
2029 digest.bv_len = sizeof(HASHdigest);
2031 slen = syntax->ssyn_oidlen;
2032 mlen = mr->smr_oidlen;
2034 integerNormalize( syntax, assertedValue, &norm );
2036 keys = ch_malloc( sizeof( struct berval ) * 2 );
2038 HASH_Init( &HASHcontext );
2039 if( prefix != NULL && prefix->bv_len > 0 ) {
2040 HASH_Update( &HASHcontext,
2041 prefix->bv_val, prefix->bv_len );
2043 HASH_Update( &HASHcontext,
2044 syntax->ssyn_oid, slen );
2045 HASH_Update( &HASHcontext,
2046 mr->smr_oid, mlen );
2047 HASH_Update( &HASHcontext,
2048 norm.bv_val, norm.bv_len );
2049 HASH_Final( HASHdigest, &HASHcontext );
2051 ber_dupbv( &keys[0], &digest );
2052 keys[1].bv_val = NULL;
2053 ch_free( norm.bv_val );
2056 return LDAP_SUCCESS;
2061 countryStringValidate(
2063 struct berval *val )
2065 if( val->bv_len != 2 ) return LDAP_INVALID_SYNTAX;
2067 if( !SLAP_PRINTABLE(val->bv_val[0]) ) {
2068 return LDAP_INVALID_SYNTAX;
2070 if( !SLAP_PRINTABLE(val->bv_val[1]) ) {
2071 return LDAP_INVALID_SYNTAX;
2074 return LDAP_SUCCESS;
2078 printableStringValidate(
2080 struct berval *val )
2084 if( val->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
2086 for(i=0; i < val->bv_len; i++) {
2087 if( !SLAP_PRINTABLE(val->bv_val[i]) ) {
2088 return LDAP_INVALID_SYNTAX;
2092 return LDAP_SUCCESS;
2096 printablesStringValidate(
2098 struct berval *val )
2102 if( val->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
2104 for(i=0,len=0; i < val->bv_len; i++) {
2105 int c = val->bv_val[i];
2109 return LDAP_INVALID_SYNTAX;
2113 } else if ( SLAP_PRINTABLE(c) ) {
2116 return LDAP_INVALID_SYNTAX;
2121 return LDAP_INVALID_SYNTAX;
2124 return LDAP_SUCCESS;
2130 struct berval *val )
2134 if( val->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
2136 for(i=0; i < val->bv_len; i++) {
2137 if( !LDAP_ASCII(val->bv_val[i]) ) {
2138 return LDAP_INVALID_SYNTAX;
2142 return LDAP_SUCCESS;
2149 struct berval *normalized )
2153 assert( val->bv_len );
2157 /* Ignore initial whitespace */
2158 while ( ASCII_SPACE( *p ) ) {
2162 normalized->bv_val = ch_strdup( p );
2163 p = q = normalized->bv_val;
2166 if ( ASCII_SPACE( *p ) ) {
2169 /* Ignore the extra whitespace */
2170 while ( ASCII_SPACE( *p ) ) {
2178 assert( normalized->bv_val <= p );
2182 * If the string ended in space, backup the pointer one
2183 * position. One is enough because the above loop collapsed
2184 * all whitespace to a single space.
2187 if ( ASCII_SPACE( q[-1] ) ) {
2191 /* null terminate */
2194 normalized->bv_len = q - normalized->bv_val;
2196 if( normalized->bv_len == 0 ) {
2197 normalized->bv_val = ch_realloc( normalized->bv_val, 2 );
2198 normalized->bv_val[0] = ' ';
2199 normalized->bv_val[1] = '\0';
2200 normalized->bv_len = 1;
2203 return LDAP_SUCCESS;
2212 struct berval *value,
2213 void *assertedValue )
2215 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
2218 match = strncmp( value->bv_val,
2219 ((struct berval *) assertedValue)->bv_val,
2224 return LDAP_SUCCESS;
2228 caseExactIA5SubstringsMatch(
2233 struct berval *value,
2234 void *assertedValue )
2237 SubstringsAssertion *sub = assertedValue;
2238 struct berval left = *value;
2242 /* Add up asserted input length */
2243 if( sub->sa_initial.bv_val ) {
2244 inlen += sub->sa_initial.bv_len;
2247 for(i=0; sub->sa_any[i].bv_val != NULL; i++) {
2248 inlen += sub->sa_any[i].bv_len;
2251 if( sub->sa_final.bv_val ) {
2252 inlen += sub->sa_final.bv_len;
2255 if( sub->sa_initial.bv_val ) {
2256 if( inlen > left.bv_len ) {
2261 match = strncmp( sub->sa_initial.bv_val, left.bv_val,
2262 sub->sa_initial.bv_len );
2268 left.bv_val += sub->sa_initial.bv_len;
2269 left.bv_len -= sub->sa_initial.bv_len;
2270 inlen -= sub->sa_initial.bv_len;
2273 if( sub->sa_final.bv_val ) {
2274 if( inlen > left.bv_len ) {
2279 match = strncmp( sub->sa_final.bv_val,
2280 &left.bv_val[left.bv_len - sub->sa_final.bv_len],
2281 sub->sa_final.bv_len );
2287 left.bv_len -= sub->sa_final.bv_len;
2288 inlen -= sub->sa_final.bv_len;
2292 for(i=0; sub->sa_any[i].bv_val; i++) {
2297 if( inlen > left.bv_len ) {
2298 /* not enough length */
2303 if( sub->sa_any[i].bv_len == 0 ) {
2307 p = strchr( left.bv_val, *sub->sa_any[i].bv_val );
2314 idx = p - left.bv_val;
2316 if( idx >= left.bv_len ) {
2317 /* this shouldn't happen */
2324 if( sub->sa_any[i].bv_len > left.bv_len ) {
2325 /* not enough left */
2330 match = strncmp( left.bv_val,
2331 sub->sa_any[i].bv_val,
2332 sub->sa_any[i].bv_len );
2340 left.bv_val += sub->sa_any[i].bv_len;
2341 left.bv_len -= sub->sa_any[i].bv_len;
2342 inlen -= sub->sa_any[i].bv_len;
2348 return LDAP_SUCCESS;
2351 /* Index generation function */
2352 static int caseExactIA5Indexer(
2357 struct berval *prefix,
2364 HASH_CONTEXT HASHcontext;
2365 unsigned char HASHdigest[HASH_BYTES];
2366 struct berval digest;
2367 digest.bv_val = HASHdigest;
2368 digest.bv_len = sizeof(HASHdigest);
2370 for( i=0; values[i].bv_val != NULL; i++ ) {
2371 /* empty - just count them */
2374 /* we should have at least one value at this point */
2377 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
2379 slen = syntax->ssyn_oidlen;
2380 mlen = mr->smr_oidlen;
2382 for( i=0; values[i].bv_val != NULL; i++ ) {
2383 struct berval *value = &values[i];
2385 HASH_Init( &HASHcontext );
2386 if( prefix != NULL && prefix->bv_len > 0 ) {
2387 HASH_Update( &HASHcontext,
2388 prefix->bv_val, prefix->bv_len );
2390 HASH_Update( &HASHcontext,
2391 syntax->ssyn_oid, slen );
2392 HASH_Update( &HASHcontext,
2393 mr->smr_oid, mlen );
2394 HASH_Update( &HASHcontext,
2395 value->bv_val, value->bv_len );
2396 HASH_Final( HASHdigest, &HASHcontext );
2398 ber_dupbv( &keys[i], &digest );
2401 keys[i].bv_val = NULL;
2403 return LDAP_SUCCESS;
2406 /* Index generation function */
2407 static int caseExactIA5Filter(
2412 struct berval *prefix,
2413 void * assertedValue,
2418 HASH_CONTEXT HASHcontext;
2419 unsigned char HASHdigest[HASH_BYTES];
2420 struct berval *value;
2421 struct berval digest;
2422 digest.bv_val = HASHdigest;
2423 digest.bv_len = sizeof(HASHdigest);
2425 slen = syntax->ssyn_oidlen;
2426 mlen = mr->smr_oidlen;
2428 value = (struct berval *) assertedValue;
2430 keys = ch_malloc( sizeof( struct berval ) * 2 );
2432 HASH_Init( &HASHcontext );
2433 if( prefix != NULL && prefix->bv_len > 0 ) {
2434 HASH_Update( &HASHcontext,
2435 prefix->bv_val, prefix->bv_len );
2437 HASH_Update( &HASHcontext,
2438 syntax->ssyn_oid, slen );
2439 HASH_Update( &HASHcontext,
2440 mr->smr_oid, mlen );
2441 HASH_Update( &HASHcontext,
2442 value->bv_val, value->bv_len );
2443 HASH_Final( HASHdigest, &HASHcontext );
2445 ber_dupbv( &keys[0], &digest );
2446 keys[1].bv_val = NULL;
2449 return LDAP_SUCCESS;
2452 /* Substrings Index generation function */
2453 static int caseExactIA5SubstringsIndexer(
2458 struct berval *prefix,
2465 HASH_CONTEXT HASHcontext;
2466 unsigned char HASHdigest[HASH_BYTES];
2467 struct berval digest;
2468 digest.bv_val = HASHdigest;
2469 digest.bv_len = sizeof(HASHdigest);
2471 /* we should have at least one value at this point */
2472 assert( values != NULL && values[0].bv_val != NULL );
2475 for( i=0; values[i].bv_val != NULL; i++ ) {
2476 /* count number of indices to generate */
2477 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
2481 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
2482 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2483 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2484 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2486 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2490 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
2491 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2492 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
2496 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
2497 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2498 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2499 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2501 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2507 /* no keys to generate */
2509 return LDAP_SUCCESS;
2512 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
2514 slen = syntax->ssyn_oidlen;
2515 mlen = mr->smr_oidlen;
2518 for( i=0; values[i].bv_val != NULL; i++ ) {
2520 struct berval *value;
2523 if( value->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
2525 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
2526 ( value->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
2528 char pre = SLAP_INDEX_SUBSTR_PREFIX;
2529 max = value->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
2531 for( j=0; j<max; j++ ) {
2532 HASH_Init( &HASHcontext );
2533 if( prefix != NULL && prefix->bv_len > 0 ) {
2534 HASH_Update( &HASHcontext,
2535 prefix->bv_val, prefix->bv_len );
2538 HASH_Update( &HASHcontext,
2539 &pre, sizeof( pre ) );
2540 HASH_Update( &HASHcontext,
2541 syntax->ssyn_oid, slen );
2542 HASH_Update( &HASHcontext,
2543 mr->smr_oid, mlen );
2544 HASH_Update( &HASHcontext,
2546 SLAP_INDEX_SUBSTR_MAXLEN );
2547 HASH_Final( HASHdigest, &HASHcontext );
2549 ber_dupbv( &keys[nkeys++], &digest );
2553 max = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2554 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2556 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
2559 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
2560 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
2561 HASH_Init( &HASHcontext );
2562 if( prefix != NULL && prefix->bv_len > 0 ) {
2563 HASH_Update( &HASHcontext,
2564 prefix->bv_val, prefix->bv_len );
2566 HASH_Update( &HASHcontext,
2567 &pre, sizeof( pre ) );
2568 HASH_Update( &HASHcontext,
2569 syntax->ssyn_oid, slen );
2570 HASH_Update( &HASHcontext,
2571 mr->smr_oid, mlen );
2572 HASH_Update( &HASHcontext,
2574 HASH_Final( HASHdigest, &HASHcontext );
2576 ber_dupbv( &keys[nkeys++], &digest );
2579 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
2580 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
2581 HASH_Init( &HASHcontext );
2582 if( prefix != NULL && prefix->bv_len > 0 ) {
2583 HASH_Update( &HASHcontext,
2584 prefix->bv_val, prefix->bv_len );
2586 HASH_Update( &HASHcontext,
2587 &pre, sizeof( pre ) );
2588 HASH_Update( &HASHcontext,
2589 syntax->ssyn_oid, slen );
2590 HASH_Update( &HASHcontext,
2591 mr->smr_oid, mlen );
2592 HASH_Update( &HASHcontext,
2593 &value->bv_val[value->bv_len-j], j );
2594 HASH_Final( HASHdigest, &HASHcontext );
2596 ber_dupbv( &keys[nkeys++], &digest );
2603 keys[nkeys].bv_val = NULL;
2610 return LDAP_SUCCESS;
2613 static int caseExactIA5SubstringsFilter(
2618 struct berval *prefix,
2619 void * assertedValue,
2622 SubstringsAssertion *sa = assertedValue;
2624 ber_len_t nkeys = 0;
2625 size_t slen, mlen, klen;
2627 HASH_CONTEXT HASHcontext;
2628 unsigned char HASHdigest[HASH_BYTES];
2629 struct berval *value;
2630 struct berval digest;
2632 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
2633 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2638 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
2640 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
2641 if( sa->sa_any[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2642 /* don't bother accounting for stepping */
2643 nkeys += sa->sa_any[i].bv_len -
2644 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
2649 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
2650 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2657 return LDAP_SUCCESS;
2660 digest.bv_val = HASHdigest;
2661 digest.bv_len = sizeof(HASHdigest);
2663 slen = syntax->ssyn_oidlen;
2664 mlen = mr->smr_oidlen;
2666 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
2669 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
2670 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2672 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
2673 value = &sa->sa_initial;
2675 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2676 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2678 HASH_Init( &HASHcontext );
2679 if( prefix != NULL && prefix->bv_len > 0 ) {
2680 HASH_Update( &HASHcontext,
2681 prefix->bv_val, prefix->bv_len );
2683 HASH_Update( &HASHcontext,
2684 &pre, sizeof( pre ) );
2685 HASH_Update( &HASHcontext,
2686 syntax->ssyn_oid, slen );
2687 HASH_Update( &HASHcontext,
2688 mr->smr_oid, mlen );
2689 HASH_Update( &HASHcontext,
2690 value->bv_val, klen );
2691 HASH_Final( HASHdigest, &HASHcontext );
2693 ber_dupbv( &keys[nkeys++], &digest );
2696 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
2698 pre = SLAP_INDEX_SUBSTR_PREFIX;
2699 klen = SLAP_INDEX_SUBSTR_MAXLEN;
2701 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
2702 if( sa->sa_any[i].bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
2706 value = &sa->sa_any[i];
2709 j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
2710 j += SLAP_INDEX_SUBSTR_STEP )
2712 HASH_Init( &HASHcontext );
2713 if( prefix != NULL && prefix->bv_len > 0 ) {
2714 HASH_Update( &HASHcontext,
2715 prefix->bv_val, prefix->bv_len );
2717 HASH_Update( &HASHcontext,
2718 &pre, sizeof( pre ) );
2719 HASH_Update( &HASHcontext,
2720 syntax->ssyn_oid, slen );
2721 HASH_Update( &HASHcontext,
2722 mr->smr_oid, mlen );
2723 HASH_Update( &HASHcontext,
2724 &value->bv_val[j], klen );
2725 HASH_Final( HASHdigest, &HASHcontext );
2727 ber_dupbv( &keys[nkeys++], &digest );
2732 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
2733 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2735 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
2736 value = &sa->sa_final;
2738 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2739 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2741 HASH_Init( &HASHcontext );
2742 if( prefix != NULL && prefix->bv_len > 0 ) {
2743 HASH_Update( &HASHcontext,
2744 prefix->bv_val, prefix->bv_len );
2746 HASH_Update( &HASHcontext,
2747 &pre, sizeof( pre ) );
2748 HASH_Update( &HASHcontext,
2749 syntax->ssyn_oid, slen );
2750 HASH_Update( &HASHcontext,
2751 mr->smr_oid, mlen );
2752 HASH_Update( &HASHcontext,
2753 &value->bv_val[value->bv_len-klen], klen );
2754 HASH_Final( HASHdigest, &HASHcontext );
2756 ber_dupbv( &keys[nkeys++], &digest );
2760 keys[nkeys].bv_val = NULL;
2767 return LDAP_SUCCESS;
2776 struct berval *value,
2777 void *assertedValue )
2779 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
2781 if( match == 0 && value->bv_len ) {
2782 match = strncasecmp( value->bv_val,
2783 ((struct berval *) assertedValue)->bv_val,
2788 return LDAP_SUCCESS;
2792 caseIgnoreIA5SubstringsMatch(
2797 struct berval *value,
2798 void *assertedValue )
2801 SubstringsAssertion *sub = assertedValue;
2802 struct berval left = *value;
2806 /* Add up asserted input length */
2807 if( sub->sa_initial.bv_val ) {
2808 inlen += sub->sa_initial.bv_len;
2811 for(i=0; sub->sa_any[i].bv_val != NULL; i++) {
2812 inlen += sub->sa_any[i].bv_len;
2815 if( sub->sa_final.bv_val ) {
2816 inlen += sub->sa_final.bv_len;
2819 if( sub->sa_initial.bv_val ) {
2820 if( inlen > left.bv_len ) {
2825 match = strncasecmp( sub->sa_initial.bv_val, left.bv_val,
2826 sub->sa_initial.bv_len );
2832 left.bv_val += sub->sa_initial.bv_len;
2833 left.bv_len -= sub->sa_initial.bv_len;
2834 inlen -= sub->sa_initial.bv_len;
2837 if( sub->sa_final.bv_val ) {
2838 if( inlen > left.bv_len ) {
2843 match = strncasecmp( sub->sa_final.bv_val,
2844 &left.bv_val[left.bv_len - sub->sa_final.bv_len],
2845 sub->sa_final.bv_len );
2851 left.bv_len -= sub->sa_final.bv_len;
2852 inlen -= sub->sa_final.bv_len;
2856 for(i=0; sub->sa_any[i].bv_val; i++) {
2861 if( inlen > left.bv_len ) {
2862 /* not enough length */
2867 if( sub->sa_any[i].bv_len == 0 ) {
2871 p = bvcasechr( &left, *sub->sa_any[i].bv_val, &idx );
2878 assert( idx < left.bv_len );
2879 if( idx >= left.bv_len ) {
2880 /* this shouldn't happen */
2887 if( sub->sa_any[i].bv_len > left.bv_len ) {
2888 /* not enough left */
2893 match = strncasecmp( left.bv_val,
2894 sub->sa_any[i].bv_val,
2895 sub->sa_any[i].bv_len );
2904 left.bv_val += sub->sa_any[i].bv_len;
2905 left.bv_len -= sub->sa_any[i].bv_len;
2906 inlen -= sub->sa_any[i].bv_len;
2912 return LDAP_SUCCESS;
2915 /* Index generation function */
2916 static int caseIgnoreIA5Indexer(
2921 struct berval *prefix,
2926 int rc = LDAP_SUCCESS;
2929 HASH_CONTEXT HASHcontext;
2930 unsigned char HASHdigest[HASH_BYTES];
2931 struct berval digest;
2932 digest.bv_val = HASHdigest;
2933 digest.bv_len = sizeof(HASHdigest);
2935 /* we should have at least one value at this point */
2936 assert( values != NULL && values[0].bv_val != NULL );
2938 for( i=0; values[i].bv_val != NULL; i++ ) {
2939 /* just count them */
2942 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
2944 slen = syntax->ssyn_oidlen;
2945 mlen = mr->smr_oidlen;
2947 for( i=0; values[i].bv_val != NULL; i++ ) {
2948 struct berval value;
2950 if( mr->smr_normalize ) {
2951 rc = (mr->smr_normalize)( use, syntax, mr, &values[i], &value );
2952 if( rc != LDAP_SUCCESS ) {
2955 } else if ( mr->smr_syntax->ssyn_normalize ) {
2956 rc = (mr->smr_syntax->ssyn_normalize)( syntax, &values[i], &value );
2957 if( rc != LDAP_SUCCESS ) {
2961 ber_dupbv( &value, &values[i] );
2964 ldap_pvt_str2lower( value.bv_val );
2966 HASH_Init( &HASHcontext );
2967 if( prefix != NULL && prefix->bv_len > 0 ) {
2968 HASH_Update( &HASHcontext,
2969 prefix->bv_val, prefix->bv_len );
2971 HASH_Update( &HASHcontext,
2972 syntax->ssyn_oid, slen );
2973 HASH_Update( &HASHcontext,
2974 mr->smr_oid, mlen );
2975 HASH_Update( &HASHcontext,
2976 value.bv_val, value.bv_len );
2977 HASH_Final( HASHdigest, &HASHcontext );
2979 free( value.bv_val );
2981 ber_dupbv( &keys[i], &digest );
2984 keys[i].bv_val = NULL;
2985 if( rc != LDAP_SUCCESS ) {
2986 ber_bvarray_free( keys );
2993 /* Index generation function */
2994 static int caseIgnoreIA5Filter(
2999 struct berval *prefix,
3000 void * assertedValue,
3005 HASH_CONTEXT HASHcontext;
3006 unsigned char HASHdigest[HASH_BYTES];
3007 struct berval value;
3008 struct berval digest;
3009 digest.bv_val = HASHdigest;
3010 digest.bv_len = sizeof(HASHdigest);
3012 slen = syntax->ssyn_oidlen;
3013 mlen = mr->smr_oidlen;
3015 ber_dupbv( &value, (struct berval *) assertedValue );
3016 ldap_pvt_str2lower( value.bv_val );
3018 keys = ch_malloc( sizeof( struct berval ) * 2 );
3020 HASH_Init( &HASHcontext );
3021 if( prefix != NULL && prefix->bv_len > 0 ) {
3022 HASH_Update( &HASHcontext,
3023 prefix->bv_val, prefix->bv_len );
3025 HASH_Update( &HASHcontext,
3026 syntax->ssyn_oid, slen );
3027 HASH_Update( &HASHcontext,
3028 mr->smr_oid, mlen );
3029 HASH_Update( &HASHcontext,
3030 value.bv_val, value.bv_len );
3031 HASH_Final( HASHdigest, &HASHcontext );
3033 ber_dupbv( &keys[0], &digest );
3034 keys[1].bv_val = NULL;
3036 free( value.bv_val );
3040 return LDAP_SUCCESS;
3043 /* Substrings Index generation function */
3044 static int caseIgnoreIA5SubstringsIndexer(
3049 struct berval *prefix,
3056 HASH_CONTEXT HASHcontext;
3057 unsigned char HASHdigest[HASH_BYTES];
3058 struct berval digest;
3059 digest.bv_val = HASHdigest;
3060 digest.bv_len = sizeof(HASHdigest);
3062 /* we should have at least one value at this point */
3063 assert( values != NULL && values[0].bv_val != NULL );
3066 for( i=0; values[i].bv_val != NULL; i++ ) {
3067 /* count number of indices to generate */
3068 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
3072 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
3073 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3074 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
3075 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
3077 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
3081 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
3082 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3083 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
3087 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
3088 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3089 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
3090 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
3092 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
3098 /* no keys to generate */
3100 return LDAP_SUCCESS;
3103 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
3105 slen = syntax->ssyn_oidlen;
3106 mlen = mr->smr_oidlen;
3109 for( i=0; values[i].bv_val != NULL; i++ ) {
3111 struct berval value;
3113 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
3115 ber_dupbv( &value, &values[i] );
3116 ldap_pvt_str2lower( value.bv_val );
3118 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
3119 ( value.bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
3121 char pre = SLAP_INDEX_SUBSTR_PREFIX;
3122 max = value.bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
3124 for( j=0; j<max; j++ ) {
3125 HASH_Init( &HASHcontext );
3126 if( prefix != NULL && prefix->bv_len > 0 ) {
3127 HASH_Update( &HASHcontext,
3128 prefix->bv_val, prefix->bv_len );
3131 HASH_Update( &HASHcontext,
3132 &pre, sizeof( pre ) );
3133 HASH_Update( &HASHcontext,
3134 syntax->ssyn_oid, slen );
3135 HASH_Update( &HASHcontext,
3136 mr->smr_oid, mlen );
3137 HASH_Update( &HASHcontext,
3139 SLAP_INDEX_SUBSTR_MAXLEN );
3140 HASH_Final( HASHdigest, &HASHcontext );
3142 ber_dupbv( &keys[nkeys++], &digest );
3146 max = SLAP_INDEX_SUBSTR_MAXLEN < value.bv_len
3147 ? SLAP_INDEX_SUBSTR_MAXLEN : value.bv_len;
3149 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
3152 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
3153 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
3154 HASH_Init( &HASHcontext );
3155 if( prefix != NULL && prefix->bv_len > 0 ) {
3156 HASH_Update( &HASHcontext,
3157 prefix->bv_val, prefix->bv_len );
3159 HASH_Update( &HASHcontext,
3160 &pre, sizeof( pre ) );
3161 HASH_Update( &HASHcontext,
3162 syntax->ssyn_oid, slen );
3163 HASH_Update( &HASHcontext,
3164 mr->smr_oid, mlen );
3165 HASH_Update( &HASHcontext,
3167 HASH_Final( HASHdigest, &HASHcontext );
3169 ber_dupbv( &keys[nkeys++], &digest );
3172 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
3173 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
3174 HASH_Init( &HASHcontext );
3175 if( prefix != NULL && prefix->bv_len > 0 ) {
3176 HASH_Update( &HASHcontext,
3177 prefix->bv_val, prefix->bv_len );
3179 HASH_Update( &HASHcontext,
3180 &pre, sizeof( pre ) );
3181 HASH_Update( &HASHcontext,
3182 syntax->ssyn_oid, slen );
3183 HASH_Update( &HASHcontext,
3184 mr->smr_oid, mlen );
3185 HASH_Update( &HASHcontext,
3186 &value.bv_val[value.bv_len-j], j );
3187 HASH_Final( HASHdigest, &HASHcontext );
3189 ber_dupbv( &keys[nkeys++], &digest );
3194 free( value.bv_val );
3198 keys[nkeys].bv_val = NULL;
3205 return LDAP_SUCCESS;
3208 static int caseIgnoreIA5SubstringsFilter(
3213 struct berval *prefix,
3214 void * assertedValue,
3217 SubstringsAssertion *sa = assertedValue;
3219 ber_len_t nkeys = 0;
3220 size_t slen, mlen, klen;
3222 HASH_CONTEXT HASHcontext;
3223 unsigned char HASHdigest[HASH_BYTES];
3224 struct berval value;
3225 struct berval digest;
3227 if((flags & SLAP_INDEX_SUBSTR_INITIAL) && sa->sa_initial.bv_val != NULL &&
3228 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3233 if((flags & SLAP_INDEX_SUBSTR_ANY) && sa->sa_any != NULL ) {
3235 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
3236 if( sa->sa_any[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3237 /* don't bother accounting for stepping */
3238 nkeys += sa->sa_any[i].bv_len -
3239 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
3244 if((flags & SLAP_INDEX_SUBSTR_FINAL) && sa->sa_final.bv_val != NULL &&
3245 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3252 return LDAP_SUCCESS;
3255 digest.bv_val = HASHdigest;
3256 digest.bv_len = sizeof(HASHdigest);
3258 slen = syntax->ssyn_oidlen;
3259 mlen = mr->smr_oidlen;
3261 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
3264 if((flags & SLAP_INDEX_SUBSTR_INITIAL) && sa->sa_initial.bv_val != NULL &&
3265 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3267 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
3268 ber_dupbv( &value, &sa->sa_initial );
3269 ldap_pvt_str2lower( value.bv_val );
3271 klen = SLAP_INDEX_SUBSTR_MAXLEN < value.bv_len
3272 ? SLAP_INDEX_SUBSTR_MAXLEN : value.bv_len;
3274 HASH_Init( &HASHcontext );
3275 if( prefix != NULL && prefix->bv_len > 0 ) {
3276 HASH_Update( &HASHcontext,
3277 prefix->bv_val, prefix->bv_len );
3279 HASH_Update( &HASHcontext,
3280 &pre, sizeof( pre ) );
3281 HASH_Update( &HASHcontext,
3282 syntax->ssyn_oid, slen );
3283 HASH_Update( &HASHcontext,
3284 mr->smr_oid, mlen );
3285 HASH_Update( &HASHcontext,
3286 value.bv_val, klen );
3287 HASH_Final( HASHdigest, &HASHcontext );
3289 free( value.bv_val );
3290 ber_dupbv( &keys[nkeys++], &digest );
3293 if((flags & SLAP_INDEX_SUBSTR_ANY) && sa->sa_any != NULL ) {
3295 pre = SLAP_INDEX_SUBSTR_PREFIX;
3296 klen = SLAP_INDEX_SUBSTR_MAXLEN;
3298 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
3299 if( sa->sa_any[i].bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
3303 ber_dupbv( &value, &sa->sa_any[i] );
3304 ldap_pvt_str2lower( value.bv_val );
3307 j <= value.bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
3308 j += SLAP_INDEX_SUBSTR_STEP )
3310 HASH_Init( &HASHcontext );
3311 if( prefix != NULL && prefix->bv_len > 0 ) {
3312 HASH_Update( &HASHcontext,
3313 prefix->bv_val, prefix->bv_len );
3315 HASH_Update( &HASHcontext,
3316 &pre, sizeof( pre ) );
3317 HASH_Update( &HASHcontext,
3318 syntax->ssyn_oid, slen );
3319 HASH_Update( &HASHcontext,
3320 mr->smr_oid, mlen );
3321 HASH_Update( &HASHcontext,
3322 &value.bv_val[j], klen );
3323 HASH_Final( HASHdigest, &HASHcontext );
3325 ber_dupbv( &keys[nkeys++], &digest );
3328 free( value.bv_val );
3332 if((flags & SLAP_INDEX_SUBSTR_FINAL) && sa->sa_final.bv_val != NULL &&
3333 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3335 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
3336 ber_dupbv( &value, &sa->sa_final );
3337 ldap_pvt_str2lower( value.bv_val );
3339 klen = SLAP_INDEX_SUBSTR_MAXLEN < value.bv_len
3340 ? SLAP_INDEX_SUBSTR_MAXLEN : value.bv_len;
3342 HASH_Init( &HASHcontext );
3343 if( prefix != NULL && prefix->bv_len > 0 ) {
3344 HASH_Update( &HASHcontext,
3345 prefix->bv_val, prefix->bv_len );
3347 HASH_Update( &HASHcontext,
3348 &pre, sizeof( pre ) );
3349 HASH_Update( &HASHcontext,
3350 syntax->ssyn_oid, slen );
3351 HASH_Update( &HASHcontext,
3352 mr->smr_oid, mlen );
3353 HASH_Update( &HASHcontext,
3354 &value.bv_val[value.bv_len-klen], klen );
3355 HASH_Final( HASHdigest, &HASHcontext );
3357 free( value.bv_val );
3358 ber_dupbv( &keys[nkeys++], &digest );
3362 keys[nkeys].bv_val = NULL;
3369 return LDAP_SUCCESS;
3373 numericStringValidate(
3379 if( in->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
3381 for(i=0; i < in->bv_len; i++) {
3382 if( !SLAP_NUMERIC(in->bv_val[i]) ) {
3383 return LDAP_INVALID_SYNTAX;
3387 return LDAP_SUCCESS;
3391 numericStringNormalize(
3394 struct berval *normalized )
3396 /* removal all spaces */
3399 assert( val->bv_len );
3401 normalized->bv_val = ch_malloc( val->bv_len + 1 );
3404 q = normalized->bv_val;
3407 if ( ASCII_SPACE( *p ) ) {
3408 /* Ignore whitespace */
3415 /* we should have copied no more then is in val */
3416 assert( (q - normalized->bv_val) <= (p - val->bv_val) );
3418 /* null terminate */
3421 normalized->bv_len = q - normalized->bv_val;
3423 if( normalized->bv_len == 0 ) {
3424 normalized->bv_val = ch_realloc( normalized->bv_val, 2 );
3425 normalized->bv_val[0] = ' ';
3426 normalized->bv_val[1] = '\0';
3427 normalized->bv_len = 1;
3430 return LDAP_SUCCESS;
3434 objectIdentifierFirstComponentMatch(
3439 struct berval *value,
3440 void *assertedValue )
3442 int rc = LDAP_SUCCESS;
3444 struct berval *asserted = (struct berval *) assertedValue;
3448 if( value->bv_len == 0 || value->bv_val[0] != '(' /*')'*/ ) {
3449 return LDAP_INVALID_SYNTAX;
3452 /* trim leading white space */
3453 for( i=1; ASCII_SPACE(value->bv_val[i]) && i < value->bv_len; i++ ) {
3457 /* grab next word */
3458 oid.bv_val = &value->bv_val[i];
3459 j = value->bv_len - i;
3460 for( i=0; !ASCII_SPACE(oid.bv_val[i]) && i < j; i++ ) {
3465 /* insert attributeTypes, objectclass check here */
3466 if( OID_LEADCHAR(asserted->bv_val[0]) ) {
3467 rc = objectIdentifierMatch( &match, flags, syntax, mr, &oid, asserted );
3470 if ( !strcmp( syntax->ssyn_oid, SLAP_SYNTAX_MATCHINGRULES_OID ) ) {
3471 MatchingRule *asserted_mr = mr_bvfind( asserted );
3472 MatchingRule *stored_mr = mr_bvfind( &oid );
3474 if( asserted_mr == NULL ) {
3475 rc = SLAPD_COMPARE_UNDEFINED;
3477 match = asserted_mr != stored_mr;
3480 } else if ( !strcmp( syntax->ssyn_oid,
3481 SLAP_SYNTAX_ATTRIBUTETYPES_OID ) )
3483 AttributeType *asserted_at = at_bvfind( asserted );
3484 AttributeType *stored_at = at_bvfind( &oid );
3486 if( asserted_at == NULL ) {
3487 rc = SLAPD_COMPARE_UNDEFINED;
3489 match = asserted_at != stored_at;
3492 } else if ( !strcmp( syntax->ssyn_oid,
3493 SLAP_SYNTAX_OBJECTCLASSES_OID ) )
3495 ObjectClass *asserted_oc = oc_bvfind( asserted );
3496 ObjectClass *stored_oc = oc_bvfind( &oid );
3498 if( asserted_oc == NULL ) {
3499 rc = SLAPD_COMPARE_UNDEFINED;
3501 match = asserted_oc != stored_oc;
3507 LDAP_LOG( CONFIG, ENTRY,
3508 "objectIdentifierFirstComponentMatch: %d\n %s\n %s\n",
3509 match, value->bv_val, asserted->bv_val );
3511 Debug( LDAP_DEBUG_ARGS, "objectIdentifierFirstComponentMatch "
3512 "%d\n\t\"%s\"\n\t\"%s\"\n",
3513 match, value->bv_val, asserted->bv_val );
3516 if( rc == LDAP_SUCCESS ) *matchp = match;
3526 struct berval *value,
3527 void *assertedValue )
3529 long lValue, lAssertedValue;
3531 /* safe to assume integers are NUL terminated? */
3532 lValue = strtol(value->bv_val, NULL, 10);
3533 if(( lValue == LONG_MIN || lValue == LONG_MAX) && errno == ERANGE ) {
3534 return LDAP_CONSTRAINT_VIOLATION;
3537 lAssertedValue = strtol(((struct berval *)assertedValue)->bv_val, NULL, 10);
3538 if(( lAssertedValue == LONG_MIN || lAssertedValue == LONG_MAX)
3539 && errno == ERANGE )
3541 return LDAP_CONSTRAINT_VIOLATION;
3544 *matchp = (lValue & lAssertedValue) ? 0 : 1;
3545 return LDAP_SUCCESS;
3554 struct berval *value,
3555 void *assertedValue )
3557 long lValue, lAssertedValue;
3559 /* safe to assume integers are NUL terminated? */
3560 lValue = strtol(value->bv_val, NULL, 10);
3561 if(( lValue == LONG_MIN || lValue == LONG_MAX) && errno == ERANGE ) {
3562 return LDAP_CONSTRAINT_VIOLATION;
3565 lAssertedValue = strtol(((struct berval *)assertedValue)->bv_val, NULL, 10);
3566 if(( lAssertedValue == LONG_MIN || lAssertedValue == LONG_MAX)
3567 && errno == ERANGE )
3569 return LDAP_CONSTRAINT_VIOLATION;
3572 *matchp = (lValue | lAssertedValue) ? 0 : -1;
3573 return LDAP_SUCCESS;
3577 #include <openssl/x509.h>
3578 #include <openssl/err.h>
3581 * Next function returns a string representation of a ASN1_INTEGER.
3582 * It works for unlimited lengths.
3585 static struct berval *
3586 asn1_integer2str(ASN1_INTEGER *a, struct berval *bv)
3590 static char digit[] = "0123456789";
3592 /* We work backwards, make it fill from the end of buf */
3593 p = buf + sizeof(buf) - 1;
3596 if ( a == NULL || a->length == 0 ) {
3604 /* We want to preserve the original */
3605 copy = ch_malloc(n*sizeof(unsigned int));
3606 for (i = 0; i<n; i++) {
3607 copy[i] = a->data[i];
3611 * base indicates the index of the most significant
3612 * byte that might be nonzero. When it goes off the
3613 * end, we now there is nothing left to do.
3619 for (i = base; i<n; i++ ) {
3620 copy[i] += carry*256;
3621 carry = copy[i] % 10;
3626 * Way too large, we need to leave
3627 * room for sign if negative
3632 *--p = digit[carry];
3634 if (copy[base] == 0) base++;
3639 if ( a->type == V_ASN1_NEG_INTEGER ) {
3643 return ber_str2bv( p, 0, 1, bv );
3647 * Given a certificate in DER format, extract the corresponding
3648 * assertion value for certificateExactMatch
3651 certificateExactConvert(
3653 struct berval * out )
3656 unsigned char *p = in->bv_val;
3657 struct berval serial;
3658 struct berval issuer_dn;
3660 xcert = d2i_X509(NULL, &p, in->bv_len);
3663 LDAP_LOG( CONFIG, ENTRY,
3664 "certificateExactConvert: error parsing cert: %s\n",
3665 ERR_error_string(ERR_get_error(),NULL), 0, 0 );
3667 Debug( LDAP_DEBUG_ARGS, "certificateExactConvert: "
3668 "error parsing cert: %s\n",
3669 ERR_error_string(ERR_get_error(),NULL), NULL, NULL );
3671 return LDAP_INVALID_SYNTAX;
3674 if ( !asn1_integer2str(xcert->cert_info->serialNumber, &serial) ) {
3676 return LDAP_INVALID_SYNTAX;
3678 if ( dnX509normalize(X509_get_issuer_name(xcert), &issuer_dn )
3682 ber_memfree(serial.bv_val);
3683 return LDAP_INVALID_SYNTAX;
3688 out->bv_len = serial.bv_len + issuer_dn.bv_len + sizeof(" $ ");
3689 out->bv_val = ch_malloc(out->bv_len);
3691 AC_MEMCPY(p, serial.bv_val, serial.bv_len);
3693 AC_MEMCPY(p, " $ ", sizeof(" $ ")-1);
3695 AC_MEMCPY(p, issuer_dn.bv_val, issuer_dn.bv_len);
3696 p += issuer_dn.bv_len;
3700 LDAP_LOG( CONFIG, ARGS,
3701 "certificateExactConvert: \n %s\n", out->bv_val, 0, 0 );
3703 Debug( LDAP_DEBUG_ARGS, "certificateExactConvert "
3705 out->bv_val, NULL, NULL );
3708 ber_memfree(serial.bv_val);
3709 ber_memfree(issuer_dn.bv_val);
3711 return LDAP_SUCCESS;
3715 serial_and_issuer_parse(
3716 struct berval *assertion,
3717 struct berval *serial,
3718 struct berval *issuer_dn
3726 begin = assertion->bv_val;
3727 end = assertion->bv_val+assertion->bv_len-1;
3728 for (p=begin; p<=end && *p != '$'; p++) /* empty */ ;
3729 if ( p > end ) return LDAP_INVALID_SYNTAX;
3731 /* p now points at the $ sign, now use
3732 * begin and end to delimit the serial number
3734 while (ASCII_SPACE(*begin)) begin++;
3736 while (ASCII_SPACE(*end)) end--;
3738 if( end <= begin ) return LDAP_INVALID_SYNTAX;
3740 bv.bv_len = end-begin+1;
3742 ber_dupbv(serial, &bv);
3744 /* now extract the issuer, remember p was at the dollar sign */
3746 end = assertion->bv_val+assertion->bv_len-1;
3747 while (ASCII_SPACE(*begin)) begin++;
3748 /* should we trim spaces at the end too? is it safe always? no, no */
3750 if( end <= begin ) return LDAP_INVALID_SYNTAX;
3753 bv.bv_len = end-begin+1;
3756 dnNormalize2( NULL, &bv, issuer_dn );
3759 return LDAP_SUCCESS;
3763 certificateExactMatch(
3768 struct berval *value,
3769 void *assertedValue )
3772 unsigned char *p = value->bv_val;
3773 struct berval serial;
3774 struct berval issuer_dn;
3775 struct berval asserted_serial;
3776 struct berval asserted_issuer_dn;
3779 xcert = d2i_X509(NULL, &p, value->bv_len);
3782 LDAP_LOG( CONFIG, ENTRY,
3783 "certificateExactMatch: error parsing cert: %s\n",
3784 ERR_error_string(ERR_get_error(),NULL), 0, 0 );
3786 Debug( LDAP_DEBUG_ARGS, "certificateExactMatch: "
3787 "error parsing cert: %s\n",
3788 ERR_error_string(ERR_get_error(),NULL), NULL, NULL );
3790 return LDAP_INVALID_SYNTAX;
3793 asn1_integer2str(xcert->cert_info->serialNumber, &serial);
3794 dnX509normalize(X509_get_issuer_name(xcert), &issuer_dn);
3798 serial_and_issuer_parse(assertedValue,
3799 &asserted_serial, &asserted_issuer_dn);
3804 slap_schema.si_syn_integer,
3805 slap_schema.si_mr_integerMatch,
3808 if ( ret == LDAP_SUCCESS ) {
3809 if ( *matchp == 0 ) {
3810 /* We need to normalize everything for dnMatch */
3814 slap_schema.si_syn_distinguishedName,
3815 slap_schema.si_mr_distinguishedNameMatch,
3817 &asserted_issuer_dn);
3822 LDAP_LOG( CONFIG, ARGS, "certificateExactMatch "
3823 "%d\n\t\"%s $ %s\"\n",
3824 *matchp, serial.bv_val, issuer_dn.bv_val );
3825 LDAP_LOG( CONFIG, ARGS, "\t\"%s $ %s\"\n",
3826 asserted_serial.bv_val, asserted_issuer_dn.bv_val,
3829 Debug( LDAP_DEBUG_ARGS, "certificateExactMatch "
3830 "%d\n\t\"%s $ %s\"\n",
3831 *matchp, serial.bv_val, issuer_dn.bv_val );
3832 Debug( LDAP_DEBUG_ARGS, "\t\"%s $ %s\"\n",
3833 asserted_serial.bv_val, asserted_issuer_dn.bv_val,
3837 ber_memfree(serial.bv_val);
3838 ber_memfree(issuer_dn.bv_val);
3839 ber_memfree(asserted_serial.bv_val);
3840 ber_memfree(asserted_issuer_dn.bv_val);
3846 * Index generation function
3847 * We just index the serials, in most scenarios the issuer DN is one of
3848 * a very small set of values.
3850 static int certificateExactIndexer(
3855 struct berval *prefix,
3863 struct berval serial;
3865 /* we should have at least one value at this point */
3866 assert( values != NULL && values[0].bv_val != NULL );
3868 for( i=0; values[i].bv_val != NULL; i++ ) {
3869 /* empty -- just count them */
3872 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
3874 for( i=0; values[i].bv_val != NULL; i++ ) {
3875 p = values[i].bv_val;
3876 xcert = d2i_X509(NULL, &p, values[i].bv_len);
3879 LDAP_LOG( CONFIG, ENTRY,
3880 "certificateExactIndexer: error parsing cert: %s\n",
3881 ERR_error_string(ERR_get_error(),NULL), 0, 0);
3883 Debug( LDAP_DEBUG_ARGS, "certificateExactIndexer: "
3884 "error parsing cert: %s\n",
3885 ERR_error_string(ERR_get_error(),NULL),
3888 /* Do we leak keys on error? */
3889 return LDAP_INVALID_SYNTAX;
3892 asn1_integer2str(xcert->cert_info->serialNumber, &serial);
3894 integerNormalize( slap_schema.si_syn_integer,
3895 &serial, &keys[i] );
3896 ber_memfree(serial.bv_val);
3898 LDAP_LOG( CONFIG, ENTRY,
3899 "certificateExactIndexer: returning: %s\n", keys[i].bv_val, 0, 0);
3901 Debug( LDAP_DEBUG_ARGS, "certificateExactIndexer: "
3908 keys[i].bv_val = NULL;
3910 return LDAP_SUCCESS;
3913 /* Index generation function */
3914 /* We think this is always called with a value in matching rule syntax */
3915 static int certificateExactFilter(
3920 struct berval *prefix,
3921 void * assertedValue,
3925 struct berval asserted_serial;
3928 ret = serial_and_issuer_parse( assertedValue, &asserted_serial, NULL );
3929 if( ret != LDAP_SUCCESS ) return ret;
3931 keys = ch_malloc( sizeof( struct berval ) * 2 );
3932 integerNormalize( syntax, &asserted_serial, &keys[0] );
3933 keys[1].bv_val = NULL;
3936 ber_memfree(asserted_serial.bv_val);
3937 return LDAP_SUCCESS;
3942 check_time_syntax (struct berval *val,
3946 static int ceiling[9] = { 99, 99, 11, 30, 23, 59, 59, 12, 59 };
3947 static int mdays[2][12] = {
3948 /* non-leap years */
3949 { 30, 27, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30 },
3951 { 30, 28, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30 }
3954 int part, c, tzoffset, leapyear = 0 ;
3956 if( val->bv_len == 0 ) {
3957 return LDAP_INVALID_SYNTAX;
3960 p = (char *)val->bv_val;
3961 e = p + val->bv_len;
3963 /* Ignore initial whitespace */
3964 while ( ( p < e ) && ASCII_SPACE( *p ) ) {
3968 if (e - p < 13 - (2 * start)) {
3969 return LDAP_INVALID_SYNTAX;
3972 for (part = 0; part < 9; part++) {
3976 for (part = start; part < 7; part++) {
3978 if ((part == 6) && (c == 'Z' || c == '+' || c == '-')) {
3985 return LDAP_INVALID_SYNTAX;
3987 if (c < 0 || c > 9) {
3988 return LDAP_INVALID_SYNTAX;
3994 return LDAP_INVALID_SYNTAX;
3996 if (c < 0 || c > 9) {
3997 return LDAP_INVALID_SYNTAX;
4002 if (part == 2 || part == 3) {
4005 if (parts[part] < 0) {
4006 return LDAP_INVALID_SYNTAX;
4008 if (parts[part] > ceiling[part]) {
4009 return LDAP_INVALID_SYNTAX;
4013 /* leapyear check for the Gregorian calendar (year>1581) */
4014 if (((parts[1] % 4 == 0) && (parts[1] != 0)) ||
4015 ((parts[0] % 4 == 0) && (parts[1] == 0)))
4020 if (parts[3] > mdays[leapyear][parts[2]]) {
4021 return LDAP_INVALID_SYNTAX;
4026 tzoffset = 0; /* UTC */
4027 } else if (c != '+' && c != '-') {
4028 return LDAP_INVALID_SYNTAX;
4032 } else /* c == '+' */ {
4037 return LDAP_INVALID_SYNTAX;
4040 for (part = 7; part < 9; part++) {
4042 if (c < 0 || c > 9) {
4043 return LDAP_INVALID_SYNTAX;
4048 if (c < 0 || c > 9) {
4049 return LDAP_INVALID_SYNTAX;
4053 if (parts[part] < 0 || parts[part] > ceiling[part]) {
4054 return LDAP_INVALID_SYNTAX;
4059 /* Ignore trailing whitespace */
4060 while ( ( p < e ) && ASCII_SPACE( *p ) ) {
4064 return LDAP_INVALID_SYNTAX;
4067 switch ( tzoffset ) {
4068 case -1: /* negativ offset to UTC, ie west of Greenwich */
4069 parts[4] += parts[7];
4070 parts[5] += parts[8];
4071 for (part = 6; --part > 0; ) { /* offset is just hhmm, no seconds */
4075 c = mdays[leapyear][parts[2]];
4077 if (parts[part] > c) {
4078 parts[part] -= c + 1;
4083 case 1: /* positive offset to UTC, ie east of Greenwich */
4084 parts[4] -= parts[7];
4085 parts[5] -= parts[8];
4086 for (part = 6; --part > 0; ) {
4090 /* first arg to % needs to be non negativ */
4091 c = mdays[leapyear][(parts[2] - 1 + 12) % 12];
4093 if (parts[part] < 0) {
4094 parts[part] += c + 1;
4099 case 0: /* already UTC */
4103 return LDAP_SUCCESS;
4106 #ifdef SUPPORT_OBSOLETE_UTC_SYNTAX
4111 struct berval *normalized )
4115 rc = check_time_syntax(val, 1, parts);
4116 if (rc != LDAP_SUCCESS) {
4120 normalized->bv_val = ch_malloc( 14 );
4121 if ( normalized->bv_val == NULL ) {
4122 return LBER_ERROR_MEMORY;
4125 sprintf( normalized->bv_val, "%02d%02d%02d%02d%02d%02dZ",
4126 parts[1], parts[2] + 1, parts[3] + 1,
4127 parts[4], parts[5], parts[6] );
4128 normalized->bv_len = 13;
4130 return LDAP_SUCCESS;
4134 #ifdef SUPPORT_OBSOLETE_UTC_SYNTAX
4142 return check_time_syntax(in, 1, parts);
4147 generalizedTimeValidate(
4153 return check_time_syntax(in, 0, parts);
4157 generalizedTimeNormalize(
4160 struct berval *normalized )
4164 rc = check_time_syntax(val, 0, parts);
4165 if (rc != LDAP_SUCCESS) {
4169 normalized->bv_val = ch_malloc( 16 );
4170 if ( normalized->bv_val == NULL ) {
4171 return LBER_ERROR_MEMORY;
4174 sprintf( normalized->bv_val, "%02d%02d%02d%02d%02d%02d%02dZ",
4175 parts[0], parts[1], parts[2] + 1, parts[3] + 1,
4176 parts[4], parts[5], parts[6] );
4177 normalized->bv_len = 15;
4179 return LDAP_SUCCESS;
4183 nisNetgroupTripleValidate(
4185 struct berval *val )
4190 if ( val->bv_len == 0 ) {
4191 return LDAP_INVALID_SYNTAX;
4194 p = (char *)val->bv_val;
4195 e = p + val->bv_len;
4197 if ( *p != '(' /*')'*/ ) {
4198 return LDAP_INVALID_SYNTAX;
4201 for ( p++; ( p < e ) && ( *p != /*'('*/ ')' ); p++ ) {
4205 return LDAP_INVALID_SYNTAX;
4208 } else if ( !AD_CHAR( *p ) ) {
4209 return LDAP_INVALID_SYNTAX;
4213 if ( ( commas != 2 ) || ( *p != /*'('*/ ')' ) ) {
4214 return LDAP_INVALID_SYNTAX;
4220 return LDAP_INVALID_SYNTAX;
4223 return LDAP_SUCCESS;
4227 bootParameterValidate(
4229 struct berval *val )
4233 if ( val->bv_len == 0 ) {
4234 return LDAP_INVALID_SYNTAX;
4237 p = (char *)val->bv_val;
4238 e = p + val->bv_len;
4241 for (; ( p < e ) && ( *p != '=' ); p++ ) {
4242 if ( !AD_CHAR( *p ) ) {
4243 return LDAP_INVALID_SYNTAX;
4248 return LDAP_INVALID_SYNTAX;
4252 for ( p++; ( p < e ) && ( *p != ':' ); p++ ) {
4253 if ( !AD_CHAR( *p ) ) {
4254 return LDAP_INVALID_SYNTAX;
4259 return LDAP_INVALID_SYNTAX;
4263 for ( p++; p < e; p++ ) {
4264 if ( !SLAP_PRINTABLE( *p ) ) {
4265 return LDAP_INVALID_SYNTAX;
4269 return LDAP_SUCCESS;
4272 #define X_BINARY "X-BINARY-TRANSFER-REQUIRED 'TRUE' "
4273 #define X_NOT_H_R "X-NOT-HUMAN-READABLE 'TRUE' "
4275 static slap_syntax_defs_rec syntax_defs[] = {
4276 {"( 1.3.6.1.4.1.1466.115.121.1.1 DESC 'ACI Item' "
4277 X_BINARY X_NOT_H_R ")",
4278 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, NULL, NULL, NULL},
4279 {"( 1.3.6.1.4.1.1466.115.121.1.2 DESC 'Access Point' " X_NOT_H_R ")",
4280 0, NULL, NULL, NULL},
4281 {"( 1.3.6.1.4.1.1466.115.121.1.3 DESC 'Attribute Type Description' )",
4282 0, NULL, NULL, NULL},
4283 {"( 1.3.6.1.4.1.1466.115.121.1.4 DESC 'Audio' "
4285 SLAP_SYNTAX_BLOB, blobValidate, NULL, NULL},
4286 {"( 1.3.6.1.4.1.1466.115.121.1.5 DESC 'Binary' "
4288 SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4289 {"( 1.3.6.1.4.1.1466.115.121.1.6 DESC 'Bit String' )",
4290 0, bitStringValidate, NULL, NULL },
4291 {"( 1.3.6.1.4.1.1466.115.121.1.7 DESC 'Boolean' )",
4292 0, booleanValidate, NULL, NULL},
4293 {"( 1.3.6.1.4.1.1466.115.121.1.8 DESC 'Certificate' "
4294 X_BINARY X_NOT_H_R ")",
4295 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4296 {"( 1.3.6.1.4.1.1466.115.121.1.9 DESC 'Certificate List' "
4297 X_BINARY X_NOT_H_R ")",
4298 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4299 {"( 1.3.6.1.4.1.1466.115.121.1.10 DESC 'Certificate Pair' "
4300 X_BINARY X_NOT_H_R ")",
4301 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4302 {"( 1.3.6.1.4.1.1466.115.121.1.11 DESC 'Country String' )",
4303 0, countryStringValidate, IA5StringNormalize, NULL},
4304 {"( 1.3.6.1.4.1.1466.115.121.1.12 DESC 'Distinguished Name' )",
4305 0, dnValidate, dnNormalize2, dnPretty2},
4306 {"( 1.3.6.1.4.1.1466.115.121.1.13 DESC 'Data Quality' )",
4307 0, NULL, NULL, NULL},
4308 {"( 1.3.6.1.4.1.1466.115.121.1.14 DESC 'Delivery Method' )",
4309 0, NULL, NULL, NULL},
4310 {"( 1.3.6.1.4.1.1466.115.121.1.15 DESC 'Directory String' )",
4311 0, UTF8StringValidate, UTF8StringNormalize, NULL},
4312 {"( 1.3.6.1.4.1.1466.115.121.1.16 DESC 'DIT Content Rule Description' )",
4313 0, NULL, NULL, NULL},
4314 {"( 1.3.6.1.4.1.1466.115.121.1.17 DESC 'DIT Structure Rule Description' )",
4315 0, NULL, NULL, NULL},
4316 {"( 1.3.6.1.4.1.1466.115.121.1.19 DESC 'DSA Quality' )",
4317 0, NULL, NULL, NULL},
4318 {"( 1.3.6.1.4.1.1466.115.121.1.20 DESC 'DSE Type' )",
4319 0, NULL, NULL, NULL},
4320 {"( 1.3.6.1.4.1.1466.115.121.1.21 DESC 'Enhanced Guide' )",
4321 0, NULL, NULL, NULL},
4322 {"( 1.3.6.1.4.1.1466.115.121.1.22 DESC 'Facsimile Telephone Number' )",
4323 0, printablesStringValidate, telephoneNumberNormalize, NULL},
4324 {"( 1.3.6.1.4.1.1466.115.121.1.23 DESC 'Fax' " X_NOT_H_R ")",
4325 SLAP_SYNTAX_BLOB, NULL, NULL, NULL},
4326 {"( 1.3.6.1.4.1.1466.115.121.1.24 DESC 'Generalized Time' )",
4327 0, generalizedTimeValidate, generalizedTimeNormalize, NULL},
4328 {"( 1.3.6.1.4.1.1466.115.121.1.25 DESC 'Guide' )",
4329 0, NULL, NULL, NULL},
4330 {"( 1.3.6.1.4.1.1466.115.121.1.26 DESC 'IA5 String' )",
4331 0, IA5StringValidate, IA5StringNormalize, NULL},
4332 {"( 1.3.6.1.4.1.1466.115.121.1.27 DESC 'Integer' )",
4333 0, integerValidate, integerNormalize, NULL},
4334 {"( 1.3.6.1.4.1.1466.115.121.1.28 DESC 'JPEG' " X_NOT_H_R ")",
4335 SLAP_SYNTAX_BLOB, blobValidate, NULL, NULL},
4336 {"( 1.3.6.1.4.1.1466.115.121.1.29 DESC 'Master And Shadow Access Points' )",
4337 0, NULL, NULL, NULL},
4338 {"( 1.3.6.1.4.1.1466.115.121.1.30 DESC 'Matching Rule Description' )",
4339 0, NULL, NULL, NULL},
4340 {"( 1.3.6.1.4.1.1466.115.121.1.31 DESC 'Matching Rule Use Description' )",
4341 0, NULL, NULL, NULL},
4342 {"( 1.3.6.1.4.1.1466.115.121.1.32 DESC 'Mail Preference' )",
4343 0, NULL, NULL, NULL},
4344 {"( 1.3.6.1.4.1.1466.115.121.1.33 DESC 'MHS OR Address' )",
4345 0, NULL, NULL, NULL},
4346 {"( 1.3.6.1.4.1.1466.115.121.1.34 DESC 'Name And Optional UID' )",
4347 0, nameUIDValidate, nameUIDNormalize, NULL},
4348 {"( 1.3.6.1.4.1.1466.115.121.1.35 DESC 'Name Form Description' )",
4349 0, NULL, NULL, NULL},
4350 {"( 1.3.6.1.4.1.1466.115.121.1.36 DESC 'Numeric String' )",
4351 0, numericStringValidate, numericStringNormalize, NULL},
4352 {"( 1.3.6.1.4.1.1466.115.121.1.37 DESC 'Object Class Description' )",
4353 0, NULL, NULL, NULL},
4354 {"( 1.3.6.1.4.1.1466.115.121.1.38 DESC 'OID' )",
4355 0, oidValidate, NULL, NULL},
4356 {"( 1.3.6.1.4.1.1466.115.121.1.39 DESC 'Other Mailbox' )",
4357 0, IA5StringValidate, IA5StringNormalize, NULL},
4358 {"( 1.3.6.1.4.1.1466.115.121.1.40 DESC 'Octet String' )",
4359 0, blobValidate, NULL, NULL},
4360 {"( 1.3.6.1.4.1.1466.115.121.1.41 DESC 'Postal Address' )",
4361 0, UTF8StringValidate, UTF8StringNormalize, NULL},
4362 {"( 1.3.6.1.4.1.1466.115.121.1.42 DESC 'Protocol Information' )",
4363 0, NULL, NULL, NULL},
4364 {"( 1.3.6.1.4.1.1466.115.121.1.43 DESC 'Presentation Address' )",
4365 0, NULL, NULL, NULL},
4366 {"( 1.3.6.1.4.1.1466.115.121.1.44 DESC 'Printable String' )",
4367 0, printableStringValidate, IA5StringNormalize, NULL},
4368 {"( 1.3.6.1.4.1.1466.115.121.1.45 DESC 'SubtreeSpecification' "
4369 X_BINARY X_NOT_H_R ")",
4370 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, NULL, NULL, NULL},
4371 {"( 1.3.6.1.4.1.1466.115.121.1.49 DESC 'Supported Algorithm' "
4372 X_BINARY X_NOT_H_R ")",
4373 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4374 {"( 1.3.6.1.4.1.1466.115.121.1.50 DESC 'Telephone Number' )",
4375 0, printableStringValidate, telephoneNumberNormalize, NULL},
4376 {"( 1.3.6.1.4.1.1466.115.121.1.51 DESC 'Teletex Terminal Identifier' )",
4377 0, NULL, NULL, NULL},
4378 {"( 1.3.6.1.4.1.1466.115.121.1.52 DESC 'Telex Number' )",
4379 0, printablesStringValidate, IA5StringNormalize, NULL},
4380 #ifdef SUPPORT_OBSOLETE_UTC_SYNTAX
4381 {"( 1.3.6.1.4.1.1466.115.121.1.53 DESC 'UTC Time' )",
4382 0, utcTimeValidate, utcTimeNormalize, NULL},
4384 {"( 1.3.6.1.4.1.1466.115.121.1.54 DESC 'LDAP Syntax Description' )",
4385 0, NULL, NULL, NULL},
4386 {"( 1.3.6.1.4.1.1466.115.121.1.55 DESC 'Modify Rights' )",
4387 0, NULL, NULL, NULL},
4388 {"( 1.3.6.1.4.1.1466.115.121.1.56 DESC 'LDAP Schema Definition' )",
4389 0, NULL, NULL, NULL},
4390 {"( 1.3.6.1.4.1.1466.115.121.1.57 DESC 'LDAP Schema Description' )",
4391 0, NULL, NULL, NULL},
4392 {"( 1.3.6.1.4.1.1466.115.121.1.58 DESC 'Substring Assertion' )",
4393 0, NULL, NULL, NULL},
4395 /* RFC 2307 NIS Syntaxes */
4396 {"( 1.3.6.1.1.1.0.0 DESC 'RFC2307 NIS Netgroup Triple' )",
4397 0, nisNetgroupTripleValidate, NULL, NULL},
4398 {"( 1.3.6.1.1.1.0.1 DESC 'RFC2307 Boot Parameter' )",
4399 0, bootParameterValidate, NULL, NULL},
4403 /* These OIDs are not published yet, but will be in the next
4404 * I-D for PKIX LDAPv3 schema as have been advanced by David
4405 * Chadwick in private mail.
4407 {"( 1.2.826.0.1.3344810.7.1 DESC 'Serial Number and Issuer' )",
4408 0, UTF8StringValidate, NULL, NULL},
4411 /* OpenLDAP Experimental Syntaxes */
4412 #ifdef SLAPD_ACI_ENABLED
4413 {"( 1.3.6.1.4.1.4203.666.2.1 DESC 'OpenLDAP Experimental ACI' )",
4415 UTF8StringValidate /* THIS WILL CHANGE FOR NEW ACI SYNTAX */,
4419 #ifdef SLAPD_AUTHPASSWD
4420 /* needs updating */
4421 {"( 1.3.6.1.4.1.4203.666.2.2 DESC 'OpenLDAP authPassword' )",
4422 SLAP_SYNTAX_HIDE, NULL, NULL, NULL},
4425 /* OpenLDAP Void Syntax */
4426 {"( 1.3.6.1.4.1.4203.1.1.1 DESC 'OpenLDAP void' )" ,
4427 SLAP_SYNTAX_HIDE, inValidate, NULL, NULL},
4428 {NULL, 0, NULL, NULL, NULL}
4432 char *certificateExactMatchSyntaxes[] = {
4433 "1.3.6.1.4.1.1466.115.121.1.8" /* certificate */,
4437 char *directoryStringSyntaxes[] = {
4438 "1.3.6.1.4.1.1466.115.121.1.44" /* printableString */,
4441 char *integerFirstComponentMatchSyntaxes[] = {
4442 "1.3.6.1.4.1.1466.115.121.1.27" /* INTEGER */,
4443 "1.3.6.1.4.1.1466.115.121.1.17" /* ditStructureRuleDescription */,
4446 char *objectIdentifierFirstComponentMatchSyntaxes[] = {
4447 "1.3.6.1.4.1.1466.115.121.1.38" /* OID */,
4448 "1.3.6.1.4.1.1466.115.121.1.3" /* attributeTypeDescription */,
4449 "1.3.6.1.4.1.1466.115.121.1.16" /* ditContentRuleDescription */,
4450 "1.3.6.1.4.1.1466.115.121.1.54" /* ldapSyntaxDescription */,
4451 "1.3.6.1.4.1.1466.115.121.1.30" /* matchingRuleDescription */,
4452 "1.3.6.1.4.1.1466.115.121.1.31" /* matchingRuleUseDescription */,
4453 "1.3.6.1.4.1.1466.115.121.1.35" /* nameFormDescription */,
4454 "1.3.6.1.4.1.1466.115.121.1.37" /* objectClassDescription */,
4459 * Other matching rules in X.520 that we do not use (yet):
4461 * 2.5.13.9 numericStringOrderingMatch
4462 * 2.5.13.19 octetStringSubstringsMatch
4463 * 2.5.13.25 uTCTimeMatch
4464 * 2.5.13.26 uTCTimeOrderingMatch
4465 * 2.5.13.31 directoryStringFirstComponentMatch
4466 * 2.5.13.32 wordMatch
4467 * 2.5.13.33 keywordMatch
4468 * 2.5.13.35 certificateMatch
4469 * 2.5.13.36 certificatePairExactMatch
4470 * 2.5.13.37 certificatePairMatch
4471 * 2.5.13.38 certificateListExactMatch
4472 * 2.5.13.39 certificateListMatch
4473 * 2.5.13.40 algorithmIdentifierMatch
4474 * 2.5.13.41 storedPrefixMatch
4475 * 2.5.13.42 attributeCertificateMatch
4476 * 2.5.13.43 readerAndKeyIDMatch
4477 * 2.5.13.44 attributeIntegrityMatch
4479 static slap_mrule_defs_rec mrule_defs[] = {
4481 * EQUALITY matching rules must be listed after associated APPROX
4482 * matching rules. So, we list all APPROX matching rules first.
4484 {"( " directoryStringApproxMatchOID " NAME 'directoryStringApproxMatch' "
4485 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4486 SLAP_MR_HIDE | SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT, NULL,
4488 directoryStringApproxMatch,
4489 directoryStringApproxIndexer,
4490 directoryStringApproxFilter,
4493 {"( " IA5StringApproxMatchOID " NAME 'IA5StringApproxMatch' "
4494 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4495 SLAP_MR_HIDE | SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT, NULL,
4497 IA5StringApproxMatch,
4498 IA5StringApproxIndexer,
4499 IA5StringApproxFilter,
4503 * Other matching rules
4506 {"( 2.5.13.0 NAME 'objectIdentifierMatch' "
4507 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
4508 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4510 objectIdentifierMatch, caseIgnoreIA5Indexer, caseIgnoreIA5Filter,
4513 {"( 2.5.13.1 NAME 'distinguishedNameMatch' "
4514 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )",
4515 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4517 dnMatch, dnIndexer, dnFilter,
4520 {"( 2.5.13.2 NAME 'caseIgnoreMatch' "
4521 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4522 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD,
4523 directoryStringSyntaxes,
4525 caseIgnoreMatch, caseExactIgnoreIndexer, caseExactIgnoreFilter,
4526 directoryStringApproxMatchOID },
4528 {"( 2.5.13.3 NAME 'caseIgnoreOrderingMatch' "
4529 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4530 SLAP_MR_ORDERING, directoryStringSyntaxes,
4532 caseIgnoreOrderingMatch, NULL, NULL,
4535 {"( 2.5.13.4 NAME 'caseIgnoreSubstringsMatch' "
4536 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4537 SLAP_MR_SUBSTR, NULL,
4539 caseExactIgnoreSubstringsMatch,
4540 caseExactIgnoreSubstringsIndexer,
4541 caseExactIgnoreSubstringsFilter,
4544 {"( 2.5.13.5 NAME 'caseExactMatch' "
4545 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4546 SLAP_MR_EQUALITY | SLAP_MR_EXT, directoryStringSyntaxes,
4548 caseExactMatch, caseExactIgnoreIndexer, caseExactIgnoreFilter,
4549 directoryStringApproxMatchOID },
4551 {"( 2.5.13.6 NAME 'caseExactOrderingMatch' "
4552 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4553 SLAP_MR_ORDERING, directoryStringSyntaxes,
4555 caseExactOrderingMatch, NULL, NULL,
4558 {"( 2.5.13.7 NAME 'caseExactSubstringsMatch' "
4559 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4560 SLAP_MR_SUBSTR, directoryStringSyntaxes,
4562 caseExactIgnoreSubstringsMatch,
4563 caseExactIgnoreSubstringsIndexer,
4564 caseExactIgnoreSubstringsFilter,
4567 {"( 2.5.13.8 NAME 'numericStringMatch' "
4568 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 )",
4569 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL,
4572 caseIgnoreIA5Indexer,
4573 caseIgnoreIA5Filter,
4576 {"( 2.5.13.10 NAME 'numericStringSubstringsMatch' "
4577 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4578 SLAP_MR_SUBSTR, NULL,
4580 caseIgnoreIA5SubstringsMatch,
4581 caseIgnoreIA5SubstringsIndexer,
4582 caseIgnoreIA5SubstringsFilter,
4585 {"( 2.5.13.11 NAME 'caseIgnoreListMatch' "
4586 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )",
4587 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL,
4589 caseIgnoreListMatch, NULL, NULL,
4592 {"( 2.5.13.12 NAME 'caseIgnoreListSubstringsMatch' "
4593 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4594 SLAP_MR_SUBSTR, NULL,
4596 caseIgnoreListSubstringsMatch, NULL, NULL,
4599 {"( 2.5.13.13 NAME 'booleanMatch' "
4600 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )",
4601 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4603 booleanMatch, NULL, NULL,
4606 {"( 2.5.13.14 NAME 'integerMatch' "
4607 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4608 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4610 integerMatch, integerIndexer, integerFilter,
4613 {"( 2.5.13.15 NAME 'integerOrderingMatch' "
4614 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4615 SLAP_MR_ORDERING, NULL,
4617 integerOrderingMatch, NULL, NULL,
4620 {"( 2.5.13.16 NAME 'bitStringMatch' "
4621 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.6 )",
4622 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4624 bitStringMatch, bitStringIndexer, bitStringFilter,
4627 {"( 2.5.13.17 NAME 'octetStringMatch' "
4628 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
4629 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4631 octetStringMatch, octetStringIndexer, octetStringFilter,
4634 {"( 2.5.13.18 NAME 'octetStringOrderingMatch' "
4635 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
4636 SLAP_MR_ORDERING, NULL,
4638 octetStringOrderingMatch, NULL, NULL,
4641 {"( 2.5.13.20 NAME 'telephoneNumberMatch' "
4642 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 )",
4643 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL,
4645 telephoneNumberMatch,
4646 telephoneNumberIndexer,
4647 telephoneNumberFilter,
4650 {"( 2.5.13.21 NAME 'telephoneNumberSubstringsMatch' "
4651 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4652 SLAP_MR_SUBSTR, NULL,
4654 telephoneNumberSubstringsMatch,
4655 telephoneNumberSubstringsIndexer,
4656 telephoneNumberSubstringsFilter,
4659 {"( 2.5.13.22 NAME 'presentationAddressMatch' "
4660 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.43 )",
4661 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4666 {"( 2.5.13.23 NAME 'uniqueMemberMatch' "
4667 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.34 )",
4668 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4670 uniqueMemberMatch, NULL, NULL,
4673 {"( 2.5.13.24 NAME 'protocolInformationMatch' "
4674 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.42 )",
4675 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4677 protocolInformationMatch, NULL, NULL,
4680 {"( 2.5.13.27 NAME 'generalizedTimeMatch' "
4681 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
4682 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4684 generalizedTimeMatch, NULL, NULL,
4687 {"( 2.5.13.28 NAME 'generalizedTimeOrderingMatch' "
4688 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
4689 SLAP_MR_ORDERING, NULL,
4691 generalizedTimeOrderingMatch, NULL, NULL,
4694 {"( 2.5.13.29 NAME 'integerFirstComponentMatch' "
4695 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4696 SLAP_MR_EQUALITY | SLAP_MR_EXT, integerFirstComponentMatchSyntaxes,
4698 integerFirstComponentMatch, NULL, NULL,
4701 {"( 2.5.13.30 NAME 'objectIdentifierFirstComponentMatch' "
4702 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
4703 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4704 objectIdentifierFirstComponentMatchSyntaxes,
4706 objectIdentifierFirstComponentMatch, NULL, NULL,
4710 {"( 2.5.13.34 NAME 'certificateExactMatch' "
4711 "SYNTAX 1.2.826.0.1.3344810.7.1 )",
4712 SLAP_MR_EQUALITY | SLAP_MR_EXT, certificateExactMatchSyntaxes,
4713 certificateExactConvert, NULL,
4714 certificateExactMatch,
4715 certificateExactIndexer, certificateExactFilter,
4719 {"( 1.3.6.1.4.1.1466.109.114.1 NAME 'caseExactIA5Match' "
4720 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4721 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4723 caseExactIA5Match, caseExactIA5Indexer, caseExactIA5Filter,
4724 IA5StringApproxMatchOID },
4726 {"( 1.3.6.1.4.1.1466.109.114.2 NAME 'caseIgnoreIA5Match' "
4727 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4728 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL,
4730 caseIgnoreIA5Match, caseIgnoreIA5Indexer, caseIgnoreIA5Filter,
4731 IA5StringApproxMatchOID },
4733 {"( 1.3.6.1.4.1.1466.109.114.3 NAME 'caseIgnoreIA5SubstringsMatch' "
4734 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4735 SLAP_MR_SUBSTR, NULL,
4737 caseIgnoreIA5SubstringsMatch,
4738 caseIgnoreIA5SubstringsIndexer,
4739 caseIgnoreIA5SubstringsFilter,
4742 {"( 1.3.6.1.4.1.4203.1.2.1 NAME 'caseExactIA5SubstringsMatch' "
4743 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4744 SLAP_MR_SUBSTR, NULL,
4746 caseExactIA5SubstringsMatch,
4747 caseExactIA5SubstringsIndexer,
4748 caseExactIA5SubstringsFilter,
4751 #ifdef SLAPD_AUTHPASSWD
4752 /* needs updating */
4753 {"( 1.3.6.1.4.1.4203.666.4.1 NAME 'authPasswordMatch' "
4754 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
4755 SLAP_MR_EQUALITY, NULL,
4757 authPasswordMatch, NULL, NULL,
4761 #ifdef SLAPD_ACI_ENABLED
4762 {"( 1.3.6.1.4.1.4203.666.4.2 NAME 'OpenLDAPaciMatch' "
4763 "SYNTAX 1.3.6.1.4.1.4203.666.2.1 )",
4764 SLAP_MR_EQUALITY, NULL,
4766 OpenLDAPaciMatch, NULL, NULL,
4770 {"( 1.2.840.113556.1.4.803 NAME 'integerBitAndMatch' "
4771 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4774 integerBitAndMatch, NULL, NULL,
4777 {"( 1.2.840.113556.1.4.804 NAME 'integerBitOrMatch' "
4778 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4781 integerBitOrMatch, NULL, NULL,
4784 {NULL, SLAP_MR_NONE, NULL,
4785 NULL, NULL, NULL, NULL, NULL,
4790 slap_schema_init( void )
4795 /* we should only be called once (from main) */
4796 assert( schema_init_done == 0 );
4798 for ( i=0; syntax_defs[i].sd_desc != NULL; i++ ) {
4799 res = register_syntax( &syntax_defs[i] );
4802 fprintf( stderr, "slap_schema_init: Error registering syntax %s\n",
4803 syntax_defs[i].sd_desc );
4808 for ( i=0; mrule_defs[i].mrd_desc != NULL; i++ ) {
4809 if( mrule_defs[i].mrd_usage == SLAP_MR_NONE &&
4810 mrule_defs[i].mrd_compat_syntaxes == NULL )
4813 "slap_schema_init: Ingoring unusable matching rule %s\n",
4814 mrule_defs[i].mrd_desc );
4818 res = register_matching_rule( &mrule_defs[i] );
4822 "slap_schema_init: Error registering matching rule %s\n",
4823 mrule_defs[i].mrd_desc );
4828 for ( i=0; i < (int)(sizeof(mr_ptr)/sizeof(mr_ptr[0])); i++ )
4829 *mr_ptr[i].mr = mr_find( mr_ptr[i].oid );
4831 res = slap_schema_load();
4832 schema_init_done = 1;
4837 schema_destroy( void )
4843 for ( i=0; i < (int)(sizeof(mr_ptr)/sizeof(mr_ptr[0])); i++ )
4844 *mr_ptr[i].mr = NULL;