diff --git a/servers/slapd/add.c b/servers/slapd/add.c index 5b99570a6b..8e5008f2d6 100644 --- a/servers/slapd/add.c +++ b/servers/slapd/add.c @@ -302,8 +302,6 @@ fe_op_add( Operation *op, SlapReply *rs ) if ( !SLAP_SINGLE_SHADOW(op->o_bd) || repl_user ) { int update = !BER_BVISEMPTY( &op->o_bd->be_update_ndn ); - op->o_bd = op_be; - if ( !update ) { rs->sr_err = slap_mods_no_user_mod_check( op, op->ora_modlist, &rs->sr_text, textbuf, textlen ); @@ -334,6 +332,12 @@ fe_op_add( Operation *op, SlapReply *rs ) } } + if ( op->o_txnSpec ) { + rc = txn_preop( op, rs ); + goto done; + } + + op->o_bd = op_be; rc = op->o_bd->be_add( op, rs ); if ( rc == LDAP_SUCCESS ) { OpExtra *oex; diff --git a/servers/slapd/back-mdb/add.c b/servers/slapd/back-mdb/add.c index 148d2d68b7..b223375600 100644 --- a/servers/slapd/back-mdb/add.c +++ b/servers/slapd/back-mdb/add.c @@ -48,9 +48,6 @@ mdb_add(Operation *op, SlapReply *rs ) Debug(LDAP_DEBUG_ARGS, "==> " LDAP_XSTRING(mdb_add) ": %s\n", op->ora_e->e_name.bv_val ); - if( op->o_txnSpec && txn_preop( op, rs )) - return rs->sr_err; - ctrls[num_ctrls] = 0; /* check entry's schema */ diff --git a/servers/slapd/back-mdb/delete.c b/servers/slapd/back-mdb/delete.c index 9ca35011e7..7dab5ee8f1 100644 --- a/servers/slapd/back-mdb/delete.c +++ b/servers/slapd/back-mdb/delete.c @@ -46,9 +46,6 @@ mdb_delete( Operation *op, SlapReply *rs ) Debug( LDAP_DEBUG_ARGS, "==> " LDAP_XSTRING(mdb_delete) ": %s\n", op->o_req_dn.bv_val ); - if( op->o_txnSpec && txn_preop( op, rs )) - return rs->sr_err; - ctrls[num_ctrls] = 0; /* begin transaction */ diff --git a/servers/slapd/back-mdb/init.c b/servers/slapd/back-mdb/init.c index 867559a9db..9d9e7ae775 100644 --- a/servers/slapd/back-mdb/init.c +++ b/servers/slapd/back-mdb/init.c @@ -408,7 +408,8 @@ mdb_back_initialize( SLAP_BFLAG_INCREMENT | SLAP_BFLAG_SUBENTRIES | SLAP_BFLAG_ALIASES | - SLAP_BFLAG_REFERRALS; + SLAP_BFLAG_REFERRALS | + SLAP_BFLAG_TXNS; bi->bi_controls = controls; diff --git a/servers/slapd/back-mdb/modify.c b/servers/slapd/back-mdb/modify.c index 84e4585e3b..d1a2a7324f 100644 --- a/servers/slapd/back-mdb/modify.c +++ b/servers/slapd/back-mdb/modify.c @@ -589,9 +589,6 @@ mdb_modify( Operation *op, SlapReply *rs ) Debug( LDAP_DEBUG_ARGS, LDAP_XSTRING(mdb_modify) ": %s\n", op->o_req_dn.bv_val ); - if( op->o_txnSpec && txn_preop( op, rs )) - return rs->sr_err; - ctrls[num_ctrls] = NULL; /* begin transaction */ diff --git a/servers/slapd/back-mdb/modrdn.c b/servers/slapd/back-mdb/modrdn.c index f51631773c..c3b0a6cd3c 100644 --- a/servers/slapd/back-mdb/modrdn.c +++ b/servers/slapd/back-mdb/modrdn.c @@ -59,9 +59,6 @@ mdb_modrdn( Operation *op, SlapReply *rs ) 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 && txn_preop( op, rs )) - return rs->sr_err; - ctrls[num_ctrls] = NULL; /* begin transaction */ diff --git a/servers/slapd/delete.c b/servers/slapd/delete.c index 7759c60793..b6fd093d8e 100644 --- a/servers/slapd/delete.c +++ b/servers/slapd/delete.c @@ -172,6 +172,11 @@ fe_op_delete( Operation *op, SlapReply *rs ) struct berval org_ndn = BER_BVNULL; int org_managedsait; + if ( op->o_txnSpec ) { + txn_preop( op, rs ); + goto cleanup; + } + op->o_bd = op_be; op->o_bd->be_delete( op, rs ); diff --git a/servers/slapd/extended.c b/servers/slapd/extended.c index 509ce5cfbe..6b47d3a355 100644 --- a/servers/slapd/extended.c +++ b/servers/slapd/extended.c @@ -174,7 +174,8 @@ do_extended( op->o_bd = frontendDB; rs->sr_err = frontendDB->be_extended( op, rs ); - if ( rs->sr_err == SLAPD_ASYNCOP ){ + if ( rs->sr_err == SLAPD_ASYNCOP || + rs->sr_err == LDAP_TXN_SPECIFY_OKAY ) { /* skip cleanup */ return rs->sr_err; } diff --git a/servers/slapd/modify.c b/servers/slapd/modify.c index b00090328e..faa10bac6d 100644 --- a/servers/slapd/modify.c +++ b/servers/slapd/modify.c @@ -289,8 +289,6 @@ fe_op_modify( Operation *op, SlapReply *rs ) if ( !SLAP_SINGLE_SHADOW(op->o_bd) || repl_user ) { int update = !BER_BVISEMPTY( &op->o_bd->be_update_ndn ); - op->o_bd = op_be; - if ( !update ) { rs->sr_err = slap_mods_no_user_mod_check( op, op->orm_modlist, &rs->sr_text, textbuf, textlen ); @@ -299,6 +297,11 @@ fe_op_modify( Operation *op, SlapReply *rs ) goto cleanup; } } + if ( op->o_txnSpec ) { + txn_preop( op, rs ); + goto cleanup; + } + op->o_bd = op_be; op->o_bd->be_modify( op, rs ); } else { /* send a referral */ diff --git a/servers/slapd/modrdn.c b/servers/slapd/modrdn.c index a48cc4add7..260eafcd99 100644 --- a/servers/slapd/modrdn.c +++ b/servers/slapd/modrdn.c @@ -313,6 +313,11 @@ fe_op_modrdn( Operation *op, SlapReply *rs ) int repl_user = be_isupdate( op ); if ( !SLAP_SINGLE_SHADOW(op->o_bd) || repl_user ) { + if ( op->o_txnSpec ) { + txn_preop( op, rs ); + goto cleanup; + } + op->o_bd = op_be; op->o_bd->be_modrdn( op, rs ); diff --git a/servers/slapd/passwd.c b/servers/slapd/passwd.c index 9de1bc0c41..9a450fa0bd 100644 --- a/servers/slapd/passwd.c +++ b/servers/slapd/passwd.c @@ -203,6 +203,11 @@ int passwd_extop( goto error_return; } + if ( op->o_txnSpec ) { + rc = txn_preop( op, rs ); + goto error_return; + } + op->o_bd = op_be; /* Give the backend a chance to handle this itself */ diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h index a5fe408dc6..0f14cdc265 100644 --- a/servers/slapd/slap.h +++ b/servers/slapd/slap.h @@ -2338,6 +2338,7 @@ struct BackendInfo { #define SLAP_BFLAG_SUBENTRIES 0x4000U #define SLAP_BFLAG_DYNAMIC 0x8000U #define SLAP_BFLAG_STANDALONE 0x10000U /* started up regardless of whether any databases use it */ +#define SLAP_BFLAG_TXNS 0x20000U /* supports LDAP transactions */ /* overlay specific */ #define SLAPO_BFLAG_SINGLE 0x01000000U @@ -2357,6 +2358,7 @@ struct BackendInfo { #define SLAP_DYNAMIC(be) ((SLAP_BFLAGS(be) & SLAP_BFLAG_DYNAMIC) || (SLAP_DBFLAGS(be) & SLAP_DBFLAG_DYNAMIC)) #define SLAP_NOLASTMODCMD(be) (SLAP_BFLAGS(be) & SLAP_BFLAG_NOLASTMODCMD) #define SLAP_LASTMODCMD(be) (!SLAP_NOLASTMODCMD(be)) +#define SLAP_TXNS(be) (SLAP_BFLAGS(be) & SLAP_BFLAG_TXNS) /* overlay specific */ #define SLAPO_SINGLE(be) (SLAP_BFLAGS(be) & SLAPO_BFLAG_SINGLE) diff --git a/servers/slapd/txn.c b/servers/slapd/txn.c index 7e56144335..b2e8d15321 100644 --- a/servers/slapd/txn.c +++ b/servers/slapd/txn.c @@ -324,17 +324,12 @@ done: int txn_preop( Operation *op, SlapReply *rs ) { - int settle = 0; - /* acquire connection lock */ ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex ); if( op->o_conn->c_txn == CONN_TXN_INACTIVE ) { rs->sr_text = "invalid transaction identifier"; rs->sr_err = LDAP_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 ) { @@ -346,6 +341,12 @@ int txn_preop( Operation *op, SlapReply *rs ) goto txnReturn; } + if ( !SLAP_TXNS( op->o_bd )) { + rs->sr_text = "backend doesn't support transactions"; + rs->sr_err = LDAP_UNWILLING_TO_PERFORM; + goto txnReturn; + } + /* insert operation into transaction */ LDAP_STAILQ_REMOVE( &op->o_conn->c_ops, op, Operation, o_next ); LDAP_STAILQ_INSERT_TAIL( &op->o_conn->c_txn_ops, op, o_next ); @@ -354,11 +355,9 @@ txnReturn: /* release connection lock */ ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex ); - if( !settle ) { + if ( op->o_tag != LDAP_REQ_EXTENDED ) send_ldap_result( op, rs ); - if ( !rs->sr_err ) - rs->sr_err = LDAP_TXN_SPECIFY_OKAY; - return rs->sr_err; - } - return LDAP_SUCCESS; /* proceed with operation */ + if ( !rs->sr_err ) + rs->sr_err = LDAP_TXN_SPECIFY_OKAY; + return rs->sr_err; }