From 739f4666d88fabc22743a2f6f36182c6a329ffde Mon Sep 17 00:00:00 2001 From: =?utf8?q?Ond=C5=99ej=20Kuzn=C3=ADk?= Date: Thu, 15 Sep 2022 09:14:10 +0100 Subject: [PATCH] ITS#9892 Free operation data at the end of a transaction --- servers/slapd/add.c | 2 +- servers/slapd/txn.c | 46 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/servers/slapd/add.c b/servers/slapd/add.c index 2898d6ce31..7934d3e4b4 100644 --- a/servers/slapd/add.c +++ b/servers/slapd/add.c @@ -198,7 +198,6 @@ do_add( Operation *op, SlapReply *rs ) return rc; } - LDAP_SLIST_REMOVE(&op->o_extra, &oex->oe, OpExtra, oe_next); if ( rc == LDAP_TXN_SPECIFY_OKAY ) { /* skip cleanup */ return rc; @@ -214,6 +213,7 @@ do_add( Operation *op, SlapReply *rs ) op->o_bd = bd; } } + LDAP_SLIST_REMOVE(&op->o_extra, &oex->oe, OpExtra, oe_next); op->o_tmpfree( oex, op->o_tmpmemctx ); done:; diff --git a/servers/slapd/txn.c b/servers/slapd/txn.c index d81de9500f..785a2d54bd 100644 --- a/servers/slapd/txn.c +++ b/servers/slapd/txn.c @@ -260,6 +260,7 @@ int txn_end_extop( rc = (&o->o_bd->bd_info->bi_op_bind)[opidx]( o, &rs ); ldap_pvt_thread_mutex_lock( &c->c_mutex ); } + LDAP_SLIST_REMOVE( &o->o_extra, txn, OpExtra, oe_next ); if ( rc ) { struct berval *bv = NULL; BerElementBuffer berbuf; @@ -304,8 +305,53 @@ int txn_end_extop( drain: /* drain txn ops list */ while (( o = LDAP_STAILQ_FIRST( &c->c_txn_ops )) != NULL ) { + int freevals = 1; + LDAP_STAILQ_REMOVE_HEAD( &c->c_txn_ops, o_next ); LDAP_STAILQ_NEXT( o, o_next ) = NULL; + + switch ( o->o_tag ) { + case LDAP_REQ_ADD: { + if ( o->ora_e != NULL ) { + OpExtra *oex; + OpExtraDB *oexdb = NULL; + LDAP_SLIST_FOREACH(oex, &o->o_extra, oe_next) { + if ( oex->oe_key == (void *)do_add ) { + oexdb = (OpExtraDB *)oex; + break; + } + } + if ( oexdb && oexdb->oe_db ) { + BackendDB *bd = o->o_bd; + o->o_bd = oexdb->oe_db; + + be_entry_release_w( o, o->ora_e ); + + o->ora_e = NULL; + o->o_bd = bd; + } else { + entry_free( o->ora_e ); + } + if ( oexdb ) { + o->o_tmpfree( oexdb, o->o_tmpmemctx ); + } + } + freevals = 0; + } /* fallthru */ + case LDAP_REQ_MODIFY: + case LDAP_REQ_MODRDN: + if ( o->orr_modlist != NULL ) { + slap_mods_free( o->orr_modlist, freevals ); + } + break; + case LDAP_REQ_DELETE: + case LDAP_REQ_EXTENDED: + break; + default: + assert( 0 ); + } + o->o_tmpfree( o->o_req_dn.bv_val, o->o_tmpmemctx ); + o->o_tmpfree( o->o_req_ndn.bv_val, o->o_tmpmemctx ); slap_op_free( o, NULL ); } -- 2.47.2