2 Unix SMB/CIFS implementation.
4 test suite for schannel operations
6 Copyright (C) Andrew Tridgell 2004
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "librpc/gen_ndr/ndr_netlogon_c.h"
24 #include "librpc/gen_ndr/ndr_lsa_c.h"
25 #include "librpc/gen_ndr/ndr_samr_c.h"
26 #include "auth/credentials/credentials.h"
27 #include "auth/credentials/credentials_krb5.h"
28 #include "torture/rpc/torture_rpc.h"
29 #include "lib/cmdline/cmdline.h"
30 #include "../libcli/auth/schannel.h"
31 #include "libcli/auth/libcli_auth.h"
32 #include "libcli/security/security.h"
33 #include "system/filesys.h"
34 #include "param/param.h"
35 #include "param/loadparm.h"
36 #include "librpc/rpc/dcerpc_proto.h"
37 #include "libcli/composite/composite.h"
38 #include "lib/events/events.h"
40 #define TEST_MACHINE_NAME "schannel"
43 try a netlogon SamLogon
45 bool test_netlogon_ex_ops(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
46 struct cli_credentials
*credentials
,
47 struct netlogon_creds_CredentialState
*creds
)
50 struct netr_LogonSamLogonEx r
= {};
51 struct netr_NetworkInfo ninfo
;
52 union netr_LogonLevel logon
;
53 union netr_Validation validation
;
54 uint8_t authoritative
= 1;
56 DATA_BLOB names_blob
, chal
, lm_resp
, nt_resp
;
58 int flags
= CLI_CRED_NTLM_AUTH
;
59 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
61 struct netr_UserSessionKey key
;
62 struct netr_LMSessionKey LMSessKey
;
63 uint32_t validation_levels
[] = { 2, 3 };
64 struct netr_SamBaseInfo
*base
= NULL
;
65 const char *crypto_alg
= "";
66 bool can_do_validation_6
= true;
67 enum dcerpc_AuthType auth_type
= DCERPC_AUTH_TYPE_NONE
;
68 enum dcerpc_AuthLevel auth_level
= DCERPC_AUTH_LEVEL_NONE
;
70 if (lpcfg_client_lanman_auth(tctx
->lp_ctx
)) {
71 flags
|= CLI_CRED_LANMAN_AUTH
;
74 if (lpcfg_client_ntlmv2_auth(tctx
->lp_ctx
)) {
75 flags
|= CLI_CRED_NTLMv2_AUTH
;
78 cli_credentials_get_ntlm_username_domain(samba_cmdline_get_creds(),
80 &ninfo
.identity_info
.account_name
.string
,
81 &ninfo
.identity_info
.domain_name
.string
);
83 generate_random_buffer(ninfo
.challenge
,
84 sizeof(ninfo
.challenge
));
85 chal
= data_blob_const(ninfo
.challenge
,
86 sizeof(ninfo
.challenge
));
88 names_blob
= NTLMv2_generate_names_blob(tctx
, cli_credentials_get_workstation(credentials
),
89 cli_credentials_get_domain(credentials
));
91 status
= cli_credentials_get_ntlm_response(
92 samba_cmdline_get_creds(),
96 NULL
, /* server_timestamp */
100 torture_assert_ntstatus_ok(tctx
, status
,
101 "cli_credentials_get_ntlm_response failed");
103 ninfo
.lm
.data
= lm_resp
.data
;
104 ninfo
.lm
.length
= lm_resp
.length
;
106 ninfo
.nt
.data
= nt_resp
.data
;
107 ninfo
.nt
.length
= nt_resp
.length
;
109 ninfo
.identity_info
.parameter_control
= 0;
110 ninfo
.identity_info
.logon_id
= 0;
111 ninfo
.identity_info
.workstation
.string
= cli_credentials_get_workstation(credentials
);
113 logon
.network
= &ninfo
;
115 r
.in
.server_name
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
116 r
.in
.computer_name
= cli_credentials_get_workstation(credentials
);
117 r
.in
.logon_level
= NetlogonNetworkInformation
;
119 r
.in
.flags
= &_flags
;
120 r
.out
.validation
= &validation
;
121 r
.out
.authoritative
= &authoritative
;
122 r
.out
.flags
= &_flags
;
126 - save usrsession and lmsession key
134 if (creds
->negotiate_flags
& NETLOGON_NEG_SUPPORTS_AES
) {
136 } else if (creds
->negotiate_flags
& NETLOGON_NEG_ARCFOUR
) {
137 crypto_alg
= "ARCFOUR";
141 dcerpc_binding_handle_auth_info(b
, &auth_type
, &auth_level
);
142 if (auth_level
== DCERPC_AUTH_LEVEL_PRIVACY
) {
143 r
.in
.validation_level
= 6;
145 torture_comment(tctx
,
146 "Testing LogonSamLogonEx with name %s using %s and validation_level: %d\n",
147 ninfo
.identity_info
.account_name
.string
, crypto_alg
,
148 r
.in
.validation_level
);
150 torture_assert_ntstatus_ok(tctx
,
151 dcerpc_netr_LogonSamLogonEx_r(b
, tctx
, &r
),
152 "LogonSamLogonEx failed");
154 torture_comment(tctx
,
155 "Skip auth_level[%u] Testing LogonSamLogonEx with name %s using %s and validation_level: %d\n",
156 auth_level
, ninfo
.identity_info
.account_name
.string
, crypto_alg
,
157 r
.in
.validation_level
);
158 r
.out
.result
= NT_STATUS_INVALID_INFO_CLASS
;
161 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_INVALID_INFO_CLASS
)) {
162 can_do_validation_6
= false;
164 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
165 "LogonSamLogonEx failed");
167 key
= r
.out
.validation
->sam6
->base
.key
;
168 LMSessKey
= r
.out
.validation
->sam6
->base
.LMSessKey
;
170 DEBUG(1,("unencrypted session keys from validation_level 6:\n"));
171 dump_data(1, r
.out
.validation
->sam6
->base
.key
.key
, 16);
172 dump_data(1, r
.out
.validation
->sam6
->base
.LMSessKey
.key
, 8);
175 for (i
=0; i
< ARRAY_SIZE(validation_levels
); i
++) {
177 r
.in
.validation_level
= validation_levels
[i
];
179 torture_comment(tctx
,
180 "Testing LogonSamLogonEx with name %s using %s and validation_level: %d\n",
181 ninfo
.identity_info
.account_name
.string
, crypto_alg
,
182 r
.in
.validation_level
);
184 torture_assert_ntstatus_ok(tctx
,
185 dcerpc_netr_LogonSamLogonEx_r(b
, tctx
, &r
),
186 "LogonSamLogonEx failed");
187 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
188 "LogonSamLogonEx failed");
191 /* when this test is called without creds no point in
192 * testing the session keys */
196 switch (validation_levels
[i
]) {
198 base
= &r
.out
.validation
->sam2
->base
;
201 base
= &r
.out
.validation
->sam3
->base
;
207 DEBUG(1,("encrypted keys validation_level %d:\n",
208 validation_levels
[i
]));
209 dump_data(1, base
->key
.key
, 16);
210 dump_data(1, base
->LMSessKey
.key
, 8);
212 status
= netlogon_creds_decrypt_samlogon_validation(creds
,
213 r
.in
.validation_level
,
217 torture_assert_ntstatus_ok(tctx
, status
, "decrypt_samlogon_validation");
219 DEBUG(1,("decrypted keys validation_level %d\n",
220 validation_levels
[i
]));
222 dump_data(1, base
->key
.key
, 16);
223 dump_data(1, base
->LMSessKey
.key
, 8);
225 if (!can_do_validation_6
) {
226 /* we can't compare against unencrypted keys */
230 torture_assert_mem_equal(tctx
,
234 "unexpected user session key\n");
235 torture_assert_mem_equal(tctx
,
239 "unexpected LM session key\n");
245 static bool test_netlogon_ex_bug14932(struct dcerpc_pipe
*p
,
246 struct torture_context
*tctx
,
247 struct cli_credentials
*credentials
,
248 struct netlogon_creds_CredentialState
*creds
)
251 struct netr_LogonSamLogonEx r
= {
256 struct netr_NetworkInfo ninfo
;
257 union netr_LogonLevel logon
;
258 union netr_Validation validation
;
259 uint8_t authoritative
= 1;
261 static const char *netapp_magic
=
262 "\x01\x01\x00\x00\x00\x00\x00\x00"
263 "\x3f\x3f\x3f\x3f\x3f\x3f\x3f\x3f"
264 "\xb8\x82\x3a\xf1\xb3\xdd\x08\x15"
265 "\x00\x00\x00\x00\x11\xa2\x08\x81"
266 "\x50\x38\x22\x78\x2b\x94\x47\xfe"
267 "\x54\x94\x7b\xff\x17\x27\x5a\xb4"
268 "\xf4\x18\xba\xdc\x2c\x38\xfd\x5b"
269 "\xfb\x0e\xc1\x85\x1e\xcc\x92\xbb"
270 "\x9b\xb1\xc4\xd5\x53\x14\xff\x8c"
271 "\x76\x49\xf5\x45\x90\x19\xa2";
272 NTTIME timestamp
= BVAL(netapp_magic
, 8);
273 DATA_BLOB names_blob
= data_blob_string_const(netapp_magic
+ 28);
274 DATA_BLOB chal
, lm_resp
, nt_resp
;
276 int flags
= CLI_CRED_NTLM_AUTH
;
277 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
278 struct netr_UserSessionKey key
;
279 struct netr_LMSessionKey LMSessKey
;
280 uint32_t validation_levels
[] = { 2, 3 };
281 struct netr_SamBaseInfo
*base
= NULL
;
282 const char *crypto_alg
= "";
283 bool can_do_validation_6
= true;
284 enum dcerpc_AuthType auth_type
= DCERPC_AUTH_TYPE_NONE
;
285 enum dcerpc_AuthLevel auth_level
= DCERPC_AUTH_LEVEL_NONE
;
287 flags
|= CLI_CRED_NTLMv2_AUTH
;
289 cli_credentials_get_ntlm_username_domain(samba_cmdline_get_creds(),
291 &ninfo
.identity_info
.account_name
.string
,
292 &ninfo
.identity_info
.domain_name
.string
);
294 generate_random_buffer(ninfo
.challenge
,
295 sizeof(ninfo
.challenge
));
297 chal
= data_blob_const(ninfo
.challenge
,
298 sizeof(ninfo
.challenge
));
300 status
= cli_credentials_get_ntlm_response(
301 samba_cmdline_get_creds(),
309 torture_assert_ntstatus_ok(tctx
, status
,
310 "cli_credentials_get_ntlm_response failed");
312 ninfo
.lm
.data
= lm_resp
.data
;
313 ninfo
.lm
.length
= lm_resp
.length
;
315 ninfo
.nt
.data
= nt_resp
.data
;
316 ninfo
.nt
.length
= nt_resp
.length
;
318 ninfo
.identity_info
.parameter_control
= 0;
319 ninfo
.identity_info
.logon_id
= 0;
320 ninfo
.identity_info
.workstation
.string
= cli_credentials_get_workstation(credentials
);
322 logon
.network
= &ninfo
;
324 r
.in
.server_name
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
325 r
.in
.computer_name
= cli_credentials_get_workstation(credentials
);
326 r
.in
.logon_level
= NetlogonNetworkInformation
;
328 r
.in
.flags
= &_flags
;
329 r
.out
.validation
= &validation
;
330 r
.out
.authoritative
= &authoritative
;
331 r
.out
.flags
= &_flags
;
335 - save usrsession and lmsession key
343 if (creds
->negotiate_flags
& NETLOGON_NEG_SUPPORTS_AES
) {
345 } else if (creds
->negotiate_flags
& NETLOGON_NEG_ARCFOUR
) {
346 crypto_alg
= "ARCFOUR";
350 dcerpc_binding_handle_auth_info(b
, &auth_type
, &auth_level
);
351 if (auth_level
== DCERPC_AUTH_LEVEL_PRIVACY
) {
352 r
.in
.validation_level
= 6;
354 torture_comment(tctx
,
355 "Testing LogonSamLogonEx with name %s using %s and validation_level: %d\n",
356 ninfo
.identity_info
.account_name
.string
, crypto_alg
,
357 r
.in
.validation_level
);
359 torture_assert_ntstatus_ok(tctx
,
360 dcerpc_netr_LogonSamLogonEx_r(b
, tctx
, &r
),
361 "LogonSamLogonEx failed");
363 torture_comment(tctx
,
364 "Skip auth_level[%u] Testing LogonSamLogonEx with name %s using %s and validation_level: %d\n",
365 auth_level
, ninfo
.identity_info
.account_name
.string
, crypto_alg
,
366 r
.in
.validation_level
);
367 r
.out
.result
= NT_STATUS_INVALID_INFO_CLASS
;
370 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_INVALID_INFO_CLASS
)) {
371 can_do_validation_6
= false;
373 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
374 "LogonSamLogonEx failed");
376 key
= r
.out
.validation
->sam6
->base
.key
;
377 LMSessKey
= r
.out
.validation
->sam6
->base
.LMSessKey
;
379 DEBUG(1,("unencrypted session keys from validation_level 6:\n"));
380 dump_data(1, r
.out
.validation
->sam6
->base
.key
.key
, 16);
381 dump_data(1, r
.out
.validation
->sam6
->base
.LMSessKey
.key
, 8);
384 for (i
=0; i
< ARRAY_SIZE(validation_levels
); i
++) {
386 r
.in
.validation_level
= validation_levels
[i
];
388 torture_comment(tctx
,
389 "Testing LogonSamLogonEx with name %s using %s and validation_level: %d\n",
390 ninfo
.identity_info
.account_name
.string
, crypto_alg
,
391 r
.in
.validation_level
);
393 torture_assert_ntstatus_ok(tctx
,
394 dcerpc_netr_LogonSamLogonEx_r(b
, tctx
, &r
),
395 "LogonSamLogonEx failed");
396 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
397 "LogonSamLogonEx failed");
400 /* when this test is called without creds no point in
401 * testing the session keys */
405 switch (validation_levels
[i
]) {
407 base
= &r
.out
.validation
->sam2
->base
;
410 base
= &r
.out
.validation
->sam3
->base
;
416 DEBUG(1,("encrypted keys validation_level %d:\n",
417 validation_levels
[i
]));
418 dump_data(1, base
->key
.key
, 16);
419 dump_data(1, base
->LMSessKey
.key
, 8);
421 status
= netlogon_creds_decrypt_samlogon_validation(creds
,
422 r
.in
.validation_level
,
426 torture_assert_ntstatus_ok(tctx
, status
, "decrypt_samlogon_validation");
428 DEBUG(1,("decrypted keys validation_level %d\n",
429 validation_levels
[i
]));
431 dump_data(1, base
->key
.key
, 16);
432 dump_data(1, base
->LMSessKey
.key
, 8);
434 if (!can_do_validation_6
) {
435 /* we can't compare against unencrypted keys */
439 torture_assert_mem_equal(tctx
,
443 "unexpected user session key\n");
444 torture_assert_mem_equal(tctx
,
448 "unexpected LM session key\n");
455 do some samr ops using the schannel connection
457 static bool test_samr_ops(struct torture_context
*tctx
,
458 struct dcerpc_binding_handle
*b
)
460 struct samr_GetDomPwInfo r
;
461 struct samr_PwInfo info
;
462 struct samr_Connect connect_r
;
463 struct samr_OpenDomain opendom
;
465 struct lsa_String name
;
466 struct policy_handle handle
;
467 struct policy_handle domain_handle
;
469 name
.string
= lpcfg_workgroup(tctx
->lp_ctx
);
470 r
.in
.domain_name
= &name
;
473 connect_r
.in
.system_name
= 0;
474 connect_r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
475 connect_r
.out
.connect_handle
= &handle
;
477 torture_comment(tctx
, "Testing Connect and OpenDomain on BUILTIN\n");
479 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_Connect_r(b
, tctx
, &connect_r
),
481 if (!NT_STATUS_IS_OK(connect_r
.out
.result
)) {
482 if (NT_STATUS_EQUAL(connect_r
.out
.result
, NT_STATUS_ACCESS_DENIED
)) {
483 torture_comment(tctx
, "Connect failed (expected, schannel mapped to anonymous): %s\n",
484 nt_errstr(connect_r
.out
.result
));
486 torture_comment(tctx
, "Connect failed - %s\n", nt_errstr(connect_r
.out
.result
));
490 opendom
.in
.connect_handle
= &handle
;
491 opendom
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
492 opendom
.in
.sid
= dom_sid_parse_talloc(tctx
, "S-1-5-32");
493 opendom
.out
.domain_handle
= &domain_handle
;
495 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OpenDomain_r(b
, tctx
, &opendom
),
496 "OpenDomain failed");
497 if (!NT_STATUS_IS_OK(opendom
.out
.result
)) {
498 torture_comment(tctx
, "OpenDomain failed - %s\n", nt_errstr(opendom
.out
.result
));
503 torture_comment(tctx
, "Testing GetDomPwInfo with name %s\n", r
.in
.domain_name
->string
);
505 /* do several ops to test credential chaining */
507 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetDomPwInfo_r(b
, tctx
, &r
),
508 "GetDomPwInfo failed");
509 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
510 if (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_ACCESS_DENIED
)) {
511 torture_comment(tctx
, "GetDomPwInfo op %d failed - %s\n", i
, nt_errstr(r
.out
.result
));
522 do some lsa ops using the schannel connection
524 static bool test_lsa_ops(struct torture_context
*tctx
, struct dcerpc_pipe
*p
)
526 struct lsa_GetUserName r
;
528 struct lsa_String
*account_name_p
= NULL
;
529 struct lsa_String
*authority_name_p
= NULL
;
530 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
532 torture_comment(tctx
, "\nTesting GetUserName\n");
534 r
.in
.system_name
= "\\";
535 r
.in
.account_name
= &account_name_p
;
536 r
.in
.authority_name
= &authority_name_p
;
537 r
.out
.account_name
= &account_name_p
;
539 /* do several ops to test credential chaining and various operations */
540 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_GetUserName_r(b
, tctx
, &r
),
541 "lsa_GetUserName failed");
543 authority_name_p
= *r
.out
.authority_name
;
545 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
546 torture_comment(tctx
, "GetUserName failed - %s\n", nt_errstr(r
.out
.result
));
549 if (!r
.out
.account_name
) {
553 if (strcmp(account_name_p
->string
, "ANONYMOUS LOGON") != 0) {
554 torture_comment(tctx
, "GetUserName returned wrong user: %s, expected %s\n",
555 account_name_p
->string
, "ANONYMOUS LOGON");
557 if (!torture_setting_bool(tctx
, "samba3", false)) {
561 if (!authority_name_p
|| !authority_name_p
->string
) {
565 if (strcmp(authority_name_p
->string
, "NT AUTHORITY") != 0) {
566 torture_comment(tctx
, "GetUserName returned wrong user: %s, expected %s\n",
567 authority_name_p
->string
, "NT AUTHORITY");
569 if (!torture_setting_bool(tctx
, "samba3", false)) {
580 test a schannel connection with the given flags
582 static bool test_schannel(struct torture_context
*tctx
,
583 uint16_t acct_flags
, uint32_t dcerpc_flags
,
586 struct test_join
*join_ctx
;
588 const char *binding
= torture_setting_string(tctx
, "binding", NULL
);
589 struct dcerpc_binding
*b
;
590 struct dcerpc_pipe
*p
= NULL
;
591 struct dcerpc_pipe
*p_netlogon
= NULL
;
592 struct dcerpc_pipe
*p_netlogon2
= NULL
;
593 struct dcerpc_pipe
*p_netlogon3
= NULL
;
594 struct dcerpc_pipe
*p_samr2
= NULL
;
595 struct dcerpc_pipe
*p_lsa
= NULL
;
596 struct netlogon_creds_CredentialState
*creds
;
597 struct cli_credentials
*credentials
;
598 enum dcerpc_transport_t transport
;
599 uint32_t requested_flags
;
601 join_ctx
= torture_join_domain(tctx
,
602 talloc_asprintf(tctx
, "%s%d", TEST_MACHINE_NAME
, i
),
603 acct_flags
, &credentials
);
604 torture_assert(tctx
, join_ctx
!= NULL
, "Failed to join domain");
606 status
= dcerpc_parse_binding(tctx
, binding
, &b
);
607 torture_assert_ntstatus_ok(tctx
, status
, "Bad binding string");
609 status
= dcerpc_binding_set_flags(b
, dcerpc_flags
, DCERPC_AUTH_OPTIONS
);
610 torture_assert_ntstatus_ok(tctx
, status
, "set flags");
612 status
= dcerpc_pipe_connect_b(tctx
, &p
, b
, &ndr_table_samr
,
613 credentials
, tctx
->ev
, tctx
->lp_ctx
);
614 torture_assert_ntstatus_ok(tctx
, status
,
615 "Failed to connect to samr with schannel");
617 torture_assert(tctx
, test_samr_ops(tctx
, p
->binding_handle
),
618 "Failed to process schannel secured SAMR ops");
620 /* Also test that when we connect to the netlogon pipe, that
621 * the credentials we setup on the first pipe are valid for
624 /* Swap the binding details from SAMR to NETLOGON */
625 status
= dcerpc_epm_map_binding(tctx
, b
, &ndr_table_netlogon
, tctx
->ev
, tctx
->lp_ctx
);
626 torture_assert_ntstatus_ok(tctx
, status
, "epm map");
628 status
= dcerpc_binding_set_flags(b
, dcerpc_flags
, DCERPC_AUTH_OPTIONS
);
629 torture_assert_ntstatus_ok(tctx
, status
, "set flags");
631 status
= dcerpc_secondary_auth_connection(p
, b
, &ndr_table_netlogon
,
632 credentials
, tctx
->lp_ctx
,
634 torture_assert_ntstatus_ok(tctx
, status
, "Failed to create secondary connection");
636 creds
= cli_credentials_get_netlogon_creds(credentials
);
637 torture_assert(tctx
, (creds
!= NULL
), "schannel creds");
639 requested_flags
= creds
->client_requested_flags
;
641 /* checks the capabilities */
643 test_netlogon_capabilities(p_netlogon
, tctx
, credentials
, requested_flags
, creds
),
644 "Failed to process schannel secured capability ops (on fresh connection)");
646 /* do a couple of logins */
647 torture_assert(tctx
, test_netlogon_ops(p_netlogon
, tctx
, credentials
, creds
),
648 "Failed to process schannel secured NETLOGON ops");
650 torture_assert(tctx
, test_netlogon_ex_ops(p_netlogon
, tctx
, credentials
, creds
),
651 "Failed to process schannel secured NETLOGON EX ops");
653 /* regression test for https://bugzilla.samba.org/show_bug.cgi?id=14932 */
654 torture_assert(tctx
, test_netlogon_ex_bug14932(p_netlogon
, tctx
, credentials
, creds
),
655 "Failed to process schannel secured NETLOGON EX for BUG 14932");
657 /* we *MUST* use ncacn_np for openpolicy etc. */
658 transport
= dcerpc_binding_get_transport(b
);
659 status
= dcerpc_binding_set_transport(b
, NCACN_NP
);
660 torture_assert_ntstatus_ok(tctx
, status
, "set transport");
662 /* Swap the binding details from SAMR to LSARPC */
663 status
= dcerpc_epm_map_binding(tctx
, b
, &ndr_table_lsarpc
, tctx
->ev
, tctx
->lp_ctx
);
664 torture_assert_ntstatus_ok(tctx
, status
, "epm map");
666 torture_assert_ntstatus_ok(tctx
,
667 dcerpc_pipe_connect_b(tctx
, &p_lsa
, b
, &ndr_table_lsarpc
,
668 credentials
, tctx
->ev
, tctx
->lp_ctx
),
669 "failed to connect lsarpc with schannel");
671 torture_assert(tctx
, test_lsa_ops(tctx
, p_lsa
),
672 "Failed to process schannel secured LSA ops");
677 /* we *MUST* use ncacn_ip_tcp for lookupsids3/lookupnames4 */
678 status
= dcerpc_binding_set_transport(b
, NCACN_IP_TCP
);
679 torture_assert_ntstatus_ok(tctx
, status
, "set transport");
681 torture_assert_ntstatus_ok(tctx
,
682 dcerpc_epm_map_binding(tctx
, b
, &ndr_table_lsarpc
, tctx
->ev
, tctx
->lp_ctx
),
683 "failed to call epm map");
685 torture_assert_ntstatus_ok(tctx
,
686 dcerpc_pipe_connect_b(tctx
, &p_lsa
, b
, &ndr_table_lsarpc
,
687 credentials
, tctx
->ev
, tctx
->lp_ctx
),
688 "failed to connect lsarpc with schannel");
691 test_many_LookupSids(p_lsa
, tctx
, NULL
, LSA_LOOKUP_NAMES_ALL
),
692 "LsaLookupSids3 failed!\n");
694 status
= dcerpc_binding_set_transport(b
, transport
);
695 torture_assert_ntstatus_ok(tctx
, status
, "set transport");
698 /* Drop the socket, we want to start from scratch */
702 /* Now see what we are still allowed to do */
704 status
= dcerpc_parse_binding(tctx
, binding
, &b
);
705 torture_assert_ntstatus_ok(tctx
, status
, "Bad binding string");
707 status
= dcerpc_binding_set_flags(b
, dcerpc_flags
, DCERPC_AUTH_OPTIONS
);
708 torture_assert_ntstatus_ok(tctx
, status
, "set flags");
710 status
= dcerpc_pipe_connect_b(tctx
, &p_samr2
, b
, &ndr_table_samr
,
711 credentials
, tctx
->ev
, tctx
->lp_ctx
);
712 torture_assert_ntstatus_ok(tctx
, status
,
713 "Failed to connect with schannel");
715 /* do a some SAMR operations. We have *not* done a new serverauthenticate */
716 torture_assert (tctx
, test_samr_ops(tctx
, p_samr2
->binding_handle
),
717 "Failed to process schannel secured SAMR ops (on fresh connection)");
719 /* Swap the binding details from SAMR to NETLOGON */
720 status
= dcerpc_epm_map_binding(tctx
, b
, &ndr_table_netlogon
, tctx
->ev
, tctx
->lp_ctx
);
721 torture_assert_ntstatus_ok(tctx
, status
, "epm");
723 status
= dcerpc_binding_set_flags(b
, dcerpc_flags
, DCERPC_AUTH_OPTIONS
);
724 torture_assert_ntstatus_ok(tctx
, status
, "set flags");
726 status
= dcerpc_secondary_auth_connection(p_samr2
, b
, &ndr_table_netlogon
,
727 credentials
, tctx
->lp_ctx
,
729 torture_assert_ntstatus_ok(tctx
, status
, "Failed to create secondary connection");
731 requested_flags
= creds
->client_requested_flags
;
733 /* checks the capabilities */
735 test_netlogon_capabilities(p_netlogon2
, tctx
, credentials
, requested_flags
, creds
),
736 "Failed to process schannel secured capability ops (on fresh connection)");
738 /* Try the schannel-only SamLogonEx operation */
739 torture_assert(tctx
, test_netlogon_ex_ops(p_netlogon2
, tctx
, credentials
, creds
),
740 "Failed to process schannel secured NETLOGON EX ops (on fresh connection)");
743 /* And the more traditional style, proving that the
744 * credentials chaining state is fully present */
745 torture_assert(tctx
, test_netlogon_ops(p_netlogon2
, tctx
, credentials
, creds
),
746 "Failed to process schannel secured NETLOGON ops (on fresh connection)");
748 /* Drop the socket, we want to start from scratch (again) */
749 talloc_free(p_samr2
);
751 /* We don't want schannel for this test */
752 status
= dcerpc_binding_set_flags(b
, 0, DCERPC_AUTH_OPTIONS
);
753 torture_assert_ntstatus_ok(tctx
, status
, "set flags");
755 status
= dcerpc_pipe_connect_b(tctx
, &p_netlogon3
, b
, &ndr_table_netlogon
,
756 credentials
, tctx
->ev
, tctx
->lp_ctx
);
757 torture_assert_ntstatus_ok(tctx
, status
, "Failed to connect without schannel");
759 torture_assert(tctx
, !test_netlogon_ex_ops(p_netlogon3
, tctx
, credentials
, creds
),
760 "Processed NOT schannel secured NETLOGON EX ops without SCHANNEL (unsafe)");
762 /* Required because the previous call will mark the current context as having failed */
763 tctx
->last_result
= TORTURE_OK
;
764 tctx
->last_reason
= NULL
;
766 torture_assert(tctx
, test_netlogon_ops(p_netlogon3
, tctx
, credentials
, creds
),
767 "Failed to processed NOT schannel secured NETLOGON ops without new ServerAuth");
769 torture_leave_domain(tctx
, join_ctx
);
774 * Purpose of this test is to demonstrate that a netlogon server carefully deals
775 * with anonymous attempts to set passwords, in particular when the server
776 * enforces the use of schannel. This test makes most sense to be run in an
777 * environment where the netlogon server enforces use of schannel.
780 static bool test_schannel_anonymous_setPassword(struct torture_context
*tctx
,
781 uint32_t dcerpc_flags
,
784 NTSTATUS status
, result
;
785 const char *binding
= torture_setting_string(tctx
, "binding", NULL
);
786 struct dcerpc_binding
*b
;
787 struct dcerpc_pipe
*p
= NULL
;
788 struct cli_credentials
*credentials
;
791 credentials
= cli_credentials_init(NULL
);
792 torture_assert(tctx
, credentials
!= NULL
, "Bad credentials");
793 cli_credentials_set_anonymous(credentials
);
795 status
= dcerpc_parse_binding(tctx
, binding
, &b
);
796 torture_assert_ntstatus_ok(tctx
, status
, "Bad binding string");
798 status
= dcerpc_binding_set_flags(b
, dcerpc_flags
, DCERPC_AUTH_OPTIONS
);
799 torture_assert_ntstatus_ok(tctx
, status
, "set flags");
801 status
= dcerpc_pipe_connect_b(tctx
,
808 torture_assert_ntstatus_ok(tctx
, status
, "Failed to connect without schannel");
811 struct netr_ServerPasswordSet2 r
= {};
812 struct netr_Authenticator credential
= {};
813 struct netr_Authenticator return_authenticator
= {};
814 struct netr_CryptPassword new_password
= {};
816 r
.in
.server_name
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
817 r
.in
.account_name
= talloc_asprintf(tctx
, "%s$", TEST_MACHINE_NAME
);
818 r
.in
.secure_channel_type
= 0;
819 r
.in
.computer_name
= TEST_MACHINE_NAME
;
820 r
.in
.credential
= &credential
;
821 r
.in
.new_password
= &new_password
;
822 r
.out
.return_authenticator
= &return_authenticator
;
824 status
= dcerpc_netr_ServerPasswordSet2_r(p
->binding_handle
, tctx
, &r
);
825 result
= r
.out
.result
;
827 struct netr_ServerPasswordSet r
= {};
828 struct netr_Authenticator credential
= {};
829 struct netr_Authenticator return_authenticator
= {};
830 struct samr_Password new_password
= {};
832 r
.in
.server_name
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
833 r
.in
.account_name
= talloc_asprintf(tctx
, "%s$", TEST_MACHINE_NAME
);
834 r
.in
.secure_channel_type
= 0;
835 r
.in
.computer_name
= TEST_MACHINE_NAME
;
836 r
.in
.credential
= &credential
;
837 r
.in
.new_password
= &new_password
;
838 r
.out
.return_authenticator
= &return_authenticator
;
840 status
= dcerpc_netr_ServerPasswordSet_r(p
->binding_handle
, tctx
, &r
);
841 result
= r
.out
.result
;
844 torture_assert_ntstatus_ok(tctx
, status
, "ServerPasswordSet failed");
846 if (NT_STATUS_IS_OK(result
)) {
847 torture_fail(tctx
, "unexpectedly received NT_STATUS_OK");
855 a schannel test suite
857 bool torture_rpc_schannel(struct torture_context
*torture
)
862 uint32_t dcerpc_flags
;
864 { ACB_WSTRUST
, DCERPC_SCHANNEL
| DCERPC_SIGN
| DCERPC_SCHANNEL_AUTO
},
865 { ACB_WSTRUST
, DCERPC_SCHANNEL
| DCERPC_SEAL
| DCERPC_SCHANNEL_AUTO
},
866 { ACB_WSTRUST
, DCERPC_SCHANNEL
| DCERPC_SIGN
| DCERPC_SCHANNEL_128
},
867 { ACB_WSTRUST
, DCERPC_SCHANNEL
| DCERPC_SEAL
| DCERPC_SCHANNEL_128
},
868 { ACB_WSTRUST
, DCERPC_SCHANNEL
| DCERPC_SIGN
| DCERPC_SCHANNEL_AES
},
869 { ACB_WSTRUST
, DCERPC_SCHANNEL
| DCERPC_SEAL
| DCERPC_SCHANNEL_AES
},
870 { ACB_SVRTRUST
, DCERPC_SCHANNEL
| DCERPC_SIGN
| DCERPC_SCHANNEL_AUTO
},
871 { ACB_SVRTRUST
, DCERPC_SCHANNEL
| DCERPC_SEAL
| DCERPC_SCHANNEL_AUTO
},
872 { ACB_SVRTRUST
, DCERPC_SCHANNEL
| DCERPC_SIGN
| DCERPC_SCHANNEL_128
},
873 { ACB_SVRTRUST
, DCERPC_SCHANNEL
| DCERPC_SEAL
| DCERPC_SCHANNEL_128
},
874 { ACB_SVRTRUST
, DCERPC_SCHANNEL
| DCERPC_SIGN
| DCERPC_SCHANNEL_AES
},
875 { ACB_SVRTRUST
, DCERPC_SCHANNEL
| DCERPC_SEAL
| DCERPC_SCHANNEL_AES
}
879 for (i
=0;i
<ARRAY_SIZE(tests
);i
++) {
880 torture_comment(torture
, "Testing with acct_flags=0x%x dcerpc_flags=0x%x \n",
881 tests
[i
].acct_flags
, tests
[i
].dcerpc_flags
);
883 if (!test_schannel(torture
,
884 tests
[i
].acct_flags
, tests
[i
].dcerpc_flags
,
886 torture_comment(torture
, "Failed with acct_flags=0x%x dcerpc_flags=0x%x \n",
887 tests
[i
].acct_flags
, tests
[i
].dcerpc_flags
);
895 bool torture_rpc_schannel_anon_setpw(struct torture_context
*torture
)
899 uint32_t dcerpc_flags
= DCERPC_SCHANNEL
| DCERPC_SIGN
| DCERPC_SCHANNEL_AUTO
;
901 ok
= test_schannel_anonymous_setPassword(torture
,
905 torture_comment(torture
,
906 "Failed with dcerpc_flags=0x%x\n",
911 ok
= test_schannel_anonymous_setPassword(torture
,
915 torture_comment(torture
,
916 "Failed with dcerpc_flags=0x%x\n",
925 test two schannel connections
927 bool torture_rpc_schannel2(struct torture_context
*torture
)
929 struct test_join
*join_ctx
;
931 const char *binding
= torture_setting_string(torture
, "binding", NULL
);
932 struct dcerpc_binding
*b
;
933 struct dcerpc_pipe
*p1
= NULL
, *p2
= NULL
;
934 struct cli_credentials
*credentials1
, *credentials2
;
935 uint32_t dcerpc_flags
= DCERPC_SCHANNEL
| DCERPC_SCHANNEL_AUTO
| DCERPC_SIGN
;
937 join_ctx
= torture_join_domain(torture
, talloc_asprintf(torture
, "%s2", TEST_MACHINE_NAME
),
938 ACB_WSTRUST
, &credentials1
);
939 torture_assert(torture
, join_ctx
!= NULL
,
940 "Failed to join domain with acct_flags=ACB_WSTRUST");
942 credentials2
= cli_credentials_shallow_copy(torture
, credentials1
);
943 cli_credentials_set_netlogon_creds(credentials1
, NULL
);
944 cli_credentials_set_netlogon_creds(credentials2
, NULL
);
946 status
= dcerpc_parse_binding(torture
, binding
, &b
);
947 torture_assert_ntstatus_ok(torture
, status
, "Bad binding string");
949 status
= dcerpc_binding_set_flags(b
, dcerpc_flags
, DCERPC_AUTH_OPTIONS
);
950 torture_assert_ntstatus_ok(torture
, status
, "set flags");
952 torture_comment(torture
, "Opening first connection\n");
953 status
= dcerpc_pipe_connect_b(torture
, &p1
, b
, &ndr_table_netlogon
,
954 credentials1
, torture
->ev
, torture
->lp_ctx
);
955 torture_assert_ntstatus_ok(torture
, status
, "Failed to connect with schannel");
957 torture_comment(torture
, "Opening second connection\n");
958 status
= dcerpc_pipe_connect_b(torture
, &p2
, b
, &ndr_table_netlogon
,
959 credentials2
, torture
->ev
, torture
->lp_ctx
);
960 torture_assert_ntstatus_ok(torture
, status
, "Failed to connect with schannel");
962 cli_credentials_set_netlogon_creds(credentials1
, NULL
);
963 cli_credentials_set_netlogon_creds(credentials2
, NULL
);
965 torture_comment(torture
, "Testing logon on pipe1\n");
966 if (!test_netlogon_ex_ops(p1
, torture
, credentials1
, NULL
))
969 torture_comment(torture
, "Testing logon on pipe2\n");
970 if (!test_netlogon_ex_ops(p2
, torture
, credentials2
, NULL
))
973 torture_comment(torture
, "Again on pipe1\n");
974 if (!test_netlogon_ex_ops(p1
, torture
, credentials1
, NULL
))
977 torture_comment(torture
, "Again on pipe2\n");
978 if (!test_netlogon_ex_ops(p2
, torture
, credentials2
, NULL
))
981 torture_leave_domain(torture
, join_ctx
);
985 struct torture_schannel_bench
;
987 struct torture_schannel_bench_conn
{
988 struct torture_schannel_bench
*s
;
990 struct cli_credentials
*wks_creds
;
991 struct dcerpc_pipe
*pipe
;
992 struct netr_LogonSamLogonEx r
;
993 struct netr_NetworkInfo ninfo
;
999 struct torture_schannel_bench
{
1000 struct torture_context
*tctx
;
1005 struct torture_schannel_bench_conn
*conns
;
1006 struct test_join
*join_ctx1
;
1007 struct cli_credentials
*wks_creds1
;
1008 struct test_join
*join_ctx2
;
1009 struct cli_credentials
*wks_creds2
;
1010 struct cli_credentials
*user1_creds
;
1011 struct cli_credentials
*user2_creds
;
1012 struct dcerpc_binding
*b
;
1020 static void torture_schannel_bench_connected(struct composite_context
*c
)
1022 struct torture_schannel_bench_conn
*conn
=
1023 (struct torture_schannel_bench_conn
*)c
->async
.private_data
;
1024 struct torture_schannel_bench
*s
= talloc_get_type(conn
->s
,
1025 struct torture_schannel_bench
);
1027 s
->error
= dcerpc_pipe_connect_b_recv(c
, s
->conns
, &conn
->pipe
);
1028 torture_comment(s
->tctx
, "conn[%u]: %s\n", conn
->index
, nt_errstr(s
->error
));
1029 if (NT_STATUS_IS_OK(s
->error
)) {
1035 static void torture_schannel_bench_recv(struct tevent_req
*subreq
);
1037 static bool torture_schannel_bench_start(struct torture_schannel_bench_conn
*conn
)
1039 struct torture_schannel_bench
*s
= conn
->s
;
1041 DATA_BLOB names_blob
, chal
, lm_resp
, nt_resp
;
1042 int flags
= CLI_CRED_NTLM_AUTH
;
1043 struct tevent_req
*subreq
;
1044 struct cli_credentials
*user_creds
;
1046 if (conn
->total
% 2) {
1047 user_creds
= s
->user1_creds
;
1049 user_creds
= s
->user2_creds
;
1052 if (lpcfg_client_lanman_auth(s
->tctx
->lp_ctx
)) {
1053 flags
|= CLI_CRED_LANMAN_AUTH
;
1056 if (lpcfg_client_ntlmv2_auth(s
->tctx
->lp_ctx
)) {
1057 flags
|= CLI_CRED_NTLMv2_AUTH
;
1060 talloc_free(conn
->tmp
);
1061 conn
->tmp
= talloc_new(s
);
1062 ZERO_STRUCT(conn
->ninfo
);
1063 ZERO_STRUCT(conn
->r
);
1065 cli_credentials_get_ntlm_username_domain(user_creds
, conn
->tmp
,
1066 &conn
->ninfo
.identity_info
.account_name
.string
,
1067 &conn
->ninfo
.identity_info
.domain_name
.string
);
1069 generate_random_buffer(conn
->ninfo
.challenge
,
1070 sizeof(conn
->ninfo
.challenge
));
1071 chal
= data_blob_const(conn
->ninfo
.challenge
,
1072 sizeof(conn
->ninfo
.challenge
));
1074 names_blob
= NTLMv2_generate_names_blob(conn
->tmp
,
1075 cli_credentials_get_workstation(conn
->wks_creds
),
1076 cli_credentials_get_domain(conn
->wks_creds
));
1078 status
= cli_credentials_get_ntlm_response(user_creds
, conn
->tmp
,
1081 NULL
, /* server_timestamp */
1085 torture_assert_ntstatus_ok(s
->tctx
, status
,
1086 "cli_credentials_get_ntlm_response failed");
1088 conn
->ninfo
.lm
.data
= lm_resp
.data
;
1089 conn
->ninfo
.lm
.length
= lm_resp
.length
;
1091 conn
->ninfo
.nt
.data
= nt_resp
.data
;
1092 conn
->ninfo
.nt
.length
= nt_resp
.length
;
1094 conn
->ninfo
.identity_info
.parameter_control
= 0;
1095 conn
->ninfo
.identity_info
.logon_id
= 0;
1096 conn
->ninfo
.identity_info
.workstation
.string
= cli_credentials_get_workstation(conn
->wks_creds
);
1098 conn
->r
.in
.server_name
= talloc_asprintf(conn
->tmp
, "\\\\%s", dcerpc_server_name(conn
->pipe
));
1099 conn
->r
.in
.computer_name
= cli_credentials_get_workstation(conn
->wks_creds
);
1100 conn
->r
.in
.logon_level
= NetlogonNetworkInformation
;
1101 conn
->r
.in
.logon
= talloc(conn
->tmp
, union netr_LogonLevel
);
1102 conn
->r
.in
.logon
->network
= &conn
->ninfo
;
1103 conn
->r
.in
.flags
= talloc(conn
->tmp
, uint32_t);
1104 conn
->r
.in
.validation_level
= 2;
1105 conn
->r
.out
.validation
= talloc(conn
->tmp
, union netr_Validation
);
1106 conn
->r
.out
.authoritative
= talloc(conn
->tmp
, uint8_t);
1107 conn
->r
.out
.flags
= conn
->r
.in
.flags
;
1109 subreq
= dcerpc_netr_LogonSamLogonEx_r_send(s
, s
->tctx
->ev
,
1110 conn
->pipe
->binding_handle
,
1112 torture_assert(s
->tctx
, subreq
, "Failed to setup LogonSamLogonEx request");
1114 tevent_req_set_callback(subreq
, torture_schannel_bench_recv
, conn
);
1119 static void torture_schannel_bench_recv(struct tevent_req
*subreq
)
1122 struct torture_schannel_bench_conn
*conn
=
1123 (struct torture_schannel_bench_conn
*)tevent_req_callback_data_void(subreq
);
1124 struct torture_schannel_bench
*s
= talloc_get_type(conn
->s
,
1125 struct torture_schannel_bench
);
1127 s
->error
= dcerpc_netr_LogonSamLogonEx_r_recv(subreq
, subreq
);
1128 TALLOC_FREE(subreq
);
1129 if (!NT_STATUS_IS_OK(s
->error
)) {
1140 ret
= torture_schannel_bench_start(conn
);
1142 s
->error
= NT_STATUS_INTERNAL_ERROR
;
1147 test multiple schannel connection in parallel
1149 bool torture_rpc_schannel_bench1(struct torture_context
*torture
)
1153 const char *binding
= torture_setting_string(torture
, "binding", NULL
);
1154 struct torture_schannel_bench
*s
;
1155 struct timeval start
;
1160 s
= talloc_zero(torture
, struct torture_schannel_bench
);
1162 s
->progress
= torture_setting_bool(torture
, "progress", true);
1163 s
->timelimit
= torture_setting_int(torture
, "timelimit", 10);
1164 s
->nprocs
= torture_setting_int(torture
, "nprocs", 4);
1165 s
->conns
= talloc_zero_array(s
, struct torture_schannel_bench_conn
, s
->nprocs
);
1167 s
->user1_creds
= cli_credentials_shallow_copy(s
,
1168 samba_cmdline_get_creds());
1169 tmp
= torture_setting_string(s
->tctx
, "extra_user1", NULL
);
1171 cli_credentials_parse_string(s
->user1_creds
, tmp
, CRED_SPECIFIED
);
1173 s
->user2_creds
= cli_credentials_shallow_copy(s
,
1174 samba_cmdline_get_creds());
1175 tmp
= torture_setting_string(s
->tctx
, "extra_user2", NULL
);
1177 cli_credentials_parse_string(s
->user1_creds
, tmp
, CRED_SPECIFIED
);
1180 s
->join_ctx1
= torture_join_domain(s
->tctx
, talloc_asprintf(s
, "%sb", TEST_MACHINE_NAME
),
1181 ACB_WSTRUST
, &s
->wks_creds1
);
1182 torture_assert(torture
, s
->join_ctx1
!= NULL
,
1183 "Failed to join domain with acct_flags=ACB_WSTRUST");
1184 s
->join_ctx2
= torture_join_domain(s
->tctx
, talloc_asprintf(s
, "%sc", TEST_MACHINE_NAME
),
1185 ACB_WSTRUST
, &s
->wks_creds2
);
1186 torture_assert(torture
, s
->join_ctx2
!= NULL
,
1187 "Failed to join domain with acct_flags=ACB_WSTRUST");
1189 cli_credentials_set_kerberos_state(s
->wks_creds1
,
1190 CRED_USE_KERBEROS_DISABLED
,
1192 cli_credentials_set_kerberos_state(s
->wks_creds2
,
1193 CRED_USE_KERBEROS_DISABLED
,
1196 for (i
=0; i
< s
->nprocs
; i
++) {
1197 struct cli_credentials
*wks
= s
->wks_creds1
;
1199 if ((i
% 2) && (torture_setting_bool(torture
, "multijoin", false))) {
1200 wks
= s
->wks_creds2
;
1204 s
->conns
[i
].index
= i
;
1205 s
->conns
[i
].wks_creds
= cli_credentials_shallow_copy(s
->conns
, wks
);
1206 cli_credentials_set_netlogon_creds(s
->conns
[i
].wks_creds
, NULL
);
1209 status
= dcerpc_parse_binding(s
, binding
, &s
->b
);
1210 torture_assert_ntstatus_ok(torture
, status
, "Bad binding string");
1212 status
= dcerpc_binding_set_flags(s
->b
, DCERPC_SCHANNEL
| DCERPC_SIGN
,
1213 DCERPC_AUTH_OPTIONS
);
1214 torture_assert_ntstatus_ok(torture
, status
, "set flags");
1216 torture_comment(torture
, "Opening %d connections in parallel\n", s
->nprocs
);
1217 for (i
=0; i
< s
->nprocs
; i
++) {
1219 s
->error
= dcerpc_pipe_connect_b(s
->conns
, &s
->conns
[i
].pipe
, s
->b
,
1220 &ndr_table_netlogon
,
1221 s
->conns
[i
].wks_creds
,
1222 torture
->ev
, torture
->lp_ctx
);
1223 torture_assert_ntstatus_ok(torture
, s
->error
, "Failed to connect with schannel");
1226 * This path doesn't work against windows,
1227 * because of windows drops the connections
1228 * which haven't reached a session setup yet
1230 * The same as the reset on zero vc stuff.
1232 struct composite_context
*c
;
1233 c
= dcerpc_pipe_connect_b_send(s
->conns
, s
->b
,
1234 &ndr_table_netlogon
,
1235 s
->conns
[i
].wks_creds
,
1238 torture_assert(torture
, c
!= NULL
, "Failed to setup connect");
1239 c
->async
.fn
= torture_schannel_bench_connected
;
1240 c
->async
.private_data
= &s
->conns
[i
];
1243 while (NT_STATUS_IS_OK(s
->error
) && s
->nprocs
!= s
->nconns
) {
1244 int ev_ret
= tevent_loop_once(torture
->ev
);
1245 torture_assert(torture
, ev_ret
== 0, "tevent_loop_once failed");
1248 torture_assert_ntstatus_ok(torture
, s
->error
, "Failed establish a connect");
1251 * Change the workstation password after establishing the netlogon
1252 * schannel connections to prove that existing connections are not
1253 * affected by a wks pwchange.
1257 struct netr_ServerPasswordSet pwset
;
1258 char *password
= generate_random_password(s
->join_ctx1
, 8, 255);
1259 struct netlogon_creds_CredentialState
*creds_state
;
1260 struct dcerpc_pipe
*net_pipe
;
1261 struct netr_Authenticator credential
, return_authenticator
;
1262 struct samr_Password new_password
;
1263 enum dcerpc_AuthType auth_type
;
1264 enum dcerpc_AuthLevel auth_level
;
1266 status
= dcerpc_pipe_connect_b(s
, &net_pipe
, s
->b
,
1267 &ndr_table_netlogon
,
1269 torture
->ev
, torture
->lp_ctx
);
1271 torture_assert_ntstatus_ok(torture
, status
,
1272 "dcerpc_pipe_connect_b failed");
1274 pwset
.in
.server_name
= talloc_asprintf(
1275 net_pipe
, "\\\\%s", dcerpc_server_name(net_pipe
));
1276 pwset
.in
.computer_name
=
1277 cli_credentials_get_workstation(s
->wks_creds1
);
1278 pwset
.in
.account_name
= talloc_asprintf(
1279 net_pipe
, "%s$", pwset
.in
.computer_name
);
1280 pwset
.in
.secure_channel_type
= SEC_CHAN_WKSTA
;
1281 pwset
.in
.credential
= &credential
;
1282 pwset
.in
.new_password
= &new_password
;
1283 pwset
.out
.return_authenticator
= &return_authenticator
;
1285 E_md4hash(password
, new_password
.hash
);
1287 creds_state
= cli_credentials_get_netlogon_creds(
1289 dcerpc_binding_handle_auth_info(net_pipe
->binding_handle
,
1292 status
= netlogon_creds_encrypt_samr_Password(creds_state
,
1296 torture_assert_ntstatus_ok(torture
, status
, "encrypt_samr_Password");
1297 netlogon_creds_client_authenticator(creds_state
, &credential
);
1299 torture_assert_ntstatus_ok(torture
, dcerpc_netr_ServerPasswordSet_r(net_pipe
->binding_handle
, torture
, &pwset
),
1300 "ServerPasswordSet failed");
1301 torture_assert_ntstatus_ok(torture
, pwset
.out
.result
,
1302 "ServerPasswordSet failed");
1304 if (!netlogon_creds_client_check(creds_state
,
1305 &pwset
.out
.return_authenticator
->cred
)) {
1306 torture_comment(torture
, "Credential chaining failed\n");
1309 cli_credentials_set_password(s
->wks_creds1
, password
,
1312 talloc_free(net_pipe
);
1314 /* Just as a test, connect with the new creds */
1316 cli_credentials_set_netlogon_creds(s
->wks_creds1
, NULL
);
1318 status
= dcerpc_pipe_connect_b(s
, &net_pipe
, s
->b
,
1319 &ndr_table_netlogon
,
1321 torture
->ev
, torture
->lp_ctx
);
1323 torture_assert_ntstatus_ok(torture
, status
,
1324 "dcerpc_pipe_connect_b failed");
1326 talloc_free(net_pipe
);
1329 torture_comment(torture
, "Start looping LogonSamLogonEx on %d connections for %d secs\n",
1330 s
->nprocs
, s
->timelimit
);
1331 for (i
=0; i
< s
->nprocs
; i
++) {
1332 ret
= torture_schannel_bench_start(&s
->conns
[i
]);
1333 torture_assert(torture
, ret
, "Failed to setup LogonSamLogonEx");
1336 start
= timeval_current();
1337 end
= timeval_add(&start
, s
->timelimit
, 0);
1339 while (NT_STATUS_IS_OK(s
->error
) && !timeval_expired(&end
)) {
1340 int ev_ret
= tevent_loop_once(torture
->ev
);
1341 torture_assert(torture
, ev_ret
== 0, "tevent_loop_once failed");
1343 torture_assert_ntstatus_ok(torture
, s
->error
, "Failed some request");
1345 talloc_free(s
->conns
);
1347 for (i
=0; i
< s
->nprocs
; i
++) {
1348 s
->total
+= s
->conns
[i
].total
;
1351 torture_comment(torture
,
1352 "Total ops[%llu] (%u ops/s)\n",
1353 (unsigned long long)s
->total
,
1354 (unsigned)s
->total
/s
->timelimit
);
1356 torture_leave_domain(torture
, s
->join_ctx1
);
1357 torture_leave_domain(torture
, s
->join_ctx2
);