From 1cf39a8568fb9b64518aaa7618e20e8cf7084006 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Kuzn=C3=ADk?= Date: Fri, 6 Aug 2021 12:58:34 +0100 Subject: [PATCH] ITS#5344 Record and maintain new DN on ModRDN ops --- contrib/slapd-modules/autogroup/autogroup.c | 50 ++++++--------------- contrib/slapd-modules/lastmod/lastmod.c | 22 +++------ servers/slapd/back-ldif/ldif.c | 19 ++------ servers/slapd/back-mdb/modrdn.c | 22 +++------ servers/slapd/back-ndb/modrdn.cpp | 22 +++------ servers/slapd/back-sql/modrdn.c | 24 +++------- servers/slapd/bconfig.c | 2 + servers/slapd/modrdn.c | 31 +++++++------ servers/slapd/overlays/accesslog.c | 7 +-- servers/slapd/overlays/constraint.c | 19 ++------ servers/slapd/overlays/memberof.c | 36 +++------------ servers/slapd/overlays/refint.c | 15 +------ servers/slapd/overlays/rwm.c | 34 +++++++++++++- servers/slapd/overlays/syncprov.c | 5 +-- servers/slapd/slap.h | 4 ++ servers/slapd/slapi/slapi_ops.c | 4 ++ servers/slapd/slapi/slapi_pblock.c | 21 +++++++++ servers/slapd/syncrepl.c | 15 +++++++ 18 files changed, 146 insertions(+), 206 deletions(-) diff --git a/contrib/slapd-modules/autogroup/autogroup.c b/contrib/slapd-modules/autogroup/autogroup.c index 2031399c5f..047f01bd83 100644 --- a/contrib/slapd-modules/autogroup/autogroup.c +++ b/contrib/slapd-modules/autogroup/autogroup.c @@ -1059,7 +1059,6 @@ autogroup_response( Operation *op, SlapReply *rs ) autogroup_def_t *agd = agi->agi_def; autogroup_entry_t *age; autogroup_filter_t *agf; - BerValue new_dn, new_ndn, pdn; Entry *e, *group; Attribute *a, *ea, *attrs; int is_olddn, is_newdn, is_value_refresh, dn_equal; @@ -1098,30 +1097,15 @@ autogroup_response( Operation *op, SlapReply *rs ) if ( rs->sr_type == REP_RESULT && rs->sr_err == LDAP_SUCCESS && !oex ) { Debug( LDAP_DEBUG_TRACE, "==> autogroup_response MODRDN from <%s>\n", op->o_req_dn.bv_val ); + Debug( LDAP_DEBUG_TRACE, "autogroup_response MODRDN to <%s>\n", op->orr_newDN ); ldap_pvt_thread_mutex_lock( &agi->agi_mutex ); - if ( op->oq_modrdn.rs_newSup ) { - pdn = *op->oq_modrdn.rs_newSup; - } else { - dnParent( &op->o_req_dn, &pdn ); - } - build_new_dn( &new_dn, &pdn, &op->orr_newrdn, op->o_tmpmemctx ); + dnMatch( &dn_equal, 0, NULL, NULL, &op->o_req_ndn, &op->orr_nnewDN ); - if ( op->oq_modrdn.rs_nnewSup ) { - pdn = *op->oq_modrdn.rs_nnewSup; - } else { - dnParent( &op->o_req_ndn, &pdn ); - } - build_new_dn( &new_ndn, &pdn, &op->orr_nnewrdn, op->o_tmpmemctx ); - - Debug( LDAP_DEBUG_TRACE, "autogroup_response MODRDN to <%s>\n", new_dn.bv_val ); - - dnMatch( &dn_equal, 0, NULL, NULL, &op->o_req_ndn, &new_ndn ); - - if ( overlay_entry_get_ov( op, &new_ndn, NULL, NULL, 0, &e, on ) != + if ( overlay_entry_get_ov( op, &op->orr_nnewDN, NULL, NULL, 0, &e, on ) != LDAP_SUCCESS || e == NULL ) { - Debug( LDAP_DEBUG_TRACE, "autogroup_response MODRDN cannot get entry for <%s>\n", new_dn.bv_val ); + Debug( LDAP_DEBUG_TRACE, "autogroup_response MODRDN cannot get entry for <%s>\n", op->orr_newDN.bv_val ); ldap_pvt_thread_mutex_unlock( &agi->agi_mutex ); return SLAP_CB_CONTINUE; } @@ -1130,7 +1114,7 @@ autogroup_response( Operation *op, SlapReply *rs ) if ( a == NULL ) { - Debug( LDAP_DEBUG_TRACE, "autogroup_response MODRDN entry <%s> has no objectClass\n", new_dn.bv_val ); + Debug( LDAP_DEBUG_TRACE, "autogroup_response MODRDN entry <%s> has no objectClass\n", op->orr_newDN.bv_val ); overlay_entry_release_ov( op, e, 0, on ); ldap_pvt_thread_mutex_unlock( &agi->agi_mutex ); return SLAP_CB_CONTINUE; @@ -1151,12 +1135,10 @@ autogroup_response( Operation *op, SlapReply *rs ) dnMatch( &match, 0, NULL, NULL, &age->age_ndn, &op->o_req_ndn ); if ( match == 0 ) { - Debug( LDAP_DEBUG_TRACE, "autogroup_response MODRDN updating group's DN to <%s>\n", new_dn.bv_val ); - ber_dupbv( &age->age_dn, &new_dn ); - ber_dupbv( &age->age_ndn, &new_ndn ); + Debug( LDAP_DEBUG_TRACE, "autogroup_response MODRDN updating group's DN to <%s>\n", op->orr_newDN.bv_val ); + ber_dupbv( &age->age_dn, &op->orr_newDN ); + ber_dupbv( &age->age_ndn, &op->orr_nnewDN ); - op->o_tmpfree( new_dn.bv_val, op->o_tmpmemctx ); - op->o_tmpfree( new_ndn.bv_val, op->o_tmpmemctx ); overlay_entry_release_ov( op, e, 0, on ); ldap_pvt_thread_mutex_unlock( &agi->agi_mutex ); return SLAP_CB_CONTINUE; @@ -1203,9 +1185,6 @@ autogroup_response( Operation *op, SlapReply *rs ) LDAP_SUCCESS || group == NULL ) { Debug( LDAP_DEBUG_TRACE, "autogroup_response MODRDN cannot get group entry <%s>\n", age->age_dn.bv_val ); - op->o_tmpfree( new_dn.bv_val, op->o_tmpmemctx ); - op->o_tmpfree( new_ndn.bv_val, op->o_tmpmemctx ); - attrs_free( attrs ); ldap_pvt_thread_mutex_unlock( &age->age_mutex ); ldap_pvt_thread_mutex_unlock( &agi->agi_mutex ); @@ -1230,7 +1209,7 @@ autogroup_response( Operation *op, SlapReply *rs ) } for ( agf = age->age_filter ; agf ; agf = agf->agf_next ) { - if ( dnIsSuffix( &new_ndn, &agf->agf_ndn ) ) { + if ( dnIsSuffix( &op->orr_nnewDN, &agf->agf_ndn ) ) { /* TODO: should retest filter as it could imply conditions on the dn */ is_newdn = 1; break; @@ -1252,7 +1231,7 @@ autogroup_response( Operation *op, SlapReply *rs ) } if ( is_olddn == 1 && is_newdn == 0 ) { if ( ea ) - autogroup_delete_member_values_from_group( op, &new_dn, age, ea ); + autogroup_delete_member_values_from_group( op, &op->orr_newDN, age, ea ); else autogroup_delete_member_from_group( op, &op->o_req_dn, &op->o_req_ndn, age ); } else @@ -1270,9 +1249,9 @@ autogroup_response( Operation *op, SlapReply *rs ) for ( agf = age->age_filter; agf; agf = agf->agf_next ) { if ( test_filter( op, &etmp, agf->agf_filter ) == LDAP_COMPARE_TRUE ) { if ( ea ) { - autogroup_add_member_values_to_group( op, &new_dn, age, ea ); + autogroup_add_member_values_to_group( op, &op->orr_newDN, age, ea ); } else - autogroup_add_member_to_group( op, &new_dn, &new_ndn, age ); + autogroup_add_member_to_group( op, &op->orr_newDN, &op->orr_nnewDN, age ); break; } } @@ -1290,16 +1269,13 @@ autogroup_response( Operation *op, SlapReply *rs ) } else { autogroup_delete_member_from_group( op, &op->o_req_dn, &op->o_req_ndn, age ); - autogroup_add_member_to_group( op, &new_dn, &new_ndn, age ); + autogroup_add_member_to_group( op, &op->orr_newDN, &op->orr_nnewDN, age ); } } ldap_pvt_thread_mutex_unlock( &age->age_mutex ); } - op->o_tmpfree( new_dn.bv_val, op->o_tmpmemctx ); - op->o_tmpfree( new_ndn.bv_val, op->o_tmpmemctx ); - attrs_free( attrs ); ldap_pvt_thread_mutex_unlock( &agi->agi_mutex ); diff --git a/contrib/slapd-modules/lastmod/lastmod.c b/contrib/slapd-modules/lastmod/lastmod.c index 6b950a2f4e..23ecdc3911 100644 --- a/contrib/slapd-modules/lastmod/lastmod.c +++ b/contrib/slapd-modules/lastmod/lastmod.c @@ -545,26 +545,12 @@ lastmod_update( Operation *op, SlapReply *rs ) lmt = LASTMOD_MODRDN; e = NULL; - if ( op->orr_newSup && !BER_BVISNULL( op->orr_newSup ) ) { - build_new_dn( &bv_name, op->orr_newSup, &op->orr_newrdn, NULL ); - build_new_dn( &bv_nname, op->orr_nnewSup, &op->orr_nnewrdn, NULL ); - - } else { - struct berval pdn; - - dnParent( &op->o_req_dn, &pdn ); - build_new_dn( &bv_name, &pdn, &op->orr_newrdn, NULL ); - - dnParent( &op->o_req_ndn, &pdn ); - build_new_dn( &bv_nname, &pdn, &op->orr_nnewrdn, NULL ); - } - if ( on->on_info->oi_orig->bi_entry_get_rw ) { BackendInfo *bi = op->o_bd->bd_info; int rc; op->o_bd->bd_info = (BackendInfo *)on->on_info->oi_orig; - rc = op->o_bd->bd_info->bi_entry_get_rw( op, &bv_name, NULL, NULL, 0, &e ); + rc = op->o_bd->bd_info->bi_entry_get_rw( op, &op->orr_nnewDN, NULL, NULL, 0, &e ); if ( rc == LDAP_SUCCESS ) { a = attr_find( e->e_attrs, slap_schema.si_ad_modifiersName ); if ( a != NULL ) { @@ -590,14 +576,16 @@ lastmod_update( Operation *op, SlapReply *rs ) } } - assert( dn_match( &bv_name, &e->e_name ) ); - assert( dn_match( &bv_nname, &e->e_nname ) ); + assert( dn_match( &op->orr_newDN, &e->e_name ) ); + assert( dn_match( &op->orr_nnewDN, &e->e_nname ) ); op->o_bd->bd_info->bi_entry_release_rw( op, e, 0 ); } op->o_bd->bd_info = bi; + ber_dupbv( &bv_name, &op->orr_newDN ); + ber_dupbv( &bv_nname, &op->orr_nnewDN ); } /* if !bi_entry_get_rw || bi_entry_get_rw failed for any reason... */ diff --git a/servers/slapd/back-ldif/ldif.c b/servers/slapd/back-ldif/ldif.c index 184bb5dee5..55f168e188 100644 --- a/servers/slapd/back-ldif/ldif.c +++ b/servers/slapd/back-ldif/ldif.c @@ -1736,8 +1736,7 @@ static int ldif_back_modrdn( Operation *op, SlapReply *rs ) { struct ldif_info *li = (struct ldif_info *) op->o_bd->be_private; - struct berval new_dn = BER_BVNULL, new_ndn = BER_BVNULL; - struct berval p_dn, old_path; + struct berval old_path; Entry *entry; char textbuf[SLAP_TEXT_BUFLEN]; int rc, same_ndn; @@ -1748,19 +1747,9 @@ ldif_back_modrdn( Operation *op, SlapReply *rs ) rc = get_entry( op, &entry, &old_path, &rs->sr_text ); if ( rc == LDAP_SUCCESS ) { - /* build new dn, and new ndn for the entry */ - if ( op->oq_modrdn.rs_newSup != NULL ) { - p_dn = *op->oq_modrdn.rs_newSup; - } else { - dnParent( &entry->e_name, &p_dn ); - } - build_new_dn( &new_dn, &p_dn, &op->oq_modrdn.rs_newrdn, NULL ); - dnNormalize( 0, NULL, NULL, &new_dn, &new_ndn, NULL ); - same_ndn = !ber_bvcmp( &entry->e_nname, &new_ndn ); - ber_memfree_x( entry->e_name.bv_val, NULL ); - ber_memfree_x( entry->e_nname.bv_val, NULL ); - entry->e_name = new_dn; - entry->e_nname = new_ndn; + same_ndn = !ber_bvcmp( &entry->e_nname, &op->orr_nnewDN ); + ber_bvreplace( &entry->e_name, &op->orr_newDN ); + ber_bvreplace( &entry->e_nname, &op->orr_nnewDN ); /* perform the modifications */ rc = apply_modify_to_entry( entry, op->orr_modlist, op, rs, textbuf ); diff --git a/servers/slapd/back-mdb/modrdn.c b/servers/slapd/back-mdb/modrdn.c index c3b0a6cd3c..883319fad1 100644 --- a/servers/slapd/back-mdb/modrdn.c +++ b/servers/slapd/back-mdb/modrdn.c @@ -28,7 +28,6 @@ mdb_modrdn( Operation *op, SlapReply *rs ) AttributeDescription *children = slap_schema.si_ad_children; AttributeDescription *entry = slap_schema.si_ad_entry; struct berval p_dn, p_ndn; - struct berval new_dn = {0, NULL}, new_ndn = {0, NULL}; Entry *e = NULL; Entry *p = NULL; /* LDAP v2 supporting correct attribute handling. */ @@ -370,20 +369,12 @@ mdb_modrdn( Operation *op, SlapReply *rs ) new_parent_dn = np_dn; } - /* 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, op->o_tmpmemctx ); - } - - if (!new_ndn.bv_val) { - dnNormalize( 0, NULL, NULL, &new_dn, &new_ndn, op->o_tmpmemctx ); - } - + /* Make sure target entry doesn't exist already. */ Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(mdb_modrdn) ": new ndn=%s\n", - new_ndn.bv_val ); + op->orr_nnewDN.bv_val ); /* Shortcut the search */ - rs->sr_err = mdb_dn2id ( op, txn, NULL, &new_ndn, &nid, NULL, NULL, NULL ); + rs->sr_err = mdb_dn2id ( op, txn, NULL, &op->orr_nnewDN, &nid, NULL, NULL, NULL ); switch( rs->sr_err ) { case MDB_NOTFOUND: break; @@ -435,8 +426,8 @@ mdb_modrdn( Operation *op, SlapReply *rs ) /* copy the entry, then override some fields */ dummy = *e; - dummy.e_name = new_dn; - dummy.e_nname = new_ndn; + dummy.e_name = op->orr_newDN; + dummy.e_nname = op->orr_nnewDN; dummy.e_attrs = NULL; /* add new DN */ @@ -582,9 +573,6 @@ return_results: done: slap_graduate_commit_csn( op ); - 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 ) { /* free new parent */ diff --git a/servers/slapd/back-ndb/modrdn.cpp b/servers/slapd/back-ndb/modrdn.cpp index 8ff42c4105..c6c9d4d11a 100644 --- a/servers/slapd/back-ndb/modrdn.cpp +++ b/servers/slapd/back-ndb/modrdn.cpp @@ -31,7 +31,6 @@ ndb_back_modrdn( Operation *op, SlapReply *rs ) struct ndb_info *ni = (struct ndb_info *) op->o_bd->be_private; AttributeDescription *children = slap_schema.si_ad_children; AttributeDescription *entry = slap_schema.si_ad_entry; - struct berval new_dn = BER_BVNULL, new_ndn = BER_BVNULL; Entry e = {0}; Entry e2 = {0}; char textbuf[SLAP_TEXT_BUFLEN]; @@ -340,23 +339,15 @@ retry: /* transaction retry */ (long) e2.e_id, 0, 0 ); } - /* Build target dn and make sure target entry doesn't exist already. */ - if (!new_dn.bv_val) { - build_new_dn( &new_dn, &e2.e_name, &op->oq_modrdn.rs_newrdn, NULL ); - } - - if (!new_ndn.bv_val) { - build_new_dn( &new_ndn, &e2.e_nname, &op->oq_modrdn.rs_nnewrdn, NULL ); - } - + /* Make sure target entry doesn't exist already. */ Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(ndb_back_modrdn) ": new ndn=%s\n", - new_ndn.bv_val, 0, 0 ); + op->orr_nnewDN.bv_val, 0, 0 ); /* Allow rename to same DN */ - if ( !bvmatch ( &new_ndn, &e.e_nname )) { + if ( !bvmatch ( &op->orr_nnewDN, &e.e_nname )) { rdn2.nr_num = 0; - e2.e_name = new_dn; - e2.e_nname = new_ndn; + e2.e_name = op->orr_newDN; + e2.e_nname = op->orr_nnewDN; NA2.ocs = &matched; rs->sr_err = ndb_entry_get_info( op, &NA2, 1, NULL ); NA2.ocs = NULL; @@ -541,9 +532,6 @@ return_results: send_ldap_result( op, rs ); 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( preread_ctrl != NULL && (*preread_ctrl) != NULL ) { slap_sl_free( (*preread_ctrl)->ldctl_value.bv_val, op->o_tmpmemctx ); slap_sl_free( *preread_ctrl, op->o_tmpmemctx ); diff --git a/servers/slapd/back-sql/modrdn.c b/servers/slapd/back-sql/modrdn.c index e5e6ab5ea0..636892aeac 100644 --- a/servers/slapd/back-sql/modrdn.c +++ b/servers/slapd/back-sql/modrdn.c @@ -42,7 +42,6 @@ backsql_modrdn( Operation *op, SlapReply *rs ) backsql_oc_map_rec *oc = NULL; struct berval pdn = BER_BVNULL, pndn = BER_BVNULL, *new_pdn = NULL, *new_npdn = NULL, - new_dn = BER_BVNULL, new_ndn = BER_BVNULL, realnew_dn = BER_BVNULL; Entry r = { 0 }, p = { 0 }, @@ -258,15 +257,10 @@ backsql_modrdn( Operation *op, SlapReply *rs ) goto done; } - build_new_dn( &new_dn, new_pdn, &op->oq_modrdn.rs_newrdn, - op->o_tmpmemctx ); - build_new_dn( &new_ndn, new_npdn, &op->oq_modrdn.rs_nnewrdn, - op->o_tmpmemctx ); - Debug( LDAP_DEBUG_TRACE, " backsql_modrdn(): new entry dn is \"%s\"\n", - new_dn.bv_val ); + op->orr_newDN.bv_val ); - realnew_dn = new_dn; + realnew_dn = op->orr_newDN; if ( backsql_api_dn2odbc( op, rs, &realnew_dn ) ) { Debug( LDAP_DEBUG_TRACE, " backsql_modrdn(\"%s\"): " "backsql_api_dn2odbc(\"%s\") failed\n", @@ -394,7 +388,7 @@ backsql_modrdn( Operation *op, SlapReply *rs ) (void)backsql_free_entryID( &e_id, 0, op->o_tmpmemctx ); bsi.bsi_e = &r; - rs->sr_err = backsql_init_search( &bsi, &new_ndn, + rs->sr_err = backsql_init_search( &bsi, &op->orr_nnewDN, LDAP_SCOPE_BASE, (time_t)(-1), NULL, dbh, op, rs, slap_anlist_all_attributes, @@ -405,7 +399,7 @@ backsql_modrdn( Operation *op, SlapReply *rs ) case LDAP_REFERRAL: if ( manageDSAit && !BER_BVISNULL( &bsi.bsi_e->e_nname ) && - dn_match( &new_ndn, &bsi.bsi_e->e_nname ) ) + dn_match( &op->orr_nnewDN, &bsi.bsi_e->e_nname ) ) { rs->sr_err = LDAP_SUCCESS; rs->sr_text = NULL; @@ -480,18 +474,10 @@ done:; send_ldap_result( op, rs ); slap_graduate_commit_csn( op ); - if ( !BER_BVISNULL( &realnew_dn ) && realnew_dn.bv_val != new_dn.bv_val ) { + if ( !BER_BVISNULL( &realnew_dn ) && realnew_dn.bv_val != op->orr_newDN.bv_val ) { ch_free( realnew_dn.bv_val ); } - if ( !BER_BVISNULL( &new_dn ) ) { - slap_sl_free( new_dn.bv_val, op->o_tmpmemctx ); - } - - if ( !BER_BVISNULL( &new_ndn ) ) { - slap_sl_free( new_ndn.bv_val, op->o_tmpmemctx ); - } - if ( !BER_BVISNULL( &e_id.eid_ndn ) ) { (void)backsql_free_entryID( &e_id, 0, op->o_tmpmemctx ); } diff --git a/servers/slapd/bconfig.c b/servers/slapd/bconfig.c index 364b4de31e..3abfffae0e 100644 --- a/servers/slapd/bconfig.c +++ b/servers/slapd/bconfig.c @@ -5133,6 +5133,8 @@ config_rename_one( Operation *op, SlapReply *rs, Entry *e, op->orr_nnewrdn = *nnewrdn; op->orr_newSup = NULL; op->orr_nnewSup = NULL; + op->orr_newDN = e->e_name; + op->orr_nnewDN = e->e_nname; op->orr_deleteoldrdn = 1; op->orr_modlist = NULL; slap_modrdn2mods( op, rs ); diff --git a/servers/slapd/modrdn.c b/servers/slapd/modrdn.c index 260eafcd99..c10cc5856b 100644 --- a/servers/slapd/modrdn.c +++ b/servers/slapd/modrdn.c @@ -54,6 +54,7 @@ do_modrdn( struct berval pnewSuperior = BER_BVNULL; struct berval nnewSuperior = BER_BVNULL; + struct berval dest_pdn, dest_pndn; ber_len_t length; @@ -167,7 +168,15 @@ do_modrdn( send_ldap_error( op, rs, LDAP_INVALID_DN_SYNTAX, "invalid newSuperior" ); goto cleanup; } + + dest_pdn = pnewSuperior; + dest_pndn = nnewSuperior; + } else { + dnParent( &op->o_req_dn, &dest_pdn ); + dnParent( &op->o_req_ndn, &dest_pndn ); } + build_new_dn( &op->orr_newDN, &dest_pdn, &op->orr_newrdn, op->o_tmpmemctx ); + build_new_dn( &op->orr_nnewDN, &dest_pndn, &op->orr_nnewrdn, op->o_tmpmemctx ); Debug( LDAP_DEBUG_STATS, "%s MODRDN dn=\"%s\"\n", op->o_log_prefix, op->o_req_dn.bv_val ); @@ -201,6 +210,9 @@ cleanup: op->o_tmpfree( op->orr_newrdn.bv_val, op->o_tmpmemctx ); op->o_tmpfree( op->orr_nnewrdn.bv_val, op->o_tmpmemctx ); + op->o_tmpfree( op->orr_newDN.bv_val, op->o_tmpmemctx ); + op->o_tmpfree( op->orr_nnewDN.bv_val, op->o_tmpmemctx ); + if ( op->orr_modlist != NULL ) slap_mods_free( op->orr_modlist, 1 ); @@ -217,7 +229,7 @@ cleanup: int fe_op_modrdn( Operation *op, SlapReply *rs ) { - struct berval dest_ndn = BER_BVNULL, dest_pndn, pdn = BER_BVNULL; + struct berval pdn = BER_BVNULL; BackendDB *op_be, *bd = op->o_bd; ber_slen_t diff; @@ -237,16 +249,9 @@ 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 ) ) + diff = (ber_slen_t) op->orr_nnewDN.bv_len - (ber_slen_t) op->o_req_ndn.bv_len; + if ( diff > 0 ? dnIsSuffix( &op->orr_nnewDN, &op->o_req_ndn ) + : diff < 0 && dnIsSuffix( &op->o_req_ndn, &op->orr_nnewDN ) ) { send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM, diff > 0 ? "cannot place an entry below itself" @@ -296,7 +301,7 @@ fe_op_modrdn( Operation *op, SlapReply *rs ) } /* check that destination DN is in the same backend as source DN */ - if ( select_backend( &dest_ndn, 0 ) != op->o_bd ) { + if ( select_backend( &op->orr_nnewDN, 0 ) != op->o_bd ) { send_ldap_error( op, rs, LDAP_AFFECTS_MULTIPLE_DSAS, "cannot rename between DSAs" ); goto cleanup; @@ -384,8 +389,6 @@ 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; } diff --git a/servers/slapd/overlays/accesslog.c b/servers/slapd/overlays/accesslog.c index 68bf6cd009..1916f61a90 100644 --- a/servers/slapd/overlays/accesslog.c +++ b/servers/slapd/overlays/accesslog.c @@ -1784,13 +1784,8 @@ static int accesslog_response(Operation *op, SlapReply *rs) { NULL ); if ( op->orr_newSup ) { attr_merge_one( e, ad_reqNewSuperior, op->orr_newSup, op->orr_nnewSup ); - bv2 = *op->orr_nnewSup; - } else { - dnParent( &op->o_req_ndn, &bv2 ); } - build_new_dn( &bv, &bv2, &op->orr_nnewrdn, op->o_tmpmemctx ); - attr_merge_one( e, ad_reqNewDN, &bv, NULL ); - op->o_tmpfree( bv.bv_val, op->o_tmpmemctx ); + attr_merge_one( e, ad_reqNewDN, &op->orr_newDN, &op->orr_nnewDN ); break; case LOG_EN_COMPARE: diff --git a/servers/slapd/overlays/constraint.c b/servers/slapd/overlays/constraint.c index d52372c415..246769f677 100644 --- a/servers/slapd/overlays/constraint.c +++ b/servers/slapd/overlays/constraint.c @@ -1051,23 +1051,10 @@ constraint_update( Operation *op, SlapReply *rs ) target_entry_copy = entry_dup(target_entry); - /* if rename, set the new entry's name - * (in normalized form only) */ + /* if rename, set the new entry's name */ if ( op->o_tag == LDAP_REQ_MODRDN ) { - struct berval pdn, ndn = BER_BVNULL; - - if ( op->orr_nnewSup ) { - pdn = *op->orr_nnewSup; - - } else { - dnParent( &target_entry_copy->e_nname, &pdn ); - } - - build_new_dn( &ndn, &pdn, &op->orr_nnewrdn, NULL ); - - ber_memfree( target_entry_copy->e_nname.bv_val ); - target_entry_copy->e_nname = ndn; - ber_bvreplace( &target_entry_copy->e_name, &ndn ); + ber_bvreplace( &target_entry_copy->e_name, &op->orr_newDN ); + ber_bvreplace( &target_entry_copy->e_nname, &op->orr_nnewDN ); } /* apply modifications, in an attempt diff --git a/servers/slapd/overlays/memberof.c b/servers/slapd/overlays/memberof.c index d76f8f40e4..5affbbf3f5 100644 --- a/servers/slapd/overlays/memberof.c +++ b/servers/slapd/overlays/memberof.c @@ -1520,7 +1520,6 @@ memberof_res_modrdn( Operation *op, SlapReply *rs ) slap_overinst *on = mci->on; memberof_t *mo = (memberof_t *)on->on_bi.bi_private; - struct berval newPDN, newDN = BER_BVNULL, newPNDN, newNDN; int i, rc; BerVarray vals; @@ -1535,20 +1534,11 @@ memberof_res_modrdn( Operation *op, SlapReply *rs ) mci->what |= MEMBEROF_IS_MEMBER; } - if ( op->orr_nnewSup ) { - newPNDN = *op->orr_nnewSup; - - } else { - dnParent( &op->o_req_ndn, &newPNDN ); - } - - build_new_dn( &newNDN, &newPNDN, &op->orr_nnewrdn, op->o_tmpmemctx ); - save_dn = op->o_req_dn; save_ndn = op->o_req_ndn; - op->o_req_dn = newNDN; - op->o_req_ndn = newNDN; + op->o_req_dn = op->orr_newDN; + op->o_req_ndn = op->orr_nnewDN; rc = memberof_isGroupOrMember( op, mci ); op->o_req_dn = save_dn; op->o_req_ndn = save_ndn; @@ -1557,18 +1547,9 @@ memberof_res_modrdn( Operation *op, SlapReply *rs ) goto done; } - if ( op->orr_newSup ) { - newPDN = *op->orr_newSup; - - } else { - dnParent( &op->o_req_dn, &newPDN ); - } - - build_new_dn( &newDN, &newPDN, &op->orr_newrdn, op->o_tmpmemctx ); - if ( mci->what & MEMBEROF_IS_GROUP ) { op->o_bd->bd_info = (BackendInfo *)on->on_info; - rc = backend_attribute( op, NULL, &newNDN, + rc = backend_attribute( op, NULL, &op->orr_nnewDN, mo->mo_ad_member, &vals, ACL_READ ); op->o_bd->bd_info = (BackendInfo *)on; @@ -1577,7 +1558,7 @@ memberof_res_modrdn( Operation *op, SlapReply *rs ) memberof_value_modify( op, &vals[ i ], mo->mo_ad_memberof, &op->o_req_dn, &op->o_req_ndn, - &newDN, &newNDN ); + &op->orr_newDN, &op->orr_nnewDN ); } ber_bvarray_free_x( vals, op->o_tmpmemctx ); } @@ -1585,7 +1566,7 @@ memberof_res_modrdn( Operation *op, SlapReply *rs ) if ( MEMBEROF_REFINT( mo ) && ( mci->what & MEMBEROF_IS_MEMBER ) ) { op->o_bd->bd_info = (BackendInfo *)on->on_info; - rc = backend_attribute( op, NULL, &newNDN, + rc = backend_attribute( op, NULL, &op->orr_nnewDN, mo->mo_ad_memberof, &vals, ACL_READ ); op->o_bd->bd_info = (BackendInfo *)on; @@ -1594,18 +1575,13 @@ memberof_res_modrdn( Operation *op, SlapReply *rs ) memberof_value_modify( op, &vals[ i ], mo->mo_ad_member, &op->o_req_dn, &op->o_req_ndn, - &newDN, &newNDN ); + &op->orr_newDN, &op->orr_nnewDN ); } ber_bvarray_free_x( vals, op->o_tmpmemctx ); } } done:; - if ( !BER_BVISNULL( &newDN ) ) { - op->o_tmpfree( newDN.bv_val, op->o_tmpmemctx ); - } - op->o_tmpfree( newNDN.bv_val, op->o_tmpmemctx ); - return SLAP_CB_CONTINUE; } diff --git a/servers/slapd/overlays/refint.c b/servers/slapd/overlays/refint.c index 602a744458..b74b10e32f 100644 --- a/servers/slapd/overlays/refint.c +++ b/servers/slapd/overlays/refint.c @@ -937,7 +937,6 @@ refint_response( refint_pre *rp; slap_overinst *on; refint_data *id; - BerValue pdn; refint_q *rq; refint_attrs *ip; int ac; @@ -959,18 +958,8 @@ refint_response( rq->do_sub = rp->do_sub; if ( op->o_tag == LDAP_REQ_MODRDN ) { - if ( op->oq_modrdn.rs_newSup ) { - pdn = *op->oq_modrdn.rs_newSup; - } else { - dnParent( &op->o_req_dn, &pdn ); - } - build_new_dn( &rq->newdn, &pdn, &op->orr_newrdn, NULL ); - if ( op->oq_modrdn.rs_nnewSup ) { - pdn = *op->oq_modrdn.rs_nnewSup; - } else { - dnParent( &op->o_req_ndn, &pdn ); - } - build_new_dn( &rq->newndn, &pdn, &op->orr_nnewrdn, NULL ); + ber_dupbv( &rq->newdn, &op->orr_newDN ); + ber_dupbv( &rq->newndn, &op->orr_nnewDN ); } ldap_pvt_thread_mutex_lock( &id->qmutex ); diff --git a/servers/slapd/overlays/rwm.c b/servers/slapd/overlays/rwm.c index 7ba80103b9..34ee7f26b7 100644 --- a/servers/slapd/overlays/rwm.c +++ b/servers/slapd/overlays/rwm.c @@ -122,6 +122,12 @@ rwm_op_rollback( Operation *op, SlapReply *rs, rwm_op_state *ros ) op->orr_newrdn = ros->orr_newrdn; op->orr_nnewrdn = ros->orr_nnewrdn; } + if ( op->orr_newDN.bv_val != ros->orr_newDN.bv_val ) { + ch_free( op->orr_newDN.bv_val ); + ch_free( op->orr_nnewDN.bv_val ); + op->orr_newDN = ros->orr_newDN; + op->orr_nnewDN = ros->orr_nnewDN; + } break; case LDAP_REQ_SEARCH: op->o_tmpfree( ros->mapped_attrs, op->o_tmpmemctx ); @@ -725,7 +731,7 @@ rwm_op_modrdn( Operation *op, SlapReply *rs ) struct ldaprwmap *rwmap = (struct ldaprwmap *)on->on_bi.bi_private; - int rc; + int rc, changedNewDN = 0; dncookie dc; rwm_op_cb *roc = rwm_callback_get( op ); @@ -751,6 +757,7 @@ rwm_op_modrdn( Operation *op, SlapReply *rs ) } if ( op->orr_newSup->bv_val != newSup.bv_val ) { + changedNewDN = 1; op->orr_newSup = op->o_tmpalloc( sizeof( struct berval ), op->o_tmpmemctx ); op->orr_nnewSup = op->o_tmpalloc( sizeof( struct berval ), @@ -781,11 +788,29 @@ rwm_op_modrdn( Operation *op, SlapReply *rs ) } if ( op->orr_newrdn.bv_val != newrdn.bv_val ) { + changedNewDN = 1; op->orr_newrdn = newrdn; op->orr_nnewrdn = nnewrdn; } } + /* + * Update the new DN if changed + */ + if ( changedNewDN ) { + struct berval pdn, pndn; + + if ( op->orr_newSup ) { + pdn = *op->orr_newSup; + pndn = *op->orr_nnewSup; + } else { + dnParent( &op->o_req_dn, &pdn ); + dnParent( &op->o_req_ndn, &pndn ); + } + build_new_dn( &op->orr_newDN, &pdn, &op->orr_newrdn, op->o_tmpmemctx ); + build_new_dn( &op->orr_nnewDN, &pndn, &op->orr_nnewrdn, op->o_tmpmemctx ); + } + /* * Rewrite the dn, if needed */ @@ -817,6 +842,13 @@ err:; op->orr_newrdn = roc->ros.orr_newrdn; op->orr_nnewrdn = roc->ros.orr_nnewrdn; } + + if ( op->orr_newDN.bv_val != roc->ros.orr_newDN.bv_val ) { + op->o_tmpfree( op->orr_newDN.bv_val, op->o_tmpmemctx ); + op->o_tmpfree( op->orr_nnewDN.bv_val, op->o_tmpmemctx ); + op->orr_newDN = roc->ros.orr_newDN; + op->orr_nnewDN = roc->ros.orr_nnewDN; + } } return rc; diff --git a/servers/slapd/overlays/syncprov.c b/servers/slapd/overlays/syncprov.c index 9a277ec40a..47e60f61c3 100644 --- a/servers/slapd/overlays/syncprov.c +++ b/servers/slapd/overlays/syncprov.c @@ -1292,10 +1292,7 @@ syncprov_matchops( Operation *op, opcookie *opc, int saveit ) fc.fdn = &op->o_req_ndn; /* compute new DN */ if ( op->o_tag == LDAP_REQ_MODRDN && !saveit ) { - struct berval pdn; - if ( op->orr_nnewSup ) pdn = *op->orr_nnewSup; - else dnParent( fc.fdn, &pdn ); - build_new_dn( &newdn, &pdn, &op->orr_nnewrdn, op->o_tmpmemctx ); + ber_dupbv_x( &newdn, &op->orr_nnewDN, op->o_tmpmemctx ); fc.fdn = &newdn; freefdn = 1; } diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h index bfb24500ab..769da46c9d 100644 --- a/servers/slapd/slap.h +++ b/servers/slapd/slap.h @@ -2070,6 +2070,8 @@ typedef struct req_modrdn_s { struct berval rs_nnewrdn; struct berval *rs_newSup; struct berval *rs_nnewSup; + struct berval rs_newDN; + struct berval rs_nnewDN; } req_modrdn_s; typedef struct req_add_s { @@ -2692,6 +2694,8 @@ struct Operation { #define orr_nnewrdn oq_modrdn.rs_nnewrdn #define orr_newSup oq_modrdn.rs_newSup #define orr_nnewSup oq_modrdn.rs_nnewSup +#define orr_newDN oq_modrdn.rs_newDN +#define orr_nnewDN oq_modrdn.rs_nnewDN #define orc_ava oq_compare.rs_ava diff --git a/servers/slapd/slapi/slapi_ops.c b/servers/slapd/slapi/slapi_ops.c index 9bff32f308..c58d9b3c8d 100644 --- a/servers/slapd/slapi/slapi_ops.c +++ b/servers/slapd/slapi/slapi_ops.c @@ -341,6 +341,10 @@ slapi_int_connection_done_pb( Slapi_PBlock *pb ) op->o_tmpfree( op->orr_nnewSup->bv_val, op->o_tmpmemctx ); op->o_tmpfree( op->orr_nnewSup, op->o_tmpmemctx ); } + if ( !BER_BVISNULL( &op->orr_newDN )) + op->o_tmpfree( op->orr_newDN.bv_val, op->o_tmpmemctx ); + if ( !BER_BVISNULL( &op->orr_nnewDN )) + op->o_tmpfree( op->orr_nnewDN.bv_val, op->o_tmpmemctx ); slap_mods_free( op->orr_modlist, 1 ); break; case LDAP_REQ_ADD: diff --git a/servers/slapd/slapi/slapi_pblock.c b/servers/slapd/slapi/slapi_pblock.c index 65b308a931..83b835b0eb 100644 --- a/servers/slapd/slapi/slapi_pblock.c +++ b/servers/slapd/slapi/slapi_pblock.c @@ -1019,6 +1019,18 @@ pblock_set( Slapi_PBlock *pb, int param, void *value ) rc = pblock_set_dn( value, &pb->pb_op->orr_newrdn, &pb->pb_op->orr_nnewrdn, pb->pb_op->o_tmpmemctx ); if ( rc == LDAP_SUCCESS ) rc = rdn_validate( &pb->pb_op->orr_nnewrdn ); + if ( rc == LDAP_SUCCESS ) { + struct berval pdn, pndn; + if ( pb->pb_op->orr_nnewSup ) { + pdn = *pb->pb_op->orr_newSup; + pndn = *pb->pb_op->orr_nnewSup; + } else { + dnParent( &pb->pb_op->o_req_dn, &pdn ); + dnParent( &pb->pb_op->o_req_ndn, &pndn ); + } + build_new_dn( &pb->pb_op->orr_newDN, &pdn, &pb->pb_op->orr_newrdn, pb->pb_op->o_tmpmemctx ); + build_new_dn( &pb->pb_op->orr_nnewDN, &pndn, &pb->pb_op->orr_nnewrdn, pb->pb_op->o_tmpmemctx ); + } } else { rc = PBLOCK_ERROR; } @@ -1028,6 +1040,7 @@ pblock_set( Slapi_PBlock *pb, int param, void *value ) PBLOCK_VALIDATE_IS_INTOP( pb ); if ( pb->pb_op->o_tag == LDAP_REQ_MODRDN ) { if ( value == NULL ) { + struct berval pdn, pndn; if ( pb->pb_op->orr_newSup != NULL ) { pb->pb_op->o_tmpfree( pb->pb_op->orr_newSup, pb->pb_op->o_tmpmemctx ); BER_BVZERO( pb->pb_op->orr_newSup ); @@ -1038,6 +1051,10 @@ pblock_set( Slapi_PBlock *pb, int param, void *value ) BER_BVZERO( pb->pb_op->orr_nnewSup ); pb->pb_op->orr_nnewSup = NULL; } + dnParent( &pb->pb_op->o_req_dn, &pdn ); + build_new_dn( &pb->pb_op->orr_newDN, &pdn, &pb->pb_op->orr_newrdn, pb->pb_op->o_tmpmemctx ); + dnParent( &pb->pb_op->o_req_ndn, &pndn ); + build_new_dn( &pb->pb_op->orr_nnewDN, &pndn, &pb->pb_op->orr_nnewrdn, pb->pb_op->o_tmpmemctx ); } else { if ( pb->pb_op->orr_newSup == NULL ) { pb->pb_op->orr_newSup = (struct berval *)pb->pb_op->o_tmpalloc( @@ -1050,6 +1067,10 @@ pblock_set( Slapi_PBlock *pb, int param, void *value ) BER_BVZERO( pb->pb_op->orr_nnewSup ); } rc = pblock_set_dn( value, pb->pb_op->orr_newSup, pb->pb_op->orr_nnewSup, pb->pb_op->o_tmpmemctx ); + if ( rc == LDAP_SUCCESS ) { + build_new_dn( &pb->pb_op->orr_newDN, pb->pb_op->orr_newSup, &pb->pb_op->orr_newrdn, pb->pb_op->o_tmpmemctx ); + build_new_dn( &pb->pb_op->orr_nnewDN, pb->pb_op->orr_nnewSup, &pb->pb_op->orr_nnewrdn, pb->pb_op->o_tmpmemctx ); + } } } else { rc = PBLOCK_ERROR; diff --git a/servers/slapd/syncrepl.c b/servers/slapd/syncrepl.c index 30eac92885..cad636b0fa 100644 --- a/servers/slapd/syncrepl.c +++ b/servers/slapd/syncrepl.c @@ -3149,9 +3149,18 @@ syncrepl_message_to_op( } else { op->orr_newSup = NULL; op->orr_nnewSup = NULL; + dnParent( &op->o_req_dn, &psup ); + dnParent( &op->o_req_ndn, &nsup ); } op->orr_newrdn = prdn; op->orr_nnewrdn = nrdn; + build_new_dn( &op->orr_newDN, &psup, &op->orr_newrdn, op->o_tmpmemctx ); + build_new_dn( &op->orr_nnewDN, &nsup, &op->orr_nnewrdn, op->o_tmpmemctx ); + if ( BER_BVISNULL( &sup ) ) { + BER_BVZERO( &psup ); + BER_BVZERO( &nsup ); + } + op->orr_deleteoldrdn = deleteOldRdn; op->orr_modlist = NULL; if ( slap_modrdn2mods( op, &rs ) ) { @@ -3213,6 +3222,10 @@ done: ch_free( prdn.bv_val ); } } + if ( op->o_tag == LDAP_REQ_MODRDN ) { + op->o_tmpfree( op->orr_newDN.bv_val, op->o_tmpmemctx ); + op->o_tmpfree( op->orr_nnewDN.bv_val, op->o_tmpmemctx ); + } if ( freeReqDn ) { ch_free( op->o_req_ndn.bv_val ); ch_free( op->o_req_dn.bv_val ); @@ -4221,6 +4234,8 @@ retry_add:; op->orr_newSup = NULL; op->orr_nnewSup = NULL; } + op->orr_newDN = entry->e_name; + op->orr_nnewDN = entry->e_nname; op->orr_deleteoldrdn = dni.delOldRDN; op->orr_modlist = NULL; #ifdef LDAP_CONTROL_X_DIRSYNC