From 061c125c6129634d220c1074fa8ed5eaa8b0e09c Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze@samba.org>
Date: Thu, 5 Aug 2021 13:31:29 +0200
Subject: [PATCH 262/266] CVE-2021-3738 s4:rpc_server/drsuapi: make use of
 
Conflict: NA 
Reference: https://git.samba.org/samba.git/?p=samba.git;a=patch;h=061c125c6129634d220c1074fa8ed5eaa8b0e09c

 assoc_group aware dcesrv_samdb_connect_as_*() helpers

This avoids a crash that's triggered by windows clients using
DsCrackNames across multiple connections within an association group
on the same DsBind context(policy) handle.

It also improves the auditing for the dcesrv_samdb_connect_as_system() case.

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

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
---
 source4/rpc_server/drsuapi/dcesrv_drsuapi.c   | 55 +++++++------------
 1 files changed, 19 insertions(+), 36 deletions(-)

diff --git a/source4/rpc_server/drsuapi/dcesrv_drsuapi.c b/source4/rpc_server/drsuapi/dcesrv_drsuapi.c
index 7e2b6174d2f..239971d7009 100644
--- a/source4/rpc_server/drsuapi/dcesrv_drsuapi.c
+++ b/source4/rpc_server/drsuapi/dcesrv_drsuapi.c
@@ -73,9 +73,7 @@ static WERROR dcesrv_drsuapi_DsBind(struct dcesrv_call_state *dce_call, TALLOC_C
 	uint32_t supported_extensions;
 	uint32_t req_length;
 	int ret;
-	struct auth_session_info *auth_info;
 	WERROR werr;
-	bool connected_as_system = false;
 
 	r->out.bind_info = NULL;
 	ZERO_STRUCTP(r->out.bind_handle);
@@ -86,45 +84,30 @@ static WERROR dcesrv_drsuapi_DsBind(struct dcesrv_call_state *dce_call, TALLOC_C
 	/* if this is a DC connecting, give them system level access */
 	werr = drs_security_level_check(dce_call, NULL, SECURITY_DOMAIN_CONTROLLER, NULL);
 	if (W_ERROR_IS_OK(werr)) {
-		DEBUG(3,(__location__ ": doing DsBind with system_session\n"));
-		auth_info = system_session(dce_call->conn->dce_ctx->lp_ctx);
-		connected_as_system = true;
+		DBG_NOTICE("doing DsBind with system_session\n");
+		b_state->sam_ctx_system = dcesrv_samdb_connect_as_system(b_state, dce_call);
+		if (b_state->sam_ctx_system == NULL) {
+			return WERR_DS_UNAVAILABLE;
+		}
+		b_state->sam_ctx = b_state->sam_ctx_system;
 	} else {
-		auth_info = dcesrv_call_session_info(dce_call);
-	}
-
-	/*
-	 * connect to the samdb
-	 */
-	b_state->sam_ctx = samdb_connect(
-		b_state,
-		dce_call->event_ctx,
-		dce_call->conn->dce_ctx->lp_ctx,
-		auth_info,
-		dce_call->conn->remote_address,
-		0);
-	if (!b_state->sam_ctx) {
-		return WERR_FOOBAR;
-	}
+		b_state->sam_ctx = dcesrv_samdb_connect_as_user(b_state, dce_call);
+		if (b_state->sam_ctx == NULL) {
+			return WERR_DS_UNAVAILABLE;
+		}
 
-	if (connected_as_system) {
-		b_state->sam_ctx_system = b_state->sam_ctx;
-	} else {
-		/* an RODC also needs system samdb access for secret
-		   attribute replication */
+		/*
+		 * an RODC also needs system samdb access for secret
+		 * attribute replication
+		 */
 		werr = drs_security_level_check(dce_call, NULL, SECURITY_RO_DOMAIN_CONTROLLER,
 						samdb_domain_sid(b_state->sam_ctx));
 		if (W_ERROR_IS_OK(werr)) {
-			b_state->sam_ctx_system
-			= samdb_connect(
-				b_state,
-				dce_call->event_ctx,
-				dce_call->conn->dce_ctx->lp_ctx,
-				system_session(dce_call->conn->dce_ctx->lp_ctx),
-				dce_call->conn->remote_address,
-				0);
-			if (!b_state->sam_ctx_system) {
-				return WERR_FOOBAR;
+			DBG_NOTICE("doing DsBind as RODC\n");
+			b_state->sam_ctx_system =
+				dcesrv_samdb_connect_as_system(b_state, dce_call);
+			if (b_state->sam_ctx_system == NULL) {
+				return WERR_DS_UNAVAILABLE;
 			}
 		}
 	}
-- 
2.23.0

