X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fmodrdn.c;h=e386ef944c8ae74fc08355ad93ad6b8a2cf1fc42;hb=6044e46ec7af21658829edde47c4c9c904093df3;hp=3aae6ac4448c7733197577d195e6069ab2d196e9;hpb=d918bc9983c454656ee90aaf34d2a9bb80b51f79;p=openldap diff --git a/servers/slapd/modrdn.c b/servers/slapd/modrdn.c index 3aae6ac444..e386ef944c 100644 --- a/servers/slapd/modrdn.c +++ b/servers/slapd/modrdn.c @@ -1,7 +1,7 @@ /* $OpenLDAP$ */ /* This work is part of OpenLDAP Software . * - * 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 @@ -214,9 +214,9 @@ cleanup: 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", @@ -234,6 +234,23 @@ fe_op_modrdn( Operation *op, SlapReply *rs ) 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" @@ -275,19 +292,11 @@ fe_op_modrdn( Operation *op, SlapReply *rs ) 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; - } } /* @@ -367,6 +376,8 @@ fe_op_modrdn( Operation *op, SlapReply *rs ) } 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; } @@ -428,6 +439,7 @@ slap_modrdn2mods( 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; @@ -469,6 +481,7 @@ slap_modrdn2mods( 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;