1 /* schema_init.c - init builtin schema */
4 * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
5 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
9 LDAP/X.500 string syntax / matching rules have a few oddities. This
10 comment attempts to detail how slapd(8) treats them.
13 In X.500(93), a directory string can be either a PrintableString,
14 a bmpString, or a UniversalString (e.g., UCS (a subset of Unicode)).
15 In later versions, more CHOICEs were added. In all cases the string
18 In LDPAv3, a directory string is a UTF-8 encoded UCS string.
20 For matching, there are both case ignore and exact rules. Both
21 also require that "insignificant" spaces be ignored.
22 spaces before the first non-space are ignored;
23 spaces after the last non-space are ignored;
24 spaces after a space are ignored.
25 Note: by these rules (and as clarified in X.520), a string of only
26 spaces is to be treated as if held one space, not empty (which would
30 In ASN.1, numeric string is just a string of digits and spaces and
31 could be empty. However, in X.500, all attribute values of numeric
32 string carry a non-empty constraint. Unfornately, some assertion
33 values are don't carry this constraint (but its unclear how such
34 an assertion could ever be true). In LDAP, there is one syntax
35 (numericString) not two (numericString with constraint, numericString
36 without constraint). This should be treated as numericString with
39 In matching, spaces are ignored.
42 In ASN.1, Printable string is just a string of printable characters and
43 can be empty. In X.500, semantics much like NumericString excepting
44 uses insignificant space handling instead of ingore all spaces.
47 Basically same as PrintableString.
61 #include <ac/string.h>
62 #include <ac/socket.h>
68 #include "ldap_utf8.h"
70 #include "lutil_hash.h"
71 #define HASH_BYTES LUTIL_HASH_BYTES
72 #define HASH_CONTEXT lutil_HASH_CTX
73 #define HASH_Init(c) lutil_HASHInit(c)
74 #define HASH_Update(c,buf,len) lutil_HASHUpdate(c,buf,len)
75 #define HASH_Final(d,c) lutil_HASHFinal(d,c)
77 /* recycled validatation routines */
78 #define berValidate blobValidate
80 /* unimplemented pretters */
81 #define integerPretty NULL
83 /* recycled matching routines */
84 #define bitStringMatch octetStringMatch
85 #define numericStringMatch caseIgnoreIA5Match
86 #define objectIdentifierMatch caseIgnoreIA5Match
87 #define telephoneNumberMatch caseIgnoreIA5Match
88 #define telephoneNumberSubstringsMatch caseIgnoreIA5SubstringsMatch
89 #define generalizedTimeMatch caseIgnoreIA5Match
90 #define generalizedTimeOrderingMatch caseIgnoreIA5Match
91 #define uniqueMemberMatch dnMatch
92 #define integerFirstComponentMatch integerMatch
94 /* approx matching rules */
95 #define directoryStringApproxMatchOID "1.3.6.1.4.1.4203.666.4.4"
96 #define directoryStringApproxMatch approxMatch
97 #define directoryStringApproxIndexer approxIndexer
98 #define directoryStringApproxFilter approxFilter
99 #define IA5StringApproxMatchOID "1.3.6.1.4.1.4203.666.4.5"
100 #define IA5StringApproxMatch approxMatch
101 #define IA5StringApproxIndexer approxIndexer
102 #define IA5StringApproxFilter approxFilter
104 /* ordering matching rules */
105 #define caseIgnoreOrderingMatch caseIgnoreMatch
106 #define caseExactOrderingMatch caseExactMatch
107 #define integerOrderingMatch integerMatch
109 /* unimplemented matching routines */
110 #define caseIgnoreListMatch NULL
111 #define caseIgnoreListSubstringsMatch NULL
112 #define protocolInformationMatch NULL
114 #ifdef SLAPD_ACI_ENABLED
115 #define OpenLDAPaciMatch NULL
117 #ifdef SLAPD_AUTHPASSWD
118 #define authPasswordMatch NULL
121 /* recycled indexing/filtering routines */
122 #define dnIndexer caseExactIgnoreIndexer
123 #define dnFilter caseExactIgnoreFilter
124 #define bitStringFilter octetStringFilter
125 #define bitStringIndexer octetStringIndexer
127 #define telephoneNumberIndexer caseIgnoreIA5Indexer
128 #define telephoneNumberFilter caseIgnoreIA5Filter
129 #define telephoneNumberSubstringsIndexer caseIgnoreIA5SubstringsIndexer
130 #define telephoneNumberSubstringsFilter caseIgnoreIA5SubstringsFilter
132 static MatchingRule *caseExactMatchingRule;
133 static MatchingRule *caseExactSubstringsMatchingRule;
134 static MatchingRule *integerFirstComponentMatchingRule;
136 static const struct MatchingRulePtr {
140 /* must match OIDs below */
141 { "2.5.13.5", &caseExactMatchingRule },
142 { "2.5.13.7", &caseExactSubstringsMatchingRule },
143 { "2.5.13.29", &integerFirstComponentMatchingRule }
147 static char *bvcasechr( struct berval *bv, unsigned char c, ber_len_t *len )
150 char lower = TOLOWER( c );
151 char upper = TOUPPER( c );
153 if( c == 0 ) return NULL;
155 for( i=0; i < bv->bv_len; i++ ) {
156 if( upper == bv->bv_val[i] || lower == bv->bv_val[i] ) {
158 return &bv->bv_val[i];
171 struct berval *value,
172 void *assertedValue )
174 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
177 match = memcmp( value->bv_val,
178 ((struct berval *) assertedValue)->bv_val,
186 /* Index generation function */
187 static int octetStringIndexer(
192 struct berval *prefix,
199 HASH_CONTEXT HASHcontext;
200 unsigned char HASHdigest[HASH_BYTES];
201 struct berval digest;
202 digest.bv_val = HASHdigest;
203 digest.bv_len = sizeof(HASHdigest);
205 for( i=0; values[i].bv_val != NULL; i++ ) {
206 /* just count them */
209 /* we should have at least one value at this point */
212 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
214 slen = syntax->ssyn_oidlen;
215 mlen = mr->smr_oidlen;
217 for( i=0; values[i].bv_val != NULL; i++ ) {
218 HASH_Init( &HASHcontext );
219 if( prefix != NULL && prefix->bv_len > 0 ) {
220 HASH_Update( &HASHcontext,
221 prefix->bv_val, prefix->bv_len );
223 HASH_Update( &HASHcontext,
224 syntax->ssyn_oid, slen );
225 HASH_Update( &HASHcontext,
227 HASH_Update( &HASHcontext,
228 values[i].bv_val, values[i].bv_len );
229 HASH_Final( HASHdigest, &HASHcontext );
231 ber_dupbv( &keys[i], &digest );
234 keys[i].bv_val = NULL;
241 /* Index generation function */
242 static int octetStringFilter(
247 struct berval *prefix,
253 HASH_CONTEXT HASHcontext;
254 unsigned char HASHdigest[HASH_BYTES];
255 struct berval *value = (struct berval *) assertValue;
256 struct berval digest;
257 digest.bv_val = HASHdigest;
258 digest.bv_len = sizeof(HASHdigest);
260 slen = syntax->ssyn_oidlen;
261 mlen = mr->smr_oidlen;
263 keys = ch_malloc( sizeof( struct berval ) * 2 );
265 HASH_Init( &HASHcontext );
266 if( prefix != NULL && prefix->bv_len > 0 ) {
267 HASH_Update( &HASHcontext,
268 prefix->bv_val, prefix->bv_len );
270 HASH_Update( &HASHcontext,
271 syntax->ssyn_oid, slen );
272 HASH_Update( &HASHcontext,
274 HASH_Update( &HASHcontext,
275 value->bv_val, value->bv_len );
276 HASH_Final( HASHdigest, &HASHcontext );
278 ber_dupbv( keys, &digest );
279 keys[1].bv_val = NULL;
291 /* any value allowed */
300 /* any value allowed */
311 /* very unforgiving validation, requires no normalization
312 * before simplistic matching
314 if( in->bv_len < 3 ) {
315 return LDAP_INVALID_SYNTAX;
319 * rfc 2252 section 6.3 Bit String
320 * bitstring = "'" *binary-digit "'"
321 * binary-digit = "0" / "1"
322 * example: '0101111101'B
325 if( in->bv_val[0] != '\'' ||
326 in->bv_val[in->bv_len-2] != '\'' ||
327 in->bv_val[in->bv_len-1] != 'B' )
329 return LDAP_INVALID_SYNTAX;
332 for( i=in->bv_len-3; i>0; i-- ) {
333 if( in->bv_val[i] != '0' && in->bv_val[i] != '1' ) {
334 return LDAP_INVALID_SYNTAX;
345 struct berval *normalized )
348 * A normalized bitString is has no extaneous (leading) zero bits.
349 * That is, '00010'B is normalized to '10'B
350 * However, as a special case, '0'B requires no normalization.
354 /* start at the first bit */
357 /* Find the first non-zero bit */
358 while ( *p == '0' ) p++;
361 /* no non-zero bits */
362 ber_str2bv( "\'0\'B", sizeof("\'0\'B") - 1, 1, normalized );
366 normalized->bv_val = ch_malloc( val->bv_len + 1 );
368 normalized->bv_val[0] = '\'';
369 normalized->bv_len = 1;
371 for( ; *p != '\0'; p++ ) {
372 normalized->bv_val[normalized->bv_len++] = *p;
375 normalized->bv_val[normalized->bv_len] = '\0';
389 if( in->bv_len == 0 ) return LDAP_SUCCESS;
391 ber_dupbv( &dn, in );
392 if( !dn.bv_val ) return LDAP_OTHER;
394 if( dn.bv_val[dn.bv_len-1] == 'B'
395 && dn.bv_val[dn.bv_len-2] == '\'' )
397 /* assume presence of optional UID */
400 for(i=dn.bv_len-3; i>1; i--) {
401 if( dn.bv_val[i] != '0' && dn.bv_val[i] != '1' ) {
405 if( dn.bv_val[i] != '\'' || dn.bv_val[i-1] != '#' ) {
406 ber_memfree( dn.bv_val );
407 return LDAP_INVALID_SYNTAX;
410 /* trim the UID to allow use of dnValidate */
411 dn.bv_val[i-1] = '\0';
415 rc = dnValidate( NULL, &dn );
417 ber_memfree( dn.bv_val );
425 struct berval *normalized )
430 ber_dupbv( &out, val );
431 if( out.bv_len != 0 ) {
432 struct berval uidin = { 0, NULL };
433 struct berval uidout = { 0, NULL };
435 if( out.bv_val[out.bv_len-1] == 'B'
436 && out.bv_val[out.bv_len-2] == '\'' )
438 /* assume presence of optional UID */
439 uidin.bv_val = strrchr( out.bv_val, '#' );
441 if( uidin.bv_val == NULL ) {
443 return LDAP_INVALID_SYNTAX;
446 uidin.bv_len = out.bv_len - (uidin.bv_val - out.bv_val);
447 out.bv_len -= uidin.bv_len--;
449 /* temporarily trim the UID */
450 *(uidin.bv_val++) = '\0';
452 rc = bitStringNormalize( syntax, &uidin, &uidout );
454 if( rc != LDAP_SUCCESS ) {
456 return LDAP_INVALID_SYNTAX;
460 #ifdef USE_DN_NORMALIZE
461 rc = dnNormalize2( NULL, &out, normalized );
463 rc = dnPretty2( NULL, &out, normalized );
466 if( rc != LDAP_SUCCESS ) {
468 free( uidout.bv_val );
469 return LDAP_INVALID_SYNTAX;
472 if( uidout.bv_len ) {
473 normalized->bv_val = ch_realloc( normalized->bv_val,
474 normalized->bv_len + uidout.bv_len + sizeof("#") );
476 /* insert the separator */
477 normalized->bv_val[normalized->bv_len++] = '#';
480 AC_MEMCPY( &normalized->bv_val[normalized->bv_len],
481 uidout.bv_val, uidout.bv_len );
482 normalized->bv_len += uidout.bv_len;
485 normalized->bv_val[normalized->bv_len] = '\0';
495 * Handling boolean syntax and matching is quite rigid.
496 * A more flexible approach would be to allow a variety
497 * of strings to be normalized and prettied into TRUE
505 /* very unforgiving validation, requires no normalization
506 * before simplistic matching
509 if( in->bv_len == 4 ) {
510 if( !memcmp( in->bv_val, "TRUE", 4 ) ) {
513 } else if( in->bv_len == 5 ) {
514 if( !memcmp( in->bv_val, "FALSE", 5 ) ) {
519 return LDAP_INVALID_SYNTAX;
528 struct berval *value,
529 void *assertedValue )
531 /* simplistic matching allowed by rigid validation */
532 struct berval *asserted = (struct berval *) assertedValue;
533 *matchp = value->bv_len != asserted->bv_len;
544 unsigned char *u = in->bv_val;
546 if( !in->bv_len ) return LDAP_INVALID_SYNTAX;
548 for( count = in->bv_len; count > 0; count-=len, u+=len ) {
549 /* get the length indicated by the first byte */
550 len = LDAP_UTF8_CHARLEN2( u, len );
552 /* very basic checks */
555 if( (u[5] & 0xC0) != 0x80 ) {
556 return LDAP_INVALID_SYNTAX;
559 if( (u[4] & 0xC0) != 0x80 ) {
560 return LDAP_INVALID_SYNTAX;
563 if( (u[3] & 0xC0) != 0x80 ) {
564 return LDAP_INVALID_SYNTAX;
567 if( (u[2] & 0xC0 )!= 0x80 ) {
568 return LDAP_INVALID_SYNTAX;
571 if( (u[1] & 0xC0) != 0x80 ) {
572 return LDAP_INVALID_SYNTAX;
575 /* CHARLEN already validated it */
578 return LDAP_INVALID_SYNTAX;
581 /* make sure len corresponds with the offset
582 to the next character */
583 if( LDAP_UTF8_OFFSET( u ) != len ) return LDAP_INVALID_SYNTAX;
586 if( count != 0 ) return LDAP_INVALID_SYNTAX;
595 struct berval *normalized )
602 /* Ignore initial whitespace */
603 /* All space is ASCII. All ASCII is 1 byte */
604 for ( ; p < val->bv_val + val->bv_len && ASCII_SPACE( p[ 0 ] ); p++ );
606 normalized->bv_len = val->bv_len - (p - val->bv_val);
607 ber_mem2bv( p, normalized->bv_len, 1, normalized );
608 e = normalized->bv_val + normalized->bv_len;
610 assert( normalized->bv_val );
612 p = q = normalized->bv_val;
617 if ( ASCII_SPACE( *p ) ) {
622 /* Ignore the extra whitespace */
623 while ( ASCII_SPACE( *p ) ) {
627 len = LDAP_UTF8_COPY(q,p);
633 assert( normalized->bv_val <= p );
634 assert( q+len <= p );
636 /* cannot start with a space */
637 assert( !ASCII_SPACE(normalized->bv_val[0]) );
640 * If the string ended in space, backup the pointer one
641 * position. One is enough because the above loop collapsed
642 * all whitespace to a single space.
650 /* cannot end with a space */
651 assert( !ASCII_SPACE( *q ) );
658 normalized->bv_len = q - normalized->bv_val;
663 /* Returns Unicode canonically normalized copy of a substring assertion
664 * Skipping attribute description */
665 static SubstringsAssertion *
666 UTF8SubstringsassertionNormalize(
667 SubstringsAssertion *sa,
670 SubstringsAssertion *nsa;
673 nsa = (SubstringsAssertion *)ch_calloc( 1, sizeof(SubstringsAssertion) );
678 if( sa->sa_initial.bv_val != NULL ) {
679 UTF8bvnormalize( &sa->sa_initial, &nsa->sa_initial, casefold );
680 if( nsa->sa_initial.bv_val == NULL ) {
685 if( sa->sa_any != NULL ) {
686 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
689 nsa->sa_any = (struct berval *)ch_malloc( (i + 1) * sizeof(struct berval) );
690 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
691 UTF8bvnormalize( &sa->sa_any[i], &nsa->sa_any[i],
693 if( nsa->sa_any[i].bv_val == NULL ) {
697 nsa->sa_any[i].bv_val = NULL;
700 if( sa->sa_final.bv_val != NULL ) {
701 UTF8bvnormalize( &sa->sa_final, &nsa->sa_final, casefold );
702 if( nsa->sa_final.bv_val == NULL ) {
710 if ( nsa->sa_final.bv_val ) free( nsa->sa_final.bv_val );
711 if ( nsa->sa_any )ber_bvarray_free( nsa->sa_any );
712 if ( nsa->sa_initial.bv_val ) free( nsa->sa_initial.bv_val );
717 #ifndef SLAPD_APPROX_OLDSINGLESTRING
719 #if defined(SLAPD_APPROX_INITIALS)
720 #define SLAPD_APPROX_DELIMITER "._ "
721 #define SLAPD_APPROX_WORDLEN 2
723 #define SLAPD_APPROX_DELIMITER " "
724 #define SLAPD_APPROX_WORDLEN 1
733 struct berval *value,
734 void *assertedValue )
736 struct berval *nval, *assertv;
737 char *val, **values, **words, *c;
738 int i, count, len, nextchunk=0, nextavail=0;
740 /* Yes, this is necessary */
741 nval = UTF8bvnormalize( value, NULL, LDAP_UTF8_APPROX );
747 /* Yes, this is necessary */
748 assertv = UTF8bvnormalize( ((struct berval *)assertedValue), NULL, LDAP_UTF8_APPROX );
749 if( assertv == NULL ) {
755 /* Isolate how many words there are */
756 for ( c = nval->bv_val, count = 1; *c; c++ ) {
757 c = strpbrk( c, SLAPD_APPROX_DELIMITER );
758 if ( c == NULL ) break;
763 /* Get a phonetic copy of each word */
764 words = (char **)ch_malloc( count * sizeof(char *) );
765 values = (char **)ch_malloc( count * sizeof(char *) );
766 for ( c = nval->bv_val, i = 0; i < count; i++, c += strlen(c) + 1 ) {
768 values[i] = phonetic(c);
771 /* Work through the asserted value's words, to see if at least some
772 of the words are there, in the same order. */
774 while ( (ber_len_t) nextchunk < assertv->bv_len ) {
775 len = strcspn( assertv->bv_val + nextchunk, SLAPD_APPROX_DELIMITER);
780 #if defined(SLAPD_APPROX_INITIALS)
781 else if( len == 1 ) {
782 /* Single letter words need to at least match one word's initial */
783 for( i=nextavail; i<count; i++ )
784 if( !strncasecmp( assertv->bv_val + nextchunk, words[i], 1 )) {
791 /* Isolate the next word in the asserted value and phonetic it */
792 assertv->bv_val[nextchunk+len] = '\0';
793 val = phonetic( assertv->bv_val + nextchunk );
795 /* See if this phonetic chunk is in the remaining words of *value */
796 for( i=nextavail; i<count; i++ ){
797 if( !strcmp( val, values[i] ) ){
805 /* This chunk in the asserted value was NOT within the *value. */
811 /* Go on to the next word in the asserted value */
815 /* If some of the words were seen, call it a match */
816 if( nextavail > 0 ) {
824 ber_bvfree( assertv );
825 for( i=0; i<count; i++ ) {
826 ch_free( values[i] );
841 struct berval *prefix,
846 int i,j, len, wordcount, keycount=0;
847 struct berval *newkeys;
850 for( j=0; values[j].bv_val != NULL; j++ ) {
851 struct berval val = { 0, NULL };
852 /* Yes, this is necessary */
853 UTF8bvnormalize( &values[j], &val, LDAP_UTF8_APPROX );
854 assert( val.bv_val != NULL );
856 /* Isolate how many words there are. There will be a key for each */
857 for( wordcount = 0, c = val.bv_val; *c; c++) {
858 len = strcspn(c, SLAPD_APPROX_DELIMITER);
859 if( len >= SLAPD_APPROX_WORDLEN ) wordcount++;
861 if (*c == '\0') break;
865 /* Allocate/increase storage to account for new keys */
866 newkeys = (struct berval *)ch_malloc( (keycount + wordcount + 1)
867 * sizeof(struct berval) );
868 AC_MEMCPY( newkeys, keys, keycount * sizeof(struct berval) );
869 if( keys ) ch_free( keys );
872 /* Get a phonetic copy of each word */
873 for( c = val.bv_val, i = 0; i < wordcount; c += len + 1 ) {
875 if( len < SLAPD_APPROX_WORDLEN ) continue;
876 ber_str2bv( phonetic( c ), 0, 0, &keys[keycount] );
881 ber_memfree( val.bv_val );
883 keys[keycount].bv_val = NULL;
895 struct berval *prefix,
904 /* Yes, this is necessary */
905 val = UTF8bvnormalize( ((struct berval *)assertValue), NULL, LDAP_UTF8_APPROX );
906 if( val == NULL || val->bv_val == NULL ) {
907 keys = (struct berval *)ch_malloc( sizeof(struct berval) );
908 keys[0].bv_val = NULL;
914 /* Isolate how many words there are. There will be a key for each */
915 for( count = 0,c = val->bv_val; *c; c++) {
916 len = strcspn(c, SLAPD_APPROX_DELIMITER);
917 if( len >= SLAPD_APPROX_WORDLEN ) count++;
919 if (*c == '\0') break;
923 /* Allocate storage for new keys */
924 keys = (struct berval *)ch_malloc( (count + 1) * sizeof(struct berval) );
926 /* Get a phonetic copy of each word */
927 for( c = val->bv_val, i = 0; i < count; c += len + 1 ) {
929 if( len < SLAPD_APPROX_WORDLEN ) continue;
930 ber_str2bv( phonetic( c ), 0, 0, &keys[i] );
936 keys[count].bv_val = NULL;
944 /* No other form of Approximate Matching is defined */
952 struct berval *value,
953 void *assertedValue )
955 char *vapprox, *avapprox;
958 /* Yes, this is necessary */
959 s = UTF8normalize( value, UTF8_NOCASEFOLD );
965 /* Yes, this is necessary */
966 t = UTF8normalize( ((struct berval *)assertedValue),
974 vapprox = phonetic( strip8bitChars( s ) );
975 avapprox = phonetic( strip8bitChars( t ) );
980 *matchp = strcmp( vapprox, avapprox );
994 struct berval *prefix,
1002 for( i=0; values[i].bv_val != NULL; i++ ) {
1003 /* empty - just count them */
1006 /* we should have at least one value at this point */
1009 keys = (struct berval *)ch_malloc( sizeof( struct berval ) * (i+1) );
1011 /* Copy each value and run it through phonetic() */
1012 for( i=0; values[i].bv_val != NULL; i++ ) {
1013 /* Yes, this is necessary */
1014 s = UTF8normalize( &values[i], UTF8_NOCASEFOLD );
1016 /* strip 8-bit chars and run through phonetic() */
1017 ber_str2bv( phonetic( strip8bitChars( s ) ), 0, 0, &keys[i] );
1020 keys[i].bv_val = NULL;
1023 return LDAP_SUCCESS;
1033 struct berval *prefix,
1040 keys = (struct berval *)ch_malloc( sizeof( struct berval * ) * 2 );
1042 /* Yes, this is necessary */
1043 s = UTF8normalize( ((struct berval *)assertValue),
1048 /* strip 8-bit chars and run through phonetic() */
1049 keys[0] = ber_bvstr( phonetic( strip8bitChars( s ) ) );
1055 return LDAP_SUCCESS;
1066 struct berval *value,
1067 void *assertedValue )
1069 *matchp = UTF8bvnormcmp( value,
1070 (struct berval *) assertedValue,
1071 LDAP_UTF8_NOCASEFOLD );
1072 return LDAP_SUCCESS;
1076 caseExactIgnoreSubstringsMatch(
1081 struct berval *value,
1082 void *assertedValue )
1085 SubstringsAssertion *sub = NULL;
1086 struct berval left = { 0, NULL };
1092 casefold = ( mr != caseExactSubstringsMatchingRule )
1093 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1095 if ( UTF8bvnormalize( value, &left, casefold ) == NULL ) {
1101 sub = UTF8SubstringsassertionNormalize( assertedValue, casefold );
1107 /* Add up asserted input length */
1108 if( sub->sa_initial.bv_val ) {
1109 inlen += sub->sa_initial.bv_len;
1112 for(i=0; sub->sa_any[i].bv_val != NULL; i++) {
1113 inlen += sub->sa_any[i].bv_len;
1116 if( sub->sa_final.bv_val ) {
1117 inlen += sub->sa_final.bv_len;
1120 if( sub->sa_initial.bv_val ) {
1121 if( inlen > left.bv_len ) {
1126 match = memcmp( sub->sa_initial.bv_val, left.bv_val,
1127 sub->sa_initial.bv_len );
1133 left.bv_val += sub->sa_initial.bv_len;
1134 left.bv_len -= sub->sa_initial.bv_len;
1135 inlen -= sub->sa_initial.bv_len;
1138 if( sub->sa_final.bv_val ) {
1139 if( inlen > left.bv_len ) {
1144 match = memcmp( sub->sa_final.bv_val,
1145 &left.bv_val[left.bv_len - sub->sa_final.bv_len],
1146 sub->sa_final.bv_len );
1152 left.bv_len -= sub->sa_final.bv_len;
1153 inlen -= sub->sa_final.bv_len;
1157 for(i=0; sub->sa_any[i].bv_val; i++) {
1162 if( inlen > left.bv_len ) {
1163 /* not enough length */
1168 if( sub->sa_any[i].bv_len == 0 ) {
1172 p = ber_bvchr( &left, *sub->sa_any[i].bv_val );
1178 idx = p - left.bv_val;
1180 if( idx >= left.bv_len ) {
1181 /* this shouldn't happen */
1183 if ( sub->sa_final.bv_val )
1184 ch_free( sub->sa_final.bv_val );
1186 ber_bvarray_free( sub->sa_any );
1187 if ( sub->sa_initial.bv_val )
1188 ch_free( sub->sa_initial.bv_val );
1196 if( sub->sa_any[i].bv_len > left.bv_len ) {
1197 /* not enough left */
1202 match = memcmp( left.bv_val,
1203 sub->sa_any[i].bv_val,
1204 sub->sa_any[i].bv_len );
1212 left.bv_val += sub->sa_any[i].bv_len;
1213 left.bv_len -= sub->sa_any[i].bv_len;
1214 inlen -= sub->sa_any[i].bv_len;
1221 if ( sub->sa_final.bv_val ) free( sub->sa_final.bv_val );
1222 if ( sub->sa_any ) ber_bvarray_free( sub->sa_any );
1223 if ( sub->sa_initial.bv_val ) free( sub->sa_initial.bv_val );
1227 return LDAP_SUCCESS;
1230 /* Index generation function */
1231 static int caseExactIgnoreIndexer(
1236 struct berval *prefix,
1244 HASH_CONTEXT HASHcontext;
1245 unsigned char HASHdigest[HASH_BYTES];
1246 struct berval digest;
1247 digest.bv_val = HASHdigest;
1248 digest.bv_len = sizeof(HASHdigest);
1250 for( i=0; values[i].bv_val != NULL; i++ ) {
1251 /* empty - just count them */
1254 /* we should have at least one value at this point */
1257 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
1259 slen = syntax->ssyn_oidlen;
1260 mlen = mr->smr_oidlen;
1262 casefold = ( mr != caseExactMatchingRule )
1263 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1265 for( i=0; values[i].bv_val != NULL; i++ ) {
1266 struct berval value;
1267 UTF8bvnormalize( &values[i], &value, casefold );
1269 HASH_Init( &HASHcontext );
1270 if( prefix != NULL && prefix->bv_len > 0 ) {
1271 HASH_Update( &HASHcontext,
1272 prefix->bv_val, prefix->bv_len );
1274 HASH_Update( &HASHcontext,
1275 syntax->ssyn_oid, slen );
1276 HASH_Update( &HASHcontext,
1277 mr->smr_oid, mlen );
1278 HASH_Update( &HASHcontext,
1279 value.bv_val, value.bv_len );
1280 HASH_Final( HASHdigest, &HASHcontext );
1282 free( value.bv_val );
1284 ber_dupbv( &keys[i], &digest );
1287 keys[i].bv_val = NULL;
1289 return LDAP_SUCCESS;
1292 /* Index generation function */
1293 static int caseExactIgnoreFilter(
1298 struct berval *prefix,
1305 HASH_CONTEXT HASHcontext;
1306 unsigned char HASHdigest[HASH_BYTES];
1307 struct berval value = { 0, NULL };
1308 struct berval digest;
1310 digest.bv_val = HASHdigest;
1311 digest.bv_len = sizeof(HASHdigest);
1313 slen = syntax->ssyn_oidlen;
1314 mlen = mr->smr_oidlen;
1316 casefold = ( mr != caseExactMatchingRule )
1317 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1319 UTF8bvnormalize( (struct berval *) assertValue, &value, casefold );
1320 /* This usually happens if filter contains bad UTF8 */
1321 if( value.bv_val == NULL ) {
1322 keys = ch_malloc( sizeof( struct berval ) );
1323 keys[0].bv_val = NULL;
1324 return LDAP_SUCCESS;
1327 keys = ch_malloc( sizeof( struct berval ) * 2 );
1329 HASH_Init( &HASHcontext );
1330 if( prefix != NULL && prefix->bv_len > 0 ) {
1331 HASH_Update( &HASHcontext,
1332 prefix->bv_val, prefix->bv_len );
1334 HASH_Update( &HASHcontext,
1335 syntax->ssyn_oid, slen );
1336 HASH_Update( &HASHcontext,
1337 mr->smr_oid, mlen );
1338 HASH_Update( &HASHcontext,
1339 value.bv_val, value.bv_len );
1340 HASH_Final( HASHdigest, &HASHcontext );
1342 ber_dupbv( keys, &digest );
1343 keys[1].bv_val = NULL;
1345 free( value.bv_val );
1348 return LDAP_SUCCESS;
1351 /* Substrings Index generation function */
1352 static int caseExactIgnoreSubstringsIndexer(
1357 struct berval *prefix,
1367 HASH_CONTEXT HASHcontext;
1368 unsigned char HASHdigest[HASH_BYTES];
1369 struct berval digest;
1370 digest.bv_val = HASHdigest;
1371 digest.bv_len = sizeof(HASHdigest);
1375 for( i=0; values[i].bv_val != NULL; i++ ) {
1376 /* empty - just count them */
1379 /* we should have at least one value at this point */
1382 casefold = ( mr != caseExactSubstringsMatchingRule )
1383 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1385 nvalues = ch_malloc( sizeof( struct berval ) * (i+1) );
1386 for( i=0; values[i].bv_val != NULL; i++ ) {
1387 UTF8bvnormalize( &values[i], &nvalues[i], casefold );
1389 nvalues[i].bv_val = NULL;
1392 for( i=0; values[i].bv_val != NULL; i++ ) {
1393 /* count number of indices to generate */
1394 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
1398 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
1399 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1400 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
1401 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
1403 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
1407 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
1408 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1409 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
1413 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
1414 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1415 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
1416 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
1418 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
1424 /* no keys to generate */
1426 ber_bvarray_free( nvalues );
1427 return LDAP_SUCCESS;
1430 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
1432 slen = syntax->ssyn_oidlen;
1433 mlen = mr->smr_oidlen;
1436 for( i=0; values[i].bv_val != NULL; i++ ) {
1439 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
1441 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
1442 ( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
1444 char pre = SLAP_INDEX_SUBSTR_PREFIX;
1445 max = values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
1447 for( j=0; j<max; j++ ) {
1448 HASH_Init( &HASHcontext );
1449 if( prefix != NULL && prefix->bv_len > 0 ) {
1450 HASH_Update( &HASHcontext,
1451 prefix->bv_val, prefix->bv_len );
1454 HASH_Update( &HASHcontext,
1455 &pre, sizeof( pre ) );
1456 HASH_Update( &HASHcontext,
1457 syntax->ssyn_oid, slen );
1458 HASH_Update( &HASHcontext,
1459 mr->smr_oid, mlen );
1460 HASH_Update( &HASHcontext,
1461 &values[i].bv_val[j],
1462 SLAP_INDEX_SUBSTR_MAXLEN );
1463 HASH_Final( HASHdigest, &HASHcontext );
1465 ber_dupbv( &keys[nkeys++], &digest );
1469 max = SLAP_INDEX_SUBSTR_MAXLEN < values[i].bv_len
1470 ? SLAP_INDEX_SUBSTR_MAXLEN : values[i].bv_len;
1472 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
1475 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
1476 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
1477 HASH_Init( &HASHcontext );
1478 if( prefix != NULL && prefix->bv_len > 0 ) {
1479 HASH_Update( &HASHcontext,
1480 prefix->bv_val, prefix->bv_len );
1482 HASH_Update( &HASHcontext,
1483 &pre, sizeof( pre ) );
1484 HASH_Update( &HASHcontext,
1485 syntax->ssyn_oid, slen );
1486 HASH_Update( &HASHcontext,
1487 mr->smr_oid, mlen );
1488 HASH_Update( &HASHcontext,
1489 values[i].bv_val, j );
1490 HASH_Final( HASHdigest, &HASHcontext );
1492 ber_dupbv( &keys[nkeys++], &digest );
1495 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
1496 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
1497 HASH_Init( &HASHcontext );
1498 if( prefix != NULL && prefix->bv_len > 0 ) {
1499 HASH_Update( &HASHcontext,
1500 prefix->bv_val, prefix->bv_len );
1502 HASH_Update( &HASHcontext,
1503 &pre, sizeof( pre ) );
1504 HASH_Update( &HASHcontext,
1505 syntax->ssyn_oid, slen );
1506 HASH_Update( &HASHcontext,
1507 mr->smr_oid, mlen );
1508 HASH_Update( &HASHcontext,
1509 &values[i].bv_val[values[i].bv_len-j], j );
1510 HASH_Final( HASHdigest, &HASHcontext );
1512 ber_dupbv( &keys[nkeys++], &digest );
1520 keys[nkeys].bv_val = NULL;
1527 ber_bvarray_free( nvalues );
1529 return LDAP_SUCCESS;
1532 static int caseExactIgnoreSubstringsFilter(
1537 struct berval *prefix,
1541 SubstringsAssertion *sa;
1544 ber_len_t nkeys = 0;
1545 size_t slen, mlen, klen;
1547 HASH_CONTEXT HASHcontext;
1548 unsigned char HASHdigest[HASH_BYTES];
1549 struct berval *value;
1550 struct berval digest;
1552 casefold = ( mr != caseExactSubstringsMatchingRule )
1553 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1555 sa = UTF8SubstringsassertionNormalize( assertValue, casefold );
1558 return LDAP_SUCCESS;
1561 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
1562 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1567 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
1569 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
1570 if( sa->sa_any[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1571 /* don't bother accounting for stepping */
1572 nkeys += sa->sa_any[i].bv_len -
1573 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
1578 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
1579 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1585 if ( sa->sa_final.bv_val ) free( sa->sa_final.bv_val );
1586 if ( sa->sa_any ) ber_bvarray_free( sa->sa_any );
1587 if ( sa->sa_initial.bv_val ) free( sa->sa_initial.bv_val );
1590 return LDAP_SUCCESS;
1593 digest.bv_val = HASHdigest;
1594 digest.bv_len = sizeof(HASHdigest);
1596 slen = syntax->ssyn_oidlen;
1597 mlen = mr->smr_oidlen;
1599 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
1602 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
1603 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1605 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
1606 value = &sa->sa_initial;
1608 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
1609 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
1611 HASH_Init( &HASHcontext );
1612 if( prefix != NULL && prefix->bv_len > 0 ) {
1613 HASH_Update( &HASHcontext,
1614 prefix->bv_val, prefix->bv_len );
1616 HASH_Update( &HASHcontext,
1617 &pre, sizeof( pre ) );
1618 HASH_Update( &HASHcontext,
1619 syntax->ssyn_oid, slen );
1620 HASH_Update( &HASHcontext,
1621 mr->smr_oid, mlen );
1622 HASH_Update( &HASHcontext,
1623 value->bv_val, klen );
1624 HASH_Final( HASHdigest, &HASHcontext );
1626 ber_dupbv( &keys[nkeys++], &digest );
1629 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
1631 pre = SLAP_INDEX_SUBSTR_PREFIX;
1632 klen = SLAP_INDEX_SUBSTR_MAXLEN;
1634 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
1635 if( sa->sa_any[i].bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
1639 value = &sa->sa_any[i];
1642 j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
1643 j += SLAP_INDEX_SUBSTR_STEP )
1645 HASH_Init( &HASHcontext );
1646 if( prefix != NULL && prefix->bv_len > 0 ) {
1647 HASH_Update( &HASHcontext,
1648 prefix->bv_val, prefix->bv_len );
1650 HASH_Update( &HASHcontext,
1651 &pre, sizeof( pre ) );
1652 HASH_Update( &HASHcontext,
1653 syntax->ssyn_oid, slen );
1654 HASH_Update( &HASHcontext,
1655 mr->smr_oid, mlen );
1656 HASH_Update( &HASHcontext,
1657 &value->bv_val[j], klen );
1658 HASH_Final( HASHdigest, &HASHcontext );
1660 ber_dupbv( &keys[nkeys++], &digest );
1666 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
1667 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1669 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
1670 value = &sa->sa_final;
1672 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
1673 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
1675 HASH_Init( &HASHcontext );
1676 if( prefix != NULL && prefix->bv_len > 0 ) {
1677 HASH_Update( &HASHcontext,
1678 prefix->bv_val, prefix->bv_len );
1680 HASH_Update( &HASHcontext,
1681 &pre, sizeof( pre ) );
1682 HASH_Update( &HASHcontext,
1683 syntax->ssyn_oid, slen );
1684 HASH_Update( &HASHcontext,
1685 mr->smr_oid, mlen );
1686 HASH_Update( &HASHcontext,
1687 &value->bv_val[value->bv_len-klen], klen );
1688 HASH_Final( HASHdigest, &HASHcontext );
1690 ber_dupbv( &keys[nkeys++], &digest );
1694 keys[nkeys].bv_val = NULL;
1700 if ( sa->sa_final.bv_val ) free( sa->sa_final.bv_val );
1701 if ( sa->sa_any ) ber_bvarray_free( sa->sa_any );
1702 if ( sa->sa_initial.bv_val ) free( sa->sa_initial.bv_val );
1705 return LDAP_SUCCESS;
1714 struct berval *value,
1715 void *assertedValue )
1717 *matchp = UTF8bvnormcmp( value,
1718 (struct berval *) assertedValue,
1719 LDAP_UTF8_CASEFOLD );
1720 return LDAP_SUCCESS;
1723 /* Remove all spaces and '-' characters */
1725 telephoneNumberNormalize(
1728 struct berval *normalized )
1732 q = normalized->bv_val = ch_malloc( val->bv_len + 1 );
1734 for( p = val->bv_val; *p; p++ )
1735 if ( ! ( ASCII_SPACE( *p ) || *p == '-' ))
1739 normalized->bv_len = q - normalized->bv_val;
1741 return LDAP_SUCCESS;
1747 struct berval *val )
1751 if( val->bv_len == 0 ) {
1752 /* disallow empty strings */
1753 return LDAP_INVALID_SYNTAX;
1756 if( OID_LEADCHAR(val->bv_val[0]) ) {
1758 for(i=1; i < val->bv_len; i++) {
1759 if( OID_SEPARATOR( val->bv_val[i] ) ) {
1760 if( dot++ ) return 1;
1761 } else if ( OID_CHAR( val->bv_val[i] ) ) {
1764 return LDAP_INVALID_SYNTAX;
1768 return !dot ? LDAP_SUCCESS : LDAP_INVALID_SYNTAX;
1770 } else if( DESC_LEADCHAR(val->bv_val[0]) ) {
1771 for(i=1; i < val->bv_len; i++) {
1772 if( !DESC_CHAR(val->bv_val[i] ) ) {
1773 return LDAP_INVALID_SYNTAX;
1777 return LDAP_SUCCESS;
1780 return LDAP_INVALID_SYNTAX;
1789 struct berval *value,
1790 void *assertedValue )
1793 int vsign = 1, avsign = 1; /* default sign = '+' */
1794 struct berval *asserted;
1795 ber_len_t vlen, avlen;
1798 /* Skip leading space/sign/zeroes, and get the sign of the *value number */
1800 vlen = value->bv_len;
1801 if( mr == integerFirstComponentMatchingRule ) {
1802 char *tmp = memchr( v, '$', vlen );
1805 while( vlen && ASCII_SPACE( v[vlen-1] ))
1808 for( ; vlen && ( *v < '1' || '9' < *v ); v++, vlen-- ) /* ANSI 2.2.1 */
1814 /* Do the same with the *assertedValue number */
1815 asserted = (struct berval *) assertedValue;
1816 av = asserted->bv_val;
1817 avlen = asserted->bv_len;
1818 for( ; avlen && ( *av < '1' || '9' < *av ); av++, avlen-- )
1824 match = vsign - avsign;
1826 match = (vlen != avlen
1827 ? ( vlen < avlen ? -1 : 1 )
1828 : memcmp( v, av, vlen ));
1834 return LDAP_SUCCESS;
1840 struct berval *val )
1844 if( !val->bv_len ) return LDAP_INVALID_SYNTAX;
1846 if(( val->bv_val[0] == '+' ) || ( val->bv_val[0] == '-' )) {
1847 if( val->bv_len < 2 ) return LDAP_INVALID_SYNTAX;
1848 } else if( !ASCII_DIGIT(val->bv_val[0]) ) {
1849 return LDAP_INVALID_SYNTAX;
1852 for( i=1; i < val->bv_len; i++ ) {
1853 if( !ASCII_DIGIT(val->bv_val[i]) ) return LDAP_INVALID_SYNTAX;
1856 return LDAP_SUCCESS;
1863 struct berval *normalized )
1873 /* Ignore leading spaces */
1874 while ( len && ( *p == ' ' )) {
1881 negative = ( *p == '-' );
1882 if(( *p == '-' ) || ( *p == '+' )) {
1888 /* Ignore leading zeros */
1889 while ( len && ( *p == '0' )) {
1894 /* If there are no non-zero digits left, the number is zero, otherwise
1895 allocate space for the number and copy it into the buffer */
1897 normalized->bv_val = ch_strdup("0");
1898 normalized->bv_len = 1;
1901 normalized->bv_len = len+negative;
1902 normalized->bv_val = ch_malloc( normalized->bv_len + 1 );
1904 normalized->bv_val[0] = '-';
1906 AC_MEMCPY( normalized->bv_val + negative, p, len );
1907 normalized->bv_val[len+negative] = '\0';
1910 return LDAP_SUCCESS;
1913 /* Index generation function */
1914 static int integerIndexer(
1919 struct berval *prefix,
1926 HASH_CONTEXT HASHcontext;
1927 unsigned char HASHdigest[HASH_BYTES];
1928 struct berval digest;
1929 digest.bv_val = HASHdigest;
1930 digest.bv_len = sizeof(HASHdigest);
1932 for( i=0; values[i].bv_val != NULL; i++ ) {
1933 /* empty - just count them */
1936 /* we should have at least one value at this point */
1939 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
1941 slen = syntax->ssyn_oidlen;
1942 mlen = mr->smr_oidlen;
1944 for( i=0; values[i].bv_val != NULL; i++ ) {
1946 integerNormalize( syntax, &values[i], &norm );
1948 HASH_Init( &HASHcontext );
1949 if( prefix != NULL && prefix->bv_len > 0 ) {
1950 HASH_Update( &HASHcontext,
1951 prefix->bv_val, prefix->bv_len );
1953 HASH_Update( &HASHcontext,
1954 syntax->ssyn_oid, slen );
1955 HASH_Update( &HASHcontext,
1956 mr->smr_oid, mlen );
1957 HASH_Update( &HASHcontext,
1958 norm.bv_val, norm.bv_len );
1959 HASH_Final( HASHdigest, &HASHcontext );
1961 ber_dupbv( &keys[i], &digest );
1962 ch_free( norm.bv_val );
1965 keys[i].bv_val = NULL;
1967 return LDAP_SUCCESS;
1970 /* Index generation function */
1971 static int integerFilter(
1976 struct berval *prefix,
1982 HASH_CONTEXT HASHcontext;
1983 unsigned char HASHdigest[HASH_BYTES];
1985 struct berval digest;
1986 digest.bv_val = HASHdigest;
1987 digest.bv_len = sizeof(HASHdigest);
1989 slen = syntax->ssyn_oidlen;
1990 mlen = mr->smr_oidlen;
1992 integerNormalize( syntax, assertValue, &norm );
1994 keys = ch_malloc( sizeof( struct berval ) * 2 );
1996 HASH_Init( &HASHcontext );
1997 if( prefix != NULL && prefix->bv_len > 0 ) {
1998 HASH_Update( &HASHcontext,
1999 prefix->bv_val, prefix->bv_len );
2001 HASH_Update( &HASHcontext,
2002 syntax->ssyn_oid, slen );
2003 HASH_Update( &HASHcontext,
2004 mr->smr_oid, mlen );
2005 HASH_Update( &HASHcontext,
2006 norm.bv_val, norm.bv_len );
2007 HASH_Final( HASHdigest, &HASHcontext );
2009 ber_dupbv( &keys[0], &digest );
2010 keys[1].bv_val = NULL;
2011 ch_free( norm.bv_val );
2014 return LDAP_SUCCESS;
2019 countryStringValidate(
2021 struct berval *val )
2023 if( val->bv_len != 2 ) return LDAP_INVALID_SYNTAX;
2025 if( !SLAP_PRINTABLE(val->bv_val[0]) ) {
2026 return LDAP_INVALID_SYNTAX;
2028 if( !SLAP_PRINTABLE(val->bv_val[1]) ) {
2029 return LDAP_INVALID_SYNTAX;
2032 return LDAP_SUCCESS;
2036 printableStringValidate(
2038 struct berval *val )
2042 for(i=0; i < val->bv_len; i++) {
2043 if( !SLAP_PRINTABLE(val->bv_val[i]) ) {
2044 return LDAP_INVALID_SYNTAX;
2048 return LDAP_SUCCESS;
2052 printablesStringValidate(
2054 struct berval *val )
2058 for(i=0; i < val->bv_len; i++) {
2059 if( !SLAP_PRINTABLES(val->bv_val[i]) ) {
2060 return LDAP_INVALID_SYNTAX;
2064 return LDAP_SUCCESS;
2070 struct berval *val )
2074 for(i=0; i < val->bv_len; i++) {
2075 if( !LDAP_ASCII(val->bv_val[i]) ) {
2076 return LDAP_INVALID_SYNTAX;
2080 return LDAP_SUCCESS;
2087 struct berval *normalized )
2093 /* Ignore initial whitespace */
2094 while ( ASCII_SPACE( *p ) ) {
2098 normalized->bv_val = ch_strdup( p );
2099 p = q = normalized->bv_val;
2102 if ( ASCII_SPACE( *p ) ) {
2105 /* Ignore the extra whitespace */
2106 while ( ASCII_SPACE( *p ) ) {
2114 assert( normalized->bv_val <= p );
2118 * If the string ended in space, backup the pointer one
2119 * position. One is enough because the above loop collapsed
2120 * all whitespace to a single space.
2123 if ( ASCII_SPACE( q[-1] ) ) {
2127 /* null terminate */
2130 normalized->bv_len = q - normalized->bv_val;
2132 return LDAP_SUCCESS;
2141 struct berval *value,
2142 void *assertedValue )
2144 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
2147 match = strncmp( value->bv_val,
2148 ((struct berval *) assertedValue)->bv_val,
2153 return LDAP_SUCCESS;
2157 caseExactIA5SubstringsMatch(
2162 struct berval *value,
2163 void *assertedValue )
2166 SubstringsAssertion *sub = assertedValue;
2167 struct berval left = *value;
2171 /* Add up asserted input length */
2172 if( sub->sa_initial.bv_val ) {
2173 inlen += sub->sa_initial.bv_len;
2176 for(i=0; sub->sa_any[i].bv_val != NULL; i++) {
2177 inlen += sub->sa_any[i].bv_len;
2180 if( sub->sa_final.bv_val ) {
2181 inlen += sub->sa_final.bv_len;
2184 if( sub->sa_initial.bv_val ) {
2185 if( inlen > left.bv_len ) {
2190 match = strncmp( sub->sa_initial.bv_val, left.bv_val,
2191 sub->sa_initial.bv_len );
2197 left.bv_val += sub->sa_initial.bv_len;
2198 left.bv_len -= sub->sa_initial.bv_len;
2199 inlen -= sub->sa_initial.bv_len;
2202 if( sub->sa_final.bv_val ) {
2203 if( inlen > left.bv_len ) {
2208 match = strncmp( sub->sa_final.bv_val,
2209 &left.bv_val[left.bv_len - sub->sa_final.bv_len],
2210 sub->sa_final.bv_len );
2216 left.bv_len -= sub->sa_final.bv_len;
2217 inlen -= sub->sa_final.bv_len;
2221 for(i=0; sub->sa_any[i].bv_val; i++) {
2226 if( inlen > left.bv_len ) {
2227 /* not enough length */
2232 if( sub->sa_any[i].bv_len == 0 ) {
2236 p = strchr( left.bv_val, *sub->sa_any[i].bv_val );
2243 idx = p - left.bv_val;
2245 if( idx >= left.bv_len ) {
2246 /* this shouldn't happen */
2253 if( sub->sa_any[i].bv_len > left.bv_len ) {
2254 /* not enough left */
2259 match = strncmp( left.bv_val,
2260 sub->sa_any[i].bv_val,
2261 sub->sa_any[i].bv_len );
2269 left.bv_val += sub->sa_any[i].bv_len;
2270 left.bv_len -= sub->sa_any[i].bv_len;
2271 inlen -= sub->sa_any[i].bv_len;
2277 return LDAP_SUCCESS;
2280 /* Index generation function */
2281 static int caseExactIA5Indexer(
2286 struct berval *prefix,
2293 HASH_CONTEXT HASHcontext;
2294 unsigned char HASHdigest[HASH_BYTES];
2295 struct berval digest;
2296 digest.bv_val = HASHdigest;
2297 digest.bv_len = sizeof(HASHdigest);
2299 for( i=0; values[i].bv_val != NULL; i++ ) {
2300 /* empty - just count them */
2303 /* we should have at least one value at this point */
2306 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
2308 slen = syntax->ssyn_oidlen;
2309 mlen = mr->smr_oidlen;
2311 for( i=0; values[i].bv_val != NULL; i++ ) {
2312 struct berval *value = &values[i];
2314 HASH_Init( &HASHcontext );
2315 if( prefix != NULL && prefix->bv_len > 0 ) {
2316 HASH_Update( &HASHcontext,
2317 prefix->bv_val, prefix->bv_len );
2319 HASH_Update( &HASHcontext,
2320 syntax->ssyn_oid, slen );
2321 HASH_Update( &HASHcontext,
2322 mr->smr_oid, mlen );
2323 HASH_Update( &HASHcontext,
2324 value->bv_val, value->bv_len );
2325 HASH_Final( HASHdigest, &HASHcontext );
2327 ber_dupbv( &keys[i], &digest );
2330 keys[i].bv_val = NULL;
2332 return LDAP_SUCCESS;
2335 /* Index generation function */
2336 static int caseExactIA5Filter(
2341 struct berval *prefix,
2347 HASH_CONTEXT HASHcontext;
2348 unsigned char HASHdigest[HASH_BYTES];
2349 struct berval *value;
2350 struct berval digest;
2351 digest.bv_val = HASHdigest;
2352 digest.bv_len = sizeof(HASHdigest);
2354 slen = syntax->ssyn_oidlen;
2355 mlen = mr->smr_oidlen;
2357 value = (struct berval *) assertValue;
2359 keys = ch_malloc( sizeof( struct berval ) * 2 );
2361 HASH_Init( &HASHcontext );
2362 if( prefix != NULL && prefix->bv_len > 0 ) {
2363 HASH_Update( &HASHcontext,
2364 prefix->bv_val, prefix->bv_len );
2366 HASH_Update( &HASHcontext,
2367 syntax->ssyn_oid, slen );
2368 HASH_Update( &HASHcontext,
2369 mr->smr_oid, mlen );
2370 HASH_Update( &HASHcontext,
2371 value->bv_val, value->bv_len );
2372 HASH_Final( HASHdigest, &HASHcontext );
2374 ber_dupbv( &keys[0], &digest );
2375 keys[1].bv_val = NULL;
2378 return LDAP_SUCCESS;
2381 /* Substrings Index generation function */
2382 static int caseExactIA5SubstringsIndexer(
2387 struct berval *prefix,
2394 HASH_CONTEXT HASHcontext;
2395 unsigned char HASHdigest[HASH_BYTES];
2396 struct berval digest;
2397 digest.bv_val = HASHdigest;
2398 digest.bv_len = sizeof(HASHdigest);
2400 /* we should have at least one value at this point */
2401 assert( values != NULL && values[0].bv_val != NULL );
2404 for( i=0; values[i].bv_val != NULL; i++ ) {
2405 /* count number of indices to generate */
2406 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
2410 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
2411 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2412 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2413 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2415 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2419 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
2420 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2421 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
2425 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
2426 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2427 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2428 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2430 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2436 /* no keys to generate */
2438 return LDAP_SUCCESS;
2441 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
2443 slen = syntax->ssyn_oidlen;
2444 mlen = mr->smr_oidlen;
2447 for( i=0; values[i].bv_val != NULL; i++ ) {
2449 struct berval *value;
2452 if( value->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
2454 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
2455 ( value->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
2457 char pre = SLAP_INDEX_SUBSTR_PREFIX;
2458 max = value->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
2460 for( j=0; j<max; j++ ) {
2461 HASH_Init( &HASHcontext );
2462 if( prefix != NULL && prefix->bv_len > 0 ) {
2463 HASH_Update( &HASHcontext,
2464 prefix->bv_val, prefix->bv_len );
2467 HASH_Update( &HASHcontext,
2468 &pre, sizeof( pre ) );
2469 HASH_Update( &HASHcontext,
2470 syntax->ssyn_oid, slen );
2471 HASH_Update( &HASHcontext,
2472 mr->smr_oid, mlen );
2473 HASH_Update( &HASHcontext,
2475 SLAP_INDEX_SUBSTR_MAXLEN );
2476 HASH_Final( HASHdigest, &HASHcontext );
2478 ber_dupbv( &keys[nkeys++], &digest );
2482 max = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2483 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2485 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
2488 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
2489 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
2490 HASH_Init( &HASHcontext );
2491 if( prefix != NULL && prefix->bv_len > 0 ) {
2492 HASH_Update( &HASHcontext,
2493 prefix->bv_val, prefix->bv_len );
2495 HASH_Update( &HASHcontext,
2496 &pre, sizeof( pre ) );
2497 HASH_Update( &HASHcontext,
2498 syntax->ssyn_oid, slen );
2499 HASH_Update( &HASHcontext,
2500 mr->smr_oid, mlen );
2501 HASH_Update( &HASHcontext,
2503 HASH_Final( HASHdigest, &HASHcontext );
2505 ber_dupbv( &keys[nkeys++], &digest );
2508 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
2509 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
2510 HASH_Init( &HASHcontext );
2511 if( prefix != NULL && prefix->bv_len > 0 ) {
2512 HASH_Update( &HASHcontext,
2513 prefix->bv_val, prefix->bv_len );
2515 HASH_Update( &HASHcontext,
2516 &pre, sizeof( pre ) );
2517 HASH_Update( &HASHcontext,
2518 syntax->ssyn_oid, slen );
2519 HASH_Update( &HASHcontext,
2520 mr->smr_oid, mlen );
2521 HASH_Update( &HASHcontext,
2522 &value->bv_val[value->bv_len-j], j );
2523 HASH_Final( HASHdigest, &HASHcontext );
2525 ber_dupbv( &keys[nkeys++], &digest );
2532 keys[nkeys].bv_val = NULL;
2539 return LDAP_SUCCESS;
2542 static int caseExactIA5SubstringsFilter(
2547 struct berval *prefix,
2551 SubstringsAssertion *sa = assertValue;
2553 ber_len_t nkeys = 0;
2554 size_t slen, mlen, klen;
2556 HASH_CONTEXT HASHcontext;
2557 unsigned char HASHdigest[HASH_BYTES];
2558 struct berval *value;
2559 struct berval digest;
2561 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
2562 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2567 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
2569 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
2570 if( sa->sa_any[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2571 /* don't bother accounting for stepping */
2572 nkeys += sa->sa_any[i].bv_len -
2573 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
2578 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
2579 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2586 return LDAP_SUCCESS;
2589 digest.bv_val = HASHdigest;
2590 digest.bv_len = sizeof(HASHdigest);
2592 slen = syntax->ssyn_oidlen;
2593 mlen = mr->smr_oidlen;
2595 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
2598 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
2599 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2601 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
2602 value = &sa->sa_initial;
2604 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2605 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2607 HASH_Init( &HASHcontext );
2608 if( prefix != NULL && prefix->bv_len > 0 ) {
2609 HASH_Update( &HASHcontext,
2610 prefix->bv_val, prefix->bv_len );
2612 HASH_Update( &HASHcontext,
2613 &pre, sizeof( pre ) );
2614 HASH_Update( &HASHcontext,
2615 syntax->ssyn_oid, slen );
2616 HASH_Update( &HASHcontext,
2617 mr->smr_oid, mlen );
2618 HASH_Update( &HASHcontext,
2619 value->bv_val, klen );
2620 HASH_Final( HASHdigest, &HASHcontext );
2622 ber_dupbv( &keys[nkeys++], &digest );
2625 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
2627 pre = SLAP_INDEX_SUBSTR_PREFIX;
2628 klen = SLAP_INDEX_SUBSTR_MAXLEN;
2630 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
2631 if( sa->sa_any[i].bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
2635 value = &sa->sa_any[i];
2638 j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
2639 j += SLAP_INDEX_SUBSTR_STEP )
2641 HASH_Init( &HASHcontext );
2642 if( prefix != NULL && prefix->bv_len > 0 ) {
2643 HASH_Update( &HASHcontext,
2644 prefix->bv_val, prefix->bv_len );
2646 HASH_Update( &HASHcontext,
2647 &pre, sizeof( pre ) );
2648 HASH_Update( &HASHcontext,
2649 syntax->ssyn_oid, slen );
2650 HASH_Update( &HASHcontext,
2651 mr->smr_oid, mlen );
2652 HASH_Update( &HASHcontext,
2653 &value->bv_val[j], klen );
2654 HASH_Final( HASHdigest, &HASHcontext );
2656 ber_dupbv( &keys[nkeys++], &digest );
2661 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
2662 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2664 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
2665 value = &sa->sa_final;
2667 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2668 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2670 HASH_Init( &HASHcontext );
2671 if( prefix != NULL && prefix->bv_len > 0 ) {
2672 HASH_Update( &HASHcontext,
2673 prefix->bv_val, prefix->bv_len );
2675 HASH_Update( &HASHcontext,
2676 &pre, sizeof( pre ) );
2677 HASH_Update( &HASHcontext,
2678 syntax->ssyn_oid, slen );
2679 HASH_Update( &HASHcontext,
2680 mr->smr_oid, mlen );
2681 HASH_Update( &HASHcontext,
2682 &value->bv_val[value->bv_len-klen], klen );
2683 HASH_Final( HASHdigest, &HASHcontext );
2685 ber_dupbv( &keys[nkeys++], &digest );
2689 keys[nkeys].bv_val = NULL;
2696 return LDAP_SUCCESS;
2705 struct berval *value,
2706 void *assertedValue )
2708 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
2710 if( match == 0 && value->bv_len ) {
2711 match = strncasecmp( value->bv_val,
2712 ((struct berval *) assertedValue)->bv_val,
2717 return LDAP_SUCCESS;
2721 caseIgnoreIA5SubstringsMatch(
2726 struct berval *value,
2727 void *assertedValue )
2730 SubstringsAssertion *sub = assertedValue;
2731 struct berval left = *value;
2735 /* Add up asserted input length */
2736 if( sub->sa_initial.bv_val ) {
2737 inlen += sub->sa_initial.bv_len;
2740 for(i=0; sub->sa_any[i].bv_val != NULL; i++) {
2741 inlen += sub->sa_any[i].bv_len;
2744 if( sub->sa_final.bv_val ) {
2745 inlen += sub->sa_final.bv_len;
2748 if( sub->sa_initial.bv_val ) {
2749 if( inlen > left.bv_len ) {
2754 match = strncasecmp( sub->sa_initial.bv_val, left.bv_val,
2755 sub->sa_initial.bv_len );
2761 left.bv_val += sub->sa_initial.bv_len;
2762 left.bv_len -= sub->sa_initial.bv_len;
2763 inlen -= sub->sa_initial.bv_len;
2766 if( sub->sa_final.bv_val ) {
2767 if( inlen > left.bv_len ) {
2772 match = strncasecmp( sub->sa_final.bv_val,
2773 &left.bv_val[left.bv_len - sub->sa_final.bv_len],
2774 sub->sa_final.bv_len );
2780 left.bv_len -= sub->sa_final.bv_len;
2781 inlen -= sub->sa_final.bv_len;
2785 for(i=0; sub->sa_any[i].bv_val; i++) {
2790 if( inlen > left.bv_len ) {
2791 /* not enough length */
2796 if( sub->sa_any[i].bv_len == 0 ) {
2800 p = bvcasechr( &left, *sub->sa_any[i].bv_val, &idx );
2807 assert( idx < left.bv_len );
2808 if( idx >= left.bv_len ) {
2809 /* this shouldn't happen */
2816 if( sub->sa_any[i].bv_len > left.bv_len ) {
2817 /* not enough left */
2822 match = strncasecmp( left.bv_val,
2823 sub->sa_any[i].bv_val,
2824 sub->sa_any[i].bv_len );
2833 left.bv_val += sub->sa_any[i].bv_len;
2834 left.bv_len -= sub->sa_any[i].bv_len;
2835 inlen -= sub->sa_any[i].bv_len;
2841 return LDAP_SUCCESS;
2844 /* Index generation function */
2845 static int caseIgnoreIA5Indexer(
2850 struct berval *prefix,
2855 int rc = LDAP_SUCCESS;
2858 HASH_CONTEXT HASHcontext;
2859 unsigned char HASHdigest[HASH_BYTES];
2860 struct berval digest;
2861 digest.bv_val = HASHdigest;
2862 digest.bv_len = sizeof(HASHdigest);
2864 /* we should have at least one value at this point */
2865 assert( values != NULL && values[0].bv_val != NULL );
2867 for( i=0; values[i].bv_val != NULL; i++ ) {
2868 /* just count them */
2871 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
2873 slen = syntax->ssyn_oidlen;
2874 mlen = mr->smr_oidlen;
2876 for( i=0; values[i].bv_val != NULL; i++ ) {
2877 struct berval value;
2879 if( mr->smr_normalize ) {
2880 rc = (mr->smr_normalize)( use, syntax, mr, &values[i], &value );
2881 if( rc != LDAP_SUCCESS ) {
2884 } else if ( mr->smr_syntax->ssyn_normalize ) {
2885 rc = (mr->smr_syntax->ssyn_normalize)( syntax, &values[i], &value );
2886 if( rc != LDAP_SUCCESS ) {
2890 ber_dupbv( &value, &values[i] );
2893 ldap_pvt_str2lower( value.bv_val );
2895 HASH_Init( &HASHcontext );
2896 if( prefix != NULL && prefix->bv_len > 0 ) {
2897 HASH_Update( &HASHcontext,
2898 prefix->bv_val, prefix->bv_len );
2900 HASH_Update( &HASHcontext,
2901 syntax->ssyn_oid, slen );
2902 HASH_Update( &HASHcontext,
2903 mr->smr_oid, mlen );
2904 HASH_Update( &HASHcontext,
2905 value.bv_val, value.bv_len );
2906 HASH_Final( HASHdigest, &HASHcontext );
2908 free( value.bv_val );
2910 ber_dupbv( &keys[i], &digest );
2913 keys[i].bv_val = NULL;
2914 if( rc != LDAP_SUCCESS ) {
2915 ber_bvarray_free( keys );
2922 /* Index generation function */
2923 static int caseIgnoreIA5Filter(
2928 struct berval *prefix,
2934 HASH_CONTEXT HASHcontext;
2935 unsigned char HASHdigest[HASH_BYTES];
2936 struct berval value;
2937 struct berval digest;
2938 digest.bv_val = HASHdigest;
2939 digest.bv_len = sizeof(HASHdigest);
2941 slen = syntax->ssyn_oidlen;
2942 mlen = mr->smr_oidlen;
2944 ber_dupbv( &value, (struct berval *) assertValue );
2945 ldap_pvt_str2lower( value.bv_val );
2947 keys = ch_malloc( sizeof( struct berval ) * 2 );
2949 HASH_Init( &HASHcontext );
2950 if( prefix != NULL && prefix->bv_len > 0 ) {
2951 HASH_Update( &HASHcontext,
2952 prefix->bv_val, prefix->bv_len );
2954 HASH_Update( &HASHcontext,
2955 syntax->ssyn_oid, slen );
2956 HASH_Update( &HASHcontext,
2957 mr->smr_oid, mlen );
2958 HASH_Update( &HASHcontext,
2959 value.bv_val, value.bv_len );
2960 HASH_Final( HASHdigest, &HASHcontext );
2962 ber_dupbv( &keys[0], &digest );
2963 keys[1].bv_val = NULL;
2965 free( value.bv_val );
2969 return LDAP_SUCCESS;
2972 /* Substrings Index generation function */
2973 static int caseIgnoreIA5SubstringsIndexer(
2978 struct berval *prefix,
2985 HASH_CONTEXT HASHcontext;
2986 unsigned char HASHdigest[HASH_BYTES];
2987 struct berval digest;
2988 digest.bv_val = HASHdigest;
2989 digest.bv_len = sizeof(HASHdigest);
2991 /* we should have at least one value at this point */
2992 assert( values != NULL && values[0].bv_val != NULL );
2995 for( i=0; values[i].bv_val != NULL; i++ ) {
2996 /* count number of indices to generate */
2997 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
3001 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
3002 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3003 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
3004 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
3006 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
3010 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
3011 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3012 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
3016 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
3017 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3018 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
3019 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
3021 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
3027 /* no keys to generate */
3029 return LDAP_SUCCESS;
3032 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
3034 slen = syntax->ssyn_oidlen;
3035 mlen = mr->smr_oidlen;
3038 for( i=0; values[i].bv_val != NULL; i++ ) {
3040 struct berval value;
3042 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
3044 ber_dupbv( &value, &values[i] );
3045 ldap_pvt_str2lower( value.bv_val );
3047 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
3048 ( value.bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
3050 char pre = SLAP_INDEX_SUBSTR_PREFIX;
3051 max = value.bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
3053 for( j=0; j<max; j++ ) {
3054 HASH_Init( &HASHcontext );
3055 if( prefix != NULL && prefix->bv_len > 0 ) {
3056 HASH_Update( &HASHcontext,
3057 prefix->bv_val, prefix->bv_len );
3060 HASH_Update( &HASHcontext,
3061 &pre, sizeof( pre ) );
3062 HASH_Update( &HASHcontext,
3063 syntax->ssyn_oid, slen );
3064 HASH_Update( &HASHcontext,
3065 mr->smr_oid, mlen );
3066 HASH_Update( &HASHcontext,
3068 SLAP_INDEX_SUBSTR_MAXLEN );
3069 HASH_Final( HASHdigest, &HASHcontext );
3071 ber_dupbv( &keys[nkeys++], &digest );
3075 max = SLAP_INDEX_SUBSTR_MAXLEN < value.bv_len
3076 ? SLAP_INDEX_SUBSTR_MAXLEN : value.bv_len;
3078 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
3081 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
3082 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
3083 HASH_Init( &HASHcontext );
3084 if( prefix != NULL && prefix->bv_len > 0 ) {
3085 HASH_Update( &HASHcontext,
3086 prefix->bv_val, prefix->bv_len );
3088 HASH_Update( &HASHcontext,
3089 &pre, sizeof( pre ) );
3090 HASH_Update( &HASHcontext,
3091 syntax->ssyn_oid, slen );
3092 HASH_Update( &HASHcontext,
3093 mr->smr_oid, mlen );
3094 HASH_Update( &HASHcontext,
3096 HASH_Final( HASHdigest, &HASHcontext );
3098 ber_dupbv( &keys[nkeys++], &digest );
3101 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
3102 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
3103 HASH_Init( &HASHcontext );
3104 if( prefix != NULL && prefix->bv_len > 0 ) {
3105 HASH_Update( &HASHcontext,
3106 prefix->bv_val, prefix->bv_len );
3108 HASH_Update( &HASHcontext,
3109 &pre, sizeof( pre ) );
3110 HASH_Update( &HASHcontext,
3111 syntax->ssyn_oid, slen );
3112 HASH_Update( &HASHcontext,
3113 mr->smr_oid, mlen );
3114 HASH_Update( &HASHcontext,
3115 &value.bv_val[value.bv_len-j], j );
3116 HASH_Final( HASHdigest, &HASHcontext );
3118 ber_dupbv( &keys[nkeys++], &digest );
3123 free( value.bv_val );
3127 keys[nkeys].bv_val = NULL;
3134 return LDAP_SUCCESS;
3137 static int caseIgnoreIA5SubstringsFilter(
3142 struct berval *prefix,
3146 SubstringsAssertion *sa = assertValue;
3148 ber_len_t nkeys = 0;
3149 size_t slen, mlen, klen;
3151 HASH_CONTEXT HASHcontext;
3152 unsigned char HASHdigest[HASH_BYTES];
3153 struct berval value;
3154 struct berval digest;
3156 if((flags & SLAP_INDEX_SUBSTR_INITIAL) && sa->sa_initial.bv_val != NULL &&
3157 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3162 if((flags & SLAP_INDEX_SUBSTR_ANY) && sa->sa_any != NULL ) {
3164 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
3165 if( sa->sa_any[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3166 /* don't bother accounting for stepping */
3167 nkeys += sa->sa_any[i].bv_len -
3168 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
3173 if((flags & SLAP_INDEX_SUBSTR_FINAL) && sa->sa_final.bv_val != NULL &&
3174 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3181 return LDAP_SUCCESS;
3184 digest.bv_val = HASHdigest;
3185 digest.bv_len = sizeof(HASHdigest);
3187 slen = syntax->ssyn_oidlen;
3188 mlen = mr->smr_oidlen;
3190 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
3193 if((flags & SLAP_INDEX_SUBSTR_INITIAL) && sa->sa_initial.bv_val != NULL &&
3194 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3196 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
3197 ber_dupbv( &value, &sa->sa_initial );
3198 ldap_pvt_str2lower( value.bv_val );
3200 klen = SLAP_INDEX_SUBSTR_MAXLEN < value.bv_len
3201 ? SLAP_INDEX_SUBSTR_MAXLEN : value.bv_len;
3203 HASH_Init( &HASHcontext );
3204 if( prefix != NULL && prefix->bv_len > 0 ) {
3205 HASH_Update( &HASHcontext,
3206 prefix->bv_val, prefix->bv_len );
3208 HASH_Update( &HASHcontext,
3209 &pre, sizeof( pre ) );
3210 HASH_Update( &HASHcontext,
3211 syntax->ssyn_oid, slen );
3212 HASH_Update( &HASHcontext,
3213 mr->smr_oid, mlen );
3214 HASH_Update( &HASHcontext,
3215 value.bv_val, klen );
3216 HASH_Final( HASHdigest, &HASHcontext );
3218 free( value.bv_val );
3219 ber_dupbv( &keys[nkeys++], &digest );
3222 if((flags & SLAP_INDEX_SUBSTR_ANY) && sa->sa_any != NULL ) {
3224 pre = SLAP_INDEX_SUBSTR_PREFIX;
3225 klen = SLAP_INDEX_SUBSTR_MAXLEN;
3227 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
3228 if( sa->sa_any[i].bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
3232 ber_dupbv( &value, &sa->sa_any[i] );
3233 ldap_pvt_str2lower( value.bv_val );
3236 j <= value.bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
3237 j += SLAP_INDEX_SUBSTR_STEP )
3239 HASH_Init( &HASHcontext );
3240 if( prefix != NULL && prefix->bv_len > 0 ) {
3241 HASH_Update( &HASHcontext,
3242 prefix->bv_val, prefix->bv_len );
3244 HASH_Update( &HASHcontext,
3245 &pre, sizeof( pre ) );
3246 HASH_Update( &HASHcontext,
3247 syntax->ssyn_oid, slen );
3248 HASH_Update( &HASHcontext,
3249 mr->smr_oid, mlen );
3250 HASH_Update( &HASHcontext,
3251 &value.bv_val[j], klen );
3252 HASH_Final( HASHdigest, &HASHcontext );
3254 ber_dupbv( &keys[nkeys++], &digest );
3257 free( value.bv_val );
3261 if((flags & SLAP_INDEX_SUBSTR_FINAL) && sa->sa_final.bv_val != NULL &&
3262 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3264 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
3265 ber_dupbv( &value, &sa->sa_final );
3266 ldap_pvt_str2lower( value.bv_val );
3268 klen = SLAP_INDEX_SUBSTR_MAXLEN < value.bv_len
3269 ? SLAP_INDEX_SUBSTR_MAXLEN : value.bv_len;
3271 HASH_Init( &HASHcontext );
3272 if( prefix != NULL && prefix->bv_len > 0 ) {
3273 HASH_Update( &HASHcontext,
3274 prefix->bv_val, prefix->bv_len );
3276 HASH_Update( &HASHcontext,
3277 &pre, sizeof( pre ) );
3278 HASH_Update( &HASHcontext,
3279 syntax->ssyn_oid, slen );
3280 HASH_Update( &HASHcontext,
3281 mr->smr_oid, mlen );
3282 HASH_Update( &HASHcontext,
3283 &value.bv_val[value.bv_len-klen], klen );
3284 HASH_Final( HASHdigest, &HASHcontext );
3286 free( value.bv_val );
3287 ber_dupbv( &keys[nkeys++], &digest );
3291 keys[nkeys].bv_val = NULL;
3298 return LDAP_SUCCESS;
3302 numericStringValidate(
3308 for(i=0; i < in->bv_len; i++) {
3309 if( !SLAP_NUMERIC(in->bv_val[i]) ) {
3310 return LDAP_INVALID_SYNTAX;
3314 return LDAP_SUCCESS;
3318 numericStringNormalize(
3321 struct berval *normalized )
3323 /* removal all spaces */
3326 normalized->bv_val = ch_malloc( val->bv_len + 1 );
3329 q = normalized->bv_val;
3332 if ( ASCII_SPACE( *p ) ) {
3333 /* Ignore whitespace */
3340 /* we should have copied no more then is in val */
3341 assert( (q - normalized->bv_val) <= (p - val->bv_val) );
3343 /* null terminate */
3346 normalized->bv_len = q - normalized->bv_val;
3348 return LDAP_SUCCESS;
3352 objectIdentifierFirstComponentMatch(
3357 struct berval *value,
3358 void *assertedValue )
3360 int rc = LDAP_SUCCESS;
3362 struct berval *asserted = (struct berval *) assertedValue;
3366 if( value->bv_len == 0 || value->bv_val[0] != '(' /*')'*/ ) {
3367 return LDAP_INVALID_SYNTAX;
3370 /* trim leading white space */
3371 for( i=1; ASCII_SPACE(value->bv_val[i]) && i < value->bv_len; i++ ) {
3375 /* grab next word */
3376 oid.bv_val = &value->bv_val[i];
3377 oid.bv_len = value->bv_len - i;
3378 for( i=1; ASCII_SPACE(value->bv_val[i]) && i < oid.bv_len; i++ ) {
3383 /* insert attributeTypes, objectclass check here */
3384 if( OID_LEADCHAR(asserted->bv_val[0]) ) {
3385 rc = objectIdentifierMatch( &match, flags, syntax, mr, &oid, asserted );
3388 if ( !strcmp( syntax->ssyn_oid, SLAP_SYNTAX_MATCHINGRULES_OID ) ) {
3389 MatchingRule *asserted_mr = mr_bvfind( asserted );
3390 MatchingRule *stored_mr = mr_bvfind( &oid );
3392 if( asserted_mr == NULL ) {
3393 rc = SLAPD_COMPARE_UNDEFINED;
3395 match = asserted_mr != stored_mr;
3398 } else if ( !strcmp( syntax->ssyn_oid,
3399 SLAP_SYNTAX_ATTRIBUTETYPES_OID ) )
3401 AttributeType *asserted_at = at_bvfind( asserted );
3402 AttributeType *stored_at = at_bvfind( &oid );
3404 if( asserted_at == NULL ) {
3405 rc = SLAPD_COMPARE_UNDEFINED;
3407 match = asserted_at != stored_at;
3410 } else if ( !strcmp( syntax->ssyn_oid,
3411 SLAP_SYNTAX_OBJECTCLASSES_OID ) )
3413 ObjectClass *asserted_oc = oc_bvfind( asserted );
3414 ObjectClass *stored_oc = oc_bvfind( &oid );
3416 if( asserted_oc == NULL ) {
3417 rc = SLAPD_COMPARE_UNDEFINED;
3419 match = asserted_oc != stored_oc;
3425 LDAP_LOG( CONFIG, ENTRY,
3426 "objectIdentifierFirstComponentMatch: %d\n %s\n %s\n",
3427 match, value->bv_val, asserted->bv_val );
3429 Debug( LDAP_DEBUG_ARGS, "objectIdentifierFirstComponentMatch "
3430 "%d\n\t\"%s\"\n\t\"%s\"\n",
3431 match, value->bv_val, asserted->bv_val );
3435 if( rc == LDAP_SUCCESS ) *matchp = match;
3445 struct berval *value,
3446 void *assertedValue )
3448 long lValue, lAssertedValue;
3450 /* safe to assume integers are NUL terminated? */
3451 lValue = strtoul(value->bv_val, NULL, 10);
3452 if(( lValue == LONG_MIN || lValue == LONG_MAX) && errno == ERANGE )
3453 return LDAP_CONSTRAINT_VIOLATION;
3455 lAssertedValue = strtol(((struct berval *)assertedValue)->bv_val, NULL, 10);
3456 if(( lAssertedValue == LONG_MIN || lAssertedValue == LONG_MAX) && errno == ERANGE )
3457 return LDAP_CONSTRAINT_VIOLATION;
3459 *matchp = (lValue & lAssertedValue);
3460 return LDAP_SUCCESS;
3469 struct berval *value,
3470 void *assertedValue )
3472 long lValue, lAssertedValue;
3474 /* safe to assume integers are NUL terminated? */
3475 lValue = strtoul(value->bv_val, NULL, 10);
3476 if(( lValue == LONG_MIN || lValue == LONG_MAX) && errno == ERANGE )
3477 return LDAP_CONSTRAINT_VIOLATION;
3479 lAssertedValue = strtol(((struct berval *)assertedValue)->bv_val, NULL, 10);
3480 if(( lAssertedValue == LONG_MIN || lAssertedValue == LONG_MAX) && errno == ERANGE )
3481 return LDAP_CONSTRAINT_VIOLATION;
3483 *matchp = (lValue | lAssertedValue);
3484 return LDAP_SUCCESS;
3488 #include <openssl/x509.h>
3489 #include <openssl/err.h>
3490 char digit[] = "0123456789";
3493 * Next function returns a string representation of a ASN1_INTEGER.
3494 * It works for unlimited lengths.
3497 static struct berval *
3498 asn1_integer2str(ASN1_INTEGER *a, struct berval *bv)
3503 /* We work backwards, make it fill from the end of buf */
3504 p = buf + sizeof(buf) - 1;
3507 if ( a == NULL || a->length == 0 ) {
3515 /* We want to preserve the original */
3516 copy = ch_malloc(n*sizeof(unsigned int));
3517 for (i = 0; i<n; i++) {
3518 copy[i] = a->data[i];
3522 * base indicates the index of the most significant
3523 * byte that might be nonzero. When it goes off the
3524 * end, we now there is nothing left to do.
3530 for (i = base; i<n; i++ ) {
3531 copy[i] += carry*256;
3532 carry = copy[i] % 10;
3537 * Way too large, we need to leave
3538 * room for sign if negative
3543 *--p = digit[carry];
3544 if (copy[base] == 0)
3550 if ( a->type == V_ASN1_NEG_INTEGER ) {
3554 return ber_str2bv( p, 0, 1, bv );
3558 * Given a certificate in DER format, extract the corresponding
3559 * assertion value for certificateExactMatch
3562 certificateExactConvert(
3564 struct berval * out )
3567 unsigned char *p = in->bv_val;
3568 struct berval serial;
3569 struct berval issuer_dn;
3571 xcert = d2i_X509(NULL, &p, in->bv_len);
3574 LDAP_LOG( CONFIG, ENTRY,
3575 "certificateExactConvert: error parsing cert: %s\n",
3576 ERR_error_string(ERR_get_error(),NULL), 0, 0 );
3578 Debug( LDAP_DEBUG_ARGS, "certificateExactConvert: "
3579 "error parsing cert: %s\n",
3580 ERR_error_string(ERR_get_error(),NULL), NULL, NULL );
3582 return LDAP_INVALID_SYNTAX;
3585 if ( !asn1_integer2str(xcert->cert_info->serialNumber, &serial) ) {
3587 return LDAP_INVALID_SYNTAX;
3589 if ( dnX509normalize(X509_get_issuer_name(xcert), &issuer_dn ) != LDAP_SUCCESS ) {
3591 ber_memfree(serial.bv_val);
3592 return LDAP_INVALID_SYNTAX;
3597 out->bv_len = serial.bv_len + issuer_dn.bv_len + sizeof(" $ ");
3598 out->bv_val = ch_malloc(out->bv_len);
3600 AC_MEMCPY(p, serial.bv_val, serial.bv_len);
3602 AC_MEMCPY(p, " $ ", sizeof(" $ ")-1);
3604 AC_MEMCPY(p, issuer_dn.bv_val, issuer_dn.bv_len);
3605 p += issuer_dn.bv_len;
3609 LDAP_LOG( CONFIG, ARGS,
3610 "certificateExactConvert: \n %s\n", out->bv_val, 0, 0 );
3612 Debug( LDAP_DEBUG_ARGS, "certificateExactConvert "
3614 out->bv_val, NULL, NULL );
3617 ber_memfree(serial.bv_val);
3618 ber_memfree(issuer_dn.bv_val);
3620 return LDAP_SUCCESS;
3624 serial_and_issuer_parse(
3625 struct berval *assertion,
3626 struct berval *serial,
3627 struct berval *issuer_dn
3635 begin = assertion->bv_val;
3636 end = assertion->bv_val+assertion->bv_len-1;
3637 for (p=begin; p<=end && *p != '$'; p++)
3640 return LDAP_INVALID_SYNTAX;
3642 /* p now points at the $ sign, now use begin and end to delimit the
3644 while (ASCII_SPACE(*begin))
3647 while (ASCII_SPACE(*end))
3650 bv.bv_len = end-begin+1;
3652 ber_dupbv(serial, &bv);
3654 /* now extract the issuer, remember p was at the dollar sign */
3657 end = assertion->bv_val+assertion->bv_len-1;
3658 while (ASCII_SPACE(*begin))
3660 /* should we trim spaces at the end too? is it safe always? */
3662 bv.bv_len = end-begin+1;
3664 dnNormalize2( NULL, &bv, issuer_dn );
3667 return LDAP_SUCCESS;
3671 certificateExactMatch(
3676 struct berval *value,
3677 void *assertedValue )
3680 unsigned char *p = value->bv_val;
3681 struct berval serial;
3682 struct berval issuer_dn;
3683 struct berval asserted_serial;
3684 struct berval asserted_issuer_dn;
3687 xcert = d2i_X509(NULL, &p, value->bv_len);
3690 LDAP_LOG( CONFIG, ENTRY,
3691 "certificateExactMatch: error parsing cert: %s\n",
3692 ERR_error_string(ERR_get_error(),NULL), 0, 0 );
3694 Debug( LDAP_DEBUG_ARGS, "certificateExactMatch: "
3695 "error parsing cert: %s\n",
3696 ERR_error_string(ERR_get_error(),NULL), NULL, NULL );
3698 return LDAP_INVALID_SYNTAX;
3701 asn1_integer2str(xcert->cert_info->serialNumber, &serial);
3702 dnX509normalize(X509_get_issuer_name(xcert), &issuer_dn);
3706 serial_and_issuer_parse(assertedValue,
3708 &asserted_issuer_dn);
3713 slap_schema.si_syn_integer,
3714 slap_schema.si_mr_integerMatch,
3717 if ( ret == LDAP_SUCCESS ) {
3718 if ( *matchp == 0 ) {
3719 /* We need to normalize everything for dnMatch */
3723 slap_schema.si_syn_distinguishedName,
3724 slap_schema.si_mr_distinguishedNameMatch,
3726 &asserted_issuer_dn);
3731 LDAP_LOG( CONFIG, ARGS, "certificateExactMatch "
3732 "%d\n\t\"%s $ %s\"\n",
3733 *matchp, serial.bv_val, issuer_dn.bv_val );
3734 LDAP_LOG( CONFIG, ARGS, "\t\"%s $ %s\"\n",
3735 asserted_serial.bv_val, asserted_issuer_dn.bv_val,
3738 Debug( LDAP_DEBUG_ARGS, "certificateExactMatch "
3739 "%d\n\t\"%s $ %s\"\n",
3740 *matchp, serial.bv_val, issuer_dn.bv_val );
3741 Debug( LDAP_DEBUG_ARGS, "\t\"%s $ %s\"\n",
3742 asserted_serial.bv_val, asserted_issuer_dn.bv_val,
3746 ber_memfree(serial.bv_val);
3747 ber_memfree(issuer_dn.bv_val);
3748 ber_memfree(asserted_serial.bv_val);
3749 ber_memfree(asserted_issuer_dn.bv_val);
3755 * Index generation function
3756 * We just index the serials, in most scenarios the issuer DN is one of
3757 * a very small set of values.
3759 static int certificateExactIndexer(
3764 struct berval *prefix,
3772 struct berval serial;
3774 /* we should have at least one value at this point */
3775 assert( values != NULL && values[0].bv_val != NULL );
3777 for( i=0; values[i].bv_val != NULL; i++ ) {
3778 /* empty -- just count them */
3781 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
3783 for( i=0; values[i].bv_val != NULL; i++ ) {
3784 p = values[i].bv_val;
3785 xcert = d2i_X509(NULL, &p, values[i].bv_len);
3788 LDAP_LOG( CONFIG, ENTRY,
3789 "certificateExactIndexer: error parsing cert: %s\n",
3790 ERR_error_string(ERR_get_error(),NULL), 0, 0);
3792 Debug( LDAP_DEBUG_ARGS, "certificateExactIndexer: "
3793 "error parsing cert: %s\n",
3794 ERR_error_string(ERR_get_error(),NULL),
3797 /* Do we leak keys on error? */
3798 return LDAP_INVALID_SYNTAX;
3801 asn1_integer2str(xcert->cert_info->serialNumber, &serial);
3803 integerNormalize( slap_schema.si_syn_integer,
3806 ber_memfree(serial.bv_val);
3808 LDAP_LOG( CONFIG, ENTRY,
3809 "certificateExactIndexer: returning: %s\n", keys[i].bv_val, 0, 0);
3811 Debug( LDAP_DEBUG_ARGS, "certificateExactIndexer: "
3818 keys[i].bv_val = NULL;
3820 return LDAP_SUCCESS;
3823 /* Index generation function */
3824 /* We think this is always called with a value in matching rule syntax */
3825 static int certificateExactFilter(
3830 struct berval *prefix,
3835 struct berval asserted_serial;
3837 serial_and_issuer_parse(assertValue,
3841 keys = ch_malloc( sizeof( struct berval ) * 2 );
3842 integerNormalize( syntax, &asserted_serial, &keys[0] );
3843 keys[1].bv_val = NULL;
3846 ber_memfree(asserted_serial.bv_val);
3847 return LDAP_SUCCESS;
3852 check_time_syntax (struct berval *val,
3856 static int ceiling[9] = { 99, 99, 11, 30, 23, 59, 59, 12, 59 };
3857 static int mdays[2][12] = {
3858 /* non-leap years */
3859 { 30, 27, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30 },
3861 { 30, 28, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30 }
3864 int part, c, tzoffset, leapyear = 0 ;
3866 if( val->bv_len == 0 ) {
3867 return LDAP_INVALID_SYNTAX;
3870 p = (char *)val->bv_val;
3871 e = p + val->bv_len;
3873 /* Ignore initial whitespace */
3874 while ( ( p < e ) && ASCII_SPACE( *p ) ) {
3878 if (e - p < 13 - (2 * start)) {
3879 return LDAP_INVALID_SYNTAX;
3882 for (part = 0; part < 9; part++) {
3886 for (part = start; part < 7; part++) {
3888 if ((part == 6) && (c == 'Z' || c == '+' || c == '-')) {
3895 return LDAP_INVALID_SYNTAX;
3897 if (c < 0 || c > 9) {
3898 return LDAP_INVALID_SYNTAX;
3904 return LDAP_INVALID_SYNTAX;
3906 if (c < 0 || c > 9) {
3907 return LDAP_INVALID_SYNTAX;
3912 if (part == 2 || part == 3) {
3915 if (parts[part] < 0) {
3916 return LDAP_INVALID_SYNTAX;
3918 if (parts[part] > ceiling[part]) {
3919 return LDAP_INVALID_SYNTAX;
3923 /* leapyear check for the Gregorian calendar (year>1581) */
3924 if (((parts[1] % 4 == 0) && (parts[1] != 0)) ||
3925 ((parts[0] % 4 == 0) && (parts[1] == 0)))
3930 if (parts[3] > mdays[leapyear][parts[2]]) {
3931 return LDAP_INVALID_SYNTAX;
3936 tzoffset = 0; /* UTC */
3937 } else if (c != '+' && c != '-') {
3938 return LDAP_INVALID_SYNTAX;
3942 } else /* c == '+' */ {
3947 return LDAP_INVALID_SYNTAX;
3950 for (part = 7; part < 9; part++) {
3952 if (c < 0 || c > 9) {
3953 return LDAP_INVALID_SYNTAX;
3958 if (c < 0 || c > 9) {
3959 return LDAP_INVALID_SYNTAX;
3963 if (parts[part] < 0 || parts[part] > ceiling[part]) {
3964 return LDAP_INVALID_SYNTAX;
3969 /* Ignore trailing whitespace */
3970 while ( ( p < e ) && ASCII_SPACE( *p ) ) {
3974 return LDAP_INVALID_SYNTAX;
3977 switch ( tzoffset ) {
3978 case -1: /* negativ offset to UTC, ie west of Greenwich */
3979 parts[4] += parts[7];
3980 parts[5] += parts[8];
3981 for (part = 6; --part > 0; ) { /* offset is just hhmm, no seconds */
3985 c = mdays[leapyear][parts[2]];
3987 if (parts[part] > c) {
3988 parts[part] -= c + 1;
3993 case 1: /* positive offset to UTC, ie east of Greenwich */
3994 parts[4] -= parts[7];
3995 parts[5] -= parts[8];
3996 for (part = 6; --part > 0; ) {
4000 /* first arg to % needs to be non negativ */
4001 c = mdays[leapyear][(parts[2] - 1 + 12) % 12];
4003 if (parts[part] < 0) {
4004 parts[part] += c + 1;
4009 case 0: /* already UTC */
4013 return LDAP_SUCCESS;
4016 #ifdef SUPPORT_OBSOLETE_UTC_SYNTAX
4021 struct berval *normalized )
4025 rc = check_time_syntax(val, 1, parts);
4026 if (rc != LDAP_SUCCESS) {
4030 normalized->bv_val = ch_malloc( 14 );
4031 if ( normalized->bv_val == NULL ) {
4032 return LBER_ERROR_MEMORY;
4035 sprintf( normalized->bv_val, "%02d%02d%02d%02d%02d%02dZ",
4036 parts[1], parts[2] + 1, parts[3] + 1,
4037 parts[4], parts[5], parts[6] );
4038 normalized->bv_len = 13;
4040 return LDAP_SUCCESS;
4044 #ifdef SUPPORT_OBSOLETE_UTC_SYNTAX
4052 return check_time_syntax(in, 1, parts);
4057 generalizedTimeValidate(
4063 return check_time_syntax(in, 0, parts);
4067 generalizedTimeNormalize(
4070 struct berval *normalized )
4074 rc = check_time_syntax(val, 0, parts);
4075 if (rc != LDAP_SUCCESS) {
4079 normalized->bv_val = ch_malloc( 16 );
4080 if ( normalized->bv_val == NULL ) {
4081 return LBER_ERROR_MEMORY;
4084 sprintf( normalized->bv_val, "%02d%02d%02d%02d%02d%02d%02dZ",
4085 parts[0], parts[1], parts[2] + 1, parts[3] + 1,
4086 parts[4], parts[5], parts[6] );
4087 normalized->bv_len = 15;
4089 return LDAP_SUCCESS;
4093 nisNetgroupTripleValidate(
4095 struct berval *val )
4100 if ( val->bv_len == 0 ) {
4101 return LDAP_INVALID_SYNTAX;
4104 p = (char *)val->bv_val;
4105 e = p + val->bv_len;
4107 if ( *p != '(' /*')'*/ ) {
4108 return LDAP_INVALID_SYNTAX;
4111 for ( p++; ( p < e ) && ( *p != /*'('*/ ')' ); p++ ) {
4115 return LDAP_INVALID_SYNTAX;
4118 } else if ( !AD_CHAR( *p ) ) {
4119 return LDAP_INVALID_SYNTAX;
4123 if ( ( commas != 2 ) || ( *p != /*'('*/ ')' ) ) {
4124 return LDAP_INVALID_SYNTAX;
4130 return LDAP_INVALID_SYNTAX;
4133 return LDAP_SUCCESS;
4137 bootParameterValidate(
4139 struct berval *val )
4143 if ( val->bv_len == 0 ) {
4144 return LDAP_INVALID_SYNTAX;
4147 p = (char *)val->bv_val;
4148 e = p + val->bv_len;
4151 for (; ( p < e ) && ( *p != '=' ); p++ ) {
4152 if ( !AD_CHAR( *p ) ) {
4153 return LDAP_INVALID_SYNTAX;
4158 return LDAP_INVALID_SYNTAX;
4162 for ( p++; ( p < e ) && ( *p != ':' ); p++ ) {
4163 if ( !AD_CHAR( *p ) ) {
4164 return LDAP_INVALID_SYNTAX;
4169 return LDAP_INVALID_SYNTAX;
4173 for ( p++; p < e; p++ ) {
4174 if ( !SLAP_PRINTABLE( *p ) ) {
4175 return LDAP_INVALID_SYNTAX;
4179 return LDAP_SUCCESS;
4182 static struct syntax_defs_rec {
4184 #define X_BINARY "X-BINARY-TRANSFER-REQUIRED 'TRUE' "
4185 #define X_NOT_H_R "X-NOT-HUMAN-READABLE 'TRUE' "
4187 slap_syntax_validate_func *sd_validate;
4188 slap_syntax_transform_func *sd_normalize;
4189 slap_syntax_transform_func *sd_pretty;
4190 #ifdef SLAPD_BINARY_CONVERSION
4191 slap_syntax_transform_func *sd_ber2str;
4192 slap_syntax_transform_func *sd_str2ber;
4195 {"( 1.3.6.1.4.1.1466.115.121.1.1 DESC 'ACI Item' "
4196 X_BINARY X_NOT_H_R ")",
4197 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, NULL, NULL, NULL},
4198 {"( 1.3.6.1.4.1.1466.115.121.1.2 DESC 'Access Point' " X_NOT_H_R ")",
4199 0, NULL, NULL, NULL},
4200 {"( 1.3.6.1.4.1.1466.115.121.1.3 DESC 'Attribute Type Description' )",
4201 0, NULL, NULL, NULL},
4202 {"( 1.3.6.1.4.1.1466.115.121.1.4 DESC 'Audio' "
4204 SLAP_SYNTAX_BLOB, blobValidate, NULL, NULL},
4205 {"( 1.3.6.1.4.1.1466.115.121.1.5 DESC 'Binary' "
4207 SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4208 {"( 1.3.6.1.4.1.1466.115.121.1.6 DESC 'Bit String' )",
4209 0, bitStringValidate, bitStringNormalize, NULL },
4210 {"( 1.3.6.1.4.1.1466.115.121.1.7 DESC 'Boolean' )",
4211 0, booleanValidate, NULL, NULL},
4212 {"( 1.3.6.1.4.1.1466.115.121.1.8 DESC 'Certificate' "
4213 X_BINARY X_NOT_H_R ")",
4214 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4215 {"( 1.3.6.1.4.1.1466.115.121.1.9 DESC 'Certificate List' "
4216 X_BINARY X_NOT_H_R ")",
4217 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4218 {"( 1.3.6.1.4.1.1466.115.121.1.10 DESC 'Certificate Pair' "
4219 X_BINARY X_NOT_H_R ")",
4220 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4221 {"( 1.3.6.1.4.1.1466.115.121.1.11 DESC 'Country String' )",
4222 0, countryStringValidate, IA5StringNormalize, NULL},
4223 {"( 1.3.6.1.4.1.1466.115.121.1.12 DESC 'Distinguished Name' )",
4224 0, dnValidate, dnNormalize2, dnPretty2},
4225 {"( 1.3.6.1.4.1.1466.115.121.1.13 DESC 'Data Quality' )",
4226 0, NULL, NULL, NULL},
4227 {"( 1.3.6.1.4.1.1466.115.121.1.14 DESC 'Delivery Method' )",
4228 0, NULL, NULL, NULL},
4229 {"( 1.3.6.1.4.1.1466.115.121.1.15 DESC 'Directory String' )",
4230 0, UTF8StringValidate, UTF8StringNormalize, NULL},
4231 {"( 1.3.6.1.4.1.1466.115.121.1.16 DESC 'DIT Content Rule Description' )",
4232 0, NULL, NULL, NULL},
4233 {"( 1.3.6.1.4.1.1466.115.121.1.17 DESC 'DIT Structure Rule Description' )",
4234 0, NULL, NULL, NULL},
4235 {"( 1.3.6.1.4.1.1466.115.121.1.19 DESC 'DSA Quality' )",
4236 0, NULL, NULL, NULL},
4237 {"( 1.3.6.1.4.1.1466.115.121.1.20 DESC 'DSE Type' )",
4238 0, NULL, NULL, NULL},
4239 {"( 1.3.6.1.4.1.1466.115.121.1.21 DESC 'Enhanced Guide' )",
4240 0, NULL, NULL, NULL},
4241 {"( 1.3.6.1.4.1.1466.115.121.1.22 DESC 'Facsimile Telephone Number' )",
4242 0, printablesStringValidate, telephoneNumberNormalize, NULL},
4243 {"( 1.3.6.1.4.1.1466.115.121.1.23 DESC 'Fax' " X_NOT_H_R ")",
4244 SLAP_SYNTAX_BLOB, NULL, NULL, NULL},
4245 {"( 1.3.6.1.4.1.1466.115.121.1.24 DESC 'Generalized Time' )",
4246 0, generalizedTimeValidate, generalizedTimeNormalize, NULL},
4247 {"( 1.3.6.1.4.1.1466.115.121.1.25 DESC 'Guide' )",
4248 0, NULL, NULL, NULL},
4249 {"( 1.3.6.1.4.1.1466.115.121.1.26 DESC 'IA5 String' )",
4250 0, IA5StringValidate, IA5StringNormalize, NULL},
4251 {"( 1.3.6.1.4.1.1466.115.121.1.27 DESC 'Integer' )",
4252 0, integerValidate, integerNormalize, NULL},
4253 {"( 1.3.6.1.4.1.1466.115.121.1.28 DESC 'JPEG' " X_NOT_H_R ")",
4254 SLAP_SYNTAX_BLOB, blobValidate, NULL, NULL},
4255 {"( 1.3.6.1.4.1.1466.115.121.1.29 DESC 'Master And Shadow Access Points' )",
4256 0, NULL, NULL, NULL},
4257 {"( 1.3.6.1.4.1.1466.115.121.1.30 DESC 'Matching Rule Description' )",
4258 0, NULL, NULL, NULL},
4259 {"( 1.3.6.1.4.1.1466.115.121.1.31 DESC 'Matching Rule Use Description' )",
4260 0, NULL, NULL, NULL},
4261 {"( 1.3.6.1.4.1.1466.115.121.1.32 DESC 'Mail Preference' )",
4262 0, NULL, NULL, NULL},
4263 {"( 1.3.6.1.4.1.1466.115.121.1.33 DESC 'MHS OR Address' )",
4264 0, NULL, NULL, NULL},
4265 {"( 1.3.6.1.4.1.1466.115.121.1.34 DESC 'Name And Optional UID' )",
4266 0, nameUIDValidate, nameUIDNormalize, NULL},
4267 {"( 1.3.6.1.4.1.1466.115.121.1.35 DESC 'Name Form Description' )",
4268 0, NULL, NULL, NULL},
4269 {"( 1.3.6.1.4.1.1466.115.121.1.36 DESC 'Numeric String' )",
4270 0, numericStringValidate, numericStringNormalize, NULL},
4271 {"( 1.3.6.1.4.1.1466.115.121.1.37 DESC 'Object Class Description' )",
4272 0, NULL, NULL, NULL},
4273 {"( 1.3.6.1.4.1.1466.115.121.1.38 DESC 'OID' )",
4274 0, oidValidate, NULL, NULL},
4275 {"( 1.3.6.1.4.1.1466.115.121.1.39 DESC 'Other Mailbox' )",
4276 0, IA5StringValidate, IA5StringNormalize, NULL},
4277 {"( 1.3.6.1.4.1.1466.115.121.1.40 DESC 'Octet String' )",
4278 0, blobValidate, NULL, NULL},
4279 {"( 1.3.6.1.4.1.1466.115.121.1.41 DESC 'Postal Address' )",
4280 0, UTF8StringValidate, UTF8StringNormalize, NULL},
4281 {"( 1.3.6.1.4.1.1466.115.121.1.42 DESC 'Protocol Information' )",
4282 0, NULL, NULL, NULL},
4283 {"( 1.3.6.1.4.1.1466.115.121.1.43 DESC 'Presentation Address' )",
4284 0, NULL, NULL, NULL},
4285 {"( 1.3.6.1.4.1.1466.115.121.1.44 DESC 'Printable String' )",
4286 0, printableStringValidate, IA5StringNormalize, NULL},
4287 {"( 1.3.6.1.4.1.1466.115.121.1.45 DESC 'SubtreeSpecification' "
4288 X_BINARY X_NOT_H_R ")",
4289 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, NULL, NULL, NULL},
4290 {"( 1.3.6.1.4.1.1466.115.121.1.49 DESC 'Supported Algorithm' "
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.50 DESC 'Telephone Number' )",
4294 0, printableStringValidate, telephoneNumberNormalize, NULL},
4295 {"( 1.3.6.1.4.1.1466.115.121.1.51 DESC 'Teletex Terminal Identifier' )",
4296 0, NULL, NULL, NULL},
4297 {"( 1.3.6.1.4.1.1466.115.121.1.52 DESC 'Telex Number' )",
4298 0, printablesStringValidate, IA5StringNormalize, NULL},
4299 #ifdef SUPPORT_OBSOLETE_UTC_SYNTAX
4300 {"( 1.3.6.1.4.1.1466.115.121.1.53 DESC 'UTC Time' )",
4301 0, utcTimeValidate, utcTimeNormalize, NULL},
4303 {"( 1.3.6.1.4.1.1466.115.121.1.54 DESC 'LDAP Syntax Description' )",
4304 0, NULL, NULL, NULL},
4305 {"( 1.3.6.1.4.1.1466.115.121.1.55 DESC 'Modify Rights' )",
4306 0, NULL, NULL, NULL},
4307 {"( 1.3.6.1.4.1.1466.115.121.1.56 DESC 'LDAP Schema Definition' )",
4308 0, NULL, NULL, NULL},
4309 {"( 1.3.6.1.4.1.1466.115.121.1.57 DESC 'LDAP Schema Description' )",
4310 0, NULL, NULL, NULL},
4311 {"( 1.3.6.1.4.1.1466.115.121.1.58 DESC 'Substring Assertion' )",
4312 0, NULL, NULL, NULL},
4314 /* RFC 2307 NIS Syntaxes */
4315 {"( 1.3.6.1.1.1.0.0 DESC 'RFC2307 NIS Netgroup Triple' )",
4316 0, nisNetgroupTripleValidate, NULL, NULL},
4317 {"( 1.3.6.1.1.1.0.1 DESC 'RFC2307 Boot Parameter' )",
4318 0, bootParameterValidate, NULL, NULL},
4322 /* These OIDs are not published yet, but will be in the next
4323 * I-D for PKIX LDAPv3 schema as have been advanced by David
4324 * Chadwick in private mail.
4326 {"( 1.2.826.0.1.3344810.7.1 DESC 'Serial Number and Issuer' )",
4327 0, NULL, NULL, NULL},
4330 /* OpenLDAP Experimental Syntaxes */
4331 #ifdef SLAPD_ACI_ENABLED
4332 {"( 1.3.6.1.4.1.4203.666.2.1 DESC 'OpenLDAP Experimental ACI' )",
4334 UTF8StringValidate /* THIS WILL CHANGE FOR NEW ACI SYNTAX */,
4338 #ifdef SLAPD_AUTHPASSWD
4339 /* needs updating */
4340 {"( 1.3.6.1.4.1.4203.666.2.2 DESC 'OpenLDAP authPassword' )",
4341 SLAP_SYNTAX_HIDE, NULL, NULL, NULL},
4344 /* OpenLDAP Void Syntax */
4345 {"( 1.3.6.1.4.1.4203.1.1.1 DESC 'OpenLDAP void' )" ,
4346 SLAP_SYNTAX_HIDE, inValidate, NULL, NULL},
4347 {NULL, 0, NULL, NULL, NULL}
4351 * Other matching rules in X.520 that we do not use (yet):
4353 * 2.5.13.9 numericStringOrderingMatch
4354 * 2.5.13.18 octetStringOrderingMatch
4355 * 2.5.13.19 octetStringSubstringsMatch
4356 * 2.5.13.25 uTCTimeMatch
4357 * 2.5.13.26 uTCTimeOrderingMatch
4358 * 2.5.13.31 directoryStringFirstComponentMatch
4359 * 2.5.13.32 wordMatch
4360 * 2.5.13.33 keywordMatch
4361 * 2.5.13.35 certificateMatch
4362 * 2.5.13.36 certificatePairExactMatch
4363 * 2.5.13.37 certificatePairMatch
4364 * 2.5.13.38 certificateListExactMatch
4365 * 2.5.13.39 certificateListMatch
4366 * 2.5.13.40 algorithmIdentifierMatch
4367 * 2.5.13.41 storedPrefixMatch
4368 * 2.5.13.42 attributeCertificateMatch
4369 * 2.5.13.43 readerAndKeyIDMatch
4370 * 2.5.13.44 attributeIntegrityMatch
4372 static struct mrule_defs_rec {
4374 slap_mask_t mrd_usage;
4375 slap_mr_convert_func * mrd_convert;
4376 slap_mr_normalize_func * mrd_normalize;
4377 slap_mr_match_func * mrd_match;
4378 slap_mr_indexer_func * mrd_indexer;
4379 slap_mr_filter_func * mrd_filter;
4381 char * mrd_associated;
4384 * EQUALITY matching rules must be listed after associated APPROX
4385 * matching rules. So, we list all APPROX matching rules first.
4387 {"( " directoryStringApproxMatchOID " NAME 'directoryStringApproxMatch' "
4388 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4389 SLAP_MR_HIDE | SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT,
4391 directoryStringApproxMatch,
4392 directoryStringApproxIndexer,
4393 directoryStringApproxFilter,
4396 {"( " IA5StringApproxMatchOID " NAME 'IA5StringApproxMatch' "
4397 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4398 SLAP_MR_HIDE | SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT,
4400 IA5StringApproxMatch,
4401 IA5StringApproxIndexer,
4402 IA5StringApproxFilter,
4406 * Other matching rules
4409 {"( 2.5.13.0 NAME 'objectIdentifierMatch' "
4410 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
4411 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4413 objectIdentifierMatch, caseIgnoreIA5Indexer, caseIgnoreIA5Filter,
4416 {"( 2.5.13.1 NAME 'distinguishedNameMatch' "
4417 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )",
4418 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4420 dnMatch, dnIndexer, dnFilter,
4423 {"( 2.5.13.2 NAME 'caseIgnoreMatch' "
4424 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4425 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD,
4427 caseIgnoreMatch, caseExactIgnoreIndexer, caseExactIgnoreFilter,
4428 directoryStringApproxMatchOID },
4430 {"( 2.5.13.3 NAME 'caseIgnoreOrderingMatch' "
4431 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4434 caseIgnoreOrderingMatch, NULL, NULL,
4437 {"( 2.5.13.4 NAME 'caseIgnoreSubstringsMatch' "
4438 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4439 SLAP_MR_SUBSTR | SLAP_MR_EXT,
4441 caseExactIgnoreSubstringsMatch,
4442 caseExactIgnoreSubstringsIndexer,
4443 caseExactIgnoreSubstringsFilter,
4446 {"( 2.5.13.5 NAME 'caseExactMatch' "
4447 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4448 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4450 caseExactMatch, caseExactIgnoreIndexer, caseExactIgnoreFilter,
4451 directoryStringApproxMatchOID },
4453 {"( 2.5.13.6 NAME 'caseExactOrderingMatch' "
4454 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4457 caseExactOrderingMatch, NULL, NULL,
4460 {"( 2.5.13.7 NAME 'caseExactSubstringsMatch' "
4461 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4462 SLAP_MR_SUBSTR | SLAP_MR_EXT,
4464 caseExactIgnoreSubstringsMatch,
4465 caseExactIgnoreSubstringsIndexer,
4466 caseExactIgnoreSubstringsFilter,
4469 {"( 2.5.13.8 NAME 'numericStringMatch' "
4470 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 )",
4471 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD,
4474 caseIgnoreIA5Indexer,
4475 caseIgnoreIA5Filter,
4478 {"( 2.5.13.10 NAME 'numericStringSubstringsMatch' "
4479 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4480 SLAP_MR_SUBSTR | SLAP_MR_EXT,
4482 caseIgnoreIA5SubstringsMatch,
4483 caseIgnoreIA5SubstringsIndexer,
4484 caseIgnoreIA5SubstringsFilter,
4487 {"( 2.5.13.11 NAME 'caseIgnoreListMatch' "
4488 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )",
4489 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD,
4491 caseIgnoreListMatch, NULL, NULL,
4494 {"( 2.5.13.12 NAME 'caseIgnoreListSubstringsMatch' "
4495 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4496 SLAP_MR_SUBSTR | SLAP_MR_EXT,
4498 caseIgnoreListSubstringsMatch, NULL, NULL,
4501 {"( 2.5.13.13 NAME 'booleanMatch' "
4502 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )",
4503 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4505 booleanMatch, NULL, NULL,
4508 {"( 2.5.13.14 NAME 'integerMatch' "
4509 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4510 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4512 integerMatch, integerIndexer, integerFilter,
4515 {"( 2.5.13.15 NAME 'integerOrderingMatch' "
4516 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4519 integerOrderingMatch, NULL, NULL,
4522 {"( 2.5.13.16 NAME 'bitStringMatch' "
4523 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.6 )",
4524 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4526 bitStringMatch, bitStringIndexer, bitStringFilter,
4529 {"( 2.5.13.17 NAME 'octetStringMatch' "
4530 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
4531 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4533 octetStringMatch, octetStringIndexer, octetStringFilter,
4536 {"( 2.5.13.20 NAME 'telephoneNumberMatch' "
4537 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 )",
4538 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD,
4540 telephoneNumberMatch,
4541 telephoneNumberIndexer,
4542 telephoneNumberFilter,
4545 {"( 2.5.13.21 NAME 'telephoneNumberSubstringsMatch' "
4546 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4547 SLAP_MR_SUBSTR | SLAP_MR_EXT,
4549 telephoneNumberSubstringsMatch,
4550 telephoneNumberSubstringsIndexer,
4551 telephoneNumberSubstringsFilter,
4554 {"( 2.5.13.22 NAME 'presentationAddressMatch' "
4555 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.43 )",
4556 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4561 {"( 2.5.13.23 NAME 'uniqueMemberMatch' "
4562 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.34 )",
4563 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4565 uniqueMemberMatch, NULL, NULL,
4568 {"( 2.5.13.24 NAME 'protocolInformationMatch' "
4569 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.42 )",
4570 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4572 protocolInformationMatch, NULL, NULL,
4575 {"( 2.5.13.27 NAME 'generalizedTimeMatch' "
4576 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
4577 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4579 generalizedTimeMatch, NULL, NULL,
4582 {"( 2.5.13.28 NAME 'generalizedTimeOrderingMatch' "
4583 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
4586 generalizedTimeOrderingMatch, NULL, NULL,
4589 {"( 2.5.13.29 NAME 'integerFirstComponentMatch' "
4590 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4591 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4593 integerFirstComponentMatch, NULL, NULL,
4596 {"( 2.5.13.30 NAME 'objectIdentifierFirstComponentMatch' "
4597 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
4598 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4600 objectIdentifierFirstComponentMatch, NULL, NULL,
4604 {"( 2.5.13.34 NAME 'certificateExactMatch' "
4605 "SYNTAX 1.2.826.0.1.3344810.7.1 )",
4606 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4607 certificateExactConvert, NULL,
4608 certificateExactMatch,
4609 certificateExactIndexer, certificateExactFilter,
4613 {"( 1.3.6.1.4.1.1466.109.114.1 NAME 'caseExactIA5Match' "
4614 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4615 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4617 caseExactIA5Match, caseExactIA5Indexer, caseExactIA5Filter,
4618 IA5StringApproxMatchOID },
4620 {"( 1.3.6.1.4.1.1466.109.114.2 NAME 'caseIgnoreIA5Match' "
4621 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4622 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD,
4624 caseIgnoreIA5Match, caseIgnoreIA5Indexer, caseIgnoreIA5Filter,
4625 IA5StringApproxMatchOID },
4627 {"( 1.3.6.1.4.1.1466.109.114.3 NAME 'caseIgnoreIA5SubstringsMatch' "
4628 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4631 caseIgnoreIA5SubstringsMatch,
4632 caseIgnoreIA5SubstringsIndexer,
4633 caseIgnoreIA5SubstringsFilter,
4636 {"( 1.3.6.1.4.1.4203.1.2.1 NAME 'caseExactIA5SubstringsMatch' "
4637 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4640 caseExactIA5SubstringsMatch,
4641 caseExactIA5SubstringsIndexer,
4642 caseExactIA5SubstringsFilter,
4645 #ifdef SLAPD_AUTHPASSWD
4646 /* needs updating */
4647 {"( 1.3.6.1.4.1.4203.666.4.1 NAME 'authPasswordMatch' "
4648 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
4651 authPasswordMatch, NULL, NULL,
4655 #ifdef SLAPD_ACI_ENABLED
4656 {"( 1.3.6.1.4.1.4203.666.4.2 NAME 'OpenLDAPaciMatch' "
4657 "SYNTAX 1.3.6.1.4.1.4203.666.2.1 )",
4660 OpenLDAPaciMatch, NULL, NULL,
4664 {"( 1.2.840.113556.1.4.803 NAME 'integerBitAndMatch' "
4665 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4668 integerBitAndMatch, NULL, NULL,
4671 {"( 1.2.840.113556.1.4.804 NAME 'integerBitOrMatch' "
4672 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4675 integerBitOrMatch, NULL, NULL,
4678 {NULL, SLAP_MR_NONE, NULL, NULL, NULL, NULL}
4682 slap_schema_init( void )
4687 /* we should only be called once (from main) */
4688 assert( schema_init_done == 0 );
4690 for ( i=0; syntax_defs[i].sd_desc != NULL; i++ ) {
4691 res = register_syntax( syntax_defs[i].sd_desc,
4692 syntax_defs[i].sd_flags,
4693 syntax_defs[i].sd_validate,
4694 syntax_defs[i].sd_normalize,
4695 syntax_defs[i].sd_pretty
4696 #ifdef SLAPD_BINARY_CONVERSION
4698 syntax_defs[i].sd_ber2str,
4699 syntax_defs[i].sd_str2ber
4704 fprintf( stderr, "slap_schema_init: Error registering syntax %s\n",
4705 syntax_defs[i].sd_desc );
4710 for ( i=0; mrule_defs[i].mrd_desc != NULL; i++ ) {
4711 if( mrule_defs[i].mrd_usage == SLAP_MR_NONE ) {
4713 "slap_schema_init: Ingoring unusable matching rule %s\n",
4714 mrule_defs[i].mrd_desc );
4718 res = register_matching_rule(
4719 mrule_defs[i].mrd_desc,
4720 mrule_defs[i].mrd_usage,
4721 mrule_defs[i].mrd_convert,
4722 mrule_defs[i].mrd_normalize,
4723 mrule_defs[i].mrd_match,
4724 mrule_defs[i].mrd_indexer,
4725 mrule_defs[i].mrd_filter,
4726 mrule_defs[i].mrd_associated );
4730 "slap_schema_init: Error registering matching rule %s\n",
4731 mrule_defs[i].mrd_desc );
4736 for ( i=0; i < (int)(sizeof(mr_ptr)/sizeof(mr_ptr[0])); i++ )
4737 *mr_ptr[i].mr = mr_find( mr_ptr[i].oid );
4739 res = slap_schema_load();
4740 schema_init_done = 1;
4745 schema_destroy( void )
4751 for ( i=0; i < (int)(sizeof(mr_ptr)/sizeof(mr_ptr[0])); i++ )
4752 *mr_ptr[i].mr = NULL;