]> git.sur5r.net Git - openldap/commitdiff
ITS#5183
authorQuanah Gibson-Mount <quanah@openldap.org>
Wed, 21 Nov 2007 19:18:32 +0000 (19:18 +0000)
committerQuanah Gibson-Mount <quanah@openldap.org>
Wed, 21 Nov 2007 19:18:32 +0000 (19:18 +0000)
CHANGES
servers/slapd/back-bdb/back-bdb.h
servers/slapd/back-bdb/dbcache.c
servers/slapd/back-bdb/index.c
servers/slapd/back-bdb/modify.c
servers/slapd/back-bdb/proto-bdb.h

diff --git a/CHANGES b/CHANGES
index 80fe37b949e559aeb50f5c66f8279c5cf31d3e66..5370f69274c723e054ad4af4a4e5dbeb1d4bf33d 100644 (file)
--- 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)
index a009ecb61fb921f9dae4ff83228acd554002fe47..168619e0fd9ed5a18000b2fa3188ceecccfd3bbc 100644 (file)
@@ -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;
 };
 
index 35529c79231b31e5d29c047cae8f103a2b0624cb..e08c2493cfdd6baf30ea177665d07d6feab54cea 100644 (file)
@@ -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 );
index e193dae30d90e5ab122931421e12b28f2dbe0ac5..8c652bd086e1b8a0e1df21c4b6023a996f9a3d9b 100644 (file)
@@ -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,
index df1cf3dfcad38c64a75ca3c54f3cdd6c9e07b42d..c08e241295ced758eca0daeac45ded766b49f29c 100644 (file)
@@ -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; i<j; ) {
+                                       rc = attr_valfind( a2, SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH,
+                                               &ap->a_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;
                }
        }
 
index 4b547dce703ed685f706805af9b6f59afcb41897..779f100a93b3968849b9506aecb0edf70f6738b7 100644 (file)
@@ -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((