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