/* $OpenLDAP$ */
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
*
- * Copyright 2000-2006 The OpenLDAP Foundation.
+ * Copyright 2000-2008 The OpenLDAP Foundation.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
int manageDSAit = get_manageDSAit( op );
- u_int32_t locker = 0;
+ BDB_LOCKER locker = 0;
DB_LOCK lock, plock, nplock;
int num_retries = 0;
int parent_is_glue = 0;
int parent_is_leaf = 0;
+#ifdef LDAP_X_TXN
+ int settle = 0;
+#endif
+
Debug( LDAP_DEBUG_TRACE, "==>" LDAP_XSTRING(bdb_modrdn) "(%s,%s,%s)\n",
op->o_req_dn.bv_val,op->oq_modrdn.rs_newrdn.bv_val,
op->oq_modrdn.rs_newSup ? op->oq_modrdn.rs_newSup->bv_val : "NULL" );
if( op->o_txnSpec ) {
/* acquire connection lock */
ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex );
- if( op->o_conn->c_txn == 0 ) {
+ if( op->o_conn->c_txn == CONN_TXN_INACTIVE ) {
rs->sr_text = "invalid transaction identifier";
rs->sr_err = LDAP_X_TXN_ID_INVALID;
goto txnReturn;
+ } else if( op->o_conn->c_txn == CONN_TXN_SETTLE ) {
+ settle=1;
+ goto txnReturn;
}
+
if( op->o_conn->c_txn_backend == NULL ) {
op->o_conn->c_txn_backend = op->o_bd;
/* insert operation into transaction */
rs->sr_text = "transaction specified";
- rs->sr_err = LDAP_SUCCESS;
+ rs->sr_err = LDAP_X_TXN_SPECIFY_OKAY;
txnReturn:
/* release connection lock */
ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex );
- send_ldap_result( op, rs );
- return rs->sr_err;
+ if( !settle ) {
+ send_ldap_result( op, rs );
+ return rs->sr_err;
+ }
}
#endif
opinfo.boi_bdb = op->o_bd;
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;
dnParent( &e->e_nname, &p_ndn );
}
np_ndn = &p_ndn;
- if ( p_ndn.bv_len != 0 ) {
+ eip = ei->bei_parent;
+ if ( eip && eip->bei_id ) {
/* Make sure parent entry exist and we can write its
* children.
*/
- eip = ei->bei_parent;
rs->sr_err = bdb_cache_find_id( op, ltid,
eip->bei_id, &eip, 0, locker, &plock );
struct berval bv = {0, NULL};
dnNormalize( 0, NULL, NULL, &new_dn, &bv, op->o_tmpmemctx );
ber_dupbv( &new_ndn, &bv );
+ /* FIXME: why not call dnNormalize() w/o ctx? */
+ op->o_tmpfree( bv.bv_val, op->o_tmpmemctx );
}
Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(bdb_modrdn) ": new ndn=%s\n",
/* Shortcut the search */
nei = neip ? neip : eip;
- rs->sr_err = bdb_cache_find_ndn ( op, ltid, &new_ndn, &nei );
+ rs->sr_err = bdb_cache_find_ndn ( op, locker, &new_ndn, &nei );
if ( nei ) bdb_cache_entryinfo_unlock( nei );
switch( rs->sr_err ) {
case DB_LOCK_DEADLOCK:
case DB_NOTFOUND:
break;
case 0:
+ /* Allow rename to same DN */
+ if ( nei == ei )
+ break;
rs->sr_err = LDAP_ALREADY_EXISTS;
goto return_results;
default:
{
Debug( LDAP_DEBUG_TRACE,
"<=- " LDAP_XSTRING(bdb_modrdn)
- ": post-read failed!\n", 0, 0, 0 );
- goto return_results;
+ ": pre-read failed!\n", 0, 0, 0 );
+ if ( op->o_preread & SLAP_CONTROL_CRITICAL ) {
+ /* FIXME: is it correct to abort
+ * operation if control fails? */
+ goto return_results;
+ }
}
}
Debug( LDAP_DEBUG_TRACE,
"<=- " LDAP_XSTRING(bdb_modrdn)
": post-read failed!\n", 0, 0, 0 );
- goto return_results;
+ if ( op->o_postread & SLAP_CONTROL_CRITICAL ) {
+ /* FIXME: is it correct to abort
+ * operation if control fails? */
+ goto return_results;
+ }
}
}
} else {
rs->sr_err = LDAP_X_NO_OPERATION;
ltid = NULL;
+ /* Only free attrs if they were dup'd. */
+ if ( dummy.e_attrs == e->e_attrs ) dummy.e_attrs = NULL;
goto return_results;
}
}
send_ldap_result( op, rs );
- if( rs->sr_err == LDAP_SUCCESS && bdb->bi_txn_cp ) {
+ if( rs->sr_err == LDAP_SUCCESS && bdb->bi_txn_cp_kbyte ) {
TXN_CHECKPOINT( bdb->bi_dbenv,
bdb->bi_txn_cp_kbyte, bdb->bi_txn_cp_min, 0 );
}
}
op->o_private = NULL;
- if( preread_ctrl != NULL ) {
+ if( preread_ctrl != NULL && (*preread_ctrl) != NULL ) {
slap_sl_free( (*preread_ctrl)->ldctl_value.bv_val, op->o_tmpmemctx );
slap_sl_free( *preread_ctrl, op->o_tmpmemctx );
}
- if( postread_ctrl != NULL ) {
+ if( postread_ctrl != NULL && (*postread_ctrl) != NULL ) {
slap_sl_free( (*postread_ctrl)->ldctl_value.bv_val, op->o_tmpmemctx );
slap_sl_free( *postread_ctrl, op->o_tmpmemctx );
}