From e741d4967b5b4ff3ec7eb558bc3d1668fde9fe35 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze@samba.org>
Date: Wed, 30 Nov 2022 16:16:05 +0100
Subject: [PATCH 05/30] CVE-2022-38023 s3:net: add and use
 net_warn_member_options() helper

This makes sure domain member related 'net' commands print warnings
about unsecure smb.conf options.

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

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
(cherry picked from commit 1fdf1d55a5dd550bdb16d037b5dc995c33c1a67a)

Conflict: NA
Reference: https://attachments.samba.org/attachment.cgi?id=17692
---
 source3/utils/net.c             |  6 ++++++
 source3/utils/net_ads.c         | 14 ++++++++++++++
 source3/utils/net_dom.c         |  2 ++
 source3/utils/net_join.c        |  2 ++
 source3/utils/net_offlinejoin.c |  2 ++
 source3/utils/net_proto.h       |  2 ++
 source3/utils/net_rpc.c         | 10 ++++++++++
 source3/utils/net_util.c        | 14 ++++++++++++++
 8 files changed, 52 insertions(+)

diff --git a/source3/utils/net.c b/source3/utils/net.c
index e1e14743c117..b96d7f5d9d48 100644
--- a/source3/utils/net.c
+++ b/source3/utils/net.c
@@ -85,6 +85,8 @@ enum netr_SchannelType get_sec_channel_type(const char *param)
 
 static int net_changetrustpw(struct net_context *c, int argc, const char **argv)
 {
+	net_warn_member_options();
+
 	if (net_ads_check_our_domain(c) == 0)
 		return net_ads_changetrustpw(c, argc, argv);
 
@@ -112,6 +114,8 @@ static int net_primarytrust_dumpinfo(struct net_context *c, int argc,
 		return 1;
 	}
 
+	net_warn_member_options();
+
 	if (c->opt_stdin) {
 		set_line_buffering(stdin);
 		set_line_buffering(stdout);
@@ -193,6 +197,8 @@ static int net_changesecretpw(struct net_context *c, int argc,
 		return 1;
 	}
 
+	net_warn_member_options();
+
 	if(c->opt_force) {
 		struct secrets_domain_info1 *info = NULL;
 		struct secrets_domain_info1_change *prev = NULL;
diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c
index 9b2cc50aa31f..7859225a03b7 100644
--- a/source3/utils/net_ads.c
+++ b/source3/utils/net_ads.c
@@ -1414,6 +1414,8 @@ static int net_ads_status(struct net_context *c, int argc, const char **argv)
 		return -1;
 	}
 
+	net_warn_member_options();
+
 	status = ads_startup(c, true, tmp_ctx, &ads);
 	if (!ADS_ERR_OK(status)) {
 		goto out;
@@ -1556,6 +1558,8 @@ static ADS_STATUS net_ads_join_ok(struct net_context *c)
 		return ADS_ERROR_NT(NT_STATUS_ACCESS_DENIED);
 	}
 
+	net_warn_member_options();
+
 	net_use_krb_machine_account(c);
 
 	get_dc_name(lp_workgroup(), lp_realm(), dc_name, &dcip);
@@ -1588,6 +1592,8 @@ int net_ads_testjoin(struct net_context *c, int argc, const char **argv)
 		return -1;
 	}
 
+	net_warn_member_options();
+
 	/* Display success or failure */
 	status = net_ads_join_ok(c);
 	if (!ADS_ERR_OK(status)) {
@@ -1685,6 +1691,8 @@ int net_ads_join(struct net_context *c, int argc, const char **argv)
 		return net_ads_join_usage(c, argc, argv);
 	}
 
+	net_warn_member_options();
+
 	if (!modify_config) {
 		werr = check_ads_config();
 		if (!W_ERROR_IS_OK(werr)) {
@@ -2659,6 +2667,8 @@ int net_ads_changetrustpw(struct net_context *c, int argc, const char **argv)
 		goto out;
 	}
 
+	net_warn_member_options();
+
 	net_use_krb_machine_account(c);
 
 	use_in_memory_ccache();
@@ -2961,6 +2971,8 @@ static int net_ads_keytab_add(struct net_context *c,
 		return -1;
 	}
 
+	net_warn_member_options();
+
 	d_printf(_("Processing principals to add...\n"));
 
 	if (!c->opt_user_specified && c->opt_password == NULL) {
@@ -3011,6 +3023,8 @@ static int net_ads_keytab_create(struct net_context *c, int argc, const char **a
 		return -1;
 	}
 
+	net_warn_member_options();
+
 	if (!c->opt_user_specified && c->opt_password == NULL) {
 		net_use_krb_machine_account(c);
 	}
diff --git a/source3/utils/net_dom.c b/source3/utils/net_dom.c
index 13e65a933142..4b48e1566bc8 100644
--- a/source3/utils/net_dom.c
+++ b/source3/utils/net_dom.c
@@ -154,6 +154,8 @@ static int net_dom_join(struct net_context *c, int argc, const char **argv)
 		return net_dom_usage(c, argc, argv);
 	}
 
+	net_warn_member_options();
+
 	if (c->opt_host) {
 		server_name = c->opt_host;
 	}
diff --git a/source3/utils/net_join.c b/source3/utils/net_join.c
index 1493dff74d7b..f67f08f79a81 100644
--- a/source3/utils/net_join.c
+++ b/source3/utils/net_join.c
@@ -39,6 +39,8 @@ int net_join(struct net_context *c, int argc, const char **argv)
 		return 0;
 	}
 
+	net_warn_member_options();
+
 	if (net_ads_check_our_domain(c) == 0) {
 		if (net_ads_join(c, argc, argv) == 0)
 			return 0;
diff --git a/source3/utils/net_offlinejoin.c b/source3/utils/net_offlinejoin.c
index 03e5df0eace9..0cfd5fdfe235 100644
--- a/source3/utils/net_offlinejoin.c
+++ b/source3/utils/net_offlinejoin.c
@@ -49,6 +49,8 @@ int net_offlinejoin(struct net_context *c, int argc, const char **argv)
 		return -1;
 	}
 
+	net_warn_member_options();
+
 	status = libnetapi_net_init(&c->netapi_ctx);
 	if (status != 0) {
 		return -1;
diff --git a/source3/utils/net_proto.h b/source3/utils/net_proto.h
index 1cc8fdf35afe..fe6b5dd9b84f 100644
--- a/source3/utils/net_proto.h
+++ b/source3/utils/net_proto.h
@@ -448,6 +448,8 @@ int net_run_function(struct net_context *c, int argc, const char **argv,
 		      const char *whoami, struct functable *table);
 void net_display_usage_from_functable(struct functable *table);
 
+void net_warn_member_options(void);
+
 const char *net_share_type_str(int num_type);
 
 NTSTATUS net_scan_dc(struct net_context *c,
diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c
index 97c0158d612f..16a541413d2e 100644
--- a/source3/utils/net_rpc.c
+++ b/source3/utils/net_rpc.c
@@ -371,6 +371,8 @@ static int net_rpc_oldjoin(struct net_context *c, int argc, const char **argv)
 		return 0;
 	}
 
+	net_warn_member_options();
+
 	mem_ctx = talloc_init("net_rpc_oldjoin");
 	if (!mem_ctx) {
 		return -1;
@@ -490,6 +492,8 @@ int net_rpc_testjoin(struct net_context *c, int argc, const char **argv)
 		return 0;
 	}
 
+	net_warn_member_options();
+
 	mem_ctx = talloc_init("net_rpc_testjoin");
 	if (!mem_ctx) {
 		return -1;
@@ -564,6 +568,8 @@ static int net_rpc_join_newstyle(struct net_context *c, int argc, const char **a
 		return 0;
 	}
 
+	net_warn_member_options();
+
 	mem_ctx = talloc_init("net_rpc_join_newstyle");
 	if (!mem_ctx) {
 		return -1;
@@ -685,6 +691,8 @@ int net_rpc_join(struct net_context *c, int argc, const char **argv)
 		return -1;
 	}
 
+	net_warn_member_options();
+
 	if (strlen(lp_netbios_name()) > 15) {
 		d_printf(_("Our netbios name can be at most 15 chars long, "
 			   "\"%s\" is %u chars long\n"),
@@ -815,6 +823,8 @@ int net_rpc_info(struct net_context *c, int argc, const char **argv)
 		return 0;
 	}
 
+	net_warn_member_options();
+
 	return run_rpc_command(c, NULL, &ndr_table_samr,
 			       NET_FLAGS_PDC, rpc_info_internals,
 			       argc, argv);
diff --git a/source3/utils/net_util.c b/source3/utils/net_util.c
index 298d9a64dc0c..f3b7755063bf 100644
--- a/source3/utils/net_util.c
+++ b/source3/utils/net_util.c
@@ -31,6 +31,7 @@
 #include "libsmb/libsmb.h"
 #include "lib/param/param.h"
 #include "auth/gensec/gensec.h"
+#include "libcli/auth/netlogon_creds_cli.h"
 #include "lib/cmdline/cmdline.h"
 
 NTSTATUS net_rpc_lookup_name(struct net_context *c,
@@ -478,6 +479,19 @@ void net_display_usage_from_functable(struct functable *table)
 	}
 }
 
+void net_warn_member_options(void)
+{
+	TALLOC_CTX *frame = talloc_stackframe();
+	struct loadparm_context *lp_ctx = NULL;
+
+	lp_ctx = loadparm_init_s3(frame, loadparm_s3_helpers());
+	if (lp_ctx != NULL) {
+		netlogon_creds_cli_warn_options(lp_ctx);
+	}
+
+	TALLOC_FREE(frame);
+}
+
 const char *net_share_type_str(int num_type)
 {
 	switch(num_type) {
-- 
2.34.1
