From: Quanah Gibson-Mount Date: Wed, 21 Nov 2007 19:18:32 +0000 (+0000) Subject: ITS#5183 X-Git-Tag: OPENLDAP_REL_ENG_2_4_7~57 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=f592910d091ead7faa1cfd5ecfbcade578465bab;p=openldap ITS#5183 --- diff --git a/CHANGES b/CHANGES index 80fe37b949..5370f69274 100644 --- a/CHANGES +++ b/CHANGES @@ -10,6 +10,7 @@ OpenLDAP 2.4.7 Engineering Fixed slapd syncrepl presentlist handling (ITS#5231) Fixed slapd core schema 'c' definition for RFC4519 (ITS#5236) Fixed slapd 3-way Multi-Master Replication (ITS#5238) + Fixed slapd hash collisions in index slots (ITS#5183) Fixed slapd-bdb to report and fail on internal errors (ITS#5232) Fixed slapo-pcache op->o_abandon handling (ITS#5187) Fixed slapo-ppolicy single password check on modify (ITS#5146) diff --git a/servers/slapd/back-bdb/back-bdb.h b/servers/slapd/back-bdb/back-bdb.h index a009ecb61f..168619e0fd 100644 --- a/servers/slapd/back-bdb/back-bdb.h +++ b/servers/slapd/back-bdb/back-bdb.h @@ -174,7 +174,7 @@ typedef struct bdb_cache { #define BDB_INDICES 128 struct bdb_db_info { - char *bdi_name; + struct berval bdi_name; DB *bdi_db; }; diff --git a/servers/slapd/back-bdb/dbcache.c b/servers/slapd/back-bdb/dbcache.c index 35529c7923..e08c2493cf 100644 --- a/servers/slapd/back-bdb/dbcache.c +++ b/servers/slapd/back-bdb/dbcache.c @@ -60,7 +60,7 @@ bdb_db_hash( int bdb_db_cache( Backend *be, - const char *name, + struct berval *name, DB **dbout ) { int i, flags; @@ -72,7 +72,7 @@ bdb_db_cache( *dbout = NULL; for( i=BDB_NDB; i < bdb->bi_ndatabases; i++ ) { - if( !strcmp( bdb->bi_databases[i]->bdi_name, name) ) { + if( !ber_bvcmp( &bdb->bi_databases[i]->bdi_name, name) ) { *dbout = bdb->bi_databases[i]->bdi_db; return 0; } @@ -82,7 +82,7 @@ bdb_db_cache( /* check again! may have been added by another thread */ for( i=BDB_NDB; i < bdb->bi_ndatabases; i++ ) { - if( !strcmp( bdb->bi_databases[i]->bdi_name, name) ) { + if( !ber_bvcmp( &bdb->bi_databases[i]->bdi_name, name) ) { *dbout = bdb->bi_databases[i]->bdi_db; ldap_pvt_thread_mutex_unlock( &bdb->bi_database_mutex ); return 0; @@ -96,7 +96,7 @@ bdb_db_cache( db = (struct bdb_db_info *) ch_calloc(1, sizeof(struct bdb_db_info)); - db->bdi_name = ch_strdup( name ); + ber_dupbv( &db->bdi_name, name ); rc = db_create( &db->bdi_db, bdb->bi_dbenv, 0 ); if( rc != 0 ) { @@ -113,8 +113,9 @@ bdb_db_cache( #endif rc = db->bdi_db->set_flags( db->bdi_db, DB_DUP | DB_DUPSORT ); - file = ch_malloc( strlen( name ) + sizeof(BDB_SUFFIX) ); - sprintf( file, "%s%s", name, BDB_SUFFIX ); + file = ch_malloc( db->bdi_name.bv_len + sizeof(BDB_SUFFIX) ); + strcpy( file, db->bdi_name.bv_val ); + strcpy( file+db->bdi_name.bv_len, BDB_SUFFIX ); #ifdef HAVE_EBCDIC __atoe( file ); diff --git a/servers/slapd/back-bdb/index.c b/servers/slapd/back-bdb/index.c index e193dae30d..8c652bd086 100644 --- a/servers/slapd/back-bdb/index.c +++ b/servers/slapd/back-bdb/index.c @@ -28,7 +28,7 @@ static char presence_keyval[LUTIL_HASH_BYTES] = {0,0,0,1}; static struct berval presence_key = {LUTIL_HASH_BYTES, presence_keyval}; -static AttrInfo *index_mask( +AttrInfo *bdb_index_mask( Backend *be, AttributeDescription *desc, struct berval *atname ) @@ -70,21 +70,6 @@ static AttrInfo *index_mask( return 0; } -int bdb_index_is_indexed( - Backend *be, - AttributeDescription *desc ) -{ - AttrInfo *ai; - struct berval prefix; - - ai = index_mask( be, desc, &prefix ); - - if( !ai ) - return LDAP_INAPPROPRIATE_MATCHING; - - return LDAP_SUCCESS; -} - /* This function is only called when evaluating search filters. */ int bdb_index_param( @@ -100,7 +85,7 @@ int bdb_index_param( slap_mask_t mask, type = 0; DB *db; - ai = index_mask( be, desc, prefixp ); + ai = bdb_index_mask( be, desc, prefixp ); if ( !ai ) { #ifdef BDB_MONITOR_IDX @@ -127,7 +112,7 @@ int bdb_index_param( } mask = ai->ai_indexmask; - rc = bdb_db_cache( be, prefixp->bv_val, &db ); + rc = bdb_db_cache( be, prefixp, &db ); if( rc != LDAP_SUCCESS ) { return rc; @@ -200,7 +185,7 @@ static int indexer( assert( mask != 0 ); - rc = bdb_db_cache( op->o_bd, atname->bv_val, &db ); + rc = bdb_db_cache( op->o_bd, atname, &db ); if ( rc != LDAP_SUCCESS ) { Debug( LDAP_DEBUG_ANY, diff --git a/servers/slapd/back-bdb/modify.c b/servers/slapd/back-bdb/modify.c index df1cf3dfca..c08e241295 100644 --- a/servers/slapd/back-bdb/modify.c +++ b/servers/slapd/back-bdb/modify.c @@ -42,6 +42,8 @@ int bdb_modify_internal( Attribute *save_attrs; Attribute *ap; int glue_attr_delete = 0; + int got_delete; + AttrInfo *ai; Debug( LDAP_DEBUG_TRACE, "bdb_modify_internal: 0x%08lx: %s\n", e->e_id, e->e_dn, 0); @@ -87,7 +89,9 @@ int bdb_modify_internal( } for ( ml = modlist; ml != NULL; ml = ml->sml_next ) { + struct berval ix_at; mod = &ml->sml_mod; + got_delete = 0; switch ( mod->sm_op ) { case LDAP_MOD_ADD: @@ -117,6 +121,8 @@ int bdb_modify_internal( if( err != LDAP_SUCCESS ) { Debug(LDAP_DEBUG_ARGS, "bdb_modify_internal: %d %s\n", err, *text, 0); + } else { + got_delete = 1; } break; @@ -129,6 +135,8 @@ int bdb_modify_internal( if( err != LDAP_SUCCESS ) { Debug(LDAP_DEBUG_ARGS, "bdb_modify_internal: %d %s\n", err, *text, 0); + } else { + got_delete = 1; } break; @@ -142,6 +150,8 @@ int bdb_modify_internal( Debug(LDAP_DEBUG_ARGS, "bdb_modify_internal: %d %s\n", err, *text, 0); + } else { + got_delete = 1; } break; @@ -194,13 +204,24 @@ int bdb_modify_internal( /* check if modified attribute was indexed * but not in case of NOOP... */ - err = bdb_index_is_indexed( op->o_bd, mod->sm_desc ); - if ( err == LDAP_SUCCESS && !op->o_noop ) { - ap = attr_find( save_attrs, mod->sm_desc ); - if ( ap ) ap->a_flags |= SLAP_ATTR_IXDEL; - - ap = attr_find( e->e_attrs, mod->sm_desc ); - if ( ap ) ap->a_flags |= SLAP_ATTR_IXADD; + ai = bdb_index_mask( op->o_bd, mod->sm_desc, &ix_at ); + if ( ai && !op->o_noop ) { + if ( got_delete ) { + struct berval ix2; + + ap = attr_find( save_attrs, mod->sm_desc ); + if ( ap ) ap->a_flags |= SLAP_ATTR_IXDEL; + + /* Find all other attrs that index to same slot */ + for ( ap = e->e_attrs; ap; ap=ap->a_next ) { + ai = bdb_index_mask( op->o_bd, ap->a_desc, &ix2 ); + if ( ai && ix2.bv_val == ix_at.bv_val ) + ap->a_flags |= SLAP_ATTR_IXADD; + } + } else { + ap = attr_find( e->e_attrs, mod->sm_desc ); + if ( ap ) ap->a_flags |= SLAP_ATTR_IXADD; + } } } @@ -230,24 +251,57 @@ int bdb_modify_internal( /* start with deleting the old index entries */ for ( ap = save_attrs; ap != NULL; ap = ap->a_next ) { if ( ap->a_flags & SLAP_ATTR_IXDEL ) { - rc = bdb_index_values( op, tid, ap->a_desc, - ap->a_nvals, - e->e_id, SLAP_INDEX_DELETE_OP ); - if ( rc != LDAP_SUCCESS ) { - attrs_free( e->e_attrs ); - e->e_attrs = save_attrs; - Debug( LDAP_DEBUG_ANY, - "Attribute index delete failure", - 0, 0, 0 ); - return rc; - } + struct berval tmp, *vals; + Attribute *a2; ap->a_flags &= ~SLAP_ATTR_IXDEL; + a2 = attr_find( e->e_attrs, ap->a_desc ); + if ( a2 ) { + /* need to detect which values were deleted */ + int i, j; + struct berval tmp; + j = ap->a_numvals; + for ( i=0; ia_nvals[i], NULL, op->o_tmpmemctx ); + /* Move deleted values to end of array */ + if ( rc == LDAP_NO_SUCH_ATTRIBUTE ) { + j--; + if ( i != j ) { + tmp = ap->a_nvals[j]; + ap->a_nvals[j] = ap->a_nvals[i]; + ap->a_nvals[i] = tmp; + tmp = ap->a_vals[j]; + ap->a_vals[j] = ap->a_vals[i]; + ap->a_vals[i] = tmp; + } + continue; + } + i++; + } + vals = &ap->a_nvals[j]; + } else { + /* attribute was completely deleted */ + vals = ap->a_nvals; + } + if ( !BER_BVISEMPTY( vals )) { + rc = bdb_index_values( op, tid, ap->a_desc, + vals, e->e_id, SLAP_INDEX_DELETE_OP ); + if ( rc != LDAP_SUCCESS ) { + attrs_free( e->e_attrs ); + e->e_attrs = save_attrs; + Debug( LDAP_DEBUG_ANY, + "Attribute index delete failure", + 0, 0, 0 ); + return rc; + } + } } } /* add the new index entries */ for ( ap = e->e_attrs; ap != NULL; ap = ap->a_next ) { if (ap->a_flags & SLAP_ATTR_IXADD) { + ap->a_flags &= ~SLAP_ATTR_IXADD; rc = bdb_index_values( op, tid, ap->a_desc, ap->a_nvals, e->e_id, SLAP_INDEX_ADD_OP ); @@ -259,7 +313,6 @@ int bdb_modify_internal( 0, 0, 0 ); return rc; } - ap->a_flags &= ~SLAP_ATTR_IXADD; } } diff --git a/servers/slapd/back-bdb/proto-bdb.h b/servers/slapd/back-bdb/proto-bdb.h index 4b547dce70..779f100a93 100644 --- a/servers/slapd/back-bdb/proto-bdb.h +++ b/servers/slapd/back-bdb/proto-bdb.h @@ -74,7 +74,7 @@ int bdb_back_init_cf( BackendInfo *bi ); int bdb_db_cache( Backend *be, - const char *name, + struct berval *name, DB **db ); /* @@ -328,17 +328,18 @@ int bdb_idl_append_one( ID *ids, ID id ); /* * index.c */ -#define bdb_index_is_indexed BDB_SYMBOL(index_is_indexed) +#define bdb_index_mask BDB_SYMBOL(index_mask) #define bdb_index_param BDB_SYMBOL(index_param) #define bdb_index_values BDB_SYMBOL(index_values) #define bdb_index_entry BDB_SYMBOL(index_entry) #define bdb_index_recset BDB_SYMBOL(index_recset) #define bdb_index_recrun BDB_SYMBOL(index_recrun) -extern int -bdb_index_is_indexed LDAP_P(( +extern AttrInfo * +bdb_index_mask LDAP_P(( Backend *be, - AttributeDescription *desc )); + AttributeDescription *desc, + struct berval *name )); extern int bdb_index_param LDAP_P((