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