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