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 360 : 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 : NTSTATUS status;
49 : struct netr_LogonSamLogonEx r;
50 : struct netr_NetworkInfo ninfo;
51 : union netr_LogonLevel logon;
52 : union netr_Validation validation;
53 360 : uint8_t authoritative = 1;
54 360 : uint32_t _flags = 0;
55 : DATA_BLOB names_blob, chal, lm_resp, nt_resp;
56 : int i;
57 360 : int flags = CLI_CRED_NTLM_AUTH;
58 360 : struct dcerpc_binding_handle *b = p->binding_handle;
59 :
60 : struct netr_UserSessionKey key;
61 : struct netr_LMSessionKey LMSessKey;
62 360 : uint32_t validation_levels[] = { 2, 3 };
63 360 : struct netr_SamBaseInfo *base = NULL;
64 360 : const char *crypto_alg = "";
65 360 : bool can_do_validation_6 = true;
66 360 : enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE;
67 :
68 360 : if (lpcfg_client_lanman_auth(tctx->lp_ctx)) {
69 240 : flags |= CLI_CRED_LANMAN_AUTH;
70 : }
71 :
72 360 : if (lpcfg_client_ntlmv2_auth(tctx->lp_ctx)) {
73 360 : flags |= CLI_CRED_NTLMv2_AUTH;
74 : }
75 :
76 360 : 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 360 : generate_random_buffer(ninfo.challenge,
82 : sizeof(ninfo.challenge));
83 360 : chal = data_blob_const(ninfo.challenge,
84 : sizeof(ninfo.challenge));
85 :
86 360 : names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(credentials),
87 : cli_credentials_get_domain(credentials));
88 :
89 360 : 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 360 : torture_assert_ntstatus_ok(tctx, status,
99 : "cli_credentials_get_ntlm_response failed");
100 :
101 360 : ninfo.lm.data = lm_resp.data;
102 360 : ninfo.lm.length = lm_resp.length;
103 :
104 360 : ninfo.nt.data = nt_resp.data;
105 360 : ninfo.nt.length = nt_resp.length;
106 :
107 360 : ninfo.identity_info.parameter_control = 0;
108 360 : ninfo.identity_info.logon_id = 0;
109 360 : ninfo.identity_info.workstation.string = cli_credentials_get_workstation(credentials);
110 :
111 360 : logon.network = &ninfo;
112 :
113 360 : r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
114 360 : r.in.computer_name = cli_credentials_get_workstation(credentials);
115 360 : r.in.logon_level = NetlogonNetworkInformation;
116 360 : r.in.logon= &logon;
117 360 : r.in.flags = &_flags;
118 360 : r.out.validation = &validation;
119 360 : r.out.authoritative = &authoritative;
120 360 : 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 360 : if (creds) {
132 324 : if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
133 216 : crypto_alg = "AES";
134 108 : } else if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
135 108 : crypto_alg = "ARCFOUR";
136 : }
137 : }
138 :
139 360 : dcerpc_binding_handle_auth_info(b, NULL, &auth_level);
140 360 : if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
141 108 : r.in.validation_level = 6;
142 :
143 108 : 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 108 : r.in.validation_level);
147 :
148 108 : torture_assert_ntstatus_ok(tctx,
149 : dcerpc_netr_LogonSamLogonEx_r(b, tctx, &r),
150 : "LogonSamLogonEx failed");
151 : } else {
152 252 : 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 252 : r.in.validation_level);
156 252 : r.out.result = NT_STATUS_INVALID_INFO_CLASS;
157 : }
158 :
159 360 : if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_INFO_CLASS)) {
160 252 : can_do_validation_6 = false;
161 : } else {
162 108 : torture_assert_ntstatus_ok(tctx, r.out.result,
163 : "LogonSamLogonEx failed");
164 :
165 108 : key = r.out.validation->sam6->base.key;
166 108 : LMSessKey = r.out.validation->sam6->base.LMSessKey;
167 :
168 108 : DEBUG(1,("unencrypted session keys from validation_level 6:\n"));
169 108 : dump_data(1, r.out.validation->sam6->base.key.key, 16);
170 108 : dump_data(1, r.out.validation->sam6->base.LMSessKey.key, 8);
171 : }
172 :
173 864 : for (i=0; i < ARRAY_SIZE(validation_levels); i++) {
174 :
175 612 : r.in.validation_level = validation_levels[i];
176 :
177 612 : 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 612 : r.in.validation_level);
181 :
182 612 : torture_assert_ntstatus_ok(tctx,
183 : dcerpc_netr_LogonSamLogonEx_r(b, tctx, &r),
184 : "LogonSamLogonEx failed");
185 612 : torture_assert_ntstatus_ok(tctx, r.out.result,
186 : "LogonSamLogonEx failed");
187 :
188 504 : if (creds == NULL) {
189 : /* when this test is called without creds no point in
190 : * testing the session keys */
191 72 : continue;
192 : }
193 :
194 432 : switch (validation_levels[i]) {
195 216 : case 2:
196 216 : base = &r.out.validation->sam2->base;
197 216 : break;
198 216 : case 3:
199 216 : base = &r.out.validation->sam3->base;
200 216 : break;
201 0 : default:
202 0 : break;
203 : }
204 :
205 432 : DEBUG(1,("encrypted keys validation_level %d:\n",
206 : validation_levels[i]));
207 432 : dump_data(1, base->key.key, 16);
208 432 : dump_data(1, base->LMSessKey.key, 8);
209 :
210 432 : if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
211 288 : netlogon_creds_aes_decrypt(creds, base->key.key, 16);
212 288 : netlogon_creds_aes_decrypt(creds, base->LMSessKey.key, 8);
213 144 : } else if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
214 144 : netlogon_creds_arcfour_crypt(creds, base->key.key, 16);
215 144 : netlogon_creds_arcfour_crypt(creds, base->LMSessKey.key, 8);
216 : }
217 :
218 432 : DEBUG(1,("decryped keys validation_level %d\n",
219 : validation_levels[i]));
220 :
221 432 : dump_data(1, base->key.key, 16);
222 432 : dump_data(1, base->LMSessKey.key, 8);
223 :
224 432 : if (!can_do_validation_6) {
225 : /* we cant compare against unencrypted keys */
226 216 : continue;
227 : }
228 :
229 216 : torture_assert_mem_equal(tctx,
230 : base->key.key,
231 : key.key,
232 : 16,
233 : "unexpected user session key\n");
234 216 : torture_assert_mem_equal(tctx,
235 : base->LMSessKey.key,
236 : LMSessKey.key,
237 : 8,
238 : "unexpected LM session key\n");
239 : }
240 :
241 252 : return true;
242 : }
243 :
244 108 : 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 : NTSTATUS status;
250 : struct netr_LogonSamLogonEx r;
251 : struct netr_NetworkInfo ninfo;
252 : union netr_LogonLevel logon;
253 : union netr_Validation validation;
254 108 : uint8_t authoritative = 1;
255 108 : uint32_t _flags = 0;
256 : 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 108 : NTTIME timestamp = BVAL(netapp_magic, 8);
268 108 : DATA_BLOB names_blob = data_blob_string_const(netapp_magic + 28);
269 : DATA_BLOB chal, lm_resp, nt_resp;
270 : int i;
271 108 : int flags = CLI_CRED_NTLM_AUTH;
272 108 : struct dcerpc_binding_handle *b = p->binding_handle;
273 : struct netr_UserSessionKey key;
274 : struct netr_LMSessionKey LMSessKey;
275 108 : uint32_t validation_levels[] = { 2, 3 };
276 108 : struct netr_SamBaseInfo *base = NULL;
277 108 : const char *crypto_alg = "";
278 108 : bool can_do_validation_6 = true;
279 108 : enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE;
280 :
281 108 : flags |= CLI_CRED_NTLMv2_AUTH;
282 :
283 108 : 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 108 : generate_random_buffer(ninfo.challenge,
289 : sizeof(ninfo.challenge));
290 :
291 108 : chal = data_blob_const(ninfo.challenge,
292 : sizeof(ninfo.challenge));
293 :
294 108 : 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 108 : torture_assert_ntstatus_ok(tctx, status,
304 : "cli_credentials_get_ntlm_response failed");
305 :
306 108 : ninfo.lm.data = lm_resp.data;
307 108 : ninfo.lm.length = lm_resp.length;
308 :
309 108 : ninfo.nt.data = nt_resp.data;
310 108 : ninfo.nt.length = nt_resp.length;
311 :
312 108 : ninfo.identity_info.parameter_control = 0;
313 108 : ninfo.identity_info.logon_id = 0;
314 108 : ninfo.identity_info.workstation.string = cli_credentials_get_workstation(credentials);
315 :
316 108 : logon.network = &ninfo;
317 :
318 108 : r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
319 108 : r.in.computer_name = cli_credentials_get_workstation(credentials);
320 108 : r.in.logon_level = NetlogonNetworkInformation;
321 108 : r.in.logon= &logon;
322 108 : r.in.flags = &_flags;
323 108 : r.out.validation = &validation;
324 108 : r.out.authoritative = &authoritative;
325 108 : 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 108 : if (creds != NULL) {
337 108 : if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
338 72 : crypto_alg = "AES";
339 36 : } else if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
340 36 : crypto_alg = "ARCFOUR";
341 : }
342 : }
343 :
344 108 : dcerpc_binding_handle_auth_info(b, NULL, &auth_level);
345 108 : if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
346 54 : r.in.validation_level = 6;
347 :
348 54 : 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 54 : r.in.validation_level);
352 :
353 54 : torture_assert_ntstatus_ok(tctx,
354 : dcerpc_netr_LogonSamLogonEx_r(b, tctx, &r),
355 : "LogonSamLogonEx failed");
356 : } else {
357 54 : 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 54 : r.in.validation_level);
361 54 : r.out.result = NT_STATUS_INVALID_INFO_CLASS;
362 : }
363 :
364 108 : if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_INFO_CLASS)) {
365 54 : can_do_validation_6 = false;
366 : } else {
367 54 : torture_assert_ntstatus_ok(tctx, r.out.result,
368 : "LogonSamLogonEx failed");
369 :
370 54 : key = r.out.validation->sam6->base.key;
371 54 : LMSessKey = r.out.validation->sam6->base.LMSessKey;
372 :
373 54 : DEBUG(1,("unencrypted session keys from validation_level 6:\n"));
374 54 : dump_data(1, r.out.validation->sam6->base.key.key, 16);
375 54 : dump_data(1, r.out.validation->sam6->base.LMSessKey.key, 8);
376 : }
377 :
378 324 : for (i=0; i < ARRAY_SIZE(validation_levels); i++) {
379 :
380 216 : r.in.validation_level = validation_levels[i];
381 :
382 216 : 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 216 : r.in.validation_level);
386 :
387 216 : torture_assert_ntstatus_ok(tctx,
388 : dcerpc_netr_LogonSamLogonEx_r(b, tctx, &r),
389 : "LogonSamLogonEx failed");
390 216 : torture_assert_ntstatus_ok(tctx, r.out.result,
391 : "LogonSamLogonEx failed");
392 :
393 216 : 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 216 : switch (validation_levels[i]) {
400 108 : case 2:
401 108 : base = &r.out.validation->sam2->base;
402 108 : break;
403 108 : case 3:
404 108 : base = &r.out.validation->sam3->base;
405 108 : break;
406 0 : default:
407 0 : break;
408 : }
409 :
410 216 : DEBUG(1,("encrypted keys validation_level %d:\n",
411 : validation_levels[i]));
412 216 : dump_data(1, base->key.key, 16);
413 216 : dump_data(1, base->LMSessKey.key, 8);
414 :
415 216 : if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
416 144 : netlogon_creds_aes_decrypt(creds, base->key.key, 16);
417 144 : netlogon_creds_aes_decrypt(creds, base->LMSessKey.key, 8);
418 72 : } else if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
419 72 : netlogon_creds_arcfour_crypt(creds, base->key.key, 16);
420 72 : netlogon_creds_arcfour_crypt(creds, base->LMSessKey.key, 8);
421 : }
422 :
423 216 : DEBUG(1,("decryped keys validation_level %d\n",
424 : validation_levels[i]));
425 :
426 216 : dump_data(1, base->key.key, 16);
427 216 : dump_data(1, base->LMSessKey.key, 8);
428 :
429 216 : if (!can_do_validation_6) {
430 : /* we cant compare against unencrypted keys */
431 108 : continue;
432 : }
433 :
434 108 : torture_assert_mem_equal(tctx,
435 : base->key.key,
436 : key.key,
437 : 16,
438 : "unexpected user session key\n");
439 108 : torture_assert_mem_equal(tctx,
440 : base->LMSessKey.key,
441 : LMSessKey.key,
442 : 8,
443 : "unexpected LM session key\n");
444 : }
445 :
446 108 : return true;
447 : }
448 :
449 : /*
450 : do some samr ops using the schannel connection
451 : */
452 216 : static bool test_samr_ops(struct torture_context *tctx,
453 : struct dcerpc_binding_handle *b)
454 : {
455 : struct samr_GetDomPwInfo r;
456 : struct samr_PwInfo info;
457 : struct samr_Connect connect_r;
458 : struct samr_OpenDomain opendom;
459 : int i;
460 : struct lsa_String name;
461 : struct policy_handle handle;
462 : struct policy_handle domain_handle;
463 :
464 216 : name.string = lpcfg_workgroup(tctx->lp_ctx);
465 216 : r.in.domain_name = &name;
466 216 : r.out.info = &info;
467 :
468 216 : connect_r.in.system_name = 0;
469 216 : connect_r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
470 216 : connect_r.out.connect_handle = &handle;
471 :
472 216 : torture_comment(tctx, "Testing Connect and OpenDomain on BUILTIN\n");
473 :
474 216 : torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect_r(b, tctx, &connect_r),
475 : "Connect failed");
476 216 : 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 216 : opendom.in.connect_handle = &handle;
486 216 : opendom.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
487 216 : opendom.in.sid = dom_sid_parse_talloc(tctx, "S-1-5-32");
488 216 : opendom.out.domain_handle = &domain_handle;
489 :
490 216 : torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenDomain_r(b, tctx, &opendom),
491 : "OpenDomain failed");
492 216 : 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 216 : torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
499 :
500 : /* do several ops to test credential chaining */
501 1296 : for (i=0;i<5;i++) {
502 1080 : torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDomPwInfo_r(b, tctx, &r),
503 : "GetDomPwInfo failed");
504 1080 : 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 216 : return true;
513 : }
514 :
515 :
516 : /*
517 : do some lsa ops using the schannel connection
518 : */
519 108 : static bool test_lsa_ops(struct torture_context *tctx, struct dcerpc_pipe *p)
520 : {
521 : struct lsa_GetUserName r;
522 108 : bool ret = true;
523 108 : struct lsa_String *account_name_p = NULL;
524 108 : struct lsa_String *authority_name_p = NULL;
525 108 : struct dcerpc_binding_handle *b = p->binding_handle;
526 :
527 108 : torture_comment(tctx, "\nTesting GetUserName\n");
528 :
529 108 : r.in.system_name = "\\";
530 108 : r.in.account_name = &account_name_p;
531 108 : r.in.authority_name = &authority_name_p;
532 108 : r.out.account_name = &account_name_p;
533 :
534 : /* do several ops to test credential chaining and various operations */
535 108 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_GetUserName_r(b, tctx, &r),
536 : "lsa_GetUserName failed");
537 :
538 108 : authority_name_p = *r.out.authority_name;
539 :
540 108 : 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 108 : if (!r.out.account_name) {
545 0 : return false;
546 : }
547 :
548 108 : if (strcmp(account_name_p->string, "ANONYMOUS LOGON") != 0) {
549 0 : torture_comment(tctx, "GetUserName returned wrong user: %s, expected %s\n",
550 0 : account_name_p->string, "ANONYMOUS LOGON");
551 : /* FIXME: gd */
552 0 : if (!torture_setting_bool(tctx, "samba3", false)) {
553 0 : return false;
554 : }
555 : }
556 108 : if (!authority_name_p || !authority_name_p->string) {
557 0 : return false;
558 : }
559 :
560 108 : if (strcmp(authority_name_p->string, "NT AUTHORITY") != 0) {
561 0 : torture_comment(tctx, "GetUserName returned wrong user: %s, expected %s\n",
562 0 : authority_name_p->string, "NT AUTHORITY");
563 : /* FIXME: gd */
564 0 : if (!torture_setting_bool(tctx, "samba3", false)) {
565 0 : return false;
566 : }
567 : }
568 : }
569 :
570 108 : return ret;
571 : }
572 :
573 :
574 : /*
575 : test a schannel connection with the given flags
576 : */
577 108 : static bool test_schannel(struct torture_context *tctx,
578 : uint16_t acct_flags, uint32_t dcerpc_flags,
579 : int i)
580 : {
581 : struct test_join *join_ctx;
582 : NTSTATUS status;
583 108 : const char *binding = torture_setting_string(tctx, "binding", NULL);
584 : struct dcerpc_binding *b;
585 108 : struct dcerpc_pipe *p = NULL;
586 108 : struct dcerpc_pipe *p_netlogon = NULL;
587 108 : struct dcerpc_pipe *p_netlogon2 = NULL;
588 108 : struct dcerpc_pipe *p_netlogon3 = NULL;
589 108 : struct dcerpc_pipe *p_samr2 = NULL;
590 108 : struct dcerpc_pipe *p_lsa = NULL;
591 : struct netlogon_creds_CredentialState *creds;
592 : struct cli_credentials *credentials;
593 : enum dcerpc_transport_t transport;
594 :
595 216 : join_ctx = torture_join_domain(tctx,
596 108 : talloc_asprintf(tctx, "%s%d", TEST_MACHINE_NAME, i),
597 : acct_flags, &credentials);
598 108 : torture_assert(tctx, join_ctx != NULL, "Failed to join domain");
599 :
600 108 : status = dcerpc_parse_binding(tctx, binding, &b);
601 108 : torture_assert_ntstatus_ok(tctx, status, "Bad binding string");
602 :
603 108 : status = dcerpc_binding_set_flags(b, dcerpc_flags, DCERPC_AUTH_OPTIONS);
604 108 : torture_assert_ntstatus_ok(tctx, status, "set flags");
605 :
606 108 : status = dcerpc_pipe_connect_b(tctx, &p, b, &ndr_table_samr,
607 : credentials, tctx->ev, tctx->lp_ctx);
608 108 : torture_assert_ntstatus_ok(tctx, status,
609 : "Failed to connect to samr with schannel");
610 :
611 108 : 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 108 : status = dcerpc_epm_map_binding(tctx, b, &ndr_table_netlogon, tctx->ev, tctx->lp_ctx);
620 108 : torture_assert_ntstatus_ok(tctx, status, "epm map");
621 :
622 108 : status = dcerpc_binding_set_flags(b, dcerpc_flags, DCERPC_AUTH_OPTIONS);
623 108 : torture_assert_ntstatus_ok(tctx, status, "set flags");
624 :
625 108 : status = dcerpc_secondary_auth_connection(p, b, &ndr_table_netlogon,
626 : credentials, tctx->lp_ctx,
627 : tctx, &p_netlogon);
628 108 : torture_assert_ntstatus_ok(tctx, status, "Failed to create secondary connection");
629 :
630 108 : creds = cli_credentials_get_netlogon_creds(credentials);
631 108 : torture_assert(tctx, (creds != NULL), "schannel creds");
632 :
633 : /* checks the capabilities */
634 108 : 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 108 : torture_assert(tctx, test_netlogon_ops(p_netlogon, tctx, credentials, creds),
639 : "Failed to process schannel secured NETLOGON ops");
640 :
641 108 : 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 108 : 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 108 : transport = dcerpc_binding_get_transport(b);
650 108 : status = dcerpc_binding_set_transport(b, NCACN_NP);
651 108 : torture_assert_ntstatus_ok(tctx, status, "set transport");
652 :
653 : /* Swap the binding details from SAMR to LSARPC */
654 108 : status = dcerpc_epm_map_binding(tctx, b, &ndr_table_lsarpc, tctx->ev, tctx->lp_ctx);
655 108 : torture_assert_ntstatus_ok(tctx, status, "epm map");
656 :
657 108 : 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 108 : torture_assert(tctx, test_lsa_ops(tctx, p_lsa),
663 : "Failed to process schannel secured LSA ops");
664 :
665 108 : talloc_free(p_lsa);
666 108 : p_lsa = NULL;
667 :
668 : /* we *MUST* use ncacn_ip_tcp for lookupsids3/lookupnames4 */
669 108 : status = dcerpc_binding_set_transport(b, NCACN_IP_TCP);
670 108 : torture_assert_ntstatus_ok(tctx, status, "set transport");
671 :
672 108 : 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 108 : 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 108 : torture_assert(tctx,
682 : test_many_LookupSids(p_lsa, tctx, NULL, LSA_LOOKUP_NAMES_ALL),
683 : "LsaLookupSids3 failed!\n");
684 :
685 108 : status = dcerpc_binding_set_transport(b, transport);
686 108 : torture_assert_ntstatus_ok(tctx, status, "set transport");
687 :
688 :
689 : /* Drop the socket, we want to start from scratch */
690 108 : talloc_free(p);
691 108 : p = NULL;
692 :
693 : /* Now see what we are still allowed to do */
694 :
695 108 : status = dcerpc_parse_binding(tctx, binding, &b);
696 108 : torture_assert_ntstatus_ok(tctx, status, "Bad binding string");
697 :
698 108 : status = dcerpc_binding_set_flags(b, dcerpc_flags, DCERPC_AUTH_OPTIONS);
699 108 : torture_assert_ntstatus_ok(tctx, status, "set flags");
700 :
701 108 : status = dcerpc_pipe_connect_b(tctx, &p_samr2, b, &ndr_table_samr,
702 : credentials, tctx->ev, tctx->lp_ctx);
703 108 : 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 108 : 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 108 : status = dcerpc_epm_map_binding(tctx, b, &ndr_table_netlogon, tctx->ev, tctx->lp_ctx);
712 108 : torture_assert_ntstatus_ok(tctx, status, "epm");
713 :
714 108 : status = dcerpc_binding_set_flags(b, dcerpc_flags, DCERPC_AUTH_OPTIONS);
715 108 : torture_assert_ntstatus_ok(tctx, status, "set flags");
716 :
717 108 : status = dcerpc_secondary_auth_connection(p_samr2, b, &ndr_table_netlogon,
718 : credentials, tctx->lp_ctx,
719 : tctx, &p_netlogon2);
720 108 : torture_assert_ntstatus_ok(tctx, status, "Failed to create secondary connection");
721 :
722 : /* checks the capabilities */
723 108 : 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 108 : 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 108 : 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 108 : talloc_free(p_samr2);
738 :
739 : /* We don't want schannel for this test */
740 108 : status = dcerpc_binding_set_flags(b, 0, DCERPC_AUTH_OPTIONS);
741 108 : torture_assert_ntstatus_ok(tctx, status, "set flags");
742 :
743 108 : status = dcerpc_pipe_connect_b(tctx, &p_netlogon3, b, &ndr_table_netlogon,
744 : credentials, tctx->ev, tctx->lp_ctx);
745 108 : torture_assert_ntstatus_ok(tctx, status, "Failed to connect without schannel");
746 :
747 108 : 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 108 : tctx->last_result = TORTURE_OK;
752 108 : tctx->last_reason = NULL;
753 :
754 108 : 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 108 : torture_leave_domain(tctx, join_ctx);
758 108 : 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 6 : static bool test_schannel_anonymous_setPassword(struct torture_context *tctx,
769 : uint32_t dcerpc_flags,
770 : bool use2)
771 : {
772 : NTSTATUS status, result;
773 6 : const char *binding = torture_setting_string(tctx, "binding", NULL);
774 : struct dcerpc_binding *b;
775 6 : struct dcerpc_pipe *p = NULL;
776 : struct cli_credentials *credentials;
777 6 : bool ok = true;
778 :
779 6 : credentials = cli_credentials_init(NULL);
780 6 : torture_assert(tctx, credentials != NULL, "Bad credentials");
781 6 : cli_credentials_set_anonymous(credentials);
782 :
783 6 : status = dcerpc_parse_binding(tctx, binding, &b);
784 6 : torture_assert_ntstatus_ok(tctx, status, "Bad binding string");
785 :
786 6 : status = dcerpc_binding_set_flags(b, dcerpc_flags, DCERPC_AUTH_OPTIONS);
787 6 : torture_assert_ntstatus_ok(tctx, status, "set flags");
788 :
789 6 : status = dcerpc_pipe_connect_b(tctx,
790 : &p,
791 : b,
792 : &ndr_table_netlogon,
793 : credentials,
794 : tctx->ev,
795 : tctx->lp_ctx);
796 6 : torture_assert_ntstatus_ok(tctx, status, "Failed to connect without schannel");
797 :
798 6 : if (use2) {
799 3 : struct netr_ServerPasswordSet2 r = {};
800 3 : struct netr_Authenticator credential = {};
801 3 : struct netr_Authenticator return_authenticator = {};
802 3 : struct netr_CryptPassword new_password = {};
803 :
804 3 : r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
805 3 : r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
806 3 : r.in.secure_channel_type = 0;
807 3 : r.in.computer_name = TEST_MACHINE_NAME;
808 3 : r.in.credential = &credential;
809 3 : r.in.new_password = &new_password;
810 3 : r.out.return_authenticator = &return_authenticator;
811 :
812 3 : status = dcerpc_netr_ServerPasswordSet2_r(p->binding_handle, tctx, &r);
813 3 : result = r.out.result;
814 : } else {
815 3 : struct netr_ServerPasswordSet r = {};
816 3 : struct netr_Authenticator credential = {};
817 3 : struct netr_Authenticator return_authenticator = {};
818 3 : struct samr_Password new_password = {};
819 :
820 3 : r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
821 3 : r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
822 3 : r.in.secure_channel_type = 0;
823 3 : r.in.computer_name = TEST_MACHINE_NAME;
824 3 : r.in.credential = &credential;
825 3 : r.in.new_password = &new_password;
826 3 : r.out.return_authenticator = &return_authenticator;
827 :
828 3 : status = dcerpc_netr_ServerPasswordSet_r(p->binding_handle, tctx, &r);
829 3 : result = r.out.result;
830 : }
831 :
832 6 : torture_assert_ntstatus_ok(tctx, status, "ServerPasswordSet failed");
833 :
834 6 : if (NT_STATUS_IS_OK(result)) {
835 0 : torture_fail(tctx, "unexpectedly received NT_STATUS_OK");
836 : }
837 :
838 6 : return ok;
839 : }
840 :
841 :
842 : /*
843 : a schannel test suite
844 : */
845 9 : bool torture_rpc_schannel(struct torture_context *torture)
846 : {
847 9 : bool ret = true;
848 : struct {
849 : uint16_t acct_flags;
850 : uint32_t dcerpc_flags;
851 9 : } 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 : int i;
866 :
867 117 : for (i=0;i<ARRAY_SIZE(tests);i++) {
868 216 : torture_comment(torture, "Testing with acct_flags=0x%x dcerpc_flags=0x%x \n",
869 108 : tests[i].acct_flags, tests[i].dcerpc_flags);
870 :
871 216 : if (!test_schannel(torture,
872 108 : 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 9 : return ret;
881 : }
882 :
883 3 : bool torture_rpc_schannel_anon_setpw(struct torture_context *torture)
884 : {
885 3 : bool ret = true;
886 : bool ok;
887 3 : uint32_t dcerpc_flags = DCERPC_SCHANNEL | DCERPC_SIGN | DCERPC_SCHANNEL_AUTO;
888 :
889 3 : ok = test_schannel_anonymous_setPassword(torture,
890 : dcerpc_flags,
891 : true);
892 3 : 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 3 : ok = test_schannel_anonymous_setPassword(torture,
900 : dcerpc_flags,
901 : false);
902 3 : 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 3 : return ret;
910 : }
911 :
912 : /*
913 : test two schannel connections
914 : */
915 9 : bool torture_rpc_schannel2(struct torture_context *torture)
916 : {
917 : struct test_join *join_ctx;
918 : NTSTATUS status;
919 9 : const char *binding = torture_setting_string(torture, "binding", NULL);
920 : struct dcerpc_binding *b;
921 9 : struct dcerpc_pipe *p1 = NULL, *p2 = NULL;
922 : struct cli_credentials *credentials1, *credentials2;
923 9 : uint32_t dcerpc_flags = DCERPC_SCHANNEL | DCERPC_SCHANNEL_AUTO | DCERPC_SIGN;
924 :
925 9 : join_ctx = torture_join_domain(torture, talloc_asprintf(torture, "%s2", TEST_MACHINE_NAME),
926 : ACB_WSTRUST, &credentials1);
927 9 : torture_assert(torture, join_ctx != NULL,
928 : "Failed to join domain with acct_flags=ACB_WSTRUST");
929 :
930 9 : credentials2 = cli_credentials_shallow_copy(torture, credentials1);
931 9 : cli_credentials_set_netlogon_creds(credentials1, NULL);
932 9 : cli_credentials_set_netlogon_creds(credentials2, NULL);
933 :
934 9 : status = dcerpc_parse_binding(torture, binding, &b);
935 9 : torture_assert_ntstatus_ok(torture, status, "Bad binding string");
936 :
937 9 : status = dcerpc_binding_set_flags(b, dcerpc_flags, DCERPC_AUTH_OPTIONS);
938 9 : torture_assert_ntstatus_ok(torture, status, "set flags");
939 :
940 9 : torture_comment(torture, "Opening first connection\n");
941 9 : status = dcerpc_pipe_connect_b(torture, &p1, b, &ndr_table_netlogon,
942 : credentials1, torture->ev, torture->lp_ctx);
943 9 : torture_assert_ntstatus_ok(torture, status, "Failed to connect with schannel");
944 :
945 9 : torture_comment(torture, "Opening second connection\n");
946 9 : status = dcerpc_pipe_connect_b(torture, &p2, b, &ndr_table_netlogon,
947 : credentials2, torture->ev, torture->lp_ctx);
948 9 : torture_assert_ntstatus_ok(torture, status, "Failed to connect with schannel");
949 :
950 9 : cli_credentials_set_netlogon_creds(credentials1, NULL);
951 9 : cli_credentials_set_netlogon_creds(credentials2, NULL);
952 :
953 9 : torture_comment(torture, "Testing logon on pipe1\n");
954 9 : if (!test_netlogon_ex_ops(p1, torture, credentials1, NULL))
955 0 : return false;
956 :
957 9 : torture_comment(torture, "Testing logon on pipe2\n");
958 9 : if (!test_netlogon_ex_ops(p2, torture, credentials2, NULL))
959 0 : return false;
960 :
961 9 : torture_comment(torture, "Again on pipe1\n");
962 9 : if (!test_netlogon_ex_ops(p1, torture, credentials1, NULL))
963 0 : return false;
964 :
965 9 : torture_comment(torture, "Again on pipe2\n");
966 9 : if (!test_netlogon_ex_ops(p2, torture, credentials2, NULL))
967 0 : return false;
968 :
969 9 : torture_leave_domain(torture, join_ctx);
970 9 : 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 : NTSTATUS status;
1029 : DATA_BLOB names_blob, chal, lm_resp, nt_resp;
1030 0 : int flags = CLI_CRED_NTLM_AUTH;
1031 : struct tevent_req *subreq;
1032 : 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 : 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 : NTSTATUS status;
1141 0 : const char *binding = torture_setting_string(torture, "binding", NULL);
1142 : struct torture_schannel_bench *s;
1143 : struct timeval start;
1144 : struct timeval end;
1145 : int i;
1146 : 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 : struct netr_ServerPasswordSet pwset;
1246 0 : char *password = generate_random_password(s->join_ctx1, 8, 255);
1247 : struct netlogon_creds_CredentialState *creds_state;
1248 : struct dcerpc_pipe *net_pipe;
1249 : struct netr_Authenticator credential, return_authenticator;
1250 : 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 : }
|