X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fschema_init.c;h=eef80beb30279966ba231ff6d1af3911b2c07fa6;hb=925714ceeff035c596ad3d3c899ff631986c6757;hp=1d3ea4241506dfc00e8e50423f73ce266fe06b8f;hpb=fe45b74798d702a12b874916b6b28375624a9999;p=openldap diff --git a/servers/slapd/schema_init.c b/servers/slapd/schema_init.c index 1d3ea42415..eef80beb30 100644 --- a/servers/slapd/schema_init.c +++ b/servers/slapd/schema_init.c @@ -1,7 +1,7 @@ /* schema_init.c - init builtin schema */ /* $OpenLDAP$ */ /* - * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved. + * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved. * COPYING RESTRICTIONS APPLY, see COPYRIGHT file */ @@ -17,6 +17,7 @@ #include "slap.h" #include "ldap_pvt.h" +#include "lber_pvt.h" #include "ldap_utf8.h" @@ -32,11 +33,6 @@ /* unimplemented pretters */ #define integerPretty NULL -#ifndef USE_LDAP_DN_PARSING -# define dnPretty NULL -#else -# define SLAP_LDAPDN_PRETTY 0x1 -#endif /* !USE_LDAP_DN_PARSING */ /* recycled matching routines */ #define bitStringMatch octetStringMatch @@ -47,6 +43,7 @@ #define generalizedTimeMatch caseIgnoreIA5Match #define generalizedTimeOrderingMatch caseIgnoreIA5Match #define uniqueMemberMatch dnMatch +#define integerFirstComponentMatch integerMatch /* approx matching rules */ #define directoryStringApproxMatchOID "1.3.6.1.4.1.4203.666.4.4" @@ -58,18 +55,22 @@ #define IA5StringApproxIndexer approxIndexer #define IA5StringApproxFilter approxFilter -/* orderring matching rules */ +/* ordering matching rules */ #define caseIgnoreOrderingMatch caseIgnoreMatch #define caseExactOrderingMatch caseExactMatch +#define integerOrderingMatch integerMatch /* unimplemented matching routines */ #define caseIgnoreListMatch NULL #define caseIgnoreListSubstringsMatch NULL #define protocolInformationMatch NULL -#define integerFirstComponentMatch NULL +#ifdef SLAPD_ACI_ENABLED #define OpenLDAPaciMatch NULL +#endif +#ifdef SLAPD_AUTHPASSWD #define authPasswordMatch NULL +#endif /* recycled indexing/filtering routines */ #define dnIndexer caseExactIgnoreIndexer @@ -82,22 +83,37 @@ #define telephoneNumberSubstringsIndexer caseIgnoreIA5SubstringsIndexer #define telephoneNumberSubstringsFilter caseIgnoreIA5SubstringsFilter -/* must match OIDs below */ -#define caseExactMatchOID "2.5.13.5" -#define caseExactSubstringsMatchOID "2.5.13.7" +static MatchingRule *caseExactMatchingRule; +static MatchingRule *caseExactSubstringsMatchingRule; +static MatchingRule *integerFirstComponentMatchingRule; + +static const struct MatchingRulePtr { + const char *oid; + MatchingRule **mr; +} mr_ptr [] = { + /* must match OIDs below */ + { "2.5.13.5", &caseExactMatchingRule }, + { "2.5.13.7", &caseExactSubstringsMatchingRule }, + { "2.5.13.29", &integerFirstComponentMatchingRule } +}; -static char *strcasechr( const char *str, int c ) + +static char *bvcasechr( struct berval *bv, unsigned char c, ber_len_t *len ) { - char *lower = strchr( str, TOLOWER(c) ); - char *upper = strchr( str, TOUPPER(c) ); + ber_len_t i; + char lower = TOLOWER( c ); + char upper = TOUPPER( c ); - if( lower && upper ) { - return lower < upper ? lower : upper; - } else if ( lower ) { - return lower; - } else { - return upper; + if( c == 0 ) return NULL; + + for( i=0; i < bv->bv_len; i++ ) { + if( upper == bv->bv_val[i] || lower == bv->bv_val[i] ) { + *len = i; + return &bv->bv_val[i]; + } } + + return NULL; } static int @@ -122,37 +138,37 @@ octetStringMatch( } /* Index generation function */ -int octetStringIndexer( +static int octetStringIndexer( slap_mask_t use, slap_mask_t flags, Syntax *syntax, MatchingRule *mr, struct berval *prefix, - struct berval **values, - struct berval ***keysp ) + BerVarray values, + BerVarray *keysp ) { int i; size_t slen, mlen; - struct berval **keys; + 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] != NULL; i++ ) { + for( i=0; values[i].bv_val != NULL; i++ ) { /* just count them */ } /* we should have at least one value at this point */ assert( i > 0 ); - keys = ch_malloc( sizeof( struct berval * ) * (i+1) ); + keys = ch_malloc( sizeof( struct berval ) * (i+1) ); - slen = strlen( syntax->ssyn_oid ); - mlen = strlen( mr->smr_oid ); + slen = syntax->ssyn_oidlen; + mlen = mr->smr_oidlen; - for( i=0; values[i] != NULL; i++ ) { + for( i=0; values[i].bv_val != NULL; i++ ) { HASH_Init( &HASHcontext ); if( prefix != NULL && prefix->bv_len > 0 ) { HASH_Update( &HASHcontext, @@ -163,13 +179,13 @@ int octetStringIndexer( HASH_Update( &HASHcontext, mr->smr_oid, mlen ); HASH_Update( &HASHcontext, - values[i]->bv_val, values[i]->bv_len ); + values[i].bv_val, values[i].bv_len ); HASH_Final( HASHdigest, &HASHcontext ); - keys[i] = ber_bvdup( &digest ); + ber_dupbv( &keys[i], &digest ); } - keys[i] = NULL; + keys[i].bv_val = NULL; *keysp = keys; @@ -177,17 +193,17 @@ int octetStringIndexer( } /* Index generation function */ -int octetStringFilter( +static int octetStringFilter( slap_mask_t use, slap_mask_t flags, Syntax *syntax, MatchingRule *mr, struct berval *prefix, void * assertValue, - struct berval ***keysp ) + BerVarray *keysp ) { size_t slen, mlen; - struct berval **keys; + BerVarray keys; HASH_CONTEXT HASHcontext; unsigned char HASHdigest[HASH_BYTES]; struct berval *value = (struct berval *) assertValue; @@ -195,10 +211,10 @@ int octetStringFilter( digest.bv_val = HASHdigest; digest.bv_len = sizeof(HASHdigest); - slen = strlen( syntax->ssyn_oid ); - mlen = strlen( mr->smr_oid ); + slen = syntax->ssyn_oidlen; + mlen = mr->smr_oidlen; - keys = ch_malloc( sizeof( struct berval * ) * 2 ); + keys = ch_malloc( sizeof( struct berval ) * 2 ); HASH_Init( &HASHcontext ); if( prefix != NULL && prefix->bv_len > 0 ) { @@ -213,588 +229,146 @@ int octetStringFilter( value->bv_val, value->bv_len ); HASH_Final( HASHdigest, &HASHcontext ); - keys[0] = ber_bvdup( &digest ); - keys[1] = NULL; + ber_dupbv( keys, &digest ); + keys[1].bv_val = NULL; *keysp = keys; return LDAP_SUCCESS; } -#ifdef USE_LDAP_DN_PARSING - -/* - * The DN syntax-related functions take advantage of the dn representation - * handling functions ldap_str2dn/ldap_dn2str. The latter are not schema- - * aware, so the attributes and their values need be validated (and possibly - * normalized). In the current implementation the required validation/nor- - * malization/"pretty"ing are done on newly created DN structural represen- - * tations; however the idea is to move towards DN handling in structural - * representation instead of the current string representation. To this - * purpose, we need to do only the required operations and keep track of - * what has been done to minimize their impact on performances. - * - * Developers are strongly encouraged to use this feature, to speed-up - * its stabilization. - */ - -#define AVA_PRIVATE( ava ) ( ( AttributeDescription * )(ava)->la_private ) - -/* - * In-place, schema-aware validation of the - * structural representation of a distinguished name. - */ static int -LDAPDN_validate( LDAPDN *dn ) +inValidate( + Syntax *syntax, + struct berval *in ) { - int iRDN; - int rc; - - assert( dn ); - - for ( iRDN = 0; dn[ iRDN ]; iRDN++ ) { - LDAPRDN *rdn = dn[ iRDN ][ 0 ]; - int iAVA; - - assert( rdn ); - - for ( iAVA = 0; rdn[ iAVA ]; iAVA++ ) { - LDAPAVA *ava = rdn[ iAVA ][ 0 ]; - AttributeDescription *ad; - slap_syntax_validate_func *validate = NULL; - - assert( ava ); - - if ( ( ad = AVA_PRIVATE( ava ) ) == NULL ) { - const char *text = NULL; - - rc = slap_bv2ad( ava->la_attr, &ad, &text ); - if ( rc != LDAP_SUCCESS ) { - return LDAP_INVALID_SYNTAX; - } - - ava->la_private = ( void * )ad; - } - - /* - * Replace attr oid/name with the canonical name - */ - ber_bvfree( ava->la_attr ); - ava->la_attr = ber_bvdup( &ad->ad_cname ); - - validate = ad->ad_type->sat_syntax->ssyn_validate; - - if ( validate ) { - /* - * validate value by validate function - */ - rc = ( *validate )( ad->ad_type->sat_syntax, - ava->la_value ); - - if ( rc != LDAP_SUCCESS ) { - return LDAP_INVALID_SYNTAX; - } - } - } - } + /* no value allowed */ + return LDAP_INVALID_SYNTAX; +} +static int +blobValidate( + Syntax *syntax, + struct berval *in ) +{ + /* any value allowed */ return LDAP_SUCCESS; } -/* - * dn validate routine - */ static int -dnValidate( +bitStringValidate( Syntax *syntax, struct berval *in ) { - int rc; - LDAPDN *dn = NULL; - - assert( in ); + ber_len_t i; - if ( in->bv_len == 0 ) { - return( LDAP_SUCCESS ); + /* very unforgiving validation, requires no normalization + * before simplistic matching + */ + if( in->bv_len < 3 ) { + return LDAP_INVALID_SYNTAX; } - rc = ldap_str2dn( in->bv_val, &dn, LDAP_DN_FORMAT_LDAP ); - /* - * Schema-aware validate + * rfc 2252 section 6.3 Bit String + * bitstring = "'" *binary-digit "'" + * binary-digit = "0" / "1" + * example: '0101111101'B */ - if ( rc == LDAP_SUCCESS ) { - rc = LDAPDN_validate( dn ); - } - ldapava_free_dn( dn ); - - if ( rc != LDAP_SUCCESS ) { - return( LDAP_INVALID_SYNTAX ); - } - - return( LDAP_SUCCESS ); -} - -/* - * AVA sorting inside a RDN - * - * rule: sort attributeTypes in alphabetical order; in case of multiple - * occurrences of the same attributeType, sort values in byte order - * (use memcmp, which implies alphabetical order in case of IA5 value; - * this should guarantee the repeatability of the operation). - * - * uses a linear search; should be fine since the number of AVAs in - * a RDN should be limited. - */ -static void -AVA_Sort( LDAPRDN *rdn, int iAVA ) -{ - int i; - LDAPAVA *ava_in = rdn[ iAVA ][ 0 ]; - - assert( rdn ); - assert( ava_in ); - - for ( i = 0; i < iAVA; i++ ) { - LDAPAVA *ava = rdn[ i ][ 0 ]; - int a, j; - - assert( ava ); - - a = strcmp( ava_in->la_attr->bv_val, ava->la_attr->bv_val ); - - if ( a > 0 ) { - break; - } - - while ( a == 0 ) { - int v, d; - - d = ava_in->la_value->bv_len - ava->la_value->bv_len; - - v = memcmp( ava_in->la_value->bv_val, - ava->la_value->bv_val, - d <= 0 ? ava_in->la_value->bv_len - : ava->la_value->bv_len ); - - if ( v == 0 && d != 0 ) { - v = d; - } - - if ( v <= 0 ) { - /* - * got it! - */ - break; - } - - if ( ++i == iAVA ) { - /* - * already sorted - */ - return; - } - - ava = rdn[ i ][ 0 ]; - a = strcmp( ava_in->la_value->bv_val, - ava->la_value->bv_val ); - } - - /* - * move ahead - */ - for ( j = iAVA; j > i; j-- ) { - rdn[ j ][ 0 ] = rdn[ j - 1 ][ 0 ]; - } - rdn[ i ][ 0 ] = ava_in; - - return; - } -} - -/* - * In-place, schema-aware normalization / "pretty"ing of the - * structural representation of a distinguished name. - */ -static int -LDAPDN_rewrite( LDAPDN *dn, unsigned flags ) -{ - int iRDN; - int rc; - - assert( dn ); - - for ( iRDN = 0; dn[ iRDN ]; iRDN++ ) { - LDAPRDN *rdn = dn[ iRDN ][ 0 ]; - int iAVA; - - assert( rdn ); - - for ( iAVA = 0; rdn[ iAVA ]; iAVA++ ) { - LDAPAVA *ava = rdn[ iAVA ][ 0 ]; - AttributeDescription *ad; - slap_syntax_transform_func *transf = NULL; - MatchingRule *mr; - struct berval *bv = NULL; - - assert( ava ); - - if ( ( ad = AVA_PRIVATE( ava ) ) == NULL ) { - const char *text = NULL; - - rc = slap_bv2ad( ava->la_attr, &ad, &text ); - if ( rc != LDAP_SUCCESS ) { - return LDAP_INVALID_SYNTAX; - } - - ava->la_private = ( void * )ad; - } - - /* - * Replace attr oid/name with the canonical name - */ - ber_bvfree( ava->la_attr ); - ava->la_attr = ber_bvdup( &ad->ad_cname ); - - if( flags & SLAP_LDAPDN_PRETTY ) { - transf = ad->ad_type->sat_syntax->ssyn_pretty; - mr = NULL; - } else { - transf = ad->ad_type->sat_syntax->ssyn_normalize; - mr = ad->ad_type->sat_equality; - } - - if ( transf ) { - /* - * transform value by normalize/pretty function - */ - rc = ( *transf )( ad->ad_type->sat_syntax, - ava->la_value, &bv ); - - if ( rc != LDAP_SUCCESS ) { - return LDAP_INVALID_SYNTAX; - } - } - - if( mr && ( mr->smr_usage & SLAP_MR_DN_FOLD ) ) { - struct berval *s = bv; - - bv = ber_bvstr( UTF8normalize( bv ? bv : ava->la_value, - UTF8_CASEFOLD ) ); - - ber_bvfree( s ); - } - - if( bv ) { - ber_bvfree( ava->la_value ); - ava->la_value = bv; - } - - AVA_Sort( rdn, iAVA ); - } + if( in->bv_val[0] != '\'' || + in->bv_val[in->bv_len-2] != '\'' || + in->bv_val[in->bv_len-1] != 'B' ) + { + return LDAP_INVALID_SYNTAX; } - return LDAP_SUCCESS; -} - -/* - * dn normalize routine - */ -int -dnNormalize( - Syntax *syntax, - struct berval *val, - struct berval **normalized ) -{ - struct berval *out = NULL; - - Debug( LDAP_DEBUG_TRACE, ">>> dnNormalize: <%s>\n", val->bv_val, 0, 0 ); - - assert( val ); - assert( normalized ); - - if ( val->bv_len != 0 ) { - LDAPDN *dn = NULL; - char *dn_out = NULL; - int rc; - - /* - * Go to structural representation - */ - rc = ldap_str2dn( val->bv_val, &dn, LDAP_DN_FORMAT_LDAP ); - if ( rc != LDAP_SUCCESS ) { - return LDAP_INVALID_SYNTAX; - } - - /* - * Schema-aware rewrite - */ - if ( LDAPDN_rewrite( dn, 0 ) != LDAP_SUCCESS ) { - ldapava_free_dn( dn ); - return LDAP_INVALID_SYNTAX; - } - - /* - * Back to string representation - */ - rc = ldap_dn2str( dn, &dn_out, LDAP_DN_FORMAT_LDAPV3 ); - - ldapava_free_dn( dn ); - - if ( rc != LDAP_SUCCESS ) { + for( i=in->bv_len-3; i>0; i-- ) { + if( in->bv_val[i] != '0' && in->bv_val[i] != '1' ) { return LDAP_INVALID_SYNTAX; } - - out = ber_bvstr( dn_out ); - - } else { - out = ber_bvdup( val ); } - Debug( LDAP_DEBUG_TRACE, "<<< dnNormalize: <%s>\n", out->bv_val, 0, 0 ); - - *normalized = out; - return LDAP_SUCCESS; } -/* - * dn "pretty"ing routine - */ -int -dnPretty( - Syntax *syntax, - struct berval *val, - struct berval **pretty) -{ - struct berval *out = NULL; - - Debug( LDAP_DEBUG_TRACE, ">>> dnPretty: <%s>\n", val->bv_val, 0, 0 ); - - assert( val ); - assert( pretty ); - - if ( val->bv_len != 0 ) { - LDAPDN *dn = NULL; - char *dn_out = NULL; - int rc; - - /* FIXME: should be liberal in what we accept */ - rc = ldap_str2dn( val->bv_val, &dn, LDAP_DN_FORMAT_LDAP ); - if ( rc != LDAP_SUCCESS ) { - return LDAP_INVALID_SYNTAX; - } - - /* - * Schema-aware rewrite - */ - if ( LDAPDN_rewrite( dn, SLAP_LDAPDN_PRETTY ) != LDAP_SUCCESS ) { - ldapava_free_dn( dn ); - return LDAP_INVALID_SYNTAX; - } - - /* FIXME: not sure why the default isn't pretty */ - /* RE: the default is the form that is used as - * an internal representation; the pretty form - * is a variant */ - rc = ldap_dn2str( dn, &dn_out, - LDAP_DN_FORMAT_LDAPV3 | LDAP_DN_PRETTY ); - - ldapava_free_dn( dn ); - - if ( rc != LDAP_SUCCESS ) { - return LDAP_INVALID_SYNTAX; - } - - out = ber_bvstr( dn_out ); - - } else { - out = ber_bvdup( val ); - } - - Debug( LDAP_DEBUG_TRACE, "<<< dnPretty: <%s>\n", out->bv_val, 0, 0 ); - - *pretty = out; - - return LDAP_SUCCESS; -} - -/* - * dn match routine - * - * note: uses exact string match (strcmp) because it is supposed to work - * on normalized DNs. - */ -int -dnMatch( - int *matchp, - slap_mask_t flags, - Syntax *syntax, - MatchingRule *mr, - struct berval *value, - void *assertedValue ) -{ - int match; - struct berval *asserted = (struct berval *) assertedValue; - - assert( matchp ); - assert( value ); - assert( assertedValue ); - - match = value->bv_len - asserted->bv_len; - - if ( match == 0 ) { - match = strcmp( value->bv_val, asserted->bv_val ); - } - -#ifdef NEW_LOGGING - LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY, - "dnMatch: %d\n %s\n %s\n", match, - value->bv_val, asserted->bv_val )); -#else - Debug( LDAP_DEBUG_ARGS, "dnMatch %d\n\t\"%s\"\n\t\"%s\"\n", - match, value->bv_val, asserted->bv_val ); -#endif - - *matchp = match; - return( LDAP_SUCCESS ); -} - -#else /* !USE_LDAP_DN_PARSING */ - static int -dnValidate( - Syntax *syntax, - struct berval *in ) -{ - int rc; - char *dn; - - if( in->bv_len == 0 ) return LDAP_SUCCESS; - - dn = ch_strdup( in->bv_val ); - - if( dn == NULL ) { - return LDAP_INVALID_SYNTAX; - - } else if ( strlen( in->bv_val ) != in->bv_len ) { - rc = LDAP_INVALID_SYNTAX; - - } else if ( dn_validate( dn ) == NULL ) { - rc = LDAP_INVALID_SYNTAX; - - } else { - rc = LDAP_SUCCESS; - } - - ch_free( dn ); - return rc; -} - -int -dnNormalize( +bitStringNormalize( Syntax *syntax, struct berval *val, - struct berval **normalized ) + struct berval *normalized ) { - struct berval *out; - - if ( val->bv_len != 0 ) { - char *dn; - out = ber_bvstr( UTF8normalize( val, UTF8_CASEFOLD ) ); + /* + * A normalized bitString is has no extaneous (leading) zero bits. + * That is, '00010'B is normalized to '10'B + * However, as a special case, '0'B requires no normalization. + */ + char *p; - dn = dn_validate( out->bv_val ); + /* start at the first bit */ + p = &val->bv_val[1]; - if( dn == NULL ) { - ber_bvfree( out ); - return LDAP_INVALID_SYNTAX; - } + /* Find the first non-zero bit */ + while ( *p == '0' ) p++; - out->bv_val = dn; - out->bv_len = strlen( dn ); - } else { - out = ber_bvdup( val ); + if( *p == '\'' ) { + /* no non-zero bits */ + ber_str2bv( "\'0\'B", sizeof("\'0\'B") - 1, 1, normalized ); + goto done; } - *normalized = out; - return LDAP_SUCCESS; -} + normalized->bv_val = ch_malloc( val->bv_len + 1 ); -int -dnMatch( - int *matchp, - slap_mask_t flags, - Syntax *syntax, - MatchingRule *mr, - struct berval *value, - void *assertedValue ) -{ - int match; - struct berval *asserted = (struct berval *) assertedValue; - - match = value->bv_len - asserted->bv_len; + normalized->bv_val[0] = '\''; + normalized->bv_len = 1; - if( match == 0 ) { -#ifdef USE_DN_NORMALIZE - match = strcmp( value->bv_val, asserted->bv_val ); -#else - match = strcasecmp( value->bv_val, asserted->bv_val ); -#endif + for( ; *p != '\0'; p++ ) { + normalized->bv_val[normalized->bv_len++] = *p; } -#ifdef NEW_LOGGING - LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY, - "dnMatch: %d\n %s\n %s\n", match, - value->bv_val, asserted->bv_val )); -#else - Debug( LDAP_DEBUG_ARGS, "dnMatch %d\n\t\"%s\"\n\t\"%s\"\n", - match, value->bv_val, asserted->bv_val ); -#endif + normalized->bv_val[normalized->bv_len] = '\0'; - - *matchp = match; +done: return LDAP_SUCCESS; } -#endif /* !USE_LDAP_DN_PARSING */ - static int nameUIDValidate( Syntax *syntax, struct berval *in ) { int rc; - struct berval *dn; + struct berval dn; if( in->bv_len == 0 ) return LDAP_SUCCESS; - dn = ber_bvdup( in ); + ber_dupbv( &dn, in ); + if( !dn.bv_val ) return LDAP_OTHER; - if( dn->bv_val[dn->bv_len-1] == '\'' ) { + if( dn.bv_val[dn.bv_len-1] == 'B' + && dn.bv_val[dn.bv_len-2] == '\'' ) + { /* assume presence of optional UID */ ber_len_t i; - for(i=dn->bv_len-2; i>2; i--) { - if( dn->bv_val[i] != '0' && dn->bv_val[i] != '1' ) { + for(i=dn.bv_len-3; i>1; i--) { + if( dn.bv_val[i] != '0' && dn.bv_val[i] != '1' ) { break; } } - if( dn->bv_val[i] != '\'' || - dn->bv_val[i-1] != 'B' || - dn->bv_val[i-2] != '#' ) { - ber_bvfree( dn ); + if( dn.bv_val[i] != '\'' || dn.bv_val[i-1] != '#' ) { + ber_memfree( dn.bv_val ); return LDAP_INVALID_SYNTAX; } - /* trim the UID to allow use of dn_validate */ - dn->bv_val[i-2] = '\0'; + /* trim the UID to allow use of dnValidate */ + dn.bv_val[i-1] = '\0'; + dn.bv_len = i-1; } - rc = dn_validate( dn->bv_val ) == NULL - ? LDAP_INVALID_SYNTAX : LDAP_SUCCESS; + rc = dnValidate( NULL, &dn ); - ber_bvfree( dn ); + ber_memfree( dn.bv_val ); return rc; } @@ -802,155 +376,72 @@ static int nameUIDNormalize( Syntax *syntax, struct berval *val, - struct berval **normalized ) + struct berval *normalized ) { - struct berval *out = ber_bvdup( val ); + struct berval out; + int rc; - if( out->bv_len != 0 ) { - char *dn; - ber_len_t dnlen; - char *uid = NULL; - ber_len_t uidlen = 0; + ber_dupbv( &out, val ); + if( out.bv_len != 0 ) { + struct berval uidin = { 0, NULL }; + struct berval uidout = { 0, NULL }; - if( out->bv_val[out->bv_len-1] == '\'' ) { + if( out.bv_val[out.bv_len-1] == 'B' + && out.bv_val[out.bv_len-2] == '\'' ) + { /* assume presence of optional UID */ - uid = strrchr( out->bv_val, '#' ); + uidin.bv_val = strrchr( out.bv_val, '#' ); - if( uid == NULL ) { - ber_bvfree( out ); + if( uidin.bv_val == NULL ) { + free( out.bv_val ); return LDAP_INVALID_SYNTAX; } - uidlen = out->bv_len - (out->bv_val - uid); + uidin.bv_len = out.bv_len - (uidin.bv_val - out.bv_val); + out.bv_len -= uidin.bv_len--; + /* temporarily trim the UID */ - *uid = '\0'; + *(uidin.bv_val++) = '\0'; + + rc = bitStringNormalize( syntax, &uidin, &uidout ); + + if( rc != LDAP_SUCCESS ) { + free( out.bv_val ); + return LDAP_INVALID_SYNTAX; + } } #ifdef USE_DN_NORMALIZE - dn = dn_normalize( out->bv_val ); + rc = dnNormalize2( NULL, &out, normalized ); #else - dn = dn_validate( out->bv_val ); + rc = dnPretty2( NULL, &out, normalized ); #endif - if( dn == NULL ) { - ber_bvfree( out ); + if( rc != LDAP_SUCCESS ) { + free( out.bv_val ); + free( uidout.bv_val ); return LDAP_INVALID_SYNTAX; } - dnlen = strlen(dn); - - if( uidlen ) { - /* restore the separator */ - *uid = '#'; - /* shift the UID */ - SAFEMEMCPY( &dn[dnlen], uid, uidlen ); - } - - out->bv_val = dn; - out->bv_len = dnlen + uidlen; - } - - *normalized = out; - return LDAP_SUCCESS; -} + if( uidout.bv_len ) { + normalized->bv_val = ch_realloc( normalized->bv_val, + normalized->bv_len + uidout.bv_len + sizeof("#") ); -static int -inValidate( - Syntax *syntax, - struct berval *in ) -{ - /* any value allowed */ - return LDAP_OTHER; -} - -static int -blobValidate( - Syntax *syntax, - struct berval *in ) -{ - /* any value allowed */ - return LDAP_SUCCESS; -} + /* insert the separator */ + normalized->bv_val[normalized->bv_len++] = '#'; -static int -bitStringValidate( - Syntax *syntax, - struct berval *in ) -{ - ber_len_t i; + /* append the UID */ + AC_MEMCPY( &normalized->bv_val[normalized->bv_len], + uidout.bv_val, uidout.bv_len ); + normalized->bv_len += uidout.bv_len; - /* very unforgiving validation, requires no normalization - * before simplistic matching - */ - if( in->bv_len < 3 ) { - return LDAP_INVALID_SYNTAX; - } - - /* - * rfc 2252 section 6.3 Bit String - * bitstring = "'" *binary-digit "'" - * binary-digit = "0" / "1" - * example: '0101111101'B - */ - - if( in->bv_val[0] != '\'' || - in->bv_val[in->bv_len-2] != '\'' || - in->bv_val[in->bv_len-1] != 'B' ) - { - return LDAP_INVALID_SYNTAX; - } - - for( i=in->bv_len-3; i>0; i-- ) { - if( in->bv_val[i] != '0' && in->bv_val[i] != '1' ) { - return LDAP_INVALID_SYNTAX; + /* terminate */ + normalized->bv_val[normalized->bv_len] = '\0'; } - } - return LDAP_SUCCESS; -} - -static int -bitStringNormalize( - Syntax *syntax, - struct berval *val, - struct berval **normalized ) -{ - /* - * A normalized bitString is has no extaneous (leading) zero bits. - * That is, '00010'B is normalized to '10'B - * However, as a special case, '0'B requires no normalization. - */ - struct berval *newval; - char *p; - - /* start at the first bit */ - p = &val->bv_val[1]; - - /* Find the first non-zero bit */ - while ( *p == '0' ) p++; - - newval = (struct berval *) ch_malloc( sizeof(struct berval) ); - - if( *p == '\'' ) { - /* no non-zero bits */ - newval->bv_val = ch_strdup("\'0\'B"); - newval->bv_len = sizeof("\'0\'B") - 1; - goto done; - } - - newval->bv_val = ch_malloc( val->bv_len + 1 ); - - newval->bv_val[0] = '\''; - newval->bv_len = 1; - - for( ; *p != '\0'; p++ ) { - newval->bv_val[newval->bv_len++] = *p; + free( out.bv_val ); } - newval->bv_val[newval->bv_len] = '\0'; - -done: - *normalized = newval; return LDAP_SUCCESS; } @@ -997,6 +488,76 @@ booleanMatch( return LDAP_SUCCESS; } +/*------------------------------------------------------------------- +LDAP/X.500 string syntax / matching rules have a few oddities. This +comment attempts to detail how slapd(8) treats them. + +Summary: + StringSyntax X.500 LDAP Matching + DirectoryString CHOICE UTF8 i/e + ignore insignificant spaces + PrintableString subset subset i/e + ignore insignificant spaces + NumericString subset subset ignore all spaces + IA5String ASCII ASCII i/e + ignore insignificant spaces + TeletexString T.61 T.61 i/e + ignore insignificant spaces + + TelephoneNumber subset subset i + ignore all spaces and "-" + + See draft-ietf-ldapbis-strpro for details (once published). + + +Directory String - + In X.500(93), a directory string can be either a PrintableString, + a bmpString, or a UniversalString (e.g., UCS (a subset of Unicode)). + In later versions, more CHOICEs were added. In all cases the string + must be non-empty. + + In LDPAv3, a directory string is a UTF-8 encoded UCS string. + + For matching, there are both case ignore and exact rules. Both + also require that "insignificant" spaces be ignored. + spaces before the first non-space are ignored; + spaces after the last non-space are ignored; + spaces after a space are ignored. + Note: by these rules (and as clarified in X.520), a string of only + spaces is to be treated as if held one space, not empty (which + would be a syntax error). + +NumericString + In ASN.1, numeric string is just a string of digits and spaces + and could be empty. However, in X.500, all attribute values of + numeric string carry a non-empty constraint. For example: + + internationalISDNNumber ATTRIBUTE ::= { + WITH SYNTAX InternationalISDNNumber + EQUALITY MATCHING RULE numericStringMatch + SUBSTRINGS MATCHING RULE numericStringSubstringsMatch + ID id-at-internationalISDNNumber } + InternationalISDNNumber ::= + NumericString (SIZE(1..ub-international-isdn-number)) + + Unforunately, some assertion values are don't carry the same + constraint (but its unclear how such an assertion could ever + be true). In LDAP, there is one syntax (numericString) not two + (numericString with constraint, numericString without constraint). + This should be treated as numericString with non-empty constraint. + Note that while someone may have no ISDN number, there are no ISDN + numbers which are zero length. + + In matching, spaces are ignored. + +PrintableString + In ASN.1, Printable string is just a string of printable characters + and can be empty. In X.500, semantics much like NumericString (see + serialNumber for a like example) excepting uses insignificant space + handling instead of ignore all spaces. + +IA5String + Basically same as PrintableString. There are no examples in X.500, + but same logic applies. So we require them to be non-empty as + well. + +-------------------------------------------------------------------*/ + static int UTF8StringValidate( Syntax *syntax, @@ -1010,10 +571,36 @@ UTF8StringValidate( for( count = in->bv_len; count > 0; count-=len, u+=len ) { /* get the length indicated by the first byte */ - len = LDAP_UTF8_CHARLEN( u ); + len = LDAP_UTF8_CHARLEN2( u, len ); - /* should not be zero */ - if( len == 0 ) return LDAP_INVALID_SYNTAX; + /* 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 */ @@ -1029,56 +616,58 @@ static int UTF8StringNormalize( Syntax *syntax, struct berval *val, - struct berval **normalized ) + struct berval *normalized ) { - struct berval *newval; - char *p, *q, *s; + char *p, *q, *s, *e; + int len = 0; - newval = ch_malloc( sizeof( struct berval ) ); + /* validator should have refused an empty string */ + assert( val->bv_len ); p = val->bv_val; /* Ignore initial whitespace */ - while ( ldap_utf8_isspace( p ) ) { - LDAP_UTF8_INCR( p ); - } + /* All space is ASCII. All ASCII is 1 byte */ + for ( ; p < val->bv_val + val->bv_len && ASCII_SPACE( p[ 0 ] ); p++ ); - if( *p == '\0' ) { - ch_free( newval ); - return LDAP_INVALID_SYNTAX; + normalized->bv_len = val->bv_len - (p - val->bv_val); + + if( !normalized->bv_len ) { + ber_mem2bv( " ", 1, 1, normalized ); + return LDAP_SUCCESS; } - newval->bv_val = ch_strdup( p ); - p = q = newval->bv_val; + ber_mem2bv( p, normalized->bv_len, 1, normalized ); + e = normalized->bv_val + normalized->bv_len; + + assert( normalized->bv_val ); + + p = q = normalized->bv_val; s = NULL; - while ( *p ) { - int len; - - if ( ldap_utf8_isspace( p ) ) { - len = LDAP_UTF8_COPY(q,p); - s=q; - p+=len; - q+=len; + while ( p < e ) { + q += len; + if ( ASCII_SPACE( *p ) ) { + s = q - len; + len = 1; + *q = *p++; /* Ignore the extra whitespace */ - while ( ldap_utf8_isspace( p ) ) { - LDAP_UTF8_INCR( p ); + while ( ASCII_SPACE( *p ) ) { + p++; } } else { len = LDAP_UTF8_COPY(q,p); s=NULL; p+=len; - q+=len; } } - assert( *newval->bv_val ); - assert( newval->bv_val < p ); - assert( q <= p ); + assert( normalized->bv_val <= p ); + assert( q+len <= p ); /* cannot start with a space */ - assert( !ldap_utf8_isspace(newval->bv_val) ); + assert( !ASCII_SPACE( normalized->bv_val[0] ) ); /* * If the string ended in space, backup the pointer one @@ -1087,27 +676,29 @@ UTF8StringNormalize( */ if ( s != NULL ) { + len = q - s; q = s; } /* cannot end with a space */ - assert( !ldap_utf8_isspace( LDAP_UTF8_PREV(q) ) ); + assert( !ASCII_SPACE( *q ) ); + + q += len; /* null terminate */ *q = '\0'; - newval->bv_len = q - newval->bv_val; - *normalized = newval; + normalized->bv_len = q - normalized->bv_val; return LDAP_SUCCESS; } -/* Returns Unicode cannonically normalized copy of a substring assertion +/* Returns Unicode canonically normalized copy of a substring assertion * Skipping attribute description */ -SubstringsAssertion * +static SubstringsAssertion * UTF8SubstringsassertionNormalize( SubstringsAssertion *sa, - char casefold ) + unsigned casefold ) { SubstringsAssertion *nsa; int i; @@ -1117,30 +708,33 @@ UTF8SubstringsassertionNormalize( return NULL; } - if( sa->sa_initial != NULL ) { - nsa->sa_initial = ber_bvstr( UTF8normalize( sa->sa_initial, casefold ) ); - if( nsa->sa_initial == 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] != NULL; i++ ) { + 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] != NULL; i++ ) { - nsa->sa_any[i] = ber_bvstr( UTF8normalize( sa->sa_any[i], casefold ) ); - if( nsa->sa_any[i] == NULL ) { + 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] = NULL; + nsa->sa_any[i].bv_val = NULL; } - if( sa->sa_final != NULL ) { - nsa->sa_final = ber_bvstr( UTF8normalize( sa->sa_final, casefold ) ); - if( nsa->sa_final == 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; } } @@ -1148,37 +742,13 @@ UTF8SubstringsassertionNormalize( return nsa; err: - ber_bvfree( nsa->sa_final ); - ber_bvecfree( nsa->sa_any ); - ber_bvfree( nsa->sa_initial ); + 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 */ -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 = memmove(p, q, strlen(q) + 1); - } else { - p++; - } - } - return in; -} - #ifndef SLAPD_APPROX_OLDSINGLESTRING #if defined(SLAPD_APPROX_INITIALS) @@ -1198,31 +768,28 @@ approxMatch( struct berval *value, void *assertedValue ) { - char *val, *nval, *assertv, **values, **words, *c; + struct berval *nval, *assertv; + char *val, **values, **words, *c; int i, count, len, nextchunk=0, nextavail=0; - size_t avlen; /* Yes, this is necessary */ - nval = UTF8normalize( value, UTF8_NOCASEFOLD ); + nval = UTF8bvnormalize( value, NULL, LDAP_UTF8_APPROX ); if( nval == NULL ) { *matchp = 1; return LDAP_SUCCESS; } - strip8bitChars( nval ); /* Yes, this is necessary */ - assertv = UTF8normalize( ((struct berval *)assertedValue), - UTF8_NOCASEFOLD ); + assertv = UTF8bvnormalize( ((struct berval *)assertedValue), + NULL, LDAP_UTF8_APPROX ); if( assertv == NULL ) { - ch_free( nval ); + ber_bvfree( nval ); *matchp = 1; return LDAP_SUCCESS; } - strip8bitChars( assertv ); - avlen = strlen( assertv ); /* Isolate how many words there are */ - for( c=nval,count=1; *c; c++ ) { + for ( c = nval->bv_val, count = 1; *c; c++ ) { c = strpbrk( c, SLAPD_APPROX_DELIMITER ); if ( c == NULL ) break; *c = '\0'; @@ -1232,7 +799,7 @@ approxMatch( /* 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; ibv_val, i = 0; i < count; i++, c += strlen(c) + 1 ) { words[i] = c; values[i] = phonetic(c); } @@ -1240,8 +807,8 @@ approxMatch( /* 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 ( nextchunk < avlen ) { - len = strcspn( assertv + nextchunk, SLAPD_APPROX_DELIMITER); + while ( (ber_len_t) nextchunk < assertv->bv_len ) { + len = strcspn( assertv->bv_val + nextchunk, SLAPD_APPROX_DELIMITER); if( len == 0 ) { nextchunk++; continue; @@ -1250,7 +817,7 @@ approxMatch( else if( len == 1 ) { /* Single letter words need to at least match one word's initial */ for( i=nextavail; ibv_val + nextchunk, words[i], 1 )) { nextavail=i+1; break; } @@ -1258,8 +825,8 @@ approxMatch( #endif else { /* Isolate the next word in the asserted value and phonetic it */ - assertv[nextchunk+len] = '\0'; - val = phonetic( assertv + nextchunk ); + assertv->bv_val[nextchunk+len] = '\0'; + val = phonetic( assertv->bv_val + nextchunk ); /* See if this phonetic chunk is in the remaining words of *value */ for( i=nextavail; i= SLAPD_APPROX_WORDLEN ) wordcount++; c+= len; @@ -1330,32 +899,30 @@ approxIndexer( } /* Allocate/increase storage to account for new keys */ - newkeys = (struct berval **)ch_malloc( (keycount + wordcount + 1) - * sizeof(struct berval *) ); - memcpy( newkeys, keys, keycount * sizeof(struct berval *) ); + 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; ibv_val = phonetic( c ); - keys[keycount]->bv_len = strlen( keys[keycount]->bv_val ); + ber_str2bv( phonetic( c ), 0, 0, &keys[keycount] ); keycount++; i++; } - free( val ); + ber_memfree( val.bv_val ); } - keys[keycount] = NULL; + keys[keycount].bv_val = NULL; *keysp = keys; return LDAP_SUCCESS; } -int +static int approxFilter( slap_mask_t use, slap_mask_t flags, @@ -1363,25 +930,26 @@ approxFilter( MatchingRule *mr, struct berval *prefix, void * assertValue, - struct berval ***keysp ) + BerVarray *keysp ) { - char *val, *c; + char *c; int i, count, len; - struct berval **keys; + struct berval *val; + BerVarray keys; /* Yes, this is necessary */ - val = UTF8normalize( ((struct berval *)assertValue), - UTF8_NOCASEFOLD ); - if( val == NULL ) { - keys = (struct berval **)ch_malloc( sizeof(struct berval *) ); - keys[0] = NULL; + val = UTF8bvnormalize( ((struct berval *)assertValue), + NULL, LDAP_UTF8_APPROX ); + if( val == NULL || val->bv_val == NULL ) { + keys = (struct berval *)ch_malloc( sizeof(struct berval) ); + keys[0].bv_val = NULL; *keysp = keys; + ber_bvfree( val ); 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++) { + for( count = 0,c = val->bv_val; *c; c++) { len = strcspn(c, SLAPD_APPROX_DELIMITER); if( len >= SLAPD_APPROX_WORDLEN ) count++; c+= len; @@ -1390,19 +958,19 @@ approxFilter( } /* Allocate storage for new keys */ - keys = (struct berval **)ch_malloc( (count + 1) * sizeof(struct berval *) ); + keys = (struct berval *)ch_malloc( (count + 1) * sizeof(struct berval) ); /* Get a phonetic copy of each word */ - for( c=val,i=0; ibv_val, i = 0; i < count; c += len + 1 ) { len = strlen(c); if( len < SLAPD_APPROX_WORDLEN ) continue; - keys[i] = ber_bvstr( phonetic( c ) ); + ber_str2bv( phonetic( c ), 0, 0, &keys[i] ); i++; } - free( val ); + ber_bvfree( val ); - keys[count] = NULL; + keys[count].bv_val = NULL; *keysp = keys; return LDAP_SUCCESS; @@ -1454,46 +1022,46 @@ approxMatch( return LDAP_SUCCESS; } -int +static int approxIndexer( slap_mask_t use, slap_mask_t flags, Syntax *syntax, MatchingRule *mr, struct berval *prefix, - struct berval **values, - struct berval ***keysp ) + BerVarray values, + BerVarray *keysp ) { int i; - struct berval **keys; + BerVarray *keys; char *s; - for( i=0; values[i] != NULL; i++ ) { + 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) ); + keys = (struct berval *)ch_malloc( sizeof( struct berval ) * (i+1) ); /* Copy each value and run it through phonetic() */ - for( i=0; values[i] != NULL; i++ ) { + for( i=0; values[i].bv_val != NULL; i++ ) { /* Yes, this is necessary */ - s = UTF8normalize( values[i], UTF8_NOCASEFOLD ); + s = UTF8normalize( &values[i], UTF8_NOCASEFOLD ); /* strip 8-bit chars and run through phonetic() */ - keys[i] = ber_bvstr( phonetic( strip8bitChars( s ) ) ); + ber_str2bv( phonetic( strip8bitChars( s ) ), 0, 0, &keys[i] ); free( s ); } - keys[i] = NULL; + keys[i].bv_val = NULL; *keysp = keys; return LDAP_SUCCESS; } -int +static int approxFilter( slap_mask_t use, slap_mask_t flags, @@ -1501,12 +1069,12 @@ approxFilter( MatchingRule *mr, struct berval *prefix, void * assertValue, - struct berval ***keysp ) + BerVarray *keysp ) { - struct berval **keys; + BerVarray keys; char *s; - keys = (struct berval **)ch_malloc( sizeof( struct berval * ) * 2 ); + keys = (struct berval *)ch_malloc( sizeof( struct berval * ) * 2 ); /* Yes, this is necessary */ s = UTF8normalize( ((struct berval *)assertValue), @@ -1535,9 +1103,9 @@ caseExactMatch( struct berval *value, void *assertedValue ) { - *matchp = UTF8normcmp( value->bv_val, - ((struct berval *) assertedValue)->bv_val, - UTF8_NOCASEFOLD ); + *matchp = UTF8bvnormcmp( value, + (struct berval *) assertedValue, + LDAP_UTF8_NOCASEFOLD ); return LDAP_SUCCESS; } @@ -1552,21 +1120,20 @@ caseExactIgnoreSubstringsMatch( { int match = 0; SubstringsAssertion *sub = NULL; - struct berval left; + struct berval left = { 0, NULL }; int i; ber_len_t inlen=0; - char *nav, casefold; + char *nav = NULL; + unsigned casefold; - casefold = strcmp( mr->smr_oid, caseExactSubstringsMatchOID ) - ? UTF8_CASEFOLD : UTF8_NOCASEFOLD; + casefold = ( mr != caseExactSubstringsMatchingRule ) + ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD; - nav = UTF8normalize( value, casefold ); - if( nav == NULL ) { + if ( UTF8bvnormalize( value, &left, casefold ) == NULL ) { match = 1; goto done; } - left.bv_val = nav; - left.bv_len = strlen( nav ); + nav = left.bv_val; sub = UTF8SubstringsassertionNormalize( assertedValue, casefold ); if( sub == NULL ) { @@ -1575,56 +1142,56 @@ caseExactIgnoreSubstringsMatch( } /* Add up asserted input length */ - if( sub->sa_initial ) { - inlen += sub->sa_initial->bv_len; + if( sub->sa_initial.bv_val ) { + inlen += sub->sa_initial.bv_len; } if( sub->sa_any ) { - for(i=0; sub->sa_any[i] != NULL; i++) { - inlen += sub->sa_any[i]->bv_len; + for(i=0; sub->sa_any[i].bv_val != NULL; i++) { + inlen += sub->sa_any[i].bv_len; } } - if( sub->sa_final ) { - inlen += sub->sa_final->bv_len; + if( sub->sa_final.bv_val ) { + inlen += sub->sa_final.bv_len; } - if( sub->sa_initial ) { + 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 ); + 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; + 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 ) { + 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 ); + 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; + 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]; i++) { + for(i=0; sub->sa_any[i].bv_val; i++) { ber_len_t idx; char *p; @@ -1635,26 +1202,27 @@ retry: goto done; } - if( sub->sa_any[i]->bv_len == 0 ) { + if( sub->sa_any[i].bv_len == 0 ) { continue; } - p = strchr( left.bv_val, *sub->sa_any[i]->bv_val ); - - if( p == NULL ) { + p = ber_bvchr( &left, *sub->sa_any[i].bv_val ); + if ( p == NULL ) { match = 1; goto done; } idx = p - left.bv_val; - assert( idx < left.bv_len ); if( idx >= left.bv_len ) { /* this shouldn't happen */ free( nav ); - ch_free( sub->sa_final ); - ber_bvecfree( sub->sa_any ); - ch_free( sub->sa_initial ); + 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; } @@ -1662,15 +1230,15 @@ retry: left.bv_val = p; left.bv_len -= idx; - if( sub->sa_any[i]->bv_len > left.bv_len ) { + 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 ); + match = memcmp( left.bv_val, + sub->sa_any[i].bv_val, + sub->sa_any[i].bv_len ); if( match != 0 ) { left.bv_val++; @@ -1678,18 +1246,18 @@ retry: 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; + 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 ) { - ber_bvfree( sub->sa_final ); - ber_bvecfree( sub->sa_any ); - ber_bvfree( sub->sa_initial ); + 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; @@ -1697,44 +1265,43 @@ done: } /* Index generation function */ -int caseExactIgnoreIndexer( +static int caseExactIgnoreIndexer( slap_mask_t use, slap_mask_t flags, Syntax *syntax, MatchingRule *mr, struct berval *prefix, - struct berval **values, - struct berval ***keysp ) + BerVarray values, + BerVarray *keysp ) { int i; - char casefold; + unsigned casefold; size_t slen, mlen; - struct berval **keys; + 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] != NULL; i++ ) { + 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) ); + keys = ch_malloc( sizeof( struct berval ) * (i+1) ); - slen = strlen( syntax->ssyn_oid ); - mlen = strlen( mr->smr_oid ); + slen = syntax->ssyn_oidlen; + mlen = mr->smr_oidlen; - casefold = strcmp( mr->smr_oid, caseExactMatchOID ) - ? UTF8_CASEFOLD : UTF8_NOCASEFOLD; + casefold = ( mr != caseExactMatchingRule ) + ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD; - for( i=0; values[i] != NULL; i++ ) { - struct berval *value; - value = ber_bvstr( UTF8normalize( values[i], - casefold ) ); + for( i=0; values[i].bv_val != NULL; i++ ) { + struct berval value; + UTF8bvnormalize( &values[i], &value, casefold ); HASH_Init( &HASHcontext ); if( prefix != NULL && prefix->bv_len > 0 ) { @@ -1746,55 +1313,55 @@ int caseExactIgnoreIndexer( HASH_Update( &HASHcontext, mr->smr_oid, mlen ); HASH_Update( &HASHcontext, - value->bv_val, value->bv_len ); + value.bv_val, value.bv_len ); HASH_Final( HASHdigest, &HASHcontext ); - ber_bvfree( value ); + free( value.bv_val ); - keys[i] = ber_bvdup( &digest ); + ber_dupbv( &keys[i], &digest ); } - keys[i] = NULL; + keys[i].bv_val = NULL; *keysp = keys; return LDAP_SUCCESS; } /* Index generation function */ -int caseExactIgnoreFilter( +static int caseExactIgnoreFilter( slap_mask_t use, slap_mask_t flags, Syntax *syntax, MatchingRule *mr, struct berval *prefix, void * assertValue, - struct berval ***keysp ) + BerVarray *keysp ) { - char casefold; + unsigned casefold; size_t slen, mlen; - struct berval **keys; + BerVarray keys; HASH_CONTEXT HASHcontext; unsigned char HASHdigest[HASH_BYTES]; - struct berval *value; + struct berval value = { 0, NULL }; struct berval digest; + digest.bv_val = HASHdigest; digest.bv_len = sizeof(HASHdigest); - slen = strlen( syntax->ssyn_oid ); - mlen = strlen( mr->smr_oid ); + slen = syntax->ssyn_oidlen; + mlen = mr->smr_oidlen; - casefold = strcmp( mr->smr_oid, caseExactMatchOID ) - ? UTF8_CASEFOLD : UTF8_NOCASEFOLD; + casefold = ( mr != caseExactMatchingRule ) + ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD; - value = ber_bvstr( UTF8normalize( ((struct berval *) assertValue), - casefold ) ); + UTF8bvnormalize( (struct berval *) assertValue, &value, casefold ); /* This usually happens if filter contains bad UTF8 */ - if( value == NULL ) { - keys = ch_malloc( sizeof( struct berval * ) ); - keys[0] = NULL; + 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 ); + keys = ch_malloc( sizeof( struct berval ) * 2 ); HASH_Init( &HASHcontext ); if( prefix != NULL && prefix->bv_len > 0 ) { @@ -1806,33 +1373,33 @@ int caseExactIgnoreFilter( HASH_Update( &HASHcontext, mr->smr_oid, mlen ); HASH_Update( &HASHcontext, - value->bv_val, value->bv_len ); + value.bv_val, value.bv_len ); HASH_Final( HASHdigest, &HASHcontext ); - keys[0] = ber_bvdup( &digest ); - keys[1] = NULL; + ber_dupbv( keys, &digest ); + keys[1].bv_val = NULL; - ber_bvfree( value ); + free( value.bv_val ); *keysp = keys; return LDAP_SUCCESS; } /* Substrings Index generation function */ -int caseExactIgnoreSubstringsIndexer( +static int caseExactIgnoreSubstringsIndexer( slap_mask_t use, slap_mask_t flags, Syntax *syntax, MatchingRule *mr, struct berval *prefix, - struct berval **values, - struct berval ***keysp ) + BerVarray values, + BerVarray *keysp ) { - char casefold; + unsigned casefold; ber_len_t i, nkeys; size_t slen, mlen; - struct berval **keys; - struct berval **nvalues; + BerVarray keys; + BerVarray nvalues; HASH_CONTEXT HASHcontext; unsigned char HASHdigest[HASH_BYTES]; @@ -1842,51 +1409,50 @@ int caseExactIgnoreSubstringsIndexer( nkeys=0; - for( i=0; values[i] != NULL; i++ ) { + 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 ) - ? UTF8_CASEFOLD : UTF8_NOCASEFOLD; + casefold = ( mr != caseExactSubstringsMatchingRule ) + ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD; - nvalues = ch_malloc( sizeof( struct berval * ) * (i+1) ); - for( i=0; values[i] != NULL; i++ ) { - nvalues[i] = ber_bvstr( UTF8normalize( values[i], - casefold ) ); + nvalues = ch_malloc( sizeof( struct berval ) * (i+1) ); + for( i=0; values[i].bv_val != NULL; i++ ) { + UTF8bvnormalize( &values[i], &nvalues[i], casefold ); } - nvalues[i] = NULL; + nvalues[i].bv_val = NULL; values = nvalues; - for( i=0; values[i] != NULL; i++ ) { + for( i=0; values[i].bv_val != NULL; i++ ) { /* count number of indices to generate */ - if( values[i]->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) { + 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 ) { + 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 ); + 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( 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 ) { + 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 ); + nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 ); } } } @@ -1894,29 +1460,26 @@ int caseExactIgnoreSubstringsIndexer( if( nkeys == 0 ) { /* no keys to generate */ *keysp = NULL; - ber_bvecfree( nvalues ); + ber_bvarray_free( nvalues ); return LDAP_SUCCESS; } - keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) ); + keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) ); - slen = strlen( syntax->ssyn_oid ); - mlen = strlen( mr->smr_oid ); + slen = syntax->ssyn_oidlen; + mlen = mr->smr_oidlen; nkeys=0; - for( i=0; values[i] != NULL; i++ ) { + for( i=0; values[i].bv_val != NULL; i++ ) { ber_len_t j,max; - struct berval *value; - if( values[i]->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue; - - value = values[i]; + if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue; if( ( flags & SLAP_INDEX_SUBSTR_ANY ) && - ( value->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) ) + ( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) ) { char pre = SLAP_INDEX_SUBSTR_PREFIX; - max = value->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1); + max = values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1); for( j=0; jsmr_oid, mlen ); HASH_Update( &HASHcontext, - &value->bv_val[j], + &values[i].bv_val[j], SLAP_INDEX_SUBSTR_MAXLEN ); HASH_Final( HASHdigest, &HASHcontext ); - keys[nkeys++] = ber_bvdup( &digest ); + ber_dupbv( &keys[nkeys++], &digest ); } } - max = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len - ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len; + 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; @@ -1960,10 +1523,10 @@ int caseExactIgnoreSubstringsIndexer( HASH_Update( &HASHcontext, mr->smr_oid, mlen ); HASH_Update( &HASHcontext, - value->bv_val, j ); + values[i].bv_val, j ); HASH_Final( HASHdigest, &HASHcontext ); - keys[nkeys++] = ber_bvdup( &digest ); + ber_dupbv( &keys[nkeys++], &digest ); } if( flags & SLAP_INDEX_SUBSTR_FINAL ) { @@ -1980,10 +1543,10 @@ int caseExactIgnoreSubstringsIndexer( HASH_Update( &HASHcontext, mr->smr_oid, mlen ); HASH_Update( &HASHcontext, - &value->bv_val[value->bv_len-j], j ); + &values[i].bv_val[values[i].bv_len-j], j ); HASH_Final( HASHdigest, &HASHcontext ); - keys[nkeys++] = ber_bvdup( &digest ); + ber_dupbv( &keys[nkeys++], &digest ); } } @@ -1991,39 +1554,40 @@ int caseExactIgnoreSubstringsIndexer( } if( nkeys > 0 ) { - keys[nkeys] = NULL; + keys[nkeys].bv_val = NULL; *keysp = keys; } else { ch_free( keys ); *keysp = NULL; } - ber_bvecfree( nvalues ); + ber_bvarray_free( nvalues ); return LDAP_SUCCESS; } -int caseExactIgnoreSubstringsFilter( +static int caseExactIgnoreSubstringsFilter( slap_mask_t use, slap_mask_t flags, Syntax *syntax, MatchingRule *mr, struct berval *prefix, void * assertValue, - struct berval ***keysp ) + BerVarray *keysp ) { SubstringsAssertion *sa; - char pre, casefold; + char pre; + unsigned casefold; ber_len_t nkeys = 0; size_t slen, mlen, klen; - struct berval **keys; + BerVarray keys; HASH_CONTEXT HASHcontext; unsigned char HASHdigest[HASH_BYTES]; struct berval *value; struct berval digest; - casefold = strcmp( mr->smr_oid, caseExactSubstringsMatchOID ) - ? UTF8_CASEFOLD : UTF8_NOCASEFOLD; + casefold = ( mr != caseExactSubstringsMatchingRule ) + ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD; sa = UTF8SubstringsassertionNormalize( assertValue, casefold ); if( sa == NULL ) { @@ -2031,33 +1595,33 @@ int caseExactIgnoreSubstringsFilter( return LDAP_SUCCESS; } - if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial != NULL && - sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN ) + 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] != NULL; i++ ) { - if( sa->sa_any[i]->bv_len >= 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 ) { /* don't bother accounting for stepping */ - nkeys += sa->sa_any[i]->bv_len - + nkeys += sa->sa_any[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 ); } } } - if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final != NULL && - sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN ) + 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 ) { - ber_bvfree( sa->sa_final ); - ber_bvecfree( sa->sa_any ); - ber_bvfree( sa->sa_initial ); + 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; @@ -2066,17 +1630,17 @@ int caseExactIgnoreSubstringsFilter( digest.bv_val = HASHdigest; digest.bv_len = sizeof(HASHdigest); - slen = strlen( syntax->ssyn_oid ); - mlen = strlen( mr->smr_oid ); + slen = syntax->ssyn_oidlen; + mlen = mr->smr_oidlen; - keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) ); + keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) ); nkeys = 0; - if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial != NULL && - sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN ) + 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; + value = &sa->sa_initial; klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len; @@ -2096,7 +1660,7 @@ int caseExactIgnoreSubstringsFilter( value->bv_val, klen ); HASH_Final( HASHdigest, &HASHcontext ); - keys[nkeys++] = ber_bvdup( &digest ); + ber_dupbv( &keys[nkeys++], &digest ); } if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) { @@ -2104,12 +1668,12 @@ int caseExactIgnoreSubstringsFilter( pre = SLAP_INDEX_SUBSTR_PREFIX; klen = SLAP_INDEX_SUBSTR_MAXLEN; - for( i=0; sa->sa_any[i] != NULL; i++ ) { - if( sa->sa_any[i]->bv_len < 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]; + value = &sa->sa_any[i]; for(j=0; j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN; @@ -2130,17 +1694,17 @@ int caseExactIgnoreSubstringsFilter( &value->bv_val[j], klen ); HASH_Final( HASHdigest, &HASHcontext ); - keys[nkeys++] = ber_bvdup( &digest ); + ber_dupbv( &keys[nkeys++], &digest ); } } } - if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final != NULL && - sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN ) + 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; + value = &sa->sa_final; klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len; @@ -2160,19 +1724,19 @@ int caseExactIgnoreSubstringsFilter( &value->bv_val[value->bv_len-klen], klen ); HASH_Final( HASHdigest, &HASHcontext ); - keys[nkeys++] = ber_bvdup( &digest ); + ber_dupbv( &keys[nkeys++], &digest ); } if( nkeys > 0 ) { - keys[nkeys] = NULL; + keys[nkeys].bv_val = NULL; *keysp = keys; } else { ch_free( keys ); *keysp = NULL; } - ber_bvfree( sa->sa_final ); - ber_bvecfree( sa->sa_any ); - ber_bvfree( sa->sa_initial ); + 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; @@ -2187,12 +1751,43 @@ caseIgnoreMatch( struct berval *value, void *assertedValue ) { - *matchp = UTF8normcmp( value->bv_val, - ((struct berval *) assertedValue)->bv_val, - UTF8_CASEFOLD ); + *matchp = UTF8bvnormcmp( value, + (struct berval *) assertedValue, + LDAP_UTF8_CASEFOLD ); return LDAP_SUCCESS; } +/* Remove all spaces and '-' characters */ +static int +telephoneNumberNormalize( + Syntax *syntax, + struct berval *val, + struct berval *normalized ) +{ + char *p, *q; + + /* validator should have refused an empty string */ + assert( val->bv_len ); + + q = normalized->bv_val = ch_malloc( val->bv_len + 1 ); + + for( p = val->bv_val; *p; p++ ) { + if ( ! ( ASCII_SPACE( *p ) || *p == '-' )) { + *q++ = *p; + } + } + *q = '\0'; + + normalized->bv_len = q - normalized->bv_val; + + if( normalized->bv_len == 0 ) { + free( normalized->bv_val ); + return LDAP_INVALID_SYNTAX; + } + + return LDAP_SUCCESS; +} + static int oidValidate( Syntax *syntax, @@ -2242,85 +1837,47 @@ integerMatch( void *assertedValue ) { char *v, *av; - int vsign=0, avsign=0; + int vsign = 1, avsign = 1; /* default sign = '+' */ struct berval *asserted; ber_len_t vlen, avlen; + int match; - - /* Start off pessimistic */ - *matchp = 1; - - /* Skip past leading spaces/zeros, and get the sign of the *value number */ + /* Skip leading space/sign/zeroes, 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 == '-' ) { + if( mr == integerFirstComponentMatchingRule ) { + char *tmp = memchr( v, '$', vlen ); + if( tmp ) + vlen = tmp - v; + while( vlen && ASCII_SPACE( v[vlen-1] )) + vlen--; + } + for( ; vlen && ( *v < '1' || '9' < *v ); v++, vlen-- ) /* ANSI 2.2.1 */ + if( *v == '-' ) vsign = -1; - } - else if ( ASCII_DIGIT(*v) ) { - if ( vsign == 0 ) vsign = 1; - vsign *= 2; - break; - } - v++; - vlen--; - } + if( vlen == 0 ) + vsign = 0; - /* Skip past leading spaces/zeros, and get the sign of the *assertedValue - number */ + /* Do the same with 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 == '-' ) { + for( ; avlen && ( *av < '1' || '9' < *av ); av++, avlen-- ) + 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( avlen == 0 ) + avsign = 0; - if( vsign != avsign ) return LDAP_SUCCESS; - - /* Check the significant digits */ - while( vlen && avlen ) { - if( *v != *av ) break; - v++; - vlen--; - av++; - avlen--; + match = vsign - avsign; + if( match == 0 ) { + match = (vlen != avlen + ? ( vlen < avlen ? -1 : 1 ) + : memcmp( v, av, vlen )); + if( vsign < 0 ) + match = -match; } - /* If all digits compared equal, the numbers are equal */ - if(( vlen == 0 ) && ( avlen == 0 )) { - *matchp = 0; - } + *matchp = match; return LDAP_SUCCESS; } @@ -2350,11 +1907,10 @@ static int integerNormalize( Syntax *syntax, struct berval *val, - struct berval **normalized ) + struct berval *normalized ) { char *p; int negative=0; - struct berval *newval; ber_len_t len; @@ -2382,75 +1938,126 @@ integerNormalize( len--; } - newval = (struct berval *) ch_malloc( sizeof(struct berval) ); - /* 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 ) { - newval->bv_val = ch_strdup("0"); - newval->bv_len = 1; + normalized->bv_val = ch_strdup("0"); + normalized->bv_len = 1; } else { - newval->bv_len = len+negative; - newval->bv_val = ch_malloc( newval->bv_len ); + normalized->bv_len = len+negative; + normalized->bv_val = ch_malloc( normalized->bv_len + 1 ); if( negative ) { - newval->bv_val[0] = '-'; + normalized->bv_val[0] = '-'; } - memcpy( newval->bv_val + negative, p, len ); + AC_MEMCPY( normalized->bv_val + negative, p, len ); + normalized->bv_val[len+negative] = '\0'; } - *normalized = newval; return LDAP_SUCCESS; } /* Index generation function */ -int integerIndexer( +static int integerIndexer( slap_mask_t use, slap_mask_t flags, Syntax *syntax, MatchingRule *mr, struct berval *prefix, - struct berval **values, - struct berval ***keysp ) + BerVarray values, + BerVarray *keysp ) { int i; - struct berval **keys; + 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( values != NULL && values[0] != NULL ); + assert( i > 0 ); - for( i=0; values[i] != NULL; i++ ) { - /* empty -- just count them */ - } + keys = ch_malloc( sizeof( struct berval ) * (i+1) ); - keys = ch_malloc( sizeof( struct berval * ) * (i+1) ); + slen = syntax->ssyn_oidlen; + mlen = mr->smr_oidlen; - for( i=0; values[i] != NULL; i++ ) { - integerNormalize( syntax, values[i], &keys[i] ); + for( i=0; values[i].bv_val != NULL; i++ ) { + struct berval norm; + integerNormalize( syntax, &values[i], &norm ); + + 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, + norm.bv_val, norm.bv_len ); + HASH_Final( HASHdigest, &HASHcontext ); + + ber_dupbv( &keys[i], &digest ); + ch_free( norm.bv_val ); } - keys[i] = NULL; + keys[i].bv_val = NULL; *keysp = keys; return LDAP_SUCCESS; } /* Index generation function */ -int integerFilter( +static int integerFilter( slap_mask_t use, slap_mask_t flags, Syntax *syntax, MatchingRule *mr, struct berval *prefix, void * assertValue, - struct berval ***keysp ) + BerVarray *keysp ) { - struct berval **keys; + size_t slen, mlen; + BerVarray keys; + HASH_CONTEXT HASHcontext; + unsigned char HASHdigest[HASH_BYTES]; + struct berval norm; + struct berval digest; + digest.bv_val = HASHdigest; + digest.bv_len = sizeof(HASHdigest); - keys = ch_malloc( sizeof( struct berval * ) * 2 ); - integerNormalize( syntax, assertValue, &keys[0] ); - keys[1] = NULL; - *keysp = keys; + slen = syntax->ssyn_oidlen; + mlen = mr->smr_oidlen; + + integerNormalize( syntax, assertValue, &norm ); + + 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, + norm.bv_val, norm.bv_len ); + HASH_Final( HASHdigest, &HASHcontext ); + ber_dupbv( &keys[0], &digest ); + keys[1].bv_val = NULL; + ch_free( norm.bv_val ); + + *keysp = keys; return LDAP_SUCCESS; } @@ -2479,7 +2086,7 @@ printableStringValidate( { ber_len_t i; - if( !val->bv_len ) return LDAP_INVALID_SYNTAX; + if( val->bv_len == 0 ) return LDAP_INVALID_SYNTAX; for(i=0; i < val->bv_len; i++) { if( !SLAP_PRINTABLE(val->bv_val[i]) ) { @@ -2495,16 +2102,30 @@ printablesStringValidate( Syntax *syntax, struct berval *val ) { - ber_len_t i; + ber_len_t i, len; - if( !val->bv_len ) return LDAP_INVALID_SYNTAX; + if( val->bv_len == 0 ) return LDAP_INVALID_SYNTAX; - for(i=0; i < val->bv_len; i++) { - if( !SLAP_PRINTABLES(val->bv_val[i]) ) { + for(i=0,len=0; i < val->bv_len; i++) { + int c = val->bv_val[i]; + + if( c == '$' ) { + if( len == 0 ) { + return LDAP_INVALID_SYNTAX; + } + len = 0; + + } else if ( SLAP_PRINTABLE(c) ) { + len++; + } else { return LDAP_INVALID_SYNTAX; } } + if( len == 0 ) { + return LDAP_INVALID_SYNTAX; + } + return LDAP_SUCCESS; } @@ -2515,10 +2136,12 @@ IA5StringValidate( { ber_len_t i; - if( !val->bv_len ) return LDAP_INVALID_SYNTAX; + if( val->bv_len == 0 ) return LDAP_INVALID_SYNTAX; for(i=0; i < val->bv_len; i++) { - if( !isascii(val->bv_val[i]) ) return LDAP_INVALID_SYNTAX; + if( !LDAP_ASCII(val->bv_val[i]) ) { + return LDAP_INVALID_SYNTAX; + } } return LDAP_SUCCESS; @@ -2528,12 +2151,11 @@ static int IA5StringNormalize( Syntax *syntax, struct berval *val, - struct berval **normalized ) + struct berval *normalized ) { - struct berval *newval; char *p, *q; - newval = ch_malloc( sizeof( struct berval ) ); + assert( val->bv_len ); p = val->bv_val; @@ -2542,13 +2164,8 @@ IA5StringNormalize( p++; } - if( *p == '\0' ) { - ch_free( newval ); - return LDAP_INVALID_SYNTAX; - } - - newval->bv_val = ch_strdup( p ); - p = q = newval->bv_val; + normalized->bv_val = ch_strdup( p ); + p = q = normalized->bv_val; while ( *p ) { if ( ASCII_SPACE( *p ) ) { @@ -2563,13 +2180,9 @@ IA5StringNormalize( } } - assert( *newval->bv_val ); - assert( newval->bv_val < p ); + assert( normalized->bv_val <= p ); assert( q <= p ); - /* cannot start with a space */ - assert( !ASCII_SPACE(*newval->bv_val) ); - /* * If the string ended in space, backup the pointer one * position. One is enough because the above loop collapsed @@ -2580,14 +2193,17 @@ IA5StringNormalize( --q; } - /* cannot end with a space */ - assert( !ASCII_SPACE( q[-1] ) ); - /* null terminate */ *q = '\0'; - newval->bv_len = q - newval->bv_val; - *normalized = newval; + normalized->bv_len = q - normalized->bv_val; + + if( normalized->bv_len == 0 ) { + normalized->bv_val = ch_realloc( normalized->bv_val, 2 ); + normalized->bv_val[0] = ' '; + normalized->bv_val[1] = '\0'; + normalized->bv_len = 1; + } return LDAP_SUCCESS; } @@ -2629,56 +2245,56 @@ caseExactIA5SubstringsMatch( ber_len_t inlen=0; /* Add up asserted input length */ - if( sub->sa_initial ) { - inlen += sub->sa_initial->bv_len; + if( sub->sa_initial.bv_val ) { + inlen += sub->sa_initial.bv_len; } if( sub->sa_any ) { - for(i=0; sub->sa_any[i] != NULL; i++) { - inlen += sub->sa_any[i]->bv_len; + for(i=0; sub->sa_any[i].bv_val != NULL; i++) { + inlen += sub->sa_any[i].bv_len; } } - if( sub->sa_final ) { - inlen += sub->sa_final->bv_len; + if( sub->sa_final.bv_val ) { + inlen += sub->sa_final.bv_len; } - if( sub->sa_initial ) { + 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 ); + 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; + 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 ) { + 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 ); + 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; + 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]; i++) { + for(i=0; sub->sa_any[i].bv_val; i++) { ber_len_t idx; char *p; @@ -2689,11 +2305,11 @@ retry: goto done; } - if( sub->sa_any[i]->bv_len == 0 ) { + if( sub->sa_any[i].bv_len == 0 ) { continue; } - p = strchr( left.bv_val, *sub->sa_any[i]->bv_val ); + p = strchr( left.bv_val, *sub->sa_any[i].bv_val ); if( p == NULL ) { match = 1; @@ -2701,7 +2317,6 @@ retry: } idx = p - left.bv_val; - assert( idx < left.bv_len ); if( idx >= left.bv_len ) { /* this shouldn't happen */ @@ -2711,15 +2326,15 @@ retry: left.bv_val = p; left.bv_len -= idx; - if( sub->sa_any[i]->bv_len > left.bv_len ) { + 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 ); + sub->sa_any[i].bv_val, + sub->sa_any[i].bv_len ); if( match != 0 ) { left.bv_val++; @@ -2727,9 +2342,9 @@ retry: 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; + 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; } } @@ -2739,38 +2354,38 @@ done: } /* Index generation function */ -int caseExactIA5Indexer( +static int caseExactIA5Indexer( slap_mask_t use, slap_mask_t flags, Syntax *syntax, MatchingRule *mr, struct berval *prefix, - struct berval **values, - struct berval ***keysp ) + BerVarray values, + BerVarray *keysp ) { int i; size_t slen, mlen; - struct berval **keys; + 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] != NULL; i++ ) { + 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) ); + keys = ch_malloc( sizeof( struct berval ) * (i+1) ); - slen = strlen( syntax->ssyn_oid ); - mlen = strlen( mr->smr_oid ); + slen = syntax->ssyn_oidlen; + mlen = mr->smr_oidlen; - for( i=0; values[i] != NULL; i++ ) { - struct berval *value = values[i]; + for( i=0; values[i].bv_val != NULL; i++ ) { + struct berval *value = &values[i]; HASH_Init( &HASHcontext ); if( prefix != NULL && prefix->bv_len > 0 ) { @@ -2785,26 +2400,26 @@ int caseExactIA5Indexer( value->bv_val, value->bv_len ); HASH_Final( HASHdigest, &HASHcontext ); - keys[i] = ber_bvdup( &digest ); + ber_dupbv( &keys[i], &digest ); } - keys[i] = NULL; + keys[i].bv_val = NULL; *keysp = keys; return LDAP_SUCCESS; } /* Index generation function */ -int caseExactIA5Filter( +static int caseExactIA5Filter( slap_mask_t use, slap_mask_t flags, Syntax *syntax, MatchingRule *mr, struct berval *prefix, void * assertValue, - struct berval ***keysp ) + BerVarray *keysp ) { size_t slen, mlen; - struct berval **keys; + BerVarray keys; HASH_CONTEXT HASHcontext; unsigned char HASHdigest[HASH_BYTES]; struct berval *value; @@ -2812,12 +2427,12 @@ int caseExactIA5Filter( digest.bv_val = HASHdigest; digest.bv_len = sizeof(HASHdigest); - slen = strlen( syntax->ssyn_oid ); - mlen = strlen( mr->smr_oid ); + slen = syntax->ssyn_oidlen; + mlen = mr->smr_oidlen; value = (struct berval *) assertValue; - keys = ch_malloc( sizeof( struct berval * ) * 2 ); + keys = ch_malloc( sizeof( struct berval ) * 2 ); HASH_Init( &HASHcontext ); if( prefix != NULL && prefix->bv_len > 0 ) { @@ -2832,26 +2447,26 @@ int caseExactIA5Filter( value->bv_val, value->bv_len ); HASH_Final( HASHdigest, &HASHcontext ); - keys[0] = ber_bvdup( &digest ); - keys[1] = NULL; + ber_dupbv( &keys[0], &digest ); + keys[1].bv_val = NULL; *keysp = keys; return LDAP_SUCCESS; } /* Substrings Index generation function */ -int caseExactIA5SubstringsIndexer( +static int caseExactIA5SubstringsIndexer( slap_mask_t use, slap_mask_t flags, Syntax *syntax, MatchingRule *mr, struct berval *prefix, - struct berval **values, - struct berval ***keysp ) + BerVarray values, + BerVarray *keysp ) { ber_len_t i, nkeys; size_t slen, mlen; - struct berval **keys; + BerVarray keys; HASH_CONTEXT HASHcontext; unsigned char HASHdigest[HASH_BYTES]; struct berval digest; @@ -2859,36 +2474,36 @@ int caseExactIA5SubstringsIndexer( digest.bv_len = sizeof(HASHdigest); /* we should have at least one value at this point */ - assert( values != NULL && values[0] != NULL ); + assert( values != NULL && values[0].bv_val != NULL ); nkeys=0; - for( i=0; values[i] != NULL; i++ ) { + for( i=0; values[i].bv_val != NULL; i++ ) { /* count number of indices to generate */ - if( values[i]->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) { + 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 ) { + 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 ); + 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( 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 ) { + 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 ); + nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 ); } } } @@ -2899,17 +2514,17 @@ int caseExactIA5SubstringsIndexer( return LDAP_SUCCESS; } - keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) ); + keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) ); - slen = strlen( syntax->ssyn_oid ); - mlen = strlen( mr->smr_oid ); + slen = syntax->ssyn_oidlen; + mlen = mr->smr_oidlen; nkeys=0; - for( i=0; values[i] != NULL; i++ ) { + for( i=0; values[i].bv_val != NULL; i++ ) { ber_len_t j,max; struct berval *value; - value = values[i]; + value = &values[i]; if( value->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue; if( ( flags & SLAP_INDEX_SUBSTR_ANY ) && @@ -2936,7 +2551,7 @@ int caseExactIA5SubstringsIndexer( SLAP_INDEX_SUBSTR_MAXLEN ); HASH_Final( HASHdigest, &HASHcontext ); - keys[nkeys++] = ber_bvdup( &digest ); + ber_dupbv( &keys[nkeys++], &digest ); } } @@ -2963,7 +2578,7 @@ int caseExactIA5SubstringsIndexer( value->bv_val, j ); HASH_Final( HASHdigest, &HASHcontext ); - keys[nkeys++] = ber_bvdup( &digest ); + ber_dupbv( &keys[nkeys++], &digest ); } if( flags & SLAP_INDEX_SUBSTR_FINAL ) { @@ -2983,14 +2598,14 @@ int caseExactIA5SubstringsIndexer( &value->bv_val[value->bv_len-j], j ); HASH_Final( HASHdigest, &HASHcontext ); - keys[nkeys++] = ber_bvdup( &digest ); + ber_dupbv( &keys[nkeys++], &digest ); } } } if( nkeys > 0 ) { - keys[nkeys] = NULL; + keys[nkeys].bv_val = NULL; *keysp = keys; } else { ch_free( keys ); @@ -3000,44 +2615,44 @@ int caseExactIA5SubstringsIndexer( return LDAP_SUCCESS; } -int caseExactIA5SubstringsFilter( +static int caseExactIA5SubstringsFilter( slap_mask_t use, slap_mask_t flags, Syntax *syntax, MatchingRule *mr, struct berval *prefix, void * assertValue, - struct berval ***keysp ) + BerVarray *keysp ) { SubstringsAssertion *sa = assertValue; char pre; ber_len_t nkeys = 0; size_t slen, mlen, klen; - struct berval **keys; + BerVarray keys; HASH_CONTEXT HASHcontext; unsigned char HASHdigest[HASH_BYTES]; struct berval *value; struct berval digest; - if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial != NULL && - sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN ) + 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] != NULL; i++ ) { - if( sa->sa_any[i]->bv_len >= 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 ) { /* don't bother accounting for stepping */ - nkeys += sa->sa_any[i]->bv_len - + nkeys += sa->sa_any[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 ); } } } - if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final != NULL && - sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN ) + if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL && + sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN ) { nkeys++; } @@ -3050,17 +2665,17 @@ int caseExactIA5SubstringsFilter( digest.bv_val = HASHdigest; digest.bv_len = sizeof(HASHdigest); - slen = strlen( syntax->ssyn_oid ); - mlen = strlen( mr->smr_oid ); + slen = syntax->ssyn_oidlen; + mlen = mr->smr_oidlen; - keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) ); + keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) ); nkeys = 0; - if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial != NULL && - sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN ) + 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; + value = &sa->sa_initial; klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len; @@ -3080,7 +2695,7 @@ int caseExactIA5SubstringsFilter( value->bv_val, klen ); HASH_Final( HASHdigest, &HASHcontext ); - keys[nkeys++] = ber_bvdup( &digest ); + ber_dupbv( &keys[nkeys++], &digest ); } if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) { @@ -3088,12 +2703,12 @@ int caseExactIA5SubstringsFilter( pre = SLAP_INDEX_SUBSTR_PREFIX; klen = SLAP_INDEX_SUBSTR_MAXLEN; - for( i=0; sa->sa_any[i] != NULL; i++ ) { - if( sa->sa_any[i]->bv_len < 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]; + value = &sa->sa_any[i]; for(j=0; j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN; @@ -3114,16 +2729,16 @@ int caseExactIA5SubstringsFilter( &value->bv_val[j], klen ); HASH_Final( HASHdigest, &HASHcontext ); - keys[nkeys++] = ber_bvdup( &digest ); + ber_dupbv( &keys[nkeys++], &digest ); } } } - if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final != NULL && - sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN ) + 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; + value = &sa->sa_final; klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len; @@ -3143,11 +2758,11 @@ int caseExactIA5SubstringsFilter( &value->bv_val[value->bv_len-klen], klen ); HASH_Final( HASHdigest, &HASHcontext ); - keys[nkeys++] = ber_bvdup( &digest ); + ber_dupbv( &keys[nkeys++], &digest ); } if( nkeys > 0 ) { - keys[nkeys] = NULL; + keys[nkeys].bv_val = NULL; *keysp = keys; } else { ch_free( keys ); @@ -3194,56 +2809,56 @@ caseIgnoreIA5SubstringsMatch( ber_len_t inlen=0; /* Add up asserted input length */ - if( sub->sa_initial ) { - inlen += sub->sa_initial->bv_len; + if( sub->sa_initial.bv_val ) { + inlen += sub->sa_initial.bv_len; } if( sub->sa_any ) { - for(i=0; sub->sa_any[i] != NULL; i++) { - inlen += sub->sa_any[i]->bv_len; + for(i=0; sub->sa_any[i].bv_val != NULL; i++) { + inlen += sub->sa_any[i].bv_len; } } - if( sub->sa_final ) { - inlen += sub->sa_final->bv_len; + if( sub->sa_final.bv_val ) { + inlen += sub->sa_final.bv_len; } - if( sub->sa_initial ) { + if( sub->sa_initial.bv_val ) { if( inlen > left.bv_len ) { match = 1; goto done; } - match = strncasecmp( sub->sa_initial->bv_val, left.bv_val, - sub->sa_initial->bv_len ); + match = strncasecmp( 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; + 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 ) { + if( sub->sa_final.bv_val ) { if( inlen > left.bv_len ) { match = 1; goto done; } - match = strncasecmp( sub->sa_final->bv_val, - &left.bv_val[left.bv_len - sub->sa_final->bv_len], - sub->sa_final->bv_len ); + match = strncasecmp( 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; + 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]; i++) { + for(i=0; sub->sa_any[i].bv_val; i++) { ber_len_t idx; char *p; @@ -3254,20 +2869,18 @@ retry: goto done; } - if( sub->sa_any[i]->bv_len == 0 ) { + if( sub->sa_any[i].bv_len == 0 ) { continue; } - p = strcasechr( left.bv_val, *sub->sa_any[i]->bv_val ); + p = bvcasechr( &left, *sub->sa_any[i].bv_val, &idx ); if( p == NULL ) { match = 1; goto done; } - idx = p - left.bv_val; assert( idx < left.bv_len ); - if( idx >= left.bv_len ) { /* this shouldn't happen */ return LDAP_OTHER; @@ -3276,15 +2889,15 @@ retry: left.bv_val = p; left.bv_len -= idx; - if( sub->sa_any[i]->bv_len > left.bv_len ) { + if( sub->sa_any[i].bv_len > left.bv_len ) { /* not enough left */ match = 1; goto done; } match = strncasecmp( left.bv_val, - sub->sa_any[i]->bv_val, - sub->sa_any[i]->bv_len ); + sub->sa_any[i].bv_val, + sub->sa_any[i].bv_len ); if( match != 0 ) { left.bv_val++; @@ -3293,9 +2906,9 @@ retry: 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; + 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; } } @@ -3305,18 +2918,19 @@ done: } /* Index generation function */ -int caseIgnoreIA5Indexer( +static int caseIgnoreIA5Indexer( slap_mask_t use, slap_mask_t flags, Syntax *syntax, MatchingRule *mr, struct berval *prefix, - struct berval **values, - struct berval ***keysp ) + BerVarray values, + BerVarray *keysp ) { int i; + int rc = LDAP_SUCCESS; size_t slen, mlen; - struct berval **keys; + BerVarray keys; HASH_CONTEXT HASHcontext; unsigned char HASHdigest[HASH_BYTES]; struct berval digest; @@ -3324,20 +2938,35 @@ int caseIgnoreIA5Indexer( digest.bv_len = sizeof(HASHdigest); /* we should have at least one value at this point */ - assert( values != NULL && values[0] != NULL ); + assert( values != NULL && values[0].bv_val != NULL ); - for( i=0; values[i] != NULL; i++ ) { + for( i=0; values[i].bv_val != NULL; i++ ) { /* just count them */ } - keys = ch_malloc( sizeof( struct berval * ) * (i+1) ); + keys = ch_malloc( sizeof( struct berval ) * (i+1) ); + + slen = syntax->ssyn_oidlen; + mlen = mr->smr_oidlen; - slen = strlen( syntax->ssyn_oid ); - mlen = strlen( mr->smr_oid ); + for( i=0; values[i].bv_val != NULL; i++ ) { + struct berval value; + + if( mr->smr_normalize ) { + rc = (mr->smr_normalize)( use, syntax, mr, &values[i], &value ); + if( rc != LDAP_SUCCESS ) { + break; + } + } else if ( mr->smr_syntax->ssyn_normalize ) { + rc = (mr->smr_syntax->ssyn_normalize)( syntax, &values[i], &value ); + if( rc != LDAP_SUCCESS ) { + break; + } + } else { + ber_dupbv( &value, &values[i] ); + } - for( i=0; values[i] != NULL; i++ ) { - struct berval *value = ber_bvdup( values[i] ); - ldap_pvt_str2upper( value->bv_val ); + ldap_pvt_str2lower( value.bv_val ); HASH_Init( &HASHcontext ); if( prefix != NULL && prefix->bv_len > 0 ) { @@ -3349,45 +2978,49 @@ int caseIgnoreIA5Indexer( HASH_Update( &HASHcontext, mr->smr_oid, mlen ); HASH_Update( &HASHcontext, - value->bv_val, value->bv_len ); + value.bv_val, value.bv_len ); HASH_Final( HASHdigest, &HASHcontext ); - ber_bvfree( value ); + free( value.bv_val ); - keys[i] = ber_bvdup( &digest ); + ber_dupbv( &keys[i], &digest ); } - keys[i] = NULL; + keys[i].bv_val = NULL; + if( rc != LDAP_SUCCESS ) { + ber_bvarray_free( keys ); + keys = NULL; + } *keysp = keys; - return LDAP_SUCCESS; + return rc; } /* Index generation function */ -int caseIgnoreIA5Filter( +static int caseIgnoreIA5Filter( slap_mask_t use, slap_mask_t flags, Syntax *syntax, MatchingRule *mr, struct berval *prefix, void * assertValue, - struct berval ***keysp ) + BerVarray *keysp ) { size_t slen, mlen; - struct berval **keys; + BerVarray keys; HASH_CONTEXT HASHcontext; unsigned char HASHdigest[HASH_BYTES]; - struct berval *value; + struct berval value; struct berval digest; digest.bv_val = HASHdigest; digest.bv_len = sizeof(HASHdigest); - slen = strlen( syntax->ssyn_oid ); - mlen = strlen( mr->smr_oid ); + slen = syntax->ssyn_oidlen; + mlen = mr->smr_oidlen; - value = ber_bvdup( (struct berval *) assertValue ); - ldap_pvt_str2upper( value->bv_val ); + ber_dupbv( &value, (struct berval *) assertValue ); + ldap_pvt_str2lower( value.bv_val ); - keys = ch_malloc( sizeof( struct berval * ) * 2 ); + keys = ch_malloc( sizeof( struct berval ) * 2 ); HASH_Init( &HASHcontext ); if( prefix != NULL && prefix->bv_len > 0 ) { @@ -3399,13 +3032,13 @@ int caseIgnoreIA5Filter( HASH_Update( &HASHcontext, mr->smr_oid, mlen ); HASH_Update( &HASHcontext, - value->bv_val, value->bv_len ); + value.bv_val, value.bv_len ); HASH_Final( HASHdigest, &HASHcontext ); - keys[0] = ber_bvdup( &digest ); - keys[1] = NULL; + ber_dupbv( &keys[0], &digest ); + keys[1].bv_val = NULL; - ber_bvfree( value ); + free( value.bv_val ); *keysp = keys; @@ -3413,18 +3046,18 @@ int caseIgnoreIA5Filter( } /* Substrings Index generation function */ -int caseIgnoreIA5SubstringsIndexer( +static int caseIgnoreIA5SubstringsIndexer( slap_mask_t use, slap_mask_t flags, Syntax *syntax, MatchingRule *mr, struct berval *prefix, - struct berval **values, - struct berval ***keysp ) + BerVarray values, + BerVarray *keysp ) { ber_len_t i, nkeys; size_t slen, mlen; - struct berval **keys; + BerVarray keys; HASH_CONTEXT HASHcontext; unsigned char HASHdigest[HASH_BYTES]; struct berval digest; @@ -3432,36 +3065,36 @@ int caseIgnoreIA5SubstringsIndexer( digest.bv_len = sizeof(HASHdigest); /* we should have at least one value at this point */ - assert( values != NULL && values[0] != NULL ); + assert( values != NULL && values[0].bv_val != NULL ); nkeys=0; - for( i=0; values[i] != NULL; i++ ) { + for( i=0; values[i].bv_val != NULL; i++ ) { /* count number of indices to generate */ - if( values[i]->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) { + 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 ) { + 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 ); + 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( 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 ) { + 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 ); + nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 ); } } } @@ -3472,26 +3105,26 @@ int caseIgnoreIA5SubstringsIndexer( return LDAP_SUCCESS; } - keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) ); + keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) ); - slen = strlen( syntax->ssyn_oid ); - mlen = strlen( mr->smr_oid ); + slen = syntax->ssyn_oidlen; + mlen = mr->smr_oidlen; nkeys=0; - for( i=0; values[i] != NULL; i++ ) { + for( i=0; values[i].bv_val != NULL; i++ ) { int j,max; - struct berval *value; + struct berval value; - if( values[i]->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue; + if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue; - value = ber_bvdup( values[i] ); - ldap_pvt_str2upper( value->bv_val ); + ber_dupbv( &value, &values[i] ); + ldap_pvt_str2lower( value.bv_val ); if( ( flags & SLAP_INDEX_SUBSTR_ANY ) && - ( value->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) ) + ( value.bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) ) { char pre = SLAP_INDEX_SUBSTR_PREFIX; - max = value->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1); + max = value.bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1); for( j=0; jsmr_oid, mlen ); HASH_Update( &HASHcontext, - &value->bv_val[j], + &value.bv_val[j], SLAP_INDEX_SUBSTR_MAXLEN ); HASH_Final( HASHdigest, &HASHcontext ); - keys[nkeys++] = ber_bvdup( &digest ); + ber_dupbv( &keys[nkeys++], &digest ); } } - max = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len - ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len; + max = SLAP_INDEX_SUBSTR_MAXLEN < value.bv_len + ? SLAP_INDEX_SUBSTR_MAXLEN : value.bv_len; for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) { char pre; @@ -3535,10 +3168,10 @@ int caseIgnoreIA5SubstringsIndexer( HASH_Update( &HASHcontext, mr->smr_oid, mlen ); HASH_Update( &HASHcontext, - value->bv_val, j ); + value.bv_val, j ); HASH_Final( HASHdigest, &HASHcontext ); - keys[nkeys++] = ber_bvdup( &digest ); + ber_dupbv( &keys[nkeys++], &digest ); } if( flags & SLAP_INDEX_SUBSTR_FINAL ) { @@ -3555,19 +3188,19 @@ int caseIgnoreIA5SubstringsIndexer( HASH_Update( &HASHcontext, mr->smr_oid, mlen ); HASH_Update( &HASHcontext, - &value->bv_val[value->bv_len-j], j ); + &value.bv_val[value.bv_len-j], j ); HASH_Final( HASHdigest, &HASHcontext ); - keys[nkeys++] = ber_bvdup( &digest ); + ber_dupbv( &keys[nkeys++], &digest ); } } - ber_bvfree( value ); + free( value.bv_val ); } if( nkeys > 0 ) { - keys[nkeys] = NULL; + keys[nkeys].bv_val = NULL; *keysp = keys; } else { ch_free( keys ); @@ -3577,44 +3210,44 @@ int caseIgnoreIA5SubstringsIndexer( return LDAP_SUCCESS; } -int caseIgnoreIA5SubstringsFilter( +static int caseIgnoreIA5SubstringsFilter( slap_mask_t use, slap_mask_t flags, Syntax *syntax, MatchingRule *mr, struct berval *prefix, void * assertValue, - struct berval ***keysp ) + BerVarray *keysp ) { SubstringsAssertion *sa = assertValue; char pre; ber_len_t nkeys = 0; size_t slen, mlen, klen; - struct berval **keys; + BerVarray keys; HASH_CONTEXT HASHcontext; unsigned char HASHdigest[HASH_BYTES]; - struct berval *value; + struct berval value; struct berval digest; - if((flags & SLAP_INDEX_SUBSTR_INITIAL) && sa->sa_initial != NULL && - sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN ) + 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] != NULL; i++ ) { - if( sa->sa_any[i]->bv_len >= 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 ) { /* don't bother accounting for stepping */ - nkeys += sa->sa_any[i]->bv_len - + nkeys += sa->sa_any[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 ); } } } - if((flags & SLAP_INDEX_SUBSTR_FINAL) && sa->sa_final != NULL && - sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN ) + if((flags & SLAP_INDEX_SUBSTR_FINAL) && sa->sa_final.bv_val != NULL && + sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN ) { nkeys++; } @@ -3627,21 +3260,21 @@ int caseIgnoreIA5SubstringsFilter( digest.bv_val = HASHdigest; digest.bv_len = sizeof(HASHdigest); - slen = strlen( syntax->ssyn_oid ); - mlen = strlen( mr->smr_oid ); + slen = syntax->ssyn_oidlen; + mlen = mr->smr_oidlen; - keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) ); + keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) ); nkeys = 0; - if((flags & SLAP_INDEX_SUBSTR_INITIAL) && sa->sa_initial != NULL && - sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN ) + 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 = ber_bvdup( sa->sa_initial ); - ldap_pvt_str2upper( value->bv_val ); + ber_dupbv( &value, &sa->sa_initial ); + ldap_pvt_str2lower( value.bv_val ); - klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len - ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len; + 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 ) { @@ -3655,11 +3288,11 @@ int caseIgnoreIA5SubstringsFilter( HASH_Update( &HASHcontext, mr->smr_oid, mlen ); HASH_Update( &HASHcontext, - value->bv_val, klen ); + value.bv_val, klen ); HASH_Final( HASHdigest, &HASHcontext ); - ber_bvfree( value ); - keys[nkeys++] = ber_bvdup( &digest ); + free( value.bv_val ); + ber_dupbv( &keys[nkeys++], &digest ); } if((flags & SLAP_INDEX_SUBSTR_ANY) && sa->sa_any != NULL ) { @@ -3667,16 +3300,16 @@ int caseIgnoreIA5SubstringsFilter( pre = SLAP_INDEX_SUBSTR_PREFIX; klen = SLAP_INDEX_SUBSTR_MAXLEN; - for( i=0; sa->sa_any[i] != NULL; i++ ) { - if( sa->sa_any[i]->bv_len < 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 = ber_bvdup( sa->sa_any[i] ); - ldap_pvt_str2upper( value->bv_val ); + ber_dupbv( &value, &sa->sa_any[i] ); + ldap_pvt_str2lower( value.bv_val ); for(j=0; - j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN; + j <= value.bv_len - SLAP_INDEX_SUBSTR_MAXLEN; j += SLAP_INDEX_SUBSTR_STEP ) { HASH_Init( &HASHcontext ); @@ -3691,25 +3324,25 @@ int caseIgnoreIA5SubstringsFilter( HASH_Update( &HASHcontext, mr->smr_oid, mlen ); HASH_Update( &HASHcontext, - &value->bv_val[j], klen ); + &value.bv_val[j], klen ); HASH_Final( HASHdigest, &HASHcontext ); - keys[nkeys++] = ber_bvdup( &digest ); + ber_dupbv( &keys[nkeys++], &digest ); } - ber_bvfree( value ); + free( value.bv_val ); } } - if((flags & SLAP_INDEX_SUBSTR_FINAL) && sa->sa_final != NULL && - sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN ) + 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 = ber_bvdup( sa->sa_final ); - ldap_pvt_str2upper( value->bv_val ); + ber_dupbv( &value, &sa->sa_final ); + ldap_pvt_str2lower( value.bv_val ); - klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len - ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len; + 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 ) { @@ -3723,15 +3356,15 @@ int caseIgnoreIA5SubstringsFilter( HASH_Update( &HASHcontext, mr->smr_oid, mlen ); HASH_Update( &HASHcontext, - &value->bv_val[value->bv_len-klen], klen ); + &value.bv_val[value.bv_len-klen], klen ); HASH_Final( HASHdigest, &HASHcontext ); - ber_bvfree( value ); - keys[nkeys++] = ber_bvdup( &digest ); + free( value.bv_val ); + ber_dupbv( &keys[nkeys++], &digest ); } if( nkeys > 0 ) { - keys[nkeys] = NULL; + keys[nkeys].bv_val = NULL; *keysp = keys; } else { ch_free( keys ); @@ -3748,6 +3381,8 @@ numericStringValidate( { ber_len_t i; + if( in->bv_len == 0 ) return LDAP_INVALID_SYNTAX; + for(i=0; i < in->bv_len; i++) { if( !SLAP_NUMERIC(in->bv_val[i]) ) { return LDAP_INVALID_SYNTAX; @@ -3761,17 +3396,17 @@ static int numericStringNormalize( Syntax *syntax, struct berval *val, - struct berval **normalized ) + struct berval *normalized ) { /* removal all spaces */ - struct berval *newval; char *p, *q; - newval = ch_malloc( sizeof( struct berval ) ); - newval->bv_val = ch_malloc( val->bv_len + 1 ); + assert( val->bv_len ); + + normalized->bv_val = ch_malloc( val->bv_len + 1 ); p = val->bv_val; - q = newval->bv_val; + q = normalized->bv_val; while ( *p ) { if ( ASCII_SPACE( *p ) ) { @@ -3783,13 +3418,19 @@ numericStringNormalize( } /* we should have copied no more then is in val */ - assert( (q - newval->bv_val) <= (p - val->bv_val) ); + assert( (q - normalized->bv_val) <= (p - val->bv_val) ); /* null terminate */ *q = '\0'; - newval->bv_len = q - newval->bv_val; - *normalized = newval; + normalized->bv_len = q - normalized->bv_val; + + if( normalized->bv_len == 0 ) { + normalized->bv_val = ch_realloc( normalized->bv_val, 2 ); + normalized->bv_val[0] = ' '; + normalized->bv_val[1] = '\0'; + normalized->bv_len = 1; + } return LDAP_SUCCESS; } @@ -3831,13 +3472,9 @@ objectIdentifierFirstComponentMatch( rc = objectIdentifierMatch( &match, flags, syntax, mr, &oid, asserted ); } else { - char *stored = ch_malloc( oid.bv_len + 1 ); - AC_MEMCPY( stored, oid.bv_val, oid.bv_len ); - stored[oid.bv_len] = '\0'; - if ( !strcmp( syntax->ssyn_oid, SLAP_SYNTAX_MATCHINGRULES_OID ) ) { - MatchingRule *asserted_mr = mr_find( asserted->bv_val ); - MatchingRule *stored_mr = mr_find( stored ); + MatchingRule *asserted_mr = mr_bvfind( asserted ); + MatchingRule *stored_mr = mr_bvfind( &oid ); if( asserted_mr == NULL ) { rc = SLAPD_COMPARE_UNDEFINED; @@ -3848,8 +3485,8 @@ objectIdentifierFirstComponentMatch( } else if ( !strcmp( syntax->ssyn_oid, SLAP_SYNTAX_ATTRIBUTETYPES_OID ) ) { - AttributeType *asserted_at = at_find( asserted->bv_val ); - AttributeType *stored_at = at_find( stored ); + AttributeType *asserted_at = at_bvfind( asserted ); + AttributeType *stored_at = at_bvfind( &oid ); if( asserted_at == NULL ) { rc = SLAPD_COMPARE_UNDEFINED; @@ -3860,8 +3497,8 @@ objectIdentifierFirstComponentMatch( } else if ( !strcmp( syntax->ssyn_oid, SLAP_SYNTAX_OBJECTCLASSES_OID ) ) { - ObjectClass *asserted_oc = oc_find( asserted->bv_val ); - ObjectClass *stored_oc = oc_find( stored ); + ObjectClass *asserted_oc = oc_bvfind( asserted ); + ObjectClass *stored_oc = oc_bvfind( &oid ); if( asserted_oc == NULL ) { rc = SLAPD_COMPARE_UNDEFINED; @@ -3869,14 +3506,12 @@ objectIdentifierFirstComponentMatch( match = asserted_oc != stored_oc; } } - - ch_free( stored ); } #ifdef NEW_LOGGING - LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY, - "objectIdentifierFirstComponentMatch: %d\n %s\n %s\n", - match, value->bv_val, asserted->bv_val )); + LDAP_LOG( CONFIG, ENTRY, + "objectIdentifierFirstComponentMatch: %d\n %s\n %s\n", + match, value->bv_val, asserted->bv_val ); #else Debug( LDAP_DEBUG_ARGS, "objectIdentifierFirstComponentMatch " "%d\n\t\"%s\"\n\t\"%s\"\n", @@ -3947,7 +3582,7 @@ char digit[] = "0123456789"; */ static struct berval * -asn1_integer2str(ASN1_INTEGER *a) +asn1_integer2str(ASN1_INTEGER *a, struct berval *bv) { char buf[256]; char *p; @@ -4003,35 +3638,7 @@ asn1_integer2str(ASN1_INTEGER *a) *--p = '-'; } - return ber_bvstrdup(p); -} - -/* Get a DN in RFC2253 format from a X509_NAME internal struct */ -static struct berval * -dn_openssl2ldap(X509_NAME *name) -{ - char issuer_dn[1024]; - BIO *bio; - - bio = BIO_new(BIO_s_mem()); - if ( !bio ) { -#ifdef NEW_LOGGING - LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY, - "dn_openssl2ldap: error creating BIO_s_mem: %s\n", - ERR_error_string(ERR_get_error(),NULL))); -#else - Debug( LDAP_DEBUG_ARGS, "dn_openssl2ldap: " - "error creating BIO: %s\n", - ERR_error_string(ERR_get_error(),NULL), NULL, NULL ); -#endif - return NULL; - } - X509_NAME_print_ex(bio, name, 0, XN_FLAG_RFC2253); - - BIO_gets(bio, issuer_dn, 1024); - - BIO_free(bio); - return ber_bvstrdup(issuer_dn); + return ber_str2bv( p, 0, 1, bv ); } /* @@ -4041,20 +3648,19 @@ dn_openssl2ldap(X509_NAME *name) static int certificateExactConvert( struct berval * in, - struct berval ** out ) + struct berval * out ) { X509 *xcert; unsigned char *p = in->bv_val; - struct berval *serial; - struct berval *issuer_dn; - struct berval *bv_tmp; + struct berval serial; + struct berval issuer_dn; xcert = d2i_X509(NULL, &p, in->bv_len); if ( !xcert ) { #ifdef NEW_LOGGING - LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY, - "certificateExactConvert: error parsing cert: %s\n", - ERR_error_string(ERR_get_error(),NULL))); + LDAP_LOG( CONFIG, ENTRY, + "certificateExactConvert: error parsing cert: %s\n", + ERR_error_string(ERR_get_error(),NULL), 0, 0 ); #else Debug( LDAP_DEBUG_ARGS, "certificateExactConvert: " "error parsing cert: %s\n", @@ -4063,54 +3669,40 @@ certificateExactConvert( return LDAP_INVALID_SYNTAX; } - serial = asn1_integer2str(xcert->cert_info->serialNumber); - if ( !serial ) { - X509_free(xcert); - return LDAP_INVALID_SYNTAX; - } - issuer_dn = dn_openssl2ldap(X509_get_issuer_name(xcert)); - if ( !issuer_dn ) { + if ( !asn1_integer2str(xcert->cert_info->serialNumber, &serial) ) { X509_free(xcert); - ber_bvfree(serial); return LDAP_INVALID_SYNTAX; } - /* Actually, dn_openssl2ldap returns in a normalized format, but - it is different from our normalized format */ - bv_tmp = issuer_dn; - if ( dnNormalize(NULL, bv_tmp, &issuer_dn) != LDAP_SUCCESS ) { + if ( dnX509normalize(X509_get_issuer_name(xcert), &issuer_dn ) != LDAP_SUCCESS ) { X509_free(xcert); - ber_bvfree(serial); - ber_bvfree(bv_tmp); + ber_memfree(serial.bv_val); return LDAP_INVALID_SYNTAX; } - ber_bvfree(bv_tmp); X509_free(xcert); - *out = ch_malloc(sizeof(struct berval)); - (*out)->bv_len = serial->bv_len + 3 + issuer_dn->bv_len + 1; - (*out)->bv_val = ch_malloc((*out)->bv_len); - p = (*out)->bv_val; - AC_MEMCPY(p, serial->bv_val, serial->bv_len); - p += serial->bv_len; - AC_MEMCPY(p, " $ ", 3); + out->bv_len = serial.bv_len + issuer_dn.bv_len + sizeof(" $ "); + out->bv_val = ch_malloc(out->bv_len); + p = out->bv_val; + AC_MEMCPY(p, serial.bv_val, serial.bv_len); + p += serial.bv_len; + AC_MEMCPY(p, " $ ", sizeof(" $ ")-1); p += 3; - AC_MEMCPY(p, issuer_dn->bv_val, issuer_dn->bv_len); - p += issuer_dn->bv_len; + AC_MEMCPY(p, issuer_dn.bv_val, issuer_dn.bv_len); + p += issuer_dn.bv_len; *p++ = '\0'; #ifdef NEW_LOGGING - LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY, - "certificateExactConvert: \n %s\n", - (*out)->bv_val)); + LDAP_LOG( CONFIG, ARGS, + "certificateExactConvert: \n %s\n", out->bv_val, 0, 0 ); #else Debug( LDAP_DEBUG_ARGS, "certificateExactConvert " "\n\t\"%s\"\n", - (*out)->bv_val, NULL, NULL ); + out->bv_val, NULL, NULL ); #endif - ber_bvfree(serial); - ber_bvfree(issuer_dn); + ber_memfree(serial.bv_val); + ber_memfree(issuer_dn.bv_val); return LDAP_SUCCESS; } @@ -4118,14 +3710,14 @@ certificateExactConvert( static int serial_and_issuer_parse( struct berval *assertion, - struct berval **serial, - struct berval **issuer_dn + struct berval *serial, + struct berval *issuer_dn ) { char *begin; char *end; char *p; - char *q; + struct berval bv; begin = assertion->bv_val; end = assertion->bv_val+assertion->bv_len-1; @@ -4142,22 +3734,22 @@ serial_and_issuer_parse( while (ASCII_SPACE(*end)) end--; - q = ch_malloc( (end-begin+1)+1 ); - AC_MEMCPY( q, begin, end-begin+1 ); - q[end-begin+1] = '\0'; - *serial = ber_bvstr(q); + bv.bv_len = end-begin+1; + bv.bv_val = begin; + ber_dupbv(serial, &bv); /* now extract the issuer, remember p was at the dollar sign */ - begin = p+1; - end = assertion->bv_val+assertion->bv_len-1; - while (ASCII_SPACE(*begin)) - begin++; - /* should we trim spaces at the end too? is it safe always? */ + if ( issuer_dn ) { + begin = p+1; + end = assertion->bv_val+assertion->bv_len-1; + while (ASCII_SPACE(*begin)) + begin++; + /* should we trim spaces at the end too? is it safe always? */ - q = ch_malloc( (end-begin+1)+1 ); - AC_MEMCPY( q, begin, end-begin+1 ); - q[end-begin+1] = '\0'; - *issuer_dn = ber_bvstr(dn_normalize(q)); + bv.bv_len = end-begin+1; + bv.bv_val = begin; + dnNormalize2( NULL, &bv, issuer_dn ); + } return LDAP_SUCCESS; } @@ -4173,18 +3765,18 @@ certificateExactMatch( { X509 *xcert; unsigned char *p = value->bv_val; - struct berval *serial; - struct berval *issuer_dn; - struct berval *asserted_serial; - struct berval *asserted_issuer_dn; + struct berval serial; + struct berval issuer_dn; + struct berval asserted_serial; + struct berval asserted_issuer_dn; int ret; xcert = d2i_X509(NULL, &p, value->bv_len); if ( !xcert ) { #ifdef NEW_LOGGING - LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY, - "certificateExactMatch: error parsing cert: %s\n", - ERR_error_string(ERR_get_error(),NULL))); + LDAP_LOG( CONFIG, ENTRY, + "certificateExactMatch: error parsing cert: %s\n", + ERR_error_string(ERR_get_error(),NULL), 0, 0 ); #else Debug( LDAP_DEBUG_ARGS, "certificateExactMatch: " "error parsing cert: %s\n", @@ -4193,8 +3785,8 @@ certificateExactMatch( return LDAP_INVALID_SYNTAX; } - serial = asn1_integer2str(xcert->cert_info->serialNumber); - issuer_dn = dn_openssl2ldap(X509_get_issuer_name(xcert)); + asn1_integer2str(xcert->cert_info->serialNumber, &serial); + dnX509normalize(X509_get_issuer_name(xcert), &issuer_dn); X509_free(xcert); @@ -4207,8 +3799,8 @@ certificateExactMatch( flags, slap_schema.si_syn_integer, slap_schema.si_mr_integerMatch, - serial, - asserted_serial); + &serial, + &asserted_serial); if ( ret == LDAP_SUCCESS ) { if ( *matchp == 0 ) { /* We need to normalize everything for dnMatch */ @@ -4217,29 +3809,31 @@ certificateExactMatch( flags, slap_schema.si_syn_distinguishedName, slap_schema.si_mr_distinguishedNameMatch, - issuer_dn, - asserted_issuer_dn); + &issuer_dn, + &asserted_issuer_dn); } } #ifdef NEW_LOGGING - LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY, - "certificateExactMatch: %d\n %s $ %s\n %s $ %s\n", - *matchp, serial->bv_val, issuer_dn->bv_val, - asserted->serial->bv_val, asserted_issuer_dn->bv_val)); + LDAP_LOG( CONFIG, ARGS, "certificateExactMatch " + "%d\n\t\"%s $ %s\"\n", + *matchp, serial.bv_val, issuer_dn.bv_val ); + LDAP_LOG( CONFIG, ARGS, "\t\"%s $ %s\"\n", + asserted_serial.bv_val, asserted_issuer_dn.bv_val, + 0 ); #else Debug( LDAP_DEBUG_ARGS, "certificateExactMatch " "%d\n\t\"%s $ %s\"\n", - *matchp, serial->bv_val, issuer_dn->bv_val ); + *matchp, serial.bv_val, issuer_dn.bv_val ); Debug( LDAP_DEBUG_ARGS, "\t\"%s $ %s\"\n", - asserted_serial->bv_val, asserted_issuer_dn->bv_val, + asserted_serial.bv_val, asserted_issuer_dn.bv_val, NULL ); #endif - ber_bvfree(serial); - ber_bvfree(issuer_dn); - ber_bvfree(asserted_serial); - ber_bvfree(asserted_issuer_dn); + ber_memfree(serial.bv_val); + ber_memfree(issuer_dn.bv_val); + ber_memfree(asserted_serial.bv_val); + ber_memfree(asserted_issuer_dn.bv_val); return ret; } @@ -4249,38 +3843,38 @@ certificateExactMatch( * We just index the serials, in most scenarios the issuer DN is one of * a very small set of values. */ -int certificateExactIndexer( +static int certificateExactIndexer( slap_mask_t use, slap_mask_t flags, Syntax *syntax, MatchingRule *mr, struct berval *prefix, - struct berval **values, - struct berval ***keysp ) + BerVarray values, + BerVarray *keysp ) { int i; - struct berval **keys; + BerVarray keys; X509 *xcert; unsigned char *p; - struct berval * serial; + struct berval serial; /* we should have at least one value at this point */ - assert( values != NULL && values[0] != NULL ); + assert( values != NULL && values[0].bv_val != NULL ); - for( i=0; values[i] != NULL; i++ ) { + for( i=0; values[i].bv_val != NULL; i++ ) { /* empty -- just count them */ } - keys = ch_malloc( sizeof( struct berval * ) * (i+1) ); + keys = ch_malloc( sizeof( struct berval ) * (i+1) ); - for( i=0; values[i] != NULL; i++ ) { - p = values[i]->bv_val; - xcert = d2i_X509(NULL, &p, values[i]->bv_len); + for( i=0; values[i].bv_val != NULL; i++ ) { + p = values[i].bv_val; + xcert = d2i_X509(NULL, &p, values[i].bv_len); if ( !xcert ) { #ifdef NEW_LOGGING - LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY, - "certificateExactIndexer: error parsing cert: %s\n", - ERR_error_string(ERR_get_error(),NULL))); + LDAP_LOG( CONFIG, ENTRY, + "certificateExactIndexer: error parsing cert: %s\n", + ERR_error_string(ERR_get_error(),NULL), 0, 0); #else Debug( LDAP_DEBUG_ARGS, "certificateExactIndexer: " "error parsing cert: %s\n", @@ -4291,55 +3885,52 @@ int certificateExactIndexer( return LDAP_INVALID_SYNTAX; } - serial = asn1_integer2str(xcert->cert_info->serialNumber); + asn1_integer2str(xcert->cert_info->serialNumber, &serial); X509_free(xcert); integerNormalize( slap_schema.si_syn_integer, - serial, + &serial, &keys[i] ); - ber_bvfree(serial); + ber_memfree(serial.bv_val); #ifdef NEW_LOGGING - LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY, - "certificateExactIndexer: returning: %s\n", - keys[i]->bv_val)); + LDAP_LOG( CONFIG, ENTRY, + "certificateExactIndexer: returning: %s\n", keys[i].bv_val, 0, 0); #else Debug( LDAP_DEBUG_ARGS, "certificateExactIndexer: " "returning: %s\n", - keys[i]->bv_val, + keys[i].bv_val, NULL, NULL ); #endif } - keys[i] = NULL; + keys[i].bv_val = NULL; *keysp = keys; return LDAP_SUCCESS; } /* Index generation function */ /* We think this is always called with a value in matching rule syntax */ -int certificateExactFilter( +static int certificateExactFilter( slap_mask_t use, slap_mask_t flags, Syntax *syntax, MatchingRule *mr, struct berval *prefix, void * assertValue, - struct berval ***keysp ) + BerVarray *keysp ) { - struct berval **keys; - struct berval *asserted_serial; - struct berval *asserted_issuer_dn; + BerVarray keys; + struct berval asserted_serial; serial_and_issuer_parse(assertValue, &asserted_serial, - &asserted_issuer_dn); + NULL); - keys = ch_malloc( sizeof( struct berval * ) * 2 ); - integerNormalize( syntax, asserted_serial, &keys[0] ); - keys[1] = NULL; + keys = ch_malloc( sizeof( struct berval ) * 2 ); + integerNormalize( syntax, &asserted_serial, &keys[0] ); + keys[1].bv_val = NULL; *keysp = keys; - ber_bvfree(asserted_serial); - ber_bvfree(asserted_issuer_dn); + ber_memfree(asserted_serial.bv_val); return LDAP_SUCCESS; } #endif @@ -4509,13 +4100,13 @@ check_time_syntax (struct berval *val, return LDAP_SUCCESS; } +#ifdef SUPPORT_OBSOLETE_UTC_SYNTAX static int utcTimeNormalize( Syntax *syntax, struct berval *val, - struct berval **normalized ) + struct berval *normalized ) { - struct berval *out; int parts[9], rc; rc = check_time_syntax(val, 1, parts); @@ -4523,27 +4114,21 @@ utcTimeNormalize( return rc; } - *normalized = NULL; - out = ch_malloc( sizeof(struct berval) ); - if( out == NULL ) { - return LBER_ERROR_MEMORY; - } - - out->bv_val = ch_malloc( 14 ); - if ( out->bv_val == NULL ) { - ch_free( out ); + normalized->bv_val = ch_malloc( 14 ); + if ( normalized->bv_val == NULL ) { return LBER_ERROR_MEMORY; } - sprintf( out->bv_val, "%02d%02d%02d%02d%02d%02dZ", + sprintf( normalized->bv_val, "%02d%02d%02d%02d%02d%02dZ", parts[1], parts[2] + 1, parts[3] + 1, parts[4], parts[5], parts[6] ); - out->bv_len = 13; - *normalized = out; + normalized->bv_len = 13; return LDAP_SUCCESS; } +#endif +#ifdef SUPPORT_OBSOLETE_UTC_SYNTAX static int utcTimeValidate( Syntax *syntax, @@ -4553,6 +4138,7 @@ utcTimeValidate( return check_time_syntax(in, 1, parts); } +#endif static int generalizedTimeValidate( @@ -4568,9 +4154,8 @@ static int generalizedTimeNormalize( Syntax *syntax, struct berval *val, - struct berval **normalized ) + struct berval *normalized ) { - struct berval *out; int parts[9], rc; rc = check_time_syntax(val, 0, parts); @@ -4578,23 +4163,15 @@ generalizedTimeNormalize( return rc; } - *normalized = NULL; - out = ch_malloc( sizeof(struct berval) ); - if( out == NULL ) { - return LBER_ERROR_MEMORY; - } - - out->bv_val = ch_malloc( 16 ); - if ( out->bv_val == NULL ) { - ch_free( out ); + normalized->bv_val = ch_malloc( 16 ); + if ( normalized->bv_val == NULL ) { return LBER_ERROR_MEMORY; } - sprintf( out->bv_val, "%02d%02d%02d%02d%02d%02d%02dZ", + sprintf( normalized->bv_val, "%02d%02d%02d%02d%02d%02d%02dZ", parts[0], parts[1], parts[2] + 1, parts[3] + 1, parts[4], parts[5], parts[6] ); - out->bv_len = 15; - *normalized = out; + normalized->bv_len = 15; return LDAP_SUCCESS; } @@ -4618,14 +4195,14 @@ nisNetgroupTripleValidate( return LDAP_INVALID_SYNTAX; } - for ( p++; ( p < e ) && ( *p != ')' ); p++ ) { + for ( p++; ( p < e ) && ( *p != /*'('*/ ')' ); p++ ) { if ( *p == ',' ) { commas++; if ( commas > 2 ) { return LDAP_INVALID_SYNTAX; } - } else if ( !ATTR_CHAR( *p ) ) { + } else if ( !AD_CHAR( *p ) ) { return LDAP_INVALID_SYNTAX; } } @@ -4659,7 +4236,7 @@ bootParameterValidate( /* key */ for (; ( p < e ) && ( *p != '=' ); p++ ) { - if ( !ATTR_CHAR( *p ) ) { + if ( !AD_CHAR( *p ) ) { return LDAP_INVALID_SYNTAX; } } @@ -4670,7 +4247,7 @@ bootParameterValidate( /* server */ for ( p++; ( p < e ) && ( *p != ':' ); p++ ) { - if ( !ATTR_CHAR( *p ) ) { + if ( !AD_CHAR( *p ) ) { return LDAP_INVALID_SYNTAX; } } @@ -4681,7 +4258,7 @@ bootParameterValidate( /* path */ for ( p++; p < e; p++ ) { - if ( !ATTR_CHAR( *p ) ) { + if ( !SLAP_PRINTABLE( *p ) ) { return LDAP_INVALID_SYNTAX; } } @@ -4689,31 +4266,22 @@ bootParameterValidate( return LDAP_SUCCESS; } -struct syntax_defs_rec { - char *sd_desc; - int sd_flags; - slap_syntax_validate_func *sd_validate; - slap_syntax_transform_func *sd_normalize; - slap_syntax_transform_func *sd_pretty; -#ifdef SLAPD_BINARY_CONVERSION - slap_syntax_transform_func *sd_ber2str; - slap_syntax_transform_func *sd_str2ber; -#endif -}; - #define X_BINARY "X-BINARY-TRANSFER-REQUIRED 'TRUE' " #define X_NOT_H_R "X-NOT-HUMAN-READABLE 'TRUE' " -struct syntax_defs_rec syntax_defs[] = { - {"( 1.3.6.1.4.1.1466.115.121.1.1 DESC 'ACI Item' " X_BINARY X_NOT_H_R ")", +static slap_syntax_defs_rec syntax_defs[] = { + {"( 1.3.6.1.4.1.1466.115.121.1.1 DESC 'ACI Item' " + X_BINARY X_NOT_H_R ")", SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, NULL, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.2 DESC 'Access Point' " X_NOT_H_R ")", 0, NULL, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.3 DESC 'Attribute Type Description' )", 0, NULL, NULL, NULL}, - {"( 1.3.6.1.4.1.1466.115.121.1.4 DESC 'Audio' " X_NOT_H_R ")", + {"( 1.3.6.1.4.1.1466.115.121.1.4 DESC 'Audio' " + X_NOT_H_R ")", SLAP_SYNTAX_BLOB, blobValidate, NULL, NULL}, - {"( 1.3.6.1.4.1.1466.115.121.1.5 DESC 'Binary' " X_NOT_H_R ")", + {"( 1.3.6.1.4.1.1466.115.121.1.5 DESC 'Binary' " + X_NOT_H_R ")", SLAP_SYNTAX_BER, berValidate, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.6 DESC 'Bit String' )", 0, bitStringValidate, bitStringNormalize, NULL }, @@ -4731,7 +4299,7 @@ struct syntax_defs_rec syntax_defs[] = { {"( 1.3.6.1.4.1.1466.115.121.1.11 DESC 'Country String' )", 0, countryStringValidate, IA5StringNormalize, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.12 DESC 'Distinguished Name' )", - 0, dnValidate, dnNormalize, dnPretty}, + 0, dnValidate, dnNormalize2, dnPretty2}, {"( 1.3.6.1.4.1.1466.115.121.1.13 DESC 'Data Quality' )", 0, NULL, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.14 DESC 'Delivery Method' )", @@ -4749,7 +4317,7 @@ struct syntax_defs_rec syntax_defs[] = { {"( 1.3.6.1.4.1.1466.115.121.1.21 DESC 'Enhanced Guide' )", 0, NULL, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.22 DESC 'Facsimile Telephone Number' )", - 0, printablesStringValidate, IA5StringNormalize, NULL}, + 0, printablesStringValidate, telephoneNumberNormalize, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.23 DESC 'Fax' " X_NOT_H_R ")", SLAP_SYNTAX_BLOB, NULL, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.24 DESC 'Generalized Time' )", @@ -4794,17 +4362,22 @@ struct syntax_defs_rec syntax_defs[] = { 0, NULL, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.44 DESC 'Printable String' )", 0, printableStringValidate, IA5StringNormalize, NULL}, + {"( 1.3.6.1.4.1.1466.115.121.1.45 DESC 'SubtreeSpecification' " + X_BINARY X_NOT_H_R ")", + SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, NULL, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.49 DESC 'Supported Algorithm' " X_BINARY X_NOT_H_R ")", SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.50 DESC 'Telephone Number' )", - 0, printableStringValidate, IA5StringNormalize, NULL}, + 0, printableStringValidate, telephoneNumberNormalize, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.51 DESC 'Teletex Terminal Identifier' )", 0, NULL, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.52 DESC 'Telex Number' )", 0, printablesStringValidate, IA5StringNormalize, NULL}, +#ifdef SUPPORT_OBSOLETE_UTC_SYNTAX {"( 1.3.6.1.4.1.1466.115.121.1.53 DESC 'UTC Time' )", 0, utcTimeValidate, utcTimeNormalize, NULL}, +#endif {"( 1.3.6.1.4.1.1466.115.121.1.54 DESC 'LDAP Syntax Description' )", 0, NULL, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.55 DESC 'Modify Rights' )", @@ -4833,14 +4406,18 @@ struct syntax_defs_rec syntax_defs[] = { #endif /* OpenLDAP Experimental Syntaxes */ +#ifdef SLAPD_ACI_ENABLED {"( 1.3.6.1.4.1.4203.666.2.1 DESC 'OpenLDAP Experimental ACI' )", SLAP_SYNTAX_HIDE, UTF8StringValidate /* THIS WILL CHANGE FOR NEW ACI SYNTAX */, NULL, NULL}, +#endif +#ifdef SLAPD_AUTHPASSWD /* needs updating */ {"( 1.3.6.1.4.1.4203.666.2.2 DESC 'OpenLDAP authPassword' )", SLAP_SYNTAX_HIDE, NULL, NULL, NULL}, +#endif /* OpenLDAP Void Syntax */ {"( 1.3.6.1.4.1.4203.1.1.1 DESC 'OpenLDAP void' )" , @@ -4848,23 +4425,10 @@ struct syntax_defs_rec syntax_defs[] = { {NULL, 0, NULL, NULL, NULL} }; -struct mrule_defs_rec { - char * mrd_desc; - slap_mask_t mrd_usage; - slap_mr_convert_func * mrd_convert; - slap_mr_normalize_func * mrd_normalize; - slap_mr_match_func * mrd_match; - slap_mr_indexer_func * mrd_indexer; - slap_mr_filter_func * mrd_filter; - - char * mrd_associated; -}; - /* * Other matching rules in X.520 that we do not use (yet): * * 2.5.13.9 numericStringOrderingMatch - * 2.5.13.15 integerOrderingMatch * 2.5.13.18 octetStringOrderingMatch * 2.5.13.19 octetStringSubstringsMatch * 2.5.13.25 uTCTimeMatch @@ -4883,15 +4447,14 @@ struct mrule_defs_rec { * 2.5.13.43 readerAndKeyIDMatch * 2.5.13.44 attributeIntegrityMatch */ - -struct mrule_defs_rec mrule_defs[] = { +static slap_mrule_defs_rec mrule_defs[] = { /* * EQUALITY matching rules must be listed after associated APPROX * matching rules. So, we list all APPROX matching rules first. */ {"( " directoryStringApproxMatchOID " NAME 'directoryStringApproxMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", - SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT, + SLAP_MR_HIDE | SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT, NULL, NULL, directoryStringApproxMatch, directoryStringApproxIndexer, @@ -4900,7 +4463,7 @@ struct mrule_defs_rec mrule_defs[] = { {"( " IA5StringApproxMatchOID " NAME 'IA5StringApproxMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )", - SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT, + SLAP_MR_HIDE | SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT, NULL, NULL, IA5StringApproxMatch, IA5StringApproxIndexer, @@ -5017,6 +4580,13 @@ struct mrule_defs_rec mrule_defs[] = { integerMatch, integerIndexer, integerFilter, NULL}, + {"( 2.5.13.15 NAME 'integerOrderingMatch' " + "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )", + SLAP_MR_ORDERING, + NULL, NULL, + integerOrderingMatch, NULL, NULL, + NULL}, + {"( 2.5.13.16 NAME 'bitStringMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.6 )", SLAP_MR_EQUALITY | SLAP_MR_EXT, @@ -5140,6 +4710,7 @@ struct mrule_defs_rec mrule_defs[] = { caseExactIA5SubstringsFilter, NULL}, +#ifdef SLAPD_AUTHPASSWD /* needs updating */ {"( 1.3.6.1.4.1.4203.666.4.1 NAME 'authPasswordMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )", @@ -5147,13 +4718,16 @@ struct mrule_defs_rec mrule_defs[] = { NULL, NULL, authPasswordMatch, NULL, NULL, NULL}, +#endif +#ifdef SLAPD_ACI_ENABLED {"( 1.3.6.1.4.1.4203.666.4.2 NAME 'OpenLDAPaciMatch' " "SYNTAX 1.3.6.1.4.1.4203.666.2.1 )", SLAP_MR_EQUALITY, NULL, NULL, OpenLDAPaciMatch, NULL, NULL, NULL}, +#endif {"( 1.2.840.113556.1.4.803 NAME 'integerBitAndMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )", @@ -5173,29 +4747,19 @@ struct mrule_defs_rec mrule_defs[] = { }; int -schema_init( void ) +slap_schema_init( void ) { int res; - int i; + int i = 0; /* we should only be called once (from main) */ assert( schema_init_done == 0 ); for ( i=0; syntax_defs[i].sd_desc != NULL; i++ ) { - res = register_syntax( syntax_defs[i].sd_desc, - syntax_defs[i].sd_flags, - syntax_defs[i].sd_validate, - syntax_defs[i].sd_normalize, - syntax_defs[i].sd_pretty -#ifdef SLAPD_BINARY_CONVERSION - , - syntax_defs[i].sd_ber2str, - syntax_defs[i].sd_str2ber -#endif - ); + res = register_syntax( &syntax_defs[i] ); if ( res ) { - fprintf( stderr, "schema_init: Error registering syntax %s\n", + fprintf( stderr, "slap_schema_init: Error registering syntax %s\n", syntax_defs[i].sd_desc ); return LDAP_OTHER; } @@ -5204,37 +4768,38 @@ schema_init( void ) for ( i=0; mrule_defs[i].mrd_desc != NULL; i++ ) { if( mrule_defs[i].mrd_usage == SLAP_MR_NONE ) { fprintf( stderr, - "schema_init: Ingoring unusable matching rule %s\n", + "slap_schema_init: Ingoring unusable matching rule %s\n", mrule_defs[i].mrd_desc ); continue; } - res = register_matching_rule( - mrule_defs[i].mrd_desc, - mrule_defs[i].mrd_usage, - mrule_defs[i].mrd_convert, - mrule_defs[i].mrd_normalize, - mrule_defs[i].mrd_match, - mrule_defs[i].mrd_indexer, - mrule_defs[i].mrd_filter, - mrule_defs[i].mrd_associated ); + res = register_matching_rule( &mrule_defs[i] ); if ( res ) { fprintf( stderr, - "schema_init: Error registering matching rule %s\n", + "slap_schema_init: Error registering matching rule %s\n", mrule_defs[i].mrd_desc ); return LDAP_OTHER; } } + + for ( i=0; i < (int)(sizeof(mr_ptr)/sizeof(mr_ptr[0])); i++ ) + *mr_ptr[i].mr = mr_find( mr_ptr[i].oid ); + + res = slap_schema_load(); schema_init_done = 1; - return LDAP_SUCCESS; + return res; } void schema_destroy( void ) { + int i; + oidm_destroy(); oc_destroy(); at_destroy(); + for ( i=0; i < (int)(sizeof(mr_ptr)/sizeof(mr_ptr[0])); i++ ) + *mr_ptr[i].mr = NULL; mr_destroy(); syn_destroy(); }