From 94efa3fc3053a623a7a5c3a4a6428356bc334152 Mon Sep 17 00:00:00 2001
From: Joseph Sutton <josephsutton@catalyst.net.nz>
Date: Tue, 14 Feb 2023 13:17:24 +1300
Subject: [PATCH 27/34] CVE-2023-0614 ldb: Centralise checking for inaccessible
 matches

This makes it less likely that we forget to handle a case.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15270

Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>

Conflict: NA
Reference: https://attachments.samba.org/attachment.cgi?id=17821
---
 lib/ldb-samba/ldb_matching_rules.c |  5 ---
 lib/ldb/common/ldb_match.c         | 56 +++++++++++++++++-------------
 2 files changed, 31 insertions(+), 30 deletions(-)

diff --git a/lib/ldb-samba/ldb_matching_rules.c b/lib/ldb-samba/ldb_matching_rules.c
index 0c4c31e49f9..b86594c1823 100644
--- a/lib/ldb-samba/ldb_matching_rules.c
+++ b/lib/ldb-samba/ldb_matching_rules.c
@@ -87,11 +87,6 @@ static int ldb_eval_transitive_filter_helper(TALLOC_CTX *mem_ctx,
 		return LDB_SUCCESS;
 	}
 
-	if (ldb_msg_element_is_inaccessible(el)) {
-		*matched = false;
-		return LDB_SUCCESS;
-	}
-
 	/*
 	 * If the value to match is present in the attribute values of the
 	 * current entry being visited, set matched to true and return OK
diff --git a/lib/ldb/common/ldb_match.c b/lib/ldb/common/ldb_match.c
index 17314f1b9ca..645cb695ef1 100644
--- a/lib/ldb/common/ldb_match.c
+++ b/lib/ldb/common/ldb_match.c
@@ -98,11 +98,6 @@ static int ldb_match_present(struct ldb_context *ldb,
 		return LDB_SUCCESS;
 	}
 
-	if (ldb_msg_element_is_inaccessible(el)) {
-		*matched = false;
-		return LDB_SUCCESS;
-	}
-
 	a = ldb_schema_attribute_by_name(ldb, el->name);
 	if (!a) {
 		return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
@@ -144,11 +139,6 @@ static int ldb_match_comparison(struct ldb_context *ldb,
 		return LDB_SUCCESS;
 	}
 
-	if (ldb_msg_element_is_inaccessible(el)) {
-		*matched = false;
-		return LDB_SUCCESS;
-	}
-
 	a = ldb_schema_attribute_by_name(ldb, el->name);
 	if (!a) {
 		return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
@@ -219,11 +209,6 @@ static int ldb_match_equality(struct ldb_context *ldb,
 		return LDB_SUCCESS;
 	}
 
-	if (ldb_msg_element_is_inaccessible(el)) {
-		*matched = false;
-		return LDB_SUCCESS;
-	}
-
 	a = ldb_schema_attribute_by_name(ldb, el->name);
 	if (a == NULL) {
 		return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
@@ -385,11 +370,6 @@ static int ldb_match_substring(struct ldb_context *ldb,
 		return LDB_SUCCESS;
 	}
 
-	if (ldb_msg_element_is_inaccessible(el)) {
-		*matched = false;
-		return LDB_SUCCESS;
-	}
-
 	for (i = 0; i < el->num_values; i++) {
 		int ret;
 		ret = ldb_wildcard_compare(ldb, tree, el->values[i], matched);
@@ -463,11 +443,6 @@ static int ldb_match_bitmask(struct ldb_context *ldb,
 		return LDB_SUCCESS;
 	}
 
-	if (ldb_msg_element_is_inaccessible(el)) {
-		*matched = false;
-		return LDB_SUCCESS;
-	}
-
 	for (i=0;i<el->num_values;i++) {
 		int ret;
 		struct ldb_val *v = &el->values[i];
@@ -556,6 +531,26 @@ static int ldb_match_extended(struct ldb_context *ldb,
 			      &tree->u.extended.value, matched);
 }
 
+static bool ldb_must_suppress_match(const struct ldb_message *msg,
+				    const struct ldb_parse_tree *tree)
+{
+	const char *attr = NULL;
+	struct ldb_message_element *el = NULL;
+
+	attr = ldb_parse_tree_get_attr(tree);
+	if (attr == NULL) {
+		return false;
+	}
+
+	/* find the message element */
+	el = ldb_msg_find_element(msg, attr);
+	if (el == NULL) {
+		return false;
+	}
+
+	return ldb_msg_element_is_inaccessible(el);
+}
+
 /*
   Check if a particular message will match the given filter
 
@@ -580,6 +575,17 @@ int ldb_match_message(struct ldb_context *ldb,
 		return LDB_SUCCESS;
 	}
 
+	/*
+	 * Suppress matches on confidential attributes (handled
+	 * manually in extended matches as these can do custom things
+	 * like read other parts of the DB or other attributes).
+	 */
+	if (tree->operation != LDB_OP_EXTENDED) {
+		if (ldb_must_suppress_match(msg, tree)) {
+			return LDB_SUCCESS;
+		}
+	}
+
 	switch (tree->operation) {
 	case LDB_OP_AND:
 		for (i=0;i<tree->u.list.num_elements;i++) {
-- 
2.25.1