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
,
525 struct cli_credentials
*credentials
)
527 struct lsa_GetUserName r
;
529 struct lsa_String
*account_name_p
= NULL
;
530 struct lsa_String
*authority_name_p
= NULL
;
531 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
532 enum dcerpc_AuthType auth_type
= DCERPC_AUTH_TYPE_NONE
;
533 enum dcerpc_AuthLevel auth_level
= DCERPC_AUTH_LEVEL_NONE
;
534 const char *expected_account_name
= "ANONYMOUS LOGON";
535 const char *expected_authority_name
= "NT AUTHORITY";
537 torture_comment(tctx
, "\nTesting GetUserName\n");
539 dcerpc_binding_handle_auth_info(b
, &auth_type
, &auth_level
);
541 if (auth_type
!= DCERPC_AUTH_TYPE_SCHANNEL
) {
542 expected_account_name
= cli_credentials_get_username(credentials
);
543 expected_authority_name
= cli_credentials_get_domain(credentials
);
546 r
.in
.system_name
= "\\";
547 r
.in
.account_name
= &account_name_p
;
548 r
.in
.authority_name
= &authority_name_p
;
549 r
.out
.account_name
= &account_name_p
;
551 /* do several ops to test credential chaining and various operations */
552 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_GetUserName_r(b
, tctx
, &r
),
553 "lsa_GetUserName failed");
555 authority_name_p
= *r
.out
.authority_name
;
557 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
558 torture_comment(tctx
, "GetUserName failed - %s\n", nt_errstr(r
.out
.result
));
561 if (!r
.out
.account_name
) {
565 if (!strequal(account_name_p
->string
, expected_account_name
)) {
566 torture_comment(tctx
, "GetUserName returned wrong user: %s, expected %s\n",
567 account_name_p
->string
, expected_account_name
);
569 if (!torture_setting_bool(tctx
, "samba3", false)) {
573 if (!authority_name_p
|| !authority_name_p
->string
) {
577 if (!strequal(authority_name_p
->string
, expected_authority_name
)) {
578 torture_comment(tctx
, "GetUserName returned wrong user: %s, expected %s\n",
579 authority_name_p
->string
, expected_authority_name
);
581 if (!torture_setting_bool(tctx
, "samba3", false)) {
592 test a schannel connection with the given flags
594 static bool test_schannel(struct torture_context
*tctx
,
595 uint16_t acct_flags
, uint32_t dcerpc_flags
,
598 struct test_join
*join_ctx
;
600 const char *binding
= torture_setting_string(tctx
, "binding", NULL
);
601 struct dcerpc_binding
*b
;
602 struct dcerpc_pipe
*p
= NULL
;
603 struct dcerpc_pipe
*p_netlogon
= NULL
;
604 struct dcerpc_pipe
*p_netlogon2
= NULL
;
605 struct dcerpc_pipe
*p_netlogon3
= NULL
;
606 struct dcerpc_pipe
*p_samr2
= NULL
;
607 struct dcerpc_pipe
*p_lsa
= NULL
;
608 struct netlogon_creds_CredentialState
*creds
;
609 struct cli_credentials
*credentials
;
610 enum dcerpc_transport_t transport
;
611 uint32_t requested_flags
;
613 join_ctx
= torture_join_domain(tctx
,
614 talloc_asprintf(tctx
, "%s%d", TEST_MACHINE_NAME
, i
),
615 acct_flags
, &credentials
);
616 torture_assert(tctx
, join_ctx
!= NULL
, "Failed to join domain");
618 status
= dcerpc_parse_binding(tctx
, binding
, &b
);
619 torture_assert_ntstatus_ok(tctx
, status
, "Bad binding string");
621 status
= dcerpc_binding_set_flags(b
, dcerpc_flags
, DCERPC_AUTH_OPTIONS
);
622 torture_assert_ntstatus_ok(tctx
, status
, "set flags");
624 transport
= dcerpc_binding_get_transport(b
);
626 if (transport
== NCALRPC
&&
627 dcerpc_flags
& DCERPC_SCHANNEL_KRB5
)
629 torture_skip(tctx
, "Skip DCERPC_SCHANNEL_KRB5 for ncalrpc");
631 if (cli_credentials_get_realm(credentials
) == NULL
&&
632 dcerpc_flags
& DCERPC_SCHANNEL_KRB5
)
634 torture_skip(tctx
, "Skip DCERPC_SCHANNEL_KRB5 for NT4 Domain");
637 status
= dcerpc_pipe_connect_b(tctx
, &p
, b
, &ndr_table_samr
,
638 credentials
, tctx
->ev
, tctx
->lp_ctx
);
639 torture_assert_ntstatus_ok(tctx
, status
,
640 "Failed to connect to samr with schannel");
642 torture_assert(tctx
, test_samr_ops(tctx
, p
->binding_handle
),
643 "Failed to process schannel secured SAMR ops");
645 /* Also test that when we connect to the netlogon pipe, that
646 * the credentials we setup on the first pipe are valid for
649 /* Swap the binding details from SAMR to NETLOGON */
650 status
= dcerpc_epm_map_binding(tctx
, b
, &ndr_table_netlogon
, tctx
->ev
, tctx
->lp_ctx
);
651 torture_assert_ntstatus_ok(tctx
, status
, "epm map");
653 status
= dcerpc_binding_set_flags(b
, dcerpc_flags
, DCERPC_AUTH_OPTIONS
);
654 torture_assert_ntstatus_ok(tctx
, status
, "set flags");
656 status
= dcerpc_secondary_auth_connection(p
, b
, &ndr_table_netlogon
,
657 credentials
, tctx
->lp_ctx
,
659 torture_assert_ntstatus_ok(tctx
, status
, "Failed to create secondary connection");
661 creds
= cli_credentials_get_netlogon_creds(credentials
);
662 torture_assert(tctx
, (creds
!= NULL
), "schannel creds");
664 requested_flags
= creds
->client_requested_flags
;
666 /* checks the capabilities */
668 test_netlogon_capabilities(p_netlogon
, tctx
, credentials
, requested_flags
, creds
),
669 "Failed to process schannel secured capability ops (on fresh connection)");
671 /* do a couple of logins */
672 torture_assert(tctx
, test_netlogon_ops(p_netlogon
, tctx
, credentials
, creds
),
673 "Failed to process schannel secured NETLOGON ops");
675 torture_assert(tctx
, test_netlogon_ex_ops(p_netlogon
, tctx
, credentials
, creds
),
676 "Failed to process schannel secured NETLOGON EX ops");
678 /* regression test for https://bugzilla.samba.org/show_bug.cgi?id=14932 */
679 torture_assert(tctx
, test_netlogon_ex_bug14932(p_netlogon
, tctx
, credentials
, creds
),
680 "Failed to process schannel secured NETLOGON EX for BUG 14932");
682 /* we *MUST* use ncacn_np for openpolicy etc. */
683 status
= dcerpc_binding_set_transport(b
, NCACN_NP
);
684 torture_assert_ntstatus_ok(tctx
, status
, "set transport");
686 /* Swap the binding details from SAMR to LSARPC */
687 status
= dcerpc_epm_map_binding(tctx
, b
, &ndr_table_lsarpc
, tctx
->ev
, tctx
->lp_ctx
);
688 torture_assert_ntstatus_ok(tctx
, status
, "epm map");
690 torture_assert_ntstatus_ok(tctx
,
691 dcerpc_pipe_connect_b(tctx
, &p_lsa
, b
, &ndr_table_lsarpc
,
692 credentials
, tctx
->ev
, tctx
->lp_ctx
),
693 "failed to connect lsarpc with schannel");
695 torture_assert(tctx
, test_lsa_ops(tctx
, p_lsa
, credentials
),
696 "Failed to process schannel secured LSA ops");
701 /* we *MUST* use ncacn_ip_tcp for lookupsids3/lookupnames4 */
702 status
= dcerpc_binding_set_transport(b
, NCACN_IP_TCP
);
703 torture_assert_ntstatus_ok(tctx
, status
, "set transport");
705 torture_assert_ntstatus_ok(tctx
,
706 dcerpc_epm_map_binding(tctx
, b
, &ndr_table_lsarpc
, tctx
->ev
, tctx
->lp_ctx
),
707 "failed to call epm map");
709 torture_assert_ntstatus_ok(tctx
,
710 dcerpc_pipe_connect_b(tctx
, &p_lsa
, b
, &ndr_table_lsarpc
,
711 credentials
, tctx
->ev
, tctx
->lp_ctx
),
712 "failed to connect lsarpc with schannel");
715 test_many_LookupSids(p_lsa
, tctx
, NULL
, LSA_LOOKUP_NAMES_ALL
),
716 "LsaLookupSids3 failed!\n");
718 status
= dcerpc_binding_set_transport(b
, transport
);
719 torture_assert_ntstatus_ok(tctx
, status
, "set transport");
722 /* Drop the socket, we want to start from scratch */
726 /* Now see what we are still allowed to do */
728 status
= dcerpc_parse_binding(tctx
, binding
, &b
);
729 torture_assert_ntstatus_ok(tctx
, status
, "Bad binding string");
731 status
= dcerpc_binding_set_flags(b
, dcerpc_flags
, DCERPC_AUTH_OPTIONS
);
732 torture_assert_ntstatus_ok(tctx
, status
, "set flags");
734 status
= dcerpc_pipe_connect_b(tctx
, &p_samr2
, b
, &ndr_table_samr
,
735 credentials
, tctx
->ev
, tctx
->lp_ctx
);
736 torture_assert_ntstatus_ok(tctx
, status
,
737 "Failed to connect with schannel");
739 /* do a some SAMR operations. We have *not* done a new serverauthenticate */
740 torture_assert (tctx
, test_samr_ops(tctx
, p_samr2
->binding_handle
),
741 "Failed to process schannel secured SAMR ops (on fresh connection)");
743 /* Swap the binding details from SAMR to NETLOGON */
744 status
= dcerpc_epm_map_binding(tctx
, b
, &ndr_table_netlogon
, tctx
->ev
, tctx
->lp_ctx
);
745 torture_assert_ntstatus_ok(tctx
, status
, "epm");
747 status
= dcerpc_binding_set_flags(b
, dcerpc_flags
, DCERPC_AUTH_OPTIONS
);
748 torture_assert_ntstatus_ok(tctx
, status
, "set flags");
750 status
= dcerpc_secondary_auth_connection(p_samr2
, b
, &ndr_table_netlogon
,
751 credentials
, tctx
->lp_ctx
,
753 torture_assert_ntstatus_ok(tctx
, status
, "Failed to create secondary connection");
755 requested_flags
= creds
->client_requested_flags
;
757 /* checks the capabilities */
759 test_netlogon_capabilities(p_netlogon2
, tctx
, credentials
, requested_flags
, creds
),
760 "Failed to process schannel secured capability ops (on fresh connection)");
762 /* Try the schannel-only SamLogonEx operation */
763 torture_assert(tctx
, test_netlogon_ex_ops(p_netlogon2
, tctx
, credentials
, creds
),
764 "Failed to process schannel secured NETLOGON EX ops (on fresh connection)");
767 /* And the more traditional style, proving that the
768 * credentials chaining state is fully present */
769 torture_assert(tctx
, test_netlogon_ops(p_netlogon2
, tctx
, credentials
, creds
),
770 "Failed to process schannel secured NETLOGON ops (on fresh connection)");
772 /* Drop the socket, we want to start from scratch (again) */
773 talloc_free(p_samr2
);
775 /* We don't want schannel for this test */
776 status
= dcerpc_binding_set_flags(b
, 0, DCERPC_AUTH_OPTIONS
);
777 torture_assert_ntstatus_ok(tctx
, status
, "set flags");
779 status
= dcerpc_pipe_connect_b(tctx
, &p_netlogon3
, b
, &ndr_table_netlogon
,
780 credentials
, tctx
->ev
, tctx
->lp_ctx
);
781 torture_assert_ntstatus_ok(tctx
, status
, "Failed to connect without schannel");
783 torture_assert(tctx
, !test_netlogon_ex_ops(p_netlogon3
, tctx
, credentials
, creds
),
784 "Processed NOT schannel secured NETLOGON EX ops without SCHANNEL (unsafe)");
786 /* Required because the previous call will mark the current context as having failed */
787 tctx
->last_result
= TORTURE_OK
;
788 tctx
->last_reason
= NULL
;
790 torture_assert(tctx
, test_netlogon_ops(p_netlogon3
, tctx
, credentials
, creds
),
791 "Failed to processed NOT schannel secured NETLOGON ops without new ServerAuth");
793 torture_leave_domain(tctx
, join_ctx
);
798 * Purpose of this test is to demonstrate that a netlogon server carefully deals
799 * with anonymous attempts to set passwords, in particular when the server
800 * enforces the use of schannel. This test makes most sense to be run in an
801 * environment where the netlogon server enforces use of schannel.
804 static bool test_schannel_anonymous_setPassword(struct torture_context
*tctx
,
805 uint32_t dcerpc_flags
,
808 NTSTATUS status
, result
;
809 const char *binding
= torture_setting_string(tctx
, "binding", NULL
);
810 struct dcerpc_binding
*b
;
811 struct dcerpc_pipe
*p
= NULL
;
812 struct cli_credentials
*credentials
;
815 credentials
= cli_credentials_init(NULL
);
816 torture_assert(tctx
, credentials
!= NULL
, "Bad credentials");
817 cli_credentials_set_anonymous(credentials
);
819 status
= dcerpc_parse_binding(tctx
, binding
, &b
);
820 torture_assert_ntstatus_ok(tctx
, status
, "Bad binding string");
822 status
= dcerpc_binding_set_flags(b
, dcerpc_flags
, DCERPC_AUTH_OPTIONS
);
823 torture_assert_ntstatus_ok(tctx
, status
, "set flags");
825 status
= dcerpc_pipe_connect_b(tctx
,
832 torture_assert_ntstatus_ok(tctx
, status
, "Failed to connect without schannel");
835 struct netr_ServerPasswordSet2 r
= {};
836 struct netr_Authenticator credential
= {};
837 struct netr_Authenticator return_authenticator
= {};
838 struct netr_CryptPassword new_password
= {};
840 r
.in
.server_name
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
841 r
.in
.account_name
= talloc_asprintf(tctx
, "%s$", TEST_MACHINE_NAME
);
842 r
.in
.secure_channel_type
= 0;
843 r
.in
.computer_name
= TEST_MACHINE_NAME
;
844 r
.in
.credential
= &credential
;
845 r
.in
.new_password
= &new_password
;
846 r
.out
.return_authenticator
= &return_authenticator
;
848 status
= dcerpc_netr_ServerPasswordSet2_r(p
->binding_handle
, tctx
, &r
);
849 result
= r
.out
.result
;
851 struct netr_ServerPasswordSet r
= {};
852 struct netr_Authenticator credential
= {};
853 struct netr_Authenticator return_authenticator
= {};
854 struct samr_Password new_password
= {};
856 r
.in
.server_name
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
857 r
.in
.account_name
= talloc_asprintf(tctx
, "%s$", TEST_MACHINE_NAME
);
858 r
.in
.secure_channel_type
= 0;
859 r
.in
.computer_name
= TEST_MACHINE_NAME
;
860 r
.in
.credential
= &credential
;
861 r
.in
.new_password
= &new_password
;
862 r
.out
.return_authenticator
= &return_authenticator
;
864 status
= dcerpc_netr_ServerPasswordSet_r(p
->binding_handle
, tctx
, &r
);
865 result
= r
.out
.result
;
868 torture_assert_ntstatus_ok(tctx
, status
, "ServerPasswordSet failed");
870 if (NT_STATUS_IS_OK(result
)) {
871 torture_fail(tctx
, "unexpectedly received NT_STATUS_OK");
879 a schannel test suite
881 bool torture_rpc_schannel(struct torture_context
*torture
)
886 uint32_t dcerpc_flags
;
889 * Note the order of these combinations is important
890 * otherwise exceptions like:
891 * 'server schannel require seal:schannel2$ = no'
892 * in selftest/target/Samba4.pm get out of sync.
894 { ACB_WSTRUST
, DCERPC_SCHANNEL
| DCERPC_SIGN
| DCERPC_SCHANNEL_AUTO
},
895 { ACB_WSTRUST
, DCERPC_SCHANNEL
| DCERPC_SEAL
| DCERPC_SCHANNEL_AUTO
},
896 { ACB_WSTRUST
, DCERPC_SCHANNEL
| DCERPC_SIGN
| DCERPC_SCHANNEL_128
},
897 { ACB_WSTRUST
, DCERPC_SCHANNEL
| DCERPC_SEAL
| DCERPC_SCHANNEL_128
},
898 { ACB_WSTRUST
, DCERPC_SCHANNEL
| DCERPC_SIGN
| DCERPC_SCHANNEL_AES
},
899 { ACB_WSTRUST
, DCERPC_SCHANNEL
| DCERPC_SEAL
| DCERPC_SCHANNEL_AES
},
900 { ACB_SVRTRUST
, DCERPC_SCHANNEL
| DCERPC_SIGN
| DCERPC_SCHANNEL_AUTO
},
901 { ACB_SVRTRUST
, DCERPC_SCHANNEL
| DCERPC_SEAL
| DCERPC_SCHANNEL_AUTO
},
902 { ACB_SVRTRUST
, DCERPC_SCHANNEL
| DCERPC_SIGN
| DCERPC_SCHANNEL_128
},
903 { ACB_SVRTRUST
, DCERPC_SCHANNEL
| DCERPC_SEAL
| DCERPC_SCHANNEL_128
},
904 { ACB_SVRTRUST
, DCERPC_SCHANNEL
| DCERPC_SIGN
| DCERPC_SCHANNEL_AES
},
905 { ACB_SVRTRUST
, DCERPC_SCHANNEL
| DCERPC_SEAL
| DCERPC_SCHANNEL_AES
},
906 { ACB_WSTRUST
, DCERPC_SCHANNEL
| DCERPC_SIGN
| DCERPC_SCHANNEL_KRB5
},
907 { ACB_WSTRUST
, DCERPC_SCHANNEL
| DCERPC_SEAL
| DCERPC_SCHANNEL_KRB5
},
908 { ACB_SVRTRUST
, DCERPC_SCHANNEL
| DCERPC_SIGN
| DCERPC_SCHANNEL_KRB5
},
909 { ACB_SVRTRUST
, DCERPC_SCHANNEL
| DCERPC_SEAL
| DCERPC_SCHANNEL_KRB5
},
913 for (i
=0;i
<ARRAY_SIZE(tests
);i
++) {
914 torture_comment(torture
, "Testing with acct_flags=0x%x dcerpc_flags=0x%x \n",
915 tests
[i
].acct_flags
, tests
[i
].dcerpc_flags
);
917 if (!test_schannel(torture
,
918 tests
[i
].acct_flags
, tests
[i
].dcerpc_flags
,
920 torture_comment(torture
, "Failed with acct_flags=0x%x dcerpc_flags=0x%x \n",
921 tests
[i
].acct_flags
, tests
[i
].dcerpc_flags
);
929 bool torture_rpc_schannel_anon_setpw(struct torture_context
*torture
)
933 uint32_t dcerpc_flags
= DCERPC_SCHANNEL
| DCERPC_SIGN
| DCERPC_SCHANNEL_AUTO
;
935 ok
= test_schannel_anonymous_setPassword(torture
,
939 torture_comment(torture
,
940 "Failed with dcerpc_flags=0x%x\n",
945 ok
= test_schannel_anonymous_setPassword(torture
,
949 torture_comment(torture
,
950 "Failed with dcerpc_flags=0x%x\n",
959 test two schannel connections
961 bool torture_rpc_schannel2(struct torture_context
*torture
)
963 struct test_join
*join_ctx
;
965 const char *binding
= torture_setting_string(torture
, "binding", NULL
);
966 struct dcerpc_binding
*b
;
967 struct dcerpc_pipe
*p1
= NULL
, *p2
= NULL
;
968 struct cli_credentials
*credentials1
, *credentials2
;
969 uint32_t dcerpc_flags
= DCERPC_SCHANNEL
| DCERPC_SCHANNEL_AUTO
| DCERPC_SIGN
;
971 join_ctx
= torture_join_domain(torture
, talloc_asprintf(torture
, "%s2", TEST_MACHINE_NAME
),
972 ACB_WSTRUST
, &credentials1
);
973 torture_assert(torture
, join_ctx
!= NULL
,
974 "Failed to join domain with acct_flags=ACB_WSTRUST");
976 credentials2
= cli_credentials_shallow_copy(torture
, credentials1
);
977 cli_credentials_set_netlogon_creds(credentials1
, NULL
);
978 cli_credentials_set_netlogon_creds(credentials2
, NULL
);
980 status
= dcerpc_parse_binding(torture
, binding
, &b
);
981 torture_assert_ntstatus_ok(torture
, status
, "Bad binding string");
983 status
= dcerpc_binding_set_flags(b
, dcerpc_flags
, DCERPC_AUTH_OPTIONS
);
984 torture_assert_ntstatus_ok(torture
, status
, "set flags");
986 torture_comment(torture
, "Opening first connection\n");
987 status
= dcerpc_pipe_connect_b(torture
, &p1
, b
, &ndr_table_netlogon
,
988 credentials1
, torture
->ev
, torture
->lp_ctx
);
989 torture_assert_ntstatus_ok(torture
, status
, "Failed to connect with schannel");
991 torture_comment(torture
, "Opening second connection\n");
992 status
= dcerpc_pipe_connect_b(torture
, &p2
, b
, &ndr_table_netlogon
,
993 credentials2
, torture
->ev
, torture
->lp_ctx
);
994 torture_assert_ntstatus_ok(torture
, status
, "Failed to connect with schannel");
996 cli_credentials_set_netlogon_creds(credentials1
, NULL
);
997 cli_credentials_set_netlogon_creds(credentials2
, NULL
);
999 torture_comment(torture
, "Testing logon on pipe1\n");
1000 if (!test_netlogon_ex_ops(p1
, torture
, credentials1
, NULL
))
1003 torture_comment(torture
, "Testing logon on pipe2\n");
1004 if (!test_netlogon_ex_ops(p2
, torture
, credentials2
, NULL
))
1007 torture_comment(torture
, "Again on pipe1\n");
1008 if (!test_netlogon_ex_ops(p1
, torture
, credentials1
, NULL
))
1011 torture_comment(torture
, "Again on pipe2\n");
1012 if (!test_netlogon_ex_ops(p2
, torture
, credentials2
, NULL
))
1015 torture_leave_domain(torture
, join_ctx
);
1019 struct torture_schannel_bench
;
1021 struct torture_schannel_bench_conn
{
1022 struct torture_schannel_bench
*s
;
1024 struct cli_credentials
*wks_creds
;
1025 struct dcerpc_pipe
*pipe
;
1026 struct netr_LogonSamLogonEx r
;
1027 struct netr_NetworkInfo ninfo
;
1033 struct torture_schannel_bench
{
1034 struct torture_context
*tctx
;
1039 struct torture_schannel_bench_conn
*conns
;
1040 struct test_join
*join_ctx1
;
1041 struct cli_credentials
*wks_creds1
;
1042 struct test_join
*join_ctx2
;
1043 struct cli_credentials
*wks_creds2
;
1044 struct cli_credentials
*user1_creds
;
1045 struct cli_credentials
*user2_creds
;
1046 struct dcerpc_binding
*b
;
1054 static void torture_schannel_bench_connected(struct composite_context
*c
)
1056 struct torture_schannel_bench_conn
*conn
=
1057 (struct torture_schannel_bench_conn
*)c
->async
.private_data
;
1058 struct torture_schannel_bench
*s
= talloc_get_type(conn
->s
,
1059 struct torture_schannel_bench
);
1061 s
->error
= dcerpc_pipe_connect_b_recv(c
, s
->conns
, &conn
->pipe
);
1062 torture_comment(s
->tctx
, "conn[%u]: %s\n", conn
->index
, nt_errstr(s
->error
));
1063 if (NT_STATUS_IS_OK(s
->error
)) {
1069 static void torture_schannel_bench_recv(struct tevent_req
*subreq
);
1071 static bool torture_schannel_bench_start(struct torture_schannel_bench_conn
*conn
)
1073 struct torture_schannel_bench
*s
= conn
->s
;
1075 DATA_BLOB names_blob
, chal
, lm_resp
, nt_resp
;
1076 int flags
= CLI_CRED_NTLM_AUTH
;
1077 struct tevent_req
*subreq
;
1078 struct cli_credentials
*user_creds
;
1080 if (conn
->total
% 2) {
1081 user_creds
= s
->user1_creds
;
1083 user_creds
= s
->user2_creds
;
1086 if (lpcfg_client_lanman_auth(s
->tctx
->lp_ctx
)) {
1087 flags
|= CLI_CRED_LANMAN_AUTH
;
1090 if (lpcfg_client_ntlmv2_auth(s
->tctx
->lp_ctx
)) {
1091 flags
|= CLI_CRED_NTLMv2_AUTH
;
1094 talloc_free(conn
->tmp
);
1095 conn
->tmp
= talloc_new(s
);
1096 ZERO_STRUCT(conn
->ninfo
);
1097 ZERO_STRUCT(conn
->r
);
1099 cli_credentials_get_ntlm_username_domain(user_creds
, conn
->tmp
,
1100 &conn
->ninfo
.identity_info
.account_name
.string
,
1101 &conn
->ninfo
.identity_info
.domain_name
.string
);
1103 generate_random_buffer(conn
->ninfo
.challenge
,
1104 sizeof(conn
->ninfo
.challenge
));
1105 chal
= data_blob_const(conn
->ninfo
.challenge
,
1106 sizeof(conn
->ninfo
.challenge
));
1108 names_blob
= NTLMv2_generate_names_blob(conn
->tmp
,
1109 cli_credentials_get_workstation(conn
->wks_creds
),
1110 cli_credentials_get_domain(conn
->wks_creds
));
1112 status
= cli_credentials_get_ntlm_response(user_creds
, conn
->tmp
,
1115 NULL
, /* server_timestamp */
1119 torture_assert_ntstatus_ok(s
->tctx
, status
,
1120 "cli_credentials_get_ntlm_response failed");
1122 conn
->ninfo
.lm
.data
= lm_resp
.data
;
1123 conn
->ninfo
.lm
.length
= lm_resp
.length
;
1125 conn
->ninfo
.nt
.data
= nt_resp
.data
;
1126 conn
->ninfo
.nt
.length
= nt_resp
.length
;
1128 conn
->ninfo
.identity_info
.parameter_control
= 0;
1129 conn
->ninfo
.identity_info
.logon_id
= 0;
1130 conn
->ninfo
.identity_info
.workstation
.string
= cli_credentials_get_workstation(conn
->wks_creds
);
1132 conn
->r
.in
.server_name
= talloc_asprintf(conn
->tmp
, "\\\\%s", dcerpc_server_name(conn
->pipe
));
1133 conn
->r
.in
.computer_name
= cli_credentials_get_workstation(conn
->wks_creds
);
1134 conn
->r
.in
.logon_level
= NetlogonNetworkInformation
;
1135 conn
->r
.in
.logon
= talloc(conn
->tmp
, union netr_LogonLevel
);
1136 conn
->r
.in
.logon
->network
= &conn
->ninfo
;
1137 conn
->r
.in
.flags
= talloc(conn
->tmp
, uint32_t);
1138 conn
->r
.in
.validation_level
= 2;
1139 conn
->r
.out
.validation
= talloc(conn
->tmp
, union netr_Validation
);
1140 conn
->r
.out
.authoritative
= talloc(conn
->tmp
, uint8_t);
1141 conn
->r
.out
.flags
= conn
->r
.in
.flags
;
1143 subreq
= dcerpc_netr_LogonSamLogonEx_r_send(s
, s
->tctx
->ev
,
1144 conn
->pipe
->binding_handle
,
1146 torture_assert(s
->tctx
, subreq
, "Failed to setup LogonSamLogonEx request");
1148 tevent_req_set_callback(subreq
, torture_schannel_bench_recv
, conn
);
1153 static void torture_schannel_bench_recv(struct tevent_req
*subreq
)
1156 struct torture_schannel_bench_conn
*conn
=
1157 (struct torture_schannel_bench_conn
*)tevent_req_callback_data_void(subreq
);
1158 struct torture_schannel_bench
*s
= talloc_get_type(conn
->s
,
1159 struct torture_schannel_bench
);
1161 s
->error
= dcerpc_netr_LogonSamLogonEx_r_recv(subreq
, subreq
);
1162 TALLOC_FREE(subreq
);
1163 if (!NT_STATUS_IS_OK(s
->error
)) {
1174 ret
= torture_schannel_bench_start(conn
);
1176 s
->error
= NT_STATUS_INTERNAL_ERROR
;
1181 test multiple schannel connection in parallel
1183 bool torture_rpc_schannel_bench1(struct torture_context
*torture
)
1187 const char *binding
= torture_setting_string(torture
, "binding", NULL
);
1188 struct torture_schannel_bench
*s
;
1189 struct timeval start
;
1194 s
= talloc_zero(torture
, struct torture_schannel_bench
);
1196 s
->progress
= torture_setting_bool(torture
, "progress", true);
1197 s
->timelimit
= torture_setting_int(torture
, "timelimit", 10);
1198 s
->nprocs
= torture_setting_int(torture
, "nprocs", 4);
1199 s
->conns
= talloc_zero_array(s
, struct torture_schannel_bench_conn
, s
->nprocs
);
1201 s
->user1_creds
= cli_credentials_shallow_copy(s
,
1202 samba_cmdline_get_creds());
1203 tmp
= torture_setting_string(s
->tctx
, "extra_user1", NULL
);
1205 cli_credentials_parse_string(s
->user1_creds
, tmp
, CRED_SPECIFIED
);
1207 s
->user2_creds
= cli_credentials_shallow_copy(s
,
1208 samba_cmdline_get_creds());
1209 tmp
= torture_setting_string(s
->tctx
, "extra_user2", NULL
);
1211 cli_credentials_parse_string(s
->user1_creds
, tmp
, CRED_SPECIFIED
);
1214 s
->join_ctx1
= torture_join_domain(s
->tctx
, talloc_asprintf(s
, "%sb", TEST_MACHINE_NAME
),
1215 ACB_WSTRUST
, &s
->wks_creds1
);
1216 torture_assert(torture
, s
->join_ctx1
!= NULL
,
1217 "Failed to join domain with acct_flags=ACB_WSTRUST");
1218 s
->join_ctx2
= torture_join_domain(s
->tctx
, talloc_asprintf(s
, "%sc", TEST_MACHINE_NAME
),
1219 ACB_WSTRUST
, &s
->wks_creds2
);
1220 torture_assert(torture
, s
->join_ctx2
!= NULL
,
1221 "Failed to join domain with acct_flags=ACB_WSTRUST");
1223 cli_credentials_set_kerberos_state(s
->wks_creds1
,
1224 CRED_USE_KERBEROS_DISABLED
,
1226 cli_credentials_set_kerberos_state(s
->wks_creds2
,
1227 CRED_USE_KERBEROS_DISABLED
,
1230 for (i
=0; i
< s
->nprocs
; i
++) {
1231 struct cli_credentials
*wks
= s
->wks_creds1
;
1233 if ((i
% 2) && (torture_setting_bool(torture
, "multijoin", false))) {
1234 wks
= s
->wks_creds2
;
1238 s
->conns
[i
].index
= i
;
1239 s
->conns
[i
].wks_creds
= cli_credentials_shallow_copy(s
->conns
, wks
);
1240 cli_credentials_set_netlogon_creds(s
->conns
[i
].wks_creds
, NULL
);
1243 status
= dcerpc_parse_binding(s
, binding
, &s
->b
);
1244 torture_assert_ntstatus_ok(torture
, status
, "Bad binding string");
1246 status
= dcerpc_binding_set_flags(s
->b
, DCERPC_SCHANNEL
| DCERPC_SIGN
,
1247 DCERPC_AUTH_OPTIONS
);
1248 torture_assert_ntstatus_ok(torture
, status
, "set flags");
1250 torture_comment(torture
, "Opening %d connections in parallel\n", s
->nprocs
);
1251 for (i
=0; i
< s
->nprocs
; i
++) {
1253 s
->error
= dcerpc_pipe_connect_b(s
->conns
, &s
->conns
[i
].pipe
, s
->b
,
1254 &ndr_table_netlogon
,
1255 s
->conns
[i
].wks_creds
,
1256 torture
->ev
, torture
->lp_ctx
);
1257 torture_assert_ntstatus_ok(torture
, s
->error
, "Failed to connect with schannel");
1260 * This path doesn't work against windows,
1261 * because of windows drops the connections
1262 * which haven't reached a session setup yet
1264 * The same as the reset on zero vc stuff.
1266 struct composite_context
*c
;
1267 c
= dcerpc_pipe_connect_b_send(s
->conns
, s
->b
,
1268 &ndr_table_netlogon
,
1269 s
->conns
[i
].wks_creds
,
1272 torture_assert(torture
, c
!= NULL
, "Failed to setup connect");
1273 c
->async
.fn
= torture_schannel_bench_connected
;
1274 c
->async
.private_data
= &s
->conns
[i
];
1277 while (NT_STATUS_IS_OK(s
->error
) && s
->nprocs
!= s
->nconns
) {
1278 int ev_ret
= tevent_loop_once(torture
->ev
);
1279 torture_assert(torture
, ev_ret
== 0, "tevent_loop_once failed");
1282 torture_assert_ntstatus_ok(torture
, s
->error
, "Failed establish a connect");
1285 * Change the workstation password after establishing the netlogon
1286 * schannel connections to prove that existing connections are not
1287 * affected by a wks pwchange.
1291 struct netr_ServerPasswordSet pwset
;
1292 char *password
= generate_random_password(s
->join_ctx1
, 8, 255);
1293 struct netlogon_creds_CredentialState
*creds_state
;
1294 struct dcerpc_pipe
*net_pipe
;
1295 struct netr_Authenticator credential
, return_authenticator
;
1296 struct samr_Password new_password
;
1297 enum dcerpc_AuthType auth_type
;
1298 enum dcerpc_AuthLevel auth_level
;
1300 status
= dcerpc_pipe_connect_b(s
, &net_pipe
, s
->b
,
1301 &ndr_table_netlogon
,
1303 torture
->ev
, torture
->lp_ctx
);
1305 torture_assert_ntstatus_ok(torture
, status
,
1306 "dcerpc_pipe_connect_b failed");
1308 pwset
.in
.server_name
= talloc_asprintf(
1309 net_pipe
, "\\\\%s", dcerpc_server_name(net_pipe
));
1310 pwset
.in
.computer_name
=
1311 cli_credentials_get_workstation(s
->wks_creds1
);
1312 pwset
.in
.account_name
= talloc_asprintf(
1313 net_pipe
, "%s$", pwset
.in
.computer_name
);
1314 pwset
.in
.secure_channel_type
= SEC_CHAN_WKSTA
;
1315 pwset
.in
.credential
= &credential
;
1316 pwset
.in
.new_password
= &new_password
;
1317 pwset
.out
.return_authenticator
= &return_authenticator
;
1319 E_md4hash(password
, new_password
.hash
);
1321 creds_state
= cli_credentials_get_netlogon_creds(
1323 dcerpc_binding_handle_auth_info(net_pipe
->binding_handle
,
1326 status
= netlogon_creds_encrypt_samr_Password(creds_state
,
1330 torture_assert_ntstatus_ok(torture
, status
, "encrypt_samr_Password");
1331 netlogon_creds_client_authenticator(creds_state
, &credential
);
1333 torture_assert_ntstatus_ok(torture
, dcerpc_netr_ServerPasswordSet_r(net_pipe
->binding_handle
, torture
, &pwset
),
1334 "ServerPasswordSet failed");
1335 torture_assert_ntstatus_ok(torture
, pwset
.out
.result
,
1336 "ServerPasswordSet failed");
1338 if (!netlogon_creds_client_check(creds_state
,
1339 &pwset
.out
.return_authenticator
->cred
)) {
1340 torture_comment(torture
, "Credential chaining failed\n");
1343 cli_credentials_set_password(s
->wks_creds1
, password
,
1346 talloc_free(net_pipe
);
1348 /* Just as a test, connect with the new creds */
1350 cli_credentials_set_netlogon_creds(s
->wks_creds1
, NULL
);
1352 status
= dcerpc_pipe_connect_b(s
, &net_pipe
, s
->b
,
1353 &ndr_table_netlogon
,
1355 torture
->ev
, torture
->lp_ctx
);
1357 torture_assert_ntstatus_ok(torture
, status
,
1358 "dcerpc_pipe_connect_b failed");
1360 talloc_free(net_pipe
);
1363 torture_comment(torture
, "Start looping LogonSamLogonEx on %d connections for %d secs\n",
1364 s
->nprocs
, s
->timelimit
);
1365 for (i
=0; i
< s
->nprocs
; i
++) {
1366 ret
= torture_schannel_bench_start(&s
->conns
[i
]);
1367 torture_assert(torture
, ret
, "Failed to setup LogonSamLogonEx");
1370 start
= timeval_current();
1371 end
= timeval_add(&start
, s
->timelimit
, 0);
1373 while (NT_STATUS_IS_OK(s
->error
) && !timeval_expired(&end
)) {
1374 int ev_ret
= tevent_loop_once(torture
->ev
);
1375 torture_assert(torture
, ev_ret
== 0, "tevent_loop_once failed");
1377 torture_assert_ntstatus_ok(torture
, s
->error
, "Failed some request");
1379 talloc_free(s
->conns
);
1381 for (i
=0; i
< s
->nprocs
; i
++) {
1382 s
->total
+= s
->conns
[i
].total
;
1385 torture_comment(torture
,
1386 "Total ops[%llu] (%u ops/s)\n",
1387 (unsigned long long)s
->total
,
1388 (unsigned)s
->total
/s
->timelimit
);
1390 torture_leave_domain(torture
, s
->join_ctx1
);
1391 torture_leave_domain(torture
, s
->join_ctx2
);