Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 : test suite for lsa rpc operations
4 :
5 : Copyright (C) Andrew Tridgell 2003
6 : Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2005
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 "torture/torture.h"
24 : #include "libcli/cldap/cldap.h"
25 : #include "../lib/tsocket/tsocket.h"
26 : #include "librpc/gen_ndr/ndr_lsa_c.h"
27 : #include "librpc/gen_ndr/netlogon.h"
28 : #include "librpc/gen_ndr/ndr_drsblobs.h"
29 : #include "librpc/gen_ndr/ndr_netlogon_c.h"
30 : #include "lib/events/events.h"
31 : #include "libcli/security/security.h"
32 : #include "libcli/auth/libcli_auth.h"
33 : #include "torture/rpc/torture_rpc.h"
34 : #include "param/param.h"
35 : #include "source4/auth/kerberos/kerberos.h"
36 : #include "source4/auth/kerberos/kerberos_util.h"
37 : #include "lib/util/util_net.h"
38 : #include "libcli/resolve/resolve.h"
39 :
40 : #include <gnutls/gnutls.h>
41 : #include <gnutls/crypto.h>
42 :
43 : #define TEST_MACHINENAME "lsatestmach"
44 : #define TRUSTPW "12345678"
45 :
46 29926 : static void init_lsa_String(struct lsa_String *name, const char *s)
47 : {
48 29926 : name->string = s;
49 25126 : }
50 :
51 27 : static bool test_OpenPolicy(struct dcerpc_binding_handle *b,
52 : struct torture_context *tctx)
53 : {
54 0 : struct lsa_ObjectAttribute attr;
55 0 : struct policy_handle handle;
56 0 : struct lsa_QosInfo qos;
57 0 : struct lsa_OpenPolicy r;
58 27 : uint16_t system_name = '\\';
59 :
60 27 : torture_comment(tctx, "\nTesting OpenPolicy\n");
61 :
62 27 : qos.len = 0;
63 27 : qos.impersonation_level = 2;
64 27 : qos.context_mode = 1;
65 27 : qos.effective_only = 0;
66 :
67 27 : attr.len = 0;
68 27 : attr.root_dir = NULL;
69 27 : attr.object_name = NULL;
70 27 : attr.attributes = 0;
71 27 : attr.sec_desc = NULL;
72 27 : attr.sec_qos = &qos;
73 :
74 27 : r.in.system_name = &system_name;
75 27 : r.in.attr = &attr;
76 27 : r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
77 27 : r.out.handle = &handle;
78 :
79 27 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenPolicy_r(b, tctx, &r),
80 : "OpenPolicy failed");
81 :
82 27 : torture_assert_ntstatus_ok(tctx,
83 : r.out.result,
84 : "OpenPolicy failed");
85 :
86 27 : return true;
87 : }
88 :
89 5 : static bool test_OpenPolicy_fail(struct dcerpc_binding_handle *b,
90 : struct torture_context *tctx)
91 : {
92 0 : struct lsa_ObjectAttribute attr;
93 0 : struct policy_handle handle;
94 0 : struct lsa_QosInfo qos;
95 0 : struct lsa_OpenPolicy r;
96 5 : uint16_t system_name = '\\';
97 0 : NTSTATUS status;
98 :
99 5 : torture_comment(tctx, "\nTesting OpenPolicy_fail\n");
100 :
101 5 : qos.len = 0;
102 5 : qos.impersonation_level = 2;
103 5 : qos.context_mode = 1;
104 5 : qos.effective_only = 0;
105 :
106 5 : attr.len = 0;
107 5 : attr.root_dir = NULL;
108 5 : attr.object_name = NULL;
109 5 : attr.attributes = 0;
110 5 : attr.sec_desc = NULL;
111 5 : attr.sec_qos = &qos;
112 :
113 5 : r.in.system_name = &system_name;
114 5 : r.in.attr = &attr;
115 5 : r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
116 5 : r.out.handle = &handle;
117 :
118 5 : status = dcerpc_lsa_OpenPolicy_r(b, tctx, &r);
119 5 : if (!NT_STATUS_IS_OK(status)) {
120 5 : if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
121 5 : torture_comment(tctx,
122 : "OpenPolicy correctly returned with "
123 : "status: %s\n",
124 : nt_errstr(status));
125 5 : return true;
126 : }
127 :
128 0 : torture_assert_ntstatus_equal(tctx,
129 : status,
130 : NT_STATUS_ACCESS_DENIED,
131 : "OpenPolicy return value should "
132 : "be ACCESS_DENIED");
133 0 : return true;
134 : }
135 :
136 0 : if (!NT_STATUS_IS_OK(r.out.result)) {
137 0 : if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED) ||
138 0 : NT_STATUS_EQUAL(r.out.result, NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED)) {
139 0 : torture_comment(tctx,
140 : "OpenPolicy correctly returned with "
141 : "result: %s\n",
142 : nt_errstr(r.out.result));
143 0 : return true;
144 : }
145 : }
146 :
147 0 : torture_assert_ntstatus_equal(tctx,
148 : r.out.result,
149 : NT_STATUS_OK,
150 : "OpenPolicy return value should be "
151 : "ACCESS_DENIED");
152 :
153 0 : return false;
154 : }
155 :
156 :
157 2397 : bool test_lsa_OpenPolicy2_ex(struct dcerpc_binding_handle *b,
158 : struct torture_context *tctx,
159 : struct policy_handle **handle,
160 : NTSTATUS expected_status,
161 : NTSTATUS expected_status2)
162 : {
163 9 : struct lsa_ObjectAttribute attr;
164 9 : struct lsa_QosInfo qos;
165 9 : struct lsa_OpenPolicy2 r;
166 9 : NTSTATUS status;
167 :
168 2397 : torture_comment(tctx, "\nTesting OpenPolicy2\n");
169 :
170 2397 : *handle = talloc(tctx, struct policy_handle);
171 2397 : torture_assert(tctx, *handle != NULL, "talloc(tctx, struct policy_handle)");
172 :
173 2397 : qos.len = 0;
174 2397 : qos.impersonation_level = 2;
175 2397 : qos.context_mode = 1;
176 2397 : qos.effective_only = 0;
177 :
178 2397 : attr.len = 0;
179 2397 : attr.root_dir = NULL;
180 2397 : attr.object_name = NULL;
181 2397 : attr.attributes = 0;
182 2397 : attr.sec_desc = NULL;
183 2397 : attr.sec_qos = &qos;
184 :
185 2397 : r.in.system_name = "\\";
186 2397 : r.in.attr = &attr;
187 2397 : r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
188 2397 : r.out.handle = *handle;
189 :
190 2397 : status = dcerpc_lsa_OpenPolicy2_r(b, tctx, &r);
191 :
192 : /* Allow two possible failure status codes */
193 2397 : if (!NT_STATUS_EQUAL(status, expected_status2)) {
194 15 : torture_assert_ntstatus_equal(tctx, status,
195 : expected_status,
196 : "OpenPolicy2 failed");
197 : }
198 2397 : if (!NT_STATUS_IS_OK(expected_status) ||
199 2382 : !NT_STATUS_IS_OK(expected_status2)) {
200 12 : return true;
201 : }
202 :
203 2382 : torture_assert_ntstatus_ok(tctx,
204 : r.out.result,
205 : "OpenPolicy2 failed");
206 :
207 2376 : return true;
208 : }
209 :
210 :
211 2382 : bool test_lsa_OpenPolicy2(struct dcerpc_binding_handle *b,
212 : struct torture_context *tctx,
213 : struct policy_handle **handle)
214 : {
215 4764 : return test_lsa_OpenPolicy2_ex(b, tctx, handle,
216 2382 : NT_STATUS_OK, NT_STATUS_OK);
217 : }
218 :
219 5 : static bool test_OpenPolicy2_fail(struct dcerpc_binding_handle *b,
220 : struct torture_context *tctx)
221 : {
222 0 : struct lsa_ObjectAttribute attr;
223 0 : struct policy_handle handle;
224 0 : struct lsa_QosInfo qos;
225 0 : struct lsa_OpenPolicy2 r;
226 0 : NTSTATUS status;
227 :
228 5 : torture_comment(tctx, "\nTesting OpenPolicy2_fail\n");
229 :
230 5 : qos.len = 0;
231 5 : qos.impersonation_level = 2;
232 5 : qos.context_mode = 1;
233 5 : qos.effective_only = 0;
234 :
235 5 : attr.len = 0;
236 5 : attr.root_dir = NULL;
237 5 : attr.object_name = NULL;
238 5 : attr.attributes = 0;
239 5 : attr.sec_desc = NULL;
240 5 : attr.sec_qos = &qos;
241 :
242 5 : r.in.system_name = "\\";
243 5 : r.in.attr = &attr;
244 5 : r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
245 5 : r.out.handle = &handle;
246 :
247 5 : status = dcerpc_lsa_OpenPolicy2_r(b, tctx, &r);
248 5 : if (!NT_STATUS_IS_OK(status)) {
249 5 : if (NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_DISCONNECTED) ||
250 5 : NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
251 5 : torture_comment(tctx,
252 : "OpenPolicy2 correctly returned with "
253 : "status: %s\n",
254 : nt_errstr(status));
255 5 : return true;
256 : }
257 :
258 0 : torture_assert_ntstatus_equal(tctx,
259 : status,
260 : NT_STATUS_ACCESS_DENIED,
261 : "OpenPolicy2 return value should "
262 : "be ACCESS_DENIED");
263 0 : return true;
264 : }
265 :
266 0 : if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED) ||
267 0 : NT_STATUS_EQUAL(r.out.result, NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED)) {
268 0 : torture_comment(tctx,
269 : "OpenPolicy2 correctly returned with "
270 : "result: %s\n",
271 : nt_errstr(r.out.result));
272 0 : return true;
273 : }
274 :
275 0 : torture_fail(tctx,
276 : "OpenPolicy2 return value should be "
277 : "ACCESS_DENIED or RPC_PROTSEQ_NOT_SUPPORTED");
278 :
279 : return false;
280 : }
281 :
282 14 : bool test_lsa_OpenPolicy3_ex(struct dcerpc_binding_handle *b,
283 : struct torture_context *tctx,
284 : struct policy_handle **handle,
285 : NTSTATUS expected_status,
286 : NTSTATUS expected_status2)
287 : {
288 14 : struct lsa_QosInfo qos = {
289 : .impersonation_level = 2,
290 : .context_mode = 1,
291 : };
292 14 : struct lsa_ObjectAttribute attr = {
293 : .len = 0,
294 : .sec_qos = &qos,
295 : };
296 14 : struct lsa_revision_info1 in_rinfo1 = {
297 : .revision = 1,
298 : .supported_features = 0,
299 : };
300 14 : union lsa_revision_info in_rinfo = {
301 : .info1 = in_rinfo1,
302 : };
303 14 : struct lsa_revision_info1 out_rinfo1 = {
304 : .revision = 0,
305 : };
306 14 : union lsa_revision_info out_rinfo = {
307 : .info1 = out_rinfo1,
308 : };
309 14 : uint32_t out_version = 0;
310 14 : struct lsa_OpenPolicy3 r = {
311 : .in.system_name = "\\",
312 : .in.attr = &attr,
313 : .in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED,
314 : .in.in_version = 1,
315 : .in.in_revision_info = &in_rinfo,
316 : .out.out_version = &out_version,
317 : .out.out_revision_info = &out_rinfo,
318 : };
319 0 : NTSTATUS status;
320 :
321 14 : torture_comment(tctx, "\nTesting OpenPolicy3\n");
322 :
323 14 : *handle = talloc(tctx, struct policy_handle);
324 14 : torture_assert(tctx,
325 : *handle != NULL,
326 : "talloc(tctx, struct policy_handle)");
327 14 : r.out.handle = *handle;
328 :
329 14 : status = dcerpc_lsa_OpenPolicy3_r(b, tctx, &r);
330 :
331 : /* Allow two possible failure status codes */
332 14 : if (!NT_STATUS_EQUAL(status, expected_status2)) {
333 14 : torture_assert_ntstatus_equal(tctx,
334 : status,
335 : expected_status,
336 : "OpenPolicy3 failed");
337 : }
338 14 : if (!NT_STATUS_IS_OK(expected_status) ||
339 14 : !NT_STATUS_IS_OK(expected_status2)) {
340 14 : return true;
341 : }
342 :
343 0 : torture_assert_ntstatus_ok(tctx, r.out.result, "OpenPolicy3 failed");
344 0 : torture_assert_int_equal(tctx, out_version, 1, "Invalid out_version");
345 0 : torture_assert_int_equal(tctx,
346 : out_rinfo1.revision,
347 : 1,
348 : "Invalid revision");
349 : #if 0 /* TODO: Enable as soon as it is supported */
350 : torture_assert_int_equal(tctx,
351 : out_rinfo1.supported_features,
352 : LSA_FEATURE_TDO_AUTH_INFO_AES_CIPHER,
353 : "Invalid supported feature set");
354 : #endif
355 :
356 0 : return true;
357 : }
358 :
359 14 : bool test_lsa_OpenPolicy3(struct dcerpc_binding_handle *b,
360 : struct torture_context *tctx,
361 : struct policy_handle **handle)
362 : {
363 28 : return test_lsa_OpenPolicy3_ex(b,
364 : tctx,
365 : handle,
366 14 : NT_STATUS_OK,
367 14 : NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE);
368 : }
369 :
370 5 : static bool test_OpenPolicy3_fail(struct dcerpc_binding_handle *b,
371 : struct torture_context *tctx)
372 : {
373 5 : struct policy_handle handle = {
374 : .handle_type = 0,
375 : };
376 5 : struct lsa_QosInfo qos = {
377 : .impersonation_level = 2,
378 : .context_mode = 1,
379 : };
380 5 : struct lsa_ObjectAttribute attr = {
381 : .len = 0,
382 : .sec_qos = &qos,
383 : };
384 5 : struct lsa_revision_info1 in_rinfo1 = {
385 : .revision = 0,
386 : .supported_features = 0,
387 : };
388 5 : union lsa_revision_info in_rinfo = {
389 : .info1 = in_rinfo1,
390 : };
391 5 : struct lsa_revision_info1 out_rinfo1 = {
392 : .revision = 0,
393 : };
394 5 : union lsa_revision_info out_rinfo = {
395 : .info1 = out_rinfo1,
396 : };
397 5 : uint32_t out_version = 0;
398 5 : struct lsa_OpenPolicy3 r = {
399 : .in.system_name = "\\",
400 : .in.attr = &attr,
401 : .in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED,
402 : .in.in_version = 1,
403 : .in.in_revision_info = &in_rinfo,
404 : .out.out_version = &out_version,
405 : .out.out_revision_info = &out_rinfo,
406 : .out.handle = &handle,
407 : };
408 0 : NTSTATUS status;
409 :
410 5 : torture_comment(tctx, "\nTesting OpenPolicy3_fail\n");
411 :
412 5 : status = dcerpc_lsa_OpenPolicy3_r(b, tctx, &r);
413 5 : if (!NT_STATUS_IS_OK(status)) {
414 5 : if (NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_DISCONNECTED) ||
415 5 : NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) ||
416 0 : NT_STATUS_EQUAL(status,
417 : NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE)) {
418 5 : torture_comment(tctx,
419 : "OpenPolicy3 correctly returned with "
420 : "status: %s\n",
421 : nt_errstr(status));
422 5 : return true;
423 : }
424 :
425 0 : torture_assert_ntstatus_equal(tctx,
426 : status,
427 : NT_STATUS_ACCESS_DENIED,
428 : "OpenPolicy3 return value should "
429 : "be ACCESS_DENIED or CONNECTION_DISCONNECTED");
430 0 : return true;
431 : }
432 :
433 0 : if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED) ||
434 0 : NT_STATUS_EQUAL(r.out.result,
435 : NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED)) {
436 0 : torture_comment(tctx,
437 : "OpenPolicy3 correctly returned with "
438 : "result: %s\n",
439 : nt_errstr(r.out.result));
440 0 : return true;
441 : }
442 :
443 0 : torture_fail(tctx,
444 : "OpenPolicy3 return value should be "
445 : "ACCESS_DENIED or RPC_PROTSEQ_NOT_SUPPORTED");
446 :
447 : return false;
448 : }
449 :
450 155 : static bool test_LookupNames(struct dcerpc_binding_handle *b,
451 : struct torture_context *tctx,
452 : struct policy_handle *handle,
453 : enum lsa_LookupNamesLevel level,
454 : struct lsa_TransNameArray *tnames)
455 : {
456 0 : struct lsa_LookupNames r;
457 0 : struct lsa_TransSidArray sids;
458 155 : struct lsa_RefDomainList *domains = NULL;
459 0 : struct lsa_String *names;
460 155 : uint32_t count = 0;
461 0 : int i;
462 0 : uint32_t *input_idx;
463 :
464 155 : torture_comment(tctx, "\nTesting LookupNames with %d names\n", tnames->count);
465 :
466 155 : sids.count = 0;
467 155 : sids.sids = NULL;
468 :
469 :
470 155 : r.in.num_names = 0;
471 :
472 155 : input_idx = talloc_array(tctx, uint32_t, tnames->count);
473 155 : names = talloc_array(tctx, struct lsa_String, tnames->count);
474 :
475 2345 : for (i=0;i<tnames->count;i++) {
476 2190 : if (tnames->names[i].sid_type != SID_NAME_UNKNOWN) {
477 2190 : init_lsa_String(&names[r.in.num_names], tnames->names[i].name.string);
478 2190 : input_idx[r.in.num_names] = i;
479 2190 : r.in.num_names++;
480 : }
481 : }
482 :
483 155 : r.in.handle = handle;
484 155 : r.in.names = names;
485 155 : r.in.sids = &sids;
486 155 : r.in.level = level;
487 155 : r.in.count = &count;
488 155 : r.out.count = &count;
489 155 : r.out.sids = &sids;
490 155 : r.out.domains = &domains;
491 :
492 155 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupNames_r(b, tctx, &r),
493 : "LookupNames failed");
494 155 : if (NT_STATUS_EQUAL(r.out.result, STATUS_SOME_UNMAPPED) ||
495 155 : NT_STATUS_EQUAL(r.out.result, NT_STATUS_NONE_MAPPED)) {
496 0 : for (i=0;i< r.in.num_names;i++) {
497 0 : if (i < count && sids.sids[i].sid_type == SID_NAME_UNKNOWN) {
498 0 : torture_comment(tctx, "LookupName of %s was unmapped\n",
499 0 : tnames->names[i].name.string);
500 0 : } else if (i >=count) {
501 0 : torture_comment(tctx, "LookupName of %s failed to return a result\n",
502 0 : tnames->names[i].name.string);
503 : }
504 : }
505 0 : torture_assert_ntstatus_ok(tctx, r.out.result,
506 : "LookupNames failed");
507 155 : } else if (!NT_STATUS_IS_OK(r.out.result)) {
508 0 : torture_assert_ntstatus_ok(tctx, r.out.result,
509 : "LookupNames failed");
510 : }
511 :
512 2345 : for (i=0;i< r.in.num_names;i++) {
513 2190 : torture_assert(tctx, (i < count),
514 : talloc_asprintf(tctx,
515 : "LookupName of %s failed to return a result\n",
516 : tnames->names[input_idx[i]].name.string));
517 :
518 2190 : torture_assert_int_equal(tctx,
519 : sids.sids[i].sid_type,
520 : tnames->names[input_idx[i]].sid_type,
521 : talloc_asprintf(tctx,
522 : "LookupName of %s got unexpected name type: %s\n",
523 : tnames->names[input_idx[i]].name.string,
524 : sid_type_lookup(sids.sids[i].sid_type)));
525 2190 : if (sids.sids[i].sid_type != SID_NAME_DOMAIN) {
526 1988 : continue;
527 : }
528 202 : torture_assert_int_equal(tctx,
529 : sids.sids[i].rid,
530 : UINT32_MAX,
531 : talloc_asprintf(tctx,
532 : "LookupName of %s got unexpected rid: %d\n",
533 : tnames->names[input_idx[i]].name.string,
534 : sids.sids[i].rid));
535 : }
536 :
537 155 : return true;
538 : }
539 :
540 5 : static bool test_LookupNames_bogus(struct dcerpc_binding_handle *b,
541 : struct torture_context *tctx,
542 : struct policy_handle *handle,
543 : enum lsa_LookupNamesLevel level)
544 : {
545 0 : struct lsa_LookupNames r;
546 0 : struct lsa_TransSidArray sids;
547 5 : struct lsa_RefDomainList *domains = NULL;
548 0 : struct lsa_String names[1];
549 5 : uint32_t count = 0;
550 :
551 5 : torture_comment(tctx, "\nTesting LookupNames with bogus name\n");
552 :
553 5 : sids.count = 0;
554 5 : sids.sids = NULL;
555 :
556 5 : init_lsa_String(&names[0], "NT AUTHORITY\\BOGUS");
557 :
558 5 : r.in.handle = handle;
559 5 : r.in.num_names = 1;
560 5 : r.in.names = names;
561 5 : r.in.sids = &sids;
562 5 : r.in.level = level;
563 5 : r.in.count = &count;
564 5 : r.out.count = &count;
565 5 : r.out.sids = &sids;
566 5 : r.out.domains = &domains;
567 :
568 5 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupNames_r(b, tctx, &r),
569 : "LookupNames bogus failed");
570 5 : if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_NONE_MAPPED)) {
571 0 : torture_comment(tctx, "LookupNames failed - %s\n",
572 : nt_errstr(r.out.result));
573 0 : return false;
574 : }
575 :
576 5 : torture_comment(tctx, "\n");
577 :
578 5 : return true;
579 : }
580 :
581 5 : static bool test_LookupNames_NULL(struct dcerpc_binding_handle *b,
582 : struct torture_context *tctx,
583 : struct policy_handle *handle,
584 : enum lsa_LookupNamesLevel level)
585 : {
586 0 : struct lsa_LookupNames r;
587 0 : struct lsa_TransSidArray sids;
588 5 : struct lsa_RefDomainList *domains = NULL;
589 0 : struct lsa_String names[1];
590 5 : uint32_t count = 0;
591 :
592 5 : torture_comment(tctx, "\nTesting LookupNames with NULL name\n");
593 :
594 5 : sids.count = 0;
595 5 : sids.sids = NULL;
596 :
597 5 : names[0].string = NULL;
598 :
599 5 : r.in.handle = handle;
600 5 : r.in.num_names = 1;
601 5 : r.in.names = names;
602 5 : r.in.sids = &sids;
603 5 : r.in.level = level;
604 5 : r.in.count = &count;
605 5 : r.out.count = &count;
606 5 : r.out.sids = &sids;
607 5 : r.out.domains = &domains;
608 :
609 : /* nt4 returns NT_STATUS_NONE_MAPPED with sid_type
610 : * SID_NAME_UNKNOWN, rid 0, and sid_index -1;
611 : *
612 : * w2k3/w2k8 return NT_STATUS_OK with sid_type
613 : * SID_NAME_DOMAIN, rid -1 and sid_index 0 and BUILTIN domain
614 : */
615 :
616 5 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupNames_r(b, tctx, &r),
617 : "LookupNames with NULL name failed");
618 5 : torture_assert_ntstatus_ok(tctx, r.out.result,
619 : "LookupNames with NULL name failed");
620 :
621 5 : torture_comment(tctx, "\n");
622 :
623 5 : return true;
624 : }
625 :
626 5 : static bool test_LookupNames_wellknown(struct dcerpc_binding_handle *b,
627 : struct torture_context *tctx,
628 : struct policy_handle *handle,
629 : enum lsa_LookupNamesLevel level)
630 : {
631 0 : struct lsa_TranslatedName name;
632 0 : struct lsa_TransNameArray tnames;
633 5 : bool ret = true;
634 :
635 5 : torture_comment(tctx, "Testing LookupNames with well known names\n");
636 :
637 5 : tnames.names = &name;
638 5 : tnames.count = 1;
639 5 : name.name.string = "NT AUTHORITY\\SYSTEM";
640 5 : name.sid_type = SID_NAME_WKN_GRP;
641 5 : ret &= test_LookupNames(b, tctx, handle, level, &tnames);
642 :
643 5 : name.name.string = "NT AUTHORITY\\ANONYMOUS LOGON";
644 5 : name.sid_type = SID_NAME_WKN_GRP;
645 5 : ret &= test_LookupNames(b, tctx, handle, level, &tnames);
646 :
647 5 : name.name.string = "NT AUTHORITY\\Authenticated Users";
648 5 : name.sid_type = SID_NAME_WKN_GRP;
649 5 : ret &= test_LookupNames(b, tctx, handle, level, &tnames);
650 :
651 : #if 0
652 : name.name.string = "NT AUTHORITY";
653 : ret &= test_LookupNames(b, tctx, handle, level, &tnames);
654 :
655 : name.name.string = "NT AUTHORITY\\";
656 : ret &= test_LookupNames(b, tctx, handle, level, &tnames);
657 : #endif
658 :
659 5 : name.name.string = "BUILTIN\\";
660 5 : name.sid_type = SID_NAME_DOMAIN;
661 5 : ret &= test_LookupNames(b, tctx, handle, level, &tnames);
662 :
663 5 : name.name.string = "BUILTIN\\Administrators";
664 5 : name.sid_type = SID_NAME_ALIAS;
665 5 : ret &= test_LookupNames(b, tctx, handle, level, &tnames);
666 :
667 5 : name.name.string = "SYSTEM";
668 5 : name.sid_type = SID_NAME_WKN_GRP;
669 5 : ret &= test_LookupNames(b, tctx, handle, level, &tnames);
670 :
671 5 : name.name.string = "Everyone";
672 5 : name.sid_type = SID_NAME_WKN_GRP;
673 5 : ret &= test_LookupNames(b, tctx, handle, level, &tnames);
674 5 : return ret;
675 : }
676 :
677 10 : static bool test_LookupNames2(struct dcerpc_binding_handle *b,
678 : struct torture_context *tctx,
679 : struct policy_handle *handle,
680 : enum lsa_LookupNamesLevel level,
681 : struct lsa_TransNameArray2 *tnames,
682 : bool check_result)
683 : {
684 0 : struct lsa_LookupNames2 r;
685 0 : struct lsa_TransSidArray2 sids;
686 10 : struct lsa_RefDomainList *domains = NULL;
687 0 : struct lsa_String *names;
688 0 : uint32_t *input_idx;
689 10 : uint32_t count = 0;
690 0 : int i;
691 :
692 10 : torture_comment(tctx, "\nTesting LookupNames2 with %d names\n", tnames->count);
693 :
694 10 : sids.count = 0;
695 10 : sids.sids = NULL;
696 :
697 10 : r.in.num_names = 0;
698 :
699 10 : input_idx = talloc_array(tctx, uint32_t, tnames->count);
700 10 : names = talloc_array(tctx, struct lsa_String, tnames->count);
701 :
702 45 : for (i=0;i<tnames->count;i++) {
703 35 : if (tnames->names[i].sid_type != SID_NAME_UNKNOWN) {
704 35 : init_lsa_String(&names[r.in.num_names], tnames->names[i].name.string);
705 35 : input_idx[r.in.num_names] = i;
706 35 : r.in.num_names++;
707 : }
708 : }
709 :
710 10 : r.in.handle = handle;
711 10 : r.in.names = names;
712 10 : r.in.sids = &sids;
713 10 : r.in.level = level;
714 10 : r.in.count = &count;
715 10 : r.in.lookup_options = 0;
716 10 : r.in.client_revision = 0;
717 10 : r.out.count = &count;
718 10 : r.out.sids = &sids;
719 10 : r.out.domains = &domains;
720 :
721 10 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupNames2_r(b, tctx, &r),
722 : "LookupNames2 failed");
723 10 : torture_assert_ntstatus_ok(tctx, r.out.result, "LookupNames2 failed");
724 :
725 10 : if (check_result) {
726 5 : torture_assert_int_equal(tctx, count, sids.count,
727 : "unexpected number of results returned");
728 5 : if (sids.count > 0) {
729 5 : torture_assert(tctx, sids.sids, "invalid sid buffer");
730 : }
731 : }
732 :
733 10 : torture_comment(tctx, "\n");
734 :
735 10 : return true;
736 : }
737 :
738 :
739 10 : static bool test_LookupNames3(struct dcerpc_binding_handle *b,
740 : struct torture_context *tctx,
741 : struct policy_handle *handle,
742 : enum lsa_LookupNamesLevel level,
743 : struct lsa_TransNameArray2 *tnames,
744 : bool check_result)
745 : {
746 0 : struct lsa_LookupNames3 r;
747 0 : struct lsa_TransSidArray3 sids;
748 10 : struct lsa_RefDomainList *domains = NULL;
749 0 : struct lsa_String *names;
750 10 : uint32_t count = 0;
751 0 : int i;
752 0 : uint32_t *input_idx;
753 :
754 10 : torture_comment(tctx, "\nTesting LookupNames3 with %d names\n", tnames->count);
755 :
756 10 : sids.count = 0;
757 10 : sids.sids = NULL;
758 :
759 10 : r.in.num_names = 0;
760 :
761 10 : input_idx = talloc_array(tctx, uint32_t, tnames->count);
762 10 : names = talloc_array(tctx, struct lsa_String, tnames->count);
763 45 : for (i=0;i<tnames->count;i++) {
764 35 : if (tnames->names[i].sid_type != SID_NAME_UNKNOWN) {
765 35 : init_lsa_String(&names[r.in.num_names], tnames->names[i].name.string);
766 35 : input_idx[r.in.num_names] = i;
767 35 : r.in.num_names++;
768 : }
769 : }
770 :
771 10 : r.in.handle = handle;
772 10 : r.in.names = names;
773 10 : r.in.sids = &sids;
774 10 : r.in.level = level;
775 10 : r.in.count = &count;
776 10 : r.in.lookup_options = 0;
777 10 : r.in.client_revision = 0;
778 10 : r.out.count = &count;
779 10 : r.out.sids = &sids;
780 10 : r.out.domains = &domains;
781 :
782 10 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupNames3_r(b, tctx, &r),
783 : "LookupNames3 failed");
784 10 : torture_assert_ntstatus_ok(tctx, r.out.result,
785 : "LookupNames3 failed");
786 :
787 10 : if (check_result) {
788 5 : torture_assert_int_equal(tctx, count, sids.count,
789 : "unexpected number of results returned");
790 5 : if (sids.count > 0) {
791 5 : torture_assert(tctx, sids.sids, "invalid sid buffer");
792 : }
793 : }
794 :
795 10 : torture_comment(tctx, "\n");
796 :
797 10 : return true;
798 : }
799 :
800 552 : static bool test_LookupNames4(struct dcerpc_binding_handle *b,
801 : struct torture_context *tctx,
802 : enum lsa_LookupNamesLevel level,
803 : struct lsa_TransNameArray2 *tnames,
804 : bool check_result)
805 : {
806 96 : struct lsa_LookupNames4 r;
807 96 : struct lsa_TransSidArray3 sids;
808 552 : struct lsa_RefDomainList *domains = NULL;
809 96 : struct lsa_String *names;
810 552 : uint32_t count = 0;
811 96 : int i;
812 96 : uint32_t *input_idx;
813 :
814 552 : torture_comment(tctx, "\nTesting LookupNames4 with %d names\n", tnames->count);
815 :
816 552 : sids.count = 0;
817 552 : sids.sids = NULL;
818 :
819 552 : r.in.num_names = 0;
820 :
821 552 : input_idx = talloc_array(tctx, uint32_t, tnames->count);
822 552 : names = talloc_array(tctx, struct lsa_String, tnames->count);
823 28248 : for (i=0;i<tnames->count;i++) {
824 27600 : if (tnames->names[i].sid_type != SID_NAME_UNKNOWN) {
825 27600 : init_lsa_String(&names[r.in.num_names], tnames->names[i].name.string);
826 27600 : input_idx[r.in.num_names] = i;
827 27600 : r.in.num_names++;
828 : }
829 : }
830 :
831 552 : r.in.num_names = tnames->count;
832 552 : r.in.names = names;
833 552 : r.in.sids = &sids;
834 552 : r.in.level = level;
835 552 : r.in.count = &count;
836 552 : r.in.lookup_options = 0;
837 552 : r.in.client_revision = 0;
838 552 : r.out.count = &count;
839 552 : r.out.sids = &sids;
840 552 : r.out.domains = &domains;
841 :
842 552 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupNames4_r(b, tctx, &r),
843 : "LookupNames4 failed");
844 :
845 552 : if (!NT_STATUS_IS_OK(r.out.result)) {
846 276 : if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NONE_MAPPED)) {
847 276 : torture_comment(tctx,
848 : "LookupNames4 failed: %s - not considered as an error",
849 : nt_errstr(r.out.result));
850 :
851 276 : return true;
852 : }
853 : }
854 276 : torture_assert_ntstatus_ok(tctx,
855 : r.out.result,
856 : "LookupNames4 failed");
857 :
858 276 : if (check_result) {
859 276 : torture_assert_int_equal(tctx, count, sids.count,
860 : "unexpected number of results returned");
861 276 : if (sids.count > 0) {
862 276 : torture_assert(tctx, sids.sids, "invalid sid buffer");
863 : }
864 : }
865 :
866 276 : torture_comment(tctx, "\n");
867 :
868 276 : return true;
869 : }
870 :
871 16 : static bool test_LookupNames4_fail(struct dcerpc_binding_handle *b,
872 : struct torture_context *tctx,
873 : enum lsa_LookupNamesLevel level)
874 : {
875 0 : struct lsa_LookupNames4 r;
876 0 : struct lsa_TransSidArray3 sids;
877 16 : struct lsa_RefDomainList *domains = NULL;
878 16 : struct lsa_String *names = NULL;
879 16 : uint32_t count = 0;
880 0 : NTSTATUS status;
881 :
882 16 : torture_comment(tctx, "\nTesting LookupNames4_fail");
883 :
884 16 : sids.count = 0;
885 16 : sids.sids = NULL;
886 :
887 16 : r.in.num_names = 0;
888 :
889 16 : r.in.num_names = count;
890 16 : r.in.names = names;
891 16 : r.in.sids = &sids;
892 16 : r.in.level = level;
893 16 : r.in.count = &count;
894 16 : r.in.lookup_options = 0;
895 16 : r.in.client_revision = 0;
896 16 : r.out.count = &count;
897 16 : r.out.sids = &sids;
898 16 : r.out.domains = &domains;
899 :
900 16 : status = dcerpc_lsa_LookupNames4_r(b, tctx, &r);
901 16 : if (!NT_STATUS_IS_OK(status)) {
902 16 : if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) ||
903 0 : NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_DISCONNECTED)) {
904 16 : torture_comment(tctx,
905 : "LookupNames4 correctly returned with "
906 : "status: %s\n",
907 : nt_errstr(status));
908 16 : return true;
909 : }
910 :
911 0 : torture_assert_ntstatus_equal(tctx,
912 : status,
913 : NT_STATUS_ACCESS_DENIED,
914 : "LookupNames4 return value should "
915 : "be ACCESS_DENIED");
916 0 : return true;
917 : }
918 :
919 0 : if (!NT_STATUS_IS_OK(r.out.result)) {
920 0 : if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED) ||
921 0 : NT_STATUS_EQUAL(r.out.result, NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED)) {
922 0 : torture_comment(tctx,
923 : "LookupSids3 correctly returned with "
924 : "result: %s\n",
925 : nt_errstr(r.out.result));
926 0 : return true;
927 : }
928 : }
929 :
930 0 : torture_fail(tctx,
931 : "LookupNames4 return value should be "
932 : "ACCESS_DENIED or RPC_PROTSEQ_NOT_SUPPORTED");
933 :
934 : return false;
935 : }
936 :
937 :
938 5 : static bool test_LookupSids(struct dcerpc_binding_handle *b,
939 : struct torture_context *tctx,
940 : struct policy_handle *handle,
941 : enum lsa_LookupNamesLevel level,
942 : struct lsa_SidArray *sids)
943 : {
944 0 : struct lsa_LookupSids r;
945 0 : struct lsa_TransNameArray names;
946 5 : struct lsa_RefDomainList *domains = NULL;
947 5 : uint32_t count = sids->num_sids;
948 :
949 5 : torture_comment(tctx, "\nTesting LookupSids\n");
950 :
951 5 : names.count = 0;
952 5 : names.names = NULL;
953 :
954 5 : r.in.handle = handle;
955 5 : r.in.sids = sids;
956 5 : r.in.names = &names;
957 5 : r.in.level = level;
958 5 : r.in.count = &count;
959 5 : r.out.count = &count;
960 5 : r.out.names = &names;
961 5 : r.out.domains = &domains;
962 :
963 5 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupSids_r(b, tctx, &r),
964 : "LookupSids failed");
965 5 : if (!NT_STATUS_EQUAL(r.out.result, STATUS_SOME_UNMAPPED)) {
966 5 : torture_assert_ntstatus_ok(tctx, r.out.result,
967 : "LookupSids failed");
968 : }
969 :
970 5 : torture_comment(tctx, "\n");
971 :
972 5 : if (!test_LookupNames(b, tctx, handle, level, &names)) {
973 0 : return false;
974 : }
975 :
976 5 : return true;
977 : }
978 :
979 :
980 5 : static bool test_LookupSids2(struct dcerpc_binding_handle *b,
981 : struct torture_context *tctx,
982 : struct policy_handle *handle,
983 : enum lsa_LookupNamesLevel level,
984 : struct lsa_SidArray *sids)
985 : {
986 0 : struct lsa_LookupSids2 r;
987 0 : struct lsa_TransNameArray2 names;
988 5 : struct lsa_RefDomainList *domains = NULL;
989 5 : uint32_t count = sids->num_sids;
990 :
991 5 : torture_comment(tctx, "\nTesting LookupSids2\n");
992 :
993 5 : names.count = 0;
994 5 : names.names = NULL;
995 :
996 5 : r.in.handle = handle;
997 5 : r.in.sids = sids;
998 5 : r.in.names = &names;
999 5 : r.in.level = level;
1000 5 : r.in.count = &count;
1001 5 : r.in.lookup_options = 0;
1002 5 : r.in.client_revision = 0;
1003 5 : r.out.count = &count;
1004 5 : r.out.names = &names;
1005 5 : r.out.domains = &domains;
1006 :
1007 5 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupSids2_r(b, tctx, &r),
1008 : "LookupSids2 failed");
1009 5 : if (!NT_STATUS_IS_OK(r.out.result) &&
1010 0 : !NT_STATUS_EQUAL(r.out.result, STATUS_SOME_UNMAPPED)) {
1011 0 : torture_comment(tctx, "LookupSids2 failed - %s\n",
1012 : nt_errstr(r.out.result));
1013 0 : return false;
1014 : }
1015 :
1016 5 : torture_comment(tctx, "\n");
1017 :
1018 5 : if (!test_LookupNames2(b, tctx, handle, level, &names, false)) {
1019 0 : return false;
1020 : }
1021 :
1022 5 : if (!test_LookupNames3(b, tctx, handle, level, &names, false)) {
1023 0 : return false;
1024 : }
1025 :
1026 5 : return true;
1027 : }
1028 :
1029 276 : static bool test_LookupSids3(struct dcerpc_binding_handle *b,
1030 : struct torture_context *tctx,
1031 : enum lsa_LookupNamesLevel level,
1032 : struct lsa_SidArray *sids)
1033 : {
1034 48 : struct lsa_LookupSids3 r;
1035 48 : struct lsa_TransNameArray2 names;
1036 276 : struct lsa_RefDomainList *domains = NULL;
1037 276 : uint32_t count = sids->num_sids;
1038 :
1039 276 : torture_comment(tctx, "\nTesting LookupSids3\n");
1040 :
1041 276 : names.count = 0;
1042 276 : names.names = NULL;
1043 :
1044 276 : r.in.sids = sids;
1045 276 : r.in.names = &names;
1046 276 : r.in.level = level;
1047 276 : r.in.count = &count;
1048 276 : r.in.lookup_options = 0;
1049 276 : r.in.client_revision = 0;
1050 276 : r.out.domains = &domains;
1051 276 : r.out.count = &count;
1052 276 : r.out.names = &names;
1053 :
1054 276 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupSids3_r(b, tctx, &r),
1055 : "LookupSids3 failed");
1056 :
1057 276 : if (!NT_STATUS_IS_OK(r.out.result)) {
1058 0 : if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NONE_MAPPED)) {
1059 0 : torture_comment(tctx,
1060 : "LookupSids3 failed: %s - not considered as an error",
1061 : nt_errstr(r.out.result));
1062 :
1063 0 : return true;
1064 : }
1065 :
1066 0 : torture_assert_ntstatus_ok(tctx,
1067 : r.out.result,
1068 : "LookupSids3 failed");
1069 :
1070 0 : return false;
1071 : }
1072 :
1073 276 : torture_comment(tctx, "\n");
1074 :
1075 276 : if (!test_LookupNames4(b, tctx, level, &names, true)) {
1076 0 : return false;
1077 : }
1078 :
1079 228 : return true;
1080 : }
1081 :
1082 16 : static bool test_LookupSids3_fail(struct dcerpc_binding_handle *b,
1083 : struct torture_context *tctx,
1084 : enum lsa_LookupNamesLevel level,
1085 : struct lsa_SidArray *sids)
1086 : {
1087 0 : struct lsa_LookupSids3 r;
1088 0 : struct lsa_TransNameArray2 names;
1089 16 : struct lsa_RefDomainList *domains = NULL;
1090 16 : uint32_t count = sids->num_sids;
1091 0 : NTSTATUS status;
1092 :
1093 16 : torture_comment(tctx, "\nTesting LookupSids3\n");
1094 :
1095 16 : names.count = 0;
1096 16 : names.names = NULL;
1097 :
1098 16 : r.in.sids = sids;
1099 16 : r.in.names = &names;
1100 16 : r.in.level = level;
1101 16 : r.in.count = &count;
1102 16 : r.in.lookup_options = 0;
1103 16 : r.in.client_revision = 0;
1104 16 : r.out.domains = &domains;
1105 16 : r.out.count = &count;
1106 16 : r.out.names = &names;
1107 :
1108 16 : status = dcerpc_lsa_LookupSids3_r(b, tctx, &r);
1109 16 : if (!NT_STATUS_IS_OK(status)) {
1110 16 : if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) ||
1111 0 : NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_DISCONNECTED)) {
1112 16 : torture_comment(tctx,
1113 : "LookupSids3 correctly returned with "
1114 : "status: %s\n",
1115 : nt_errstr(status));
1116 16 : return true;
1117 : }
1118 :
1119 0 : torture_assert_ntstatus_equal(tctx,
1120 : status,
1121 : NT_STATUS_ACCESS_DENIED,
1122 : "LookupSids3 return value should "
1123 : "be ACCESS_DENIED");
1124 0 : return true;
1125 : }
1126 :
1127 0 : if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED) ||
1128 0 : NT_STATUS_EQUAL(r.out.result, NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED)) {
1129 0 : torture_comment(tctx,
1130 : "LookupNames4 correctly returned with "
1131 : "result: %s\n",
1132 : nt_errstr(r.out.result));
1133 0 : return true;
1134 : }
1135 :
1136 0 : torture_fail(tctx,
1137 : "LookupSids3 return value should be "
1138 : "ACCESS_DENIED or RPC_PROTSEQ_NOT_SUPPORTED");
1139 :
1140 : return false;
1141 : }
1142 :
1143 295 : bool test_many_LookupSids(struct dcerpc_pipe *p,
1144 : struct torture_context *tctx,
1145 : struct policy_handle *handle,
1146 : enum lsa_LookupNamesLevel level)
1147 : {
1148 48 : uint32_t count;
1149 48 : struct lsa_SidArray sids;
1150 48 : int i;
1151 295 : struct dcerpc_binding_handle *b = p->binding_handle;
1152 295 : enum dcerpc_transport_t transport = dcerpc_binding_get_transport(p->binding);
1153 :
1154 295 : torture_comment(tctx, "\nTesting LookupSids with lots of SIDs\n");
1155 :
1156 295 : sids.num_sids = 100;
1157 :
1158 295 : sids.sids = talloc_array(tctx, struct lsa_SidPtr, sids.num_sids);
1159 :
1160 29795 : for (i=0; i<sids.num_sids; i++) {
1161 29500 : const char *sidstr = "S-1-5-32-545";
1162 29500 : sids.sids[i].sid = dom_sid_parse_talloc(tctx, sidstr);
1163 : }
1164 :
1165 295 : count = sids.num_sids;
1166 :
1167 295 : if (handle) {
1168 0 : struct lsa_LookupSids r;
1169 0 : struct lsa_TransNameArray names;
1170 14 : struct lsa_RefDomainList *domains = NULL;
1171 14 : names.count = 0;
1172 14 : names.names = NULL;
1173 :
1174 14 : r.in.handle = handle;
1175 14 : r.in.sids = &sids;
1176 14 : r.in.names = &names;
1177 14 : r.in.level = level;
1178 14 : r.in.count = &names.count;
1179 14 : r.out.count = &count;
1180 14 : r.out.names = &names;
1181 14 : r.out.domains = &domains;
1182 :
1183 14 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupSids_r(b, tctx, &r),
1184 : "LookupSids failed");
1185 14 : if (!NT_STATUS_IS_OK(r.out.result)) {
1186 0 : torture_comment(tctx, "LookupSids failed - %s\n",
1187 : nt_errstr(r.out.result));
1188 0 : return false;
1189 : }
1190 :
1191 14 : torture_comment(tctx, "\n");
1192 :
1193 14 : if (!test_LookupNames(b, tctx, handle, level, &names)) {
1194 0 : return false;
1195 : }
1196 : }
1197 :
1198 295 : if (transport == NCACN_NP) {
1199 11 : if (!test_LookupSids3_fail(b, tctx, level, &sids)) {
1200 0 : return false;
1201 : }
1202 11 : if (!test_LookupNames4_fail(b, tctx, level)) {
1203 0 : return false;
1204 : }
1205 284 : } else if (transport == NCACN_IP_TCP) {
1206 48 : struct lsa_TransNameArray2 names;
1207 48 : enum dcerpc_AuthType auth_type;
1208 48 : enum dcerpc_AuthLevel auth_level;
1209 :
1210 281 : names.count = 0;
1211 281 : names.names = NULL;
1212 :
1213 281 : dcerpc_binding_handle_auth_info(p->binding_handle,
1214 : &auth_type, &auth_level);
1215 :
1216 281 : if (auth_type == DCERPC_AUTH_TYPE_SCHANNEL &&
1217 276 : auth_level >= DCERPC_AUTH_LEVEL_INTEGRITY) {
1218 276 : if (!test_LookupSids3(b, tctx, level, &sids)) {
1219 0 : return false;
1220 : }
1221 276 : if (!test_LookupNames4(b, tctx, level, &names, true)) {
1222 0 : return false;
1223 : }
1224 : } else {
1225 : /*
1226 : * If we don't have a secure channel these tests must
1227 : * fail with ACCESS_DENIED.
1228 : */
1229 5 : if (!test_LookupSids3_fail(b, tctx, level, &sids)) {
1230 0 : return false;
1231 : }
1232 5 : if (!test_LookupNames4_fail(b, tctx, level)) {
1233 0 : return false;
1234 : }
1235 : }
1236 : }
1237 :
1238 295 : torture_comment(tctx, "\n");
1239 :
1240 :
1241 :
1242 295 : return true;
1243 : }
1244 :
1245 700 : static void lookupsids_cb(struct tevent_req *subreq)
1246 : {
1247 700 : int *replies = (int *)tevent_req_callback_data_void(subreq);
1248 0 : NTSTATUS status;
1249 :
1250 700 : status = dcerpc_lsa_LookupSids_r_recv(subreq, subreq);
1251 700 : TALLOC_FREE(subreq);
1252 700 : if (!NT_STATUS_IS_OK(status)) {
1253 0 : printf("lookupsids returned %s\n", nt_errstr(status));
1254 0 : *replies = -1;
1255 : }
1256 :
1257 700 : if (*replies >= 0) {
1258 700 : *replies += 1;
1259 : }
1260 700 : }
1261 :
1262 14 : static bool test_LookupSids_async(struct dcerpc_binding_handle *b,
1263 : struct torture_context *tctx,
1264 : struct policy_handle *handle,
1265 : enum lsa_LookupNamesLevel level)
1266 : {
1267 0 : struct lsa_SidArray sids;
1268 0 : struct lsa_SidPtr sidptr;
1269 0 : uint32_t *count;
1270 0 : struct lsa_TransNameArray *names;
1271 0 : struct lsa_LookupSids *r;
1272 14 : struct lsa_RefDomainList *domains = NULL;
1273 0 : struct tevent_req **req;
1274 0 : int i, replies;
1275 14 : bool ret = true;
1276 14 : const int num_async_requests = 50;
1277 :
1278 14 : count = talloc_array(tctx, uint32_t, num_async_requests);
1279 14 : names = talloc_array(tctx, struct lsa_TransNameArray, num_async_requests);
1280 14 : r = talloc_array(tctx, struct lsa_LookupSids, num_async_requests);
1281 :
1282 14 : torture_comment(tctx, "\nTesting %d async lookupsids request\n", num_async_requests);
1283 :
1284 14 : req = talloc_array(tctx, struct tevent_req *, num_async_requests);
1285 :
1286 14 : sids.num_sids = 1;
1287 14 : sids.sids = &sidptr;
1288 14 : sidptr.sid = dom_sid_parse_talloc(tctx, "S-1-5-32-545");
1289 :
1290 14 : replies = 0;
1291 :
1292 714 : for (i=0; i<num_async_requests; i++) {
1293 700 : count[i] = 0;
1294 700 : names[i].count = 0;
1295 700 : names[i].names = NULL;
1296 :
1297 700 : r[i].in.handle = handle;
1298 700 : r[i].in.sids = &sids;
1299 700 : r[i].in.names = &names[i];
1300 700 : r[i].in.level = level;
1301 700 : r[i].in.count = &names[i].count;
1302 700 : r[i].out.count = &count[i];
1303 700 : r[i].out.names = &names[i];
1304 700 : r[i].out.domains = &domains;
1305 :
1306 700 : req[i] = dcerpc_lsa_LookupSids_r_send(tctx, tctx->ev, b, &r[i]);
1307 700 : if (req[i] == NULL) {
1308 0 : ret = false;
1309 0 : break;
1310 : }
1311 :
1312 700 : tevent_req_set_callback(req[i], lookupsids_cb, &replies);
1313 : }
1314 :
1315 7567 : while (replies >= 0 && replies < num_async_requests) {
1316 7553 : tevent_loop_once(tctx->ev);
1317 : }
1318 :
1319 14 : talloc_free(req);
1320 :
1321 14 : if (replies < 0) {
1322 0 : ret = false;
1323 : }
1324 :
1325 14 : return ret;
1326 : }
1327 :
1328 93 : static bool test_LookupPrivValue(struct dcerpc_binding_handle *b,
1329 : struct torture_context *tctx,
1330 : struct policy_handle *handle,
1331 : struct lsa_String *name)
1332 : {
1333 0 : struct lsa_LookupPrivValue r;
1334 0 : struct lsa_LUID luid;
1335 :
1336 93 : r.in.handle = handle;
1337 93 : r.in.name = name;
1338 93 : r.out.luid = &luid;
1339 :
1340 93 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupPrivValue_r(b, tctx, &r),
1341 : "LookupPrivValue failed");
1342 93 : torture_assert_ntstatus_ok(tctx, r.out.result,
1343 : "LookupPrivValue failed");
1344 :
1345 93 : return true;
1346 : }
1347 :
1348 146 : static bool test_LookupPrivName(struct dcerpc_binding_handle *b,
1349 : struct torture_context *tctx,
1350 : struct policy_handle *handle,
1351 : struct lsa_LUID *luid)
1352 : {
1353 0 : struct lsa_LookupPrivName r;
1354 146 : struct lsa_StringLarge *name = NULL;
1355 :
1356 146 : r.in.handle = handle;
1357 146 : r.in.luid = luid;
1358 146 : r.out.name = &name;
1359 :
1360 146 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupPrivName_r(b, tctx, &r),
1361 : "LookupPrivName failed");
1362 146 : torture_assert_ntstatus_ok(tctx, r.out.result, "LookupPrivName failed");
1363 :
1364 146 : return true;
1365 : }
1366 :
1367 17 : static bool test_RemovePrivilegesFromAccount(struct dcerpc_binding_handle *b,
1368 : struct torture_context *tctx,
1369 : struct policy_handle *handle,
1370 : struct policy_handle *acct_handle,
1371 : struct lsa_LUID *luid)
1372 : {
1373 0 : struct lsa_RemovePrivilegesFromAccount r;
1374 0 : struct lsa_PrivilegeSet privs;
1375 17 : bool ret = true;
1376 :
1377 17 : torture_comment(tctx, "\nTesting RemovePrivilegesFromAccount\n");
1378 :
1379 17 : r.in.handle = acct_handle;
1380 17 : r.in.remove_all = 0;
1381 17 : r.in.privs = &privs;
1382 :
1383 17 : privs.count = 1;
1384 17 : privs.unknown = 0;
1385 17 : privs.set = talloc_array(tctx, struct lsa_LUIDAttribute, 1);
1386 17 : privs.set[0].luid = *luid;
1387 17 : privs.set[0].attribute = 0;
1388 :
1389 17 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_RemovePrivilegesFromAccount_r(b, tctx, &r),
1390 : "RemovePrivilegesFromAccount failed");
1391 17 : if (!NT_STATUS_IS_OK(r.out.result)) {
1392 :
1393 0 : struct lsa_LookupPrivName r_name;
1394 0 : struct lsa_StringLarge *name = NULL;
1395 :
1396 0 : r_name.in.handle = handle;
1397 0 : r_name.in.luid = luid;
1398 0 : r_name.out.name = &name;
1399 :
1400 0 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupPrivName_r(b, tctx, &r_name),
1401 : "LookupPrivName failed");
1402 0 : if (!NT_STATUS_IS_OK(r_name.out.result)) {
1403 0 : torture_comment(tctx, "\nLookupPrivName failed - %s\n",
1404 : nt_errstr(r_name.out.result));
1405 0 : return false;
1406 : }
1407 : /* Windows 2008 does not allow this to be removed */
1408 0 : if (strcmp("SeAuditPrivilege", name->string) == 0) {
1409 0 : return ret;
1410 : }
1411 :
1412 0 : torture_comment(tctx, "RemovePrivilegesFromAccount failed to remove %s - %s\n",
1413 0 : name->string,
1414 : nt_errstr(r.out.result));
1415 0 : return false;
1416 : }
1417 :
1418 17 : return ret;
1419 : }
1420 :
1421 17 : static bool test_AddPrivilegesToAccount(struct dcerpc_binding_handle *b,
1422 : struct torture_context *tctx,
1423 : struct policy_handle *acct_handle,
1424 : struct lsa_LUID *luid)
1425 : {
1426 0 : struct lsa_AddPrivilegesToAccount r;
1427 0 : struct lsa_PrivilegeSet privs;
1428 17 : bool ret = true;
1429 :
1430 17 : torture_comment(tctx, "\nTesting AddPrivilegesToAccount\n");
1431 :
1432 17 : r.in.handle = acct_handle;
1433 17 : r.in.privs = &privs;
1434 :
1435 17 : privs.count = 1;
1436 17 : privs.unknown = 0;
1437 17 : privs.set = talloc_array(tctx, struct lsa_LUIDAttribute, 1);
1438 17 : privs.set[0].luid = *luid;
1439 17 : privs.set[0].attribute = 0;
1440 :
1441 17 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_AddPrivilegesToAccount_r(b, tctx, &r),
1442 : "AddPrivilegesToAccount failed");
1443 17 : torture_assert_ntstatus_ok(tctx, r.out.result,
1444 : "AddPrivilegesToAccount failed");
1445 17 : return ret;
1446 : }
1447 :
1448 30 : static bool test_EnumPrivsAccount(struct dcerpc_binding_handle *b,
1449 : struct torture_context *tctx,
1450 : struct policy_handle *handle,
1451 : struct policy_handle *acct_handle)
1452 : {
1453 0 : struct lsa_EnumPrivsAccount r;
1454 30 : struct lsa_PrivilegeSet *privs = NULL;
1455 30 : bool ret = true;
1456 :
1457 30 : torture_comment(tctx, "\nTesting EnumPrivsAccount\n");
1458 :
1459 30 : r.in.handle = acct_handle;
1460 30 : r.out.privs = &privs;
1461 :
1462 30 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumPrivsAccount_r(b, tctx, &r),
1463 : "EnumPrivsAccount failed");
1464 30 : torture_assert_ntstatus_ok(tctx, r.out.result,
1465 : "EnumPrivsAccount failed");
1466 :
1467 30 : if (privs && privs->count > 0) {
1468 : int i;
1469 163 : for (i=0;i<privs->count;i++) {
1470 146 : test_LookupPrivName(b, tctx, handle,
1471 146 : &privs->set[i].luid);
1472 : }
1473 :
1474 34 : ret &= test_RemovePrivilegesFromAccount(b, tctx, handle, acct_handle,
1475 17 : &privs->set[0].luid);
1476 17 : ret &= test_AddPrivilegesToAccount(b, tctx, acct_handle,
1477 17 : &privs->set[0].luid);
1478 : }
1479 :
1480 30 : return ret;
1481 : }
1482 :
1483 30 : static bool test_GetSystemAccessAccount(struct dcerpc_binding_handle *b,
1484 : struct torture_context *tctx,
1485 : struct policy_handle *handle,
1486 : struct policy_handle *acct_handle)
1487 : {
1488 0 : uint32_t access_mask;
1489 0 : struct lsa_GetSystemAccessAccount r;
1490 :
1491 30 : torture_comment(tctx, "\nTesting GetSystemAccessAccount\n");
1492 :
1493 30 : r.in.handle = acct_handle;
1494 30 : r.out.access_mask = &access_mask;
1495 :
1496 30 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_GetSystemAccessAccount_r(b, tctx, &r),
1497 : "GetSystemAccessAccount failed");
1498 30 : torture_assert_ntstatus_ok(tctx, r.out.result,
1499 : "GetSystemAccessAccount failed");
1500 :
1501 30 : if (r.out.access_mask != NULL) {
1502 30 : torture_comment(tctx, "Rights:");
1503 30 : if (*(r.out.access_mask) & LSA_POLICY_MODE_INTERACTIVE)
1504 27 : torture_comment(tctx, " LSA_POLICY_MODE_INTERACTIVE");
1505 30 : if (*(r.out.access_mask) & LSA_POLICY_MODE_NETWORK)
1506 15 : torture_comment(tctx, " LSA_POLICY_MODE_NETWORK");
1507 30 : if (*(r.out.access_mask) & LSA_POLICY_MODE_BATCH)
1508 0 : torture_comment(tctx, " LSA_POLICY_MODE_BATCH");
1509 30 : if (*(r.out.access_mask) & LSA_POLICY_MODE_SERVICE)
1510 0 : torture_comment(tctx, " LSA_POLICY_MODE_SERVICE");
1511 30 : if (*(r.out.access_mask) & LSA_POLICY_MODE_PROXY)
1512 0 : torture_comment(tctx, " LSA_POLICY_MODE_PROXY");
1513 30 : if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_INTERACTIVE)
1514 0 : torture_comment(tctx, " LSA_POLICY_MODE_DENY_INTERACTIVE");
1515 30 : if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_NETWORK)
1516 0 : torture_comment(tctx, " LSA_POLICY_MODE_DENY_NETWORK");
1517 30 : if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_BATCH)
1518 0 : torture_comment(tctx, " LSA_POLICY_MODE_DENY_BATCH");
1519 30 : if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_SERVICE)
1520 0 : torture_comment(tctx, " LSA_POLICY_MODE_DENY_SERVICE");
1521 30 : if (*(r.out.access_mask) & LSA_POLICY_MODE_REMOTE_INTERACTIVE)
1522 6 : torture_comment(tctx, " LSA_POLICY_MODE_REMOTE_INTERACTIVE");
1523 30 : if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_REMOTE_INTERACTIVE)
1524 0 : torture_comment(tctx, " LSA_POLICY_MODE_DENY_REMOTE_INTERACTIVE");
1525 30 : if (*(r.out.access_mask) & LSA_POLICY_MODE_ALL)
1526 30 : torture_comment(tctx, " LSA_POLICY_MODE_ALL");
1527 30 : if (*(r.out.access_mask) & LSA_POLICY_MODE_ALL_NT4)
1528 27 : torture_comment(tctx, " LSA_POLICY_MODE_ALL_NT4");
1529 30 : torture_comment(tctx, "\n");
1530 : }
1531 :
1532 30 : return true;
1533 : }
1534 :
1535 41 : static bool test_Delete(struct dcerpc_binding_handle *b,
1536 : struct torture_context *tctx,
1537 : struct policy_handle *handle)
1538 : {
1539 0 : struct lsa_Delete r;
1540 :
1541 41 : torture_comment(tctx, "\nTesting Delete\n");
1542 :
1543 41 : r.in.handle = handle;
1544 41 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_Delete_r(b, tctx, &r),
1545 : "Delete failed");
1546 41 : torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_SUPPORTED,
1547 : "Delete should have failed NT_STATUS_NOT_SUPPORTED");
1548 :
1549 41 : return true;
1550 : }
1551 :
1552 27 : static bool test_DeleteObject(struct dcerpc_binding_handle *b,
1553 : struct torture_context *tctx,
1554 : struct policy_handle *handle)
1555 : {
1556 0 : struct lsa_DeleteObject r;
1557 :
1558 27 : torture_comment(tctx, "\nTesting DeleteObject\n");
1559 :
1560 27 : r.in.handle = handle;
1561 27 : r.out.handle = handle;
1562 27 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_DeleteObject_r(b, tctx, &r),
1563 : "DeleteObject failed");
1564 27 : torture_assert_ntstatus_ok(tctx, r.out.result,
1565 : "DeleteObject failed");
1566 :
1567 27 : return true;
1568 : }
1569 :
1570 :
1571 5 : static bool test_CreateAccount(struct dcerpc_binding_handle *b,
1572 : struct torture_context *tctx,
1573 : struct policy_handle *handle)
1574 : {
1575 0 : struct lsa_CreateAccount r;
1576 0 : struct dom_sid2 *newsid;
1577 0 : struct policy_handle acct_handle;
1578 :
1579 5 : newsid = dom_sid_parse_talloc(tctx, "S-1-5-12349876-4321-2854");
1580 :
1581 5 : torture_comment(tctx, "\nTesting CreateAccount\n");
1582 :
1583 5 : r.in.handle = handle;
1584 5 : r.in.sid = newsid;
1585 5 : r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1586 5 : r.out.acct_handle = &acct_handle;
1587 :
1588 5 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_CreateAccount_r(b, tctx, &r),
1589 : "CreateAccount failed");
1590 5 : if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_OBJECT_NAME_COLLISION)) {
1591 0 : struct lsa_OpenAccount r_o;
1592 0 : r_o.in.handle = handle;
1593 0 : r_o.in.sid = newsid;
1594 0 : r_o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1595 0 : r_o.out.acct_handle = &acct_handle;
1596 :
1597 0 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenAccount_r(b, tctx, &r_o),
1598 : "OpenAccount failed");
1599 0 : torture_assert_ntstatus_ok(tctx, r_o.out.result,
1600 : "OpenAccount failed");
1601 : } else {
1602 5 : torture_assert_ntstatus_ok(tctx, r.out.result,
1603 : "CreateAccount failed");
1604 : }
1605 :
1606 5 : if (!test_Delete(b, tctx, &acct_handle)) {
1607 0 : return false;
1608 : }
1609 :
1610 5 : if (!test_DeleteObject(b, tctx, &acct_handle)) {
1611 0 : return false;
1612 : }
1613 :
1614 5 : return true;
1615 : }
1616 :
1617 0 : static bool test_DeleteTrustedDomain(struct dcerpc_binding_handle *b,
1618 : struct torture_context *tctx,
1619 : struct policy_handle *handle,
1620 : struct lsa_StringLarge name)
1621 : {
1622 0 : struct lsa_OpenTrustedDomainByName r;
1623 0 : struct policy_handle trustdom_handle;
1624 :
1625 0 : r.in.handle = handle;
1626 0 : r.in.name.string = name.string;
1627 0 : r.in.access_mask = SEC_STD_DELETE;
1628 0 : r.out.trustdom_handle = &trustdom_handle;
1629 :
1630 0 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenTrustedDomainByName_r(b, tctx, &r),
1631 : "OpenTrustedDomainByName failed");
1632 0 : torture_assert_ntstatus_ok(tctx, r.out.result,
1633 : "OpenTrustedDomainByName failed");
1634 :
1635 0 : if (!test_Delete(b, tctx, &trustdom_handle)) {
1636 0 : return false;
1637 : }
1638 :
1639 0 : if (!test_DeleteObject(b, tctx, &trustdom_handle)) {
1640 0 : return false;
1641 : }
1642 :
1643 0 : return true;
1644 : }
1645 :
1646 108 : static bool test_DeleteTrustedDomainBySid(struct dcerpc_binding_handle *b,
1647 : struct torture_context *tctx,
1648 : struct policy_handle *handle,
1649 : struct dom_sid *sid)
1650 : {
1651 0 : struct lsa_DeleteTrustedDomain r;
1652 :
1653 108 : r.in.handle = handle;
1654 108 : r.in.dom_sid = sid;
1655 :
1656 108 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_DeleteTrustedDomain_r(b, tctx, &r),
1657 : "DeleteTrustedDomain failed");
1658 108 : torture_assert_ntstatus_ok(tctx, r.out.result,
1659 : "DeleteTrustedDomain failed");
1660 :
1661 108 : return true;
1662 : }
1663 :
1664 :
1665 14 : static bool test_CreateSecret(struct dcerpc_pipe *p,
1666 : struct torture_context *tctx,
1667 : struct policy_handle *handle)
1668 : {
1669 0 : struct lsa_CreateSecret r;
1670 0 : struct lsa_OpenSecret r2;
1671 0 : struct lsa_SetSecret r3;
1672 0 : struct lsa_QuerySecret r4;
1673 0 : struct lsa_SetSecret r5;
1674 0 : struct lsa_QuerySecret r6;
1675 0 : struct lsa_SetSecret r7;
1676 0 : struct lsa_QuerySecret r8;
1677 0 : struct policy_handle sec_handle, sec_handle2, sec_handle3;
1678 0 : struct lsa_DeleteObject d_o;
1679 0 : struct lsa_DATA_BUF buf1;
1680 0 : struct lsa_DATA_BUF_PTR bufp1;
1681 0 : struct lsa_DATA_BUF_PTR bufp2;
1682 0 : DATA_BLOB enc_key;
1683 14 : bool ret = true;
1684 0 : DATA_BLOB session_key;
1685 0 : NTTIME old_mtime, new_mtime;
1686 0 : DATA_BLOB blob1;
1687 14 : const char *secret1 = "abcdef12345699qwerty";
1688 0 : char *secret2;
1689 14 : const char *secret3 = "ABCDEF12345699QWERTY";
1690 0 : char *secret4;
1691 14 : const char *secret5 = "NEW-SAMBA4-SECRET";
1692 0 : char *secret6;
1693 0 : char *secname[2];
1694 0 : int i;
1695 14 : const int LOCAL = 0;
1696 14 : const int GLOBAL = 1;
1697 14 : struct dcerpc_binding_handle *b = p->binding_handle;
1698 :
1699 14 : secname[LOCAL] = talloc_asprintf(tctx, "torturesecret-%u", (unsigned int)random());
1700 14 : secname[GLOBAL] = talloc_asprintf(tctx, "G$torturesecret-%u", (unsigned int)random());
1701 :
1702 36 : for (i=0; i< 2; i++) {
1703 25 : torture_comment(tctx, "\nTesting CreateSecret of %s\n", secname[i]);
1704 :
1705 25 : init_lsa_String(&r.in.name, secname[i]);
1706 :
1707 25 : r.in.handle = handle;
1708 25 : r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1709 25 : r.out.sec_handle = &sec_handle;
1710 :
1711 25 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_CreateSecret_r(b, tctx, &r),
1712 : "CreateSecret failed");
1713 25 : torture_assert_ntstatus_ok(tctx, r.out.result,
1714 : "CreateSecret failed");
1715 :
1716 25 : r.in.handle = handle;
1717 25 : r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1718 25 : r.out.sec_handle = &sec_handle3;
1719 :
1720 25 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_CreateSecret_r(b, tctx, &r),
1721 : "CreateSecret failed");
1722 25 : torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_OBJECT_NAME_COLLISION,
1723 : "CreateSecret should have failed OBJECT_NAME_COLLISION");
1724 :
1725 25 : r2.in.handle = handle;
1726 25 : r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1727 25 : r2.in.name = r.in.name;
1728 25 : r2.out.sec_handle = &sec_handle2;
1729 :
1730 25 : torture_comment(tctx, "Testing OpenSecret\n");
1731 :
1732 25 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenSecret_r(b, tctx, &r2),
1733 : "OpenSecret failed");
1734 25 : torture_assert_ntstatus_ok(tctx, r2.out.result,
1735 : "OpenSecret failed");
1736 :
1737 25 : torture_assert_ntstatus_ok(tctx, dcerpc_fetch_session_key(p, &session_key),
1738 : "dcerpc_fetch_session_key failed");
1739 :
1740 22 : enc_key = sess_encrypt_string(secret1, &session_key);
1741 :
1742 22 : r3.in.sec_handle = &sec_handle;
1743 22 : r3.in.new_val = &buf1;
1744 22 : r3.in.old_val = NULL;
1745 22 : r3.in.new_val->data = enc_key.data;
1746 22 : r3.in.new_val->length = enc_key.length;
1747 22 : r3.in.new_val->size = enc_key.length;
1748 :
1749 22 : torture_comment(tctx, "Testing SetSecret\n");
1750 :
1751 22 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_SetSecret_r(b, tctx, &r3),
1752 : "SetSecret failed");
1753 22 : torture_assert_ntstatus_ok(tctx, r3.out.result,
1754 : "SetSecret failed");
1755 :
1756 22 : r3.in.sec_handle = &sec_handle;
1757 22 : r3.in.new_val = &buf1;
1758 22 : r3.in.old_val = NULL;
1759 22 : r3.in.new_val->data = enc_key.data;
1760 22 : r3.in.new_val->length = enc_key.length;
1761 22 : r3.in.new_val->size = enc_key.length;
1762 :
1763 : /* break the encrypted data */
1764 22 : enc_key.data[0]++;
1765 :
1766 22 : torture_comment(tctx, "Testing SetSecret with broken key\n");
1767 :
1768 22 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_SetSecret_r(b, tctx, &r3),
1769 : "SetSecret failed");
1770 22 : torture_assert_ntstatus_equal(tctx, r3.out.result, NT_STATUS_UNKNOWN_REVISION,
1771 : "SetSecret should have failed UNKNOWN_REVISION");
1772 :
1773 22 : data_blob_free(&enc_key);
1774 :
1775 22 : ZERO_STRUCT(new_mtime);
1776 22 : ZERO_STRUCT(old_mtime);
1777 :
1778 : /* fetch the secret back again */
1779 22 : r4.in.sec_handle = &sec_handle;
1780 22 : r4.in.new_val = &bufp1;
1781 22 : r4.in.new_mtime = &new_mtime;
1782 22 : r4.in.old_val = NULL;
1783 22 : r4.in.old_mtime = NULL;
1784 :
1785 22 : bufp1.buf = NULL;
1786 :
1787 22 : torture_comment(tctx, "Testing QuerySecret\n");
1788 22 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QuerySecret_r(b, tctx, &r4),
1789 : "QuerySecret failed");
1790 22 : if (!NT_STATUS_IS_OK(r4.out.result)) {
1791 0 : torture_comment(tctx, "QuerySecret failed - %s\n", nt_errstr(r4.out.result));
1792 0 : ret = false;
1793 : } else {
1794 22 : if (r4.out.new_val == NULL || r4.out.new_val->buf == NULL) {
1795 0 : torture_comment(tctx, "No secret buffer returned\n");
1796 0 : ret = false;
1797 : } else {
1798 22 : blob1.data = r4.out.new_val->buf->data;
1799 22 : blob1.length = r4.out.new_val->buf->size;
1800 :
1801 22 : secret2 = sess_decrypt_string(tctx,
1802 : &blob1, &session_key);
1803 :
1804 22 : if (strcmp(secret1, secret2) != 0) {
1805 0 : torture_comment(tctx, "Returned secret (r4) '%s' doesn't match '%s'\n",
1806 : secret2, secret1);
1807 0 : ret = false;
1808 : }
1809 : }
1810 : }
1811 :
1812 22 : enc_key = sess_encrypt_string(secret3, &session_key);
1813 :
1814 22 : r5.in.sec_handle = &sec_handle;
1815 22 : r5.in.new_val = &buf1;
1816 22 : r5.in.old_val = NULL;
1817 22 : r5.in.new_val->data = enc_key.data;
1818 22 : r5.in.new_val->length = enc_key.length;
1819 22 : r5.in.new_val->size = enc_key.length;
1820 :
1821 :
1822 22 : smb_msleep(200);
1823 22 : torture_comment(tctx, "Testing SetSecret (existing value should move to old)\n");
1824 :
1825 22 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_SetSecret_r(b, tctx, &r5),
1826 : "SetSecret failed");
1827 22 : if (!NT_STATUS_IS_OK(r5.out.result)) {
1828 0 : torture_comment(tctx, "SetSecret failed - %s\n", nt_errstr(r5.out.result));
1829 0 : ret = false;
1830 : }
1831 :
1832 22 : data_blob_free(&enc_key);
1833 :
1834 22 : ZERO_STRUCT(new_mtime);
1835 22 : ZERO_STRUCT(old_mtime);
1836 :
1837 : /* fetch the secret back again */
1838 22 : r6.in.sec_handle = &sec_handle;
1839 22 : r6.in.new_val = &bufp1;
1840 22 : r6.in.new_mtime = &new_mtime;
1841 22 : r6.in.old_val = &bufp2;
1842 22 : r6.in.old_mtime = &old_mtime;
1843 :
1844 22 : bufp1.buf = NULL;
1845 22 : bufp2.buf = NULL;
1846 :
1847 22 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QuerySecret_r(b, tctx, &r6),
1848 : "QuerySecret failed");
1849 22 : if (!NT_STATUS_IS_OK(r6.out.result)) {
1850 0 : torture_comment(tctx, "QuerySecret failed - %s\n", nt_errstr(r6.out.result));
1851 0 : ret = false;
1852 0 : secret4 = NULL;
1853 : } else {
1854 :
1855 22 : if (r6.out.new_val->buf == NULL || r6.out.old_val->buf == NULL
1856 22 : || r6.out.new_mtime == NULL || r6.out.old_mtime == NULL) {
1857 0 : torture_comment(tctx, "Both secret buffers and both times not returned\n");
1858 0 : ret = false;
1859 0 : secret4 = NULL;
1860 : } else {
1861 22 : blob1.data = r6.out.new_val->buf->data;
1862 22 : blob1.length = r6.out.new_val->buf->size;
1863 :
1864 22 : secret4 = sess_decrypt_string(tctx,
1865 : &blob1, &session_key);
1866 :
1867 22 : if (strcmp(secret3, secret4) != 0) {
1868 0 : torture_comment(tctx, "Returned NEW secret %s doesn't match %s\n", secret4, secret3);
1869 0 : ret = false;
1870 : }
1871 :
1872 22 : blob1.data = r6.out.old_val->buf->data;
1873 22 : blob1.length = r6.out.old_val->buf->length;
1874 :
1875 22 : secret2 = sess_decrypt_string(tctx,
1876 : &blob1, &session_key);
1877 :
1878 22 : if (strcmp(secret1, secret2) != 0) {
1879 0 : torture_comment(tctx, "Returned OLD secret %s doesn't match %s\n", secret2, secret1);
1880 0 : ret = false;
1881 : }
1882 :
1883 22 : if (*r6.out.new_mtime == *r6.out.old_mtime) {
1884 0 : torture_comment(tctx, "Returned secret (r6-%d) %s must not have same mtime for both secrets: %s != %s\n",
1885 : i,
1886 : secname[i],
1887 0 : nt_time_string(tctx, *r6.out.old_mtime),
1888 0 : nt_time_string(tctx, *r6.out.new_mtime));
1889 0 : ret = false;
1890 : }
1891 : }
1892 : }
1893 :
1894 22 : enc_key = sess_encrypt_string(secret5, &session_key);
1895 :
1896 22 : r7.in.sec_handle = &sec_handle;
1897 22 : r7.in.old_val = &buf1;
1898 22 : r7.in.old_val->data = enc_key.data;
1899 22 : r7.in.old_val->length = enc_key.length;
1900 22 : r7.in.old_val->size = enc_key.length;
1901 22 : r7.in.new_val = NULL;
1902 :
1903 22 : torture_comment(tctx, "Testing SetSecret of old Secret only\n");
1904 :
1905 22 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_SetSecret_r(b, tctx, &r7),
1906 : "SetSecret failed");
1907 22 : if (!NT_STATUS_IS_OK(r7.out.result)) {
1908 0 : torture_comment(tctx, "SetSecret failed - %s\n", nt_errstr(r7.out.result));
1909 0 : ret = false;
1910 : }
1911 :
1912 22 : data_blob_free(&enc_key);
1913 :
1914 : /* fetch the secret back again */
1915 22 : r8.in.sec_handle = &sec_handle;
1916 22 : r8.in.new_val = &bufp1;
1917 22 : r8.in.new_mtime = &new_mtime;
1918 22 : r8.in.old_val = &bufp2;
1919 22 : r8.in.old_mtime = &old_mtime;
1920 :
1921 22 : bufp1.buf = NULL;
1922 22 : bufp2.buf = NULL;
1923 :
1924 22 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QuerySecret_r(b, tctx, &r8),
1925 : "QuerySecret failed");
1926 22 : if (!NT_STATUS_IS_OK(r8.out.result)) {
1927 0 : torture_comment(tctx, "QuerySecret failed - %s\n", nt_errstr(r8.out.result));
1928 0 : ret = false;
1929 : } else {
1930 22 : if (!r8.out.new_val || !r8.out.old_val) {
1931 0 : torture_comment(tctx, "in/out pointers not returned, despite being set on in for QuerySecret\n");
1932 0 : ret = false;
1933 22 : } else if (r8.out.new_val->buf != NULL) {
1934 0 : torture_comment(tctx, "NEW secret buffer must not be returned after OLD set\n");
1935 0 : ret = false;
1936 22 : } else if (r8.out.old_val->buf == NULL) {
1937 0 : torture_comment(tctx, "OLD secret buffer was not returned after OLD set\n");
1938 0 : ret = false;
1939 22 : } else if (r8.out.new_mtime == NULL || r8.out.old_mtime == NULL) {
1940 0 : torture_comment(tctx, "Both times not returned after OLD set\n");
1941 0 : ret = false;
1942 : } else {
1943 22 : blob1.data = r8.out.old_val->buf->data;
1944 22 : blob1.length = r8.out.old_val->buf->size;
1945 :
1946 22 : secret6 = sess_decrypt_string(tctx,
1947 : &blob1, &session_key);
1948 :
1949 22 : if (strcmp(secret5, secret6) != 0) {
1950 0 : torture_comment(tctx, "Returned OLD secret %s doesn't match %s\n", secret5, secret6);
1951 0 : ret = false;
1952 : }
1953 :
1954 22 : if (*r8.out.new_mtime != *r8.out.old_mtime) {
1955 0 : torture_comment(tctx, "Returned secret (r8) %s did not had same mtime for both secrets: %s != %s\n",
1956 : secname[i],
1957 0 : nt_time_string(tctx, *r8.out.old_mtime),
1958 0 : nt_time_string(tctx, *r8.out.new_mtime));
1959 0 : ret = false;
1960 : }
1961 : }
1962 : }
1963 :
1964 22 : if (!test_Delete(b, tctx, &sec_handle)) {
1965 0 : ret = false;
1966 : }
1967 :
1968 22 : if (!test_DeleteObject(b, tctx, &sec_handle)) {
1969 0 : return false;
1970 : }
1971 :
1972 22 : d_o.in.handle = &sec_handle2;
1973 22 : d_o.out.handle = &sec_handle2;
1974 22 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_DeleteObject_r(b, tctx, &d_o),
1975 : "DeleteObject failed");
1976 22 : torture_assert_ntstatus_equal(tctx, d_o.out.result, NT_STATUS_INVALID_HANDLE,
1977 : "OpenSecret expected INVALID_HANDLE");
1978 :
1979 22 : torture_comment(tctx, "Testing OpenSecret of just-deleted secret\n");
1980 :
1981 22 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenSecret_r(b, tctx, &r2),
1982 : "OpenSecret failed");
1983 22 : torture_assert_ntstatus_equal(tctx, r2.out.result, NT_STATUS_OBJECT_NAME_NOT_FOUND,
1984 : "OpenSecret expected OBJECT_NAME_NOT_FOUND");
1985 : }
1986 11 : return ret;
1987 : }
1988 :
1989 :
1990 30 : static bool test_EnumAccountRights(struct dcerpc_binding_handle *b,
1991 : struct torture_context *tctx,
1992 : struct policy_handle *acct_handle,
1993 : struct dom_sid *sid)
1994 : {
1995 0 : struct lsa_EnumAccountRights r;
1996 0 : struct lsa_RightSet rights;
1997 :
1998 30 : torture_comment(tctx, "\nTesting EnumAccountRights\n");
1999 :
2000 30 : r.in.handle = acct_handle;
2001 30 : r.in.sid = sid;
2002 30 : r.out.rights = &rights;
2003 :
2004 30 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(b, tctx, &r),
2005 : "EnumAccountRights failed");
2006 30 : if (!NT_STATUS_IS_OK(r.out.result)) {
2007 0 : torture_comment(tctx, "EnumAccountRights of %s failed - %s\n",
2008 : dom_sid_string(tctx, sid), nt_errstr(r.out.result));
2009 : }
2010 30 : torture_assert_ntstatus_ok(tctx, r.out.result,
2011 : "EnumAccountRights failed");
2012 :
2013 30 : return true;
2014 : }
2015 :
2016 :
2017 30 : static bool test_QuerySecurity(struct dcerpc_binding_handle *b,
2018 : struct torture_context *tctx,
2019 : struct policy_handle *handle,
2020 : struct policy_handle *acct_handle)
2021 : {
2022 0 : struct lsa_QuerySecurity r;
2023 30 : struct sec_desc_buf *sdbuf = NULL;
2024 :
2025 30 : if (torture_setting_bool(tctx, "samba4", false)) {
2026 18 : torture_comment(tctx, "\nskipping QuerySecurity test against Samba4\n");
2027 18 : return true;
2028 : }
2029 :
2030 12 : torture_comment(tctx, "\nTesting QuerySecurity\n");
2031 :
2032 12 : r.in.handle = acct_handle;
2033 12 : r.in.sec_info = SECINFO_OWNER |
2034 : SECINFO_GROUP |
2035 : SECINFO_DACL;
2036 12 : r.out.sdbuf = &sdbuf;
2037 :
2038 12 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QuerySecurity_r(b, tctx, &r),
2039 : "QuerySecurity failed");
2040 12 : if (!NT_STATUS_IS_OK(r.out.result)) {
2041 0 : torture_comment(tctx, "QuerySecurity failed - %s\n", nt_errstr(r.out.result));
2042 0 : return false;
2043 : }
2044 :
2045 12 : return true;
2046 : }
2047 :
2048 30 : static bool test_OpenAccount(struct dcerpc_binding_handle *b,
2049 : struct torture_context *tctx,
2050 : struct policy_handle *handle,
2051 : struct dom_sid *sid)
2052 : {
2053 0 : struct lsa_OpenAccount r;
2054 0 : struct policy_handle acct_handle;
2055 :
2056 30 : torture_comment(tctx, "\nTesting OpenAccount\n");
2057 :
2058 30 : r.in.handle = handle;
2059 30 : r.in.sid = sid;
2060 30 : r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2061 30 : r.out.acct_handle = &acct_handle;
2062 :
2063 30 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenAccount_r(b, tctx, &r),
2064 : "OpenAccount failed");
2065 30 : torture_assert_ntstatus_ok(tctx, r.out.result,
2066 : "OpenAccount failed");
2067 :
2068 30 : if (!test_EnumPrivsAccount(b, tctx, handle, &acct_handle)) {
2069 0 : return false;
2070 : }
2071 :
2072 30 : if (!test_GetSystemAccessAccount(b, tctx, handle, &acct_handle)) {
2073 0 : return false;
2074 : }
2075 :
2076 30 : if (!test_QuerySecurity(b, tctx, handle, &acct_handle)) {
2077 0 : return false;
2078 : }
2079 :
2080 30 : return true;
2081 : }
2082 :
2083 5 : static bool test_EnumAccounts(struct dcerpc_binding_handle *b,
2084 : struct torture_context *tctx,
2085 : struct policy_handle *handle)
2086 : {
2087 0 : struct lsa_EnumAccounts r;
2088 0 : struct lsa_SidArray sids1, sids2;
2089 5 : uint32_t resume_handle = 0;
2090 0 : int i;
2091 5 : bool ret = true;
2092 :
2093 5 : torture_comment(tctx, "\nTesting EnumAccounts\n");
2094 :
2095 5 : r.in.handle = handle;
2096 5 : r.in.resume_handle = &resume_handle;
2097 5 : r.in.num_entries = 100;
2098 5 : r.out.resume_handle = &resume_handle;
2099 5 : r.out.sids = &sids1;
2100 :
2101 5 : resume_handle = 0;
2102 0 : while (true) {
2103 10 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccounts_r(b, tctx, &r),
2104 : "EnumAccounts failed");
2105 10 : if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NO_MORE_ENTRIES)) {
2106 5 : break;
2107 : }
2108 5 : torture_assert_ntstatus_ok(tctx, r.out.result,
2109 : "EnumAccounts failed");
2110 :
2111 5 : if (!test_LookupSids(b, tctx, handle, LSA_LOOKUP_NAMES_ALL, &sids1)) {
2112 0 : return false;
2113 : }
2114 :
2115 5 : if (!test_LookupSids2(b, tctx, handle, LSA_LOOKUP_NAMES_ALL, &sids1)) {
2116 0 : return false;
2117 : }
2118 :
2119 : /* Can't test lookupSids3 here, as clearly we must not
2120 : * be on schannel, or we would not be able to do the
2121 : * rest */
2122 :
2123 5 : torture_comment(tctx, "Testing all accounts\n");
2124 35 : for (i=0;i<sids1.num_sids;i++) {
2125 30 : ret &= test_OpenAccount(b, tctx, handle, sids1.sids[i].sid);
2126 30 : ret &= test_EnumAccountRights(b, tctx, handle, sids1.sids[i].sid);
2127 : }
2128 5 : torture_comment(tctx, "\n");
2129 : }
2130 :
2131 5 : if (sids1.num_sids < 3) {
2132 5 : return ret;
2133 : }
2134 :
2135 0 : torture_comment(tctx, "Trying EnumAccounts partial listing (asking for 1 at 2)\n");
2136 0 : resume_handle = 2;
2137 0 : r.in.num_entries = 1;
2138 0 : r.out.sids = &sids2;
2139 :
2140 0 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccounts_r(b, tctx, &r),
2141 : "EnumAccounts failed");
2142 0 : torture_assert_ntstatus_ok(tctx, r.out.result,
2143 : "EnumAccounts failed");
2144 :
2145 0 : if (sids2.num_sids != 1) {
2146 0 : torture_comment(tctx, "Returned wrong number of entries (%d)\n", sids2.num_sids);
2147 0 : return false;
2148 : }
2149 :
2150 0 : return true;
2151 : }
2152 :
2153 93 : static bool test_LookupPrivDisplayName(struct dcerpc_binding_handle *b,
2154 : struct torture_context *tctx,
2155 : struct policy_handle *handle,
2156 : struct lsa_String *priv_name)
2157 : {
2158 0 : struct lsa_LookupPrivDisplayName r;
2159 : /* produce a reasonable range of language output without screwing up
2160 : terminals */
2161 93 : uint16_t language_id = (random() % 4) + 0x409;
2162 93 : uint16_t returned_language_id = 0;
2163 93 : struct lsa_StringLarge *disp_name = NULL;
2164 :
2165 93 : torture_comment(tctx, "\nTesting LookupPrivDisplayName(%s)\n", priv_name->string);
2166 :
2167 93 : r.in.handle = handle;
2168 93 : r.in.name = priv_name;
2169 93 : r.in.language_id = language_id;
2170 93 : r.in.language_id_sys = 0;
2171 93 : r.out.returned_language_id = &returned_language_id;
2172 93 : r.out.disp_name = &disp_name;
2173 :
2174 93 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupPrivDisplayName_r(b, tctx, &r),
2175 : "LookupPrivDisplayName failed");
2176 93 : if (!NT_STATUS_IS_OK(r.out.result)) {
2177 0 : torture_comment(tctx, "LookupPrivDisplayName failed - %s\n", nt_errstr(r.out.result));
2178 0 : return false;
2179 : }
2180 93 : torture_comment(tctx, "%s -> \"%s\" (language 0x%x/0x%x)\n",
2181 93 : priv_name->string, disp_name->string,
2182 93 : r.in.language_id, *r.out.returned_language_id);
2183 :
2184 93 : return true;
2185 : }
2186 :
2187 93 : static bool test_EnumAccountsWithUserRight(struct dcerpc_binding_handle *b,
2188 : struct torture_context *tctx,
2189 : struct policy_handle *handle,
2190 : struct lsa_String *priv_name)
2191 : {
2192 0 : struct lsa_EnumAccountsWithUserRight r;
2193 0 : struct lsa_SidArray sids;
2194 :
2195 93 : ZERO_STRUCT(sids);
2196 :
2197 93 : torture_comment(tctx, "\nTesting EnumAccountsWithUserRight(%s)\n", priv_name->string);
2198 :
2199 93 : r.in.handle = handle;
2200 93 : r.in.name = priv_name;
2201 93 : r.out.sids = &sids;
2202 :
2203 93 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountsWithUserRight_r(b, tctx, &r),
2204 : "EnumAccountsWithUserRight failed");
2205 :
2206 : /* NT_STATUS_NO_MORE_ENTRIES means no one has this privilege */
2207 93 : if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NO_MORE_ENTRIES)) {
2208 12 : return true;
2209 : }
2210 :
2211 81 : if (!NT_STATUS_IS_OK(r.out.result)) {
2212 0 : torture_comment(tctx, "EnumAccountsWithUserRight failed - %s\n", nt_errstr(r.out.result));
2213 0 : return false;
2214 : }
2215 :
2216 81 : return true;
2217 : }
2218 :
2219 :
2220 5 : static bool test_EnumPrivs(struct dcerpc_binding_handle *b,
2221 : struct torture_context *tctx,
2222 : struct policy_handle *handle)
2223 : {
2224 0 : struct lsa_EnumPrivs r;
2225 0 : struct lsa_PrivArray privs1;
2226 5 : uint32_t resume_handle = 0;
2227 0 : int i;
2228 5 : bool ret = true;
2229 :
2230 5 : torture_comment(tctx, "\nTesting EnumPrivs\n");
2231 :
2232 5 : r.in.handle = handle;
2233 5 : r.in.resume_handle = &resume_handle;
2234 5 : r.in.max_count = 100;
2235 5 : r.out.resume_handle = &resume_handle;
2236 5 : r.out.privs = &privs1;
2237 :
2238 5 : resume_handle = 0;
2239 5 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumPrivs_r(b, tctx, &r),
2240 : "EnumPrivs failed");
2241 5 : torture_assert_ntstatus_ok(tctx, r.out.result,
2242 : "EnumPrivs failed");
2243 :
2244 98 : for (i = 0; i< privs1.count; i++) {
2245 93 : test_LookupPrivDisplayName(b, tctx, handle, (struct lsa_String *)&privs1.privs[i].name);
2246 93 : test_LookupPrivValue(b, tctx, handle, (struct lsa_String *)&privs1.privs[i].name);
2247 93 : if (!test_EnumAccountsWithUserRight(b, tctx, handle, (struct lsa_String *)&privs1.privs[i].name)) {
2248 0 : ret = false;
2249 : }
2250 : }
2251 :
2252 5 : return ret;
2253 : }
2254 :
2255 0 : static bool test_QueryForestTrustInformation(struct dcerpc_binding_handle *b,
2256 : struct torture_context *tctx,
2257 : struct policy_handle *handle,
2258 : const char *trusted_domain_name)
2259 : {
2260 0 : bool ret = true;
2261 0 : struct lsa_lsaRQueryForestTrustInformation r;
2262 0 : struct lsa_String string;
2263 0 : struct lsa_ForestTrustInformation info, *info_ptr;
2264 :
2265 0 : torture_comment(tctx, "\nTesting lsaRQueryForestTrustInformation\n");
2266 :
2267 0 : if (torture_setting_bool(tctx, "samba4", false)) {
2268 0 : torture_comment(tctx, "skipping QueryForestTrustInformation against Samba4\n");
2269 0 : return true;
2270 : }
2271 :
2272 0 : ZERO_STRUCT(string);
2273 :
2274 0 : if (trusted_domain_name) {
2275 0 : init_lsa_String(&string, trusted_domain_name);
2276 : }
2277 :
2278 0 : info_ptr = &info;
2279 :
2280 0 : r.in.handle = handle;
2281 0 : r.in.trusted_domain_name = &string;
2282 0 : r.in.highest_record_type = LSA_FOREST_TRUST_TOP_LEVEL_NAME;
2283 0 : r.out.forest_trust_info = &info_ptr;
2284 :
2285 0 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_lsaRQueryForestTrustInformation_r(b, tctx, &r),
2286 : "lsaRQueryForestTrustInformation failed");
2287 :
2288 0 : if (!NT_STATUS_IS_OK(r.out.result)) {
2289 0 : torture_comment(tctx, "lsaRQueryForestTrustInformation of %s failed - %s\n", trusted_domain_name, nt_errstr(r.out.result));
2290 0 : ret = false;
2291 : }
2292 :
2293 0 : return ret;
2294 : }
2295 :
2296 27 : static bool test_query_each_TrustDomEx(struct dcerpc_binding_handle *b,
2297 : struct torture_context *tctx,
2298 : struct policy_handle *handle,
2299 : struct lsa_DomainListEx *domains)
2300 : {
2301 0 : int i;
2302 27 : bool ret = true;
2303 :
2304 135 : for (i=0; i< domains->count; i++) {
2305 :
2306 108 : if (domains->domains[i].trust_attributes & LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) {
2307 0 : ret &= test_QueryForestTrustInformation(b, tctx, handle,
2308 0 : domains->domains[i].domain_name.string);
2309 : }
2310 : }
2311 :
2312 27 : return ret;
2313 : }
2314 :
2315 27 : static bool test_query_each_TrustDom(struct dcerpc_binding_handle *b,
2316 : struct torture_context *tctx,
2317 : struct policy_handle *handle,
2318 : struct lsa_DomainList *domains)
2319 : {
2320 0 : int i,j;
2321 27 : bool ret = true;
2322 :
2323 27 : torture_comment(tctx, "\nTesting OpenTrustedDomain, OpenTrustedDomainByName and QueryInfoTrustedDomain\n");
2324 135 : for (i=0; i< domains->count; i++) {
2325 0 : struct lsa_OpenTrustedDomain trust;
2326 0 : struct lsa_OpenTrustedDomainByName trust_by_name;
2327 0 : struct policy_handle trustdom_handle;
2328 0 : struct policy_handle handle2;
2329 0 : struct lsa_Close c;
2330 0 : struct lsa_CloseTrustedDomainEx c_trust;
2331 108 : int levels [] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13};
2332 108 : int ok[] = {1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1};
2333 :
2334 108 : if (domains->domains[i].sid) {
2335 108 : trust.in.handle = handle;
2336 108 : trust.in.sid = domains->domains[i].sid;
2337 108 : trust.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2338 108 : trust.out.trustdom_handle = &trustdom_handle;
2339 :
2340 108 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenTrustedDomain_r(b, tctx, &trust),
2341 : "OpenTrustedDomain failed");
2342 :
2343 108 : if (NT_STATUS_EQUAL(trust.out.result, NT_STATUS_NO_SUCH_DOMAIN)) {
2344 0 : torture_comment(tctx, "DOMAIN(%s, %s) not a direct trust?\n",
2345 0 : domains->domains[i].name.string,
2346 0 : dom_sid_string(tctx, domains->domains[i].sid));
2347 0 : continue;
2348 : }
2349 108 : if (!NT_STATUS_IS_OK(trust.out.result)) {
2350 0 : torture_comment(tctx, "OpenTrustedDomain failed - %s\n", nt_errstr(trust.out.result));
2351 0 : return false;
2352 : }
2353 :
2354 108 : c.in.handle = &trustdom_handle;
2355 108 : c.out.handle = &handle2;
2356 :
2357 108 : c_trust.in.handle = &trustdom_handle;
2358 108 : c_trust.out.handle = &handle2;
2359 :
2360 1512 : for (j=0; j < ARRAY_SIZE(levels); j++) {
2361 0 : struct lsa_QueryTrustedDomainInfo q;
2362 1404 : union lsa_TrustedDomainInfo *info = NULL;
2363 1404 : q.in.trustdom_handle = &trustdom_handle;
2364 1404 : q.in.level = levels[j];
2365 1404 : q.out.info = &info;
2366 1404 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryTrustedDomainInfo_r(b, tctx, &q),
2367 : "QueryTrustedDomainInfo failed");
2368 1404 : if (!NT_STATUS_IS_OK(q.out.result) && ok[j]) {
2369 0 : torture_comment(tctx, "QueryTrustedDomainInfo level %d failed - %s\n",
2370 : levels[j], nt_errstr(q.out.result));
2371 0 : ret = false;
2372 1404 : } else if (NT_STATUS_IS_OK(q.out.result) && !ok[j]) {
2373 0 : torture_comment(tctx, "QueryTrustedDomainInfo level %d unexpectedly succeeded - %s\n",
2374 : levels[j], nt_errstr(q.out.result));
2375 0 : ret = false;
2376 : }
2377 : }
2378 :
2379 108 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_CloseTrustedDomainEx_r(b, tctx, &c_trust),
2380 : "CloseTrustedDomainEx failed");
2381 108 : if (!NT_STATUS_EQUAL(c_trust.out.result, NT_STATUS_NOT_IMPLEMENTED)) {
2382 0 : torture_comment(tctx, "Expected CloseTrustedDomainEx to return NT_STATUS_NOT_IMPLEMENTED, instead - %s\n", nt_errstr(c_trust.out.result));
2383 0 : return false;
2384 : }
2385 :
2386 108 : c.in.handle = &trustdom_handle;
2387 108 : c.out.handle = &handle2;
2388 :
2389 108 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_Close_r(b, tctx, &c),
2390 : "Close failed");
2391 108 : if (!NT_STATUS_IS_OK(c.out.result)) {
2392 0 : torture_comment(tctx, "Close of trusted domain failed - %s\n", nt_errstr(c.out.result));
2393 0 : return false;
2394 : }
2395 :
2396 1512 : for (j=0; j < ARRAY_SIZE(levels); j++) {
2397 0 : struct lsa_QueryTrustedDomainInfoBySid q;
2398 1404 : union lsa_TrustedDomainInfo *info = NULL;
2399 :
2400 1404 : if (!domains->domains[i].sid) {
2401 0 : continue;
2402 : }
2403 :
2404 1404 : q.in.handle = handle;
2405 1404 : q.in.dom_sid = domains->domains[i].sid;
2406 1404 : q.in.level = levels[j];
2407 1404 : q.out.info = &info;
2408 :
2409 1404 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryTrustedDomainInfoBySid_r(b, tctx, &q),
2410 : "lsa_QueryTrustedDomainInfoBySid failed");
2411 1404 : if (!NT_STATUS_IS_OK(q.out.result) && ok[j]) {
2412 0 : torture_comment(tctx, "QueryTrustedDomainInfoBySid level %d failed - %s\n",
2413 : levels[j], nt_errstr(q.out.result));
2414 0 : ret = false;
2415 1404 : } else if (NT_STATUS_IS_OK(q.out.result) && !ok[j]) {
2416 0 : torture_comment(tctx, "QueryTrustedDomainInfoBySid level %d unexpectedly succeeded - %s\n",
2417 : levels[j], nt_errstr(q.out.result));
2418 0 : ret = false;
2419 : }
2420 : }
2421 : }
2422 :
2423 108 : trust_by_name.in.handle = handle;
2424 108 : trust_by_name.in.name.string = domains->domains[i].name.string;
2425 108 : trust_by_name.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2426 108 : trust_by_name.out.trustdom_handle = &trustdom_handle;
2427 :
2428 108 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenTrustedDomainByName_r(b, tctx, &trust_by_name),
2429 : "OpenTrustedDomainByName failed");
2430 :
2431 108 : if (NT_STATUS_EQUAL(trust_by_name.out.result, NT_STATUS_NO_SUCH_DOMAIN)) {
2432 0 : torture_comment(tctx, "DOMAIN(%s, %s) not a direct trust?\n",
2433 0 : domains->domains[i].name.string,
2434 0 : dom_sid_string(tctx, domains->domains[i].sid));
2435 0 : continue;
2436 : }
2437 108 : if (!NT_STATUS_IS_OK(trust_by_name.out.result)) {
2438 0 : torture_comment(tctx, "OpenTrustedDomainByName failed - %s\n", nt_errstr(trust_by_name.out.result));
2439 0 : return false;
2440 : }
2441 :
2442 1512 : for (j=0; j < ARRAY_SIZE(levels); j++) {
2443 0 : struct lsa_QueryTrustedDomainInfo q;
2444 1404 : union lsa_TrustedDomainInfo *info = NULL;
2445 1404 : q.in.trustdom_handle = &trustdom_handle;
2446 1404 : q.in.level = levels[j];
2447 1404 : q.out.info = &info;
2448 1404 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryTrustedDomainInfo_r(b, tctx, &q),
2449 : "QueryTrustedDomainInfo failed");
2450 1404 : if (!NT_STATUS_IS_OK(q.out.result) && ok[j]) {
2451 0 : torture_comment(tctx, "QueryTrustedDomainInfo level %d failed - %s\n",
2452 : levels[j], nt_errstr(q.out.result));
2453 0 : ret = false;
2454 1404 : } else if (NT_STATUS_IS_OK(q.out.result) && !ok[j]) {
2455 0 : torture_comment(tctx, "QueryTrustedDomainInfo level %d unexpectedly succeeded - %s\n",
2456 : levels[j], nt_errstr(q.out.result));
2457 0 : ret = false;
2458 : }
2459 : }
2460 :
2461 108 : c.in.handle = &trustdom_handle;
2462 108 : c.out.handle = &handle2;
2463 :
2464 108 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_Close_r(b, tctx, &c),
2465 : "Close failed");
2466 108 : if (!NT_STATUS_IS_OK(c.out.result)) {
2467 0 : torture_comment(tctx, "Close of trusted domain failed - %s\n", nt_errstr(c.out.result));
2468 0 : return false;
2469 : }
2470 :
2471 1512 : for (j=0; j < ARRAY_SIZE(levels); j++) {
2472 0 : struct lsa_QueryTrustedDomainInfoByName q;
2473 1404 : union lsa_TrustedDomainInfo *info = NULL;
2474 0 : struct lsa_String name;
2475 :
2476 1404 : name.string = domains->domains[i].name.string;
2477 :
2478 1404 : q.in.handle = handle;
2479 1404 : q.in.trusted_domain = &name;
2480 1404 : q.in.level = levels[j];
2481 1404 : q.out.info = &info;
2482 1404 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryTrustedDomainInfoByName_r(b, tctx, &q),
2483 : "QueryTrustedDomainInfoByName failed");
2484 1404 : if (!NT_STATUS_IS_OK(q.out.result) && ok[j]) {
2485 0 : torture_comment(tctx, "QueryTrustedDomainInfoByName level %d failed - %s\n",
2486 : levels[j], nt_errstr(q.out.result));
2487 0 : ret = false;
2488 1404 : } else if (NT_STATUS_IS_OK(q.out.result) && !ok[j]) {
2489 0 : torture_comment(tctx, "QueryTrustedDomainInfoByName level %d unexpectedly succeeded - %s\n",
2490 : levels[j], nt_errstr(q.out.result));
2491 0 : ret = false;
2492 : }
2493 : }
2494 : }
2495 27 : return ret;
2496 : }
2497 :
2498 12 : static bool test_EnumTrustDom(struct dcerpc_binding_handle *b,
2499 : struct torture_context *tctx,
2500 : struct policy_handle *handle)
2501 : {
2502 0 : struct lsa_EnumTrustDom r;
2503 12 : uint32_t in_resume_handle = 0;
2504 0 : uint32_t out_resume_handle;
2505 0 : struct lsa_DomainList domains;
2506 12 : bool ret = true;
2507 :
2508 12 : torture_comment(tctx, "\nTesting EnumTrustDom\n");
2509 :
2510 12 : r.in.handle = handle;
2511 12 : r.in.resume_handle = &in_resume_handle;
2512 12 : r.in.max_size = 0;
2513 12 : r.out.domains = &domains;
2514 12 : r.out.resume_handle = &out_resume_handle;
2515 :
2516 12 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumTrustDom_r(b, tctx, &r),
2517 : "lsa_EnumTrustDom failed");
2518 :
2519 : /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
2520 : * always be larger than the previous input resume handle, in
2521 : * particular when hitting the last query it is vital to set the
2522 : * resume handle correctly to avoid infinite client loops, as
2523 : * seen e.g. with Windows XP SP3 when resume handle is 0 and
2524 : * status is NT_STATUS_OK - gd */
2525 :
2526 12 : if (NT_STATUS_IS_OK(r.out.result) ||
2527 12 : NT_STATUS_EQUAL(r.out.result, NT_STATUS_NO_MORE_ENTRIES) ||
2528 9 : NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES))
2529 : {
2530 12 : if (out_resume_handle <= in_resume_handle) {
2531 0 : torture_comment(tctx, "EnumTrustDom failed - should have returned output resume_handle (0x%08x) larger than input resume handle (0x%08x)\n",
2532 : out_resume_handle, in_resume_handle);
2533 0 : return false;
2534 : }
2535 : }
2536 :
2537 12 : if (NT_STATUS_IS_OK(r.out.result)) {
2538 0 : if (domains.count == 0) {
2539 0 : torture_comment(tctx, "EnumTrustDom failed - should have returned 'NT_STATUS_NO_MORE_ENTRIES' for 0 trusted domains\n");
2540 0 : return false;
2541 : }
2542 12 : } else if (!(NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) || NT_STATUS_EQUAL(r.out.result, NT_STATUS_NO_MORE_ENTRIES))) {
2543 0 : torture_comment(tctx, "EnumTrustDom of zero size failed - %s\n", nt_errstr(r.out.result));
2544 0 : return false;
2545 : }
2546 :
2547 : /* Start from the bottom again */
2548 12 : in_resume_handle = 0;
2549 :
2550 0 : do {
2551 30 : r.in.handle = handle;
2552 30 : r.in.resume_handle = &in_resume_handle;
2553 30 : r.in.max_size = LSA_ENUM_TRUST_DOMAIN_MULTIPLIER * 3;
2554 30 : r.out.domains = &domains;
2555 30 : r.out.resume_handle = &out_resume_handle;
2556 :
2557 30 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumTrustDom_r(b, tctx, &r),
2558 : "EnumTrustDom failed");
2559 :
2560 : /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
2561 : * always be larger than the previous input resume handle, in
2562 : * particular when hitting the last query it is vital to set the
2563 : * resume handle correctly to avoid infinite client loops, as
2564 : * seen e.g. with Windows XP SP3 when resume handle is 0 and
2565 : * status is NT_STATUS_OK - gd */
2566 :
2567 30 : if (NT_STATUS_IS_OK(r.out.result) ||
2568 21 : NT_STATUS_EQUAL(r.out.result, NT_STATUS_NO_MORE_ENTRIES) ||
2569 18 : NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES))
2570 : {
2571 30 : if (out_resume_handle <= in_resume_handle) {
2572 0 : torture_comment(tctx, "EnumTrustDom failed - should have returned output resume_handle (0x%08x) larger than input resume handle (0x%08x)\n",
2573 : out_resume_handle, in_resume_handle);
2574 0 : return false;
2575 : }
2576 : }
2577 :
2578 : /* NO_MORE_ENTRIES is allowed */
2579 30 : if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NO_MORE_ENTRIES)) {
2580 3 : if (domains.count == 0) {
2581 3 : return true;
2582 : }
2583 0 : torture_comment(tctx, "EnumTrustDom failed - should have returned 0 trusted domains with 'NT_STATUS_NO_MORE_ENTRIES'\n");
2584 0 : return false;
2585 27 : } else if (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES)) {
2586 : /* Windows 2003 gets this off by one on the first run */
2587 18 : if (r.out.domains->count < 3 || r.out.domains->count > 4) {
2588 0 : torture_comment(tctx, "EnumTrustDom didn't fill the buffer we "
2589 : "asked it to (got %d, expected %d / %d == %d entries)\n",
2590 0 : r.out.domains->count, LSA_ENUM_TRUST_DOMAIN_MULTIPLIER * 3,
2591 : LSA_ENUM_TRUST_DOMAIN_MULTIPLIER, r.in.max_size);
2592 0 : ret = false;
2593 : }
2594 9 : } else if (!NT_STATUS_IS_OK(r.out.result)) {
2595 0 : torture_comment(tctx, "EnumTrustDom failed - %s\n", nt_errstr(r.out.result));
2596 0 : return false;
2597 : }
2598 :
2599 27 : if (domains.count == 0) {
2600 0 : torture_comment(tctx, "EnumTrustDom failed - should have returned 'NT_STATUS_NO_MORE_ENTRIES' for 0 trusted domains\n");
2601 0 : return false;
2602 : }
2603 :
2604 27 : ret &= test_query_each_TrustDom(b, tctx, handle, &domains);
2605 :
2606 27 : in_resume_handle = out_resume_handle;
2607 :
2608 27 : } while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES));
2609 :
2610 9 : return ret;
2611 : }
2612 :
2613 12 : static bool test_EnumTrustDomEx(struct dcerpc_binding_handle *b,
2614 : struct torture_context *tctx,
2615 : struct policy_handle *handle)
2616 : {
2617 0 : struct lsa_EnumTrustedDomainsEx r_ex;
2618 12 : uint32_t in_resume_handle = 0;
2619 0 : uint32_t out_resume_handle;
2620 0 : struct lsa_DomainListEx domains_ex;
2621 12 : bool ret = true;
2622 :
2623 12 : torture_comment(tctx, "\nTesting EnumTrustedDomainsEx\n");
2624 :
2625 12 : r_ex.in.handle = handle;
2626 12 : r_ex.in.resume_handle = &in_resume_handle;
2627 12 : r_ex.in.max_size = 0;
2628 12 : r_ex.out.domains = &domains_ex;
2629 12 : r_ex.out.resume_handle = &out_resume_handle;
2630 :
2631 12 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumTrustedDomainsEx_r(b, tctx, &r_ex),
2632 : "EnumTrustedDomainsEx failed");
2633 :
2634 : /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
2635 : * always be larger than the previous input resume handle, in
2636 : * particular when hitting the last query it is vital to set the
2637 : * resume handle correctly to avoid infinite client loops, as
2638 : * seen e.g. with Windows XP SP3 when resume handle is 0 and
2639 : * status is NT_STATUS_OK - gd */
2640 :
2641 12 : if (NT_STATUS_IS_OK(r_ex.out.result) ||
2642 12 : NT_STATUS_EQUAL(r_ex.out.result, NT_STATUS_NO_MORE_ENTRIES) ||
2643 9 : NT_STATUS_EQUAL(r_ex.out.result, STATUS_MORE_ENTRIES))
2644 : {
2645 12 : if (out_resume_handle <= in_resume_handle) {
2646 0 : torture_comment(tctx, "EnumTrustDomEx failed - should have returned output resume_handle (0x%08x) larger than input resume handle (0x%08x)\n",
2647 : out_resume_handle, in_resume_handle);
2648 0 : return false;
2649 : }
2650 : }
2651 :
2652 12 : if (NT_STATUS_IS_OK(r_ex.out.result)) {
2653 0 : if (domains_ex.count == 0) {
2654 0 : torture_comment(tctx, "EnumTrustDom failed - should have returned 'NT_STATUS_NO_MORE_ENTRIES' for 0 trusted domains\n");
2655 0 : return false;
2656 : }
2657 12 : } else if (!(NT_STATUS_EQUAL(r_ex.out.result, STATUS_MORE_ENTRIES) ||
2658 3 : NT_STATUS_EQUAL(r_ex.out.result, NT_STATUS_NO_MORE_ENTRIES))) {
2659 0 : torture_comment(tctx, "EnumTrustDom of zero size failed - %s\n",
2660 : nt_errstr(r_ex.out.result));
2661 0 : return false;
2662 : }
2663 :
2664 12 : in_resume_handle = 0;
2665 0 : do {
2666 30 : r_ex.in.handle = handle;
2667 30 : r_ex.in.resume_handle = &in_resume_handle;
2668 30 : r_ex.in.max_size = LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER * 3;
2669 30 : r_ex.out.domains = &domains_ex;
2670 30 : r_ex.out.resume_handle = &out_resume_handle;
2671 :
2672 30 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumTrustedDomainsEx_r(b, tctx, &r_ex),
2673 : "EnumTrustedDomainsEx failed");
2674 :
2675 30 : in_resume_handle = out_resume_handle;
2676 :
2677 : /* NO_MORE_ENTRIES is allowed */
2678 30 : if (NT_STATUS_EQUAL(r_ex.out.result, NT_STATUS_NO_MORE_ENTRIES)) {
2679 3 : if (domains_ex.count == 0) {
2680 3 : return true;
2681 : }
2682 0 : torture_comment(tctx, "EnumTrustDomainsEx failed - should have returned 0 trusted domains with 'NT_STATUS_NO_MORE_ENTRIES'\n");
2683 0 : return false;
2684 27 : } else if (NT_STATUS_EQUAL(r_ex.out.result, STATUS_MORE_ENTRIES)) {
2685 : /* Windows 2003 gets this off by one on the first run */
2686 18 : if (r_ex.out.domains->count < 3 || r_ex.out.domains->count > 4) {
2687 0 : torture_comment(tctx, "EnumTrustDom didn't fill the buffer we "
2688 : "asked it to (got %d, expected %d / %d == %d entries)\n",
2689 0 : r_ex.out.domains->count,
2690 : r_ex.in.max_size,
2691 : LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER,
2692 0 : r_ex.in.max_size / LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER);
2693 : }
2694 9 : } else if (!NT_STATUS_IS_OK(r_ex.out.result)) {
2695 0 : torture_comment(tctx, "EnumTrustedDomainEx failed - %s\n", nt_errstr(r_ex.out.result));
2696 0 : return false;
2697 : }
2698 :
2699 27 : if (domains_ex.count == 0) {
2700 0 : torture_comment(tctx, "EnumTrustDomainEx failed - should have returned 'NT_STATUS_NO_MORE_ENTRIES' for 0 trusted domains\n");
2701 0 : return false;
2702 : }
2703 :
2704 27 : ret &= test_query_each_TrustDomEx(b, tctx, handle, &domains_ex);
2705 :
2706 27 : } while (NT_STATUS_EQUAL(r_ex.out.result, STATUS_MORE_ENTRIES));
2707 :
2708 9 : return ret;
2709 : }
2710 :
2711 :
2712 3 : static bool test_CreateTrustedDomain(struct dcerpc_binding_handle *b,
2713 : struct torture_context *tctx,
2714 : struct policy_handle *handle,
2715 : uint32_t num_trusts)
2716 : {
2717 3 : bool ret = true;
2718 0 : struct lsa_CreateTrustedDomain r;
2719 0 : struct lsa_DomainInfo trustinfo;
2720 0 : struct dom_sid **domsid;
2721 0 : struct policy_handle *trustdom_handle;
2722 0 : struct lsa_QueryTrustedDomainInfo q;
2723 3 : union lsa_TrustedDomainInfo *info = NULL;
2724 0 : int i;
2725 :
2726 3 : torture_comment(tctx, "\nTesting CreateTrustedDomain for %d domains\n", num_trusts);
2727 :
2728 3 : if (!test_EnumTrustDom(b, tctx, handle)) {
2729 0 : ret = false;
2730 : }
2731 :
2732 3 : if (!test_EnumTrustDomEx(b, tctx, handle)) {
2733 0 : ret = false;
2734 : }
2735 :
2736 3 : domsid = talloc_array(tctx, struct dom_sid *, num_trusts);
2737 3 : trustdom_handle = talloc_array(tctx, struct policy_handle, num_trusts);
2738 :
2739 39 : for (i=0; i< num_trusts; i++) {
2740 36 : char *trust_name = talloc_asprintf(tctx, "TORTURE1%02d", i);
2741 36 : char *trust_sid = talloc_asprintf(tctx, "S-1-5-21-97398-379795-1%02d", i);
2742 :
2743 36 : domsid[i] = dom_sid_parse_talloc(tctx, trust_sid);
2744 :
2745 36 : trustinfo.sid = domsid[i];
2746 36 : init_lsa_String((struct lsa_String *)&trustinfo.name, trust_name);
2747 :
2748 36 : r.in.policy_handle = handle;
2749 36 : r.in.info = &trustinfo;
2750 36 : r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2751 36 : r.out.trustdom_handle = &trustdom_handle[i];
2752 :
2753 36 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_CreateTrustedDomain_r(b, tctx, &r),
2754 : "CreateTrustedDomain failed");
2755 36 : if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_OBJECT_NAME_COLLISION)) {
2756 0 : test_DeleteTrustedDomain(b, tctx, handle, trustinfo.name);
2757 0 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_CreateTrustedDomain_r(b, tctx, &r),
2758 : "CreateTrustedDomain failed");
2759 : }
2760 36 : if (!NT_STATUS_IS_OK(r.out.result)) {
2761 0 : torture_comment(tctx, "CreateTrustedDomain failed - %s\n", nt_errstr(r.out.result));
2762 0 : ret = false;
2763 : } else {
2764 :
2765 36 : q.in.trustdom_handle = &trustdom_handle[i];
2766 36 : q.in.level = LSA_TRUSTED_DOMAIN_INFO_INFO_EX;
2767 36 : q.out.info = &info;
2768 36 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryTrustedDomainInfo_r(b, tctx, &q),
2769 : "QueryTrustedDomainInfo failed");
2770 36 : if (!NT_STATUS_IS_OK(q.out.result)) {
2771 0 : torture_comment(tctx, "QueryTrustedDomainInfo level %d failed - %s\n", q.in.level, nt_errstr(q.out.result));
2772 0 : ret = false;
2773 36 : } else if (!q.out.info) {
2774 0 : ret = false;
2775 : } else {
2776 36 : if (strcmp(info->info_ex.domain_name.string, trustinfo.name.string) != 0) {
2777 0 : torture_comment(tctx, "QueryTrustedDomainInfo returned inconsistent long name: %s != %s\n",
2778 0 : info->info_ex.domain_name.string, trustinfo.name.string);
2779 0 : ret = false;
2780 : }
2781 36 : if (strcmp(info->info_ex.netbios_name.string, trustinfo.name.string) != 0) {
2782 0 : torture_comment(tctx, "QueryTrustedDomainInfo returned inconsistent short name: %s != %s\n",
2783 0 : info->info_ex.netbios_name.string, trustinfo.name.string);
2784 0 : ret = false;
2785 : }
2786 36 : if (info->info_ex.trust_type != LSA_TRUST_TYPE_DOWNLEVEL) {
2787 0 : torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust type %d != %d\n",
2788 0 : trust_name, info->info_ex.trust_type, LSA_TRUST_TYPE_DOWNLEVEL);
2789 0 : ret = false;
2790 : }
2791 36 : if (info->info_ex.trust_attributes != 0) {
2792 0 : torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust attributes %d != %d\n",
2793 0 : trust_name, info->info_ex.trust_attributes, 0);
2794 0 : ret = false;
2795 : }
2796 36 : if (info->info_ex.trust_direction != LSA_TRUST_DIRECTION_OUTBOUND) {
2797 0 : torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust direction %d != %d\n",
2798 0 : trust_name, info->info_ex.trust_direction, LSA_TRUST_DIRECTION_OUTBOUND);
2799 0 : ret = false;
2800 : }
2801 : }
2802 : }
2803 : }
2804 :
2805 : /* now that we have some domains to look over, we can test the enum calls */
2806 3 : if (!test_EnumTrustDom(b, tctx, handle)) {
2807 0 : ret = false;
2808 : }
2809 :
2810 3 : if (!test_EnumTrustDomEx(b, tctx, handle)) {
2811 0 : ret = false;
2812 : }
2813 :
2814 39 : for (i=0; i<num_trusts; i++) {
2815 36 : if (!test_DeleteTrustedDomainBySid(b, tctx, handle, domsid[i])) {
2816 0 : ret = false;
2817 : }
2818 : }
2819 :
2820 3 : return ret;
2821 : }
2822 :
2823 72 : static bool gen_authinfo_internal(TALLOC_CTX *mem_ctx,
2824 : const char *incoming_old, const char *incoming_new,
2825 : const char *outgoing_old, const char *outgoing_new,
2826 : DATA_BLOB session_key,
2827 : struct lsa_TrustDomainInfoAuthInfoInternal **_authinfo_internal)
2828 : {
2829 0 : struct lsa_TrustDomainInfoAuthInfoInternal *authinfo_internal;
2830 0 : struct trustDomainPasswords auth_struct;
2831 0 : struct AuthenticationInformation in_info;
2832 0 : struct AuthenticationInformation io_info;
2833 0 : struct AuthenticationInformation on_info;
2834 0 : struct AuthenticationInformation oo_info;
2835 0 : size_t converted_size;
2836 0 : DATA_BLOB auth_blob;
2837 0 : enum ndr_err_code ndr_err;
2838 0 : bool ok;
2839 72 : gnutls_cipher_hd_t cipher_hnd = NULL;
2840 0 : gnutls_datum_t _session_key;
2841 :
2842 72 : authinfo_internal = talloc_zero(mem_ctx, struct lsa_TrustDomainInfoAuthInfoInternal);
2843 72 : if (authinfo_internal == NULL) {
2844 0 : return false;
2845 : }
2846 :
2847 72 : in_info.AuthType = TRUST_AUTH_TYPE_CLEAR;
2848 72 : ok = convert_string_talloc(mem_ctx, CH_UNIX, CH_UTF16,
2849 : incoming_new,
2850 : strlen(incoming_new),
2851 : &in_info.AuthInfo.clear.password,
2852 : &converted_size);
2853 72 : if (!ok) {
2854 0 : return false;
2855 : }
2856 72 : in_info.AuthInfo.clear.size = converted_size;
2857 :
2858 72 : io_info.AuthType = TRUST_AUTH_TYPE_CLEAR;
2859 72 : ok = convert_string_talloc(mem_ctx, CH_UNIX, CH_UTF16,
2860 : incoming_old,
2861 : strlen(incoming_old),
2862 : &io_info.AuthInfo.clear.password,
2863 : &converted_size);
2864 72 : if (!ok) {
2865 0 : return false;
2866 : }
2867 72 : io_info.AuthInfo.clear.size = converted_size;
2868 :
2869 72 : on_info.AuthType = TRUST_AUTH_TYPE_CLEAR;
2870 72 : ok = convert_string_talloc(mem_ctx, CH_UNIX, CH_UTF16,
2871 : outgoing_new,
2872 : strlen(outgoing_new),
2873 : &on_info.AuthInfo.clear.password,
2874 : &converted_size);
2875 72 : if (!ok) {
2876 0 : return false;
2877 : }
2878 72 : on_info.AuthInfo.clear.size = converted_size;
2879 :
2880 72 : oo_info.AuthType = TRUST_AUTH_TYPE_CLEAR;
2881 72 : ok = convert_string_talloc(mem_ctx, CH_UNIX, CH_UTF16,
2882 : outgoing_old,
2883 : strlen(outgoing_old),
2884 : &oo_info.AuthInfo.clear.password,
2885 : &converted_size);
2886 72 : if (!ok) {
2887 0 : return false;
2888 : }
2889 72 : oo_info.AuthInfo.clear.size = converted_size;
2890 :
2891 72 : generate_random_buffer(auth_struct.confounder, sizeof(auth_struct.confounder));
2892 72 : auth_struct.outgoing.count = 1;
2893 72 : auth_struct.outgoing.current.count = 1;
2894 72 : auth_struct.outgoing.current.array = &on_info;
2895 72 : auth_struct.outgoing.previous.count = 1;
2896 72 : auth_struct.outgoing.previous.array = &oo_info;
2897 :
2898 72 : auth_struct.incoming.count = 1;
2899 72 : auth_struct.incoming.current.count = 1;
2900 72 : auth_struct.incoming.current.array = &in_info;
2901 72 : auth_struct.incoming.previous.count = 1;
2902 72 : auth_struct.incoming.previous.array = &io_info;
2903 :
2904 72 : ndr_err = ndr_push_struct_blob(&auth_blob, mem_ctx, &auth_struct,
2905 : (ndr_push_flags_fn_t)ndr_push_trustDomainPasswords);
2906 72 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2907 0 : return false;
2908 : }
2909 :
2910 72 : _session_key = (gnutls_datum_t) {
2911 72 : .data = session_key.data,
2912 72 : .size = session_key.length,
2913 : };
2914 :
2915 72 : gnutls_cipher_init(&cipher_hnd,
2916 : GNUTLS_CIPHER_ARCFOUR_128,
2917 : &_session_key,
2918 : NULL);
2919 72 : gnutls_cipher_encrypt(cipher_hnd,
2920 72 : auth_blob.data,
2921 : auth_blob.length);
2922 72 : gnutls_cipher_deinit(cipher_hnd);
2923 :
2924 72 : authinfo_internal->auth_blob.size = auth_blob.length;
2925 72 : authinfo_internal->auth_blob.data = auth_blob.data;
2926 :
2927 72 : *_authinfo_internal = authinfo_internal;
2928 :
2929 72 : return true;
2930 : }
2931 :
2932 72 : static bool gen_authinfo(TALLOC_CTX *mem_ctx,
2933 : const char *incoming_old, const char *incoming_new,
2934 : const char *outgoing_old, const char *outgoing_new,
2935 : struct lsa_TrustDomainInfoAuthInfo **_authinfo)
2936 : {
2937 0 : struct lsa_TrustDomainInfoAuthInfo *authinfo;
2938 0 : struct lsa_TrustDomainInfoBuffer *in_buffer;
2939 0 : struct lsa_TrustDomainInfoBuffer *io_buffer;
2940 0 : struct lsa_TrustDomainInfoBuffer *on_buffer;
2941 0 : struct lsa_TrustDomainInfoBuffer *oo_buffer;
2942 0 : size_t converted_size;
2943 0 : bool ok;
2944 :
2945 72 : authinfo = talloc_zero(mem_ctx, struct lsa_TrustDomainInfoAuthInfo);
2946 72 : if (authinfo == NULL) {
2947 0 : return false;
2948 : }
2949 :
2950 72 : in_buffer = talloc_zero(authinfo, struct lsa_TrustDomainInfoBuffer);
2951 72 : if (in_buffer == NULL) {
2952 0 : return false;
2953 : }
2954 72 : in_buffer->AuthType = TRUST_AUTH_TYPE_CLEAR;
2955 72 : ok = convert_string_talloc(in_buffer, CH_UNIX, CH_UTF16,
2956 : incoming_new,
2957 : strlen(incoming_new),
2958 72 : &in_buffer->data.data,
2959 : &converted_size);
2960 72 : if (!ok) {
2961 0 : return false;
2962 : }
2963 72 : in_buffer->data.size = converted_size;
2964 :
2965 72 : io_buffer = talloc_zero(authinfo, struct lsa_TrustDomainInfoBuffer);
2966 72 : if (io_buffer == NULL) {
2967 0 : return false;
2968 : }
2969 72 : io_buffer->AuthType = TRUST_AUTH_TYPE_CLEAR;
2970 72 : ok = convert_string_talloc(io_buffer, CH_UNIX, CH_UTF16,
2971 : incoming_old,
2972 : strlen(incoming_old),
2973 72 : &io_buffer->data.data,
2974 : &converted_size);
2975 72 : if (!ok) {
2976 0 : return false;
2977 : }
2978 72 : io_buffer->data.size = converted_size;
2979 :
2980 72 : on_buffer = talloc_zero(authinfo, struct lsa_TrustDomainInfoBuffer);
2981 72 : if (on_buffer == NULL) {
2982 0 : return false;
2983 : }
2984 72 : on_buffer->AuthType = TRUST_AUTH_TYPE_CLEAR;
2985 72 : ok = convert_string_talloc(on_buffer, CH_UNIX, CH_UTF16,
2986 : outgoing_new,
2987 : strlen(outgoing_new),
2988 72 : &on_buffer->data.data,
2989 : &converted_size);
2990 72 : if (!ok) {
2991 0 : return false;
2992 : }
2993 72 : on_buffer->data.size = converted_size;
2994 :
2995 72 : oo_buffer = talloc_zero(authinfo, struct lsa_TrustDomainInfoBuffer);
2996 72 : if (oo_buffer == NULL) {
2997 0 : return false;
2998 : }
2999 72 : oo_buffer->AuthType = TRUST_AUTH_TYPE_CLEAR;
3000 72 : ok = convert_string_talloc(oo_buffer, CH_UNIX, CH_UTF16,
3001 : outgoing_old,
3002 : strlen(outgoing_old),
3003 72 : &oo_buffer->data.data,
3004 : &converted_size);
3005 72 : if (!ok) {
3006 0 : return false;
3007 : }
3008 72 : oo_buffer->data.size = converted_size;
3009 :
3010 72 : authinfo->incoming_count = 1;
3011 72 : authinfo->incoming_current_auth_info = in_buffer;
3012 72 : authinfo->incoming_previous_auth_info = io_buffer;
3013 72 : authinfo->outgoing_count = 1;
3014 72 : authinfo->outgoing_current_auth_info = on_buffer;
3015 72 : authinfo->outgoing_previous_auth_info = oo_buffer;
3016 :
3017 72 : *_authinfo = authinfo;
3018 :
3019 72 : return true;
3020 : }
3021 :
3022 126 : static bool check_pw_with_ServerAuthenticate3(struct dcerpc_pipe *p,
3023 : struct torture_context *tctx,
3024 : uint32_t negotiate_flags,
3025 : const char *server_name,
3026 : struct cli_credentials *machine_credentials,
3027 : struct netlogon_creds_CredentialState **creds_out)
3028 : {
3029 0 : struct netr_ServerReqChallenge r;
3030 0 : struct netr_ServerAuthenticate3 a;
3031 0 : struct netr_Credential credentials1, credentials2, credentials3;
3032 0 : struct netlogon_creds_CredentialState *creds;
3033 126 : const struct samr_Password *new_password = NULL;
3034 126 : const struct samr_Password *old_password = NULL;
3035 0 : uint32_t rid;
3036 126 : struct dcerpc_binding_handle *b = p->binding_handle;
3037 :
3038 126 : new_password = cli_credentials_get_nt_hash(machine_credentials, tctx);
3039 126 : old_password = cli_credentials_get_old_nt_hash(machine_credentials, tctx);
3040 :
3041 126 : r.in.server_name = server_name;
3042 126 : r.in.computer_name = cli_credentials_get_workstation(machine_credentials);
3043 126 : r.in.credentials = &credentials1;
3044 126 : r.out.return_credentials = &credentials2;
3045 :
3046 126 : netlogon_creds_random_challenge(&credentials1);
3047 :
3048 126 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
3049 : "ServerReqChallenge failed");
3050 126 : torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
3051 :
3052 126 : a.in.server_name = server_name;
3053 126 : a.in.account_name = cli_credentials_get_username(machine_credentials);
3054 126 : a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
3055 126 : a.in.computer_name = cli_credentials_get_workstation(machine_credentials);
3056 126 : a.in.negotiate_flags = &negotiate_flags;
3057 126 : a.in.credentials = &credentials3;
3058 126 : a.out.return_credentials = &credentials3;
3059 126 : a.out.negotiate_flags = &negotiate_flags;
3060 126 : a.out.rid = &rid;
3061 :
3062 126 : creds = netlogon_creds_client_init(tctx, a.in.account_name,
3063 : a.in.computer_name,
3064 126 : a.in.secure_channel_type,
3065 : &credentials1, &credentials2,
3066 : new_password, &credentials3,
3067 : negotiate_flags);
3068 :
3069 126 : torture_assert(tctx, creds != NULL, "memory allocation");
3070 :
3071 126 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b, tctx, &a),
3072 : "ServerAuthenticate3 failed");
3073 126 : if (!NT_STATUS_IS_OK(a.out.result)) {
3074 18 : if (!NT_STATUS_EQUAL(a.out.result, NT_STATUS_ACCESS_DENIED)) {
3075 0 : torture_assert_ntstatus_ok(tctx, a.out.result,
3076 : "ServerAuthenticate3 failed");
3077 : }
3078 18 : return false;
3079 : }
3080 108 : torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
3081 :
3082 108 : if (old_password != NULL) {
3083 108 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
3084 : "ServerReqChallenge failed");
3085 108 : torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
3086 :
3087 108 : creds = netlogon_creds_client_init(tctx, a.in.account_name,
3088 : a.in.computer_name,
3089 108 : a.in.secure_channel_type,
3090 : &credentials1, &credentials2,
3091 : old_password, &credentials3,
3092 : negotiate_flags);
3093 :
3094 108 : torture_assert(tctx, creds != NULL, "memory allocation");
3095 :
3096 108 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b, tctx, &a),
3097 : "ServerAuthenticate3 failed");
3098 108 : if (!NT_STATUS_IS_OK(a.out.result)) {
3099 0 : if (!NT_STATUS_EQUAL(a.out.result, NT_STATUS_ACCESS_DENIED)) {
3100 0 : torture_assert_ntstatus_ok(tctx, a.out.result,
3101 : "ServerAuthenticate3 (old) failed");
3102 : }
3103 0 : return false;
3104 : }
3105 108 : torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential (old) chaining failed");
3106 : }
3107 :
3108 : /* Prove that requesting a challenge again won't break it */
3109 108 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
3110 : "ServerReqChallenge failed");
3111 108 : torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
3112 :
3113 108 : *creds_out = creds;
3114 108 : return true;
3115 : }
3116 :
3117 : #ifdef SAMBA4_USES_HEIMDAL
3118 :
3119 : /*
3120 : * This function is set in torture_krb5_init_context as krb5
3121 : * send_and_recv function. This allows us to override what server the
3122 : * test is aimed at, and to inspect the packets just before they are
3123 : * sent to the network, and before they are processed on the recv
3124 : * side.
3125 : *
3126 : * The torture_krb5_pre_send_test() and torture_krb5_post_recv_test()
3127 : * functions are implement the actual tests.
3128 : *
3129 : * When this asserts, the caller will get a spurious 'cannot contact
3130 : * any KDC' message.
3131 : *
3132 : */
3133 : struct check_pw_with_krb5_ctx {
3134 : struct addrinfo *server;
3135 : const char *server_nb_domain;
3136 : const char *server_dns_domain;
3137 : struct {
3138 : unsigned io;
3139 : unsigned fail;
3140 : unsigned errors;
3141 : unsigned error_io;
3142 : unsigned ok;
3143 : } counts;
3144 : krb5_error error;
3145 : struct smb_krb5_context *smb_krb5_context;
3146 : krb5_get_init_creds_opt *krb_options;
3147 : krb5_creds my_creds;
3148 : krb5_get_creds_opt opt_canon;
3149 : krb5_get_creds_opt opt_nocanon;
3150 : krb5_principal upn_realm;
3151 : krb5_principal upn_dns;
3152 : krb5_principal upn_netbios;
3153 : krb5_ccache krbtgt_ccache;
3154 : krb5_principal krbtgt_trust_realm;
3155 : krb5_creds *krbtgt_trust_realm_creds;
3156 : krb5_principal krbtgt_trust_dns;
3157 : krb5_creds *krbtgt_trust_dns_creds;
3158 : krb5_principal krbtgt_trust_netbios;
3159 : krb5_creds *krbtgt_trust_netbios_creds;
3160 : krb5_principal cifs_trust_dns;
3161 : krb5_creds *cifs_trust_dns_creds;
3162 : krb5_principal cifs_trust_netbios;
3163 : krb5_creds *cifs_trust_netbios_creds;
3164 : krb5_principal drs_trust_dns;
3165 : krb5_creds *drs_trust_dns_creds;
3166 : krb5_principal drs_trust_netbios;
3167 : krb5_creds *drs_trust_netbios_creds;
3168 : krb5_principal four_trust_dns;
3169 : krb5_creds *four_trust_dns_creds;
3170 : krb5_creds krbtgt_referral_creds;
3171 : Ticket krbtgt_referral_ticket;
3172 : krb5_keyblock krbtgt_referral_keyblock;
3173 : EncTicketPart krbtgt_referral_enc_part;
3174 : };
3175 :
3176 2184 : static krb5_error_code check_pw_with_krb5_send_to_realm(
3177 : struct smb_krb5_context *smb_krb5_context,
3178 : void *data, /* struct check_pw_with_krb5_ctx */
3179 : krb5_const_realm realm,
3180 : time_t timeout,
3181 : const krb5_data *send_buf,
3182 : krb5_data *recv_buf)
3183 : {
3184 0 : struct check_pw_with_krb5_ctx *ctx =
3185 2184 : talloc_get_type_abort(data, struct check_pw_with_krb5_ctx);
3186 0 : krb5_error_code k5ret;
3187 0 : size_t used;
3188 0 : int ret;
3189 :
3190 2184 : SMB_ASSERT(smb_krb5_context == ctx->smb_krb5_context);
3191 :
3192 2184 : if (!strequal_m(realm, ctx->server_nb_domain) &&
3193 2184 : !strequal_m(realm, ctx->server_dns_domain))
3194 : {
3195 540 : return KRB5_KDC_UNREACH;
3196 : }
3197 :
3198 1644 : krb5_free_error_contents(ctx->smb_krb5_context->krb5_context,
3199 : &ctx->error);
3200 1644 : ctx->counts.io++;
3201 :
3202 1644 : k5ret = smb_krb5_send_and_recv_func_forced_tcp(ctx->smb_krb5_context,
3203 : ctx->server,
3204 : timeout, send_buf, recv_buf);
3205 1644 : if (k5ret != 0) {
3206 0 : ctx->counts.fail++;
3207 0 : return k5ret;
3208 : }
3209 :
3210 1644 : ret = decode_KRB_ERROR(recv_buf->data, recv_buf->length,
3211 1644 : &ctx->error, &used);
3212 1644 : if (ret == 0) {
3213 636 : ctx->counts.errors++;
3214 636 : ctx->counts.error_io = ctx->counts.io;
3215 : } else {
3216 1008 : ctx->counts.ok++;
3217 : }
3218 :
3219 1644 : return k5ret;
3220 : }
3221 :
3222 84 : static int check_pw_with_krb5_ctx_destructor(struct check_pw_with_krb5_ctx *ctx)
3223 : {
3224 84 : if (ctx->server != NULL) {
3225 84 : freeaddrinfo(ctx->server);
3226 84 : ctx->server = NULL;
3227 : }
3228 :
3229 84 : if (ctx->krb_options != NULL) {
3230 84 : krb5_get_init_creds_opt_free(ctx->smb_krb5_context->krb5_context,
3231 : ctx->krb_options);
3232 84 : ctx->krb_options = NULL;
3233 : }
3234 :
3235 84 : krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
3236 : &ctx->my_creds);
3237 :
3238 84 : if (ctx->opt_canon != NULL) {
3239 72 : krb5_get_creds_opt_free(ctx->smb_krb5_context->krb5_context,
3240 : ctx->opt_canon);
3241 72 : ctx->opt_canon = NULL;
3242 : }
3243 :
3244 84 : if (ctx->opt_nocanon != NULL) {
3245 72 : krb5_get_creds_opt_free(ctx->smb_krb5_context->krb5_context,
3246 : ctx->opt_nocanon);
3247 72 : ctx->opt_nocanon = NULL;
3248 : }
3249 :
3250 84 : if (ctx->krbtgt_ccache != NULL) {
3251 72 : krb5_cc_close(ctx->smb_krb5_context->krb5_context,
3252 : ctx->krbtgt_ccache);
3253 72 : ctx->krbtgt_ccache = NULL;
3254 : }
3255 :
3256 84 : if (ctx->upn_realm != NULL) {
3257 84 : krb5_free_principal(ctx->smb_krb5_context->krb5_context,
3258 : ctx->upn_realm);
3259 84 : ctx->upn_realm = NULL;
3260 : }
3261 :
3262 84 : if (ctx->upn_dns != NULL) {
3263 84 : krb5_free_principal(ctx->smb_krb5_context->krb5_context,
3264 : ctx->upn_dns);
3265 84 : ctx->upn_dns = NULL;
3266 : }
3267 :
3268 84 : if (ctx->upn_netbios != NULL) {
3269 84 : krb5_free_principal(ctx->smb_krb5_context->krb5_context,
3270 : ctx->upn_netbios);
3271 84 : ctx->upn_netbios = NULL;
3272 : }
3273 :
3274 84 : if (ctx->krbtgt_trust_realm != NULL) {
3275 72 : krb5_free_principal(ctx->smb_krb5_context->krb5_context,
3276 : ctx->krbtgt_trust_realm);
3277 72 : ctx->krbtgt_trust_realm = NULL;
3278 : }
3279 :
3280 84 : if (ctx->krbtgt_trust_realm_creds != NULL) {
3281 72 : krb5_free_creds(ctx->smb_krb5_context->krb5_context,
3282 : ctx->krbtgt_trust_realm_creds);
3283 72 : ctx->krbtgt_trust_realm_creds = NULL;
3284 : }
3285 :
3286 84 : if (ctx->krbtgt_trust_dns != NULL) {
3287 72 : krb5_free_principal(ctx->smb_krb5_context->krb5_context,
3288 : ctx->krbtgt_trust_dns);
3289 72 : ctx->krbtgt_trust_dns = NULL;
3290 : }
3291 :
3292 84 : if (ctx->krbtgt_trust_dns_creds != NULL) {
3293 72 : krb5_free_creds(ctx->smb_krb5_context->krb5_context,
3294 : ctx->krbtgt_trust_dns_creds);
3295 72 : ctx->krbtgt_trust_dns_creds = NULL;
3296 : }
3297 :
3298 84 : if (ctx->krbtgt_trust_netbios != NULL) {
3299 72 : krb5_free_principal(ctx->smb_krb5_context->krb5_context,
3300 : ctx->krbtgt_trust_netbios);
3301 72 : ctx->krbtgt_trust_netbios = NULL;
3302 : }
3303 :
3304 84 : if (ctx->krbtgt_trust_netbios_creds != NULL) {
3305 72 : krb5_free_creds(ctx->smb_krb5_context->krb5_context,
3306 : ctx->krbtgt_trust_netbios_creds);
3307 72 : ctx->krbtgt_trust_netbios_creds = NULL;
3308 : }
3309 :
3310 84 : if (ctx->cifs_trust_dns != NULL) {
3311 72 : krb5_free_principal(ctx->smb_krb5_context->krb5_context,
3312 : ctx->cifs_trust_dns);
3313 72 : ctx->cifs_trust_dns = NULL;
3314 : }
3315 :
3316 84 : if (ctx->cifs_trust_dns_creds != NULL) {
3317 0 : krb5_free_creds(ctx->smb_krb5_context->krb5_context,
3318 : ctx->cifs_trust_dns_creds);
3319 0 : ctx->cifs_trust_dns_creds = NULL;
3320 : }
3321 :
3322 84 : if (ctx->cifs_trust_netbios != NULL) {
3323 72 : krb5_free_principal(ctx->smb_krb5_context->krb5_context,
3324 : ctx->cifs_trust_netbios);
3325 72 : ctx->cifs_trust_netbios = NULL;
3326 : }
3327 :
3328 84 : if (ctx->cifs_trust_netbios_creds != NULL) {
3329 0 : krb5_free_creds(ctx->smb_krb5_context->krb5_context,
3330 : ctx->cifs_trust_netbios_creds);
3331 0 : ctx->cifs_trust_netbios_creds = NULL;
3332 : }
3333 :
3334 84 : if (ctx->drs_trust_dns != NULL) {
3335 72 : krb5_free_principal(ctx->smb_krb5_context->krb5_context,
3336 : ctx->drs_trust_dns);
3337 72 : ctx->drs_trust_dns = NULL;
3338 : }
3339 :
3340 84 : if (ctx->drs_trust_dns_creds != NULL) {
3341 0 : krb5_free_creds(ctx->smb_krb5_context->krb5_context,
3342 : ctx->drs_trust_dns_creds);
3343 0 : ctx->drs_trust_dns_creds = NULL;
3344 : }
3345 :
3346 84 : if (ctx->drs_trust_netbios != NULL) {
3347 72 : krb5_free_principal(ctx->smb_krb5_context->krb5_context,
3348 : ctx->drs_trust_netbios);
3349 72 : ctx->drs_trust_netbios = NULL;
3350 : }
3351 :
3352 84 : if (ctx->drs_trust_netbios_creds != NULL) {
3353 0 : krb5_free_creds(ctx->smb_krb5_context->krb5_context,
3354 : ctx->drs_trust_netbios_creds);
3355 0 : ctx->drs_trust_netbios_creds = NULL;
3356 : }
3357 :
3358 84 : if (ctx->four_trust_dns != NULL) {
3359 72 : krb5_free_principal(ctx->smb_krb5_context->krb5_context,
3360 : ctx->four_trust_dns);
3361 72 : ctx->four_trust_dns = NULL;
3362 : }
3363 :
3364 84 : if (ctx->four_trust_dns_creds != NULL) {
3365 0 : krb5_free_creds(ctx->smb_krb5_context->krb5_context,
3366 : ctx->four_trust_dns_creds);
3367 0 : ctx->four_trust_dns_creds = NULL;
3368 : }
3369 :
3370 84 : krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
3371 : &ctx->krbtgt_referral_creds);
3372 :
3373 84 : free_Ticket(&ctx->krbtgt_referral_ticket);
3374 :
3375 84 : krb5_free_keyblock_contents(ctx->smb_krb5_context->krb5_context,
3376 : &ctx->krbtgt_referral_keyblock);
3377 :
3378 84 : free_EncTicketPart(&ctx->krbtgt_referral_enc_part);
3379 :
3380 84 : krb5_free_error_contents(ctx->smb_krb5_context->krb5_context,
3381 : &ctx->error);
3382 :
3383 84 : talloc_unlink(ctx, ctx->smb_krb5_context);
3384 84 : ctx->smb_krb5_context = NULL;
3385 84 : return 0;
3386 : }
3387 :
3388 84 : static bool check_pw_with_krb5(struct torture_context *tctx,
3389 : struct cli_credentials *credentials,
3390 : const struct lsa_TrustDomainInfoInfoEx *trusted)
3391 : {
3392 84 : const char *trusted_dns_name = trusted->domain_name.string;
3393 84 : const char *trusted_netbios_name = trusted->netbios_name.string;
3394 84 : char *trusted_realm_name = NULL;
3395 84 : krb5_principal principal = NULL;
3396 0 : enum credentials_obtained obtained;
3397 84 : const char *error_string = NULL;
3398 84 : const char *workstation = cli_credentials_get_workstation(credentials);
3399 84 : const char *password = cli_credentials_get_password(credentials);
3400 : #ifndef USING_EMBEDDED_HEIMDAL
3401 0 : const struct samr_Password *nthash = NULL;
3402 0 : const struct samr_Password *old_nthash = NULL;
3403 : #endif
3404 84 : const char *old_password = cli_credentials_get_old_password(credentials);
3405 : #ifndef USING_EMBEDDED_HEIMDAL
3406 0 : int kvno = cli_credentials_get_kvno(credentials);
3407 0 : int expected_kvno = 0;
3408 0 : krb5uint32 t_kvno = 0;
3409 : #endif
3410 84 : const char *host = torture_setting_string(tctx, "host", NULL);
3411 0 : krb5_error_code k5ret;
3412 0 : krb5_boolean k5ok;
3413 0 : int type;
3414 0 : bool ok;
3415 84 : struct check_pw_with_krb5_ctx *ctx = NULL;
3416 84 : char *assertion_message = NULL;
3417 84 : const char *realm = NULL;
3418 84 : char *upn_realm_string = NULL;
3419 84 : char *upn_dns_string = NULL;
3420 84 : char *upn_netbios_string = NULL;
3421 84 : char *krbtgt_cc_name = NULL;
3422 84 : char *krbtgt_trust_realm_string = NULL;
3423 84 : char *krbtgt_trust_dns_string = NULL;
3424 84 : char *krbtgt_trust_netbios_string = NULL;
3425 84 : char *cifs_trust_dns_string = NULL;
3426 84 : char *cifs_trust_netbios_string = NULL;
3427 84 : char *drs_trust_dns_string = NULL;
3428 84 : char *drs_trust_netbios_string = NULL;
3429 84 : char *four_trust_dns_string = NULL;
3430 :
3431 84 : ctx = talloc_zero(tctx, struct check_pw_with_krb5_ctx);
3432 84 : torture_assert(tctx, ctx != NULL, "Failed to allocate");
3433 :
3434 84 : realm = cli_credentials_get_realm(credentials);
3435 84 : trusted_realm_name = strupper_talloc(tctx, trusted_dns_name);
3436 :
3437 : #ifndef USING_EMBEDDED_HEIMDAL
3438 0 : nthash = cli_credentials_get_nt_hash(credentials, ctx);
3439 0 : old_nthash = cli_credentials_get_old_nt_hash(credentials, ctx);
3440 : #endif
3441 :
3442 84 : k5ret = smb_krb5_init_context(ctx, tctx->lp_ctx, &ctx->smb_krb5_context);
3443 84 : torture_assert_int_equal(tctx, k5ret, 0, "smb_krb5_init_context failed");
3444 :
3445 84 : ctx->server_nb_domain = cli_credentials_get_domain(credentials);
3446 84 : ctx->server_dns_domain = cli_credentials_get_realm(credentials);
3447 :
3448 84 : ok = interpret_string_addr_internal(&ctx->server, host, 0);
3449 84 : torture_assert(tctx, ok, "Failed to parse target server");
3450 84 : talloc_set_destructor(ctx, check_pw_with_krb5_ctx_destructor);
3451 :
3452 84 : set_sockaddr_port(ctx->server->ai_addr, 88);
3453 :
3454 84 : k5ret = smb_krb5_set_send_to_kdc_func(ctx->smb_krb5_context,
3455 : check_pw_with_krb5_send_to_realm,
3456 : NULL, /* send_to_kdc */
3457 : ctx);
3458 84 : torture_assert_int_equal(tctx, k5ret, 0, "krb5_set_send_to_kdc_func failed");
3459 :
3460 84 : torture_assert_int_equal(tctx,
3461 : krb5_get_init_creds_opt_alloc(ctx->smb_krb5_context->krb5_context,
3462 : &ctx->krb_options),
3463 : 0, "krb5_get_init_creds_opt_alloc failed");
3464 84 : torture_assert_int_equal(tctx,
3465 : krb5_get_init_creds_opt_set_pac_request(
3466 : ctx->smb_krb5_context->krb5_context,
3467 : ctx->krb_options, true),
3468 : 0, "krb5_get_init_creds_opt_set_pac_request failed");
3469 :
3470 84 : upn_realm_string = talloc_asprintf(ctx, "user@%s",
3471 : trusted_realm_name);
3472 84 : torture_assert_int_equal(tctx,
3473 : smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
3474 : &ctx->upn_realm,
3475 : realm, upn_realm_string, NULL),
3476 : 0, "smb_krb5_make_principal failed");
3477 84 : smb_krb5_principal_set_type(ctx->smb_krb5_context->krb5_context,
3478 : ctx->upn_realm, KRB5_NT_ENTERPRISE_PRINCIPAL);
3479 :
3480 84 : upn_dns_string = talloc_asprintf(ctx, "user@%s",
3481 : trusted_dns_name);
3482 84 : torture_assert_int_equal(tctx,
3483 : smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
3484 : &ctx->upn_dns,
3485 : realm, upn_dns_string, NULL),
3486 : 0, "smb_krb5_make_principal failed");
3487 84 : smb_krb5_principal_set_type(ctx->smb_krb5_context->krb5_context,
3488 : ctx->upn_dns, KRB5_NT_ENTERPRISE_PRINCIPAL);
3489 :
3490 84 : upn_netbios_string = talloc_asprintf(ctx, "user@%s",
3491 : trusted_netbios_name);
3492 84 : torture_assert_int_equal(tctx,
3493 : smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
3494 : &ctx->upn_netbios,
3495 : realm, upn_netbios_string, NULL),
3496 : 0, "smb_krb5_make_principal failed");
3497 84 : smb_krb5_principal_set_type(ctx->smb_krb5_context->krb5_context,
3498 : ctx->upn_netbios, KRB5_NT_ENTERPRISE_PRINCIPAL);
3499 :
3500 84 : k5ret = principal_from_credentials(ctx, credentials, ctx->smb_krb5_context,
3501 : &principal, &obtained, &error_string);
3502 84 : torture_assert_int_equal(tctx, k5ret, 0, error_string);
3503 :
3504 84 : ZERO_STRUCT(ctx->counts);
3505 84 : k5ret = krb5_get_init_creds_password(ctx->smb_krb5_context->krb5_context,
3506 : &ctx->my_creds, ctx->upn_realm,
3507 : "_none_", NULL, NULL, 0,
3508 : NULL, ctx->krb_options);
3509 84 : assertion_message = talloc_asprintf(ctx,
3510 : "krb5_get_init_creds_password(%s, canon) for failed: "
3511 : "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u/%u,ok=%u]",
3512 : upn_realm_string,
3513 : k5ret,
3514 84 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3515 : k5ret, ctx),
3516 84 : trusted->trust_direction,
3517 84 : trusted->trust_type,
3518 84 : trusted->trust_attributes,
3519 : ctx->counts.io, ctx->counts.error_io, ctx->counts.errors, ctx->counts.ok);
3520 84 : torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
3521 84 : torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
3522 84 : torture_assert_int_equal(tctx, ctx->counts.error_io, 1, assertion_message);
3523 84 : torture_assert_int_equal(tctx, KRB5_ERROR_CODE(&ctx->error), 68, assertion_message);
3524 84 : torture_assert(tctx, ctx->error.crealm != NULL, assertion_message);
3525 84 : torture_assert_str_equal(tctx, *ctx->error.crealm, trusted_realm_name, assertion_message);
3526 : #ifdef USING_EMBEDDED_HEIMDAL
3527 84 : torture_assert(tctx, ctx->error.cname != NULL, assertion_message);
3528 84 : torture_assert_int_equal(tctx, ctx->error.cname->name_type, KRB5_NT_ENTERPRISE_PRINCIPAL, assertion_message);
3529 84 : torture_assert_int_equal(tctx, ctx->error.cname->name_string.len, 1, assertion_message);
3530 84 : torture_assert_str_equal(tctx, ctx->error.cname->name_string.val[0], upn_realm_string, assertion_message);
3531 : #else
3532 0 : torture_assert(tctx, ctx->error.cname == NULL, assertion_message);
3533 : #endif
3534 84 : torture_assert_str_equal(tctx, ctx->error.realm, realm, assertion_message);
3535 :
3536 84 : ZERO_STRUCT(ctx->counts);
3537 84 : k5ret = krb5_get_init_creds_password(ctx->smb_krb5_context->krb5_context,
3538 : &ctx->my_creds, ctx->upn_dns,
3539 : "_none_", NULL, NULL, 0,
3540 : NULL, ctx->krb_options);
3541 84 : assertion_message = talloc_asprintf(ctx,
3542 : "krb5_get_init_creds_password(%s, canon) for failed: "
3543 : "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u/%u,ok=%u]",
3544 : upn_dns_string,
3545 : k5ret,
3546 84 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3547 : k5ret, ctx),
3548 84 : trusted->trust_direction,
3549 84 : trusted->trust_type,
3550 84 : trusted->trust_attributes,
3551 : ctx->counts.io, ctx->counts.error_io, ctx->counts.errors, ctx->counts.ok);
3552 84 : torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
3553 84 : torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
3554 84 : torture_assert_int_equal(tctx, ctx->counts.error_io, 1, assertion_message);
3555 84 : torture_assert_int_equal(tctx, KRB5_ERROR_CODE(&ctx->error), 68, assertion_message);
3556 84 : torture_assert(tctx, ctx->error.crealm != NULL, assertion_message);
3557 84 : torture_assert_str_equal(tctx, *ctx->error.crealm, trusted_realm_name, assertion_message);
3558 : #ifdef USING_EMBEDDED_HEIMDAL
3559 84 : torture_assert(tctx, ctx->error.cname != NULL, assertion_message);
3560 84 : torture_assert_int_equal(tctx, ctx->error.cname->name_type, KRB5_NT_ENTERPRISE_PRINCIPAL, assertion_message);
3561 84 : torture_assert_int_equal(tctx, ctx->error.cname->name_string.len, 1, assertion_message);
3562 84 : torture_assert_str_equal(tctx, ctx->error.cname->name_string.val[0], upn_dns_string, assertion_message);
3563 : #else
3564 0 : torture_assert(tctx, ctx->error.cname == NULL, assertion_message);
3565 : #endif
3566 84 : torture_assert_str_equal(tctx, ctx->error.realm, realm, assertion_message);
3567 :
3568 84 : ZERO_STRUCT(ctx->counts);
3569 84 : k5ret = krb5_get_init_creds_password(ctx->smb_krb5_context->krb5_context,
3570 : &ctx->my_creds, ctx->upn_netbios,
3571 : "_none_", NULL, NULL, 0,
3572 : NULL, ctx->krb_options);
3573 84 : assertion_message = talloc_asprintf(ctx,
3574 : "krb5_get_init_creds_password(%s, canon) for failed: "
3575 : "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u/%u,ok=%u]",
3576 : upn_netbios_string,
3577 : k5ret,
3578 84 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3579 : k5ret, ctx),
3580 84 : trusted->trust_direction,
3581 84 : trusted->trust_type,
3582 84 : trusted->trust_attributes,
3583 : ctx->counts.io, ctx->counts.error_io, ctx->counts.errors, ctx->counts.ok);
3584 84 : torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
3585 84 : torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
3586 84 : torture_assert_int_equal(tctx, ctx->counts.error_io, 1, assertion_message);
3587 84 : torture_assert_int_equal(tctx, KRB5_ERROR_CODE(&ctx->error), 68, assertion_message);
3588 84 : torture_assert(tctx, ctx->error.crealm != NULL, assertion_message);
3589 84 : torture_assert_str_equal(tctx, *ctx->error.crealm, trusted_realm_name, assertion_message);
3590 : #ifdef USING_EMBEDDED_HEIMDAL
3591 84 : torture_assert(tctx, ctx->error.cname != NULL, assertion_message);
3592 84 : torture_assert_int_equal(tctx, ctx->error.cname->name_type, KRB5_NT_ENTERPRISE_PRINCIPAL, assertion_message);
3593 84 : torture_assert_int_equal(tctx, ctx->error.cname->name_string.len, 1, assertion_message);
3594 84 : torture_assert_str_equal(tctx, ctx->error.cname->name_string.val[0], upn_netbios_string, assertion_message);
3595 : #else
3596 0 : torture_assert(tctx, ctx->error.cname == NULL, assertion_message);
3597 : #endif
3598 84 : torture_assert_str_equal(tctx, ctx->error.realm, realm, assertion_message);
3599 :
3600 84 : torture_comment(tctx, "(%s:%s) password[%s] old_password[%s]\n",
3601 : __location__, __FUNCTION__,
3602 : password, old_password);
3603 84 : if (old_password != NULL) {
3604 72 : k5ret = krb5_get_init_creds_password(ctx->smb_krb5_context->krb5_context,
3605 : &ctx->my_creds, principal,
3606 : old_password, NULL, NULL, 0,
3607 : NULL, ctx->krb_options);
3608 72 : torture_assert_int_equal(tctx, k5ret, KRB5KDC_ERR_PREAUTH_FAILED,
3609 : "preauth should fail with old password");
3610 : }
3611 :
3612 84 : k5ret = krb5_get_init_creds_password(ctx->smb_krb5_context->krb5_context,
3613 : &ctx->my_creds, principal,
3614 : password, NULL, NULL, 0,
3615 : NULL, ctx->krb_options);
3616 84 : if (k5ret == KRB5KDC_ERR_PREAUTH_FAILED) {
3617 12 : TALLOC_FREE(ctx);
3618 12 : return false;
3619 : }
3620 :
3621 72 : assertion_message = talloc_asprintf(ctx,
3622 : "krb5_get_init_creds_password for failed: %s",
3623 72 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3624 : k5ret, ctx));
3625 72 : torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3626 :
3627 72 : torture_assert_int_equal(tctx,
3628 : krb5_get_creds_opt_alloc(ctx->smb_krb5_context->krb5_context,
3629 : &ctx->opt_canon),
3630 : 0, "krb5_get_creds_opt_alloc");
3631 :
3632 72 : krb5_get_creds_opt_add_options(ctx->smb_krb5_context->krb5_context,
3633 : ctx->opt_canon,
3634 : KRB5_GC_CANONICALIZE);
3635 :
3636 72 : krb5_get_creds_opt_add_options(ctx->smb_krb5_context->krb5_context,
3637 : ctx->opt_canon,
3638 : KRB5_GC_NO_STORE);
3639 :
3640 72 : torture_assert_int_equal(tctx,
3641 : krb5_get_creds_opt_alloc(ctx->smb_krb5_context->krb5_context,
3642 : &ctx->opt_nocanon),
3643 : 0, "krb5_get_creds_opt_alloc");
3644 :
3645 72 : krb5_get_creds_opt_add_options(ctx->smb_krb5_context->krb5_context,
3646 : ctx->opt_nocanon,
3647 : KRB5_GC_NO_STORE);
3648 :
3649 72 : krbtgt_cc_name = talloc_asprintf(ctx, "MEMORY:%p.krbtgt", ctx->smb_krb5_context);
3650 72 : torture_assert_int_equal(tctx,
3651 : krb5_cc_resolve(ctx->smb_krb5_context->krb5_context,
3652 : krbtgt_cc_name,
3653 : &ctx->krbtgt_ccache),
3654 : 0, "krb5_cc_resolve failed");
3655 :
3656 72 : torture_assert_int_equal(tctx,
3657 : krb5_cc_initialize(ctx->smb_krb5_context->krb5_context,
3658 : ctx->krbtgt_ccache,
3659 : ctx->my_creds.client),
3660 : 0, "krb5_cc_initialize failed");
3661 :
3662 72 : torture_assert_int_equal(tctx,
3663 : krb5_cc_store_cred(ctx->smb_krb5_context->krb5_context,
3664 : ctx->krbtgt_ccache,
3665 : &ctx->my_creds),
3666 : 0, "krb5_cc_store_cred failed");
3667 :
3668 72 : krbtgt_trust_realm_string = talloc_asprintf(ctx, "krbtgt/%s@%s",
3669 : trusted_realm_name, realm);
3670 72 : torture_assert_int_equal(tctx,
3671 : smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
3672 : &ctx->krbtgt_trust_realm,
3673 : realm, "krbtgt",
3674 : trusted_realm_name, NULL),
3675 : 0, "smb_krb5_make_principal failed");
3676 :
3677 72 : krbtgt_trust_dns_string = talloc_asprintf(ctx, "krbtgt/%s@%s",
3678 : trusted_dns_name, realm);
3679 72 : torture_assert_int_equal(tctx,
3680 : smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
3681 : &ctx->krbtgt_trust_dns,
3682 : realm, "krbtgt",
3683 : trusted_dns_name, NULL),
3684 : 0, "smb_krb5_make_principal failed");
3685 :
3686 72 : krbtgt_trust_netbios_string = talloc_asprintf(ctx, "krbtgt/%s@%s",
3687 : trusted_netbios_name, realm);
3688 72 : torture_assert_int_equal(tctx,
3689 : smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
3690 : &ctx->krbtgt_trust_netbios,
3691 : realm, "krbtgt",
3692 : trusted_netbios_name, NULL),
3693 : 0, "smb_krb5_make_principal failed");
3694 :
3695 : /* Confirm if we can do a TGS for krbtgt/trusted_realm */
3696 72 : ZERO_STRUCT(ctx->counts);
3697 72 : k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
3698 : ctx->opt_nocanon,
3699 : ctx->krbtgt_ccache,
3700 72 : ctx->krbtgt_trust_realm,
3701 : &ctx->krbtgt_trust_realm_creds);
3702 72 : assertion_message = talloc_asprintf(ctx,
3703 : "krb5_get_creds(%s, canon) for failed: "
3704 : "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
3705 : krbtgt_trust_realm_string,
3706 : k5ret,
3707 72 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3708 : k5ret, ctx),
3709 72 : trusted->trust_direction,
3710 72 : trusted->trust_type,
3711 72 : trusted->trust_attributes,
3712 : ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
3713 72 : torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3714 72 : torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
3715 72 : torture_assert_int_equal(tctx, ctx->counts.ok, 1, assertion_message);
3716 :
3717 72 : k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
3718 72 : ctx->krbtgt_trust_realm_creds->server,
3719 72 : ctx->krbtgt_trust_realm);
3720 72 : torture_assert(tctx, k5ok, assertion_message);
3721 72 : type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
3722 72 : ctx->krbtgt_trust_realm_creds->server);
3723 72 : torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
3724 :
3725 : /* Confirm if we have no referral ticket in the cache */
3726 72 : krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
3727 : &ctx->krbtgt_referral_creds);
3728 72 : k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
3729 : ctx->krbtgt_ccache,
3730 : 0,
3731 72 : ctx->krbtgt_trust_realm_creds,
3732 : &ctx->krbtgt_referral_creds);
3733 72 : assertion_message = talloc_asprintf(ctx,
3734 : "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
3735 : krbtgt_trust_realm_string,
3736 : k5ret,
3737 72 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3738 : k5ret, ctx));
3739 72 : torture_assert_int_equal(tctx, k5ret, KRB5_CC_END, assertion_message);
3740 :
3741 : /* Confirm if we can do a TGS for krbtgt/trusted_dns with CANON */
3742 72 : ZERO_STRUCT(ctx->counts);
3743 72 : k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
3744 : ctx->opt_canon,
3745 : ctx->krbtgt_ccache,
3746 72 : ctx->krbtgt_trust_dns,
3747 : &ctx->krbtgt_trust_dns_creds);
3748 72 : assertion_message = talloc_asprintf(ctx,
3749 : "krb5_get_creds(%s, canon) for failed: "
3750 : "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
3751 : krbtgt_trust_dns_string,
3752 : k5ret,
3753 72 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3754 : k5ret, ctx),
3755 72 : trusted->trust_direction,
3756 72 : trusted->trust_type,
3757 72 : trusted->trust_attributes,
3758 : ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
3759 : #ifdef USING_EMBEDDED_HEIMDAL
3760 72 : torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3761 : #else
3762 0 : torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
3763 : #endif
3764 72 : torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
3765 72 : torture_assert_int_equal(tctx, ctx->counts.ok, 1, assertion_message);
3766 :
3767 : /* Confirm if we have the referral ticket in the cache */
3768 72 : krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
3769 : &ctx->krbtgt_referral_creds);
3770 72 : k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
3771 : ctx->krbtgt_ccache,
3772 : 0,
3773 72 : ctx->krbtgt_trust_realm_creds,
3774 : &ctx->krbtgt_referral_creds);
3775 72 : assertion_message = talloc_asprintf(ctx,
3776 : "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
3777 : krbtgt_trust_realm_string,
3778 : k5ret,
3779 72 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3780 : k5ret, ctx));
3781 : #ifdef USING_EMBEDDED_HEIMDAL
3782 72 : torture_assert_int_equal(tctx, k5ret, KRB5_CC_END, assertion_message);
3783 : #else
3784 0 : torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3785 :
3786 0 : k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
3787 0 : ctx->krbtgt_referral_creds.server,
3788 0 : ctx->krbtgt_trust_realm);
3789 0 : torture_assert(tctx, k5ok, assertion_message);
3790 0 : type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
3791 0 : ctx->krbtgt_referral_creds.server);
3792 0 : torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
3793 0 : k5ret = decode_Ticket(ctx->krbtgt_referral_creds.ticket.data,
3794 : ctx->krbtgt_referral_creds.ticket.length,
3795 : &ctx->krbtgt_referral_ticket, NULL);
3796 0 : torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3797 0 : if (kvno > 0) {
3798 0 : expected_kvno = kvno - 1;
3799 : }
3800 0 : if (ctx->krbtgt_referral_ticket.enc_part.kvno != NULL) {
3801 0 : t_kvno = *ctx->krbtgt_referral_ticket.enc_part.kvno;
3802 0 : assertion_message = talloc_asprintf(ctx,
3803 : "krbtgt_referral_ticket(%s) kvno(%u) expected(%u) current(%u)",
3804 : krbtgt_trust_realm_string,
3805 : (unsigned)t_kvno, (unsigned)expected_kvno,(unsigned)kvno);
3806 0 : torture_comment(tctx, "%s\n", assertion_message);
3807 0 : torture_assert_int_not_equal(tctx, t_kvno, 0, assertion_message);
3808 : } else {
3809 0 : assertion_message = talloc_asprintf(ctx,
3810 : "krbtgt_referral_ticket(%s) kvno(NULL) expected(%u) current(%u)",
3811 : krbtgt_trust_realm_string,
3812 : (unsigned)expected_kvno,(unsigned)kvno);
3813 0 : torture_comment(tctx, "%s\n", assertion_message);
3814 : }
3815 0 : torture_assert_int_equal(tctx, t_kvno, expected_kvno, assertion_message);
3816 :
3817 0 : if (old_nthash != NULL && expected_kvno != kvno) {
3818 0 : torture_comment(tctx, "old_nthash: %s\n", assertion_message);
3819 0 : k5ret = smb_krb5_keyblock_init_contents(ctx->smb_krb5_context->krb5_context,
3820 : ENCTYPE_ARCFOUR_HMAC,
3821 0 : old_nthash->hash,
3822 : sizeof(old_nthash->hash),
3823 : &ctx->krbtgt_referral_keyblock);
3824 0 : torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3825 : } else {
3826 0 : torture_comment(tctx, "nthash: %s\n", assertion_message);
3827 0 : k5ret = smb_krb5_keyblock_init_contents(ctx->smb_krb5_context->krb5_context,
3828 : ENCTYPE_ARCFOUR_HMAC,
3829 0 : nthash->hash,
3830 : sizeof(nthash->hash),
3831 : &ctx->krbtgt_referral_keyblock);
3832 0 : torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3833 : }
3834 0 : k5ret = krb5_decrypt_ticket(ctx->smb_krb5_context->krb5_context,
3835 : &ctx->krbtgt_referral_ticket,
3836 : &ctx->krbtgt_referral_keyblock,
3837 : &ctx->krbtgt_referral_enc_part,
3838 : 0);
3839 0 : torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3840 :
3841 : /* Delete the referral ticket from the cache */
3842 0 : k5ret = krb5_cc_remove_cred(ctx->smb_krb5_context->krb5_context,
3843 : ctx->krbtgt_ccache,
3844 : 0,
3845 : &ctx->krbtgt_referral_creds);
3846 0 : assertion_message = talloc_asprintf(ctx,
3847 : "krb5_cc_remove_cred(%s) for failed: (%d) %s",
3848 : krbtgt_trust_realm_string,
3849 : k5ret,
3850 0 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3851 : k5ret, ctx));
3852 0 : torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3853 : #endif
3854 :
3855 : /* Confirm if we can do a TGS for krbtgt/trusted_dns no CANON */
3856 72 : ZERO_STRUCT(ctx->counts);
3857 72 : k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
3858 : ctx->opt_nocanon,
3859 : ctx->krbtgt_ccache,
3860 72 : ctx->krbtgt_trust_dns,
3861 : &ctx->krbtgt_trust_dns_creds);
3862 72 : assertion_message = talloc_asprintf(ctx,
3863 : "krb5_get_creds(%s, nocanon) for failed: "
3864 : "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
3865 : krbtgt_trust_dns_string,
3866 : k5ret,
3867 72 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3868 : k5ret, ctx),
3869 72 : trusted->trust_direction,
3870 72 : trusted->trust_type,
3871 72 : trusted->trust_attributes,
3872 : ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
3873 72 : torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3874 : #ifdef USING_EMBEDDED_HEIMDAL
3875 72 : torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
3876 72 : torture_assert_int_equal(tctx, ctx->counts.ok, 1, assertion_message);
3877 : #else
3878 0 : torture_assert_int_equal(tctx, ctx->counts.io, 2, assertion_message);
3879 0 : torture_assert_int_equal(tctx, ctx->counts.ok, 2, assertion_message);
3880 : #endif
3881 :
3882 72 : k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
3883 72 : ctx->krbtgt_trust_dns_creds->server,
3884 : #ifdef USING_EMBEDDED_HEIMDAL
3885 72 : ctx->krbtgt_trust_dns);
3886 : #else
3887 0 : ctx->krbtgt_trust_realm);
3888 : #endif
3889 72 : torture_assert(tctx, k5ok, assertion_message);
3890 72 : type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
3891 72 : ctx->krbtgt_trust_dns_creds->server);
3892 72 : torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
3893 :
3894 : /* Confirm if we have the referral ticket in the cache */
3895 72 : krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
3896 : &ctx->krbtgt_referral_creds);
3897 72 : k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
3898 : ctx->krbtgt_ccache,
3899 : 0,
3900 72 : ctx->krbtgt_trust_realm_creds,
3901 : &ctx->krbtgt_referral_creds);
3902 72 : assertion_message = talloc_asprintf(ctx,
3903 : "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
3904 : krbtgt_trust_realm_string,
3905 : k5ret,
3906 72 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3907 : k5ret, ctx));
3908 : #ifdef USING_EMBEDDED_HEIMDAL
3909 72 : torture_assert_int_equal(tctx, k5ret, KRB5_CC_END, assertion_message);
3910 : #else
3911 0 : torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3912 :
3913 0 : k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
3914 0 : ctx->krbtgt_referral_creds.server,
3915 0 : ctx->krbtgt_trust_realm);
3916 0 : torture_assert(tctx, k5ok, assertion_message);
3917 0 : type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
3918 0 : ctx->krbtgt_referral_creds.server);
3919 0 : torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
3920 :
3921 : /* Delete the referral ticket from the cache */
3922 0 : k5ret = krb5_cc_remove_cred(ctx->smb_krb5_context->krb5_context,
3923 : ctx->krbtgt_ccache,
3924 : 0,
3925 : &ctx->krbtgt_referral_creds);
3926 0 : assertion_message = talloc_asprintf(ctx,
3927 : "krb5_cc_remove_cred(%s) for failed: (%d) %s",
3928 : krbtgt_trust_realm_string,
3929 : k5ret,
3930 0 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3931 : k5ret, ctx));
3932 0 : torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3933 : #endif
3934 :
3935 : /* Confirm if we can do a TGS for krbtgt/NETBIOS with CANON */
3936 72 : ZERO_STRUCT(ctx->counts);
3937 72 : k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
3938 : ctx->opt_canon,
3939 : ctx->krbtgt_ccache,
3940 72 : ctx->krbtgt_trust_netbios,
3941 : &ctx->krbtgt_trust_netbios_creds);
3942 72 : assertion_message = talloc_asprintf(ctx,
3943 : "krb5_get_creds(%s, canon) for failed: "
3944 : "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
3945 : krbtgt_trust_netbios_string,
3946 : k5ret,
3947 72 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3948 : k5ret, ctx),
3949 72 : trusted->trust_direction,
3950 72 : trusted->trust_type,
3951 72 : trusted->trust_attributes,
3952 : ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
3953 : #ifdef USING_EMBEDDED_HEIMDAL
3954 72 : torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3955 : #else
3956 0 : torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
3957 : #endif
3958 72 : torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
3959 72 : torture_assert_int_equal(tctx, ctx->counts.ok, 1, assertion_message);
3960 :
3961 : /* Confirm if we have the referral ticket in the cache */
3962 72 : krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
3963 : &ctx->krbtgt_referral_creds);
3964 72 : k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
3965 : ctx->krbtgt_ccache,
3966 : 0,
3967 72 : ctx->krbtgt_trust_realm_creds,
3968 : &ctx->krbtgt_referral_creds);
3969 72 : assertion_message = talloc_asprintf(ctx,
3970 : "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
3971 : krbtgt_trust_netbios_string,
3972 : k5ret,
3973 72 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3974 : k5ret, ctx));
3975 : #ifdef USING_EMBEDDED_HEIMDAL
3976 72 : torture_assert_int_equal(tctx, k5ret, KRB5_CC_END, assertion_message);
3977 : #else
3978 0 : torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3979 :
3980 0 : k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
3981 0 : ctx->krbtgt_referral_creds.server,
3982 0 : ctx->krbtgt_trust_realm);
3983 0 : torture_assert(tctx, k5ok, assertion_message);
3984 0 : type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
3985 0 : ctx->krbtgt_referral_creds.server);
3986 0 : torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
3987 :
3988 : /* Delete the referral ticket from the cache */
3989 0 : k5ret = krb5_cc_remove_cred(ctx->smb_krb5_context->krb5_context,
3990 : ctx->krbtgt_ccache,
3991 : 0,
3992 : &ctx->krbtgt_referral_creds);
3993 0 : assertion_message = talloc_asprintf(ctx,
3994 : "krb5_cc_remove_cred(%s) for failed: (%d) %s",
3995 : krbtgt_trust_realm_string,
3996 : k5ret,
3997 0 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3998 : k5ret, ctx));
3999 0 : torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
4000 : #endif
4001 :
4002 : /* Confirm if we can do a TGS for krbtgt/NETBIOS no CANON */
4003 72 : ZERO_STRUCT(ctx->counts);
4004 72 : k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
4005 : ctx->opt_nocanon,
4006 : ctx->krbtgt_ccache,
4007 72 : ctx->krbtgt_trust_netbios,
4008 : &ctx->krbtgt_trust_netbios_creds);
4009 72 : assertion_message = talloc_asprintf(ctx,
4010 : "krb5_get_creds(%s, nocanon) for failed: "
4011 : "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
4012 : krbtgt_trust_netbios_string,
4013 : k5ret,
4014 72 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
4015 : k5ret, ctx),
4016 72 : trusted->trust_direction,
4017 72 : trusted->trust_type,
4018 72 : trusted->trust_attributes,
4019 : ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
4020 72 : torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
4021 : #ifdef USING_EMBEDDED_HEIMDAL
4022 72 : torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
4023 72 : torture_assert_int_equal(tctx, ctx->counts.ok, 1, assertion_message);
4024 : #else
4025 0 : torture_assert_int_equal(tctx, ctx->counts.io, 2, assertion_message);
4026 0 : torture_assert_int_equal(tctx, ctx->counts.ok, 2, assertion_message);
4027 : #endif
4028 :
4029 72 : k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
4030 72 : ctx->krbtgt_trust_netbios_creds->server,
4031 : #ifdef USING_EMBEDDED_HEIMDAL
4032 72 : ctx->krbtgt_trust_netbios);
4033 : #else
4034 0 : ctx->krbtgt_trust_realm);
4035 : #endif
4036 72 : torture_assert(tctx, k5ok, assertion_message);
4037 72 : type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
4038 72 : ctx->krbtgt_trust_netbios_creds->server);
4039 72 : torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
4040 :
4041 : /* Confirm if we have the referral ticket in the cache */
4042 72 : krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
4043 : &ctx->krbtgt_referral_creds);
4044 72 : k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
4045 : ctx->krbtgt_ccache,
4046 : 0,
4047 72 : ctx->krbtgt_trust_realm_creds,
4048 : &ctx->krbtgt_referral_creds);
4049 72 : assertion_message = talloc_asprintf(ctx,
4050 : "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
4051 : krbtgt_trust_realm_string,
4052 : k5ret,
4053 72 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
4054 : k5ret, ctx));
4055 : #ifdef USING_EMBEDDED_HEIMDAL
4056 72 : torture_assert_int_equal(tctx, k5ret, KRB5_CC_END, assertion_message);
4057 : #else
4058 0 : torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
4059 :
4060 0 : k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
4061 0 : ctx->krbtgt_referral_creds.server,
4062 0 : ctx->krbtgt_trust_realm);
4063 0 : torture_assert(tctx, k5ok, assertion_message);
4064 0 : type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
4065 0 : ctx->krbtgt_referral_creds.server);
4066 0 : torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
4067 :
4068 : /* Delete the referral ticket from the cache */
4069 0 : k5ret = krb5_cc_remove_cred(ctx->smb_krb5_context->krb5_context,
4070 : ctx->krbtgt_ccache,
4071 : 0,
4072 : &ctx->krbtgt_referral_creds);
4073 0 : assertion_message = talloc_asprintf(ctx,
4074 : "krb5_cc_remove_cred(%s) for failed: (%d) %s",
4075 : krbtgt_trust_realm_string,
4076 : k5ret,
4077 0 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
4078 : k5ret, ctx));
4079 0 : torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
4080 : #endif
4081 :
4082 72 : cifs_trust_dns_string = talloc_asprintf(ctx, "cifs/%s@%s",
4083 : trusted_dns_name, realm);
4084 72 : torture_assert_int_equal(tctx,
4085 : smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
4086 : &ctx->cifs_trust_dns,
4087 : realm, "cifs",
4088 : trusted_dns_name, NULL),
4089 : 0, "smb_krb5_make_principal failed");
4090 :
4091 : /* Confirm if we get krbtgt/trusted_realm back when asking for cifs/trusted_realm */
4092 72 : ZERO_STRUCT(ctx->counts);
4093 72 : k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
4094 : ctx->opt_canon,
4095 : ctx->krbtgt_ccache,
4096 72 : ctx->cifs_trust_dns,
4097 : &ctx->cifs_trust_dns_creds);
4098 72 : assertion_message = talloc_asprintf(ctx,
4099 : "krb5_get_creds(%s) for failed: (%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
4100 : cifs_trust_dns_string,
4101 : k5ret,
4102 72 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
4103 : k5ret, ctx),
4104 72 : trusted->trust_direction,
4105 72 : trusted->trust_type,
4106 72 : trusted->trust_attributes,
4107 : ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
4108 72 : torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
4109 : #ifdef USING_EMBEDDED_HEIMDAL
4110 72 : torture_assert_int_equal(tctx, ctx->counts.io, 2, assertion_message);
4111 72 : torture_assert_int_equal(tctx, ctx->counts.ok, 2, assertion_message);
4112 : #else
4113 0 : torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
4114 0 : torture_assert_int_equal(tctx, ctx->counts.ok, 1, assertion_message);
4115 : #endif
4116 :
4117 : /* Confirm if we have the referral ticket in the cache */
4118 72 : krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
4119 : &ctx->krbtgt_referral_creds);
4120 72 : k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
4121 : ctx->krbtgt_ccache,
4122 : 0,
4123 72 : ctx->krbtgt_trust_realm_creds,
4124 : &ctx->krbtgt_referral_creds);
4125 72 : assertion_message = talloc_asprintf(ctx,
4126 : "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
4127 : krbtgt_trust_realm_string,
4128 : k5ret,
4129 72 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
4130 : k5ret, ctx));
4131 : #ifdef USING_EMBEDDED_HEIMDAL
4132 72 : torture_assert_int_equal(tctx, k5ret, KRB5_CC_END, assertion_message);
4133 : #else
4134 0 : torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
4135 :
4136 0 : k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
4137 0 : ctx->krbtgt_referral_creds.server,
4138 0 : ctx->krbtgt_trust_realm);
4139 0 : torture_assert(tctx, k5ok, assertion_message);
4140 0 : type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
4141 0 : ctx->krbtgt_referral_creds.server);
4142 0 : torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
4143 :
4144 : /* Delete the referral ticket from the cache */
4145 0 : k5ret = krb5_cc_remove_cred(ctx->smb_krb5_context->krb5_context,
4146 : ctx->krbtgt_ccache,
4147 : 0,
4148 : &ctx->krbtgt_referral_creds);
4149 0 : assertion_message = talloc_asprintf(ctx,
4150 : "krb5_cc_remove_cred(%s) for failed: (%d) %s",
4151 : krbtgt_trust_realm_string,
4152 : k5ret,
4153 0 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
4154 : k5ret, ctx));
4155 0 : torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
4156 : #endif
4157 :
4158 72 : cifs_trust_netbios_string = talloc_asprintf(ctx, "cifs/%s@%s",
4159 : trusted_netbios_name, realm);
4160 72 : torture_assert_int_equal(tctx,
4161 : smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
4162 : &ctx->cifs_trust_netbios,
4163 : realm, "cifs",
4164 : trusted_netbios_name, NULL),
4165 : 0, "smb_krb5_make_principal failed");
4166 :
4167 : /* Confirm if we get krbtgt/trusted_realm back when asking for cifs/trusted_realm */
4168 72 : ZERO_STRUCT(ctx->counts);
4169 72 : k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
4170 : ctx->opt_canon,
4171 : ctx->krbtgt_ccache,
4172 72 : ctx->cifs_trust_netbios,
4173 : &ctx->cifs_trust_netbios_creds);
4174 72 : assertion_message = talloc_asprintf(ctx,
4175 : "krb5_get_creds(%s) for failed: (%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
4176 : cifs_trust_netbios_string,
4177 : k5ret,
4178 72 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
4179 : k5ret, ctx),
4180 72 : trusted->trust_direction,
4181 72 : trusted->trust_type,
4182 72 : trusted->trust_attributes,
4183 : ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
4184 72 : torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
4185 : #ifdef USING_EMBEDDED_HEIMDAL
4186 72 : torture_assert_int_equal(tctx, ctx->counts.io, 2, assertion_message);
4187 72 : torture_assert_int_equal(tctx, ctx->counts.ok, 2, assertion_message);
4188 : #else
4189 0 : torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
4190 0 : torture_assert_int_equal(tctx, ctx->counts.ok, 1, assertion_message);
4191 : #endif
4192 :
4193 : /* Confirm if we have the referral ticket in the cache */
4194 72 : krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
4195 : &ctx->krbtgt_referral_creds);
4196 72 : k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
4197 : ctx->krbtgt_ccache,
4198 : 0,
4199 72 : ctx->krbtgt_trust_realm_creds,
4200 : &ctx->krbtgt_referral_creds);
4201 72 : assertion_message = talloc_asprintf(ctx,
4202 : "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
4203 : krbtgt_trust_realm_string,
4204 : k5ret,
4205 72 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
4206 : k5ret, ctx));
4207 : #ifdef USING_EMBEDDED_HEIMDAL
4208 72 : torture_assert_int_equal(tctx, k5ret, KRB5_CC_END, assertion_message);
4209 : #else
4210 0 : torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
4211 :
4212 0 : k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
4213 0 : ctx->krbtgt_referral_creds.server,
4214 0 : ctx->krbtgt_trust_realm);
4215 0 : torture_assert(tctx, k5ok, assertion_message);
4216 0 : type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
4217 0 : ctx->krbtgt_referral_creds.server);
4218 0 : torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
4219 :
4220 : /* Delete the referral ticket from the cache */
4221 0 : k5ret = krb5_cc_remove_cred(ctx->smb_krb5_context->krb5_context,
4222 : ctx->krbtgt_ccache,
4223 : 0,
4224 : &ctx->krbtgt_referral_creds);
4225 0 : assertion_message = talloc_asprintf(ctx,
4226 : "krb5_cc_remove_cred(%s) for failed: (%d) %s",
4227 : krbtgt_trust_realm_string,
4228 : k5ret,
4229 0 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
4230 : k5ret, ctx));
4231 0 : torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
4232 : #endif
4233 :
4234 72 : drs_trust_dns_string = talloc_asprintf(ctx,
4235 : "E3514235-4B06-11D1-AB04-00C04FC2DCD2/%s/%s@%s",
4236 : workstation, trusted_dns_name, realm);
4237 72 : torture_assert_int_equal(tctx,
4238 : smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
4239 : &ctx->drs_trust_dns,
4240 : realm, "E3514235-4B06-11D1-AB04-00C04FC2DCD2",
4241 : workstation, trusted_dns_name, NULL),
4242 : 0, "smb_krb5_make_principal failed");
4243 :
4244 : /* Confirm if we get krbtgt/trusted_realm back when asking for a 3 part principal */
4245 72 : ZERO_STRUCT(ctx->counts);
4246 72 : k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
4247 : ctx->opt_canon,
4248 : ctx->krbtgt_ccache,
4249 72 : ctx->drs_trust_dns,
4250 : &ctx->drs_trust_dns_creds);
4251 72 : assertion_message = talloc_asprintf(ctx,
4252 : "krb5_get_creds(%s) for failed: (%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
4253 : drs_trust_dns_string,
4254 : k5ret,
4255 72 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
4256 : k5ret, ctx),
4257 72 : trusted->trust_direction,
4258 72 : trusted->trust_type,
4259 72 : trusted->trust_attributes,
4260 : ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
4261 72 : torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
4262 : #ifdef USING_EMBEDDED_HEIMDAL
4263 72 : torture_assert_int_equal(tctx, ctx->counts.io, 2, assertion_message);
4264 72 : torture_assert_int_equal(tctx, ctx->counts.ok, 2, assertion_message);
4265 : #else
4266 0 : torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
4267 0 : torture_assert_int_equal(tctx, ctx->counts.ok, 1, assertion_message);
4268 : #endif
4269 :
4270 : /* Confirm if we have the referral ticket in the cache */
4271 72 : krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
4272 : &ctx->krbtgt_referral_creds);
4273 72 : k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
4274 : ctx->krbtgt_ccache,
4275 : 0,
4276 72 : ctx->krbtgt_trust_realm_creds,
4277 : &ctx->krbtgt_referral_creds);
4278 72 : assertion_message = talloc_asprintf(ctx,
4279 : "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
4280 : krbtgt_trust_realm_string,
4281 : k5ret,
4282 72 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
4283 : k5ret, ctx));
4284 : #ifdef USING_EMBEDDED_HEIMDAL
4285 72 : torture_assert_int_equal(tctx, k5ret, KRB5_CC_END, assertion_message);
4286 : #else
4287 0 : torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
4288 :
4289 0 : k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
4290 0 : ctx->krbtgt_referral_creds.server,
4291 0 : ctx->krbtgt_trust_realm);
4292 0 : torture_assert(tctx, k5ok, assertion_message);
4293 0 : type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
4294 0 : ctx->krbtgt_referral_creds.server);
4295 0 : torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
4296 :
4297 : /* Delete the referral ticket from the cache */
4298 0 : k5ret = krb5_cc_remove_cred(ctx->smb_krb5_context->krb5_context,
4299 : ctx->krbtgt_ccache,
4300 : 0,
4301 : &ctx->krbtgt_referral_creds);
4302 0 : assertion_message = talloc_asprintf(ctx,
4303 : "krb5_cc_remove_cred(%s) for failed: (%d) %s",
4304 : krbtgt_trust_realm_string,
4305 : k5ret,
4306 0 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
4307 : k5ret, ctx));
4308 0 : torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
4309 : #endif
4310 :
4311 72 : drs_trust_netbios_string = talloc_asprintf(ctx,
4312 : "E3514235-4B06-11D1-AB04-00C04FC2DCD2/%s/%s@%s",
4313 : workstation, trusted_netbios_name, realm);
4314 72 : torture_assert_int_equal(tctx,
4315 : smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
4316 : &ctx->drs_trust_netbios,
4317 : realm, "E3514235-4B06-11D1-AB04-00C04FC2DCD2",
4318 : workstation, trusted_netbios_name, NULL),
4319 : 0, "smb_krb5_make_principal failed");
4320 :
4321 : /* Confirm if we get krbtgt/trusted_realm back when asking for a 3 part principal */
4322 72 : ZERO_STRUCT(ctx->counts);
4323 72 : k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
4324 : ctx->opt_canon,
4325 : ctx->krbtgt_ccache,
4326 72 : ctx->drs_trust_netbios,
4327 : &ctx->drs_trust_netbios_creds);
4328 72 : assertion_message = talloc_asprintf(ctx,
4329 : "krb5_get_creds(%s) for failed: (%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
4330 : drs_trust_netbios_string,
4331 : k5ret,
4332 72 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
4333 : k5ret, ctx),
4334 72 : trusted->trust_direction,
4335 72 : trusted->trust_type,
4336 72 : trusted->trust_attributes,
4337 : ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
4338 72 : torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
4339 : #ifdef USING_EMBEDDED_HEIMDAL
4340 72 : torture_assert_int_equal(tctx, ctx->counts.io, 2, assertion_message);
4341 72 : torture_assert_int_equal(tctx, ctx->counts.ok, 2, assertion_message);
4342 : #else
4343 0 : torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
4344 0 : torture_assert_int_equal(tctx, ctx->counts.ok, 1, assertion_message);
4345 : #endif
4346 :
4347 : /* Confirm if we have the referral ticket in the cache */
4348 72 : krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
4349 : &ctx->krbtgt_referral_creds);
4350 72 : k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
4351 : ctx->krbtgt_ccache,
4352 : 0,
4353 72 : ctx->krbtgt_trust_realm_creds,
4354 : &ctx->krbtgt_referral_creds);
4355 72 : assertion_message = talloc_asprintf(ctx,
4356 : "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
4357 : krbtgt_trust_realm_string,
4358 : k5ret,
4359 72 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
4360 : k5ret, ctx));
4361 : #ifdef USING_EMBEDDED_HEIMDAL
4362 72 : torture_assert_int_equal(tctx, k5ret, KRB5_CC_END, assertion_message);
4363 : #else
4364 0 : torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
4365 :
4366 0 : k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
4367 0 : ctx->krbtgt_referral_creds.server,
4368 0 : ctx->krbtgt_trust_realm);
4369 0 : torture_assert(tctx, k5ok, assertion_message);
4370 0 : type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
4371 0 : ctx->krbtgt_referral_creds.server);
4372 0 : torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
4373 :
4374 : /* Delete the referral ticket from the cache */
4375 0 : k5ret = krb5_cc_remove_cred(ctx->smb_krb5_context->krb5_context,
4376 : ctx->krbtgt_ccache,
4377 : 0,
4378 : &ctx->krbtgt_referral_creds);
4379 0 : assertion_message = talloc_asprintf(ctx,
4380 : "krb5_cc_remove_cred(%s) for failed: (%d) %s",
4381 : krbtgt_trust_realm_string,
4382 : k5ret,
4383 0 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
4384 : k5ret, ctx));
4385 0 : torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
4386 : #endif
4387 :
4388 72 : four_trust_dns_string = talloc_asprintf(ctx, "four/tree/two/%s@%s",
4389 : trusted_dns_name, realm);
4390 72 : torture_assert_int_equal(tctx,
4391 : smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
4392 : &ctx->four_trust_dns,
4393 : realm, "four", "tree", "two",
4394 : trusted_dns_name, NULL),
4395 : 0, "smb_krb5_make_principal failed");
4396 :
4397 : /* Confirm if we get an error back for a 4 part principal */
4398 72 : ZERO_STRUCT(ctx->counts);
4399 72 : k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
4400 : ctx->opt_canon,
4401 : ctx->krbtgt_ccache,
4402 72 : ctx->four_trust_dns,
4403 : &ctx->four_trust_dns_creds);
4404 72 : assertion_message = talloc_asprintf(ctx,
4405 : "krb5_get_creds(%s) for failed: (%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
4406 : four_trust_dns_string,
4407 : k5ret,
4408 72 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
4409 : k5ret, ctx),
4410 72 : trusted->trust_direction,
4411 72 : trusted->trust_type,
4412 72 : trusted->trust_attributes,
4413 : ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
4414 72 : torture_assert_int_equal(tctx, k5ret, KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN, assertion_message);
4415 : #ifdef USING_EMBEDDED_HEIMDAL
4416 72 : torture_assert_int_equal(tctx, ctx->counts.io, 2, assertion_message);
4417 72 : torture_assert_int_equal(tctx, ctx->counts.error_io, 2, assertion_message);
4418 : #else
4419 0 : torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
4420 0 : torture_assert_int_equal(tctx, ctx->counts.error_io, 1, assertion_message);
4421 : #endif
4422 72 : torture_assert_int_equal(tctx, KRB5_ERROR_CODE(&ctx->error), 7, assertion_message);
4423 :
4424 : /* Confirm if we have no referral ticket in the cache */
4425 72 : krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
4426 : &ctx->krbtgt_referral_creds);
4427 72 : k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
4428 : ctx->krbtgt_ccache,
4429 : 0,
4430 72 : ctx->krbtgt_trust_realm_creds,
4431 : &ctx->krbtgt_referral_creds);
4432 72 : assertion_message = talloc_asprintf(ctx,
4433 : "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
4434 : krbtgt_trust_realm_string,
4435 : k5ret,
4436 72 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
4437 : k5ret, ctx));
4438 72 : torture_assert_int_equal(tctx, k5ret, KRB5_CC_END, assertion_message);
4439 :
4440 72 : TALLOC_FREE(ctx);
4441 72 : return true;
4442 : }
4443 : #endif
4444 :
4445 72 : static bool check_dom_trust_pw(struct dcerpc_pipe *p,
4446 : struct torture_context *tctx,
4447 : const char *our_netbios_name,
4448 : const char *our_dns_name,
4449 : enum netr_SchannelType secure_channel_type,
4450 : const struct lsa_TrustDomainInfoInfoEx *trusted,
4451 : const char *previous_password,
4452 : const char *current_password,
4453 : uint32_t current_version,
4454 : const char *next_password,
4455 : uint32_t next_version,
4456 : bool expected_result)
4457 : {
4458 0 : struct cli_credentials *incoming_creds;
4459 72 : char *server_name = NULL;
4460 72 : char *account = NULL;
4461 72 : char *principal = NULL;
4462 72 : char *workstation = NULL;
4463 72 : const char *binding = torture_setting_string(tctx, "binding", NULL);
4464 72 : const char *host = torture_setting_string(tctx, "host", NULL);
4465 0 : const char *ip;
4466 0 : struct nbt_name nbt_name;
4467 0 : struct dcerpc_binding *b2;
4468 0 : struct netlogon_creds_CredentialState *creds;
4469 0 : struct samr_CryptPassword samr_crypt_password;
4470 0 : struct netr_CryptPassword netr_crypt_password;
4471 0 : struct netr_Authenticator req_auth;
4472 0 : struct netr_Authenticator rep_auth;
4473 0 : struct netr_ServerPasswordSet2 s;
4474 72 : struct dcerpc_pipe *p1 = NULL;
4475 72 : struct dcerpc_pipe *p2 = NULL;
4476 0 : NTSTATUS status;
4477 0 : bool ok;
4478 0 : int rc;
4479 72 : const char *trusted_netbios_name = trusted->netbios_name.string;
4480 72 : const char *trusted_dns_name = trusted->domain_name.string;
4481 0 : struct tsocket_address *dest_addr;
4482 0 : struct cldap_socket *cldap;
4483 0 : struct cldap_netlogon cldap1;
4484 :
4485 72 : incoming_creds = cli_credentials_init(tctx);
4486 72 : torture_assert(tctx, incoming_creds, "cli_credentials_init");
4487 :
4488 72 : cli_credentials_set_domain(incoming_creds, our_netbios_name, CRED_SPECIFIED);
4489 72 : cli_credentials_set_realm(incoming_creds, our_dns_name, CRED_SPECIFIED);
4490 :
4491 72 : if (secure_channel_type == SEC_CHAN_DNS_DOMAIN) {
4492 36 : account = talloc_asprintf(tctx, "%s.", trusted_dns_name);
4493 36 : torture_assert(tctx, account, __location__);
4494 :
4495 36 : principal = talloc_asprintf(tctx, "%s$@%s",
4496 : trusted_netbios_name,
4497 : cli_credentials_get_realm(incoming_creds));
4498 36 : torture_assert(tctx, principal, __location__);
4499 :
4500 36 : workstation = talloc_asprintf(tctx, "%sUP",
4501 : trusted_netbios_name);
4502 36 : torture_assert(tctx, workstation, __location__);
4503 : } else {
4504 36 : account = talloc_asprintf(tctx, "%s$", trusted_netbios_name);
4505 36 : torture_assert(tctx, account, __location__);
4506 :
4507 36 : workstation = talloc_asprintf(tctx, "%sDOWN",
4508 : trusted_netbios_name);
4509 36 : torture_assert(tctx, workstation, __location__);
4510 : }
4511 :
4512 72 : cli_credentials_set_username(incoming_creds, account, CRED_SPECIFIED);
4513 72 : if (principal != NULL) {
4514 36 : cli_credentials_set_principal(incoming_creds, principal,
4515 : CRED_SPECIFIED);
4516 : }
4517 72 : cli_credentials_set_kvno(incoming_creds, current_version);
4518 72 : cli_credentials_set_password(incoming_creds, current_password, CRED_SPECIFIED);
4519 72 : cli_credentials_set_old_password(incoming_creds, previous_password, CRED_SPECIFIED);
4520 72 : cli_credentials_set_workstation(incoming_creds, workstation, CRED_SPECIFIED);
4521 72 : cli_credentials_set_secure_channel_type(incoming_creds, secure_channel_type);
4522 :
4523 72 : make_nbt_name_server(&nbt_name, host);
4524 :
4525 72 : status = resolve_name_ex(lpcfg_resolve_context(tctx->lp_ctx),
4526 : 0, 0, &nbt_name, tctx, &ip, tctx->ev);
4527 72 : torture_assert_ntstatus_ok(tctx, status,
4528 : talloc_asprintf(tctx,"Failed to resolve %s: %s",
4529 : nbt_name.name, nt_errstr(status)));
4530 :
4531 72 : rc = tsocket_address_inet_from_strings(tctx, "ip",
4532 : ip,
4533 : lpcfg_cldap_port(tctx->lp_ctx),
4534 : &dest_addr);
4535 72 : torture_assert_int_equal(tctx, rc, 0,
4536 : talloc_asprintf(tctx,
4537 : "tsocket_address_inet_from_strings failed parsing %s:%d",
4538 : host, lpcfg_cldap_port(tctx->lp_ctx)));
4539 :
4540 : /* cldap_socket_init should now know about the dest. address */
4541 72 : status = cldap_socket_init(tctx, NULL, dest_addr, &cldap);
4542 72 : torture_assert_ntstatus_ok(tctx, status, "cldap_socket_init");
4543 :
4544 72 : ZERO_STRUCT(cldap1);
4545 72 : cldap1.in.dest_address = NULL;
4546 72 : cldap1.in.dest_port = 0;
4547 72 : cldap1.in.version = NETLOGON_NT_VERSION_5 | NETLOGON_NT_VERSION_5EX;
4548 72 : cldap1.in.user = account;
4549 72 : if (secure_channel_type == SEC_CHAN_DNS_DOMAIN) {
4550 36 : cldap1.in.acct_control = ACB_AUTOLOCK;
4551 : } else {
4552 36 : cldap1.in.acct_control = ACB_DOMTRUST;
4553 : }
4554 72 : status = cldap_netlogon(cldap, tctx, &cldap1);
4555 72 : torture_assert_ntstatus_ok(tctx, status, "cldap_netlogon");
4556 72 : torture_assert_int_equal(tctx, cldap1.out.netlogon.ntver,
4557 : NETLOGON_NT_VERSION_5EX,
4558 : "ntver");
4559 72 : torture_assert_int_equal(tctx, cldap1.out.netlogon.data.nt5_ex.nt_version,
4560 : NETLOGON_NT_VERSION_1 | NETLOGON_NT_VERSION_5EX,
4561 : "nt_version");
4562 72 : torture_assert_int_equal(tctx, cldap1.out.netlogon.data.nt5_ex.command,
4563 : LOGON_SAM_LOGON_RESPONSE_EX,
4564 : "command");
4565 72 : torture_assert_str_equal(tctx, cldap1.out.netlogon.data.nt5_ex.user_name,
4566 : cldap1.in.user,
4567 : "user_name");
4568 72 : server_name = talloc_asprintf(tctx, "\\\\%s",
4569 : cldap1.out.netlogon.data.nt5_ex.pdc_dns_name);
4570 72 : torture_assert(tctx, server_name, __location__);
4571 :
4572 72 : status = dcerpc_parse_binding(tctx, binding, &b2);
4573 72 : torture_assert_ntstatus_ok(tctx, status, "Bad binding string");
4574 :
4575 72 : status = dcerpc_pipe_connect_b(tctx, &p1, b2,
4576 : &ndr_table_netlogon,
4577 : cli_credentials_init_anon(tctx),
4578 : tctx->ev, tctx->lp_ctx);
4579 72 : torture_assert_ntstatus_ok(tctx, status, "dcerpc_pipe_connect_b");
4580 :
4581 72 : ok = check_pw_with_ServerAuthenticate3(p1, tctx,
4582 : NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES,
4583 : server_name,
4584 : incoming_creds, &creds);
4585 72 : torture_assert_int_equal(tctx, ok, expected_result,
4586 : "check_pw_with_ServerAuthenticate3");
4587 72 : if (expected_result == true) {
4588 54 : ok = test_SetupCredentialsPipe(p1, tctx, incoming_creds, creds,
4589 : DCERPC_SIGN | DCERPC_SEAL, &p2);
4590 54 : torture_assert_int_equal(tctx, ok, true,
4591 : "test_SetupCredentialsPipe");
4592 : }
4593 72 : TALLOC_FREE(p1);
4594 :
4595 72 : if (trusted->trust_type != LSA_TRUST_TYPE_DOWNLEVEL) {
4596 : #ifdef SAMBA4_USES_HEIMDAL
4597 48 : ok = check_pw_with_krb5(tctx, incoming_creds, trusted);
4598 48 : torture_assert_int_equal(tctx, ok, expected_result,
4599 : "check_pw_with_krb5");
4600 : #else
4601 0 : torture_comment(tctx, "skipping check_pw_with_krb5 for MIT Kerberos build");
4602 : #endif
4603 : }
4604 :
4605 72 : if (expected_result != true || next_password == NULL) {
4606 18 : TALLOC_FREE(p2);
4607 18 : return true;
4608 : }
4609 :
4610 : /*
4611 : * netr_ServerPasswordSet2
4612 : */
4613 54 : ok = encode_pw_buffer(samr_crypt_password.data,
4614 : next_password, STR_UNICODE);
4615 54 : torture_assert(tctx, ok, "encode_pw_buffer");
4616 :
4617 54 : if (next_version != 0) {
4618 0 : struct NL_PASSWORD_VERSION version;
4619 54 : uint32_t len = IVAL(samr_crypt_password.data, 512);
4620 54 : uint32_t ofs = 512 - len;
4621 0 : uint8_t *ptr;
4622 :
4623 54 : ofs -= 12;
4624 :
4625 54 : version.ReservedField = 0;
4626 54 : version.PasswordVersionNumber = next_version;
4627 54 : version.PasswordVersionPresent =
4628 : NETLOGON_PASSWORD_VERSION_NUMBER_PRESENT;
4629 :
4630 54 : ptr = samr_crypt_password.data + ofs;
4631 54 : SIVAL(ptr, 0, version.ReservedField);
4632 54 : SIVAL(ptr, 4, version.PasswordVersionNumber);
4633 54 : SIVAL(ptr, 8, version.PasswordVersionPresent);
4634 : }
4635 :
4636 54 : netlogon_creds_client_authenticator(creds, &req_auth);
4637 54 : ZERO_STRUCT(rep_auth);
4638 :
4639 54 : if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
4640 54 : netlogon_creds_aes_encrypt(creds,
4641 : samr_crypt_password.data,
4642 : 516);
4643 : } else {
4644 0 : netlogon_creds_arcfour_crypt(creds,
4645 : samr_crypt_password.data,
4646 : 516);
4647 : }
4648 :
4649 54 : memcpy(netr_crypt_password.data,
4650 : samr_crypt_password.data, 512);
4651 54 : netr_crypt_password.length = IVAL(samr_crypt_password.data, 512);
4652 :
4653 :
4654 54 : s.in.server_name = server_name;
4655 54 : s.in.account_name = cli_credentials_get_username(incoming_creds);
4656 54 : s.in.secure_channel_type = cli_credentials_get_secure_channel_type(incoming_creds);
4657 54 : s.in.computer_name = cli_credentials_get_workstation(incoming_creds);
4658 54 : s.in.credential = &req_auth;
4659 54 : s.in.new_password = &netr_crypt_password;
4660 54 : s.out.return_authenticator = &rep_auth;
4661 54 : status = dcerpc_netr_ServerPasswordSet2_r(p2->binding_handle, tctx, &s);
4662 54 : torture_assert_ntstatus_ok(tctx, status, "failed to set password");
4663 :
4664 54 : ok = netlogon_creds_client_check(creds, &rep_auth.cred);
4665 54 : torture_assert(tctx, ok, "netlogon_creds_client_check");
4666 :
4667 54 : cli_credentials_set_kvno(incoming_creds, next_version);
4668 54 : cli_credentials_set_password(incoming_creds, next_password, CRED_SPECIFIED);
4669 54 : cli_credentials_set_old_password(incoming_creds, current_password, CRED_SPECIFIED);
4670 :
4671 54 : TALLOC_FREE(p2);
4672 54 : status = dcerpc_pipe_connect_b(tctx, &p2, b2,
4673 : &ndr_table_netlogon,
4674 : cli_credentials_init_anon(tctx),
4675 : tctx->ev, tctx->lp_ctx);
4676 54 : torture_assert_ntstatus_ok(tctx, status, "dcerpc_pipe_connect_b");
4677 :
4678 54 : ok = check_pw_with_ServerAuthenticate3(p2, tctx,
4679 : NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES,
4680 : server_name,
4681 : incoming_creds, &creds);
4682 54 : torture_assert(tctx, ok, "check_pw_with_ServerAuthenticate3 with changed password");
4683 :
4684 54 : if (trusted->trust_type != LSA_TRUST_TYPE_DOWNLEVEL) {
4685 : #if SAMBA4_USES_HEIMDAL
4686 36 : ok = check_pw_with_krb5(tctx, incoming_creds, trusted);
4687 36 : torture_assert(tctx, ok, "check_pw_with_krb5 with changed password");
4688 : #else
4689 0 : torture_comment(tctx, "skipping check_pw_with_krb5 for MIT Kerberos build");
4690 : #endif
4691 : }
4692 :
4693 54 : TALLOC_FREE(p2);
4694 54 : return true;
4695 : }
4696 :
4697 6 : static bool test_CreateTrustedDomainEx_common(struct dcerpc_pipe *p,
4698 : struct torture_context *tctx,
4699 : struct policy_handle *handle,
4700 : uint32_t num_trusts,
4701 : bool ex2_call)
4702 : {
4703 0 : NTSTATUS status;
4704 6 : bool ret = true;
4705 0 : struct lsa_QueryInfoPolicy2 p2;
4706 6 : union lsa_PolicyInformation *our_info = NULL;
4707 0 : struct lsa_CreateTrustedDomainEx r;
4708 0 : struct lsa_CreateTrustedDomainEx2 r2;
4709 0 : struct lsa_TrustDomainInfoInfoEx trustinfo;
4710 6 : struct lsa_TrustDomainInfoAuthInfoInternal *authinfo_internal = NULL;
4711 6 : struct lsa_TrustDomainInfoAuthInfo *authinfo = NULL;
4712 0 : struct dom_sid **domsid;
4713 0 : struct policy_handle *trustdom_handle;
4714 0 : struct lsa_QueryTrustedDomainInfo q;
4715 6 : union lsa_TrustedDomainInfo *info = NULL;
4716 0 : DATA_BLOB session_key;
4717 0 : int i;
4718 6 : struct dcerpc_binding_handle *b = p->binding_handle;
4719 0 : const char *id;
4720 6 : const char *incoming_v00 = TRUSTPW "InV00";
4721 6 : const char *incoming_v0 = TRUSTPW "InV0";
4722 6 : const char *incoming_v1 = TRUSTPW "InV1";
4723 6 : const char *incoming_v2 = TRUSTPW "InV2";
4724 6 : const char *incoming_v40 = TRUSTPW "InV40";
4725 6 : const char *outgoing_v00 = TRUSTPW "OutV00";
4726 6 : const char *outgoing_v0 = TRUSTPW "OutV0";
4727 :
4728 6 : if (ex2_call) {
4729 3 : torture_comment(tctx, "\nTesting CreateTrustedDomainEx2 for %d domains\n", num_trusts);
4730 3 : id = "3";
4731 : } else {
4732 3 : torture_comment(tctx, "\nTesting CreateTrustedDomainEx for %d domains\n", num_trusts);
4733 3 : id = "2";
4734 : }
4735 :
4736 6 : domsid = talloc_array(tctx, struct dom_sid *, num_trusts);
4737 6 : trustdom_handle = talloc_array(tctx, struct policy_handle, num_trusts);
4738 :
4739 6 : status = dcerpc_fetch_session_key(p, &session_key);
4740 6 : if (!NT_STATUS_IS_OK(status)) {
4741 0 : torture_comment(tctx, "dcerpc_fetch_session_key failed - %s\n", nt_errstr(status));
4742 0 : return false;
4743 : }
4744 :
4745 6 : ZERO_STRUCT(p2);
4746 6 : p2.in.handle = handle;
4747 6 : p2.in.level = LSA_POLICY_INFO_DNS;
4748 6 : p2.out.info = &our_info;
4749 :
4750 6 : torture_assert_ntstatus_ok(tctx,
4751 : dcerpc_lsa_QueryInfoPolicy2_r(b, tctx, &p2),
4752 : "lsa_QueryInfoPolicy2 failed");
4753 6 : torture_assert_ntstatus_ok(tctx, p2.out.result,
4754 : "lsa_QueryInfoPolicy2 failed");
4755 6 : torture_assert(tctx, our_info != NULL, "lsa_QueryInfoPolicy2 our_info");
4756 :
4757 78 : for (i=0; i< num_trusts; i++) {
4758 72 : char *trust_name = talloc_asprintf(tctx, "TORTURE%s%02d", id, i);
4759 72 : char *trust_name_dns = talloc_asprintf(tctx, "torturedom%s%02d.samba._none_.example.com", id, i);
4760 72 : char *trust_sid = talloc_asprintf(tctx, "S-1-5-21-97398-379795-%s%02d", id, i);
4761 0 : bool ok;
4762 :
4763 72 : domsid[i] = dom_sid_parse_talloc(tctx, trust_sid);
4764 :
4765 72 : trustinfo.sid = domsid[i];
4766 72 : trustinfo.netbios_name.string = trust_name;
4767 72 : trustinfo.domain_name.string = trust_name_dns;
4768 :
4769 : /* Create inbound, some outbound, and some
4770 : * bi-directional trusts in a repeating pattern based
4771 : * on i */
4772 :
4773 : /* 1 == inbound, 2 == outbound, 3 == both */
4774 72 : trustinfo.trust_direction = (i % 3) + 1;
4775 :
4776 : /* Try different trust types too */
4777 :
4778 : /* 1 == downlevel (NT4), 2 == uplevel (ADS), 3 == MIT (kerberos but not AD) */
4779 72 : trustinfo.trust_type = (((i / 3) + 1) % 3) + 1;
4780 :
4781 72 : trustinfo.trust_attributes = LSA_TRUST_ATTRIBUTE_USES_RC4_ENCRYPTION;
4782 :
4783 72 : ok = gen_authinfo_internal(tctx, incoming_v00, incoming_v0,
4784 : outgoing_v00, outgoing_v0,
4785 : session_key, &authinfo_internal);
4786 72 : if (!ok) {
4787 0 : torture_comment(tctx, "gen_authinfo_internal failed");
4788 0 : ret = false;
4789 : }
4790 :
4791 72 : ok = gen_authinfo(tctx, incoming_v00, incoming_v0,
4792 : outgoing_v00, outgoing_v0,
4793 : &authinfo);
4794 72 : if (!ok) {
4795 0 : torture_comment(tctx, "gen_authinfonfo failed");
4796 0 : ret = false;
4797 : }
4798 :
4799 72 : if (ex2_call) {
4800 :
4801 36 : r2.in.policy_handle = handle;
4802 36 : r2.in.info = &trustinfo;
4803 36 : r2.in.auth_info_internal = authinfo_internal;
4804 36 : r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4805 36 : r2.out.trustdom_handle = &trustdom_handle[i];
4806 :
4807 36 : torture_assert_ntstatus_ok(tctx,
4808 : dcerpc_lsa_CreateTrustedDomainEx2_r(b, tctx, &r2),
4809 : "CreateTrustedDomainEx2 failed");
4810 :
4811 36 : status = r2.out.result;
4812 : } else {
4813 :
4814 36 : r.in.policy_handle = handle;
4815 36 : r.in.info = &trustinfo;
4816 36 : r.in.auth_info = authinfo;
4817 36 : r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4818 36 : r.out.trustdom_handle = &trustdom_handle[i];
4819 :
4820 36 : torture_assert_ntstatus_ok(tctx,
4821 : dcerpc_lsa_CreateTrustedDomainEx_r(b, tctx, &r),
4822 : "CreateTrustedDomainEx failed");
4823 :
4824 36 : status = r.out.result;
4825 : }
4826 :
4827 72 : if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) {
4828 0 : test_DeleteTrustedDomain(b, tctx, handle, trustinfo.netbios_name);
4829 0 : if (ex2_call) {
4830 0 : torture_assert_ntstatus_ok(tctx,
4831 : dcerpc_lsa_CreateTrustedDomainEx2_r(b, tctx, &r2),
4832 : "CreateTrustedDomainEx2 failed");
4833 0 : status = r2.out.result;
4834 : } else {
4835 0 : torture_assert_ntstatus_ok(tctx,
4836 : dcerpc_lsa_CreateTrustedDomainEx_r(b, tctx, &r),
4837 : "CreateTrustedDomainEx2 failed");
4838 0 : status = r.out.result;
4839 : }
4840 : }
4841 72 : if (!NT_STATUS_IS_OK(status)) {
4842 0 : torture_comment(tctx, "CreateTrustedDomainEx failed2 - %s\n", nt_errstr(status));
4843 0 : ret = false;
4844 : } else {
4845 : /* For outbound and MIT trusts there is no trust account */
4846 72 : if (trustinfo.trust_direction != 2 &&
4847 48 : trustinfo.trust_type != 3) {
4848 :
4849 36 : if (torture_setting_bool(tctx, "samba3", false)) {
4850 0 : torture_comment(tctx, "skipping trusted domain auth tests against samba3\n");
4851 54 : } else if (ex2_call == false &&
4852 18 : torture_setting_bool(tctx, "samba4", false)) {
4853 18 : torture_comment(tctx, "skipping CreateTrustedDomainEx trusted domain auth tests against samba4\n");
4854 :
4855 : } else {
4856 18 : ok = check_dom_trust_pw(p, tctx,
4857 18 : our_info->dns.name.string,
4858 18 : our_info->dns.dns_domain.string,
4859 : SEC_CHAN_DOMAIN,
4860 : &trustinfo,
4861 : NULL,
4862 : "x" TRUSTPW "x", 0,
4863 : NULL, 0,
4864 : false);
4865 18 : if (!ok) {
4866 0 : torture_comment(tctx, "Password check passed unexpectedly\n");
4867 0 : ret = false;
4868 : }
4869 18 : ok = check_dom_trust_pw(p, tctx,
4870 18 : our_info->dns.name.string,
4871 18 : our_info->dns.dns_domain.string,
4872 : SEC_CHAN_DOMAIN,
4873 : &trustinfo,
4874 : incoming_v00,
4875 : incoming_v0, 0,
4876 : incoming_v1, 1,
4877 : true);
4878 18 : if (!ok) {
4879 0 : torture_comment(tctx, "Password check failed (SEC_CHAN_DOMAIN)\n");
4880 0 : ret = false;
4881 : }
4882 18 : ok = check_dom_trust_pw(p, tctx,
4883 18 : our_info->dns.name.string,
4884 18 : our_info->dns.dns_domain.string,
4885 : SEC_CHAN_DNS_DOMAIN,
4886 : &trustinfo,
4887 : incoming_v0,
4888 : incoming_v1, 1,
4889 : incoming_v2, 2,
4890 : true);
4891 18 : if (!ok) {
4892 0 : torture_comment(tctx, "Password check failed v2 (SEC_CHAN_DNS_DOMAIN)\n");
4893 0 : ret = false;
4894 : }
4895 18 : ok = check_dom_trust_pw(p, tctx,
4896 18 : our_info->dns.name.string,
4897 18 : our_info->dns.dns_domain.string,
4898 : SEC_CHAN_DNS_DOMAIN,
4899 : &trustinfo,
4900 : incoming_v1,
4901 : incoming_v2, 2,
4902 : incoming_v40, 40,
4903 : true);
4904 18 : if (!ok) {
4905 0 : torture_comment(tctx, "Password check failed v4 (SEC_CHAN_DNS_DOMAIN)\n");
4906 0 : ret = false;
4907 : }
4908 : }
4909 : }
4910 :
4911 72 : q.in.trustdom_handle = &trustdom_handle[i];
4912 72 : q.in.level = LSA_TRUSTED_DOMAIN_INFO_INFO_EX;
4913 72 : q.out.info = &info;
4914 72 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryTrustedDomainInfo_r(b, tctx, &q),
4915 : "QueryTrustedDomainInfo failed");
4916 72 : if (!NT_STATUS_IS_OK(q.out.result)) {
4917 0 : torture_comment(tctx, "QueryTrustedDomainInfo level 1 failed - %s\n", nt_errstr(q.out.result));
4918 0 : ret = false;
4919 72 : } else if (!q.out.info) {
4920 0 : torture_comment(tctx, "QueryTrustedDomainInfo level 1 failed to return an info pointer\n");
4921 0 : ret = false;
4922 : } else {
4923 72 : if (strcmp(info->info_ex.domain_name.string, trustinfo.domain_name.string) != 0) {
4924 0 : torture_comment(tctx, "QueryTrustedDomainInfo returned inconsistent long name: %s != %s\n",
4925 0 : info->info_ex.domain_name.string, trustinfo.domain_name.string);
4926 0 : ret = false;
4927 : }
4928 72 : if (strcmp(info->info_ex.netbios_name.string, trustinfo.netbios_name.string) != 0) {
4929 0 : torture_comment(tctx, "QueryTrustedDomainInfo returned inconsistent short name: %s != %s\n",
4930 0 : info->info_ex.netbios_name.string, trustinfo.netbios_name.string);
4931 0 : ret = false;
4932 : }
4933 72 : if (info->info_ex.trust_type != trustinfo.trust_type) {
4934 0 : torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust type %d != %d\n",
4935 0 : trust_name, info->info_ex.trust_type, trustinfo.trust_type);
4936 0 : ret = false;
4937 : }
4938 72 : if (info->info_ex.trust_attributes != LSA_TRUST_ATTRIBUTE_USES_RC4_ENCRYPTION) {
4939 0 : torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust attributes %d != %d\n",
4940 0 : trust_name, info->info_ex.trust_attributes, LSA_TRUST_ATTRIBUTE_USES_RC4_ENCRYPTION);
4941 0 : ret = false;
4942 : }
4943 72 : if (info->info_ex.trust_direction != trustinfo.trust_direction) {
4944 0 : torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust direction %d != %d\n",
4945 0 : trust_name, info->info_ex.trust_direction, trustinfo.trust_direction);
4946 0 : ret = false;
4947 : }
4948 : }
4949 : }
4950 : }
4951 :
4952 : /* now that we have some domains to look over, we can test the enum calls */
4953 6 : if (!test_EnumTrustDom(b, tctx, handle)) {
4954 0 : torture_comment(tctx, "test_EnumTrustDom failed\n");
4955 0 : ret = false;
4956 : }
4957 :
4958 6 : if (!test_EnumTrustDomEx(b, tctx, handle)) {
4959 0 : torture_comment(tctx, "test_EnumTrustDomEx failed\n");
4960 0 : ret = false;
4961 : }
4962 :
4963 78 : for (i=0; i<num_trusts; i++) {
4964 72 : if (!test_DeleteTrustedDomainBySid(b, tctx, handle, domsid[i])) {
4965 0 : torture_comment(tctx, "test_DeleteTrustedDomainBySid failed\n");
4966 0 : ret = false;
4967 : }
4968 : }
4969 :
4970 6 : return ret;
4971 : }
4972 :
4973 3 : static bool test_CreateTrustedDomainEx2(struct dcerpc_pipe *p,
4974 : struct torture_context *tctx,
4975 : struct policy_handle *handle,
4976 : uint32_t num_trusts)
4977 : {
4978 3 : return test_CreateTrustedDomainEx_common(p, tctx, handle, num_trusts, true);
4979 : }
4980 :
4981 3 : static bool test_CreateTrustedDomainEx(struct dcerpc_pipe *p,
4982 : struct torture_context *tctx,
4983 : struct policy_handle *handle,
4984 : uint32_t num_trusts)
4985 : {
4986 3 : return test_CreateTrustedDomainEx_common(p, tctx, handle, num_trusts, false);
4987 : }
4988 :
4989 14 : static bool test_QueryDomainInfoPolicy(struct dcerpc_binding_handle *b,
4990 : struct torture_context *tctx,
4991 : struct policy_handle *handle)
4992 : {
4993 0 : struct lsa_QueryDomainInformationPolicy r;
4994 14 : union lsa_DomainInformationPolicy *info = NULL;
4995 0 : int i;
4996 14 : bool ret = true;
4997 :
4998 14 : if (torture_setting_bool(tctx, "samba3", false)) {
4999 2 : torture_skip(tctx, "skipping QueryDomainInformationPolicy test\n");
5000 : }
5001 :
5002 12 : torture_comment(tctx, "\nTesting QueryDomainInformationPolicy\n");
5003 :
5004 36 : for (i=2;i<4;i++) {
5005 24 : r.in.handle = handle;
5006 24 : r.in.level = i;
5007 24 : r.out.info = &info;
5008 :
5009 24 : torture_comment(tctx, "\nTrying QueryDomainInformationPolicy level %d\n", i);
5010 :
5011 24 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryDomainInformationPolicy_r(b, tctx, &r),
5012 : "QueryDomainInformationPolicy failed");
5013 :
5014 : /* If the server does not support EFS, then this is the correct return */
5015 24 : if (i == LSA_DOMAIN_INFO_POLICY_EFS && NT_STATUS_EQUAL(r.out.result, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
5016 12 : continue;
5017 12 : } else if (!NT_STATUS_IS_OK(r.out.result)) {
5018 0 : torture_comment(tctx, "QueryDomainInformationPolicy failed - %s\n", nt_errstr(r.out.result));
5019 0 : ret = false;
5020 0 : continue;
5021 : }
5022 : }
5023 :
5024 12 : return ret;
5025 : }
5026 :
5027 :
5028 28 : static bool test_QueryInfoPolicyCalls( bool version2,
5029 : struct dcerpc_binding_handle *b,
5030 : struct torture_context *tctx,
5031 : struct policy_handle *handle)
5032 : {
5033 0 : struct lsa_QueryInfoPolicy r;
5034 28 : union lsa_PolicyInformation *info = NULL;
5035 0 : int i;
5036 28 : bool ret = true;
5037 28 : const char *call = talloc_asprintf(tctx, "QueryInfoPolicy%s", version2 ? "2":"");
5038 :
5039 28 : torture_comment(tctx, "\nTesting %s\n", call);
5040 :
5041 28 : if (version2 && torture_setting_bool(tctx, "samba3", false)) {
5042 2 : torture_skip(tctx, "skipping QueryInfoPolicy2 tests\n");
5043 : }
5044 :
5045 390 : for (i=1;i<=14;i++) {
5046 364 : r.in.handle = handle;
5047 364 : r.in.level = i;
5048 364 : r.out.info = &info;
5049 :
5050 364 : torture_comment(tctx, "\nTrying %s level %d\n", call, i);
5051 :
5052 364 : if (version2)
5053 : /* We can perform the cast, because both types are
5054 : structurally equal */
5055 168 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryInfoPolicy2_r(b, tctx,
5056 : (struct lsa_QueryInfoPolicy2*) &r),
5057 : "QueryInfoPolicy2 failed");
5058 : else
5059 196 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryInfoPolicy_r(b, tctx, &r),
5060 : "QueryInfoPolicy2 failed");
5061 :
5062 364 : switch (i) {
5063 78 : case LSA_POLICY_INFO_MOD:
5064 : case LSA_POLICY_INFO_AUDIT_FULL_SET:
5065 : case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
5066 78 : if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_PARAMETER)) {
5067 0 : torture_comment(tctx, "Server should have failed level %u: %s\n", i, nt_errstr(r.out.result));
5068 0 : ret = false;
5069 : }
5070 78 : break;
5071 208 : case LSA_POLICY_INFO_DOMAIN:
5072 : case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
5073 : case LSA_POLICY_INFO_REPLICA:
5074 : case LSA_POLICY_INFO_QUOTA:
5075 : case LSA_POLICY_INFO_ROLE:
5076 : case LSA_POLICY_INFO_AUDIT_LOG:
5077 : case LSA_POLICY_INFO_AUDIT_EVENTS:
5078 : case LSA_POLICY_INFO_PD:
5079 208 : if (!NT_STATUS_IS_OK(r.out.result)) {
5080 0 : torture_comment(tctx, "%s failed - %s\n", call, nt_errstr(r.out.result));
5081 0 : ret = false;
5082 : }
5083 208 : break;
5084 78 : case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN:
5085 : case LSA_POLICY_INFO_DNS_INT:
5086 : case LSA_POLICY_INFO_DNS:
5087 78 : if (torture_setting_bool(tctx, "samba3", false)) {
5088 : /* Other levels not implemented yet */
5089 6 : if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_INFO_CLASS)) {
5090 0 : torture_comment(tctx, "%s failed - %s\n", call, nt_errstr(r.out.result));
5091 0 : ret = false;
5092 : }
5093 72 : } else if (!NT_STATUS_IS_OK(r.out.result)) {
5094 0 : torture_comment(tctx, "%s failed - %s\n", call, nt_errstr(r.out.result));
5095 0 : ret = false;
5096 : }
5097 78 : break;
5098 0 : default:
5099 0 : if (torture_setting_bool(tctx, "samba4", false)) {
5100 : /* Other levels not implemented yet */
5101 0 : if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_INFO_CLASS)) {
5102 0 : torture_comment(tctx, "%s failed - %s\n", call, nt_errstr(r.out.result));
5103 0 : ret = false;
5104 : }
5105 0 : } else if (!NT_STATUS_IS_OK(r.out.result)) {
5106 0 : torture_comment(tctx, "%s failed - %s\n", call, nt_errstr(r.out.result));
5107 0 : ret = false;
5108 : }
5109 0 : break;
5110 : }
5111 :
5112 364 : if (NT_STATUS_IS_OK(r.out.result) && (i == LSA_POLICY_INFO_DNS
5113 256 : || i == LSA_POLICY_INFO_DNS_INT)) {
5114 : /* Let's look up some of these names */
5115 :
5116 0 : struct lsa_TransNameArray tnames, dnames;
5117 48 : tnames.count = 14;
5118 48 : tnames.names = talloc_zero_array(tctx, struct lsa_TranslatedName, tnames.count);
5119 48 : tnames.names[0].name.string = info->dns.name.string;
5120 48 : tnames.names[0].sid_type = SID_NAME_DOMAIN;
5121 48 : tnames.names[1].name.string = info->dns.dns_domain.string;
5122 48 : tnames.names[1].sid_type = SID_NAME_DOMAIN;
5123 48 : tnames.names[2].name.string = talloc_asprintf(tctx, "%s\\", info->dns.name.string);
5124 48 : tnames.names[2].sid_type = SID_NAME_DOMAIN;
5125 48 : tnames.names[3].name.string = talloc_asprintf(tctx, "%s\\", info->dns.dns_domain.string);
5126 48 : tnames.names[3].sid_type = SID_NAME_DOMAIN;
5127 48 : tnames.names[4].name.string = talloc_asprintf(tctx, "%s\\guest", info->dns.name.string);
5128 48 : tnames.names[4].sid_type = SID_NAME_USER;
5129 48 : tnames.names[5].name.string = talloc_asprintf(tctx, "%s\\krbtgt", info->dns.name.string);
5130 48 : tnames.names[5].sid_type = SID_NAME_USER;
5131 48 : tnames.names[6].name.string = talloc_asprintf(tctx, "%s\\guest", info->dns.dns_domain.string);
5132 48 : tnames.names[6].sid_type = SID_NAME_USER;
5133 48 : tnames.names[7].name.string = talloc_asprintf(tctx, "%s\\krbtgt", info->dns.dns_domain.string);
5134 48 : tnames.names[7].sid_type = SID_NAME_USER;
5135 48 : tnames.names[8].name.string = talloc_asprintf(tctx, "krbtgt@%s", info->dns.name.string);
5136 48 : tnames.names[8].sid_type = SID_NAME_USER;
5137 48 : tnames.names[9].name.string = talloc_asprintf(tctx, "krbtgt@%s", info->dns.dns_domain.string);
5138 48 : tnames.names[9].sid_type = SID_NAME_USER;
5139 48 : tnames.names[10].name.string = talloc_asprintf(tctx, "%s\\"TEST_MACHINENAME "$", info->dns.name.string);
5140 48 : tnames.names[10].sid_type = SID_NAME_USER;
5141 48 : tnames.names[11].name.string = talloc_asprintf(tctx, "%s\\"TEST_MACHINENAME "$", info->dns.dns_domain.string);
5142 48 : tnames.names[11].sid_type = SID_NAME_USER;
5143 48 : tnames.names[12].name.string = talloc_asprintf(tctx, TEST_MACHINENAME "$@%s", info->dns.name.string);
5144 48 : tnames.names[12].sid_type = SID_NAME_USER;
5145 48 : tnames.names[13].name.string = talloc_asprintf(tctx, TEST_MACHINENAME "$@%s", info->dns.dns_domain.string);
5146 48 : tnames.names[13].sid_type = SID_NAME_USER;
5147 48 : ret &= test_LookupNames(b, tctx, handle, LSA_LOOKUP_NAMES_ALL, &tnames);
5148 :
5149 : /* Try to use in-forest search for the test machine */
5150 48 : dnames.count = 1;
5151 48 : dnames.names = talloc_zero_array(tctx, struct lsa_TranslatedName, dnames.count);
5152 48 : dnames.names[0].name.string = talloc_asprintf(tctx, "%s\\"TEST_MACHINENAME "$", info->dns.name.string);
5153 48 : dnames.names[0].sid_type = SID_NAME_USER;
5154 48 : ret &= test_LookupNames(b, tctx, handle, LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY2, &dnames);
5155 : }
5156 : }
5157 :
5158 26 : return ret;
5159 : }
5160 :
5161 14 : static bool test_QueryInfoPolicy(struct dcerpc_binding_handle *b,
5162 : struct torture_context *tctx,
5163 : struct policy_handle *handle)
5164 : {
5165 14 : return test_QueryInfoPolicyCalls(false, b, tctx, handle);
5166 : }
5167 :
5168 14 : static bool test_QueryInfoPolicy2(struct dcerpc_binding_handle *b,
5169 : struct torture_context *tctx,
5170 : struct policy_handle *handle)
5171 : {
5172 14 : return test_QueryInfoPolicyCalls(true, b, tctx, handle);
5173 : }
5174 :
5175 46 : static bool test_GetUserName(struct dcerpc_binding_handle *b,
5176 : struct torture_context *tctx)
5177 : {
5178 0 : struct lsa_GetUserName r;
5179 46 : struct lsa_String *authority_name_p = NULL;
5180 46 : struct lsa_String *account_name_p = NULL;
5181 :
5182 46 : torture_comment(tctx, "\nTesting GetUserName\n");
5183 :
5184 46 : r.in.system_name = "\\";
5185 46 : r.in.account_name = &account_name_p;
5186 46 : r.in.authority_name = NULL;
5187 46 : r.out.account_name = &account_name_p;
5188 :
5189 46 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_GetUserName_r(b, tctx, &r),
5190 : "GetUserName failed");
5191 46 : torture_assert_ntstatus_ok(tctx, r.out.result,
5192 : "GetUserName result failed");
5193 46 : torture_assert_not_null(tctx, r.out.account_name, "r.out.account_name");
5194 46 : torture_assert_not_null(tctx, *r.out.account_name, "*r.out.account_name");
5195 46 : torture_assert(tctx, r.out.authority_name == NULL, "r.out.authority_name");
5196 :
5197 46 : account_name_p = NULL;
5198 46 : r.in.account_name = &account_name_p;
5199 46 : r.in.authority_name = &authority_name_p;
5200 46 : r.out.account_name = &account_name_p;
5201 :
5202 46 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_GetUserName_r(b, tctx, &r),
5203 : "GetUserName failed");
5204 46 : torture_assert_ntstatus_ok(tctx, r.out.result,
5205 : "GetUserName result failed");
5206 46 : torture_assert_not_null(tctx, r.out.account_name, "r.out.account_name");
5207 46 : torture_assert_not_null(tctx, *r.out.account_name, "*r.out.account_name");
5208 46 : torture_assert_not_null(tctx, r.out.authority_name, "r.out.authority_name");
5209 46 : torture_assert_not_null(tctx, *r.out.authority_name, "*r.out.authority_name");
5210 :
5211 46 : torture_comment(tctx,
5212 : "Account Name: %s, Authority Name: %s\n",
5213 46 : (*r.out.account_name)->string,
5214 46 : (*r.out.authority_name)->string);
5215 :
5216 46 : return true;
5217 : }
5218 :
5219 3 : static bool test_GetUserName_fail(struct dcerpc_binding_handle *b,
5220 : struct torture_context *tctx)
5221 : {
5222 0 : struct lsa_GetUserName r;
5223 3 : struct lsa_String *account_name_p = NULL;
5224 0 : NTSTATUS status;
5225 :
5226 3 : torture_comment(tctx, "\nTesting GetUserName_fail\n");
5227 :
5228 3 : r.in.system_name = "\\";
5229 3 : r.in.account_name = &account_name_p;
5230 3 : r.in.authority_name = NULL;
5231 3 : r.out.account_name = &account_name_p;
5232 :
5233 3 : status = dcerpc_lsa_GetUserName_r(b, tctx, &r);
5234 3 : if (!NT_STATUS_IS_OK(status)) {
5235 3 : if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5236 3 : torture_comment(tctx,
5237 : "GetUserName correctly returned with "
5238 : "status: %s\n",
5239 : nt_errstr(status));
5240 3 : return true;
5241 : }
5242 :
5243 0 : torture_assert_ntstatus_equal(tctx,
5244 : status,
5245 : NT_STATUS_ACCESS_DENIED,
5246 : "GetUserName return value should "
5247 : "be ACCESS_DENIED");
5248 0 : return true;
5249 : }
5250 :
5251 0 : if (!NT_STATUS_IS_OK(r.out.result)) {
5252 0 : if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED) ||
5253 0 : NT_STATUS_EQUAL(r.out.result, NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED)) {
5254 0 : torture_comment(tctx,
5255 : "GetUserName correctly returned with "
5256 : "result: %s\n",
5257 : nt_errstr(r.out.result));
5258 0 : return true;
5259 : }
5260 : }
5261 :
5262 0 : torture_assert_ntstatus_equal(tctx,
5263 : r.out.result,
5264 : NT_STATUS_OK,
5265 : "GetUserName return value should be "
5266 : "ACCESS_DENIED");
5267 :
5268 0 : return false;
5269 : }
5270 :
5271 123 : bool test_lsa_Close(struct dcerpc_binding_handle *b,
5272 : struct torture_context *tctx,
5273 : struct policy_handle *handle)
5274 : {
5275 6 : struct lsa_Close r;
5276 6 : struct policy_handle handle2;
5277 :
5278 123 : torture_comment(tctx, "\nTesting Close\n");
5279 :
5280 123 : r.in.handle = handle;
5281 123 : r.out.handle = &handle2;
5282 :
5283 123 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_Close_r(b, tctx, &r),
5284 : "Close failed");
5285 123 : torture_assert_ntstatus_ok(tctx, r.out.result,
5286 : "Close failed");
5287 :
5288 123 : torture_assert_ntstatus_equal(tctx, dcerpc_lsa_Close_r(b, tctx, &r),
5289 : NT_STATUS_RPC_SS_CONTEXT_MISMATCH, "Close should failed");
5290 :
5291 123 : torture_comment(tctx, "\n");
5292 :
5293 123 : return true;
5294 : }
5295 :
5296 19 : bool torture_rpc_lsa(struct torture_context *tctx)
5297 : {
5298 0 : NTSTATUS status;
5299 0 : struct dcerpc_pipe *p;
5300 19 : bool ret = true;
5301 19 : struct policy_handle *handle = NULL;
5302 19 : struct test_join *join = NULL;
5303 0 : struct cli_credentials *machine_creds;
5304 0 : struct dcerpc_binding_handle *b;
5305 0 : enum dcerpc_transport_t transport;
5306 :
5307 19 : status = torture_rpc_connection(tctx, &p, &ndr_table_lsarpc);
5308 19 : torture_assert_ntstatus_ok(tctx, status, "Error connecting to server");
5309 :
5310 19 : b = p->binding_handle;
5311 19 : transport = dcerpc_binding_get_transport(p->binding);
5312 :
5313 : /* Test lsaLookupSids3 and lsaLookupNames4 over tcpip */
5314 19 : if (transport == NCACN_IP_TCP) {
5315 5 : if (!test_OpenPolicy_fail(b, tctx)) {
5316 0 : ret = false;
5317 : }
5318 :
5319 5 : if (!test_OpenPolicy2_fail(b, tctx)) {
5320 0 : ret = false;
5321 : }
5322 :
5323 5 : if (!test_OpenPolicy3_fail(b, tctx)) {
5324 0 : ret = false;
5325 : }
5326 :
5327 5 : if (!test_many_LookupSids(p, tctx, handle, LSA_LOOKUP_NAMES_ALL)) {
5328 0 : ret = false;
5329 : }
5330 :
5331 5 : return ret;
5332 : }
5333 :
5334 14 : if (!test_OpenPolicy(b, tctx)) {
5335 0 : ret = false;
5336 : }
5337 :
5338 14 : if (!test_lsa_OpenPolicy2(b, tctx, &handle)) {
5339 0 : ret = false;
5340 : }
5341 :
5342 14 : if (!test_lsa_OpenPolicy3(b, tctx, &handle)) {
5343 0 : ret = false;
5344 : }
5345 :
5346 14 : if (handle) {
5347 14 : join = torture_join_domain(tctx, TEST_MACHINENAME, ACB_WSTRUST, &machine_creds);
5348 14 : if (!join) {
5349 0 : ret = false;
5350 : }
5351 :
5352 14 : if (!test_LookupSids_async(b, tctx, handle, LSA_LOOKUP_NAMES_ALL)) {
5353 0 : ret = false;
5354 : }
5355 :
5356 14 : if (!test_QueryDomainInfoPolicy(b, tctx, handle)) {
5357 0 : ret = false;
5358 : }
5359 :
5360 14 : if (!test_CreateSecret(p, tctx, handle)) {
5361 3 : ret = false;
5362 : }
5363 :
5364 14 : if (!test_QueryInfoPolicy(b, tctx, handle)) {
5365 0 : ret = false;
5366 : }
5367 :
5368 14 : if (!test_QueryInfoPolicy2(b, tctx, handle)) {
5369 0 : ret = false;
5370 : }
5371 :
5372 14 : if (!test_Delete(b, tctx, handle)) {
5373 0 : ret = false;
5374 : }
5375 :
5376 14 : if (!test_many_LookupSids(p, tctx, handle, LSA_LOOKUP_NAMES_ALL)) {
5377 0 : ret = false;
5378 : }
5379 :
5380 14 : if (!test_lsa_Close(b, tctx, handle)) {
5381 0 : ret = false;
5382 : }
5383 :
5384 14 : torture_leave_domain(tctx, join);
5385 :
5386 : } else {
5387 0 : if (!test_many_LookupSids(p, tctx, handle, LSA_LOOKUP_NAMES_ALL)) {
5388 0 : ret = false;
5389 : }
5390 : }
5391 :
5392 14 : if (!test_GetUserName(b, tctx)) {
5393 0 : ret = false;
5394 : }
5395 :
5396 14 : return ret;
5397 : }
5398 :
5399 37 : bool torture_rpc_lsa_get_user(struct torture_context *tctx)
5400 : {
5401 0 : NTSTATUS status;
5402 0 : struct dcerpc_pipe *p;
5403 37 : bool ret = true;
5404 0 : struct dcerpc_binding_handle *b;
5405 0 : enum dcerpc_transport_t transport;
5406 :
5407 37 : status = torture_rpc_connection(tctx, &p, &ndr_table_lsarpc);
5408 37 : torture_assert_ntstatus_ok(tctx, status, "Error connecting to server");
5409 :
5410 35 : b = p->binding_handle;
5411 35 : transport = dcerpc_binding_get_transport(p->binding);
5412 :
5413 35 : if (transport == NCACN_IP_TCP) {
5414 3 : if (!test_GetUserName_fail(b, tctx)) {
5415 0 : ret = false;
5416 : }
5417 3 : return ret;
5418 : }
5419 :
5420 32 : if (!test_GetUserName(b, tctx)) {
5421 0 : ret = false;
5422 : }
5423 :
5424 32 : return ret;
5425 : }
5426 :
5427 5 : static bool testcase_LookupNames(struct torture_context *tctx,
5428 : struct dcerpc_pipe *p)
5429 : {
5430 5 : bool ret = true;
5431 0 : struct policy_handle *handle;
5432 0 : struct lsa_TransNameArray tnames;
5433 0 : struct lsa_TransNameArray2 tnames2;
5434 5 : struct dcerpc_binding_handle *b = p->binding_handle;
5435 5 : enum dcerpc_transport_t transport = dcerpc_binding_get_transport(p->binding);
5436 :
5437 5 : if (transport != NCACN_NP && transport != NCALRPC) {
5438 0 : torture_comment(tctx, "testcase_LookupNames is only available "
5439 : "over NCACN_NP or NCALRPC");
5440 0 : return true;
5441 : }
5442 :
5443 5 : if (!test_OpenPolicy(b, tctx)) {
5444 0 : ret = false;
5445 : }
5446 :
5447 5 : if (!test_lsa_OpenPolicy2(b, tctx, &handle)) {
5448 0 : ret = false;
5449 : }
5450 :
5451 5 : if (!handle) {
5452 0 : ret = false;
5453 : }
5454 :
5455 5 : tnames.count = 1;
5456 5 : tnames.names = talloc_array(tctx, struct lsa_TranslatedName, tnames.count);
5457 5 : ZERO_STRUCT(tnames.names[0]);
5458 5 : tnames.names[0].name.string = "BUILTIN";
5459 5 : tnames.names[0].sid_type = SID_NAME_DOMAIN;
5460 :
5461 5 : if (!test_LookupNames(b, tctx, handle, LSA_LOOKUP_NAMES_ALL, &tnames)) {
5462 0 : ret = false;
5463 : }
5464 :
5465 5 : tnames2.count = 1;
5466 5 : tnames2.names = talloc_array(tctx, struct lsa_TranslatedName2, tnames2.count);
5467 5 : ZERO_STRUCT(tnames2.names[0]);
5468 5 : tnames2.names[0].name.string = "BUILTIN";
5469 5 : tnames2.names[0].sid_type = SID_NAME_DOMAIN;
5470 :
5471 5 : if (!test_LookupNames2(b, tctx, handle, LSA_LOOKUP_NAMES_ALL, &tnames2, true)) {
5472 0 : ret = false;
5473 : }
5474 :
5475 5 : if (!test_LookupNames3(b, tctx, handle, LSA_LOOKUP_NAMES_ALL, &tnames2, true)) {
5476 0 : ret = false;
5477 : }
5478 :
5479 5 : if (!test_LookupNames_wellknown(b, tctx, handle, LSA_LOOKUP_NAMES_ALL)) {
5480 0 : ret = false;
5481 : }
5482 :
5483 5 : if (!test_LookupNames_NULL(b, tctx, handle, LSA_LOOKUP_NAMES_ALL)) {
5484 0 : ret = false;
5485 : }
5486 :
5487 5 : if (!test_LookupNames_bogus(b, tctx, handle, LSA_LOOKUP_NAMES_ALL)) {
5488 0 : ret = false;
5489 : }
5490 :
5491 5 : if (!test_lsa_Close(b, tctx, handle)) {
5492 0 : ret = false;
5493 : }
5494 :
5495 5 : return ret;
5496 : }
5497 :
5498 2358 : struct torture_suite *torture_rpc_lsa_lookup_names(TALLOC_CTX *mem_ctx)
5499 : {
5500 125 : struct torture_suite *suite;
5501 125 : struct torture_rpc_tcase *tcase;
5502 :
5503 2358 : suite = torture_suite_create(mem_ctx, "lsa.lookupnames");
5504 :
5505 2358 : tcase = torture_suite_add_rpc_iface_tcase(suite, "lsa",
5506 : &ndr_table_lsarpc);
5507 2358 : torture_rpc_tcase_add_test(tcase, "LookupNames",
5508 : testcase_LookupNames);
5509 :
5510 2358 : return suite;
5511 : }
5512 :
5513 : struct lsa_trustdom_state {
5514 : uint32_t num_trusts;
5515 : };
5516 :
5517 3 : static bool testcase_TrustedDomains(struct torture_context *tctx,
5518 : struct dcerpc_pipe *p,
5519 : void *data)
5520 : {
5521 3 : bool ret = true;
5522 0 : struct policy_handle *handle;
5523 0 : struct lsa_trustdom_state *state =
5524 3 : talloc_get_type_abort(data, struct lsa_trustdom_state);
5525 3 : struct dcerpc_binding_handle *b = p->binding_handle;
5526 3 : enum dcerpc_transport_t transport = dcerpc_binding_get_transport(p->binding);
5527 :
5528 3 : if (transport != NCACN_NP && transport != NCALRPC) {
5529 0 : torture_comment(tctx, "testcase_TrustedDomains is only available "
5530 : "over NCACN_NP or NCALRPC");
5531 0 : return true;
5532 : }
5533 :
5534 3 : torture_comment(tctx, "Testing %d domains\n", state->num_trusts);
5535 :
5536 3 : if (!test_OpenPolicy(b, tctx)) {
5537 0 : ret = false;
5538 : }
5539 :
5540 3 : if (!test_lsa_OpenPolicy2(b, tctx, &handle)) {
5541 0 : ret = false;
5542 : }
5543 :
5544 3 : if (!handle) {
5545 0 : ret = false;
5546 : }
5547 :
5548 3 : if (!test_CreateTrustedDomain(b, tctx, handle, state->num_trusts)) {
5549 0 : ret = false;
5550 : }
5551 :
5552 3 : if (!test_CreateTrustedDomainEx(p, tctx, handle, state->num_trusts)) {
5553 0 : ret = false;
5554 : }
5555 :
5556 3 : if (!test_CreateTrustedDomainEx2(p, tctx, handle, state->num_trusts)) {
5557 0 : ret = false;
5558 : }
5559 :
5560 3 : if (!test_lsa_Close(b, tctx, handle)) {
5561 0 : ret = false;
5562 : }
5563 :
5564 3 : return ret;
5565 : }
5566 :
5567 2358 : struct torture_suite *torture_rpc_lsa_trusted_domains(TALLOC_CTX *mem_ctx)
5568 : {
5569 125 : struct torture_suite *suite;
5570 125 : struct torture_rpc_tcase *tcase;
5571 125 : struct lsa_trustdom_state *state;
5572 :
5573 2358 : state = talloc(mem_ctx, struct lsa_trustdom_state);
5574 :
5575 2358 : state->num_trusts = 12;
5576 :
5577 2358 : suite = torture_suite_create(mem_ctx, "lsa.trusted.domains");
5578 :
5579 2358 : tcase = torture_suite_add_rpc_iface_tcase(suite, "lsa",
5580 : &ndr_table_lsarpc);
5581 2358 : torture_rpc_tcase_add_test_ex(tcase, "TrustedDomains",
5582 : testcase_TrustedDomains,
5583 : state);
5584 :
5585 2358 : return suite;
5586 : }
5587 :
5588 5 : static bool testcase_Privileges(struct torture_context *tctx,
5589 : struct dcerpc_pipe *p)
5590 : {
5591 0 : struct policy_handle *handle;
5592 5 : struct dcerpc_binding_handle *b = p->binding_handle;
5593 5 : enum dcerpc_transport_t transport = dcerpc_binding_get_transport(p->binding);
5594 :
5595 5 : if (transport != NCACN_NP && transport != NCALRPC) {
5596 0 : torture_skip(tctx, "testcase_Privileges is only available "
5597 : "over NCACN_NP or NCALRPC");
5598 : }
5599 :
5600 5 : if (!test_OpenPolicy(b, tctx)) {
5601 0 : return false;
5602 : }
5603 :
5604 5 : if (!test_lsa_OpenPolicy2(b, tctx, &handle)) {
5605 0 : return false;
5606 : }
5607 :
5608 5 : if (!handle) {
5609 0 : return false;
5610 : }
5611 :
5612 5 : if (!test_CreateAccount(b, tctx, handle)) {
5613 0 : return false;
5614 : }
5615 :
5616 5 : if (!test_EnumAccounts(b, tctx, handle)) {
5617 0 : return false;
5618 : }
5619 :
5620 5 : if (!test_EnumPrivs(b, tctx, handle)) {
5621 0 : return false;
5622 : }
5623 :
5624 5 : if (!test_lsa_Close(b, tctx, handle)) {
5625 0 : return false;
5626 : }
5627 :
5628 5 : return true;
5629 : }
5630 :
5631 :
5632 2358 : struct torture_suite *torture_rpc_lsa_privileges(TALLOC_CTX *mem_ctx)
5633 : {
5634 125 : struct torture_suite *suite;
5635 125 : struct torture_rpc_tcase *tcase;
5636 :
5637 2358 : suite = torture_suite_create(mem_ctx, "lsa.privileges");
5638 :
5639 2358 : tcase = torture_suite_add_rpc_iface_tcase(suite, "lsa",
5640 : &ndr_table_lsarpc);
5641 2358 : torture_rpc_tcase_add_test(tcase, "Privileges",
5642 : testcase_Privileges);
5643 :
5644 2358 : return suite;
5645 : }
|