diff --git a/doc/man/man5/slapd-config.5 b/doc/man/man5/slapd-config.5
index 80e0bce7ac025bd9de2947f2028f2dcb8f76871f..43dec6df8ec467ded3f9c0dcbe4697bf034cd188 100644
--- a/doc/man/man5/slapd-config.5
+++ b/doc/man/man5/slapd-config.5
@@ -446,6 +446,20 @@ upon StartTLS operation receipt.
 disallows the StartTLS operation if authenticated (see also
 .BR tls_2_anon ).
 .TP
+.B olcExtraAttrs: <attr>
+Lists what attributes need to be added to search requests.
+Local storage backends return the entire entry to the frontend.
+The frontend takes care of only returning the requested attributes
+that are allowed by ACLs.
+However, features like access checking and so may need specific
+attributes that are not automatically returned by remote storage
+backends, like proxy backends and so on.
+.B <attr>
+is an attribute that is needed for internal purposes
+and thus always needs to be collected, even when not explicitly
+requested by clients.
+This attribute is multi-valued.
+.TP
 .B olcGentleHUP: { TRUE | FALSE }
 A SIGHUP signal will only cause a 'gentle' shutdown-attempt:
 .B Slapd
diff --git a/doc/man/man5/slapd.conf.5 b/doc/man/man5/slapd.conf.5
index b28a2ebc5020d6afd3a2f3af6b164d23f247071a..dd6899bcea0622c95c97135a7a32d34b535d9451 100644
--- a/doc/man/man5/slapd.conf.5
+++ b/doc/man/man5/slapd.conf.5
@@ -1278,6 +1278,19 @@ by default. See the
 manual page for more details on ACL requirements for
 Add operations.
 .TP
+.B extra_attrs <attrlist>
+Lists what attributes need to be added to search requests.
+Local storage backends return the entire entry to the frontend.
+The frontend takes care of only returning the requested attributes
+that are allowed by ACLs.
+However, features like access checking and so may need specific
+attributes that are not automatically returned by remote storage
+backends, like proxy backends and so on.
+.B <attrlist>
+is a list of attributes that are needed for internal purposes
+and thus always need to be collected, even when not explicitly
+requested by clients.
+.TP
 .B hidden on | off
 Controls whether the database will be used to answer
 queries. A database that is hidden will never be
