/* $OpenLDAP$ */
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
*
- * Copyright 1998-2007 The OpenLDAP Foundation.
+ * Copyright 1998-2009 The OpenLDAP Foundation.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
int
fe_op_modrdn( Operation *op, SlapReply *rs )
{
- Backend *newSuperior_be = NULL;
- struct berval pdn = BER_BVNULL;
+ struct berval dest_ndn = BER_BVNULL, dest_pndn, pdn = BER_BVNULL;
BackendDB *op_be, *bd = op->o_bd;
+ ber_slen_t diff;
if( op->o_req_ndn.bv_len == 0 ) {
Debug( LDAP_DEBUG_ANY, "%s do_modrdn: root dse!\n",
goto cleanup;
}
+ if( op->orr_nnewSup ) {
+ dest_pndn = *op->orr_nnewSup;
+ } else {
+ dnParent( &op->o_req_ndn, &dest_pndn );
+ }
+ build_new_dn( &dest_ndn, &dest_pndn, &op->orr_nnewrdn, op->o_tmpmemctx );
+
+ diff = (ber_slen_t) dest_ndn.bv_len - (ber_slen_t) op->o_req_ndn.bv_len;
+ if ( diff > 0 ? dnIsSuffix( &dest_ndn, &op->o_req_ndn )
+ : diff < 0 && dnIsSuffix( &op->o_req_ndn, &dest_ndn ) )
+ {
+ send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
+ diff > 0 ? "cannot place an entry below itself"
+ : "cannot place an entry above itself" );
+ goto cleanup;
+ }
+
/*
* We could be serving multiple database backends. Select the
* appropriate one, or send a referral to our "referral server"
goto cleanup;
}
- /* Make sure that the entry being changed and the newSuperior are in
- * the same backend, otherwise we return an error.
- */
- if( op->orr_newSup ) {
- newSuperior_be = select_backend( op->orr_nnewSup, 0 );
-
- if ( newSuperior_be != op->o_bd ) {
- /* newSuperior is in different backend */
+ /* check that destination DN is in the same backend as source DN */
+ if ( select_backend( &dest_ndn, 0 ) != op->o_bd ) {
send_ldap_error( op, rs, LDAP_AFFECTS_MULTIPLE_DSAS,
"cannot rename between DSAs" );
-
goto cleanup;
- }
}
/*
}
cleanup:;
+ if ( dest_ndn.bv_val != NULL )
+ ber_memfree_x( dest_ndn.bv_val, op->o_tmpmemctx );
op->o_bd = bd;
return rs->sr_err;
}
mod_tmp = ( Modifications * )ch_malloc( sizeof( Modifications ) );
mod_tmp->sml_desc = desc;
BER_BVZERO( &mod_tmp->sml_type );
+ mod_tmp->sml_numvals = 1;
mod_tmp->sml_values = ( BerVarray )ch_malloc( 2 * sizeof( struct berval ) );
ber_dupbv( &mod_tmp->sml_values[0], &new_rdn[a_cnt]->la_value );
mod_tmp->sml_values[1].bv_val = NULL;
mod_tmp = ( Modifications * )ch_malloc( sizeof( Modifications ) );
mod_tmp->sml_desc = desc;
BER_BVZERO( &mod_tmp->sml_type );
+ mod_tmp->sml_numvals = 1;
mod_tmp->sml_values = ( BerVarray )ch_malloc( 2 * sizeof( struct berval ) );
ber_dupbv( &mod_tmp->sml_values[0], &old_rdn[d_cnt]->la_value );
mod_tmp->sml_values[1].bv_val = NULL;