diff --git a/CHANGES b/CHANGES
index ea8469dcbcb6e7af0a6af83d3a387a9f5f271d9e..7e5a9e2d2bf49227c2f3f0c37a0946fb0d2dd979 100644
--- a/CHANGES
+++ b/CHANGES
@@ -90,6 +90,7 @@ OpenLDAP 2.4.24 Engineering
 	Fixed slapo-refint with subtree rename (ITS#6730)
 	Fixed slapo-rwm double free (ITS#6720)
 	Fixed slapo-rwm crasher (ITS#6632)
+	Fixed slapo-rwm entry handling (ITS#6760)
 	Fixed slapo-sssvlv initialization (ITS#6649)
 	Fixed slapo-sssvlv to not advertise when unused (ITS#6647)
 	Fixed slapo-sssvlv fix result code (ITS#6685)
diff --git a/servers/slapd/overlays/rwm.c b/servers/slapd/overlays/rwm.c
index e792ab3255734c74de2b5284e61b9f48565b169b..c7e277b4aabd8107784e98229c05e52541259c6e 100644
--- a/servers/slapd/overlays/rwm.c
+++ b/servers/slapd/overlays/rwm.c
@@ -916,9 +916,16 @@ rwm_entry_get_rw( Operation *op, struct berval *ndn,
 		/* duplicate & release */
 		op2.o_bd->bd_info = (BackendInfo *)on;
 		rc = rwm_send_entry( &op2, &rs );
+		RS_ASSERT( rs.sr_flags & REP_ENTRY_MUSTFLUSH );
 		if ( rc == SLAP_CB_CONTINUE ) {
 			*ep = rs.sr_entry;
 			rc = LDAP_SUCCESS;
+		} else {
+			assert( rc != LDAP_SUCCESS && rs.sr_entry == *ep );
+			*ep = NULL;
+			op2.o_bd->bd_info = (BackendInfo *)on->on_info;
+			be_entry_release_r( &op2, rs.sr_entry );
+			op2.o_bd->bd_info = (BackendInfo *)on;
 		}
 	}
 
@@ -1461,6 +1468,7 @@ cleanup_attr:;
 	return 0;
 }
 
+/* Should return SLAP_CB_CONTINUE or failure, never LDAP_SUCCESS. */
 static int
 rwm_send_entry( Operation *op, SlapReply *rs )
 {
@@ -1469,7 +1477,6 @@ rwm_send_entry( Operation *op, SlapReply *rs )
 			(struct ldaprwmap *)on->on_bi.bi_private;
 
 	Entry			*e = NULL;
-	slap_mask_t		flags;
 	struct berval		dn = BER_BVNULL,
 				ndn = BER_BVNULL;
 	dncookie		dc;
@@ -1486,7 +1493,6 @@ rwm_send_entry( Operation *op, SlapReply *rs )
 	dc.ctx = "searchEntryDN";
 
 	e = rs->sr_entry;
-	flags = rs->sr_flags;
 	if ( !( rs->sr_flags & REP_ENTRY_MODIFIABLE ) ) {
 		/* FIXME: all we need to duplicate are:
 		 * - dn
@@ -1494,15 +1500,17 @@ rwm_send_entry( Operation *op, SlapReply *rs )
 		 * - attributes that are requested
 		 * - no values if attrsonly is set
 		 */
-
 		e = entry_dup( e );
 		if ( e == NULL ) {
 			rc = LDAP_NO_MEMORY;
 			goto fail;
 		}
-
-		flags &= ~REP_ENTRY_MUSTRELEASE;
-		flags |= ( REP_ENTRY_MODIFIABLE | REP_ENTRY_MUSTBEFREED );
+	} else if ( rs->sr_flags & REP_ENTRY_MUSTRELEASE ) {
+		/* ITS#6423: REP_ENTRY_MUSTRELEASE incompatible
+		 * with REP_ENTRY_MODIFIABLE */
+		RS_ASSERT( 0 );
+		rc = 1;
+		goto fail;
 	}
 
 	/*
@@ -1534,22 +1542,21 @@ rwm_send_entry( Operation *op, SlapReply *rs )
 	 * to return, and remap them accordingly */
 	(void)rwm_attrs( op, rs, &e->e_attrs, 1 );
 
-	if ( rs->sr_flags & REP_ENTRY_MUSTRELEASE ) {
-		/* ITS#6423: REP_ENTRY_MUSTRELEASE incompatible
-		 * with REP_ENTRY_MODIFIABLE */
-		if ( rs->sr_entry == e ) {
-			rc = 1;
-			goto fail;
+	if ( e != rs->sr_entry ) {
+		/* Reimplementing rs_replace_entry(), I suppose to
+		 * bypass our own dubious rwm_entry_release_rw() */
+		if ( rs->sr_flags & REP_ENTRY_MUSTRELEASE ) {
+			rs->sr_flags ^= REP_ENTRY_MUSTRELEASE;
+			op->o_bd->bd_info = (BackendInfo *)on->on_info;
+			be_entry_release_r( op, rs->sr_entry );
+			op->o_bd->bd_info = (BackendInfo *)on;
+		} else if ( rs->sr_flags & REP_ENTRY_MUSTBEFREED ) {
+			entry_free( rs->sr_entry );
 		}
-
-		op->o_bd->bd_info = (BackendInfo *)on->on_info;
-		be_entry_release_r( op, rs->sr_entry );
-		op->o_bd->bd_info = (BackendInfo *)on;
+		rs->sr_entry = e;
+		rs->sr_flags |= REP_ENTRY_MODIFIABLE | REP_ENTRY_MUSTBEFREED;
 	}
 
-	rs->sr_entry = e;
-	rs->sr_flags = flags;
-
 	return SLAP_CB_CONTINUE;
 
 fail:;