diff --git a/servers/slapd/back-ldap/search.c b/servers/slapd/back-ldap/search.c
index 0120640e6d537801c78a8b4087795114250999a3..f5c9d30e7b4e12aa4a138aaa6544defcf64e664b 100644
--- a/servers/slapd/back-ldap/search.c
+++ b/servers/slapd/back-ldap/search.c
@@ -141,7 +141,7 @@ ldap_back_search(
 			msgid; 
 	struct berval	match = BER_BVNULL,
 			filter = BER_BVNULL;
-	int		i;
+	int		i, x;
 	char		**attrs = NULL;
 	int		freetext = 0, filter_undef = 0;
 	int		do_retry = 1, dont_retry = 0;
@@ -169,22 +169,48 @@ ldap_back_search(
 		LDAP_BACK_TV_SET( &tv );
 	}
 
+	i = 0;
 	if ( op->ors_attrs ) {
-		for ( i = 0; !BER_BVISNULL( &op->ors_attrs[i].an_name ); i++ )
+		for ( ; !BER_BVISNULL( &op->ors_attrs[i].an_name ); i++ )
 			/* just count attrs */ ;
+	}
+
+	x = 0;
+	if ( op->o_bd->be_extra_anlist ) {
+		for ( ; !BER_BVISNULL( &op->o_bd->be_extra_anlist[x].an_name ); x++ )
+			/* just count attrs */ ;
+	}
 
-		attrs = op->o_tmpalloc( ( i + 1 )*sizeof( char * ),
+	if ( i > 0 || x > 0 ) {
+		int j = 0;
+
+		attrs = op->o_tmpalloc( ( i + x + 1 )*sizeof( char * ),
 			op->o_tmpmemctx );
 		if ( attrs == NULL ) {
 			rs->sr_err = LDAP_NO_MEMORY;
 			rc = -1;
 			goto finish;
 		}
-	
-		for ( i = 0; !BER_BVISNULL( &op->ors_attrs[i].an_name ); i++ ) {
-			attrs[ i ] = op->ors_attrs[i].an_name.bv_val;
+
+		if ( i > 0 ) {	
+			for ( i = 0; !BER_BVISNULL( &op->ors_attrs[i].an_name ); i++, j++ ) {
+				attrs[ j ] = op->ors_attrs[i].an_name.bv_val;
+			}
+		}
+
+		if ( x > 0 ) {
+			for ( x = 0; !BER_BVISNULL( &op->o_bd->be_extra_anlist[x].an_name ); x++, j++ ) {
+				if ( op->o_bd->be_extra_anlist[x].an_desc &&
+					ad_inlist( op->o_bd->be_extra_anlist[x].an_desc, op->ors_attrs ) )
+				{
+					continue;
+				}
+
+				attrs[ j ] = op->o_bd->be_extra_anlist[x].an_name.bv_val;
+			}
 		}
-		attrs[ i ] = NULL;
+
+		attrs[ j ] = NULL;
 	}
 
 	ctrls = op->o_ctrls;
diff --git a/servers/slapd/back-meta/back-meta.h b/servers/slapd/back-meta/back-meta.h
index 0aa7304a3974875d5508d5de9059b4128943927b..3f98381350073738de8a142cbd83cdfa2b64b975 100644
--- a/servers/slapd/back-meta/back-meta.h
+++ b/servers/slapd/back-meta/back-meta.h
@@ -118,11 +118,11 @@ ldap_back_map_filter(
 
 int
 ldap_back_map_attrs(
+	Operation *op,
 	struct ldapmap *at_map,
 	AttributeName *a,
 	int remap,
-	char ***mapped_attrs,
-	void *memctx );
+	char ***mapped_attrs );
 
 extern int ldap_back_map_config(
 	struct ldapmap	*oc_map,
diff --git a/servers/slapd/back-meta/map.c b/servers/slapd/back-meta/map.c
index 0bdb1f765a123c66e29122a06d5d690004b0f33e..7bb172469b7362a308d468688d1351765d9887d3 100644
--- a/servers/slapd/back-meta/map.c
+++ b/servers/slapd/back-meta/map.c
@@ -171,42 +171,73 @@ ldap_back_map ( struct ldapmap *map, struct berval *s, struct berval *bv,
 
 int
 ldap_back_map_attrs(
+		Operation *op,
 		struct ldapmap *at_map,
 		AttributeName *an,
 		int remap,
-		char ***mapped_attrs,
-		void *memctx )
+		char ***mapped_attrs )
 {
-	int i, j;
+	int i, x, j;
 	char **na;
 	struct berval mapped;
 
-	if ( an == NULL ) {
+	if ( an == NULL && op->o_bd->be_extra_anlist == NULL ) {
 		*mapped_attrs = NULL;
 		return LDAP_SUCCESS;
 	}
 
-	for ( i = 0; !BER_BVISNULL( &an[i].an_name ); i++ )
-		/*  */ ;
+	i = 0;
+	if ( an != NULL ) {
+		for ( ; !BER_BVISNULL( &an[i].an_name ); i++ )
+			/*  */ ;
+	}
+
+	x = 0;
+	if ( op->o_bd->be_extra_anlist != NULL ) {
+		for ( ; !BER_BVISNULL( &op->o_bd->be_extra_anlist[x].an_name ); x++ )
+			/*  */ ;
+	}
 
-	na = (char **)ber_memcalloc_x( i + 1, sizeof(char *), memctx );
+	assert( i > 0 || x > 0 );
+	
+	na = (char **)ber_memcalloc_x( i + x + 1, sizeof(char *), op->o_tmpmemctx );
 	if ( na == NULL ) {
 		*mapped_attrs = NULL;
 		return LDAP_NO_MEMORY;
 	}
 
-	for ( i = j = 0; !BER_BVISNULL( &an[i].an_name ); i++ ) {
-		ldap_back_map( at_map, &an[i].an_name, &mapped, remap );
-		if ( !BER_BVISNULL( &mapped ) && !BER_BVISEMPTY( &mapped ) ) {
-			na[j++] = mapped.bv_val;
+	j = 0;
+	if ( i > 0 ) {
+		for ( i = 0; !BER_BVISNULL( &an[i].an_name ); i++ ) {
+			ldap_back_map( at_map, &an[i].an_name, &mapped, remap );
+			if ( !BER_BVISNULL( &mapped ) && !BER_BVISEMPTY( &mapped ) ) {
+				na[j++] = mapped.bv_val;
+			}
+		}
+	}
+
+	if ( x > 0 ) {
+		for ( x = 0; !BER_BVISNULL( &op->o_bd->be_extra_anlist[x].an_name ); x++ ) {
+			if ( op->o_bd->be_extra_anlist[x].an_desc &&
+				ad_inlist( op->o_bd->be_extra_anlist[x].an_desc, an ) )
+			{
+				continue;
+			}
+
+			ldap_back_map( at_map, &op->o_bd->be_extra_anlist[x].an_name, &mapped, remap );
+			if ( !BER_BVISNULL( &mapped ) && !BER_BVISEMPTY( &mapped ) ) {
+				na[j++] = mapped.bv_val;
+			}
 		}
 	}
-	if ( j == 0 && i != 0 ) {
+
+	if ( j == 0 && ( i > 0 || x > 0 ) ) {
 		na[j++] = LDAP_NO_ATTRS;
 	}
 	na[j] = NULL;
 
 	*mapped_attrs = na;
+
 	return LDAP_SUCCESS;
 }
 
diff --git a/servers/slapd/back-meta/search.c b/servers/slapd/back-meta/search.c
index a187939159105670b1af881a381dd34701a408f8..f4135fe2aba22549a91946805f7bbeebf612c3a3 100644
--- a/servers/slapd/back-meta/search.c
+++ b/servers/slapd/back-meta/search.c
@@ -603,9 +603,8 @@ meta_back_search_start(
 	/*
 	 * Maps required attributes
 	 */
-	rc = ldap_back_map_attrs( &mt->mt_rwmap.rwm_at,
-			op->ors_attrs, BACKLDAP_MAP, &mapped_attrs,
-			op->o_tmpmemctx );
+	rc = ldap_back_map_attrs( op, &mt->mt_rwmap.rwm_at,
+			op->ors_attrs, BACKLDAP_MAP, &mapped_attrs );
 	if ( rc != LDAP_SUCCESS ) {
 		/*
 		 * this target is no longer candidate
diff --git a/servers/slapd/backend.c b/servers/slapd/backend.c
index 0982a22485d7e2f78b5084b09c6ba51f43e54574..006c47370e97297b14fc0de87d38d3d13e155b85 100644
--- a/servers/slapd/backend.c
+++ b/servers/slapd/backend.c
@@ -464,6 +464,9 @@ void backend_destroy_one( BackendDB *bd, int dynamic )
 	}
 	acl_destroy( bd->be_acl );
 	limits_destroy( bd->be_limits );
+	if ( bd->be_extra_anlist ) {
+		anlist_free( bd->be_extra_anlist, 1, NULL );
+	}
 	if ( !BER_BVISNULL( &bd->be_update_ndn ) ) {
 		ch_free( bd->be_update_ndn.bv_val );
 	}
diff --git a/servers/slapd/bconfig.c b/servers/slapd/bconfig.c
index 42861ec1873b7190e1162b701658bccefa84de85..006647bf23f0ea76d5db4c4bc64b9098a9ee64c7 100644
--- a/servers/slapd/bconfig.c
+++ b/servers/slapd/bconfig.c
@@ -135,6 +135,7 @@ static ConfigDriver config_referral;
 static ConfigDriver config_loglevel;
 static ConfigDriver config_updatedn;
 static ConfigDriver config_updateref;
+static ConfigDriver config_extra_attrs;
 static ConfigDriver config_include;
 static ConfigDriver config_obsolete;
 #ifdef HAVE_TLS
@@ -366,6 +367,10 @@ static ConfigTable config_back_cf_table[] = {
 			"SUBSTR caseIgnoreSubstringsMatch "
 			"SYNTAX OMsDirectoryString X-ORDERED 'VALUES' )",
 			NULL, NULL },
+	{ "extra_attrs", "attrlist", 2, 2, 0, ARG_DB|ARG_MAGIC,
+		&config_extra_attrs, "( OLcfgDbAt:0.20 NAME 'olcExtraAttrs' "
+			"EQUALITY caseIgnoreMatch "
+			"SYNTAX OMsDirectoryString )", NULL, NULL },
 	{ "gentlehup", "on|off", 2, 2, 0,
 #ifdef SIGHUP
 		ARG_ON_OFF, &global_gentlehup,
@@ -837,7 +842,7 @@ static ConfigOCs cf_ocs[] = {
 		 "olcReplogFile $ olcRequires $ olcRestrict $ olcRootDN $ olcRootPW $ "
 		 "olcSchemaDN $ olcSecurity $ olcSizeLimit $ olcSyncUseSubentry $ olcSyncrepl $ "
 		 "olcTimeLimit $ olcUpdateDN $ olcUpdateRef $ olcMirrorMode $ "
-		 "olcMonitoring ) )",
+		 "olcMonitoring $ olcExtraAttrs ) )",
 		 	Cft_Database, NULL, cfAddDatabase },
 	{ "( OLcfgGlOc:5 "
 		"NAME 'olcOverlayConfig' "
@@ -3174,6 +3179,58 @@ config_requires(ConfigArgs *c) {
 	return(0);
 }
 
+static int
+config_extra_attrs(ConfigArgs *c)
+{
+	assert( c->be != NULL );
+
+	if ( c->op == SLAP_CONFIG_EMIT ) {
+		int i;
+
+		if ( c->be->be_extra_anlist == NULL ) {
+			return 1;
+		}
+
+		for ( i = 0; !BER_BVISNULL( &c->be->be_extra_anlist[i].an_name ); i++ ) {
+			value_add_one( &c->rvalue_vals, &c->be->be_extra_anlist[i].an_name );
+		}
+
+	} else if ( c->op == LDAP_MOD_DELETE ) {
+		if ( c->be->be_extra_anlist == NULL ) {
+			return 1;
+		}
+
+		if ( c->valx < 0 ) {
+			anlist_free( c->be->be_extra_anlist, 1, NULL );
+			c->be->be_extra_anlist = NULL;
+
+		} else {
+			int i;
+
+			for ( i = 0; i < c->valx && !BER_BVISNULL( &c->be->be_extra_anlist[i + 1].an_name ); i++ )
+				;
+
+			if ( BER_BVISNULL( &c->be->be_extra_anlist[i].an_name ) ) {
+				return 1;
+			}
+
+			ch_free( c->be->be_extra_anlist[i].an_name.bv_val );
+
+			for ( ; !BER_BVISNULL( &c->be->be_extra_anlist[i].an_name ); i++ ) {
+				c->be->be_extra_anlist[i] = c->be->be_extra_anlist[i + 1];
+			}
+		}
+
+	} else {
+		c->be->be_extra_anlist = str2anlist( c->be->be_extra_anlist, c->argv[1], " ,\t" );
+		if ( c->be->be_extra_anlist == NULL ) {
+			return 1;
+		}
+	}
+
+	return 0;
+}
+
 static slap_verbmasks	*loglevel_ops;
 
 static int
diff --git a/servers/slapd/overlays/rwmmap.c b/servers/slapd/overlays/rwmmap.c
index d3c8c19a1dd316f472f7756969e8387156886bda..5141e6714a9463de3b4bc15fc6911ad62fe9da91 100644
--- a/servers/slapd/overlays/rwmmap.c
+++ b/servers/slapd/overlays/rwmmap.c
@@ -186,19 +186,30 @@ rwm_map_attrnames(
 	AttributeName	**anp,
 	int		remap )
 {
-	int		i, j;
+	int		i, j, x;
 
 	assert( anp != NULL );
 
 	*anp = NULL;
 
-	if ( an == NULL ) {
+	if ( an == NULL && op->o_bd->be_extra_anlist == NULL ) {
 		return LDAP_SUCCESS;
 	}
 
-	for ( i = 0; !BER_BVISNULL( &an[i].an_name ); i++ )
-		/* just count */ ;
-	*anp = op->o_tmpalloc( ( i + 1 )* sizeof( AttributeName ),
+	i = 0;
+	if ( an != NULL ) {
+		for ( i = 0; !BER_BVISNULL( &an[i].an_name ); i++ )
+			/* just count */ ;
+	}
+
+	x = 0;
+	if ( op->o_bd->be_extra_anlist ) {
+		for ( ; !BER_BVISNULL( &op->o_bd->be_extra_anlist[x].an_name ); x++ )
+			/* just count */ ;
+	}
+
+	assert( i > 0 || x > 0 );
+	*anp = op->o_tmpalloc( ( i + x + 1 )* sizeof( AttributeName ),
 		op->o_tmpmemctx );
 	if ( *anp == NULL ) {
 		return LDAP_NO_MEMORY;
@@ -321,7 +332,22 @@ rwm_map_attrnames(
 		}
 	}
 
-	if ( j == 0 && i != 0 ) {
+	if ( op->o_bd->be_extra_anlist != NULL ) {
+		/* we assume be_extra_anlist are already mapped */
+		for ( x = 0; !BER_BVISNULL( &op->o_bd->be_extra_anlist[x].an_name ); x++ ) {
+			BER_BVZERO( &(*anp)[j].an_name );
+			if ( op->o_bd->be_extra_anlist[x].an_desc &&
+				ad_inlist( op->o_bd->be_extra_anlist[x].an_desc, *anp ) )
+			{
+				continue;
+			}
+
+			(*anp)[j] = op->o_bd->be_extra_anlist[x];
+			j++;
+		}
+	}
+
+	if ( j == 0 && ( i != 0 || x != 0 ) ) {
 		memset( &(*anp)[0], 0, sizeof( AttributeName ) );
 		(*anp)[0].an_name = *slap_bv_no_attrs;
 		j = 1;
diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h
index 3ebc10a7d20719675fe1ffad4b16cd5ed6885124..9d524c6cbc73fe9304377a7556eaf178ef111e31 100644
--- a/servers/slapd/slap.h
+++ b/servers/slapd/slap.h
@@ -1939,6 +1939,7 @@ struct BackendDB {
 	struct slap_limits **be_limits; /* regex-based size and time limits */
 	AccessControl *be_acl;	/* access control list for this backend	   */
 	slap_access_t	be_dfltaccess;	/* access given if no acl matches	   */
+	AttributeName	*be_extra_anlist;	/* attributes that need to be added to search requests (ITS#6513) */
 
 	/* Replica Information */
 	struct berval be_update_ndn;	/* allowed to make changes (in replicas) */