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