- normalized->bv_val[normalized->bv_len] = '\0';
-
-done:
- return LDAP_SUCCESS;
-}
-
-/*
- * Handling boolean syntax and matching is quite rigid.
- * A more flexible approach would be to allow a variety
- * of strings to be normalized and prettied into TRUE
- * and FALSE.
- */
-static int
-booleanValidate(
- Syntax *syntax,
- struct berval *in )
-{
- /* very unforgiving validation, requires no normalization
- * before simplistic matching
- */
-
- if( in->bv_len == 4 ) {
- if( !memcmp( in->bv_val, "TRUE", 4 ) ) {
- return LDAP_SUCCESS;
- }
- } else if( in->bv_len == 5 ) {
- if( !memcmp( in->bv_val, "FALSE", 5 ) ) {
- return LDAP_SUCCESS;
- }
- }
-
- return LDAP_INVALID_SYNTAX;
-}
-
-static int
-booleanMatch(
- int *matchp,
- slap_mask_t flags,
- Syntax *syntax,
- MatchingRule *mr,
- struct berval *value,
- void *assertedValue )
-{
- /* simplistic matching allowed by rigid validation */
- struct berval *asserted = (struct berval *) assertedValue;
- *matchp = value->bv_len != asserted->bv_len;
- return LDAP_SUCCESS;
-}
-
-static int
-UTF8StringValidate(
- Syntax *syntax,
- struct berval *in )
-{
- ber_len_t count;
- int len;
- unsigned char *u = in->bv_val;
-
- if( !in->bv_len ) return LDAP_INVALID_SYNTAX;
-
- for( count = in->bv_len; count > 0; count-=len, u+=len ) {
- /* get the length indicated by the first byte */
- len = LDAP_UTF8_CHARLEN2( u, len );
-
- /* very basic checks */
- switch( len ) {
- case 6:
- if( (u[5] & 0xC0) != 0x80 ) {
- return LDAP_INVALID_SYNTAX;
- }
- case 5:
- if( (u[4] & 0xC0) != 0x80 ) {
- return LDAP_INVALID_SYNTAX;
- }
- case 4:
- if( (u[3] & 0xC0) != 0x80 ) {
- return LDAP_INVALID_SYNTAX;
- }
- case 3:
- if( (u[2] & 0xC0 )!= 0x80 ) {
- return LDAP_INVALID_SYNTAX;
- }
- case 2:
- if( (u[1] & 0xC0) != 0x80 ) {
- return LDAP_INVALID_SYNTAX;
- }
- case 1:
- /* CHARLEN already validated it */
- break;
- default:
- return LDAP_INVALID_SYNTAX;
- }
-
- /* make sure len corresponds with the offset
- to the next character */
- if( LDAP_UTF8_OFFSET( u ) != len ) return LDAP_INVALID_SYNTAX;
- }
-
- if( count != 0 ) return LDAP_INVALID_SYNTAX;
-
- return LDAP_SUCCESS;
-}
-
-static int
-UTF8StringNormalize(
- Syntax *syntax,
- struct berval *val,
- struct berval *normalized )
-{
- char *p, *q, *s, *e;
- int len = 0;
-
- p = val->bv_val;
-
- /* Ignore initial whitespace */
- /* All space is ASCII. All ASCII is 1 byte */
- for ( ; p < val->bv_val + val->bv_len && ASCII_SPACE( p[ 0 ] ); p++ );
-
- ber_mem2bv( p, val->bv_len - (p - val->bv_val), 1, normalized );
- e = normalized->bv_val + val->bv_len - (p - val->bv_val);
-
- assert( normalized->bv_val );
-
- p = q = normalized->bv_val;
- s = NULL;
-
- while ( p < e ) {
- q += len;
- if ( ASCII_SPACE( *p ) ) {
- s = q - len;
- len = 1;
- *q = *p++;
-
- /* Ignore the extra whitespace */
- while ( ASCII_SPACE( *p ) ) {
- p++;
- }
- } else {
- len = LDAP_UTF8_COPY(q,p);
- s=NULL;
- p+=len;
- }
- }
-
- assert( normalized->bv_val < p );
- assert( q+len <= p );
-
- /* cannot start with a space */
- assert( !ASCII_SPACE(normalized->bv_val[0]) );
-
- /*
- * If the string ended in space, backup the pointer one
- * position. One is enough because the above loop collapsed
- * all whitespace to a single space.
- */
-
- if ( s != NULL ) {
- len = q - s;
- q = s;
- }
-
- /* cannot end with a space */
- assert( !ASCII_SPACE( *q ) );
-
- q += len;
-
- /* null terminate */
- *q = '\0';
-
- normalized->bv_len = q - normalized->bv_val;
-
- return LDAP_SUCCESS;
-}
-
-/* Returns Unicode canonically normalized copy of a substring assertion
- * Skipping attribute description */
-static SubstringsAssertion *
-UTF8SubstringsassertionNormalize(
- SubstringsAssertion *sa,
- unsigned casefold )
-{
- SubstringsAssertion *nsa;
- int i;
-
- nsa = (SubstringsAssertion *)ch_calloc( 1, sizeof(SubstringsAssertion) );
- if( nsa == NULL ) {
- return NULL;
- }
-
- if( sa->sa_initial.bv_val != NULL ) {
- UTF8bvnormalize( &sa->sa_initial, &nsa->sa_initial, casefold );
- if( nsa->sa_initial.bv_val == NULL ) {
- goto err;
- }
- }
-
- if( sa->sa_any != NULL ) {
- for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
- /* empty */
- }
- nsa->sa_any = (struct berval *)ch_malloc( (i + 1) * sizeof(struct berval) );
- for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
- UTF8bvnormalize( &sa->sa_any[i], &nsa->sa_any[i],
- casefold );
- if( nsa->sa_any[i].bv_val == NULL ) {
- goto err;
- }
- }
- nsa->sa_any[i].bv_val = NULL;
- }
-
- if( sa->sa_final.bv_val != NULL ) {
- UTF8bvnormalize( &sa->sa_final, &nsa->sa_final, casefold );
- if( nsa->sa_final.bv_val == NULL ) {
- goto err;
- }
- }
-
- return nsa;
-
-err:
- if ( nsa->sa_final.bv_val ) free( nsa->sa_final.bv_val );
- if ( nsa->sa_any )ber_bvarray_free( nsa->sa_any );
- if ( nsa->sa_initial.bv_val ) free( nsa->sa_initial.bv_val );
- ch_free( nsa );
- return NULL;
-}
-
-/* Strip characters with the 8th bit set */
-static char *
-strip8bitChars(
- char *in )
-{
- char *p = in, *q;
-
- if( in == NULL ) {
- return NULL;
- }
- while( *p ) {
- if( *p & 0x80 ) {
- q = p;
- while( *++q & 0x80 ) {
- /* empty */
- }
- p = AC_MEMCPY(p, q, strlen(q) + 1);
- } else {
- p++;
- }
- }
- return in;
-}
-
-#ifndef SLAPD_APPROX_OLDSINGLESTRING
-
-#if defined(SLAPD_APPROX_INITIALS)
-#define SLAPD_APPROX_DELIMITER "._ "
-#define SLAPD_APPROX_WORDLEN 2
-#else
-#define SLAPD_APPROX_DELIMITER " "
-#define SLAPD_APPROX_WORDLEN 1
-#endif
-
-static int
-approxMatch(
- int *matchp,
- slap_mask_t flags,
- Syntax *syntax,
- MatchingRule *mr,
- struct berval *value,
- void *assertedValue )
-{
- char *val, *nval, *assertv, **values, **words, *c;
- int i, count, len, nextchunk=0, nextavail=0;
- size_t avlen;
-
- /* Yes, this is necessary */
- nval = UTF8normalize( value, LDAP_UTF8_NOCASEFOLD );
- if( nval == NULL ) {
- *matchp = 1;
- return LDAP_SUCCESS;
- }
- strip8bitChars( nval );
-
- /* Yes, this is necessary */
- assertv = UTF8normalize( ((struct berval *)assertedValue),
- LDAP_UTF8_NOCASEFOLD );
- if( assertv == NULL ) {
- ch_free( nval );
- *matchp = 1;
- return LDAP_SUCCESS;
- }
- strip8bitChars( assertv );
- avlen = strlen( assertv );
-
- /* Isolate how many words there are */
- for( c=nval,count=1; *c; c++ ) {
- c = strpbrk( c, SLAPD_APPROX_DELIMITER );
- if ( c == NULL ) break;
- *c = '\0';
- count++;
- }
-
- /* Get a phonetic copy of each word */
- words = (char **)ch_malloc( count * sizeof(char *) );
- values = (char **)ch_malloc( count * sizeof(char *) );
- for( c=nval,i=0; i<count; i++,c+=strlen(c)+1 ) {
- words[i] = c;
- values[i] = phonetic(c);
- }
-
- /* Work through the asserted value's words, to see if at least some
- of the words are there, in the same order. */
- len = 0;
- while ( (size_t) nextchunk < avlen ) {
- len = strcspn( assertv + nextchunk, SLAPD_APPROX_DELIMITER);
- if( len == 0 ) {
- nextchunk++;
- continue;
- }
-#if defined(SLAPD_APPROX_INITIALS)
- else if( len == 1 ) {
- /* Single letter words need to at least match one word's initial */
- for( i=nextavail; i<count; i++ )
- if( !strncasecmp( assertv+nextchunk, words[i], 1 )) {
- nextavail=i+1;
- break;
- }
- }
-#endif
- else {
- /* Isolate the next word in the asserted value and phonetic it */
- assertv[nextchunk+len] = '\0';
- val = phonetic( assertv + nextchunk );
-
- /* See if this phonetic chunk is in the remaining words of *value */
- for( i=nextavail; i<count; i++ ){
- if( !strcmp( val, values[i] ) ){
- nextavail = i+1;
- break;
- }
- }
- ch_free( val );
- }
-
- /* This chunk in the asserted value was NOT within the *value. */
- if( i >= count ) {
- nextavail=-1;
- break;
- }
-
- /* Go on to the next word in the asserted value */
- nextchunk += len+1;
- }
-
- /* If some of the words were seen, call it a match */
- if( nextavail > 0 ) {
- *matchp = 0;
- }
- else {
- *matchp = 1;
- }
-
- /* Cleanup allocs */
- free( assertv );
- for( i=0; i<count; i++ ) {
- ch_free( values[i] );
- }
- ch_free( values );
- ch_free( words );
- ch_free( nval );
-
- return LDAP_SUCCESS;
-}
-
-static int
-approxIndexer(
- slap_mask_t use,
- slap_mask_t flags,
- Syntax *syntax,
- MatchingRule *mr,
- struct berval *prefix,
- BerVarray values,
- BerVarray *keysp )
-{
- char *val, *c;
- int i,j, len, wordcount, keycount=0;
- struct berval *newkeys;
- BerVarray keys=NULL;
-
- for( j=0; values[j].bv_val != NULL; j++ ) {
- /* Yes, this is necessary */
- val = UTF8normalize( &values[j], LDAP_UTF8_NOCASEFOLD );
- strip8bitChars( val );
-
- /* Isolate how many words there are. There will be a key for each */
- for( wordcount=0,c=val; *c; c++) {
- len = strcspn(c, SLAPD_APPROX_DELIMITER);
- if( len >= SLAPD_APPROX_WORDLEN ) wordcount++;
- c+= len;
- if (*c == '\0') break;
- *c = '\0';
- }
-
- /* Allocate/increase storage to account for new keys */
- newkeys = (struct berval *)ch_malloc( (keycount + wordcount + 1)
- * sizeof(struct berval) );
- AC_MEMCPY( newkeys, keys, keycount * sizeof(struct berval) );
- if( keys ) ch_free( keys );
- keys = newkeys;
-
- /* Get a phonetic copy of each word */
- for( c=val,i=0; i<wordcount; c+=len+1 ) {
- len = strlen( c );
- if( len < SLAPD_APPROX_WORDLEN ) continue;
- ber_str2bv( phonetic( c ), 0, 0, &keys[keycount] );
- keycount++;
- i++;
- }
-
- free( val );
- }
- keys[keycount].bv_val = NULL;
- *keysp = keys;
-
- return LDAP_SUCCESS;
-}
-
-static int
-approxFilter(
- slap_mask_t use,
- slap_mask_t flags,
- Syntax *syntax,
- MatchingRule *mr,
- struct berval *prefix,
- void * assertValue,
- BerVarray *keysp )
-{
- char *val, *c;
- int i, count, len;
- BerVarray keys;
-
- /* Yes, this is necessary */
- val = UTF8normalize( ((struct berval *)assertValue),
- LDAP_UTF8_NOCASEFOLD );
- if( val == NULL ) {
- keys = (struct berval *)ch_malloc( sizeof(struct berval) );
- keys[0].bv_val = NULL;
- *keysp = keys;
- return LDAP_SUCCESS;
- }
- strip8bitChars( val );
-
- /* Isolate how many words there are. There will be a key for each */
- for( count=0,c=val; *c; c++) {
- len = strcspn(c, SLAPD_APPROX_DELIMITER);
- if( len >= SLAPD_APPROX_WORDLEN ) count++;
- c+= len;
- if (*c == '\0') break;
- *c = '\0';
- }
-
- /* Allocate storage for new keys */
- keys = (struct berval *)ch_malloc( (count + 1) * sizeof(struct berval) );
-
- /* Get a phonetic copy of each word */
- for( c=val,i=0; i<count; c+=len+1 ) {
- len = strlen(c);
- if( len < SLAPD_APPROX_WORDLEN ) continue;
- ber_str2bv( phonetic( c ), 0, 0, &keys[i] );
- i++;
- }
-
- free( val );
-
- keys[count].bv_val = NULL;
- *keysp = keys;
-
- return LDAP_SUCCESS;
-}
-
-
-#else
-/* No other form of Approximate Matching is defined */
-
-static int
-approxMatch(
- int *matchp,
- slap_mask_t flags,
- Syntax *syntax,
- MatchingRule *mr,
- struct berval *value,
- void *assertedValue )
-{
- char *vapprox, *avapprox;
- char *s, *t;
-
- /* Yes, this is necessary */
- s = UTF8normalize( value, UTF8_NOCASEFOLD );
- if( s == NULL ) {
- *matchp = 1;
- return LDAP_SUCCESS;
- }
-
- /* Yes, this is necessary */
- t = UTF8normalize( ((struct berval *)assertedValue),
- UTF8_NOCASEFOLD );
- if( t == NULL ) {
- free( s );
- *matchp = -1;
- return LDAP_SUCCESS;
- }
-
- vapprox = phonetic( strip8bitChars( s ) );
- avapprox = phonetic( strip8bitChars( t ) );
-
- free( s );
- free( t );
-
- *matchp = strcmp( vapprox, avapprox );
-
- ch_free( vapprox );
- ch_free( avapprox );
-
- return LDAP_SUCCESS;
-}
-
-static int
-approxIndexer(
- slap_mask_t use,
- slap_mask_t flags,
- Syntax *syntax,
- MatchingRule *mr,
- struct berval *prefix,
- BerVarray values,
- BerVarray *keysp )
-{
- int i;
- BerVarray *keys;
- char *s;
-
- for( i=0; values[i].bv_val != NULL; i++ ) {
- /* empty - just count them */
- }
-
- /* we should have at least one value at this point */
- assert( i > 0 );
-
- keys = (struct berval *)ch_malloc( sizeof( struct berval ) * (i+1) );
-
- /* Copy each value and run it through phonetic() */
- for( i=0; values[i].bv_val != NULL; i++ ) {
- /* Yes, this is necessary */
- s = UTF8normalize( &values[i], UTF8_NOCASEFOLD );
-
- /* strip 8-bit chars and run through phonetic() */
- ber_str2bv( phonetic( strip8bitChars( s ) ), 0, 0, &keys[i] );
- free( s );
- }
- keys[i].bv_val = NULL;
-
- *keysp = keys;
- return LDAP_SUCCESS;
-}
-
-
-static int
-approxFilter(
- slap_mask_t use,
- slap_mask_t flags,
- Syntax *syntax,
- MatchingRule *mr,
- struct berval *prefix,
- void * assertValue,
- BerVarray *keysp )
-{
- BerVarray keys;
- char *s;
-
- keys = (struct berval *)ch_malloc( sizeof( struct berval * ) * 2 );
-
- /* Yes, this is necessary */
- s = UTF8normalize( ((struct berval *)assertValue),
- UTF8_NOCASEFOLD );
- if( s == NULL ) {
- keys[0] = NULL;
- } else {
- /* strip 8-bit chars and run through phonetic() */
- keys[0] = ber_bvstr( phonetic( strip8bitChars( s ) ) );
- free( s );
- keys[1] = NULL;
- }
-
- *keysp = keys;
- return LDAP_SUCCESS;
-}
-#endif
-
-
-static int
-caseExactMatch(
- int *matchp,
- slap_mask_t flags,
- Syntax *syntax,
- MatchingRule *mr,
- struct berval *value,
- void *assertedValue )
-{
- *matchp = UTF8normcmp( value->bv_val,
- ((struct berval *) assertedValue)->bv_val,
- LDAP_UTF8_NOCASEFOLD );
- return LDAP_SUCCESS;
-}
-
-static int
-caseExactIgnoreSubstringsMatch(
- int *matchp,
- slap_mask_t flags,
- Syntax *syntax,
- MatchingRule *mr,
- struct berval *value,
- void *assertedValue )
-{
- int match = 0;
- SubstringsAssertion *sub = NULL;
- struct berval left = { 0, NULL };
- int i;
- ber_len_t inlen=0;
- char *nav = NULL;
- unsigned casefold;
-
- casefold = strcmp( mr->smr_oid, caseExactSubstringsMatchOID )
- ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
-
- if ( UTF8bvnormalize( value, &left, casefold ) == NULL ) {
- match = 1;
- goto done;
- }
- nav = left.bv_val;
-
- sub = UTF8SubstringsassertionNormalize( assertedValue, casefold );
- if( sub == NULL ) {
- match = -1;
- goto done;
- }
-
- /* Add up asserted input length */
- if( sub->sa_initial.bv_val ) {
- inlen += sub->sa_initial.bv_len;
- }
- if( sub->sa_any ) {
- for(i=0; sub->sa_any[i].bv_val != NULL; i++) {
- inlen += sub->sa_any[i].bv_len;
- }
- }
- if( sub->sa_final.bv_val ) {
- inlen += sub->sa_final.bv_len;
- }
-
- if( sub->sa_initial.bv_val ) {
- if( inlen > left.bv_len ) {
- match = 1;
- goto done;
- }
-
- match = memcmp( sub->sa_initial.bv_val, left.bv_val,
- sub->sa_initial.bv_len );
-
- if( match != 0 ) {
- goto done;
- }
-
- left.bv_val += sub->sa_initial.bv_len;
- left.bv_len -= sub->sa_initial.bv_len;
- inlen -= sub->sa_initial.bv_len;
- }
-
- if( sub->sa_final.bv_val ) {
- if( inlen > left.bv_len ) {
- match = 1;
- goto done;
- }
-
- match = memcmp( sub->sa_final.bv_val,
- &left.bv_val[left.bv_len - sub->sa_final.bv_len],
- sub->sa_final.bv_len );
-
- if( match != 0 ) {
- goto done;
- }
-
- left.bv_len -= sub->sa_final.bv_len;
- inlen -= sub->sa_final.bv_len;
- }
-
- if( sub->sa_any ) {
- for(i=0; sub->sa_any[i].bv_val; i++) {
- ber_len_t idx;
- char *p;
-
-retry:
- if( inlen > left.bv_len ) {
- /* not enough length */
- match = 1;
- goto done;
- }
-
- if( sub->sa_any[i].bv_len == 0 ) {
- continue;
- }
-
- p = ber_bvchr( &left, *sub->sa_any[i].bv_val );
-
- if ( p == NULL ) {
- match = 1;
- goto done;
- }
-
- idx = p - left.bv_val;
-
- if( idx >= left.bv_len ) {
- /* this shouldn't happen */
- free( nav );
- if ( sub->sa_final.bv_val )
- ch_free( sub->sa_final.bv_val );
- if ( sub->sa_any )
- ber_bvarray_free( sub->sa_any );
- if ( sub->sa_initial.bv_val )
- ch_free( sub->sa_initial.bv_val );
- ch_free( sub );
- return LDAP_OTHER;
- }
-
- left.bv_val = p;
- left.bv_len -= idx;
-
- if( sub->sa_any[i].bv_len > left.bv_len ) {
- /* not enough left */
- match = 1;
- goto done;
- }
-
- match = memcmp( left.bv_val,
- sub->sa_any[i].bv_val,
- sub->sa_any[i].bv_len );
-
- if( match != 0 ) {
- left.bv_val++;
- left.bv_len--;
- goto retry;
- }
-
- left.bv_val += sub->sa_any[i].bv_len;
- left.bv_len -= sub->sa_any[i].bv_len;
- inlen -= sub->sa_any[i].bv_len;
- }
- }
-
-done:
- free( nav );
- if( sub != NULL ) {
- if ( sub->sa_final.bv_val ) free( sub->sa_final.bv_val );
- if ( sub->sa_any ) ber_bvarray_free( sub->sa_any );
- if ( sub->sa_initial.bv_val ) free( sub->sa_initial.bv_val );
- ch_free( sub );
- }
- *matchp = match;
- return LDAP_SUCCESS;
-}
-
-/* Index generation function */
-static int caseExactIgnoreIndexer(
- slap_mask_t use,
- slap_mask_t flags,
- Syntax *syntax,
- MatchingRule *mr,
- struct berval *prefix,
- BerVarray values,
- BerVarray *keysp )
-{
- int i;
- unsigned casefold;
- size_t slen, mlen;
- BerVarray keys;
- HASH_CONTEXT HASHcontext;
- unsigned char HASHdigest[HASH_BYTES];
- struct berval digest;
- digest.bv_val = HASHdigest;
- digest.bv_len = sizeof(HASHdigest);
-
- for( i=0; values[i].bv_val != NULL; i++ ) {
- /* empty - just count them */
- }
-
- /* we should have at least one value at this point */
- assert( i > 0 );
-
- keys = ch_malloc( sizeof( struct berval ) * (i+1) );
-
- slen = syntax->ssyn_oidlen;
- mlen = mr->smr_oidlen;
-
- casefold = strcmp( mr->smr_oid, caseExactMatchOID )
- ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
-
- for( i=0; values[i].bv_val != NULL; i++ ) {
- struct berval value;
- ber_str2bv( UTF8normalize( &values[i], casefold ), 0, 0,
- &value );
-
- HASH_Init( &HASHcontext );
- if( prefix != NULL && prefix->bv_len > 0 ) {
- HASH_Update( &HASHcontext,
- prefix->bv_val, prefix->bv_len );
- }
- HASH_Update( &HASHcontext,
- syntax->ssyn_oid, slen );
- HASH_Update( &HASHcontext,
- mr->smr_oid, mlen );
- HASH_Update( &HASHcontext,
- value.bv_val, value.bv_len );
- HASH_Final( HASHdigest, &HASHcontext );
-
- free( value.bv_val );
-
- ber_dupbv( &keys[i], &digest );
- }
-
- keys[i].bv_val = NULL;
- *keysp = keys;
- return LDAP_SUCCESS;
-}
-
-/* Index generation function */
-static int caseExactIgnoreFilter(
- slap_mask_t use,
- slap_mask_t flags,
- Syntax *syntax,
- MatchingRule *mr,
- struct berval *prefix,
- void * assertValue,
- BerVarray *keysp )
-{
- unsigned casefold;
- size_t slen, mlen;
- BerVarray keys;
- HASH_CONTEXT HASHcontext;
- unsigned char HASHdigest[HASH_BYTES];
- struct berval value;
- struct berval digest;
- digest.bv_val = HASHdigest;
- digest.bv_len = sizeof(HASHdigest);
-
- slen = syntax->ssyn_oidlen;
- mlen = mr->smr_oidlen;
-
- casefold = strcmp( mr->smr_oid, caseExactMatchOID )
- ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
-
- ber_str2bv( UTF8normalize( ((struct berval *) assertValue), casefold ),
- 0, 0, &value );
- /* This usually happens if filter contains bad UTF8 */
- if( value.bv_val == NULL ) {
- keys = ch_malloc( sizeof( struct berval ) );
- keys[0].bv_val = NULL;
- return LDAP_SUCCESS;
- }
-
- keys = ch_malloc( sizeof( struct berval ) * 2 );
-
- HASH_Init( &HASHcontext );
- if( prefix != NULL && prefix->bv_len > 0 ) {
- HASH_Update( &HASHcontext,
- prefix->bv_val, prefix->bv_len );
- }
- HASH_Update( &HASHcontext,
- syntax->ssyn_oid, slen );
- HASH_Update( &HASHcontext,
- mr->smr_oid, mlen );
- HASH_Update( &HASHcontext,
- value.bv_val, value.bv_len );
- HASH_Final( HASHdigest, &HASHcontext );
-
- ber_dupbv( keys, &digest );
- keys[1].bv_val = NULL;
-
- free( value.bv_val );
-
- *keysp = keys;
- return LDAP_SUCCESS;
-}
-
-/* Substrings Index generation function */
-static int caseExactIgnoreSubstringsIndexer(
- slap_mask_t use,
- slap_mask_t flags,
- Syntax *syntax,
- MatchingRule *mr,
- struct berval *prefix,
- BerVarray values,
- BerVarray *keysp )
-{
- unsigned casefold;
- ber_len_t i, nkeys;
- size_t slen, mlen;
- BerVarray keys;
- BerVarray nvalues;
-
- HASH_CONTEXT HASHcontext;
- unsigned char HASHdigest[HASH_BYTES];
- struct berval digest;
- digest.bv_val = HASHdigest;
- digest.bv_len = sizeof(HASHdigest);
-
- nkeys=0;
-
- for( i=0; values[i].bv_val != NULL; i++ ) {
- /* empty - just count them */
- }
-
- /* we should have at least one value at this point */
- assert( i > 0 );
-
- casefold = strcmp( mr->smr_oid, caseExactSubstringsMatchOID )
- ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
-
- nvalues = ch_malloc( sizeof( struct berval ) * (i+1) );
- for( i=0; values[i].bv_val != NULL; i++ ) {
- ber_str2bv( UTF8normalize( &values[i], casefold ),
- 0, 0, &nvalues[i] );
- }
- nvalues[i].bv_val = NULL;
- values = nvalues;
-
- for( i=0; values[i].bv_val != NULL; i++ ) {
- /* count number of indices to generate */
- if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
- continue;
- }
-
- if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
- if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
- nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
- ( SLAP_INDEX_SUBSTR_MINLEN - 1);
- } else {
- nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
- }
- }
-
- if( flags & SLAP_INDEX_SUBSTR_ANY ) {
- if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
- nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
- }
- }
-
- if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
- if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
- nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
- ( SLAP_INDEX_SUBSTR_MINLEN - 1);
- } else {
- nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
- }
- }
- }
-
- if( nkeys == 0 ) {
- /* no keys to generate */
- *keysp = NULL;
- ber_bvarray_free( nvalues );
- return LDAP_SUCCESS;
- }
-
- keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
-
- slen = syntax->ssyn_oidlen;
- mlen = mr->smr_oidlen;
-
- nkeys=0;
- for( i=0; values[i].bv_val != NULL; i++ ) {
- ber_len_t j,max;
-
- if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
-
- if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
- ( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
- {
- char pre = SLAP_INDEX_SUBSTR_PREFIX;
- max = values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
-
- for( j=0; j<max; j++ ) {
- HASH_Init( &HASHcontext );
- if( prefix != NULL && prefix->bv_len > 0 ) {
- HASH_Update( &HASHcontext,
- prefix->bv_val, prefix->bv_len );
- }
-
- HASH_Update( &HASHcontext,
- &pre, sizeof( pre ) );
- HASH_Update( &HASHcontext,
- syntax->ssyn_oid, slen );
- HASH_Update( &HASHcontext,
- mr->smr_oid, mlen );
- HASH_Update( &HASHcontext,
- &values[i].bv_val[j],
- SLAP_INDEX_SUBSTR_MAXLEN );
- HASH_Final( HASHdigest, &HASHcontext );
-
- ber_dupbv( &keys[nkeys++], &digest );
- }
- }
-
- max = SLAP_INDEX_SUBSTR_MAXLEN < values[i].bv_len
- ? SLAP_INDEX_SUBSTR_MAXLEN : values[i].bv_len;
-
- for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
- char pre;
-
- if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
- pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
- HASH_Init( &HASHcontext );
- if( prefix != NULL && prefix->bv_len > 0 ) {
- HASH_Update( &HASHcontext,
- prefix->bv_val, prefix->bv_len );
- }
- HASH_Update( &HASHcontext,
- &pre, sizeof( pre ) );
- HASH_Update( &HASHcontext,
- syntax->ssyn_oid, slen );
- HASH_Update( &HASHcontext,
- mr->smr_oid, mlen );
- HASH_Update( &HASHcontext,
- values[i].bv_val, j );
- HASH_Final( HASHdigest, &HASHcontext );
-
- ber_dupbv( &keys[nkeys++], &digest );
- }
-
- if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
- pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
- HASH_Init( &HASHcontext );
- if( prefix != NULL && prefix->bv_len > 0 ) {
- HASH_Update( &HASHcontext,
- prefix->bv_val, prefix->bv_len );
- }
- HASH_Update( &HASHcontext,
- &pre, sizeof( pre ) );
- HASH_Update( &HASHcontext,
- syntax->ssyn_oid, slen );
- HASH_Update( &HASHcontext,
- mr->smr_oid, mlen );
- HASH_Update( &HASHcontext,
- &values[i].bv_val[values[i].bv_len-j], j );
- HASH_Final( HASHdigest, &HASHcontext );
-
- ber_dupbv( &keys[nkeys++], &digest );
- }
-
- }
-
- }
-
- if( nkeys > 0 ) {
- keys[nkeys].bv_val = NULL;
- *keysp = keys;
- } else {
- ch_free( keys );
- *keysp = NULL;
- }
-
- ber_bvarray_free( nvalues );
-
- return LDAP_SUCCESS;
-}
-
-static int caseExactIgnoreSubstringsFilter(
- slap_mask_t use,
- slap_mask_t flags,
- Syntax *syntax,
- MatchingRule *mr,
- struct berval *prefix,
- void * assertValue,
- BerVarray *keysp )
-{
- SubstringsAssertion *sa;
- char pre;
- unsigned casefold;
- ber_len_t nkeys = 0;
- size_t slen, mlen, klen;
- BerVarray keys;
- HASH_CONTEXT HASHcontext;
- unsigned char HASHdigest[HASH_BYTES];
- struct berval *value;
- struct berval digest;
-
- casefold = strcmp( mr->smr_oid, caseExactSubstringsMatchOID )
- ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
-
- sa = UTF8SubstringsassertionNormalize( assertValue, casefold );
- if( sa == NULL ) {
- *keysp = NULL;
- return LDAP_SUCCESS;
- }
-
- if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
- sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
- {
- nkeys++;
- }
-
- if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
- ber_len_t i;
- for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
- if( sa->sa_any[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
- /* don't bother accounting for stepping */
- nkeys += sa->sa_any[i].bv_len -
- ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
- }
- }
- }
-
- if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
- sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
- {
- nkeys++;
- }
-
- if( nkeys == 0 ) {
- if ( sa->sa_final.bv_val ) free( sa->sa_final.bv_val );
- if ( sa->sa_any ) ber_bvarray_free( sa->sa_any );
- if ( sa->sa_initial.bv_val ) free( sa->sa_initial.bv_val );
- ch_free( sa );
- *keysp = NULL;
- return LDAP_SUCCESS;
- }
-
- digest.bv_val = HASHdigest;
- digest.bv_len = sizeof(HASHdigest);
-
- slen = syntax->ssyn_oidlen;
- mlen = mr->smr_oidlen;
-
- keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
- nkeys = 0;
-
- if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
- sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
- {
- pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
- value = &sa->sa_initial;
-
- klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
- ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
-
- HASH_Init( &HASHcontext );
- if( prefix != NULL && prefix->bv_len > 0 ) {
- HASH_Update( &HASHcontext,
- prefix->bv_val, prefix->bv_len );
- }
- HASH_Update( &HASHcontext,
- &pre, sizeof( pre ) );
- HASH_Update( &HASHcontext,
- syntax->ssyn_oid, slen );
- HASH_Update( &HASHcontext,
- mr->smr_oid, mlen );
- HASH_Update( &HASHcontext,
- value->bv_val, klen );
- HASH_Final( HASHdigest, &HASHcontext );
-
- ber_dupbv( &keys[nkeys++], &digest );
- }
-
- if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
- ber_len_t i, j;
- pre = SLAP_INDEX_SUBSTR_PREFIX;
- klen = SLAP_INDEX_SUBSTR_MAXLEN;
-
- for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
- if( sa->sa_any[i].bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
- continue;
- }
-
- value = &sa->sa_any[i];
-
- for(j=0;
- j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
- j += SLAP_INDEX_SUBSTR_STEP )
- {
- HASH_Init( &HASHcontext );
- if( prefix != NULL && prefix->bv_len > 0 ) {
- HASH_Update( &HASHcontext,
- prefix->bv_val, prefix->bv_len );
- }
- HASH_Update( &HASHcontext,
- &pre, sizeof( pre ) );
- HASH_Update( &HASHcontext,
- syntax->ssyn_oid, slen );
- HASH_Update( &HASHcontext,
- mr->smr_oid, mlen );
- HASH_Update( &HASHcontext,
- &value->bv_val[j], klen );
- HASH_Final( HASHdigest, &HASHcontext );
-
- ber_dupbv( &keys[nkeys++], &digest );
- }
-
- }
- }
-
- if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
- sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
- {
- pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
- value = &sa->sa_final;
-
- klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
- ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
-
- HASH_Init( &HASHcontext );
- if( prefix != NULL && prefix->bv_len > 0 ) {
- HASH_Update( &HASHcontext,
- prefix->bv_val, prefix->bv_len );
- }
- HASH_Update( &HASHcontext,
- &pre, sizeof( pre ) );
- HASH_Update( &HASHcontext,
- syntax->ssyn_oid, slen );
- HASH_Update( &HASHcontext,
- mr->smr_oid, mlen );
- HASH_Update( &HASHcontext,
- &value->bv_val[value->bv_len-klen], klen );
- HASH_Final( HASHdigest, &HASHcontext );
-
- ber_dupbv( &keys[nkeys++], &digest );
- }
-
- if( nkeys > 0 ) {
- keys[nkeys].bv_val = NULL;
- *keysp = keys;
- } else {
- ch_free( keys );
- *keysp = NULL;
- }
- if ( sa->sa_final.bv_val ) free( sa->sa_final.bv_val );
- if ( sa->sa_any ) ber_bvarray_free( sa->sa_any );
- if ( sa->sa_initial.bv_val ) free( sa->sa_initial.bv_val );
- ch_free( sa );
-
- return LDAP_SUCCESS;
-}
-
-static int
-caseIgnoreMatch(
- int *matchp,
- slap_mask_t flags,
- Syntax *syntax,
- MatchingRule *mr,
- struct berval *value,
- void *assertedValue )
-{
- *matchp = UTF8normcmp( value->bv_val,
- ((struct berval *) assertedValue)->bv_val,
- LDAP_UTF8_CASEFOLD );
- return LDAP_SUCCESS;
-}
-
-static int
-oidValidate(
- Syntax *syntax,
- struct berval *val )
-{
- ber_len_t i;
-
- if( val->bv_len == 0 ) {
- /* disallow empty strings */
- return LDAP_INVALID_SYNTAX;
- }
-
- if( OID_LEADCHAR(val->bv_val[0]) ) {
- int dot = 0;
- for(i=1; i < val->bv_len; i++) {
- if( OID_SEPARATOR( val->bv_val[i] ) ) {
- if( dot++ ) return 1;
- } else if ( OID_CHAR( val->bv_val[i] ) ) {
- dot = 0;
- } else {
- return LDAP_INVALID_SYNTAX;
- }
- }
-
- return !dot ? LDAP_SUCCESS : LDAP_INVALID_SYNTAX;
-
- } else if( DESC_LEADCHAR(val->bv_val[0]) ) {
- for(i=1; i < val->bv_len; i++) {
- if( !DESC_CHAR(val->bv_val[i] ) ) {
- return LDAP_INVALID_SYNTAX;
- }
- }
-
- return LDAP_SUCCESS;
- }
-
- return LDAP_INVALID_SYNTAX;
-}
-
-static int
-integerMatch(
- int *matchp,
- slap_mask_t flags,
- Syntax *syntax,
- MatchingRule *mr,
- struct berval *value,
- void *assertedValue )
-{
- char *v, *av;
- int vsign=0, avsign=0;
- struct berval *asserted;
- ber_len_t vlen, avlen;
-
-
- /* Start off pessimistic */
- *matchp = 1;
-
- /* Skip past leading spaces/zeros, and get the sign of the *value number */
- v = value->bv_val;
- vlen = value->bv_len;
- while( vlen ) {
- if( ASCII_SPACE(*v) || ( *v == '0' )) {
- /* empty -- skip spaces */
- }
- else if ( *v == '+' ) {
- vsign = 1;
- }
- else if ( *v == '-' ) {
- vsign = -1;
- }
- else if ( ASCII_DIGIT(*v) ) {
- if ( vsign == 0 ) vsign = 1;
- vsign *= 2;
- break;
- }
- v++;
- vlen--;
- }
-
- /* Skip past leading spaces/zeros, and get the sign of the *assertedValue
- number */
- asserted = (struct berval *) assertedValue;
- av = asserted->bv_val;
- avlen = asserted->bv_len;
- while( avlen ) {
- if( ASCII_SPACE(*av) || ( *av == '0' )) {
- /* empty -- skip spaces */
- }
- else if ( *av == '+' ) {
- avsign = 1;
- }
- else if ( *av == '-' ) {
- avsign = -1;
- }
- else if ( ASCII_DIGIT(*av) ) {
- if ( avsign == 0 ) avsign = 1;
- avsign *= 2;
- break;
- }
- av++;
- avlen--;
- }
-
- /* The two ?sign vars are now one of :
- -2 negative non-zero number
- -1 -0 \
- 0 0 collapse these three to 0
- +1 +0 /
- +2 positive non-zero number
- */
- if ( abs( vsign ) == 1 ) vsign = 0;
- if ( abs( avsign ) == 1 ) avsign = 0;
-
- if( vsign != avsign ) return LDAP_SUCCESS;
-
- /* Check the significant digits */
- while( vlen && avlen ) {
- if( *v != *av ) break;
- v++;
- vlen--;
- av++;
- avlen--;
- }
-
- /* If all digits compared equal, the numbers are equal */
- if(( vlen == 0 ) && ( avlen == 0 )) {
- *matchp = 0;
- }
- return LDAP_SUCCESS;
-}
-
-static int
-integerValidate(
- Syntax *syntax,
- struct berval *val )
-{
- ber_len_t i;
-
- if( !val->bv_len ) return LDAP_INVALID_SYNTAX;
-
- if(( val->bv_val[0] == '+' ) || ( val->bv_val[0] == '-' )) {
- if( val->bv_len < 2 ) return LDAP_INVALID_SYNTAX;
- } else if( !ASCII_DIGIT(val->bv_val[0]) ) {
- return LDAP_INVALID_SYNTAX;
- }
-
- for( i=1; i < val->bv_len; i++ ) {
- if( !ASCII_DIGIT(val->bv_val[i]) ) return LDAP_INVALID_SYNTAX;
- }
-
- return LDAP_SUCCESS;
-}
-
-static int
-integerNormalize(
- Syntax *syntax,
- struct berval *val,
- struct berval *normalized )
-{
- char *p;
- int negative=0;
- ber_len_t len;
-
-
- p = val->bv_val;
- len = val->bv_len;
-
- /* Ignore leading spaces */
- while ( len && ( *p == ' ' )) {
- p++;
- len--;
- }
-
- /* save sign */
- if( len ) {
- negative = ( *p == '-' );
- if(( *p == '-' ) || ( *p == '+' )) {
- p++;
- len--;
- }
- }
-
- /* Ignore leading zeros */
- while ( len && ( *p == '0' )) {
- p++;
- len--;
- }
-
- /* If there are no non-zero digits left, the number is zero, otherwise
- allocate space for the number and copy it into the buffer */
- if( len == 0 ) {
- normalized->bv_val = ch_strdup("0");
- normalized->bv_len = 1;
- }
- else {
- normalized->bv_len = len+negative;
- normalized->bv_val = ch_malloc( normalized->bv_len );
- if( negative ) {
- normalized->bv_val[0] = '-';
- }
- AC_MEMCPY( normalized->bv_val + negative, p, len );
- }
-
- return LDAP_SUCCESS;
-}
-
-/* Index generation function */
-static int integerIndexer(
- slap_mask_t use,
- slap_mask_t flags,
- Syntax *syntax,
- MatchingRule *mr,
- struct berval *prefix,
- BerVarray values,
- BerVarray *keysp )
-{
- int i;
- BerVarray keys;
-
- /* we should have at least one value at this point */
- assert( values != NULL && values[0].bv_val != NULL );
-
- for( i=0; values[i].bv_val != NULL; i++ ) {
- /* empty -- just count them */
- }
-
- keys = ch_malloc( sizeof( struct berval ) * (i+1) );
-
- for( i=0; values[i].bv_val != NULL; i++ ) {
- integerNormalize( syntax, &values[i], &keys[i] );
- }
-
- keys[i].bv_val = NULL;
- *keysp = keys;
- return LDAP_SUCCESS;
-}
-
-/* Index generation function */
-static int integerFilter(
- slap_mask_t use,
- slap_mask_t flags,
- Syntax *syntax,
- MatchingRule *mr,
- struct berval *prefix,
- void * assertValue,
- BerVarray *keysp )
-{
- BerVarray keys;
-
- keys = ch_malloc( sizeof( struct berval ) * 2 );
- integerNormalize( syntax, assertValue, &keys[0] );
- keys[1].bv_val = NULL;
- *keysp = keys;
-
- return LDAP_SUCCESS;
-}
-
-
-static int
-countryStringValidate(
- Syntax *syntax,
- struct berval *val )
-{
- if( val->bv_len != 2 ) return LDAP_INVALID_SYNTAX;
-
- if( !SLAP_PRINTABLE(val->bv_val[0]) ) {
- return LDAP_INVALID_SYNTAX;
- }
- if( !SLAP_PRINTABLE(val->bv_val[1]) ) {
- return LDAP_INVALID_SYNTAX;
- }
-
- return LDAP_SUCCESS;
-}
-
-static int
-printableStringValidate(
- Syntax *syntax,
- struct berval *val )
-{
- ber_len_t i;
-
- for(i=0; i < val->bv_len; i++) {
- if( !SLAP_PRINTABLE(val->bv_val[i]) ) {
- return LDAP_INVALID_SYNTAX;
- }
- }
-
- return LDAP_SUCCESS;
-}
-
-static int
-printablesStringValidate(
- Syntax *syntax,
- struct berval *val )
-{
- ber_len_t i;
-
- for(i=0; i < val->bv_len; i++) {
- if( !SLAP_PRINTABLES(val->bv_val[i]) ) {
- return LDAP_INVALID_SYNTAX;
- }
- }
-
- return LDAP_SUCCESS;
-}
-
-static int
-IA5StringValidate(
- Syntax *syntax,
- struct berval *val )
-{
- ber_len_t i;
-
- for(i=0; i < val->bv_len; i++) {
- if( !LDAP_ASCII(val->bv_val[i]) ) {
- return LDAP_INVALID_SYNTAX;
- }
- }
-
- return LDAP_SUCCESS;
-}
-
-static int
-IA5StringNormalize(
- Syntax *syntax,
- struct berval *val,
- struct berval *normalized )
-{
- char *p, *q;
-
- p = val->bv_val;
-
- /* Ignore initial whitespace */
- while ( ASCII_SPACE( *p ) ) {
- p++;
- }
-
- normalized->bv_val = ch_strdup( p );
- p = q = normalized->bv_val;
-
- while ( *p ) {
- if ( ASCII_SPACE( *p ) ) {
- *q++ = *p++;
-
- /* Ignore the extra whitespace */
- while ( ASCII_SPACE( *p ) ) {
- p++;
- }
- } else {
- *q++ = *p++;
- }
- }
-
- assert( normalized->bv_val <= p );
- assert( q <= p );
-
- /*
- * If the string ended in space, backup the pointer one
- * position. One is enough because the above loop collapsed
- * all whitespace to a single space.
- */
-
- if ( ASCII_SPACE( q[-1] ) ) {
- --q;
- }
-
- /* null terminate */
- *q = '\0';
-
- normalized->bv_len = q - normalized->bv_val;
-
- return LDAP_SUCCESS;
-}
-
-static int
-caseExactIA5Match(
- int *matchp,
- slap_mask_t flags,
- Syntax *syntax,
- MatchingRule *mr,
- struct berval *value,
- void *assertedValue )
-{
- int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
-
- if( match == 0 ) {
- match = strncmp( value->bv_val,
- ((struct berval *) assertedValue)->bv_val,
- value->bv_len );
- }
-
- *matchp = match;
- return LDAP_SUCCESS;
-}
-
-static int
-caseExactIA5SubstringsMatch(
- int *matchp,
- slap_mask_t flags,
- Syntax *syntax,
- MatchingRule *mr,
- struct berval *value,
- void *assertedValue )
-{
- int match = 0;
- SubstringsAssertion *sub = assertedValue;
- struct berval left = *value;
- int i;
- ber_len_t inlen=0;
-
- /* Add up asserted input length */
- if( sub->sa_initial.bv_val ) {
- inlen += sub->sa_initial.bv_len;
- }
- if( sub->sa_any ) {
- for(i=0; sub->sa_any[i].bv_val != NULL; i++) {
- inlen += sub->sa_any[i].bv_len;
- }
- }
- if( sub->sa_final.bv_val ) {
- inlen += sub->sa_final.bv_len;
- }
-
- if( sub->sa_initial.bv_val ) {
- if( inlen > left.bv_len ) {
- match = 1;
- goto done;
- }
-
- match = strncmp( sub->sa_initial.bv_val, left.bv_val,
- sub->sa_initial.bv_len );
-
- if( match != 0 ) {
- goto done;
- }
-
- left.bv_val += sub->sa_initial.bv_len;
- left.bv_len -= sub->sa_initial.bv_len;
- inlen -= sub->sa_initial.bv_len;
- }
-
- if( sub->sa_final.bv_val ) {
- if( inlen > left.bv_len ) {
- match = 1;
- goto done;
- }
-
- match = strncmp( sub->sa_final.bv_val,
- &left.bv_val[left.bv_len - sub->sa_final.bv_len],
- sub->sa_final.bv_len );
-
- if( match != 0 ) {
- goto done;
- }
-
- left.bv_len -= sub->sa_final.bv_len;
- inlen -= sub->sa_final.bv_len;
- }
-
- if( sub->sa_any ) {
- for(i=0; sub->sa_any[i].bv_val; i++) {
- ber_len_t idx;
- char *p;
-
-retry:
- if( inlen > left.bv_len ) {
- /* not enough length */
- match = 1;
- goto done;
- }
-
- if( sub->sa_any[i].bv_len == 0 ) {
- continue;
- }
-
- p = strchr( left.bv_val, *sub->sa_any[i].bv_val );
-
- if( p == NULL ) {
- match = 1;
- goto done;
- }
-
- idx = p - left.bv_val;
-
- if( idx >= left.bv_len ) {
- /* this shouldn't happen */
- return LDAP_OTHER;
- }
-
- left.bv_val = p;
- left.bv_len -= idx;
-
- if( sub->sa_any[i].bv_len > left.bv_len ) {
- /* not enough left */
- match = 1;
- goto done;
- }
-
- match = strncmp( left.bv_val,
- sub->sa_any[i].bv_val,
- sub->sa_any[i].bv_len );
-
- if( match != 0 ) {
- left.bv_val++;
- left.bv_len--;
- goto retry;
- }
-
- left.bv_val += sub->sa_any[i].bv_len;
- left.bv_len -= sub->sa_any[i].bv_len;
- inlen -= sub->sa_any[i].bv_len;
- }
- }
-
-done:
- *matchp = match;
- return LDAP_SUCCESS;
-}
-
-/* Index generation function */
-static int caseExactIA5Indexer(
- slap_mask_t use,
- slap_mask_t flags,
- Syntax *syntax,
- MatchingRule *mr,
- struct berval *prefix,
- BerVarray values,
- BerVarray *keysp )
-{
- int i;
- size_t slen, mlen;
- BerVarray keys;
- HASH_CONTEXT HASHcontext;
- unsigned char HASHdigest[HASH_BYTES];
- struct berval digest;
- digest.bv_val = HASHdigest;
- digest.bv_len = sizeof(HASHdigest);
-
- for( i=0; values[i].bv_val != NULL; i++ ) {
- /* empty - just count them */
- }
-
- /* we should have at least one value at this point */
- assert( i > 0 );
-
- keys = ch_malloc( sizeof( struct berval ) * (i+1) );
-
- slen = syntax->ssyn_oidlen;
- mlen = mr->smr_oidlen;
-
- for( i=0; values[i].bv_val != NULL; i++ ) {
- struct berval *value = &values[i];
-
- HASH_Init( &HASHcontext );
- if( prefix != NULL && prefix->bv_len > 0 ) {
- HASH_Update( &HASHcontext,
- prefix->bv_val, prefix->bv_len );
- }
- HASH_Update( &HASHcontext,
- syntax->ssyn_oid, slen );
- HASH_Update( &HASHcontext,
- mr->smr_oid, mlen );
- HASH_Update( &HASHcontext,
- value->bv_val, value->bv_len );
- HASH_Final( HASHdigest, &HASHcontext );
-
- ber_dupbv( &keys[i], &digest );
- }
-
- keys[i].bv_val = NULL;
- *keysp = keys;
- return LDAP_SUCCESS;
-}
-
-/* Index generation function */
-static int caseExactIA5Filter(
- slap_mask_t use,
- slap_mask_t flags,
- Syntax *syntax,
- MatchingRule *mr,
- struct berval *prefix,
- void * assertValue,
- BerVarray *keysp )
-{
- size_t slen, mlen;
- BerVarray keys;
- HASH_CONTEXT HASHcontext;
- unsigned char HASHdigest[HASH_BYTES];
- struct berval *value;
- struct berval digest;
- digest.bv_val = HASHdigest;
- digest.bv_len = sizeof(HASHdigest);
-
- slen = syntax->ssyn_oidlen;
- mlen = mr->smr_oidlen;
-
- value = (struct berval *) assertValue;
-
- keys = ch_malloc( sizeof( struct berval ) * 2 );
-
- HASH_Init( &HASHcontext );
- if( prefix != NULL && prefix->bv_len > 0 ) {
- HASH_Update( &HASHcontext,
- prefix->bv_val, prefix->bv_len );
- }
- HASH_Update( &HASHcontext,
- syntax->ssyn_oid, slen );
- HASH_Update( &HASHcontext,
- mr->smr_oid, mlen );
- HASH_Update( &HASHcontext,
- value->bv_val, value->bv_len );
- HASH_Final( HASHdigest, &HASHcontext );
-
- ber_dupbv( &keys[0], &digest );
- keys[1].bv_val = NULL;
-
- *keysp = keys;
- return LDAP_SUCCESS;
-}
-
-/* Substrings Index generation function */
-static int caseExactIA5SubstringsIndexer(
- slap_mask_t use,
- slap_mask_t flags,
- Syntax *syntax,
- MatchingRule *mr,
- struct berval *prefix,
- BerVarray values,
- BerVarray *keysp )
-{
- ber_len_t i, nkeys;
- size_t slen, mlen;
- BerVarray keys;
- HASH_CONTEXT HASHcontext;
- unsigned char HASHdigest[HASH_BYTES];
- struct berval digest;
- digest.bv_val = HASHdigest;
- digest.bv_len = sizeof(HASHdigest);
-
- /* we should have at least one value at this point */
- assert( values != NULL && values[0].bv_val != NULL );
-
- nkeys=0;
- for( i=0; values[i].bv_val != NULL; i++ ) {
- /* count number of indices to generate */
- if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
- continue;
- }
-
- if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
- if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
- nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
- ( SLAP_INDEX_SUBSTR_MINLEN - 1);
- } else {
- nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
- }
- }
-
- if( flags & SLAP_INDEX_SUBSTR_ANY ) {
- if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
- nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
- }
- }