07e63612e81f274edbf75b63a67ea47677b8d8a1
[vlendec/samba-autobuild/.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/cmdline.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                                 samba_cmdline_get_creds());
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                                 samba_cmdline_get_creds());
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 | NETLOGON_NEG_SUPPORTS_AES,
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 | NETLOGON_NEG_SUPPORTS_AES;
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 | NETLOGON_NEG_SUPPORTS_AES;
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 | NETLOGON_NEG_SUPPORTS_AES;
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 | NETLOGON_NEG_SUPPORTS_AES;
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 | NETLOGON_NEG_SUPPORTS_AES;
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; /* no AES desired here */
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 | NETLOGON_NEG_SUPPORTS_AES;
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; /* no AES desired here */
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(samba_cmdline_get_creds(),
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                                 samba_cmdline_get_creds(), 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 with query_level=0\n");
2060
2061         r.in.query_level = 0;
2062         ZERO_STRUCT(return_auth);
2063
2064         /*
2065          * we need to operate on a temporary copy of creds
2066          * because dcerpc_netr_LogonGetCapabilities with
2067          * an unknown query level returns DCERPC_NCA_S_FAULT_INVALID_TAG
2068          * => NT_STATUS_RPC_ENUM_VALUE_OUT_OF_RANGE
2069          * without looking at the authenticator.
2070          */
2071         tmp_creds = *creds;
2072         netlogon_creds_client_authenticator(&tmp_creds, &auth);
2073
2074         status = dcerpc_netr_LogonGetCapabilities_r(b, tctx, &r);
2075         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_RPC_ENUM_VALUE_OUT_OF_RANGE,
2076                                       "LogonGetCapabilities query_level=0 failed");
2077
2078         torture_comment(tctx, "Testing LogonGetCapabilities with query_level=3\n");
2079
2080         r.in.query_level = 3;
2081         ZERO_STRUCT(return_auth);
2082
2083         /*
2084          * we need to operate on a temporary copy of creds
2085          * because dcerpc_netr_LogonGetCapabilities with
2086          * an unknown query level returns DCERPC_NCA_S_FAULT_INVALID_TAG
2087          * => NT_STATUS_RPC_ENUM_VALUE_OUT_OF_RANGE
2088          * without looking at the authenticator.
2089          */
2090         tmp_creds = *creds;
2091         netlogon_creds_client_authenticator(&tmp_creds, &auth);
2092
2093         status = dcerpc_netr_LogonGetCapabilities_r(b, tctx, &r);
2094         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_RPC_ENUM_VALUE_OUT_OF_RANGE,
2095                                       "LogonGetCapabilities query_level=0 failed");
2096
2097         torture_comment(tctx, "Testing LogonGetCapabilities with query_level=1\n");
2098
2099         r.in.query_level = 1;
2100         ZERO_STRUCT(return_auth);
2101
2102         /*
2103          * we need to operate on a temporary copy of creds
2104          * because dcerpc_netr_LogonGetCapabilities was
2105          * dcerpc_netr_DummyFunction and returns NT_STATUS_NOT_IMPLEMENTED
2106          * without looking at the authenticator.
2107          */
2108         tmp_creds = *creds;
2109         netlogon_creds_client_authenticator(&tmp_creds, &auth);
2110
2111         status = dcerpc_netr_LogonGetCapabilities_r(b, tctx, &r);
2112         torture_assert_ntstatus_ok(tctx, status, "LogonGetCapabilities failed");
2113         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_IMPLEMENTED)) {
2114                 return true;
2115         }
2116
2117         *creds = tmp_creds;
2118
2119         torture_assert(tctx, netlogon_creds_client_check(creds,
2120                                                          &r.out.return_authenticator->cred),
2121                        "Credential chaining failed");
2122
2123         torture_assert_int_equal(tctx, creds->negotiate_flags,
2124                                  capabilities.server_capabilities,
2125                                  "negotiate flags");
2126
2127         torture_comment(tctx, "Testing LogonGetCapabilities with query_level=2\n");
2128
2129         r.in.query_level = 2;
2130         ZERO_STRUCT(return_auth);
2131
2132         /*
2133          * we need to operate on a temporary copy of creds
2134          * because dcerpc_netr_LogonGetCapabilities with
2135          * an query level 2 may returns DCERPC_NCA_S_FAULT_INVALID_TAG
2136          * => NT_STATUS_RPC_ENUM_VALUE_OUT_OF_RANGE
2137          * without looking at the authenticator.
2138          */
2139         tmp_creds = *creds;
2140         netlogon_creds_client_authenticator(&tmp_creds, &auth);
2141
2142         status = dcerpc_netr_LogonGetCapabilities_r(b, tctx, &r);
2143         if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_ENUM_VALUE_OUT_OF_RANGE)) {
2144                 /*
2145                  * an server without KB5028166 returns
2146                  * DCERPC_NCA_S_FAULT_INVALID_TAG =>
2147                  * NT_STATUS_RPC_ENUM_VALUE_OUT_OF_RANGE
2148                  */
2149                 return true;
2150         }
2151         torture_assert_ntstatus_ok(tctx, status, "LogonGetCapabilities query_level=2 failed");
2152
2153         *creds = tmp_creds;
2154
2155         torture_assert(tctx, netlogon_creds_client_check(creds,
2156                                                          &r.out.return_authenticator->cred),
2157                        "Credential chaining failed");
2158
2159         torture_assert_int_equal(tctx, creds->negotiate_flags,
2160                                  capabilities.server_capabilities,
2161                                  "negotiate flags");
2162
2163         return true;
2164 }
2165
2166 /*
2167   try a netlogon SamLogon
2168 */
2169 static bool test_SamLogon(struct torture_context *tctx,
2170                           struct dcerpc_pipe *p,
2171                           struct cli_credentials *credentials)
2172 {
2173         struct netlogon_creds_CredentialState *creds;
2174
2175         if (!test_SetupCredentials(p, tctx, credentials, &creds)) {
2176                 return false;
2177         }
2178
2179         return test_netlogon_ops(p, tctx, credentials, creds);
2180 }
2181
2182 static bool test_invalidAuthenticate2(struct torture_context *tctx,
2183                                       struct dcerpc_pipe *p,
2184                                       struct cli_credentials *credentials)
2185 {
2186         struct netlogon_creds_CredentialState *creds;
2187         uint32_t flags = NETLOGON_NEG_AUTH2_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
2188
2189         torture_comment(tctx, "Testing invalidAuthenticate2\n");
2190
2191         if (!test_SetupCredentials2(p, tctx, flags,
2192                                     credentials,
2193                                     cli_credentials_get_secure_channel_type(credentials),
2194                                     &creds)) {
2195                 return false;
2196         }
2197
2198         if (!test_SetupCredentials2ex(p, tctx, flags,
2199                                       credentials,
2200                                       "1234567890123456",
2201                                       cli_credentials_get_secure_channel_type(credentials),
2202                                       STATUS_BUFFER_OVERFLOW,
2203                                       &creds)) {
2204                 return false;
2205         }
2206
2207         if (!test_SetupCredentials2ex(p, tctx, flags,
2208                                       credentials,
2209                                       "123456789012345",
2210                                       cli_credentials_get_secure_channel_type(credentials),
2211                                       NT_STATUS_OK,
2212                                       &creds)) {
2213                 return false;
2214         }
2215
2216         return true;
2217 }
2218
2219 static bool test_ServerReqChallengeGlobal(struct torture_context *tctx,
2220                                           struct dcerpc_pipe *p1,
2221                                           struct cli_credentials *machine_credentials)
2222 {
2223         uint32_t flags = NETLOGON_NEG_AUTH2_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
2224         struct netr_ServerReqChallenge r;
2225         struct netr_ServerAuthenticate3 a;
2226         struct netr_Credential credentials1, credentials2, credentials3;
2227         struct netlogon_creds_CredentialState *creds;
2228         struct samr_Password mach_password;
2229         uint32_t rid;
2230         const char *machine_name;
2231         const char *plain_pass;
2232         struct dcerpc_binding_handle *b1 = p1->binding_handle;
2233         struct dcerpc_pipe *p2 = NULL;
2234         struct dcerpc_binding_handle *b2 = NULL;
2235
2236         machine_name = cli_credentials_get_workstation(machine_credentials);
2237         torture_assert(tctx, machine_name != NULL, "machine_name");
2238         plain_pass = cli_credentials_get_password(machine_credentials);
2239         torture_assert(tctx, plain_pass != NULL, "plain_pass");
2240
2241         torture_comment(tctx, "Testing ServerReqChallenge on b1\n");
2242
2243         torture_assert_ntstatus_ok(tctx,
2244                 dcerpc_pipe_connect_b(tctx, &p2, p1->binding,
2245                                       &ndr_table_netlogon,
2246                                       machine_credentials,
2247                                       tctx->ev, tctx->lp_ctx),
2248                 "dcerpc_pipe_connect_b failed");
2249         b2 = p2->binding_handle;
2250
2251         r.in.server_name = NULL;
2252         r.in.computer_name = machine_name;
2253         r.in.credentials = &credentials1;
2254         r.out.return_credentials = &credentials2;
2255
2256         netlogon_creds_random_challenge(&credentials1);
2257
2258         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b1, tctx, &r),
2259                 "ServerReqChallenge failed on b1");
2260         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed on b1");
2261
2262         E_md4hash(plain_pass, mach_password.hash);
2263
2264         a.in.server_name = NULL;
2265         a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
2266         a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
2267         a.in.computer_name = machine_name;
2268         a.in.negotiate_flags = &flags;
2269         a.in.credentials = &credentials3;
2270         a.out.return_credentials = &credentials3;
2271         a.out.negotiate_flags = &flags;
2272         a.out.rid = &rid;
2273
2274         creds = netlogon_creds_client_init(tctx, a.in.account_name,
2275                                            a.in.computer_name,
2276                                            a.in.secure_channel_type,
2277                                            &credentials1, &credentials2,
2278                                            &mach_password, &credentials3,
2279                                            flags);
2280
2281         torture_assert(tctx, creds != NULL, "memory allocation");
2282
2283         torture_comment(tctx, "Testing ServerAuthenticate3 on b2\n");
2284
2285         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b2, tctx, &a),
2286                 "ServerAuthenticate3 failed on b2");
2287         torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate3 failed on b2");
2288         torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
2289
2290         return true;
2291 }
2292
2293 /*
2294  * Test the re-use of the challenge is not possible on a third
2295  * connection, after first using it second one.
2296  */
2297
2298 static bool test_ServerReqChallengeReuseGlobal(struct torture_context *tctx,
2299                                           struct dcerpc_pipe *p1,
2300                                           struct cli_credentials *machine_credentials)
2301 {
2302         uint32_t flags = NETLOGON_NEG_AUTH2_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
2303         struct netr_ServerReqChallenge r;
2304         struct netr_ServerAuthenticate3 a;
2305         struct netr_Credential credentials1, credentials2, credentials3;
2306         struct netlogon_creds_CredentialState *creds;
2307         struct samr_Password mach_password;
2308         uint32_t rid;
2309         const char *machine_name;
2310         const char *plain_pass;
2311         struct dcerpc_binding_handle *b1 = p1->binding_handle;
2312         struct dcerpc_pipe *p2 = NULL;
2313         struct dcerpc_binding_handle *b2 = NULL;
2314         struct dcerpc_pipe *p3 = NULL;
2315         struct dcerpc_binding_handle *b3 = NULL;
2316
2317         machine_name = cli_credentials_get_workstation(machine_credentials);
2318         torture_assert(tctx, machine_name != NULL, "machine_name");
2319         plain_pass = cli_credentials_get_password(machine_credentials);
2320         torture_assert(tctx, plain_pass != NULL, "plain_pass");
2321
2322         torture_comment(tctx, "Testing ServerReqChallenge on b1\n");
2323
2324         torture_assert_ntstatus_ok(tctx,
2325                 dcerpc_pipe_connect_b(tctx, &p2, p1->binding,
2326                                       &ndr_table_netlogon,
2327                                       machine_credentials,
2328                                       tctx->ev, tctx->lp_ctx),
2329                 "dcerpc_pipe_connect_b failed");
2330         b2 = p2->binding_handle;
2331
2332         torture_assert_ntstatus_ok(tctx,
2333                 dcerpc_pipe_connect_b(tctx, &p3, p1->binding,
2334                                       &ndr_table_netlogon,
2335                                       machine_credentials,
2336                                       tctx->ev, tctx->lp_ctx),
2337                 "dcerpc_pipe_connect_b failed");
2338         b3 = p3->binding_handle;
2339
2340         r.in.server_name = NULL;
2341         r.in.computer_name = machine_name;
2342         r.in.credentials = &credentials1;
2343         r.out.return_credentials = &credentials2;
2344
2345         netlogon_creds_random_challenge(&credentials1);
2346
2347         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b1, tctx, &r),
2348                 "ServerReqChallenge failed on b1");
2349         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed on b1");
2350
2351         E_md4hash(plain_pass, mach_password.hash);
2352
2353         a.in.server_name = NULL;
2354         a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
2355         a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
2356         a.in.computer_name = machine_name;
2357         a.in.negotiate_flags = &flags;
2358         a.in.credentials = &credentials3;
2359         a.out.return_credentials = &credentials3;
2360         a.out.negotiate_flags = &flags;
2361         a.out.rid = &rid;
2362
2363         creds = netlogon_creds_client_init(tctx, a.in.account_name,
2364                                            a.in.computer_name,
2365                                            a.in.secure_channel_type,
2366                                            &credentials1, &credentials2,
2367                                            &mach_password, &credentials3,
2368                                            flags);
2369
2370         torture_assert(tctx, creds != NULL, "memory allocation");
2371
2372         torture_comment(tctx, "Testing ServerAuthenticate3 on b2\n");
2373
2374         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b2, tctx, &a),
2375                 "ServerAuthenticate3 failed on b2");
2376         torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate3 failed on b2");
2377         torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
2378
2379         /* We have to re-run this part */
2380         creds = netlogon_creds_client_init(tctx, a.in.account_name,
2381                                            a.in.computer_name,
2382                                            a.in.secure_channel_type,
2383                                            &credentials1, &credentials2,
2384                                            &mach_password, &credentials3,
2385                                            flags);
2386
2387         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b3, tctx, &a),
2388                 "ServerAuthenticate3 failed on b3");
2389         torture_assert_ntstatus_equal(tctx, a.out.result, NT_STATUS_ACCESS_DENIED,
2390                                       "ServerAuthenticate3 should have failed on b3, due to credential reuse");
2391         return true;
2392 }
2393
2394 /*
2395  * Test if use of the per-pipe challenge will wipe out the globally cached challenge
2396  */
2397 static bool test_ServerReqChallengeReuseGlobal2(struct torture_context *tctx,
2398                                                 struct dcerpc_pipe *p1,
2399                                                 struct cli_credentials *machine_credentials)
2400 {
2401         uint32_t flags = NETLOGON_NEG_AUTH2_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
2402         struct netr_ServerReqChallenge r;
2403         struct netr_ServerAuthenticate3 a;
2404         struct netr_Credential credentials1, credentials2, credentials3;
2405         struct netlogon_creds_CredentialState *creds;
2406         struct samr_Password mach_password;
2407         uint32_t rid;
2408         const char *machine_name;
2409         const char *plain_pass;
2410         struct dcerpc_binding_handle *b1 = p1->binding_handle;
2411         struct dcerpc_pipe *p2 = NULL;
2412         struct dcerpc_binding_handle *b2 = NULL;
2413
2414         machine_name = cli_credentials_get_workstation(machine_credentials);
2415         torture_assert(tctx, machine_name != NULL, "machine_name");
2416         plain_pass = cli_credentials_get_password(machine_credentials);
2417         torture_assert(tctx, plain_pass != NULL, "plain_pass");
2418
2419         torture_comment(tctx, "Testing ServerReqChallenge on b1\n");
2420
2421         torture_assert_ntstatus_ok(tctx,
2422                 dcerpc_pipe_connect_b(tctx, &p2, p1->binding,
2423                                       &ndr_table_netlogon,
2424                                       machine_credentials,
2425                                       tctx->ev, tctx->lp_ctx),
2426                 "dcerpc_pipe_connect_b failed");
2427         b2 = p2->binding_handle;
2428
2429         r.in.server_name = NULL;
2430         r.in.computer_name = machine_name;
2431         r.in.credentials = &credentials1;
2432         r.out.return_credentials = &credentials2;
2433
2434         netlogon_creds_random_challenge(&credentials1);
2435
2436         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b1, tctx, &r),
2437                 "ServerReqChallenge failed on b1");
2438         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed on b1");
2439
2440         E_md4hash(plain_pass, mach_password.hash);
2441
2442         a.in.server_name = NULL;
2443         a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
2444         a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
2445         a.in.computer_name = machine_name;
2446         a.in.negotiate_flags = &flags;
2447         a.in.credentials = &credentials3;
2448         a.out.return_credentials = &credentials3;
2449         a.out.negotiate_flags = &flags;
2450         a.out.rid = &rid;
2451
2452         creds = netlogon_creds_client_init(tctx, a.in.account_name,
2453                                            a.in.computer_name,
2454                                            a.in.secure_channel_type,
2455                                            &credentials1, &credentials2,
2456                                            &mach_password, &credentials3,
2457                                            flags);
2458
2459         torture_assert(tctx, creds != NULL, "memory allocation");
2460
2461         torture_comment(tctx, "Testing ServerAuthenticate3 on b2\n");
2462
2463         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b1, tctx, &a),
2464                 "ServerAuthenticate3 failed on b");
2465         torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate3 failed on b");
2466         torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
2467
2468         /* We have to re-run this part */
2469         creds = netlogon_creds_client_init(tctx, a.in.account_name,
2470                                            a.in.computer_name,
2471                                            a.in.secure_channel_type,
2472                                            &credentials1, &credentials2,
2473                                            &mach_password, &credentials3,
2474                                            flags);
2475
2476         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b2, tctx, &a),
2477                 "ServerAuthenticate3 failed on b2");
2478         torture_assert_ntstatus_equal(tctx, a.out.result, NT_STATUS_ACCESS_DENIED,
2479                                       "ServerAuthenticate3 should have failed on b2, due to credential reuse");
2480         return true;
2481 }
2482
2483 /*
2484  * Test if use of the globally cached challenge will wipe out the
2485  * per-pipe challenge
2486  */
2487 static bool test_ServerReqChallengeReuseGlobal3(struct torture_context *tctx,
2488                                                 struct dcerpc_pipe *p1,
2489                                                 struct cli_credentials *machine_credentials)
2490 {
2491         uint32_t flags = NETLOGON_NEG_AUTH2_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
2492         struct netr_ServerReqChallenge r;
2493         struct netr_ServerAuthenticate3 a;
2494         struct netr_Credential credentials1, credentials2, credentials3;
2495         struct netlogon_creds_CredentialState *creds;
2496         struct samr_Password mach_password;
2497         uint32_t rid;
2498         const char *machine_name;
2499         const char *plain_pass;
2500         struct dcerpc_binding_handle *b1 = p1->binding_handle;
2501         struct dcerpc_pipe *p2 = NULL;
2502         struct dcerpc_binding_handle *b2 = NULL;
2503
2504         machine_name = cli_credentials_get_workstation(machine_credentials);
2505         torture_assert(tctx, machine_name != NULL, "machine_name");
2506         plain_pass = cli_credentials_get_password(machine_credentials);
2507         torture_assert(tctx, plain_pass != NULL, "plain_pass");
2508
2509         torture_comment(tctx, "Testing ServerReqChallenge on b1\n");
2510
2511         torture_assert_ntstatus_ok(tctx,
2512                 dcerpc_pipe_connect_b(tctx, &p2, p1->binding,
2513                                       &ndr_table_netlogon,
2514                                       machine_credentials,
2515                                       tctx->ev, tctx->lp_ctx),
2516                 "dcerpc_pipe_connect_b failed");
2517         b2 = p2->binding_handle;
2518
2519         r.in.server_name = NULL;
2520         r.in.computer_name = machine_name;
2521         r.in.credentials = &credentials1;
2522         r.out.return_credentials = &credentials2;
2523
2524         netlogon_creds_random_challenge(&credentials1);
2525
2526         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b1, tctx, &r),
2527                 "ServerReqChallenge failed on b1");
2528         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed on b1");
2529
2530         E_md4hash(plain_pass, mach_password.hash);
2531
2532         a.in.server_name = NULL;
2533         a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
2534         a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
2535         a.in.computer_name = machine_name;
2536         a.in.negotiate_flags = &flags;
2537         a.in.credentials = &credentials3;
2538         a.out.return_credentials = &credentials3;
2539         a.out.negotiate_flags = &flags;
2540         a.out.rid = &rid;
2541
2542         creds = netlogon_creds_client_init(tctx, a.in.account_name,
2543                                            a.in.computer_name,
2544                                            a.in.secure_channel_type,
2545                                            &credentials1, &credentials2,
2546                                            &mach_password, &credentials3,
2547                                            flags);
2548
2549         torture_assert(tctx, creds != NULL, "memory allocation");
2550
2551         torture_comment(tctx, "Testing ServerAuthenticate3 on b2\n");
2552
2553         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b2, tctx, &a),
2554                 "ServerAuthenticate3 failed on b2");
2555         torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate3 failed on b");
2556         torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
2557
2558         /* We have to re-run this part */
2559         creds = netlogon_creds_client_init(tctx, a.in.account_name,
2560                                            a.in.computer_name,
2561                                            a.in.secure_channel_type,
2562                                            &credentials1, &credentials2,
2563                                            &mach_password, &credentials3,
2564                                            flags);
2565
2566         torture_assert(tctx, creds != NULL, "memory allocation");
2567
2568         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b1, tctx, &a),
2569                 "ServerAuthenticate3 failed on b1");
2570         torture_assert_ntstatus_equal(tctx, a.out.result, NT_STATUS_ACCESS_DENIED,
2571                                       "ServerAuthenticate3 should have failed on b1, due to credential reuse");
2572         return true;
2573 }
2574
2575 /*
2576  * Test if more than one globally cached challenge works
2577  */
2578 static bool test_ServerReqChallengeReuseGlobal4(struct torture_context *tctx,
2579                                                 struct dcerpc_pipe *p1,
2580                                                 struct cli_credentials *machine_credentials)
2581 {
2582         uint32_t flags = NETLOGON_NEG_AUTH2_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
2583         struct netr_ServerReqChallenge r;
2584         struct netr_ServerAuthenticate3 a;
2585         struct netr_Credential credentials1, credentials1_random,
2586                 credentials2, credentials3, credentials_discard;
2587         struct netlogon_creds_CredentialState *creds;
2588         struct samr_Password mach_password;
2589         uint32_t rid;
2590         const char *machine_name;
2591         const char *plain_pass;
2592         struct dcerpc_binding_handle *b1 = p1->binding_handle;
2593         struct dcerpc_pipe *p2 = NULL;
2594         struct dcerpc_binding_handle *b2 = NULL;
2595
2596         machine_name = cli_credentials_get_workstation(machine_credentials);
2597         torture_assert(tctx, machine_name != NULL, "machine_name");
2598         plain_pass = cli_credentials_get_password(machine_credentials);
2599         torture_assert(tctx, plain_pass != NULL, "plain_pass");
2600
2601         torture_comment(tctx, "Testing ServerReqChallenge on b1\n");
2602
2603         torture_assert_ntstatus_ok(tctx,
2604                 dcerpc_pipe_connect_b(tctx, &p2, p1->binding,
2605                                       &ndr_table_netlogon,
2606                                       machine_credentials,
2607                                       tctx->ev, tctx->lp_ctx),
2608                 "dcerpc_pipe_connect_b failed");
2609         b2 = p2->binding_handle;
2610
2611         r.in.server_name = NULL;
2612         r.in.computer_name = "CHALTEST1";
2613         r.in.credentials = &credentials1_random;
2614         r.out.return_credentials = &credentials_discard;
2615
2616         netlogon_creds_random_challenge(&credentials1_random);
2617
2618         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b1, tctx, &r),
2619                 "ServerReqChallenge failed on b1");
2620         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed on b1");
2621
2622         /* Now ask for the actual client name */
2623         r.in.server_name = NULL;
2624         r.in.computer_name = machine_name;
2625         r.in.credentials = &credentials1;
2626         r.out.return_credentials = &credentials2;
2627
2628         netlogon_creds_random_challenge(&credentials1);
2629
2630         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b1, tctx, &r),
2631                 "ServerReqChallenge failed on b1");
2632         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed on b1");
2633
2634         r.in.server_name = NULL;
2635         r.in.computer_name = "CHALTEST2";
2636         r.in.credentials = &credentials1_random;
2637         r.out.return_credentials = &credentials_discard;
2638
2639         netlogon_creds_random_challenge(&credentials1_random);
2640
2641         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b1, tctx, &r),
2642                 "ServerReqChallenge failed on b1");
2643         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed on b1");
2644
2645         E_md4hash(plain_pass, mach_password.hash);
2646
2647         a.in.server_name = NULL;
2648         a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
2649         a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
2650         a.in.computer_name = machine_name;
2651         a.in.negotiate_flags = &flags;
2652         a.in.credentials = &credentials3;
2653         a.out.return_credentials = &credentials3;
2654         a.out.negotiate_flags = &flags;
2655         a.out.rid = &rid;
2656
2657         creds = netlogon_creds_client_init(tctx, a.in.account_name,
2658                                            a.in.computer_name,
2659                                            a.in.secure_channel_type,
2660                                            &credentials1, &credentials2,
2661                                            &mach_password, &credentials3,
2662                                            flags);
2663
2664         torture_assert(tctx, creds != NULL, "memory allocation");
2665
2666         torture_comment(tctx, "Testing ServerAuthenticate3 on b2 (must use global credentials)\n");
2667
2668         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b2, tctx, &a),
2669                 "ServerAuthenticate3 failed on b2");
2670         torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate3 failed on b2");
2671         torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
2672
2673         /* We have to re-run this part */
2674         creds = netlogon_creds_client_init(tctx, a.in.account_name,
2675                                            a.in.computer_name,
2676                                            a.in.secure_channel_type,
2677                                            &credentials1, &credentials2,
2678                                            &mach_password, &credentials3,
2679                                            flags);
2680
2681         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b1, tctx, &a),
2682                 "ServerAuthenticate3 failed on b1");
2683         torture_assert_ntstatus_equal(tctx, a.out.result, NT_STATUS_ACCESS_DENIED,
2684                                       "ServerAuthenticate3 should have failed on b1, due to credential reuse");
2685         return true;
2686 }
2687
2688 static bool test_ServerReqChallengeReuse(struct torture_context *tctx,
2689                                          struct dcerpc_pipe *p,
2690                                          struct cli_credentials *machine_credentials)
2691 {
2692         uint32_t flags = NETLOGON_NEG_AUTH2_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
2693         struct netr_ServerReqChallenge r;
2694         struct netr_ServerAuthenticate3 a;
2695         struct netr_Credential credentials1, credentials2, credentials3;
2696         struct netlogon_creds_CredentialState *creds;
2697         struct samr_Password mach_password;
2698         uint32_t rid;
2699         const char *machine_name;
2700         const char *plain_pass;
2701         struct dcerpc_binding_handle *b = p->binding_handle;
2702
2703         machine_name = cli_credentials_get_workstation(machine_credentials);
2704         torture_assert(tctx, machine_name != NULL, "machine_name");
2705         plain_pass = cli_credentials_get_password(machine_credentials);
2706         torture_assert(tctx, plain_pass != NULL, "plain_pass");
2707
2708         torture_comment(tctx, "Testing ServerReqChallenge on b1\n");
2709
2710         r.in.server_name = NULL;
2711         r.in.computer_name = machine_name;
2712         r.in.credentials = &credentials1;
2713         r.out.return_credentials = &credentials2;
2714
2715         netlogon_creds_random_challenge(&credentials1);
2716
2717         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
2718                 "ServerReqChallenge");
2719         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed on b1");
2720
2721         E_md4hash(plain_pass, mach_password.hash);
2722
2723         a.in.server_name = NULL;
2724         a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
2725         a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
2726         a.in.computer_name = machine_name;
2727         a.in.negotiate_flags = &flags;
2728         a.in.credentials = &credentials3;
2729         a.out.return_credentials = &credentials3;
2730         a.out.negotiate_flags = &flags;
2731         a.out.rid = &rid;
2732
2733         creds = netlogon_creds_client_init(tctx, a.in.account_name,
2734                                            a.in.computer_name,
2735                                            a.in.secure_channel_type,
2736                                            &credentials1, &credentials2,
2737                                            &mach_password, &credentials3,
2738                                            flags);
2739
2740         torture_assert(tctx, creds != NULL, "memory allocation");
2741
2742         torture_comment(tctx, "Testing ServerAuthenticate3\n");
2743
2744         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b, tctx, &a),
2745                 "ServerAuthenticate3 failed");
2746         torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate3 failed");
2747         torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
2748
2749         /* We have to re-run this part */
2750         creds = netlogon_creds_client_init(tctx, a.in.account_name,
2751                                            a.in.computer_name,
2752                                            a.in.secure_channel_type,
2753                                            &credentials1, &credentials2,
2754                                            &mach_password, &credentials3,
2755                                            flags);
2756
2757         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b, tctx, &a),
2758                 "ServerAuthenticate3 failed");
2759         torture_assert_ntstatus_equal(tctx, a.out.result, NT_STATUS_ACCESS_DENIED,
2760                                       "ServerAuthenticate3 should have failed on b3, due to credential reuse");
2761
2762         ZERO_STRUCT(credentials1.data);
2763         ZERO_STRUCT(credentials2.data);
2764         creds = netlogon_creds_client_init(tctx, a.in.account_name,
2765                                            a.in.computer_name,
2766                                            a.in.secure_channel_type,
2767                                            &credentials1, &credentials2,
2768                                            &mach_password, &credentials3,
2769                                            flags);
2770
2771         torture_assert(tctx, creds != NULL, "memory allocation");
2772
2773         torture_comment(tctx, "Testing ServerAuthenticate3 with zero'ed challenge\n");
2774
2775         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b, tctx, &a),
2776                 "ServerAuthenticate3 failed");
2777         torture_assert_ntstatus_equal(tctx, a.out.result, NT_STATUS_ACCESS_DENIED,
2778                                       "ServerAuthenticate3 should have failed on b3, due to credential reuse");
2779         return true;
2780 }
2781
2782 static bool test_SamLogon_NULL_domain(struct torture_context *tctx,
2783                                       struct dcerpc_pipe *p,
2784                                       struct cli_credentials *credentials)
2785 {
2786         struct netlogon_creds_CredentialState *creds;
2787
2788         if (!test_SetupCredentials(p, tctx, credentials, &creds)) {
2789                 return false;
2790         }
2791
2792         return test_netlogon_ops_args(p, tctx, credentials, creds, true);
2793 }
2794
2795 /* we remember the sequence numbers so we can easily do a DatabaseDelta */
2796 static uint64_t sequence_nums[3];
2797
2798 /*
2799   try a netlogon DatabaseSync
2800 */
2801 static bool test_DatabaseSync(struct torture_context *tctx,
2802                               struct dcerpc_pipe *p,
2803                               struct cli_credentials *machine_credentials)
2804 {
2805         struct netr_DatabaseSync r;
2806         struct netlogon_creds_CredentialState *creds;
2807         const uint32_t database_ids[] = {SAM_DATABASE_DOMAIN, SAM_DATABASE_BUILTIN, SAM_DATABASE_PRIVS};
2808         int i;
2809         struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
2810         struct netr_Authenticator credential, return_authenticator;
2811         struct dcerpc_binding_handle *b = p->binding_handle;
2812
2813         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
2814                 return false;
2815         }
2816
2817         ZERO_STRUCT(return_authenticator);
2818
2819         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2820         r.in.computername = TEST_MACHINE_NAME;
2821         r.in.preferredmaximumlength = (uint32_t)-1;
2822         r.in.return_authenticator = &return_authenticator;
2823         r.out.delta_enum_array = &delta_enum_array;
2824         r.out.return_authenticator = &return_authenticator;
2825
2826         for (i=0;i<ARRAY_SIZE(database_ids);i++) {
2827
2828                 uint32_t sync_context = 0;
2829
2830                 r.in.database_id = database_ids[i];
2831                 r.in.sync_context = &sync_context;
2832                 r.out.sync_context = &sync_context;
2833
2834                 torture_comment(tctx, "Testing DatabaseSync of id %d\n", r.in.database_id);
2835
2836                 do {
2837                         netlogon_creds_client_authenticator(creds, &credential);
2838
2839                         r.in.credential = &credential;
2840
2841                         torture_assert_ntstatus_ok(tctx, dcerpc_netr_DatabaseSync_r(b, tctx, &r),
2842                                 "DatabaseSync failed");
2843                         if (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES))
2844                             break;
2845
2846                         /* Native mode servers don't do this */
2847                         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_SUPPORTED)) {
2848                                 return true;
2849                         }
2850                         torture_assert_ntstatus_ok(tctx, r.out.result, "DatabaseSync");
2851
2852                         if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
2853                                 torture_comment(tctx, "Credential chaining failed\n");
2854                         }
2855
2856                         if (delta_enum_array &&
2857                             delta_enum_array->num_deltas > 0 &&
2858                             delta_enum_array->delta_enum[0].delta_type == NETR_DELTA_DOMAIN &&
2859                             delta_enum_array->delta_enum[0].delta_union.domain) {
2860                                 sequence_nums[r.in.database_id] =
2861                                         delta_enum_array->delta_enum[0].delta_union.domain->sequence_num;
2862                                 torture_comment(tctx, "\tsequence_nums[%d]=%llu\n",
2863                                        r.in.database_id,
2864                                        (unsigned long long)sequence_nums[r.in.database_id]);
2865                         }
2866                 } while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES));
2867         }
2868
2869         return true;
2870 }
2871
2872
2873 /*
2874   try a netlogon DatabaseDeltas
2875 */
2876 static bool test_DatabaseDeltas(struct torture_context *tctx,
2877                                 struct dcerpc_pipe *p,
2878                                 struct cli_credentials *machine_credentials)
2879 {
2880         struct netr_DatabaseDeltas r;
2881         struct netlogon_creds_CredentialState *creds;
2882         struct netr_Authenticator credential;
2883         struct netr_Authenticator return_authenticator;
2884         struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
2885         const uint32_t database_ids[] = {0, 1, 2};
2886         int i;
2887         struct dcerpc_binding_handle *b = p->binding_handle;
2888
2889         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
2890                 return false;
2891         }
2892
2893         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2894         r.in.computername = TEST_MACHINE_NAME;
2895         r.in.preferredmaximumlength = (uint32_t)-1;
2896         ZERO_STRUCT(r.in.return_authenticator);
2897         r.out.return_authenticator = &return_authenticator;
2898         r.out.delta_enum_array = &delta_enum_array;
2899
2900         for (i=0;i<ARRAY_SIZE(database_ids);i++) {
2901                 r.in.database_id = database_ids[i];
2902                 r.in.sequence_num = &sequence_nums[r.in.database_id];
2903
2904                 if (*r.in.sequence_num == 0) continue;
2905
2906                 *r.in.sequence_num -= 1;
2907
2908                 torture_comment(tctx, "Testing DatabaseDeltas of id %d at %llu\n",
2909                        r.in.database_id, (unsigned long long)*r.in.sequence_num);
2910
2911                 do {
2912                         netlogon_creds_client_authenticator(creds, &credential);
2913
2914                         torture_assert_ntstatus_ok(tctx, dcerpc_netr_DatabaseDeltas_r(b, tctx, &r),
2915                                 "DatabaseDeltas failed");
2916                         if (NT_STATUS_EQUAL(r.out.result,
2917                                              NT_STATUS_SYNCHRONIZATION_REQUIRED)) {
2918                                 torture_comment(tctx, "not considering %s to be an error\n",
2919                                        nt_errstr(r.out.result));
2920                                 return true;
2921                         }
2922                         if (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES))
2923                             break;
2924
2925                         torture_assert_ntstatus_ok(tctx, r.out.result, "DatabaseDeltas");
2926
2927                         if (!netlogon_creds_client_check(creds, &return_authenticator.cred)) {
2928                                 torture_comment(tctx, "Credential chaining failed\n");
2929                         }
2930
2931                         (*r.in.sequence_num)++;
2932                 } while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES));
2933         }
2934
2935         return true;
2936 }
2937
2938 static bool test_DatabaseRedo(struct torture_context *tctx,
2939                               struct dcerpc_pipe *p,
2940                               struct cli_credentials *machine_credentials)
2941 {
2942         struct netr_DatabaseRedo r;
2943         struct netlogon_creds_CredentialState *creds;
2944         struct netr_Authenticator credential;
2945         struct netr_Authenticator return_authenticator;
2946         struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
2947         struct netr_ChangeLogEntry e;
2948         struct dom_sid null_sid, *sid;
2949         int i,d;
2950         struct dcerpc_binding_handle *b = p->binding_handle;
2951
2952         ZERO_STRUCT(null_sid);
2953
2954         sid = dom_sid_parse_talloc(tctx, "S-1-5-21-1111111111-2222222222-333333333-500");
2955
2956         {
2957
2958         struct {
2959                 uint32_t rid;
2960                 uint16_t flags;
2961                 uint8_t db_index;
2962                 uint8_t delta_type;
2963                 struct dom_sid sid;
2964                 const char *name;
2965                 NTSTATUS expected_error;
2966                 uint32_t expected_num_results;
2967                 uint8_t expected_delta_type_1;
2968                 uint8_t expected_delta_type_2;
2969                 const char *comment;
2970         } changes[] = {
2971
2972                 /* SAM_DATABASE_DOMAIN */
2973
2974                 {
2975                         .rid                    = 0,
2976                         .flags                  = 0,
2977                         .db_index               = SAM_DATABASE_DOMAIN,
2978                         .delta_type             = NETR_DELTA_MODIFY_COUNT,
2979                         .sid                    = null_sid,
2980                         .name                   = NULL,
2981                         .expected_error         = NT_STATUS_SYNCHRONIZATION_REQUIRED,
2982                         .expected_num_results   = 0,
2983                         .comment                = "NETR_DELTA_MODIFY_COUNT"
2984                 },
2985                 {
2986                         .rid                    = 0,
2987                         .flags                  = 0,
2988                         .db_index               = SAM_DATABASE_DOMAIN,
2989                         .delta_type             = 0,
2990                         .sid                    = null_sid,
2991                         .name                   = NULL,
2992                         .expected_error         = NT_STATUS_OK,
2993                         .expected_num_results   = 1,
2994                         .expected_delta_type_1  = NETR_DELTA_DOMAIN,
2995                         .comment                = "NULL DELTA"
2996                 },
2997                 {
2998                         .rid                    = 0,
2999                         .flags                  = 0,
3000                         .db_index               = SAM_DATABASE_DOMAIN,
3001                         .delta_type             = NETR_DELTA_DOMAIN,
3002                         .sid                    = null_sid,
3003                         .name                   = NULL,
3004                         .expected_error         = NT_STATUS_OK,
3005                         .expected_num_results   = 1,
3006                         .expected_delta_type_1  = NETR_DELTA_DOMAIN,
3007                         .comment                = "NETR_DELTA_DOMAIN"
3008                 },
3009                 {
3010                         .rid                    = DOMAIN_RID_ADMINISTRATOR,
3011                         .flags                  = 0,
3012                         .db_index               = SAM_DATABASE_DOMAIN,
3013                         .delta_type             = NETR_DELTA_USER,
3014                         .sid                    = null_sid,
3015                         .name                   = NULL,
3016                         .expected_error         = NT_STATUS_OK,
3017                         .expected_num_results   = 1,
3018                         .expected_delta_type_1  = NETR_DELTA_USER,
3019                         .comment                = "NETR_DELTA_USER by rid 500"
3020                 },
3021                 {
3022                         .rid                    = DOMAIN_RID_GUEST,
3023                         .flags                  = 0,
3024                         .db_index               = SAM_DATABASE_DOMAIN,
3025                         .delta_type             = NETR_DELTA_USER,
3026                         .sid                    = null_sid,
3027                         .name                   = NULL,
3028                         .expected_error         = NT_STATUS_OK,
3029                         .expected_num_results   = 1,
3030                         .expected_delta_type_1  = NETR_DELTA_USER,
3031                         .comment                = "NETR_DELTA_USER by rid 501"
3032                 },
3033                 {
3034                         .rid                    = 0,
3035                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
3036                         .db_index               = SAM_DATABASE_DOMAIN,
3037                         .delta_type             = NETR_DELTA_USER,
3038                         .sid                    = *sid,
3039                         .name                   = NULL,
3040                         .expected_error         = NT_STATUS_OK,
3041                         .expected_num_results   = 1,
3042                         .expected_delta_type_1  = NETR_DELTA_DELETE_USER,
3043                         .comment                = "NETR_DELTA_USER by sid and flags"
3044                 },
3045                 {
3046                         .rid                    = 0,
3047                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
3048                         .db_index               = SAM_DATABASE_DOMAIN,
3049                         .delta_type             = NETR_DELTA_USER,
3050                         .sid                    = null_sid,
3051                         .name                   = NULL,
3052                         .expected_error         = NT_STATUS_OK,
3053                         .expected_num_results   = 1,
3054                         .expected_delta_type_1  = NETR_DELTA_DELETE_USER,
3055                         .comment                = "NETR_DELTA_USER by null_sid and flags"
3056                 },
3057                 {
3058                         .rid                    = 0,
3059                         .flags                  = NETR_CHANGELOG_NAME_INCLUDED,
3060                         .db_index               = SAM_DATABASE_DOMAIN,
3061                         .delta_type             = NETR_DELTA_USER,
3062                         .sid                    = null_sid,
3063                         .name                   = "administrator",
3064                         .expected_error         = NT_STATUS_OK,
3065                         .expected_num_results   = 1,
3066                         .expected_delta_type_1  = NETR_DELTA_DELETE_USER,
3067                         .comment                = "NETR_DELTA_USER by name 'administrator'"
3068                 },
3069                 {
3070                         .rid                    = DOMAIN_RID_ADMINS,
3071                         .flags                  = 0,
3072                         .db_index               = SAM_DATABASE_DOMAIN,
3073                         .delta_type             = NETR_DELTA_GROUP,
3074                         .sid                    = null_sid,
3075                         .name                   = NULL,
3076                         .expected_error         = NT_STATUS_OK,
3077                         .expected_num_results   = 2,
3078                         .expected_delta_type_1  = NETR_DELTA_GROUP,
3079                         .expected_delta_type_2  = NETR_DELTA_GROUP_MEMBER,
3080                         .comment                = "NETR_DELTA_GROUP by rid 512"
3081                 },
3082                 {
3083                         .rid                    = DOMAIN_RID_ADMINS,
3084                         .flags                  = 0,
3085                         .db_index               = SAM_DATABASE_DOMAIN,
3086                         .delta_type             = NETR_DELTA_GROUP_MEMBER,
3087                         .sid                    = null_sid,
3088                         .name                   = NULL,
3089                         .expected_error         = NT_STATUS_OK,
3090                         .expected_num_results   = 2,
3091                         .expected_delta_type_1  = NETR_DELTA_GROUP,
3092                         .expected_delta_type_2  = NETR_DELTA_GROUP_MEMBER,
3093                         .comment                = "NETR_DELTA_GROUP_MEMBER by rid 512"
3094                 },
3095
3096
3097                 /* SAM_DATABASE_BUILTIN */
3098
3099                 {
3100                         .rid                    = 0,
3101                         .flags                  = 0,
3102                         .db_index               = SAM_DATABASE_BUILTIN,
3103                         .delta_type             = NETR_DELTA_MODIFY_COUNT,
3104                         .sid                    = null_sid,
3105                         .name                   = NULL,
3106                         .expected_error         = NT_STATUS_SYNCHRONIZATION_REQUIRED,
3107                         .expected_num_results   = 0,
3108                         .comment                = "NETR_DELTA_MODIFY_COUNT"
3109                 },
3110                 {
3111                         .rid                    = 0,
3112                         .flags                  = 0,
3113                         .db_index               = SAM_DATABASE_BUILTIN,
3114                         .delta_type             = NETR_DELTA_DOMAIN,
3115                         .sid                    = null_sid,
3116                         .name                   = NULL,
3117                         .expected_error         = NT_STATUS_OK,
3118                         .expected_num_results   = 1,
3119                         .expected_delta_type_1  = NETR_DELTA_DOMAIN,
3120                         .comment                = "NETR_DELTA_DOMAIN"
3121                 },
3122                 {
3123                         .rid                    = DOMAIN_RID_ADMINISTRATOR,
3124                         .flags                  = 0,
3125                         .db_index               = SAM_DATABASE_BUILTIN,
3126                         .delta_type             = NETR_DELTA_USER,
3127                         .sid                    = null_sid,
3128                         .name                   = NULL,
3129                         .expected_error         = NT_STATUS_OK,
3130                         .expected_num_results   = 1,
3131                         .expected_delta_type_1  = NETR_DELTA_DELETE_USER,
3132                         .comment                = "NETR_DELTA_USER by rid 500"
3133                 },
3134                 {
3135                         .rid                    = 0,
3136                         .flags                  = 0,
3137                         .db_index               = SAM_DATABASE_BUILTIN,
3138                         .delta_type             = NETR_DELTA_USER,
3139                         .sid                    = null_sid,
3140                         .name                   = NULL,
3141                         .expected_error         = NT_STATUS_OK,
3142                         .expected_num_results   = 1,
3143                         .expected_delta_type_1  = NETR_DELTA_DELETE_USER,
3144                         .comment                = "NETR_DELTA_USER"
3145                 },
3146                 {
3147                         .rid                    = 544,
3148                         .flags                  = 0,
3149                         .db_index               = SAM_DATABASE_BUILTIN,
3150                         .delta_type             = NETR_DELTA_ALIAS,
3151                         .sid                    = null_sid,
3152                         .name                   = NULL,
3153                         .expected_error         = NT_STATUS_OK,
3154                         .expected_num_results   = 2,
3155                         .expected_delta_type_1  = NETR_DELTA_ALIAS,
3156                         .expected_delta_type_2  = NETR_DELTA_ALIAS_MEMBER,
3157                         .comment                = "NETR_DELTA_ALIAS by rid 544"
3158                 },
3159                 {
3160                         .rid                    = 544,
3161                         .flags                  = 0,
3162                         .db_index               = SAM_DATABASE_BUILTIN,
3163                         .delta_type             = NETR_DELTA_ALIAS_MEMBER,
3164                         .sid                    = null_sid,
3165                         .name                   = NULL,
3166                         .expected_error         = NT_STATUS_OK,
3167                         .expected_num_results   = 2,
3168                         .expected_delta_type_1  = NETR_DELTA_ALIAS,
3169                         .expected_delta_type_2  = NETR_DELTA_ALIAS_MEMBER,
3170                         .comment                = "NETR_DELTA_ALIAS_MEMBER by rid 544"
3171                 },
3172                 {
3173                         .rid                    = 544,
3174                         .flags                  = 0,
3175                         .db_index               = SAM_DATABASE_BUILTIN,
3176                         .delta_type             = 0,
3177                         .sid                    = null_sid,
3178                         .name                   = NULL,
3179                         .expected_error         = NT_STATUS_OK,
3180                         .expected_num_results   = 1,
3181                         .expected_delta_type_1  = NETR_DELTA_DOMAIN,
3182                         .comment                = "NULL DELTA by rid 544"
3183                 },
3184                 {
3185                         .rid                    = 544,
3186                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
3187                         .db_index               = SAM_DATABASE_BUILTIN,
3188                         .delta_type             = 0,
3189                         .sid                    = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
3190                         .name                   = NULL,
3191                         .expected_error         = NT_STATUS_OK,
3192                         .expected_num_results   = 1,
3193                         .expected_delta_type_1  = NETR_DELTA_DOMAIN,
3194                         .comment                = "NULL DELTA by rid 544 sid S-1-5-32-544 and flags"
3195                 },
3196                 {
3197                         .rid                    = 544,
3198                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
3199                         .db_index               = SAM_DATABASE_BUILTIN,
3200                         .delta_type             = NETR_DELTA_ALIAS,
3201                         .sid                    = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
3202                         .name                   = NULL,
3203                         .expected_error         = NT_STATUS_OK,
3204                         .expected_num_results   = 2,
3205                         .expected_delta_type_1  = NETR_DELTA_ALIAS,
3206                         .expected_delta_type_2  = NETR_DELTA_ALIAS_MEMBER,
3207                         .comment                = "NETR_DELTA_ALIAS by rid 544 and sid S-1-5-32-544 and flags"
3208                 },
3209                 {
3210                         .rid                    = 0,
3211                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
3212                         .db_index               = SAM_DATABASE_BUILTIN,
3213                         .delta_type             = NETR_DELTA_ALIAS,
3214                         .sid                    = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
3215                         .name                   = NULL,
3216                         .expected_error         = NT_STATUS_OK,
3217                         .expected_num_results   = 1,
3218                         .expected_delta_type_1  = NETR_DELTA_DELETE_ALIAS,
3219                         .comment                = "NETR_DELTA_ALIAS by sid S-1-5-32-544 and flags"
3220                 },
3221
3222                 /* SAM_DATABASE_PRIVS */
3223
3224                 {
3225                         .rid                    = 0,
3226                         .flags                  = 0,
3227                         .db_index               = SAM_DATABASE_PRIVS,
3228                         .delta_type             = 0,
3229                         .sid                    = null_sid,
3230                         .name                   = NULL,
3231                         .expected_error         = NT_STATUS_ACCESS_DENIED,
3232                         .expected_num_results   = 0,
3233                         .comment                = "NULL DELTA"
3234                 },
3235                 {
3236                         .rid                    = 0,
3237                         .flags                  = 0,
3238                         .db_index               = SAM_DATABASE_PRIVS,
3239                         .delta_type             = NETR_DELTA_MODIFY_COUNT,
3240                         .sid                    = null_sid,
3241                         .name                   = NULL,
3242                         .expected_error         = NT_STATUS_SYNCHRONIZATION_REQUIRED,
3243                         .expected_num_results   = 0,
3244                         .comment                = "NETR_DELTA_MODIFY_COUNT"
3245                 },
3246                 {
3247                         .rid                    = 0,
3248                         .flags                  = 0,
3249                         .db_index               = SAM_DATABASE_PRIVS,
3250                         .delta_type             = NETR_DELTA_POLICY,
3251                         .sid                    = null_sid,
3252                         .name                   = NULL,
3253                         .expected_error         = NT_STATUS_OK,
3254                         .expected_num_results   = 1,
3255                         .expected_delta_type_1  = NETR_DELTA_POLICY,
3256                         .comment                = "NETR_DELTA_POLICY"
3257                 },
3258                 {
3259                         .rid                    = 0,
3260                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
3261                         .db_index               = SAM_DATABASE_PRIVS,
3262                         .delta_type             = NETR_DELTA_POLICY,
3263                         .sid                    = null_sid,
3264                         .name                   = NULL,
3265                         .expected_error         = NT_STATUS_OK,
3266                         .expected_num_results   = 1,
3267                         .expected_delta_type_1  = NETR_DELTA_POLICY,
3268                         .comment                = "NETR_DELTA_POLICY by null sid and flags"
3269                 },
3270                 {
3271                         .rid                    = 0,
3272                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
3273                         .db_index               = SAM_DATABASE_PRIVS,
3274                         .delta_type             = NETR_DELTA_POLICY,
3275                         .sid                    = *dom_sid_parse_talloc(tctx, "S-1-5-32"),
3276                         .name                   = NULL,
3277                         .expected_error         = NT_STATUS_OK,
3278                         .expected_num_results   = 1,
3279                         .expected_delta_type_1  = NETR_DELTA_POLICY,
3280                         .comment                = "NETR_DELTA_POLICY by sid S-1-5-32 and flags"
3281                 },
3282                 {
3283                         .rid                    = DOMAIN_RID_ADMINISTRATOR,
3284                         .flags                  = 0,
3285                         .db_index               = SAM_DATABASE_PRIVS,
3286                         .delta_type             = NETR_DELTA_ACCOUNT,
3287                         .sid                    = null_sid,
3288                         .name                   = NULL,
3289                         .expected_error         = NT_STATUS_SYNCHRONIZATION_REQUIRED, /* strange */
3290                         .expected_num_results   = 0,
3291                         .comment                = "NETR_DELTA_ACCOUNT by rid 500"
3292                 },
3293                 {
3294                         .rid                    = 0,
3295                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
3296                         .db_index               = SAM_DATABASE_PRIVS,
3297                         .delta_type             = NETR_DELTA_ACCOUNT,
3298                         .sid                    = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
3299                         .name                   = NULL,
3300                         .expected_error         = NT_STATUS_OK,
3301                         .expected_num_results   = 1,
3302                         .expected_delta_type_1  = NETR_DELTA_ACCOUNT,
3303                         .comment                = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and flags"
3304                 },
3305                 {
3306                         .rid                    = 0,
3307                         .flags                  = NETR_CHANGELOG_SID_INCLUDED |
3308                                                   NETR_CHANGELOG_IMMEDIATE_REPL_REQUIRED,
3309                         .db_index               = SAM_DATABASE_PRIVS,
3310                         .delta_type             = NETR_DELTA_ACCOUNT,
3311                         .sid                    = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
3312                         .name                   = NULL,
3313                         .expected_error         = NT_STATUS_OK,
3314                         .expected_num_results   = 1,
3315                         .expected_delta_type_1  = NETR_DELTA_ACCOUNT,
3316                         .comment                = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and 2 flags"
3317                 },
3318                 {
3319                         .rid                    = 0,
3320                         .flags                  = NETR_CHANGELOG_SID_INCLUDED |
3321                                                   NETR_CHANGELOG_NAME_INCLUDED,
3322                         .db_index               = SAM_DATABASE_PRIVS,
3323                         .delta_type             = NETR_DELTA_ACCOUNT,
3324                         .sid                    = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
3325                         .name                   = NULL,
3326                         .expected_error         = NT_STATUS_INVALID_PARAMETER,
3327                         .expected_num_results   = 0,
3328                         .comment                = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and invalid flags"
3329                 },
3330                 {
3331                         .rid                    = DOMAIN_RID_ADMINISTRATOR,
3332                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
3333                         .db_index               = SAM_DATABASE_PRIVS,
3334                         .delta_type             = NETR_DELTA_ACCOUNT,
3335                         .sid                    = *sid,
3336                         .name                   = NULL,
3337                         .expected_error         = NT_STATUS_OK,
3338                         .expected_num_results   = 1,
3339                         .expected_delta_type_1  = NETR_DELTA_DELETE_ACCOUNT,
3340                         .comment                = "NETR_DELTA_ACCOUNT by rid 500, sid and flags"
3341                 },
3342                 {
3343                         .rid                    = 0,
3344                         .flags                  = NETR_CHANGELOG_NAME_INCLUDED,
3345                         .db_index               = SAM_DATABASE_PRIVS,
3346                         .delta_type             = NETR_DELTA_SECRET,
3347                         .sid                    = null_sid,
3348                         .name                   = "IsurelydontexistIhope",
3349                         .expected_error         = NT_STATUS_OK,
3350                         .expected_num_results   = 1,
3351                         .expected_delta_type_1  = NETR_DELTA_DELETE_SECRET,
3352                         .comment                = "NETR_DELTA_SECRET by name 'IsurelydontexistIhope' and flags"
3353                 },
3354                 {
3355                         .rid                    = 0,
3356                         .flags                  = NETR_CHANGELOG_NAME_INCLUDED,
3357                         .db_index               = SAM_DATABASE_PRIVS,
3358                         .delta_type             = NETR_DELTA_SECRET,
3359                         .sid                    = null_sid,
3360                         .name                   = "G$BCKUPKEY_P",
3361                         .expected_error         = NT_STATUS_OK,
3362                         .expected_num_results   = 1,
3363                         .expected_delta_type_1  = NETR_DELTA_SECRET,
3364                         .comment                = "NETR_DELTA_SECRET by name 'G$BCKUPKEY_P' and flags"
3365                 }
3366         };
3367
3368         ZERO_STRUCT(return_authenticator);
3369
3370         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3371         r.in.computername = TEST_MACHINE_NAME;
3372         r.in.return_authenticator = &return_authenticator;
3373         r.out.return_authenticator = &return_authenticator;
3374         r.out.delta_enum_array = &delta_enum_array;
3375
3376         for (d=0; d<3; d++) {
3377                 const char *database = NULL;
3378
3379                 switch (d) {
3380                 case 0:
3381                         database = "SAM";
3382                         break;
3383                 case 1:
3384                         database = "BUILTIN";
3385                         break;
3386                 case 2:
3387                         database = "LSA";
3388                         break;
3389                 default:
3390                         break;
3391                 }
3392
3393                 torture_comment(tctx, "Testing DatabaseRedo\n");
3394
3395                 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
3396                         return false;
3397                 }
3398
3399                 for (i=0;i<ARRAY_SIZE(changes);i++) {
3400
3401                         if (d != changes[i].db_index) {
3402                                 continue;
3403                         }
3404
3405                         netlogon_creds_client_authenticator(creds, &credential);
3406
3407                         r.in.credential = &credential;
3408
3409                         e.serial_number1        = 0;
3410                         e.serial_number2        = 0;
3411                         e.object_rid            = changes[i].rid;
3412                         e.flags                 = changes[i].flags;
3413                         e.db_index              = changes[i].db_index;
3414                         e.delta_type            = changes[i].delta_type;
3415
3416                         switch (changes[i].flags & (NETR_CHANGELOG_NAME_INCLUDED | NETR_CHANGELOG_SID_INCLUDED)) {
3417                         case NETR_CHANGELOG_SID_INCLUDED:
3418                                 e.object.object_sid             = changes[i].sid;
3419                                 break;
3420                         case NETR_CHANGELOG_NAME_INCLUDED:
3421                                 e.object.object_name            = changes[i].name;
3422                                 break;
3423                         default:
3424                                 break;
3425                         }
3426
3427                         r.in.change_log_entry = e;
3428
3429                         torture_comment(tctx, "Testing DatabaseRedo with database %s and %s\n",
3430                                 database, changes[i].comment);
3431
3432                         torture_assert_ntstatus_ok(tctx, dcerpc_netr_DatabaseRedo_r(b, tctx, &r),
3433                                 "DatabaseRedo failed");
3434                         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_SUPPORTED)) {
3435                                 return true;
3436                         }
3437
3438                         torture_assert_ntstatus_equal(tctx, r.out.result, changes[i].expected_error, changes[i].comment);
3439                         if (delta_enum_array) {
3440                                 torture_assert_int_equal(tctx,
3441                                         delta_enum_array->num_deltas,
3442                                         changes[i].expected_num_results,
3443                                         changes[i].comment);
3444                                 if (delta_enum_array->num_deltas > 0) {
3445                                         torture_assert_int_equal(tctx,
3446                                                 delta_enum_array->delta_enum[0].delta_type,
3447                                                 changes[i].expected_delta_type_1,
3448                                                 changes[i].comment);
3449                                 }
3450                                 if (delta_enum_array->num_deltas > 1) {
3451                                         torture_assert_int_equal(tctx,
3452                                                 delta_enum_array->delta_enum[1].delta_type,
3453                                                 changes[i].expected_delta_type_2,
3454                                                 changes[i].comment);
3455                                 }
3456                         }
3457
3458                         if (!netlogon_creds_client_check(creds, &return_authenticator.cred)) {
3459                                 torture_comment(tctx, "Credential chaining failed\n");
3460                                 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
3461                                         return false;
3462                                 }
3463                         }
3464                 }
3465         }
3466         }
3467
3468         return true;
3469 }
3470
3471 /*
3472   try a netlogon AccountDeltas
3473 */
3474 static bool test_AccountDeltas(struct torture_context *tctx,
3475                                struct dcerpc_pipe *p,
3476                                struct cli_credentials *machine_credentials)
3477 {
3478         struct netr_AccountDeltas r;
3479         struct netlogon_creds_CredentialState *creds;
3480
3481         struct netr_AccountBuffer buffer;
3482         uint32_t count_returned = 0;
3483         uint32_t total_entries = 0;
3484         struct netr_UAS_INFO_0 recordid;
3485         struct netr_Authenticator return_authenticator;
3486         struct dcerpc_binding_handle *b = p->binding_handle;
3487
3488         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
3489                 return false;
3490         }
3491
3492         ZERO_STRUCT(return_authenticator);
3493
3494         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3495         r.in.computername = TEST_MACHINE_NAME;
3496         r.in.return_authenticator = &return_authenticator;
3497         netlogon_creds_client_authenticator(creds, &r.in.credential);
3498         ZERO_STRUCT(r.in.uas);
3499         r.in.count=10;
3500         r.in.level=0;
3501         r.in.buffersize=100;
3502         r.out.buffer = &buffer;
3503         r.out.count_returned = &count_returned;
3504         r.out.total_entries = &total_entries;
3505         r.out.recordid = &recordid;
3506         r.out.return_authenticator = &return_authenticator;
3507
3508         /* w2k3 returns "NOT IMPLEMENTED" for this call */
3509         torture_assert_ntstatus_ok(tctx, dcerpc_netr_AccountDeltas_r(b, tctx, &r),
3510                 "AccountDeltas failed");
3511         torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_IMPLEMENTED, "AccountDeltas");
3512
3513         return true;
3514 }
3515
3516 /*
3517   try a netlogon AccountSync
3518 */
3519 static bool test_AccountSync(struct torture_context *tctx, struct dcerpc_pipe *p,
3520                              struct cli_credentials *machine_credentials)
3521 {
3522         struct netr_AccountSync r;
3523         struct netlogon_creds_CredentialState *creds;
3524
3525         struct netr_AccountBuffer buffer;
3526         uint32_t count_returned = 0;
3527         uint32_t total_entries = 0;
3528         uint32_t next_reference = 0;
3529         struct netr_UAS_INFO_0 recordid;
3530         struct netr_Authenticator return_authenticator;
3531         struct dcerpc_binding_handle *b = p->binding_handle;
3532
3533         ZERO_STRUCT(recordid);
3534         ZERO_STRUCT(return_authenticator);
3535
3536         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
3537                 return false;
3538         }
3539
3540         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3541         r.in.computername = TEST_MACHINE_NAME;
3542         r.in.return_authenticator = &return_authenticator;
3543         netlogon_creds_client_authenticator(creds, &r.in.credential);
3544         r.in.recordid = &recordid;
3545         r.in.reference=0;
3546         r.in.level=0;
3547         r.in.buffersize=100;
3548         r.out.buffer = &buffer;
3549         r.out.count_returned = &count_returned;
3550         r.out.total_entries = &total_entries;
3551         r.out.next_reference = &next_reference;
3552         r.out.recordid = &recordid;
3553         r.out.return_authenticator = &return_authenticator;
3554
3555         /* w2k3 returns "NOT IMPLEMENTED" for this call */
3556         torture_assert_ntstatus_ok(tctx, dcerpc_netr_AccountSync_r(b, tctx, &r),
3557                 "AccountSync failed");
3558         torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_IMPLEMENTED, "AccountSync");
3559
3560         return true;
3561 }
3562
3563 /*
3564   try a netlogon GetDcName
3565 */
3566 static bool test_GetDcName(struct torture_context *tctx,
3567                            struct dcerpc_pipe *p)
3568 {
3569         struct netr_GetDcName r;
3570         const char *dcname = NULL;
3571         struct dcerpc_binding_handle *b = p->binding_handle;
3572
3573         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3574         r.in.domainname = lpcfg_workgroup(tctx->lp_ctx);
3575         r.out.dcname = &dcname;
3576
3577         torture_assert_ntstatus_ok(tctx, dcerpc_netr_GetDcName_r(b, tctx, &r),
3578                 "GetDcName failed");
3579         torture_assert_werr_ok(tctx, r.out.result, "GetDcName failed");
3580
3581         torture_comment(tctx, "\tDC is at '%s'\n", dcname);
3582
3583         return true;
3584 }
3585
3586 static const char *function_code_str(TALLOC_CTX *mem_ctx,
3587                                      enum netr_LogonControlCode function_code)
3588 {
3589         switch (function_code) {
3590         case NETLOGON_CONTROL_QUERY:
3591                 return "NETLOGON_CONTROL_QUERY";
3592         case NETLOGON_CONTROL_REPLICATE:
3593                 return "NETLOGON_CONTROL_REPLICATE";
3594         case NETLOGON_CONTROL_SYNCHRONIZE:
3595                 return "NETLOGON_CONTROL_SYNCHRONIZE";
3596         case NETLOGON_CONTROL_PDC_REPLICATE:
3597                 return "NETLOGON_CONTROL_PDC_REPLICATE";
3598         case NETLOGON_CONTROL_REDISCOVER:
3599                 return "NETLOGON_CONTROL_REDISCOVER";
3600         case NETLOGON_CONTROL_TC_QUERY:
3601                 return "NETLOGON_CONTROL_TC_QUERY";
3602         case NETLOGON_CONTROL_TRANSPORT_NOTIFY:
3603                 return "NETLOGON_CONTROL_TRANSPORT_NOTIFY";
3604         case NETLOGON_CONTROL_FIND_USER:
3605                 return "NETLOGON_CONTROL_FIND_USER";
3606         case NETLOGON_CONTROL_CHANGE_PASSWORD:
3607                 return "NETLOGON_CONTROL_CHANGE_PASSWORD";
3608         case NETLOGON_CONTROL_TC_VERIFY:
3609                 return "NETLOGON_CONTROL_TC_VERIFY";
3610         case NETLOGON_CONTROL_FORCE_DNS_REG:
3611                 return "NETLOGON_CONTROL_FORCE_DNS_REG";
3612         case NETLOGON_CONTROL_QUERY_DNS_REG:
3613                 return "NETLOGON_CONTROL_QUERY_DNS_REG";
3614         case NETLOGON_CONTROL_BACKUP_CHANGE_LOG:
3615                 return "NETLOGON_CONTROL_BACKUP_CHANGE_LOG";
3616         case NETLOGON_CONTROL_TRUNCATE_LOG:
3617                 return "NETLOGON_CONTROL_TRUNCATE_LOG";
3618         case NETLOGON_CONTROL_SET_DBFLAG:
3619                 return "NETLOGON_CONTROL_SET_DBFLAG";
3620         case NETLOGON_CONTROL_BREAKPOINT:
3621                 return "NETLOGON_CONTROL_BREAKPOINT";
3622         default:
3623                 return talloc_asprintf(mem_ctx, "unknown function code: %d",
3624                                        function_code);
3625         }
3626 }
3627
3628
3629 /*
3630   try a netlogon LogonControl
3631 */
3632 static bool test_LogonControl(struct torture_context *tctx,
3633                               struct dcerpc_pipe *p,
3634                               struct cli_credentials *machine_credentials)
3635
3636 {
3637         NTSTATUS status;
3638         struct netr_LogonControl r;
3639         union netr_CONTROL_QUERY_INFORMATION query;
3640         int i,f;
3641         enum netr_SchannelType secure_channel_type = SEC_CHAN_NULL;
3642         struct dcerpc_binding_handle *b = p->binding_handle;
3643
3644         uint32_t function_codes[] = {
3645                 NETLOGON_CONTROL_QUERY,
3646                 NETLOGON_CONTROL_REPLICATE,
3647                 NETLOGON_CONTROL_SYNCHRONIZE,
3648                 NETLOGON_CONTROL_PDC_REPLICATE,
3649                 NETLOGON_CONTROL_REDISCOVER,
3650                 NETLOGON_CONTROL_TC_QUERY,
3651                 NETLOGON_CONTROL_TRANSPORT_NOTIFY,
3652                 NETLOGON_CONTROL_FIND_USER,
3653                 NETLOGON_CONTROL_CHANGE_PASSWORD,
3654                 NETLOGON_CONTROL_TC_VERIFY,
3655                 NETLOGON_CONTROL_FORCE_DNS_REG,
3656                 NETLOGON_CONTROL_QUERY_DNS_REG,
3657                 NETLOGON_CONTROL_BACKUP_CHANGE_LOG,
3658                 NETLOGON_CONTROL_TRUNCATE_LOG,
3659                 NETLOGON_CONTROL_SET_DBFLAG,
3660                 NETLOGON_CONTROL_BREAKPOINT
3661         };
3662
3663         if (machine_credentials) {
3664                 secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
3665         }
3666
3667         torture_comment(tctx, "Testing LogonControl with secure channel type: %d\n",
3668                 secure_channel_type);
3669
3670         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3671         r.in.function_code = 1;
3672         r.out.query = &query;
3673
3674         for (f=0;f<ARRAY_SIZE(function_codes); f++) {
3675         for (i=1;i<5;i++) {
3676
3677                 r.in.function_code = function_codes[f];
3678                 r.in.level = i;
3679
3680                 torture_comment(tctx, "Testing LogonControl function code %s (%d) level %d\n",
3681                                 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
3682
3683                 status = dcerpc_netr_LogonControl_r(b, tctx, &r);
3684                 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
3685
3686                 switch (r.in.level) {
3687                 case 1:
3688                         switch (r.in.function_code) {
3689                         case NETLOGON_CONTROL_REPLICATE:
3690                         case NETLOGON_CONTROL_SYNCHRONIZE:
3691                         case NETLOGON_CONTROL_PDC_REPLICATE:
3692                         case NETLOGON_CONTROL_BREAKPOINT:
3693                         case NETLOGON_CONTROL_BACKUP_CHANGE_LOG:
3694                                 if ((secure_channel_type == SEC_CHAN_BDC) ||
3695                                     (secure_channel_type == SEC_CHAN_WKSTA)) {
3696                                         torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED,
3697                                                 "LogonControl returned unexpected error code");
3698                                 } else {
3699                                         torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
3700                                                 "LogonControl returned unexpected error code");
3701                                 }
3702                                 break;
3703
3704                         case NETLOGON_CONTROL_REDISCOVER:
3705                         case NETLOGON_CONTROL_TC_QUERY:
3706                         case NETLOGON_CONTROL_TRANSPORT_NOTIFY:
3707                         case NETLOGON_CONTROL_FIND_USER:
3708                         case NETLOGON_CONTROL_CHANGE_PASSWORD:
3709                         case NETLOGON_CONTROL_TC_VERIFY:
3710                         case NETLOGON_CONTROL_FORCE_DNS_REG:
3711                         case NETLOGON_CONTROL_QUERY_DNS_REG:
3712                         case NETLOGON_CONTROL_SET_DBFLAG:
3713                                 torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
3714                                         "LogonControl returned unexpected error code");
3715                                 break;
3716                         case NETLOGON_CONTROL_TRUNCATE_LOG:
3717                                 if ((secure_channel_type == SEC_CHAN_BDC) ||
3718                                     (secure_channel_type == SEC_CHAN_WKSTA)) {
3719                                         torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED,
3720                                                 "LogonControl returned unexpected error code");
3721                                 } else if (!W_ERROR_EQUAL(r.out.result, WERR_NOT_SUPPORTED)) {
3722                                         torture_assert_werr_ok(tctx, r.out.result,
3723                                                 "LogonControl returned unexpected result");
3724                                 }
3725                                 break;
3726                         default:
3727                                 torture_assert_werr_ok(tctx, r.out.result,
3728                                         "LogonControl returned unexpected result");
3729                                 break;
3730                         }
3731                         break;
3732                 case 2:
3733                         torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
3734                                 "LogonControl returned unexpected error code");
3735                         break;
3736                 default:
3737                         torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_LEVEL,
3738                                 "LogonControl returned unexpected error code");
3739                         break;
3740                 }
3741         }
3742         }
3743
3744         r.in.level = 52;
3745         torture_comment(tctx, "Testing LogonControl function code %s (%d) level %d\n",
3746                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
3747         status = dcerpc_netr_LogonControl_r(b, tctx, &r);
3748         torture_assert_ntstatus_ok(tctx, status, "LogonControl");
3749         torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_LEVEL, "LogonControl");
3750
3751         return true;
3752 }
3753
3754
3755 /*
3756   try a netlogon GetAnyDCName
3757 */
3758 static bool test_GetAnyDCName(struct torture_context *tctx,
3759                               struct dcerpc_pipe *p)
3760 {
3761         NTSTATUS status;
3762         struct netr_GetAnyDCName r;
3763         const char *dcname = NULL;
3764         struct dcerpc_binding_handle *b = p->binding_handle;
3765
3766         r.in.domainname = lpcfg_workgroup(tctx->lp_ctx);
3767         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3768         r.out.dcname = &dcname;
3769
3770         status = dcerpc_netr_GetAnyDCName_r(b, tctx, &r);
3771         torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
3772         if ((!W_ERROR_IS_OK(r.out.result)) &&
3773             (!W_ERROR_EQUAL(r.out.result, WERR_NO_SUCH_DOMAIN))) {
3774                 return false;
3775         }
3776
3777         if (dcname) {
3778             torture_comment(tctx, "\tDC is at '%s'\n", dcname);
3779         }
3780
3781         r.in.domainname = NULL;
3782
3783         status = dcerpc_netr_GetAnyDCName_r(b, tctx, &r);
3784         torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
3785         if ((!W_ERROR_IS_OK(r.out.result)) &&
3786             (!W_ERROR_EQUAL(r.out.result, WERR_NO_SUCH_DOMAIN))) {
3787                 return false;
3788         }
3789
3790         r.in.domainname = "";
3791
3792         status = dcerpc_netr_GetAnyDCName_r(b, tctx, &r);
3793         torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
3794         if ((!W_ERROR_IS_OK(r.out.result)) &&
3795             (!W_ERROR_EQUAL(r.out.result, WERR_NO_SUCH_DOMAIN))) {
3796                 return false;
3797         }
3798
3799         return true;
3800 }
3801
3802
3803 /*
3804   try a netlogon LogonControl2
3805 */
3806 static bool test_LogonControl2(struct torture_context *tctx,
3807                                struct dcerpc_pipe *p,
3808                                struct cli_credentials *machine_credentials)
3809
3810 {
3811         NTSTATUS status;
3812         struct netr_LogonControl2 r;
3813         union netr_CONTROL_DATA_INFORMATION data;
3814         union netr_CONTROL_QUERY_INFORMATION query;
3815         enum netr_SchannelType secure_channel_type = SEC_CHAN_NULL;
3816         int i;
3817         struct dcerpc_binding_handle *b = p->binding_handle;
3818
3819         data.domain = lpcfg_workgroup(tctx->lp_ctx);
3820
3821         if (machine_credentials) {
3822                 secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
3823         }
3824
3825         torture_comment(tctx, "Testing LogonControl2 with secure channel type: %d\n",
3826                 secure_channel_type);
3827
3828         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3829
3830         r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
3831         r.in.data = &data;
3832         r.out.query = &query;
3833
3834         for (i=1;i<4;i++) {
3835                 r.in.level = i;
3836
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         }
3843
3844         data.domain = lpcfg_workgroup(tctx->lp_ctx);
3845
3846         r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
3847         r.in.data = &data;
3848
3849         for (i=1;i<4;i++) {
3850                 r.in.level = i;
3851
3852                 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
3853                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
3854
3855                 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
3856                 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
3857         }
3858
3859         data.domain = lpcfg_workgroup(tctx->lp_ctx);
3860
3861         r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
3862         r.in.data = &data;
3863
3864         for (i=1;i<4;i++) {
3865                 r.in.level = i;
3866
3867                 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
3868                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
3869
3870                 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
3871                 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
3872         }
3873
3874         data.debug_level = ~0;
3875
3876         r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
3877         r.in.data = &data;
3878
3879         for (i=1;i<4;i++) {
3880                 r.in.level = i;
3881
3882                 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
3883                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
3884
3885                 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
3886                 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
3887         }
3888
3889         ZERO_STRUCT(data);
3890         r.in.function_code = 52;
3891         r.in.data = &data;
3892
3893         torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
3894                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
3895
3896         status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
3897         torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
3898         switch (secure_channel_type) {
3899         case SEC_CHAN_NULL:
3900                 torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED, "LogonControl2");
3901                 break;
3902         default:
3903                 torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED, "LogonControl2");
3904                 break;
3905         }
3906         data.debug_level = ~0;
3907
3908         r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
3909         r.in.data = &data;
3910
3911         r.in.level = 52;
3912         torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
3913                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
3914
3915         status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
3916         torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
3917         torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_LEVEL, "LogonControl2");
3918
3919         return true;
3920 }
3921
3922 /*
3923   try a netlogon DatabaseSync2
3924 */
3925 static bool test_DatabaseSync2(struct torture_context *tctx,
3926                                struct dcerpc_pipe *p,
3927                                struct cli_credentials *machine_credentials)
3928 {
3929         struct netr_DatabaseSync2 r;
3930         struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
3931         struct netr_Authenticator return_authenticator, credential;
3932
3933         struct netlogon_creds_CredentialState *creds;
3934         const uint32_t database_ids[] = {0, 1, 2};
3935         int i;
3936         struct dcerpc_binding_handle *b = p->binding_handle;
3937
3938         if (!test_SetupCredentials2(p, tctx, NETLOGON_NEG_AUTH2_FLAGS,
3939                                     machine_credentials,
3940                                     cli_credentials_get_secure_channel_type(machine_credentials),
3941                                     &creds)) {
3942                 return false;
3943         }
3944
3945         ZERO_STRUCT(return_authenticator);
3946
3947         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3948         r.in.computername = TEST_MACHINE_NAME;
3949         r.in.preferredmaximumlength = (uint32_t)-1;
3950         r.in.return_authenticator = &return_authenticator;
3951         r.out.return_authenticator = &return_authenticator;
3952         r.out.delta_enum_array = &delta_enum_array;
3953
3954         for (i=0;i<ARRAY_SIZE(database_ids);i++) {
3955
3956                 uint32_t sync_context = 0;
3957
3958                 r.in.database_id = database_ids[i];
3959                 r.in.sync_context = &sync_context;
3960                 r.out.sync_context = &sync_context;
3961                 r.in.restart_state = 0;
3962
3963                 torture_comment(tctx, "Testing DatabaseSync2 of id %d\n", r.in.database_id);
3964
3965                 do {
3966                         netlogon_creds_client_authenticator(creds, &credential);
3967
3968                         r.in.credential = &credential;
3969
3970                         torture_assert_ntstatus_ok(tctx, dcerpc_netr_DatabaseSync2_r(b, tctx, &r),
3971                                 "DatabaseSync2 failed");
3972                         if (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES))
3973                             break;
3974
3975                         /* Native mode servers don't do this */
3976                         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_SUPPORTED)) {
3977                                 return true;
3978                         }
3979
3980                         torture_assert_ntstatus_ok(tctx, r.out.result, "DatabaseSync2");
3981
3982                         if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
3983                                 torture_comment(tctx, "Credential chaining failed\n");
3984                         }
3985
3986                 } while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES));
3987         }
3988
3989         return true;
3990 }
3991
3992
3993 /*
3994   try a netlogon LogonControl2Ex
3995 */
3996 static bool test_LogonControl2Ex(struct torture_context *tctx,
3997                                  struct dcerpc_pipe *p,
3998                                  struct cli_credentials *machine_credentials)
3999
4000 {
4001         NTSTATUS status;
4002         struct netr_LogonControl2Ex r;
4003         union netr_CONTROL_DATA_INFORMATION data;
4004         union netr_CONTROL_QUERY_INFORMATION query;
4005         enum netr_SchannelType secure_channel_type = SEC_CHAN_NULL;
4006         int i;
4007         struct dcerpc_binding_handle *b = p->binding_handle;
4008
4009         data.domain = lpcfg_workgroup(tctx->lp_ctx);
4010
4011         if (machine_credentials) {
4012                 secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
4013         }
4014
4015         torture_comment(tctx, "Testing LogonControl2Ex with secure channel type: %d\n",
4016                 secure_channel_type);
4017
4018         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
4019
4020         r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
4021         r.in.data = &data;
4022         r.out.query = &query;
4023
4024         for (i=1;i<4;i++) {
4025                 r.in.level = i;
4026
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         }
4033
4034         data.domain = lpcfg_workgroup(tctx->lp_ctx);
4035
4036         r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
4037         r.in.data = &data;
4038
4039         for (i=1;i<4;i++) {
4040                 r.in.level = i;
4041
4042                 torture_comment(tctx, "Testing LogonControl2Ex function code %s (%d) level %d\n",
4043                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
4044
4045                 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
4046                 torture_assert_ntstatus_ok(tctx, status, "LogonControl2Ex");
4047         }
4048
4049         data.domain = lpcfg_workgroup(tctx->lp_ctx);
4050
4051         r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
4052         r.in.data = &data;
4053
4054         for (i=1;i<4;i++) {
4055                 r.in.level = i;
4056
4057                 torture_comment(tctx, "Testing LogonControl2Ex function code %s (%d) level %d\n",
4058                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
4059
4060                 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
4061                 torture_assert_ntstatus_ok(tctx, status, "LogonControl2Ex");
4062         }
4063
4064         data.debug_level = ~0;
4065
4066         r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
4067         r.in.data = &data;
4068
4069         for (i=1;i<4;i++) {
4070                 r.in.level = i;
4071
4072                 torture_comment(tctx, "Testing LogonControl2Ex function code %s (%d) level %d\n",
4073                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
4074
4075                 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
4076                 torture_assert_ntstatus_ok(tctx, status, "LogonControl2Ex");
4077         }
4078
4079         ZERO_STRUCT(data);
4080         r.in.function_code = 52;
4081         r.in.data = &data;
4082
4083         torture_comment(tctx, "Testing LogonControl2Ex function code %s (%d) level %d\n",
4084                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
4085
4086         status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
4087         torture_assert_ntstatus_ok(tctx, status, "LogonControl2Ex");
4088         switch (secure_channel_type) {
4089         case SEC_CHAN_NULL:
4090                 torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED, "LogonControl2Ex");
4091                 break;
4092         default:
4093                 torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED, "LogonControl2Ex");
4094                 break;
4095         }
4096         data.debug_level = ~0;
4097
4098         r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
4099         r.in.data = &data;
4100
4101         r.in.level = 52;
4102         torture_comment(tctx, "Testing LogonControl2Ex function code %s (%d) level %d\n",
4103                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
4104
4105         status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
4106         torture_assert_ntstatus_ok(tctx, status, "LogonControl2Ex");
4107         torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_LEVEL, "LogonControl2Ex");
4108
4109         return true;
4110 }
4111
4112 static bool test_netr_GetForestTrustInformation(struct torture_context *tctx,
4113                                                 struct dcerpc_pipe *p1,
4114                                                 struct cli_credentials *machine_credentials)
4115 {
4116         struct netr_GetForestTrustInformation r;
4117         struct netlogon_creds_CredentialState *creds;
4118         struct netr_Authenticator a;
4119         struct netr_Authenticator return_authenticator;
4120         struct lsa_ForestTrustInformation *forest_trust_info;
4121         struct dcerpc_pipe *p = NULL;
4122         struct dcerpc_binding_handle *b = NULL;
4123
4124         if (!test_SetupCredentials3(p1, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES,
4125                                     machine_credentials, &creds)) {
4126                 return false;
4127         }
4128         if (!test_SetupCredentialsPipe(p1, tctx, machine_credentials, creds,
4129                                        DCERPC_SIGN | DCERPC_SEAL, &p)) {
4130                 return false;
4131         }
4132         b = p->binding_handle;
4133
4134         netlogon_creds_client_authenticator(creds, &a);
4135
4136         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
4137         r.in.computer_name = TEST_MACHINE_NAME;
4138         r.in.credential = &a;
4139         r.in.flags = 0;
4140         r.out.return_authenticator = &return_authenticator;
4141         r.out.forest_trust_info = &forest_trust_info;
4142
4143         torture_assert_ntstatus_ok(tctx,
4144                 dcerpc_netr_GetForestTrustInformation_r(b, tctx, &r),
4145                 "netr_GetForestTrustInformation failed");
4146         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_IMPLEMENTED)) {
4147                 torture_comment(tctx, "not considering NT_STATUS_NOT_IMPLEMENTED as an error\n");
4148         } else {
4149                 torture_assert_ntstatus_ok(tctx, r.out.result,
4150                         "netr_GetForestTrustInformation failed");
4151         }
4152
4153         torture_assert(tctx,
4154                 netlogon_creds_client_check(creds, &return_authenticator.cred),
4155                 "Credential chaining failed");
4156
4157         return true;
4158 }
4159
4160 static bool test_netr_DsRGetForestTrustInformation(struct torture_context *tctx,
4161                                                    struct dcerpc_pipe *p, const char *trusted_domain_name)
4162 {
4163         NTSTATUS status;
4164         struct netr_DsRGetForestTrustInformation r;
4165         struct lsa_ForestTrustInformation info, *info_ptr;
4166         struct dcerpc_binding_handle *b = p->binding_handle;
4167
4168         info_ptr = &info;
4169
4170         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
4171         r.in.trusted_domain_name = trusted_domain_name;
4172         r.in.flags = 0;
4173         r.out.forest_trust_info = &info_ptr;
4174
4175         torture_comment(tctx ,"Testing netr_DsRGetForestTrustInformation\n");
4176
4177         status = dcerpc_netr_DsRGetForestTrustInformation_r(b, tctx, &r);
4178         torture_assert_ntstatus_ok(tctx, status, "DsRGetForestTrustInformation");
4179         torture_assert_werr_ok(tctx, r.out.result, "DsRGetForestTrustInformation");
4180
4181         return true;
4182 }
4183
4184 /*
4185   try a netlogon netr_DsrEnumerateDomainTrusts
4186 */
4187 static bool test_DsrEnumerateDomainTrusts(struct torture_context *tctx,
4188                                           struct dcerpc_pipe *p)
4189 {
4190         NTSTATUS status;
4191         struct netr_DsrEnumerateDomainTrusts r;
4192         struct netr_DomainTrustList trusts;
4193         int i;
4194         struct dcerpc_binding_handle *b = p->binding_handle;
4195
4196         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
4197         r.in.trust_flags = 0x3f;
4198         r.out.trusts = &trusts;
4199
4200         status = dcerpc_netr_DsrEnumerateDomainTrusts_r(b, tctx, &r);
4201         torture_assert_ntstatus_ok(tctx, status, "DsrEnumerateDomaintrusts");
4202         torture_assert_werr_ok(tctx, r.out.result, "DsrEnumerateDomaintrusts");
4203
4204         /* when trusted_domain_name is NULL, netr_DsRGetForestTrustInformation
4205          * will show non-forest trusts and all UPN suffixes of the own forest
4206          * as LSA_FOREST_TRUST_TOP_LEVEL_NAME types */
4207
4208         if (r.out.trusts->count) {
4209                 if (!test_netr_DsRGetForestTrustInformation(tctx, p, NULL)) {
4210                         return false;
4211                 }
4212         }
4213
4214         for (i=0; i<r.out.trusts->count; i++) {
4215
4216                 /* get info for transitive forest trusts */
4217
4218                 if (r.out.trusts->array[i].trust_attributes & LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) {
4219                         if (!test_netr_DsRGetForestTrustInformation(tctx, p,
4220                                                                     r.out.trusts->array[i].dns_name)) {
4221                                 return false;
4222                         }
4223                 }
4224         }
4225
4226         return true;
4227 }
4228
4229 static bool test_netr_NetrEnumerateTrustedDomains(struct torture_context *tctx,
4230                                                   struct dcerpc_pipe *p)
4231 {
4232         NTSTATUS status;
4233         struct netr_NetrEnumerateTrustedDomains r;
4234         struct netr_Blob trusted_domains_blob;
4235         struct dcerpc_binding_handle *b = p->binding_handle;
4236
4237         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
4238         r.out.trusted_domains_blob = &trusted_domains_blob;
4239
4240         status = dcerpc_netr_NetrEnumerateTrustedDomains_r(b, tctx, &r);
4241         torture_assert_ntstatus_ok(tctx, status, "netr_NetrEnumerateTrustedDomains");
4242         torture_assert_ntstatus_ok(tctx, r.out.result, "NetrEnumerateTrustedDomains");
4243
4244         return true;
4245 }
4246
4247 static bool test_netr_NetrEnumerateTrustedDomainsEx(struct torture_context *tctx,
4248                                                     struct dcerpc_pipe *p)
4249 {
4250         NTSTATUS status;
4251         struct netr_NetrEnumerateTrustedDomainsEx r;
4252         struct netr_DomainTrustList dom_trust_list;
4253         struct dcerpc_binding_handle *b = p->binding_handle;
4254
4255         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
4256         r.out.dom_trust_list = &dom_trust_list;
4257
4258         status = dcerpc_netr_NetrEnumerateTrustedDomainsEx_r(b, tctx, &r);
4259         torture_assert_ntstatus_ok(tctx, status, "netr_NetrEnumerateTrustedDomainsEx");
4260         torture_assert_werr_ok(tctx, r.out.result, "NetrEnumerateTrustedDomainsEx");
4261
4262         return true;
4263 }
4264
4265
4266 static bool test_netr_DsRGetSiteName(struct dcerpc_pipe *p, struct torture_context *tctx,
4267                                      const char *computer_name,
4268                                      const char *expected_site)
4269 {
4270         NTSTATUS status;
4271         struct netr_DsRGetSiteName r;
4272         const char *site = NULL;
4273         struct dcerpc_binding_handle *b = p->binding_handle;
4274
4275         r.in.computer_name              = computer_name;
4276         r.out.site                      = &site;
4277         torture_comment(tctx, "Testing netr_DsRGetSiteName\n");
4278
4279         status = dcerpc_netr_DsRGetSiteName_r(b, tctx, &r);
4280         torture_assert_ntstatus_ok(tctx, status, "DsRGetSiteName");
4281         torture_assert_werr_ok(tctx, r.out.result, "DsRGetSiteName");
4282         torture_assert_str_equal(tctx, expected_site, site, "netr_DsRGetSiteName");
4283
4284         return true;
4285 }
4286
4287 /*
4288   try a netlogon netr_DsRGetDCName
4289 */
4290 static bool test_netr_DsRGetDCName(struct torture_context *tctx,
4291                                    struct dcerpc_pipe *p)
4292 {
4293         NTSTATUS status;
4294         struct netr_DsRGetDCName r;
4295         struct netr_DsRGetDCNameInfo *info = NULL;
4296         struct dcerpc_binding_handle *b = p->binding_handle;
4297
4298         r.in.server_unc         = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
4299         r.in.domain_name        = lpcfg_dnsdomain(tctx->lp_ctx);
4300         r.in.domain_guid        = NULL;
4301         r.in.site_guid          = NULL;
4302         r.in.flags              = DS_RETURN_DNS_NAME;
4303         r.out.info              = &info;
4304
4305         status = dcerpc_netr_DsRGetDCName_r(b, tctx, &r);
4306         torture_assert_ntstatus_ok(tctx, status, "DsRGetDCName");
4307         torture_assert_werr_ok(tctx, r.out.result, "DsRGetDCName");
4308
4309         torture_assert_int_equal(tctx,
4310                                  (info->dc_flags & (DS_DNS_CONTROLLER)),
4311                                  DS_DNS_CONTROLLER,
4312                                  "DsRGetDCName");
4313         torture_assert_int_equal(tctx,
4314                                  (info->dc_flags & (DS_DNS_DOMAIN)),
4315                                  DS_DNS_DOMAIN,
4316                                  "DsRGetDCName");
4317         torture_assert_int_equal(tctx,
4318                                  (info->dc_flags & (DS_DNS_FOREST_ROOT)),
4319                                  DS_DNS_FOREST_ROOT,
4320                                  "DsRGetDCName");
4321
4322         r.in.domain_name        = lpcfg_workgroup(tctx->lp_ctx);
4323         r.in.flags              = 0;
4324
4325         status = dcerpc_netr_DsRGetDCName_r(b, tctx, &r);
4326         torture_assert_ntstatus_ok(tctx, status, "DsRGetDCName");
4327         torture_assert_werr_ok(tctx, r.out.result, "DsRGetDCName");
4328
4329         torture_assert_int_equal(tctx,
4330                                  (info->dc_flags & (DS_DNS_CONTROLLER)), 0,
4331                                  "DsRGetDCName");
4332         torture_assert_int_equal(tctx,
4333                                  (info->dc_flags & (DS_DNS_DOMAIN)), 0,
4334                                  "DsRGetDCName");
4335         torture_assert_int_equal(tctx,
4336                                  (info->dc_flags & (DS_DNS_FOREST_ROOT)),
4337                                  DS_DNS_FOREST_ROOT,
4338                                  "DsRGetDCName");
4339
4340         if (strcasecmp(info->dc_site_name, info->client_site_name) == 0) {
4341                 torture_assert_int_equal(tctx,
4342                                          (info->dc_flags & (DS_SERVER_CLOSEST)),
4343                                          DS_SERVER_CLOSEST,
4344                                          "DsRGetDCName");
4345         }
4346
4347         return test_netr_DsRGetSiteName(p, tctx,
4348                                        info->dc_unc,
4349                                        info->dc_site_name);
4350 }
4351
4352 /*
4353   try a netlogon netr_DsRGetDCNameEx
4354 */
4355 static bool test_netr_DsRGetDCNameEx(struct torture_context *tctx,
4356                                      struct dcerpc_pipe *p)
4357 {
4358         NTSTATUS status;
4359         struct netr_DsRGetDCNameEx r;
4360         struct netr_DsRGetDCNameInfo *info = NULL;
4361         struct dcerpc_binding_handle *b = p->binding_handle;
4362
4363         r.in.server_unc         = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
4364         r.in.domain_name        = lpcfg_dnsdomain(tctx->lp_ctx);
4365         r.in.domain_guid        = NULL;
4366         r.in.site_name          = NULL;
4367         r.in.flags              = DS_RETURN_DNS_NAME;
4368         r.out.info              = &info;
4369
4370         status = dcerpc_netr_DsRGetDCNameEx_r(b, tctx, &r);
4371         torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx");
4372         torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx");
4373
4374         torture_assert_int_equal(tctx,
4375                                  (info->dc_flags & (DS_DNS_CONTROLLER)),
4376                                  DS_DNS_CONTROLLER,
4377                                  "DsRGetDCNameEx");
4378         torture_assert_int_equal(tctx,
4379                                  (info->dc_flags & (DS_DNS_DOMAIN)),
4380                                  DS_DNS_DOMAIN,
4381                                  "DsRGetDCNameEx");
4382         torture_assert_int_equal(tctx,
4383                                  (info->dc_flags & (DS_DNS_FOREST_ROOT)),
4384                                  DS_DNS_FOREST_ROOT,
4385                                  "DsRGetDCNameEx");
4386
4387         r.in.domain_name        = lpcfg_workgroup(tctx->lp_ctx);
4388         r.in.flags              = 0;
4389
4390         status = dcerpc_netr_DsRGetDCNameEx_r(b, tctx, &r);
4391         torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx");
4392         torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx");
4393
4394         torture_assert_int_equal(tctx,
4395                                  (info->dc_flags & (DS_DNS_CONTROLLER)), 0,
4396                                  "DsRGetDCNameEx");
4397         torture_assert_int_equal(tctx,
4398                                  (info->dc_flags & (DS_DNS_DOMAIN)), 0,
4399                                  "DsRGetDCNameEx");
4400         torture_assert_int_equal(tctx,
4401                                  (info->dc_flags & (DS_DNS_FOREST_ROOT)),
4402                                  DS_DNS_FOREST_ROOT,
4403                                  "DsRGetDCNameEx");
4404
4405         if (strcasecmp(info->dc_site_name, info->client_site_name) == 0) {
4406                 torture_assert_int_equal(tctx,
4407                                          (info->dc_flags & (DS_SERVER_CLOSEST)),
4408                                          DS_SERVER_CLOSEST,
4409                                          "DsRGetDCNameEx");
4410         }
4411
4412         return test_netr_DsRGetSiteName(p, tctx, info->dc_unc,
4413                                         info->dc_site_name);
4414 }
4415
4416 /*
4417   try a netlogon netr_DsRGetDCNameEx2
4418 */
4419 static bool test_netr_DsRGetDCNameEx2(struct torture_context *tctx,
4420                                       struct dcerpc_pipe *p)
4421 {
4422         NTSTATUS status;
4423         struct netr_DsRGetDCNameEx2 r;
4424         struct netr_DsRGetDCNameInfo *info = NULL;
4425         struct dcerpc_binding_handle *b = p->binding_handle;
4426
4427         torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 with no inputs\n");
4428         ZERO_STRUCT(r.in);
4429         r.in.flags              = DS_RETURN_DNS_NAME;
4430         r.out.info              = &info;
4431
4432         status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
4433         torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
4434         torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
4435
4436         torture_assert_int_equal(tctx,
4437                                  (info->dc_flags & (DS_DNS_CONTROLLER)),
4438                                  DS_DNS_CONTROLLER,
4439                                  "DsRGetDCNameEx2");
4440         torture_assert_int_equal(tctx,
4441                                  (info->dc_flags & (DS_DNS_DOMAIN)),
4442                                  DS_DNS_DOMAIN,
4443                                  "DsRGetDCNameEx2");
4444         torture_assert_int_equal(tctx,
4445                                  (info->dc_flags & (DS_DNS_FOREST_ROOT)),
4446                                  DS_DNS_FOREST_ROOT,
4447                                  "DsRGetDCNameEx2");
4448
4449         r.in.server_unc         = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
4450         r.in.client_account     = NULL;
4451         r.in.mask               = 0x00000000;
4452         r.in.domain_name        = lpcfg_dnsdomain(tctx->lp_ctx);
4453         r.in.domain_guid        = NULL;
4454         r.in.site_name          = NULL;
4455         r.in.flags              = DS_RETURN_DNS_NAME;
4456         r.out.info              = &info;
4457
4458         torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 without client account\n");
4459
4460         status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
4461         torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
4462         torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
4463
4464         r.in.domain_name        = lpcfg_workgroup(tctx->lp_ctx);
4465         r.in.flags              = 0;
4466
4467         status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
4468         torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
4469         torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
4470
4471         torture_assert_int_equal(tctx,
4472                                  (info->dc_flags & (DS_DNS_CONTROLLER)), 0,
4473                                  "DsRGetDCNameEx2");
4474         torture_assert_int_equal(tctx,
4475                                  (info->dc_flags & (DS_DNS_DOMAIN)), 0,
4476                                  "DsRGetDCNameEx2");
4477         torture_assert_int_equal(tctx,
4478                                  (info->dc_flags & (DS_DNS_FOREST_ROOT)),
4479                                  DS_DNS_FOREST_ROOT,
4480                                  "DsRGetDCNameEx2");
4481
4482         if (strcasecmp(info->dc_site_name, info->client_site_name) == 0) {
4483                 torture_assert_int_equal(tctx,
4484                                          (info->dc_flags & (DS_SERVER_CLOSEST)),
4485                                          DS_SERVER_CLOSEST,
4486                                          "DsRGetDCNameEx2");
4487         }
4488
4489         torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 with client account\n");
4490         r.in.client_account     = TEST_MACHINE_NAME"$";
4491         r.in.mask               = ACB_SVRTRUST;
4492         r.in.flags              = DS_RETURN_FLAT_NAME;
4493         r.out.info              = &info;
4494
4495         status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
4496         torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
4497         torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
4498
4499         return test_netr_DsRGetSiteName(p, tctx, info->dc_unc,
4500                                         info->dc_site_name);
4501 }
4502
4503 /* This is a substitution for "samdb_server_site_name" which relies on the
4504  * correct "lp_ctx" and therefore can't be used here. */
4505 static const char *server_site_name(struct torture_context *tctx,
4506                                     struct ldb_context *ldb)
4507 {
4508         TALLOC_CTX *tmp_ctx;
4509         struct ldb_dn *dn, *server_dn;
4510         const struct ldb_val *site_name_val;
4511         const char *server_dn_str, *site_name;
4512
4513         tmp_ctx = talloc_new(ldb);
4514         if (tmp_ctx == NULL) {
4515                 goto failed;
4516         }
4517
4518         dn = ldb_dn_new(tmp_ctx, ldb, "");
4519         if (dn == NULL) {
4520                 goto failed;
4521         }
4522
4523         server_dn_str = samdb_search_string(ldb, tmp_ctx, dn, "serverName",
4524                                             NULL);
4525         if (server_dn_str == NULL) {
4526                 goto failed;
4527         }
4528
4529         server_dn = ldb_dn_new(tmp_ctx, ldb, server_dn_str);
4530         if (server_dn == NULL) {
4531                 goto failed;
4532         }
4533
4534         /* CN=<Server name>, CN=Servers, CN=<Site name>, CN=Sites, ... */
4535         site_name_val = ldb_dn_get_component_val(server_dn, 2);
4536         if (site_name_val == NULL) {
4537                 goto failed;
4538         }
4539
4540         site_name = (const char *) site_name_val->data;
4541
4542         talloc_steal(tctx, site_name);
4543         talloc_free(tmp_ctx);
4544
4545         return site_name;
4546
4547 failed:
4548         talloc_free(tmp_ctx);
4549         return NULL;
4550 }
4551
4552 static bool test_netr_DsrGetDcSiteCoverageW(struct torture_context *tctx,
4553                                             struct dcerpc_pipe *p)
4554 {
4555         char *url;
4556         struct ldb_context *sam_ctx = NULL;
4557         NTSTATUS status;
4558         struct netr_DsrGetDcSiteCoverageW r;
4559         struct DcSitesCtr *ctr = NULL;
4560         struct dcerpc_binding_handle *b = p->binding_handle;
4561
4562         torture_comment(tctx, "This does only pass with the default site\n");
4563
4564         /* We won't double-check this when we are over 'local' transports */
4565         if (dcerpc_server_name(p)) {
4566                 /* Set up connection to SAMDB on DC */
4567                 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
4568                 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
4569                                            NULL,
4570                                            samba_cmdline_get_creds(),
4571                                            0);
4572
4573                 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
4574         }
4575
4576         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
4577         r.out.ctr = &ctr;
4578
4579         status = dcerpc_netr_DsrGetDcSiteCoverageW_r(b, tctx, &r);
4580         torture_assert_ntstatus_ok(tctx, status, "failed");
4581         torture_assert_werr_ok(tctx, r.out.result, "failed");
4582
4583         torture_assert(tctx, ctr->num_sites == 1,
4584                        "we should per default only get the default site");
4585         if (sam_ctx != NULL) {
4586                 torture_assert_casestr_equal(tctx, ctr->sites[0].string,
4587                                              server_site_name(tctx, sam_ctx),
4588                                              "didn't return default site");
4589         }
4590
4591         return true;
4592 }
4593
4594 static bool test_netr_DsRAddressToSitenamesW(struct torture_context *tctx,
4595                                              struct dcerpc_pipe *p)
4596 {
4597         char *url;
4598         struct ldb_context *sam_ctx = NULL;
4599         NTSTATUS status;
4600         struct netr_DsRAddressToSitenamesW r;
4601         struct netr_DsRAddress addrs[6];
4602         struct sockaddr_in *addr;
4603 #ifdef HAVE_IPV6
4604         struct sockaddr_in6 *addr6;
4605 #endif
4606         struct netr_DsRAddressToSitenamesWCtr *ctr;
4607         struct dcerpc_binding_handle *b = p->binding_handle;
4608         uint32_t i;
4609         int ret;
4610
4611         torture_comment(tctx, "This does only pass with the default site\n");
4612
4613         /* We won't double-check this when we are over 'local' transports */
4614         if (dcerpc_server_name(p)) {
4615                 /* Set up connection to SAMDB on DC */
4616                 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
4617                 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
4618                                            NULL,
4619                                            samba_cmdline_get_creds(),
4620                                            0);
4621
4622                 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
4623         }
4624
4625         /* First try valid IP addresses */
4626
4627         addrs[0].size = sizeof(struct sockaddr_in);
4628         addrs[0].buffer = talloc_zero_array(tctx, uint8_t, addrs[0].size);
4629         addr = (struct sockaddr_in *) addrs[0].buffer;
4630         addrs[0].buffer[0] = AF_INET;
4631         ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
4632         torture_assert(tctx, ret > 0, "inet_pton failed");
4633
4634         addrs[1].size = sizeof(struct sockaddr_in);
4635         addrs[1].buffer = talloc_zero_array(tctx, uint8_t, addrs[1].size);
4636         addr = (struct sockaddr_in *) addrs[1].buffer;
4637         addrs[1].buffer[0] = AF_INET;
4638         ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
4639         torture_assert(tctx, ret > 0, "inet_pton failed");
4640
4641         addrs[2].size = sizeof(struct sockaddr_in);
4642         addrs[2].buffer = talloc_zero_array(tctx, uint8_t, addrs[2].size);
4643         addr = (struct sockaddr_in *) addrs[2].buffer;
4644         addrs[2].buffer[0] = AF_INET;
4645         ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
4646         torture_assert(tctx, ret > 0, "inet_pton failed");
4647
4648 #ifdef HAVE_IPV6
4649         addrs[3].size = sizeof(struct sockaddr_in6);
4650         addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
4651         addr6 = (struct sockaddr_in6 *) addrs[3].buffer;
4652         addrs[3].buffer[0] = AF_INET6;
4653         ret = inet_pton(AF_INET6, "::1", &addr6->sin6_addr);
4654         torture_assert(tctx, ret > 0, "inet_pton failed");
4655
4656         addrs[4].size = sizeof(struct sockaddr_in6);
4657         addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
4658         addr6 = (struct sockaddr_in6 *) addrs[4].buffer;
4659         addrs[4].buffer[0] = AF_INET6;
4660         ret = inet_pton(AF_INET6, "::", &addr6->sin6_addr);
4661         torture_assert(tctx, ret > 0, "inet_pton failed");
4662
4663         addrs[5].size = sizeof(struct sockaddr_in6);
4664         addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
4665         addr6 = (struct sockaddr_in6 *) addrs[5].buffer;
4666         addrs[5].buffer[0] = AF_INET6;
4667         ret = inet_pton(AF_INET6, "ff02::1", &addr6->sin6_addr);
4668         torture_assert(tctx, ret > 0, "inet_pton failed");
4669 #else
4670         /* the test cases are repeated to have exactly 6. This is for
4671          * compatibility with IPv4-only machines */
4672         addrs[3].size = sizeof(struct sockaddr_in);
4673         addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
4674         addr = (struct sockaddr_in *) addrs[3].buffer;
4675         addrs[3].buffer[0] = AF_INET;
4676         ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
4677         torture_assert(tctx, ret > 0, "inet_pton failed");
4678
4679         addrs[4].size = sizeof(struct sockaddr_in);
4680         addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
4681         addr = (struct sockaddr_in *) addrs[4].buffer;
4682         addrs[4].buffer[0] = AF_INET;
4683         ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
4684         torture_assert(tctx, ret > 0, "inet_pton failed");
4685
4686         addrs[5].size = sizeof(struct sockaddr_in);
4687         addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
4688         addr = (struct sockaddr_in *) addrs[5].buffer;
4689         addrs[5].buffer[0] = AF_INET;
4690         ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
4691         torture_assert(tctx, ret > 0, "inet_pton failed");
4692 #endif
4693
4694         ctr = talloc(tctx, struct netr_DsRAddressToSitenamesWCtr);
4695
4696         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
4697         r.in.count = 6;
4698         r.in.addresses = addrs;
4699         r.out.ctr = &ctr;
4700
4701         status = dcerpc_netr_DsRAddressToSitenamesW_r(b, tctx, &r);
4702         torture_assert_ntstatus_ok(tctx, status, "failed");
4703         torture_assert_werr_ok(tctx, r.out.result, "failed");
4704
4705         if (sam_ctx != NULL) {
4706                 for (i = 0; i < 3; i++) {
4707                         torture_assert_casestr_equal(tctx,
4708                                                      ctr->sitename[i].string,
4709                                                      server_site_name(tctx, sam_ctx),
4710                                                      "didn't return default site");
4711                 }
4712                 for (i = 3; i < 6; i++) {
4713                         /* Windows returns "NULL" for the sitename if it isn't
4714                          * IPv6 configured */
4715                         if (torture_setting_bool(tctx, "samba4", false)) {
4716                                 torture_assert_casestr_equal(tctx,
4717                                                              ctr->sitename[i].string,
4718                                                              server_site_name(tctx, sam_ctx),
4719                                                              "didn't return default site");
4720                         }
4721                 }
4722         }
4723
4724         /* Now try invalid ones (too short buffers) */
4725
4726         addrs[0].size = 0;
4727         addrs[1].size = 1;
4728         addrs[2].size = 4;
4729
4730         addrs[3].size = 0;
4731         addrs[4].size = 1;
4732         addrs[5].size = 4;
4733
4734         status = dcerpc_netr_DsRAddressToSitenamesW_r(b, tctx, &r);
4735         torture_assert_ntstatus_ok(tctx, status, "failed");
4736         torture_assert_werr_ok(tctx, r.out.result, "failed");
4737
4738         for (i = 0; i < 6; i++) {
4739                 torture_assert(tctx, ctr->sitename[i].string == NULL,
4740                                "sitename should be null");
4741         }
4742
4743         /* Now try invalid ones (wrong address types) */
4744
4745         addrs[0].size = 10;
4746         addrs[0].buffer[0] = AF_UNSPEC;
4747         addrs[1].size = 10;
4748         addrs[1].buffer[0] = AF_UNIX; /* AF_LOCAL = AF_UNIX */
4749         addrs[2].size = 10;
4750         addrs[2].buffer[0] = AF_UNIX;
4751
4752         addrs[3].size = 10;
4753         addrs[3].buffer[0] = 250;
4754         addrs[4].size = 10;
4755         addrs[4].buffer[0] = 251;
4756         addrs[5].size = 10;
4757         addrs[5].buffer[0] = 252;
4758
4759         status = dcerpc_netr_DsRAddressToSitenamesW_r(b, tctx, &r);
4760         torture_assert_ntstatus_ok(tctx, status, "failed");
4761         torture_assert_werr_ok(tctx, r.out.result, "failed");
4762
4763         for (i = 0; i < 6; i++) {
4764                 torture_assert(tctx, ctr->sitename[i].string == NULL,
4765                                "sitename should be null");
4766         }
4767
4768         return true;
4769 }
4770
4771 static bool test_netr_DsRAddressToSitenamesExW(struct torture_context *tctx,
4772                                                struct dcerpc_pipe *p)
4773 {
4774         char *url;
4775         struct ldb_context *sam_ctx = NULL;
4776         NTSTATUS status;
4777         struct netr_DsRAddressToSitenamesExW r;
4778         struct netr_DsRAddress addrs[6];
4779         struct sockaddr_in *addr;
4780 #ifdef HAVE_IPV6
4781         struct sockaddr_in6 *addr6;
4782 #endif
4783         struct netr_DsRAddressToSitenamesExWCtr *ctr;
4784         struct dcerpc_binding_handle *b = p->binding_handle;
4785         uint32_t i;
4786         int ret;
4787
4788         torture_comment(tctx, "This does pass with the default site\n");
4789
4790         /* We won't double-check this when we are over 'local' transports */
4791         if (dcerpc_server_name(p)) {
4792                 /* Set up connection to SAMDB on DC */
4793                 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
4794                 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
4795                                            NULL,
4796                                            samba_cmdline_get_creds(),
4797                                            0);
4798
4799                 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
4800         }
4801
4802         /* First try valid IP addresses */
4803
4804         addrs[0].size = sizeof(struct sockaddr_in);
4805         addrs[0].buffer = talloc_zero_array(tctx, uint8_t, addrs[0].size);
4806         addr = (struct sockaddr_in *) addrs[0].buffer;
4807         addrs[0].buffer[0] = AF_INET;
4808         ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
4809         torture_assert(tctx, ret > 0, "inet_pton failed");
4810
4811         addrs[1].size = sizeof(struct sockaddr_in);
4812         addrs[1].buffer = talloc_zero_array(tctx, uint8_t, addrs[1].size);
4813         addr = (struct sockaddr_in *) addrs[1].buffer;
4814         addrs[1].buffer[0] = AF_INET;
4815         ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
4816         torture_assert(tctx, ret > 0, "inet_pton failed");
4817
4818         addrs[2].size = sizeof(struct sockaddr_in);
4819         addrs[2].buffer = talloc_zero_array(tctx, uint8_t, addrs[2].size);
4820         addr = (struct sockaddr_in *) addrs[2].buffer;
4821         addrs[2].buffer[0] = AF_INET;
4822         ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
4823         torture_assert(tctx, ret > 0, "inet_pton failed");
4824
4825 #ifdef HAVE_IPV6
4826         addrs[3].size = sizeof(struct sockaddr_in6);
4827         addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
4828         addr6 = (struct sockaddr_in6 *) addrs[3].buffer;
4829         addrs[3].buffer[0] = AF_INET6;
4830         ret = inet_pton(AF_INET6, "::1", &addr6->sin6_addr);
4831         torture_assert(tctx, ret > 0, "inet_pton failed");
4832
4833         addrs[4].size = sizeof(struct sockaddr_in6);
4834         addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
4835         addr6 = (struct sockaddr_in6 *) addrs[4].buffer;
4836         addrs[4].buffer[0] = AF_INET6;
4837         ret = inet_pton(AF_INET6, "::", &addr6->sin6_addr);
4838         torture_assert(tctx, ret > 0, "inet_pton failed");
4839
4840         addrs[5].size = sizeof(struct sockaddr_in6);
4841         addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
4842         addr6 = (struct sockaddr_in6 *) addrs[5].buffer;
4843         addrs[5].buffer[0] = AF_INET6;
4844         ret = inet_pton(AF_INET6, "ff02::1", &addr6->sin6_addr);
4845         torture_assert(tctx, ret > 0, "inet_pton failed");
4846 #else
4847         /* the test cases are repeated to have exactly 6. This is for
4848          * compatibility with IPv4-only machines */
4849         addrs[3].size = sizeof(struct sockaddr_in);
4850         addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
4851         addr = (struct sockaddr_in *) addrs[3].buffer;
4852         addrs[3].buffer[0] = AF_INET;
4853         ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
4854         torture_assert(tctx, ret > 0, "inet_pton failed");
4855
4856         addrs[4].size = sizeof(struct sockaddr_in);
4857         addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
4858         addr = (struct sockaddr_in *) addrs[4].buffer;
4859         addrs[4].buffer[0] = AF_INET;
4860         ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
4861         torture_assert(tctx, ret > 0, "inet_pton failed");
4862
4863         addrs[5].size = sizeof(struct sockaddr_in);
4864         addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
4865         addr = (struct sockaddr_in *) addrs[5].buffer;
4866         addrs[5].buffer[0] = AF_INET;
4867         ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
4868         torture_assert(tctx, ret > 0, "inet_pton failed");
4869 #endif
4870
4871         ctr = talloc(tctx, struct netr_DsRAddressToSitenamesExWCtr);
4872
4873         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
4874         r.in.count = 6;
4875         r.in.addresses = addrs;
4876         r.out.ctr = &ctr;
4877
4878         status = dcerpc_netr_DsRAddressToSitenamesExW_r(b, tctx, &r);
4879         torture_assert_ntstatus_ok(tctx, status, "failed");
4880         torture_assert_werr_ok(tctx, r.out.result, "failed");
4881
4882         if (sam_ctx != NULL) {
4883                 for (i = 0; i < 3; i++) {
4884                         torture_assert_casestr_equal(tctx,
4885                                                      ctr->sitename[i].string,
4886                                                      server_site_name(tctx, sam_ctx),
4887                                                      "didn't return default site");
4888                         torture_assert(tctx, ctr->subnetname[i].string == NULL,
4889                                        "subnet should be null");
4890                 }
4891                 for (i = 3; i < 6; i++) {
4892                         /* Windows returns "NULL" for the sitename if it isn't
4893                          * IPv6 configured */
4894                         if (torture_setting_bool(tctx, "samba4", false)) {
4895                                 torture_assert_casestr_equal(tctx,
4896                                                              ctr->sitename[i].string,
4897                                                              server_site_name(tctx, sam_ctx),
4898                                                              "didn't return default site");
4899                         }
4900                         torture_assert(tctx, ctr->subnetname[i].string == NULL,
4901                                        "subnet should be null");
4902                 }
4903         }
4904
4905         /* Now try invalid ones (too short buffers) */
4906
4907         addrs[0].size = 0;
4908         addrs[1].size = 1;
4909         addrs[2].size = 4;
4910
4911         addrs[3].size = 0;
4912         addrs[4].size = 1;
4913         addrs[5].size = 4;
4914
4915         status = dcerpc_netr_DsRAddressToSitenamesExW_r(b, tctx, &r);
4916         torture_assert_ntstatus_ok(tctx, status, "failed");
4917         torture_assert_werr_ok(tctx, r.out.result, "failed");
4918
4919         for (i = 0; i < 6; i++) {
4920                 torture_assert(tctx, ctr->sitename[i].string == NULL,
4921                                "sitename should be null");
4922                 torture_assert(tctx, ctr->subnetname[i].string == NULL,
4923                                "subnet should be null");
4924         }
4925
4926         addrs[0].size = 10;
4927         addrs[0].buffer[0] = AF_UNSPEC;
4928         addrs[1].size = 10;
4929         addrs[1].buffer[0] = AF_UNIX; /* AF_LOCAL = AF_UNIX */
4930         addrs[2].size = 10;
4931         addrs[2].buffer[0] = AF_UNIX;
4932
4933         addrs[3].size = 10;
4934         addrs[3].buffer[0] = 250;
4935         addrs[4].size = 10;
4936         addrs[4].buffer[0] = 251;
4937         addrs[5].size = 10;
4938         addrs[5].buffer[0] = 252;
4939
4940         status = dcerpc_netr_DsRAddressToSitenamesExW_r(b, tctx, &r);
4941         torture_assert_ntstatus_ok(tctx, status, "failed");
4942         torture_assert_werr_ok(tctx, r.out.result, "failed");
4943
4944         for (i = 0; i < 6; i++) {
4945                 torture_assert(tctx, ctr->sitename[i].string == NULL,
4946                                "sitename should be null");
4947                 torture_assert(tctx, ctr->subnetname[i].string == NULL,
4948                                "subnet should be null");
4949         }
4950
4951         return true;
4952 }
4953
4954 static bool test_netr_ServerGetTrustInfo_flags(struct torture_context *tctx,
4955                                                struct dcerpc_pipe *p1,
4956                                                struct cli_credentials *machine_credentials,
4957                                                uint32_t negotiate_flags)
4958 {
4959         struct netr_ServerGetTrustInfo r;
4960
4961         struct netr_Authenticator a;
4962         struct netr_Authenticator return_authenticator;
4963         struct samr_Password new_owf_password;
4964         struct samr_Password old_owf_password;
4965         struct netr_TrustInfo *trust_info;
4966
4967         struct netlogon_creds_CredentialState *creds;
4968         struct dcerpc_pipe *p = NULL;
4969         struct dcerpc_binding_handle *b = NULL;
4970
4971         struct samr_Password nt_hash;
4972
4973         if (!test_SetupCredentials3(p1, tctx, negotiate_flags,
4974                                     machine_credentials, &creds)) {
4975                 return false;
4976         }
4977         if (!test_SetupCredentialsPipe(p1, tctx, machine_credentials, creds,
4978                                        DCERPC_SIGN | DCERPC_SEAL, &p)) {
4979                 return false;
4980         }
4981         b = p->binding_handle;
4982
4983         netlogon_creds_client_authenticator(creds, &a);
4984
4985         r.in.server_name                = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
4986         r.in.account_name               = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
4987         r.in.secure_channel_type        = cli_credentials_get_secure_channel_type(machine_credentials);
4988         r.in.computer_name              = TEST_MACHINE_NAME;
4989         r.in.credential                 = &a;
4990
4991         r.out.return_authenticator      = &return_authenticator;
4992         r.out.new_owf_password          = &new_owf_password;
4993         r.out.old_owf_password          = &old_owf_password;
4994         r.out.trust_info                = &trust_info;
4995
4996         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerGetTrustInfo_r(b, tctx, &r),
4997                 "ServerGetTrustInfo failed");
4998         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerGetTrustInfo failed");
4999         torture_assert(tctx, netlogon_creds_client_check(creds, &return_authenticator.cred), "Credential chaining failed");
5000
5001         E_md4hash(cli_credentials_get_password(machine_credentials), nt_hash.hash);
5002
5003         netlogon_creds_des_decrypt(creds, &new_owf_password);
5004
5005         dump_data(1, new_owf_password.hash, 16);
5006         dump_data(1, nt_hash.hash, 16);
5007
5008         torture_assert_mem_equal(tctx, new_owf_password.hash, nt_hash.hash, 16,
5009                 "received unexpected owf password\n");
5010
5011         return true;
5012 }
5013
5014 static bool test_netr_ServerGetTrustInfo(struct torture_context *tctx,
5015                                          struct dcerpc_pipe *p,
5016                                          struct cli_credentials *machine_credentials)
5017 {
5018         return test_netr_ServerGetTrustInfo_flags(tctx, p, machine_credentials,
5019                                                   NETLOGON_NEG_AUTH2_ADS_FLAGS);
5020 }
5021
5022 static bool test_netr_ServerGetTrustInfo_AES(struct torture_context *tctx,
5023                                              struct dcerpc_pipe *p,
5024                                              struct cli_credentials *machine_credentials)
5025 {
5026         return test_netr_ServerGetTrustInfo_flags(tctx, p, machine_credentials,
5027                                                   NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES);
5028 }
5029
5030 static bool test_GetDomainInfo(struct torture_context *tctx,
5031                                struct dcerpc_pipe *p1,
5032                                struct cli_credentials *machine_credentials)
5033 {
5034         struct netr_LogonGetDomainInfo r;
5035         struct netr_WorkstationInformation q1;
5036         struct netr_Authenticator a;
5037         struct netlogon_creds_CredentialState *creds;
5038         struct netr_OsVersion os;
5039         union netr_WorkstationInfo query;
5040         union netr_DomainInfo info;
5041         const char* const attrs[] = { "dNSHostName", "operatingSystem",
5042                 "operatingSystemServicePack", "operatingSystemVersion",
5043                 "servicePrincipalName", NULL };
5044         char *url;
5045         struct ldb_context *sam_ctx = NULL;
5046         struct ldb_message **res;
5047         struct ldb_message_element *spn_el;
5048         int ret, i;
5049         char *version_str;
5050         const char *old_dnsname = NULL;
5051         char **spns = NULL;
5052         int num_spns = 0;
5053         char *temp_str = NULL;
5054         char *temp_str2 = NULL;
5055         struct dcerpc_pipe *p = NULL;
5056         struct dcerpc_binding_handle *b = NULL;
5057         struct netr_OneDomainInfo *odi1 = NULL;
5058         struct netr_OneDomainInfo *odi2 = NULL;
5059         struct netr_trust_extension_info *tex2 = NULL;
5060
5061         torture_comment(tctx, "Testing netr_LogonGetDomainInfo\n");
5062
5063         if (!test_SetupCredentials3(p1, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES,
5064                                     machine_credentials, &creds)) {
5065                 return false;
5066         }
5067         if (!test_SetupCredentialsPipe(p1, tctx, machine_credentials, creds,
5068                                        DCERPC_SIGN | DCERPC_SEAL, &p)) {
5069                 return false;
5070         }
5071         b = p->binding_handle;
5072
5073         /* We won't double-check this when we are over 'local' transports */
5074         if (dcerpc_server_name(p)) {
5075                 /* Set up connection to SAMDB on DC */
5076                 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
5077                 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
5078                                            NULL,
5079                                            samba_cmdline_get_creds(),
5080                                            0);
5081
5082                 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
5083         }
5084
5085         torture_comment(tctx, "Testing netr_LogonGetDomainInfo 1st call (no variation of DNS hostname)\n");
5086         netlogon_creds_client_authenticator(creds, &a);
5087
5088         ZERO_STRUCT(r);
5089         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
5090         r.in.computer_name = TEST_MACHINE_NAME;
5091         r.in.credential = &a;
5092         r.in.level = 1;
5093         r.in.return_authenticator = &a;
5094         r.in.query = &query;
5095         r.out.return_authenticator = &a;
5096         r.out.info = &info;
5097
5098         ZERO_STRUCT(os);
5099         os.os.MajorVersion = 123;
5100         os.os.MinorVersion = 456;
5101         os.os.BuildNumber = 789;
5102         os.os.CSDVersion = "Service Pack 10";
5103         os.os.ServicePackMajor = 10;
5104         os.os.ServicePackMinor = 1;
5105         os.os.SuiteMask = NETR_VER_SUITE_SINGLEUSERTS;
5106         os.os.ProductType = NETR_VER_NT_SERVER;
5107         os.os.Reserved = 0;
5108
5109         version_str = talloc_asprintf(tctx, "%d.%d (%d)", os.os.MajorVersion,
5110                 os.os.MinorVersion, os.os.BuildNumber);
5111
5112         ZERO_STRUCT(q1);
5113         q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
5114                 lpcfg_dnsdomain(tctx->lp_ctx));
5115         q1.sitename = "Default-First-Site-Name";
5116         q1.os_version.os = &os;
5117         q1.os_name.string = talloc_asprintf(tctx,
5118                                             "Tortured by Samba4 RPC-NETLOGON: %s",
5119                                             timestring(tctx, time(NULL)));
5120
5121         /* The workstation handles the "servicePrincipalName" and DNS hostname
5122            updates */
5123         q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
5124
5125         query.workstation_info = &q1;
5126
5127         if (sam_ctx) {
5128                 /* Gets back the old DNS hostname in AD */
5129                 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
5130                                    "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
5131                 old_dnsname =
5132                         ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL);
5133
5134                 /* Gets back the "servicePrincipalName"s in AD */
5135                 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
5136                 if (spn_el != NULL) {
5137                         for (i=0; i < spn_el->num_values; i++) {
5138                                 spns = talloc_realloc(tctx, spns, char *, i + 1);
5139                                 spns[i] = (char *) spn_el->values[i].data;
5140                         }
5141                         num_spns = i;
5142                 }
5143         }
5144
5145         torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
5146                 "LogonGetDomainInfo failed");
5147         torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
5148         torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
5149
5150         smb_msleep(250);
5151
5152         if (sam_ctx) {
5153                 /* AD workstation infos entry check */
5154                 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
5155                                    "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
5156                 torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
5157                 torture_assert_str_equal(tctx,
5158                                          ldb_msg_find_attr_as_string(res[0], "operatingSystem", NULL),
5159                                          q1.os_name.string, "'operatingSystem' wrong!");
5160                 torture_assert_str_equal(tctx,
5161                                          ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL),
5162                                          os.os.CSDVersion, "'operatingSystemServicePack' wrong!");
5163                 torture_assert_str_equal(tctx,
5164                                          ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL),
5165                                          version_str, "'operatingSystemVersion' wrong!");
5166
5167                 if (old_dnsname != NULL) {
5168                         /* If before a DNS hostname was set then it should remain
5169                            the same in combination with the "servicePrincipalName"s.
5170                            The DNS hostname should also be returned by our
5171                            "LogonGetDomainInfo" call (in the domain info structure). */
5172
5173                         torture_assert_str_equal(tctx,
5174                                                  ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL),
5175                                                  old_dnsname, "'DNS hostname' was not set!");
5176
5177                         spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
5178                         torture_assert(tctx, ((spns != NULL) && (spn_el != NULL)),
5179                                        "'servicePrincipalName's not set!");
5180                         torture_assert(tctx, spn_el->num_values == num_spns,
5181                                        "'servicePrincipalName's incorrect!");
5182                         for (i=0; (i < spn_el->num_values) && (i < num_spns); i++)
5183                                 torture_assert_str_equal(tctx,
5184                                                          (char *) spn_el->values[i].data,
5185                                 spns[i], "'servicePrincipalName's incorrect!");
5186
5187                         torture_assert_str_equal(tctx,
5188                                                  info.domain_info->dns_hostname.string,
5189                                                  old_dnsname,
5190                                                  "Out 'DNS hostname' doesn't match the old one!");
5191                 } else {
5192                         /* If no DNS hostname was set then also now none should be set,
5193                            the "servicePrincipalName"s should remain empty and no DNS
5194                            hostname should be returned by our "LogonGetDomainInfo"
5195                            call (in the domain info structure). */
5196
5197                         torture_assert(tctx,
5198                                        ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL) == NULL,
5199                                        "'DNS hostname' was set!");
5200
5201                         spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
5202                         torture_assert(tctx, ((spns == NULL) && (spn_el == NULL)),
5203                                        "'servicePrincipalName's were set!");
5204
5205                         torture_assert(tctx,
5206                                        info.domain_info->dns_hostname.string == NULL,
5207                                        "Out 'DNS host name' was set!");
5208                 }
5209         }
5210
5211         /* Checks "workstation flags" */
5212         torture_assert(tctx,
5213                 info.domain_info->workstation_flags
5214                 == NETR_WS_FLAG_HANDLES_SPN_UPDATE,
5215                 "Out 'workstation flags' don't match!");
5216
5217
5218         torture_comment(tctx, "Testing netr_LogonGetDomainInfo 2nd call (variation of DNS hostname doesn't work)\n");
5219         netlogon_creds_client_authenticator(creds, &a);
5220
5221         /* Wipe out the CSDVersion, and prove which values still 'stick' */
5222         os.os.CSDVersion = "";
5223
5224         /* Change also the DNS hostname to test differences in behaviour */
5225         talloc_free(discard_const_p(char, q1.dns_hostname));
5226         q1.dns_hostname = talloc_asprintf(tctx, "%s2.%s", TEST_MACHINE_NAME,
5227                 lpcfg_dnsdomain(tctx->lp_ctx));
5228
5229         /* The workstation handles the "servicePrincipalName" and DNS hostname
5230            updates */
5231         q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
5232
5233         torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
5234                 "LogonGetDomainInfo failed");
5235         torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
5236
5237         torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
5238
5239         smb_msleep(250);
5240
5241         if (sam_ctx) {
5242                 /* AD workstation infos entry check */
5243                 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
5244                                    "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
5245                 torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
5246
5247                 torture_assert_str_equal(tctx,
5248                                          ldb_msg_find_attr_as_string(res[0], "operatingSystem", NULL),
5249                                          q1.os_name.string, "'operatingSystem' should stick!");
5250                 torture_assert(tctx,
5251                                ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL) == NULL,
5252                                "'operatingSystemServicePack' shouldn't stick!");
5253                 torture_assert_str_equal(tctx,
5254                                          ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL),
5255                                          version_str, "'operatingSystemVersion' wrong!");
5256
5257                 /* The DNS host name shouldn't have been updated by the server */
5258
5259                 torture_assert_str_equal(tctx,
5260                                          ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL),
5261                                          old_dnsname, "'DNS host name' did change!");
5262
5263                 /* Find the two "servicePrincipalName"s which the DC shouldn't have been
5264                    updated (HOST/<Netbios name> and HOST/<FQDN name>) - see MS-NRPC
5265                    3.5.4.3.9 */
5266                 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
5267                 torture_assert(tctx, spn_el != NULL,
5268                                "There should exist 'servicePrincipalName's in AD!");
5269                 temp_str = talloc_asprintf(tctx, "HOST/%s", TEST_MACHINE_NAME);
5270                 for (i=0; i < spn_el->num_values; i++)
5271                         if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
5272                                 break;
5273                 torture_assert(tctx, i != spn_el->num_values,
5274                                "'servicePrincipalName' HOST/<Netbios name> not found!");
5275                 temp_str = talloc_asprintf(tctx, "HOST/%s", old_dnsname);
5276                 for (i=0; i < spn_el->num_values; i++)
5277                         if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
5278                                 break;
5279                 torture_assert(tctx, i != spn_el->num_values,
5280                                "'servicePrincipalName' HOST/<FQDN name> not found!");
5281
5282                 /* Check that the out DNS hostname was set properly */
5283                 torture_assert_str_equal(tctx, info.domain_info->dns_hostname.string,
5284                                          old_dnsname, "Out 'DNS hostname' doesn't match the old one!");
5285         }
5286
5287         /* Checks "workstation flags" */
5288         torture_assert(tctx,
5289                 info.domain_info->workstation_flags == NETR_WS_FLAG_HANDLES_SPN_UPDATE,
5290                 "Out 'workstation flags' don't match!");
5291
5292
5293         /* Now try the same but the workstation flags set to 0 */
5294
5295         torture_comment(tctx, "Testing netr_LogonGetDomainInfo 3rd call (variation of DNS hostname doesn't work)\n");
5296         netlogon_creds_client_authenticator(creds, &a);
5297
5298         /* Change also the DNS hostname to test differences in behaviour */
5299         talloc_free(discard_const_p(char, q1.dns_hostname));
5300         q1.dns_hostname = talloc_asprintf(tctx, "%s2.%s", TEST_MACHINE_NAME,
5301                 lpcfg_dnsdomain(tctx->lp_ctx));
5302
5303         /* Wipe out the osVersion, and prove which values still 'stick' */
5304         q1.os_version.os = NULL;
5305
5306         /* Let the DC handle the "servicePrincipalName" and DNS hostname
5307            updates */
5308         q1.workstation_flags = 0;
5309
5310         torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
5311                 "LogonGetDomainInfo failed");
5312         torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
5313         torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
5314
5315         smb_msleep(250);
5316
5317         if (sam_ctx) {
5318                 /* AD workstation infos entry check */
5319                 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
5320                                    "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
5321                 torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
5322
5323                 torture_assert_str_equal(tctx,
5324                                          ldb_msg_find_attr_as_string(res[0], "operatingSystem", NULL),
5325                                          q1.os_name.string, "'operatingSystem' should stick!");
5326                 torture_assert(tctx,
5327                                ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL) == NULL,
5328                                "'operatingSystemServicePack' shouldn't stick!");
5329                 torture_assert_str_equal(tctx,
5330                                          ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL),
5331                                          version_str, "'operatingSystemVersion' wrong!");
5332
5333                 /* The DNS host name shouldn't have been updated by the server */
5334
5335                 torture_assert_str_equal(tctx,
5336                                          ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL),
5337                                          old_dnsname, "'DNS host name' did change!");
5338
5339                 /* Find the two "servicePrincipalName"s which the DC shouldn't have been
5340                    updated (HOST/<Netbios name> and HOST/<FQDN name>) - see MS-NRPC
5341                    3.5.4.3.9 */
5342                 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
5343                 torture_assert(tctx, spn_el != NULL,
5344                                "There should exist 'servicePrincipalName's in AD!");
5345                 temp_str = talloc_asprintf(tctx, "HOST/%s", TEST_MACHINE_NAME);
5346                 for (i=0; i < spn_el->num_values; i++)
5347                         if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
5348                                 break;
5349                 torture_assert(tctx, i != spn_el->num_values,
5350                                "'servicePrincipalName' HOST/<Netbios name> not found!");
5351                 temp_str = talloc_asprintf(tctx, "HOST/%s", old_dnsname);
5352                 for (i=0; i < spn_el->num_values; i++)
5353                         if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
5354                                 break;
5355                 torture_assert(tctx, i != spn_el->num_values,
5356                                "'servicePrincipalName' HOST/<FQDN name> not found!");
5357
5358                 /* Here the server gives us NULL as the out DNS hostname */
5359                 torture_assert(tctx, info.domain_info->dns_hostname.string == NULL,
5360                                "Out 'DNS hostname' should be NULL!");
5361         }
5362
5363         /* Checks "workstation flags" */
5364         torture_assert(tctx,
5365                 info.domain_info->workstation_flags == 0,
5366                 "Out 'workstation flags' don't match!");
5367
5368
5369         torture_comment(tctx, "Testing netr_LogonGetDomainInfo 4th call (verification of DNS hostname and check for trusted domains)\n");
5370         netlogon_creds_client_authenticator(creds, &a);
5371
5372         /* Put the DNS hostname back */
5373         talloc_free(discard_const_p(char, q1.dns_hostname));
5374         q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
5375                 lpcfg_dnsdomain(tctx->lp_ctx));
5376
5377         /* The workstation handles the "servicePrincipalName" and DNS hostname
5378            updates */
5379         q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
5380
5381         torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
5382                 "LogonGetDomainInfo failed");
5383         torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
5384         torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
5385
5386         smb_msleep(250);
5387
5388         /* Now the in/out DNS hostnames should be the same */
5389         torture_assert_str_equal(tctx,
5390                 info.domain_info->dns_hostname.string,
5391                 query.workstation_info->dns_hostname,
5392                 "In/Out 'DNS hostnames' don't match!");
5393         old_dnsname = info.domain_info->dns_hostname.string;
5394
5395         /* Checks "workstation flags" */
5396         torture_assert(tctx,
5397                 info.domain_info->workstation_flags
5398                 == NETR_WS_FLAG_HANDLES_SPN_UPDATE,
5399                 "Out 'workstation flags' don't match!");
5400
5401         /* Checks for trusted domains */
5402         torture_assert(tctx,
5403                 (info.domain_info->trusted_domain_count != 0)
5404                 && (info.domain_info->trusted_domains != NULL),
5405                 "Trusted domains have been requested!");
5406
5407
5408         torture_comment(tctx, "Testing netr_LogonGetDomainInfo 5th call (check for trusted domains)\n");
5409         netlogon_creds_client_authenticator(creds, &a);
5410
5411         /* The workstation handles the "servicePrincipalName" and DNS hostname
5412            updates and requests inbound trusts */
5413         q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE
5414                 | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS;
5415
5416         torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
5417                 "LogonGetDomainInfo failed");
5418         torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
5419         torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
5420
5421         smb_msleep(250);
5422
5423         /* Checks "workstation flags" */
5424         torture_assert(tctx,
5425                 info.domain_info->workstation_flags
5426                 == (NETR_WS_FLAG_HANDLES_SPN_UPDATE
5427                         | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS),
5428                 "Out 'workstation flags' don't match!");
5429
5430         /* Checks for trusted domains */
5431         torture_assert(tctx,
5432                 (info.domain_info->trusted_domain_count != 0)
5433                 && (info.domain_info->trusted_domains != NULL),
5434                 "Trusted domains have been requested!");
5435
5436         odi1 = &info.domain_info->primary_domain;
5437
5438         torture_assert(tctx, !GUID_all_zero(&odi1->domain_guid),
5439                        "primary domain_guid needs to be valid");
5440
5441         for (i=0; i < info.domain_info->trusted_domain_count; i++) {
5442                 struct netr_OneDomainInfo *odiT =
5443                         &info.domain_info->trusted_domains[i];
5444                 struct netr_trust_extension_info *texT = NULL;
5445
5446                 torture_assert_int_equal(tctx, odiT->trust_extension.length, 16,
5447                                          "trust_list should have extension");
5448                 torture_assert(tctx, odiT->trust_extension.info != NULL,
5449                                "trust_list should have extension");
5450                 texT = &odiT->trust_extension.info->info;
5451
5452                 if (GUID_equal(&odiT->domain_guid, &odi1->domain_guid)) {
5453                         odi2 = odiT;
5454                         tex2 = texT;
5455                         continue;
5456                 }
5457
5458                 torture_assert_int_equal(tctx,
5459                                  texT->flags & NETR_TRUST_FLAG_PRIMARY,
5460                                  0,
5461                                  "trust_list flags should not have PRIMARY");
5462
5463                 torture_assert(tctx, odiT->domainname.string != NULL,
5464                                "trust_list domainname should be valid");
5465                 if (texT->trust_type == LSA_TRUST_TYPE_DOWNLEVEL ||
5466                     texT->trust_type == LSA_TRUST_TYPE_MIT)
5467                 {
5468                         torture_assert(tctx, odiT->dns_domainname.string == NULL,
5469                                "trust_list dns_domainname should be NULL for downlevel or MIT");
5470                 } else {
5471                         torture_assert(tctx, odiT->dns_domainname.string != NULL,
5472                                "trust_list dns_domainname should be valid for uplevel");
5473                 }
5474                 torture_assert(tctx, odiT->dns_forestname.string == NULL,
5475                                "trust_list dns_forestname needs to be NULL");
5476
5477                 torture_assert(tctx, odiT->domain_sid != NULL,
5478                                "trust_list domain_sid needs to be valid");
5479         }
5480
5481         torture_assert(tctx, odi2 != NULL,
5482                        "trust_list primary domain not found.");
5483
5484         torture_assert_str_equal(tctx,
5485                                  odi1->domainname.string,
5486                                  odi2->domainname.string,
5487                                  "netbios name should match");
5488
5489         temp_str = talloc_strdup(tctx, odi1->dns_domainname.string);
5490         torture_assert(tctx, temp_str != NULL,
5491                        "primary_domain dns_domainname copy");
5492         temp_str2 = strrchr(temp_str, '.');
5493         torture_assert(tctx, temp_str2 != NULL && temp_str2[1] == '\0',
5494                        "primary_domain dns_domainname needs trailing '.'");
5495         temp_str2[0] = '\0';
5496         torture_assert_str_equal(tctx,
5497                                  temp_str,
5498                                  odi2->dns_domainname.string,
5499                                  "dns domainname should match "
5500                                  "(without trailing '.')");
5501
5502         temp_str = talloc_strdup(tctx, odi1->dns_forestname.string);
5503         torture_assert(tctx, temp_str != NULL,
5504                        "primary_domain dns_forestname copy");
5505         temp_str2 = strrchr(temp_str, '.');
5506         torture_assert(tctx, temp_str2 != NULL && temp_str2[1] == '\0',
5507                        "primary_domain dns_forestname needs trailing '.'");
5508         temp_str2[0] = '\0';
5509         torture_assert(tctx, odi2->dns_forestname.string == NULL,
5510                        "trust_list dns_forestname needs to be NULL");
5511
5512         torture_assert_guid_equal(tctx, odi1->domain_guid, odi2->domain_guid,
5513                                   "domain_guid should match");
5514         torture_assert(tctx, odi1->domain_sid != NULL,
5515                        "primary domain_sid needs to be valid");
5516         torture_assert(tctx, odi2->domain_sid != NULL,
5517                        "trust_list domain_sid needs to be valid");
5518         torture_assert_sid_equal(tctx, odi1->domain_sid, odi2->domain_sid,
5519                                  "domain_sid should match");
5520
5521         torture_assert_int_equal(tctx, odi1->trust_extension.length, 0,
5522                                  "primary_domain should not have extension");
5523         torture_assert_int_equal(tctx, odi2->trust_extension.length, 16,
5524                                  "trust_list should have extension");
5525         torture_assert(tctx, odi2->trust_extension.info != NULL,
5526                        "trust_list should have extension");
5527         tex2 = &odi2->trust_extension.info->info;
5528         torture_assert_int_equal(tctx,
5529                                  tex2->flags & NETR_TRUST_FLAG_PRIMARY,
5530                                  NETR_TRUST_FLAG_PRIMARY,
5531                                  "trust_list flags should have PRIMARY");
5532         torture_assert_int_equal(tctx,
5533                                  tex2->flags & NETR_TRUST_FLAG_IN_FOREST,
5534                                  NETR_TRUST_FLAG_IN_FOREST,
5535                                  "trust_list flags should have IN_FOREST");
5536         torture_assert_int_equal(tctx,
5537                                  tex2->flags & NETR_TRUST_FLAG_NATIVE,
5538                                  NETR_TRUST_FLAG_NATIVE,
5539                                  "trust_list flags should have NATIVE");
5540         torture_assert_int_equal(tctx,
5541                                  tex2->flags & ~NETR_TRUST_FLAG_TREEROOT,
5542                                  NETR_TRUST_FLAG_IN_FOREST |
5543                                  NETR_TRUST_FLAG_PRIMARY |
5544                                  NETR_TRUST_FLAG_NATIVE,
5545                                  "trust_list flags IN_FOREST, PRIMARY, NATIVE "
5546                                  "(TREEROOT optional)");
5547         if (strcmp(odi1->dns_domainname.string, odi1->dns_forestname.string) == 0) {
5548                 torture_assert_int_equal(tctx,
5549                                          tex2->flags & NETR_TRUST_FLAG_TREEROOT,
5550                                          NETR_TRUST_FLAG_TREEROOT,
5551                                          "trust_list flags TREEROOT on forest root");
5552                 torture_assert_int_equal(tctx,
5553                                          tex2->parent_index, 0,
5554                                          "trust_list no parent on foreset root");
5555         }
5556         torture_assert_int_equal(tctx,
5557                                  tex2->trust_type, LSA_TRUST_TYPE_UPLEVEL,
5558                                  "trust_list uplevel");
5559         torture_assert_int_equal(tctx,
5560                                  tex2->trust_attributes, 0,
5561                                  "trust_list no attributes");
5562
5563         torture_comment(tctx, "Testing netr_LogonGetDomainInfo 6th call (no DNS hostname)\n");
5564         netlogon_creds_client_authenticator(creds, &a);
5565
5566         query.workstation_info->dns_hostname = NULL;
5567
5568         torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
5569                 "LogonGetDomainInfo failed");
5570         torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
5571         torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
5572
5573         /* The old DNS hostname should stick */
5574         torture_assert_str_equal(tctx,
5575                 info.domain_info->dns_hostname.string,
5576                 old_dnsname,
5577                 "'DNS hostname' changed!");
5578
5579         torture_comment(tctx, "Testing netr_LogonGetDomainInfo 7th call (extra workstation flags)\n");
5580         netlogon_creds_client_authenticator(creds, &a);
5581
5582         q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE
5583                 | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS | 0x4;
5584
5585         /* Put the DNS hostname back */
5586         talloc_free(discard_const_p(char, q1.dns_hostname));
5587         q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
5588                 lpcfg_dnsdomain(tctx->lp_ctx));
5589
5590         torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
5591                 "LogonGetDomainInfo failed");
5592         torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
5593         torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
5594
5595         /* Checks "workstation flags" */
5596         torture_assert(tctx,
5597                 info.domain_info->workstation_flags
5598                 == (NETR_WS_FLAG_HANDLES_SPN_UPDATE
5599                         | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS),
5600                 "Out 'workstation flags' don't match!");
5601
5602         if (!torture_setting_bool(tctx, "dangerous", false)) {
5603                 torture_comment(tctx, "Not testing netr_LogonGetDomainInfo 8th call (no workstation info) - enable dangerous tests in order to do so\n");
5604         } else {
5605                 /* Try a call without the workstation information structure */
5606
5607                 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 8th call (no workstation info)\n");
5608                 netlogon_creds_client_authenticator(creds, &a);
5609
5610                 query.workstation_info = NULL;
5611
5612                 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
5613                         "LogonGetDomainInfo failed");
5614                 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
5615                 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
5616         }
5617
5618         return true;
5619 }
5620
5621 static bool test_GetDomainInfo_async(struct torture_context *tctx,
5622                                      struct dcerpc_pipe *p1,
5623                                      struct cli_credentials *machine_credentials)
5624 {
5625         NTSTATUS status;
5626         struct netr_LogonGetDomainInfo r;
5627         struct netr_WorkstationInformation q1;
5628         struct netr_Authenticator a;
5629 #define ASYNC_COUNT 100
5630         struct netlogon_creds_CredentialState *creds;
5631         struct netlogon_creds_CredentialState *creds_async[ASYNC_COUNT];
5632         struct tevent_req *req[ASYNC_COUNT];
5633         int i;
5634         union netr_WorkstationInfo query;
5635         union netr_DomainInfo info;
5636         struct dcerpc_pipe *p = NULL;
5637
5638         torture_comment(tctx, "Testing netr_LogonGetDomainInfo - async count %d\n", ASYNC_COUNT);
5639
5640         if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES,
5641                                     machine_credentials, &creds)) {
5642                 return false;
5643         }
5644         if (!test_SetupCredentialsPipe(p1, tctx, machine_credentials, creds,
5645                                        DCERPC_SIGN | DCERPC_SEAL, &p)) {
5646                 return false;
5647         }
5648
5649         ZERO_STRUCT(r);
5650         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
5651         r.in.computer_name = TEST_MACHINE_NAME;
5652         r.in.credential = &a;
5653         r.in.level = 1;
5654         r.in.return_authenticator = &a;
5655         r.in.query = &query;
5656         r.out.return_authenticator = &a;
5657         r.out.info = &info;
5658
5659         ZERO_STRUCT(q1);
5660         q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
5661                 lpcfg_dnsdomain(tctx->lp_ctx));
5662         q1.sitename = "Default-First-Site-Name";
5663         q1.os_name.string = "UNIX/Linux or similar";
5664
5665         query.workstation_info = &q1;
5666
5667         for (i=0;i<ASYNC_COUNT;i++) {
5668                 netlogon_creds_client_authenticator(creds, &a);
5669
5670                 creds_async[i] = (struct netlogon_creds_CredentialState *)talloc_memdup(creds, creds, sizeof(*creds));
5671                 req[i] = dcerpc_netr_LogonGetDomainInfo_r_send(tctx, tctx->ev, p->binding_handle, &r);
5672
5673                 /* even with this flush per request a w2k3 server seems to
5674                    clag with multiple outstanding requests. bleergh. */
5675                 torture_assert_int_equal(tctx, tevent_loop_once(tctx->ev), 0,
5676                                          "tevent_loop_once failed");
5677         }
5678
5679         for (i=0;i<ASYNC_COUNT;i++) {
5680                 torture_assert_int_equal(tctx, tevent_req_poll(req[i], tctx->ev), true,
5681                                          "tevent_req_poll() failed");
5682
5683                 status = dcerpc_netr_LogonGetDomainInfo_r_recv(req[i], tctx);
5684
5685                 torture_assert_ntstatus_ok(tctx, status, "netr_LogonGetDomainInfo_async");
5686                 torture_assert_ntstatus_ok(tctx, r.out.result, "netr_LogonGetDomainInfo_async");
5687
5688                 torture_assert(tctx, netlogon_creds_client_check(creds_async[i], &a.cred),
5689                         "Credential chaining failed at async");
5690         }
5691
5692         torture_comment(tctx,
5693                         "Testing netr_LogonGetDomainInfo - async count %d OK\n", ASYNC_COUNT);
5694
5695         return true;
5696 }
5697
5698 static bool test_ManyGetDCName(struct torture_context *tctx,
5699                                struct dcerpc_pipe *p)
5700 {
5701         NTSTATUS status;
5702         struct cli_credentials *anon_creds;
5703         struct dcerpc_binding *binding2;
5704         struct dcerpc_pipe *p2;
5705         struct lsa_ObjectAttribute attr;
5706         struct lsa_QosInfo qos;
5707         struct lsa_OpenPolicy2 o;
5708         struct policy_handle lsa_handle;
5709         struct lsa_DomainList domains;
5710
5711         struct lsa_EnumTrustDom t;
5712         uint32_t resume_handle = 0;
5713         struct netr_GetAnyDCName d;
5714         const char *dcname = NULL;
5715         struct dcerpc_binding_handle *b = p->binding_handle;
5716         struct dcerpc_binding_handle *b2;
5717
5718         int i;
5719
5720         if (p->conn->transport.transport != NCACN_NP) {
5721                 torture_skip(tctx, "test_ManyGetDCName works only with NCACN_NP");
5722         }
5723
5724         torture_comment(tctx, "Torturing GetDCName\n");
5725
5726         anon_creds = cli_credentials_init_anon(tctx);
5727         torture_assert(tctx, anon_creds != NULL, "cli_credentials_init_anon failed");
5728
5729         binding2 = dcerpc_binding_dup(tctx, p->binding);
5730         /* Swap the binding details from NETLOGON to LSA */
5731         status = dcerpc_epm_map_binding(tctx, binding2, &ndr_table_lsarpc, tctx->ev, tctx->lp_ctx);
5732         dcerpc_binding_set_assoc_group_id(binding2, 0);
5733         torture_assert_ntstatus_ok(tctx, status, "epm map");
5734
5735         status = dcerpc_secondary_auth_connection(p, binding2, &ndr_table_lsarpc,
5736                                                   anon_creds, tctx->lp_ctx,
5737                                                   tctx, &p2);
5738         torture_assert_ntstatus_ok(tctx, status, "Failed to create secondary connection");
5739         b2 = p2->binding_handle;
5740
5741         qos.len = 0;
5742         qos.impersonation_level = 2;
5743         qos.context_mode = 1;
5744         qos.effective_only = 0;
5745
5746         attr.len = 0;
5747         attr.root_dir = NULL;
5748         attr.object_name = NULL;
5749         attr.attributes = 0;
5750         attr.sec_desc = NULL;
5751         attr.sec_qos = &qos;
5752
5753         o.in.system_name = "\\";
5754         o.in.attr = &attr;
5755         o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5756         o.out.handle = &lsa_handle;
5757
5758         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenPolicy2_r(b2, tctx, &o),
5759                 "OpenPolicy2 failed");
5760         torture_assert_ntstatus_ok(tctx, o.out.result, "OpenPolicy2 failed");
5761
5762         t.in.handle = &lsa_handle;
5763         t.in.resume_handle = &resume_handle;
5764         t.in.max_size = 1000;
5765         t.out.domains = &domains;
5766         t.out.resume_handle = &resume_handle;
5767
5768         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumTrustDom_r(b2, tctx, &t),
5769                 "EnumTrustDom failed");
5770
5771         if ((!NT_STATUS_IS_OK(t.out.result) &&
5772              (!NT_STATUS_EQUAL(t.out.result, NT_STATUS_NO_MORE_ENTRIES))))
5773                 torture_fail(tctx, "Could not list domains");
5774
5775         talloc_free(p2);
5776
5777         d.in.logon_server = talloc_asprintf(tctx, "\\\\%s",
5778                                             dcerpc_server_name(p));
5779         d.out.dcname = &dcname;
5780
5781         for (i=0; i<domains.count * 4; i++) {
5782                 struct lsa_DomainInfo *info =
5783                         &domains.domains[rand()%domains.count];
5784
5785                 d.in.domainname = info->name.string;
5786
5787                 status = dcerpc_netr_GetAnyDCName_r(b, tctx, &d);
5788                 torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
5789
5790                 torture_comment(tctx, "\tDC for domain %s is %s\n", info->name.string,
5791                        dcname ? dcname : "unknown");
5792         }
5793
5794         return true;
5795 }
5796
5797 static bool test_lsa_over_netlogon(struct torture_context *tctx,
5798                                    struct dcerpc_pipe *p)
5799 {
5800         NTSTATUS status;
5801         struct cli_credentials *anon_creds;
5802         const struct dcerpc_binding *binding2;
5803         struct dcerpc_pipe *p2;
5804         struct lsa_ObjectAttribute attr;
5805         struct lsa_QosInfo qos;
5806         struct lsa_OpenPolicy2 o;
5807         struct policy_handle lsa_handle;
5808
5809         struct dcerpc_binding_handle *b2;
5810
5811
5812         if (p->conn->transport.transport != NCACN_NP) {
5813                 torture_skip(tctx, "test_lsa_over_netlogon works only with NCACN_NP");
5814         }
5815
5816         torture_comment(tctx, "Testing if we can access the LSA server over\n"
5817                         " \\\\pipe\\netlogon rather than \\\\pipe\\lsarpc\n");
5818
5819         anon_creds = cli_credentials_init_anon(tctx);
5820         torture_assert(tctx, anon_creds != NULL, "cli_credentials_init_anon failed");
5821
5822         binding2 = p->binding;
5823
5824         status = dcerpc_secondary_auth_connection(p, binding2, &ndr_table_lsarpc,
5825                                                   anon_creds, tctx->lp_ctx,
5826                                                   tctx, &p2);
5827         torture_assert_ntstatus_ok(tctx, status, "Failed to create secondary connection");
5828         b2 = p2->binding_handle;
5829
5830         qos.len = 0;
5831         qos.impersonation_level = 2;
5832         qos.context_mode = 1;
5833         qos.effective_only = 0;
5834
5835         attr.len = 0;
5836         attr.root_dir = NULL;
5837         attr.object_name = NULL;
5838         attr.attributes = 0;
5839         attr.sec_desc = NULL;
5840         attr.sec_qos = &qos;
5841
5842         o.in.system_name = "\\";
5843         o.in.attr = &attr;
5844         o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5845         o.out.handle = &lsa_handle;
5846
5847         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenPolicy2_r(b2, tctx, &o),
5848                 "OpenPolicy2 failed");
5849         torture_assert_ntstatus_ok(tctx, o.out.result, "OpenPolicy2 failed");
5850
5851         talloc_free(p2);
5852
5853         return true;
5854 }
5855
5856 static bool test_SetPassword_with_flags(struct torture_context *tctx,
5857                                         struct dcerpc_pipe *p,
5858                                         struct cli_credentials *machine_credentials)
5859 {
5860         uint32_t flags[] = { 0, NETLOGON_NEG_STRONG_KEYS };
5861         struct netlogon_creds_CredentialState *creds;
5862         int i;
5863
5864         if (!test_SetupCredentials2(p, tctx, 0,
5865                                     machine_credentials,
5866                                     cli_credentials_get_secure_channel_type(machine_credentials),
5867                                     &creds)) {
5868                 torture_skip(tctx, "DC does not support negotiation of 64bit session keys");
5869         }
5870
5871         for (i=0; i < ARRAY_SIZE(flags); i++) {
5872                 torture_assert(tctx,
5873                         test_SetPassword_flags(tctx, p, machine_credentials, flags[i]),
5874                         talloc_asprintf(tctx, "failed to test SetPassword negotiating with 0x%08x flags", flags[i]));
5875         }
5876
5877         return true;
5878 }
5879
5880 struct torture_suite *torture_rpc_netlogon(TALLOC_CTX *mem_ctx)
5881 {
5882         struct torture_suite *suite = torture_suite_create(mem_ctx, "netlogon");
5883         struct torture_rpc_tcase *tcase;
5884         struct torture_test *test;
5885
5886         tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netlogon",
5887                                                   &ndr_table_netlogon, TEST_MACHINE_NAME);
5888
5889         torture_rpc_tcase_add_test_creds(tcase, "SetupCredentialsDowngrade", test_SetupCredentialsDowngrade);
5890         torture_rpc_tcase_add_test(tcase, "lsa_over_netlogon", test_lsa_over_netlogon);
5891
5892         torture_rpc_tcase_add_test_creds(tcase, "GetForestTrustInformation", test_netr_GetForestTrustInformation);
5893         torture_rpc_tcase_add_test_creds(tcase, "ServerGetTrustInfo_AES", test_netr_ServerGetTrustInfo_AES);
5894         torture_rpc_tcase_add_test_creds(tcase, "ServerGetTrustInfo", test_netr_ServerGetTrustInfo);
5895         torture_rpc_tcase_add_test(tcase, "DsRAddressToSitenamesExW", test_netr_DsRAddressToSitenamesExW);
5896         torture_rpc_tcase_add_test(tcase, "DsRAddressToSitenamesW", test_netr_DsRAddressToSitenamesW);
5897         torture_rpc_tcase_add_test(tcase, "DsrGetDcSiteCoverageW", test_netr_DsrGetDcSiteCoverageW);
5898         torture_rpc_tcase_add_test(tcase, "DsRGetDCNameEx2", test_netr_DsRGetDCNameEx2);
5899         torture_rpc_tcase_add_test(tcase, "DsRGetDCNameEx", test_netr_DsRGetDCNameEx);
5900         torture_rpc_tcase_add_test(tcase, "DsRGetDCName", test_netr_DsRGetDCName);
5901         test = torture_rpc_tcase_add_test_creds(tcase, "GetDomainInfo_async", test_GetDomainInfo_async);
5902         test->dangerous = true;
5903         torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomainsEx", test_netr_NetrEnumerateTrustedDomainsEx);
5904         torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomains", test_netr_NetrEnumerateTrustedDomains);
5905         torture_rpc_tcase_add_test(tcase, "DsrEnumerateDomainTrusts", test_DsrEnumerateDomainTrusts);
5906         torture_rpc_tcase_add_test_creds(tcase, "DatabaseSync2", test_DatabaseSync2);
5907         torture_rpc_tcase_add_test(tcase, "GetAnyDCName", test_GetAnyDCName);
5908         torture_rpc_tcase_add_test(tcase, "ManyGetDCName", test_ManyGetDCName);
5909         torture_rpc_tcase_add_test(tcase, "GetDcName", test_GetDcName);
5910         torture_rpc_tcase_add_test_creds(tcase, "AccountSync", test_AccountSync);
5911         torture_rpc_tcase_add_test_creds(tcase, "AccountDeltas", test_AccountDeltas);
5912         torture_rpc_tcase_add_test_creds(tcase, "DatabaseRedo", test_DatabaseRedo);
5913         torture_rpc_tcase_add_test_creds(tcase, "DatabaseDeltas", test_DatabaseDeltas);
5914         torture_rpc_tcase_add_test_creds(tcase, "DatabaseSync", test_DatabaseSync);
5915         torture_rpc_tcase_add_test_creds(tcase, "GetDomainInfo", test_GetDomainInfo);
5916         torture_rpc_tcase_add_test_creds(tcase, "GetTrustPasswords", test_GetTrustPasswords);
5917         torture_rpc_tcase_add_test_creds(tcase, "GetPassword", test_GetPassword);
5918         torture_rpc_tcase_add_test_creds(tcase, "SetPassword2_AES", test_SetPassword2_AES);
5919         torture_rpc_tcase_add_test_creds(tcase, "SetPassword2", test_SetPassword2);
5920         torture_rpc_tcase_add_test_creds(tcase, "SetPassword", test_SetPassword);
5921         torture_rpc_tcase_add_test_creds(tcase, "ServerReqChallengeReuse", test_ServerReqChallengeReuse);
5922         torture_rpc_tcase_add_test_creds(tcase, "ServerReqChallengeReuseGlobal4", test_ServerReqChallengeReuseGlobal4);
5923         torture_rpc_tcase_add_test_creds(tcase, "ServerReqChallengeReuseGlobal3", test_ServerReqChallengeReuseGlobal3);
5924         torture_rpc_tcase_add_test_creds(tcase, "ServerReqChallengeReuseGlobal2", test_ServerReqChallengeReuseGlobal2);
5925         torture_rpc_tcase_add_test_creds(tcase, "ServerReqChallengeReuseGlobal", test_ServerReqChallengeReuseGlobal);
5926         torture_rpc_tcase_add_test_creds(tcase, "ServerReqChallengeGlobal", test_ServerReqChallengeGlobal);
5927         torture_rpc_tcase_add_test_creds(tcase, "invalidAuthenticate2", test_invalidAuthenticate2);
5928         torture_rpc_tcase_add_test_creds(tcase, "SamLogon", test_SamLogon);
5929         torture_rpc_tcase_add_test(tcase, "LogonUasLogoff", test_LogonUasLogoff);
5930         torture_rpc_tcase_add_test(tcase, "LogonUasLogon", test_LogonUasLogon);
5931
5932         torture_rpc_tcase_add_test(tcase, "Broken RPC binding handle",
5933                                    test_netr_broken_binding_handle);
5934
5935         return suite;
5936 }
5937
5938 struct torture_suite *torture_rpc_netlogon_s3(TALLOC_CTX *mem_ctx)
5939 {
5940         struct torture_suite *suite = torture_suite_create(mem_ctx, "netlogon-s3");
5941         struct torture_rpc_tcase *tcase;
5942
5943         tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netlogon",
5944                                                   &ndr_table_netlogon, TEST_MACHINE_NAME);
5945
5946         torture_rpc_tcase_add_test_creds(tcase, "SamLogon", test_SamLogon);
5947         torture_rpc_tcase_add_test_creds(tcase, "SamLogon_NULL_domain", test_SamLogon_NULL_domain);
5948         torture_rpc_tcase_add_test_creds(tcase, "SetPassword", test_SetPassword);
5949         torture_rpc_tcase_add_test_creds(tcase, "SetPassword_with_flags", test_SetPassword_with_flags);
5950         torture_rpc_tcase_add_test_creds(tcase, "SetPassword2", test_SetPassword2);
5951         torture_rpc_tcase_add_test_creds(tcase, "SetPassword2_AES", test_SetPassword2_AES);
5952         torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomains", test_netr_NetrEnumerateTrustedDomains);
5953
5954         return suite;
5955 }
5956
5957 struct torture_suite *torture_rpc_netlogon_zerologon(TALLOC_CTX *mem_ctx)
5958 {
5959         struct torture_suite *suite = torture_suite_create(
5960                 mem_ctx,
5961                 "netlogon.zerologon");
5962         struct torture_rpc_tcase *tcase;
5963
5964         tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(
5965                 suite,
5966                 "netlogon",
5967                 &ndr_table_netlogon,
5968                 TEST_MACHINE_NAME);
5969
5970         torture_rpc_tcase_add_test_creds(
5971                 tcase,
5972                 "ServerReqChallenge",
5973                 test_ServerReqChallenge);
5974         torture_rpc_tcase_add_test_creds(
5975                 tcase,
5976                 "ServerReqChallenge_zero_challenge",
5977                 test_ServerReqChallenge_zero_challenge);
5978         torture_rpc_tcase_add_test_creds(
5979                 tcase,
5980                 "ServerReqChallenge_5_repeats",
5981                 test_ServerReqChallenge_5_repeats);
5982         torture_rpc_tcase_add_test_creds(
5983                 tcase,
5984                 "ServerReqChallenge_4_repeats",
5985                 test_ServerReqChallenge_4_repeats);
5986         torture_rpc_tcase_add_test_creds(
5987                 tcase,
5988                 "test_SetPassword2_encrypted_to_all_zeros",
5989                 test_SetPassword2_encrypted_to_all_zeros);
5990         torture_rpc_tcase_add_test_creds(
5991                 tcase,
5992                 "test_SetPassword2_password_encrypts_to_zero",
5993                 test_SetPassword2_password_encrypts_to_zero);
5994         torture_rpc_tcase_add_test_creds(
5995                 tcase,
5996                 "test_SetPassword2_confounder",
5997                 test_SetPassword2_confounder);
5998         torture_rpc_tcase_add_test_creds(
5999                 tcase,
6000                 "test_SetPassword2_all_zeros",
6001                 test_SetPassword2_all_zeros);
6002         torture_rpc_tcase_add_test_creds(
6003                 tcase,
6004                 "test_SetPassword2_all_zero_password",
6005                 test_SetPassword2_all_zero_password);
6006         torture_rpc_tcase_add_test_creds(
6007                 tcase,
6008                 "test_SetPassword2_maximum_length_password",
6009                 test_SetPassword2_maximum_length_password);
6010
6011         return suite;
6012 }
6013
6014 struct torture_suite *torture_rpc_netlogon_admin(TALLOC_CTX *mem_ctx)
6015 {
6016         struct torture_suite *suite = torture_suite_create(mem_ctx, "netlogon.admin");
6017         struct torture_rpc_tcase *tcase;
6018
6019         tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "bdc",
6020                                                   &ndr_table_netlogon, TEST_MACHINE_NAME);
6021         torture_rpc_tcase_add_test_creds(tcase, "LogonControl", test_LogonControl);
6022         torture_rpc_tcase_add_test_creds(tcase, "LogonControl2", test_LogonControl2);
6023         torture_rpc_tcase_add_test_creds(tcase, "LogonControl2Ex", test_LogonControl2Ex);
6024
6025         tcase = torture_suite_add_machine_workstation_rpc_iface_tcase(suite, "wkst",
6026                                                   &ndr_table_netlogon, TEST_MACHINE_NAME);
6027         torture_rpc_tcase_add_test_creds(tcase, "LogonControl", test_LogonControl);
6028         torture_rpc_tcase_add_test_creds(tcase, "LogonControl2", test_LogonControl2);
6029         torture_rpc_tcase_add_test_creds(tcase, "LogonControl2Ex", test_LogonControl2Ex);
6030
6031         tcase = torture_suite_add_rpc_iface_tcase(suite, "admin",
6032                                                   &ndr_table_netlogon);
6033         torture_rpc_tcase_add_test_creds(tcase, "LogonControl", test_LogonControl);
6034         torture_rpc_tcase_add_test_creds(tcase, "LogonControl2", test_LogonControl2);
6035         torture_rpc_tcase_add_test_creds(tcase, "LogonControl2Ex", test_LogonControl2Ex);
6036
6037         return suite;
6038 }