X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fback-bdb%2Fmodrdn.c;h=749f6571deefbf33906fd52d3e7475a4218ae1e9;hb=82c1b0d1f0a27e374961c910473f549878e81e24;hp=ef54c7a744c73c785b5cf73aeb7e508061dbd635;hpb=6f461690c1647a710fcb25022ad72e5c82b56674;p=openldap diff --git a/servers/slapd/back-bdb/modrdn.c b/servers/slapd/back-bdb/modrdn.c index ef54c7a744..749f6571de 100644 --- a/servers/slapd/back-bdb/modrdn.c +++ b/servers/slapd/back-bdb/modrdn.c @@ -1,8 +1,17 @@ /* modrdn.c - bdb backend modrdn routine */ /* $OpenLDAP$ */ -/* - * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved. - * COPYING RESTRICTIONS APPLY, see COPYRIGHT file +/* This work is part of OpenLDAP Software . + * + * Copyright 2000-2004 The OpenLDAP Foundation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted only as authorized by the OpenLDAP + * Public License. + * + * A copy of this license is available in the file LICENSE in the + * top-level directory of the distribution or, alternatively, at + * . */ #include "portable.h" @@ -49,12 +58,20 @@ bdb_modrdn( Operation *op, SlapReply *rs ) u_int32_t locker = 0; DB_LOCK lock, plock, nplock; - int noop = 0; + int num_retries = 0; -#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC) - Operation *ps_list; + LDAPControl *ctrls[SLAP_MAX_RESPONSE_CONTROLS]; + int num_ctrls = 0; + + Operation *ps_list; struct psid_entry *pm_list, *pm_prev; -#endif + int rc; + EntryInfo *suffix_ei; + Entry *ctxcsn_e; + int ctxcsn_added = 0; + + int parent_is_glue = 0; + int parent_is_leaf = 0; #ifdef NEW_LOGGING LDAP_LOG ( OPERATION, ENTRY, "==>bdb_modrdn(%s,%s,%s)\n", @@ -85,16 +102,13 @@ retry: /* transaction retry */ #else Debug( LDAP_DEBUG_TRACE, "==>bdb_modrdn: retrying...\n", 0, 0, 0 ); #endif - -#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC) - pm_list = LDAP_LIST_FIRST(&op->o_pm_list); - while ( pm_list != NULL ) { - LDAP_LIST_REMOVE ( pm_list, ps_link ); + pm_list = LDAP_LIST_FIRST(&op->o_pm_list); + while ( pm_list != NULL ) { + LDAP_LIST_REMOVE ( pm_list, ps_link ); pm_prev = pm_list; - pm_list = LDAP_LIST_NEXT ( pm_list, ps_link ); + pm_list = LDAP_LIST_NEXT ( pm_list, ps_link ); ch_free( pm_prev ); - } -#endif + } rs->sr_err = TXN_ABORT( ltid ); ltid = NULL; @@ -105,7 +119,10 @@ retry: /* transaction retry */ rs->sr_text = "internal error"; goto return_results; } + parent_is_glue = 0; + parent_is_leaf = 0; ldap_pvt_thread_yield(); + bdb_trans_backoff( ++num_retries ); } /* begin transaction */ @@ -137,8 +154,8 @@ retry: /* transaction retry */ op->o_private = &opinfo; /* get entry */ - rs->sr_err = bdb_dn2entry( op->o_bd, ltid, &op->o_req_ndn, &ei, 1, - locker, &lock, op->o_tmpmemctx ); + rs->sr_err = bdb_dn2entry( op, ltid, &op->o_req_ndn, &ei, 1, + locker, &lock ); switch( rs->sr_err ) { case 0: @@ -157,7 +174,10 @@ retry: /* transaction retry */ } e = ei->bei_e; - if ( rs->sr_err == DB_NOTFOUND ) { + /* FIXME: dn2entry() should return non-glue entry */ + if (( rs->sr_err == DB_NOTFOUND ) || + ( !manageDSAit && e && is_entry_glue( e ))) + { if( e != NULL ) { rs->sr_matched = ch_strdup( e->e_dn ); rs->sr_ref = is_entry_referral( e ) @@ -167,8 +187,19 @@ retry: /* transaction retry */ e = NULL; } else { - rs->sr_ref = referral_rewrite( default_referral, - NULL, &op->o_req_dn, LDAP_SCOPE_DEFAULT ); + BerVarray deref = NULL; + if ( !LDAP_STAILQ_EMPTY( &op->o_bd->be_syncinfo )) { + syncinfo_t *si; + LDAP_STAILQ_FOREACH( si, &op->o_bd->be_syncinfo, si_next ) { + struct berval tmpbv; + ber_dupbv( &tmpbv, &si->si_provideruri_bv[0] ); + ber_bvarray_add( &deref, &tmpbv ); + } + } else { + deref = default_referral; + } + rs->sr_ref = referral_rewrite( deref, NULL, &op->o_req_dn, + LDAP_SCOPE_DEFAULT ); } rs->sr_err = LDAP_REFERRAL; @@ -182,9 +213,15 @@ retry: /* transaction retry */ goto done; } + if ( get_assert( op ) && + ( test_filter( op, e, get_assertion( op )) != LDAP_COMPARE_TRUE )) + { + rs->sr_err = LDAP_ASSERTION_FAILED; + goto return_results; + } + /* check write on old entry */ rs->sr_err = access_allowed( op, e, entry, NULL, ACL_WRITE, NULL ); - if ( ! rs->sr_err ) { switch( opinfo.boi_err ) { case DB_LOCK_DEADLOCK: @@ -240,6 +277,7 @@ retry: /* transaction retry */ } ei->bei_state |= CACHE_ENTRY_NO_KIDS; #endif + if (!manageDSAit && is_entry_referral( e ) ) { /* parent is a referral, don't allow add */ rs->sr_ref = get_entry_referrals( op, e ); @@ -273,8 +311,8 @@ retry: /* transaction retry */ * children. */ eip = ei->bei_parent; - rs->sr_err = bdb_cache_find_id( op->o_bd, ltid, - eip->bei_id, &eip, 0, locker, &plock, op->o_tmpmemctx ); + rs->sr_err = bdb_cache_find_id( op, ltid, + eip->bei_id, &eip, 0, locker, &plock ); switch( rs->sr_err ) { case 0: @@ -355,10 +393,10 @@ retry: /* transaction retry */ } else { /* no parent, modrdn entry directly under root */ - isroot = be_isroot( op->o_bd, &op->o_ndn ); + isroot = be_isroot( op ); if ( ! isroot ) { if ( be_issuffix( op->o_bd, (struct berval *)&slap_empty_bv ) - || be_isupdate( op->o_bd, &op->o_ndn ) ) { + || be_shadow_update( op ) ) { p = (Entry *)&slap_entry_root; @@ -465,8 +503,8 @@ retry: /* transaction retry */ /* newSuperior == entry being moved?, if so ==> ERROR */ /* Get Entry with dn=newSuperior. Does newSuperior exist? */ - rs->sr_err = bdb_dn2entry( op->o_bd, ltid, np_ndn, - &neip, 0, locker, &nplock, op->o_tmpmemctx ); + rs->sr_err = bdb_dn2entry( op, ltid, np_ndn, + &neip, 0, locker, &nplock ); switch( rs->sr_err ) { case 0: np = neip->bei_e; @@ -502,11 +540,11 @@ retry: /* transaction retry */ #ifdef NEW_LOGGING LDAP_LOG ( OPERATION, DETAIL1, "==>bdb_modrdn: wr to new parent OK np=%p, id=%ld\n", - np, (long) np->e_id, 0 ); + (void *) np, (long) np->e_id, 0 ); #else Debug( LDAP_DEBUG_TRACE, "bdb_modrdn: wr to new parent OK np=%p, id=%ld\n", - np, (long) np->e_id, 0 ); + (void *) np, (long) np->e_id, 0 ); #endif /* check newSuperior for "children" acl */ @@ -565,7 +603,7 @@ retry: /* transaction retry */ } else { if ( isroot == -1 ) { - isroot = be_isroot( op->o_bd, &op->o_ndn ); + isroot = be_isroot( op ); } np_dn = NULL; @@ -573,7 +611,7 @@ retry: /* transaction retry */ /* no parent, modrdn entry directly under root */ if ( ! isroot ) { if ( be_issuffix( op->o_bd, (struct berval *)&slap_empty_bv ) - || be_isupdate( op->o_bd, &op->o_ndn ) ) { + || be_isupdate( op ) ) { np = (Entry *)&slap_entry_root; /* check parent for "children" acl */ @@ -598,7 +636,8 @@ retry: /* transaction retry */ "no access to new superior\n", 0, 0, 0 ); #endif - rs->sr_text = "no write access to new superior's children"; + rs->sr_text = + "no write access to new superior's children"; goto return_results; } @@ -651,11 +690,13 @@ retry: /* transaction retry */ } /* Build target dn and make sure target entry doesn't exist already. */ - if (!new_dn.bv_val) build_new_dn( &new_dn, new_parent_dn, &op->oq_modrdn.rs_newrdn ); + if (!new_dn.bv_val) { + build_new_dn( &new_dn, new_parent_dn, &op->oq_modrdn.rs_newrdn, NULL ); + } if (!new_ndn.bv_val) { struct berval bv = {0, NULL}; - dnNormalize2( NULL, &new_dn, &bv, op->o_tmpmemctx ); + dnNormalize( 0, NULL, NULL, &new_dn, &bv, op->o_tmpmemctx ); ber_dupbv( &new_ndn, &bv ); } @@ -669,8 +710,7 @@ retry: /* transaction retry */ /* Shortcut the search */ nei = neip ? neip : eip; - rs->sr_err = bdb_cache_find_ndn ( op->o_bd, ltid, &new_ndn, - &nei, locker, op->o_tmpmemctx ); + rs->sr_err = bdb_cache_find_ndn ( op, ltid, &new_ndn, &nei ); if ( nei ) bdb_cache_entryinfo_unlock( nei ); switch( rs->sr_err ) { case DB_LOCK_DEADLOCK: @@ -690,8 +730,8 @@ retry: /* transaction retry */ /* Get attribute type and attribute value of our new rdn, we will * need to add that to our new entry */ - if ( !new_rdn && ldap_bv2rdn_x( &op->oq_modrdn.rs_newrdn, &new_rdn, (char **)&rs->sr_text, - LDAP_DN_FORMAT_LDAP, op->o_tmpmemctx ) ) + if ( !new_rdn && ldap_bv2rdn_x( &op->oq_modrdn.rs_newrdn, &new_rdn, + (char **)&rs->sr_text, LDAP_DN_FORMAT_LDAP, op->o_tmpmemctx ) ) { #ifdef NEW_LOGGING LDAP_LOG ( OPERATION, ERR, @@ -711,21 +751,17 @@ retry: /* transaction retry */ #ifdef NEW_LOGGING LDAP_LOG ( OPERATION, RESULTS, - "bdb_modrdn: new_rdn_type=\"%s\", " - "new_rdn_val=\"%s\"\n", - new_rdn[ 0 ]->la_attr.bv_val, - new_rdn[ 0 ]->la_value.bv_val, 0 ); + "bdb_modrdn: new_rdn_type=\"%s\", new_rdn_val=\"%s\"\n", + new_rdn[ 0 ]->la_attr.bv_val, new_rdn[ 0 ]->la_value.bv_val, 0 ); #else Debug( LDAP_DEBUG_TRACE, - "bdb_modrdn: new_rdn_type=\"%s\", " - "new_rdn_val=\"%s\"\n", - new_rdn[ 0 ]->la_attr.bv_val, - new_rdn[ 0 ]->la_value.bv_val, 0 ); + "bdb_modrdn: new_rdn_type=\"%s\", new_rdn_val=\"%s\"\n", + new_rdn[ 0 ]->la_attr.bv_val, new_rdn[ 0 ]->la_value.bv_val, 0 ); #endif if ( op->oq_modrdn.rs_deleteoldrdn ) { - if ( !old_rdn && ldap_bv2rdn_x( &op->o_req_dn, &old_rdn, (char **)&rs->sr_text, - LDAP_DN_FORMAT_LDAP, op->o_tmpmemctx ) ) + if ( !old_rdn && ldap_bv2rdn_x( &op->o_req_dn, &old_rdn, + (char **)&rs->sr_text, LDAP_DN_FORMAT_LDAP, op->o_tmpmemctx ) ) { #ifdef NEW_LOGGING LDAP_LOG ( OPERATION, ERR, @@ -752,14 +788,31 @@ retry: /* transaction retry */ } } + if( op->o_preread ) { + if( slap_read_controls( op, rs, e, + &slap_pre_read_bv, &ctrls[num_ctrls] ) ) + { +#ifdef NEW_LOGGING + LDAP_LOG ( OPERATION, DETAIL1, + "<=- bdb_modrdn: post-read failed!\n", 0, 0, 0 ); +#else + Debug( LDAP_DEBUG_TRACE, + "<=- bdb_modrdn: post-read failed!\n", 0, 0, 0 ); +#endif + goto return_results; + } + ctrls[++num_ctrls] = NULL; + op->o_preread = 0; /* prevent redo on retry */ + } + /* nested transaction */ - rs->sr_err = TXN_BEGIN( bdb->bi_dbenv, ltid, <2, - bdb->bi_db_opflags ); + rs->sr_err = TXN_BEGIN( bdb->bi_dbenv, ltid, <2, bdb->bi_db_opflags ); rs->sr_text = NULL; if( rs->sr_err != 0 ) { #ifdef NEW_LOGGING LDAP_LOG ( OPERATION, ERR, - "bdb_modrdn: txn_begin(2) failed: %s (%d)\n", db_strerror(rs->sr_err), rs->sr_err, 0 ); + "bdb_modrdn: txn_begin(2) failed: %s (%d)\n", + db_strerror(rs->sr_err), rs->sr_err, 0 ); #else Debug( LDAP_DEBUG_TRACE, "bdb_modrdn: txn_begin(2) failed: %s (%d)\n", @@ -775,9 +828,17 @@ retry: /* transaction retry */ e = &dummy; /* delete old one */ - rs->sr_err = bdb_dn2id_delete( op->o_bd, lt2, eip, e, - op->o_tmpmemctx ); + rs->sr_err = bdb_dn2id_delete( op, lt2, eip, e ); if ( rs->sr_err != 0 ) { +#ifdef NEW_LOGGING + LDAP_LOG ( OPERATION, ERR, + "<=- bdb_modrdn: dn2id del failed: %s (%d)\n", + db_strerror(rs->sr_err), rs->sr_err, 0 ); +#else + Debug(LDAP_DEBUG_TRACE, + "<=- bdb_modrdn: dn2id del failed: %s (%d)\n", + db_strerror(rs->sr_err), rs->sr_err, 0 ); +#endif switch( rs->sr_err ) { case DB_LOCK_DEADLOCK: case DB_LOCK_NOTGRANTED: @@ -793,16 +854,9 @@ retry: /* transaction retry */ * already happened, must free the names. The frees are * done in bdb_cache_modrdn(). */ -#ifdef BDB_HIER - e->e_name.bv_val = ch_malloc(new_dn.bv_len + new_ndn.bv_len + 2); - e->e_name.bv_len = new_dn.bv_len; - e->e_nname.bv_val = e->e_name.bv_val + new_dn.bv_len + 1; - e->e_nname.bv_len = new_ndn.bv_len; - strcpy(e->e_name.bv_val, new_dn.bv_val); - strcpy(e->e_nname.bv_val, new_ndn.bv_val); -#else - if( e->e_nname.bv_val < e->e_bv.bv_val || e->e_nname.bv_val > - e->e_bv.bv_val + e->e_bv.bv_len ) { + if( e->e_nname.bv_val < e->e_bv.bv_val || + e->e_nname.bv_val > e->e_bv.bv_val + e->e_bv.bv_len ) + { e->e_name.bv_val = NULL; e->e_nname.bv_val = NULL; } @@ -810,11 +864,19 @@ retry: /* transaction retry */ e->e_nname = new_ndn; new_dn.bv_val = NULL; new_ndn.bv_val = NULL; -#endif + /* add new one */ - rs->sr_err = bdb_dn2id_add( op->o_bd, lt2, neip ? neip : eip, e, - op->o_tmpmemctx ); + rs->sr_err = bdb_dn2id_add( op, lt2, neip ? neip : eip, e ); if ( rs->sr_err != 0 ) { +#ifdef NEW_LOGGING + LDAP_LOG ( OPERATION, ERR, + "<=- bdb_modrdn: dn2id add failed: %s (%d)\n", + db_strerror(rs->sr_err), rs->sr_err, 0 ); +#else + Debug(LDAP_DEBUG_TRACE, + "<=- bdb_modrdn: dn2id add failed: %s (%d)\n", + db_strerror(rs->sr_err), rs->sr_err, 0 ); +#endif switch( rs->sr_err ) { case DB_LOCK_DEADLOCK: case DB_LOCK_NOTGRANTED: @@ -825,19 +887,27 @@ retry: /* transaction retry */ goto return_results; } -#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC) - if ( rs->sr_err == LDAP_SUCCESS && !op->o_noop ) { + if ( rs->sr_err == LDAP_SUCCESS && !op->o_noop && !op->o_no_psearch ) { + ldap_pvt_thread_rdwr_rlock( &bdb->bi_pslist_rwlock ); LDAP_LIST_FOREACH ( ps_list, &bdb->bi_psearch_list, o_ps_link ) { bdb_psearch( op, rs, ps_list, e, LDAP_PSEARCH_BY_PREMODIFY ); } + ldap_pvt_thread_rdwr_runlock( &bdb->bi_pslist_rwlock ); } -#endif /* modify entry */ rs->sr_err = bdb_modify_internal( op, lt2, &mod[0], e, &rs->sr_text, textbuf, textlen ); - if( rs->sr_err != LDAP_SUCCESS ) { +#ifdef NEW_LOGGING + LDAP_LOG ( OPERATION, ERR, + "<=- bdb_modrdn: modify failed: %s (%d)\n", + db_strerror(rs->sr_err), rs->sr_err, 0 ); +#else + Debug(LDAP_DEBUG_TRACE, + "<=- bdb_modrdn: modify failed: %s (%d)\n", + db_strerror(rs->sr_err), rs->sr_err, 0 ); +#endif if ( ( rs->sr_err == LDAP_INSUFFICIENT_ACCESS ) && opinfo.boi_err ) { rs->sr_err = opinfo.boi_err; } @@ -848,10 +918,37 @@ retry: /* transaction retry */ } goto return_results; } - + + if( op->o_postread ) { + if( slap_read_controls( op, rs, e, + &slap_post_read_bv, &ctrls[num_ctrls] ) ) + { +#ifdef NEW_LOGGING + LDAP_LOG ( OPERATION, DETAIL1, + "<=- bdb_modrdn: post-read failed!\n", 0, 0, 0 ); +#else + Debug( LDAP_DEBUG_TRACE, + "<=- bdb_modrdn: post-read failed!\n", 0, 0, 0 ); +#endif + goto return_results; + } + ctrls[++num_ctrls] = NULL; + op->o_postread = 0; /* prevent redo on retry */ + /* FIXME: should read entry on the last retry */ + } + /* id2entry index */ rs->sr_err = bdb_id2entry_update( op->o_bd, lt2, e ); if ( rs->sr_err != 0 ) { +#ifdef NEW_LOGGING + LDAP_LOG ( OPERATION, ERR, + "<=- bdb_modrdn: id2entry failed: %s (%d)\n", + db_strerror(rs->sr_err), rs->sr_err, 0 ); +#else + Debug(LDAP_DEBUG_TRACE, + "<=- bdb_modrdn: id2entry failed: %s (%d)\n", + db_strerror(rs->sr_err), rs->sr_err, 0 ); +#endif switch( rs->sr_err ) { case DB_LOCK_DEADLOCK: case DB_LOCK_NOTGRANTED: @@ -861,54 +958,109 @@ retry: /* transaction retry */ rs->sr_text = "entry update failed"; goto return_results; } + + bdb_cache_find_id( op, lt2, eip->bei_id, &eip, 0, locker, &plock ); + if ( eip ) p = eip->bei_e; + if ( p_ndn.bv_len != 0 ) { + parent_is_glue = is_entry_glue(p); + rs->sr_err = bdb_cache_children( op, lt2, p ); + if ( rs->sr_err != DB_NOTFOUND ) { + switch( rs->sr_err ) { + case DB_LOCK_DEADLOCK: + case DB_LOCK_NOTGRANTED: + goto retry; + case 0: + break; + default: +#ifdef NEW_LOGGING + LDAP_LOG ( OPERATION, ERR, + "<=- bdb_modrdn: has_children failed %s (%d)\n", + db_strerror(rs->sr_err), rs->sr_err, 0 ); +#else + Debug(LDAP_DEBUG_ARGS, + "<=- bdb_modrdn: has_children failed: %s (%d)\n", + db_strerror(rs->sr_err), rs->sr_err, 0 ); +#endif + rs->sr_err = LDAP_OTHER; + rs->sr_text = "internal error"; + goto return_results; + } + parent_is_leaf = 1; + } + bdb_unlocked_cache_return_entry_r(&bdb->bi_cache, p); + p = NULL; + } + if ( TXN_COMMIT( lt2, 0 ) != 0 ) { rs->sr_err = LDAP_OTHER; rs->sr_text = "txn_commit(2) failed"; goto return_results; } + if ( LDAP_STAILQ_EMPTY( &op->o_bd->be_syncinfo )) { + rc = bdb_csn_commit( op, rs, ltid, ei, &suffix_ei, + &ctxcsn_e, &ctxcsn_added, locker ); + switch ( rc ) { + case BDB_CSN_ABORT : + goto return_results; + case BDB_CSN_RETRY : + goto retry; + } + } + if( op->o_noop ) { if(( rs->sr_err=TXN_ABORT( ltid )) != 0 ) { rs->sr_text = "txn_abort (no-op) failed"; } else { - noop = 1; rs->sr_err = LDAP_SUCCESS; + goto return_results; } } else { - char gid[DB_XIDDATASIZE]; + rc = bdb_cache_modrdn( save, &op->orr_nnewrdn, e, neip, + bdb->bi_dbenv, locker, &lock ); + switch( rc ) { + case DB_LOCK_DEADLOCK: + case DB_LOCK_NOTGRANTED: + goto retry; + } - snprintf( gid, sizeof( gid ), "%s-%08lx-%08lx", - bdb_uuid.bv_val, (long) op->o_connid, (long) op->o_opid ); + if ( LDAP_STAILQ_EMPTY( &op->o_bd->be_syncinfo )) { + if ( ctxcsn_added ) { + bdb_cache_add( bdb, suffix_ei, ctxcsn_e, + (struct berval *)&slap_ldapsync_cn_bv, locker ); + } + } - if(( rs->sr_err=TXN_PREPARE( ltid, gid )) != 0 ) { - rs->sr_text = "txn_prepare failed"; - } else { - bdb_cache_modrdn( save, &op->orr_nnewrdn, e, neip, - bdb->bi_dbenv, locker, &lock ); - if(( rs->sr_err=TXN_COMMIT( ltid, 0 )) != 0 ) { - rs->sr_text = "txn_commit failed"; - } else { - rs->sr_err = LDAP_SUCCESS; + if ( rs->sr_err == LDAP_SUCCESS ) { + /* Loop through in-scope entries for each psearch spec */ + ldap_pvt_thread_rdwr_rlock( &bdb->bi_pslist_rwlock ); + LDAP_LIST_FOREACH ( ps_list, &bdb->bi_psearch_list, o_ps_link ) { + bdb_psearch( op, rs, ps_list, e, LDAP_PSEARCH_BY_MODIFY ); } + ldap_pvt_thread_rdwr_runlock( &bdb->bi_pslist_rwlock ); + pm_list = LDAP_LIST_FIRST(&op->o_pm_list); + while ( pm_list != NULL ) { + bdb_psearch(op, rs, pm_list->ps_op, + e, LDAP_PSEARCH_BY_SCOPEOUT); + pm_prev = pm_list; + LDAP_LIST_REMOVE ( pm_list, ps_link ); + pm_list = LDAP_LIST_NEXT ( pm_list, ps_link ); + ch_free( pm_prev ); + } + } + + if(( rs->sr_err=TXN_COMMIT( ltid, 0 )) != 0 ) { + rs->sr_text = "txn_commit failed"; + } else { + rs->sr_err = LDAP_SUCCESS; } } ltid = NULL; op->o_private = NULL; - if( rs->sr_err == LDAP_SUCCESS ) { -#ifdef NEW_LOGGING - LDAP_LOG ( OPERATION, RESULTS, - "bdb_modrdn: rdn modified%s id=%08lx dn=\"%s\"\n", - op->o_noop ? " (no-op)" : "", e->e_id, e->e_dn ); -#else - Debug(LDAP_DEBUG_TRACE, - "bdb_modrdn: rdn modified%s id=%08lx dn=\"%s\"\n", - op->o_noop ? " (no-op)" : "", e->e_id, e->e_dn ); -#endif - rs->sr_text = NULL; - } else { + if( rs->sr_err != LDAP_SUCCESS ) { #ifdef NEW_LOGGING LDAP_LOG ( OPERATION, RESULTS, "bdb_modrdn: %s : %s (%d)\n", rs->sr_text, db_strerror(rs->sr_err), rs->sr_err ); @@ -917,34 +1069,36 @@ retry: /* transaction retry */ rs->sr_text, db_strerror(rs->sr_err), rs->sr_err ); #endif rs->sr_err = LDAP_OTHER; + + goto return_results; } +#ifdef NEW_LOGGING + LDAP_LOG ( OPERATION, RESULTS, + "bdb_modrdn: rdn modified%s id=%08lx dn=\"%s\"\n", + op->o_noop ? " (no-op)" : "", + e->e_id, e->e_dn ); +#else + Debug(LDAP_DEBUG_TRACE, + "bdb_modrdn: rdn modified%s id=%08lx dn=\"%s\"\n", + op->o_noop ? " (no-op)" : "", + e->e_id, e->e_dn ); +#endif + rs->sr_text = NULL; + if( num_ctrls ) rs->sr_ctrls = ctrls; + return_results: send_ldap_result( op, rs ); -#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC) - if ( rs->sr_err == LDAP_SUCCESS && !op->o_noop ) { - /* Loop through in-scope entries for each psearch spec */ - LDAP_LIST_FOREACH ( ps_list, &bdb->bi_psearch_list, o_ps_link ) { - bdb_psearch( op, rs, ps_list, e, LDAP_PSEARCH_BY_MODIFY ); - } - pm_list = LDAP_LIST_FIRST(&op->o_pm_list); - while ( pm_list != NULL ) { - bdb_psearch(op, rs, pm_list->ps_op, - e, LDAP_PSEARCH_BY_SCOPEOUT); - pm_prev = pm_list; - LDAP_LIST_REMOVE ( pm_list, ps_link ); - pm_list = LDAP_LIST_NEXT ( pm_list, ps_link ); - ch_free( pm_prev ); - } - } -#endif - if( rs->sr_err == 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 ( rs->sr_err == LDAP_SUCCESS && parent_is_glue && parent_is_leaf ) { + op->o_delete_glue_parent = 1; + } done: if( new_dn.bv_val != NULL ) free( new_dn.bv_val ); @@ -961,9 +1115,15 @@ done: Modifications *tmp; for (; mod; mod=tmp ) { tmp = mod->sml_next; + /* slap_modrdn2mods does things one way, + * slap_mods_opattrs does it differently + */ + if ( mod->sml_op != SLAP_MOD_SOFTADD && + mod->sml_op != LDAP_MOD_DELETE ) break; if ( mod->sml_nvalues ) free( mod->sml_nvalues[0].bv_val ); free( mod ); } + slap_mods_free( mod ); } /* LDAP v3 Support */ @@ -983,18 +1143,16 @@ done: } if( ltid != NULL ) { -#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC) - pm_list = LDAP_LIST_FIRST(&op->o_pm_list); - while ( pm_list != NULL ) { - LDAP_LIST_REMOVE ( pm_list, ps_link ); + pm_list = LDAP_LIST_FIRST(&op->o_pm_list); + while ( pm_list != NULL ) { + LDAP_LIST_REMOVE ( pm_list, ps_link ); pm_prev = pm_list; - pm_list = LDAP_LIST_NEXT ( pm_list, ps_link ); + pm_list = LDAP_LIST_NEXT ( pm_list, ps_link ); ch_free( pm_prev ); - } -#endif + } TXN_ABORT( ltid ); op->o_private = NULL; } - return ( ( rs->sr_err == LDAP_SUCCESS ) ? noop : rs->sr_err ); + return rs->sr_err; }