]> git.ipfire.org Git - thirdparty/openldap.git/commitdiff
ITS#9892 Free operation data at the end of a transaction
authorOndřej Kuzník <ondra@mistotebe.net>
Thu, 15 Sep 2022 08:14:10 +0000 (09:14 +0100)
committerQuanah Gibson-Mount <quanah@openldap.org>
Mon, 26 Sep 2022 16:50:21 +0000 (16:50 +0000)
servers/slapd/add.c
servers/slapd/txn.c

index 2898d6ce319c5f4ac6f67f7462247afca1718e78..7934d3e4b440510daf517484b3369d0f209059b7 100644 (file)
@@ -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:;
index d81de9500f2417e56f0aa8800b6a745a3a85490d..785a2d54bd7761afff447d0cac441860517cc632 100644 (file)
@@ -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 );
        }