diff --git a/servers/slapd/back-bdb/compare.c b/servers/slapd/back-bdb/compare.c
index 3d6946aff1b49d93d41f42816d4a463fdf0ef912..9565a3ab62e2e492e747a955a2c4b21413676fc7 100644
--- a/servers/slapd/back-bdb/compare.c
+++ b/servers/slapd/back-bdb/compare.c
@@ -65,12 +65,17 @@ dn2entry_retry:
 	e = ei->bei_e;
 	if ( rs->sr_err == DB_NOTFOUND ) {
 		if ( e != NULL ) {
+#ifdef SLAP_ACL_HONOR_DISCLOSE
+			/* return referral only if "disclose"
+			 * is granted on the object */
 			if ( ! access_allowed( op, e, slap_schema.si_ad_entry,
 						NULL, ACL_DISCLOSE, NULL ) )
 			{
 				rs->sr_err = LDAP_NO_SUCH_OBJECT;
 
-			} else {
+			} else
+#endif /* SLAP_ACL_HONOR_DISCLOSE */
+			{
 				rs->sr_matched = ch_strdup( e->e_dn );
 				rs->sr_ref = is_entry_referral( e )
 					? get_entry_referrals( op, e )
@@ -97,22 +102,26 @@ dn2entry_retry:
 		goto done;
 	}
 
-	rs->sr_err = access_allowed( op, e, slap_schema.si_ad_entry,
-		NULL, ACL_DISCLOSE, NULL );
-	if ( ! rs->sr_err ) {
-		rs->sr_err = LDAP_NO_SUCH_OBJECT;
-		goto return_results;
-	}
-
 	if (!manageDSAit && is_entry_referral( e ) ) {
-		/* entry is a referral, don't allow add */
-		rs->sr_ref = get_entry_referrals( op, e );
+#ifdef SLAP_ACL_HONOR_DISCLOSE
+		/* return referral only if "disclose"
+		 * is granted on the object */
+		if ( !access_allowed( op, e, slap_schema.si_ad_entry,
+					NULL, ACL_DISCLOSE, NULL ) )
+		{
+			rs->sr_err = LDAP_NO_SUCH_OBJECT;
+		} else
+#endif /* SLAP_ACL_HONOR_DISCLOSE */
+		{
+			/* entry is a referral, don't allow compare */
+			rs->sr_ref = get_entry_referrals( op, e );
+			rs->sr_err = LDAP_REFERRAL;
+			rs->sr_matched = e->e_name.bv_val;
+		}
 
 		Debug( LDAP_DEBUG_TRACE, "entry is referral\n", 0,
 			0, 0 );
 
-		rs->sr_err = LDAP_REFERRAL;
-		rs->sr_matched = e->e_name.bv_val;
 		send_ldap_result( op, rs );
 
 		ber_bvarray_free( rs->sr_ref );
@@ -128,18 +137,29 @@ dn2entry_retry:
 		goto return_results;
 	}
 
-	rs->sr_err = access_allowed( op, e, op->oq_compare.rs_ava->aa_desc,
-		&op->oq_compare.rs_ava->aa_value, ACL_COMPARE, NULL );
-	if ( ! rs->sr_err ) {
-		rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
+	if ( !access_allowed( op, e, op->oq_compare.rs_ava->aa_desc,
+		&op->oq_compare.rs_ava->aa_value, ACL_COMPARE, NULL ) )
+	{
+#ifdef SLAP_ACL_HONOR_DISCLOSE
+		/* return error only if "disclose"
+		 * is granted on the object */
+		if ( !access_allowed( op, e, slap_schema.si_ad_entry,
+					NULL, ACL_DISCLOSE, NULL ) )
+		{
+			rs->sr_err = LDAP_NO_SUCH_OBJECT;
+		} else
+#endif /* SLAP_ACL_HONOR_DISCLOSE */
+		{
+			rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
+		}
 		goto return_results;
 	}
 
 	rs->sr_err = LDAP_NO_SUCH_ATTRIBUTE;
 
-	for(a = attrs_find( e->e_attrs, op->oq_compare.rs_ava->aa_desc );
+	for ( a = attrs_find( e->e_attrs, op->oq_compare.rs_ava->aa_desc );
 		a != NULL;
-		a = attrs_find( a->a_next, op->oq_compare.rs_ava->aa_desc ))
+		a = attrs_find( a->a_next, op->oq_compare.rs_ava->aa_desc ) )
 	{
 		rs->sr_err = LDAP_COMPARE_FALSE;
 
@@ -156,14 +176,18 @@ dn2entry_retry:
 return_results:
 	send_ldap_result( op, rs );
 
-	if( rs->sr_err == LDAP_COMPARE_FALSE || rs->sr_err == LDAP_COMPARE_TRUE ) {
+	switch ( rs->sr_err ) {
+	case LDAP_COMPARE_FALSE:
+	case LDAP_COMPARE_TRUE:
 		rs->sr_err = LDAP_SUCCESS;
+		break;
 	}
 
 done:
 	/* free entry */
-	if( e != NULL ) {
-		bdb_cache_return_entry_r( bdb->bi_dbenv, &bdb->bi_cache, e, &lock );
+	if ( e != NULL ) {
+		bdb_cache_return_entry_r( bdb->bi_dbenv, &bdb->bi_cache,
+				e, &lock );
 	}
 
 	LOCK_ID_FREE ( bdb->bi_dbenv, locker );
diff --git a/servers/slapd/back-bdb/search.c b/servers/slapd/back-bdb/search.c
index d2d5812ee559ffa6ca6c0e45562c0b84c787d10f..9b863f1217b92b2022445a0fae075ed1b4b73986 100644
--- a/servers/slapd/back-bdb/search.c
+++ b/servers/slapd/back-bdb/search.c
@@ -313,6 +313,7 @@ bdb_search( Operation *op, SlapReply *rs )
 	Entry		*matched = NULL;
 	EntryInfo	*ei, ei_root = {0};
 	struct berval	realbase = BER_BVNULL;
+	slap_mask_t	mask;
 	int		manageDSAit;
 	int		tentries = 0;
 	ID		lastid = NOID;
@@ -396,13 +397,18 @@ dn2entry_retry:
 		if ( matched != NULL ) {
 			BerVarray erefs = NULL;
 
+#ifdef SLAP_ACL_HONOR_DISCLOSE
+			/* return referral only if "disclose"
+			 * is granted on the object */
 			if ( ! access_allowed( op, matched,
 						slap_schema.si_ad_entry,
 						NULL, ACL_DISCLOSE, NULL ) )
 			{
 				rs->sr_err = LDAP_NO_SUCH_OBJECT;
 
-			} else {
+			} else
+#endif /* SLAP_ACL_HONOR_DISCLOSE */
+			{
 				ber_dupbv( &matched_dn, &matched->e_name );
 
 				erefs = is_entry_referral( matched )
@@ -449,10 +455,17 @@ dn2entry_retry:
 		return rs->sr_err;
 	}
 
-	if ( ! access_allowed( op, e, slap_schema.si_ad_entry,
-				NULL, ACL_DISCLOSE, NULL ) )
+#ifdef SLAP_ACL_HONOR_DISCLOSE
+	/* NOTE: __NEW__ "search" access is required
+	 * on searchBase object */
+	if ( ! access_allowed_mask( op, e, slap_schema.si_ad_entry,
+				NULL, ACL_SEARCH, NULL, &mask ) )
 	{
-		rs->sr_err = LDAP_NO_SUCH_OBJECT;
+		if ( !ACL_GRANT( mask, ACL_DISCLOSE ) ) {
+			rs->sr_err = LDAP_NO_SUCH_OBJECT;
+		} else {
+			rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
+		}
 
 #ifdef SLAP_ZONE_ALLOC
 		slap_zn_runlock(bdb->bi_cache.c_zctx, e);
@@ -463,6 +476,7 @@ dn2entry_retry:
 		send_ldap_result( op, rs );
 		return 1;
 	}
+#endif /* SLAP_ACL_HONOR_DISCLOSE */
 
 	if ( !manageDSAit && e != &e_root && is_entry_referral( e ) ) {
 		/* entry is a referral, don't allow add */
diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h
index c7ae76acd5baf8ed84fac4100df540dc317d91bc..edcaae20f2a925aefdee557f6ecaef32c63d05ea 100644
--- a/servers/slapd/slap.h
+++ b/servers/slapd/slap.h
@@ -1117,6 +1117,10 @@ typedef struct slap_ldap_modlist {
 #define ml_values	ml_mod.mod_values
 } LDAPModList;
 
+#ifdef LDAP_DEVEL
+#define SLAP_ACL_HONOR_DISCLOSE
+#endif /* LDAP_DEVEL */
+
 /*
  * represents an access control list
  */