diff --git a/CHANGES b/CHANGES
index 978072d572daa1c9de0ef179e7afd4833e139283..bf02dd1fa5768df1612bd6c27d54545dab06050d 100644
--- a/CHANGES
+++ b/CHANGES
@@ -18,6 +18,7 @@ OpenLDAP 2.4.24 Engineering
 	Fixed slapd-ndb to honor rootpw setting (ITS#6661)
 	Fixed slapd-meta anon retry with failed auth method (ITS#6643)
 	Fixed slapd-meta rebind proc (ITS#6665)
+	Fixed slapd-meta to correctly rebind as user (ITS#6574)
 	Fixed slapd-null back-config support (ITS#6624)
 	Fixed slapo-pcache callback freeing (ITS#6640)
 	Fixed slapo-pcache to ignore undefined attrs (ITS#6600)
diff --git a/servers/slapd/back-meta/bind.c b/servers/slapd/back-meta/bind.c
index 7c89bee1898bf2287c22f68dfee07c9d638f6663..55c088bd6b0de6ca1ed054ff1d774971a6d25ba9 100644
--- a/servers/slapd/back-meta/bind.c
+++ b/servers/slapd/back-meta/bind.c
@@ -586,7 +586,6 @@ meta_back_single_dobind(
 	metatarget_t		*mt = mi->mi_targets[ candidate ];
 	metaconn_t		*mc = *mcp;
 	metasingleconn_t	*msc = &mc->mc_conns[ candidate ];
-	static struct berval	cred = BER_BVC( "" );
 	int			msgid;
 
 	assert( !LDAP_BACK_CONN_ISBOUND( msc ) );
@@ -602,12 +601,22 @@ meta_back_single_dobind(
 		(void)meta_back_proxy_authz_bind( mc, candidate, op, rs, sendok );
 
 	} else {
+		char *binddn = "";
+		struct berval cred = BER_BVC( "" );
+
+		/* use credentials if available */
+		if ( !BER_BVISNULL( &msc->msc_bound_ndn )
+			&& !BER_BVISNULL( &msc->msc_cred ) )
+		{
+			binddn = msc->msc_bound_ndn.bv_val;
+			cred = msc->msc_cred;
+		}
 
 		/* FIXME: should we check if at least some of the op->o_ctrls
 		 * can/should be passed? */
 		for (;;) {
 			rs->sr_err = ldap_sasl_bind( msc->msc_ld,
-				"", LDAP_SASL_SIMPLE, &cred,
+				binddn, LDAP_SASL_SIMPLE, &cred,
 				NULL, NULL, &msgid );
 			if ( rs->sr_err != LDAP_X_CONNECTING ) {
 				break;
@@ -616,15 +625,26 @@ meta_back_single_dobind(
 		}
 
 		rs->sr_err = meta_back_bind_op_result( op, rs, mc, candidate, msgid, sendok );
+
+		/* if bind succeeded, but anonymous, clear msc_bound_ndn */
+		if ( rs->sr_err == LDAP_SUCCESS ) {
+			if ( binddn[0] == '\0' &&
+				!BER_BVISNULL( &msc->msc_bound_ndn ) && 
+				!BER_BVISEMPTY( &msc->msc_bound_ndn ) )
+			{
+				ber_memfree( msc->msc_bound_ndn.bv_val );
+				BER_BVZERO( &msc->msc_bound_ndn );
+			}
+		}
 	}
 
 	if ( rs->sr_err != LDAP_SUCCESS ) {
 		if ( dolock ) {
 			ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex );
 		}
-	        LDAP_BACK_CONN_BINDING_CLEAR( msc );
+		LDAP_BACK_CONN_BINDING_CLEAR( msc );
 		if ( META_BACK_ONERR_STOP( mi ) ) {
-	        	LDAP_BACK_CONN_TAINTED_SET( mc );
+			LDAP_BACK_CONN_TAINTED_SET( mc );
 			meta_back_release_conn_lock( mi, mc, 0 );
 			*mcp = NULL;
 		}
@@ -1124,6 +1144,10 @@ retry:;
 			char			*xtext = NULL;
 			char			*xmatched = NULL;
 
+			if ( msc->msc_ld == NULL ) {
+				continue;
+			}
+
 			rs->sr_err = LDAP_SUCCESS;
 
 			ldap_get_option( msc->msc_ld, LDAP_OPT_RESULT_CODE, &rs->sr_err );
@@ -1514,6 +1538,11 @@ meta_back_proxy_authz_cred(
 	}
 
 done:;
+
+	if ( !BER_BVISEMPTY( binddn ) ) {
+		LDAP_BACK_CONN_ISIDASSERT_SET( msc );
+	}
+
 	return rs->sr_err;
 }
 
diff --git a/servers/slapd/back-meta/conn.c b/servers/slapd/back-meta/conn.c
index ca5b7932c380ff1f616ccb30411261273ccb40d5..c8fe33ae1c2927b31113d3b49b46f5ff61191336 100644
--- a/servers/slapd/back-meta/conn.c
+++ b/servers/slapd/back-meta/conn.c
@@ -572,6 +572,7 @@ retry:;
 				}
 				ber_bvreplace( &msc->msc_cred, &mt->mt_idassert_passwd );
 			}
+			LDAP_BACK_CONN_ISIDASSERT_SET( msc );
 
 		} else {
 			ber_bvreplace( &msc->msc_bound_ndn, &slap_empty_bv );
@@ -685,6 +686,8 @@ meta_back_retry(
 
 	assert( mc->mc_refcnt > 0 );
 	if ( mc->mc_refcnt == 1 ) {
+		struct berval save_cred;
+
 		if ( LogTest( LDAP_DEBUG_ANY ) ) {
 			char	buf[ SLAP_TEXT_BUFLEN ];
 
@@ -703,6 +706,11 @@ meta_back_retry(
 				op->o_log_prefix, candidate, buf );
 		}
 
+		/* save credentials, if any, for later use;
+		 * meta_clear_one_candidate() would free them */
+		save_cred = msc->msc_cred;
+		BER_BVZERO( &msc->msc_cred );
+
 		meta_clear_one_candidate( op, mc, candidate );
 		LDAP_BACK_CONN_ISBOUND_CLEAR( msc );
 
@@ -712,6 +720,17 @@ meta_back_retry(
 		rc = meta_back_init_one_conn( op, rs, mc, candidate,
 			LDAP_BACK_CONN_ISPRIV( mc ), sendok, 0 );
 
+		/* restore credentials, if any;
+		 * meta_back_init_one_conn() restores msc_bound_ndn, if any;
+		 * if no msc_bound_ndn is restored, destroy credentials */
+		if ( !BER_BVISNULL( &msc->msc_bound_ndn ) ) {
+			msc->msc_cred = save_cred;
+
+		} else if ( !BER_BVISNULL( &save_cred ) ) {
+			memset( save_cred.bv_val, 0, save_cred.bv_len );
+			ber_memfree( save_cred.bv_val );
+		}
+
 		/* restore the "binding" flag, in case */
 		if ( binding ) {
 			LDAP_BACK_CONN_BINDING_SET( msc );
@@ -1095,6 +1114,7 @@ retry_lock:;
 			}
 
 			if ( mc != NULL ) {
+				/* move to tail of queue */
 				if ( mc != LDAP_TAILQ_LAST( &mi->mi_conn_priv[ LDAP_BACK_CONN2PRIV( mc ) ].mic_priv,
 					metaconn_t, mc_q ) )
 				{