]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/back-mdb/modrdn.c
Plug memleaks
[openldap] / servers / slapd / back-mdb / modrdn.c
index 8aa4097d86a927b849f27a47664944712ec79728..b628c259b5f797a386de8581f29bd1e74bca27f9 100644 (file)
@@ -35,7 +35,7 @@ mdb_modrdn( Operation *op, SlapReply *rs )
        char textbuf[SLAP_TEXT_BUFLEN];
        size_t textlen = sizeof textbuf;
        MDB_txn         *txn = NULL;
-       struct mdb_op_info opinfo = {{{ 0 }}};
+       struct mdb_op_info opinfo = {{{ 0 }}}, *moi = &opinfo;
        Entry dummy = {0};
 
        Entry           *np = NULL;                     /* newSuperior Entry */
@@ -105,7 +105,7 @@ txnReturn:
        slap_mods_opattrs( op, &op->orr_modlist, 1 );
 
        /* begin transaction */
-       rs->sr_err = mdb_txn_begin( mdb->mi_dbenv, 0, &txn );
+       rs->sr_err = mdb_opinfo_get( op, mdb, 0, &moi );
        rs->sr_text = NULL;
        if( rs->sr_err != 0 ) {
                Debug( LDAP_DEBUG_TRACE,
@@ -116,13 +116,9 @@ txnReturn:
                goto return_results;
        }
 
-       opinfo.moi_oe.oe_key = mdb;
-       opinfo.moi_txn = txn;
-       opinfo.moi_err = 0;
-       opinfo.moi_acl_cache = op->o_do_not_cache;
-       LDAP_SLIST_INSERT_HEAD( &op->o_extra, &opinfo.moi_oe, oe_next );
+       txn = moi->moi_txn;
 
-       if ( be_issuffix( op->o_bd, &e->e_nname ) ) {
+       if ( be_issuffix( op->o_bd, &op->o_req_ndn ) ) {
 #ifdef MDB_MULTIPLE_SUFFIXES
                /* Allow renaming one suffix entry to another */
                p_ndn = slap_empty_bv;
@@ -133,7 +129,7 @@ txnReturn:
                goto return_results;
 #endif
        } else {
-               dnParent( &e->e_nname, &p_ndn );
+               dnParent( &op->o_req_ndn, &p_ndn );
        }
        np_ndn = &p_ndn;
        /* Make sure parent entry exist and we can write its
@@ -144,9 +140,14 @@ txnReturn:
        case MDB_NOTFOUND:
                Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(mdb_modrdn)
                        ": parent does not exist\n", 0, 0, 0);
-               rs->sr_err = LDAP_OTHER;
-               rs->sr_text = "entry's parent does not exist";
-               goto return_results;
+               rs->sr_ref = referral_rewrite( default_referral, NULL,
+                                       &op->o_req_dn, LDAP_SCOPE_DEFAULT );
+               rs->sr_err = LDAP_REFERRAL;
+
+               send_ldap_result( op, rs );
+
+               ber_bvarray_free( rs->sr_ref );
+               goto done;
        case 0:
                break;
        case LDAP_BUSY:
@@ -180,7 +181,7 @@ txnReturn:
        if ( p_ndn.bv_val == slap_empty_bv.bv_val ) {
                p_dn = slap_empty_bv;
        } else {
-               dnParent( &e->e_name, &p_dn );
+               dnParent( &op->o_req_dn, &p_dn );
        }
 
        Debug( LDAP_DEBUG_TRACE,
@@ -190,8 +191,10 @@ txnReturn:
        /* get entry */
        rs->sr_err = mdb_dn2entry( op, txn, &op->o_req_ndn, &e, 0 );
        switch( rs->sr_err ) {
-       case 0:
        case MDB_NOTFOUND:
+               e = p;
+               p = NULL;
+       case 0:
                break;
        case LDAP_BUSY:
                rs->sr_text = "ldap server busy";
@@ -208,9 +211,14 @@ txnReturn:
        {
                if( e != NULL ) {
                        rs->sr_matched = ch_strdup( e->e_dn );
-                       rs->sr_ref = is_entry_referral( e )
-                               ? get_entry_referrals( op, e )
-                               : NULL;
+                       if ( is_entry_referral( e )) {
+                               BerVarray ref = get_entry_referrals( op, e );
+                               rs->sr_ref = referral_rewrite( ref, &e->e_name,
+                                       &op->o_req_dn, LDAP_SCOPE_DEFAULT );
+                               ber_bvarray_free( ref );
+                       } else {
+                               rs->sr_ref = NULL;
+                       }
                        mdb_entry_return( e );
                        e = NULL;
 
@@ -404,22 +412,18 @@ txnReturn:
 
        /* 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, NULL );
+               build_new_dn( &new_dn, new_parent_dn, &op->oq_modrdn.rs_newrdn, op->o_tmpmemctx );
        }
 
        if (!new_ndn.bv_val) {
-               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 );
+               dnNormalize( 0, NULL, NULL, &new_dn, &new_ndn, op->o_tmpmemctx );
        }
 
        Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(mdb_modrdn) ": new ndn=%s\n",
                new_ndn.bv_val, 0, 0 );
 
        /* Shortcut the search */
-       rs->sr_err = mdb_dn2id ( op, txn, &new_ndn, &nid, NULL );
+       rs->sr_err = mdb_dn2id ( op, txn, &new_ndn, &nid, NULL, NULL );
        switch( rs->sr_err ) {
        case MDB_NOTFOUND:
                break;
@@ -496,9 +500,6 @@ txnReturn:
                        "<=- " LDAP_XSTRING(mdb_modrdn)
                        ": modify failed: %s (%d)\n",
                        mdb_strerror(rs->sr_err), rs->sr_err, 0 );
-               if ( ( rs->sr_err == LDAP_INSUFFICIENT_ACCESS ) && opinfo.moi_err ) {
-                       rs->sr_err = opinfo.moi_err;
-               }
                if ( dummy.e_attrs == e->e_attrs ) dummy.e_attrs = NULL;
                goto return_results;
        }
@@ -556,30 +557,27 @@ txnReturn:
                }
        }
 
-       if( op->o_noop ) {
-               mdb_txn_abort( txn );
-               rs->sr_err = LDAP_X_NO_OPERATION;
-               txn = NULL;
-               /* Only free attrs if they were dup'd.  */
-               if ( dummy.e_attrs == e->e_attrs ) dummy.e_attrs = NULL;
-               goto return_results;
-
-       } else {
-               dummy.e_attrs = NULL;
-               new_dn.bv_val = NULL;
-               new_ndn.bv_val = NULL;
+       if( moi == &opinfo ) {
+               LDAP_SLIST_REMOVE( &op->o_extra, &opinfo.moi_oe, OpExtra, oe_next );
+               opinfo.moi_oe.oe_key = NULL;
+               if( op->o_noop ) {
+                       mdb_txn_abort( txn );
+                       rs->sr_err = LDAP_X_NO_OPERATION;
+                       txn = NULL;
+                       /* Only free attrs if they were dup'd.  */
+                       if ( dummy.e_attrs == e->e_attrs ) dummy.e_attrs = NULL;
+                       goto return_results;
 
-               if(( rs->sr_err=mdb_txn_commit( txn )) != 0 ) {
-                       rs->sr_text = "txn_commit failed";
                } else {
-                       rs->sr_err = LDAP_SUCCESS;
+                       if(( rs->sr_err=mdb_txn_commit( txn )) != 0 ) {
+                               rs->sr_text = "txn_commit failed";
+                       } else {
+                               rs->sr_err = LDAP_SUCCESS;
+                       }
+                       txn = NULL;
                }
        }
 
-       txn = NULL;
-       LDAP_SLIST_REMOVE( &op->o_extra, &opinfo.moi_oe, OpExtra, oe_next );
-       opinfo.moi_oe.oe_key = NULL;
-
        if( rs->sr_err != LDAP_SUCCESS ) {
                Debug( LDAP_DEBUG_TRACE,
                        LDAP_XSTRING(mdb_modrdn) ": %s : %s (%d)\n",
@@ -617,8 +615,8 @@ return_results:
 done:
        slap_graduate_commit_csn( op );
 
-       if( new_dn.bv_val != NULL ) free( new_dn.bv_val );
-       if( new_ndn.bv_val != NULL ) free( new_ndn.bv_val );
+       if( new_ndn.bv_val != NULL ) op->o_tmpfree( new_ndn.bv_val, op->o_tmpmemctx );
+       if( new_dn.bv_val != NULL ) op->o_tmpfree( new_dn.bv_val, op->o_tmpmemctx );
 
        /* LDAP v3 Support */
        if( np != NULL ) {
@@ -636,11 +634,13 @@ done:
                mdb_entry_return( e );
        }
 
-       if( txn != NULL ) {
-               mdb_txn_abort( txn );
-       }
-       if ( opinfo.moi_oe.oe_key ) {
-               LDAP_SLIST_REMOVE( &op->o_extra, &opinfo.moi_oe, OpExtra, oe_next );
+       if( moi == &opinfo ) {
+               if( txn != NULL ) {
+                       mdb_txn_abort( txn );
+               }
+               if ( opinfo.moi_oe.oe_key ) {
+                       LDAP_SLIST_REMOVE( &op->o_extra, &opinfo.moi_oe, OpExtra, oe_next );
+               }
        }
 
        if( preread_ctrl != NULL && (*preread_ctrl) != NULL ) {