1 /* schema_init.c - init builtin schema */
4 * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
5 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
13 #include <ac/string.h>
14 #include <ac/socket.h>
19 #include "ldap_utf8.h"
21 #include "lutil_hash.h"
22 /* We should replace MD5 with a faster hash */
23 #define HASH_BYTES LUTIL_HASH_BYTES
24 #define HASH_CONTEXT lutil_HASH_CTX
25 #define HASH_Init(c) lutil_HASHInit(c)
26 #define HASH_Update(c,buf,len) lutil_HASHUpdate(c,buf,len)
27 #define HASH_Final(d,c) lutil_HASHFinal(d,c)
29 /* recycled validatation routines */
30 #define berValidate blobValidate
32 /* unimplemented pretters */
34 #define integerPretty NULL
36 /* recycled matching routines */
37 #define bitStringMatch octetStringMatch
38 #define integerMatch caseIgnoreIA5Match
39 #define numericStringMatch caseIgnoreIA5Match
40 #define objectIdentifierMatch caseIgnoreIA5Match
41 #define telephoneNumberMatch caseIgnoreIA5Match
42 #define telephoneNumberSubstringsMatch caseIgnoreIA5SubstringsMatch
43 #define generalizedTimeMatch caseIgnoreIA5Match
44 #define generalizedTimeOrderingMatch caseIgnoreIA5Match
45 #define uniqueMemberMatch dnMatch
47 /* approx matching rules */
48 #define directoryStringApproxMatchOID "1.3.6.1.4.1.4203.666.4.4"
49 #define directoryStringApproxMatch approxMatch
50 #define directoryStringApproxIndexer approxIndexer
51 #define directoryStringApproxFilter approxFilter
52 #define IA5StringApproxMatchOID "1.3.6.1.4.1.4203.666.4.5"
53 #define IA5StringApproxMatch approxMatch
54 #define IA5StringApproxIndexer approxIndexer
55 #define IA5StringApproxFilter approxFilter
57 /* orderring matching rules */
58 #define caseIgnoreOrderingMatch caseIgnoreMatch
59 #define caseExactOrderingMatch caseExactMatch
61 /* unimplemented matching routines */
62 #define caseIgnoreListMatch NULL
63 #define caseIgnoreListSubstringsMatch NULL
64 #define protocolInformationMatch NULL
65 #define integerFirstComponentMatch NULL
67 #define OpenLDAPaciMatch NULL
68 #define authPasswordMatch NULL
70 /* recycled indexing/filtering routines */
71 #define dnIndexer caseExactIgnoreIndexer
72 #define dnFilter caseExactIgnoreFilter
73 #define integerIndexer caseIgnoreIA5Indexer
74 #define integerFilter caseIgnoreIA5Filter
76 #define telephoneNumberIndexer caseIgnoreIA5Indexer
77 #define telephoneNumberFilter caseIgnoreIA5Filter
78 #define telephoneNumberSubstringsIndexer caseIgnoreIA5SubstringsIndexer
79 #define telephoneNumberSubstringsFilter caseIgnoreIA5SubstringsFilter
81 /* must match OIDs below */
82 #define caseExactMatchOID "2.5.13.5"
83 #define caseExactSubstringsMatchOID "2.5.13.7"
85 static char *strcasechr( const char *str, int c )
87 char *lower = strchr( str, TOLOWER(c) );
88 char *upper = strchr( str, TOUPPER(c) );
90 if( lower && upper ) {
91 return lower < upper ? lower : upper;
105 struct berval *value,
106 void *assertedValue )
108 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
111 match = memcmp( value->bv_val,
112 ((struct berval *) assertedValue)->bv_val,
120 /* Index generation function */
121 int octetStringIndexer(
126 struct berval *prefix,
127 struct berval **values,
128 struct berval ***keysp )
132 struct berval **keys;
133 HASH_CONTEXT HASHcontext;
134 unsigned char HASHdigest[HASH_BYTES];
135 struct berval digest;
136 digest.bv_val = HASHdigest;
137 digest.bv_len = sizeof(HASHdigest);
139 for( i=0; values[i] != NULL; i++ ) {
140 /* just count them */
143 /* we should have at least one value at this point */
146 keys = ch_malloc( sizeof( struct berval * ) * (i+1) );
148 slen = strlen( syntax->ssyn_oid );
149 mlen = strlen( mr->smr_oid );
151 for( i=0; values[i] != NULL; i++ ) {
152 HASH_Init( &HASHcontext );
153 if( prefix != NULL && prefix->bv_len > 0 ) {
154 HASH_Update( &HASHcontext,
155 prefix->bv_val, prefix->bv_len );
157 HASH_Update( &HASHcontext,
158 syntax->ssyn_oid, slen );
159 HASH_Update( &HASHcontext,
161 HASH_Update( &HASHcontext,
162 values[i]->bv_val, values[i]->bv_len );
163 HASH_Final( HASHdigest, &HASHcontext );
165 keys[i] = ber_bvdup( &digest );
175 /* Index generation function */
176 int octetStringFilter(
181 struct berval *prefix,
183 struct berval ***keysp )
186 struct berval **keys;
187 HASH_CONTEXT HASHcontext;
188 unsigned char HASHdigest[HASH_BYTES];
189 struct berval *value = (struct berval *) assertValue;
190 struct berval digest;
191 digest.bv_val = HASHdigest;
192 digest.bv_len = sizeof(HASHdigest);
194 slen = strlen( syntax->ssyn_oid );
195 mlen = strlen( mr->smr_oid );
197 keys = ch_malloc( sizeof( struct berval * ) * 2 );
199 HASH_Init( &HASHcontext );
200 if( prefix != NULL && prefix->bv_len > 0 ) {
201 HASH_Update( &HASHcontext,
202 prefix->bv_val, prefix->bv_len );
204 HASH_Update( &HASHcontext,
205 syntax->ssyn_oid, slen );
206 HASH_Update( &HASHcontext,
208 HASH_Update( &HASHcontext,
209 value->bv_val, value->bv_len );
210 HASH_Final( HASHdigest, &HASHcontext );
212 keys[0] = ber_bvdup( &digest );
228 if( in->bv_len == 0 ) return LDAP_SUCCESS;
230 dn = ch_strdup( in->bv_val );
233 return LDAP_INVALID_SYNTAX;
235 } else if ( strlen( in->bv_val ) != in->bv_len ) {
236 rc = LDAP_INVALID_SYNTAX;
238 } else if ( dn_validate( dn ) == NULL ) {
239 rc = LDAP_INVALID_SYNTAX;
253 struct berval **normalized )
257 if ( val->bv_len != 0 ) {
259 out = ber_bvstr( UTF8normalize( val->bv_val, UTF8_CASEFOLD ) );
261 dn = dn_validate( out->bv_val );
265 return LDAP_INVALID_SYNTAX;
269 out->bv_len = strlen( dn );
271 out = ber_bvdup( val );
284 struct berval *value,
285 void *assertedValue )
288 struct berval *asserted = (struct berval *) assertedValue;
290 match = value->bv_len - asserted->bv_len;
293 #ifdef USE_DN_NORMALIZE
294 match = strcmp( value->bv_val, asserted->bv_val );
296 match = strcasecmp( value->bv_val, asserted->bv_val );
301 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
302 "dnMatch: %d\n %s\n %s\n", match,
303 value->bv_val, asserted->bv_val ));
305 Debug( LDAP_DEBUG_ARGS, "dnMatch %d\n\t\"%s\"\n\t\"%s\"\n",
306 match, value->bv_val, asserted->bv_val );
322 if( in->bv_len == 0 ) return LDAP_SUCCESS;
324 dn = ber_bvdup( in );
326 if( dn->bv_val[dn->bv_len-1] == '\'' ) {
327 /* assume presence of optional UID */
330 for(i=dn->bv_len-2; i>2; i--) {
331 if( dn->bv_val[i] != '0' && dn->bv_val[i] != '1' ) {
335 if( dn->bv_val[i] != '\'' ) {
336 return LDAP_INVALID_SYNTAX;
338 if( dn->bv_val[i-1] != 'B' ) {
339 return LDAP_INVALID_SYNTAX;
341 if( dn->bv_val[i-2] != '#' ) {
342 return LDAP_INVALID_SYNTAX;
345 /* trim the UID to allow use of dn_validate */
346 dn->bv_val[i-2] = '\0';
349 rc = dn_validate( dn->bv_val ) == NULL
350 ? LDAP_INVALID_SYNTAX : LDAP_SUCCESS;
360 struct berval **normalized )
362 struct berval *out = ber_bvdup( val );
364 if( out->bv_len != 0 ) {
368 ber_len_t uidlen = 0;
370 if( out->bv_val[out->bv_len-1] == '\'' ) {
371 /* assume presence of optional UID */
372 uid = strrchr( out->bv_val, '#' );
376 return LDAP_INVALID_SYNTAX;
379 uidlen = out->bv_len - (out->bv_val - uid);
380 /* temporarily trim the UID */
384 #ifdef USE_DN_NORMALIZE
385 dn = dn_normalize( out->bv_val );
387 dn = dn_validate( out->bv_val );
392 return LDAP_INVALID_SYNTAX;
398 /* restore the separator */
401 SAFEMEMCPY( &dn[dnlen], uid, uidlen );
405 out->bv_len = dnlen + uidlen;
417 /* any value allowed */
426 /* any value allowed */
437 /* very unforgiving validation, requires no normalization
438 * before simplistic matching
440 if( in->bv_len < 3 ) {
441 return LDAP_INVALID_SYNTAX;
444 if( in->bv_val[0] != 'B' ||
445 in->bv_val[1] != '\'' ||
446 in->bv_val[in->bv_len-1] != '\'' )
448 return LDAP_INVALID_SYNTAX;
451 for( i=in->bv_len-2; i>1; i-- ) {
452 if( in->bv_val[i] != '0' && in->bv_val[i] != '1' ) {
453 return LDAP_INVALID_SYNTAX;
461 * Handling boolean syntax and matching is quite rigid.
462 * A more flexible approach would be to allow a variety
463 * of strings to be normalized and prettied into TRUE
471 /* very unforgiving validation, requires no normalization
472 * before simplistic matching
475 if( in->bv_len == 4 ) {
476 if( !memcmp( in->bv_val, "TRUE", 4 ) ) {
479 } else if( in->bv_len == 5 ) {
480 if( !memcmp( in->bv_val, "FALSE", 5 ) ) {
485 return LDAP_INVALID_SYNTAX;
494 struct berval *value,
495 void *assertedValue )
497 /* simplistic matching allowed by rigid validation */
498 struct berval *asserted = (struct berval *) assertedValue;
499 *matchp = value->bv_len != asserted->bv_len;
510 unsigned char *u = in->bv_val;
512 if( !in->bv_len ) return LDAP_INVALID_SYNTAX;
514 for( count = in->bv_len; count > 0; count-=len, u+=len ) {
515 /* get the length indicated by the first byte */
516 len = LDAP_UTF8_CHARLEN( u );
518 /* should not be zero */
519 if( len == 0 ) return LDAP_INVALID_SYNTAX;
521 /* make sure len corresponds with the offset
522 to the next character */
523 if( LDAP_UTF8_OFFSET( u ) != len ) return LDAP_INVALID_SYNTAX;
526 if( count != 0 ) return LDAP_INVALID_SYNTAX;
535 struct berval **normalized )
537 struct berval *newval;
540 newval = ch_malloc( sizeof( struct berval ) );
544 /* Ignore initial whitespace */
545 while ( ldap_utf8_isspace( p ) ) {
551 return LDAP_INVALID_SYNTAX;
554 newval->bv_val = ch_strdup( p );
555 p = q = newval->bv_val;
561 if ( ldap_utf8_isspace( p ) ) {
562 len = LDAP_UTF8_COPY(q,p);
567 /* Ignore the extra whitespace */
568 while ( ldap_utf8_isspace( p ) ) {
572 len = LDAP_UTF8_COPY(q,p);
579 assert( *newval->bv_val );
580 assert( newval->bv_val < p );
583 /* cannot start with a space */
584 assert( !ldap_utf8_isspace(newval->bv_val) );
587 * If the string ended in space, backup the pointer one
588 * position. One is enough because the above loop collapsed
589 * all whitespace to a single space.
596 /* cannot end with a space */
597 assert( !ldap_utf8_isspace( LDAP_UTF8_PREV(q) ) );
602 newval->bv_len = q - newval->bv_val;
603 *normalized = newval;
608 /* Returns Unicode cannonically normalized copy of a substring assertion
609 * Skipping attribute description */
610 SubstringsAssertion *
611 UTF8SubstringsassertionNormalize(
612 SubstringsAssertion *sa,
615 SubstringsAssertion *nsa;
618 nsa = (SubstringsAssertion *)ch_calloc( 1, sizeof(SubstringsAssertion) );
623 if( sa->sa_initial != NULL ) {
624 nsa->sa_initial = ber_bvstr( UTF8normalize( sa->sa_initial->bv_val, casefold ) );
625 if( nsa->sa_initial == NULL ) {
630 if( sa->sa_any != NULL ) {
631 for( i=0; sa->sa_any[i] != NULL; i++ ) {
634 nsa->sa_any = (struct berval **)ch_malloc( (i + 1) * sizeof(struct berval *) );
635 for( i=0; sa->sa_any[i] != NULL; i++ ) {
636 nsa->sa_any[i] = ber_bvstr( UTF8normalize( sa->sa_any[i]->bv_val, casefold ) );
637 if( nsa->sa_any[i] == NULL ) {
641 nsa->sa_any[i] = NULL;
644 if( sa->sa_final != NULL ) {
645 nsa->sa_final = ber_bvstr( UTF8normalize( sa->sa_final->bv_val, casefold ) );
646 if( nsa->sa_final == NULL ) {
654 ch_free( nsa->sa_final );
655 ber_bvecfree( nsa->sa_any );
656 ch_free( nsa->sa_initial );
661 /* Strip characters with the 8th bit set */
674 while( *++q & 0x80 ) {
677 p = memmove(p, q, strlen(q) + 1);
685 #ifndef SLAPD_APPROX_OLDSINGLESTRING
687 #if defined(SLAPD_APPROX_INITIALS)
688 #define SLAPD_APPROX_DELIMITER "._ "
689 #define SLAPD_APPROX_WORDLEN 2
691 #define SLAPD_APPROX_DELIMITER " "
692 #define SLAPD_APPROX_WORDLEN 1
701 struct berval *value,
702 void *assertedValue )
704 char *val, *assertv, **values, **words, *c;
705 int i, count, len, nextchunk=0, nextavail=0;
708 /* Yes, this is necessary */
709 val = UTF8normalize( value->bv_val, UTF8_NOCASEFOLD );
714 strip8bitChars( val );
716 /* Yes, this is necessary */
717 assertv = UTF8normalize( ((struct berval *)assertedValue)->bv_val,
719 if( assertv == NULL ) {
724 strip8bitChars( assertv );
725 avlen = strlen( assertv );
727 /* Isolate how many words there are */
728 for( c=val,count=1; *c; c++ ) {
729 c = strpbrk( c, SLAPD_APPROX_DELIMITER );
730 if ( c == NULL ) break;
735 /* Get a phonetic copy of each word */
736 words = (char **)ch_malloc( count * sizeof(char *) );
737 values = (char **)ch_malloc( count * sizeof(char *) );
738 for( c=val,i=0; i<count; i++,c+=strlen(c)+1 ) {
740 values[i] = phonetic(c);
743 /* Work through the asserted value's words, to see if at least some
744 of the words are there, in the same order. */
746 while ( nextchunk < avlen ) {
747 len = strcspn( assertv + nextchunk, SLAPD_APPROX_DELIMITER);
752 #if defined(SLAPD_APPROX_INITIALS)
753 else if( len == 1 ) {
754 /* Single letter words need to at least match one word's initial */
755 for( i=nextavail; i<count; i++ )
756 if( !strncasecmp( assertv+nextchunk, words[i], 1 )) {
763 /* Isolate the next word in the asserted value and phonetic it */
764 assertv[nextchunk+len] = '\0';
765 val = phonetic( assertv + nextchunk );
767 /* See if this phonetic chunk is in the remaining words of *value */
768 for( i=nextavail; i<count; i++ ){
769 if( !strcmp( val, values[i] ) ){
776 /* This chunk in the asserted value was NOT within the *value. */
782 /* Go on to the next word in the asserted value */
786 /* If some of the words were seen, call it a match */
787 if( nextavail > 0 ) {
796 for( i=0; i<count; i++ ) {
797 ch_free( values[i] );
812 struct berval *prefix,
813 struct berval **values,
814 struct berval ***keysp )
817 int i,j, len, wordcount, keycount=0;
818 struct berval **newkeys, **keys=NULL;
820 for( j=0; values[j] != NULL; j++ ) {
821 /* Yes, this is necessary */
822 val = UTF8normalize( values[j]->bv_val, UTF8_NOCASEFOLD );
823 strip8bitChars( val );
825 /* Isolate how many words there are. There will be a key for each */
826 for( wordcount=0,c=val; *c; c++) {
827 len = strcspn(c, SLAPD_APPROX_DELIMITER);
828 if( len >= SLAPD_APPROX_WORDLEN ) wordcount++;
830 if (*c == '\0') break;
834 /* Allocate/increase storage to account for new keys */
835 newkeys = (struct berval **)ch_malloc( (keycount + wordcount + 1)
836 * sizeof(struct berval *) );
837 memcpy( newkeys, keys, keycount * sizeof(struct berval *) );
838 if( keys ) ch_free( keys );
841 /* Get a phonetic copy of each word */
842 for( c=val,i=0; i<wordcount; c+=len+1 ) {
844 if( len < SLAPD_APPROX_WORDLEN ) continue;
845 keys[keycount] = (struct berval *)ch_malloc( sizeof(struct berval) );
846 keys[keycount]->bv_val = phonetic( c );
847 keys[keycount]->bv_len = strlen( keys[keycount]->bv_val );
854 keys[keycount] = NULL;
866 struct berval *prefix,
868 struct berval ***keysp )
872 struct berval **keys;
874 /* Yes, this is necessary */
875 val = UTF8normalize( ((struct berval *)assertValue)->bv_val,
878 keys = (struct berval **)ch_malloc( sizeof(struct berval *) );
883 strip8bitChars( val );
885 /* Isolate how many words there are. There will be a key for each */
886 for( count=0,c=val; *c; c++) {
887 len = strcspn(c, SLAPD_APPROX_DELIMITER);
888 if( len >= SLAPD_APPROX_WORDLEN ) count++;
890 if (*c == '\0') break;
894 /* Allocate storage for new keys */
895 keys = (struct berval **)ch_malloc( (count + 1) * sizeof(struct berval *) );
897 /* Get a phonetic copy of each word */
898 for( c=val,i=0; i<count; c+=len+1 ) {
900 if( len < SLAPD_APPROX_WORDLEN ) continue;
901 keys[i] = ber_bvstr( phonetic( c ) );
915 /* No other form of Approximate Matching is defined */
923 struct berval *value,
924 void *assertedValue )
926 char *vapprox, *avapprox;
929 /* Yes, this is necessary */
930 s = UTF8normalize( value->bv_val, UTF8_NOCASEFOLD );
936 /* Yes, this is necessary */
937 t = UTF8normalize( ((struct berval *)assertedValue)->bv_val,
945 vapprox = phonetic( strip8bitChars( s ) );
946 avapprox = phonetic( strip8bitChars( t ) );
951 *matchp = strcmp( vapprox, avapprox );
965 struct berval *prefix,
966 struct berval **values,
967 struct berval ***keysp )
970 struct berval **keys;
973 for( i=0; values[i] != NULL; i++ ) {
974 /* empty - just count them */
977 /* we should have at least one value at this point */
980 keys = (struct berval **)ch_malloc( sizeof( struct berval * ) * (i+1) );
982 /* Copy each value and run it through phonetic() */
983 for( i=0; values[i] != NULL; i++ ) {
984 /* Yes, this is necessary */
985 s = UTF8normalize( values[i]->bv_val, UTF8_NOCASEFOLD );
987 /* strip 8-bit chars and run through phonetic() */
988 keys[i] = ber_bvstr( phonetic( strip8bitChars( s ) ) );
1004 struct berval *prefix,
1006 struct berval ***keysp )
1008 struct berval **keys;
1011 keys = (struct berval **)ch_malloc( sizeof( struct berval * ) * 2 );
1013 /* Yes, this is necessary */
1014 s = UTF8normalize( ((struct berval *)assertValue)->bv_val,
1019 /* strip 8-bit chars and run through phonetic() */
1020 keys[0] = ber_bvstr( phonetic( strip8bitChars( s ) ) );
1026 return LDAP_SUCCESS;
1037 struct berval *value,
1038 void *assertedValue )
1040 *matchp = UTF8normcmp( value->bv_val,
1041 ((struct berval *) assertedValue)->bv_val,
1043 return LDAP_SUCCESS;
1047 caseExactIgnoreSubstringsMatch(
1052 struct berval *value,
1053 void *assertedValue )
1056 SubstringsAssertion *sub;
1060 char *nav, casefold;
1062 casefold = strcmp( mr->smr_oid, caseExactSubstringsMatchOID )
1063 ? UTF8_CASEFOLD : UTF8_NOCASEFOLD;
1065 nav = UTF8normalize( value->bv_val, casefold );
1071 left.bv_len = strlen( nav );
1073 sub = UTF8SubstringsassertionNormalize( assertedValue, casefold );
1079 /* Add up asserted input length */
1080 if( sub->sa_initial ) {
1081 inlen += sub->sa_initial->bv_len;
1084 for(i=0; sub->sa_any[i] != NULL; i++) {
1085 inlen += sub->sa_any[i]->bv_len;
1088 if( sub->sa_final ) {
1089 inlen += sub->sa_final->bv_len;
1092 if( sub->sa_initial ) {
1093 if( inlen > left.bv_len ) {
1098 match = strncmp( sub->sa_initial->bv_val, left.bv_val,
1099 sub->sa_initial->bv_len );
1105 left.bv_val += sub->sa_initial->bv_len;
1106 left.bv_len -= sub->sa_initial->bv_len;
1107 inlen -= sub->sa_initial->bv_len;
1110 if( sub->sa_final ) {
1111 if( inlen > left.bv_len ) {
1116 match = strncmp( sub->sa_final->bv_val,
1117 &left.bv_val[left.bv_len - sub->sa_final->bv_len],
1118 sub->sa_final->bv_len );
1124 left.bv_len -= sub->sa_final->bv_len;
1125 inlen -= sub->sa_final->bv_len;
1129 for(i=0; sub->sa_any[i]; i++) {
1134 if( inlen > left.bv_len ) {
1135 /* not enough length */
1140 if( sub->sa_any[i]->bv_len == 0 ) {
1144 p = strchr( left.bv_val, *sub->sa_any[i]->bv_val );
1151 idx = p - left.bv_val;
1152 assert( idx < left.bv_len );
1154 if( idx >= left.bv_len ) {
1155 /* this shouldn't happen */
1162 if( sub->sa_any[i]->bv_len > left.bv_len ) {
1163 /* not enough left */
1168 match = strncmp( left.bv_val,
1169 sub->sa_any[i]->bv_val,
1170 sub->sa_any[i]->bv_len );
1178 left.bv_val += sub->sa_any[i]->bv_len;
1179 left.bv_len -= sub->sa_any[i]->bv_len;
1180 inlen -= sub->sa_any[i]->bv_len;
1187 ch_free( sub->sa_final );
1188 ber_bvecfree( sub->sa_any );
1189 ch_free( sub->sa_initial );
1193 return LDAP_SUCCESS;
1196 /* Index generation function */
1197 int caseExactIgnoreIndexer(
1202 struct berval *prefix,
1203 struct berval **values,
1204 struct berval ***keysp )
1209 struct berval **keys;
1210 HASH_CONTEXT HASHcontext;
1211 unsigned char HASHdigest[HASH_BYTES];
1212 struct berval digest;
1213 digest.bv_val = HASHdigest;
1214 digest.bv_len = sizeof(HASHdigest);
1216 for( i=0; values[i] != NULL; i++ ) {
1217 /* empty - just count them */
1220 /* we should have at least one value at this point */
1223 keys = ch_malloc( sizeof( struct berval * ) * (i+1) );
1225 slen = strlen( syntax->ssyn_oid );
1226 mlen = strlen( mr->smr_oid );
1228 casefold = strcmp( mr->smr_oid, caseExactMatchOID )
1229 ? UTF8_CASEFOLD : UTF8_NOCASEFOLD;
1231 for( i=0; values[i] != NULL; i++ ) {
1232 struct berval *value;
1233 value = ber_bvstr( UTF8normalize( values[i]->bv_val,
1236 HASH_Init( &HASHcontext );
1237 if( prefix != NULL && prefix->bv_len > 0 ) {
1238 HASH_Update( &HASHcontext,
1239 prefix->bv_val, prefix->bv_len );
1241 HASH_Update( &HASHcontext,
1242 syntax->ssyn_oid, slen );
1243 HASH_Update( &HASHcontext,
1244 mr->smr_oid, mlen );
1245 HASH_Update( &HASHcontext,
1246 value->bv_val, value->bv_len );
1247 HASH_Final( HASHdigest, &HASHcontext );
1249 ber_bvfree( value );
1251 keys[i] = ber_bvdup( &digest );
1256 return LDAP_SUCCESS;
1259 /* Index generation function */
1260 int caseExactIgnoreFilter(
1265 struct berval *prefix,
1267 struct berval ***keysp )
1271 struct berval **keys;
1272 HASH_CONTEXT HASHcontext;
1273 unsigned char HASHdigest[HASH_BYTES];
1274 struct berval *value;
1275 struct berval digest;
1276 digest.bv_val = HASHdigest;
1277 digest.bv_len = sizeof(HASHdigest);
1279 slen = strlen( syntax->ssyn_oid );
1280 mlen = strlen( mr->smr_oid );
1282 casefold = strcmp( mr->smr_oid, caseExactMatchOID )
1283 ? UTF8_CASEFOLD : UTF8_NOCASEFOLD;
1285 value = ber_bvstr( UTF8normalize( ((struct berval *) assertValue)->bv_val,
1287 /* This usually happens if filter contains bad UTF8 */
1288 if( value == NULL ) {
1289 keys = ch_malloc( sizeof( struct berval * ) );
1291 return LDAP_SUCCESS;
1294 keys = ch_malloc( sizeof( struct berval * ) * 2 );
1296 HASH_Init( &HASHcontext );
1297 if( prefix != NULL && prefix->bv_len > 0 ) {
1298 HASH_Update( &HASHcontext,
1299 prefix->bv_val, prefix->bv_len );
1301 HASH_Update( &HASHcontext,
1302 syntax->ssyn_oid, slen );
1303 HASH_Update( &HASHcontext,
1304 mr->smr_oid, mlen );
1305 HASH_Update( &HASHcontext,
1306 value->bv_val, value->bv_len );
1307 HASH_Final( HASHdigest, &HASHcontext );
1309 keys[0] = ber_bvdup( &digest );
1312 ber_bvfree( value );
1315 return LDAP_SUCCESS;
1318 /* Substrings Index generation function */
1319 int caseExactIgnoreSubstringsIndexer(
1324 struct berval *prefix,
1325 struct berval **values,
1326 struct berval ***keysp )
1331 struct berval **keys;
1332 struct berval **nvalues;
1334 HASH_CONTEXT HASHcontext;
1335 unsigned char HASHdigest[HASH_BYTES];
1336 struct berval digest;
1337 digest.bv_val = HASHdigest;
1338 digest.bv_len = sizeof(HASHdigest);
1342 for( i=0; values[i] != NULL; i++ ) {
1343 /* empty - just count them */
1346 /* we should have at least one value at this point */
1349 casefold = strcmp( mr->smr_oid, caseExactSubstringsMatchOID )
1350 ? UTF8_CASEFOLD : UTF8_NOCASEFOLD;
1352 nvalues = ch_malloc( sizeof( struct berval * ) * (i+1) );
1353 for( i=0; values[i] != NULL; i++ ) {
1354 nvalues[i] = ber_bvstr( UTF8normalize( values[i]->bv_val,
1360 for( i=0; values[i] != NULL; i++ ) {
1361 /* count number of indices to generate */
1362 if( values[i]->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
1366 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
1367 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1368 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
1369 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
1371 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
1375 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
1376 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1377 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
1381 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
1382 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1383 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
1384 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
1386 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
1392 /* no keys to generate */
1394 return LDAP_SUCCESS;
1397 keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) );
1399 slen = strlen( syntax->ssyn_oid );
1400 mlen = strlen( mr->smr_oid );
1403 for( i=0; values[i] != NULL; i++ ) {
1405 struct berval *value;
1407 if( values[i]->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
1411 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
1412 ( value->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
1414 char pre = SLAP_INDEX_SUBSTR_PREFIX;
1415 max = value->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
1417 for( j=0; j<max; j++ ) {
1418 HASH_Init( &HASHcontext );
1419 if( prefix != NULL && prefix->bv_len > 0 ) {
1420 HASH_Update( &HASHcontext,
1421 prefix->bv_val, prefix->bv_len );
1424 HASH_Update( &HASHcontext,
1425 &pre, sizeof( pre ) );
1426 HASH_Update( &HASHcontext,
1427 syntax->ssyn_oid, slen );
1428 HASH_Update( &HASHcontext,
1429 mr->smr_oid, mlen );
1430 HASH_Update( &HASHcontext,
1432 SLAP_INDEX_SUBSTR_MAXLEN );
1433 HASH_Final( HASHdigest, &HASHcontext );
1435 keys[nkeys++] = ber_bvdup( &digest );
1439 max = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
1440 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
1442 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
1445 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
1446 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
1447 HASH_Init( &HASHcontext );
1448 if( prefix != NULL && prefix->bv_len > 0 ) {
1449 HASH_Update( &HASHcontext,
1450 prefix->bv_val, prefix->bv_len );
1452 HASH_Update( &HASHcontext,
1453 &pre, sizeof( pre ) );
1454 HASH_Update( &HASHcontext,
1455 syntax->ssyn_oid, slen );
1456 HASH_Update( &HASHcontext,
1457 mr->smr_oid, mlen );
1458 HASH_Update( &HASHcontext,
1460 HASH_Final( HASHdigest, &HASHcontext );
1462 keys[nkeys++] = ber_bvdup( &digest );
1465 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
1466 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
1467 HASH_Init( &HASHcontext );
1468 if( prefix != NULL && prefix->bv_len > 0 ) {
1469 HASH_Update( &HASHcontext,
1470 prefix->bv_val, prefix->bv_len );
1472 HASH_Update( &HASHcontext,
1473 &pre, sizeof( pre ) );
1474 HASH_Update( &HASHcontext,
1475 syntax->ssyn_oid, slen );
1476 HASH_Update( &HASHcontext,
1477 mr->smr_oid, mlen );
1478 HASH_Update( &HASHcontext,
1479 &value->bv_val[value->bv_len-j], j );
1480 HASH_Final( HASHdigest, &HASHcontext );
1482 keys[nkeys++] = ber_bvdup( &digest );
1497 ber_bvecfree( nvalues );
1499 return LDAP_SUCCESS;
1502 int caseExactIgnoreSubstringsFilter(
1507 struct berval *prefix,
1509 struct berval ***keysp )
1511 SubstringsAssertion *sa;
1513 ber_len_t nkeys = 0;
1514 size_t slen, mlen, klen;
1515 struct berval **keys;
1516 HASH_CONTEXT HASHcontext;
1517 unsigned char HASHdigest[HASH_BYTES];
1518 struct berval *value;
1519 struct berval digest;
1521 casefold = strcmp( mr->smr_oid, caseExactSubstringsMatchOID )
1522 ? UTF8_CASEFOLD : UTF8_NOCASEFOLD;
1524 sa = UTF8SubstringsassertionNormalize( assertValue, casefold );
1527 return LDAP_SUCCESS;
1530 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial != NULL &&
1531 sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1536 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
1538 for( i=0; sa->sa_any[i] != NULL; i++ ) {
1539 if( sa->sa_any[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1540 /* don't bother accounting for stepping */
1541 nkeys += sa->sa_any[i]->bv_len -
1542 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
1547 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final != NULL &&
1548 sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1555 return LDAP_SUCCESS;
1558 digest.bv_val = HASHdigest;
1559 digest.bv_len = sizeof(HASHdigest);
1561 slen = strlen( syntax->ssyn_oid );
1562 mlen = strlen( mr->smr_oid );
1564 keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) );
1567 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial != NULL &&
1568 sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1570 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
1571 value = sa->sa_initial;
1573 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
1574 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
1576 HASH_Init( &HASHcontext );
1577 if( prefix != NULL && prefix->bv_len > 0 ) {
1578 HASH_Update( &HASHcontext,
1579 prefix->bv_val, prefix->bv_len );
1581 HASH_Update( &HASHcontext,
1582 &pre, sizeof( pre ) );
1583 HASH_Update( &HASHcontext,
1584 syntax->ssyn_oid, slen );
1585 HASH_Update( &HASHcontext,
1586 mr->smr_oid, mlen );
1587 HASH_Update( &HASHcontext,
1588 value->bv_val, klen );
1589 HASH_Final( HASHdigest, &HASHcontext );
1591 keys[nkeys++] = ber_bvdup( &digest );
1594 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
1596 pre = SLAP_INDEX_SUBSTR_PREFIX;
1597 klen = SLAP_INDEX_SUBSTR_MAXLEN;
1599 for( i=0; sa->sa_any[i] != NULL; i++ ) {
1600 if( sa->sa_any[i]->bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
1604 value = sa->sa_any[i];
1607 j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
1608 j += SLAP_INDEX_SUBSTR_STEP )
1610 HASH_Init( &HASHcontext );
1611 if( prefix != NULL && prefix->bv_len > 0 ) {
1612 HASH_Update( &HASHcontext,
1613 prefix->bv_val, prefix->bv_len );
1615 HASH_Update( &HASHcontext,
1616 &pre, sizeof( pre ) );
1617 HASH_Update( &HASHcontext,
1618 syntax->ssyn_oid, slen );
1619 HASH_Update( &HASHcontext,
1620 mr->smr_oid, mlen );
1621 HASH_Update( &HASHcontext,
1622 &value->bv_val[j], klen );
1623 HASH_Final( HASHdigest, &HASHcontext );
1625 keys[nkeys++] = ber_bvdup( &digest );
1631 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final != NULL &&
1632 sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1634 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
1635 value = sa->sa_final;
1637 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
1638 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
1640 HASH_Init( &HASHcontext );
1641 if( prefix != NULL && prefix->bv_len > 0 ) {
1642 HASH_Update( &HASHcontext,
1643 prefix->bv_val, prefix->bv_len );
1645 HASH_Update( &HASHcontext,
1646 &pre, sizeof( pre ) );
1647 HASH_Update( &HASHcontext,
1648 syntax->ssyn_oid, slen );
1649 HASH_Update( &HASHcontext,
1650 mr->smr_oid, mlen );
1651 HASH_Update( &HASHcontext,
1652 &value->bv_val[value->bv_len-klen], klen );
1653 HASH_Final( HASHdigest, &HASHcontext );
1655 keys[nkeys++] = ber_bvdup( &digest );
1665 ch_free( sa->sa_final );
1666 ber_bvecfree( sa->sa_any );
1667 ch_free( sa->sa_initial );
1670 return LDAP_SUCCESS;
1679 struct berval *value,
1680 void *assertedValue )
1682 *matchp = UTF8normcmp( value->bv_val,
1683 ((struct berval *) assertedValue)->bv_val,
1685 return LDAP_SUCCESS;
1691 struct berval *val )
1695 if( val->bv_len == 0 ) {
1696 /* disallow empty strings */
1697 return LDAP_INVALID_SYNTAX;
1700 if( OID_LEADCHAR(val->bv_val[0]) ) {
1702 for(i=1; i < val->bv_len; i++) {
1703 if( OID_SEPARATOR( val->bv_val[i] ) ) {
1704 if( dot++ ) return 1;
1705 } else if ( OID_CHAR( val->bv_val[i] ) ) {
1708 return LDAP_INVALID_SYNTAX;
1712 return !dot ? LDAP_SUCCESS : LDAP_INVALID_SYNTAX;
1714 } else if( DESC_LEADCHAR(val->bv_val[0]) ) {
1715 for(i=1; i < val->bv_len; i++) {
1716 if( !DESC_CHAR(val->bv_val[i] ) ) {
1717 return LDAP_INVALID_SYNTAX;
1721 return LDAP_SUCCESS;
1724 return LDAP_INVALID_SYNTAX;
1730 struct berval *val )
1734 if( !val->bv_len ) return LDAP_INVALID_SYNTAX;
1736 if( val->bv_val[0] == '+' || val->bv_val[0] == '-' ) {
1737 if( val->bv_len < 2 ) return LDAP_INVALID_SYNTAX;
1738 } else if( !ASCII_DIGIT(val->bv_val[0]) ) {
1739 return LDAP_INVALID_SYNTAX;
1742 for(i=1; i < val->bv_len; i++) {
1743 if( !ASCII_DIGIT(val->bv_val[i]) ) return LDAP_INVALID_SYNTAX;
1746 return LDAP_SUCCESS;
1753 struct berval **normalized )
1756 struct berval *newval;
1762 negative = ( *p == '-' );
1763 if( *p == '-' || *p == '+' ) p++;
1765 /* Ignore leading zeros */
1766 while ( *p == '0' ) p++;
1768 newval = (struct berval *) ch_malloc( sizeof(struct berval) );
1771 newval->bv_val = ch_strdup("0");
1776 newval->bv_val = ch_malloc( val->bv_len + 1 );
1780 newval->bv_val[newval->bv_len++] = '-';
1783 for( ; *p != '\0'; p++ ) {
1784 newval->bv_val[newval->bv_len++] = *p;
1788 *normalized = newval;
1789 return LDAP_SUCCESS;
1793 countryStringValidate(
1795 struct berval *val )
1797 if( val->bv_len != 2 ) return LDAP_INVALID_SYNTAX;
1799 if( !SLAP_PRINTABLE(val->bv_val[0]) ) {
1800 return LDAP_INVALID_SYNTAX;
1802 if( !SLAP_PRINTABLE(val->bv_val[1]) ) {
1803 return LDAP_INVALID_SYNTAX;
1806 return LDAP_SUCCESS;
1810 printableStringValidate(
1812 struct berval *val )
1816 if( !val->bv_len ) return LDAP_INVALID_SYNTAX;
1818 for(i=0; i < val->bv_len; i++) {
1819 if( !SLAP_PRINTABLE(val->bv_val[i]) ) {
1820 return LDAP_INVALID_SYNTAX;
1824 return LDAP_SUCCESS;
1828 printablesStringValidate(
1830 struct berval *val )
1834 if( !val->bv_len ) return LDAP_INVALID_SYNTAX;
1836 for(i=0; i < val->bv_len; i++) {
1837 if( !SLAP_PRINTABLES(val->bv_val[i]) ) {
1838 return LDAP_INVALID_SYNTAX;
1842 return LDAP_SUCCESS;
1848 struct berval *val )
1852 if( !val->bv_len ) return LDAP_INVALID_SYNTAX;
1854 for(i=0; i < val->bv_len; i++) {
1855 if( !isascii(val->bv_val[i]) ) return LDAP_INVALID_SYNTAX;
1858 return LDAP_SUCCESS;
1865 struct berval **normalized )
1867 struct berval *newval;
1870 newval = ch_malloc( sizeof( struct berval ) );
1874 /* Ignore initial whitespace */
1875 while ( ASCII_SPACE( *p ) ) {
1881 return LDAP_INVALID_SYNTAX;
1884 newval->bv_val = ch_strdup( p );
1885 p = q = newval->bv_val;
1888 if ( ASCII_SPACE( *p ) ) {
1891 /* Ignore the extra whitespace */
1892 while ( ASCII_SPACE( *p ) ) {
1900 assert( *newval->bv_val );
1901 assert( newval->bv_val < p );
1904 /* cannot start with a space */
1905 assert( !ASCII_SPACE(*newval->bv_val) );
1908 * If the string ended in space, backup the pointer one
1909 * position. One is enough because the above loop collapsed
1910 * all whitespace to a single space.
1913 if ( ASCII_SPACE( q[-1] ) ) {
1917 /* cannot end with a space */
1918 assert( !ASCII_SPACE( q[-1] ) );
1920 /* null terminate */
1923 newval->bv_len = q - newval->bv_val;
1924 *normalized = newval;
1926 return LDAP_SUCCESS;
1935 struct berval *value,
1936 void *assertedValue )
1938 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
1941 match = strncmp( value->bv_val,
1942 ((struct berval *) assertedValue)->bv_val,
1947 return LDAP_SUCCESS;
1951 caseExactIA5SubstringsMatch(
1956 struct berval *value,
1957 void *assertedValue )
1960 SubstringsAssertion *sub = assertedValue;
1961 struct berval left = *value;
1965 /* Add up asserted input length */
1966 if( sub->sa_initial ) {
1967 inlen += sub->sa_initial->bv_len;
1970 for(i=0; sub->sa_any[i] != NULL; i++) {
1971 inlen += sub->sa_any[i]->bv_len;
1974 if( sub->sa_final ) {
1975 inlen += sub->sa_final->bv_len;
1978 if( sub->sa_initial ) {
1979 if( inlen > left.bv_len ) {
1984 match = strncmp( sub->sa_initial->bv_val, left.bv_val,
1985 sub->sa_initial->bv_len );
1991 left.bv_val += sub->sa_initial->bv_len;
1992 left.bv_len -= sub->sa_initial->bv_len;
1993 inlen -= sub->sa_initial->bv_len;
1996 if( sub->sa_final ) {
1997 if( inlen > left.bv_len ) {
2002 match = strncmp( sub->sa_final->bv_val,
2003 &left.bv_val[left.bv_len - sub->sa_final->bv_len],
2004 sub->sa_final->bv_len );
2010 left.bv_len -= sub->sa_final->bv_len;
2011 inlen -= sub->sa_final->bv_len;
2015 for(i=0; sub->sa_any[i]; i++) {
2020 if( inlen > left.bv_len ) {
2021 /* not enough length */
2026 if( sub->sa_any[i]->bv_len == 0 ) {
2030 p = strchr( left.bv_val, *sub->sa_any[i]->bv_val );
2037 idx = p - left.bv_val;
2038 assert( idx < left.bv_len );
2040 if( idx >= left.bv_len ) {
2041 /* this shouldn't happen */
2048 if( sub->sa_any[i]->bv_len > left.bv_len ) {
2049 /* not enough left */
2054 match = strncmp( left.bv_val,
2055 sub->sa_any[i]->bv_val,
2056 sub->sa_any[i]->bv_len );
2064 left.bv_val += sub->sa_any[i]->bv_len;
2065 left.bv_len -= sub->sa_any[i]->bv_len;
2066 inlen -= sub->sa_any[i]->bv_len;
2072 return LDAP_SUCCESS;
2075 /* Index generation function */
2076 int caseExactIA5Indexer(
2081 struct berval *prefix,
2082 struct berval **values,
2083 struct berval ***keysp )
2087 struct berval **keys;
2088 HASH_CONTEXT HASHcontext;
2089 unsigned char HASHdigest[HASH_BYTES];
2090 struct berval digest;
2091 digest.bv_val = HASHdigest;
2092 digest.bv_len = sizeof(HASHdigest);
2094 for( i=0; values[i] != NULL; i++ ) {
2095 /* empty - just count them */
2098 /* we should have at least one value at this point */
2101 keys = ch_malloc( sizeof( struct berval * ) * (i+1) );
2103 slen = strlen( syntax->ssyn_oid );
2104 mlen = strlen( mr->smr_oid );
2106 for( i=0; values[i] != NULL; i++ ) {
2107 struct berval *value = values[i];
2109 HASH_Init( &HASHcontext );
2110 if( prefix != NULL && prefix->bv_len > 0 ) {
2111 HASH_Update( &HASHcontext,
2112 prefix->bv_val, prefix->bv_len );
2114 HASH_Update( &HASHcontext,
2115 syntax->ssyn_oid, slen );
2116 HASH_Update( &HASHcontext,
2117 mr->smr_oid, mlen );
2118 HASH_Update( &HASHcontext,
2119 value->bv_val, value->bv_len );
2120 HASH_Final( HASHdigest, &HASHcontext );
2122 keys[i] = ber_bvdup( &digest );
2127 return LDAP_SUCCESS;
2130 /* Index generation function */
2131 int caseExactIA5Filter(
2136 struct berval *prefix,
2138 struct berval ***keysp )
2141 struct berval **keys;
2142 HASH_CONTEXT HASHcontext;
2143 unsigned char HASHdigest[HASH_BYTES];
2144 struct berval *value;
2145 struct berval digest;
2146 digest.bv_val = HASHdigest;
2147 digest.bv_len = sizeof(HASHdigest);
2149 slen = strlen( syntax->ssyn_oid );
2150 mlen = strlen( mr->smr_oid );
2152 value = (struct berval *) assertValue;
2154 keys = ch_malloc( sizeof( struct berval * ) * 2 );
2156 HASH_Init( &HASHcontext );
2157 if( prefix != NULL && prefix->bv_len > 0 ) {
2158 HASH_Update( &HASHcontext,
2159 prefix->bv_val, prefix->bv_len );
2161 HASH_Update( &HASHcontext,
2162 syntax->ssyn_oid, slen );
2163 HASH_Update( &HASHcontext,
2164 mr->smr_oid, mlen );
2165 HASH_Update( &HASHcontext,
2166 value->bv_val, value->bv_len );
2167 HASH_Final( HASHdigest, &HASHcontext );
2169 keys[0] = ber_bvdup( &digest );
2173 return LDAP_SUCCESS;
2176 /* Substrings Index generation function */
2177 int caseExactIA5SubstringsIndexer(
2182 struct berval *prefix,
2183 struct berval **values,
2184 struct berval ***keysp )
2188 struct berval **keys;
2189 HASH_CONTEXT HASHcontext;
2190 unsigned char HASHdigest[HASH_BYTES];
2191 struct berval digest;
2192 digest.bv_val = HASHdigest;
2193 digest.bv_len = sizeof(HASHdigest);
2195 /* we should have at least one value at this point */
2196 assert( values != NULL && values[0] != NULL );
2199 for( i=0; values[i] != NULL; i++ ) {
2200 /* count number of indices to generate */
2201 if( values[i]->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
2205 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
2206 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2207 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2208 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2210 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2214 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
2215 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2216 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
2220 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
2221 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2222 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2223 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2225 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2231 /* no keys to generate */
2233 return LDAP_SUCCESS;
2236 keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) );
2238 slen = strlen( syntax->ssyn_oid );
2239 mlen = strlen( mr->smr_oid );
2242 for( i=0; values[i] != NULL; i++ ) {
2244 struct berval *value;
2247 if( value->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
2249 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
2250 ( value->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
2252 char pre = SLAP_INDEX_SUBSTR_PREFIX;
2253 max = value->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
2255 for( j=0; j<max; j++ ) {
2256 HASH_Init( &HASHcontext );
2257 if( prefix != NULL && prefix->bv_len > 0 ) {
2258 HASH_Update( &HASHcontext,
2259 prefix->bv_val, prefix->bv_len );
2262 HASH_Update( &HASHcontext,
2263 &pre, sizeof( pre ) );
2264 HASH_Update( &HASHcontext,
2265 syntax->ssyn_oid, slen );
2266 HASH_Update( &HASHcontext,
2267 mr->smr_oid, mlen );
2268 HASH_Update( &HASHcontext,
2270 SLAP_INDEX_SUBSTR_MAXLEN );
2271 HASH_Final( HASHdigest, &HASHcontext );
2273 keys[nkeys++] = ber_bvdup( &digest );
2277 max = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2278 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2280 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
2283 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
2284 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
2285 HASH_Init( &HASHcontext );
2286 if( prefix != NULL && prefix->bv_len > 0 ) {
2287 HASH_Update( &HASHcontext,
2288 prefix->bv_val, prefix->bv_len );
2290 HASH_Update( &HASHcontext,
2291 &pre, sizeof( pre ) );
2292 HASH_Update( &HASHcontext,
2293 syntax->ssyn_oid, slen );
2294 HASH_Update( &HASHcontext,
2295 mr->smr_oid, mlen );
2296 HASH_Update( &HASHcontext,
2298 HASH_Final( HASHdigest, &HASHcontext );
2300 keys[nkeys++] = ber_bvdup( &digest );
2303 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
2304 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
2305 HASH_Init( &HASHcontext );
2306 if( prefix != NULL && prefix->bv_len > 0 ) {
2307 HASH_Update( &HASHcontext,
2308 prefix->bv_val, prefix->bv_len );
2310 HASH_Update( &HASHcontext,
2311 &pre, sizeof( pre ) );
2312 HASH_Update( &HASHcontext,
2313 syntax->ssyn_oid, slen );
2314 HASH_Update( &HASHcontext,
2315 mr->smr_oid, mlen );
2316 HASH_Update( &HASHcontext,
2317 &value->bv_val[value->bv_len-j], j );
2318 HASH_Final( HASHdigest, &HASHcontext );
2320 keys[nkeys++] = ber_bvdup( &digest );
2334 return LDAP_SUCCESS;
2337 int caseExactIA5SubstringsFilter(
2342 struct berval *prefix,
2344 struct berval ***keysp )
2346 SubstringsAssertion *sa = assertValue;
2348 ber_len_t nkeys = 0;
2349 size_t slen, mlen, klen;
2350 struct berval **keys;
2351 HASH_CONTEXT HASHcontext;
2352 unsigned char HASHdigest[HASH_BYTES];
2353 struct berval *value;
2354 struct berval digest;
2356 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial != NULL &&
2357 sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2362 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
2364 for( i=0; sa->sa_any[i] != NULL; i++ ) {
2365 if( sa->sa_any[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2366 /* don't bother accounting for stepping */
2367 nkeys += sa->sa_any[i]->bv_len -
2368 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
2373 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final != NULL &&
2374 sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2381 return LDAP_SUCCESS;
2384 digest.bv_val = HASHdigest;
2385 digest.bv_len = sizeof(HASHdigest);
2387 slen = strlen( syntax->ssyn_oid );
2388 mlen = strlen( mr->smr_oid );
2390 keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) );
2393 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial != NULL &&
2394 sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2396 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
2397 value = sa->sa_initial;
2399 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2400 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2402 HASH_Init( &HASHcontext );
2403 if( prefix != NULL && prefix->bv_len > 0 ) {
2404 HASH_Update( &HASHcontext,
2405 prefix->bv_val, prefix->bv_len );
2407 HASH_Update( &HASHcontext,
2408 &pre, sizeof( pre ) );
2409 HASH_Update( &HASHcontext,
2410 syntax->ssyn_oid, slen );
2411 HASH_Update( &HASHcontext,
2412 mr->smr_oid, mlen );
2413 HASH_Update( &HASHcontext,
2414 value->bv_val, klen );
2415 HASH_Final( HASHdigest, &HASHcontext );
2417 keys[nkeys++] = ber_bvdup( &digest );
2420 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
2422 pre = SLAP_INDEX_SUBSTR_PREFIX;
2423 klen = SLAP_INDEX_SUBSTR_MAXLEN;
2425 for( i=0; sa->sa_any[i] != NULL; i++ ) {
2426 if( sa->sa_any[i]->bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
2430 value = sa->sa_any[i];
2433 j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
2434 j += SLAP_INDEX_SUBSTR_STEP )
2436 HASH_Init( &HASHcontext );
2437 if( prefix != NULL && prefix->bv_len > 0 ) {
2438 HASH_Update( &HASHcontext,
2439 prefix->bv_val, prefix->bv_len );
2441 HASH_Update( &HASHcontext,
2442 &pre, sizeof( pre ) );
2443 HASH_Update( &HASHcontext,
2444 syntax->ssyn_oid, slen );
2445 HASH_Update( &HASHcontext,
2446 mr->smr_oid, mlen );
2447 HASH_Update( &HASHcontext,
2448 &value->bv_val[j], klen );
2449 HASH_Final( HASHdigest, &HASHcontext );
2451 keys[nkeys++] = ber_bvdup( &digest );
2456 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final != NULL &&
2457 sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2459 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
2460 value = sa->sa_final;
2462 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2463 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2465 HASH_Init( &HASHcontext );
2466 if( prefix != NULL && prefix->bv_len > 0 ) {
2467 HASH_Update( &HASHcontext,
2468 prefix->bv_val, prefix->bv_len );
2470 HASH_Update( &HASHcontext,
2471 &pre, sizeof( pre ) );
2472 HASH_Update( &HASHcontext,
2473 syntax->ssyn_oid, slen );
2474 HASH_Update( &HASHcontext,
2475 mr->smr_oid, mlen );
2476 HASH_Update( &HASHcontext,
2477 &value->bv_val[value->bv_len-klen], klen );
2478 HASH_Final( HASHdigest, &HASHcontext );
2480 keys[nkeys++] = ber_bvdup( &digest );
2491 return LDAP_SUCCESS;
2500 struct berval *value,
2501 void *assertedValue )
2503 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
2505 if( match == 0 && value->bv_len ) {
2506 match = strncasecmp( value->bv_val,
2507 ((struct berval *) assertedValue)->bv_val,
2512 return LDAP_SUCCESS;
2516 caseIgnoreIA5SubstringsMatch(
2521 struct berval *value,
2522 void *assertedValue )
2525 SubstringsAssertion *sub = assertedValue;
2526 struct berval left = *value;
2530 /* Add up asserted input length */
2531 if( sub->sa_initial ) {
2532 inlen += sub->sa_initial->bv_len;
2535 for(i=0; sub->sa_any[i] != NULL; i++) {
2536 inlen += sub->sa_any[i]->bv_len;
2539 if( sub->sa_final ) {
2540 inlen += sub->sa_final->bv_len;
2543 if( sub->sa_initial ) {
2544 if( inlen > left.bv_len ) {
2549 match = strncasecmp( sub->sa_initial->bv_val, left.bv_val,
2550 sub->sa_initial->bv_len );
2556 left.bv_val += sub->sa_initial->bv_len;
2557 left.bv_len -= sub->sa_initial->bv_len;
2558 inlen -= sub->sa_initial->bv_len;
2561 if( sub->sa_final ) {
2562 if( inlen > left.bv_len ) {
2567 match = strncasecmp( sub->sa_final->bv_val,
2568 &left.bv_val[left.bv_len - sub->sa_final->bv_len],
2569 sub->sa_final->bv_len );
2575 left.bv_len -= sub->sa_final->bv_len;
2576 inlen -= sub->sa_final->bv_len;
2580 for(i=0; sub->sa_any[i]; i++) {
2585 if( inlen > left.bv_len ) {
2586 /* not enough length */
2591 if( sub->sa_any[i]->bv_len == 0 ) {
2595 p = strcasechr( left.bv_val, *sub->sa_any[i]->bv_val );
2602 idx = p - left.bv_val;
2603 assert( idx < left.bv_len );
2605 if( idx >= left.bv_len ) {
2606 /* this shouldn't happen */
2613 if( sub->sa_any[i]->bv_len > left.bv_len ) {
2614 /* not enough left */
2619 match = strncasecmp( left.bv_val,
2620 sub->sa_any[i]->bv_val,
2621 sub->sa_any[i]->bv_len );
2630 left.bv_val += sub->sa_any[i]->bv_len;
2631 left.bv_len -= sub->sa_any[i]->bv_len;
2632 inlen -= sub->sa_any[i]->bv_len;
2638 return LDAP_SUCCESS;
2641 /* Index generation function */
2642 int caseIgnoreIA5Indexer(
2647 struct berval *prefix,
2648 struct berval **values,
2649 struct berval ***keysp )
2653 struct berval **keys;
2654 HASH_CONTEXT HASHcontext;
2655 unsigned char HASHdigest[HASH_BYTES];
2656 struct berval digest;
2657 digest.bv_val = HASHdigest;
2658 digest.bv_len = sizeof(HASHdigest);
2660 /* we should have at least one value at this point */
2661 assert( values != NULL && values[0] != NULL );
2663 for( i=0; values[i] != NULL; i++ ) {
2664 /* just count them */
2667 keys = ch_malloc( sizeof( struct berval * ) * (i+1) );
2669 slen = strlen( syntax->ssyn_oid );
2670 mlen = strlen( mr->smr_oid );
2672 for( i=0; values[i] != NULL; i++ ) {
2673 struct berval *value = ber_bvdup( values[i] );
2674 ldap_pvt_str2upper( value->bv_val );
2676 HASH_Init( &HASHcontext );
2677 if( prefix != NULL && prefix->bv_len > 0 ) {
2678 HASH_Update( &HASHcontext,
2679 prefix->bv_val, prefix->bv_len );
2681 HASH_Update( &HASHcontext,
2682 syntax->ssyn_oid, slen );
2683 HASH_Update( &HASHcontext,
2684 mr->smr_oid, mlen );
2685 HASH_Update( &HASHcontext,
2686 value->bv_val, value->bv_len );
2687 HASH_Final( HASHdigest, &HASHcontext );
2689 ber_bvfree( value );
2691 keys[i] = ber_bvdup( &digest );
2696 return LDAP_SUCCESS;
2699 /* Index generation function */
2700 int caseIgnoreIA5Filter(
2705 struct berval *prefix,
2707 struct berval ***keysp )
2710 struct berval **keys;
2711 HASH_CONTEXT HASHcontext;
2712 unsigned char HASHdigest[HASH_BYTES];
2713 struct berval *value;
2714 struct berval digest;
2715 digest.bv_val = HASHdigest;
2716 digest.bv_len = sizeof(HASHdigest);
2718 slen = strlen( syntax->ssyn_oid );
2719 mlen = strlen( mr->smr_oid );
2721 value = ber_bvdup( (struct berval *) assertValue );
2722 ldap_pvt_str2upper( value->bv_val );
2724 keys = ch_malloc( sizeof( struct berval * ) * 2 );
2726 HASH_Init( &HASHcontext );
2727 if( prefix != NULL && prefix->bv_len > 0 ) {
2728 HASH_Update( &HASHcontext,
2729 prefix->bv_val, prefix->bv_len );
2731 HASH_Update( &HASHcontext,
2732 syntax->ssyn_oid, slen );
2733 HASH_Update( &HASHcontext,
2734 mr->smr_oid, mlen );
2735 HASH_Update( &HASHcontext,
2736 value->bv_val, value->bv_len );
2737 HASH_Final( HASHdigest, &HASHcontext );
2739 keys[0] = ber_bvdup( &digest );
2742 ber_bvfree( value );
2746 return LDAP_SUCCESS;
2749 /* Substrings Index generation function */
2750 int caseIgnoreIA5SubstringsIndexer(
2755 struct berval *prefix,
2756 struct berval **values,
2757 struct berval ***keysp )
2761 struct berval **keys;
2762 HASH_CONTEXT HASHcontext;
2763 unsigned char HASHdigest[HASH_BYTES];
2764 struct berval digest;
2765 digest.bv_val = HASHdigest;
2766 digest.bv_len = sizeof(HASHdigest);
2768 /* we should have at least one value at this point */
2769 assert( values != NULL && values[0] != NULL );
2772 for( i=0; values[i] != NULL; i++ ) {
2773 /* count number of indices to generate */
2774 if( values[i]->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
2778 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
2779 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2780 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2781 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2783 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2787 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
2788 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2789 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
2793 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
2794 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2795 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2796 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2798 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2804 /* no keys to generate */
2806 return LDAP_SUCCESS;
2809 keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) );
2811 slen = strlen( syntax->ssyn_oid );
2812 mlen = strlen( mr->smr_oid );
2815 for( i=0; values[i] != NULL; i++ ) {
2817 struct berval *value;
2819 if( values[i]->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
2821 value = ber_bvdup( values[i] );
2822 ldap_pvt_str2upper( value->bv_val );
2824 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
2825 ( value->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
2827 char pre = SLAP_INDEX_SUBSTR_PREFIX;
2828 max = value->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
2830 for( j=0; j<max; j++ ) {
2831 HASH_Init( &HASHcontext );
2832 if( prefix != NULL && prefix->bv_len > 0 ) {
2833 HASH_Update( &HASHcontext,
2834 prefix->bv_val, prefix->bv_len );
2837 HASH_Update( &HASHcontext,
2838 &pre, sizeof( pre ) );
2839 HASH_Update( &HASHcontext,
2840 syntax->ssyn_oid, slen );
2841 HASH_Update( &HASHcontext,
2842 mr->smr_oid, mlen );
2843 HASH_Update( &HASHcontext,
2845 SLAP_INDEX_SUBSTR_MAXLEN );
2846 HASH_Final( HASHdigest, &HASHcontext );
2848 keys[nkeys++] = ber_bvdup( &digest );
2852 max = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2853 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2855 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
2858 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
2859 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
2860 HASH_Init( &HASHcontext );
2861 if( prefix != NULL && prefix->bv_len > 0 ) {
2862 HASH_Update( &HASHcontext,
2863 prefix->bv_val, prefix->bv_len );
2865 HASH_Update( &HASHcontext,
2866 &pre, sizeof( pre ) );
2867 HASH_Update( &HASHcontext,
2868 syntax->ssyn_oid, slen );
2869 HASH_Update( &HASHcontext,
2870 mr->smr_oid, mlen );
2871 HASH_Update( &HASHcontext,
2873 HASH_Final( HASHdigest, &HASHcontext );
2875 keys[nkeys++] = ber_bvdup( &digest );
2878 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
2879 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
2880 HASH_Init( &HASHcontext );
2881 if( prefix != NULL && prefix->bv_len > 0 ) {
2882 HASH_Update( &HASHcontext,
2883 prefix->bv_val, prefix->bv_len );
2885 HASH_Update( &HASHcontext,
2886 &pre, sizeof( pre ) );
2887 HASH_Update( &HASHcontext,
2888 syntax->ssyn_oid, slen );
2889 HASH_Update( &HASHcontext,
2890 mr->smr_oid, mlen );
2891 HASH_Update( &HASHcontext,
2892 &value->bv_val[value->bv_len-j], j );
2893 HASH_Final( HASHdigest, &HASHcontext );
2895 keys[nkeys++] = ber_bvdup( &digest );
2900 ber_bvfree( value );
2911 return LDAP_SUCCESS;
2914 int caseIgnoreIA5SubstringsFilter(
2919 struct berval *prefix,
2921 struct berval ***keysp )
2923 SubstringsAssertion *sa = assertValue;
2925 ber_len_t nkeys = 0;
2926 size_t slen, mlen, klen;
2927 struct berval **keys;
2928 HASH_CONTEXT HASHcontext;
2929 unsigned char HASHdigest[HASH_BYTES];
2930 struct berval *value;
2931 struct berval digest;
2933 if((flags & SLAP_INDEX_SUBSTR_INITIAL) && sa->sa_initial != NULL &&
2934 sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2939 if((flags & SLAP_INDEX_SUBSTR_ANY) && sa->sa_any != NULL ) {
2941 for( i=0; sa->sa_any[i] != NULL; i++ ) {
2942 if( sa->sa_any[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2943 /* don't bother accounting for stepping */
2944 nkeys += sa->sa_any[i]->bv_len -
2945 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
2950 if((flags & SLAP_INDEX_SUBSTR_FINAL) && sa->sa_final != NULL &&
2951 sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2958 return LDAP_SUCCESS;
2961 digest.bv_val = HASHdigest;
2962 digest.bv_len = sizeof(HASHdigest);
2964 slen = strlen( syntax->ssyn_oid );
2965 mlen = strlen( mr->smr_oid );
2967 keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) );
2970 if((flags & SLAP_INDEX_SUBSTR_INITIAL) && sa->sa_initial != NULL &&
2971 sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2973 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
2974 value = ber_bvdup( sa->sa_initial );
2975 ldap_pvt_str2upper( value->bv_val );
2977 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2978 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2980 HASH_Init( &HASHcontext );
2981 if( prefix != NULL && prefix->bv_len > 0 ) {
2982 HASH_Update( &HASHcontext,
2983 prefix->bv_val, prefix->bv_len );
2985 HASH_Update( &HASHcontext,
2986 &pre, sizeof( pre ) );
2987 HASH_Update( &HASHcontext,
2988 syntax->ssyn_oid, slen );
2989 HASH_Update( &HASHcontext,
2990 mr->smr_oid, mlen );
2991 HASH_Update( &HASHcontext,
2992 value->bv_val, klen );
2993 HASH_Final( HASHdigest, &HASHcontext );
2995 ber_bvfree( value );
2996 keys[nkeys++] = ber_bvdup( &digest );
2999 if((flags & SLAP_INDEX_SUBSTR_ANY) && sa->sa_any != NULL ) {
3001 pre = SLAP_INDEX_SUBSTR_PREFIX;
3002 klen = SLAP_INDEX_SUBSTR_MAXLEN;
3004 for( i=0; sa->sa_any[i] != NULL; i++ ) {
3005 if( sa->sa_any[i]->bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
3009 value = ber_bvdup( sa->sa_any[i] );
3010 ldap_pvt_str2upper( value->bv_val );
3013 j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
3014 j += SLAP_INDEX_SUBSTR_STEP )
3016 HASH_Init( &HASHcontext );
3017 if( prefix != NULL && prefix->bv_len > 0 ) {
3018 HASH_Update( &HASHcontext,
3019 prefix->bv_val, prefix->bv_len );
3021 HASH_Update( &HASHcontext,
3022 &pre, sizeof( pre ) );
3023 HASH_Update( &HASHcontext,
3024 syntax->ssyn_oid, slen );
3025 HASH_Update( &HASHcontext,
3026 mr->smr_oid, mlen );
3027 HASH_Update( &HASHcontext,
3028 &value->bv_val[j], klen );
3029 HASH_Final( HASHdigest, &HASHcontext );
3031 keys[nkeys++] = ber_bvdup( &digest );
3034 ber_bvfree( value );
3038 if((flags & SLAP_INDEX_SUBSTR_FINAL) && sa->sa_final != NULL &&
3039 sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3041 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
3042 value = ber_bvdup( sa->sa_final );
3043 ldap_pvt_str2upper( value->bv_val );
3045 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
3046 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
3048 HASH_Init( &HASHcontext );
3049 if( prefix != NULL && prefix->bv_len > 0 ) {
3050 HASH_Update( &HASHcontext,
3051 prefix->bv_val, prefix->bv_len );
3053 HASH_Update( &HASHcontext,
3054 &pre, sizeof( pre ) );
3055 HASH_Update( &HASHcontext,
3056 syntax->ssyn_oid, slen );
3057 HASH_Update( &HASHcontext,
3058 mr->smr_oid, mlen );
3059 HASH_Update( &HASHcontext,
3060 &value->bv_val[value->bv_len-klen], klen );
3061 HASH_Final( HASHdigest, &HASHcontext );
3063 ber_bvfree( value );
3064 keys[nkeys++] = ber_bvdup( &digest );
3075 return LDAP_SUCCESS;
3079 numericStringValidate(
3085 for(i=0; i < in->bv_len; i++) {
3086 if( !SLAP_NUMERIC(in->bv_val[i]) ) {
3087 return LDAP_INVALID_SYNTAX;
3091 return LDAP_SUCCESS;
3095 numericStringNormalize(
3098 struct berval **normalized )
3100 /* removal all spaces */
3101 struct berval *newval;
3104 newval = ch_malloc( sizeof( struct berval ) );
3105 newval->bv_val = ch_malloc( val->bv_len + 1 );
3111 if ( ASCII_SPACE( *p ) ) {
3112 /* Ignore whitespace */
3119 /* we should have copied no more then is in val */
3120 assert( (q - newval->bv_val) <= (p - val->bv_val) );
3122 /* null terminate */
3125 newval->bv_len = q - newval->bv_val;
3126 *normalized = newval;
3128 return LDAP_SUCCESS;
3132 objectIdentifierFirstComponentMatch(
3137 struct berval *value,
3138 void *assertedValue )
3140 int rc = LDAP_SUCCESS;
3142 struct berval *asserted = (struct berval *) assertedValue;
3146 if( value->bv_len == 0 || value->bv_val[0] != '(' /*')'*/ ) {
3147 return LDAP_INVALID_SYNTAX;
3150 /* trim leading white space */
3151 for( i=1; ASCII_SPACE(value->bv_val[i]) && i < value->bv_len; i++ ) {
3155 /* grab next word */
3156 oid.bv_val = &value->bv_val[i];
3157 oid.bv_len = value->bv_len - i;
3158 for( i=1; ASCII_SPACE(value->bv_val[i]) && i < oid.bv_len; i++ ) {
3163 /* insert attributeTypes, objectclass check here */
3164 if( OID_LEADCHAR(asserted->bv_val[0]) ) {
3165 rc = objectIdentifierMatch( &match, flags, syntax, mr, &oid, asserted );
3168 char *stored = ch_malloc( oid.bv_len + 1 );
3169 AC_MEMCPY( stored, oid.bv_val, oid.bv_len );
3170 stored[oid.bv_len] = '\0';
3172 if ( !strcmp( syntax->ssyn_oid, SLAP_SYNTAX_MATCHINGRULES_OID ) ) {
3173 MatchingRule *asserted_mr = mr_find( asserted->bv_val );
3174 MatchingRule *stored_mr = mr_find( stored );
3176 if( asserted_mr == NULL ) {
3177 rc = SLAPD_COMPARE_UNDEFINED;
3179 match = asserted_mr != stored_mr;
3182 } else if ( !strcmp( syntax->ssyn_oid,
3183 SLAP_SYNTAX_ATTRIBUTETYPES_OID ) )
3185 AttributeType *asserted_at = at_find( asserted->bv_val );
3186 AttributeType *stored_at = at_find( stored );
3188 if( asserted_at == NULL ) {
3189 rc = SLAPD_COMPARE_UNDEFINED;
3191 match = asserted_at != stored_at;
3194 } else if ( !strcmp( syntax->ssyn_oid,
3195 SLAP_SYNTAX_OBJECTCLASSES_OID ) )
3197 ObjectClass *asserted_oc = oc_find( asserted->bv_val );
3198 ObjectClass *stored_oc = oc_find( stored );
3200 if( asserted_oc == NULL ) {
3201 rc = SLAPD_COMPARE_UNDEFINED;
3203 match = asserted_oc != stored_oc;
3211 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
3212 "objectIdentifierFirstComponentMatch: %d\n %s\n %s\n",
3213 match, value->bv_val, asserted->bv_val ));
3215 Debug( LDAP_DEBUG_ARGS, "objectIdentifierFirstComponentMatch "
3216 "%d\n\t\"%s\"\n\t\"%s\"\n",
3217 match, value->bv_val, asserted->bv_val );
3221 if( rc == LDAP_SUCCESS ) *matchp = match;
3226 check_time_syntax (struct berval *val,
3230 static int ceiling[9] = { 99, 99, 11, 30, 23, 59, 59, 12, 59 };
3231 static int mdays[2][12] = {
3232 /* non-leap years */
3233 { 30, 27, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30 },
3235 { 30, 28, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30 }
3238 int part, c, tzoffset, leapyear = 0 ;
3240 if( val->bv_len == 0 ) {
3241 return LDAP_INVALID_SYNTAX;
3244 p = (char *)val->bv_val;
3245 e = p + val->bv_len;
3247 /* Ignore initial whitespace */
3248 while ( ( p < e ) && ASCII_SPACE( *p ) ) {
3252 if (e - p < 13 - (2 * start)) {
3253 return LDAP_INVALID_SYNTAX;
3256 for (part = 0; part < 9; part++) {
3260 for (part = start; part < 7; part++) {
3262 if ((part == 6) && (c == 'Z' || c == '+' || c == '-')) {
3269 return LDAP_INVALID_SYNTAX;
3271 if (c < 0 || c > 9) {
3272 return LDAP_INVALID_SYNTAX;
3278 return LDAP_INVALID_SYNTAX;
3280 if (c < 0 || c > 9) {
3281 return LDAP_INVALID_SYNTAX;
3286 if (part == 2 || part == 3) {
3289 if (parts[part] < 0) {
3290 return LDAP_INVALID_SYNTAX;
3292 if (parts[part] > ceiling[part]) {
3293 return LDAP_INVALID_SYNTAX;
3297 /* leapyear check for the Gregorian calendar (year>1581) */
3298 if (((parts[1] % 4 == 0) && (parts[1] != 0)) ||
3299 ((parts[0] % 4 == 0) && (parts[1] == 0)))
3304 if (parts[3] > mdays[leapyear][parts[2]]) {
3305 return LDAP_INVALID_SYNTAX;
3310 tzoffset = 0; /* UTC */
3311 } else if (c != '+' && c != '-') {
3312 return LDAP_INVALID_SYNTAX;
3316 } else /* c == '+' */ {
3321 return LDAP_INVALID_SYNTAX;
3324 for (part = 7; part < 9; part++) {
3326 if (c < 0 || c > 9) {
3327 return LDAP_INVALID_SYNTAX;
3332 if (c < 0 || c > 9) {
3333 return LDAP_INVALID_SYNTAX;
3337 if (parts[part] < 0 || parts[part] > ceiling[part]) {
3338 return LDAP_INVALID_SYNTAX;
3343 /* Ignore trailing whitespace */
3344 while ( ( p < e ) && ASCII_SPACE( *p ) ) {
3348 return LDAP_INVALID_SYNTAX;
3351 switch ( tzoffset ) {
3352 case -1: /* negativ offset to UTC, ie west of Greenwich */
3353 parts[4] += parts[7];
3354 parts[5] += parts[8];
3355 for (part = 6; --part > 0; ) { /* offset is just hhmm, no seconds */
3359 c = mdays[leapyear][parts[2]];
3361 if (parts[part] > c) {
3362 parts[part] -= c + 1;
3367 case 1: /* positive offset to UTC, ie east of Greenwich */
3368 parts[4] -= parts[7];
3369 parts[5] -= parts[8];
3370 for (part = 6; --part > 0; ) {
3374 /* first arg to % needs to be non negativ */
3375 c = mdays[leapyear][(parts[2] - 1 + 12) % 12];
3377 if (parts[part] < 0) {
3378 parts[part] += c + 1;
3383 case 0: /* already UTC */
3387 return LDAP_SUCCESS;
3394 struct berval **normalized )
3399 rc = check_time_syntax(val, 1, parts);
3400 if (rc != LDAP_SUCCESS) {
3405 out = ch_malloc( sizeof(struct berval) );
3407 return LBER_ERROR_MEMORY;
3410 out->bv_val = ch_malloc( 14 );
3411 if ( out->bv_val == NULL ) {
3413 return LBER_ERROR_MEMORY;
3416 sprintf( out->bv_val, "%02ld%02ld%02ld%02ld%02ld%02ldZ",
3417 parts[1], parts[2] + 1, parts[3] + 1,
3418 parts[4], parts[5], parts[6] );
3422 return LDAP_SUCCESS;
3432 return check_time_syntax(in, 1, parts);
3436 generalizedTimeValidate(
3442 return check_time_syntax(in, 0, parts);
3446 generalizedTimeNormalize(
3449 struct berval **normalized )
3454 rc = check_time_syntax(val, 0, parts);
3455 if (rc != LDAP_SUCCESS) {
3460 out = ch_malloc( sizeof(struct berval) );
3462 return LBER_ERROR_MEMORY;
3465 out->bv_val = ch_malloc( 16 );
3466 if ( out->bv_val == NULL ) {
3468 return LBER_ERROR_MEMORY;
3471 sprintf( out->bv_val, "%02ld%02ld%02ld%02ld%02ld%02ld%02ldZ",
3472 parts[0], parts[1], parts[2] + 1, parts[3] + 1,
3473 parts[4], parts[5], parts[6] );
3477 return LDAP_SUCCESS;
3481 nisNetgroupTripleValidate(
3483 struct berval *val )
3488 if ( val->bv_len == 0 ) {
3489 return LDAP_INVALID_SYNTAX;
3492 p = (char *)val->bv_val;
3493 e = p + val->bv_len;
3495 if ( *p != '(' /*')'*/ ) {
3496 return LDAP_INVALID_SYNTAX;
3499 for ( p++; ( p < e ) && ( *p != ')' ); p++ ) {
3503 return LDAP_INVALID_SYNTAX;
3506 } else if ( !ATTR_CHAR( *p ) ) {
3507 return LDAP_INVALID_SYNTAX;
3511 if ( ( commas != 2 ) || ( *p != /*'('*/ ')' ) ) {
3512 return LDAP_INVALID_SYNTAX;
3518 return LDAP_INVALID_SYNTAX;
3521 return LDAP_SUCCESS;
3525 bootParameterValidate(
3527 struct berval *val )
3531 if ( val->bv_len == 0 ) {
3532 return LDAP_INVALID_SYNTAX;
3535 p = (char *)val->bv_val;
3536 e = p + val->bv_len;
3539 for (; ( p < e ) && ( *p != '=' ); p++ ) {
3540 if ( !ATTR_CHAR( *p ) ) {
3541 return LDAP_INVALID_SYNTAX;
3546 return LDAP_INVALID_SYNTAX;
3550 for ( p++; ( p < e ) && ( *p != ':' ); p++ ) {
3551 if ( !ATTR_CHAR( *p ) ) {
3552 return LDAP_INVALID_SYNTAX;
3557 return LDAP_INVALID_SYNTAX;
3561 for ( p++; p < e; p++ ) {
3562 if ( !ATTR_CHAR( *p ) ) {
3563 return LDAP_INVALID_SYNTAX;
3567 return LDAP_SUCCESS;
3570 struct syntax_defs_rec {
3573 slap_syntax_validate_func *sd_validate;
3574 slap_syntax_transform_func *sd_normalize;
3575 slap_syntax_transform_func *sd_pretty;
3576 #ifdef SLAPD_BINARY_CONVERSION
3577 slap_syntax_transform_func *sd_ber2str;
3578 slap_syntax_transform_func *sd_str2ber;
3582 #define X_BINARY "X-BINARY-TRANSFER-REQUIRED 'TRUE' "
3583 #define X_NOT_H_R "X-NOT-HUMAN-READABLE 'TRUE' "
3585 struct syntax_defs_rec syntax_defs[] = {
3586 {"( 1.3.6.1.4.1.1466.115.121.1.1 DESC 'ACI Item' " X_BINARY X_NOT_H_R ")",
3587 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, NULL, NULL, NULL},
3588 {"( 1.3.6.1.4.1.1466.115.121.1.2 DESC 'Access Point' " X_NOT_H_R ")",
3589 0, NULL, NULL, NULL},
3590 {"( 1.3.6.1.4.1.1466.115.121.1.3 DESC 'Attribute Type Description' )",
3591 0, NULL, NULL, NULL},
3592 {"( 1.3.6.1.4.1.1466.115.121.1.4 DESC 'Audio' " X_NOT_H_R ")",
3593 SLAP_SYNTAX_BLOB, blobValidate, NULL, NULL},
3594 {"( 1.3.6.1.4.1.1466.115.121.1.5 DESC 'Binary' " X_NOT_H_R ")",
3595 SLAP_SYNTAX_BER, berValidate, NULL, NULL},
3596 {"( 1.3.6.1.4.1.1466.115.121.1.6 DESC 'Bit String' )",
3597 0, bitStringValidate, NULL, NULL },
3598 {"( 1.3.6.1.4.1.1466.115.121.1.7 DESC 'Boolean' )",
3599 0, booleanValidate, NULL, NULL},
3600 {"( 1.3.6.1.4.1.1466.115.121.1.8 DESC 'Certificate' "
3601 X_BINARY X_NOT_H_R ")",
3602 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
3603 {"( 1.3.6.1.4.1.1466.115.121.1.9 DESC 'Certificate List' "
3604 X_BINARY X_NOT_H_R ")",
3605 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
3606 {"( 1.3.6.1.4.1.1466.115.121.1.10 DESC 'Certificate Pair' "
3607 X_BINARY X_NOT_H_R ")",
3608 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
3609 {"( 1.3.6.1.4.1.1466.115.121.1.11 DESC 'Country String' )",
3610 0, countryStringValidate, IA5StringNormalize, NULL},
3611 {"( 1.3.6.1.4.1.1466.115.121.1.12 DESC 'Distinguished Name' )",
3612 0, dnValidate, dnNormalize, dnPretty},
3613 {"( 1.3.6.1.4.1.1466.115.121.1.13 DESC 'Data Quality' )",
3614 0, NULL, NULL, NULL},
3615 {"( 1.3.6.1.4.1.1466.115.121.1.14 DESC 'Delivery Method' )",
3616 0, NULL, NULL, NULL},
3617 {"( 1.3.6.1.4.1.1466.115.121.1.15 DESC 'Directory String' )",
3618 0, UTF8StringValidate, UTF8StringNormalize, NULL},
3619 {"( 1.3.6.1.4.1.1466.115.121.1.16 DESC 'DIT Content Rule Description' )",
3620 0, NULL, NULL, NULL},
3621 {"( 1.3.6.1.4.1.1466.115.121.1.17 DESC 'DIT Structure Rule Description' )",
3622 0, NULL, NULL, NULL},
3623 {"( 1.3.6.1.4.1.1466.115.121.1.19 DESC 'DSA Quality' )",
3624 0, NULL, NULL, NULL},
3625 {"( 1.3.6.1.4.1.1466.115.121.1.20 DESC 'DSE Type' )",
3626 0, NULL, NULL, NULL},
3627 {"( 1.3.6.1.4.1.1466.115.121.1.21 DESC 'Enhanced Guide' )",
3628 0, NULL, NULL, NULL},
3629 {"( 1.3.6.1.4.1.1466.115.121.1.22 DESC 'Facsimile Telephone Number' )",
3630 0, printablesStringValidate, IA5StringNormalize, NULL},
3631 {"( 1.3.6.1.4.1.1466.115.121.1.23 DESC 'Fax' " X_NOT_H_R ")",
3632 SLAP_SYNTAX_BLOB, NULL, NULL, NULL},
3633 {"( 1.3.6.1.4.1.1466.115.121.1.24 DESC 'Generalized Time' )",
3634 0, generalizedTimeValidate, generalizedTimeNormalize, NULL},
3635 {"( 1.3.6.1.4.1.1466.115.121.1.25 DESC 'Guide' )",
3636 0, NULL, NULL, NULL},
3637 {"( 1.3.6.1.4.1.1466.115.121.1.26 DESC 'IA5 String' )",
3638 0, IA5StringValidate, IA5StringNormalize, NULL},
3639 {"( 1.3.6.1.4.1.1466.115.121.1.27 DESC 'Integer' )",
3640 0, integerValidate, integerNormalize, integerPretty},
3641 {"( 1.3.6.1.4.1.1466.115.121.1.28 DESC 'JPEG' " X_NOT_H_R ")",
3642 SLAP_SYNTAX_BLOB, blobValidate, NULL, NULL},
3643 {"( 1.3.6.1.4.1.1466.115.121.1.29 DESC 'Master And Shadow Access Points' )",
3644 0, NULL, NULL, NULL},
3645 {"( 1.3.6.1.4.1.1466.115.121.1.30 DESC 'Matching Rule Description' )",
3646 0, NULL, NULL, NULL},
3647 {"( 1.3.6.1.4.1.1466.115.121.1.31 DESC 'Matching Rule Use Description' )",
3648 0, NULL, NULL, NULL},
3649 {"( 1.3.6.1.4.1.1466.115.121.1.32 DESC 'Mail Preference' )",
3650 0, NULL, NULL, NULL},
3651 {"( 1.3.6.1.4.1.1466.115.121.1.33 DESC 'MHS OR Address' )",
3652 0, NULL, NULL, NULL},
3653 {"( 1.3.6.1.4.1.1466.115.121.1.34 DESC 'Name And Optional UID' )",
3654 0, nameUIDValidate, nameUIDNormalize, NULL},
3655 {"( 1.3.6.1.4.1.1466.115.121.1.35 DESC 'Name Form Description' )",
3656 0, NULL, NULL, NULL},
3657 {"( 1.3.6.1.4.1.1466.115.121.1.36 DESC 'Numeric String' )",
3658 0, numericStringValidate, numericStringNormalize, NULL},
3659 {"( 1.3.6.1.4.1.1466.115.121.1.37 DESC 'Object Class Description' )",
3660 0, NULL, NULL, NULL},
3661 {"( 1.3.6.1.4.1.1466.115.121.1.38 DESC 'OID' )",
3662 0, oidValidate, NULL, NULL},
3663 {"( 1.3.6.1.4.1.1466.115.121.1.39 DESC 'Other Mailbox' )",
3664 0, IA5StringValidate, IA5StringNormalize, NULL},
3665 {"( 1.3.6.1.4.1.1466.115.121.1.40 DESC 'Octet String' )",
3666 0, blobValidate, NULL, NULL},
3667 {"( 1.3.6.1.4.1.1466.115.121.1.41 DESC 'Postal Address' )",
3668 0, UTF8StringValidate, UTF8StringNormalize, NULL},
3669 {"( 1.3.6.1.4.1.1466.115.121.1.42 DESC 'Protocol Information' )",
3670 0, NULL, NULL, NULL},
3671 {"( 1.3.6.1.4.1.1466.115.121.1.43 DESC 'Presentation Address' )",
3672 0, NULL, NULL, NULL},
3673 {"( 1.3.6.1.4.1.1466.115.121.1.44 DESC 'Printable String' )",
3674 0, printableStringValidate, IA5StringNormalize, NULL},
3675 {"( 1.3.6.1.4.1.1466.115.121.1.49 DESC 'Supported Algorithm' "
3676 X_BINARY X_NOT_H_R ")",
3677 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
3678 {"( 1.3.6.1.4.1.1466.115.121.1.50 DESC 'Telephone Number' )",
3679 0, printableStringValidate, IA5StringNormalize, NULL},
3680 {"( 1.3.6.1.4.1.1466.115.121.1.51 DESC 'Teletex Terminal Identifier' )",
3681 0, NULL, NULL, NULL},
3682 {"( 1.3.6.1.4.1.1466.115.121.1.52 DESC 'Telex Number' )",
3683 0, printableStringValidate, IA5StringNormalize, NULL},
3684 {"( 1.3.6.1.4.1.1466.115.121.1.53 DESC 'UTC Time' )",
3685 0, utcTimeValidate, utcTimeNormalize, NULL},
3686 {"( 1.3.6.1.4.1.1466.115.121.1.54 DESC 'LDAP Syntax Description' )",
3687 0, NULL, NULL, NULL},
3688 {"( 1.3.6.1.4.1.1466.115.121.1.55 DESC 'Modify Rights' )",
3689 0, NULL, NULL, NULL},
3690 {"( 1.3.6.1.4.1.1466.115.121.1.56 DESC 'LDAP Schema Definition' )",
3691 0, NULL, NULL, NULL},
3692 {"( 1.3.6.1.4.1.1466.115.121.1.57 DESC 'LDAP Schema Description' )",
3693 0, NULL, NULL, NULL},
3694 {"( 1.3.6.1.4.1.1466.115.121.1.58 DESC 'Substring Assertion' )",
3695 0, NULL, NULL, NULL},
3697 /* RFC 2307 NIS Syntaxes */
3698 {"( 1.3.6.1.1.1.0.0 DESC 'RFC2307 NIS Netgroup Triple' )",
3699 0, nisNetgroupTripleValidate, NULL, NULL},
3700 {"( 1.3.6.1.1.1.0.1 DESC 'RFC2307 Boot Parameter' )",
3701 0, bootParameterValidate, NULL, NULL},
3703 /* OpenLDAP Experimental Syntaxes */
3704 {"( 1.3.6.1.4.1.4203.666.2.1 DESC 'OpenLDAP Experimental ACI' )",
3705 0, UTF8StringValidate /* THIS WILL CHANGE FOR NEW ACI SYNTAX */,
3707 {"( 1.3.6.1.4.1.4203.666.2.2 DESC 'OpenLDAP authPassword' )",
3708 0, NULL, NULL, NULL},
3710 /* OpenLDAP Void Syntax */
3711 {"( 1.3.6.1.4.1.4203.1.1.1 DESC 'OpenLDAP void' )" ,
3712 SLAP_SYNTAX_HIDE, inValidate, NULL, NULL},
3713 {NULL, 0, NULL, NULL, NULL}
3716 struct mrule_defs_rec {
3718 slap_mask_t mrd_usage;
3719 slap_mr_convert_func * mrd_convert;
3720 slap_mr_normalize_func * mrd_normalize;
3721 slap_mr_match_func * mrd_match;
3722 slap_mr_indexer_func * mrd_indexer;
3723 slap_mr_filter_func * mrd_filter;
3725 char * mrd_associated;
3729 * Other matching rules in X.520 that we do not use (yet):
3731 * 2.5.13.9 numericStringOrderingMatch
3732 * 2.5.13.15 integerOrderingMatch
3733 * 2.5.13.18 octetStringOrderingMatch
3734 * 2.5.13.19 octetStringSubstringsMatch
3735 * 2.5.13.25 uTCTimeMatch
3736 * 2.5.13.26 uTCTimeOrderingMatch
3737 * 2.5.13.31 directoryStringFirstComponentMatch
3738 * 2.5.13.32 wordMatch
3739 * 2.5.13.33 keywordMatch
3740 * 2.5.13.34 certificateExactMatch
3741 * 2.5.13.35 certificateMatch
3742 * 2.5.13.36 certificatePairExactMatch
3743 * 2.5.13.37 certificatePairMatch
3744 * 2.5.13.38 certificateListExactMatch
3745 * 2.5.13.39 certificateListMatch
3746 * 2.5.13.40 algorithmIdentifierMatch
3747 * 2.5.13.41 storedPrefixMatch
3748 * 2.5.13.42 attributeCertificateMatch
3749 * 2.5.13.43 readerAndKeyIDMatch
3750 * 2.5.13.44 attributeIntegrityMatch
3753 struct mrule_defs_rec mrule_defs[] = {
3755 * EQUALITY matching rules must be listed after associated APPROX
3756 * matching rules. So, we list all APPROX matching rules first.
3758 {"( " directoryStringApproxMatchOID " NAME 'directoryStringApproxMatch' "
3759 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
3760 SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT,
3762 directoryStringApproxMatch,
3763 directoryStringApproxIndexer,
3764 directoryStringApproxFilter,
3767 {"( " IA5StringApproxMatchOID " NAME 'IA5StringApproxMatch' "
3768 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
3769 SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT,
3771 IA5StringApproxMatch,
3772 IA5StringApproxIndexer,
3773 IA5StringApproxFilter,
3777 * Other matching rules
3780 {"( 2.5.13.0 NAME 'objectIdentifierMatch' "
3781 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
3782 SLAP_MR_EQUALITY | SLAP_MR_EXT,
3784 objectIdentifierMatch, caseIgnoreIA5Indexer, caseIgnoreIA5Filter,
3787 {"( 2.5.13.1 NAME 'distinguishedNameMatch' "
3788 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )",
3789 SLAP_MR_EQUALITY | SLAP_MR_EXT,
3791 dnMatch, dnIndexer, dnFilter,
3794 {"( 2.5.13.2 NAME 'caseIgnoreMatch' "
3795 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
3796 SLAP_MR_EQUALITY | SLAP_MR_EXT,
3798 caseIgnoreMatch, caseExactIgnoreIndexer, caseExactIgnoreFilter,
3799 directoryStringApproxMatchOID },
3801 {"( 2.5.13.3 NAME 'caseIgnoreOrderingMatch' "
3802 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
3805 caseIgnoreOrderingMatch, NULL, NULL,
3808 {"( 2.5.13.4 NAME 'caseIgnoreSubstringsMatch' "
3809 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
3810 SLAP_MR_SUBSTR | SLAP_MR_EXT,
3812 caseExactIgnoreSubstringsMatch,
3813 caseExactIgnoreSubstringsIndexer,
3814 caseExactIgnoreSubstringsFilter,
3817 {"( 2.5.13.5 NAME 'caseExactMatch' "
3818 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
3819 SLAP_MR_EQUALITY | SLAP_MR_EXT,
3821 caseExactMatch, caseExactIgnoreIndexer, caseExactIgnoreFilter,
3822 directoryStringApproxMatchOID },
3824 {"( 2.5.13.6 NAME 'caseExactOrderingMatch' "
3825 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
3828 caseExactOrderingMatch, NULL, NULL,
3831 {"( 2.5.13.7 NAME 'caseExactSubstringsMatch' "
3832 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
3833 SLAP_MR_SUBSTR | SLAP_MR_EXT,
3835 caseExactIgnoreSubstringsMatch,
3836 caseExactIgnoreSubstringsIndexer,
3837 caseExactIgnoreSubstringsFilter,
3840 {"( 2.5.13.8 NAME 'numericStringMatch' "
3841 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 )",
3842 SLAP_MR_EQUALITY | SLAP_MR_EXT,
3845 caseIgnoreIA5Indexer,
3846 caseIgnoreIA5Filter,
3849 {"( 2.5.13.10 NAME 'numericStringSubstringsMatch' "
3850 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
3851 SLAP_MR_SUBSTR | SLAP_MR_EXT,
3853 caseIgnoreIA5SubstringsMatch,
3854 caseIgnoreIA5SubstringsIndexer,
3855 caseIgnoreIA5SubstringsFilter,
3858 {"( 2.5.13.11 NAME 'caseIgnoreListMatch' "
3859 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )",
3860 SLAP_MR_EQUALITY | SLAP_MR_EXT,
3862 caseIgnoreListMatch, NULL, NULL,
3865 {"( 2.5.13.12 NAME 'caseIgnoreListSubstringsMatch' "
3866 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
3867 SLAP_MR_SUBSTR | SLAP_MR_EXT,
3869 caseIgnoreListSubstringsMatch, NULL, NULL,
3872 {"( 2.5.13.13 NAME 'booleanMatch' "
3873 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )",
3874 SLAP_MR_EQUALITY | SLAP_MR_EXT,
3876 booleanMatch, NULL, NULL,
3879 {"( 2.5.13.14 NAME 'integerMatch' "
3880 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
3881 SLAP_MR_EQUALITY | SLAP_MR_EXT,
3883 integerMatch, integerIndexer, integerFilter,
3886 {"( 2.5.13.16 NAME 'bitStringMatch' "
3887 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.6 )",
3888 SLAP_MR_EQUALITY | SLAP_MR_EXT,
3890 bitStringMatch, NULL, NULL,
3893 {"( 2.5.13.17 NAME 'octetStringMatch' "
3894 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
3895 SLAP_MR_EQUALITY | SLAP_MR_EXT,
3897 octetStringMatch, octetStringIndexer, octetStringFilter,
3900 {"( 2.5.13.20 NAME 'telephoneNumberMatch' "
3901 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 )",
3902 SLAP_MR_EQUALITY | SLAP_MR_EXT,
3904 telephoneNumberMatch,
3905 telephoneNumberIndexer,
3906 telephoneNumberFilter,
3909 {"( 2.5.13.21 NAME 'telephoneNumberSubstringsMatch' "
3910 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
3911 SLAP_MR_SUBSTR | SLAP_MR_EXT,
3913 telephoneNumberSubstringsMatch,
3914 telephoneNumberSubstringsIndexer,
3915 telephoneNumberSubstringsFilter,
3918 {"( 2.5.13.22 NAME 'presentationAddressMatch' "
3919 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.43 )",
3920 SLAP_MR_EQUALITY | SLAP_MR_EXT,
3925 {"( 2.5.13.23 NAME 'uniqueMemberMatch' "
3926 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.34 )",
3927 SLAP_MR_EQUALITY | SLAP_MR_EXT,
3929 uniqueMemberMatch, NULL, NULL,
3932 {"( 2.5.13.24 NAME 'protocolInformationMatch' "
3933 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.42 )",
3934 SLAP_MR_EQUALITY | SLAP_MR_EXT,
3936 protocolInformationMatch, NULL, NULL,
3939 {"( 2.5.13.27 NAME 'generalizedTimeMatch' "
3940 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
3941 SLAP_MR_EQUALITY | SLAP_MR_EXT,
3943 generalizedTimeMatch, NULL, NULL,
3946 {"( 2.5.13.28 NAME 'generalizedTimeOrderingMatch' "
3947 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
3950 generalizedTimeOrderingMatch, NULL, NULL,
3953 {"( 2.5.13.29 NAME 'integerFirstComponentMatch' "
3954 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
3955 SLAP_MR_EQUALITY | SLAP_MR_EXT,
3957 integerFirstComponentMatch, NULL, NULL,
3960 {"( 2.5.13.30 NAME 'objectIdentifierFirstComponentMatch' "
3961 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
3962 SLAP_MR_EQUALITY | SLAP_MR_EXT,
3964 objectIdentifierFirstComponentMatch, NULL, NULL,
3967 {"( 1.3.6.1.4.1.1466.109.114.1 NAME 'caseExactIA5Match' "
3968 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
3969 SLAP_MR_EQUALITY | SLAP_MR_EXT,
3971 caseExactIA5Match, caseExactIA5Indexer, caseExactIA5Filter,
3972 IA5StringApproxMatchOID },
3974 {"( 1.3.6.1.4.1.1466.109.114.2 NAME 'caseIgnoreIA5Match' "
3975 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
3976 SLAP_MR_EQUALITY | SLAP_MR_EXT,
3978 caseIgnoreIA5Match, caseIgnoreIA5Indexer, caseIgnoreIA5Filter,
3979 IA5StringApproxMatchOID },
3981 {"( 1.3.6.1.4.1.1466.109.114.3 NAME 'caseIgnoreIA5SubstringsMatch' "
3982 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
3985 caseIgnoreIA5SubstringsMatch,
3986 caseIgnoreIA5SubstringsIndexer,
3987 caseIgnoreIA5SubstringsFilter,
3990 {"( 1.3.6.1.4.1.4203.1.2.1 NAME 'caseExactIA5SubstringsMatch' "
3991 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
3994 caseExactIA5SubstringsMatch,
3995 caseExactIA5SubstringsIndexer,
3996 caseExactIA5SubstringsFilter,
3999 {"( 1.3.6.1.4.1.4203.666.4.1 NAME 'authPasswordMatch' "
4000 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
4003 authPasswordMatch, NULL, NULL,
4006 {"( 1.3.6.1.4.1.4203.666.4.2 NAME 'OpenLDAPaciMatch' "
4007 "SYNTAX 1.3.6.1.4.1.4203.666.2.1 )",
4010 OpenLDAPaciMatch, NULL, NULL,
4013 {NULL, SLAP_MR_NONE, NULL, NULL, NULL, NULL}
4022 /* we should only be called once (from main) */
4023 assert( schema_init_done == 0 );
4025 for ( i=0; syntax_defs[i].sd_desc != NULL; i++ ) {
4026 res = register_syntax( syntax_defs[i].sd_desc,
4027 syntax_defs[i].sd_flags,
4028 syntax_defs[i].sd_validate,
4029 syntax_defs[i].sd_normalize,
4030 syntax_defs[i].sd_pretty
4031 #ifdef SLAPD_BINARY_CONVERSION
4033 syntax_defs[i].sd_ber2str,
4034 syntax_defs[i].sd_str2ber
4039 fprintf( stderr, "schema_init: Error registering syntax %s\n",
4040 syntax_defs[i].sd_desc );
4045 for ( i=0; mrule_defs[i].mrd_desc != NULL; i++ ) {
4046 if( mrule_defs[i].mrd_usage == SLAP_MR_NONE ) {
4048 "schema_init: Ingoring unusable matching rule %s\n",
4049 mrule_defs[i].mrd_desc );
4053 res = register_matching_rule(
4054 mrule_defs[i].mrd_desc,
4055 mrule_defs[i].mrd_usage,
4056 mrule_defs[i].mrd_convert,
4057 mrule_defs[i].mrd_normalize,
4058 mrule_defs[i].mrd_match,
4059 mrule_defs[i].mrd_indexer,
4060 mrule_defs[i].mrd_filter,
4061 mrule_defs[i].mrd_associated );
4065 "schema_init: Error registering matching rule %s\n",
4066 mrule_defs[i].mrd_desc );
4070 schema_init_done = 1;
4071 return LDAP_SUCCESS;