CVE-2020-1472(ZeroLogon): torture: ServerSetPassword2 zero password
[amitay/samba.git] / source4 / torture / rpc / netlogon.c
1 /*
2    Unix SMB/CIFS implementation.
3
4    test suite for netlogon rpc operations
5
6    Copyright (C) Andrew Tridgell 2003
7    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003-2004
8    Copyright (C) Tim Potter      2003
9    Copyright (C) Matthias Dieter Wallnöfer            2009-2010
10
11    This program is free software; you can redistribute it and/or modify
12    it under the terms of the GNU General Public License as published by
13    the Free Software Foundation; either version 3 of the License, or
14    (at your option) any later version.
15
16    This program is distributed in the hope that it will be useful,
17    but WITHOUT ANY WARRANTY; without even the implied warranty of
18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19    GNU General Public License for more details.
20
21    You should have received a copy of the GNU General Public License
22    along with this program.  If not, see <http://www.gnu.org/licenses/>.
23 */
24
25 #include "includes.h"
26 #include "lib/events/events.h"
27 #include "lib/cmdline/popt_common.h"
28 #include "torture/rpc/torture_rpc.h"
29 #include "../lib/crypto/crypto.h"
30 #include "libcli/auth/libcli_auth.h"
31 #include "librpc/gen_ndr/ndr_netlogon_c.h"
32 #include "librpc/gen_ndr/ndr_lsa_c.h"
33 #include "param/param.h"
34 #include "libcli/security/security.h"
35 #include <ldb.h>
36 #include "lib/util/util_ldb.h"
37 #include "ldb_wrap.h"
38 #include "lib/replace/system/network.h"
39 #include "dsdb/samdb/samdb.h"
40
41 #undef strcasecmp
42
43 #define TEST_MACHINE_NAME "torturetest"
44
45 static bool test_netr_broken_binding_handle(struct torture_context *tctx,
46                                             struct dcerpc_pipe *p)
47 {
48         NTSTATUS status;
49         struct netr_DsRGetSiteName r;
50         const char *site = NULL;
51         struct dcerpc_binding_handle *b = p->binding_handle;
52
53         r.in.computer_name      = talloc_asprintf(tctx, "\\\\%s",
54                                                   dcerpc_server_name(p));
55         r.out.site              = &site;
56
57         torture_comment(tctx,
58                         "Testing netlogon request with correct binding handle: %s\n",
59                         r.in.computer_name);
60
61         status = dcerpc_netr_DsRGetSiteName_r(b, tctx, &r);
62         torture_assert_ntstatus_ok(tctx, status,
63                                    "Netlogon request with broken binding handle");
64         torture_assert_werr_ok(tctx, r.out.result,
65                                "Netlogon request with broken binding handle");
66
67         if (torture_setting_bool(tctx, "samba3", false) ||
68             torture_setting_bool(tctx, "samba4", false)) {
69                 torture_skip(tctx,
70                              "Skipping broken binding handle check against Samba");
71         }
72
73         r.in.computer_name      = talloc_asprintf(tctx, "\\\\\\\\%s",
74                                                   dcerpc_server_name(p));
75
76         torture_comment(tctx,
77                         "Testing netlogon request with broken binding handle: %s\n",
78                         r.in.computer_name);
79
80         status = dcerpc_netr_DsRGetSiteName_r(b, tctx, &r);
81         torture_assert_ntstatus_ok(tctx, status,
82                                    "Netlogon request with broken binding handle");
83         torture_assert_werr_equal(tctx, r.out.result,
84                                   WERR_INVALID_COMPUTERNAME,
85                                   "Netlogon request with broken binding handle");
86
87         r.in.computer_name      = "\\\\\\\\THIS_IS_NOT_VALID";
88
89         torture_comment(tctx,
90                         "Testing netlogon request with broken binding handle: %s\n",
91                         r.in.computer_name);
92
93         status = dcerpc_netr_DsRGetSiteName_r(b, tctx, &r);
94         torture_assert_ntstatus_ok(tctx, status,
95                                    "Netlogon request with broken binding handle");
96         torture_assert_werr_equal(tctx, r.out.result,
97                                   WERR_INVALID_COMPUTERNAME,
98                                   "Netlogon request with broken binding handle");
99
100         return true;
101 }
102
103 static bool test_LogonUasLogon(struct torture_context *tctx,
104                                struct dcerpc_pipe *p)
105 {
106         NTSTATUS status;
107         struct netr_LogonUasLogon r;
108         struct netr_UasInfo *info = NULL;
109         struct dcerpc_binding_handle *b = p->binding_handle;
110
111         r.in.server_name = NULL;
112         r.in.account_name = cli_credentials_get_username(
113                                 popt_get_cmdline_credentials());
114         r.in.workstation = TEST_MACHINE_NAME;
115         r.out.info = &info;
116
117         status = dcerpc_netr_LogonUasLogon_r(b, tctx, &r);
118         torture_assert_ntstatus_ok(tctx, status, "LogonUasLogon");
119
120         return true;
121 }
122
123 static bool test_LogonUasLogoff(struct torture_context *tctx,
124                                 struct dcerpc_pipe *p)
125 {
126         NTSTATUS status;
127         struct netr_LogonUasLogoff r;
128         struct netr_UasLogoffInfo info;
129         struct dcerpc_binding_handle *b = p->binding_handle;
130
131         r.in.server_name = NULL;
132         r.in.account_name = cli_credentials_get_username(
133                                 popt_get_cmdline_credentials());
134         r.in.workstation = TEST_MACHINE_NAME;
135         r.out.info = &info;
136
137         status = dcerpc_netr_LogonUasLogoff_r(b, tctx, &r);
138         torture_assert_ntstatus_ok(tctx, status, "LogonUasLogoff");
139
140         return true;
141 }
142
143 bool test_SetupCredentials(struct dcerpc_pipe *p, struct torture_context *tctx,
144                                   struct cli_credentials *credentials,
145                                   struct netlogon_creds_CredentialState **creds_out)
146 {
147         struct netr_ServerReqChallenge r;
148         struct netr_ServerAuthenticate a;
149         struct netr_Credential credentials1, credentials2, credentials3;
150         struct netlogon_creds_CredentialState *creds;
151         const struct samr_Password *mach_password;
152         const char *machine_name;
153         struct dcerpc_binding_handle *b = p->binding_handle;
154
155         mach_password = cli_credentials_get_nt_hash(credentials, tctx);
156         machine_name = cli_credentials_get_workstation(credentials);
157
158         torture_comment(tctx, "Testing ServerReqChallenge\n");
159
160         r.in.server_name = NULL;
161         r.in.computer_name = machine_name;
162         r.in.credentials = &credentials1;
163         r.out.return_credentials = &credentials2;
164
165         netlogon_creds_random_challenge(&credentials1);
166
167         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
168                 "ServerReqChallenge failed");
169         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
170
171         a.in.server_name = NULL;
172         a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
173         a.in.secure_channel_type = cli_credentials_get_secure_channel_type(credentials);
174         a.in.computer_name = machine_name;
175         a.in.credentials = &credentials3;
176         a.out.return_credentials = &credentials3;
177
178         creds = netlogon_creds_client_init(tctx, a.in.account_name,
179                                            a.in.computer_name,
180                                            a.in.secure_channel_type,
181                                            &credentials1, &credentials2,
182                                            mach_password, &credentials3,
183                                            0);
184         torture_assert(tctx, creds != NULL, "memory allocation");
185
186
187         torture_comment(tctx, "Testing ServerAuthenticate\n");
188
189         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate_r(b, tctx, &a),
190                 "ServerAuthenticate failed");
191
192         /* This allows the tests to continue against the more fussy windows 2008 */
193         if (NT_STATUS_EQUAL(a.out.result, NT_STATUS_DOWNGRADE_DETECTED)) {
194                 return test_SetupCredentials2(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
195                                               credentials,
196                                               cli_credentials_get_secure_channel_type(credentials),
197                                               creds_out);
198         }
199
200         torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate");
201
202         torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3),
203                        "Credential chaining failed");
204
205         *creds_out = creds;
206         return true;
207 }
208
209 bool test_SetupCredentials2ex(struct dcerpc_pipe *p, struct torture_context *tctx,
210                               uint32_t negotiate_flags,
211                               struct cli_credentials *machine_credentials,
212                               const char *computer_name,
213                               enum netr_SchannelType sec_chan_type,
214                               NTSTATUS expected_result,
215                               struct netlogon_creds_CredentialState **creds_out)
216 {
217         struct netr_ServerReqChallenge r;
218         struct netr_ServerAuthenticate2 a;
219         struct netr_Credential credentials1, credentials2, credentials3;
220         struct netlogon_creds_CredentialState *creds;
221         const struct samr_Password *mach_password;
222         struct dcerpc_binding_handle *b = p->binding_handle;
223         const char *account_name = cli_credentials_get_username(machine_credentials);
224
225         mach_password = cli_credentials_get_nt_hash(machine_credentials, tctx);
226
227         torture_comment(tctx, "Testing ServerReqChallenge\n");
228
229         r.in.server_name = NULL;
230         r.in.computer_name = computer_name;
231         r.in.credentials = &credentials1;
232         r.out.return_credentials = &credentials2;
233
234         netlogon_creds_random_challenge(&credentials1);
235
236         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
237                 "ServerReqChallenge failed");
238         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
239
240         a.in.server_name = NULL;
241         a.in.account_name = account_name;
242         a.in.secure_channel_type = sec_chan_type;
243         a.in.computer_name = computer_name;
244         a.in.negotiate_flags = &negotiate_flags;
245         a.out.negotiate_flags = &negotiate_flags;
246         a.in.credentials = &credentials3;
247         a.out.return_credentials = &credentials3;
248
249         creds = netlogon_creds_client_init(tctx, a.in.account_name,
250                                            a.in.computer_name,
251                                            a.in.secure_channel_type,
252                                            &credentials1, &credentials2,
253                                            mach_password, &credentials3,
254                                            negotiate_flags);
255
256         torture_assert(tctx, creds != NULL, "memory allocation");
257
258         torture_comment(tctx, "Testing ServerAuthenticate2\n");
259
260         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate2_r(b, tctx, &a),
261                 "ServerAuthenticate2 failed");
262         torture_assert_ntstatus_equal(tctx, a.out.result, expected_result,
263                                       "ServerAuthenticate2 unexpected");
264
265         if (NT_STATUS_IS_OK(expected_result)) {
266                 torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3),
267                                "Credential chaining failed");
268         } else {
269                 torture_assert(tctx, !netlogon_creds_client_check(creds, &credentials3),
270                                "Credential chaining passed unexptected");
271         }
272
273         torture_comment(tctx, "negotiate_flags=0x%08x\n", negotiate_flags);
274
275         *creds_out = creds;
276         return true;
277 }
278
279 bool test_SetupCredentials2(struct dcerpc_pipe *p, struct torture_context *tctx,
280                             uint32_t negotiate_flags,
281                             struct cli_credentials *machine_credentials,
282                             enum netr_SchannelType sec_chan_type,
283                             struct netlogon_creds_CredentialState **creds_out)
284 {
285         const char *computer_name =
286                 cli_credentials_get_workstation(machine_credentials);
287
288         return test_SetupCredentials2ex(p, tctx, negotiate_flags,
289                                         machine_credentials,
290                                         computer_name,
291                                         sec_chan_type,
292                                         NT_STATUS_OK,
293                                         creds_out);
294 }
295
296 bool test_SetupCredentials3(struct dcerpc_pipe *p, struct torture_context *tctx,
297                             uint32_t negotiate_flags,
298                             struct cli_credentials *machine_credentials,
299                             struct netlogon_creds_CredentialState **creds_out)
300 {
301         struct netr_ServerReqChallenge r;
302         struct netr_ServerAuthenticate3 a;
303         struct netr_Credential credentials1, credentials2, credentials3;
304         struct netlogon_creds_CredentialState *creds;
305         struct samr_Password mach_password;
306         uint32_t rid;
307         const char *machine_name;
308         const char *plain_pass;
309         struct dcerpc_binding_handle *b = NULL;
310
311         if (p == NULL) {
312                 return false;
313         }
314
315         b = p->binding_handle;
316
317         machine_name = cli_credentials_get_workstation(machine_credentials);
318         torture_assert(tctx, machine_name != NULL, "machine_name");
319         plain_pass = cli_credentials_get_password(machine_credentials);
320         torture_assert(tctx, plain_pass != NULL, "plain_pass");
321
322         torture_comment(tctx, "Testing ServerReqChallenge\n");
323
324         r.in.server_name = NULL;
325         r.in.computer_name = machine_name;
326         r.in.credentials = &credentials1;
327         r.out.return_credentials = &credentials2;
328
329         netlogon_creds_random_challenge(&credentials1);
330
331         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
332                 "ServerReqChallenge failed");
333         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
334
335         E_md4hash(plain_pass, mach_password.hash);
336
337         a.in.server_name = NULL;
338         a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
339         a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
340         a.in.computer_name = machine_name;
341         a.in.negotiate_flags = &negotiate_flags;
342         a.in.credentials = &credentials3;
343         a.out.return_credentials = &credentials3;
344         a.out.negotiate_flags = &negotiate_flags;
345         a.out.rid = &rid;
346
347         creds = netlogon_creds_client_init(tctx, a.in.account_name,
348                                            a.in.computer_name,
349                                            a.in.secure_channel_type,
350                                            &credentials1, &credentials2,
351                                            &mach_password, &credentials3,
352                                            negotiate_flags);
353
354         torture_assert(tctx, creds != NULL, "memory allocation");
355
356         torture_comment(tctx, "Testing ServerAuthenticate3\n");
357
358         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b, tctx, &a),
359                 "ServerAuthenticate3 failed");
360         torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate3 failed");
361         torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
362
363         torture_comment(tctx, "negotiate_flags=0x%08x\n", negotiate_flags);
364
365         /* Prove that requesting a challenge again won't break it */
366         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
367                 "ServerReqChallenge failed");
368         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
369
370         *creds_out = creds;
371         return true;
372 }
373
374 bool test_SetupCredentialsDowngrade(struct torture_context *tctx,
375                                         struct dcerpc_pipe *p,
376                                         struct cli_credentials *machine_credentials)
377 {
378         struct netr_ServerReqChallenge r;
379         struct netr_ServerAuthenticate3 a;
380         struct netr_Credential credentials1, credentials2, credentials3;
381         struct netlogon_creds_CredentialState *creds;
382         struct samr_Password mach_password;
383         uint32_t rid;
384         const char *machine_name;
385         const char *plain_pass;
386         struct dcerpc_binding_handle *b = p->binding_handle;
387         uint32_t negotiate_flags = 0;
388
389         machine_name = cli_credentials_get_workstation(machine_credentials);
390         torture_assert(tctx, machine_name != NULL, "machine_name");
391         plain_pass = cli_credentials_get_password(machine_credentials);
392         torture_assert(tctx, plain_pass != NULL, "plain_pass");
393
394         torture_comment(tctx, "Testing ServerReqChallenge\n");
395
396         r.in.server_name = NULL;
397         r.in.computer_name = machine_name;
398         r.in.credentials = &credentials1;
399         r.out.return_credentials = &credentials2;
400
401         netlogon_creds_random_challenge(&credentials1);
402
403         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
404                 "ServerReqChallenge failed");
405         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
406
407         E_md4hash(plain_pass, mach_password.hash);
408
409         a.in.server_name = NULL;
410         a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
411         a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
412         a.in.computer_name = machine_name;
413         a.in.negotiate_flags = &negotiate_flags;
414         a.in.credentials = &credentials3;
415         a.out.return_credentials = &credentials3;
416         a.out.negotiate_flags = &negotiate_flags;
417         a.out.rid = &rid;
418
419         creds = netlogon_creds_client_init(tctx, a.in.account_name,
420                                            a.in.computer_name,
421                                            a.in.secure_channel_type,
422                                            &credentials1, &credentials2,
423                                            &mach_password, &credentials3,
424                                            negotiate_flags);
425
426         torture_assert(tctx, creds != NULL, "memory allocation");
427
428         torture_comment(tctx, "Testing ServerAuthenticate3\n");
429
430         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b, tctx, &a),
431                 "ServerAuthenticate3 failed");
432         torture_assert_ntstatus_equal(tctx, a.out.result, NT_STATUS_DOWNGRADE_DETECTED, "ServerAuthenticate3 should have failed");
433
434         negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
435         creds = netlogon_creds_client_init(tctx, a.in.account_name,
436                                            a.in.computer_name,
437                                            a.in.secure_channel_type,
438                                            &credentials1, &credentials2,
439                                            &mach_password, &credentials3,
440                                            negotiate_flags);
441
442         torture_assert(tctx, creds != NULL, "memory allocation");
443
444         torture_comment(tctx, "Testing ServerAuthenticate3\n");
445
446         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b, tctx, &a),
447                 "ServerAuthenticate3 failed");
448         torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate3 should succeed");
449
450         torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
451
452         torture_comment(tctx, "negotiate_flags=0x%08x\n", negotiate_flags);
453
454         /* Prove that requesting a challenge again won't break it */
455         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
456                 "ServerReqChallenge failed");
457         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
458
459         return true;
460 }
461
462 bool test_SetupCredentialsPipe(const struct dcerpc_pipe *p1,
463                                struct torture_context *tctx,
464                                struct cli_credentials *machine_credentials,
465                                struct netlogon_creds_CredentialState *creds,
466                                uint32_t additional_flags,
467                                struct dcerpc_pipe **_p2)
468 {
469         NTSTATUS status;
470         struct dcerpc_binding *b2 = NULL;
471         struct dcerpc_pipe *p2 = NULL;
472
473         b2 = dcerpc_binding_dup(tctx, p1->binding);
474         torture_assert(tctx, b2 != NULL, "dcerpc_binding_dup");
475         dcerpc_binding_set_flags(b2,
476                                  DCERPC_SCHANNEL | additional_flags,
477                                  DCERPC_AUTH_OPTIONS);
478
479         cli_credentials_set_netlogon_creds(machine_credentials, creds);
480         status = dcerpc_pipe_connect_b(tctx, &p2, b2,
481                                        &ndr_table_netlogon,
482                                        machine_credentials,
483                                        tctx->ev, tctx->lp_ctx);
484         cli_credentials_set_netlogon_creds(machine_credentials, NULL);
485         torture_assert_ntstatus_ok(tctx, status, "dcerpc_pipe_connect_b schannel");
486
487         *_p2 = p2;
488         return true;
489 }
490
491 static bool test_ServerReqChallenge(
492         struct torture_context *tctx,
493         struct dcerpc_pipe *p,
494         struct cli_credentials *credentials)
495 {
496         struct netr_ServerReqChallenge r;
497         struct netr_Credential credentials1, credentials2, credentials3;
498         const char *machine_name;
499         struct dcerpc_binding_handle *b = p->binding_handle;
500         struct netr_ServerAuthenticate2 a;
501         uint32_t in_negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
502         uint32_t out_negotiate_flags = 0;
503         const struct samr_Password *mach_password = NULL;
504         enum netr_SchannelType sec_chan_type = 0;
505         struct netlogon_creds_CredentialState *creds = NULL;
506         const char *account_name = NULL;
507
508         machine_name = cli_credentials_get_workstation(credentials);
509         mach_password = cli_credentials_get_nt_hash(credentials, tctx);
510         account_name = cli_credentials_get_username(credentials);
511         sec_chan_type = cli_credentials_get_secure_channel_type(credentials);
512
513         torture_comment(tctx, "Testing ServerReqChallenge\n");
514
515         r.in.server_name = NULL;
516         r.in.computer_name = machine_name;
517         r.in.credentials = &credentials1;
518         r.out.return_credentials = &credentials2;
519
520         netlogon_creds_random_challenge(&credentials1);
521
522         torture_assert_ntstatus_ok(
523                 tctx,
524                 dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
525                 "ServerReqChallenge failed");
526         torture_assert_ntstatus_ok(
527                 tctx,
528                 r.out.result,
529                 "ServerReqChallenge failed");
530         a.in.server_name = NULL;
531         a.in.account_name = account_name;
532         a.in.secure_channel_type = sec_chan_type;
533         a.in.computer_name = machine_name;
534         a.in.negotiate_flags = &in_negotiate_flags;
535         a.out.negotiate_flags = &out_negotiate_flags;
536         a.in.credentials = &credentials3;
537         a.out.return_credentials = &credentials3;
538
539         creds = netlogon_creds_client_init(tctx, a.in.account_name,
540                                            a.in.computer_name,
541                                            a.in.secure_channel_type,
542                                            &credentials1, &credentials2,
543                                            mach_password, &credentials3,
544                                            in_negotiate_flags);
545
546         torture_assert(tctx, creds != NULL, "memory allocation");
547
548         torture_comment(tctx, "Testing ServerAuthenticate2\n");
549
550         torture_assert_ntstatus_ok(
551                 tctx,
552                 dcerpc_netr_ServerAuthenticate2_r(b, tctx, &a),
553                 "ServerAuthenticate2 failed");
554         torture_assert_ntstatus_equal(
555                 tctx,
556                 a.out.result,
557                 NT_STATUS_OK,
558                 "ServerAuthenticate2 unexpected");
559
560         return true;
561 }
562
563 static bool test_ServerReqChallenge_zero_challenge(
564         struct torture_context *tctx,
565         struct dcerpc_pipe *p,
566         struct cli_credentials *credentials)
567 {
568         struct netr_ServerReqChallenge r;
569         struct netr_Credential credentials1, credentials2, credentials3;
570         const char *machine_name;
571         struct dcerpc_binding_handle *b = p->binding_handle;
572         struct netr_ServerAuthenticate2 a;
573         uint32_t in_negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
574         uint32_t out_negotiate_flags = 0;
575         const struct samr_Password *mach_password = NULL;
576         enum netr_SchannelType sec_chan_type = 0;
577         struct netlogon_creds_CredentialState *creds = NULL;
578         const char *account_name = NULL;
579
580         machine_name = cli_credentials_get_workstation(credentials);
581         mach_password = cli_credentials_get_nt_hash(credentials, tctx);
582         account_name = cli_credentials_get_username(credentials);
583         sec_chan_type = cli_credentials_get_secure_channel_type(credentials);
584
585         torture_comment(tctx, "Testing ServerReqChallenge\n");
586
587         r.in.server_name = NULL;
588         r.in.computer_name = machine_name;
589         r.in.credentials = &credentials1;
590         r.out.return_credentials = &credentials2;
591
592         /*
593          * Set the client challenge to zero, this should fail
594          * CVE-2020-1472(ZeroLogon)
595          * BUG: https://bugzilla.samba.org/show_bug.cgi?id=14497
596          */
597         ZERO_STRUCT(credentials1);
598
599         torture_assert_ntstatus_ok(
600                 tctx,
601                 dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
602                 "ServerReqChallenge failed");
603         torture_assert_ntstatus_ok(
604                 tctx,
605                 r.out.result,
606                 "ServerReqChallenge failed");
607         a.in.server_name = NULL;
608         a.in.account_name = account_name;
609         a.in.secure_channel_type = sec_chan_type;
610         a.in.computer_name = machine_name;
611         a.in.negotiate_flags = &in_negotiate_flags;
612         a.out.negotiate_flags = &out_negotiate_flags;
613         a.in.credentials = &credentials3;
614         a.out.return_credentials = &credentials3;
615
616         creds = netlogon_creds_client_init(tctx, a.in.account_name,
617                                            a.in.computer_name,
618                                            a.in.secure_channel_type,
619                                            &credentials1, &credentials2,
620                                            mach_password, &credentials3,
621                                            in_negotiate_flags);
622
623         torture_assert(tctx, creds != NULL, "memory allocation");
624
625         torture_comment(tctx, "Testing ServerAuthenticate2\n");
626
627         torture_assert_ntstatus_ok(
628                 tctx,
629                 dcerpc_netr_ServerAuthenticate2_r(b, tctx, &a),
630                 "ServerAuthenticate2 failed");
631         torture_assert_ntstatus_equal(
632                 tctx,
633                 a.out.result,
634                 NT_STATUS_ACCESS_DENIED,
635                 "ServerAuthenticate2 unexpected");
636
637         return true;
638 }
639
640 static bool test_ServerReqChallenge_5_repeats(
641         struct torture_context *tctx,
642         struct dcerpc_pipe *p,
643         struct cli_credentials *credentials)
644 {
645         struct netr_ServerReqChallenge r;
646         struct netr_Credential credentials1, credentials2, credentials3;
647         const char *machine_name;
648         struct dcerpc_binding_handle *b = p->binding_handle;
649         struct netr_ServerAuthenticate2 a;
650         uint32_t in_negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
651         uint32_t out_negotiate_flags = 0;
652         const struct samr_Password *mach_password = NULL;
653         enum netr_SchannelType sec_chan_type = 0;
654         struct netlogon_creds_CredentialState *creds = NULL;
655         const char *account_name = NULL;
656
657         machine_name = cli_credentials_get_workstation(credentials);
658         mach_password = cli_credentials_get_nt_hash(credentials, tctx);
659         account_name = cli_credentials_get_username(credentials);
660         sec_chan_type = cli_credentials_get_secure_channel_type(credentials);
661
662         torture_comment(tctx, "Testing ServerReqChallenge\n");
663
664         r.in.server_name = NULL;
665         r.in.computer_name = machine_name;
666         r.in.credentials = &credentials1;
667         r.out.return_credentials = &credentials2;
668
669         /*
670          * Set the first 5 bytes of the client challenge to the same value,
671          * this should fail CVE-2020-1472(ZeroLogon)
672          * BUG: https://bugzilla.samba.org/show_bug.cgi?id=14497
673          */
674         credentials1.data[0] = 'A';
675         credentials1.data[1] = 'A';
676         credentials1.data[2] = 'A';
677         credentials1.data[3] = 'A';
678         credentials1.data[4] = 'A';
679         credentials1.data[5] = 'B';
680         credentials1.data[6] = 'C';
681         credentials1.data[7] = 'D';
682
683         torture_assert_ntstatus_ok(
684                 tctx,
685                 dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
686                 "ServerReqChallenge failed");
687         torture_assert_ntstatus_ok(
688                 tctx,
689                 r.out.result,
690                 "ServerReqChallenge failed");
691         a.in.server_name = NULL;
692         a.in.account_name = account_name;
693         a.in.secure_channel_type = sec_chan_type;
694         a.in.computer_name = machine_name;
695         a.in.negotiate_flags = &in_negotiate_flags;
696         a.out.negotiate_flags = &out_negotiate_flags;
697         a.in.credentials = &credentials3;
698         a.out.return_credentials = &credentials3;
699
700         creds = netlogon_creds_client_init(tctx, a.in.account_name,
701                                            a.in.computer_name,
702                                            a.in.secure_channel_type,
703                                            &credentials1, &credentials2,
704                                            mach_password, &credentials3,
705                                            in_negotiate_flags);
706
707         torture_assert(tctx, creds != NULL, "memory allocation");
708
709         torture_comment(tctx, "Testing ServerAuthenticate2\n");
710
711         torture_assert_ntstatus_ok(
712                 tctx,
713                 dcerpc_netr_ServerAuthenticate2_r(b, tctx, &a),
714                 "ServerAuthenticate2 failed");
715         torture_assert_ntstatus_equal(
716                 tctx,
717                 a.out.result,
718                 NT_STATUS_ACCESS_DENIED,
719                 "ServerAuthenticate2 unexpected");
720
721         return true;
722 }
723
724 static bool test_ServerReqChallenge_4_repeats(
725         struct torture_context *tctx,
726         struct dcerpc_pipe *p,
727         struct cli_credentials *credentials)
728 {
729         struct netr_ServerReqChallenge r;
730         struct netr_Credential credentials1, credentials2, credentials3;
731         const char *machine_name;
732         struct dcerpc_binding_handle *b = p->binding_handle;
733         struct netr_ServerAuthenticate2 a;
734         uint32_t in_negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
735         uint32_t out_negotiate_flags = 0;
736         const struct samr_Password *mach_password = NULL;
737         enum netr_SchannelType sec_chan_type = 0;
738         struct netlogon_creds_CredentialState *creds = NULL;
739         const char *account_name = NULL;
740
741         machine_name = cli_credentials_get_workstation(credentials);
742         mach_password = cli_credentials_get_nt_hash(credentials, tctx);
743         account_name = cli_credentials_get_username(credentials);
744         sec_chan_type = cli_credentials_get_secure_channel_type(credentials);
745
746         torture_comment(tctx, "Testing ServerReqChallenge\n");
747
748         r.in.server_name = NULL;
749         r.in.computer_name = machine_name;
750         r.in.credentials = &credentials1;
751         r.out.return_credentials = &credentials2;
752
753         /*
754          * Set the first 4 bytes of the client challenge to the same
755          * value, this should pass as 5 bytes identical are needed to
756          * fail for CVE-2020-1472(ZeroLogon)
757          *
758          * BUG: https://bugzilla.samba.org/show_bug.cgi?id=14497
759          */
760         credentials1.data[0] = 'A';
761         credentials1.data[1] = 'A';
762         credentials1.data[2] = 'A';
763         credentials1.data[3] = 'A';
764         credentials1.data[4] = 'B';
765         credentials1.data[5] = 'C';
766         credentials1.data[6] = 'D';
767         credentials1.data[7] = 'E';
768
769         torture_assert_ntstatus_ok(
770                 tctx,
771                 dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
772                 "ServerReqChallenge failed");
773         torture_assert_ntstatus_ok(
774                 tctx,
775                 r.out.result,
776                 "ServerReqChallenge failed");
777         a.in.server_name = NULL;
778         a.in.account_name = account_name;
779         a.in.secure_channel_type = sec_chan_type;
780         a.in.computer_name = machine_name;
781         a.in.negotiate_flags = &in_negotiate_flags;
782         a.out.negotiate_flags = &out_negotiate_flags;
783         a.in.credentials = &credentials3;
784         a.out.return_credentials = &credentials3;
785
786         creds = netlogon_creds_client_init(tctx, a.in.account_name,
787                                            a.in.computer_name,
788                                            a.in.secure_channel_type,
789                                            &credentials1, &credentials2,
790                                            mach_password, &credentials3,
791                                            in_negotiate_flags);
792
793         torture_assert(tctx, creds != NULL, "memory allocation");
794
795         torture_comment(tctx, "Testing ServerAuthenticate2\n");
796
797         torture_assert_ntstatus_ok(
798                 tctx,
799                 dcerpc_netr_ServerAuthenticate2_r(b, tctx, &a),
800                 "ServerAuthenticate2 failed");
801         torture_assert_ntstatus_equal(
802                 tctx,
803                 a.out.result,
804                 NT_STATUS_OK,
805                 "ServerAuthenticate2 unexpected");
806
807         return true;
808 }
809
810 /*
811  * Establish a NetLogon session, using a session key that encrypts the
812  * target character to zero
813  */
814 static bool test_ServerAuthenticate2_encrypts_to_zero(
815         struct torture_context *tctx,
816         struct dcerpc_pipe *p,
817         struct cli_credentials *machine_credentials,
818         const char target,
819         struct netlogon_creds_CredentialState **creds_out)
820 {
821         const char *computer_name =
822                 cli_credentials_get_workstation(machine_credentials);
823         struct netr_ServerReqChallenge r;
824         struct netr_ServerAuthenticate2 a;
825         struct netr_Credential credentials1, credentials2, credentials3;
826         struct netlogon_creds_CredentialState *creds  = NULL;
827         const struct samr_Password *mach_password;
828         struct dcerpc_binding_handle *b = p->binding_handle;
829         const char *account_name = cli_credentials_get_username(
830                 machine_credentials);
831         uint32_t flags =
832                 NETLOGON_NEG_AUTH2_ADS_FLAGS |
833                 NETLOGON_NEG_SUPPORTS_AES;
834         enum netr_SchannelType sec_chan_type =
835                 cli_credentials_get_secure_channel_type(machine_credentials);
836         /*
837          * Limit the number of attempts to generate a suitable session key.
838          */
839         const unsigned MAX_ITER = 4096;
840         unsigned i = 0;
841
842         mach_password = cli_credentials_get_nt_hash(machine_credentials, tctx);
843
844         r.in.server_name = NULL;
845         r.in.computer_name = computer_name;
846         r.in.credentials = &credentials1;
847         r.out.return_credentials = &credentials2;
848
849         netlogon_creds_random_challenge(&credentials1);
850         credentials1.data[0] = target;
851         i = 0;
852         torture_comment(tctx, "Generating candidate session keys\n");
853         do {
854                 TALLOC_FREE(creds);
855                 i++;
856
857                 torture_assert_ntstatus_ok(
858                         tctx,
859                         dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
860                         "ServerReqChallenge failed");
861                 torture_assert_ntstatus_ok(
862                         tctx,
863                         r.out.result,
864                         "ServerReqChallenge failed");
865
866                 a.in.server_name = NULL;
867                 a.in.account_name = account_name;
868                 a.in.secure_channel_type = sec_chan_type;
869                 a.in.computer_name = computer_name;
870                 a.in.negotiate_flags = &flags;
871                 a.out.negotiate_flags = &flags;
872                 a.in.credentials = &credentials3;
873                 a.out.return_credentials = &credentials3;
874
875                 creds = netlogon_creds_client_init(
876                         tctx,
877                         a.in.account_name,
878                         a.in.computer_name,
879                         a.in.secure_channel_type,
880                         &credentials1,
881                         &credentials2,
882                         mach_password,
883                         &credentials3,
884                         flags);
885
886                 torture_assert(tctx, creds != NULL, "memory allocation");
887         } while (credentials3.data[0] != 0 && i < MAX_ITER);
888
889         if (i >= MAX_ITER) {
890                 torture_comment(
891                         tctx,
892                         "Unable to obtain a suitable session key, "
893                         "after [%u] attempts\n",
894                         i);
895                 torture_fail(tctx, "Unable obtain suitable session key");
896         }
897
898         torture_assert_ntstatus_ok(
899                 tctx,
900                 dcerpc_netr_ServerAuthenticate2_r(b, tctx, &a),
901                 "ServerAuthenticate2 failed");
902         torture_assert_ntstatus_equal(
903                 tctx,
904                 a.out.result,
905                 NT_STATUS_OK,
906                 "ServerAuthenticate2 unexpected result code");
907
908         *creds_out = creds;
909         return true;
910 }
911
912 /*
913   try a change password for our machine account
914 */
915 static bool test_SetPassword(struct torture_context *tctx,
916                              struct dcerpc_pipe *p,
917                              struct cli_credentials *machine_credentials)
918 {
919         struct netr_ServerPasswordSet r;
920         const char *password;
921         struct netlogon_creds_CredentialState *creds;
922         struct netr_Authenticator credential, return_authenticator;
923         struct samr_Password new_password;
924         struct dcerpc_binding_handle *b = p->binding_handle;
925
926         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
927                 return false;
928         }
929
930         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
931         r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
932         r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
933         r.in.computer_name = TEST_MACHINE_NAME;
934         r.in.credential = &credential;
935         r.in.new_password = &new_password;
936         r.out.return_authenticator = &return_authenticator;
937
938         password = generate_random_password(tctx, 8, 255);
939         E_md4hash(password, new_password.hash);
940
941         netlogon_creds_des_encrypt(creds, &new_password);
942
943         torture_comment(tctx, "Testing ServerPasswordSet on machine account\n");
944         torture_comment(tctx, "Changing machine account password to '%s'\n",
945                         password);
946
947         netlogon_creds_client_authenticator(creds, &credential);
948
949         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet_r(b, tctx, &r),
950                 "ServerPasswordSet failed");
951         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet failed");
952
953         if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
954                 torture_comment(tctx, "Credential chaining failed\n");
955         }
956
957         /* by changing the machine password twice we test the
958            credentials chaining fully, and we verify that the server
959            allows the password to be set to the same value twice in a
960            row (match win2k3) */
961         torture_comment(tctx,
962                 "Testing a second ServerPasswordSet on machine account\n");
963         torture_comment(tctx,
964                 "Changing machine account password to '%s' (same as previous run)\n", password);
965
966         netlogon_creds_client_authenticator(creds, &credential);
967
968         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet_r(b, tctx, &r),
969                 "ServerPasswordSet (2) failed");
970         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet (2) failed");
971
972         if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
973                 torture_comment(tctx, "Credential chaining failed\n");
974         }
975
976         cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
977
978         torture_assert(tctx,
979                 test_SetupCredentials(p, tctx, machine_credentials, &creds),
980                 "ServerPasswordSet failed to actually change the password");
981
982         return true;
983 }
984
985 /*
986   try a change password for our machine account
987 */
988 static bool test_SetPassword_flags(struct torture_context *tctx,
989                                    struct dcerpc_pipe *p1,
990                                    struct cli_credentials *machine_credentials,
991                                    uint32_t negotiate_flags)
992 {
993         struct netr_ServerPasswordSet r;
994         const char *password;
995         struct netlogon_creds_CredentialState *creds;
996         struct netr_Authenticator credential, return_authenticator;
997         struct samr_Password new_password;
998         struct dcerpc_pipe *p = NULL;
999         struct dcerpc_binding_handle *b = NULL;
1000
1001         if (!test_SetupCredentials2(p1, tctx, negotiate_flags,
1002                                     machine_credentials,
1003                                     cli_credentials_get_secure_channel_type(machine_credentials),
1004                                     &creds)) {
1005                 return false;
1006         }
1007         if (!test_SetupCredentialsPipe(p1, tctx, machine_credentials, creds,
1008                                        DCERPC_SIGN | DCERPC_SEAL, &p)) {
1009                 return false;
1010         }
1011         b = p->binding_handle;
1012
1013         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1014         r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
1015         r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
1016         r.in.computer_name = TEST_MACHINE_NAME;
1017         r.in.credential = &credential;
1018         r.in.new_password = &new_password;
1019         r.out.return_authenticator = &return_authenticator;
1020
1021         password = generate_random_password(tctx, 8, 255);
1022         E_md4hash(password, new_password.hash);
1023
1024         netlogon_creds_des_encrypt(creds, &new_password);
1025
1026         torture_comment(tctx, "Testing ServerPasswordSet on machine account\n");
1027         torture_comment(tctx, "Changing machine account password to '%s'\n",
1028                         password);
1029
1030         netlogon_creds_client_authenticator(creds, &credential);
1031
1032         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet_r(b, tctx, &r),
1033                 "ServerPasswordSet failed");
1034         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet failed");
1035
1036         if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
1037                 torture_comment(tctx, "Credential chaining failed\n");
1038         }
1039
1040         /* by changing the machine password twice we test the
1041            credentials chaining fully, and we verify that the server
1042            allows the password to be set to the same value twice in a
1043            row (match win2k3) */
1044         torture_comment(tctx,
1045                 "Testing a second ServerPasswordSet on machine account\n");
1046         torture_comment(tctx,
1047                 "Changing machine account password to '%s' (same as previous run)\n", password);
1048
1049         netlogon_creds_client_authenticator(creds, &credential);
1050
1051         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet_r(b, tctx, &r),
1052                 "ServerPasswordSet (2) failed");
1053         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet (2) failed");
1054
1055         if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
1056                 torture_comment(tctx, "Credential chaining failed\n");
1057         }
1058
1059         cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
1060
1061         torture_assert(tctx,
1062                 test_SetupCredentials(p, tctx, machine_credentials, &creds),
1063                 "ServerPasswordSet failed to actually change the password");
1064
1065         return true;
1066 }
1067
1068
1069 /*
1070   generate a random password for password change tests
1071 */
1072 static DATA_BLOB netlogon_very_rand_pass(TALLOC_CTX *mem_ctx, int len)
1073 {
1074         int i;
1075         DATA_BLOB password = data_blob_talloc(mem_ctx, NULL, len * 2 /* number of unicode chars */);
1076         generate_random_buffer(password.data, password.length);
1077
1078         for (i=0; i < len; i++) {
1079                 if (((uint16_t *)password.data)[i] == 0) {
1080                         ((uint16_t *)password.data)[i] = 1;
1081                 }
1082         }
1083
1084         return password;
1085 }
1086
1087 /*
1088   try a change password for our machine account
1089 */
1090 static bool test_SetPassword2_with_flags(struct torture_context *tctx,
1091                                          struct dcerpc_pipe *p1,
1092                                          struct cli_credentials *machine_credentials,
1093                                          uint32_t flags)
1094 {
1095         struct netr_ServerPasswordSet2 r;
1096         const char *password;
1097         DATA_BLOB new_random_pass;
1098         struct netlogon_creds_CredentialState *creds;
1099         struct samr_CryptPassword password_buf;
1100         struct samr_Password nt_hash;
1101         struct netr_Authenticator credential, return_authenticator;
1102         struct netr_CryptPassword new_password;
1103         struct dcerpc_pipe *p = NULL;
1104         struct dcerpc_binding_handle *b = NULL;
1105
1106         if (!test_SetupCredentials2(p1, tctx, flags, machine_credentials,
1107                                     cli_credentials_get_secure_channel_type(machine_credentials),
1108                                     &creds)) {
1109                 return false;
1110         }
1111         if (!test_SetupCredentialsPipe(p1, tctx, machine_credentials, creds,
1112                                        DCERPC_SIGN | DCERPC_SEAL, &p)) {
1113                 return false;
1114         }
1115         b = p->binding_handle;
1116
1117         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1118         r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
1119         r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
1120         r.in.computer_name = TEST_MACHINE_NAME;
1121         r.in.credential = &credential;
1122         r.in.new_password = &new_password;
1123         r.out.return_authenticator = &return_authenticator;
1124
1125         password = generate_random_password(tctx, 8, 255);
1126         encode_pw_buffer(password_buf.data, password, STR_UNICODE);
1127         if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
1128                 netlogon_creds_aes_encrypt(creds, password_buf.data, 516);
1129         } else {
1130                 netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
1131         }
1132
1133         memcpy(new_password.data, password_buf.data, 512);
1134         new_password.length = IVAL(password_buf.data, 512);
1135
1136         torture_comment(tctx, "Testing ServerPasswordSet2 on machine account\n");
1137         torture_comment(tctx, "Changing machine account password to '%s'\n", password);
1138
1139         netlogon_creds_client_authenticator(creds, &credential);
1140
1141         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
1142                 "ServerPasswordSet2 failed");
1143         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet2 failed");
1144
1145         if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
1146                 torture_comment(tctx, "Credential chaining failed\n");
1147         }
1148
1149         cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
1150
1151         /*
1152          * As a consequence of CVE-2020-1472(ZeroLogon)
1153          * Samba explicitly disallows the setting of an empty machine account
1154          * password.
1155          *
1156          * Note that this may fail against Windows, and leave a machine account
1157          * with an empty password.
1158          */
1159         password = "";
1160         encode_pw_buffer(password_buf.data, password, STR_UNICODE);
1161         if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
1162                 netlogon_creds_aes_encrypt(creds, password_buf.data, 516);
1163         } else {
1164                 netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
1165         }
1166         memcpy(new_password.data, password_buf.data, 512);
1167         new_password.length = IVAL(password_buf.data, 512);
1168
1169         torture_comment(tctx,
1170                 "Testing ServerPasswordSet2 on machine account\n");
1171         torture_comment(tctx,
1172                 "Changing machine account password to '%s'\n", password);
1173
1174         netlogon_creds_client_authenticator(creds, &credential);
1175
1176         torture_assert_ntstatus_ok(
1177                 tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
1178                 "ServerPasswordSet2 failed");
1179         torture_assert_ntstatus_equal(
1180                 tctx,
1181                 r.out.result,
1182                 NT_STATUS_WRONG_PASSWORD,
1183                 "ServerPasswordSet2 did not return NT_STATUS_WRONG_PASSWORD");
1184
1185         /* now try a random password */
1186         password = generate_random_password(tctx, 8, 255);
1187         encode_pw_buffer(password_buf.data, password, STR_UNICODE);
1188         if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
1189                 netlogon_creds_aes_encrypt(creds, password_buf.data, 516);
1190         } else {
1191                 netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
1192         }
1193         memcpy(new_password.data, password_buf.data, 512);
1194         new_password.length = IVAL(password_buf.data, 512);
1195
1196         torture_comment(tctx, "Testing second ServerPasswordSet2 on machine account\n");
1197         torture_comment(tctx, "Changing machine account password to '%s'\n", password);
1198
1199         netlogon_creds_client_authenticator(creds, &credential);
1200
1201         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
1202                 "ServerPasswordSet2 (2) failed");
1203         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet2 (2) failed");
1204
1205         if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
1206                 torture_comment(tctx, "Credential chaining failed\n");
1207         }
1208
1209         /* by changing the machine password twice we test the
1210            credentials chaining fully, and we verify that the server
1211            allows the password to be set to the same value twice in a
1212            row (match win2k3) */
1213         torture_comment(tctx,
1214                 "Testing a second ServerPasswordSet2 on machine account\n");
1215         torture_comment(tctx,
1216                 "Changing machine account password to '%s' (same as previous run)\n", password);
1217
1218         netlogon_creds_client_authenticator(creds, &credential);
1219
1220         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
1221                 "ServerPasswordSet (3) failed");
1222         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet (3) failed");
1223
1224         if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
1225                 torture_comment(tctx, "Credential chaining failed\n");
1226         }
1227
1228         cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
1229
1230         torture_assert (tctx,
1231                 test_SetupCredentials(p, tctx, machine_credentials, &creds),
1232                 "ServerPasswordSet failed to actually change the password");
1233
1234         new_random_pass = netlogon_very_rand_pass(tctx, 128);
1235
1236         /* now try a random stream of bytes for a password */
1237         set_pw_in_buffer(password_buf.data, &new_random_pass);
1238
1239         if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
1240                 netlogon_creds_aes_encrypt(creds, password_buf.data, 516);
1241         } else {
1242                 netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
1243         }
1244
1245         memcpy(new_password.data, password_buf.data, 512);
1246         new_password.length = IVAL(password_buf.data, 512);
1247
1248         torture_comment(tctx,
1249                 "Testing a third ServerPasswordSet2 on machine account, with a completely random password\n");
1250
1251         netlogon_creds_client_authenticator(creds, &credential);
1252
1253         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
1254                 "ServerPasswordSet (3) failed");
1255         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet (3) failed");
1256
1257         if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
1258                 torture_comment(tctx, "Credential chaining failed\n");
1259         }
1260
1261         mdfour(nt_hash.hash, new_random_pass.data, new_random_pass.length);
1262
1263         cli_credentials_set_password(machine_credentials, NULL, CRED_UNINITIALISED);
1264         cli_credentials_set_nt_hash(machine_credentials, &nt_hash, CRED_SPECIFIED);
1265
1266         torture_assert (tctx,
1267                 test_SetupCredentials(p, tctx, machine_credentials, &creds),
1268                 "ServerPasswordSet failed to actually change the password");
1269
1270         return true;
1271 }
1272
1273 /*
1274   try to change the password of our machine account using a buffer of all zeros,
1275   and a session key that encrypts that to all zeros.
1276
1277 Note: The test does use sign and seal, it's purpose is to exercise
1278       the detection code in dcesrv_netr_ServerPasswordSet2
1279 */
1280 static bool test_SetPassword2_encrypted_to_all_zeros(
1281         struct torture_context *tctx,
1282         struct dcerpc_pipe *p1,
1283         struct cli_credentials *machine_credentials)
1284 {
1285         struct netr_ServerPasswordSet2 r;
1286         struct netlogon_creds_CredentialState *creds;
1287         struct samr_CryptPassword password_buf;
1288         struct netr_Authenticator credential, return_authenticator;
1289         struct netr_CryptPassword new_password;
1290         struct dcerpc_pipe *p = NULL;
1291         struct dcerpc_binding_handle *b = NULL;
1292
1293         if (!test_ServerAuthenticate2_encrypts_to_zero(
1294                 tctx,
1295                 p1,
1296                 machine_credentials,
1297                 '\0',
1298                 &creds)) {
1299
1300                 return false;
1301         }
1302
1303         if (!test_SetupCredentialsPipe(
1304                 p1,
1305                 tctx,
1306                 machine_credentials,
1307                 creds,
1308                 DCERPC_SIGN | DCERPC_SEAL,
1309                 &p))
1310         {
1311                 return false;
1312         }
1313         b = p->binding_handle;
1314
1315         r.in.server_name = talloc_asprintf(
1316                 tctx,
1317                 "\\\\%s", dcerpc_server_name(p));
1318         r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
1319         r.in.secure_channel_type =
1320                 cli_credentials_get_secure_channel_type(machine_credentials);
1321         r.in.computer_name = TEST_MACHINE_NAME;
1322         r.in.credential = &credential;
1323         r.in.new_password = &new_password;
1324         r.out.return_authenticator = &return_authenticator;
1325
1326         ZERO_STRUCT(password_buf);
1327
1328         if (!(creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES)) {
1329                 torture_fail(tctx, "NETLOGON_NEG_SUPPORTS_AES not set");
1330         }
1331         netlogon_creds_aes_encrypt(creds, password_buf.data, 516);
1332         if(!all_zero(password_buf.data, 516)) {
1333                 torture_fail(tctx, "Password did not encrypt to all zeros\n");
1334         }
1335
1336         memcpy(new_password.data, password_buf.data, 512);
1337         new_password.length = IVAL(password_buf.data, 512);
1338         torture_assert_int_equal(
1339                 tctx,
1340                 new_password.length,
1341                 0,
1342                 "Length should have encrypted to 0");
1343
1344         netlogon_creds_client_authenticator(creds, &credential);
1345
1346         torture_assert_ntstatus_ok(
1347                 tctx,
1348                 dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
1349                 "ServerPasswordSet2 zero length check failed");
1350         torture_assert_ntstatus_equal(
1351                 tctx, r.out.result, NT_STATUS_WRONG_PASSWORD, "");
1352
1353         return true;
1354 }
1355
1356 /*
1357  * Choose a session key that encrypts a password of all zeros to all zeros.
1358  * Then try to set the password, using a zeroed buffer, with a non zero
1359  * length.
1360  *
1361  * This exercises the password self encryption check.
1362  *
1363  * Note: The test does use sign and seal, it's purpose is to exercise
1364  *     the detection code in dcesrv_netr_ServerPasswordSet2
1365 */
1366 static bool test_SetPassword2_password_encrypts_to_zero(
1367         struct torture_context *tctx,
1368         struct dcerpc_pipe *p1,
1369         struct cli_credentials *machine_credentials)
1370 {
1371         struct netr_ServerPasswordSet2 r;
1372         struct netlogon_creds_CredentialState *creds;
1373         struct samr_CryptPassword password_buf;
1374         struct netr_Authenticator credential, return_authenticator;
1375         struct netr_CryptPassword new_password;
1376         struct dcerpc_pipe *p = NULL;
1377         struct dcerpc_binding_handle *b = NULL;
1378
1379         if (!test_ServerAuthenticate2_encrypts_to_zero(
1380                 tctx,
1381                 p1,
1382                 machine_credentials,
1383                 0x00,
1384                 &creds)) {
1385
1386                 return false;
1387         }
1388
1389         if (!test_SetupCredentialsPipe(
1390                 p1,
1391                 tctx,
1392                 machine_credentials,
1393                 creds,
1394                 DCERPC_SIGN | DCERPC_SEAL,
1395                 &p))
1396         {
1397                 return false;
1398         }
1399         b = p->binding_handle;
1400
1401         r.in.server_name = talloc_asprintf(
1402                 tctx,
1403                 "\\\\%s", dcerpc_server_name(p));
1404         r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
1405         r.in.secure_channel_type =
1406                 cli_credentials_get_secure_channel_type(machine_credentials);
1407         r.in.computer_name = TEST_MACHINE_NAME;
1408         r.in.credential = &credential;
1409         r.in.new_password = &new_password;
1410         r.out.return_authenticator = &return_authenticator;
1411
1412         ZERO_STRUCT(password_buf);
1413         SIVAL(password_buf.data, 512, 512);
1414
1415         if (!(creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES)) {
1416                 torture_fail(tctx, "NETLOGON_NEG_SUPPORTS_AES not set");
1417         }
1418         netlogon_creds_aes_encrypt(creds, password_buf.data, 516);
1419
1420         memcpy(new_password.data, password_buf.data, 512);
1421         new_password.length = IVAL(password_buf.data, 512);
1422
1423         netlogon_creds_client_authenticator(creds, &credential);
1424
1425         torture_assert_ntstatus_ok(
1426                 tctx,
1427                 dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
1428                 "ServerPasswordSet2 password encrypts to zero check failed");
1429         torture_assert_ntstatus_equal(
1430                 tctx, r.out.result, NT_STATUS_WRONG_PASSWORD, "");
1431
1432         return true;
1433 }
1434
1435 /*
1436  * Check that an all zero confounder, that encrypts to all zeros is
1437  * rejected.
1438  *
1439  * Note: The test does use sign and seal, it's purpose is to exercise
1440  *       the detection code in dcesrv_netr_ServerPasswordSet2
1441  */
1442 static bool test_SetPassword2_confounder(
1443         struct torture_context *tctx,
1444         struct dcerpc_pipe *p1,
1445         struct cli_credentials *machine_credentials)
1446 {
1447         struct netr_ServerPasswordSet2 r;
1448         struct netlogon_creds_CredentialState *creds;
1449         struct samr_CryptPassword password_buf;
1450         struct netr_Authenticator credential, return_authenticator;
1451         struct netr_CryptPassword new_password;
1452         struct dcerpc_pipe *p = NULL;
1453         struct dcerpc_binding_handle *b = NULL;
1454
1455         if (!test_ServerAuthenticate2_encrypts_to_zero(
1456                 tctx,
1457                 p1,
1458                 machine_credentials,
1459                 '\0',
1460                 &creds)) {
1461
1462                 return false;
1463         }
1464
1465         if (!test_SetupCredentialsPipe(
1466                 p1,
1467                 tctx,
1468                 machine_credentials,
1469                 creds,
1470                 DCERPC_SIGN | DCERPC_SEAL,
1471                 &p))
1472         {
1473                 return false;
1474         }
1475         b = p->binding_handle;
1476
1477         r.in.server_name = talloc_asprintf(
1478                 tctx,
1479                 "\\\\%s", dcerpc_server_name(p));
1480         r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
1481         r.in.secure_channel_type =
1482                 cli_credentials_get_secure_channel_type(machine_credentials);
1483         r.in.computer_name = TEST_MACHINE_NAME;
1484         r.in.credential = &credential;
1485         r.in.new_password = &new_password;
1486         r.out.return_authenticator = &return_authenticator;
1487
1488         ZERO_STRUCT(password_buf);
1489         password_buf.data[511] = 'A';
1490         SIVAL(password_buf.data, 512, 2);
1491
1492         if (!(creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES)) {
1493                 torture_fail(tctx, "NETLOGON_NEG_SUPPORTS_AES not set");
1494         }
1495         netlogon_creds_aes_encrypt(creds, password_buf.data, 516);
1496
1497         memcpy(new_password.data, password_buf.data, 512);
1498         new_password.length = IVAL(password_buf.data, 512);
1499
1500         netlogon_creds_client_authenticator(creds, &credential);
1501
1502         torture_assert_ntstatus_ok(
1503                 tctx,
1504                 dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
1505                 "ServerPasswordSet2 confounder check failed");
1506         torture_assert_ntstatus_equal(
1507                 tctx, r.out.result, NT_STATUS_WRONG_PASSWORD, "");
1508
1509         return true;
1510 }
1511
1512 /*
1513  * try a change password for our machine account, using an all zero
1514  *  request. This should fail on the zero length check.
1515  *
1516  * Note: This test uses ARC4 encryption to exercise the desired check.
1517  */
1518 static bool test_SetPassword2_all_zeros(
1519         struct torture_context *tctx,
1520         struct dcerpc_pipe *p1,
1521         struct cli_credentials *machine_credentials)
1522 {
1523         struct netr_ServerPasswordSet2 r;
1524         struct netlogon_creds_CredentialState *creds;
1525         struct samr_CryptPassword password_buf;
1526         struct netr_Authenticator credential, return_authenticator;
1527         struct netr_CryptPassword new_password;
1528         struct dcerpc_pipe *p = NULL;
1529         struct dcerpc_binding_handle *b = NULL;
1530         uint32_t flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
1531
1532         if (!test_SetupCredentials2(
1533                 p1,
1534                 tctx,
1535                 flags,
1536                 machine_credentials,
1537                 cli_credentials_get_secure_channel_type(machine_credentials),
1538                 &creds))
1539         {
1540                 return false;
1541         }
1542         if (!test_SetupCredentialsPipe(
1543                 p1,
1544                 tctx,
1545                 machine_credentials,
1546                 creds,
1547                 DCERPC_SIGN | DCERPC_SEAL,
1548                 &p))
1549         {
1550                 return false;
1551         }
1552         b = p->binding_handle;
1553
1554         r.in.server_name = talloc_asprintf(
1555                 tctx,
1556                 "\\\\%s", dcerpc_server_name(p));
1557         r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
1558         r.in.secure_channel_type =
1559                 cli_credentials_get_secure_channel_type(machine_credentials);
1560         r.in.computer_name = TEST_MACHINE_NAME;
1561         r.in.credential = &credential;
1562         r.in.new_password = &new_password;
1563         r.out.return_authenticator = &return_authenticator;
1564
1565         ZERO_STRUCT(password_buf.data);
1566         if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
1567                 torture_fail(tctx, "NETLOGON_NEG_SUPPORTS_AES enabled\n");
1568         }
1569         netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
1570
1571         memcpy(new_password.data, password_buf.data, 512);
1572         new_password.length = IVAL(password_buf.data, 512);
1573
1574         torture_comment(
1575                 tctx,
1576                 "Testing ServerPasswordSet2 on machine account\n");
1577
1578         netlogon_creds_client_authenticator(creds, &credential);
1579
1580         torture_assert_ntstatus_ok(
1581                 tctx,
1582                 dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
1583                 "ServerPasswordSet2 zero length check failed");
1584         torture_assert_ntstatus_equal(
1585                 tctx, r.out.result, NT_STATUS_WRONG_PASSWORD, "");
1586
1587         return true;
1588 }
1589
1590 /*
1591   try a change password for our machine account, using a maximum length
1592   password
1593 */
1594 static bool test_SetPassword2_maximum_length_password(
1595         struct torture_context *tctx,
1596         struct dcerpc_pipe *p1,
1597         struct cli_credentials *machine_credentials)
1598 {
1599         struct netr_ServerPasswordSet2 r;
1600         struct netlogon_creds_CredentialState *creds;
1601         struct samr_CryptPassword password_buf;
1602         struct netr_Authenticator credential, return_authenticator;
1603         struct netr_CryptPassword new_password;
1604         struct dcerpc_pipe *p = NULL;
1605         struct dcerpc_binding_handle *b = NULL;
1606         uint32_t flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
1607         DATA_BLOB new_random_pass = data_blob_null;
1608
1609         if (!test_SetupCredentials2(
1610                 p1,
1611                 tctx,
1612                 flags,
1613                 machine_credentials,
1614                 cli_credentials_get_secure_channel_type(machine_credentials),
1615                 &creds))
1616         {
1617                 return false;
1618         }
1619         if (!test_SetupCredentialsPipe(
1620                 p1,
1621                 tctx,
1622                 machine_credentials,
1623                 creds,
1624                 DCERPC_SIGN | DCERPC_SEAL,
1625                 &p))
1626         {
1627                 return false;
1628         }
1629         b = p->binding_handle;
1630
1631         r.in.server_name = talloc_asprintf(
1632                 tctx,
1633                 "\\\\%s", dcerpc_server_name(p));
1634         r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
1635         r.in.secure_channel_type =
1636                 cli_credentials_get_secure_channel_type(machine_credentials);
1637         r.in.computer_name = TEST_MACHINE_NAME;
1638         r.in.credential = &credential;
1639         r.in.new_password = &new_password;
1640         r.out.return_authenticator = &return_authenticator;
1641
1642         new_random_pass = netlogon_very_rand_pass(tctx, 256);
1643         set_pw_in_buffer(password_buf.data, &new_random_pass);
1644         SIVAL(password_buf.data, 512, 512);
1645         if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
1646                 netlogon_creds_aes_encrypt(creds, password_buf.data, 516);
1647         } else {
1648                 netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
1649         }
1650
1651         memcpy(new_password.data, password_buf.data, 512);
1652         new_password.length = IVAL(password_buf.data, 512);
1653
1654         torture_comment(
1655                 tctx,
1656                 "Testing ServerPasswordSet2 on machine account\n");
1657
1658         netlogon_creds_client_authenticator(creds, &credential);
1659
1660         torture_assert_ntstatus_ok(
1661                 tctx,
1662                 dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
1663                 "ServerPasswordSet2 zero length check failed");
1664         torture_assert_ntstatus_equal(
1665                 tctx, r.out.result, NT_STATUS_OK, "");
1666
1667         return true;
1668 }
1669
1670 /*
1671   try a change password for our machine account, using a password of
1672   all zeros, and a non zero password length.
1673
1674   This test relies on the buffer being encrypted with ARC4, to
1675   trigger the appropriate check in the rpc server code
1676 */
1677 static bool test_SetPassword2_all_zero_password(
1678         struct torture_context *tctx,
1679         struct dcerpc_pipe *p1,
1680         struct cli_credentials *machine_credentials)
1681 {
1682         struct netr_ServerPasswordSet2 r;
1683         struct netlogon_creds_CredentialState *creds;
1684         struct samr_CryptPassword password_buf;
1685         struct netr_Authenticator credential, return_authenticator;
1686         struct netr_CryptPassword new_password;
1687         struct dcerpc_pipe *p = NULL;
1688         struct dcerpc_binding_handle *b = NULL;
1689         uint32_t flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
1690
1691         if (!test_SetupCredentials2(
1692                 p1,
1693                 tctx,
1694                 flags,
1695                 machine_credentials,
1696                 cli_credentials_get_secure_channel_type(machine_credentials),
1697                 &creds))
1698         {
1699                 return false;
1700         }
1701         if (!test_SetupCredentialsPipe(
1702                 p1,
1703                 tctx,
1704                 machine_credentials,
1705                 creds,
1706                 DCERPC_SIGN | DCERPC_SEAL,
1707                 &p))
1708         {
1709                 return false;
1710         }
1711         b = p->binding_handle;
1712
1713         r.in.server_name = talloc_asprintf(
1714                 tctx,
1715                 "\\\\%s", dcerpc_server_name(p));
1716         r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
1717         r.in.secure_channel_type =
1718                 cli_credentials_get_secure_channel_type(machine_credentials);
1719         r.in.computer_name = TEST_MACHINE_NAME;
1720         r.in.credential = &credential;
1721         r.in.new_password = &new_password;
1722         r.out.return_authenticator = &return_authenticator;
1723
1724         ZERO_STRUCT(password_buf.data);
1725         SIVAL(password_buf.data, 512, 128);
1726         if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
1727                 torture_fail(tctx, "NETLOGON_NEG_SUPPORTS_AES set");
1728         }
1729         netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
1730
1731         memcpy(new_password.data, password_buf.data, 512);
1732         new_password.length = IVAL(password_buf.data, 512);
1733
1734         torture_comment(
1735                 tctx,
1736                 "Testing ServerPasswordSet2 on machine account\n");
1737
1738         netlogon_creds_client_authenticator(creds, &credential);
1739
1740         torture_assert_ntstatus_ok(
1741                 tctx,
1742                 dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
1743                 "ServerPasswordSet2 all zero password check failed");
1744         torture_assert_ntstatus_equal(
1745                 tctx, r.out.result, NT_STATUS_WRONG_PASSWORD, "");
1746
1747         return true;
1748 }
1749
1750
1751 static bool test_SetPassword2(struct torture_context *tctx,
1752                               struct dcerpc_pipe *p,
1753                               struct cli_credentials *machine_credentials)
1754 {
1755         return test_SetPassword2_with_flags(tctx, p, machine_credentials, NETLOGON_NEG_AUTH2_ADS_FLAGS);
1756 }
1757
1758 static bool test_SetPassword2_AES(struct torture_context *tctx,
1759                                   struct dcerpc_pipe *p,
1760                                   struct cli_credentials *machine_credentials)
1761 {
1762         return test_SetPassword2_with_flags(tctx, p, machine_credentials, NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES);
1763 }
1764
1765 static bool test_GetPassword(struct torture_context *tctx,
1766                              struct dcerpc_pipe *p,
1767                              struct cli_credentials *machine_credentials)
1768 {
1769         struct netr_ServerPasswordGet r;
1770         struct netlogon_creds_CredentialState *creds;
1771         struct netr_Authenticator credential;
1772         NTSTATUS status;
1773         struct netr_Authenticator return_authenticator;
1774         struct samr_Password password;
1775         struct dcerpc_binding_handle *b = p->binding_handle;
1776
1777         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1778                 return false;
1779         }
1780
1781         netlogon_creds_client_authenticator(creds, &credential);
1782
1783         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1784         r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
1785         r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
1786         r.in.computer_name = TEST_MACHINE_NAME;
1787         r.in.credential = &credential;
1788         r.out.return_authenticator = &return_authenticator;
1789         r.out.password = &password;
1790
1791         status = dcerpc_netr_ServerPasswordGet_r(b, tctx, &r);
1792         torture_assert_ntstatus_ok(tctx, status, "ServerPasswordGet");
1793         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordGet");
1794
1795         return true;
1796 }
1797
1798 static bool test_GetTrustPasswords(struct torture_context *tctx,
1799                                    struct dcerpc_pipe *p,
1800                                    struct cli_credentials *machine_credentials)
1801 {
1802         struct netr_ServerTrustPasswordsGet r;
1803         struct netlogon_creds_CredentialState *creds;
1804         struct netr_Authenticator credential;
1805         struct netr_Authenticator return_authenticator;
1806         struct samr_Password password, password2;
1807         struct dcerpc_binding_handle *b = p->binding_handle;
1808
1809         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1810                 return false;
1811         }
1812
1813         netlogon_creds_client_authenticator(creds, &credential);
1814
1815         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1816         r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
1817         r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
1818         r.in.computer_name = TEST_MACHINE_NAME;
1819         r.in.credential = &credential;
1820         r.out.return_authenticator = &return_authenticator;
1821         r.out.new_owf_password = &password;
1822         r.out.old_owf_password = &password2;
1823
1824         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerTrustPasswordsGet_r(b, tctx, &r),
1825                 "ServerTrustPasswordsGet failed");
1826         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerTrustPasswordsGet failed");
1827
1828         return true;
1829 }
1830
1831 /*
1832   try a netlogon SamLogon
1833 */
1834 static bool test_netlogon_ops_args(struct dcerpc_pipe *p, struct torture_context *tctx,
1835                                    struct cli_credentials *credentials,
1836                                    struct netlogon_creds_CredentialState *creds,
1837                                    bool null_domain)
1838 {
1839         NTSTATUS status;
1840         struct netr_LogonSamLogon r;
1841         struct netr_Authenticator auth, auth2;
1842         union netr_LogonLevel logon;
1843         union netr_Validation validation;
1844         uint8_t authoritative;
1845         struct netr_NetworkInfo ninfo;
1846         DATA_BLOB names_blob, chal, lm_resp, nt_resp;
1847         int i;
1848         struct dcerpc_binding_handle *b = p->binding_handle;
1849         int flags = CLI_CRED_NTLM_AUTH;
1850         if (lpcfg_client_lanman_auth(tctx->lp_ctx)) {
1851                 flags |= CLI_CRED_LANMAN_AUTH;
1852         }
1853
1854         if (lpcfg_client_ntlmv2_auth(tctx->lp_ctx) && !null_domain) {
1855                 flags |= CLI_CRED_NTLMv2_AUTH;
1856         }
1857
1858         cli_credentials_get_ntlm_username_domain(popt_get_cmdline_credentials(),
1859                                                  tctx,
1860                                                  &ninfo.identity_info.account_name.string,
1861                                                  &ninfo.identity_info.domain_name.string);
1862
1863         if (null_domain) {
1864                 ninfo.identity_info.domain_name.string = NULL;
1865         }
1866
1867         generate_random_buffer(ninfo.challenge,
1868                                sizeof(ninfo.challenge));
1869         chal = data_blob_const(ninfo.challenge,
1870                                sizeof(ninfo.challenge));
1871
1872         names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(credentials),
1873                                                 cli_credentials_get_domain(credentials));
1874
1875         status = cli_credentials_get_ntlm_response(
1876                                 popt_get_cmdline_credentials(), tctx,
1877                                 &flags,
1878                                 chal,
1879                                 NULL, /* server_timestamp */
1880                                 names_blob,
1881                                 &lm_resp, &nt_resp,
1882                                 NULL, NULL);
1883         torture_assert_ntstatus_ok(tctx, status, "cli_credentials_get_ntlm_response failed");
1884
1885         ninfo.lm.data = lm_resp.data;
1886         ninfo.lm.length = lm_resp.length;
1887
1888         ninfo.nt.data = nt_resp.data;
1889         ninfo.nt.length = nt_resp.length;
1890
1891         ninfo.identity_info.parameter_control = 0;
1892         ninfo.identity_info.logon_id = 0;
1893         ninfo.identity_info.workstation.string = cli_credentials_get_workstation(credentials);
1894
1895         logon.network = &ninfo;
1896
1897         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1898         r.in.computer_name = cli_credentials_get_workstation(credentials);
1899         r.in.credential = &auth;
1900         r.in.return_authenticator = &auth2;
1901         r.in.logon_level = NetlogonNetworkInformation;
1902         r.in.logon = &logon;
1903         r.out.validation = &validation;
1904         r.out.authoritative = &authoritative;
1905
1906         d_printf("Testing LogonSamLogon with name %s\n", ninfo.identity_info.account_name.string);
1907
1908         for (i=2;i<=3;i++) {
1909                 ZERO_STRUCT(auth2);
1910                 netlogon_creds_client_authenticator(creds, &auth);
1911
1912                 r.in.validation_level = i;
1913
1914                 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
1915                         "LogonSamLogon failed");
1916                 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonSamLogon failed");
1917
1918                 torture_assert(tctx, netlogon_creds_client_check(creds,
1919                                                                  &r.out.return_authenticator->cred),
1920                         "Credential chaining failed");
1921                 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
1922                                          "LogonSamLogon invalid  *r.out.authoritative");
1923         }
1924
1925         /* this makes sure we get the unmarshalling right for invalid levels */
1926         for (i=52;i<53;i++) {
1927                 ZERO_STRUCT(auth2);
1928                 /* the authenticator should be ignored by the server */
1929                 generate_random_buffer((uint8_t *) &auth, sizeof(auth));
1930
1931                 r.in.validation_level = i;
1932
1933                 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
1934                                            "LogonSamLogon failed");
1935                 torture_assert_ntstatus_equal(tctx, r.out.result,
1936                                               NT_STATUS_INVALID_INFO_CLASS,
1937                                               "LogonSamLogon failed");
1938
1939                 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
1940                                          "LogonSamLogon invalid  *r.out.authoritative");
1941                 torture_assert(tctx,
1942                                all_zero((uint8_t *)&auth2, sizeof(auth2)),
1943                                "Return authenticator non zero");
1944         }
1945
1946         for (i=2;i<=3;i++) {
1947                 ZERO_STRUCT(auth2);
1948                 netlogon_creds_client_authenticator(creds, &auth);
1949
1950                 r.in.validation_level = i;
1951
1952                 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
1953                         "LogonSamLogon failed");
1954                 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonSamLogon failed");
1955
1956                 torture_assert(tctx, netlogon_creds_client_check(creds,
1957                                                                  &r.out.return_authenticator->cred),
1958                         "Credential chaining failed");
1959                 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
1960                                          "LogonSamLogon invalid  *r.out.authoritative");
1961         }
1962
1963         r.in.logon_level = 52;
1964
1965         for (i=2;i<=3;i++) {
1966                 ZERO_STRUCT(auth2);
1967                 /* the authenticator should be ignored by the server */
1968                 generate_random_buffer((uint8_t *) &auth, sizeof(auth));
1969
1970                 r.in.validation_level = i;
1971
1972                 torture_comment(tctx, "Testing SamLogon with validation level %d and a NULL credential\n", i);
1973
1974                 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
1975                         "LogonSamLogon failed");
1976                 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_INVALID_PARAMETER,
1977                         "LogonSamLogon expected INVALID_PARAMETER");
1978
1979                 torture_assert(tctx,
1980                                all_zero((uint8_t *)&auth2, sizeof(auth2)),
1981                                "Return authenticator non zero");
1982                 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
1983                                          "LogonSamLogon invalid  *r.out.authoritative");
1984         }
1985
1986         r.in.credential = NULL;
1987
1988         for (i=2;i<=3;i++) {
1989                 ZERO_STRUCT(auth2);
1990
1991                 r.in.validation_level = i;
1992
1993                 torture_comment(tctx, "Testing SamLogon with validation level %d and a NULL credential\n", i);
1994
1995                 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
1996                         "LogonSamLogon failed");
1997                 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_INVALID_PARAMETER,
1998                         "LogonSamLogon expected INVALID_PARAMETER");
1999
2000                 torture_assert(tctx,
2001                                all_zero((uint8_t *)&auth2, sizeof(auth2)),
2002                                "Return authenticator non zero");
2003                 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
2004                                          "LogonSamLogon invalid  *r.out.authoritative");
2005         }
2006
2007         r.in.logon_level = NetlogonNetworkInformation;
2008         r.in.credential = &auth;
2009
2010         for (i=2;i<=3;i++) {
2011                 ZERO_STRUCT(auth2);
2012                 netlogon_creds_client_authenticator(creds, &auth);
2013
2014                 r.in.validation_level = i;
2015
2016                 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
2017                         "LogonSamLogon failed");
2018                 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonSamLogon failed");
2019
2020                 torture_assert(tctx, netlogon_creds_client_check(creds,
2021                                                                  &r.out.return_authenticator->cred),
2022                         "Credential chaining failed");
2023                 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
2024                                          "LogonSamLogon invalid  *r.out.authoritative");
2025         }
2026
2027         return true;
2028 }
2029
2030 bool test_netlogon_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
2031                        struct cli_credentials *credentials,
2032                        struct netlogon_creds_CredentialState *creds)
2033 {
2034         return test_netlogon_ops_args(p, tctx, credentials, creds, false);
2035 }
2036
2037 /*
2038   try a netlogon GetCapabilities
2039 */
2040 bool test_netlogon_capabilities(struct dcerpc_pipe *p, struct torture_context *tctx,
2041                                 struct cli_credentials *credentials,
2042                                 struct netlogon_creds_CredentialState *creds)
2043 {
2044         NTSTATUS status;
2045         struct netr_LogonGetCapabilities r;
2046         union netr_Capabilities capabilities;
2047         struct netr_Authenticator auth, return_auth;
2048         struct netlogon_creds_CredentialState tmp_creds;
2049         struct dcerpc_binding_handle *b = p->binding_handle;
2050
2051         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2052         r.in.computer_name = cli_credentials_get_workstation(credentials);
2053         r.in.credential = &auth;
2054         r.in.return_authenticator = &return_auth;
2055         r.in.query_level = 1;
2056         r.out.capabilities = &capabilities;
2057         r.out.return_authenticator = &return_auth;
2058
2059         torture_comment(tctx, "Testing LogonGetCapabilities\n");
2060
2061         ZERO_STRUCT(return_auth);
2062
2063         /*
2064          * we need to operate on a temporary copy of creds
2065          * because dcerpc_netr_LogonGetCapabilities was
2066          * dcerpc_netr_DummyFunction and returns NT_STATUS_NOT_IMPLEMENTED
2067          * without looking a the authenticator.
2068          */
2069         tmp_creds = *creds;
2070         netlogon_creds_client_authenticator(&tmp_creds, &auth);
2071
2072         status = dcerpc_netr_LogonGetCapabilities_r(b, tctx, &r);
2073         torture_assert_ntstatus_ok(tctx, status, "LogonGetCapabilities failed");
2074         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_IMPLEMENTED)) {
2075                 return true;
2076         }
2077
2078         *creds = tmp_creds;
2079
2080         torture_assert(tctx, netlogon_creds_client_check(creds,
2081                                                          &r.out.return_authenticator->cred),
2082                        "Credential chaining failed");
2083
2084         torture_assert_int_equal(tctx, creds->negotiate_flags,
2085                                  capabilities.server_capabilities,
2086                                  "negotiate flags");
2087
2088         return true;
2089 }
2090
2091 /*
2092   try a netlogon SamLogon
2093 */
2094 static bool test_SamLogon(struct torture_context *tctx,
2095                           struct dcerpc_pipe *p,
2096                           struct cli_credentials *credentials)
2097 {
2098         struct netlogon_creds_CredentialState *creds;
2099
2100         if (!test_SetupCredentials(p, tctx, credentials, &creds)) {
2101                 return false;
2102         }
2103
2104         return test_netlogon_ops(p, tctx, credentials, creds);
2105 }
2106
2107 static bool test_invalidAuthenticate2(struct torture_context *tctx,
2108                                       struct dcerpc_pipe *p,
2109                                       struct cli_credentials *credentials)
2110 {
2111         struct netlogon_creds_CredentialState *creds;
2112         uint32_t flags = NETLOGON_NEG_AUTH2_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
2113
2114         torture_comment(tctx, "Testing invalidAuthenticate2\n");
2115
2116         if (!test_SetupCredentials2(p, tctx, flags,
2117                                     credentials,
2118                                     cli_credentials_get_secure_channel_type(credentials),
2119                                     &creds)) {
2120                 return false;
2121         }
2122
2123         if (!test_SetupCredentials2ex(p, tctx, flags,
2124                                       credentials,
2125                                       "1234567890123456",
2126                                       cli_credentials_get_secure_channel_type(credentials),
2127                                       STATUS_BUFFER_OVERFLOW,
2128                                       &creds)) {
2129                 return false;
2130         }
2131
2132         if (!test_SetupCredentials2ex(p, tctx, flags,
2133                                       credentials,
2134                                       "123456789012345",
2135                                       cli_credentials_get_secure_channel_type(credentials),
2136                                       NT_STATUS_OK,
2137                                       &creds)) {
2138                 return false;
2139         }
2140
2141         return true;
2142 }
2143
2144 static bool test_ServerReqChallengeGlobal(struct torture_context *tctx,
2145                                           struct dcerpc_pipe *p1,
2146                                           struct cli_credentials *machine_credentials)
2147 {
2148         uint32_t flags = NETLOGON_NEG_AUTH2_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
2149         struct netr_ServerReqChallenge r;
2150         struct netr_ServerAuthenticate3 a;
2151         struct netr_Credential credentials1, credentials2, credentials3;
2152         struct netlogon_creds_CredentialState *creds;
2153         struct samr_Password mach_password;
2154         uint32_t rid;
2155         const char *machine_name;
2156         const char *plain_pass;
2157         struct dcerpc_binding_handle *b1 = p1->binding_handle;
2158         struct dcerpc_pipe *p2 = NULL;
2159         struct dcerpc_binding_handle *b2 = NULL;
2160
2161         machine_name = cli_credentials_get_workstation(machine_credentials);
2162         torture_assert(tctx, machine_name != NULL, "machine_name");
2163         plain_pass = cli_credentials_get_password(machine_credentials);
2164         torture_assert(tctx, plain_pass != NULL, "plain_pass");
2165
2166         torture_comment(tctx, "Testing ServerReqChallenge on b1\n");
2167
2168         torture_assert_ntstatus_ok(tctx,
2169                 dcerpc_pipe_connect_b(tctx, &p2, p1->binding,
2170                                       &ndr_table_netlogon,
2171                                       machine_credentials,
2172                                       tctx->ev, tctx->lp_ctx),
2173                 "dcerpc_pipe_connect_b failed");
2174         b2 = p2->binding_handle;
2175
2176         r.in.server_name = NULL;
2177         r.in.computer_name = machine_name;
2178         r.in.credentials = &credentials1;
2179         r.out.return_credentials = &credentials2;
2180
2181         netlogon_creds_random_challenge(&credentials1);
2182
2183         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b1, tctx, &r),
2184                 "ServerReqChallenge failed on b1");
2185         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed on b1");
2186
2187         E_md4hash(plain_pass, mach_password.hash);
2188
2189         a.in.server_name = NULL;
2190         a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
2191         a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
2192         a.in.computer_name = machine_name;
2193         a.in.negotiate_flags = &flags;
2194         a.in.credentials = &credentials3;
2195         a.out.return_credentials = &credentials3;
2196         a.out.negotiate_flags = &flags;
2197         a.out.rid = &rid;
2198
2199         creds = netlogon_creds_client_init(tctx, a.in.account_name,
2200                                            a.in.computer_name,
2201                                            a.in.secure_channel_type,
2202                                            &credentials1, &credentials2,
2203                                            &mach_password, &credentials3,
2204                                            flags);
2205
2206         torture_assert(tctx, creds != NULL, "memory allocation");
2207
2208         torture_comment(tctx, "Testing ServerAuthenticate3 on b2\n");
2209
2210         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b2, tctx, &a),
2211                 "ServerAuthenticate3 failed on b2");
2212         torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate3 failed on b2");
2213         torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
2214
2215         return true;
2216 }
2217
2218 /*
2219  * Test the re-use of the challenge is not possible on a third
2220  * connection, after first useing it second one.
2221  */
2222
2223 static bool test_ServerReqChallengeReuseGlobal(struct torture_context *tctx,
2224                                           struct dcerpc_pipe *p1,
2225                                           struct cli_credentials *machine_credentials)
2226 {
2227         uint32_t flags = NETLOGON_NEG_AUTH2_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
2228         struct netr_ServerReqChallenge r;
2229         struct netr_ServerAuthenticate3 a;
2230         struct netr_Credential credentials1, credentials2, credentials3;
2231         struct netlogon_creds_CredentialState *creds;
2232         struct samr_Password mach_password;
2233         uint32_t rid;
2234         const char *machine_name;
2235         const char *plain_pass;
2236         struct dcerpc_binding_handle *b1 = p1->binding_handle;
2237         struct dcerpc_pipe *p2 = NULL;
2238         struct dcerpc_binding_handle *b2 = NULL;
2239         struct dcerpc_pipe *p3 = NULL;
2240         struct dcerpc_binding_handle *b3 = NULL;
2241
2242         machine_name = cli_credentials_get_workstation(machine_credentials);
2243         torture_assert(tctx, machine_name != NULL, "machine_name");
2244         plain_pass = cli_credentials_get_password(machine_credentials);
2245         torture_assert(tctx, plain_pass != NULL, "plain_pass");
2246
2247         torture_comment(tctx, "Testing ServerReqChallenge on b1\n");
2248
2249         torture_assert_ntstatus_ok(tctx,
2250                 dcerpc_pipe_connect_b(tctx, &p2, p1->binding,
2251                                       &ndr_table_netlogon,
2252                                       machine_credentials,
2253                                       tctx->ev, tctx->lp_ctx),
2254                 "dcerpc_pipe_connect_b failed");
2255         b2 = p2->binding_handle;
2256
2257         torture_assert_ntstatus_ok(tctx,
2258                 dcerpc_pipe_connect_b(tctx, &p3, p1->binding,
2259                                       &ndr_table_netlogon,
2260                                       machine_credentials,
2261                                       tctx->ev, tctx->lp_ctx),
2262                 "dcerpc_pipe_connect_b failed");
2263         b3 = p3->binding_handle;
2264
2265         r.in.server_name = NULL;
2266         r.in.computer_name = machine_name;
2267         r.in.credentials = &credentials1;
2268         r.out.return_credentials = &credentials2;
2269
2270         netlogon_creds_random_challenge(&credentials1);
2271
2272         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b1, tctx, &r),
2273                 "ServerReqChallenge failed on b1");
2274         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed on b1");
2275
2276         E_md4hash(plain_pass, mach_password.hash);
2277
2278         a.in.server_name = NULL;
2279         a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
2280         a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
2281         a.in.computer_name = machine_name;
2282         a.in.negotiate_flags = &flags;
2283         a.in.credentials = &credentials3;
2284         a.out.return_credentials = &credentials3;
2285         a.out.negotiate_flags = &flags;
2286         a.out.rid = &rid;
2287
2288         creds = netlogon_creds_client_init(tctx, a.in.account_name,
2289                                            a.in.computer_name,
2290                                            a.in.secure_channel_type,
2291                                            &credentials1, &credentials2,
2292                                            &mach_password, &credentials3,
2293                                            flags);
2294
2295         torture_assert(tctx, creds != NULL, "memory allocation");
2296
2297         torture_comment(tctx, "Testing ServerAuthenticate3 on b2\n");
2298
2299         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b2, tctx, &a),
2300                 "ServerAuthenticate3 failed on b2");
2301         torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate3 failed on b2");
2302         torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
2303
2304         /* We have to re-run this part */
2305         creds = netlogon_creds_client_init(tctx, a.in.account_name,
2306                                            a.in.computer_name,
2307                                            a.in.secure_channel_type,
2308                                            &credentials1, &credentials2,
2309                                            &mach_password, &credentials3,
2310                                            flags);
2311
2312         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b3, tctx, &a),
2313                 "ServerAuthenticate3 failed on b3");
2314         torture_assert_ntstatus_equal(tctx, a.out.result, NT_STATUS_ACCESS_DENIED,
2315                                       "ServerAuthenticate3 should have failed on b3, due to credential reuse");
2316         return true;
2317 }
2318
2319 /*
2320  * Test if use of the per-pipe challenge will wipe out the globally cached challenge
2321  */
2322 static bool test_ServerReqChallengeReuseGlobal2(struct torture_context *tctx,
2323                                                 struct dcerpc_pipe *p1,
2324                                                 struct cli_credentials *machine_credentials)
2325 {
2326         uint32_t flags = NETLOGON_NEG_AUTH2_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
2327         struct netr_ServerReqChallenge r;
2328         struct netr_ServerAuthenticate3 a;
2329         struct netr_Credential credentials1, credentials2, credentials3;
2330         struct netlogon_creds_CredentialState *creds;
2331         struct samr_Password mach_password;
2332         uint32_t rid;
2333         const char *machine_name;
2334         const char *plain_pass;
2335         struct dcerpc_binding_handle *b1 = p1->binding_handle;
2336         struct dcerpc_pipe *p2 = NULL;
2337         struct dcerpc_binding_handle *b2 = NULL;
2338
2339         machine_name = cli_credentials_get_workstation(machine_credentials);
2340         torture_assert(tctx, machine_name != NULL, "machine_name");
2341         plain_pass = cli_credentials_get_password(machine_credentials);
2342         torture_assert(tctx, plain_pass != NULL, "plain_pass");
2343
2344         torture_comment(tctx, "Testing ServerReqChallenge on b1\n");
2345
2346         torture_assert_ntstatus_ok(tctx,
2347                 dcerpc_pipe_connect_b(tctx, &p2, p1->binding,
2348                                       &ndr_table_netlogon,
2349                                       machine_credentials,
2350                                       tctx->ev, tctx->lp_ctx),
2351                 "dcerpc_pipe_connect_b failed");
2352         b2 = p2->binding_handle;
2353
2354         r.in.server_name = NULL;
2355         r.in.computer_name = machine_name;
2356         r.in.credentials = &credentials1;
2357         r.out.return_credentials = &credentials2;
2358
2359         netlogon_creds_random_challenge(&credentials1);
2360
2361         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b1, tctx, &r),
2362                 "ServerReqChallenge failed on b1");
2363         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed on b1");
2364
2365         E_md4hash(plain_pass, mach_password.hash);
2366
2367         a.in.server_name = NULL;
2368         a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
2369         a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
2370         a.in.computer_name = machine_name;
2371         a.in.negotiate_flags = &flags;
2372         a.in.credentials = &credentials3;
2373         a.out.return_credentials = &credentials3;
2374         a.out.negotiate_flags = &flags;
2375         a.out.rid = &rid;
2376
2377         creds = netlogon_creds_client_init(tctx, a.in.account_name,
2378                                            a.in.computer_name,
2379                                            a.in.secure_channel_type,
2380                                            &credentials1, &credentials2,
2381                                            &mach_password, &credentials3,
2382                                            flags);
2383
2384         torture_assert(tctx, creds != NULL, "memory allocation");
2385
2386         torture_comment(tctx, "Testing ServerAuthenticate3 on b2\n");
2387
2388         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b1, tctx, &a),
2389                 "ServerAuthenticate3 failed on b");
2390         torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate3 failed on b");
2391         torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
2392
2393         /* We have to re-run this part */
2394         creds = netlogon_creds_client_init(tctx, a.in.account_name,
2395                                            a.in.computer_name,
2396                                            a.in.secure_channel_type,
2397                                            &credentials1, &credentials2,
2398                                            &mach_password, &credentials3,
2399                                            flags);
2400
2401         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b2, tctx, &a),
2402                 "ServerAuthenticate3 failed on b2");
2403         torture_assert_ntstatus_equal(tctx, a.out.result, NT_STATUS_ACCESS_DENIED,
2404                                       "ServerAuthenticate3 should have failed on b2, due to credential reuse");
2405         return true;
2406 }
2407
2408 /*
2409  * Test if use of the globally cached challenge will wipe out the
2410  * per-pipe challenge
2411  */
2412 static bool test_ServerReqChallengeReuseGlobal3(struct torture_context *tctx,
2413                                                 struct dcerpc_pipe *p1,
2414                                                 struct cli_credentials *machine_credentials)
2415 {
2416         uint32_t flags = NETLOGON_NEG_AUTH2_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
2417         struct netr_ServerReqChallenge r;
2418         struct netr_ServerAuthenticate3 a;
2419         struct netr_Credential credentials1, credentials2, credentials3;
2420         struct netlogon_creds_CredentialState *creds;
2421         struct samr_Password mach_password;
2422         uint32_t rid;
2423         const char *machine_name;
2424         const char *plain_pass;
2425         struct dcerpc_binding_handle *b1 = p1->binding_handle;
2426         struct dcerpc_pipe *p2 = NULL;
2427         struct dcerpc_binding_handle *b2 = NULL;
2428
2429         machine_name = cli_credentials_get_workstation(machine_credentials);
2430         torture_assert(tctx, machine_name != NULL, "machine_name");
2431         plain_pass = cli_credentials_get_password(machine_credentials);
2432         torture_assert(tctx, plain_pass != NULL, "plain_pass");
2433
2434         torture_comment(tctx, "Testing ServerReqChallenge on b1\n");
2435
2436         torture_assert_ntstatus_ok(tctx,
2437                 dcerpc_pipe_connect_b(tctx, &p2, p1->binding,
2438                                       &ndr_table_netlogon,
2439                                       machine_credentials,
2440                                       tctx->ev, tctx->lp_ctx),
2441                 "dcerpc_pipe_connect_b failed");
2442         b2 = p2->binding_handle;
2443
2444         r.in.server_name = NULL;
2445         r.in.computer_name = machine_name;
2446         r.in.credentials = &credentials1;
2447         r.out.return_credentials = &credentials2;
2448
2449         netlogon_creds_random_challenge(&credentials1);
2450
2451         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b1, tctx, &r),
2452                 "ServerReqChallenge failed on b1");
2453         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed on b1");
2454
2455         E_md4hash(plain_pass, mach_password.hash);
2456
2457         a.in.server_name = NULL;
2458         a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
2459         a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
2460         a.in.computer_name = machine_name;
2461         a.in.negotiate_flags = &flags;
2462         a.in.credentials = &credentials3;
2463         a.out.return_credentials = &credentials3;
2464         a.out.negotiate_flags = &flags;
2465         a.out.rid = &rid;
2466
2467         creds = netlogon_creds_client_init(tctx, a.in.account_name,
2468                                            a.in.computer_name,
2469                                            a.in.secure_channel_type,
2470                                            &credentials1, &credentials2,
2471                                            &mach_password, &credentials3,
2472                                            flags);
2473
2474         torture_assert(tctx, creds != NULL, "memory allocation");
2475
2476         torture_comment(tctx, "Testing ServerAuthenticate3 on b2\n");
2477
2478         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b2, tctx, &a),
2479                 "ServerAuthenticate3 failed on b2");
2480         torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate3 failed on b");
2481         torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
2482
2483         /* We have to re-run this part */
2484         creds = netlogon_creds_client_init(tctx, a.in.account_name,
2485                                            a.in.computer_name,
2486                                            a.in.secure_channel_type,
2487                                            &credentials1, &credentials2,
2488                                            &mach_password, &credentials3,
2489                                            flags);
2490
2491         torture_assert(tctx, creds != NULL, "memory allocation");
2492
2493         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b1, tctx, &a),
2494                 "ServerAuthenticate3 failed on b1");
2495         torture_assert_ntstatus_equal(tctx, a.out.result, NT_STATUS_ACCESS_DENIED,
2496                                       "ServerAuthenticate3 should have failed on b1, due to credential reuse");
2497         return true;
2498 }
2499
2500 /*
2501  * Test if more than one globally cached challenge works
2502  */
2503 static bool test_ServerReqChallengeReuseGlobal4(struct torture_context *tctx,
2504                                                 struct dcerpc_pipe *p1,
2505                                                 struct cli_credentials *machine_credentials)
2506 {
2507         uint32_t flags = NETLOGON_NEG_AUTH2_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
2508         struct netr_ServerReqChallenge r;
2509         struct netr_ServerAuthenticate3 a;
2510         struct netr_Credential credentials1, credentials1_random,
2511                 credentials2, credentials3, credentials_discard;
2512         struct netlogon_creds_CredentialState *creds;
2513         struct samr_Password mach_password;
2514         uint32_t rid;
2515         const char *machine_name;
2516         const char *plain_pass;
2517         struct dcerpc_binding_handle *b1 = p1->binding_handle;
2518         struct dcerpc_pipe *p2 = NULL;
2519         struct dcerpc_binding_handle *b2 = NULL;
2520
2521         machine_name = cli_credentials_get_workstation(machine_credentials);
2522         torture_assert(tctx, machine_name != NULL, "machine_name");
2523         plain_pass = cli_credentials_get_password(machine_credentials);
2524         torture_assert(tctx, plain_pass != NULL, "plain_pass");
2525
2526         torture_comment(tctx, "Testing ServerReqChallenge on b1\n");
2527
2528         torture_assert_ntstatus_ok(tctx,
2529                 dcerpc_pipe_connect_b(tctx, &p2, p1->binding,
2530                                       &ndr_table_netlogon,
2531                                       machine_credentials,
2532                                       tctx->ev, tctx->lp_ctx),
2533                 "dcerpc_pipe_connect_b failed");
2534         b2 = p2->binding_handle;
2535
2536         r.in.server_name = NULL;
2537         r.in.computer_name = "CHALTEST1";
2538         r.in.credentials = &credentials1_random;
2539         r.out.return_credentials = &credentials_discard;
2540
2541         netlogon_creds_random_challenge(&credentials1_random);
2542
2543         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b1, tctx, &r),
2544                 "ServerReqChallenge failed on b1");
2545         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed on b1");
2546
2547         /* Now ask for the actual client name */
2548         r.in.server_name = NULL;
2549         r.in.computer_name = machine_name;
2550         r.in.credentials = &credentials1;
2551         r.out.return_credentials = &credentials2;
2552
2553         netlogon_creds_random_challenge(&credentials1);
2554
2555         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b1, tctx, &r),
2556                 "ServerReqChallenge failed on b1");
2557         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed on b1");
2558
2559         r.in.server_name = NULL;
2560         r.in.computer_name = "CHALTEST2";
2561         r.in.credentials = &credentials1_random;
2562         r.out.return_credentials = &credentials_discard;
2563
2564         netlogon_creds_random_challenge(&credentials1_random);
2565
2566         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b1, tctx, &r),
2567                 "ServerReqChallenge failed on b1");
2568         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed on b1");
2569
2570         E_md4hash(plain_pass, mach_password.hash);
2571
2572         a.in.server_name = NULL;
2573         a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
2574         a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
2575         a.in.computer_name = machine_name;
2576         a.in.negotiate_flags = &flags;
2577         a.in.credentials = &credentials3;
2578         a.out.return_credentials = &credentials3;
2579         a.out.negotiate_flags = &flags;
2580         a.out.rid = &rid;
2581
2582         creds = netlogon_creds_client_init(tctx, a.in.account_name,
2583                                            a.in.computer_name,
2584                                            a.in.secure_channel_type,
2585                                            &credentials1, &credentials2,
2586                                            &mach_password, &credentials3,
2587                                            flags);
2588
2589         torture_assert(tctx, creds != NULL, "memory allocation");
2590
2591         torture_comment(tctx, "Testing ServerAuthenticate3 on b2 (must use global credentials)\n");
2592
2593         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b2, tctx, &a),
2594                 "ServerAuthenticate3 failed on b2");
2595         torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate3 failed on b2");
2596         torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
2597
2598         /* We have to re-run this part */
2599         creds = netlogon_creds_client_init(tctx, a.in.account_name,
2600                                            a.in.computer_name,
2601                                            a.in.secure_channel_type,
2602                                            &credentials1, &credentials2,
2603                                            &mach_password, &credentials3,
2604                                            flags);
2605
2606         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b1, tctx, &a),
2607                 "ServerAuthenticate3 failed on b1");
2608         torture_assert_ntstatus_equal(tctx, a.out.result, NT_STATUS_ACCESS_DENIED,
2609                                       "ServerAuthenticate3 should have failed on b1, due to credential reuse");
2610         return true;
2611 }
2612
2613 static bool test_ServerReqChallengeReuse(struct torture_context *tctx,
2614                                          struct dcerpc_pipe *p,
2615                                          struct cli_credentials *machine_credentials)
2616 {
2617         uint32_t flags = NETLOGON_NEG_AUTH2_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
2618         struct netr_ServerReqChallenge r;
2619         struct netr_ServerAuthenticate3 a;
2620         struct netr_Credential credentials1, credentials2, credentials3;
2621         struct netlogon_creds_CredentialState *creds;
2622         struct samr_Password mach_password;
2623         uint32_t rid;
2624         const char *machine_name;
2625         const char *plain_pass;
2626         struct dcerpc_binding_handle *b = p->binding_handle;
2627
2628         machine_name = cli_credentials_get_workstation(machine_credentials);
2629         torture_assert(tctx, machine_name != NULL, "machine_name");
2630         plain_pass = cli_credentials_get_password(machine_credentials);
2631         torture_assert(tctx, plain_pass != NULL, "plain_pass");
2632
2633         torture_comment(tctx, "Testing ServerReqChallenge on b1\n");
2634
2635         r.in.server_name = NULL;
2636         r.in.computer_name = machine_name;
2637         r.in.credentials = &credentials1;
2638         r.out.return_credentials = &credentials2;
2639
2640         netlogon_creds_random_challenge(&credentials1);
2641
2642         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
2643                 "ServerReqChallenge");
2644         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed on b1");
2645
2646         E_md4hash(plain_pass, mach_password.hash);
2647
2648         a.in.server_name = NULL;
2649         a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
2650         a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
2651         a.in.computer_name = machine_name;
2652         a.in.negotiate_flags = &flags;
2653         a.in.credentials = &credentials3;
2654         a.out.return_credentials = &credentials3;
2655         a.out.negotiate_flags = &flags;
2656         a.out.rid = &rid;
2657
2658         creds = netlogon_creds_client_init(tctx, a.in.account_name,
2659                                            a.in.computer_name,
2660                                            a.in.secure_channel_type,
2661                                            &credentials1, &credentials2,
2662                                            &mach_password, &credentials3,
2663                                            flags);
2664
2665         torture_assert(tctx, creds != NULL, "memory allocation");
2666
2667         torture_comment(tctx, "Testing ServerAuthenticate3\n");
2668
2669         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b, tctx, &a),
2670                 "ServerAuthenticate3 failed");
2671         torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate3 failed");
2672         torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
2673
2674         /* We have to re-run this part */
2675         creds = netlogon_creds_client_init(tctx, a.in.account_name,
2676                                            a.in.computer_name,
2677                                            a.in.secure_channel_type,
2678                                            &credentials1, &credentials2,
2679                                            &mach_password, &credentials3,
2680                                            flags);
2681
2682         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b, tctx, &a),
2683                 "ServerAuthenticate3 failed");
2684         torture_assert_ntstatus_equal(tctx, a.out.result, NT_STATUS_ACCESS_DENIED,
2685                                       "ServerAuthenticate3 should have failed on b3, due to credential reuse");
2686
2687         ZERO_STRUCT(credentials1.data);
2688         ZERO_STRUCT(credentials2.data);
2689         creds = netlogon_creds_client_init(tctx, a.in.account_name,
2690                                            a.in.computer_name,
2691                                            a.in.secure_channel_type,
2692                                            &credentials1, &credentials2,
2693                                            &mach_password, &credentials3,
2694                                            flags);
2695
2696         torture_assert(tctx, creds != NULL, "memory allocation");
2697
2698         torture_comment(tctx, "Testing ServerAuthenticate3 with zero'ed challenge\n");
2699
2700         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b, tctx, &a),
2701                 "ServerAuthenticate3 failed");
2702         torture_assert_ntstatus_equal(tctx, a.out.result, NT_STATUS_ACCESS_DENIED,
2703                                       "ServerAuthenticate3 should have failed on b3, due to credential reuse");
2704         return true;
2705 }
2706
2707 static bool test_SamLogon_NULL_domain(struct torture_context *tctx,
2708                                       struct dcerpc_pipe *p,
2709                                       struct cli_credentials *credentials)
2710 {
2711         struct netlogon_creds_CredentialState *creds;
2712
2713         if (!test_SetupCredentials(p, tctx, credentials, &creds)) {
2714                 return false;
2715         }
2716
2717         return test_netlogon_ops_args(p, tctx, credentials, creds, true);
2718 }
2719
2720 /* we remember the sequence numbers so we can easily do a DatabaseDelta */
2721 static uint64_t sequence_nums[3];
2722
2723 /*
2724   try a netlogon DatabaseSync
2725 */
2726 static bool test_DatabaseSync(struct torture_context *tctx,
2727                               struct dcerpc_pipe *p,
2728                               struct cli_credentials *machine_credentials)
2729 {
2730         struct netr_DatabaseSync r;
2731         struct netlogon_creds_CredentialState *creds;
2732         const uint32_t database_ids[] = {SAM_DATABASE_DOMAIN, SAM_DATABASE_BUILTIN, SAM_DATABASE_PRIVS};
2733         int i;
2734         struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
2735         struct netr_Authenticator credential, return_authenticator;
2736         struct dcerpc_binding_handle *b = p->binding_handle;
2737
2738         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
2739                 return false;
2740         }
2741
2742         ZERO_STRUCT(return_authenticator);
2743
2744         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2745         r.in.computername = TEST_MACHINE_NAME;
2746         r.in.preferredmaximumlength = (uint32_t)-1;
2747         r.in.return_authenticator = &return_authenticator;
2748         r.out.delta_enum_array = &delta_enum_array;
2749         r.out.return_authenticator = &return_authenticator;
2750
2751         for (i=0;i<ARRAY_SIZE(database_ids);i++) {
2752
2753                 uint32_t sync_context = 0;
2754
2755                 r.in.database_id = database_ids[i];
2756                 r.in.sync_context = &sync_context;
2757                 r.out.sync_context = &sync_context;
2758
2759                 torture_comment(tctx, "Testing DatabaseSync of id %d\n", r.in.database_id);
2760
2761                 do {
2762                         netlogon_creds_client_authenticator(creds, &credential);
2763
2764                         r.in.credential = &credential;
2765
2766                         torture_assert_ntstatus_ok(tctx, dcerpc_netr_DatabaseSync_r(b, tctx, &r),
2767                                 "DatabaseSync failed");
2768                         if (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES))
2769                             break;
2770
2771                         /* Native mode servers don't do this */
2772                         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_SUPPORTED)) {
2773                                 return true;
2774                         }
2775                         torture_assert_ntstatus_ok(tctx, r.out.result, "DatabaseSync");
2776
2777                         if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
2778                                 torture_comment(tctx, "Credential chaining failed\n");
2779                         }
2780
2781                         if (delta_enum_array &&
2782                             delta_enum_array->num_deltas > 0 &&
2783                             delta_enum_array->delta_enum[0].delta_type == NETR_DELTA_DOMAIN &&
2784                             delta_enum_array->delta_enum[0].delta_union.domain) {
2785                                 sequence_nums[r.in.database_id] =
2786                                         delta_enum_array->delta_enum[0].delta_union.domain->sequence_num;
2787                                 torture_comment(tctx, "\tsequence_nums[%d]=%llu\n",
2788                                        r.in.database_id,
2789                                        (unsigned long long)sequence_nums[r.in.database_id]);
2790                         }
2791                 } while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES));
2792         }
2793
2794         return true;
2795 }
2796
2797
2798 /*
2799   try a netlogon DatabaseDeltas
2800 */
2801 static bool test_DatabaseDeltas(struct torture_context *tctx,
2802                                 struct dcerpc_pipe *p,
2803                                 struct cli_credentials *machine_credentials)
2804 {
2805         struct netr_DatabaseDeltas r;
2806         struct netlogon_creds_CredentialState *creds;
2807         struct netr_Authenticator credential;
2808         struct netr_Authenticator return_authenticator;
2809         struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
2810         const uint32_t database_ids[] = {0, 1, 2};
2811         int i;
2812         struct dcerpc_binding_handle *b = p->binding_handle;
2813
2814         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
2815                 return false;
2816         }
2817
2818         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2819         r.in.computername = TEST_MACHINE_NAME;
2820         r.in.preferredmaximumlength = (uint32_t)-1;
2821         ZERO_STRUCT(r.in.return_authenticator);
2822         r.out.return_authenticator = &return_authenticator;
2823         r.out.delta_enum_array = &delta_enum_array;
2824
2825         for (i=0;i<ARRAY_SIZE(database_ids);i++) {
2826                 r.in.database_id = database_ids[i];
2827                 r.in.sequence_num = &sequence_nums[r.in.database_id];
2828
2829                 if (*r.in.sequence_num == 0) continue;
2830
2831                 *r.in.sequence_num -= 1;
2832
2833                 torture_comment(tctx, "Testing DatabaseDeltas of id %d at %llu\n",
2834                        r.in.database_id, (unsigned long long)*r.in.sequence_num);
2835
2836                 do {
2837                         netlogon_creds_client_authenticator(creds, &credential);
2838
2839                         torture_assert_ntstatus_ok(tctx, dcerpc_netr_DatabaseDeltas_r(b, tctx, &r),
2840                                 "DatabaseDeltas failed");
2841                         if (NT_STATUS_EQUAL(r.out.result,
2842                                              NT_STATUS_SYNCHRONIZATION_REQUIRED)) {
2843                                 torture_comment(tctx, "not considering %s to be an error\n",
2844                                        nt_errstr(r.out.result));
2845                                 return true;
2846                         }
2847                         if (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES))
2848                             break;
2849
2850                         torture_assert_ntstatus_ok(tctx, r.out.result, "DatabaseDeltas");
2851
2852                         if (!netlogon_creds_client_check(creds, &return_authenticator.cred)) {
2853                                 torture_comment(tctx, "Credential chaining failed\n");
2854                         }
2855
2856                         (*r.in.sequence_num)++;
2857                 } while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES));
2858         }
2859
2860         return true;
2861 }
2862
2863 static bool test_DatabaseRedo(struct torture_context *tctx,
2864                               struct dcerpc_pipe *p,
2865                               struct cli_credentials *machine_credentials)
2866 {
2867         struct netr_DatabaseRedo r;
2868         struct netlogon_creds_CredentialState *creds;
2869         struct netr_Authenticator credential;
2870         struct netr_Authenticator return_authenticator;
2871         struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
2872         struct netr_ChangeLogEntry e;
2873         struct dom_sid null_sid, *sid;
2874         int i,d;
2875         struct dcerpc_binding_handle *b = p->binding_handle;
2876
2877         ZERO_STRUCT(null_sid);
2878
2879         sid = dom_sid_parse_talloc(tctx, "S-1-5-21-1111111111-2222222222-333333333-500");
2880
2881         {
2882
2883         struct {
2884                 uint32_t rid;
2885                 uint16_t flags;
2886                 uint8_t db_index;
2887                 uint8_t delta_type;
2888                 struct dom_sid sid;
2889                 const char *name;
2890                 NTSTATUS expected_error;
2891                 uint32_t expected_num_results;
2892                 uint8_t expected_delta_type_1;
2893                 uint8_t expected_delta_type_2;
2894                 const char *comment;
2895         } changes[] = {
2896
2897                 /* SAM_DATABASE_DOMAIN */
2898
2899                 {
2900                         .rid                    = 0,
2901                         .flags                  = 0,
2902                         .db_index               = SAM_DATABASE_DOMAIN,
2903                         .delta_type             = NETR_DELTA_MODIFY_COUNT,
2904                         .sid                    = null_sid,
2905                         .name                   = NULL,
2906                         .expected_error         = NT_STATUS_SYNCHRONIZATION_REQUIRED,
2907                         .expected_num_results   = 0,
2908                         .comment                = "NETR_DELTA_MODIFY_COUNT"
2909                 },
2910                 {
2911                         .rid                    = 0,
2912                         .flags                  = 0,
2913                         .db_index               = SAM_DATABASE_DOMAIN,
2914                         .delta_type             = 0,
2915                         .sid                    = null_sid,
2916                         .name                   = NULL,
2917                         .expected_error         = NT_STATUS_OK,
2918                         .expected_num_results   = 1,
2919                         .expected_delta_type_1  = NETR_DELTA_DOMAIN,
2920                         .comment                = "NULL DELTA"
2921                 },
2922                 {
2923                         .rid                    = 0,
2924                         .flags                  = 0,
2925                         .db_index               = SAM_DATABASE_DOMAIN,
2926                         .delta_type             = NETR_DELTA_DOMAIN,
2927                         .sid                    = null_sid,
2928                         .name                   = NULL,
2929                         .expected_error         = NT_STATUS_OK,
2930                         .expected_num_results   = 1,
2931                         .expected_delta_type_1  = NETR_DELTA_DOMAIN,
2932                         .comment                = "NETR_DELTA_DOMAIN"
2933                 },
2934                 {
2935                         .rid                    = DOMAIN_RID_ADMINISTRATOR,
2936                         .flags                  = 0,
2937                         .db_index               = SAM_DATABASE_DOMAIN,
2938                         .delta_type             = NETR_DELTA_USER,
2939                         .sid                    = null_sid,
2940                         .name                   = NULL,
2941                         .expected_error         = NT_STATUS_OK,
2942                         .expected_num_results   = 1,
2943                         .expected_delta_type_1  = NETR_DELTA_USER,
2944                         .comment                = "NETR_DELTA_USER by rid 500"
2945                 },
2946                 {
2947                         .rid                    = DOMAIN_RID_GUEST,
2948                         .flags                  = 0,
2949                         .db_index               = SAM_DATABASE_DOMAIN,
2950                         .delta_type             = NETR_DELTA_USER,
2951                         .sid                    = null_sid,
2952                         .name                   = NULL,
2953                         .expected_error         = NT_STATUS_OK,
2954                         .expected_num_results   = 1,
2955                         .expected_delta_type_1  = NETR_DELTA_USER,
2956                         .comment                = "NETR_DELTA_USER by rid 501"
2957                 },
2958                 {
2959                         .rid                    = 0,
2960                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
2961                         .db_index               = SAM_DATABASE_DOMAIN,
2962                         .delta_type             = NETR_DELTA_USER,
2963                         .sid                    = *sid,
2964                         .name                   = NULL,
2965                         .expected_error         = NT_STATUS_OK,
2966                         .expected_num_results   = 1,
2967                         .expected_delta_type_1  = NETR_DELTA_DELETE_USER,
2968                         .comment                = "NETR_DELTA_USER by sid and flags"
2969                 },
2970                 {
2971                         .rid                    = 0,
2972                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
2973                         .db_index               = SAM_DATABASE_DOMAIN,
2974                         .delta_type             = NETR_DELTA_USER,
2975                         .sid                    = null_sid,
2976                         .name                   = NULL,
2977                         .expected_error         = NT_STATUS_OK,
2978                         .expected_num_results   = 1,
2979                         .expected_delta_type_1  = NETR_DELTA_DELETE_USER,
2980                         .comment                = "NETR_DELTA_USER by null_sid and flags"
2981                 },
2982                 {
2983                         .rid                    = 0,
2984                         .flags                  = NETR_CHANGELOG_NAME_INCLUDED,
2985                         .db_index               = SAM_DATABASE_DOMAIN,
2986                         .delta_type             = NETR_DELTA_USER,
2987                         .sid                    = null_sid,
2988                         .name                   = "administrator",
2989                         .expected_error         = NT_STATUS_OK,
2990                         .expected_num_results   = 1,
2991                         .expected_delta_type_1  = NETR_DELTA_DELETE_USER,
2992                         .comment                = "NETR_DELTA_USER by name 'administrator'"
2993                 },
2994                 {
2995                         .rid                    = DOMAIN_RID_ADMINS,
2996                         .flags                  = 0,
2997                         .db_index               = SAM_DATABASE_DOMAIN,
2998                         .delta_type             = NETR_DELTA_GROUP,
2999                         .sid                    = null_sid,
3000                         .name                   = NULL,
3001                         .expected_error         = NT_STATUS_OK,
3002                         .expected_num_results   = 2,
3003                         .expected_delta_type_1  = NETR_DELTA_GROUP,
3004                         .expected_delta_type_2  = NETR_DELTA_GROUP_MEMBER,
3005                         .comment                = "NETR_DELTA_GROUP by rid 512"
3006                 },
3007                 {
3008                         .rid                    = DOMAIN_RID_ADMINS,
3009                         .flags                  = 0,
3010                         .db_index               = SAM_DATABASE_DOMAIN,
3011                         .delta_type             = NETR_DELTA_GROUP_MEMBER,
3012                         .sid                    = null_sid,
3013                         .name                   = NULL,
3014                         .expected_error         = NT_STATUS_OK,
3015                         .expected_num_results   = 2,
3016                         .expected_delta_type_1  = NETR_DELTA_GROUP,
3017                         .expected_delta_type_2  = NETR_DELTA_GROUP_MEMBER,
3018                         .comment                = "NETR_DELTA_GROUP_MEMBER by rid 512"
3019                 },
3020
3021
3022                 /* SAM_DATABASE_BUILTIN */
3023
3024                 {
3025                         .rid                    = 0,
3026                         .flags                  = 0,
3027                         .db_index               = SAM_DATABASE_BUILTIN,
3028                         .delta_type             = NETR_DELTA_MODIFY_COUNT,
3029                         .sid                    = null_sid,
3030                         .name                   = NULL,
3031                         .expected_error         = NT_STATUS_SYNCHRONIZATION_REQUIRED,
3032                         .expected_num_results   = 0,
3033                         .comment                = "NETR_DELTA_MODIFY_COUNT"
3034                 },
3035                 {
3036                         .rid                    = 0,
3037                         .flags                  = 0,
3038                         .db_index               = SAM_DATABASE_BUILTIN,
3039                         .delta_type             = NETR_DELTA_DOMAIN,
3040                         .sid                    = null_sid,
3041                         .name                   = NULL,
3042                         .expected_error         = NT_STATUS_OK,
3043                         .expected_num_results   = 1,
3044                         .expected_delta_type_1  = NETR_DELTA_DOMAIN,
3045                         .comment                = "NETR_DELTA_DOMAIN"
3046                 },
3047                 {
3048                         .rid                    = DOMAIN_RID_ADMINISTRATOR,
3049                         .flags                  = 0,
3050                         .db_index               = SAM_DATABASE_BUILTIN,
3051                         .delta_type             = NETR_DELTA_USER,
3052                         .sid                    = null_sid,
3053                         .name                   = NULL,
3054                         .expected_error         = NT_STATUS_OK,
3055                         .expected_num_results   = 1,
3056                         .expected_delta_type_1  = NETR_DELTA_DELETE_USER,
3057                         .comment                = "NETR_DELTA_USER by rid 500"
3058                 },
3059                 {
3060                         .rid                    = 0,
3061                         .flags                  = 0,
3062                         .db_index               = SAM_DATABASE_BUILTIN,
3063                         .delta_type             = NETR_DELTA_USER,
3064                         .sid                    = null_sid,
3065                         .name                   = NULL,
3066                         .expected_error         = NT_STATUS_OK,
3067                         .expected_num_results   = 1,
3068                         .expected_delta_type_1  = NETR_DELTA_DELETE_USER,
3069                         .comment                = "NETR_DELTA_USER"
3070                 },
3071                 {
3072                         .rid                    = 544,
3073                         .flags                  = 0,
3074                         .db_index               = SAM_DATABASE_BUILTIN,
3075                         .delta_type             = NETR_DELTA_ALIAS,
3076                         .sid                    = null_sid,
3077                         .name                   = NULL,
3078                         .expected_error         = NT_STATUS_OK,
3079                         .expected_num_results   = 2,
3080                         .expected_delta_type_1  = NETR_DELTA_ALIAS,
3081                         .expected_delta_type_2  = NETR_DELTA_ALIAS_MEMBER,
3082                         .comment                = "NETR_DELTA_ALIAS by rid 544"
3083                 },
3084                 {
3085                         .rid                    = 544,
3086                         .flags                  = 0,
3087                         .db_index               = SAM_DATABASE_BUILTIN,
3088                         .delta_type             = NETR_DELTA_ALIAS_MEMBER,
3089                         .sid                    = null_sid,
3090                         .name                   = NULL,
3091                         .expected_error         = NT_STATUS_OK,
3092                         .expected_num_results   = 2,
3093                         .expected_delta_type_1  = NETR_DELTA_ALIAS,
3094                         .expected_delta_type_2  = NETR_DELTA_ALIAS_MEMBER,
3095                         .comment                = "NETR_DELTA_ALIAS_MEMBER by rid 544"
3096                 },
3097                 {
3098                         .rid                    = 544,
3099                         .flags                  = 0,
3100                         .db_index               = SAM_DATABASE_BUILTIN,
3101                         .delta_type             = 0,
3102                         .sid                    = null_sid,
3103                         .name                   = NULL,
3104                         .expected_error         = NT_STATUS_OK,
3105                         .expected_num_results   = 1,
3106                         .expected_delta_type_1  = NETR_DELTA_DOMAIN,
3107                         .comment                = "NULL DELTA by rid 544"
3108                 },
3109                 {
3110                         .rid                    = 544,
3111                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
3112                         .db_index               = SAM_DATABASE_BUILTIN,
3113                         .delta_type             = 0,
3114                         .sid                    = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
3115                         .name                   = NULL,
3116                         .expected_error         = NT_STATUS_OK,
3117                         .expected_num_results   = 1,
3118                         .expected_delta_type_1  = NETR_DELTA_DOMAIN,
3119                         .comment                = "NULL DELTA by rid 544 sid S-1-5-32-544 and flags"
3120                 },
3121                 {
3122                         .rid                    = 544,
3123                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
3124                         .db_index               = SAM_DATABASE_BUILTIN,
3125                         .delta_type             = NETR_DELTA_ALIAS,
3126                         .sid                    = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
3127                         .name                   = NULL,
3128                         .expected_error         = NT_STATUS_OK,
3129                         .expected_num_results   = 2,
3130                         .expected_delta_type_1  = NETR_DELTA_ALIAS,
3131                         .expected_delta_type_2  = NETR_DELTA_ALIAS_MEMBER,
3132                         .comment                = "NETR_DELTA_ALIAS by rid 544 and sid S-1-5-32-544 and flags"
3133                 },
3134                 {
3135                         .rid                    = 0,
3136                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
3137                         .db_index               = SAM_DATABASE_BUILTIN,
3138                         .delta_type             = NETR_DELTA_ALIAS,
3139                         .sid                    = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
3140                         .name                   = NULL,
3141                         .expected_error         = NT_STATUS_OK,
3142                         .expected_num_results   = 1,
3143                         .expected_delta_type_1  = NETR_DELTA_DELETE_ALIAS,
3144                         .comment                = "NETR_DELTA_ALIAS by sid S-1-5-32-544 and flags"
3145                 },
3146
3147                 /* SAM_DATABASE_PRIVS */
3148
3149                 {
3150                         .rid                    = 0,
3151                         .flags                  = 0,
3152                         .db_index               = SAM_DATABASE_PRIVS,
3153                         .delta_type             = 0,
3154                         .sid                    = null_sid,
3155                         .name                   = NULL,
3156                         .expected_error         = NT_STATUS_ACCESS_DENIED,
3157                         .expected_num_results   = 0,
3158                         .comment                = "NULL DELTA"
3159                 },
3160                 {
3161                         .rid                    = 0,
3162                         .flags                  = 0,
3163                         .db_index               = SAM_DATABASE_PRIVS,
3164                         .delta_type             = NETR_DELTA_MODIFY_COUNT,
3165                         .sid                    = null_sid,
3166                         .name                   = NULL,
3167                         .expected_error         = NT_STATUS_SYNCHRONIZATION_REQUIRED,
3168                         .expected_num_results   = 0,
3169                         .comment                = "NETR_DELTA_MODIFY_COUNT"
3170                 },
3171                 {
3172                         .rid                    = 0,
3173                         .flags                  = 0,
3174                         .db_index               = SAM_DATABASE_PRIVS,
3175                         .delta_type             = NETR_DELTA_POLICY,
3176                         .sid                    = null_sid,
3177                         .name                   = NULL,
3178                         .expected_error         = NT_STATUS_OK,
3179                         .expected_num_results   = 1,
3180                         .expected_delta_type_1  = NETR_DELTA_POLICY,
3181                         .comment                = "NETR_DELTA_POLICY"
3182                 },
3183                 {
3184                         .rid                    = 0,
3185                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
3186                         .db_index               = SAM_DATABASE_PRIVS,
3187                         .delta_type             = NETR_DELTA_POLICY,
3188                         .sid                    = null_sid,
3189                         .name                   = NULL,
3190                         .expected_error         = NT_STATUS_OK,
3191                         .expected_num_results   = 1,
3192                         .expected_delta_type_1  = NETR_DELTA_POLICY,
3193                         .comment                = "NETR_DELTA_POLICY by null sid and flags"
3194                 },
3195                 {
3196                         .rid                    = 0,
3197                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
3198                         .db_index               = SAM_DATABASE_PRIVS,
3199                         .delta_type             = NETR_DELTA_POLICY,
3200                         .sid                    = *dom_sid_parse_talloc(tctx, "S-1-5-32"),
3201                         .name                   = NULL,
3202                         .expected_error         = NT_STATUS_OK,
3203                         .expected_num_results   = 1,
3204                         .expected_delta_type_1  = NETR_DELTA_POLICY,
3205                         .comment                = "NETR_DELTA_POLICY by sid S-1-5-32 and flags"
3206                 },
3207                 {
3208                         .rid                    = DOMAIN_RID_ADMINISTRATOR,
3209                         .flags                  = 0,
3210                         .db_index               = SAM_DATABASE_PRIVS,
3211                         .delta_type             = NETR_DELTA_ACCOUNT,
3212                         .sid                    = null_sid,
3213                         .name                   = NULL,
3214                         .expected_error         = NT_STATUS_SYNCHRONIZATION_REQUIRED, /* strange */
3215                         .expected_num_results   = 0,
3216                         .comment                = "NETR_DELTA_ACCOUNT by rid 500"
3217                 },
3218                 {
3219                         .rid                    = 0,
3220                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
3221                         .db_index               = SAM_DATABASE_PRIVS,
3222                         .delta_type             = NETR_DELTA_ACCOUNT,
3223                         .sid                    = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
3224                         .name                   = NULL,
3225                         .expected_error         = NT_STATUS_OK,
3226                         .expected_num_results   = 1,
3227                         .expected_delta_type_1  = NETR_DELTA_ACCOUNT,
3228                         .comment                = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and flags"
3229                 },
3230                 {
3231                         .rid                    = 0,
3232                         .flags                  = NETR_CHANGELOG_SID_INCLUDED |
3233                                                   NETR_CHANGELOG_IMMEDIATE_REPL_REQUIRED,
3234                         .db_index               = SAM_DATABASE_PRIVS,
3235                         .delta_type             = NETR_DELTA_ACCOUNT,
3236                         .sid                    = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
3237                         .name                   = NULL,
3238                         .expected_error         = NT_STATUS_OK,
3239                         .expected_num_results   = 1,
3240                         .expected_delta_type_1  = NETR_DELTA_ACCOUNT,
3241                         .comment                = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and 2 flags"
3242                 },
3243                 {
3244                         .rid                    = 0,
3245                         .flags                  = NETR_CHANGELOG_SID_INCLUDED |
3246                                                   NETR_CHANGELOG_NAME_INCLUDED,
3247                         .db_index               = SAM_DATABASE_PRIVS,
3248                         .delta_type             = NETR_DELTA_ACCOUNT,
3249                         .sid                    = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
3250                         .name                   = NULL,
3251                         .expected_error         = NT_STATUS_INVALID_PARAMETER,
3252                         .expected_num_results   = 0,
3253                         .comment                = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and invalid flags"
3254                 },
3255                 {
3256                         .rid                    = DOMAIN_RID_ADMINISTRATOR,
3257                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
3258                         .db_index               = SAM_DATABASE_PRIVS,
3259                         .delta_type             = NETR_DELTA_ACCOUNT,
3260                         .sid                    = *sid,
3261                         .name                   = NULL,
3262                         .expected_error         = NT_STATUS_OK,
3263                         .expected_num_results   = 1,
3264                         .expected_delta_type_1  = NETR_DELTA_DELETE_ACCOUNT,
3265                         .comment                = "NETR_DELTA_ACCOUNT by rid 500, sid and flags"
3266                 },
3267                 {
3268                         .rid                    = 0,
3269                         .flags                  = NETR_CHANGELOG_NAME_INCLUDED,
3270                         .db_index               = SAM_DATABASE_PRIVS,
3271                         .delta_type             = NETR_DELTA_SECRET,
3272                         .sid                    = null_sid,
3273                         .name                   = "IsurelydontexistIhope",
3274                         .expected_error         = NT_STATUS_OK,
3275                         .expected_num_results   = 1,
3276                         .expected_delta_type_1  = NETR_DELTA_DELETE_SECRET,
3277                         .comment                = "NETR_DELTA_SECRET by name 'IsurelydontexistIhope' and flags"
3278                 },
3279                 {
3280                         .rid                    = 0,
3281                         .flags                  = NETR_CHANGELOG_NAME_INCLUDED,
3282                         .db_index               = SAM_DATABASE_PRIVS,
3283                         .delta_type             = NETR_DELTA_SECRET,
3284                         .sid                    = null_sid,
3285                         .name                   = "G$BCKUPKEY_P",
3286                         .expected_error         = NT_STATUS_OK,
3287                         .expected_num_results   = 1,
3288                         .expected_delta_type_1  = NETR_DELTA_SECRET,
3289                         .comment                = "NETR_DELTA_SECRET by name 'G$BCKUPKEY_P' and flags"
3290                 }
3291         };
3292
3293         ZERO_STRUCT(return_authenticator);
3294
3295         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3296         r.in.computername = TEST_MACHINE_NAME;
3297         r.in.return_authenticator = &return_authenticator;
3298         r.out.return_authenticator = &return_authenticator;
3299         r.out.delta_enum_array = &delta_enum_array;
3300
3301         for (d=0; d<3; d++) {
3302                 const char *database = NULL;
3303
3304                 switch (d) {
3305                 case 0:
3306                         database = "SAM";
3307                         break;
3308                 case 1:
3309                         database = "BUILTIN";
3310                         break;
3311                 case 2:
3312                         database = "LSA";
3313                         break;
3314                 default:
3315                         break;
3316                 }
3317
3318                 torture_comment(tctx, "Testing DatabaseRedo\n");
3319
3320                 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
3321                         return false;
3322                 }
3323
3324                 for (i=0;i<ARRAY_SIZE(changes);i++) {
3325
3326                         if (d != changes[i].db_index) {
3327                                 continue;
3328                         }
3329
3330                         netlogon_creds_client_authenticator(creds, &credential);
3331
3332                         r.in.credential = &credential;
3333
3334                         e.serial_number1        = 0;
3335                         e.serial_number2        = 0;
3336                         e.object_rid            = changes[i].rid;
3337                         e.flags                 = changes[i].flags;
3338                         e.db_index              = changes[i].db_index;
3339                         e.delta_type            = changes[i].delta_type;
3340
3341                         switch (changes[i].flags & (NETR_CHANGELOG_NAME_INCLUDED | NETR_CHANGELOG_SID_INCLUDED)) {
3342                         case NETR_CHANGELOG_SID_INCLUDED:
3343                                 e.object.object_sid             = changes[i].sid;
3344                                 break;
3345                         case NETR_CHANGELOG_NAME_INCLUDED:
3346                                 e.object.object_name            = changes[i].name;
3347                                 break;
3348                         default:
3349                                 break;
3350                         }
3351
3352                         r.in.change_log_entry = e;
3353
3354                         torture_comment(tctx, "Testing DatabaseRedo with database %s and %s\n",
3355                                 database, changes[i].comment);
3356
3357                         torture_assert_ntstatus_ok(tctx, dcerpc_netr_DatabaseRedo_r(b, tctx, &r),
3358                                 "DatabaseRedo failed");
3359                         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_SUPPORTED)) {
3360                                 return true;
3361                         }
3362
3363                         torture_assert_ntstatus_equal(tctx, r.out.result, changes[i].expected_error, changes[i].comment);
3364                         if (delta_enum_array) {
3365                                 torture_assert_int_equal(tctx,
3366                                         delta_enum_array->num_deltas,
3367                                         changes[i].expected_num_results,
3368                                         changes[i].comment);
3369                                 if (delta_enum_array->num_deltas > 0) {
3370                                         torture_assert_int_equal(tctx,
3371                                                 delta_enum_array->delta_enum[0].delta_type,
3372                                                 changes[i].expected_delta_type_1,
3373                                                 changes[i].comment);
3374                                 }
3375                                 if (delta_enum_array->num_deltas > 1) {
3376                                         torture_assert_int_equal(tctx,
3377                                                 delta_enum_array->delta_enum[1].delta_type,
3378                                                 changes[i].expected_delta_type_2,
3379                                                 changes[i].comment);
3380                                 }
3381                         }
3382
3383                         if (!netlogon_creds_client_check(creds, &return_authenticator.cred)) {
3384                                 torture_comment(tctx, "Credential chaining failed\n");
3385                                 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
3386                                         return false;
3387                                 }
3388                         }
3389                 }
3390         }
3391         }
3392
3393         return true;
3394 }
3395
3396 /*
3397   try a netlogon AccountDeltas
3398 */
3399 static bool test_AccountDeltas(struct torture_context *tctx,
3400                                struct dcerpc_pipe *p,
3401                                struct cli_credentials *machine_credentials)
3402 {
3403         struct netr_AccountDeltas r;
3404         struct netlogon_creds_CredentialState *creds;
3405
3406         struct netr_AccountBuffer buffer;
3407         uint32_t count_returned = 0;
3408         uint32_t total_entries = 0;
3409         struct netr_UAS_INFO_0 recordid;
3410         struct netr_Authenticator return_authenticator;
3411         struct dcerpc_binding_handle *b = p->binding_handle;
3412
3413         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
3414                 return false;
3415         }
3416
3417         ZERO_STRUCT(return_authenticator);
3418
3419         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3420         r.in.computername = TEST_MACHINE_NAME;
3421         r.in.return_authenticator = &return_authenticator;
3422         netlogon_creds_client_authenticator(creds, &r.in.credential);
3423         ZERO_STRUCT(r.in.uas);
3424         r.in.count=10;
3425         r.in.level=0;
3426         r.in.buffersize=100;
3427         r.out.buffer = &buffer;
3428         r.out.count_returned = &count_returned;
3429         r.out.total_entries = &total_entries;
3430         r.out.recordid = &recordid;
3431         r.out.return_authenticator = &return_authenticator;
3432
3433         /* w2k3 returns "NOT IMPLEMENTED" for this call */
3434         torture_assert_ntstatus_ok(tctx, dcerpc_netr_AccountDeltas_r(b, tctx, &r),
3435                 "AccountDeltas failed");
3436         torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_IMPLEMENTED, "AccountDeltas");
3437
3438         return true;
3439 }
3440
3441 /*
3442   try a netlogon AccountSync
3443 */
3444 static bool test_AccountSync(struct torture_context *tctx, struct dcerpc_pipe *p,
3445                              struct cli_credentials *machine_credentials)
3446 {
3447         struct netr_AccountSync r;
3448         struct netlogon_creds_CredentialState *creds;
3449
3450         struct netr_AccountBuffer buffer;
3451         uint32_t count_returned = 0;
3452         uint32_t total_entries = 0;
3453         uint32_t next_reference = 0;
3454         struct netr_UAS_INFO_0 recordid;
3455         struct netr_Authenticator return_authenticator;
3456         struct dcerpc_binding_handle *b = p->binding_handle;
3457
3458         ZERO_STRUCT(recordid);
3459         ZERO_STRUCT(return_authenticator);
3460
3461         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
3462                 return false;
3463         }
3464
3465         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3466         r.in.computername = TEST_MACHINE_NAME;
3467         r.in.return_authenticator = &return_authenticator;
3468         netlogon_creds_client_authenticator(creds, &r.in.credential);
3469         r.in.recordid = &recordid;
3470         r.in.reference=0;
3471         r.in.level=0;
3472         r.in.buffersize=100;
3473         r.out.buffer = &buffer;
3474         r.out.count_returned = &count_returned;
3475         r.out.total_entries = &total_entries;
3476         r.out.next_reference = &next_reference;
3477         r.out.recordid = &recordid;
3478         r.out.return_authenticator = &return_authenticator;
3479
3480         /* w2k3 returns "NOT IMPLEMENTED" for this call */
3481         torture_assert_ntstatus_ok(tctx, dcerpc_netr_AccountSync_r(b, tctx, &r),
3482                 "AccountSync failed");
3483         torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_IMPLEMENTED, "AccountSync");
3484
3485         return true;
3486 }
3487
3488 /*
3489   try a netlogon GetDcName
3490 */
3491 static bool test_GetDcName(struct torture_context *tctx,
3492                            struct dcerpc_pipe *p)
3493 {
3494         struct netr_GetDcName r;
3495         const char *dcname = NULL;
3496         struct dcerpc_binding_handle *b = p->binding_handle;
3497
3498         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3499         r.in.domainname = lpcfg_workgroup(tctx->lp_ctx);
3500         r.out.dcname = &dcname;
3501
3502         torture_assert_ntstatus_ok(tctx, dcerpc_netr_GetDcName_r(b, tctx, &r),
3503                 "GetDcName failed");
3504         torture_assert_werr_ok(tctx, r.out.result, "GetDcName failed");
3505
3506         torture_comment(tctx, "\tDC is at '%s'\n", dcname);
3507
3508         return true;
3509 }
3510
3511 static const char *function_code_str(TALLOC_CTX *mem_ctx,
3512                                      enum netr_LogonControlCode function_code)
3513 {
3514         switch (function_code) {
3515         case NETLOGON_CONTROL_QUERY:
3516                 return "NETLOGON_CONTROL_QUERY";
3517         case NETLOGON_CONTROL_REPLICATE:
3518                 return "NETLOGON_CONTROL_REPLICATE";
3519         case NETLOGON_CONTROL_SYNCHRONIZE:
3520                 return "NETLOGON_CONTROL_SYNCHRONIZE";
3521         case NETLOGON_CONTROL_PDC_REPLICATE:
3522                 return "NETLOGON_CONTROL_PDC_REPLICATE";
3523         case NETLOGON_CONTROL_REDISCOVER:
3524                 return "NETLOGON_CONTROL_REDISCOVER";
3525         case NETLOGON_CONTROL_TC_QUERY:
3526                 return "NETLOGON_CONTROL_TC_QUERY";
3527         case NETLOGON_CONTROL_TRANSPORT_NOTIFY:
3528                 return "NETLOGON_CONTROL_TRANSPORT_NOTIFY";
3529         case NETLOGON_CONTROL_FIND_USER:
3530                 return "NETLOGON_CONTROL_FIND_USER";
3531         case NETLOGON_CONTROL_CHANGE_PASSWORD:
3532                 return "NETLOGON_CONTROL_CHANGE_PASSWORD";
3533         case NETLOGON_CONTROL_TC_VERIFY:
3534                 return "NETLOGON_CONTROL_TC_VERIFY";
3535         case NETLOGON_CONTROL_FORCE_DNS_REG:
3536                 return "NETLOGON_CONTROL_FORCE_DNS_REG";
3537         case NETLOGON_CONTROL_QUERY_DNS_REG:
3538                 return "NETLOGON_CONTROL_QUERY_DNS_REG";
3539         case NETLOGON_CONTROL_BACKUP_CHANGE_LOG:
3540                 return "NETLOGON_CONTROL_BACKUP_CHANGE_LOG";
3541         case NETLOGON_CONTROL_TRUNCATE_LOG:
3542                 return "NETLOGON_CONTROL_TRUNCATE_LOG";
3543         case NETLOGON_CONTROL_SET_DBFLAG:
3544                 return "NETLOGON_CONTROL_SET_DBFLAG";
3545         case NETLOGON_CONTROL_BREAKPOINT:
3546                 return "NETLOGON_CONTROL_BREAKPOINT";
3547         default:
3548                 return talloc_asprintf(mem_ctx, "unknown function code: %d",
3549                                        function_code);
3550         }
3551 }
3552
3553
3554 /*
3555   try a netlogon LogonControl
3556 */
3557 static bool test_LogonControl(struct torture_context *tctx,
3558                               struct dcerpc_pipe *p,
3559                               struct cli_credentials *machine_credentials)
3560
3561 {
3562         NTSTATUS status;
3563         struct netr_LogonControl r;
3564         union netr_CONTROL_QUERY_INFORMATION query;
3565         int i,f;
3566         enum netr_SchannelType secure_channel_type = SEC_CHAN_NULL;
3567         struct dcerpc_binding_handle *b = p->binding_handle;
3568
3569         uint32_t function_codes[] = {
3570                 NETLOGON_CONTROL_QUERY,
3571                 NETLOGON_CONTROL_REPLICATE,
3572                 NETLOGON_CONTROL_SYNCHRONIZE,
3573                 NETLOGON_CONTROL_PDC_REPLICATE,
3574                 NETLOGON_CONTROL_REDISCOVER,
3575                 NETLOGON_CONTROL_TC_QUERY,
3576                 NETLOGON_CONTROL_TRANSPORT_NOTIFY,
3577                 NETLOGON_CONTROL_FIND_USER,
3578                 NETLOGON_CONTROL_CHANGE_PASSWORD,
3579                 NETLOGON_CONTROL_TC_VERIFY,
3580                 NETLOGON_CONTROL_FORCE_DNS_REG,
3581                 NETLOGON_CONTROL_QUERY_DNS_REG,
3582                 NETLOGON_CONTROL_BACKUP_CHANGE_LOG,
3583                 NETLOGON_CONTROL_TRUNCATE_LOG,
3584                 NETLOGON_CONTROL_SET_DBFLAG,
3585                 NETLOGON_CONTROL_BREAKPOINT
3586         };
3587
3588         if (machine_credentials) {
3589                 secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
3590         }
3591
3592         torture_comment(tctx, "Testing LogonControl with secure channel type: %d\n",
3593                 secure_channel_type);
3594
3595         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3596         r.in.function_code = 1;
3597         r.out.query = &query;
3598
3599         for (f=0;f<ARRAY_SIZE(function_codes); f++) {
3600         for (i=1;i<5;i++) {
3601
3602                 r.in.function_code = function_codes[f];
3603                 r.in.level = i;
3604
3605                 torture_comment(tctx, "Testing LogonControl function code %s (%d) level %d\n",
3606                                 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
3607
3608                 status = dcerpc_netr_LogonControl_r(b, tctx, &r);
3609                 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
3610
3611                 switch (r.in.level) {
3612                 case 1:
3613                         switch (r.in.function_code) {
3614                         case NETLOGON_CONTROL_REPLICATE:
3615                         case NETLOGON_CONTROL_SYNCHRONIZE:
3616                         case NETLOGON_CONTROL_PDC_REPLICATE:
3617                         case NETLOGON_CONTROL_BREAKPOINT:
3618                         case NETLOGON_CONTROL_BACKUP_CHANGE_LOG:
3619                                 if ((secure_channel_type == SEC_CHAN_BDC) ||
3620                                     (secure_channel_type == SEC_CHAN_WKSTA)) {
3621                                         torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED,
3622                                                 "LogonControl returned unexpected error code");
3623                                 } else {
3624                                         torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
3625                                                 "LogonControl returned unexpected error code");
3626                                 }
3627                                 break;
3628
3629                         case NETLOGON_CONTROL_REDISCOVER:
3630                         case NETLOGON_CONTROL_TC_QUERY:
3631                         case NETLOGON_CONTROL_TRANSPORT_NOTIFY:
3632                         case NETLOGON_CONTROL_FIND_USER:
3633                         case NETLOGON_CONTROL_CHANGE_PASSWORD:
3634                         case NETLOGON_CONTROL_TC_VERIFY:
3635                         case NETLOGON_CONTROL_FORCE_DNS_REG:
3636                         case NETLOGON_CONTROL_QUERY_DNS_REG:
3637                         case NETLOGON_CONTROL_SET_DBFLAG:
3638                                 torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
3639                                         "LogonControl returned unexpected error code");
3640                                 break;
3641                         case NETLOGON_CONTROL_TRUNCATE_LOG:
3642                                 if ((secure_channel_type == SEC_CHAN_BDC) ||
3643                                     (secure_channel_type == SEC_CHAN_WKSTA)) {
3644                                         torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED,
3645                                                 "LogonControl returned unexpected error code");
3646                                 } else if (!W_ERROR_EQUAL(r.out.result, WERR_NOT_SUPPORTED)) {
3647                                         torture_assert_werr_ok(tctx, r.out.result,
3648                                                 "LogonControl returned unexpected result");
3649                                 }
3650                                 break;
3651                         default:
3652                                 torture_assert_werr_ok(tctx, r.out.result,
3653                                         "LogonControl returned unexpected result");
3654                                 break;
3655                         }
3656                         break;
3657                 case 2:
3658                         torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
3659                                 "LogonControl returned unexpected error code");
3660                         break;
3661                 default:
3662                         torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_LEVEL,
3663                                 "LogonControl returned unexpected error code");
3664                         break;
3665                 }
3666         }
3667         }
3668
3669         r.in.level = 52;
3670         torture_comment(tctx, "Testing LogonControl function code %s (%d) level %d\n",
3671                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
3672         status = dcerpc_netr_LogonControl_r(b, tctx, &r);
3673         torture_assert_ntstatus_ok(tctx, status, "LogonControl");
3674         torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_LEVEL, "LogonControl");
3675
3676         return true;
3677 }
3678
3679
3680 /*
3681   try a netlogon GetAnyDCName
3682 */
3683 static bool test_GetAnyDCName(struct torture_context *tctx,
3684                               struct dcerpc_pipe *p)
3685 {
3686         NTSTATUS status;
3687         struct netr_GetAnyDCName r;
3688         const char *dcname = NULL;
3689         struct dcerpc_binding_handle *b = p->binding_handle;
3690
3691         r.in.domainname = lpcfg_workgroup(tctx->lp_ctx);
3692         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3693         r.out.dcname = &dcname;
3694
3695         status = dcerpc_netr_GetAnyDCName_r(b, tctx, &r);
3696         torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
3697         if ((!W_ERROR_IS_OK(r.out.result)) &&
3698             (!W_ERROR_EQUAL(r.out.result, WERR_NO_SUCH_DOMAIN))) {
3699                 return false;
3700         }
3701
3702         if (dcname) {
3703             torture_comment(tctx, "\tDC is at '%s'\n", dcname);
3704         }
3705
3706         r.in.domainname = NULL;
3707
3708         status = dcerpc_netr_GetAnyDCName_r(b, tctx, &r);
3709         torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
3710         if ((!W_ERROR_IS_OK(r.out.result)) &&
3711             (!W_ERROR_EQUAL(r.out.result, WERR_NO_SUCH_DOMAIN))) {
3712                 return false;
3713         }
3714
3715         r.in.domainname = "";
3716
3717         status = dcerpc_netr_GetAnyDCName_r(b, tctx, &r);
3718         torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
3719         if ((!W_ERROR_IS_OK(r.out.result)) &&
3720             (!W_ERROR_EQUAL(r.out.result, WERR_NO_SUCH_DOMAIN))) {
3721                 return false;
3722         }
3723
3724         return true;
3725 }
3726
3727
3728 /*
3729   try a netlogon LogonControl2
3730 */
3731 static bool test_LogonControl2(struct torture_context *tctx,
3732                                struct dcerpc_pipe *p,
3733                                struct cli_credentials *machine_credentials)
3734
3735 {
3736         NTSTATUS status;
3737         struct netr_LogonControl2 r;
3738         union netr_CONTROL_DATA_INFORMATION data;
3739         union netr_CONTROL_QUERY_INFORMATION query;
3740         enum netr_SchannelType secure_channel_type = SEC_CHAN_NULL;
3741         int i;
3742         struct dcerpc_binding_handle *b = p->binding_handle;
3743
3744         data.domain = lpcfg_workgroup(tctx->lp_ctx);
3745
3746         if (machine_credentials) {
3747                 secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
3748         }
3749
3750         torture_comment(tctx, "Testing LogonControl2 with secure channel type: %d\n",
3751                 secure_channel_type);
3752
3753         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3754
3755         r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
3756         r.in.data = &data;
3757         r.out.query = &query;
3758
3759         for (i=1;i<4;i++) {
3760                 r.in.level = i;
3761
3762                 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
3763                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
3764
3765                 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
3766                 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
3767         }
3768
3769         data.domain = lpcfg_workgroup(tctx->lp_ctx);
3770
3771         r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
3772         r.in.data = &data;
3773
3774         for (i=1;i<4;i++) {
3775                 r.in.level = i;
3776
3777                 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
3778                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
3779
3780                 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
3781                 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
3782         }
3783
3784         data.domain = lpcfg_workgroup(tctx->lp_ctx);
3785
3786         r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
3787         r.in.data = &data;
3788
3789         for (i=1;i<4;i++) {
3790                 r.in.level = i;
3791
3792                 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
3793                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
3794
3795                 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
3796                 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
3797         }
3798
3799         data.debug_level = ~0;
3800
3801         r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
3802         r.in.data = &data;
3803
3804         for (i=1;i<4;i++) {
3805                 r.in.level = i;
3806
3807                 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
3808                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
3809
3810                 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
3811                 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
3812         }
3813
3814         ZERO_STRUCT(data);
3815         r.in.function_code = 52;
3816         r.in.data = &data;
3817
3818         torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
3819                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
3820
3821         status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
3822         torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
3823         switch (secure_channel_type) {
3824         case SEC_CHAN_NULL:
3825                 torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED, "LogonControl2");
3826                 break;
3827         default:
3828                 torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED, "LogonControl2");
3829                 break;
3830         }
3831         data.debug_level = ~0;
3832
3833         r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
3834         r.in.data = &data;
3835
3836         r.in.level = 52;
3837         torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
3838                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
3839
3840         status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
3841         torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
3842         torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_LEVEL, "LogonControl2");
3843
3844         return true;
3845 }
3846
3847 /*
3848   try a netlogon DatabaseSync2
3849 */
3850 static bool test_DatabaseSync2(struct torture_context *tctx,
3851                                struct dcerpc_pipe *p,
3852                                struct cli_credentials *machine_credentials)
3853 {
3854         struct netr_DatabaseSync2 r;
3855         struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
3856         struct netr_Authenticator return_authenticator, credential;
3857
3858         struct netlogon_creds_CredentialState *creds;
3859         const uint32_t database_ids[] = {0, 1, 2};
3860         int i;
3861         struct dcerpc_binding_handle *b = p->binding_handle;
3862
3863         if (!test_SetupCredentials2(p, tctx, NETLOGON_NEG_AUTH2_FLAGS,
3864                                     machine_credentials,
3865                                     cli_credentials_get_secure_channel_type(machine_credentials),
3866                                     &creds)) {
3867                 return false;
3868         }
3869
3870         ZERO_STRUCT(return_authenticator);
3871
3872         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3873         r.in.computername = TEST_MACHINE_NAME;
3874         r.in.preferredmaximumlength = (uint32_t)-1;
3875         r.in.return_authenticator = &return_authenticator;
3876         r.out.return_authenticator = &return_authenticator;
3877         r.out.delta_enum_array = &delta_enum_array;
3878
3879         for (i=0;i<ARRAY_SIZE(database_ids);i++) {
3880
3881                 uint32_t sync_context = 0;
3882
3883                 r.in.database_id = database_ids[i];
3884                 r.in.sync_context = &sync_context;
3885                 r.out.sync_context = &sync_context;
3886                 r.in.restart_state = 0;
3887
3888                 torture_comment(tctx, "Testing DatabaseSync2 of id %d\n", r.in.database_id);
3889
3890                 do {
3891                         netlogon_creds_client_authenticator(creds, &credential);
3892
3893                         r.in.credential = &credential;
3894
3895                         torture_assert_ntstatus_ok(tctx, dcerpc_netr_DatabaseSync2_r(b, tctx, &r),
3896                                 "DatabaseSync2 failed");
3897                         if (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES))
3898                             break;
3899
3900                         /* Native mode servers don't do this */
3901                         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_SUPPORTED)) {
3902                                 return true;
3903                         }
3904
3905                         torture_assert_ntstatus_ok(tctx, r.out.result, "DatabaseSync2");
3906
3907                         if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
3908                                 torture_comment(tctx, "Credential chaining failed\n");
3909                         }
3910
3911                 } while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES));
3912         }
3913
3914         return true;
3915 }
3916
3917
3918 /*
3919   try a netlogon LogonControl2Ex
3920 */
3921 static bool test_LogonControl2Ex(struct torture_context *tctx,
3922                                  struct dcerpc_pipe *p,
3923                                  struct cli_credentials *machine_credentials)
3924
3925 {
3926         NTSTATUS status;
3927         struct netr_LogonControl2Ex r;
3928         union netr_CONTROL_DATA_INFORMATION data;
3929         union netr_CONTROL_QUERY_INFORMATION query;
3930         enum netr_SchannelType secure_channel_type = SEC_CHAN_NULL;
3931         int i;
3932         struct dcerpc_binding_handle *b = p->binding_handle;
3933
3934         data.domain = lpcfg_workgroup(tctx->lp_ctx);
3935
3936         if (machine_credentials) {
3937                 secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
3938         }
3939
3940         torture_comment(tctx, "Testing LogonControl2Ex with secure channel type: %d\n",
3941                 secure_channel_type);
3942
3943         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3944
3945         r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
3946         r.in.data = &data;
3947         r.out.query = &query;
3948
3949         for (i=1;i<4;i++) {
3950                 r.in.level = i;
3951
3952                 torture_comment(tctx, "Testing LogonControl2Ex function code %s (%d) level %d\n",
3953                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
3954
3955                 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
3956                 torture_assert_ntstatus_ok(tctx, status, "LogonControl2Ex");
3957         }
3958
3959         data.domain = lpcfg_workgroup(tctx->lp_ctx);
3960
3961         r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
3962         r.in.data = &data;
3963
3964         for (i=1;i<4;i++) {
3965                 r.in.level = i;
3966
3967                 torture_comment(tctx, "Testing LogonControl2Ex function code %s (%d) level %d\n",
3968                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
3969
3970                 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
3971                 torture_assert_ntstatus_ok(tctx, status, "LogonControl2Ex");
3972         }
3973
3974         data.domain = lpcfg_workgroup(tctx->lp_ctx);
3975
3976         r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
3977         r.in.data = &data;
3978
3979         for (i=1;i<4;i++) {
3980                 r.in.level = i;
3981
3982                 torture_comment(tctx, "Testing LogonControl2Ex function code %s (%d) level %d\n",
3983                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
3984
3985                 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
3986                 torture_assert_ntstatus_ok(tctx, status, "LogonControl2Ex");
3987         }
3988
3989         data.debug_level = ~0;
3990
3991         r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
3992         r.in.data = &data;
3993
3994         for (i=1;i<4;i++) {
3995                 r.in.level = i;
3996
3997                 torture_comment(tctx, "Testing LogonControl2Ex function code %s (%d) level %d\n",
3998                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
3999
4000                 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
4001                 torture_assert_ntstatus_ok(tctx, status, "LogonControl2Ex");
4002         }
4003
4004         ZERO_STRUCT(data);
4005         r.in.function_code = 52;
4006         r.in.data = &data;
4007
4008         torture_comment(tctx, "Testing LogonControl2Ex function code %s (%d) level %d\n",
4009                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
4010
4011         status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
4012         torture_assert_ntstatus_ok(tctx, status, "LogonControl2Ex");
4013         switch (secure_channel_type) {
4014         case SEC_CHAN_NULL:
4015                 torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED, "LogonControl2Ex");
4016                 break;
4017         default:
4018                 torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED, "LogonControl2Ex");
4019                 break;
4020         }
4021         data.debug_level = ~0;
4022
4023         r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
4024         r.in.data = &data;
4025
4026         r.in.level = 52;
4027         torture_comment(tctx, "Testing LogonControl2Ex function code %s (%d) level %d\n",
4028                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
4029
4030         status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
4031         torture_assert_ntstatus_ok(tctx, status, "LogonControl2Ex");
4032         torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_LEVEL, "LogonControl2Ex");
4033
4034         return true;
4035 }
4036
4037 static bool test_netr_GetForestTrustInformation(struct torture_context *tctx,
4038                                                 struct dcerpc_pipe *p1,
4039                                                 struct cli_credentials *machine_credentials)
4040 {
4041         struct netr_GetForestTrustInformation r;
4042         struct netlogon_creds_CredentialState *creds;
4043         struct netr_Authenticator a;
4044         struct netr_Authenticator return_authenticator;
4045         struct lsa_ForestTrustInformation *forest_trust_info;
4046         struct dcerpc_pipe *p = NULL;
4047         struct dcerpc_binding_handle *b = NULL;
4048
4049         if (!test_SetupCredentials3(p1, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
4050                                     machine_credentials, &creds)) {
4051                 return false;
4052         }
4053         if (!test_SetupCredentialsPipe(p1, tctx, machine_credentials, creds,
4054                                        DCERPC_SIGN | DCERPC_SEAL, &p)) {
4055                 return false;
4056         }
4057         b = p->binding_handle;
4058
4059         netlogon_creds_client_authenticator(creds, &a);
4060
4061         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
4062         r.in.computer_name = TEST_MACHINE_NAME;
4063         r.in.credential = &a;
4064         r.in.flags = 0;
4065         r.out.return_authenticator = &return_authenticator;
4066         r.out.forest_trust_info = &forest_trust_info;
4067
4068         torture_assert_ntstatus_ok(tctx,
4069                 dcerpc_netr_GetForestTrustInformation_r(b, tctx, &r),
4070                 "netr_GetForestTrustInformation failed");
4071         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_IMPLEMENTED)) {
4072                 torture_comment(tctx, "not considering NT_STATUS_NOT_IMPLEMENTED as an error\n");
4073         } else {
4074                 torture_assert_ntstatus_ok(tctx, r.out.result,
4075                         "netr_GetForestTrustInformation failed");
4076         }
4077
4078         torture_assert(tctx,
4079                 netlogon_creds_client_check(creds, &return_authenticator.cred),
4080                 "Credential chaining failed");
4081
4082         return true;
4083 }
4084
4085 static bool test_netr_DsRGetForestTrustInformation(struct torture_context *tctx,
4086                                                    struct dcerpc_pipe *p, const char *trusted_domain_name)
4087 {
4088         NTSTATUS status;
4089         struct netr_DsRGetForestTrustInformation r;
4090         struct lsa_ForestTrustInformation info, *info_ptr;
4091         struct dcerpc_binding_handle *b = p->binding_handle;
4092
4093         info_ptr = &info;
4094
4095         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
4096         r.in.trusted_domain_name = trusted_domain_name;
4097         r.in.flags = 0;
4098         r.out.forest_trust_info = &info_ptr;
4099
4100         torture_comment(tctx ,"Testing netr_DsRGetForestTrustInformation\n");
4101
4102         status = dcerpc_netr_DsRGetForestTrustInformation_r(b, tctx, &r);
4103         torture_assert_ntstatus_ok(tctx, status, "DsRGetForestTrustInformation");
4104         torture_assert_werr_ok(tctx, r.out.result, "DsRGetForestTrustInformation");
4105
4106         return true;
4107 }
4108
4109 /*
4110   try a netlogon netr_DsrEnumerateDomainTrusts
4111 */
4112 static bool test_DsrEnumerateDomainTrusts(struct torture_context *tctx,
4113                                           struct dcerpc_pipe *p)
4114 {
4115         NTSTATUS status;
4116         struct netr_DsrEnumerateDomainTrusts r;
4117         struct netr_DomainTrustList trusts;
4118         int i;
4119         struct dcerpc_binding_handle *b = p->binding_handle;
4120
4121         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
4122         r.in.trust_flags = 0x3f;
4123         r.out.trusts = &trusts;
4124
4125         status = dcerpc_netr_DsrEnumerateDomainTrusts_r(b, tctx, &r);
4126         torture_assert_ntstatus_ok(tctx, status, "DsrEnumerateDomaintrusts");
4127         torture_assert_werr_ok(tctx, r.out.result, "DsrEnumerateDomaintrusts");
4128
4129         /* when trusted_domain_name is NULL, netr_DsRGetForestTrustInformation
4130          * will show non-forest trusts and all UPN suffixes of the own forest
4131          * as LSA_FOREST_TRUST_TOP_LEVEL_NAME types */
4132
4133         if (r.out.trusts->count) {
4134                 if (!test_netr_DsRGetForestTrustInformation(tctx, p, NULL)) {
4135                         return false;
4136                 }
4137         }
4138
4139         for (i=0; i<r.out.trusts->count; i++) {
4140
4141                 /* get info for transitive forest trusts */
4142
4143                 if (r.out.trusts->array[i].trust_attributes & LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) {
4144                         if (!test_netr_DsRGetForestTrustInformation(tctx, p,
4145                                                                     r.out.trusts->array[i].dns_name)) {
4146                                 return false;
4147                         }
4148                 }
4149         }
4150
4151         return true;
4152 }
4153
4154 static bool test_netr_NetrEnumerateTrustedDomains(struct torture_context *tctx,
4155                                                   struct dcerpc_pipe *p)
4156 {
4157         NTSTATUS status;
4158         struct netr_NetrEnumerateTrustedDomains r;
4159         struct netr_Blob trusted_domains_blob;
4160         struct dcerpc_binding_handle *b = p->binding_handle;
4161
4162         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
4163         r.out.trusted_domains_blob = &trusted_domains_blob;
4164
4165         status = dcerpc_netr_NetrEnumerateTrustedDomains_r(b, tctx, &r);
4166         torture_assert_ntstatus_ok(tctx, status, "netr_NetrEnumerateTrustedDomains");
4167         torture_assert_ntstatus_ok(tctx, r.out.result, "NetrEnumerateTrustedDomains");
4168
4169         return true;
4170 }
4171
4172 static bool test_netr_NetrEnumerateTrustedDomainsEx(struct torture_context *tctx,
4173                                                     struct dcerpc_pipe *p)
4174 {
4175         NTSTATUS status;
4176         struct netr_NetrEnumerateTrustedDomainsEx r;
4177         struct netr_DomainTrustList dom_trust_list;
4178         struct dcerpc_binding_handle *b = p->binding_handle;
4179
4180         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
4181         r.out.dom_trust_list = &dom_trust_list;
4182
4183         status = dcerpc_netr_NetrEnumerateTrustedDomainsEx_r(b, tctx, &r);
4184         torture_assert_ntstatus_ok(tctx, status, "netr_NetrEnumerateTrustedDomainsEx");
4185         torture_assert_werr_ok(tctx, r.out.result, "NetrEnumerateTrustedDomainsEx");
4186
4187         return true;
4188 }
4189
4190
4191 static bool test_netr_DsRGetSiteName(struct dcerpc_pipe *p, struct torture_context *tctx,
4192                                      const char *computer_name,
4193                                      const char *expected_site)
4194 {
4195         NTSTATUS status;
4196         struct netr_DsRGetSiteName r;
4197         const char *site = NULL;
4198         struct dcerpc_binding_handle *b = p->binding_handle;
4199
4200         r.in.computer_name              = computer_name;
4201         r.out.site                      = &site;
4202         torture_comment(tctx, "Testing netr_DsRGetSiteName\n");
4203
4204         status = dcerpc_netr_DsRGetSiteName_r(b, tctx, &r);
4205         torture_assert_ntstatus_ok(tctx, status, "DsRGetSiteName");
4206         torture_assert_werr_ok(tctx, r.out.result, "DsRGetSiteName");
4207         torture_assert_str_equal(tctx, expected_site, site, "netr_DsRGetSiteName");
4208
4209         return true;
4210 }
4211
4212 /*
4213   try a netlogon netr_DsRGetDCName
4214 */
4215 static bool test_netr_DsRGetDCName(struct torture_context *tctx,
4216                                    struct dcerpc_pipe *p)
4217 {
4218         NTSTATUS status;
4219         struct netr_DsRGetDCName r;
4220         struct netr_DsRGetDCNameInfo *info = NULL;
4221         struct dcerpc_binding_handle *b = p->binding_handle;
4222
4223         r.in.server_unc         = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
4224         r.in.domain_name        = lpcfg_dnsdomain(tctx->lp_ctx);
4225         r.in.domain_guid        = NULL;
4226         r.in.site_guid          = NULL;
4227         r.in.flags              = DS_RETURN_DNS_NAME;
4228         r.out.info              = &info;
4229
4230         status = dcerpc_netr_DsRGetDCName_r(b, tctx, &r);
4231         torture_assert_ntstatus_ok(tctx, status, "DsRGetDCName");
4232         torture_assert_werr_ok(tctx, r.out.result, "DsRGetDCName");
4233
4234         torture_assert_int_equal(tctx,
4235                                  (info->dc_flags & (DS_DNS_CONTROLLER)),
4236                                  DS_DNS_CONTROLLER,
4237                                  "DsRGetDCName");
4238         torture_assert_int_equal(tctx,
4239                                  (info->dc_flags & (DS_DNS_DOMAIN)),
4240                                  DS_DNS_DOMAIN,
4241                                  "DsRGetDCName");
4242         torture_assert_int_equal(tctx,
4243                                  (info->dc_flags & (DS_DNS_FOREST_ROOT)),
4244                                  DS_DNS_FOREST_ROOT,
4245                                  "DsRGetDCName");
4246
4247         r.in.domain_name        = lpcfg_workgroup(tctx->lp_ctx);
4248         r.in.flags              = 0;
4249
4250         status = dcerpc_netr_DsRGetDCName_r(b, tctx, &r);
4251         torture_assert_ntstatus_ok(tctx, status, "DsRGetDCName");
4252         torture_assert_werr_ok(tctx, r.out.result, "DsRGetDCName");
4253
4254         torture_assert_int_equal(tctx,
4255                                  (info->dc_flags & (DS_DNS_CONTROLLER)), 0,
4256                                  "DsRGetDCName");
4257         torture_assert_int_equal(tctx,
4258                                  (info->dc_flags & (DS_DNS_DOMAIN)), 0,
4259                                  "DsRGetDCName");
4260         torture_assert_int_equal(tctx,
4261                                  (info->dc_flags & (DS_DNS_FOREST_ROOT)),
4262                                  DS_DNS_FOREST_ROOT,
4263                                  "DsRGetDCName");
4264
4265         if (strcasecmp(info->dc_site_name, info->client_site_name) == 0) {
4266                 torture_assert_int_equal(tctx,
4267                                          (info->dc_flags & (DS_SERVER_CLOSEST)),
4268                                          DS_SERVER_CLOSEST,
4269                                          "DsRGetDCName");
4270         }
4271
4272         return test_netr_DsRGetSiteName(p, tctx,
4273                                        info->dc_unc,
4274                                        info->dc_site_name);
4275 }
4276
4277 /*
4278   try a netlogon netr_DsRGetDCNameEx
4279 */
4280 static bool test_netr_DsRGetDCNameEx(struct torture_context *tctx,
4281                                      struct dcerpc_pipe *p)
4282 {
4283         NTSTATUS status;
4284         struct netr_DsRGetDCNameEx r;
4285         struct netr_DsRGetDCNameInfo *info = NULL;
4286         struct dcerpc_binding_handle *b = p->binding_handle;
4287
4288         r.in.server_unc         = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
4289         r.in.domain_name        = lpcfg_dnsdomain(tctx->lp_ctx);
4290         r.in.domain_guid        = NULL;
4291         r.in.site_name          = NULL;
4292         r.in.flags              = DS_RETURN_DNS_NAME;
4293         r.out.info              = &info;
4294
4295         status = dcerpc_netr_DsRGetDCNameEx_r(b, tctx, &r);
4296         torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx");
4297         torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx");
4298
4299         torture_assert_int_equal(tctx,
4300                                  (info->dc_flags & (DS_DNS_CONTROLLER)),
4301                                  DS_DNS_CONTROLLER,
4302                                  "DsRGetDCNameEx");
4303         torture_assert_int_equal(tctx,
4304                                  (info->dc_flags & (DS_DNS_DOMAIN)),
4305                                  DS_DNS_DOMAIN,
4306                                  "DsRGetDCNameEx");
4307         torture_assert_int_equal(tctx,
4308                                  (info->dc_flags & (DS_DNS_FOREST_ROOT)),
4309                                  DS_DNS_FOREST_ROOT,
4310                                  "DsRGetDCNameEx");
4311
4312         r.in.domain_name        = lpcfg_workgroup(tctx->lp_ctx);
4313         r.in.flags              = 0;
4314
4315         status = dcerpc_netr_DsRGetDCNameEx_r(b, tctx, &r);
4316         torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx");
4317         torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx");
4318
4319         torture_assert_int_equal(tctx,
4320                                  (info->dc_flags & (DS_DNS_CONTROLLER)), 0,
4321                                  "DsRGetDCNameEx");
4322         torture_assert_int_equal(tctx,
4323                                  (info->dc_flags & (DS_DNS_DOMAIN)), 0,
4324                                  "DsRGetDCNameEx");
4325         torture_assert_int_equal(tctx,
4326                                  (info->dc_flags & (DS_DNS_FOREST_ROOT)),
4327                                  DS_DNS_FOREST_ROOT,
4328                                  "DsRGetDCNameEx");
4329
4330         if (strcasecmp(info->dc_site_name, info->client_site_name) == 0) {
4331                 torture_assert_int_equal(tctx,
4332                                          (info->dc_flags & (DS_SERVER_CLOSEST)),
4333                                          DS_SERVER_CLOSEST,
4334                                          "DsRGetDCNameEx");
4335         }
4336
4337         return test_netr_DsRGetSiteName(p, tctx, info->dc_unc,
4338                                         info->dc_site_name);
4339 }
4340
4341 /*
4342   try a netlogon netr_DsRGetDCNameEx2
4343 */
4344 static bool test_netr_DsRGetDCNameEx2(struct torture_context *tctx,
4345                                       struct dcerpc_pipe *p)
4346 {
4347         NTSTATUS status;
4348         struct netr_DsRGetDCNameEx2 r;
4349         struct netr_DsRGetDCNameInfo *info = NULL;
4350         struct dcerpc_binding_handle *b = p->binding_handle;
4351
4352         torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 with no inputs\n");
4353         ZERO_STRUCT(r.in);
4354         r.in.flags              = DS_RETURN_DNS_NAME;
4355         r.out.info              = &info;
4356
4357         status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
4358         torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
4359         torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
4360
4361         torture_assert_int_equal(tctx,
4362                                  (info->dc_flags & (DS_DNS_CONTROLLER)),
4363                                  DS_DNS_CONTROLLER,
4364                                  "DsRGetDCNameEx2");
4365         torture_assert_int_equal(tctx,
4366                                  (info->dc_flags & (DS_DNS_DOMAIN)),
4367                                  DS_DNS_DOMAIN,
4368                                  "DsRGetDCNameEx2");
4369         torture_assert_int_equal(tctx,
4370                                  (info->dc_flags & (DS_DNS_FOREST_ROOT)),
4371                                  DS_DNS_FOREST_ROOT,
4372                                  "DsRGetDCNameEx2");
4373
4374         r.in.server_unc         = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
4375         r.in.client_account     = NULL;
4376         r.in.mask               = 0x00000000;
4377         r.in.domain_name        = lpcfg_dnsdomain(tctx->lp_ctx);
4378         r.in.domain_guid        = NULL;
4379         r.in.site_name          = NULL;
4380         r.in.flags              = DS_RETURN_DNS_NAME;
4381         r.out.info              = &info;
4382
4383         torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 without client account\n");
4384
4385         status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
4386         torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
4387         torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
4388
4389         r.in.domain_name        = lpcfg_workgroup(tctx->lp_ctx);
4390         r.in.flags              = 0;
4391
4392         status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
4393         torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
4394         torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
4395
4396         torture_assert_int_equal(tctx,
4397                                  (info->dc_flags & (DS_DNS_CONTROLLER)), 0,
4398                                  "DsRGetDCNameEx2");
4399         torture_assert_int_equal(tctx,
4400                                  (info->dc_flags & (DS_DNS_DOMAIN)), 0,
4401                                  "DsRGetDCNameEx2");
4402         torture_assert_int_equal(tctx,
4403                                  (info->dc_flags & (DS_DNS_FOREST_ROOT)),
4404                                  DS_DNS_FOREST_ROOT,
4405                                  "DsRGetDCNameEx2");
4406
4407         if (strcasecmp(info->dc_site_name, info->client_site_name) == 0) {
4408                 torture_assert_int_equal(tctx,
4409                                          (info->dc_flags & (DS_SERVER_CLOSEST)),
4410                                          DS_SERVER_CLOSEST,
4411                                          "DsRGetDCNameEx2");
4412         }
4413
4414         torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 with client account\n");
4415         r.in.client_account     = TEST_MACHINE_NAME"$";
4416         r.in.mask               = ACB_SVRTRUST;
4417         r.in.flags              = DS_RETURN_FLAT_NAME;
4418         r.out.info              = &info;
4419
4420         status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
4421         torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
4422         torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
4423
4424         return test_netr_DsRGetSiteName(p, tctx, info->dc_unc,
4425                                         info->dc_site_name);
4426 }
4427
4428 /* This is a substitution for "samdb_server_site_name" which relies on the
4429  * correct "lp_ctx" and therefore can't be used here. */
4430 static const char *server_site_name(struct torture_context *tctx,
4431                                     struct ldb_context *ldb)
4432 {
4433         TALLOC_CTX *tmp_ctx;
4434         struct ldb_dn *dn, *server_dn;
4435         const struct ldb_val *site_name_val;
4436         const char *server_dn_str, *site_name;
4437
4438         tmp_ctx = talloc_new(ldb);
4439         if (tmp_ctx == NULL) {
4440                 goto failed;
4441         }
4442
4443         dn = ldb_dn_new(tmp_ctx, ldb, "");
4444         if (dn == NULL) {
4445                 goto failed;
4446         }
4447
4448         server_dn_str = samdb_search_string(ldb, tmp_ctx, dn, "serverName",
4449                                             NULL);
4450         if (server_dn_str == NULL) {
4451                 goto failed;
4452         }
4453
4454         server_dn = ldb_dn_new(tmp_ctx, ldb, server_dn_str);
4455         if (server_dn == NULL) {
4456                 goto failed;
4457         }
4458
4459         /* CN=<Server name>, CN=Servers, CN=<Site name>, CN=Sites, ... */
4460         site_name_val = ldb_dn_get_component_val(server_dn, 2);
4461         if (site_name_val == NULL) {
4462                 goto failed;
4463         }
4464
4465         site_name = (const char *) site_name_val->data;
4466
4467         talloc_steal(tctx, site_name);
4468         talloc_free(tmp_ctx);
4469
4470         return site_name;
4471
4472 failed:
4473         talloc_free(tmp_ctx);
4474         return NULL;
4475 }
4476
4477 static bool test_netr_DsrGetDcSiteCoverageW(struct torture_context *tctx,
4478                                             struct dcerpc_pipe *p)
4479 {
4480         char *url;
4481         struct ldb_context *sam_ctx = NULL;
4482         NTSTATUS status;
4483         struct netr_DsrGetDcSiteCoverageW r;
4484         struct DcSitesCtr *ctr = NULL;
4485         struct dcerpc_binding_handle *b = p->binding_handle;
4486
4487         torture_comment(tctx, "This does only pass with the default site\n");
4488
4489         /* We won't double-check this when we are over 'local' transports */
4490         if (dcerpc_server_name(p)) {
4491                 /* Set up connection to SAMDB on DC */
4492                 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
4493                 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
4494                                            NULL,
4495                                            popt_get_cmdline_credentials(),
4496                                            0);
4497
4498                 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
4499         }
4500
4501         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
4502         r.out.ctr = &ctr;
4503
4504         status = dcerpc_netr_DsrGetDcSiteCoverageW_r(b, tctx, &r);
4505         torture_assert_ntstatus_ok(tctx, status, "failed");
4506         torture_assert_werr_ok(tctx, r.out.result, "failed");
4507
4508         torture_assert(tctx, ctr->num_sites == 1,
4509                        "we should per default only get the default site");
4510         if (sam_ctx != NULL) {
4511                 torture_assert_casestr_equal(tctx, ctr->sites[0].string,
4512                                              server_site_name(tctx, sam_ctx),
4513                                              "didn't return default site");
4514         }
4515
4516         return true;
4517 }
4518
4519 static bool test_netr_DsRAddressToSitenamesW(struct torture_context *tctx,
4520                                              struct dcerpc_pipe *p)
4521 {
4522         char *url;
4523         struct ldb_context *sam_ctx = NULL;
4524         NTSTATUS status;
4525         struct netr_DsRAddressToSitenamesW r;
4526         struct netr_DsRAddress addrs[6];
4527         struct sockaddr_in *addr;
4528 #ifdef HAVE_IPV6
4529         struct sockaddr_in6 *addr6;
4530 #endif
4531         struct netr_DsRAddressToSitenamesWCtr *ctr;
4532         struct dcerpc_binding_handle *b = p->binding_handle;
4533         uint32_t i;
4534         int ret;
4535
4536         torture_comment(tctx, "This does only pass with the default site\n");
4537
4538         /* We won't double-check this when we are over 'local' transports */
4539         if (dcerpc_server_name(p)) {
4540                 /* Set up connection to SAMDB on DC */
4541                 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
4542                 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
4543                                            NULL,
4544                                            popt_get_cmdline_credentials(),
4545                                            0);
4546
4547                 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
4548         }
4549
4550         /* First try valid IP addresses */
4551
4552         addrs[0].size = sizeof(struct sockaddr_in);
4553         addrs[0].buffer = talloc_zero_array(tctx, uint8_t, addrs[0].size);
4554         addr = (struct sockaddr_in *) addrs[0].buffer;
4555         addrs[0].buffer[0] = AF_INET;
4556         ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
4557         torture_assert(tctx, ret > 0, "inet_pton failed");
4558
4559         addrs[1].size = sizeof(struct sockaddr_in);
4560         addrs[1].buffer = talloc_zero_array(tctx, uint8_t, addrs[1].size);
4561         addr = (struct sockaddr_in *) addrs[1].buffer;
4562         addrs[1].buffer[0] = AF_INET;
4563         ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
4564         torture_assert(tctx, ret > 0, "inet_pton failed");
4565
4566         addrs[2].size = sizeof(struct sockaddr_in);
4567         addrs[2].buffer = talloc_zero_array(tctx, uint8_t, addrs[2].size);
4568         addr = (struct sockaddr_in *) addrs[2].buffer;
4569         addrs[2].buffer[0] = AF_INET;
4570         ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
4571         torture_assert(tctx, ret > 0, "inet_pton failed");
4572
4573 #ifdef HAVE_IPV6
4574         addrs[3].size = sizeof(struct sockaddr_in6);
4575         addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
4576         addr6 = (struct sockaddr_in6 *) addrs[3].buffer;
4577         addrs[3].buffer[0] = AF_INET6;
4578         ret = inet_pton(AF_INET6, "::1", &addr6->sin6_addr);
4579         torture_assert(tctx, ret > 0, "inet_pton failed");
4580
4581         addrs[4].size = sizeof(struct sockaddr_in6);
4582         addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
4583         addr6 = (struct sockaddr_in6 *) addrs[4].buffer;
4584         addrs[4].buffer[0] = AF_INET6;
4585         ret = inet_pton(AF_INET6, "::", &addr6->sin6_addr);
4586         torture_assert(tctx, ret > 0, "inet_pton failed");
4587
4588         addrs[5].size = sizeof(struct sockaddr_in6);
4589         addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
4590         addr6 = (struct sockaddr_in6 *) addrs[5].buffer;
4591         addrs[5].buffer[0] = AF_INET6;
4592         ret = inet_pton(AF_INET6, "ff02::1", &addr6->sin6_addr);
4593         torture_assert(tctx, ret > 0, "inet_pton failed");
4594 #else
4595         /* the test cases are repeated to have exactly 6. This is for
4596          * compatibility with IPv4-only machines */
4597         addrs[3].size = sizeof(struct sockaddr_in);
4598         addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
4599         addr = (struct sockaddr_in *) addrs[3].buffer;
4600         addrs[3].buffer[0] = AF_INET;
4601         ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
4602         torture_assert(tctx, ret > 0, "inet_pton failed");
4603
4604         addrs[4].size = sizeof(struct sockaddr_in);
4605         addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
4606         addr = (struct sockaddr_in *) addrs[4].buffer;
4607         addrs[4].buffer[0] = AF_INET;
4608         ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
4609         torture_assert(tctx, ret > 0, "inet_pton failed");
4610
4611         addrs[5].size = sizeof(struct sockaddr_in);
4612         addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
4613         addr = (struct sockaddr_in *) addrs[5].buffer;
4614         addrs[5].buffer[0] = AF_INET;
4615         ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
4616         torture_assert(tctx, ret > 0, "inet_pton failed");
4617 #endif
4618
4619         ctr = talloc(tctx, struct netr_DsRAddressToSitenamesWCtr);
4620
4621         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
4622         r.in.count = 6;
4623         r.in.addresses = addrs;
4624         r.out.ctr = &ctr;
4625
4626         status = dcerpc_netr_DsRAddressToSitenamesW_r(b, tctx, &r);
4627         torture_assert_ntstatus_ok(tctx, status, "failed");
4628         torture_assert_werr_ok(tctx, r.out.result, "failed");
4629
4630         if (sam_ctx != NULL) {
4631                 for (i = 0; i < 3; i++) {
4632                         torture_assert_casestr_equal(tctx,
4633                                                      ctr->sitename[i].string,
4634                                                      server_site_name(tctx, sam_ctx),
4635                                                      "didn't return default site");
4636                 }
4637                 for (i = 3; i < 6; i++) {
4638                         /* Windows returns "NULL" for the sitename if it isn't
4639                          * IPv6 configured */
4640                         if (torture_setting_bool(tctx, "samba4", false)) {
4641                                 torture_assert_casestr_equal(tctx,
4642                                                              ctr->sitename[i].string,
4643                                                              server_site_name(tctx, sam_ctx),
4644                                                              "didn't return default site");
4645                         }
4646                 }
4647         }
4648
4649         /* Now try invalid ones (too short buffers) */
4650
4651         addrs[0].size = 0;
4652         addrs[1].size = 1;
4653         addrs[2].size = 4;
4654
4655         addrs[3].size = 0;
4656         addrs[4].size = 1;
4657         addrs[5].size = 4;
4658
4659         status = dcerpc_netr_DsRAddressToSitenamesW_r(b, tctx, &r);
4660         torture_assert_ntstatus_ok(tctx, status, "failed");
4661         torture_assert_werr_ok(tctx, r.out.result, "failed");
4662
4663         for (i = 0; i < 6; i++) {
4664                 torture_assert(tctx, ctr->sitename[i].string == NULL,
4665                                "sitename should be null");
4666         }
4667
4668         /* Now try invalid ones (wrong address types) */
4669
4670         addrs[0].size = 10;
4671         addrs[0].buffer[0] = AF_UNSPEC;
4672         addrs[1].size = 10;
4673         addrs[1].buffer[0] = AF_UNIX; /* AF_LOCAL = AF_UNIX */
4674         addrs[2].size = 10;
4675         addrs[2].buffer[0] = AF_UNIX;
4676
4677         addrs[3].size = 10;
4678         addrs[3].buffer[0] = 250;
4679         addrs[4].size = 10;
4680         addrs[4].buffer[0] = 251;
4681         addrs[5].size = 10;
4682         addrs[5].buffer[0] = 252;
4683
4684         status = dcerpc_netr_DsRAddressToSitenamesW_r(b, tctx, &r);
4685         torture_assert_ntstatus_ok(tctx, status, "failed");
4686         torture_assert_werr_ok(tctx, r.out.result, "failed");
4687
4688         for (i = 0; i < 6; i++) {
4689                 torture_assert(tctx, ctr->sitename[i].string == NULL,
4690                                "sitename should be null");
4691         }
4692
4693         return true;
4694 }
4695
4696 static bool test_netr_DsRAddressToSitenamesExW(struct torture_context *tctx,
4697                                                struct dcerpc_pipe *p)
4698 {
4699         char *url;
4700         struct ldb_context *sam_ctx = NULL;
4701         NTSTATUS status;
4702         struct netr_DsRAddressToSitenamesExW r;
4703         struct netr_DsRAddress addrs[6];
4704         struct sockaddr_in *addr;
4705 #ifdef HAVE_IPV6
4706         struct sockaddr_in6 *addr6;
4707 #endif
4708         struct netr_DsRAddressToSitenamesExWCtr *ctr;
4709         struct dcerpc_binding_handle *b = p->binding_handle;
4710         uint32_t i;
4711         int ret;
4712
4713         torture_comment(tctx, "This does pass with the default site\n");
4714
4715         /* We won't double-check this when we are over 'local' transports */
4716         if (dcerpc_server_name(p)) {
4717                 /* Set up connection to SAMDB on DC */
4718                 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
4719                 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
4720                                            NULL,
4721                                            popt_get_cmdline_credentials(),
4722                                            0);
4723
4724                 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
4725         }
4726
4727         /* First try valid IP addresses */
4728
4729         addrs[0].size = sizeof(struct sockaddr_in);
4730         addrs[0].buffer = talloc_zero_array(tctx, uint8_t, addrs[0].size);
4731         addr = (struct sockaddr_in *) addrs[0].buffer;
4732         addrs[0].buffer[0] = AF_INET;
4733         ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
4734         torture_assert(tctx, ret > 0, "inet_pton failed");
4735
4736         addrs[1].size = sizeof(struct sockaddr_in);
4737         addrs[1].buffer = talloc_zero_array(tctx, uint8_t, addrs[1].size);
4738         addr = (struct sockaddr_in *) addrs[1].buffer;
4739         addrs[1].buffer[0] = AF_INET;
4740         ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
4741         torture_assert(tctx, ret > 0, "inet_pton failed");
4742
4743         addrs[2].size = sizeof(struct sockaddr_in);
4744         addrs[2].buffer = talloc_zero_array(tctx, uint8_t, addrs[2].size);
4745         addr = (struct sockaddr_in *) addrs[2].buffer;
4746         addrs[2].buffer[0] = AF_INET;
4747         ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
4748         torture_assert(tctx, ret > 0, "inet_pton failed");
4749
4750 #ifdef HAVE_IPV6
4751         addrs[3].size = sizeof(struct sockaddr_in6);
4752         addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
4753         addr6 = (struct sockaddr_in6 *) addrs[3].buffer;
4754         addrs[3].buffer[0] = AF_INET6;
4755         ret = inet_pton(AF_INET6, "::1", &addr6->sin6_addr);
4756         torture_assert(tctx, ret > 0, "inet_pton failed");
4757
4758         addrs[4].size = sizeof(struct sockaddr_in6);
4759         addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
4760         addr6 = (struct sockaddr_in6 *) addrs[4].buffer;
4761         addrs[4].buffer[0] = AF_INET6;
4762         ret = inet_pton(AF_INET6, "::", &addr6->sin6_addr);
4763         torture_assert(tctx, ret > 0, "inet_pton failed");
4764
4765         addrs[5].size = sizeof(struct sockaddr_in6);
4766         addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
4767         addr6 = (struct sockaddr_in6 *) addrs[5].buffer;
4768         addrs[5].buffer[0] = AF_INET6;
4769         ret = inet_pton(AF_INET6, "ff02::1", &addr6->sin6_addr);
4770         torture_assert(tctx, ret > 0, "inet_pton failed");
4771 #else
4772         /* the test cases are repeated to have exactly 6. This is for
4773          * compatibility with IPv4-only machines */
4774         addrs[3].size = sizeof(struct sockaddr_in);
4775         addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
4776         addr = (struct sockaddr_in *) addrs[3].buffer;
4777         addrs[3].buffer[0] = AF_INET;
4778         ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
4779         torture_assert(tctx, ret > 0, "inet_pton failed");
4780
4781         addrs[4].size = sizeof(struct sockaddr_in);
4782         addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
4783         addr = (struct sockaddr_in *) addrs[4].buffer;
4784         addrs[4].buffer[0] = AF_INET;
4785         ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
4786         torture_assert(tctx, ret > 0, "inet_pton failed");
4787
4788         addrs[5].size = sizeof(struct sockaddr_in);
4789         addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
4790         addr = (struct sockaddr_in *) addrs[5].buffer;
4791         addrs[5].buffer[0] = AF_INET;
4792         ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
4793         torture_assert(tctx, ret > 0, "inet_pton failed");
4794 #endif
4795
4796         ctr = talloc(tctx, struct netr_DsRAddressToSitenamesExWCtr);
4797
4798         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
4799         r.in.count = 6;
4800         r.in.addresses = addrs;
4801         r.out.ctr = &ctr;
4802
4803         status = dcerpc_netr_DsRAddressToSitenamesExW_r(b, tctx, &r);
4804         torture_assert_ntstatus_ok(tctx, status, "failed");
4805         torture_assert_werr_ok(tctx, r.out.result, "failed");
4806
4807         if (sam_ctx != NULL) {
4808                 for (i = 0; i < 3; i++) {
4809                         torture_assert_casestr_equal(tctx,
4810                                                      ctr->sitename[i].string,
4811                                                      server_site_name(tctx, sam_ctx),
4812                                                      "didn't return default site");
4813                         torture_assert(tctx, ctr->subnetname[i].string == NULL,
4814                                        "subnet should be null");
4815                 }
4816                 for (i = 3; i < 6; i++) {
4817                         /* Windows returns "NULL" for the sitename if it isn't
4818                          * IPv6 configured */
4819                         if (torture_setting_bool(tctx, "samba4", false)) {
4820                                 torture_assert_casestr_equal(tctx,
4821                                                              ctr->sitename[i].string,
4822                                                              server_site_name(tctx, sam_ctx),
4823                                                              "didn't return default site");
4824                         }
4825                         torture_assert(tctx, ctr->subnetname[i].string == NULL,
4826                                        "subnet should be null");
4827                 }
4828         }
4829
4830         /* Now try invalid ones (too short buffers) */
4831
4832         addrs[0].size = 0;
4833         addrs[1].size = 1;
4834         addrs[2].size = 4;
4835
4836         addrs[3].size = 0;
4837         addrs[4].size = 1;
4838         addrs[5].size = 4;
4839
4840         status = dcerpc_netr_DsRAddressToSitenamesExW_r(b, tctx, &r);
4841         torture_assert_ntstatus_ok(tctx, status, "failed");
4842         torture_assert_werr_ok(tctx, r.out.result, "failed");
4843
4844         for (i = 0; i < 6; i++) {
4845                 torture_assert(tctx, ctr->sitename[i].string == NULL,
4846                                "sitename should be null");
4847                 torture_assert(tctx, ctr->subnetname[i].string == NULL,
4848                                "subnet should be null");
4849         }
4850
4851         addrs[0].size = 10;
4852         addrs[0].buffer[0] = AF_UNSPEC;
4853         addrs[1].size = 10;
4854         addrs[1].buffer[0] = AF_UNIX; /* AF_LOCAL = AF_UNIX */
4855         addrs[2].size = 10;
4856         addrs[2].buffer[0] = AF_UNIX;
4857
4858         addrs[3].size = 10;
4859         addrs[3].buffer[0] = 250;
4860         addrs[4].size = 10;
4861         addrs[4].buffer[0] = 251;
4862         addrs[5].size = 10;
4863         addrs[5].buffer[0] = 252;
4864
4865         status = dcerpc_netr_DsRAddressToSitenamesExW_r(b, tctx, &r);
4866         torture_assert_ntstatus_ok(tctx, status, "failed");
4867         torture_assert_werr_ok(tctx, r.out.result, "failed");
4868
4869         for (i = 0; i < 6; i++) {
4870                 torture_assert(tctx, ctr->sitename[i].string == NULL,
4871                                "sitename should be null");
4872                 torture_assert(tctx, ctr->subnetname[i].string == NULL,
4873                                "subnet should be null");
4874         }
4875
4876         return true;
4877 }
4878
4879 static bool test_netr_ServerGetTrustInfo_flags(struct torture_context *tctx,
4880                                                struct dcerpc_pipe *p1,
4881                                                struct cli_credentials *machine_credentials,
4882                                                uint32_t negotiate_flags)
4883 {
4884         struct netr_ServerGetTrustInfo r;
4885
4886         struct netr_Authenticator a;
4887         struct netr_Authenticator return_authenticator;
4888         struct samr_Password new_owf_password;
4889         struct samr_Password old_owf_password;
4890         struct netr_TrustInfo *trust_info;
4891
4892         struct netlogon_creds_CredentialState *creds;
4893         struct dcerpc_pipe *p = NULL;
4894         struct dcerpc_binding_handle *b = NULL;
4895
4896         struct samr_Password nt_hash;
4897
4898         if (!test_SetupCredentials3(p1, tctx, negotiate_flags,
4899                                     machine_credentials, &creds)) {
4900                 return false;
4901         }
4902         if (!test_SetupCredentialsPipe(p1, tctx, machine_credentials, creds,
4903                                        DCERPC_SIGN | DCERPC_SEAL, &p)) {
4904                 return false;
4905         }
4906         b = p->binding_handle;
4907
4908         netlogon_creds_client_authenticator(creds, &a);
4909
4910         r.in.server_name                = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
4911         r.in.account_name               = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
4912         r.in.secure_channel_type        = cli_credentials_get_secure_channel_type(machine_credentials);
4913         r.in.computer_name              = TEST_MACHINE_NAME;
4914         r.in.credential                 = &a;
4915
4916         r.out.return_authenticator      = &return_authenticator;
4917         r.out.new_owf_password          = &new_owf_password;
4918         r.out.old_owf_password          = &old_owf_password;
4919         r.out.trust_info                = &trust_info;
4920
4921         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerGetTrustInfo_r(b, tctx, &r),
4922                 "ServerGetTrustInfo failed");
4923         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerGetTrustInfo failed");
4924         torture_assert(tctx, netlogon_creds_client_check(creds, &return_authenticator.cred), "Credential chaining failed");
4925
4926         E_md4hash(cli_credentials_get_password(machine_credentials), nt_hash.hash);
4927
4928         netlogon_creds_des_decrypt(creds, &new_owf_password);
4929
4930         dump_data(1, new_owf_password.hash, 16);
4931         dump_data(1, nt_hash.hash, 16);
4932
4933         torture_assert_mem_equal(tctx, new_owf_password.hash, nt_hash.hash, 16,
4934                 "received unexpected owf password\n");
4935
4936         return true;
4937 }
4938
4939 static bool test_netr_ServerGetTrustInfo(struct torture_context *tctx,
4940                                          struct dcerpc_pipe *p,
4941                                          struct cli_credentials *machine_credentials)
4942 {
4943         return test_netr_ServerGetTrustInfo_flags(tctx, p, machine_credentials,
4944                                                   NETLOGON_NEG_AUTH2_ADS_FLAGS);
4945 }
4946
4947 static bool test_netr_ServerGetTrustInfo_AES(struct torture_context *tctx,
4948                                              struct dcerpc_pipe *p,
4949                                              struct cli_credentials *machine_credentials)
4950 {
4951         return test_netr_ServerGetTrustInfo_flags(tctx, p, machine_credentials,
4952                                                   NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES);
4953 }
4954
4955 static bool test_GetDomainInfo(struct torture_context *tctx,
4956                                struct dcerpc_pipe *p1,
4957                                struct cli_credentials *machine_credentials)
4958 {
4959         struct netr_LogonGetDomainInfo r;
4960         struct netr_WorkstationInformation q1;
4961         struct netr_Authenticator a;
4962         struct netlogon_creds_CredentialState *creds;
4963         struct netr_OsVersion os;
4964         union netr_WorkstationInfo query;
4965         union netr_DomainInfo info;
4966         const char* const attrs[] = { "dNSHostName", "operatingSystem",
4967                 "operatingSystemServicePack", "operatingSystemVersion",
4968                 "servicePrincipalName", NULL };
4969         char *url;
4970         struct ldb_context *sam_ctx = NULL;
4971         struct ldb_message **res;
4972         struct ldb_message_element *spn_el;
4973         int ret, i;
4974         char *version_str;
4975         const char *old_dnsname = NULL;
4976         char **spns = NULL;
4977         int num_spns = 0;
4978         char *temp_str = NULL;
4979         char *temp_str2 = NULL;
4980         struct dcerpc_pipe *p = NULL;
4981         struct dcerpc_binding_handle *b = NULL;
4982         struct netr_OneDomainInfo *odi1 = NULL;
4983         struct netr_OneDomainInfo *odi2 = NULL;
4984         struct netr_trust_extension_info *tex2 = NULL;
4985
4986         torture_comment(tctx, "Testing netr_LogonGetDomainInfo\n");
4987
4988         if (!test_SetupCredentials3(p1, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
4989                                     machine_credentials, &creds)) {
4990                 return false;
4991         }
4992         if (!test_SetupCredentialsPipe(p1, tctx, machine_credentials, creds,
4993                                        DCERPC_SIGN | DCERPC_SEAL, &p)) {
4994                 return false;
4995         }
4996         b = p->binding_handle;
4997
4998         /* We won't double-check this when we are over 'local' transports */
4999         if (dcerpc_server_name(p)) {
5000                 /* Set up connection to SAMDB on DC */
5001                 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
5002                 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
5003                                            NULL,
5004                                            popt_get_cmdline_credentials(),
5005                                            0);
5006
5007                 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
5008         }
5009
5010         torture_comment(tctx, "Testing netr_LogonGetDomainInfo 1st call (no variation of DNS hostname)\n");
5011         netlogon_creds_client_authenticator(creds, &a);
5012
5013         ZERO_STRUCT(r);
5014         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
5015         r.in.computer_name = TEST_MACHINE_NAME;
5016         r.in.credential = &a;
5017         r.in.level = 1;
5018         r.in.return_authenticator = &a;
5019         r.in.query = &query;
5020         r.out.return_authenticator = &a;
5021         r.out.info = &info;
5022
5023         ZERO_STRUCT(os);
5024         os.os.MajorVersion = 123;
5025         os.os.MinorVersion = 456;
5026         os.os.BuildNumber = 789;
5027         os.os.CSDVersion = "Service Pack 10";
5028         os.os.ServicePackMajor = 10;
5029         os.os.ServicePackMinor = 1;
5030         os.os.SuiteMask = NETR_VER_SUITE_SINGLEUSERTS;
5031         os.os.ProductType = NETR_VER_NT_SERVER;
5032         os.os.Reserved = 0;
5033
5034         version_str = talloc_asprintf(tctx, "%d.%d (%d)", os.os.MajorVersion,
5035                 os.os.MinorVersion, os.os.BuildNumber);
5036
5037         ZERO_STRUCT(q1);
5038         q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
5039                 lpcfg_dnsdomain(tctx->lp_ctx));
5040         q1.sitename = "Default-First-Site-Name";
5041         q1.os_version.os = &os;
5042         q1.os_name.string = talloc_asprintf(tctx,
5043                                             "Tortured by Samba4 RPC-NETLOGON: %s",
5044                                             timestring(tctx, time(NULL)));
5045
5046         /* The workstation handles the "servicePrincipalName" and DNS hostname
5047            updates */
5048         q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
5049
5050         query.workstation_info = &q1;
5051
5052         if (sam_ctx) {
5053                 /* Gets back the old DNS hostname in AD */
5054                 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
5055                                    "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
5056                 old_dnsname =
5057                         ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL);
5058
5059                 /* Gets back the "servicePrincipalName"s in AD */
5060                 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
5061                 if (spn_el != NULL) {
5062                         for (i=0; i < spn_el->num_values; i++) {
5063                                 spns = talloc_realloc(tctx, spns, char *, i + 1);
5064                                 spns[i] = (char *) spn_el->values[i].data;
5065                         }
5066                         num_spns = i;
5067                 }
5068         }
5069
5070         torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
5071                 "LogonGetDomainInfo failed");
5072         torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
5073         torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
5074
5075         smb_msleep(250);
5076
5077         if (sam_ctx) {
5078                 /* AD workstation infos entry check */
5079                 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
5080                                    "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
5081                 torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
5082                 torture_assert_str_equal(tctx,
5083                                          ldb_msg_find_attr_as_string(res[0], "operatingSystem", NULL),
5084                                          q1.os_name.string, "'operatingSystem' wrong!");
5085                 torture_assert_str_equal(tctx,
5086                                          ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL),
5087                                          os.os.CSDVersion, "'operatingSystemServicePack' wrong!");
5088                 torture_assert_str_equal(tctx,
5089                                          ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL),
5090                                          version_str, "'operatingSystemVersion' wrong!");
5091
5092                 if (old_dnsname != NULL) {
5093                         /* If before a DNS hostname was set then it should remain
5094                            the same in combination with the "servicePrincipalName"s.
5095                            The DNS hostname should also be returned by our
5096                            "LogonGetDomainInfo" call (in the domain info structure). */
5097
5098                         torture_assert_str_equal(tctx,
5099                                                  ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL),
5100                                                  old_dnsname, "'DNS hostname' was not set!");
5101
5102                         spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
5103                         torture_assert(tctx, ((spns != NULL) && (spn_el != NULL)),
5104                                        "'servicePrincipalName's not set!");
5105                         torture_assert(tctx, spn_el->num_values == num_spns,
5106                                        "'servicePrincipalName's incorrect!");
5107                         for (i=0; (i < spn_el->num_values) && (i < num_spns); i++)
5108                                 torture_assert_str_equal(tctx,
5109                                                          (char *) spn_el->values[i].data,
5110                                 spns[i], "'servicePrincipalName's incorrect!");
5111
5112                         torture_assert_str_equal(tctx,
5113                                                  info.domain_info->dns_hostname.string,
5114                                                  old_dnsname,
5115                                                  "Out 'DNS hostname' doesn't match the old one!");
5116                 } else {
5117                         /* If no DNS hostname was set then also now none should be set,
5118                            the "servicePrincipalName"s should remain empty and no DNS
5119                            hostname should be returned by our "LogonGetDomainInfo"
5120                            call (in the domain info structure). */
5121
5122                         torture_assert(tctx,
5123                                        ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL) == NULL,
5124                                        "'DNS hostname' was set!");
5125
5126                         spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
5127                         torture_assert(tctx, ((spns == NULL) && (spn_el == NULL)),
5128                                        "'servicePrincipalName's were set!");
5129
5130                         torture_assert(tctx,
5131                                        info.domain_info->dns_hostname.string == NULL,
5132                                        "Out 'DNS host name' was set!");
5133                 }
5134         }
5135
5136         /* Checks "workstation flags" */
5137         torture_assert(tctx,
5138                 info.domain_info->workstation_flags
5139                 == NETR_WS_FLAG_HANDLES_SPN_UPDATE,
5140                 "Out 'workstation flags' don't match!");
5141
5142
5143         torture_comment(tctx, "Testing netr_LogonGetDomainInfo 2nd call (variation of DNS hostname doesn't work)\n");
5144         netlogon_creds_client_authenticator(creds, &a);
5145
5146         /* Wipe out the osVersion, and prove which values still 'stick' */
5147         q1.os_version.os = NULL;
5148
5149         /* Change also the DNS hostname to test differences in behaviour */
5150         talloc_free(discard_const_p(char, q1.dns_hostname));
5151         q1.dns_hostname = talloc_asprintf(tctx, "%s2.%s", TEST_MACHINE_NAME,
5152                 lpcfg_dnsdomain(tctx->lp_ctx));
5153
5154         /* The workstation handles the "servicePrincipalName" and DNS hostname
5155            updates */
5156         q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
5157
5158         torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
5159                 "LogonGetDomainInfo failed");
5160         torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
5161
5162         torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
5163
5164         smb_msleep(250);
5165
5166         if (sam_ctx) {
5167                 /* AD workstation infos entry check */
5168                 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
5169                                    "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
5170                 torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
5171
5172                 torture_assert_str_equal(tctx,
5173                                          ldb_msg_find_attr_as_string(res[0], "operatingSystem", NULL),
5174                                          q1.os_name.string, "'operatingSystem' should stick!");
5175                 torture_assert(tctx,
5176                                ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL) == NULL,
5177                                "'operatingSystemServicePack' shouldn't stick!");
5178                 torture_assert(tctx,
5179                                ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL) == NULL,
5180                                "'operatingSystemVersion' shouldn't stick!");
5181
5182                 /* The DNS host name shouldn't have been updated by the server */
5183
5184                 torture_assert_str_equal(tctx,
5185                                          ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL),
5186                                          old_dnsname, "'DNS host name' did change!");
5187
5188                 /* Find the two "servicePrincipalName"s which the DC shouldn't have been
5189                    updated (HOST/<Netbios name> and HOST/<FQDN name>) - see MS-NRPC
5190                    3.5.4.3.9 */
5191                 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
5192                 torture_assert(tctx, spn_el != NULL,
5193                                "There should exist 'servicePrincipalName's in AD!");
5194                 temp_str = talloc_asprintf(tctx, "HOST/%s", TEST_MACHINE_NAME);
5195                 for (i=0; i < spn_el->num_values; i++)
5196                         if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
5197                                 break;
5198                 torture_assert(tctx, i != spn_el->num_values,
5199                                "'servicePrincipalName' HOST/<Netbios name> not found!");
5200                 temp_str = talloc_asprintf(tctx, "HOST/%s", old_dnsname);
5201                 for (i=0; i < spn_el->num_values; i++)
5202                         if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
5203                                 break;
5204                 torture_assert(tctx, i != spn_el->num_values,
5205                                "'servicePrincipalName' HOST/<FQDN name> not found!");
5206
5207                 /* Check that the out DNS hostname was set properly */
5208                 torture_assert_str_equal(tctx, info.domain_info->dns_hostname.string,
5209                                          old_dnsname, "Out 'DNS hostname' doesn't match the old one!");
5210         }
5211
5212         /* Checks "workstation flags" */
5213         torture_assert(tctx,
5214                 info.domain_info->workstation_flags == NETR_WS_FLAG_HANDLES_SPN_UPDATE,
5215                 "Out 'workstation flags' don't match!");
5216
5217
5218         /* Now try the same but the workstation flags set to 0 */
5219
5220         torture_comment(tctx, "Testing netr_LogonGetDomainInfo 3rd call (variation of DNS hostname doesn't work)\n");
5221         netlogon_creds_client_authenticator(creds, &a);
5222
5223         /* Change also the DNS hostname to test differences in behaviour */
5224         talloc_free(discard_const_p(char, q1.dns_hostname));
5225         q1.dns_hostname = talloc_asprintf(tctx, "%s2.%s", TEST_MACHINE_NAME,
5226                 lpcfg_dnsdomain(tctx->lp_ctx));
5227
5228         /* Wipe out the osVersion, and prove which values still 'stick' */
5229         q1.os_version.os = NULL;
5230
5231         /* Let the DC handle the "servicePrincipalName" and DNS hostname
5232            updates */
5233         q1.workstation_flags = 0;
5234
5235         torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
5236                 "LogonGetDomainInfo failed");
5237         torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
5238         torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
5239
5240         smb_msleep(250);
5241
5242         if (sam_ctx) {
5243                 /* AD workstation infos entry check */
5244                 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
5245                                    "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
5246                 torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
5247
5248                 torture_assert_str_equal(tctx,
5249                                          ldb_msg_find_attr_as_string(res[0], "operatingSystem", NULL),
5250                                          q1.os_name.string, "'operatingSystem' should stick!");
5251                 torture_assert(tctx,
5252                                ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL) == NULL,
5253                                "'operatingSystemServicePack' shouldn't stick!");
5254                 torture_assert(tctx,
5255                                ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL) == NULL,
5256                                "'operatingSystemVersion' shouldn't stick!");
5257
5258                 /* The DNS host name shouldn't have been updated by the server */
5259
5260                 torture_assert_str_equal(tctx,
5261                                          ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL),
5262                                          old_dnsname, "'DNS host name' did change!");
5263
5264                 /* Find the two "servicePrincipalName"s which the DC shouldn't have been
5265                    updated (HOST/<Netbios name> and HOST/<FQDN name>) - see MS-NRPC
5266                    3.5.4.3.9 */
5267                 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
5268                 torture_assert(tctx, spn_el != NULL,
5269                                "There should exist 'servicePrincipalName's in AD!");
5270                 temp_str = talloc_asprintf(tctx, "HOST/%s", TEST_MACHINE_NAME);
5271                 for (i=0; i < spn_el->num_values; i++)
5272                         if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
5273                                 break;
5274                 torture_assert(tctx, i != spn_el->num_values,
5275                                "'servicePrincipalName' HOST/<Netbios name> not found!");
5276                 temp_str = talloc_asprintf(tctx, "HOST/%s", old_dnsname);
5277                 for (i=0; i < spn_el->num_values; i++)
5278                         if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
5279                                 break;
5280                 torture_assert(tctx, i != spn_el->num_values,
5281                                "'servicePrincipalName' HOST/<FQDN name> not found!");
5282
5283                 /* Here the server gives us NULL as the out DNS hostname */
5284                 torture_assert(tctx, info.domain_info->dns_hostname.string == NULL,
5285                                "Out 'DNS hostname' should be NULL!");
5286         }
5287
5288         /* Checks "workstation flags" */
5289         torture_assert(tctx,
5290                 info.domain_info->workstation_flags == 0,
5291                 "Out 'workstation flags' don't match!");
5292
5293
5294         torture_comment(tctx, "Testing netr_LogonGetDomainInfo 4th call (verification of DNS hostname and check for trusted domains)\n");
5295         netlogon_creds_client_authenticator(creds, &a);
5296
5297         /* Put the DNS hostname back */
5298         talloc_free(discard_const_p(char, q1.dns_hostname));
5299         q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
5300                 lpcfg_dnsdomain(tctx->lp_ctx));
5301
5302         /* The workstation handles the "servicePrincipalName" and DNS hostname
5303            updates */
5304         q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
5305
5306         torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
5307                 "LogonGetDomainInfo failed");
5308         torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
5309         torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
5310
5311         smb_msleep(250);
5312
5313         /* Now the in/out DNS hostnames should be the same */
5314         torture_assert_str_equal(tctx,
5315                 info.domain_info->dns_hostname.string,
5316                 query.workstation_info->dns_hostname,
5317                 "In/Out 'DNS hostnames' don't match!");
5318         old_dnsname = info.domain_info->dns_hostname.string;
5319
5320         /* Checks "workstation flags" */
5321         torture_assert(tctx,
5322                 info.domain_info->workstation_flags
5323                 == NETR_WS_FLAG_HANDLES_SPN_UPDATE,
5324                 "Out 'workstation flags' don't match!");
5325
5326         /* Checks for trusted domains */
5327         torture_assert(tctx,
5328                 (info.domain_info->trusted_domain_count != 0)
5329                 && (info.domain_info->trusted_domains != NULL),
5330                 "Trusted domains have been requested!");
5331
5332
5333         torture_comment(tctx, "Testing netr_LogonGetDomainInfo 5th call (check for trusted domains)\n");
5334         netlogon_creds_client_authenticator(creds, &a);
5335
5336         /* The workstation handles the "servicePrincipalName" and DNS hostname
5337            updates and requests inbound trusts */
5338         q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE
5339                 | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS;
5340
5341         torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
5342                 "LogonGetDomainInfo failed");
5343         torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
5344         torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
5345
5346         smb_msleep(250);
5347
5348         /* Checks "workstation flags" */
5349         torture_assert(tctx,
5350                 info.domain_info->workstation_flags
5351                 == (NETR_WS_FLAG_HANDLES_SPN_UPDATE
5352                         | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS),
5353                 "Out 'workstation flags' don't match!");
5354
5355         /* Checks for trusted domains */
5356         torture_assert(tctx,
5357                 (info.domain_info->trusted_domain_count != 0)
5358                 && (info.domain_info->trusted_domains != NULL),
5359                 "Trusted domains have been requested!");
5360
5361         odi1 = &info.domain_info->primary_domain;
5362
5363         torture_assert(tctx, !GUID_all_zero(&odi1->domain_guid),
5364                        "primary domain_guid needs to be valid");
5365
5366         for (i=0; i < info.domain_info->trusted_domain_count; i++) {
5367                 struct netr_OneDomainInfo *odiT =
5368                         &info.domain_info->trusted_domains[i];
5369                 struct netr_trust_extension_info *texT = NULL;
5370
5371                 torture_assert_int_equal(tctx, odiT->trust_extension.length, 16,
5372                                          "trust_list should have extension");
5373                 torture_assert(tctx, odiT->trust_extension.info != NULL,
5374                                "trust_list should have extension");
5375                 texT = &odiT->trust_extension.info->info;
5376
5377                 if (GUID_equal(&odiT->domain_guid, &odi1->domain_guid)) {
5378                         odi2 = odiT;
5379                         tex2 = texT;
5380                         continue;
5381                 }
5382
5383                 torture_assert_int_equal(tctx,
5384                                  texT->flags & NETR_TRUST_FLAG_PRIMARY,
5385                                  0,
5386                                  "trust_list flags should not have PRIMARY");
5387
5388                 torture_assert(tctx, odiT->domainname.string != NULL,
5389                                "trust_list domainname should be valid");
5390                 if (texT->trust_type == LSA_TRUST_TYPE_DOWNLEVEL) {
5391                         torture_assert(tctx, odiT->dns_domainname.string == NULL,
5392                                "trust_list dns_domainname should be NULL for downlevel");
5393                 } else {
5394                         torture_assert(tctx, odiT->dns_domainname.string != NULL,
5395                                "trust_list dns_domainname should be valid for uplevel");
5396                 }
5397                 torture_assert(tctx, odiT->dns_forestname.string == NULL,
5398                                "trust_list dns_forestname needs to be NULL");
5399
5400                 torture_assert(tctx, odiT->domain_sid != NULL,
5401                                "trust_list domain_sid needs to be valid");
5402         }
5403
5404         torture_assert(tctx, odi2 != NULL,
5405                        "trust_list primary domain not found.");
5406
5407         torture_assert_str_equal(tctx,
5408                                  odi1->domainname.string,
5409                                  odi2->domainname.string,
5410                                  "netbios name should match");
5411
5412         temp_str = talloc_strdup(tctx, odi1->dns_domainname.string);
5413         torture_assert(tctx, temp_str != NULL,
5414                        "primary_domain dns_domainname copy");
5415         temp_str2 = strrchr(temp_str, '.');
5416         torture_assert(tctx, temp_str2 != NULL && temp_str2[1] == '\0',
5417                        "primary_domain dns_domainname needs trailing '.'");
5418         temp_str2[0] = '\0';
5419         torture_assert_str_equal(tctx,
5420                                  temp_str,
5421                                  odi2->dns_domainname.string,
5422                                  "dns domainname should match "
5423                                  "(without trailing '.')");
5424
5425         temp_str = talloc_strdup(tctx, odi1->dns_forestname.string);
5426         torture_assert(tctx, temp_str != NULL,
5427                        "primary_domain dns_forestname copy");
5428         temp_str2 = strrchr(temp_str, '.');
5429         torture_assert(tctx, temp_str2 != NULL && temp_str2[1] == '\0',
5430                        "primary_domain dns_forestname needs trailing '.'");
5431         temp_str2[0] = '\0';
5432         torture_assert(tctx, odi2->dns_forestname.string == NULL,
5433                        "trust_list dns_forestname needs to be NULL");
5434
5435         torture_assert_guid_equal(tctx, odi1->domain_guid, odi2->domain_guid,
5436                                   "domain_guid should match");
5437         torture_assert(tctx, odi1->domain_sid != NULL,
5438                        "primary domain_sid needs to be valid");
5439         torture_assert(tctx, odi2->domain_sid != NULL,
5440                        "trust_list domain_sid needs to be valid");
5441         torture_assert_sid_equal(tctx, odi1->domain_sid, odi2->domain_sid,
5442                                  "domain_sid should match");
5443
5444         torture_assert_int_equal(tctx, odi1->trust_extension.length, 0,
5445                                  "primary_domain should not have extension");
5446         torture_assert_int_equal(tctx, odi2->trust_extension.length, 16,
5447                                  "trust_list should have extension");
5448         torture_assert(tctx, odi2->trust_extension.info != NULL,
5449                        "trust_list should have extension");
5450         tex2 = &odi2->trust_extension.info->info;
5451         torture_assert_int_equal(tctx,
5452                                  tex2->flags & NETR_TRUST_FLAG_PRIMARY,
5453                                  NETR_TRUST_FLAG_PRIMARY,
5454                                  "trust_list flags should have PRIMARY");
5455         torture_assert_int_equal(tctx,
5456                                  tex2->flags & NETR_TRUST_FLAG_IN_FOREST,
5457                                  NETR_TRUST_FLAG_IN_FOREST,
5458                                  "trust_list flags should have IN_FOREST");
5459         torture_assert_int_equal(tctx,
5460                                  tex2->flags & NETR_TRUST_FLAG_NATIVE,
5461                                  NETR_TRUST_FLAG_NATIVE,
5462                                  "trust_list flags should have NATIVE");
5463         torture_assert_int_equal(tctx,
5464                                  tex2->flags & ~NETR_TRUST_FLAG_TREEROOT,
5465                                  NETR_TRUST_FLAG_IN_FOREST |
5466                                  NETR_TRUST_FLAG_PRIMARY |
5467                                  NETR_TRUST_FLAG_NATIVE,
5468                                  "trust_list flags IN_FOREST, PRIMARY, NATIVE "
5469                                  "(TREEROOT optional)");
5470         if (strcmp(odi1->dns_domainname.string, odi1->dns_forestname.string) == 0) {
5471                 torture_assert_int_equal(tctx,
5472                                          tex2->flags & NETR_TRUST_FLAG_TREEROOT,
5473                                          NETR_TRUST_FLAG_TREEROOT,
5474                                          "trust_list flags TREEROOT on forest root");
5475                 torture_assert_int_equal(tctx,
5476                                          tex2->parent_index, 0,
5477                                          "trust_list no parent on foreset root");
5478         }
5479         torture_assert_int_equal(tctx,
5480                                  tex2->trust_type, LSA_TRUST_TYPE_UPLEVEL,
5481                                  "trust_list uplevel");
5482         torture_assert_int_equal(tctx,
5483                                  tex2->trust_attributes, 0,
5484                                  "trust_list no attributes");
5485
5486         torture_comment(tctx, "Testing netr_LogonGetDomainInfo 6th call (no DNS hostname)\n");
5487         netlogon_creds_client_authenticator(creds, &a);
5488
5489         query.workstation_info->dns_hostname = NULL;
5490
5491         torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
5492                 "LogonGetDomainInfo failed");
5493         torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
5494         torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
5495
5496         /* The old DNS hostname should stick */
5497         torture_assert_str_equal(tctx,
5498                 info.domain_info->dns_hostname.string,
5499                 old_dnsname,
5500                 "'DNS hostname' changed!");
5501
5502         torture_comment(tctx, "Testing netr_LogonGetDomainInfo 7th call (extra workstation flags)\n");
5503         netlogon_creds_client_authenticator(creds, &a);
5504
5505         q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE
5506                 | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS | 0x4;
5507
5508         /* Put the DNS hostname back */
5509         talloc_free(discard_const_p(char, q1.dns_hostname));
5510         q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
5511                 lpcfg_dnsdomain(tctx->lp_ctx));
5512
5513         torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
5514                 "LogonGetDomainInfo failed");
5515         torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
5516         torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
5517
5518         /* Checks "workstation flags" */
5519         torture_assert(tctx,
5520                 info.domain_info->workstation_flags
5521                 == (NETR_WS_FLAG_HANDLES_SPN_UPDATE
5522                         | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS),
5523                 "Out 'workstation flags' don't match!");
5524
5525         if (!torture_setting_bool(tctx, "dangerous", false)) {
5526                 torture_comment(tctx, "Not testing netr_LogonGetDomainInfo 8th call (no workstation info) - enable dangerous tests in order to do so\n");
5527         } else {
5528                 /* Try a call without the workstation information structure */
5529
5530                 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 8th call (no workstation info)\n");
5531                 netlogon_creds_client_authenticator(creds, &a);
5532
5533                 query.workstation_info = NULL;
5534
5535                 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
5536                         "LogonGetDomainInfo failed");
5537                 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
5538                 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
5539         }
5540
5541         return true;
5542 }
5543
5544 static bool test_GetDomainInfo_async(struct torture_context *tctx,
5545                                      struct dcerpc_pipe *p1,
5546                                      struct cli_credentials *machine_credentials)
5547 {
5548         NTSTATUS status;
5549         struct netr_LogonGetDomainInfo r;
5550         struct netr_WorkstationInformation q1;
5551         struct netr_Authenticator a;
5552 #define ASYNC_COUNT 100
5553         struct netlogon_creds_CredentialState *creds;
5554         struct netlogon_creds_CredentialState *creds_async[ASYNC_COUNT];
5555         struct tevent_req *req[ASYNC_COUNT];
5556         int i;
5557         union netr_WorkstationInfo query;
5558         union netr_DomainInfo info;
5559         struct dcerpc_pipe *p = NULL;
5560
5561         torture_comment(tctx, "Testing netr_LogonGetDomainInfo - async count %d\n", ASYNC_COUNT);
5562
5563         if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
5564                                     machine_credentials, &creds)) {
5565                 return false;
5566         }
5567         if (!test_SetupCredentialsPipe(p1, tctx, machine_credentials, creds,
5568                                        DCERPC_SIGN | DCERPC_SEAL, &p)) {
5569                 return false;
5570         }
5571
5572         ZERO_STRUCT(r);
5573         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
5574         r.in.computer_name = TEST_MACHINE_NAME;
5575         r.in.credential = &a;
5576         r.in.level = 1;
5577         r.in.return_authenticator = &a;
5578         r.in.query = &query;
5579         r.out.return_authenticator = &a;
5580         r.out.info = &info;
5581
5582         ZERO_STRUCT(q1);
5583         q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
5584                 lpcfg_dnsdomain(tctx->lp_ctx));
5585         q1.sitename = "Default-First-Site-Name";
5586         q1.os_name.string = "UNIX/Linux or similar";
5587
5588         query.workstation_info = &q1;
5589
5590         for (i=0;i<ASYNC_COUNT;i++) {
5591                 netlogon_creds_client_authenticator(creds, &a);
5592
5593                 creds_async[i] = (struct netlogon_creds_CredentialState *)talloc_memdup(creds, creds, sizeof(*creds));
5594                 req[i] = dcerpc_netr_LogonGetDomainInfo_r_send(tctx, tctx->ev, p->binding_handle, &r);
5595
5596                 /* even with this flush per request a w2k3 server seems to
5597                    clag with multiple outstanding requests. bleergh. */
5598                 torture_assert_int_equal(tctx, tevent_loop_once(tctx->ev), 0,
5599                                          "tevent_loop_once failed");
5600         }
5601
5602         for (i=0;i<ASYNC_COUNT;i++) {
5603                 torture_assert_int_equal(tctx, tevent_req_poll(req[i], tctx->ev), true,
5604                                          "tevent_req_poll() failed");
5605
5606                 status = dcerpc_netr_LogonGetDomainInfo_r_recv(req[i], tctx);
5607
5608                 torture_assert_ntstatus_ok(tctx, status, "netr_LogonGetDomainInfo_async");
5609                 torture_assert_ntstatus_ok(tctx, r.out.result, "netr_LogonGetDomainInfo_async");
5610
5611                 torture_assert(tctx, netlogon_creds_client_check(creds_async[i], &a.cred),
5612                         "Credential chaining failed at async");
5613         }
5614
5615         torture_comment(tctx,
5616                         "Testing netr_LogonGetDomainInfo - async count %d OK\n", ASYNC_COUNT);
5617
5618         return true;
5619 }
5620
5621 static bool test_ManyGetDCName(struct torture_context *tctx,
5622                                struct dcerpc_pipe *p)
5623 {
5624         NTSTATUS status;
5625         struct cli_credentials *anon_creds;
5626         struct dcerpc_binding *binding2;
5627         struct dcerpc_pipe *p2;
5628         struct lsa_ObjectAttribute attr;
5629         struct lsa_QosInfo qos;
5630         struct lsa_OpenPolicy2 o;
5631         struct policy_handle lsa_handle;
5632         struct lsa_DomainList domains;
5633
5634         struct lsa_EnumTrustDom t;
5635         uint32_t resume_handle = 0;
5636         struct netr_GetAnyDCName d;
5637         const char *dcname = NULL;
5638         struct dcerpc_binding_handle *b = p->binding_handle;
5639         struct dcerpc_binding_handle *b2;
5640
5641         int i;
5642
5643         if (p->conn->transport.transport != NCACN_NP) {
5644                 torture_skip(tctx, "test_ManyGetDCName works only with NCACN_NP");
5645         }
5646
5647         torture_comment(tctx, "Torturing GetDCName\n");
5648
5649         anon_creds = cli_credentials_init_anon(tctx);
5650         torture_assert(tctx, anon_creds != NULL, "cli_credentials_init_anon failed");
5651
5652         binding2 = dcerpc_binding_dup(tctx, p->binding);
5653         /* Swap the binding details from NETLOGON to LSA */
5654         status = dcerpc_epm_map_binding(tctx, binding2, &ndr_table_lsarpc, tctx->ev, tctx->lp_ctx);
5655         dcerpc_binding_set_assoc_group_id(binding2, 0);
5656         torture_assert_ntstatus_ok(tctx, status, "epm map");
5657
5658         status = dcerpc_secondary_auth_connection(p, binding2, &ndr_table_lsarpc,
5659                                                   anon_creds, tctx->lp_ctx,
5660                                                   tctx, &p2);
5661         torture_assert_ntstatus_ok(tctx, status, "Failed to create secondary connection");
5662         b2 = p2->binding_handle;
5663
5664         qos.len = 0;
5665         qos.impersonation_level = 2;
5666         qos.context_mode = 1;
5667         qos.effective_only = 0;
5668
5669         attr.len = 0;
5670         attr.root_dir = NULL;
5671         attr.object_name = NULL;
5672         attr.attributes = 0;
5673         attr.sec_desc = NULL;
5674         attr.sec_qos = &qos;
5675
5676         o.in.system_name = "\\";
5677         o.in.attr = &attr;
5678         o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5679         o.out.handle = &lsa_handle;
5680
5681         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenPolicy2_r(b2, tctx, &o),
5682                 "OpenPolicy2 failed");
5683         torture_assert_ntstatus_ok(tctx, o.out.result, "OpenPolicy2 failed");
5684
5685         t.in.handle = &lsa_handle;
5686         t.in.resume_handle = &resume_handle;
5687         t.in.max_size = 1000;
5688         t.out.domains = &domains;
5689         t.out.resume_handle = &resume_handle;
5690
5691         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumTrustDom_r(b2, tctx, &t),
5692                 "EnumTrustDom failed");
5693
5694         if ((!NT_STATUS_IS_OK(t.out.result) &&
5695              (!NT_STATUS_EQUAL(t.out.result, NT_STATUS_NO_MORE_ENTRIES))))
5696                 torture_fail(tctx, "Could not list domains");
5697
5698         talloc_free(p2);
5699
5700         d.in.logon_server = talloc_asprintf(tctx, "\\\\%s",
5701                                             dcerpc_server_name(p));
5702         d.out.dcname = &dcname;
5703
5704         for (i=0; i<domains.count * 4; i++) {
5705                 struct lsa_DomainInfo *info =
5706                         &domains.domains[rand()%domains.count];
5707
5708                 d.in.domainname = info->name.string;
5709
5710                 status = dcerpc_netr_GetAnyDCName_r(b, tctx, &d);
5711                 torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
5712
5713                 torture_comment(tctx, "\tDC for domain %s is %s\n", info->name.string,
5714                        dcname ? dcname : "unknown");
5715         }
5716
5717         return true;
5718 }
5719
5720 static bool test_lsa_over_netlogon(struct torture_context *tctx,
5721                                    struct dcerpc_pipe *p)
5722 {
5723         NTSTATUS status;
5724         struct cli_credentials *anon_creds;
5725         const struct dcerpc_binding *binding2;
5726         struct dcerpc_pipe *p2;
5727         struct lsa_ObjectAttribute attr;
5728         struct lsa_QosInfo qos;
5729         struct lsa_OpenPolicy2 o;
5730         struct policy_handle lsa_handle;
5731
5732         struct dcerpc_binding_handle *b2;
5733
5734
5735         if (p->conn->transport.transport != NCACN_NP) {
5736                 torture_skip(tctx, "test_lsa_over_netlogon works only with NCACN_NP");
5737         }
5738
5739         torture_comment(tctx, "Testing if we can access the LSA server over\n"
5740                         " \\\\pipe\\netlogon rather than \\\\pipe\\lsarpc\n");
5741
5742         anon_creds = cli_credentials_init_anon(tctx);
5743         torture_assert(tctx, anon_creds != NULL, "cli_credentials_init_anon failed");
5744
5745         binding2 = p->binding;
5746
5747         status = dcerpc_secondary_auth_connection(p, binding2, &ndr_table_lsarpc,
5748                                                   anon_creds, tctx->lp_ctx,
5749                                                   tctx, &p2);
5750         torture_assert_ntstatus_ok(tctx, status, "Failed to create secondary connection");
5751         b2 = p2->binding_handle;
5752
5753         qos.len = 0;
5754         qos.impersonation_level = 2;
5755         qos.context_mode = 1;
5756         qos.effective_only = 0;
5757
5758         attr.len = 0;
5759         attr.root_dir = NULL;
5760         attr.object_name = NULL;
5761         attr.attributes = 0;
5762         attr.sec_desc = NULL;
5763         attr.sec_qos = &qos;
5764
5765         o.in.system_name = "\\";
5766         o.in.attr = &attr;
5767         o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5768         o.out.handle = &lsa_handle;
5769
5770         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenPolicy2_r(b2, tctx, &o),
5771                 "OpenPolicy2 failed");
5772         torture_assert_ntstatus_ok(tctx, o.out.result, "OpenPolicy2 failed");
5773
5774         talloc_free(p2);
5775
5776         return true;
5777 }
5778
5779 static bool test_SetPassword_with_flags(struct torture_context *tctx,
5780                                         struct dcerpc_pipe *p,
5781                                         struct cli_credentials *machine_credentials)
5782 {
5783         uint32_t flags[] = { 0, NETLOGON_NEG_STRONG_KEYS };
5784         struct netlogon_creds_CredentialState *creds;
5785         int i;
5786
5787         if (!test_SetupCredentials2(p, tctx, 0,
5788                                     machine_credentials,
5789                                     cli_credentials_get_secure_channel_type(machine_credentials),
5790                                     &creds)) {
5791                 torture_skip(tctx, "DC does not support negotiation of 64bit session keys");
5792         }
5793
5794         for (i=0; i < ARRAY_SIZE(flags); i++) {
5795                 torture_assert(tctx,
5796                         test_SetPassword_flags(tctx, p, machine_credentials, flags[i]),
5797                         talloc_asprintf(tctx, "failed to test SetPassword negotiating with 0x%08x flags", flags[i]));
5798         }
5799
5800         return true;
5801 }
5802
5803 struct torture_suite *torture_rpc_netlogon(TALLOC_CTX *mem_ctx)
5804 {
5805         struct torture_suite *suite = torture_suite_create(mem_ctx, "netlogon");
5806         struct torture_rpc_tcase *tcase;
5807         struct torture_test *test;
5808
5809         tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netlogon",
5810                                                   &ndr_table_netlogon, TEST_MACHINE_NAME);
5811
5812         torture_rpc_tcase_add_test_creds(tcase, "SetupCredentialsDowngrade", test_SetupCredentialsDowngrade);
5813         torture_rpc_tcase_add_test(tcase, "lsa_over_netlogon", test_lsa_over_netlogon);
5814
5815         torture_rpc_tcase_add_test_creds(tcase, "GetForestTrustInformation", test_netr_GetForestTrustInformation);
5816         torture_rpc_tcase_add_test_creds(tcase, "ServerGetTrustInfo_AES", test_netr_ServerGetTrustInfo_AES);
5817         torture_rpc_tcase_add_test_creds(tcase, "ServerGetTrustInfo", test_netr_ServerGetTrustInfo);
5818         torture_rpc_tcase_add_test(tcase, "DsRAddressToSitenamesExW", test_netr_DsRAddressToSitenamesExW);
5819         torture_rpc_tcase_add_test(tcase, "DsRAddressToSitenamesW", test_netr_DsRAddressToSitenamesW);
5820         torture_rpc_tcase_add_test(tcase, "DsrGetDcSiteCoverageW", test_netr_DsrGetDcSiteCoverageW);
5821         torture_rpc_tcase_add_test(tcase, "DsRGetDCNameEx2", test_netr_DsRGetDCNameEx2);
5822         torture_rpc_tcase_add_test(tcase, "DsRGetDCNameEx", test_netr_DsRGetDCNameEx);
5823         torture_rpc_tcase_add_test(tcase, "DsRGetDCName", test_netr_DsRGetDCName);
5824         test = torture_rpc_tcase_add_test_creds(tcase, "GetDomainInfo_async", test_GetDomainInfo_async);
5825         test->dangerous = true;
5826         torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomainsEx", test_netr_NetrEnumerateTrustedDomainsEx);
5827         torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomains", test_netr_NetrEnumerateTrustedDomains);
5828         torture_rpc_tcase_add_test(tcase, "DsrEnumerateDomainTrusts", test_DsrEnumerateDomainTrusts);
5829         torture_rpc_tcase_add_test_creds(tcase, "DatabaseSync2", test_DatabaseSync2);
5830         torture_rpc_tcase_add_test(tcase, "GetAnyDCName", test_GetAnyDCName);
5831         torture_rpc_tcase_add_test(tcase, "ManyGetDCName", test_ManyGetDCName);
5832         torture_rpc_tcase_add_test(tcase, "GetDcName", test_GetDcName);
5833         torture_rpc_tcase_add_test_creds(tcase, "AccountSync", test_AccountSync);
5834         torture_rpc_tcase_add_test_creds(tcase, "AccountDeltas", test_AccountDeltas);
5835         torture_rpc_tcase_add_test_creds(tcase, "DatabaseRedo", test_DatabaseRedo);
5836         torture_rpc_tcase_add_test_creds(tcase, "DatabaseDeltas", test_DatabaseDeltas);
5837         torture_rpc_tcase_add_test_creds(tcase, "DatabaseSync", test_DatabaseSync);
5838         torture_rpc_tcase_add_test_creds(tcase, "GetDomainInfo", test_GetDomainInfo);
5839         torture_rpc_tcase_add_test_creds(tcase, "GetTrustPasswords", test_GetTrustPasswords);
5840         torture_rpc_tcase_add_test_creds(tcase, "GetPassword", test_GetPassword);
5841         torture_rpc_tcase_add_test_creds(tcase, "SetPassword2_AES", test_SetPassword2_AES);
5842         torture_rpc_tcase_add_test_creds(tcase, "SetPassword2", test_SetPassword2);
5843         torture_rpc_tcase_add_test_creds(tcase, "SetPassword", test_SetPassword);
5844         torture_rpc_tcase_add_test_creds(tcase, "ServerReqChallengeReuse", test_ServerReqChallengeReuse);
5845         torture_rpc_tcase_add_test_creds(tcase, "ServerReqChallengeReuseGlobal4", test_ServerReqChallengeReuseGlobal4);
5846         torture_rpc_tcase_add_test_creds(tcase, "ServerReqChallengeReuseGlobal3", test_ServerReqChallengeReuseGlobal3);
5847         torture_rpc_tcase_add_test_creds(tcase, "ServerReqChallengeReuseGlobal2", test_ServerReqChallengeReuseGlobal2);
5848         torture_rpc_tcase_add_test_creds(tcase, "ServerReqChallengeReuseGlobal", test_ServerReqChallengeReuseGlobal);
5849         torture_rpc_tcase_add_test_creds(tcase, "ServerReqChallengeGlobal", test_ServerReqChallengeGlobal);
5850         torture_rpc_tcase_add_test_creds(tcase, "invalidAuthenticate2", test_invalidAuthenticate2);
5851         torture_rpc_tcase_add_test_creds(tcase, "SamLogon", test_SamLogon);
5852         torture_rpc_tcase_add_test(tcase, "LogonUasLogoff", test_LogonUasLogoff);
5853         torture_rpc_tcase_add_test(tcase, "LogonUasLogon", test_LogonUasLogon);
5854
5855         torture_rpc_tcase_add_test(tcase, "Broken RPC binding handle",
5856                                    test_netr_broken_binding_handle);
5857
5858         return suite;
5859 }
5860
5861 struct torture_suite *torture_rpc_netlogon_s3(TALLOC_CTX *mem_ctx)
5862 {
5863         struct torture_suite *suite = torture_suite_create(mem_ctx, "netlogon-s3");
5864         struct torture_rpc_tcase *tcase;
5865
5866         tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netlogon",
5867                                                   &ndr_table_netlogon, TEST_MACHINE_NAME);
5868
5869         torture_rpc_tcase_add_test_creds(tcase, "SamLogon", test_SamLogon);
5870         torture_rpc_tcase_add_test_creds(tcase, "SamLogon_NULL_domain", test_SamLogon_NULL_domain);
5871         torture_rpc_tcase_add_test_creds(tcase, "SetPassword", test_SetPassword);
5872         torture_rpc_tcase_add_test_creds(tcase, "SetPassword_with_flags", test_SetPassword_with_flags);
5873         torture_rpc_tcase_add_test_creds(tcase, "SetPassword2", test_SetPassword2);
5874         torture_rpc_tcase_add_test_creds(tcase, "SetPassword2_AES", test_SetPassword2_AES);
5875         torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomains", test_netr_NetrEnumerateTrustedDomains);
5876
5877         return suite;
5878 }
5879
5880 struct torture_suite *torture_rpc_netlogon_zerologon(TALLOC_CTX *mem_ctx)
5881 {
5882         struct torture_suite *suite = torture_suite_create(
5883                 mem_ctx,
5884                 "netlogon.zerologon");
5885         struct torture_rpc_tcase *tcase;
5886
5887         tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(
5888                 suite,
5889                 "netlogon",
5890                 &ndr_table_netlogon,
5891                 TEST_MACHINE_NAME);
5892
5893         torture_rpc_tcase_add_test_creds(
5894                 tcase,
5895                 "ServerReqChallenge",
5896                 test_ServerReqChallenge);
5897         torture_rpc_tcase_add_test_creds(
5898                 tcase,
5899                 "ServerReqChallenge_zero_challenge",
5900                 test_ServerReqChallenge_zero_challenge);
5901         torture_rpc_tcase_add_test_creds(
5902                 tcase,
5903                 "ServerReqChallenge_5_repeats",
5904                 test_ServerReqChallenge_5_repeats);
5905         torture_rpc_tcase_add_test_creds(
5906                 tcase,
5907                 "ServerReqChallenge_4_repeats",
5908                 test_ServerReqChallenge_4_repeats);
5909         torture_rpc_tcase_add_test_creds(
5910                 tcase,
5911                 "test_SetPassword2_encrypted_to_all_zeros",
5912                 test_SetPassword2_encrypted_to_all_zeros);
5913         torture_rpc_tcase_add_test_creds(
5914                 tcase,
5915                 "test_SetPassword2_password_encrypts_to_zero",
5916                 test_SetPassword2_password_encrypts_to_zero);
5917         torture_rpc_tcase_add_test_creds(
5918                 tcase,
5919                 "test_SetPassword2_confounder",
5920                 test_SetPassword2_confounder);
5921         torture_rpc_tcase_add_test_creds(
5922                 tcase,
5923                 "test_SetPassword2_all_zeros",
5924                 test_SetPassword2_all_zeros);
5925         torture_rpc_tcase_add_test_creds(
5926                 tcase,
5927                 "test_SetPassword2_all_zero_password",
5928                 test_SetPassword2_all_zero_password);
5929         torture_rpc_tcase_add_test_creds(
5930                 tcase,
5931                 "test_SetPassword2_maximum_length_password",
5932                 test_SetPassword2_maximum_length_password);
5933
5934         return suite;
5935 }
5936
5937 struct torture_suite *torture_rpc_netlogon_admin(TALLOC_CTX *mem_ctx)
5938 {
5939         struct torture_suite *suite = torture_suite_create(mem_ctx, "netlogon.admin");
5940         struct torture_rpc_tcase *tcase;
5941
5942         tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "bdc",
5943                                                   &ndr_table_netlogon, TEST_MACHINE_NAME);
5944         torture_rpc_tcase_add_test_creds(tcase, "LogonControl", test_LogonControl);
5945         torture_rpc_tcase_add_test_creds(tcase, "LogonControl2", test_LogonControl2);
5946         torture_rpc_tcase_add_test_creds(tcase, "LogonControl2Ex", test_LogonControl2Ex);
5947
5948         tcase = torture_suite_add_machine_workstation_rpc_iface_tcase(suite, "wkst",
5949                                                   &ndr_table_netlogon, TEST_MACHINE_NAME);
5950         torture_rpc_tcase_add_test_creds(tcase, "LogonControl", test_LogonControl);
5951         torture_rpc_tcase_add_test_creds(tcase, "LogonControl2", test_LogonControl2);
5952         torture_rpc_tcase_add_test_creds(tcase, "LogonControl2Ex", test_LogonControl2Ex);
5953
5954         tcase = torture_suite_add_rpc_iface_tcase(suite, "admin",
5955                                                   &ndr_table_netlogon);
5956         torture_rpc_tcase_add_test_creds(tcase, "LogonControl", test_LogonControl);
5957         torture_rpc_tcase_add_test_creds(tcase, "LogonControl2", test_LogonControl2);
5958         torture_rpc_tcase_add_test_creds(tcase, "LogonControl2Ex", test_LogonControl2Ex);
5959
5960         return suite;
5961 }