From: Kurt Zeilenga Date: Wed, 26 Feb 2003 16:17:49 +0000 (+0000) Subject: Fix slapd directoryString exact index normalization bug X-Git-Tag: OPENLDAP_REL_ENG_2_1_14~8 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=c48f56dbaf644181638c805ba2776460592f7d6e;p=openldap Fix slapd directoryString exact index normalization bug Fix back-bdb bdb_cache_find_entry* retry bug Fix back-bdb log message bug Fix back-bdb group/atttribute txn code Updated slapadd to complain about holes in the DIT --- diff --git a/CHANGES b/CHANGES index 99baba13bb..275cacdac4 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,14 @@ OpenLDAP 2.1 Change Log +OpenLDAP 2.1.14 Engineering + Fix slapd directoryString exact index normalization bug + Fix back-bdb bdb_cache_find_entry* retry bug + Fix back-bdb log message bug + Fix back-bdb group/atttribute txn code + Updated slapadd to complain about holes in the DIT + Documentation + Misc man page updates + OpenLDAP 2.1.13 Release Fixed back-bdb group ACL deadlock bug (ITS#2195) Fixed back-bdb passwd hang bug (ITS#2122) @@ -29,8 +38,9 @@ OpenLDAP 2.1.13 Release Build Environment Check back-bdb requirement for BDB 4.1 Removed configure flags for deprecated features - Misc man page updates Updated test suite + Documentation + Misc man page updates OpenLDAP 2.1.12 Release Build Environment diff --git a/servers/slapd/ad.c b/servers/slapd/ad.c index ece6019282..4ed522cd2c 100644 --- a/servers/slapd/ad.c +++ b/servers/slapd/ad.c @@ -325,6 +325,7 @@ done:; } d2 = ch_malloc(sizeof(AttributeDescription) + dlen); + d2->ad_next = NULL; d2->ad_type = desc.ad_type; d2->ad_flags = desc.ad_flags; d2->ad_cname.bv_len = desc.ad_type->sat_cname.bv_len; diff --git a/servers/slapd/back-bdb/add.c b/servers/slapd/back-bdb/add.c index 3e85b1a7ad..b7c47dadb4 100644 --- a/servers/slapd/back-bdb/add.c +++ b/servers/slapd/back-bdb/add.c @@ -99,6 +99,7 @@ retry: /* transaction retry */ rc = TXN_ABORT( ltid ); ltid = NULL; op->o_private = NULL; + op->o_do_not_cache = opinfo.boi_acl_cache; if( rc != 0 ) { rc = LDAP_OTHER; text = "internal error"; @@ -134,6 +135,7 @@ retry: /* transaction retry */ opinfo.boi_txn = ltid; opinfo.boi_locker = locker; opinfo.boi_err = 0; + opinfo.boi_acl_cache = op->o_do_not_cache; op->o_private = &opinfo; /* @@ -216,13 +218,13 @@ retry: /* transaction retry */ rc = access_allowed( be, conn, op, p, children, NULL, ACL_WRITE, NULL ); - switch( opinfo.boi_err ) { - case DB_LOCK_DEADLOCK: - case DB_LOCK_NOTGRANTED: - goto retry; - } - if ( ! rc ) { + switch( opinfo.boi_err ) { + case DB_LOCK_DEADLOCK: + case DB_LOCK_NOTGRANTED: + goto retry; + } + #ifdef NEW_LOGGING LDAP_LOG ( OPERATION, DETAIL1, "bdb_add: no write access to parent\n", 0, 0, 0 ); @@ -316,13 +318,13 @@ retry: /* transaction retry */ p = NULL; - switch( opinfo.boi_err ) { - case DB_LOCK_DEADLOCK: - case DB_LOCK_NOTGRANTED: - goto retry; - } - if ( ! rc ) { + switch( opinfo.boi_err ) { + case DB_LOCK_DEADLOCK: + case DB_LOCK_NOTGRANTED: + goto retry; + } + #ifdef NEW_LOGGING LDAP_LOG ( OPERATION, DETAIL1, "bdb_add: no write access to parent\n", 0, 0, 0 ); @@ -379,13 +381,13 @@ retry: /* transaction retry */ rc = access_allowed( be, conn, op, e, entry, NULL, ACL_WRITE, NULL ); - switch( opinfo.boi_err ) { - case DB_LOCK_DEADLOCK: - case DB_LOCK_NOTGRANTED: - goto retry; - } - if ( ! rc ) { + switch( opinfo.boi_err ) { + case DB_LOCK_DEADLOCK: + case DB_LOCK_NOTGRANTED: + goto retry; + } + #ifdef NEW_LOGGING LDAP_LOG ( OPERATION, DETAIL1, "bdb_add: no write access to entry\n", 0, 0, 0 ); diff --git a/servers/slapd/back-bdb/attribute.c b/servers/slapd/back-bdb/attribute.c index 10ef737fae..f5cbdf7577 100644 --- a/servers/slapd/back-bdb/attribute.c +++ b/servers/slapd/back-bdb/attribute.c @@ -97,13 +97,19 @@ bdb_attribute( } else { dn2entry_retry: /* can we find entry */ - rc = bdb_dn2entry_r( be, NULL, entry_ndn, &e, NULL, 0, locker, &lock ); + rc = bdb_dn2entry_r( be, txn, entry_ndn, &e, NULL, 0, locker, &lock ); switch( rc ) { case DB_NOTFOUND: case 0: break; case DB_LOCK_DEADLOCK: case DB_LOCK_NOTGRANTED: + /* the txn must abort and retry */ + if ( txn ) { + boi->boi_err = rc; + return LDAP_BUSY; + } + ldap_pvt_thread_yield(); goto dn2entry_retry; default: boi->boi_err = rc; diff --git a/servers/slapd/back-bdb/back-bdb.h b/servers/slapd/back-bdb/back-bdb.h index 5a28d25581..449d0f6d73 100644 --- a/servers/slapd/back-bdb/back-bdb.h +++ b/servers/slapd/back-bdb/back-bdb.h @@ -157,6 +157,7 @@ struct bdb_op_info { DB_TXN* boi_txn; u_int32_t boi_err; u_int32_t boi_locker; + int boi_acl_cache; }; #define DB_OPEN(db, file, name, type, flags, mode) \ diff --git a/servers/slapd/back-bdb/cache.c b/servers/slapd/back-bdb/cache.c index ad98106a69..ef753b29e1 100644 --- a/servers/slapd/back-bdb/cache.c +++ b/servers/slapd/back-bdb/cache.c @@ -794,7 +794,7 @@ try_again: /* * entry is deleted or not fully created yet */ - if ( state != CACHE_ENTRY_READY ) { + if ( state != CACHE_ENTRY_READY && state != CACHE_ENTRY_COMMITTED ) { assert(state != CACHE_ENTRY_UNDEFINED); /* free cache read lock */ @@ -889,7 +889,7 @@ try_again: /* * entry is deleted or not fully created yet */ - if ( state != CACHE_ENTRY_READY ) { + if ( state != CACHE_ENTRY_READY && state != CACHE_ENTRY_COMMITTED ) { assert(state != CACHE_ENTRY_UNDEFINED); diff --git a/servers/slapd/back-bdb/delete.c b/servers/slapd/back-bdb/delete.c index 79cb460843..079b44081c 100644 --- a/servers/slapd/back-bdb/delete.c +++ b/servers/slapd/back-bdb/delete.c @@ -70,6 +70,7 @@ retry: /* transaction retry */ rc = TXN_ABORT( ltid ); ltid = NULL; op->o_private = NULL; + op->o_do_not_cache = opinfo.boi_acl_cache; if( rc != 0 ) { rc = LDAP_OTHER; text = "internal error"; @@ -106,6 +107,7 @@ retry: /* transaction retry */ opinfo.boi_txn = ltid; opinfo.boi_locker = locker; opinfo.boi_err = 0; + opinfo.boi_acl_cache = op->o_do_not_cache; op->o_private = &opinfo; if ( !be_issuffix( be, ndn ) ) { @@ -162,13 +164,13 @@ retry: /* transaction retry */ bdb_unlocked_cache_return_entry_r(&bdb->bi_cache, p); p = NULL; - switch( opinfo.boi_err ) { - case DB_LOCK_DEADLOCK: - case DB_LOCK_NOTGRANTED: - goto retry; - } - if ( !rc ) { + switch( opinfo.boi_err ) { + case DB_LOCK_DEADLOCK: + case DB_LOCK_NOTGRANTED: + goto retry; + } + #ifdef NEW_LOGGING LDAP_LOG ( OPERATION, DETAIL1, "<=- bdb_delete: no write access to parent\n", 0, 0, 0 ); @@ -195,13 +197,13 @@ retry: /* transaction retry */ p = NULL; - switch( opinfo.boi_err ) { - case DB_LOCK_DEADLOCK: - case DB_LOCK_NOTGRANTED: - goto retry; - } - if ( !rc ) { + switch( opinfo.boi_err ) { + case DB_LOCK_DEADLOCK: + case DB_LOCK_NOTGRANTED: + goto retry; + } + #ifdef NEW_LOGGING LDAP_LOG ( OPERATION, DETAIL1, "<=- bdb_delete: no access to parent\n", 0, 0, 0 ); @@ -298,13 +300,13 @@ retry: /* transaction retry */ rc = access_allowed( be, conn, op, e, entry, NULL, ACL_WRITE, NULL ); - switch( opinfo.boi_err ) { - case DB_LOCK_DEADLOCK: - case DB_LOCK_NOTGRANTED: - goto retry; - } - if ( !rc ) { + switch( opinfo.boi_err ) { + case DB_LOCK_DEADLOCK: + case DB_LOCK_NOTGRANTED: + goto retry; + } + #ifdef NEW_LOGGING LDAP_LOG ( OPERATION, DETAIL1, "<=- bdb_delete: no write access to entry\n", 0, 0, 0 ); diff --git a/servers/slapd/back-bdb/group.c b/servers/slapd/back-bdb/group.c index d449056794..ddb23f7055 100644 --- a/servers/slapd/back-bdb/group.c +++ b/servers/slapd/back-bdb/group.c @@ -107,11 +107,21 @@ bdb_group( } else { dn2entry_retry: /* can we find group entry */ - rc = bdb_dn2entry_r( be, NULL, gr_ndn, &e, NULL, 0, locker, &lock ); + rc = bdb_dn2entry_r( be, txn, gr_ndn, &e, NULL, 0, locker, &lock ); if( rc ) { - if ( rc == DB_LOCK_DEADLOCK || rc == DB_LOCK_NOTGRANTED ) - goto dn2entry_retry; boi->boi_err = rc; + if ( rc == DB_LOCK_DEADLOCK || rc == DB_LOCK_NOTGRANTED ) { + if ( txn ) { + /* must let owning txn abort, but our result + * is still inconclusive, so don't let it + * get cached. + */ + op->o_do_not_cache = 1; + return( 1 ); + } + ldap_pvt_thread_yield(); + goto dn2entry_retry; + } if ( free_lock_id ) { LOCK_ID_FREE ( bdb->bi_dbenv, locker ); } @@ -206,8 +216,10 @@ dn2entry_retry: group_oc_name, group_at_name, 0 ); #endif - if( value_find_ex( group_at, SLAP_MR_VALUE_NORMALIZED_MATCH, - attr->a_vals, op_ndn ) != LDAP_SUCCESS ) { + if( value_find_ex( group_at, + SLAP_MR_VALUE_NORMALIZED_MATCH, + attr->a_vals, op_ndn ) != LDAP_SUCCESS ) + { #ifdef NEW_LOGGING LDAP_LOG( BACK_BDB, DETAIL1, "bdb_group: \"%s\" not in \"%s\": %s\n", diff --git a/servers/slapd/back-bdb/id2entry.c b/servers/slapd/back-bdb/id2entry.c index 5e4ef60df4..87260b65d8 100644 --- a/servers/slapd/back-bdb/id2entry.c +++ b/servers/slapd/back-bdb/id2entry.c @@ -204,6 +204,18 @@ int bdb_entry_return( if( (void *) e->e_attrs != (void *) (e+1)) { attrs_free( e->e_attrs ); } +#ifdef SLAP_NVALUES + else { + /* nvals are not contiguous with the rest. oh well. */ + Attribute *a; + for (a = e->e_attrs; a; a=a->a_next) { + if (a->a_nvals) { + ber_bvarray_free( a->a_nvals ); + a->a_nvals = NULL; + } + } + } +#endif #ifndef BDB_HIER /* See if the DNs were changed by modrdn */ diff --git a/servers/slapd/back-bdb/modify.c b/servers/slapd/back-bdb/modify.c index b2ffc7a178..167938a960 100644 --- a/servers/slapd/back-bdb/modify.c +++ b/servers/slapd/back-bdb/modify.c @@ -210,7 +210,7 @@ int bdb_modify_internal( for ( ap = save_attrs; ap != NULL; ap = ap->a_next ) { if ( ap->a_flags & SLAP_ATTR_IXDEL ) { rc = bdb_index_values( be, tid, ap->a_desc, ap->a_vals, - e->e_id, SLAP_INDEX_DELETE_OP ); + e->e_id, SLAP_INDEX_DELETE_OP ); if ( rc != LDAP_SUCCESS ) { attrs_free( e->e_attrs ); e->e_attrs = save_attrs; @@ -233,7 +233,7 @@ int bdb_modify_internal( for ( ap = e->e_attrs; ap != NULL; ap = ap->a_next ) { if (ap->a_flags & SLAP_ATTR_IXADD) { rc = bdb_index_values( be, tid, ap->a_desc, ap->a_vals, - e->e_id, SLAP_INDEX_ADD_OP ); + e->e_id, SLAP_INDEX_ADD_OP ); if ( rc != LDAP_SUCCESS ) { attrs_free( e->e_attrs ); e->e_attrs = save_attrs; @@ -319,6 +319,7 @@ retry: /* transaction retry */ rc = TXN_ABORT( ltid ); ltid = NULL; op->o_private = NULL; + op->o_do_not_cache = opinfo.boi_acl_cache; if( rc != 0 ) { rc = LDAP_OTHER; text = "internal error"; @@ -351,6 +352,7 @@ retry: /* transaction retry */ opinfo.boi_txn = ltid; opinfo.boi_locker = locker; opinfo.boi_err = 0; + opinfo.boi_acl_cache = op->o_do_not_cache; op->o_private = &opinfo; /* get entry */ @@ -449,6 +451,9 @@ retry: /* transaction retry */ "bdb_modify: modify failed (%d)\n", rc, 0, 0 ); #endif + if ( (rc == LDAP_INSUFFICIENT_ACCESS) && opinfo.boi_err ) { + rc = opinfo.boi_err; + } switch( rc ) { case DB_LOCK_DEADLOCK: case DB_LOCK_NOTGRANTED: diff --git a/servers/slapd/back-bdb/modrdn.c b/servers/slapd/back-bdb/modrdn.c index 8fcba26ffd..783bd70fc5 100644 --- a/servers/slapd/back-bdb/modrdn.c +++ b/servers/slapd/back-bdb/modrdn.c @@ -108,6 +108,7 @@ retry: /* transaction retry */ rc = TXN_ABORT( ltid ); ltid = NULL; op->o_private = NULL; + op->o_do_not_cache = opinfo.boi_acl_cache; if( rc != 0 ) { rc = LDAP_OTHER; text = "internal error"; @@ -141,6 +142,7 @@ retry: /* transaction retry */ opinfo.boi_txn = ltid; opinfo.boi_locker = locker; opinfo.boi_err = 0; + opinfo.boi_acl_cache = op->o_do_not_cache; op->o_private = &opinfo; /* get entry */ @@ -191,13 +193,13 @@ retry: /* transaction retry */ /* check write on old entry */ rc = access_allowed( be, conn, op, e, entry, NULL, ACL_WRITE, NULL ); - switch( opinfo.boi_err ) { - case DB_LOCK_DEADLOCK: - case DB_LOCK_NOTGRANTED: - goto retry; - } - if ( ! rc ) { + switch( opinfo.boi_err ) { + case DB_LOCK_DEADLOCK: + case DB_LOCK_NOTGRANTED: + goto retry; + } + #ifdef NEW_LOGGING LDAP_LOG ( OPERATION, ERR, "==>bdb_modrdn: no access to entry\n", 0, 0, 0 ); @@ -277,6 +279,12 @@ retry: /* transaction retry */ children, NULL, ACL_WRITE, NULL ); if ( ! rc ) { + switch( opinfo.boi_err ) { + case DB_LOCK_DEADLOCK: + case DB_LOCK_NOTGRANTED: + goto retry; + } + rc = LDAP_INSUFFICIENT_ACCESS; #ifdef NEW_LOGGING LDAP_LOG ( OPERATION, ERR, @@ -329,6 +337,12 @@ retry: /* transaction retry */ p = NULL; if ( ! rc ) { + switch( opinfo.boi_err ) { + case DB_LOCK_DEADLOCK: + case DB_LOCK_NOTGRANTED: + goto retry; + } + rc = LDAP_INSUFFICIENT_ACCESS; #ifdef NEW_LOGGING LDAP_LOG ( OPERATION, ERR, @@ -468,6 +482,12 @@ retry: /* transaction retry */ NULL, ACL_WRITE, NULL ); if( ! rc ) { + switch( opinfo.boi_err ) { + case DB_LOCK_DEADLOCK: + case DB_LOCK_NOTGRANTED: + goto retry; + } + #ifdef NEW_LOGGING LDAP_LOG ( OPERATION, DETAIL1, "==>bdb_modrdn: no wr to newSup children\n", 0, 0, 0 ); @@ -531,6 +551,12 @@ retry: /* transaction retry */ np = NULL; if ( ! rc ) { + switch( opinfo.boi_err ) { + case DB_LOCK_DEADLOCK: + case DB_LOCK_NOTGRANTED: + goto retry; + } + rc = LDAP_INSUFFICIENT_ACCESS; #ifdef NEW_LOGGING LDAP_LOG ( OPERATION, ERR, @@ -621,15 +647,6 @@ retry: /* transaction retry */ goto return_results; } -#ifdef NEW_LOGGING - LDAP_LOG ( OPERATION, ERR, - "bdb_modrdn: new ndn=%s does not exist\n", new_ndn.bv_val, 0, 0 ); -#else - Debug( LDAP_DEBUG_TRACE, - "bdb_modrdn: new ndn=%s does not exist\n", - new_ndn.bv_val, 0, 0 ); -#endif - /* Get attribute type and attribute value of our new rdn, we will * need to add that to our new entry */ @@ -745,6 +762,9 @@ retry: /* transaction retry */ &text, textbuf, textlen ); if( rc != LDAP_SUCCESS ) { + if ( ( rc == LDAP_INSUFFICIENT_ACCESS ) && opinfo.boi_err ) { + rc = opinfo.boi_err; + } switch( rc ) { case DB_LOCK_DEADLOCK: case DB_LOCK_NOTGRANTED: diff --git a/servers/slapd/back-bdb/operational.c b/servers/slapd/back-bdb/operational.c index ca87a6c727..8ffb72c2fb 100644 --- a/servers/slapd/back-bdb/operational.c +++ b/servers/slapd/back-bdb/operational.c @@ -29,63 +29,17 @@ bdb_hasSubordinates( { struct bdb_info *bdb = (struct bdb_info *) be->be_private; int rc; - DB_TXN *ltid = NULL; - struct bdb_op_info opinfo; assert( e ); assert( hasSubordinates ); - if( 0 ) { -retry: /* transaction retry */ -#if 0 - if( e != NULL ) { - bdb_unlocked_cache_return_entry_w(&bdb->bi_cache, e); - } -#endif -#ifdef NEW_LOGGING - LDAP_LOG ( OPERATION, DETAIL1, - "=> bdb_hasSubordinates: retrying...\n", 0, 0, 0 ); -#else - Debug( LDAP_DEBUG_TRACE, "==> bdb_hasSubordinates: retrying...\n", - 0, 0, 0 ); -#endif - rc = TXN_ABORT( ltid ); - ltid = NULL; - op->o_private = NULL; - if( rc != 0 ) { - rc = LDAP_OTHER; - goto return_results; - } - ldap_pvt_thread_yield(); - } - - /* begin transaction */ - rc = TXN_BEGIN( bdb->bi_dbenv, NULL, <id, bdb->bi_db_opflags ); - if ( rc != 0 ) { -#ifdef NEW_LOGGING - LDAP_LOG ( OPERATION, ERR, - "=> bdb_hasSubordinates: txn_begin failed: %s (%d)\n", - db_strerror(rc), rc, 0 ); -#else - Debug( LDAP_DEBUG_TRACE, - "bdb_hasSubordinates: txn_begin failed: %s (%d)\n", - db_strerror( rc ), rc, 0 ); -#endif - rc = LDAP_OTHER; - return rc; - } - - opinfo.boi_bdb = be; - opinfo.boi_txn = ltid; - opinfo.boi_locker = TXN_ID ( ltid ); - opinfo.boi_err = 0; - op->o_private = &opinfo; - - rc = bdb_dn2id_children( be, ltid, &e->e_nname, 0 ); +retry: + rc = bdb_dn2id_children( be, NULL, &e->e_nname, 0 ); switch( rc ) { case DB_LOCK_DEADLOCK: case DB_LOCK_NOTGRANTED: + ldap_pvt_thread_yield(); goto retry; case 0: @@ -110,18 +64,6 @@ retry: /* transaction retry */ rc = LDAP_OTHER; } -return_results: - if ( rc == LDAP_SUCCESS && bdb->bi_txn_cp ) { - ldap_pvt_thread_yield(); - TXN_CHECKPOINT( bdb->bi_dbenv, - bdb->bi_txn_cp_kbyte, bdb->bi_txn_cp_min, 0 ); - } - - if ( ltid != NULL ) { - TXN_ABORT( ltid ); - op->o_private = NULL; - } - return rc; } diff --git a/servers/slapd/back-bdb/passwd.c b/servers/slapd/back-bdb/passwd.c index d801fb9260..33803ff633 100644 --- a/servers/slapd/back-bdb/passwd.c +++ b/servers/slapd/back-bdb/passwd.c @@ -122,6 +122,7 @@ retry: /* transaction retry */ rc = TXN_ABORT( ltid ); ltid = NULL; op->o_private = NULL; + op->o_do_not_cache = opinfo.boi_acl_cache; if( rc != 0 ) { rc = LDAP_OTHER; *text = "internal error"; @@ -155,6 +156,7 @@ retry: /* transaction retry */ opinfo.boi_txn = ltid; opinfo.boi_locker = locker; opinfo.boi_err = 0; + opinfo.boi_acl_cache = op->o_do_not_cache; op->o_private = &opinfo; /* get entry */ @@ -221,6 +223,9 @@ retry: /* transaction retry */ rc = bdb_modify_internal( be, conn, op, ltid, &ml, e, text, textbuf, textlen ); + if ( (rc == LDAP_INSUFFICIENT_ACCESS) && opinfo.boi_err ) { + rc = opinfo.boi_err; + } switch(rc) { case DB_LOCK_DEADLOCK: case DB_LOCK_NOTGRANTED: diff --git a/servers/slapd/back-bdb/search.c b/servers/slapd/back-bdb/search.c index 34a60cf355..feea82ee22 100644 --- a/servers/slapd/back-bdb/search.c +++ b/servers/slapd/back-bdb/search.c @@ -84,7 +84,6 @@ bdb_search( u_int32_t locker = 0; DB_LOCK lock; - struct bdb_op_info opinfo; #ifdef NEW_LOGGING LDAP_LOG ( OPERATION, ENTRY, "bdb_back_search\n", 0, 0, 0 ); @@ -136,12 +135,6 @@ bdb_search( return rc; } - opinfo.boi_bdb = be; - opinfo.boi_txn = NULL; - opinfo.boi_locker = locker; - opinfo.boi_err = 0; - op->o_private = &opinfo; - if ( nbase->bv_len == 0 ) { /* DIT root special case */ e = (Entry *) &slap_entry_root; @@ -809,10 +802,10 @@ id2entry_retry: } else { #ifdef NEW_LOGGING LDAP_LOG ( OPERATION, RESULTS, - "bdb_search: %ld does match filter\n", (long) id, 0, 0); + "bdb_search: %ld does not match filter\n", (long) id, 0, 0); #else Debug( LDAP_DEBUG_TRACE, - "bdb_search: %ld does match filter\n", + "bdb_search: %ld does not match filter\n", (long) id, 0, 0 ); #endif } diff --git a/servers/slapd/back-bdb/tools.c b/servers/slapd/back-bdb/tools.c index 04307c5c7c..679ca32c00 100644 --- a/servers/slapd/back-bdb/tools.c +++ b/servers/slapd/back-bdb/tools.c @@ -15,6 +15,16 @@ static DBC *cursor = NULL; static DBT key, data; +typedef struct dn_id { + ID id; + struct berval dn; +} dn_id; + +#define HOLE_SIZE 4096 +dn_id hbuf[HOLE_SIZE], *holes = hbuf; +unsigned nhmax = HOLE_SIZE; +unsigned nholes; + int bdb_tool_entry_open( BackendDB *be, int mode ) { @@ -46,6 +56,16 @@ int bdb_tool_entry_close( cursor = NULL; } + if( nholes ) { + unsigned i; + fprintf( stderr, "Error, entries missing!\n"); + for (i=0; ibe_private; struct berval dn = e->e_nname; @@ -126,7 +147,7 @@ int bdb_tool_next_id( } else { dnParent( &dn, &pdn ); e->e_nname = pdn; - rc = bdb_tool_next_id( be, tid, e, text ); + rc = bdb_tool_next_id( be, tid, e, text, 1 ); if ( rc ) { return rc; } @@ -158,6 +179,33 @@ int bdb_tool_next_id( Debug( LDAP_DEBUG_ANY, "=> bdb_tool_entry_put: %s\n", text->bv_val, 0, 0 ); #endif + } else if ( hole ) { + if ( nholes == nhmax - 1 ) { + if ( holes == hbuf ) { + holes = malloc( nhmax * sizeof(ID) * 2 ); + AC_MEMCPY( holes, hbuf, sizeof(hbuf) ); + } else { + holes = realloc( holes, nhmax * sizeof(ID) * 2 ); + } + nhmax *= 2; + } + ber_dupbv( &holes[nholes].dn, &dn ); + holes[nholes++].id = e->e_id; + } + } else if ( !hole ) { + unsigned i; + + for ( i=0; ie_id ) { + int j; + free(holes[i].dn.bv_val); + for (j=i;j e->e_id ) { + break; + } } } return rc; @@ -205,7 +253,7 @@ ID bdb_tool_entry_put( } /* add dn2id indices */ - rc = bdb_tool_next_id( be, tid, e, text ); + rc = bdb_tool_next_id( be, tid, e, text, 0 ); if( rc != 0 ) { goto done; } diff --git a/servers/slapd/entry.c b/servers/slapd/entry.c index 40f29db621..8f3fa9ad02 100644 --- a/servers/slapd/entry.c +++ b/servers/slapd/entry.c @@ -87,6 +87,7 @@ str2entry( char *s ) e->e_id = NOID; /* dn + attributes */ + vals[0].bv_len = 0; vals[1].bv_val = NULL; next = s; diff --git a/servers/slapd/schema_init.c b/servers/slapd/schema_init.c index 12d0d5d324..53cdb6a6f2 100644 --- a/servers/slapd/schema_init.c +++ b/servers/slapd/schema_init.c @@ -1246,8 +1246,8 @@ static int caseExactIgnoreIndexer( BerVarray values, BerVarray *keysp ) { - int i; - unsigned casefold; + int i,j; + unsigned casefold,wasspace; size_t slen, mlen; BerVarray keys; HASH_CONTEXT HASHcontext; @@ -1272,9 +1272,33 @@ static int caseExactIgnoreIndexer( ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD; for( i=0; values[i].bv_val != NULL; i++ ) { - struct berval value; + struct berval value, nvalue; UTF8bvnormalize( &values[i], &value, casefold ); + /* collapse spaces (in place) */ + nvalue.bv_len = 0; + nvalue.bv_val = value.bv_val; + + wasspace=1; + for( j=0; jbv_len > 0 ) { HASH_Update( &HASHcontext, @@ -1285,11 +1309,10 @@ static int caseExactIgnoreIndexer( HASH_Update( &HASHcontext, mr->smr_oid, mlen ); HASH_Update( &HASHcontext, - value.bv_val, value.bv_len ); + nvalue.bv_val, nvalue.bv_len ); HASH_Final( HASHdigest, &HASHcontext ); free( value.bv_val ); - ber_dupbv( &keys[i], &digest ); } @@ -1367,11 +1390,11 @@ static int caseExactIgnoreSubstringsIndexer( BerVarray values, BerVarray *keysp ) { - unsigned casefold; - ber_len_t i, nkeys; + unsigned casefold, wasspace; + ber_len_t i, j, nkeys; size_t slen, mlen; BerVarray keys; - BerVarray nvalues; + BerVarray tvalues, nvalues; HASH_CONTEXT HASHcontext; unsigned char HASHdigest[HASH_BYTES]; @@ -1391,10 +1414,39 @@ static int caseExactIgnoreSubstringsIndexer( casefold = ( mr != caseExactSubstringsMatchingRule ) ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD; + tvalues = ch_malloc( sizeof( struct berval ) * (i+1) ); nvalues = ch_malloc( sizeof( struct berval ) * (i+1) ); + for( i=0; values[i].bv_val != NULL; i++ ) { - UTF8bvnormalize( &values[i], &nvalues[i], casefold ); + UTF8bvnormalize( &values[i], &tvalues[i], casefold ); + + /* collapse spaces (in place) */ + nvalues[i].bv_len = 0; + nvalues[i].bv_val = tvalues[i].bv_val; + + wasspace=1; + for( j=0; jbe_entry_close( be ); + if( be->be_entry_close( be )) rc = EXIT_FAILURE; if( be->be_sync ) { be->be_sync( be );