]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/back-ldap/modrdn.c
Merge remote-tracking branch 'origin/mdb.master'
[openldap] / servers / slapd / back-ldap / modrdn.c
index a578dd19ab02ae6540967243df578faace94caa6..a4c99fcc535966284f994b3b6dda6f8261292605 100644 (file)
@@ -2,7 +2,7 @@
 /* $OpenLDAP$ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
- * Copyright 1999-2007 The OpenLDAP Foundation.
+ * Copyright 1999-2012 The OpenLDAP Foundation.
  * Portions Copyright 1999-2003 Howard Chu.
  * Portions Copyright 2000-2003 Pierangelo Masarati.
  * All rights reserved.
@@ -44,6 +44,7 @@ ldap_back_modrdn(
        ldap_back_send_t        retrying = LDAP_BACK_RETRYING;
        int                     rc = LDAP_SUCCESS;
        char                    *newSup = NULL;
+       struct berval           newrdn = BER_BVNULL;
 
        if ( !ldap_back_dobind( &lc, op, rs, LDAP_BACK_SENDERR ) ) {
                return rs->sr_err;
@@ -72,10 +73,16 @@ ldap_back_modrdn(
                newSup = op->orr_newSup->bv_val;
        }
 
+       /* NOTE: we need to copy the newRDN in case it was formed
+        * from a DN by simply changing the length (ITS#5397) */
+       newrdn = op->orr_newrdn;
+       if ( newrdn.bv_val[ newrdn.bv_len ] != '\0' ) {
+               ber_dupbv_x( &newrdn, &op->orr_newrdn, op->o_tmpmemctx );
+       }
+
 retry:
        ctrls = op->o_ctrls;
-       rc = ldap_back_proxy_authz_ctrl( &lc->lc_bound_ndn,
-               li->li_version, &li->li_idassert, op, rs, &ctrls );
+       rc = ldap_back_controls_add( op, rs, lc, &ctrls );
        if ( rc != LDAP_SUCCESS ) {
                send_ldap_result( op, rs );
                rc = -1;
@@ -83,22 +90,30 @@ retry:
        }
 
        rs->sr_err = ldap_rename( lc->lc_ld, op->o_req_dn.bv_val,
-                       op->orr_newrdn.bv_val, newSup,
+                       newrdn.bv_val, newSup,
                        op->orr_deleteoldrdn, ctrls, NULL, &msgid );
        rc = ldap_back_op_result( lc, op, rs, msgid,
                li->li_timeout[ SLAP_OP_MODRDN ],
                ( LDAP_BACK_SENDRESULT | retrying ) );
-       if ( rs->sr_err == LDAP_SERVER_DOWN && retrying ) {
+       if ( rs->sr_err == LDAP_UNAVAILABLE && retrying ) {
                retrying &= ~LDAP_BACK_RETRYING;
                if ( ldap_back_retry( &lc, op, rs, LDAP_BACK_SENDERR ) ) {
                        /* if the identity changed, there might be need to re-authz */
-                       (void)ldap_back_proxy_authz_ctrl_free( op, &ctrls );
+                       (void)ldap_back_controls_free( op, rs, &ctrls );
                        goto retry;
                }
        }
 
+       ldap_pvt_thread_mutex_lock( &li->li_counter_mutex );
+       ldap_pvt_mp_add( li->li_ops_completed[ SLAP_OP_MODRDN ], 1 );
+       ldap_pvt_thread_mutex_unlock( &li->li_counter_mutex );
+
 cleanup:
-       (void)ldap_back_proxy_authz_ctrl_free( op, &ctrls );
+       (void)ldap_back_controls_free( op, rs, &ctrls );
+
+       if ( newrdn.bv_val != op->orr_newrdn.bv_val ) {
+               op->o_tmpfree( newrdn.bv_val, op->o_tmpmemctx );
+       }
 
        if ( lc != NULL ) {
                ldap_back_release_conn( li, lc );