[Pkg-samba-maint] [samba] 07/10: backport torture test for CVE-2015-0240
Ivo De Decker
ivodd at moszumanska.debian.org
Mon Feb 23 19:40:42 UTC 2015
This is an automated email from the git hooks/post-receive script.
ivodd pushed a commit to annotated tag debian/2%4.1.17+dfsg-1
in repository samba.
commit 1cff678e65e3eed2bc957525aa8f0f31482dd2d2
Author: Ivo De Decker <ivodd at debian.org>
Date: Mon Feb 23 19:30:50 2015 +0100
backport torture test for CVE-2015-0240
---
debian/changelog | 2 +
debian/patches/samba_bug_11077_torturetest.patch | 259 +++++++++++++++++++++++
debian/patches/series | 1 +
3 files changed, 262 insertions(+)
diff --git a/debian/changelog b/debian/changelog
index 358a57a..fd0228d 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -5,6 +5,8 @@ samba (2:4.1.17+dfsg-1) UNRELEASED; urgency=medium
Controller. Closes: #776993
- CVE-2015-0240: Unexpected code execution in smbd. Closes: #779033
* Refresh patch add-so-version-to-private-libraries.
+ * Add new smbtorture test rpc.schannel_anon_setpw to detect the conditions
+ leading to CVE-2015-0240.
-- Ivo De Decker <ivodd at debian.org> Sun, 22 Feb 2015 19:53:54 +0100
diff --git a/debian/patches/samba_bug_11077_torturetest.patch b/debian/patches/samba_bug_11077_torturetest.patch
new file mode 100644
index 0000000..c4a0f18
--- /dev/null
+++ b/debian/patches/samba_bug_11077_torturetest.patch
@@ -0,0 +1,259 @@
+From cbb435953365ddc7ceb5364ae6cc45ac80ba11f6 Mon Sep 17 00:00:00 2001
+From: Andreas Schneider <asn at samba.org>
+Date: Mon, 16 Feb 2015 08:56:28 +0100
+Subject: [PATCH] torture: Add netr_setPassword(2) schannel test.
+
+Thanks to Florian Weimer <fweimer at redhat.com> for the help to write
+this torture test.
+
+Pair-Programmed-With: Guenther Deschner <gd at samba.org>
+Signed-off-by: Andreas Schneider <asn at samba.org>
+Signed-off-by: Guenther Deschner <gd at samba.org>
+---
+ selftest/target/Samba.pm | 1 +
+ selftest/target/Samba3.pm | 50 +++++++++++++++++++
+ source3/selftest/tests.py | 6 ++-
+ source4/torture/rpc/rpc.c | 1 +
+ source4/torture/rpc/schannel.c | 109 +++++++++++++++++++++++++++++++++++++++++
+ 5 files changed, 166 insertions(+), 1 deletion(-)
+
+Index: samba/selftest/target/Samba.pm
+===================================================================
+--- samba.orig/selftest/target/Samba.pm
++++ samba/selftest/target/Samba.pm
+@@ -156,6 +156,7 @@ sub get_interface($)
+
+ $interfaces{"localktest6"} = 7;
+ $interfaces{"maptoguest"} = 8;
++ $interfaces{"locals3dc9"} = 9;
+
+ # 11-16 used by selftest.pl for client interfaces
+
+Index: samba/selftest/target/Samba3.pm
+===================================================================
+--- samba.orig/selftest/target/Samba3.pm
++++ samba/selftest/target/Samba3.pm
+@@ -153,6 +153,8 @@ sub setup_env($$$)
+
+ if ($envname eq "s3dc") {
+ return $self->setup_s3dc("$path/s3dc");
++ } elsif ($envname eq "s3dc_schannel") {
++ return $self->setup_s3dc_schannel("$path/s3dc_schannel");
+ } elsif ($envname eq "simpleserver") {
+ return $self->setup_simpleserver("$path/simpleserver");
+ } elsif ($envname eq "maptoguest") {
+@@ -216,6 +218,54 @@ sub setup_s3dc($$)
+
+ return $vars;
+ }
++
++sub setup_s3dc_schannel($$)
++{
++ my ($self, $path) = @_;
++
++ print "PROVISIONING S3DC WITH SERVER SCHANNEL ...";
++
++ my $pdc_options = "
++ domain master = yes
++ domain logons = yes
++ lanman auth = yes
++
++ rpc_server:epmapper = external
++ rpc_server:spoolss = external
++ rpc_server:lsarpc = external
++ rpc_server:samr = external
++ rpc_server:netlogon = external
++ rpc_server:register_embedded_np = yes
++
++ rpc_daemon:epmd = fork
++ rpc_daemon:spoolssd = fork
++ rpc_daemon:lsasd = fork
++
++ server schannel = yes
++";
++
++ my $vars = $self->provision($path,
++ "LOCALS3DC9",
++ "locals3dc9pass",
++ $pdc_options);
++
++ $vars or return undef;
++
++ if (not $self->check_or_start($vars, "yes", "yes", "yes")) {
++ return undef;
++ }
++
++ $vars->{DC_SERVER} = $vars->{SERVER};
++ $vars->{DC_SERVER_IP} = $vars->{SERVER_IP};
++ $vars->{DC_SERVER_IPV6} = $vars->{SERVER_IPV6};
++ $vars->{DC_NETBIOSNAME} = $vars->{NETBIOSNAME};
++ $vars->{DC_USERNAME} = $vars->{USERNAME};
++ $vars->{DC_PASSWORD} = $vars->{PASSWORD};
++
++ $self->{vars}->{s3dc_schannel} = $vars;
++
++ return $vars;
++}
+
+ sub setup_member($$$)
+ {
+Index: samba/source3/selftest/tests.py
+===================================================================
+--- samba.orig/source3/selftest/tests.py
++++ samba/source3/selftest/tests.py
+@@ -274,7 +274,7 @@ rpc = ["rpc.authcontext", "rpc.samba3.bi
+ "rpc.samr.passwords.pwdlastset", "rpc.samr.large-dc", "rpc.samr.machine.auth",
+ "rpc.samr.priv", "rpc.samr.passwords.validate",
+ "rpc.netlogon.admin",
+- "rpc.schannel", "rpc.schannel2", "rpc.bench-schannel1", "rpc.join", "rpc.bind"]
++ "rpc.schannel", "rpc.schannel2", "rpc.bench-schannel1", "rpc.schannel_anon_setpw", "rpc.join", "rpc.bind"]
+
+ local = ["local.nss-wrapper", "local.ndr"]
+
+@@ -358,6 +358,10 @@ for t in tests:
+ # test the dirsort module.
+ plansmbtorture4testsuite(t, "s3dc", '//$SERVER_IP/tmpsort -U$USERNAME%$PASSWORD')
+ plansmbtorture4testsuite(t, "plugin_s4_dc", '//$SERVER/tmp -U$USERNAME%$PASSWORD')
++ elif t == "rpc.schannel_anon_setpw":
++ plansmbtorture4testsuite(t, "s3dc", '//$SERVER_IP/tmp -U$%', description="anonymous password set")
++ plansmbtorture4testsuite(t, "s3dc_schannel", '//$SERVER_IP/tmp -U$%', description="anonymous password set (schannel enforced server-side)")
++ plansmbtorture4testsuite(t, "plugin_s4_dc", '//$SERVER/tmp -U$%', description="anonymous password set")
+ else:
+ plansmbtorture4testsuite(t, "s3dc", '//$SERVER_IP/tmp -U$USERNAME%$PASSWORD')
+ plansmbtorture4testsuite(t, "plugin_s4_dc", '//$SERVER/tmp -U$USERNAME%$PASSWORD')
+Index: samba/source4/torture/rpc/rpc.c
+===================================================================
+--- samba.orig/source4/torture/rpc/rpc.c
++++ samba/source4/torture/rpc/rpc.c
+@@ -496,6 +496,7 @@ NTSTATUS torture_rpc_init(void)
+ torture_suite_add_simple_test(suite, "schannel", torture_rpc_schannel);
+ torture_suite_add_simple_test(suite, "schannel2", torture_rpc_schannel2);
+ torture_suite_add_simple_test(suite, "bench-schannel1", torture_rpc_schannel_bench1);
++ torture_suite_add_simple_test(suite, "schannel_anon_setpw", torture_rpc_schannel_anon_setpw);
+ torture_suite_add_suite(suite, torture_rpc_srvsvc(suite));
+ torture_suite_add_suite(suite, torture_rpc_svcctl(suite));
+ torture_suite_add_suite(suite, torture_rpc_samr_accessmask(suite));
+Index: samba/source4/torture/rpc/schannel.c
+===================================================================
+--- samba.orig/source4/torture/rpc/schannel.c
++++ samba/source4/torture/rpc/schannel.c
+@@ -543,6 +543,83 @@ static bool test_schannel(struct torture
+ return true;
+ }
+
++/*
++ * Purpose of this test is to demonstrate that a netlogon server carefully deals
++ * with anonymous attempts to set passwords, in particular when the server
++ * enforces the use of schannel. This test makes most sense to be run in an
++ * environment where the netlogon server enforces use of schannel.
++ */
++
++static bool test_schannel_anonymous_setPassword(struct torture_context *tctx,
++ uint32_t dcerpc_flags,
++ bool use2)
++{
++ struct test_join *join_ctx;
++ NTSTATUS status, result;
++ const char *binding = torture_setting_string(tctx, "binding", NULL);
++ struct dcerpc_binding *b;
++ struct dcerpc_pipe *p = NULL;
++ struct cli_credentials *credentials;
++ bool ok = true;
++
++ credentials = cli_credentials_init(NULL);
++ torture_assert(tctx, credentials != NULL, "Bad credentials");
++ cli_credentials_set_anonymous(credentials);
++
++ status = dcerpc_parse_binding(tctx, binding, &b);
++ torture_assert_ntstatus_ok(tctx, status, "Bad binding string");
++
++ status = dcerpc_pipe_connect_b(tctx,
++ &p,
++ b,
++ &ndr_table_netlogon,
++ credentials,
++ tctx->ev,
++ tctx->lp_ctx);
++ torture_assert_ntstatus_ok(tctx, status, "Failed to connect without schannel");
++
++ if (use2) {
++ struct netr_ServerPasswordSet2 r = {};
++ struct netr_Authenticator credential = {};
++ struct netr_Authenticator return_authenticator = {};
++ struct netr_CryptPassword new_password = {};
++
++ r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
++ r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
++ r.in.secure_channel_type = 0;
++ r.in.computer_name = TEST_MACHINE_NAME;
++ r.in.credential = &credential;
++ r.in.new_password = &new_password;
++ r.out.return_authenticator = &return_authenticator;
++
++ status = dcerpc_netr_ServerPasswordSet2_r(p->binding_handle, tctx, &r);
++ result = r.out.result;
++ } else {
++ struct netr_ServerPasswordSet r = {};
++ struct netr_Authenticator credential = {};
++ struct netr_Authenticator return_authenticator = {};
++ struct samr_Password new_password = {};
++
++ r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
++ r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
++ r.in.secure_channel_type = 0;
++ r.in.computer_name = TEST_MACHINE_NAME;
++ r.in.credential = &credential;
++ r.in.new_password = &new_password;
++ r.out.return_authenticator = &return_authenticator;
++
++ status = dcerpc_netr_ServerPasswordSet_r(p->binding_handle, tctx, &r);
++ result = r.out.result;
++ }
++
++ torture_assert_ntstatus_ok(tctx, status, "ServerPasswordSet failed");
++
++ if (NT_STATUS_IS_OK(result)) {
++ torture_fail(tctx, "unexpectedly received NT_STATUS_OK");
++ }
++
++ return ok;
++}
+
+
+ /*
+@@ -584,6 +661,35 @@ bool torture_rpc_schannel(struct torture
+ }
+
+ return ret;
++}
++
++bool torture_rpc_schannel_anon_setpw(struct torture_context *torture)
++{
++ bool ret = true;
++ bool ok;
++ uint32_t dcerpc_flags = DCERPC_SCHANNEL | DCERPC_SIGN | DCERPC_SCHANNEL_AUTO;
++
++ ok = test_schannel_anonymous_setPassword(torture,
++ dcerpc_flags,
++ true);
++ if (!ok) {
++ torture_comment(torture,
++ "Failed with dcerpc_flags=0x%x\n",
++ dcerpc_flags);
++ ret = false;
++ }
++
++ ok = test_schannel_anonymous_setPassword(torture,
++ dcerpc_flags,
++ false);
++ if (!ok) {
++ torture_comment(torture,
++ "Failed with dcerpc_flags=0x%x\n",
++ dcerpc_flags);
++ ret = false;
++ }
++
++ return ret;
+ }
+
+ /*
diff --git a/debian/patches/series b/debian/patches/series
index 79134da..42249d9 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -14,3 +14,4 @@ waf_smbpasswd_location
add-so-version-to-private-libraries
do-not-install-smbclient4-and-nmbclient4
xsltproc_dont_build_smb.conf.5.patch
+samba_bug_11077_torturetest.patch
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-samba/samba.git
More information about the Pkg-samba-maint
mailing list