1
0
mirror of https://github.com/samba-team/samba.git synced 2025-03-26 18:50:30 +03:00

torture: Add netr_setPassword(2) schannel test.

Thanks to Florian Weimer <fweimer@redhat.com> for the help to write
this torture test.

Pair-Programmed-With: Guenther Deschner <gd@samba.org>
Signed-off-by: Andreas Schneider <asn@samba.org>
Signed-off-by: Guenther Deschner <gd@samba.org>

Autobuild-User(master): Karolin Seeger <kseeger@samba.org>
Autobuild-Date(master): Mon Feb 23 20:01:01 CET 2015 on sn-devel-104
This commit is contained in:
Andreas Schneider 2015-02-16 08:56:28 +01:00 committed by Karolin Seeger
parent bb41484509
commit 6e5debf33b
5 changed files with 166 additions and 1 deletions

View File

@ -164,6 +164,7 @@ sub get_interface($)
$interfaces{"localktest6"} = 7;
$interfaces{"maptoguest"} = 8;
$interfaces{"locals3dc9"} = 9;
# 11-16 used by selftest.pl for client interfaces

View File

@ -175,6 +175,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") {
@ -239,6 +241,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($$$)
{
my ($self, $prefix, $s3dcvars) = @_;

View File

@ -278,7 +278,7 @@ rpc = ["rpc.authcontext", "rpc.samba3.bind", "rpc.samba3.srvsvc", "rpc.samba3.sh
"rpc.samr.passwords.pwdlastset", "rpc.samr.passwords.lockout", "rpc.samr.passwords.badpwdcount", "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.ndr"]
@ -372,6 +372,10 @@ for t in tests:
elif t == "vfs.fruit":
plansmbtorture4testsuite(t, "s3dc", '//$SERVER_IP/tmp -U$USERNAME%$PASSWORD --option=torture:share1=vfs_fruit --option=torture:share2=tmp --option=torture:localdir=$SELFTEST_PREFIX/s3dc/share')
plansmbtorture4testsuite(t, "plugin_s4_dc", '//$SERVER_IP/tmp -U$USERNAME%$PASSWORD --option=torture:share1=vfs_fruit --option=torture:share2=tmp --option=torture:localdir=$SELFTEST_PREFIX/plugin_s4_dc/share')
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')

View File

@ -507,6 +507,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));

View File

@ -543,6 +543,86 @@ static bool test_schannel(struct torture_context *tctx,
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_binding_set_flags(b, dcerpc_flags, DCERPC_AUTH_OPTIONS);
torture_assert_ntstatus_ok(tctx, status, "set flags");
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;
}
/*
@ -586,6 +666,35 @@ bool torture_rpc_schannel(struct torture_context *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;
}
/*
test two schannel connections
*/