Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 :
4 : test suite for schannel operations
5 :
6 : Copyright (C) Andrew Tridgell 2004
7 :
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.
12 :
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.
17 :
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/>.
20 : */
21 :
22 : #include "includes.h"
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 "librpc/rpc/dcerpc_proto.h"
36 : #include "libcli/composite/composite.h"
37 : #include "lib/events/events.h"
38 :
39 : #define TEST_MACHINE_NAME "schannel"
40 :
41 : /*
42 : try a netlogon SamLogon
43 : */
44 920 : bool test_netlogon_ex_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
45 : struct cli_credentials *credentials,
46 : struct netlogon_creds_CredentialState *creds)
47 : {
48 160 : NTSTATUS status;
49 160 : struct netr_LogonSamLogonEx r;
50 160 : struct netr_NetworkInfo ninfo;
51 160 : union netr_LogonLevel logon;
52 160 : union netr_Validation validation;
53 920 : uint8_t authoritative = 1;
54 920 : uint32_t _flags = 0;
55 160 : DATA_BLOB names_blob, chal, lm_resp, nt_resp;
56 160 : int i;
57 920 : int flags = CLI_CRED_NTLM_AUTH;
58 920 : struct dcerpc_binding_handle *b = p->binding_handle;
59 :
60 160 : struct netr_UserSessionKey key;
61 160 : struct netr_LMSessionKey LMSessKey;
62 920 : uint32_t validation_levels[] = { 2, 3 };
63 920 : struct netr_SamBaseInfo *base = NULL;
64 920 : const char *crypto_alg = "";
65 920 : bool can_do_validation_6 = true;
66 920 : enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE;
67 :
68 920 : if (lpcfg_client_lanman_auth(tctx->lp_ctx)) {
69 800 : flags |= CLI_CRED_LANMAN_AUTH;
70 : }
71 :
72 920 : if (lpcfg_client_ntlmv2_auth(tctx->lp_ctx)) {
73 920 : flags |= CLI_CRED_NTLMv2_AUTH;
74 : }
75 :
76 920 : cli_credentials_get_ntlm_username_domain(samba_cmdline_get_creds(),
77 : tctx,
78 : &ninfo.identity_info.account_name.string,
79 : &ninfo.identity_info.domain_name.string);
80 :
81 920 : generate_random_buffer(ninfo.challenge,
82 : sizeof(ninfo.challenge));
83 920 : chal = data_blob_const(ninfo.challenge,
84 : sizeof(ninfo.challenge));
85 :
86 920 : names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(credentials),
87 : cli_credentials_get_domain(credentials));
88 :
89 920 : status = cli_credentials_get_ntlm_response(
90 : samba_cmdline_get_creds(),
91 : tctx,
92 : &flags,
93 : chal,
94 : NULL, /* server_timestamp */
95 : names_blob,
96 : &lm_resp, &nt_resp,
97 : NULL, NULL);
98 920 : torture_assert_ntstatus_ok(tctx, status,
99 : "cli_credentials_get_ntlm_response failed");
100 :
101 920 : ninfo.lm.data = lm_resp.data;
102 920 : ninfo.lm.length = lm_resp.length;
103 :
104 920 : ninfo.nt.data = nt_resp.data;
105 920 : ninfo.nt.length = nt_resp.length;
106 :
107 920 : ninfo.identity_info.parameter_control = 0;
108 920 : ninfo.identity_info.logon_id = 0;
109 920 : ninfo.identity_info.workstation.string = cli_credentials_get_workstation(credentials);
110 :
111 920 : logon.network = &ninfo;
112 :
113 920 : r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
114 920 : r.in.computer_name = cli_credentials_get_workstation(credentials);
115 920 : r.in.logon_level = NetlogonNetworkInformation;
116 920 : r.in.logon= &logon;
117 920 : r.in.flags = &_flags;
118 920 : r.out.validation = &validation;
119 920 : r.out.authoritative = &authoritative;
120 920 : r.out.flags = &_flags;
121 :
122 : /*
123 : - retrieve level6
124 : - save usrsession and lmsession key
125 : - retrieve level 2
126 : - calculate, compare
127 : - retrieve level 3
128 : - calculate, compare
129 : */
130 :
131 920 : if (creds) {
132 828 : if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
133 456 : crypto_alg = "AES";
134 276 : } else if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
135 276 : crypto_alg = "ARCFOUR";
136 : }
137 : }
138 :
139 920 : dcerpc_binding_handle_auth_info(b, NULL, &auth_level);
140 920 : if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
141 276 : r.in.validation_level = 6;
142 :
143 276 : torture_comment(tctx,
144 : "Testing LogonSamLogonEx with name %s using %s and validation_level: %d\n",
145 : ninfo.identity_info.account_name.string, crypto_alg,
146 228 : r.in.validation_level);
147 :
148 276 : torture_assert_ntstatus_ok(tctx,
149 : dcerpc_netr_LogonSamLogonEx_r(b, tctx, &r),
150 : "LogonSamLogonEx failed");
151 : } else {
152 644 : torture_comment(tctx,
153 : "Skip auth_level[%u] Testing LogonSamLogonEx with name %s using %s and validation_level: %d\n",
154 : auth_level, ninfo.identity_info.account_name.string, crypto_alg,
155 644 : r.in.validation_level);
156 644 : r.out.result = NT_STATUS_INVALID_INFO_CLASS;
157 : }
158 :
159 920 : if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_INFO_CLASS)) {
160 556 : can_do_validation_6 = false;
161 : } else {
162 252 : torture_assert_ntstatus_ok(tctx, r.out.result,
163 : "LogonSamLogonEx failed");
164 :
165 252 : key = r.out.validation->sam6->base.key;
166 252 : LMSessKey = r.out.validation->sam6->base.LMSessKey;
167 :
168 252 : DEBUG(1,("unencrypted session keys from validation_level 6:\n"));
169 252 : dump_data(1, r.out.validation->sam6->base.key.key, 16);
170 252 : dump_data(1, r.out.validation->sam6->base.LMSessKey.key, 8);
171 : }
172 :
173 2208 : for (i=0; i < ARRAY_SIZE(validation_levels); i++) {
174 :
175 1564 : r.in.validation_level = validation_levels[i];
176 :
177 1564 : torture_comment(tctx,
178 : "Testing LogonSamLogonEx with name %s using %s and validation_level: %d\n",
179 : ninfo.identity_info.account_name.string, crypto_alg,
180 1292 : r.in.validation_level);
181 :
182 1564 : torture_assert_ntstatus_ok(tctx,
183 : dcerpc_netr_LogonSamLogonEx_r(b, tctx, &r),
184 : "LogonSamLogonEx failed");
185 1564 : torture_assert_ntstatus_ok(tctx, r.out.result,
186 : "LogonSamLogonEx failed");
187 :
188 1288 : if (creds == NULL) {
189 : /* when this test is called without creds no point in
190 : * testing the session keys */
191 184 : continue;
192 : }
193 :
194 1104 : switch (validation_levels[i]) {
195 552 : case 2:
196 552 : base = &r.out.validation->sam2->base;
197 552 : break;
198 552 : case 3:
199 552 : base = &r.out.validation->sam3->base;
200 552 : break;
201 0 : default:
202 0 : break;
203 : }
204 :
205 1104 : DEBUG(1,("encrypted keys validation_level %d:\n",
206 : validation_levels[i]));
207 1104 : dump_data(1, base->key.key, 16);
208 1104 : dump_data(1, base->LMSessKey.key, 8);
209 :
210 1104 : if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
211 736 : netlogon_creds_aes_decrypt(creds, base->key.key, 16);
212 736 : netlogon_creds_aes_decrypt(creds, base->LMSessKey.key, 8);
213 368 : } else if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
214 368 : netlogon_creds_arcfour_crypt(creds, base->key.key, 16);
215 368 : netlogon_creds_arcfour_crypt(creds, base->LMSessKey.key, 8);
216 : }
217 :
218 1104 : DEBUG(1,("decrypted keys validation_level %d\n",
219 : validation_levels[i]));
220 :
221 1104 : dump_data(1, base->key.key, 16);
222 1104 : dump_data(1, base->LMSessKey.key, 8);
223 :
224 1104 : if (!can_do_validation_6) {
225 : /* we can't compare against unencrypted keys */
226 600 : continue;
227 : }
228 :
229 504 : torture_assert_mem_equal(tctx,
230 : base->key.key,
231 : key.key,
232 : 16,
233 : "unexpected user session key\n");
234 632 : torture_assert_mem_equal(tctx,
235 : base->LMSessKey.key,
236 : LMSessKey.key,
237 : 8,
238 : "unexpected LM session key\n");
239 : }
240 :
241 532 : return true;
242 : }
243 :
244 276 : static bool test_netlogon_ex_bug14932(struct dcerpc_pipe *p,
245 : struct torture_context *tctx,
246 : struct cli_credentials *credentials,
247 : struct netlogon_creds_CredentialState *creds)
248 : {
249 48 : NTSTATUS status;
250 48 : struct netr_LogonSamLogonEx r;
251 48 : struct netr_NetworkInfo ninfo;
252 48 : union netr_LogonLevel logon;
253 48 : union netr_Validation validation;
254 276 : uint8_t authoritative = 1;
255 276 : uint32_t _flags = 0;
256 48 : static const char *netapp_magic =
257 : "\x01\x01\x00\x00\x00\x00\x00\x00"
258 : "\x3f\x3f\x3f\x3f\x3f\x3f\x3f\x3f"
259 : "\xb8\x82\x3a\xf1\xb3\xdd\x08\x15"
260 : "\x00\x00\x00\x00\x11\xa2\x08\x81"
261 : "\x50\x38\x22\x78\x2b\x94\x47\xfe"
262 : "\x54\x94\x7b\xff\x17\x27\x5a\xb4"
263 : "\xf4\x18\xba\xdc\x2c\x38\xfd\x5b"
264 : "\xfb\x0e\xc1\x85\x1e\xcc\x92\xbb"
265 : "\x9b\xb1\xc4\xd5\x53\x14\xff\x8c"
266 : "\x76\x49\xf5\x45\x90\x19\xa2";
267 276 : NTTIME timestamp = BVAL(netapp_magic, 8);
268 276 : DATA_BLOB names_blob = data_blob_string_const(netapp_magic + 28);
269 48 : DATA_BLOB chal, lm_resp, nt_resp;
270 48 : int i;
271 276 : int flags = CLI_CRED_NTLM_AUTH;
272 276 : struct dcerpc_binding_handle *b = p->binding_handle;
273 48 : struct netr_UserSessionKey key;
274 48 : struct netr_LMSessionKey LMSessKey;
275 276 : uint32_t validation_levels[] = { 2, 3 };
276 276 : struct netr_SamBaseInfo *base = NULL;
277 276 : const char *crypto_alg = "";
278 276 : bool can_do_validation_6 = true;
279 276 : enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE;
280 :
281 276 : flags |= CLI_CRED_NTLMv2_AUTH;
282 :
283 276 : cli_credentials_get_ntlm_username_domain(samba_cmdline_get_creds(),
284 : tctx,
285 : &ninfo.identity_info.account_name.string,
286 : &ninfo.identity_info.domain_name.string);
287 :
288 276 : generate_random_buffer(ninfo.challenge,
289 : sizeof(ninfo.challenge));
290 :
291 276 : chal = data_blob_const(ninfo.challenge,
292 : sizeof(ninfo.challenge));
293 :
294 276 : status = cli_credentials_get_ntlm_response(
295 : samba_cmdline_get_creds(),
296 : tctx,
297 : &flags,
298 : chal,
299 : ×tamp,
300 : names_blob,
301 : &lm_resp, &nt_resp,
302 : NULL, NULL);
303 276 : torture_assert_ntstatus_ok(tctx, status,
304 : "cli_credentials_get_ntlm_response failed");
305 :
306 276 : ninfo.lm.data = lm_resp.data;
307 276 : ninfo.lm.length = lm_resp.length;
308 :
309 276 : ninfo.nt.data = nt_resp.data;
310 276 : ninfo.nt.length = nt_resp.length;
311 :
312 276 : ninfo.identity_info.parameter_control = 0;
313 276 : ninfo.identity_info.logon_id = 0;
314 276 : ninfo.identity_info.workstation.string = cli_credentials_get_workstation(credentials);
315 :
316 276 : logon.network = &ninfo;
317 :
318 276 : r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
319 276 : r.in.computer_name = cli_credentials_get_workstation(credentials);
320 276 : r.in.logon_level = NetlogonNetworkInformation;
321 276 : r.in.logon= &logon;
322 276 : r.in.flags = &_flags;
323 276 : r.out.validation = &validation;
324 276 : r.out.authoritative = &authoritative;
325 276 : r.out.flags = &_flags;
326 :
327 : /*
328 : - retrieve level6
329 : - save usrsession and lmsession key
330 : - retrieve level 2
331 : - calculate, compare
332 : - retrieve level 3
333 : - calculate, compare
334 : */
335 :
336 276 : if (creds != NULL) {
337 276 : if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
338 152 : crypto_alg = "AES";
339 92 : } else if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
340 92 : crypto_alg = "ARCFOUR";
341 : }
342 : }
343 :
344 276 : dcerpc_binding_handle_auth_info(b, NULL, &auth_level);
345 276 : if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
346 138 : r.in.validation_level = 6;
347 :
348 138 : torture_comment(tctx,
349 : "Testing LogonSamLogonEx with name %s using %s and validation_level: %d\n",
350 : ninfo.identity_info.account_name.string, crypto_alg,
351 114 : r.in.validation_level);
352 :
353 138 : torture_assert_ntstatus_ok(tctx,
354 : dcerpc_netr_LogonSamLogonEx_r(b, tctx, &r),
355 : "LogonSamLogonEx failed");
356 : } else {
357 138 : torture_comment(tctx,
358 : "Skip auth_level[%u] Testing LogonSamLogonEx with name %s using %s and validation_level: %d\n",
359 : auth_level, ninfo.identity_info.account_name.string, crypto_alg,
360 138 : r.in.validation_level);
361 138 : r.out.result = NT_STATUS_INVALID_INFO_CLASS;
362 : }
363 :
364 276 : if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_INFO_CLASS)) {
365 126 : can_do_validation_6 = false;
366 : } else {
367 126 : torture_assert_ntstatus_ok(tctx, r.out.result,
368 : "LogonSamLogonEx failed");
369 :
370 126 : key = r.out.validation->sam6->base.key;
371 126 : LMSessKey = r.out.validation->sam6->base.LMSessKey;
372 :
373 126 : DEBUG(1,("unencrypted session keys from validation_level 6:\n"));
374 126 : dump_data(1, r.out.validation->sam6->base.key.key, 16);
375 126 : dump_data(1, r.out.validation->sam6->base.LMSessKey.key, 8);
376 : }
377 :
378 828 : for (i=0; i < ARRAY_SIZE(validation_levels); i++) {
379 :
380 552 : r.in.validation_level = validation_levels[i];
381 :
382 552 : torture_comment(tctx,
383 : "Testing LogonSamLogonEx with name %s using %s and validation_level: %d\n",
384 : ninfo.identity_info.account_name.string, crypto_alg,
385 456 : r.in.validation_level);
386 :
387 552 : torture_assert_ntstatus_ok(tctx,
388 : dcerpc_netr_LogonSamLogonEx_r(b, tctx, &r),
389 : "LogonSamLogonEx failed");
390 552 : torture_assert_ntstatus_ok(tctx, r.out.result,
391 : "LogonSamLogonEx failed");
392 :
393 552 : if (creds == NULL) {
394 : /* when this test is called without creds no point in
395 : * testing the session keys */
396 0 : continue;
397 : }
398 :
399 552 : switch (validation_levels[i]) {
400 276 : case 2:
401 276 : base = &r.out.validation->sam2->base;
402 276 : break;
403 276 : case 3:
404 276 : base = &r.out.validation->sam3->base;
405 276 : break;
406 0 : default:
407 0 : break;
408 : }
409 :
410 552 : DEBUG(1,("encrypted keys validation_level %d:\n",
411 : validation_levels[i]));
412 552 : dump_data(1, base->key.key, 16);
413 552 : dump_data(1, base->LMSessKey.key, 8);
414 :
415 552 : if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
416 368 : netlogon_creds_aes_decrypt(creds, base->key.key, 16);
417 368 : netlogon_creds_aes_decrypt(creds, base->LMSessKey.key, 8);
418 184 : } else if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
419 184 : netlogon_creds_arcfour_crypt(creds, base->key.key, 16);
420 184 : netlogon_creds_arcfour_crypt(creds, base->LMSessKey.key, 8);
421 : }
422 :
423 552 : DEBUG(1,("decrypted keys validation_level %d\n",
424 : validation_levels[i]));
425 :
426 552 : dump_data(1, base->key.key, 16);
427 552 : dump_data(1, base->LMSessKey.key, 8);
428 :
429 552 : if (!can_do_validation_6) {
430 : /* we can't compare against unencrypted keys */
431 300 : continue;
432 : }
433 :
434 252 : torture_assert_mem_equal(tctx,
435 : base->key.key,
436 : key.key,
437 : 16,
438 : "unexpected user session key\n");
439 300 : torture_assert_mem_equal(tctx,
440 : base->LMSessKey.key,
441 : LMSessKey.key,
442 : 8,
443 : "unexpected LM session key\n");
444 : }
445 :
446 228 : return true;
447 : }
448 :
449 : /*
450 : do some samr ops using the schannel connection
451 : */
452 552 : static bool test_samr_ops(struct torture_context *tctx,
453 : struct dcerpc_binding_handle *b)
454 : {
455 96 : struct samr_GetDomPwInfo r;
456 96 : struct samr_PwInfo info;
457 96 : struct samr_Connect connect_r;
458 96 : struct samr_OpenDomain opendom;
459 96 : int i;
460 96 : struct lsa_String name;
461 96 : struct policy_handle handle;
462 96 : struct policy_handle domain_handle;
463 :
464 552 : name.string = lpcfg_workgroup(tctx->lp_ctx);
465 552 : r.in.domain_name = &name;
466 552 : r.out.info = &info;
467 :
468 552 : connect_r.in.system_name = 0;
469 552 : connect_r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
470 552 : connect_r.out.connect_handle = &handle;
471 :
472 552 : torture_comment(tctx, "Testing Connect and OpenDomain on BUILTIN\n");
473 :
474 552 : torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect_r(b, tctx, &connect_r),
475 : "Connect failed");
476 552 : if (!NT_STATUS_IS_OK(connect_r.out.result)) {
477 0 : if (NT_STATUS_EQUAL(connect_r.out.result, NT_STATUS_ACCESS_DENIED)) {
478 0 : torture_comment(tctx, "Connect failed (expected, schannel mapped to anonymous): %s\n",
479 : nt_errstr(connect_r.out.result));
480 : } else {
481 0 : torture_comment(tctx, "Connect failed - %s\n", nt_errstr(connect_r.out.result));
482 0 : return false;
483 : }
484 : } else {
485 552 : opendom.in.connect_handle = &handle;
486 552 : opendom.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
487 552 : opendom.in.sid = dom_sid_parse_talloc(tctx, "S-1-5-32");
488 552 : opendom.out.domain_handle = &domain_handle;
489 :
490 552 : torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenDomain_r(b, tctx, &opendom),
491 : "OpenDomain failed");
492 552 : if (!NT_STATUS_IS_OK(opendom.out.result)) {
493 0 : torture_comment(tctx, "OpenDomain failed - %s\n", nt_errstr(opendom.out.result));
494 0 : return false;
495 : }
496 : }
497 :
498 552 : torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
499 :
500 : /* do several ops to test credential chaining */
501 3408 : for (i=0;i<5;i++) {
502 2760 : torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDomPwInfo_r(b, tctx, &r),
503 : "GetDomPwInfo failed");
504 2760 : if (!NT_STATUS_IS_OK(r.out.result)) {
505 0 : if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED)) {
506 0 : torture_comment(tctx, "GetDomPwInfo op %d failed - %s\n", i, nt_errstr(r.out.result));
507 0 : return false;
508 : }
509 : }
510 : }
511 :
512 456 : return true;
513 : }
514 :
515 :
516 : /*
517 : do some lsa ops using the schannel connection
518 : */
519 276 : static bool test_lsa_ops(struct torture_context *tctx, struct dcerpc_pipe *p)
520 : {
521 48 : struct lsa_GetUserName r;
522 276 : bool ret = true;
523 276 : struct lsa_String *account_name_p = NULL;
524 276 : struct lsa_String *authority_name_p = NULL;
525 276 : struct dcerpc_binding_handle *b = p->binding_handle;
526 :
527 276 : torture_comment(tctx, "\nTesting GetUserName\n");
528 :
529 276 : r.in.system_name = "\\";
530 276 : r.in.account_name = &account_name_p;
531 276 : r.in.authority_name = &authority_name_p;
532 276 : r.out.account_name = &account_name_p;
533 :
534 : /* do several ops to test credential chaining and various operations */
535 276 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_GetUserName_r(b, tctx, &r),
536 : "lsa_GetUserName failed");
537 :
538 276 : authority_name_p = *r.out.authority_name;
539 :
540 276 : if (!NT_STATUS_IS_OK(r.out.result)) {
541 0 : torture_comment(tctx, "GetUserName failed - %s\n", nt_errstr(r.out.result));
542 0 : return false;
543 : } else {
544 276 : if (!r.out.account_name) {
545 0 : return false;
546 : }
547 :
548 276 : if (strcmp(account_name_p->string, "ANONYMOUS LOGON") != 0) {
549 24 : torture_comment(tctx, "GetUserName returned wrong user: %s, expected %s\n",
550 24 : account_name_p->string, "ANONYMOUS LOGON");
551 : /* FIXME: gd */
552 24 : if (!torture_setting_bool(tctx, "samba3", false)) {
553 0 : return false;
554 : }
555 : }
556 276 : if (!authority_name_p || !authority_name_p->string) {
557 0 : return false;
558 : }
559 :
560 276 : if (strcmp(authority_name_p->string, "NT AUTHORITY") != 0) {
561 24 : torture_comment(tctx, "GetUserName returned wrong user: %s, expected %s\n",
562 24 : authority_name_p->string, "NT AUTHORITY");
563 : /* FIXME: gd */
564 24 : if (!torture_setting_bool(tctx, "samba3", false)) {
565 0 : return false;
566 : }
567 : }
568 : }
569 :
570 228 : return ret;
571 : }
572 :
573 :
574 : /*
575 : test a schannel connection with the given flags
576 : */
577 276 : static bool test_schannel(struct torture_context *tctx,
578 : uint16_t acct_flags, uint32_t dcerpc_flags,
579 : int i)
580 : {
581 48 : struct test_join *join_ctx;
582 48 : NTSTATUS status;
583 276 : const char *binding = torture_setting_string(tctx, "binding", NULL);
584 48 : struct dcerpc_binding *b;
585 276 : struct dcerpc_pipe *p = NULL;
586 276 : struct dcerpc_pipe *p_netlogon = NULL;
587 276 : struct dcerpc_pipe *p_netlogon2 = NULL;
588 276 : struct dcerpc_pipe *p_netlogon3 = NULL;
589 276 : struct dcerpc_pipe *p_samr2 = NULL;
590 276 : struct dcerpc_pipe *p_lsa = NULL;
591 48 : struct netlogon_creds_CredentialState *creds;
592 48 : struct cli_credentials *credentials;
593 48 : enum dcerpc_transport_t transport;
594 :
595 276 : join_ctx = torture_join_domain(tctx,
596 276 : talloc_asprintf(tctx, "%s%d", TEST_MACHINE_NAME, i),
597 : acct_flags, &credentials);
598 276 : torture_assert(tctx, join_ctx != NULL, "Failed to join domain");
599 :
600 276 : status = dcerpc_parse_binding(tctx, binding, &b);
601 276 : torture_assert_ntstatus_ok(tctx, status, "Bad binding string");
602 :
603 276 : status = dcerpc_binding_set_flags(b, dcerpc_flags, DCERPC_AUTH_OPTIONS);
604 276 : torture_assert_ntstatus_ok(tctx, status, "set flags");
605 :
606 276 : status = dcerpc_pipe_connect_b(tctx, &p, b, &ndr_table_samr,
607 : credentials, tctx->ev, tctx->lp_ctx);
608 276 : torture_assert_ntstatus_ok(tctx, status,
609 : "Failed to connect to samr with schannel");
610 :
611 276 : torture_assert(tctx, test_samr_ops(tctx, p->binding_handle),
612 : "Failed to process schannel secured SAMR ops");
613 :
614 : /* Also test that when we connect to the netlogon pipe, that
615 : * the credentials we setup on the first pipe are valid for
616 : * the second */
617 :
618 : /* Swap the binding details from SAMR to NETLOGON */
619 276 : status = dcerpc_epm_map_binding(tctx, b, &ndr_table_netlogon, tctx->ev, tctx->lp_ctx);
620 276 : torture_assert_ntstatus_ok(tctx, status, "epm map");
621 :
622 276 : status = dcerpc_binding_set_flags(b, dcerpc_flags, DCERPC_AUTH_OPTIONS);
623 276 : torture_assert_ntstatus_ok(tctx, status, "set flags");
624 :
625 276 : status = dcerpc_secondary_auth_connection(p, b, &ndr_table_netlogon,
626 : credentials, tctx->lp_ctx,
627 : tctx, &p_netlogon);
628 276 : torture_assert_ntstatus_ok(tctx, status, "Failed to create secondary connection");
629 :
630 276 : creds = cli_credentials_get_netlogon_creds(credentials);
631 276 : torture_assert(tctx, (creds != NULL), "schannel creds");
632 :
633 : /* checks the capabilities */
634 276 : torture_assert(tctx, test_netlogon_capabilities(p_netlogon, tctx, credentials, creds),
635 : "Failed to process schannel secured capability ops (on fresh connection)");
636 :
637 : /* do a couple of logins */
638 276 : torture_assert(tctx, test_netlogon_ops(p_netlogon, tctx, credentials, creds),
639 : "Failed to process schannel secured NETLOGON ops");
640 :
641 276 : torture_assert(tctx, test_netlogon_ex_ops(p_netlogon, tctx, credentials, creds),
642 : "Failed to process schannel secured NETLOGON EX ops");
643 :
644 : /* regression test for https://bugzilla.samba.org/show_bug.cgi?id=14932 */
645 276 : torture_assert(tctx, test_netlogon_ex_bug14932(p_netlogon, tctx, credentials, creds),
646 : "Failed to process schannel secured NETLOGON EX for BUG 14932");
647 :
648 : /* we *MUST* use ncacn_np for openpolicy etc. */
649 276 : transport = dcerpc_binding_get_transport(b);
650 276 : status = dcerpc_binding_set_transport(b, NCACN_NP);
651 276 : torture_assert_ntstatus_ok(tctx, status, "set transport");
652 :
653 : /* Swap the binding details from SAMR to LSARPC */
654 276 : status = dcerpc_epm_map_binding(tctx, b, &ndr_table_lsarpc, tctx->ev, tctx->lp_ctx);
655 276 : torture_assert_ntstatus_ok(tctx, status, "epm map");
656 :
657 276 : torture_assert_ntstatus_ok(tctx,
658 : dcerpc_pipe_connect_b(tctx, &p_lsa, b, &ndr_table_lsarpc,
659 : credentials, tctx->ev, tctx->lp_ctx),
660 : "failed to connect lsarpc with schannel");
661 :
662 276 : torture_assert(tctx, test_lsa_ops(tctx, p_lsa),
663 : "Failed to process schannel secured LSA ops");
664 :
665 276 : talloc_free(p_lsa);
666 276 : p_lsa = NULL;
667 :
668 : /* we *MUST* use ncacn_ip_tcp for lookupsids3/lookupnames4 */
669 276 : status = dcerpc_binding_set_transport(b, NCACN_IP_TCP);
670 276 : torture_assert_ntstatus_ok(tctx, status, "set transport");
671 :
672 276 : torture_assert_ntstatus_ok(tctx,
673 : dcerpc_epm_map_binding(tctx, b, &ndr_table_lsarpc, tctx->ev, tctx->lp_ctx),
674 : "failed to call epm map");
675 :
676 276 : torture_assert_ntstatus_ok(tctx,
677 : dcerpc_pipe_connect_b(tctx, &p_lsa, b, &ndr_table_lsarpc,
678 : credentials, tctx->ev, tctx->lp_ctx),
679 : "failed to connect lsarpc with schannel");
680 :
681 276 : torture_assert(tctx,
682 : test_many_LookupSids(p_lsa, tctx, NULL, LSA_LOOKUP_NAMES_ALL),
683 : "LsaLookupSids3 failed!\n");
684 :
685 276 : status = dcerpc_binding_set_transport(b, transport);
686 276 : torture_assert_ntstatus_ok(tctx, status, "set transport");
687 :
688 :
689 : /* Drop the socket, we want to start from scratch */
690 276 : talloc_free(p);
691 276 : p = NULL;
692 :
693 : /* Now see what we are still allowed to do */
694 :
695 276 : status = dcerpc_parse_binding(tctx, binding, &b);
696 276 : torture_assert_ntstatus_ok(tctx, status, "Bad binding string");
697 :
698 276 : status = dcerpc_binding_set_flags(b, dcerpc_flags, DCERPC_AUTH_OPTIONS);
699 276 : torture_assert_ntstatus_ok(tctx, status, "set flags");
700 :
701 276 : status = dcerpc_pipe_connect_b(tctx, &p_samr2, b, &ndr_table_samr,
702 : credentials, tctx->ev, tctx->lp_ctx);
703 276 : torture_assert_ntstatus_ok(tctx, status,
704 : "Failed to connect with schannel");
705 :
706 : /* do a some SAMR operations. We have *not* done a new serverauthenticate */
707 276 : torture_assert (tctx, test_samr_ops(tctx, p_samr2->binding_handle),
708 : "Failed to process schannel secured SAMR ops (on fresh connection)");
709 :
710 : /* Swap the binding details from SAMR to NETLOGON */
711 276 : status = dcerpc_epm_map_binding(tctx, b, &ndr_table_netlogon, tctx->ev, tctx->lp_ctx);
712 276 : torture_assert_ntstatus_ok(tctx, status, "epm");
713 :
714 276 : status = dcerpc_binding_set_flags(b, dcerpc_flags, DCERPC_AUTH_OPTIONS);
715 276 : torture_assert_ntstatus_ok(tctx, status, "set flags");
716 :
717 276 : status = dcerpc_secondary_auth_connection(p_samr2, b, &ndr_table_netlogon,
718 : credentials, tctx->lp_ctx,
719 : tctx, &p_netlogon2);
720 276 : torture_assert_ntstatus_ok(tctx, status, "Failed to create secondary connection");
721 :
722 : /* checks the capabilities */
723 276 : torture_assert(tctx, test_netlogon_capabilities(p_netlogon2, tctx, credentials, creds),
724 : "Failed to process schannel secured capability ops (on fresh connection)");
725 :
726 : /* Try the schannel-only SamLogonEx operation */
727 276 : torture_assert(tctx, test_netlogon_ex_ops(p_netlogon2, tctx, credentials, creds),
728 : "Failed to process schannel secured NETLOGON EX ops (on fresh connection)");
729 :
730 :
731 : /* And the more traditional style, proving that the
732 : * credentials chaining state is fully present */
733 276 : torture_assert(tctx, test_netlogon_ops(p_netlogon2, tctx, credentials, creds),
734 : "Failed to process schannel secured NETLOGON ops (on fresh connection)");
735 :
736 : /* Drop the socket, we want to start from scratch (again) */
737 276 : talloc_free(p_samr2);
738 :
739 : /* We don't want schannel for this test */
740 276 : status = dcerpc_binding_set_flags(b, 0, DCERPC_AUTH_OPTIONS);
741 276 : torture_assert_ntstatus_ok(tctx, status, "set flags");
742 :
743 276 : status = dcerpc_pipe_connect_b(tctx, &p_netlogon3, b, &ndr_table_netlogon,
744 : credentials, tctx->ev, tctx->lp_ctx);
745 276 : torture_assert_ntstatus_ok(tctx, status, "Failed to connect without schannel");
746 :
747 276 : torture_assert(tctx, !test_netlogon_ex_ops(p_netlogon3, tctx, credentials, creds),
748 : "Processed NOT schannel secured NETLOGON EX ops without SCHANNEL (unsafe)");
749 :
750 : /* Required because the previous call will mark the current context as having failed */
751 276 : tctx->last_result = TORTURE_OK;
752 276 : tctx->last_reason = NULL;
753 :
754 276 : torture_assert(tctx, test_netlogon_ops(p_netlogon3, tctx, credentials, creds),
755 : "Failed to processed NOT schannel secured NETLOGON ops without new ServerAuth");
756 :
757 276 : torture_leave_domain(tctx, join_ctx);
758 276 : return true;
759 : }
760 :
761 : /*
762 : * Purpose of this test is to demonstrate that a netlogon server carefully deals
763 : * with anonymous attempts to set passwords, in particular when the server
764 : * enforces the use of schannel. This test makes most sense to be run in an
765 : * environment where the netlogon server enforces use of schannel.
766 : */
767 :
768 20 : static bool test_schannel_anonymous_setPassword(struct torture_context *tctx,
769 : uint32_t dcerpc_flags,
770 : bool use2)
771 : {
772 2 : NTSTATUS status, result;
773 20 : const char *binding = torture_setting_string(tctx, "binding", NULL);
774 2 : struct dcerpc_binding *b;
775 20 : struct dcerpc_pipe *p = NULL;
776 2 : struct cli_credentials *credentials;
777 20 : bool ok = true;
778 :
779 20 : credentials = cli_credentials_init(NULL);
780 20 : torture_assert(tctx, credentials != NULL, "Bad credentials");
781 20 : cli_credentials_set_anonymous(credentials);
782 :
783 20 : status = dcerpc_parse_binding(tctx, binding, &b);
784 20 : torture_assert_ntstatus_ok(tctx, status, "Bad binding string");
785 :
786 20 : status = dcerpc_binding_set_flags(b, dcerpc_flags, DCERPC_AUTH_OPTIONS);
787 20 : torture_assert_ntstatus_ok(tctx, status, "set flags");
788 :
789 20 : status = dcerpc_pipe_connect_b(tctx,
790 : &p,
791 : b,
792 : &ndr_table_netlogon,
793 : credentials,
794 : tctx->ev,
795 : tctx->lp_ctx);
796 20 : torture_assert_ntstatus_ok(tctx, status, "Failed to connect without schannel");
797 :
798 20 : if (use2) {
799 10 : struct netr_ServerPasswordSet2 r = {};
800 10 : struct netr_Authenticator credential = {};
801 10 : struct netr_Authenticator return_authenticator = {};
802 10 : struct netr_CryptPassword new_password = {};
803 :
804 10 : r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
805 10 : r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
806 10 : r.in.secure_channel_type = 0;
807 10 : r.in.computer_name = TEST_MACHINE_NAME;
808 10 : r.in.credential = &credential;
809 10 : r.in.new_password = &new_password;
810 10 : r.out.return_authenticator = &return_authenticator;
811 :
812 10 : status = dcerpc_netr_ServerPasswordSet2_r(p->binding_handle, tctx, &r);
813 10 : result = r.out.result;
814 : } else {
815 10 : struct netr_ServerPasswordSet r = {};
816 10 : struct netr_Authenticator credential = {};
817 10 : struct netr_Authenticator return_authenticator = {};
818 10 : struct samr_Password new_password = {};
819 :
820 10 : r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
821 10 : r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
822 10 : r.in.secure_channel_type = 0;
823 10 : r.in.computer_name = TEST_MACHINE_NAME;
824 10 : r.in.credential = &credential;
825 10 : r.in.new_password = &new_password;
826 10 : r.out.return_authenticator = &return_authenticator;
827 :
828 10 : status = dcerpc_netr_ServerPasswordSet_r(p->binding_handle, tctx, &r);
829 10 : result = r.out.result;
830 : }
831 :
832 20 : torture_assert_ntstatus_ok(tctx, status, "ServerPasswordSet failed");
833 :
834 20 : if (NT_STATUS_IS_OK(result)) {
835 0 : torture_fail(tctx, "unexpectedly received NT_STATUS_OK");
836 : }
837 :
838 18 : return ok;
839 : }
840 :
841 :
842 : /*
843 : a schannel test suite
844 : */
845 23 : bool torture_rpc_schannel(struct torture_context *torture)
846 : {
847 23 : bool ret = true;
848 4 : struct {
849 : uint16_t acct_flags;
850 : uint32_t dcerpc_flags;
851 23 : } tests[] = {
852 : { ACB_WSTRUST, DCERPC_SCHANNEL | DCERPC_SIGN | DCERPC_SCHANNEL_AUTO},
853 : { ACB_WSTRUST, DCERPC_SCHANNEL | DCERPC_SEAL | DCERPC_SCHANNEL_AUTO},
854 : { ACB_WSTRUST, DCERPC_SCHANNEL | DCERPC_SIGN | DCERPC_SCHANNEL_128},
855 : { ACB_WSTRUST, DCERPC_SCHANNEL | DCERPC_SEAL | DCERPC_SCHANNEL_128 },
856 : { ACB_WSTRUST, DCERPC_SCHANNEL | DCERPC_SIGN | DCERPC_SCHANNEL_AES},
857 : { ACB_WSTRUST, DCERPC_SCHANNEL | DCERPC_SEAL | DCERPC_SCHANNEL_AES },
858 : { ACB_SVRTRUST, DCERPC_SCHANNEL | DCERPC_SIGN | DCERPC_SCHANNEL_AUTO},
859 : { ACB_SVRTRUST, DCERPC_SCHANNEL | DCERPC_SEAL | DCERPC_SCHANNEL_AUTO},
860 : { ACB_SVRTRUST, DCERPC_SCHANNEL | DCERPC_SIGN | DCERPC_SCHANNEL_128 },
861 : { ACB_SVRTRUST, DCERPC_SCHANNEL | DCERPC_SEAL | DCERPC_SCHANNEL_128 },
862 : { ACB_SVRTRUST, DCERPC_SCHANNEL | DCERPC_SIGN | DCERPC_SCHANNEL_AES },
863 : { ACB_SVRTRUST, DCERPC_SCHANNEL | DCERPC_SEAL | DCERPC_SCHANNEL_AES }
864 : };
865 4 : int i;
866 :
867 299 : for (i=0;i<ARRAY_SIZE(tests);i++) {
868 276 : torture_comment(torture, "Testing with acct_flags=0x%x dcerpc_flags=0x%x \n",
869 276 : tests[i].acct_flags, tests[i].dcerpc_flags);
870 :
871 276 : if (!test_schannel(torture,
872 228 : tests[i].acct_flags, tests[i].dcerpc_flags,
873 : i)) {
874 0 : torture_comment(torture, "Failed with acct_flags=0x%x dcerpc_flags=0x%x \n",
875 0 : tests[i].acct_flags, tests[i].dcerpc_flags);
876 0 : ret = false;
877 : }
878 : }
879 :
880 23 : return ret;
881 : }
882 :
883 10 : bool torture_rpc_schannel_anon_setpw(struct torture_context *torture)
884 : {
885 10 : bool ret = true;
886 1 : bool ok;
887 10 : uint32_t dcerpc_flags = DCERPC_SCHANNEL | DCERPC_SIGN | DCERPC_SCHANNEL_AUTO;
888 :
889 10 : ok = test_schannel_anonymous_setPassword(torture,
890 : dcerpc_flags,
891 : true);
892 10 : if (!ok) {
893 0 : torture_comment(torture,
894 : "Failed with dcerpc_flags=0x%x\n",
895 : dcerpc_flags);
896 0 : ret = false;
897 : }
898 :
899 10 : ok = test_schannel_anonymous_setPassword(torture,
900 : dcerpc_flags,
901 : false);
902 10 : if (!ok) {
903 0 : torture_comment(torture,
904 : "Failed with dcerpc_flags=0x%x\n",
905 : dcerpc_flags);
906 0 : ret = false;
907 : }
908 :
909 10 : return ret;
910 : }
911 :
912 : /*
913 : test two schannel connections
914 : */
915 23 : bool torture_rpc_schannel2(struct torture_context *torture)
916 : {
917 4 : struct test_join *join_ctx;
918 4 : NTSTATUS status;
919 23 : const char *binding = torture_setting_string(torture, "binding", NULL);
920 4 : struct dcerpc_binding *b;
921 23 : struct dcerpc_pipe *p1 = NULL, *p2 = NULL;
922 4 : struct cli_credentials *credentials1, *credentials2;
923 23 : uint32_t dcerpc_flags = DCERPC_SCHANNEL | DCERPC_SCHANNEL_AUTO | DCERPC_SIGN;
924 :
925 23 : join_ctx = torture_join_domain(torture, talloc_asprintf(torture, "%s2", TEST_MACHINE_NAME),
926 : ACB_WSTRUST, &credentials1);
927 23 : torture_assert(torture, join_ctx != NULL,
928 : "Failed to join domain with acct_flags=ACB_WSTRUST");
929 :
930 23 : credentials2 = cli_credentials_shallow_copy(torture, credentials1);
931 23 : cli_credentials_set_netlogon_creds(credentials1, NULL);
932 23 : cli_credentials_set_netlogon_creds(credentials2, NULL);
933 :
934 23 : status = dcerpc_parse_binding(torture, binding, &b);
935 23 : torture_assert_ntstatus_ok(torture, status, "Bad binding string");
936 :
937 23 : status = dcerpc_binding_set_flags(b, dcerpc_flags, DCERPC_AUTH_OPTIONS);
938 23 : torture_assert_ntstatus_ok(torture, status, "set flags");
939 :
940 23 : torture_comment(torture, "Opening first connection\n");
941 23 : status = dcerpc_pipe_connect_b(torture, &p1, b, &ndr_table_netlogon,
942 : credentials1, torture->ev, torture->lp_ctx);
943 23 : torture_assert_ntstatus_ok(torture, status, "Failed to connect with schannel");
944 :
945 23 : torture_comment(torture, "Opening second connection\n");
946 23 : status = dcerpc_pipe_connect_b(torture, &p2, b, &ndr_table_netlogon,
947 : credentials2, torture->ev, torture->lp_ctx);
948 23 : torture_assert_ntstatus_ok(torture, status, "Failed to connect with schannel");
949 :
950 23 : cli_credentials_set_netlogon_creds(credentials1, NULL);
951 23 : cli_credentials_set_netlogon_creds(credentials2, NULL);
952 :
953 23 : torture_comment(torture, "Testing logon on pipe1\n");
954 23 : if (!test_netlogon_ex_ops(p1, torture, credentials1, NULL))
955 0 : return false;
956 :
957 23 : torture_comment(torture, "Testing logon on pipe2\n");
958 23 : if (!test_netlogon_ex_ops(p2, torture, credentials2, NULL))
959 0 : return false;
960 :
961 23 : torture_comment(torture, "Again on pipe1\n");
962 23 : if (!test_netlogon_ex_ops(p1, torture, credentials1, NULL))
963 0 : return false;
964 :
965 23 : torture_comment(torture, "Again on pipe2\n");
966 23 : if (!test_netlogon_ex_ops(p2, torture, credentials2, NULL))
967 0 : return false;
968 :
969 23 : torture_leave_domain(torture, join_ctx);
970 23 : return true;
971 : }
972 :
973 : struct torture_schannel_bench;
974 :
975 : struct torture_schannel_bench_conn {
976 : struct torture_schannel_bench *s;
977 : int index;
978 : struct cli_credentials *wks_creds;
979 : struct dcerpc_pipe *pipe;
980 : struct netr_LogonSamLogonEx r;
981 : struct netr_NetworkInfo ninfo;
982 : TALLOC_CTX *tmp;
983 : uint64_t total;
984 : uint32_t count;
985 : };
986 :
987 : struct torture_schannel_bench {
988 : struct torture_context *tctx;
989 : bool progress;
990 : int timelimit;
991 : int nprocs;
992 : int nconns;
993 : struct torture_schannel_bench_conn *conns;
994 : struct test_join *join_ctx1;
995 : struct cli_credentials *wks_creds1;
996 : struct test_join *join_ctx2;
997 : struct cli_credentials *wks_creds2;
998 : struct cli_credentials *user1_creds;
999 : struct cli_credentials *user2_creds;
1000 : struct dcerpc_binding *b;
1001 : NTSTATUS error;
1002 : uint64_t total;
1003 : uint32_t count;
1004 : bool stopped;
1005 : };
1006 :
1007 : #if 0
1008 : static void torture_schannel_bench_connected(struct composite_context *c)
1009 : {
1010 : struct torture_schannel_bench_conn *conn =
1011 : (struct torture_schannel_bench_conn *)c->async.private_data;
1012 : struct torture_schannel_bench *s = talloc_get_type(conn->s,
1013 : struct torture_schannel_bench);
1014 :
1015 : s->error = dcerpc_pipe_connect_b_recv(c, s->conns, &conn->pipe);
1016 : torture_comment(s->tctx, "conn[%u]: %s\n", conn->index, nt_errstr(s->error));
1017 : if (NT_STATUS_IS_OK(s->error)) {
1018 : s->nconns++;
1019 : }
1020 : }
1021 : #endif
1022 :
1023 : static void torture_schannel_bench_recv(struct tevent_req *subreq);
1024 :
1025 0 : static bool torture_schannel_bench_start(struct torture_schannel_bench_conn *conn)
1026 : {
1027 0 : struct torture_schannel_bench *s = conn->s;
1028 0 : NTSTATUS status;
1029 0 : DATA_BLOB names_blob, chal, lm_resp, nt_resp;
1030 0 : int flags = CLI_CRED_NTLM_AUTH;
1031 0 : struct tevent_req *subreq;
1032 0 : struct cli_credentials *user_creds;
1033 :
1034 0 : if (conn->total % 2) {
1035 0 : user_creds = s->user1_creds;
1036 : } else {
1037 0 : user_creds = s->user2_creds;
1038 : }
1039 :
1040 0 : if (lpcfg_client_lanman_auth(s->tctx->lp_ctx)) {
1041 0 : flags |= CLI_CRED_LANMAN_AUTH;
1042 : }
1043 :
1044 0 : if (lpcfg_client_ntlmv2_auth(s->tctx->lp_ctx)) {
1045 0 : flags |= CLI_CRED_NTLMv2_AUTH;
1046 : }
1047 :
1048 0 : talloc_free(conn->tmp);
1049 0 : conn->tmp = talloc_new(s);
1050 0 : ZERO_STRUCT(conn->ninfo);
1051 0 : ZERO_STRUCT(conn->r);
1052 :
1053 0 : cli_credentials_get_ntlm_username_domain(user_creds, conn->tmp,
1054 : &conn->ninfo.identity_info.account_name.string,
1055 : &conn->ninfo.identity_info.domain_name.string);
1056 :
1057 0 : generate_random_buffer(conn->ninfo.challenge,
1058 : sizeof(conn->ninfo.challenge));
1059 0 : chal = data_blob_const(conn->ninfo.challenge,
1060 : sizeof(conn->ninfo.challenge));
1061 :
1062 0 : names_blob = NTLMv2_generate_names_blob(conn->tmp,
1063 : cli_credentials_get_workstation(conn->wks_creds),
1064 : cli_credentials_get_domain(conn->wks_creds));
1065 :
1066 0 : status = cli_credentials_get_ntlm_response(user_creds, conn->tmp,
1067 : &flags,
1068 : chal,
1069 : NULL, /* server_timestamp */
1070 : names_blob,
1071 : &lm_resp, &nt_resp,
1072 : NULL, NULL);
1073 0 : torture_assert_ntstatus_ok(s->tctx, status,
1074 : "cli_credentials_get_ntlm_response failed");
1075 :
1076 0 : conn->ninfo.lm.data = lm_resp.data;
1077 0 : conn->ninfo.lm.length = lm_resp.length;
1078 :
1079 0 : conn->ninfo.nt.data = nt_resp.data;
1080 0 : conn->ninfo.nt.length = nt_resp.length;
1081 :
1082 0 : conn->ninfo.identity_info.parameter_control = 0;
1083 0 : conn->ninfo.identity_info.logon_id = 0;
1084 0 : conn->ninfo.identity_info.workstation.string = cli_credentials_get_workstation(conn->wks_creds);
1085 :
1086 0 : conn->r.in.server_name = talloc_asprintf(conn->tmp, "\\\\%s", dcerpc_server_name(conn->pipe));
1087 0 : conn->r.in.computer_name = cli_credentials_get_workstation(conn->wks_creds);
1088 0 : conn->r.in.logon_level = NetlogonNetworkInformation;
1089 0 : conn->r.in.logon = talloc(conn->tmp, union netr_LogonLevel);
1090 0 : conn->r.in.logon->network = &conn->ninfo;
1091 0 : conn->r.in.flags = talloc(conn->tmp, uint32_t);
1092 0 : conn->r.in.validation_level = 2;
1093 0 : conn->r.out.validation = talloc(conn->tmp, union netr_Validation);
1094 0 : conn->r.out.authoritative = talloc(conn->tmp, uint8_t);
1095 0 : conn->r.out.flags = conn->r.in.flags;
1096 :
1097 0 : subreq = dcerpc_netr_LogonSamLogonEx_r_send(s, s->tctx->ev,
1098 0 : conn->pipe->binding_handle,
1099 : &conn->r);
1100 0 : torture_assert(s->tctx, subreq, "Failed to setup LogonSamLogonEx request");
1101 :
1102 0 : tevent_req_set_callback(subreq, torture_schannel_bench_recv, conn);
1103 :
1104 0 : return true;
1105 : }
1106 :
1107 0 : static void torture_schannel_bench_recv(struct tevent_req *subreq)
1108 : {
1109 0 : bool ret;
1110 0 : struct torture_schannel_bench_conn *conn =
1111 0 : (struct torture_schannel_bench_conn *)tevent_req_callback_data_void(subreq);
1112 0 : struct torture_schannel_bench *s = talloc_get_type(conn->s,
1113 : struct torture_schannel_bench);
1114 :
1115 0 : s->error = dcerpc_netr_LogonSamLogonEx_r_recv(subreq, subreq);
1116 0 : TALLOC_FREE(subreq);
1117 0 : if (!NT_STATUS_IS_OK(s->error)) {
1118 0 : return;
1119 : }
1120 :
1121 0 : conn->total++;
1122 0 : conn->count++;
1123 :
1124 0 : if (s->stopped) {
1125 0 : return;
1126 : }
1127 :
1128 0 : ret = torture_schannel_bench_start(conn);
1129 0 : if (!ret) {
1130 0 : s->error = NT_STATUS_INTERNAL_ERROR;
1131 : }
1132 : }
1133 :
1134 : /*
1135 : test multiple schannel connection in parallel
1136 : */
1137 0 : bool torture_rpc_schannel_bench1(struct torture_context *torture)
1138 : {
1139 0 : bool ret = true;
1140 0 : NTSTATUS status;
1141 0 : const char *binding = torture_setting_string(torture, "binding", NULL);
1142 0 : struct torture_schannel_bench *s;
1143 0 : struct timeval start;
1144 0 : struct timeval end;
1145 0 : int i;
1146 0 : const char *tmp;
1147 :
1148 0 : s = talloc_zero(torture, struct torture_schannel_bench);
1149 0 : s->tctx = torture;
1150 0 : s->progress = torture_setting_bool(torture, "progress", true);
1151 0 : s->timelimit = torture_setting_int(torture, "timelimit", 10);
1152 0 : s->nprocs = torture_setting_int(torture, "nprocs", 4);
1153 0 : s->conns = talloc_zero_array(s, struct torture_schannel_bench_conn, s->nprocs);
1154 :
1155 0 : s->user1_creds = cli_credentials_shallow_copy(s,
1156 : samba_cmdline_get_creds());
1157 0 : tmp = torture_setting_string(s->tctx, "extra_user1", NULL);
1158 0 : if (tmp) {
1159 0 : cli_credentials_parse_string(s->user1_creds, tmp, CRED_SPECIFIED);
1160 : }
1161 0 : s->user2_creds = cli_credentials_shallow_copy(s,
1162 : samba_cmdline_get_creds());
1163 0 : tmp = torture_setting_string(s->tctx, "extra_user2", NULL);
1164 0 : if (tmp) {
1165 0 : cli_credentials_parse_string(s->user1_creds, tmp, CRED_SPECIFIED);
1166 : }
1167 :
1168 0 : s->join_ctx1 = torture_join_domain(s->tctx, talloc_asprintf(s, "%sb", TEST_MACHINE_NAME),
1169 : ACB_WSTRUST, &s->wks_creds1);
1170 0 : torture_assert(torture, s->join_ctx1 != NULL,
1171 : "Failed to join domain with acct_flags=ACB_WSTRUST");
1172 0 : s->join_ctx2 = torture_join_domain(s->tctx, talloc_asprintf(s, "%sc", TEST_MACHINE_NAME),
1173 : ACB_WSTRUST, &s->wks_creds2);
1174 0 : torture_assert(torture, s->join_ctx2 != NULL,
1175 : "Failed to join domain with acct_flags=ACB_WSTRUST");
1176 :
1177 0 : cli_credentials_set_kerberos_state(s->wks_creds1,
1178 : CRED_USE_KERBEROS_DISABLED,
1179 : CRED_SPECIFIED);
1180 0 : cli_credentials_set_kerberos_state(s->wks_creds2,
1181 : CRED_USE_KERBEROS_DISABLED,
1182 : CRED_SPECIFIED);
1183 :
1184 0 : for (i=0; i < s->nprocs; i++) {
1185 0 : struct cli_credentials *wks = s->wks_creds1;
1186 :
1187 0 : if ((i % 2) && (torture_setting_bool(torture, "multijoin", false))) {
1188 0 : wks = s->wks_creds2;
1189 : }
1190 :
1191 0 : s->conns[i].s = s;
1192 0 : s->conns[i].index = i;
1193 0 : s->conns[i].wks_creds = cli_credentials_shallow_copy(s->conns, wks);
1194 0 : cli_credentials_set_netlogon_creds(s->conns[i].wks_creds, NULL);
1195 : }
1196 :
1197 0 : status = dcerpc_parse_binding(s, binding, &s->b);
1198 0 : torture_assert_ntstatus_ok(torture, status, "Bad binding string");
1199 :
1200 0 : status = dcerpc_binding_set_flags(s->b, DCERPC_SCHANNEL | DCERPC_SIGN,
1201 : DCERPC_AUTH_OPTIONS);
1202 0 : torture_assert_ntstatus_ok(torture, status, "set flags");
1203 :
1204 0 : torture_comment(torture, "Opening %d connections in parallel\n", s->nprocs);
1205 0 : for (i=0; i < s->nprocs; i++) {
1206 : #if 1
1207 0 : s->error = dcerpc_pipe_connect_b(s->conns, &s->conns[i].pipe, s->b,
1208 : &ndr_table_netlogon,
1209 0 : s->conns[i].wks_creds,
1210 : torture->ev, torture->lp_ctx);
1211 0 : torture_assert_ntstatus_ok(torture, s->error, "Failed to connect with schannel");
1212 : #else
1213 : /*
1214 : * This path doesn't work against windows,
1215 : * because of windows drops the connections
1216 : * which haven't reached a session setup yet
1217 : *
1218 : * The same as the reset on zero vc stuff.
1219 : */
1220 : struct composite_context *c;
1221 : c = dcerpc_pipe_connect_b_send(s->conns, s->b,
1222 : &ndr_table_netlogon,
1223 : s->conns[i].wks_creds,
1224 : torture->ev,
1225 : torture->lp_ctx);
1226 : torture_assert(torture, c != NULL, "Failed to setup connect");
1227 : c->async.fn = torture_schannel_bench_connected;
1228 : c->async.private_data = &s->conns[i];
1229 : }
1230 :
1231 : while (NT_STATUS_IS_OK(s->error) && s->nprocs != s->nconns) {
1232 : int ev_ret = tevent_loop_once(torture->ev);
1233 : torture_assert(torture, ev_ret == 0, "tevent_loop_once failed");
1234 : #endif
1235 : }
1236 0 : torture_assert_ntstatus_ok(torture, s->error, "Failed establish a connect");
1237 :
1238 : /*
1239 : * Change the workstation password after establishing the netlogon
1240 : * schannel connections to prove that existing connections are not
1241 : * affected by a wks pwchange.
1242 : */
1243 :
1244 : {
1245 0 : struct netr_ServerPasswordSet pwset;
1246 0 : char *password = generate_random_password(s->join_ctx1, 8, 255);
1247 0 : struct netlogon_creds_CredentialState *creds_state;
1248 0 : struct dcerpc_pipe *net_pipe;
1249 0 : struct netr_Authenticator credential, return_authenticator;
1250 0 : struct samr_Password new_password;
1251 :
1252 0 : status = dcerpc_pipe_connect_b(s, &net_pipe, s->b,
1253 : &ndr_table_netlogon,
1254 : s->wks_creds1,
1255 : torture->ev, torture->lp_ctx);
1256 :
1257 0 : torture_assert_ntstatus_ok(torture, status,
1258 : "dcerpc_pipe_connect_b failed");
1259 :
1260 0 : pwset.in.server_name = talloc_asprintf(
1261 : net_pipe, "\\\\%s", dcerpc_server_name(net_pipe));
1262 0 : pwset.in.computer_name =
1263 0 : cli_credentials_get_workstation(s->wks_creds1);
1264 0 : pwset.in.account_name = talloc_asprintf(
1265 : net_pipe, "%s$", pwset.in.computer_name);
1266 0 : pwset.in.secure_channel_type = SEC_CHAN_WKSTA;
1267 0 : pwset.in.credential = &credential;
1268 0 : pwset.in.new_password = &new_password;
1269 0 : pwset.out.return_authenticator = &return_authenticator;
1270 :
1271 0 : E_md4hash(password, new_password.hash);
1272 :
1273 0 : creds_state = cli_credentials_get_netlogon_creds(
1274 : s->wks_creds1);
1275 0 : netlogon_creds_des_encrypt(creds_state, &new_password);
1276 0 : netlogon_creds_client_authenticator(creds_state, &credential);
1277 :
1278 0 : torture_assert_ntstatus_ok(torture, dcerpc_netr_ServerPasswordSet_r(net_pipe->binding_handle, torture, &pwset),
1279 : "ServerPasswordSet failed");
1280 0 : torture_assert_ntstatus_ok(torture, pwset.out.result,
1281 : "ServerPasswordSet failed");
1282 :
1283 0 : if (!netlogon_creds_client_check(creds_state,
1284 0 : &pwset.out.return_authenticator->cred)) {
1285 0 : torture_comment(torture, "Credential chaining failed\n");
1286 : }
1287 :
1288 0 : cli_credentials_set_password(s->wks_creds1, password,
1289 : CRED_SPECIFIED);
1290 :
1291 0 : talloc_free(net_pipe);
1292 :
1293 : /* Just as a test, connect with the new creds */
1294 :
1295 0 : cli_credentials_set_netlogon_creds(s->wks_creds1, NULL);
1296 :
1297 0 : status = dcerpc_pipe_connect_b(s, &net_pipe, s->b,
1298 : &ndr_table_netlogon,
1299 : s->wks_creds1,
1300 : torture->ev, torture->lp_ctx);
1301 :
1302 0 : torture_assert_ntstatus_ok(torture, status,
1303 : "dcerpc_pipe_connect_b failed");
1304 :
1305 0 : talloc_free(net_pipe);
1306 : }
1307 :
1308 0 : torture_comment(torture, "Start looping LogonSamLogonEx on %d connections for %d secs\n",
1309 : s->nprocs, s->timelimit);
1310 0 : for (i=0; i < s->nprocs; i++) {
1311 0 : ret = torture_schannel_bench_start(&s->conns[i]);
1312 0 : torture_assert(torture, ret, "Failed to setup LogonSamLogonEx");
1313 : }
1314 :
1315 0 : start = timeval_current();
1316 0 : end = timeval_add(&start, s->timelimit, 0);
1317 :
1318 0 : while (NT_STATUS_IS_OK(s->error) && !timeval_expired(&end)) {
1319 0 : int ev_ret = tevent_loop_once(torture->ev);
1320 0 : torture_assert(torture, ev_ret == 0, "tevent_loop_once failed");
1321 : }
1322 0 : torture_assert_ntstatus_ok(torture, s->error, "Failed some request");
1323 0 : s->stopped = true;
1324 0 : talloc_free(s->conns);
1325 :
1326 0 : for (i=0; i < s->nprocs; i++) {
1327 0 : s->total += s->conns[i].total;
1328 : }
1329 :
1330 0 : torture_comment(torture,
1331 : "Total ops[%llu] (%u ops/s)\n",
1332 0 : (unsigned long long)s->total,
1333 0 : (unsigned)s->total/s->timelimit);
1334 :
1335 0 : torture_leave_domain(torture, s->join_ctx1);
1336 0 : torture_leave_domain(torture, s->join_ctx2);
1337 0 : return true;
1338 : }
|