From e96d5002fc10b3e74c7ed90f8cf7cf234a06a3d1 Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow@samba.org>
Date: Wed, 21 Jun 2023 15:06:12 +0200
Subject: [PATCH 19/28] CVE-2023-3347: smbd: pass lp_ctx to
 smb[1|2]_srv_init_signing()

No change in behaviour.

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

Signed-off-by: Ralph Boehme <slow@samba.org>

Conflict: NA
Reference: https://download.samba.org/pub/samba/patches/security/samba-4.17.10-security-2023-07-19.patch
---
 source3/smbd/proto.h        |  3 ++-
 source3/smbd/smb1_signing.c | 10 ++--------
 source3/smbd/smb1_signing.h |  3 ++-
 source3/smbd/smb2_signing.c | 25 +++++++++++++++----------
 4 files changed, 21 insertions(+), 20 deletions(-)

diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
index c4a33014515..67cc5e8a380 100644
--- a/source3/smbd/proto.h
+++ b/source3/smbd/proto.h
@@ -52,7 +52,8 @@ struct dcesrv_context;
 
 /* The following definitions come from smbd/smb2_signing.c */
 
-bool smb2_srv_init_signing(struct smbXsrv_connection *conn);
+bool smb2_srv_init_signing(struct loadparm_context *lp_ctx,
+			   struct smbXsrv_connection *conn);
 bool srv_init_signing(struct smbXsrv_connection *conn);
 
 /* The following definitions come from smbd/aio.c  */
diff --git a/source3/smbd/smb1_signing.c b/source3/smbd/smb1_signing.c
index 6bcb0629c4f..aa3027d5318 100644
--- a/source3/smbd/smb1_signing.c
+++ b/source3/smbd/smb1_signing.c
@@ -170,18 +170,13 @@ static void smbd_shm_signing_free(TALLOC_CTX *mem_ctx, void *ptr)
  Called by server negprot when signing has been negotiated.
 ************************************************************/
 
-bool smb1_srv_init_signing(struct smbXsrv_connection *conn)
+bool smb1_srv_init_signing(struct loadparm_context *lp_ctx,
+			   struct smbXsrv_connection *conn)
 {
 	bool allowed = true;
 	bool desired;
 	bool mandatory = false;
 
-	struct loadparm_context *lp_ctx = loadparm_init_s3(conn, loadparm_s3_helpers());
-	if (lp_ctx == NULL) {
-		DEBUG(10, ("loadparm_init_s3 failed\n"));
-		return false;
-	}
-
 	/*
 	 * if the client and server allow signing,
 	 * we desire to use it.
@@ -195,7 +190,6 @@ bool smb1_srv_init_signing(struct smbXsrv_connection *conn)
 	 */
 
 	desired = lpcfg_server_signing_allowed(lp_ctx, &mandatory);
-	talloc_unlink(conn, lp_ctx);
 
 	if (lp_async_smb_echo_handler()) {
 		struct smbd_shm_signing *s;
diff --git a/source3/smbd/smb1_signing.h b/source3/smbd/smb1_signing.h
index 56c59c5bbc2..26f60420dfa 100644
--- a/source3/smbd/smb1_signing.h
+++ b/source3/smbd/smb1_signing.h
@@ -33,4 +33,5 @@ bool smb1_srv_is_signing_negotiated(struct smbXsrv_connection *conn);
 void smb1_srv_set_signing(struct smbXsrv_connection *conn,
 		     const DATA_BLOB user_session_key,
 		     const DATA_BLOB response);
-bool smb1_srv_init_signing(struct smbXsrv_connection *conn);
+bool smb1_srv_init_signing(struct loadparm_context *lp_ctx,
+			   struct smbXsrv_connection *conn);
diff --git a/source3/smbd/smb2_signing.c b/source3/smbd/smb2_signing.c
index 4691ef4d613..c1f876f9cd7 100644
--- a/source3/smbd/smb2_signing.c
+++ b/source3/smbd/smb2_signing.c
@@ -26,32 +26,37 @@
 #include "lib/param/param.h"
 #include "smb2_signing.h"
 
-bool smb2_srv_init_signing(struct smbXsrv_connection *conn)
+bool smb2_srv_init_signing(struct loadparm_context *lp_ctx,
+			   struct smbXsrv_connection *conn)
 {
-	struct loadparm_context *lp_ctx = loadparm_init_s3(conn, loadparm_s3_helpers());
-	if (lp_ctx == NULL) {
-		DBG_DEBUG("loadparm_init_s3 failed\n");
-		return false;
-	}
-
 	/*
 	 * For SMB2 all we need to know is if signing is mandatory.
 	 * It is always allowed and desired, whatever the smb.conf says.
 	 */
 	(void)lpcfg_server_signing_allowed(lp_ctx, &conn->smb2.signing_mandatory);
-	talloc_unlink(conn, lp_ctx);
 	return true;
 }
 
 bool srv_init_signing(struct smbXsrv_connection *conn)
 {
+	struct loadparm_context *lp_ctx = NULL;
+	bool ok;
+
+	lp_ctx = loadparm_init_s3(conn, loadparm_s3_helpers());
+	if (lp_ctx == NULL) {
+		DBG_DEBUG("loadparm_init_s3 failed\n");
+		return false;
+	}
+
 #if defined(WITH_SMB1SERVER)
 	if (conn->protocol >= PROTOCOL_SMB2_02) {
 #endif
-		return smb2_srv_init_signing(conn);
+		ok = smb2_srv_init_signing(lp_ctx, conn);
 #if defined(WITH_SMB1SERVER)
 	} else {
-		return smb1_srv_init_signing(conn);
+		ok = smb1_srv_init_signing(lp_ctx, conn);
 	}
 #endif
+	talloc_unlink(conn, lp_ctx);
+	return ok;
 }
-- 
2.34.1
