1 /* schema_init.c - init builtin schema */
4 * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
5 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
15 #include <ac/string.h>
16 #include <ac/socket.h>
22 #include "ldap_utf8.h"
24 #include "lutil_hash.h"
25 #define HASH_BYTES LUTIL_HASH_BYTES
26 #define HASH_CONTEXT lutil_HASH_CTX
27 #define HASH_Init(c) lutil_HASHInit(c)
28 #define HASH_Update(c,buf,len) lutil_HASHUpdate(c,buf,len)
29 #define HASH_Final(d,c) lutil_HASHFinal(d,c)
31 /* recycled validatation routines */
32 #define berValidate blobValidate
34 /* unimplemented pretters */
35 #define integerPretty NULL
37 /* recycled matching routines */
38 #define bitStringMatch octetStringMatch
39 #define numericStringMatch caseIgnoreIA5Match
40 #define objectIdentifierMatch caseIgnoreIA5Match
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,
140 /* Index generation function */
141 static int octetStringIndexer(
146 struct berval *prefix,
153 HASH_CONTEXT HASHcontext;
154 unsigned char HASHdigest[HASH_BYTES];
155 struct berval digest;
156 digest.bv_val = HASHdigest;
157 digest.bv_len = sizeof(HASHdigest);
159 for( i=0; values[i].bv_val != NULL; i++ ) {
160 /* just count them */
163 /* we should have at least one value at this point */
166 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
168 slen = syntax->ssyn_oidlen;
169 mlen = mr->smr_oidlen;
171 for( i=0; values[i].bv_val != NULL; i++ ) {
172 HASH_Init( &HASHcontext );
173 if( prefix != NULL && prefix->bv_len > 0 ) {
174 HASH_Update( &HASHcontext,
175 prefix->bv_val, prefix->bv_len );
177 HASH_Update( &HASHcontext,
178 syntax->ssyn_oid, slen );
179 HASH_Update( &HASHcontext,
181 HASH_Update( &HASHcontext,
182 values[i].bv_val, values[i].bv_len );
183 HASH_Final( HASHdigest, &HASHcontext );
185 ber_dupbv( &keys[i], &digest );
188 keys[i].bv_val = NULL;
195 /* Index generation function */
196 static int octetStringFilter(
201 struct berval *prefix,
207 HASH_CONTEXT HASHcontext;
208 unsigned char HASHdigest[HASH_BYTES];
209 struct berval *value = (struct berval *) assertValue;
210 struct berval digest;
211 digest.bv_val = HASHdigest;
212 digest.bv_len = sizeof(HASHdigest);
214 slen = syntax->ssyn_oidlen;
215 mlen = mr->smr_oidlen;
217 keys = ch_malloc( sizeof( struct berval ) * 2 );
219 HASH_Init( &HASHcontext );
220 if( prefix != NULL && prefix->bv_len > 0 ) {
221 HASH_Update( &HASHcontext,
222 prefix->bv_val, prefix->bv_len );
224 HASH_Update( &HASHcontext,
225 syntax->ssyn_oid, slen );
226 HASH_Update( &HASHcontext,
228 HASH_Update( &HASHcontext,
229 value->bv_val, value->bv_len );
230 HASH_Final( HASHdigest, &HASHcontext );
232 ber_dupbv( keys, &digest );
233 keys[1].bv_val = NULL;
245 /* no value allowed */
246 return LDAP_INVALID_SYNTAX;
254 /* any value allowed */
265 /* very unforgiving validation, requires no normalization
266 * before simplistic matching
268 if( in->bv_len < 3 ) {
269 return LDAP_INVALID_SYNTAX;
273 * rfc 2252 section 6.3 Bit String
274 * bitstring = "'" *binary-digit "'"
275 * binary-digit = "0" / "1"
276 * example: '0101111101'B
279 if( in->bv_val[0] != '\'' ||
280 in->bv_val[in->bv_len-2] != '\'' ||
281 in->bv_val[in->bv_len-1] != 'B' )
283 return LDAP_INVALID_SYNTAX;
286 for( i=in->bv_len-3; i>0; i-- ) {
287 if( in->bv_val[i] != '0' && in->bv_val[i] != '1' ) {
288 return LDAP_INVALID_SYNTAX;
299 struct berval *normalized )
302 * A normalized bitString is has no extaneous (leading) zero bits.
303 * That is, '00010'B is normalized to '10'B
304 * However, as a special case, '0'B requires no normalization.
308 /* start at the first bit */
311 /* Find the first non-zero bit */
312 while ( *p == '0' ) p++;
315 /* no non-zero bits */
316 ber_str2bv( "\'0\'B", sizeof("\'0\'B") - 1, 1, normalized );
320 normalized->bv_val = ch_malloc( val->bv_len + 1 );
322 normalized->bv_val[0] = '\'';
323 normalized->bv_len = 1;
325 for( ; *p != '\0'; p++ ) {
326 normalized->bv_val[normalized->bv_len++] = *p;
329 normalized->bv_val[normalized->bv_len] = '\0';
343 if( in->bv_len == 0 ) return LDAP_SUCCESS;
345 ber_dupbv( &dn, in );
346 if( !dn.bv_val ) return LDAP_OTHER;
348 if( dn.bv_val[dn.bv_len-1] == 'B'
349 && dn.bv_val[dn.bv_len-2] == '\'' )
351 /* assume presence of optional UID */
354 for(i=dn.bv_len-3; i>1; i--) {
355 if( dn.bv_val[i] != '0' && dn.bv_val[i] != '1' ) {
359 if( dn.bv_val[i] != '\'' || dn.bv_val[i-1] != '#' ) {
360 ber_memfree( dn.bv_val );
361 return LDAP_INVALID_SYNTAX;
364 /* trim the UID to allow use of dnValidate */
365 dn.bv_val[i-1] = '\0';
369 rc = dnValidate( NULL, &dn );
371 ber_memfree( dn.bv_val );
379 struct berval *normalized )
384 ber_dupbv( &out, val );
385 if( out.bv_len != 0 ) {
386 struct berval uidin = { 0, NULL };
387 struct berval uidout = { 0, NULL };
389 if( out.bv_val[out.bv_len-1] == 'B'
390 && out.bv_val[out.bv_len-2] == '\'' )
392 /* assume presence of optional UID */
393 uidin.bv_val = strrchr( out.bv_val, '#' );
395 if( uidin.bv_val == NULL ) {
397 return LDAP_INVALID_SYNTAX;
400 uidin.bv_len = out.bv_len - (uidin.bv_val - out.bv_val);
401 out.bv_len -= uidin.bv_len--;
403 /* temporarily trim the UID */
404 *(uidin.bv_val++) = '\0';
406 rc = bitStringNormalize( syntax, &uidin, &uidout );
408 if( rc != LDAP_SUCCESS ) {
410 return LDAP_INVALID_SYNTAX;
414 #ifdef USE_DN_NORMALIZE
415 rc = dnNormalize2( NULL, &out, normalized );
417 rc = dnPretty2( NULL, &out, normalized );
420 if( rc != LDAP_SUCCESS ) {
422 free( uidout.bv_val );
423 return LDAP_INVALID_SYNTAX;
426 if( uidout.bv_len ) {
427 normalized->bv_val = ch_realloc( normalized->bv_val,
428 normalized->bv_len + uidout.bv_len + sizeof("#") );
430 /* insert the separator */
431 normalized->bv_val[normalized->bv_len++] = '#';
434 AC_MEMCPY( &normalized->bv_val[normalized->bv_len],
435 uidout.bv_val, uidout.bv_len );
436 normalized->bv_len += uidout.bv_len;
439 normalized->bv_val[normalized->bv_len] = '\0';
449 * Handling boolean syntax and matching is quite rigid.
450 * A more flexible approach would be to allow a variety
451 * of strings to be normalized and prettied into TRUE
459 /* very unforgiving validation, requires no normalization
460 * before simplistic matching
463 if( in->bv_len == 4 ) {
464 if( !memcmp( in->bv_val, "TRUE", 4 ) ) {
467 } else if( in->bv_len == 5 ) {
468 if( !memcmp( in->bv_val, "FALSE", 5 ) ) {
473 return LDAP_INVALID_SYNTAX;
482 struct berval *value,
483 void *assertedValue )
485 /* simplistic matching allowed by rigid validation */
486 struct berval *asserted = (struct berval *) assertedValue;
487 *matchp = value->bv_len != asserted->bv_len;
491 /*-------------------------------------------------------------------
492 LDAP/X.500 string syntax / matching rules have a few oddities. This
493 comment attempts to detail how slapd(8) treats them.
496 StringSyntax X.500 LDAP Matching
497 DirectoryString CHOICE UTF8 i/e + ignore insignificant spaces
498 PrintableString subset subset i/e + ignore insignificant spaces
499 NumericString subset subset ignore all spaces
500 IA5String ASCII ASCII i/e + ignore insignificant spaces
501 TeletexString T.61 T.61 i/e + ignore insignificant spaces
503 TelephoneNumber subset subset i + ignore all spaces and "-"
505 See draft-ietf-ldapbis-strpro for details (once published).
509 In X.500(93), a directory string can be either a PrintableString,
510 a bmpString, or a UniversalString (e.g., UCS (a subset of Unicode)).
511 In later versions, more CHOICEs were added. In all cases the string
514 In LDPAv3, a directory string is a UTF-8 encoded UCS string.
516 For matching, there are both case ignore and exact rules. Both
517 also require that "insignificant" spaces be ignored.
518 spaces before the first non-space are ignored;
519 spaces after the last non-space are ignored;
520 spaces after a space are ignored.
521 Note: by these rules (and as clarified in X.520), a string of only
522 spaces is to be treated as if held one space, not empty (which
523 would be a syntax error).
526 In ASN.1, numeric string is just a string of digits and spaces
527 and could be empty. However, in X.500, all attribute values of
528 numeric string carry a non-empty constraint. For example:
530 internationalISDNNumber ATTRIBUTE ::= {
531 WITH SYNTAX InternationalISDNNumber
532 EQUALITY MATCHING RULE numericStringMatch
533 SUBSTRINGS MATCHING RULE numericStringSubstringsMatch
534 ID id-at-internationalISDNNumber }
535 InternationalISDNNumber ::=
536 NumericString (SIZE(1..ub-international-isdn-number))
538 Unforunately, some assertion values are don't carry the same
539 constraint (but its unclear how such an assertion could ever
540 be true). In LDAP, there is one syntax (numericString) not two
541 (numericString with constraint, numericString without constraint).
542 This should be treated as numericString with non-empty constraint.
543 Note that while someone may have no ISDN number, there are no ISDN
544 numbers which are zero length.
546 In matching, spaces are ignored.
549 In ASN.1, Printable string is just a string of printable characters
550 and can be empty. In X.500, semantics much like NumericString (see
551 serialNumber for a like example) excepting uses insignificant space
552 handling instead of ignore all spaces.
555 Basically same as PrintableString. There are no examples in X.500,
556 but same logic applies. So we require them to be non-empty as
559 -------------------------------------------------------------------*/
568 unsigned char *u = in->bv_val;
570 if( !in->bv_len ) return LDAP_INVALID_SYNTAX;
572 for( count = in->bv_len; count > 0; count-=len, u+=len ) {
573 /* get the length indicated by the first byte */
574 len = LDAP_UTF8_CHARLEN2( u, len );
576 /* very basic checks */
579 if( (u[5] & 0xC0) != 0x80 ) {
580 return LDAP_INVALID_SYNTAX;
583 if( (u[4] & 0xC0) != 0x80 ) {
584 return LDAP_INVALID_SYNTAX;
587 if( (u[3] & 0xC0) != 0x80 ) {
588 return LDAP_INVALID_SYNTAX;
591 if( (u[2] & 0xC0 )!= 0x80 ) {
592 return LDAP_INVALID_SYNTAX;
595 if( (u[1] & 0xC0) != 0x80 ) {
596 return LDAP_INVALID_SYNTAX;
599 /* CHARLEN already validated it */
602 return LDAP_INVALID_SYNTAX;
605 /* make sure len corresponds with the offset
606 to the next character */
607 if( LDAP_UTF8_OFFSET( u ) != len ) return LDAP_INVALID_SYNTAX;
610 if( count != 0 ) return LDAP_INVALID_SYNTAX;
619 struct berval *normalized )
624 /* validator should have refused an empty string */
625 assert( val->bv_len );
629 /* Ignore initial whitespace */
630 /* All space is ASCII. All ASCII is 1 byte */
631 for ( ; p < val->bv_val + val->bv_len && ASCII_SPACE( p[ 0 ] ); p++ );
633 normalized->bv_len = val->bv_len - (p - val->bv_val);
635 if( !normalized->bv_len ) {
636 ber_mem2bv( " ", 1, 1, normalized );
640 ber_mem2bv( p, normalized->bv_len, 1, normalized );
641 e = normalized->bv_val + normalized->bv_len;
643 assert( normalized->bv_val );
645 p = q = normalized->bv_val;
650 if ( ASCII_SPACE( *p ) ) {
655 /* Ignore the extra whitespace */
656 while ( ASCII_SPACE( *p ) ) {
660 len = LDAP_UTF8_COPY(q,p);
666 assert( normalized->bv_val <= p );
667 assert( q+len <= p );
669 /* cannot start with a space */
670 assert( !ASCII_SPACE( normalized->bv_val[0] ) );
673 * If the string ended in space, backup the pointer one
674 * position. One is enough because the above loop collapsed
675 * all whitespace to a single space.
683 /* cannot end with a space */
684 assert( !ASCII_SPACE( *q ) );
691 normalized->bv_len = q - normalized->bv_val;
696 /* Returns Unicode canonically normalized copy of a substring assertion
697 * Skipping attribute description */
698 static SubstringsAssertion *
699 UTF8SubstringsassertionNormalize(
700 SubstringsAssertion *sa,
703 SubstringsAssertion *nsa;
706 nsa = (SubstringsAssertion *)ch_calloc( 1, sizeof(SubstringsAssertion) );
711 if( sa->sa_initial.bv_val != NULL ) {
712 UTF8bvnormalize( &sa->sa_initial, &nsa->sa_initial, casefold );
713 if( nsa->sa_initial.bv_val == NULL ) {
718 if( sa->sa_any != NULL ) {
719 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
722 nsa->sa_any = (struct berval *)
723 ch_malloc( (i + 1) * sizeof(struct berval) );
725 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
726 UTF8bvnormalize( &sa->sa_any[i], &nsa->sa_any[i],
728 if( nsa->sa_any[i].bv_val == NULL ) {
732 nsa->sa_any[i].bv_val = NULL;
735 if( sa->sa_final.bv_val != NULL ) {
736 UTF8bvnormalize( &sa->sa_final, &nsa->sa_final, casefold );
737 if( nsa->sa_final.bv_val == NULL ) {
745 if ( nsa->sa_final.bv_val ) free( nsa->sa_final.bv_val );
746 if ( nsa->sa_any ) ber_bvarray_free( nsa->sa_any );
747 if ( nsa->sa_initial.bv_val ) free( nsa->sa_initial.bv_val );
752 #ifndef SLAPD_APPROX_OLDSINGLESTRING
754 #if defined(SLAPD_APPROX_INITIALS)
755 #define SLAPD_APPROX_DELIMITER "._ "
756 #define SLAPD_APPROX_WORDLEN 2
758 #define SLAPD_APPROX_DELIMITER " "
759 #define SLAPD_APPROX_WORDLEN 1
768 struct berval *value,
769 void *assertedValue )
771 struct berval *nval, *assertv;
772 char *val, **values, **words, *c;
773 int i, count, len, nextchunk=0, nextavail=0;
775 /* Yes, this is necessary */
776 nval = UTF8bvnormalize( value, NULL, LDAP_UTF8_APPROX );
782 /* Yes, this is necessary */
783 assertv = UTF8bvnormalize( ((struct berval *)assertedValue),
784 NULL, LDAP_UTF8_APPROX );
785 if( assertv == NULL ) {
791 /* Isolate how many words there are */
792 for ( c = nval->bv_val, count = 1; *c; c++ ) {
793 c = strpbrk( c, SLAPD_APPROX_DELIMITER );
794 if ( c == NULL ) break;
799 /* Get a phonetic copy of each word */
800 words = (char **)ch_malloc( count * sizeof(char *) );
801 values = (char **)ch_malloc( count * sizeof(char *) );
802 for ( c = nval->bv_val, i = 0; i < count; i++, c += strlen(c) + 1 ) {
804 values[i] = phonetic(c);
807 /* Work through the asserted value's words, to see if at least some
808 of the words are there, in the same order. */
810 while ( (ber_len_t) nextchunk < assertv->bv_len ) {
811 len = strcspn( assertv->bv_val + nextchunk, SLAPD_APPROX_DELIMITER);
816 #if defined(SLAPD_APPROX_INITIALS)
817 else if( len == 1 ) {
818 /* Single letter words need to at least match one word's initial */
819 for( i=nextavail; i<count; i++ )
820 if( !strncasecmp( assertv->bv_val + nextchunk, words[i], 1 )) {
827 /* Isolate the next word in the asserted value and phonetic it */
828 assertv->bv_val[nextchunk+len] = '\0';
829 val = phonetic( assertv->bv_val + nextchunk );
831 /* See if this phonetic chunk is in the remaining words of *value */
832 for( i=nextavail; i<count; i++ ){
833 if( !strcmp( val, values[i] ) ){
841 /* This chunk in the asserted value was NOT within the *value. */
847 /* Go on to the next word in the asserted value */
851 /* If some of the words were seen, call it a match */
852 if( nextavail > 0 ) {
860 ber_bvfree( assertv );
861 for( i=0; i<count; i++ ) {
862 ch_free( values[i] );
877 struct berval *prefix,
882 int i,j, len, wordcount, keycount=0;
883 struct berval *newkeys;
886 for( j=0; values[j].bv_val != NULL; j++ ) {
887 struct berval val = { 0, NULL };
888 /* Yes, this is necessary */
889 UTF8bvnormalize( &values[j], &val, LDAP_UTF8_APPROX );
890 assert( val.bv_val != NULL );
892 /* Isolate how many words there are. There will be a key for each */
893 for( wordcount = 0, c = val.bv_val; *c; c++) {
894 len = strcspn(c, SLAPD_APPROX_DELIMITER);
895 if( len >= SLAPD_APPROX_WORDLEN ) wordcount++;
897 if (*c == '\0') break;
901 /* Allocate/increase storage to account for new keys */
902 newkeys = (struct berval *)ch_malloc( (keycount + wordcount + 1)
903 * sizeof(struct berval) );
904 AC_MEMCPY( newkeys, keys, keycount * sizeof(struct berval) );
905 if( keys ) ch_free( keys );
908 /* Get a phonetic copy of each word */
909 for( c = val.bv_val, i = 0; i < wordcount; c += len + 1 ) {
911 if( len < SLAPD_APPROX_WORDLEN ) continue;
912 ber_str2bv( phonetic( c ), 0, 0, &keys[keycount] );
917 ber_memfree( val.bv_val );
919 keys[keycount].bv_val = NULL;
931 struct berval *prefix,
940 /* Yes, this is necessary */
941 val = UTF8bvnormalize( ((struct berval *)assertValue),
942 NULL, LDAP_UTF8_APPROX );
943 if( val == NULL || val->bv_val == NULL ) {
944 keys = (struct berval *)ch_malloc( sizeof(struct berval) );
945 keys[0].bv_val = NULL;
951 /* Isolate how many words there are. There will be a key for each */
952 for( count = 0,c = val->bv_val; *c; c++) {
953 len = strcspn(c, SLAPD_APPROX_DELIMITER);
954 if( len >= SLAPD_APPROX_WORDLEN ) count++;
956 if (*c == '\0') break;
960 /* Allocate storage for new keys */
961 keys = (struct berval *)ch_malloc( (count + 1) * sizeof(struct berval) );
963 /* Get a phonetic copy of each word */
964 for( c = val->bv_val, i = 0; i < count; c += len + 1 ) {
966 if( len < SLAPD_APPROX_WORDLEN ) continue;
967 ber_str2bv( phonetic( c ), 0, 0, &keys[i] );
973 keys[count].bv_val = NULL;
981 /* No other form of Approximate Matching is defined */
989 struct berval *value,
990 void *assertedValue )
992 char *vapprox, *avapprox;
995 /* Yes, this is necessary */
996 s = UTF8normalize( value, UTF8_NOCASEFOLD );
1002 /* Yes, this is necessary */
1003 t = UTF8normalize( ((struct berval *)assertedValue),
1008 return LDAP_SUCCESS;
1011 vapprox = phonetic( strip8bitChars( s ) );
1012 avapprox = phonetic( strip8bitChars( t ) );
1017 *matchp = strcmp( vapprox, avapprox );
1020 ch_free( avapprox );
1022 return LDAP_SUCCESS;
1031 struct berval *prefix,
1039 for( i=0; values[i].bv_val != NULL; i++ ) {
1040 /* empty - just count them */
1043 /* we should have at least one value at this point */
1046 keys = (struct berval *)ch_malloc( sizeof( struct berval ) * (i+1) );
1048 /* Copy each value and run it through phonetic() */
1049 for( i=0; values[i].bv_val != NULL; i++ ) {
1050 /* Yes, this is necessary */
1051 s = UTF8normalize( &values[i], UTF8_NOCASEFOLD );
1053 /* strip 8-bit chars and run through phonetic() */
1054 ber_str2bv( phonetic( strip8bitChars( s ) ), 0, 0, &keys[i] );
1057 keys[i].bv_val = NULL;
1060 return LDAP_SUCCESS;
1070 struct berval *prefix,
1077 keys = (struct berval *)ch_malloc( sizeof( struct berval * ) * 2 );
1079 /* Yes, this is necessary */
1080 s = UTF8normalize( ((struct berval *)assertValue),
1085 /* strip 8-bit chars and run through phonetic() */
1086 keys[0] = ber_bvstr( phonetic( strip8bitChars( s ) ) );
1092 return LDAP_SUCCESS;
1103 struct berval *value,
1104 void *assertedValue )
1106 *matchp = UTF8bvnormcmp( value,
1107 (struct berval *) assertedValue,
1108 LDAP_UTF8_NOCASEFOLD );
1109 return LDAP_SUCCESS;
1113 caseExactIgnoreSubstringsMatch(
1118 struct berval *value,
1119 void *assertedValue )
1122 SubstringsAssertion *sub = NULL;
1123 struct berval left = { 0, NULL };
1129 casefold = ( mr != caseExactSubstringsMatchingRule )
1130 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1132 if ( UTF8bvnormalize( value, &left, casefold ) == NULL ) {
1138 sub = UTF8SubstringsassertionNormalize( assertedValue, casefold );
1144 /* Add up asserted input length */
1145 if( sub->sa_initial.bv_val ) {
1146 inlen += sub->sa_initial.bv_len;
1149 for(i=0; sub->sa_any[i].bv_val != NULL; i++) {
1150 inlen += sub->sa_any[i].bv_len;
1153 if( sub->sa_final.bv_val ) {
1154 inlen += sub->sa_final.bv_len;
1157 if( sub->sa_initial.bv_val ) {
1158 if( inlen > left.bv_len ) {
1163 match = memcmp( sub->sa_initial.bv_val, left.bv_val,
1164 sub->sa_initial.bv_len );
1170 left.bv_val += sub->sa_initial.bv_len;
1171 left.bv_len -= sub->sa_initial.bv_len;
1172 inlen -= sub->sa_initial.bv_len;
1175 if( sub->sa_final.bv_val ) {
1176 if( inlen > left.bv_len ) {
1181 match = memcmp( sub->sa_final.bv_val,
1182 &left.bv_val[left.bv_len - sub->sa_final.bv_len],
1183 sub->sa_final.bv_len );
1189 left.bv_len -= sub->sa_final.bv_len;
1190 inlen -= sub->sa_final.bv_len;
1194 for(i=0; sub->sa_any[i].bv_val; i++) {
1199 if( inlen > left.bv_len ) {
1200 /* not enough length */
1205 if( sub->sa_any[i].bv_len == 0 ) {
1209 p = ber_bvchr( &left, *sub->sa_any[i].bv_val );
1215 idx = p - left.bv_val;
1217 if( idx >= left.bv_len ) {
1218 /* this shouldn't happen */
1220 if ( sub->sa_final.bv_val )
1221 ch_free( sub->sa_final.bv_val );
1223 ber_bvarray_free( sub->sa_any );
1224 if ( sub->sa_initial.bv_val )
1225 ch_free( sub->sa_initial.bv_val );
1233 if( sub->sa_any[i].bv_len > left.bv_len ) {
1234 /* not enough left */
1239 match = memcmp( left.bv_val,
1240 sub->sa_any[i].bv_val,
1241 sub->sa_any[i].bv_len );
1249 left.bv_val += sub->sa_any[i].bv_len;
1250 left.bv_len -= sub->sa_any[i].bv_len;
1251 inlen -= sub->sa_any[i].bv_len;
1258 if ( sub->sa_final.bv_val ) free( sub->sa_final.bv_val );
1259 if ( sub->sa_any ) ber_bvarray_free( sub->sa_any );
1260 if ( sub->sa_initial.bv_val ) free( sub->sa_initial.bv_val );
1264 return LDAP_SUCCESS;
1267 /* Index generation function */
1268 static int caseExactIgnoreIndexer(
1273 struct berval *prefix,
1281 HASH_CONTEXT HASHcontext;
1282 unsigned char HASHdigest[HASH_BYTES];
1283 struct berval digest;
1284 digest.bv_val = HASHdigest;
1285 digest.bv_len = sizeof(HASHdigest);
1287 for( i=0; values[i].bv_val != NULL; i++ ) {
1288 /* empty - just count them */
1291 /* we should have at least one value at this point */
1294 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
1296 slen = syntax->ssyn_oidlen;
1297 mlen = mr->smr_oidlen;
1299 casefold = ( mr != caseExactMatchingRule )
1300 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1302 for( i=0; values[i].bv_val != NULL; i++ ) {
1303 struct berval value;
1304 UTF8bvnormalize( &values[i], &value, casefold );
1306 HASH_Init( &HASHcontext );
1307 if( prefix != NULL && prefix->bv_len > 0 ) {
1308 HASH_Update( &HASHcontext,
1309 prefix->bv_val, prefix->bv_len );
1311 HASH_Update( &HASHcontext,
1312 syntax->ssyn_oid, slen );
1313 HASH_Update( &HASHcontext,
1314 mr->smr_oid, mlen );
1315 HASH_Update( &HASHcontext,
1316 value.bv_val, value.bv_len );
1317 HASH_Final( HASHdigest, &HASHcontext );
1319 free( value.bv_val );
1321 ber_dupbv( &keys[i], &digest );
1324 keys[i].bv_val = NULL;
1326 return LDAP_SUCCESS;
1329 /* Index generation function */
1330 static int caseExactIgnoreFilter(
1335 struct berval *prefix,
1342 HASH_CONTEXT HASHcontext;
1343 unsigned char HASHdigest[HASH_BYTES];
1344 struct berval value = { 0, NULL };
1345 struct berval digest;
1347 digest.bv_val = HASHdigest;
1348 digest.bv_len = sizeof(HASHdigest);
1350 slen = syntax->ssyn_oidlen;
1351 mlen = mr->smr_oidlen;
1353 casefold = ( mr != caseExactMatchingRule )
1354 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1356 UTF8bvnormalize( (struct berval *) assertValue, &value, casefold );
1357 /* This usually happens if filter contains bad UTF8 */
1358 if( value.bv_val == NULL ) {
1359 keys = ch_malloc( sizeof( struct berval ) );
1360 keys[0].bv_val = NULL;
1361 return LDAP_SUCCESS;
1364 keys = ch_malloc( sizeof( struct berval ) * 2 );
1366 HASH_Init( &HASHcontext );
1367 if( prefix != NULL && prefix->bv_len > 0 ) {
1368 HASH_Update( &HASHcontext,
1369 prefix->bv_val, prefix->bv_len );
1371 HASH_Update( &HASHcontext,
1372 syntax->ssyn_oid, slen );
1373 HASH_Update( &HASHcontext,
1374 mr->smr_oid, mlen );
1375 HASH_Update( &HASHcontext,
1376 value.bv_val, value.bv_len );
1377 HASH_Final( HASHdigest, &HASHcontext );
1379 ber_dupbv( keys, &digest );
1380 keys[1].bv_val = NULL;
1382 free( value.bv_val );
1385 return LDAP_SUCCESS;
1388 /* Substrings Index generation function */
1389 static int caseExactIgnoreSubstringsIndexer(
1394 struct berval *prefix,
1404 HASH_CONTEXT HASHcontext;
1405 unsigned char HASHdigest[HASH_BYTES];
1406 struct berval digest;
1407 digest.bv_val = HASHdigest;
1408 digest.bv_len = sizeof(HASHdigest);
1412 for( i=0; values[i].bv_val != NULL; i++ ) {
1413 /* empty - just count them */
1416 /* we should have at least one value at this point */
1419 casefold = ( mr != caseExactSubstringsMatchingRule )
1420 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1422 nvalues = ch_malloc( sizeof( struct berval ) * (i+1) );
1423 for( i=0; values[i].bv_val != NULL; i++ ) {
1424 UTF8bvnormalize( &values[i], &nvalues[i], casefold );
1426 nvalues[i].bv_val = NULL;
1429 for( i=0; values[i].bv_val != NULL; i++ ) {
1430 /* count number of indices to generate */
1431 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
1435 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
1436 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1437 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
1438 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
1440 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
1444 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
1445 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1446 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
1450 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
1451 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1452 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
1453 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
1455 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
1461 /* no keys to generate */
1463 ber_bvarray_free( nvalues );
1464 return LDAP_SUCCESS;
1467 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
1469 slen = syntax->ssyn_oidlen;
1470 mlen = mr->smr_oidlen;
1473 for( i=0; values[i].bv_val != NULL; i++ ) {
1476 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
1478 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
1479 ( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
1481 char pre = SLAP_INDEX_SUBSTR_PREFIX;
1482 max = values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
1484 for( j=0; j<max; j++ ) {
1485 HASH_Init( &HASHcontext );
1486 if( prefix != NULL && prefix->bv_len > 0 ) {
1487 HASH_Update( &HASHcontext,
1488 prefix->bv_val, prefix->bv_len );
1491 HASH_Update( &HASHcontext,
1492 &pre, sizeof( pre ) );
1493 HASH_Update( &HASHcontext,
1494 syntax->ssyn_oid, slen );
1495 HASH_Update( &HASHcontext,
1496 mr->smr_oid, mlen );
1497 HASH_Update( &HASHcontext,
1498 &values[i].bv_val[j],
1499 SLAP_INDEX_SUBSTR_MAXLEN );
1500 HASH_Final( HASHdigest, &HASHcontext );
1502 ber_dupbv( &keys[nkeys++], &digest );
1506 max = SLAP_INDEX_SUBSTR_MAXLEN < values[i].bv_len
1507 ? SLAP_INDEX_SUBSTR_MAXLEN : values[i].bv_len;
1509 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
1512 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
1513 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
1514 HASH_Init( &HASHcontext );
1515 if( prefix != NULL && prefix->bv_len > 0 ) {
1516 HASH_Update( &HASHcontext,
1517 prefix->bv_val, prefix->bv_len );
1519 HASH_Update( &HASHcontext,
1520 &pre, sizeof( pre ) );
1521 HASH_Update( &HASHcontext,
1522 syntax->ssyn_oid, slen );
1523 HASH_Update( &HASHcontext,
1524 mr->smr_oid, mlen );
1525 HASH_Update( &HASHcontext,
1526 values[i].bv_val, j );
1527 HASH_Final( HASHdigest, &HASHcontext );
1529 ber_dupbv( &keys[nkeys++], &digest );
1532 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
1533 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
1534 HASH_Init( &HASHcontext );
1535 if( prefix != NULL && prefix->bv_len > 0 ) {
1536 HASH_Update( &HASHcontext,
1537 prefix->bv_val, prefix->bv_len );
1539 HASH_Update( &HASHcontext,
1540 &pre, sizeof( pre ) );
1541 HASH_Update( &HASHcontext,
1542 syntax->ssyn_oid, slen );
1543 HASH_Update( &HASHcontext,
1544 mr->smr_oid, mlen );
1545 HASH_Update( &HASHcontext,
1546 &values[i].bv_val[values[i].bv_len-j], j );
1547 HASH_Final( HASHdigest, &HASHcontext );
1549 ber_dupbv( &keys[nkeys++], &digest );
1557 keys[nkeys].bv_val = NULL;
1564 ber_bvarray_free( nvalues );
1566 return LDAP_SUCCESS;
1569 static int caseExactIgnoreSubstringsFilter(
1574 struct berval *prefix,
1578 SubstringsAssertion *sa;
1581 ber_len_t nkeys = 0;
1582 size_t slen, mlen, klen;
1584 HASH_CONTEXT HASHcontext;
1585 unsigned char HASHdigest[HASH_BYTES];
1586 struct berval *value;
1587 struct berval digest;
1589 casefold = ( mr != caseExactSubstringsMatchingRule )
1590 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1592 sa = UTF8SubstringsassertionNormalize( assertValue, casefold );
1595 return LDAP_SUCCESS;
1598 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
1599 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1604 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
1606 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
1607 if( sa->sa_any[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1608 /* don't bother accounting for stepping */
1609 nkeys += sa->sa_any[i].bv_len -
1610 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
1615 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
1616 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1622 if ( sa->sa_final.bv_val ) free( sa->sa_final.bv_val );
1623 if ( sa->sa_any ) ber_bvarray_free( sa->sa_any );
1624 if ( sa->sa_initial.bv_val ) free( sa->sa_initial.bv_val );
1627 return LDAP_SUCCESS;
1630 digest.bv_val = HASHdigest;
1631 digest.bv_len = sizeof(HASHdigest);
1633 slen = syntax->ssyn_oidlen;
1634 mlen = mr->smr_oidlen;
1636 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
1639 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
1640 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1642 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
1643 value = &sa->sa_initial;
1645 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
1646 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
1648 HASH_Init( &HASHcontext );
1649 if( prefix != NULL && prefix->bv_len > 0 ) {
1650 HASH_Update( &HASHcontext,
1651 prefix->bv_val, prefix->bv_len );
1653 HASH_Update( &HASHcontext,
1654 &pre, sizeof( pre ) );
1655 HASH_Update( &HASHcontext,
1656 syntax->ssyn_oid, slen );
1657 HASH_Update( &HASHcontext,
1658 mr->smr_oid, mlen );
1659 HASH_Update( &HASHcontext,
1660 value->bv_val, klen );
1661 HASH_Final( HASHdigest, &HASHcontext );
1663 ber_dupbv( &keys[nkeys++], &digest );
1666 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
1668 pre = SLAP_INDEX_SUBSTR_PREFIX;
1669 klen = SLAP_INDEX_SUBSTR_MAXLEN;
1671 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
1672 if( sa->sa_any[i].bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
1676 value = &sa->sa_any[i];
1679 j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
1680 j += SLAP_INDEX_SUBSTR_STEP )
1682 HASH_Init( &HASHcontext );
1683 if( prefix != NULL && prefix->bv_len > 0 ) {
1684 HASH_Update( &HASHcontext,
1685 prefix->bv_val, prefix->bv_len );
1687 HASH_Update( &HASHcontext,
1688 &pre, sizeof( pre ) );
1689 HASH_Update( &HASHcontext,
1690 syntax->ssyn_oid, slen );
1691 HASH_Update( &HASHcontext,
1692 mr->smr_oid, mlen );
1693 HASH_Update( &HASHcontext,
1694 &value->bv_val[j], klen );
1695 HASH_Final( HASHdigest, &HASHcontext );
1697 ber_dupbv( &keys[nkeys++], &digest );
1703 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
1704 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1706 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
1707 value = &sa->sa_final;
1709 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
1710 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
1712 HASH_Init( &HASHcontext );
1713 if( prefix != NULL && prefix->bv_len > 0 ) {
1714 HASH_Update( &HASHcontext,
1715 prefix->bv_val, prefix->bv_len );
1717 HASH_Update( &HASHcontext,
1718 &pre, sizeof( pre ) );
1719 HASH_Update( &HASHcontext,
1720 syntax->ssyn_oid, slen );
1721 HASH_Update( &HASHcontext,
1722 mr->smr_oid, mlen );
1723 HASH_Update( &HASHcontext,
1724 &value->bv_val[value->bv_len-klen], klen );
1725 HASH_Final( HASHdigest, &HASHcontext );
1727 ber_dupbv( &keys[nkeys++], &digest );
1731 keys[nkeys].bv_val = NULL;
1737 if ( sa->sa_final.bv_val ) free( sa->sa_final.bv_val );
1738 if ( sa->sa_any ) ber_bvarray_free( sa->sa_any );
1739 if ( sa->sa_initial.bv_val ) free( sa->sa_initial.bv_val );
1742 return LDAP_SUCCESS;
1751 struct berval *value,
1752 void *assertedValue )
1754 *matchp = UTF8bvnormcmp( value,
1755 (struct berval *) assertedValue,
1756 LDAP_UTF8_CASEFOLD );
1757 return LDAP_SUCCESS;
1760 /* Remove all spaces and '-' characters */
1762 telephoneNumberNormalize(
1765 struct berval *normalized )
1769 /* validator should have refused an empty string */
1770 assert( val->bv_len );
1772 q = normalized->bv_val = ch_malloc( val->bv_len + 1 );
1774 for( p = val->bv_val; *p; p++ ) {
1775 if ( ! ( ASCII_SPACE( *p ) || *p == '-' )) {
1781 normalized->bv_len = q - normalized->bv_val;
1783 if( normalized->bv_len == 0 ) {
1784 free( normalized->bv_val );
1785 return LDAP_INVALID_SYNTAX;
1788 return LDAP_SUCCESS;
1794 struct berval *val )
1798 if( val->bv_len == 0 ) {
1799 /* disallow empty strings */
1800 return LDAP_INVALID_SYNTAX;
1803 if( OID_LEADCHAR(val->bv_val[0]) ) {
1805 for(i=1; i < val->bv_len; i++) {
1806 if( OID_SEPARATOR( val->bv_val[i] ) ) {
1807 if( dot++ ) return 1;
1808 } else if ( OID_CHAR( val->bv_val[i] ) ) {
1811 return LDAP_INVALID_SYNTAX;
1815 return !dot ? LDAP_SUCCESS : LDAP_INVALID_SYNTAX;
1817 } else if( DESC_LEADCHAR(val->bv_val[0]) ) {
1818 for(i=1; i < val->bv_len; i++) {
1819 if( !DESC_CHAR(val->bv_val[i] ) ) {
1820 return LDAP_INVALID_SYNTAX;
1824 return LDAP_SUCCESS;
1827 return LDAP_INVALID_SYNTAX;
1836 struct berval *value,
1837 void *assertedValue )
1840 int vsign = 1, avsign = 1; /* default sign = '+' */
1841 struct berval *asserted;
1842 ber_len_t vlen, avlen;
1845 /* Skip leading space/sign/zeroes, and get the sign of the *value number */
1847 vlen = value->bv_len;
1848 if( mr == integerFirstComponentMatchingRule ) {
1849 char *tmp = memchr( v, '$', vlen );
1852 while( vlen && ASCII_SPACE( v[vlen-1] ))
1855 for( ; vlen && ( *v < '1' || '9' < *v ); v++, vlen-- ) /* ANSI 2.2.1 */
1861 /* Do the same with the *assertedValue number */
1862 asserted = (struct berval *) assertedValue;
1863 av = asserted->bv_val;
1864 avlen = asserted->bv_len;
1865 for( ; avlen && ( *av < '1' || '9' < *av ); av++, avlen-- )
1871 match = vsign - avsign;
1873 match = (vlen != avlen
1874 ? ( vlen < avlen ? -1 : 1 )
1875 : memcmp( v, av, vlen ));
1881 return LDAP_SUCCESS;
1887 struct berval *val )
1891 if( !val->bv_len ) return LDAP_INVALID_SYNTAX;
1893 if(( val->bv_val[0] == '+' ) || ( val->bv_val[0] == '-' )) {
1894 if( val->bv_len < 2 ) return LDAP_INVALID_SYNTAX;
1895 } else if( !ASCII_DIGIT(val->bv_val[0]) ) {
1896 return LDAP_INVALID_SYNTAX;
1899 for( i=1; i < val->bv_len; i++ ) {
1900 if( !ASCII_DIGIT(val->bv_val[i]) ) return LDAP_INVALID_SYNTAX;
1903 return LDAP_SUCCESS;
1910 struct berval *normalized )
1920 /* Ignore leading spaces */
1921 while ( len && ( *p == ' ' )) {
1928 negative = ( *p == '-' );
1929 if(( *p == '-' ) || ( *p == '+' )) {
1935 /* Ignore leading zeros */
1936 while ( len && ( *p == '0' )) {
1941 /* If there are no non-zero digits left, the number is zero, otherwise
1942 allocate space for the number and copy it into the buffer */
1944 normalized->bv_val = ch_strdup("0");
1945 normalized->bv_len = 1;
1948 normalized->bv_len = len+negative;
1949 normalized->bv_val = ch_malloc( normalized->bv_len + 1 );
1951 normalized->bv_val[0] = '-';
1953 AC_MEMCPY( normalized->bv_val + negative, p, len );
1954 normalized->bv_val[len+negative] = '\0';
1957 return LDAP_SUCCESS;
1960 /* Index generation function */
1961 static int integerIndexer(
1966 struct berval *prefix,
1973 HASH_CONTEXT HASHcontext;
1974 unsigned char HASHdigest[HASH_BYTES];
1975 struct berval digest;
1976 digest.bv_val = HASHdigest;
1977 digest.bv_len = sizeof(HASHdigest);
1979 for( i=0; values[i].bv_val != NULL; i++ ) {
1980 /* empty - just count them */
1983 /* we should have at least one value at this point */
1986 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
1988 slen = syntax->ssyn_oidlen;
1989 mlen = mr->smr_oidlen;
1991 for( i=0; values[i].bv_val != NULL; i++ ) {
1993 integerNormalize( syntax, &values[i], &norm );
1995 HASH_Init( &HASHcontext );
1996 if( prefix != NULL && prefix->bv_len > 0 ) {
1997 HASH_Update( &HASHcontext,
1998 prefix->bv_val, prefix->bv_len );
2000 HASH_Update( &HASHcontext,
2001 syntax->ssyn_oid, slen );
2002 HASH_Update( &HASHcontext,
2003 mr->smr_oid, mlen );
2004 HASH_Update( &HASHcontext,
2005 norm.bv_val, norm.bv_len );
2006 HASH_Final( HASHdigest, &HASHcontext );
2008 ber_dupbv( &keys[i], &digest );
2009 ch_free( norm.bv_val );
2012 keys[i].bv_val = NULL;
2014 return LDAP_SUCCESS;
2017 /* Index generation function */
2018 static int integerFilter(
2023 struct berval *prefix,
2029 HASH_CONTEXT HASHcontext;
2030 unsigned char HASHdigest[HASH_BYTES];
2032 struct berval digest;
2033 digest.bv_val = HASHdigest;
2034 digest.bv_len = sizeof(HASHdigest);
2036 slen = syntax->ssyn_oidlen;
2037 mlen = mr->smr_oidlen;
2039 integerNormalize( syntax, assertValue, &norm );
2041 keys = ch_malloc( sizeof( struct berval ) * 2 );
2043 HASH_Init( &HASHcontext );
2044 if( prefix != NULL && prefix->bv_len > 0 ) {
2045 HASH_Update( &HASHcontext,
2046 prefix->bv_val, prefix->bv_len );
2048 HASH_Update( &HASHcontext,
2049 syntax->ssyn_oid, slen );
2050 HASH_Update( &HASHcontext,
2051 mr->smr_oid, mlen );
2052 HASH_Update( &HASHcontext,
2053 norm.bv_val, norm.bv_len );
2054 HASH_Final( HASHdigest, &HASHcontext );
2056 ber_dupbv( &keys[0], &digest );
2057 keys[1].bv_val = NULL;
2058 ch_free( norm.bv_val );
2061 return LDAP_SUCCESS;
2066 countryStringValidate(
2068 struct berval *val )
2070 if( val->bv_len != 2 ) return LDAP_INVALID_SYNTAX;
2072 if( !SLAP_PRINTABLE(val->bv_val[0]) ) {
2073 return LDAP_INVALID_SYNTAX;
2075 if( !SLAP_PRINTABLE(val->bv_val[1]) ) {
2076 return LDAP_INVALID_SYNTAX;
2079 return LDAP_SUCCESS;
2083 printableStringValidate(
2085 struct berval *val )
2089 if( val->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
2091 for(i=0; i < val->bv_len; i++) {
2092 if( !SLAP_PRINTABLE(val->bv_val[i]) ) {
2093 return LDAP_INVALID_SYNTAX;
2097 return LDAP_SUCCESS;
2101 printablesStringValidate(
2103 struct berval *val )
2107 if( val->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
2109 for(i=0,len=0; i < val->bv_len; i++) {
2110 int c = val->bv_val[i];
2114 return LDAP_INVALID_SYNTAX;
2118 } else if ( SLAP_PRINTABLE(c) ) {
2121 return LDAP_INVALID_SYNTAX;
2126 return LDAP_INVALID_SYNTAX;
2129 return LDAP_SUCCESS;
2135 struct berval *val )
2139 if( val->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
2141 for(i=0; i < val->bv_len; i++) {
2142 if( !LDAP_ASCII(val->bv_val[i]) ) {
2143 return LDAP_INVALID_SYNTAX;
2147 return LDAP_SUCCESS;
2154 struct berval *normalized )
2158 assert( val->bv_len );
2162 /* Ignore initial whitespace */
2163 while ( ASCII_SPACE( *p ) ) {
2167 normalized->bv_val = ch_strdup( p );
2168 p = q = normalized->bv_val;
2171 if ( ASCII_SPACE( *p ) ) {
2174 /* Ignore the extra whitespace */
2175 while ( ASCII_SPACE( *p ) ) {
2183 assert( normalized->bv_val <= p );
2187 * If the string ended in space, backup the pointer one
2188 * position. One is enough because the above loop collapsed
2189 * all whitespace to a single space.
2192 if ( ASCII_SPACE( q[-1] ) ) {
2196 /* null terminate */
2199 normalized->bv_len = q - normalized->bv_val;
2201 if( normalized->bv_len == 0 ) {
2202 normalized->bv_val = ch_realloc( normalized->bv_val, 2 );
2203 normalized->bv_val[0] = ' ';
2204 normalized->bv_val[1] = '\0';
2205 normalized->bv_len = 1;
2208 return LDAP_SUCCESS;
2217 struct berval *value,
2218 void *assertedValue )
2220 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
2223 match = strncmp( value->bv_val,
2224 ((struct berval *) assertedValue)->bv_val,
2229 return LDAP_SUCCESS;
2233 caseExactIA5SubstringsMatch(
2238 struct berval *value,
2239 void *assertedValue )
2242 SubstringsAssertion *sub = assertedValue;
2243 struct berval left = *value;
2247 /* Add up asserted input length */
2248 if( sub->sa_initial.bv_val ) {
2249 inlen += sub->sa_initial.bv_len;
2252 for(i=0; sub->sa_any[i].bv_val != NULL; i++) {
2253 inlen += sub->sa_any[i].bv_len;
2256 if( sub->sa_final.bv_val ) {
2257 inlen += sub->sa_final.bv_len;
2260 if( sub->sa_initial.bv_val ) {
2261 if( inlen > left.bv_len ) {
2266 match = strncmp( sub->sa_initial.bv_val, left.bv_val,
2267 sub->sa_initial.bv_len );
2273 left.bv_val += sub->sa_initial.bv_len;
2274 left.bv_len -= sub->sa_initial.bv_len;
2275 inlen -= sub->sa_initial.bv_len;
2278 if( sub->sa_final.bv_val ) {
2279 if( inlen > left.bv_len ) {
2284 match = strncmp( sub->sa_final.bv_val,
2285 &left.bv_val[left.bv_len - sub->sa_final.bv_len],
2286 sub->sa_final.bv_len );
2292 left.bv_len -= sub->sa_final.bv_len;
2293 inlen -= sub->sa_final.bv_len;
2297 for(i=0; sub->sa_any[i].bv_val; i++) {
2302 if( inlen > left.bv_len ) {
2303 /* not enough length */
2308 if( sub->sa_any[i].bv_len == 0 ) {
2312 p = strchr( left.bv_val, *sub->sa_any[i].bv_val );
2319 idx = p - left.bv_val;
2321 if( idx >= left.bv_len ) {
2322 /* this shouldn't happen */
2329 if( sub->sa_any[i].bv_len > left.bv_len ) {
2330 /* not enough left */
2335 match = strncmp( left.bv_val,
2336 sub->sa_any[i].bv_val,
2337 sub->sa_any[i].bv_len );
2345 left.bv_val += sub->sa_any[i].bv_len;
2346 left.bv_len -= sub->sa_any[i].bv_len;
2347 inlen -= sub->sa_any[i].bv_len;
2353 return LDAP_SUCCESS;
2356 /* Index generation function */
2357 static int caseExactIA5Indexer(
2362 struct berval *prefix,
2369 HASH_CONTEXT HASHcontext;
2370 unsigned char HASHdigest[HASH_BYTES];
2371 struct berval digest;
2372 digest.bv_val = HASHdigest;
2373 digest.bv_len = sizeof(HASHdigest);
2375 for( i=0; values[i].bv_val != NULL; i++ ) {
2376 /* empty - just count them */
2379 /* we should have at least one value at this point */
2382 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
2384 slen = syntax->ssyn_oidlen;
2385 mlen = mr->smr_oidlen;
2387 for( i=0; values[i].bv_val != NULL; i++ ) {
2388 struct berval *value = &values[i];
2390 HASH_Init( &HASHcontext );
2391 if( prefix != NULL && prefix->bv_len > 0 ) {
2392 HASH_Update( &HASHcontext,
2393 prefix->bv_val, prefix->bv_len );
2395 HASH_Update( &HASHcontext,
2396 syntax->ssyn_oid, slen );
2397 HASH_Update( &HASHcontext,
2398 mr->smr_oid, mlen );
2399 HASH_Update( &HASHcontext,
2400 value->bv_val, value->bv_len );
2401 HASH_Final( HASHdigest, &HASHcontext );
2403 ber_dupbv( &keys[i], &digest );
2406 keys[i].bv_val = NULL;
2408 return LDAP_SUCCESS;
2411 /* Index generation function */
2412 static int caseExactIA5Filter(
2417 struct berval *prefix,
2423 HASH_CONTEXT HASHcontext;
2424 unsigned char HASHdigest[HASH_BYTES];
2425 struct berval *value;
2426 struct berval digest;
2427 digest.bv_val = HASHdigest;
2428 digest.bv_len = sizeof(HASHdigest);
2430 slen = syntax->ssyn_oidlen;
2431 mlen = mr->smr_oidlen;
2433 value = (struct berval *) assertValue;
2435 keys = ch_malloc( sizeof( struct berval ) * 2 );
2437 HASH_Init( &HASHcontext );
2438 if( prefix != NULL && prefix->bv_len > 0 ) {
2439 HASH_Update( &HASHcontext,
2440 prefix->bv_val, prefix->bv_len );
2442 HASH_Update( &HASHcontext,
2443 syntax->ssyn_oid, slen );
2444 HASH_Update( &HASHcontext,
2445 mr->smr_oid, mlen );
2446 HASH_Update( &HASHcontext,
2447 value->bv_val, value->bv_len );
2448 HASH_Final( HASHdigest, &HASHcontext );
2450 ber_dupbv( &keys[0], &digest );
2451 keys[1].bv_val = NULL;
2454 return LDAP_SUCCESS;
2457 /* Substrings Index generation function */
2458 static int caseExactIA5SubstringsIndexer(
2463 struct berval *prefix,
2470 HASH_CONTEXT HASHcontext;
2471 unsigned char HASHdigest[HASH_BYTES];
2472 struct berval digest;
2473 digest.bv_val = HASHdigest;
2474 digest.bv_len = sizeof(HASHdigest);
2476 /* we should have at least one value at this point */
2477 assert( values != NULL && values[0].bv_val != NULL );
2480 for( i=0; values[i].bv_val != NULL; i++ ) {
2481 /* count number of indices to generate */
2482 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
2486 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
2487 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2488 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2489 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2491 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2495 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
2496 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2497 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
2501 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
2502 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2503 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2504 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2506 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2512 /* no keys to generate */
2514 return LDAP_SUCCESS;
2517 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
2519 slen = syntax->ssyn_oidlen;
2520 mlen = mr->smr_oidlen;
2523 for( i=0; values[i].bv_val != NULL; i++ ) {
2525 struct berval *value;
2528 if( value->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
2530 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
2531 ( value->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
2533 char pre = SLAP_INDEX_SUBSTR_PREFIX;
2534 max = value->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
2536 for( j=0; j<max; j++ ) {
2537 HASH_Init( &HASHcontext );
2538 if( prefix != NULL && prefix->bv_len > 0 ) {
2539 HASH_Update( &HASHcontext,
2540 prefix->bv_val, prefix->bv_len );
2543 HASH_Update( &HASHcontext,
2544 &pre, sizeof( pre ) );
2545 HASH_Update( &HASHcontext,
2546 syntax->ssyn_oid, slen );
2547 HASH_Update( &HASHcontext,
2548 mr->smr_oid, mlen );
2549 HASH_Update( &HASHcontext,
2551 SLAP_INDEX_SUBSTR_MAXLEN );
2552 HASH_Final( HASHdigest, &HASHcontext );
2554 ber_dupbv( &keys[nkeys++], &digest );
2558 max = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2559 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2561 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
2564 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
2565 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
2566 HASH_Init( &HASHcontext );
2567 if( prefix != NULL && prefix->bv_len > 0 ) {
2568 HASH_Update( &HASHcontext,
2569 prefix->bv_val, prefix->bv_len );
2571 HASH_Update( &HASHcontext,
2572 &pre, sizeof( pre ) );
2573 HASH_Update( &HASHcontext,
2574 syntax->ssyn_oid, slen );
2575 HASH_Update( &HASHcontext,
2576 mr->smr_oid, mlen );
2577 HASH_Update( &HASHcontext,
2579 HASH_Final( HASHdigest, &HASHcontext );
2581 ber_dupbv( &keys[nkeys++], &digest );
2584 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
2585 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
2586 HASH_Init( &HASHcontext );
2587 if( prefix != NULL && prefix->bv_len > 0 ) {
2588 HASH_Update( &HASHcontext,
2589 prefix->bv_val, prefix->bv_len );
2591 HASH_Update( &HASHcontext,
2592 &pre, sizeof( pre ) );
2593 HASH_Update( &HASHcontext,
2594 syntax->ssyn_oid, slen );
2595 HASH_Update( &HASHcontext,
2596 mr->smr_oid, mlen );
2597 HASH_Update( &HASHcontext,
2598 &value->bv_val[value->bv_len-j], j );
2599 HASH_Final( HASHdigest, &HASHcontext );
2601 ber_dupbv( &keys[nkeys++], &digest );
2608 keys[nkeys].bv_val = NULL;
2615 return LDAP_SUCCESS;
2618 static int caseExactIA5SubstringsFilter(
2623 struct berval *prefix,
2627 SubstringsAssertion *sa = assertValue;
2629 ber_len_t nkeys = 0;
2630 size_t slen, mlen, klen;
2632 HASH_CONTEXT HASHcontext;
2633 unsigned char HASHdigest[HASH_BYTES];
2634 struct berval *value;
2635 struct berval digest;
2637 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
2638 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2643 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
2645 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
2646 if( sa->sa_any[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2647 /* don't bother accounting for stepping */
2648 nkeys += sa->sa_any[i].bv_len -
2649 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
2654 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
2655 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2662 return LDAP_SUCCESS;
2665 digest.bv_val = HASHdigest;
2666 digest.bv_len = sizeof(HASHdigest);
2668 slen = syntax->ssyn_oidlen;
2669 mlen = mr->smr_oidlen;
2671 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
2674 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
2675 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2677 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
2678 value = &sa->sa_initial;
2680 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2681 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2683 HASH_Init( &HASHcontext );
2684 if( prefix != NULL && prefix->bv_len > 0 ) {
2685 HASH_Update( &HASHcontext,
2686 prefix->bv_val, prefix->bv_len );
2688 HASH_Update( &HASHcontext,
2689 &pre, sizeof( pre ) );
2690 HASH_Update( &HASHcontext,
2691 syntax->ssyn_oid, slen );
2692 HASH_Update( &HASHcontext,
2693 mr->smr_oid, mlen );
2694 HASH_Update( &HASHcontext,
2695 value->bv_val, klen );
2696 HASH_Final( HASHdigest, &HASHcontext );
2698 ber_dupbv( &keys[nkeys++], &digest );
2701 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
2703 pre = SLAP_INDEX_SUBSTR_PREFIX;
2704 klen = SLAP_INDEX_SUBSTR_MAXLEN;
2706 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
2707 if( sa->sa_any[i].bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
2711 value = &sa->sa_any[i];
2714 j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
2715 j += SLAP_INDEX_SUBSTR_STEP )
2717 HASH_Init( &HASHcontext );
2718 if( prefix != NULL && prefix->bv_len > 0 ) {
2719 HASH_Update( &HASHcontext,
2720 prefix->bv_val, prefix->bv_len );
2722 HASH_Update( &HASHcontext,
2723 &pre, sizeof( pre ) );
2724 HASH_Update( &HASHcontext,
2725 syntax->ssyn_oid, slen );
2726 HASH_Update( &HASHcontext,
2727 mr->smr_oid, mlen );
2728 HASH_Update( &HASHcontext,
2729 &value->bv_val[j], klen );
2730 HASH_Final( HASHdigest, &HASHcontext );
2732 ber_dupbv( &keys[nkeys++], &digest );
2737 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
2738 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2740 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
2741 value = &sa->sa_final;
2743 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2744 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2746 HASH_Init( &HASHcontext );
2747 if( prefix != NULL && prefix->bv_len > 0 ) {
2748 HASH_Update( &HASHcontext,
2749 prefix->bv_val, prefix->bv_len );
2751 HASH_Update( &HASHcontext,
2752 &pre, sizeof( pre ) );
2753 HASH_Update( &HASHcontext,
2754 syntax->ssyn_oid, slen );
2755 HASH_Update( &HASHcontext,
2756 mr->smr_oid, mlen );
2757 HASH_Update( &HASHcontext,
2758 &value->bv_val[value->bv_len-klen], klen );
2759 HASH_Final( HASHdigest, &HASHcontext );
2761 ber_dupbv( &keys[nkeys++], &digest );
2765 keys[nkeys].bv_val = NULL;
2772 return LDAP_SUCCESS;
2781 struct berval *value,
2782 void *assertedValue )
2784 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
2786 if( match == 0 && value->bv_len ) {
2787 match = strncasecmp( value->bv_val,
2788 ((struct berval *) assertedValue)->bv_val,
2793 return LDAP_SUCCESS;
2797 caseIgnoreIA5SubstringsMatch(
2802 struct berval *value,
2803 void *assertedValue )
2806 SubstringsAssertion *sub = assertedValue;
2807 struct berval left = *value;
2811 /* Add up asserted input length */
2812 if( sub->sa_initial.bv_val ) {
2813 inlen += sub->sa_initial.bv_len;
2816 for(i=0; sub->sa_any[i].bv_val != NULL; i++) {
2817 inlen += sub->sa_any[i].bv_len;
2820 if( sub->sa_final.bv_val ) {
2821 inlen += sub->sa_final.bv_len;
2824 if( sub->sa_initial.bv_val ) {
2825 if( inlen > left.bv_len ) {
2830 match = strncasecmp( sub->sa_initial.bv_val, left.bv_val,
2831 sub->sa_initial.bv_len );
2837 left.bv_val += sub->sa_initial.bv_len;
2838 left.bv_len -= sub->sa_initial.bv_len;
2839 inlen -= sub->sa_initial.bv_len;
2842 if( sub->sa_final.bv_val ) {
2843 if( inlen > left.bv_len ) {
2848 match = strncasecmp( sub->sa_final.bv_val,
2849 &left.bv_val[left.bv_len - sub->sa_final.bv_len],
2850 sub->sa_final.bv_len );
2856 left.bv_len -= sub->sa_final.bv_len;
2857 inlen -= sub->sa_final.bv_len;
2861 for(i=0; sub->sa_any[i].bv_val; i++) {
2866 if( inlen > left.bv_len ) {
2867 /* not enough length */
2872 if( sub->sa_any[i].bv_len == 0 ) {
2876 p = bvcasechr( &left, *sub->sa_any[i].bv_val, &idx );
2883 assert( idx < left.bv_len );
2884 if( idx >= left.bv_len ) {
2885 /* this shouldn't happen */
2892 if( sub->sa_any[i].bv_len > left.bv_len ) {
2893 /* not enough left */
2898 match = strncasecmp( left.bv_val,
2899 sub->sa_any[i].bv_val,
2900 sub->sa_any[i].bv_len );
2909 left.bv_val += sub->sa_any[i].bv_len;
2910 left.bv_len -= sub->sa_any[i].bv_len;
2911 inlen -= sub->sa_any[i].bv_len;
2917 return LDAP_SUCCESS;
2920 /* Index generation function */
2921 static int caseIgnoreIA5Indexer(
2926 struct berval *prefix,
2931 int rc = LDAP_SUCCESS;
2934 HASH_CONTEXT HASHcontext;
2935 unsigned char HASHdigest[HASH_BYTES];
2936 struct berval digest;
2937 digest.bv_val = HASHdigest;
2938 digest.bv_len = sizeof(HASHdigest);
2940 /* we should have at least one value at this point */
2941 assert( values != NULL && values[0].bv_val != NULL );
2943 for( i=0; values[i].bv_val != NULL; i++ ) {
2944 /* just count them */
2947 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
2949 slen = syntax->ssyn_oidlen;
2950 mlen = mr->smr_oidlen;
2952 for( i=0; values[i].bv_val != NULL; i++ ) {
2953 struct berval value;
2955 if( mr->smr_normalize ) {
2956 rc = (mr->smr_normalize)( use, syntax, mr, &values[i], &value );
2957 if( rc != LDAP_SUCCESS ) {
2960 } else if ( mr->smr_syntax->ssyn_normalize ) {
2961 rc = (mr->smr_syntax->ssyn_normalize)( syntax, &values[i], &value );
2962 if( rc != LDAP_SUCCESS ) {
2966 ber_dupbv( &value, &values[i] );
2969 ldap_pvt_str2lower( value.bv_val );
2971 HASH_Init( &HASHcontext );
2972 if( prefix != NULL && prefix->bv_len > 0 ) {
2973 HASH_Update( &HASHcontext,
2974 prefix->bv_val, prefix->bv_len );
2976 HASH_Update( &HASHcontext,
2977 syntax->ssyn_oid, slen );
2978 HASH_Update( &HASHcontext,
2979 mr->smr_oid, mlen );
2980 HASH_Update( &HASHcontext,
2981 value.bv_val, value.bv_len );
2982 HASH_Final( HASHdigest, &HASHcontext );
2984 free( value.bv_val );
2986 ber_dupbv( &keys[i], &digest );
2989 keys[i].bv_val = NULL;
2990 if( rc != LDAP_SUCCESS ) {
2991 ber_bvarray_free( keys );
2998 /* Index generation function */
2999 static int caseIgnoreIA5Filter(
3004 struct berval *prefix,
3010 HASH_CONTEXT HASHcontext;
3011 unsigned char HASHdigest[HASH_BYTES];
3012 struct berval value;
3013 struct berval digest;
3014 digest.bv_val = HASHdigest;
3015 digest.bv_len = sizeof(HASHdigest);
3017 slen = syntax->ssyn_oidlen;
3018 mlen = mr->smr_oidlen;
3020 ber_dupbv( &value, (struct berval *) assertValue );
3021 ldap_pvt_str2lower( value.bv_val );
3023 keys = ch_malloc( sizeof( struct berval ) * 2 );
3025 HASH_Init( &HASHcontext );
3026 if( prefix != NULL && prefix->bv_len > 0 ) {
3027 HASH_Update( &HASHcontext,
3028 prefix->bv_val, prefix->bv_len );
3030 HASH_Update( &HASHcontext,
3031 syntax->ssyn_oid, slen );
3032 HASH_Update( &HASHcontext,
3033 mr->smr_oid, mlen );
3034 HASH_Update( &HASHcontext,
3035 value.bv_val, value.bv_len );
3036 HASH_Final( HASHdigest, &HASHcontext );
3038 ber_dupbv( &keys[0], &digest );
3039 keys[1].bv_val = NULL;
3041 free( value.bv_val );
3045 return LDAP_SUCCESS;
3048 /* Substrings Index generation function */
3049 static int caseIgnoreIA5SubstringsIndexer(
3054 struct berval *prefix,
3061 HASH_CONTEXT HASHcontext;
3062 unsigned char HASHdigest[HASH_BYTES];
3063 struct berval digest;
3064 digest.bv_val = HASHdigest;
3065 digest.bv_len = sizeof(HASHdigest);
3067 /* we should have at least one value at this point */
3068 assert( values != NULL && values[0].bv_val != NULL );
3071 for( i=0; values[i].bv_val != NULL; i++ ) {
3072 /* count number of indices to generate */
3073 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
3077 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
3078 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3079 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
3080 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
3082 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
3086 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
3087 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3088 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
3092 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
3093 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3094 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
3095 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
3097 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
3103 /* no keys to generate */
3105 return LDAP_SUCCESS;
3108 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
3110 slen = syntax->ssyn_oidlen;
3111 mlen = mr->smr_oidlen;
3114 for( i=0; values[i].bv_val != NULL; i++ ) {
3116 struct berval value;
3118 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
3120 ber_dupbv( &value, &values[i] );
3121 ldap_pvt_str2lower( value.bv_val );
3123 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
3124 ( value.bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
3126 char pre = SLAP_INDEX_SUBSTR_PREFIX;
3127 max = value.bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
3129 for( j=0; j<max; j++ ) {
3130 HASH_Init( &HASHcontext );
3131 if( prefix != NULL && prefix->bv_len > 0 ) {
3132 HASH_Update( &HASHcontext,
3133 prefix->bv_val, prefix->bv_len );
3136 HASH_Update( &HASHcontext,
3137 &pre, sizeof( pre ) );
3138 HASH_Update( &HASHcontext,
3139 syntax->ssyn_oid, slen );
3140 HASH_Update( &HASHcontext,
3141 mr->smr_oid, mlen );
3142 HASH_Update( &HASHcontext,
3144 SLAP_INDEX_SUBSTR_MAXLEN );
3145 HASH_Final( HASHdigest, &HASHcontext );
3147 ber_dupbv( &keys[nkeys++], &digest );
3151 max = SLAP_INDEX_SUBSTR_MAXLEN < value.bv_len
3152 ? SLAP_INDEX_SUBSTR_MAXLEN : value.bv_len;
3154 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
3157 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
3158 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
3159 HASH_Init( &HASHcontext );
3160 if( prefix != NULL && prefix->bv_len > 0 ) {
3161 HASH_Update( &HASHcontext,
3162 prefix->bv_val, prefix->bv_len );
3164 HASH_Update( &HASHcontext,
3165 &pre, sizeof( pre ) );
3166 HASH_Update( &HASHcontext,
3167 syntax->ssyn_oid, slen );
3168 HASH_Update( &HASHcontext,
3169 mr->smr_oid, mlen );
3170 HASH_Update( &HASHcontext,
3172 HASH_Final( HASHdigest, &HASHcontext );
3174 ber_dupbv( &keys[nkeys++], &digest );
3177 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
3178 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
3179 HASH_Init( &HASHcontext );
3180 if( prefix != NULL && prefix->bv_len > 0 ) {
3181 HASH_Update( &HASHcontext,
3182 prefix->bv_val, prefix->bv_len );
3184 HASH_Update( &HASHcontext,
3185 &pre, sizeof( pre ) );
3186 HASH_Update( &HASHcontext,
3187 syntax->ssyn_oid, slen );
3188 HASH_Update( &HASHcontext,
3189 mr->smr_oid, mlen );
3190 HASH_Update( &HASHcontext,
3191 &value.bv_val[value.bv_len-j], j );
3192 HASH_Final( HASHdigest, &HASHcontext );
3194 ber_dupbv( &keys[nkeys++], &digest );
3199 free( value.bv_val );
3203 keys[nkeys].bv_val = NULL;
3210 return LDAP_SUCCESS;
3213 static int caseIgnoreIA5SubstringsFilter(
3218 struct berval *prefix,
3222 SubstringsAssertion *sa = assertValue;
3224 ber_len_t nkeys = 0;
3225 size_t slen, mlen, klen;
3227 HASH_CONTEXT HASHcontext;
3228 unsigned char HASHdigest[HASH_BYTES];
3229 struct berval value;
3230 struct berval digest;
3232 if((flags & SLAP_INDEX_SUBSTR_INITIAL) && sa->sa_initial.bv_val != NULL &&
3233 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3238 if((flags & SLAP_INDEX_SUBSTR_ANY) && sa->sa_any != NULL ) {
3240 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
3241 if( sa->sa_any[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3242 /* don't bother accounting for stepping */
3243 nkeys += sa->sa_any[i].bv_len -
3244 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
3249 if((flags & SLAP_INDEX_SUBSTR_FINAL) && sa->sa_final.bv_val != NULL &&
3250 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3257 return LDAP_SUCCESS;
3260 digest.bv_val = HASHdigest;
3261 digest.bv_len = sizeof(HASHdigest);
3263 slen = syntax->ssyn_oidlen;
3264 mlen = mr->smr_oidlen;
3266 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
3269 if((flags & SLAP_INDEX_SUBSTR_INITIAL) && sa->sa_initial.bv_val != NULL &&
3270 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3272 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
3273 ber_dupbv( &value, &sa->sa_initial );
3274 ldap_pvt_str2lower( value.bv_val );
3276 klen = SLAP_INDEX_SUBSTR_MAXLEN < value.bv_len
3277 ? SLAP_INDEX_SUBSTR_MAXLEN : value.bv_len;
3279 HASH_Init( &HASHcontext );
3280 if( prefix != NULL && prefix->bv_len > 0 ) {
3281 HASH_Update( &HASHcontext,
3282 prefix->bv_val, prefix->bv_len );
3284 HASH_Update( &HASHcontext,
3285 &pre, sizeof( pre ) );
3286 HASH_Update( &HASHcontext,
3287 syntax->ssyn_oid, slen );
3288 HASH_Update( &HASHcontext,
3289 mr->smr_oid, mlen );
3290 HASH_Update( &HASHcontext,
3291 value.bv_val, klen );
3292 HASH_Final( HASHdigest, &HASHcontext );
3294 free( value.bv_val );
3295 ber_dupbv( &keys[nkeys++], &digest );
3298 if((flags & SLAP_INDEX_SUBSTR_ANY) && sa->sa_any != NULL ) {
3300 pre = SLAP_INDEX_SUBSTR_PREFIX;
3301 klen = SLAP_INDEX_SUBSTR_MAXLEN;
3303 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
3304 if( sa->sa_any[i].bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
3308 ber_dupbv( &value, &sa->sa_any[i] );
3309 ldap_pvt_str2lower( value.bv_val );
3312 j <= value.bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
3313 j += SLAP_INDEX_SUBSTR_STEP )
3315 HASH_Init( &HASHcontext );
3316 if( prefix != NULL && prefix->bv_len > 0 ) {
3317 HASH_Update( &HASHcontext,
3318 prefix->bv_val, prefix->bv_len );
3320 HASH_Update( &HASHcontext,
3321 &pre, sizeof( pre ) );
3322 HASH_Update( &HASHcontext,
3323 syntax->ssyn_oid, slen );
3324 HASH_Update( &HASHcontext,
3325 mr->smr_oid, mlen );
3326 HASH_Update( &HASHcontext,
3327 &value.bv_val[j], klen );
3328 HASH_Final( HASHdigest, &HASHcontext );
3330 ber_dupbv( &keys[nkeys++], &digest );
3333 free( value.bv_val );
3337 if((flags & SLAP_INDEX_SUBSTR_FINAL) && sa->sa_final.bv_val != NULL &&
3338 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3340 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
3341 ber_dupbv( &value, &sa->sa_final );
3342 ldap_pvt_str2lower( value.bv_val );
3344 klen = SLAP_INDEX_SUBSTR_MAXLEN < value.bv_len
3345 ? SLAP_INDEX_SUBSTR_MAXLEN : value.bv_len;
3347 HASH_Init( &HASHcontext );
3348 if( prefix != NULL && prefix->bv_len > 0 ) {
3349 HASH_Update( &HASHcontext,
3350 prefix->bv_val, prefix->bv_len );
3352 HASH_Update( &HASHcontext,
3353 &pre, sizeof( pre ) );
3354 HASH_Update( &HASHcontext,
3355 syntax->ssyn_oid, slen );
3356 HASH_Update( &HASHcontext,
3357 mr->smr_oid, mlen );
3358 HASH_Update( &HASHcontext,
3359 &value.bv_val[value.bv_len-klen], klen );
3360 HASH_Final( HASHdigest, &HASHcontext );
3362 free( value.bv_val );
3363 ber_dupbv( &keys[nkeys++], &digest );
3367 keys[nkeys].bv_val = NULL;
3374 return LDAP_SUCCESS;
3378 numericStringValidate(
3384 if( in->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
3386 for(i=0; i < in->bv_len; i++) {
3387 if( !SLAP_NUMERIC(in->bv_val[i]) ) {
3388 return LDAP_INVALID_SYNTAX;
3392 return LDAP_SUCCESS;
3396 numericStringNormalize(
3399 struct berval *normalized )
3401 /* removal all spaces */
3404 assert( val->bv_len );
3406 normalized->bv_val = ch_malloc( val->bv_len + 1 );
3409 q = normalized->bv_val;
3412 if ( ASCII_SPACE( *p ) ) {
3413 /* Ignore whitespace */
3420 /* we should have copied no more then is in val */
3421 assert( (q - normalized->bv_val) <= (p - val->bv_val) );
3423 /* null terminate */
3426 normalized->bv_len = q - normalized->bv_val;
3428 if( normalized->bv_len == 0 ) {
3429 normalized->bv_val = ch_realloc( normalized->bv_val, 2 );
3430 normalized->bv_val[0] = ' ';
3431 normalized->bv_val[1] = '\0';
3432 normalized->bv_len = 1;
3435 return LDAP_SUCCESS;
3439 objectIdentifierFirstComponentMatch(
3444 struct berval *value,
3445 void *assertedValue )
3447 int rc = LDAP_SUCCESS;
3449 struct berval *asserted = (struct berval *) assertedValue;
3453 if( value->bv_len == 0 || value->bv_val[0] != '(' /*')'*/ ) {
3454 return LDAP_INVALID_SYNTAX;
3457 /* trim leading white space */
3458 for( i=1; ASCII_SPACE(value->bv_val[i]) && i < value->bv_len; i++ ) {
3462 /* grab next word */
3463 oid.bv_val = &value->bv_val[i];
3464 oid.bv_len = value->bv_len - i;
3465 for( i=1; ASCII_SPACE(value->bv_val[i]) && i < oid.bv_len; i++ ) {
3470 /* insert attributeTypes, objectclass check here */
3471 if( OID_LEADCHAR(asserted->bv_val[0]) ) {
3472 rc = objectIdentifierMatch( &match, flags, syntax, mr, &oid, asserted );
3475 if ( !strcmp( syntax->ssyn_oid, SLAP_SYNTAX_MATCHINGRULES_OID ) ) {
3476 MatchingRule *asserted_mr = mr_bvfind( asserted );
3477 MatchingRule *stored_mr = mr_bvfind( &oid );
3479 if( asserted_mr == NULL ) {
3480 rc = SLAPD_COMPARE_UNDEFINED;
3482 match = asserted_mr != stored_mr;
3485 } else if ( !strcmp( syntax->ssyn_oid,
3486 SLAP_SYNTAX_ATTRIBUTETYPES_OID ) )
3488 AttributeType *asserted_at = at_bvfind( asserted );
3489 AttributeType *stored_at = at_bvfind( &oid );
3491 if( asserted_at == NULL ) {
3492 rc = SLAPD_COMPARE_UNDEFINED;
3494 match = asserted_at != stored_at;
3497 } else if ( !strcmp( syntax->ssyn_oid,
3498 SLAP_SYNTAX_OBJECTCLASSES_OID ) )
3500 ObjectClass *asserted_oc = oc_bvfind( asserted );
3501 ObjectClass *stored_oc = oc_bvfind( &oid );
3503 if( asserted_oc == NULL ) {
3504 rc = SLAPD_COMPARE_UNDEFINED;
3506 match = asserted_oc != stored_oc;
3512 LDAP_LOG( CONFIG, ENTRY,
3513 "objectIdentifierFirstComponentMatch: %d\n %s\n %s\n",
3514 match, value->bv_val, asserted->bv_val );
3516 Debug( LDAP_DEBUG_ARGS, "objectIdentifierFirstComponentMatch "
3517 "%d\n\t\"%s\"\n\t\"%s\"\n",
3518 match, value->bv_val, asserted->bv_val );
3522 if( rc == LDAP_SUCCESS ) *matchp = match;
3532 struct berval *value,
3533 void *assertedValue )
3535 long lValue, lAssertedValue;
3537 /* safe to assume integers are NUL terminated? */
3538 lValue = strtoul(value->bv_val, NULL, 10);
3539 if(( lValue == LONG_MIN || lValue == LONG_MAX) && errno == ERANGE )
3540 return LDAP_CONSTRAINT_VIOLATION;
3542 lAssertedValue = strtol(((struct berval *)assertedValue)->bv_val, NULL, 10);
3543 if(( lAssertedValue == LONG_MIN || lAssertedValue == LONG_MAX) && errno == ERANGE )
3544 return LDAP_CONSTRAINT_VIOLATION;
3546 *matchp = (lValue & lAssertedValue);
3547 return LDAP_SUCCESS;
3556 struct berval *value,
3557 void *assertedValue )
3559 long lValue, lAssertedValue;
3561 /* safe to assume integers are NUL terminated? */
3562 lValue = strtoul(value->bv_val, NULL, 10);
3563 if(( lValue == LONG_MIN || lValue == LONG_MAX) && errno == ERANGE )
3564 return LDAP_CONSTRAINT_VIOLATION;
3566 lAssertedValue = strtol(((struct berval *)assertedValue)->bv_val, NULL, 10);
3567 if(( lAssertedValue == LONG_MIN || lAssertedValue == LONG_MAX) && errno == ERANGE )
3568 return LDAP_CONSTRAINT_VIOLATION;
3570 *matchp = (lValue | lAssertedValue);
3571 return LDAP_SUCCESS;
3575 #include <openssl/x509.h>
3576 #include <openssl/err.h>
3577 char digit[] = "0123456789";
3580 * Next function returns a string representation of a ASN1_INTEGER.
3581 * It works for unlimited lengths.
3584 static struct berval *
3585 asn1_integer2str(ASN1_INTEGER *a, struct berval *bv)
3590 /* We work backwards, make it fill from the end of buf */
3591 p = buf + sizeof(buf) - 1;
3594 if ( a == NULL || a->length == 0 ) {
3602 /* We want to preserve the original */
3603 copy = ch_malloc(n*sizeof(unsigned int));
3604 for (i = 0; i<n; i++) {
3605 copy[i] = a->data[i];
3609 * base indicates the index of the most significant
3610 * byte that might be nonzero. When it goes off the
3611 * end, we now there is nothing left to do.
3617 for (i = base; i<n; i++ ) {
3618 copy[i] += carry*256;
3619 carry = copy[i] % 10;
3624 * Way too large, we need to leave
3625 * room for sign if negative
3630 *--p = digit[carry];
3631 if (copy[base] == 0)
3637 if ( a->type == V_ASN1_NEG_INTEGER ) {
3641 return ber_str2bv( p, 0, 1, bv );
3645 * Given a certificate in DER format, extract the corresponding
3646 * assertion value for certificateExactMatch
3649 certificateExactConvert(
3651 struct berval * out )
3654 unsigned char *p = in->bv_val;
3655 struct berval serial;
3656 struct berval issuer_dn;
3658 xcert = d2i_X509(NULL, &p, in->bv_len);
3661 LDAP_LOG( CONFIG, ENTRY,
3662 "certificateExactConvert: error parsing cert: %s\n",
3663 ERR_error_string(ERR_get_error(),NULL), 0, 0 );
3665 Debug( LDAP_DEBUG_ARGS, "certificateExactConvert: "
3666 "error parsing cert: %s\n",
3667 ERR_error_string(ERR_get_error(),NULL), NULL, NULL );
3669 return LDAP_INVALID_SYNTAX;
3672 if ( !asn1_integer2str(xcert->cert_info->serialNumber, &serial) ) {
3674 return LDAP_INVALID_SYNTAX;
3676 if ( dnX509normalize(X509_get_issuer_name(xcert), &issuer_dn ) != LDAP_SUCCESS ) {
3678 ber_memfree(serial.bv_val);
3679 return LDAP_INVALID_SYNTAX;
3684 out->bv_len = serial.bv_len + issuer_dn.bv_len + sizeof(" $ ");
3685 out->bv_val = ch_malloc(out->bv_len);
3687 AC_MEMCPY(p, serial.bv_val, serial.bv_len);
3689 AC_MEMCPY(p, " $ ", sizeof(" $ ")-1);
3691 AC_MEMCPY(p, issuer_dn.bv_val, issuer_dn.bv_len);
3692 p += issuer_dn.bv_len;
3696 LDAP_LOG( CONFIG, ARGS,
3697 "certificateExactConvert: \n %s\n", out->bv_val, 0, 0 );
3699 Debug( LDAP_DEBUG_ARGS, "certificateExactConvert "
3701 out->bv_val, NULL, NULL );
3704 ber_memfree(serial.bv_val);
3705 ber_memfree(issuer_dn.bv_val);
3707 return LDAP_SUCCESS;
3711 serial_and_issuer_parse(
3712 struct berval *assertion,
3713 struct berval *serial,
3714 struct berval *issuer_dn
3722 begin = assertion->bv_val;
3723 end = assertion->bv_val+assertion->bv_len-1;
3724 for (p=begin; p<=end && *p != '$'; p++)
3727 return LDAP_INVALID_SYNTAX;
3729 /* p now points at the $ sign, now use begin and end to delimit the
3731 while (ASCII_SPACE(*begin))
3734 while (ASCII_SPACE(*end))
3737 bv.bv_len = end-begin+1;
3739 ber_dupbv(serial, &bv);
3741 /* now extract the issuer, remember p was at the dollar sign */
3744 end = assertion->bv_val+assertion->bv_len-1;
3745 while (ASCII_SPACE(*begin))
3747 /* should we trim spaces at the end too? is it safe always? */
3749 bv.bv_len = end-begin+1;
3751 dnNormalize2( NULL, &bv, issuer_dn );
3754 return LDAP_SUCCESS;
3758 certificateExactMatch(
3763 struct berval *value,
3764 void *assertedValue )
3767 unsigned char *p = value->bv_val;
3768 struct berval serial;
3769 struct berval issuer_dn;
3770 struct berval asserted_serial;
3771 struct berval asserted_issuer_dn;
3774 xcert = d2i_X509(NULL, &p, value->bv_len);
3777 LDAP_LOG( CONFIG, ENTRY,
3778 "certificateExactMatch: error parsing cert: %s\n",
3779 ERR_error_string(ERR_get_error(),NULL), 0, 0 );
3781 Debug( LDAP_DEBUG_ARGS, "certificateExactMatch: "
3782 "error parsing cert: %s\n",
3783 ERR_error_string(ERR_get_error(),NULL), NULL, NULL );
3785 return LDAP_INVALID_SYNTAX;
3788 asn1_integer2str(xcert->cert_info->serialNumber, &serial);
3789 dnX509normalize(X509_get_issuer_name(xcert), &issuer_dn);
3793 serial_and_issuer_parse(assertedValue,
3795 &asserted_issuer_dn);
3800 slap_schema.si_syn_integer,
3801 slap_schema.si_mr_integerMatch,
3804 if ( ret == LDAP_SUCCESS ) {
3805 if ( *matchp == 0 ) {
3806 /* We need to normalize everything for dnMatch */
3810 slap_schema.si_syn_distinguishedName,
3811 slap_schema.si_mr_distinguishedNameMatch,
3813 &asserted_issuer_dn);
3818 LDAP_LOG( CONFIG, ARGS, "certificateExactMatch "
3819 "%d\n\t\"%s $ %s\"\n",
3820 *matchp, serial.bv_val, issuer_dn.bv_val );
3821 LDAP_LOG( CONFIG, ARGS, "\t\"%s $ %s\"\n",
3822 asserted_serial.bv_val, asserted_issuer_dn.bv_val,
3825 Debug( LDAP_DEBUG_ARGS, "certificateExactMatch "
3826 "%d\n\t\"%s $ %s\"\n",
3827 *matchp, serial.bv_val, issuer_dn.bv_val );
3828 Debug( LDAP_DEBUG_ARGS, "\t\"%s $ %s\"\n",
3829 asserted_serial.bv_val, asserted_issuer_dn.bv_val,
3833 ber_memfree(serial.bv_val);
3834 ber_memfree(issuer_dn.bv_val);
3835 ber_memfree(asserted_serial.bv_val);
3836 ber_memfree(asserted_issuer_dn.bv_val);
3842 * Index generation function
3843 * We just index the serials, in most scenarios the issuer DN is one of
3844 * a very small set of values.
3846 static int certificateExactIndexer(
3851 struct berval *prefix,
3859 struct berval serial;
3861 /* we should have at least one value at this point */
3862 assert( values != NULL && values[0].bv_val != NULL );
3864 for( i=0; values[i].bv_val != NULL; i++ ) {
3865 /* empty -- just count them */
3868 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
3870 for( i=0; values[i].bv_val != NULL; i++ ) {
3871 p = values[i].bv_val;
3872 xcert = d2i_X509(NULL, &p, values[i].bv_len);
3875 LDAP_LOG( CONFIG, ENTRY,
3876 "certificateExactIndexer: error parsing cert: %s\n",
3877 ERR_error_string(ERR_get_error(),NULL), 0, 0);
3879 Debug( LDAP_DEBUG_ARGS, "certificateExactIndexer: "
3880 "error parsing cert: %s\n",
3881 ERR_error_string(ERR_get_error(),NULL),
3884 /* Do we leak keys on error? */
3885 return LDAP_INVALID_SYNTAX;
3888 asn1_integer2str(xcert->cert_info->serialNumber, &serial);
3890 integerNormalize( slap_schema.si_syn_integer,
3893 ber_memfree(serial.bv_val);
3895 LDAP_LOG( CONFIG, ENTRY,
3896 "certificateExactIndexer: returning: %s\n", keys[i].bv_val, 0, 0);
3898 Debug( LDAP_DEBUG_ARGS, "certificateExactIndexer: "
3905 keys[i].bv_val = NULL;
3907 return LDAP_SUCCESS;
3910 /* Index generation function */
3911 /* We think this is always called with a value in matching rule syntax */
3912 static int certificateExactFilter(
3917 struct berval *prefix,
3922 struct berval asserted_serial;
3924 serial_and_issuer_parse(assertValue,
3928 keys = ch_malloc( sizeof( struct berval ) * 2 );
3929 integerNormalize( syntax, &asserted_serial, &keys[0] );
3930 keys[1].bv_val = NULL;
3933 ber_memfree(asserted_serial.bv_val);
3934 return LDAP_SUCCESS;
3939 check_time_syntax (struct berval *val,
3943 static int ceiling[9] = { 99, 99, 11, 30, 23, 59, 59, 12, 59 };
3944 static int mdays[2][12] = {
3945 /* non-leap years */
3946 { 30, 27, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30 },
3948 { 30, 28, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30 }
3951 int part, c, tzoffset, leapyear = 0 ;
3953 if( val->bv_len == 0 ) {
3954 return LDAP_INVALID_SYNTAX;
3957 p = (char *)val->bv_val;
3958 e = p + val->bv_len;
3960 /* Ignore initial whitespace */
3961 while ( ( p < e ) && ASCII_SPACE( *p ) ) {
3965 if (e - p < 13 - (2 * start)) {
3966 return LDAP_INVALID_SYNTAX;
3969 for (part = 0; part < 9; part++) {
3973 for (part = start; part < 7; part++) {
3975 if ((part == 6) && (c == 'Z' || c == '+' || c == '-')) {
3982 return LDAP_INVALID_SYNTAX;
3984 if (c < 0 || c > 9) {
3985 return LDAP_INVALID_SYNTAX;
3991 return LDAP_INVALID_SYNTAX;
3993 if (c < 0 || c > 9) {
3994 return LDAP_INVALID_SYNTAX;
3999 if (part == 2 || part == 3) {
4002 if (parts[part] < 0) {
4003 return LDAP_INVALID_SYNTAX;
4005 if (parts[part] > ceiling[part]) {
4006 return LDAP_INVALID_SYNTAX;
4010 /* leapyear check for the Gregorian calendar (year>1581) */
4011 if (((parts[1] % 4 == 0) && (parts[1] != 0)) ||
4012 ((parts[0] % 4 == 0) && (parts[1] == 0)))
4017 if (parts[3] > mdays[leapyear][parts[2]]) {
4018 return LDAP_INVALID_SYNTAX;
4023 tzoffset = 0; /* UTC */
4024 } else if (c != '+' && c != '-') {
4025 return LDAP_INVALID_SYNTAX;
4029 } else /* c == '+' */ {
4034 return LDAP_INVALID_SYNTAX;
4037 for (part = 7; part < 9; part++) {
4039 if (c < 0 || c > 9) {
4040 return LDAP_INVALID_SYNTAX;
4045 if (c < 0 || c > 9) {
4046 return LDAP_INVALID_SYNTAX;
4050 if (parts[part] < 0 || parts[part] > ceiling[part]) {
4051 return LDAP_INVALID_SYNTAX;
4056 /* Ignore trailing whitespace */
4057 while ( ( p < e ) && ASCII_SPACE( *p ) ) {
4061 return LDAP_INVALID_SYNTAX;
4064 switch ( tzoffset ) {
4065 case -1: /* negativ offset to UTC, ie west of Greenwich */
4066 parts[4] += parts[7];
4067 parts[5] += parts[8];
4068 for (part = 6; --part > 0; ) { /* offset is just hhmm, no seconds */
4072 c = mdays[leapyear][parts[2]];
4074 if (parts[part] > c) {
4075 parts[part] -= c + 1;
4080 case 1: /* positive offset to UTC, ie east of Greenwich */
4081 parts[4] -= parts[7];
4082 parts[5] -= parts[8];
4083 for (part = 6; --part > 0; ) {
4087 /* first arg to % needs to be non negativ */
4088 c = mdays[leapyear][(parts[2] - 1 + 12) % 12];
4090 if (parts[part] < 0) {
4091 parts[part] += c + 1;
4096 case 0: /* already UTC */
4100 return LDAP_SUCCESS;
4103 #ifdef SUPPORT_OBSOLETE_UTC_SYNTAX
4108 struct berval *normalized )
4112 rc = check_time_syntax(val, 1, parts);
4113 if (rc != LDAP_SUCCESS) {
4117 normalized->bv_val = ch_malloc( 14 );
4118 if ( normalized->bv_val == NULL ) {
4119 return LBER_ERROR_MEMORY;
4122 sprintf( normalized->bv_val, "%02d%02d%02d%02d%02d%02dZ",
4123 parts[1], parts[2] + 1, parts[3] + 1,
4124 parts[4], parts[5], parts[6] );
4125 normalized->bv_len = 13;
4127 return LDAP_SUCCESS;
4131 #ifdef SUPPORT_OBSOLETE_UTC_SYNTAX
4139 return check_time_syntax(in, 1, parts);
4144 generalizedTimeValidate(
4150 return check_time_syntax(in, 0, parts);
4154 generalizedTimeNormalize(
4157 struct berval *normalized )
4161 rc = check_time_syntax(val, 0, parts);
4162 if (rc != LDAP_SUCCESS) {
4166 normalized->bv_val = ch_malloc( 16 );
4167 if ( normalized->bv_val == NULL ) {
4168 return LBER_ERROR_MEMORY;
4171 sprintf( normalized->bv_val, "%02d%02d%02d%02d%02d%02d%02dZ",
4172 parts[0], parts[1], parts[2] + 1, parts[3] + 1,
4173 parts[4], parts[5], parts[6] );
4174 normalized->bv_len = 15;
4176 return LDAP_SUCCESS;
4180 nisNetgroupTripleValidate(
4182 struct berval *val )
4187 if ( val->bv_len == 0 ) {
4188 return LDAP_INVALID_SYNTAX;
4191 p = (char *)val->bv_val;
4192 e = p + val->bv_len;
4194 if ( *p != '(' /*')'*/ ) {
4195 return LDAP_INVALID_SYNTAX;
4198 for ( p++; ( p < e ) && ( *p != /*'('*/ ')' ); p++ ) {
4202 return LDAP_INVALID_SYNTAX;
4205 } else if ( !AD_CHAR( *p ) ) {
4206 return LDAP_INVALID_SYNTAX;
4210 if ( ( commas != 2 ) || ( *p != /*'('*/ ')' ) ) {
4211 return LDAP_INVALID_SYNTAX;
4217 return LDAP_INVALID_SYNTAX;
4220 return LDAP_SUCCESS;
4224 bootParameterValidate(
4226 struct berval *val )
4230 if ( val->bv_len == 0 ) {
4231 return LDAP_INVALID_SYNTAX;
4234 p = (char *)val->bv_val;
4235 e = p + val->bv_len;
4238 for (; ( p < e ) && ( *p != '=' ); p++ ) {
4239 if ( !AD_CHAR( *p ) ) {
4240 return LDAP_INVALID_SYNTAX;
4245 return LDAP_INVALID_SYNTAX;
4249 for ( p++; ( p < e ) && ( *p != ':' ); p++ ) {
4250 if ( !AD_CHAR( *p ) ) {
4251 return LDAP_INVALID_SYNTAX;
4256 return LDAP_INVALID_SYNTAX;
4260 for ( p++; p < e; p++ ) {
4261 if ( !SLAP_PRINTABLE( *p ) ) {
4262 return LDAP_INVALID_SYNTAX;
4266 return LDAP_SUCCESS;
4269 #define X_BINARY "X-BINARY-TRANSFER-REQUIRED 'TRUE' "
4270 #define X_NOT_H_R "X-NOT-HUMAN-READABLE 'TRUE' "
4272 static slap_syntax_defs_rec syntax_defs[] = {
4273 {"( 1.3.6.1.4.1.1466.115.121.1.1 DESC 'ACI Item' "
4274 X_BINARY X_NOT_H_R ")",
4275 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, NULL, NULL, NULL},
4276 {"( 1.3.6.1.4.1.1466.115.121.1.2 DESC 'Access Point' " X_NOT_H_R ")",
4277 0, NULL, NULL, NULL},
4278 {"( 1.3.6.1.4.1.1466.115.121.1.3 DESC 'Attribute Type Description' )",
4279 0, NULL, NULL, NULL},
4280 {"( 1.3.6.1.4.1.1466.115.121.1.4 DESC 'Audio' "
4282 SLAP_SYNTAX_BLOB, blobValidate, NULL, NULL},
4283 {"( 1.3.6.1.4.1.1466.115.121.1.5 DESC 'Binary' "
4285 SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4286 {"( 1.3.6.1.4.1.1466.115.121.1.6 DESC 'Bit String' )",
4287 0, bitStringValidate, bitStringNormalize, NULL },
4288 {"( 1.3.6.1.4.1.1466.115.121.1.7 DESC 'Boolean' )",
4289 0, booleanValidate, NULL, NULL},
4290 {"( 1.3.6.1.4.1.1466.115.121.1.8 DESC 'Certificate' "
4291 X_BINARY X_NOT_H_R ")",
4292 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4293 {"( 1.3.6.1.4.1.1466.115.121.1.9 DESC 'Certificate List' "
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.10 DESC 'Certificate Pair' "
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.11 DESC 'Country String' )",
4300 0, countryStringValidate, IA5StringNormalize, NULL},
4301 {"( 1.3.6.1.4.1.1466.115.121.1.12 DESC 'Distinguished Name' )",
4302 0, dnValidate, dnNormalize2, dnPretty2},
4303 {"( 1.3.6.1.4.1.1466.115.121.1.13 DESC 'Data Quality' )",
4304 0, NULL, NULL, NULL},
4305 {"( 1.3.6.1.4.1.1466.115.121.1.14 DESC 'Delivery Method' )",
4306 0, NULL, NULL, NULL},
4307 {"( 1.3.6.1.4.1.1466.115.121.1.15 DESC 'Directory String' )",
4308 0, UTF8StringValidate, UTF8StringNormalize, NULL},
4309 {"( 1.3.6.1.4.1.1466.115.121.1.16 DESC 'DIT Content Rule Description' )",
4310 0, NULL, NULL, NULL},
4311 {"( 1.3.6.1.4.1.1466.115.121.1.17 DESC 'DIT Structure Rule Description' )",
4312 0, NULL, NULL, NULL},
4313 {"( 1.3.6.1.4.1.1466.115.121.1.19 DESC 'DSA Quality' )",
4314 0, NULL, NULL, NULL},
4315 {"( 1.3.6.1.4.1.1466.115.121.1.20 DESC 'DSE Type' )",
4316 0, NULL, NULL, NULL},
4317 {"( 1.3.6.1.4.1.1466.115.121.1.21 DESC 'Enhanced Guide' )",
4318 0, NULL, NULL, NULL},
4319 {"( 1.3.6.1.4.1.1466.115.121.1.22 DESC 'Facsimile Telephone Number' )",
4320 0, printablesStringValidate, telephoneNumberNormalize, NULL},
4321 {"( 1.3.6.1.4.1.1466.115.121.1.23 DESC 'Fax' " X_NOT_H_R ")",
4322 SLAP_SYNTAX_BLOB, NULL, NULL, NULL},
4323 {"( 1.3.6.1.4.1.1466.115.121.1.24 DESC 'Generalized Time' )",
4324 0, generalizedTimeValidate, generalizedTimeNormalize, NULL},
4325 {"( 1.3.6.1.4.1.1466.115.121.1.25 DESC 'Guide' )",
4326 0, NULL, NULL, NULL},
4327 {"( 1.3.6.1.4.1.1466.115.121.1.26 DESC 'IA5 String' )",
4328 0, IA5StringValidate, IA5StringNormalize, NULL},
4329 {"( 1.3.6.1.4.1.1466.115.121.1.27 DESC 'Integer' )",
4330 0, integerValidate, integerNormalize, NULL},
4331 {"( 1.3.6.1.4.1.1466.115.121.1.28 DESC 'JPEG' " X_NOT_H_R ")",
4332 SLAP_SYNTAX_BLOB, blobValidate, NULL, NULL},
4333 {"( 1.3.6.1.4.1.1466.115.121.1.29 DESC 'Master And Shadow Access Points' )",
4334 0, NULL, NULL, NULL},
4335 {"( 1.3.6.1.4.1.1466.115.121.1.30 DESC 'Matching Rule Description' )",
4336 0, NULL, NULL, NULL},
4337 {"( 1.3.6.1.4.1.1466.115.121.1.31 DESC 'Matching Rule Use Description' )",
4338 0, NULL, NULL, NULL},
4339 {"( 1.3.6.1.4.1.1466.115.121.1.32 DESC 'Mail Preference' )",
4340 0, NULL, NULL, NULL},
4341 {"( 1.3.6.1.4.1.1466.115.121.1.33 DESC 'MHS OR Address' )",
4342 0, NULL, NULL, NULL},
4343 {"( 1.3.6.1.4.1.1466.115.121.1.34 DESC 'Name And Optional UID' )",
4344 0, nameUIDValidate, nameUIDNormalize, NULL},
4345 {"( 1.3.6.1.4.1.1466.115.121.1.35 DESC 'Name Form Description' )",
4346 0, NULL, NULL, NULL},
4347 {"( 1.3.6.1.4.1.1466.115.121.1.36 DESC 'Numeric String' )",
4348 0, numericStringValidate, numericStringNormalize, NULL},
4349 {"( 1.3.6.1.4.1.1466.115.121.1.37 DESC 'Object Class Description' )",
4350 0, NULL, NULL, NULL},
4351 {"( 1.3.6.1.4.1.1466.115.121.1.38 DESC 'OID' )",
4352 0, oidValidate, NULL, NULL},
4353 {"( 1.3.6.1.4.1.1466.115.121.1.39 DESC 'Other Mailbox' )",
4354 0, IA5StringValidate, IA5StringNormalize, NULL},
4355 {"( 1.3.6.1.4.1.1466.115.121.1.40 DESC 'Octet String' )",
4356 0, blobValidate, NULL, NULL},
4357 {"( 1.3.6.1.4.1.1466.115.121.1.41 DESC 'Postal Address' )",
4358 0, UTF8StringValidate, UTF8StringNormalize, NULL},
4359 {"( 1.3.6.1.4.1.1466.115.121.1.42 DESC 'Protocol Information' )",
4360 0, NULL, NULL, NULL},
4361 {"( 1.3.6.1.4.1.1466.115.121.1.43 DESC 'Presentation Address' )",
4362 0, NULL, NULL, NULL},
4363 {"( 1.3.6.1.4.1.1466.115.121.1.44 DESC 'Printable String' )",
4364 0, printableStringValidate, IA5StringNormalize, NULL},
4365 {"( 1.3.6.1.4.1.1466.115.121.1.45 DESC 'SubtreeSpecification' "
4366 X_BINARY X_NOT_H_R ")",
4367 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, NULL, NULL, NULL},
4368 {"( 1.3.6.1.4.1.1466.115.121.1.49 DESC 'Supported Algorithm' "
4369 X_BINARY X_NOT_H_R ")",
4370 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4371 {"( 1.3.6.1.4.1.1466.115.121.1.50 DESC 'Telephone Number' )",
4372 0, printableStringValidate, telephoneNumberNormalize, NULL},
4373 {"( 1.3.6.1.4.1.1466.115.121.1.51 DESC 'Teletex Terminal Identifier' )",
4374 0, NULL, NULL, NULL},
4375 {"( 1.3.6.1.4.1.1466.115.121.1.52 DESC 'Telex Number' )",
4376 0, printablesStringValidate, IA5StringNormalize, NULL},
4377 #ifdef SUPPORT_OBSOLETE_UTC_SYNTAX
4378 {"( 1.3.6.1.4.1.1466.115.121.1.53 DESC 'UTC Time' )",
4379 0, utcTimeValidate, utcTimeNormalize, NULL},
4381 {"( 1.3.6.1.4.1.1466.115.121.1.54 DESC 'LDAP Syntax Description' )",
4382 0, NULL, NULL, NULL},
4383 {"( 1.3.6.1.4.1.1466.115.121.1.55 DESC 'Modify Rights' )",
4384 0, NULL, NULL, NULL},
4385 {"( 1.3.6.1.4.1.1466.115.121.1.56 DESC 'LDAP Schema Definition' )",
4386 0, NULL, NULL, NULL},
4387 {"( 1.3.6.1.4.1.1466.115.121.1.57 DESC 'LDAP Schema Description' )",
4388 0, NULL, NULL, NULL},
4389 {"( 1.3.6.1.4.1.1466.115.121.1.58 DESC 'Substring Assertion' )",
4390 0, NULL, NULL, NULL},
4392 /* RFC 2307 NIS Syntaxes */
4393 {"( 1.3.6.1.1.1.0.0 DESC 'RFC2307 NIS Netgroup Triple' )",
4394 0, nisNetgroupTripleValidate, NULL, NULL},
4395 {"( 1.3.6.1.1.1.0.1 DESC 'RFC2307 Boot Parameter' )",
4396 0, bootParameterValidate, NULL, NULL},
4400 /* These OIDs are not published yet, but will be in the next
4401 * I-D for PKIX LDAPv3 schema as have been advanced by David
4402 * Chadwick in private mail.
4404 {"( 1.2.826.0.1.3344810.7.1 DESC 'Serial Number and Issuer' )",
4405 0, NULL, NULL, NULL},
4408 /* OpenLDAP Experimental Syntaxes */
4409 #ifdef SLAPD_ACI_ENABLED
4410 {"( 1.3.6.1.4.1.4203.666.2.1 DESC 'OpenLDAP Experimental ACI' )",
4412 UTF8StringValidate /* THIS WILL CHANGE FOR NEW ACI SYNTAX */,
4416 #ifdef SLAPD_AUTHPASSWD
4417 /* needs updating */
4418 {"( 1.3.6.1.4.1.4203.666.2.2 DESC 'OpenLDAP authPassword' )",
4419 SLAP_SYNTAX_HIDE, NULL, NULL, NULL},
4422 /* OpenLDAP Void Syntax */
4423 {"( 1.3.6.1.4.1.4203.1.1.1 DESC 'OpenLDAP void' )" ,
4424 SLAP_SYNTAX_HIDE, inValidate, NULL, NULL},
4425 {NULL, 0, NULL, NULL, NULL}
4429 * Other matching rules in X.520 that we do not use (yet):
4431 * 2.5.13.9 numericStringOrderingMatch
4432 * 2.5.13.18 octetStringOrderingMatch
4433 * 2.5.13.19 octetStringSubstringsMatch
4434 * 2.5.13.25 uTCTimeMatch
4435 * 2.5.13.26 uTCTimeOrderingMatch
4436 * 2.5.13.31 directoryStringFirstComponentMatch
4437 * 2.5.13.32 wordMatch
4438 * 2.5.13.33 keywordMatch
4439 * 2.5.13.35 certificateMatch
4440 * 2.5.13.36 certificatePairExactMatch
4441 * 2.5.13.37 certificatePairMatch
4442 * 2.5.13.38 certificateListExactMatch
4443 * 2.5.13.39 certificateListMatch
4444 * 2.5.13.40 algorithmIdentifierMatch
4445 * 2.5.13.41 storedPrefixMatch
4446 * 2.5.13.42 attributeCertificateMatch
4447 * 2.5.13.43 readerAndKeyIDMatch
4448 * 2.5.13.44 attributeIntegrityMatch
4450 static slap_mrule_defs_rec mrule_defs[] = {
4452 * EQUALITY matching rules must be listed after associated APPROX
4453 * matching rules. So, we list all APPROX matching rules first.
4455 {"( " directoryStringApproxMatchOID " NAME 'directoryStringApproxMatch' "
4456 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4457 SLAP_MR_HIDE | SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT,
4459 directoryStringApproxMatch,
4460 directoryStringApproxIndexer,
4461 directoryStringApproxFilter,
4464 {"( " IA5StringApproxMatchOID " NAME 'IA5StringApproxMatch' "
4465 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4466 SLAP_MR_HIDE | SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT,
4468 IA5StringApproxMatch,
4469 IA5StringApproxIndexer,
4470 IA5StringApproxFilter,
4474 * Other matching rules
4477 {"( 2.5.13.0 NAME 'objectIdentifierMatch' "
4478 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
4479 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4481 objectIdentifierMatch, caseIgnoreIA5Indexer, caseIgnoreIA5Filter,
4484 {"( 2.5.13.1 NAME 'distinguishedNameMatch' "
4485 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )",
4486 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4488 dnMatch, dnIndexer, dnFilter,
4491 {"( 2.5.13.2 NAME 'caseIgnoreMatch' "
4492 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4493 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD,
4495 caseIgnoreMatch, caseExactIgnoreIndexer, caseExactIgnoreFilter,
4496 directoryStringApproxMatchOID },
4498 {"( 2.5.13.3 NAME 'caseIgnoreOrderingMatch' "
4499 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4502 caseIgnoreOrderingMatch, NULL, NULL,
4505 {"( 2.5.13.4 NAME 'caseIgnoreSubstringsMatch' "
4506 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4507 SLAP_MR_SUBSTR | SLAP_MR_EXT,
4509 caseExactIgnoreSubstringsMatch,
4510 caseExactIgnoreSubstringsIndexer,
4511 caseExactIgnoreSubstringsFilter,
4514 {"( 2.5.13.5 NAME 'caseExactMatch' "
4515 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4516 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4518 caseExactMatch, caseExactIgnoreIndexer, caseExactIgnoreFilter,
4519 directoryStringApproxMatchOID },
4521 {"( 2.5.13.6 NAME 'caseExactOrderingMatch' "
4522 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4525 caseExactOrderingMatch, NULL, NULL,
4528 {"( 2.5.13.7 NAME 'caseExactSubstringsMatch' "
4529 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4530 SLAP_MR_SUBSTR | SLAP_MR_EXT,
4532 caseExactIgnoreSubstringsMatch,
4533 caseExactIgnoreSubstringsIndexer,
4534 caseExactIgnoreSubstringsFilter,
4537 {"( 2.5.13.8 NAME 'numericStringMatch' "
4538 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 )",
4539 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD,
4542 caseIgnoreIA5Indexer,
4543 caseIgnoreIA5Filter,
4546 {"( 2.5.13.10 NAME 'numericStringSubstringsMatch' "
4547 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4548 SLAP_MR_SUBSTR | SLAP_MR_EXT,
4550 caseIgnoreIA5SubstringsMatch,
4551 caseIgnoreIA5SubstringsIndexer,
4552 caseIgnoreIA5SubstringsFilter,
4555 {"( 2.5.13.11 NAME 'caseIgnoreListMatch' "
4556 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )",
4557 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD,
4559 caseIgnoreListMatch, NULL, NULL,
4562 {"( 2.5.13.12 NAME 'caseIgnoreListSubstringsMatch' "
4563 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4564 SLAP_MR_SUBSTR | SLAP_MR_EXT,
4566 caseIgnoreListSubstringsMatch, NULL, NULL,
4569 {"( 2.5.13.13 NAME 'booleanMatch' "
4570 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )",
4571 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4573 booleanMatch, NULL, NULL,
4576 {"( 2.5.13.14 NAME 'integerMatch' "
4577 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4578 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4580 integerMatch, integerIndexer, integerFilter,
4583 {"( 2.5.13.15 NAME 'integerOrderingMatch' "
4584 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4587 integerOrderingMatch, NULL, NULL,
4590 {"( 2.5.13.16 NAME 'bitStringMatch' "
4591 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.6 )",
4592 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4594 bitStringMatch, bitStringIndexer, bitStringFilter,
4597 {"( 2.5.13.17 NAME 'octetStringMatch' "
4598 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
4599 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4601 octetStringMatch, octetStringIndexer, octetStringFilter,
4604 {"( 2.5.13.20 NAME 'telephoneNumberMatch' "
4605 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 )",
4606 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD,
4608 telephoneNumberMatch,
4609 telephoneNumberIndexer,
4610 telephoneNumberFilter,
4613 {"( 2.5.13.21 NAME 'telephoneNumberSubstringsMatch' "
4614 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4615 SLAP_MR_SUBSTR | SLAP_MR_EXT,
4617 telephoneNumberSubstringsMatch,
4618 telephoneNumberSubstringsIndexer,
4619 telephoneNumberSubstringsFilter,
4622 {"( 2.5.13.22 NAME 'presentationAddressMatch' "
4623 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.43 )",
4624 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4629 {"( 2.5.13.23 NAME 'uniqueMemberMatch' "
4630 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.34 )",
4631 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4633 uniqueMemberMatch, NULL, NULL,
4636 {"( 2.5.13.24 NAME 'protocolInformationMatch' "
4637 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.42 )",
4638 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4640 protocolInformationMatch, NULL, NULL,
4643 {"( 2.5.13.27 NAME 'generalizedTimeMatch' "
4644 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
4645 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4647 generalizedTimeMatch, NULL, NULL,
4650 {"( 2.5.13.28 NAME 'generalizedTimeOrderingMatch' "
4651 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
4654 generalizedTimeOrderingMatch, NULL, NULL,
4657 {"( 2.5.13.29 NAME 'integerFirstComponentMatch' "
4658 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4659 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4661 integerFirstComponentMatch, NULL, NULL,
4664 {"( 2.5.13.30 NAME 'objectIdentifierFirstComponentMatch' "
4665 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
4666 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4668 objectIdentifierFirstComponentMatch, NULL, NULL,
4672 {"( 2.5.13.34 NAME 'certificateExactMatch' "
4673 "SYNTAX 1.2.826.0.1.3344810.7.1 )",
4674 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4675 certificateExactConvert, NULL,
4676 certificateExactMatch,
4677 certificateExactIndexer, certificateExactFilter,
4681 {"( 1.3.6.1.4.1.1466.109.114.1 NAME 'caseExactIA5Match' "
4682 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4683 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4685 caseExactIA5Match, caseExactIA5Indexer, caseExactIA5Filter,
4686 IA5StringApproxMatchOID },
4688 {"( 1.3.6.1.4.1.1466.109.114.2 NAME 'caseIgnoreIA5Match' "
4689 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4690 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD,
4692 caseIgnoreIA5Match, caseIgnoreIA5Indexer, caseIgnoreIA5Filter,
4693 IA5StringApproxMatchOID },
4695 {"( 1.3.6.1.4.1.1466.109.114.3 NAME 'caseIgnoreIA5SubstringsMatch' "
4696 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4699 caseIgnoreIA5SubstringsMatch,
4700 caseIgnoreIA5SubstringsIndexer,
4701 caseIgnoreIA5SubstringsFilter,
4704 {"( 1.3.6.1.4.1.4203.1.2.1 NAME 'caseExactIA5SubstringsMatch' "
4705 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4708 caseExactIA5SubstringsMatch,
4709 caseExactIA5SubstringsIndexer,
4710 caseExactIA5SubstringsFilter,
4713 #ifdef SLAPD_AUTHPASSWD
4714 /* needs updating */
4715 {"( 1.3.6.1.4.1.4203.666.4.1 NAME 'authPasswordMatch' "
4716 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
4719 authPasswordMatch, NULL, NULL,
4723 #ifdef SLAPD_ACI_ENABLED
4724 {"( 1.3.6.1.4.1.4203.666.4.2 NAME 'OpenLDAPaciMatch' "
4725 "SYNTAX 1.3.6.1.4.1.4203.666.2.1 )",
4728 OpenLDAPaciMatch, NULL, NULL,
4732 {"( 1.2.840.113556.1.4.803 NAME 'integerBitAndMatch' "
4733 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4736 integerBitAndMatch, NULL, NULL,
4739 {"( 1.2.840.113556.1.4.804 NAME 'integerBitOrMatch' "
4740 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4743 integerBitOrMatch, NULL, NULL,
4746 {NULL, SLAP_MR_NONE, NULL, NULL, NULL, NULL}
4750 slap_schema_init( void )
4755 /* we should only be called once (from main) */
4756 assert( schema_init_done == 0 );
4758 for ( i=0; syntax_defs[i].sd_desc != NULL; i++ ) {
4759 res = register_syntax( &syntax_defs[i] );
4762 fprintf( stderr, "slap_schema_init: Error registering syntax %s\n",
4763 syntax_defs[i].sd_desc );
4768 for ( i=0; mrule_defs[i].mrd_desc != NULL; i++ ) {
4769 if( mrule_defs[i].mrd_usage == SLAP_MR_NONE ) {
4771 "slap_schema_init: Ingoring unusable matching rule %s\n",
4772 mrule_defs[i].mrd_desc );
4776 res = register_matching_rule( &mrule_defs[i] );
4780 "slap_schema_init: Error registering matching rule %s\n",
4781 mrule_defs[i].mrd_desc );
4786 for ( i=0; i < (int)(sizeof(mr_ptr)/sizeof(mr_ptr[0])); i++ )
4787 *mr_ptr[i].mr = mr_find( mr_ptr[i].oid );
4789 res = slap_schema_load();
4790 schema_init_done = 1;
4795 schema_destroy( void )
4801 for ( i=0; i < (int)(sizeof(mr_ptr)/sizeof(mr_ptr[0])); i++ )
4802 *mr_ptr[i].mr = NULL;