diff --git a/servers/slapd/modrdn.c b/servers/slapd/modrdn.c
index c16cf90fdefe1c2a38f3412fe29310dac924793d..bd85e5434f0a280537502e9c240f2626c2b90051 100644
--- a/servers/slapd/modrdn.c
+++ b/servers/slapd/modrdn.c
@@ -385,6 +385,50 @@ cleanup:;
 	return rs->sr_err;
 }
 
+/* extracted from slap_modrdn2mods() */
+static int
+mod_op_add_val(
+	Operation *op,
+	AttributeDescription * const desc,
+	struct berval * const val,
+	short const sm_op )
+{
+	int rv = LDAP_SUCCESS;
+	Modifications *mod_tmp;
+	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], val );
+	mod_tmp->sml_values[1].bv_val = NULL;
+	if( desc->ad_type->sat_equality && desc->ad_type->sat_equality->smr_normalize) {
+		mod_tmp->sml_nvalues = ( BerVarray )ch_malloc( 2 * sizeof( struct berval ) );
+		rv = desc->ad_type->sat_equality->smr_normalize(
+			SLAP_MR_EQUALITY|SLAP_MR_VALUE_OF_ASSERTION_SYNTAX,
+			desc->ad_type->sat_syntax,
+			desc->ad_type->sat_equality,
+			&mod_tmp->sml_values[0],
+			&mod_tmp->sml_nvalues[0], NULL );
+		if (rv != LDAP_SUCCESS) {
+			ch_free(mod_tmp->sml_nvalues);
+			ch_free(mod_tmp->sml_values[0].bv_val);
+			ch_free(mod_tmp->sml_values);
+			ch_free(mod_tmp);
+			goto done;
+		}
+		mod_tmp->sml_nvalues[1].bv_val = NULL;
+	} else {
+		mod_tmp->sml_nvalues = NULL;
+	}
+	mod_tmp->sml_op = sm_op;
+	mod_tmp->sml_flags = 0;
+	mod_tmp->sml_next = op->orr_modlist;
+	op->orr_modlist = mod_tmp;
+done:
+	return rv;
+}
+
 int
 slap_modrdn2mods(
 	Operation	*op,
@@ -427,7 +471,6 @@ slap_modrdn2mods(
 	/* Add new attribute values to the entry */
 	for ( a_cnt = 0; new_rdn[a_cnt]; a_cnt++ ) {
 		AttributeDescription	*desc = NULL;
-		Modifications 		*mod_tmp;
 
 		rs->sr_err = slap_bv2ad( &new_rdn[a_cnt]->la_attr, &desc, &rs->sr_text );
 
@@ -452,43 +495,15 @@ slap_modrdn2mods(
 		}
 
 		/* Apply modification */
-		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;
-		if( desc->ad_type->sat_equality->smr_normalize) {
-			mod_tmp->sml_nvalues = ( BerVarray )ch_malloc( 2 * sizeof( struct berval ) );
-			rs->sr_err = desc->ad_type->sat_equality->smr_normalize(
-				SLAP_MR_EQUALITY|SLAP_MR_VALUE_OF_ASSERTION_SYNTAX,
-				desc->ad_type->sat_syntax,
-				desc->ad_type->sat_equality,
-				&mod_tmp->sml_values[0],
-				&mod_tmp->sml_nvalues[0], NULL );
-			if (rs->sr_err != LDAP_SUCCESS) {
-				ch_free(mod_tmp->sml_nvalues);
-				ch_free(mod_tmp->sml_values[0].bv_val);
-				ch_free(mod_tmp->sml_values);
-				ch_free(mod_tmp);
-				goto done;
-			}
-			mod_tmp->sml_nvalues[1].bv_val = NULL;
-		} else {
-			mod_tmp->sml_nvalues = NULL;
-		}
-		mod_tmp->sml_op = SLAP_MOD_SOFTADD;
-		mod_tmp->sml_flags = 0;
-		mod_tmp->sml_next = op->orr_modlist;
-		op->orr_modlist = mod_tmp;
+		rs->sr_err = mod_op_add_val( op, desc, &new_rdn[a_cnt]->la_value, SLAP_MOD_SOFTADD );
+		if (rs->sr_err != LDAP_SUCCESS)
+			goto done;
 	}
 
 	/* Remove old rdn value if required */
 	if ( op->orr_deleteoldrdn ) {
 		for ( d_cnt = 0; old_rdn[d_cnt]; d_cnt++ ) {
 			AttributeDescription	*desc = NULL;
-			Modifications 		*mod_tmp;
 
 			rs->sr_err = slap_bv2ad( &old_rdn[d_cnt]->la_attr, &desc, &rs->sr_text );
 			if ( rs->sr_err != LDAP_SUCCESS ) {
@@ -501,29 +516,9 @@ slap_modrdn2mods(
 			}
 
 			/* Apply modification */
-			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;
-			if( desc->ad_type->sat_equality && desc->ad_type->sat_equality->smr_normalize) {
-				mod_tmp->sml_nvalues = ( BerVarray )ch_malloc( 2 * sizeof( struct berval ) );
-				(void) (*desc->ad_type->sat_equality->smr_normalize)(
-					SLAP_MR_EQUALITY|SLAP_MR_VALUE_OF_ASSERTION_SYNTAX,
-					desc->ad_type->sat_syntax,
-					desc->ad_type->sat_equality,
-					&mod_tmp->sml_values[0],
-					&mod_tmp->sml_nvalues[0], NULL );
-				mod_tmp->sml_nvalues[1].bv_val = NULL;
-			} else {
-				mod_tmp->sml_nvalues = NULL;
-			}
-			mod_tmp->sml_op = LDAP_MOD_DELETE;
-			mod_tmp->sml_flags = 0;
-			mod_tmp->sml_next = op->orr_modlist;
-			op->orr_modlist = mod_tmp;
+			rs->sr_err = mod_op_add_val( op, desc, &old_rdn[d_cnt]->la_value, LDAP_MOD_DELETE );
+			if (rs->sr_err != LDAP_SUCCESS)
+				goto done;
 		}
 	}
 	
@@ -531,12 +526,8 @@ done:
 
 	/* LDAP v2 supporting correct attribute handling. */
 	if ( rs->sr_err != LDAP_SUCCESS && op->orr_modlist != NULL ) {
-		Modifications *tmp;
-
-		for ( ; op->orr_modlist != NULL; op->orr_modlist = tmp ) {
-			tmp = op->orr_modlist->sml_next;
-			ch_free( op->orr_modlist );
-		}
+		slap_mods_free( op->orr_modlist, 1 );
+		op->orr_modlist = NULL;
 	}
 
 	if ( new_rdn != NULL ) {