torture: Add ServerReqChallengeReuseGlobal2 to rpc.netlogon
authorAndrew Bartlett <abartlet@samba.org>
Wed, 14 Dec 2016 02:59:08 +0000 (15:59 +1300)
committerStefan Metzmacher <metze@samba.org>
Wed, 14 Dec 2016 14:56:37 +0000 (15:56 +0100)
This test ensures that when the per-pipe challenge is used, the tdb cache
is wiped as well

Signed-off-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
Autobuild-User(master): Stefan Metzmacher <metze@samba.org>
Autobuild-Date(master): Wed Dec 14 15:56:37 CET 2016 on sn-devel-144

source4/torture/rpc/netlogon.c

index 0d3fe6f31668a8aa54b7b9a87e9868ba0e17dd0b..1d24f07858c94b5e2f7144886e70c504c103884e 100644 (file)
@@ -1397,6 +1397,85 @@ static bool test_ServerReqChallengeReuseGlobal(struct torture_context *tctx,
        return true;
 }
 
+/*
+ * Test if use of the per-pipe challenge will wipe out the globally cached challenge
+ */
+static bool test_ServerReqChallengeReuseGlobal2(struct torture_context *tctx,
+                                               struct dcerpc_pipe *p1,
+                                               struct cli_credentials *machine_credentials)
+{
+       uint32_t flags = NETLOGON_NEG_AUTH2_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
+       struct netr_ServerReqChallenge r;
+       struct netr_ServerAuthenticate3 a;
+       struct netr_Credential credentials1, credentials2, credentials3;
+       struct netlogon_creds_CredentialState *creds;
+       struct samr_Password mach_password;
+       uint32_t rid;
+       const char *machine_name;
+       const char *plain_pass;
+       struct dcerpc_binding_handle *b1 = p1->binding_handle;
+       struct dcerpc_pipe *p2 = NULL;
+       struct dcerpc_binding_handle *b2 = NULL;
+
+       machine_name = cli_credentials_get_workstation(machine_credentials);
+       plain_pass = cli_credentials_get_password(machine_credentials);
+
+       torture_comment(tctx, "Testing ServerReqChallenge on b1\n");
+
+       torture_assert_ntstatus_ok(tctx,
+               dcerpc_pipe_connect_b(tctx, &p2, p1->binding,
+                                     &ndr_table_netlogon,
+                                     machine_credentials,
+                                     tctx->ev, tctx->lp_ctx),
+               "dcerpc_pipe_connect_b failed");
+       b2 = p2->binding_handle;
+
+       r.in.server_name = NULL;
+       r.in.computer_name = machine_name;
+       r.in.credentials = &credentials1;
+       r.out.return_credentials = &credentials2;
+
+       generate_random_buffer(credentials1.data, sizeof(credentials1.data));
+
+       torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b1, tctx, &r),
+               "ServerReqChallenge failed on b1");
+       torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed on b1");
+
+       E_md4hash(plain_pass, mach_password.hash);
+
+       a.in.server_name = NULL;
+       a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
+       a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
+       a.in.computer_name = machine_name;
+       a.in.negotiate_flags = &flags;
+       a.in.credentials = &credentials3;
+       a.out.return_credentials = &credentials3;
+       a.out.negotiate_flags = &flags;
+       a.out.rid = &rid;
+
+       creds = netlogon_creds_client_init(tctx, a.in.account_name,
+                                          a.in.computer_name,
+                                          a.in.secure_channel_type,
+                                          &credentials1, &credentials2,
+                                          &mach_password, &credentials3,
+                                          flags);
+
+       torture_assert(tctx, creds != NULL, "memory allocation");
+
+       torture_comment(tctx, "Testing ServerAuthenticate3 on b2\n");
+
+       torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b1, tctx, &a),
+               "ServerAuthenticate3 failed on b");
+       torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate3 failed on b");
+       torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
+
+       torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b2, tctx, &a),
+               "ServerAuthenticate3 failed on b2");
+       torture_assert_ntstatus_equal(tctx, a.out.result, NT_STATUS_ACCESS_DENIED,
+                                     "ServerAuthenticate3 should have failed on b2, due to credential reuse");
+       return true;
+}
+
 static bool test_ServerReqChallengeReuse(struct torture_context *tctx,
                                         struct dcerpc_pipe *p,
                                         struct cli_credentials *machine_credentials)
@@ -4467,6 +4546,7 @@ struct torture_suite *torture_rpc_netlogon(TALLOC_CTX *mem_ctx)
        torture_rpc_tcase_add_test_creds(tcase, "invalidAuthenticate2", test_invalidAuthenticate2);
        torture_rpc_tcase_add_test_creds(tcase, "ServerReqChallengeGlobal", test_ServerReqChallengeGlobal);
        torture_rpc_tcase_add_test_creds(tcase, "ServerReqChallengeReuseGlobal", test_ServerReqChallengeReuseGlobal);
+       torture_rpc_tcase_add_test_creds(tcase, "ServerReqChallengeReuseGlobal2", test_ServerReqChallengeReuseGlobal2);
        torture_rpc_tcase_add_test_creds(tcase, "ServerReqChallengeReuse", test_ServerReqChallengeReuse);
        torture_rpc_tcase_add_test_creds(tcase, "SetPassword", test_SetPassword);
        torture_rpc_tcase_add_test_creds(tcase, "SetPassword2", test_SetPassword2);