s4: popt: Global replace of cmdline_credentials -> popt_get_cmdline_credentials().
[gd/samba-autobuild/.git] / source4 / torture / rpc / netlogon.c
1 /*
2    Unix SMB/CIFS implementation.
3
4    test suite for netlogon rpc operations
5
6    Copyright (C) Andrew Tridgell 2003
7    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003-2004
8    Copyright (C) Tim Potter      2003
9    Copyright (C) Matthias Dieter Wallnöfer            2009-2010
10
11    This program is free software; you can redistribute it and/or modify
12    it under the terms of the GNU General Public License as published by
13    the Free Software Foundation; either version 3 of the License, or
14    (at your option) any later version.
15
16    This program is distributed in the hope that it will be useful,
17    but WITHOUT ANY WARRANTY; without even the implied warranty of
18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19    GNU General Public License for more details.
20
21    You should have received a copy of the GNU General Public License
22    along with this program.  If not, see <http://www.gnu.org/licenses/>.
23 */
24
25 #include "includes.h"
26 #include "lib/events/events.h"
27 #include "lib/cmdline/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         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b3, tctx, &a),
1397                 "ServerAuthenticate3 failed on b3");
1398         torture_assert_ntstatus_equal(tctx, a.out.result, NT_STATUS_ACCESS_DENIED,
1399                                       "ServerAuthenticate3 should have failed on b3, due to credential reuse");
1400         return true;
1401 }
1402
1403 /*
1404  * Test if use of the per-pipe challenge will wipe out the globally cached challenge
1405  */
1406 static bool test_ServerReqChallengeReuseGlobal2(struct torture_context *tctx,
1407                                                 struct dcerpc_pipe *p1,
1408                                                 struct cli_credentials *machine_credentials)
1409 {
1410         uint32_t flags = NETLOGON_NEG_AUTH2_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
1411         struct netr_ServerReqChallenge r;
1412         struct netr_ServerAuthenticate3 a;
1413         struct netr_Credential credentials1, credentials2, credentials3;
1414         struct netlogon_creds_CredentialState *creds;
1415         struct samr_Password mach_password;
1416         uint32_t rid;
1417         const char *machine_name;
1418         const char *plain_pass;
1419         struct dcerpc_binding_handle *b1 = p1->binding_handle;
1420         struct dcerpc_pipe *p2 = NULL;
1421         struct dcerpc_binding_handle *b2 = NULL;
1422
1423         machine_name = cli_credentials_get_workstation(machine_credentials);
1424         plain_pass = cli_credentials_get_password(machine_credentials);
1425
1426         torture_comment(tctx, "Testing ServerReqChallenge on b1\n");
1427
1428         torture_assert_ntstatus_ok(tctx,
1429                 dcerpc_pipe_connect_b(tctx, &p2, p1->binding,
1430                                       &ndr_table_netlogon,
1431                                       machine_credentials,
1432                                       tctx->ev, tctx->lp_ctx),
1433                 "dcerpc_pipe_connect_b failed");
1434         b2 = p2->binding_handle;
1435
1436         r.in.server_name = NULL;
1437         r.in.computer_name = machine_name;
1438         r.in.credentials = &credentials1;
1439         r.out.return_credentials = &credentials2;
1440
1441         generate_random_buffer(credentials1.data, sizeof(credentials1.data));
1442
1443         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b1, tctx, &r),
1444                 "ServerReqChallenge failed on b1");
1445         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed on b1");
1446
1447         E_md4hash(plain_pass, mach_password.hash);
1448
1449         a.in.server_name = NULL;
1450         a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
1451         a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
1452         a.in.computer_name = machine_name;
1453         a.in.negotiate_flags = &flags;
1454         a.in.credentials = &credentials3;
1455         a.out.return_credentials = &credentials3;
1456         a.out.negotiate_flags = &flags;
1457         a.out.rid = &rid;
1458
1459         creds = netlogon_creds_client_init(tctx, a.in.account_name,
1460                                            a.in.computer_name,
1461                                            a.in.secure_channel_type,
1462                                            &credentials1, &credentials2,
1463                                            &mach_password, &credentials3,
1464                                            flags);
1465
1466         torture_assert(tctx, creds != NULL, "memory allocation");
1467
1468         torture_comment(tctx, "Testing ServerAuthenticate3 on b2\n");
1469
1470         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b1, tctx, &a),
1471                 "ServerAuthenticate3 failed on b");
1472         torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate3 failed on b");
1473         torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
1474
1475         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b2, tctx, &a),
1476                 "ServerAuthenticate3 failed on b2");
1477         torture_assert_ntstatus_equal(tctx, a.out.result, NT_STATUS_ACCESS_DENIED,
1478                                       "ServerAuthenticate3 should have failed on b2, due to credential reuse");
1479         return true;
1480 }
1481
1482 static bool test_ServerReqChallengeReuse(struct torture_context *tctx,
1483                                          struct dcerpc_pipe *p,
1484                                          struct cli_credentials *machine_credentials)
1485 {
1486         uint32_t flags = NETLOGON_NEG_AUTH2_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
1487         struct netr_ServerReqChallenge r;
1488         struct netr_ServerAuthenticate3 a;
1489         struct netr_Credential credentials1, credentials2, credentials3;
1490         struct netlogon_creds_CredentialState *creds;
1491         struct samr_Password mach_password;
1492         uint32_t rid;
1493         const char *machine_name;
1494         const char *plain_pass;
1495         struct dcerpc_binding_handle *b = p->binding_handle;
1496
1497         machine_name = cli_credentials_get_workstation(machine_credentials);
1498         plain_pass = cli_credentials_get_password(machine_credentials);
1499
1500         torture_comment(tctx, "Testing ServerReqChallenge on b1\n");
1501
1502         r.in.server_name = NULL;
1503         r.in.computer_name = machine_name;
1504         r.in.credentials = &credentials1;
1505         r.out.return_credentials = &credentials2;
1506
1507         generate_random_buffer(credentials1.data, sizeof(credentials1.data));
1508
1509         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
1510                 "ServerReqChallenge");
1511         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed on b1");
1512
1513         E_md4hash(plain_pass, mach_password.hash);
1514
1515         a.in.server_name = NULL;
1516         a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
1517         a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
1518         a.in.computer_name = machine_name;
1519         a.in.negotiate_flags = &flags;
1520         a.in.credentials = &credentials3;
1521         a.out.return_credentials = &credentials3;
1522         a.out.negotiate_flags = &flags;
1523         a.out.rid = &rid;
1524
1525         creds = netlogon_creds_client_init(tctx, a.in.account_name,
1526                                            a.in.computer_name,
1527                                            a.in.secure_channel_type,
1528                                            &credentials1, &credentials2,
1529                                            &mach_password, &credentials3,
1530                                            flags);
1531
1532         torture_assert(tctx, creds != NULL, "memory allocation");
1533
1534         torture_comment(tctx, "Testing ServerAuthenticate3\n");
1535
1536         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b, tctx, &a),
1537                 "ServerAuthenticate3 failed");
1538         torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate3 failed");
1539         torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
1540
1541         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b, tctx, &a),
1542                 "ServerAuthenticate3 failed");
1543         torture_assert_ntstatus_equal(tctx, a.out.result, NT_STATUS_ACCESS_DENIED,
1544                                       "ServerAuthenticate3 should have failed on b3, due to credential reuse");
1545
1546         ZERO_STRUCT(credentials1.data);
1547         ZERO_STRUCT(credentials2.data);
1548         creds = netlogon_creds_client_init(tctx, a.in.account_name,
1549                                            a.in.computer_name,
1550                                            a.in.secure_channel_type,
1551                                            &credentials1, &credentials2,
1552                                            &mach_password, &credentials3,
1553                                            flags);
1554
1555         torture_assert(tctx, creds != NULL, "memory allocation");
1556
1557         torture_comment(tctx, "Testing ServerAuthenticate3 with zero'ed challenge\n");
1558
1559         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b, tctx, &a),
1560                 "ServerAuthenticate3 failed");
1561         torture_assert_ntstatus_equal(tctx, a.out.result, NT_STATUS_ACCESS_DENIED,
1562                                       "ServerAuthenticate3 should have failed on b3, due to credential reuse");
1563         return true;
1564 }
1565
1566 static bool test_SamLogon_NULL_domain(struct torture_context *tctx,
1567                                       struct dcerpc_pipe *p,
1568                                       struct cli_credentials *credentials)
1569 {
1570         struct netlogon_creds_CredentialState *creds;
1571
1572         if (!test_SetupCredentials(p, tctx, credentials, &creds)) {
1573                 return false;
1574         }
1575
1576         return test_netlogon_ops_args(p, tctx, credentials, creds, true);
1577 }
1578
1579 /* we remember the sequence numbers so we can easily do a DatabaseDelta */
1580 static uint64_t sequence_nums[3];
1581
1582 /*
1583   try a netlogon DatabaseSync
1584 */
1585 static bool test_DatabaseSync(struct torture_context *tctx,
1586                               struct dcerpc_pipe *p,
1587                               struct cli_credentials *machine_credentials)
1588 {
1589         struct netr_DatabaseSync r;
1590         struct netlogon_creds_CredentialState *creds;
1591         const uint32_t database_ids[] = {SAM_DATABASE_DOMAIN, SAM_DATABASE_BUILTIN, SAM_DATABASE_PRIVS};
1592         int i;
1593         struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
1594         struct netr_Authenticator credential, return_authenticator;
1595         struct dcerpc_binding_handle *b = p->binding_handle;
1596
1597         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1598                 return false;
1599         }
1600
1601         ZERO_STRUCT(return_authenticator);
1602
1603         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1604         r.in.computername = TEST_MACHINE_NAME;
1605         r.in.preferredmaximumlength = (uint32_t)-1;
1606         r.in.return_authenticator = &return_authenticator;
1607         r.out.delta_enum_array = &delta_enum_array;
1608         r.out.return_authenticator = &return_authenticator;
1609
1610         for (i=0;i<ARRAY_SIZE(database_ids);i++) {
1611
1612                 uint32_t sync_context = 0;
1613
1614                 r.in.database_id = database_ids[i];
1615                 r.in.sync_context = &sync_context;
1616                 r.out.sync_context = &sync_context;
1617
1618                 torture_comment(tctx, "Testing DatabaseSync of id %d\n", r.in.database_id);
1619
1620                 do {
1621                         netlogon_creds_client_authenticator(creds, &credential);
1622
1623                         r.in.credential = &credential;
1624
1625                         torture_assert_ntstatus_ok(tctx, dcerpc_netr_DatabaseSync_r(b, tctx, &r),
1626                                 "DatabaseSync failed");
1627                         if (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES))
1628                             break;
1629
1630                         /* Native mode servers don't do this */
1631                         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_SUPPORTED)) {
1632                                 return true;
1633                         }
1634                         torture_assert_ntstatus_ok(tctx, r.out.result, "DatabaseSync");
1635
1636                         if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
1637                                 torture_comment(tctx, "Credential chaining failed\n");
1638                         }
1639
1640                         if (delta_enum_array &&
1641                             delta_enum_array->num_deltas > 0 &&
1642                             delta_enum_array->delta_enum[0].delta_type == NETR_DELTA_DOMAIN &&
1643                             delta_enum_array->delta_enum[0].delta_union.domain) {
1644                                 sequence_nums[r.in.database_id] =
1645                                         delta_enum_array->delta_enum[0].delta_union.domain->sequence_num;
1646                                 torture_comment(tctx, "\tsequence_nums[%d]=%llu\n",
1647                                        r.in.database_id,
1648                                        (unsigned long long)sequence_nums[r.in.database_id]);
1649                         }
1650                 } while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES));
1651         }
1652
1653         return true;
1654 }
1655
1656
1657 /*
1658   try a netlogon DatabaseDeltas
1659 */
1660 static bool test_DatabaseDeltas(struct torture_context *tctx,
1661                                 struct dcerpc_pipe *p,
1662                                 struct cli_credentials *machine_credentials)
1663 {
1664         struct netr_DatabaseDeltas r;
1665         struct netlogon_creds_CredentialState *creds;
1666         struct netr_Authenticator credential;
1667         struct netr_Authenticator return_authenticator;
1668         struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
1669         const uint32_t database_ids[] = {0, 1, 2};
1670         int i;
1671         struct dcerpc_binding_handle *b = p->binding_handle;
1672
1673         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1674                 return false;
1675         }
1676
1677         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1678         r.in.computername = TEST_MACHINE_NAME;
1679         r.in.preferredmaximumlength = (uint32_t)-1;
1680         ZERO_STRUCT(r.in.return_authenticator);
1681         r.out.return_authenticator = &return_authenticator;
1682         r.out.delta_enum_array = &delta_enum_array;
1683
1684         for (i=0;i<ARRAY_SIZE(database_ids);i++) {
1685                 r.in.database_id = database_ids[i];
1686                 r.in.sequence_num = &sequence_nums[r.in.database_id];
1687
1688                 if (*r.in.sequence_num == 0) continue;
1689
1690                 *r.in.sequence_num -= 1;
1691
1692                 torture_comment(tctx, "Testing DatabaseDeltas of id %d at %llu\n",
1693                        r.in.database_id, (unsigned long long)*r.in.sequence_num);
1694
1695                 do {
1696                         netlogon_creds_client_authenticator(creds, &credential);
1697
1698                         torture_assert_ntstatus_ok(tctx, dcerpc_netr_DatabaseDeltas_r(b, tctx, &r),
1699                                 "DatabaseDeltas failed");
1700                         if (NT_STATUS_EQUAL(r.out.result,
1701                                              NT_STATUS_SYNCHRONIZATION_REQUIRED)) {
1702                                 torture_comment(tctx, "not considering %s to be an error\n",
1703                                        nt_errstr(r.out.result));
1704                                 return true;
1705                         }
1706                         if (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES))
1707                             break;
1708
1709                         torture_assert_ntstatus_ok(tctx, r.out.result, "DatabaseDeltas");
1710
1711                         if (!netlogon_creds_client_check(creds, &return_authenticator.cred)) {
1712                                 torture_comment(tctx, "Credential chaining failed\n");
1713                         }
1714
1715                         (*r.in.sequence_num)++;
1716                 } while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES));
1717         }
1718
1719         return true;
1720 }
1721
1722 static bool test_DatabaseRedo(struct torture_context *tctx,
1723                               struct dcerpc_pipe *p,
1724                               struct cli_credentials *machine_credentials)
1725 {
1726         struct netr_DatabaseRedo r;
1727         struct netlogon_creds_CredentialState *creds;
1728         struct netr_Authenticator credential;
1729         struct netr_Authenticator return_authenticator;
1730         struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
1731         struct netr_ChangeLogEntry e;
1732         struct dom_sid null_sid, *sid;
1733         int i,d;
1734         struct dcerpc_binding_handle *b = p->binding_handle;
1735
1736         ZERO_STRUCT(null_sid);
1737
1738         sid = dom_sid_parse_talloc(tctx, "S-1-5-21-1111111111-2222222222-333333333-500");
1739
1740         {
1741
1742         struct {
1743                 uint32_t rid;
1744                 uint16_t flags;
1745                 uint8_t db_index;
1746                 uint8_t delta_type;
1747                 struct dom_sid sid;
1748                 const char *name;
1749                 NTSTATUS expected_error;
1750                 uint32_t expected_num_results;
1751                 uint8_t expected_delta_type_1;
1752                 uint8_t expected_delta_type_2;
1753                 const char *comment;
1754         } changes[] = {
1755
1756                 /* SAM_DATABASE_DOMAIN */
1757
1758                 {
1759                         .rid                    = 0,
1760                         .flags                  = 0,
1761                         .db_index               = SAM_DATABASE_DOMAIN,
1762                         .delta_type             = NETR_DELTA_MODIFY_COUNT,
1763                         .sid                    = null_sid,
1764                         .name                   = NULL,
1765                         .expected_error         = NT_STATUS_SYNCHRONIZATION_REQUIRED,
1766                         .expected_num_results   = 0,
1767                         .comment                = "NETR_DELTA_MODIFY_COUNT"
1768                 },
1769                 {
1770                         .rid                    = 0,
1771                         .flags                  = 0,
1772                         .db_index               = SAM_DATABASE_DOMAIN,
1773                         .delta_type             = 0,
1774                         .sid                    = null_sid,
1775                         .name                   = NULL,
1776                         .expected_error         = NT_STATUS_OK,
1777                         .expected_num_results   = 1,
1778                         .expected_delta_type_1  = NETR_DELTA_DOMAIN,
1779                         .comment                = "NULL DELTA"
1780                 },
1781                 {
1782                         .rid                    = 0,
1783                         .flags                  = 0,
1784                         .db_index               = SAM_DATABASE_DOMAIN,
1785                         .delta_type             = NETR_DELTA_DOMAIN,
1786                         .sid                    = null_sid,
1787                         .name                   = NULL,
1788                         .expected_error         = NT_STATUS_OK,
1789                         .expected_num_results   = 1,
1790                         .expected_delta_type_1  = NETR_DELTA_DOMAIN,
1791                         .comment                = "NETR_DELTA_DOMAIN"
1792                 },
1793                 {
1794                         .rid                    = DOMAIN_RID_ADMINISTRATOR,
1795                         .flags                  = 0,
1796                         .db_index               = SAM_DATABASE_DOMAIN,
1797                         .delta_type             = NETR_DELTA_USER,
1798                         .sid                    = null_sid,
1799                         .name                   = NULL,
1800                         .expected_error         = NT_STATUS_OK,
1801                         .expected_num_results   = 1,
1802                         .expected_delta_type_1  = NETR_DELTA_USER,
1803                         .comment                = "NETR_DELTA_USER by rid 500"
1804                 },
1805                 {
1806                         .rid                    = DOMAIN_RID_GUEST,
1807                         .flags                  = 0,
1808                         .db_index               = SAM_DATABASE_DOMAIN,
1809                         .delta_type             = NETR_DELTA_USER,
1810                         .sid                    = null_sid,
1811                         .name                   = NULL,
1812                         .expected_error         = NT_STATUS_OK,
1813                         .expected_num_results   = 1,
1814                         .expected_delta_type_1  = NETR_DELTA_USER,
1815                         .comment                = "NETR_DELTA_USER by rid 501"
1816                 },
1817                 {
1818                         .rid                    = 0,
1819                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
1820                         .db_index               = SAM_DATABASE_DOMAIN,
1821                         .delta_type             = NETR_DELTA_USER,
1822                         .sid                    = *sid,
1823                         .name                   = NULL,
1824                         .expected_error         = NT_STATUS_OK,
1825                         .expected_num_results   = 1,
1826                         .expected_delta_type_1  = NETR_DELTA_DELETE_USER,
1827                         .comment                = "NETR_DELTA_USER by sid and flags"
1828                 },
1829                 {
1830                         .rid                    = 0,
1831                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
1832                         .db_index               = SAM_DATABASE_DOMAIN,
1833                         .delta_type             = NETR_DELTA_USER,
1834                         .sid                    = null_sid,
1835                         .name                   = NULL,
1836                         .expected_error         = NT_STATUS_OK,
1837                         .expected_num_results   = 1,
1838                         .expected_delta_type_1  = NETR_DELTA_DELETE_USER,
1839                         .comment                = "NETR_DELTA_USER by null_sid and flags"
1840                 },
1841                 {
1842                         .rid                    = 0,
1843                         .flags                  = NETR_CHANGELOG_NAME_INCLUDED,
1844                         .db_index               = SAM_DATABASE_DOMAIN,
1845                         .delta_type             = NETR_DELTA_USER,
1846                         .sid                    = null_sid,
1847                         .name                   = "administrator",
1848                         .expected_error         = NT_STATUS_OK,
1849                         .expected_num_results   = 1,
1850                         .expected_delta_type_1  = NETR_DELTA_DELETE_USER,
1851                         .comment                = "NETR_DELTA_USER by name 'administrator'"
1852                 },
1853                 {
1854                         .rid                    = DOMAIN_RID_ADMINS,
1855                         .flags                  = 0,
1856                         .db_index               = SAM_DATABASE_DOMAIN,
1857                         .delta_type             = NETR_DELTA_GROUP,
1858                         .sid                    = null_sid,
1859                         .name                   = NULL,
1860                         .expected_error         = NT_STATUS_OK,
1861                         .expected_num_results   = 2,
1862                         .expected_delta_type_1  = NETR_DELTA_GROUP,
1863                         .expected_delta_type_2  = NETR_DELTA_GROUP_MEMBER,
1864                         .comment                = "NETR_DELTA_GROUP by rid 512"
1865                 },
1866                 {
1867                         .rid                    = DOMAIN_RID_ADMINS,
1868                         .flags                  = 0,
1869                         .db_index               = SAM_DATABASE_DOMAIN,
1870                         .delta_type             = NETR_DELTA_GROUP_MEMBER,
1871                         .sid                    = null_sid,
1872                         .name                   = NULL,
1873                         .expected_error         = NT_STATUS_OK,
1874                         .expected_num_results   = 2,
1875                         .expected_delta_type_1  = NETR_DELTA_GROUP,
1876                         .expected_delta_type_2  = NETR_DELTA_GROUP_MEMBER,
1877                         .comment                = "NETR_DELTA_GROUP_MEMBER by rid 512"
1878                 },
1879
1880
1881                 /* SAM_DATABASE_BUILTIN */
1882
1883                 {
1884                         .rid                    = 0,
1885                         .flags                  = 0,
1886                         .db_index               = SAM_DATABASE_BUILTIN,
1887                         .delta_type             = NETR_DELTA_MODIFY_COUNT,
1888                         .sid                    = null_sid,
1889                         .name                   = NULL,
1890                         .expected_error         = NT_STATUS_SYNCHRONIZATION_REQUIRED,
1891                         .expected_num_results   = 0,
1892                         .comment                = "NETR_DELTA_MODIFY_COUNT"
1893                 },
1894                 {
1895                         .rid                    = 0,
1896                         .flags                  = 0,
1897                         .db_index               = SAM_DATABASE_BUILTIN,
1898                         .delta_type             = NETR_DELTA_DOMAIN,
1899                         .sid                    = null_sid,
1900                         .name                   = NULL,
1901                         .expected_error         = NT_STATUS_OK,
1902                         .expected_num_results   = 1,
1903                         .expected_delta_type_1  = NETR_DELTA_DOMAIN,
1904                         .comment                = "NETR_DELTA_DOMAIN"
1905                 },
1906                 {
1907                         .rid                    = DOMAIN_RID_ADMINISTRATOR,
1908                         .flags                  = 0,
1909                         .db_index               = SAM_DATABASE_BUILTIN,
1910                         .delta_type             = NETR_DELTA_USER,
1911                         .sid                    = null_sid,
1912                         .name                   = NULL,
1913                         .expected_error         = NT_STATUS_OK,
1914                         .expected_num_results   = 1,
1915                         .expected_delta_type_1  = NETR_DELTA_DELETE_USER,
1916                         .comment                = "NETR_DELTA_USER by rid 500"
1917                 },
1918                 {
1919                         .rid                    = 0,
1920                         .flags                  = 0,
1921                         .db_index               = SAM_DATABASE_BUILTIN,
1922                         .delta_type             = NETR_DELTA_USER,
1923                         .sid                    = null_sid,
1924                         .name                   = NULL,
1925                         .expected_error         = NT_STATUS_OK,
1926                         .expected_num_results   = 1,
1927                         .expected_delta_type_1  = NETR_DELTA_DELETE_USER,
1928                         .comment                = "NETR_DELTA_USER"
1929                 },
1930                 {
1931                         .rid                    = 544,
1932                         .flags                  = 0,
1933                         .db_index               = SAM_DATABASE_BUILTIN,
1934                         .delta_type             = NETR_DELTA_ALIAS,
1935                         .sid                    = null_sid,
1936                         .name                   = NULL,
1937                         .expected_error         = NT_STATUS_OK,
1938                         .expected_num_results   = 2,
1939                         .expected_delta_type_1  = NETR_DELTA_ALIAS,
1940                         .expected_delta_type_2  = NETR_DELTA_ALIAS_MEMBER,
1941                         .comment                = "NETR_DELTA_ALIAS by rid 544"
1942                 },
1943                 {
1944                         .rid                    = 544,
1945                         .flags                  = 0,
1946                         .db_index               = SAM_DATABASE_BUILTIN,
1947                         .delta_type             = NETR_DELTA_ALIAS_MEMBER,
1948                         .sid                    = null_sid,
1949                         .name                   = NULL,
1950                         .expected_error         = NT_STATUS_OK,
1951                         .expected_num_results   = 2,
1952                         .expected_delta_type_1  = NETR_DELTA_ALIAS,
1953                         .expected_delta_type_2  = NETR_DELTA_ALIAS_MEMBER,
1954                         .comment                = "NETR_DELTA_ALIAS_MEMBER by rid 544"
1955                 },
1956                 {
1957                         .rid                    = 544,
1958                         .flags                  = 0,
1959                         .db_index               = SAM_DATABASE_BUILTIN,
1960                         .delta_type             = 0,
1961                         .sid                    = null_sid,
1962                         .name                   = NULL,
1963                         .expected_error         = NT_STATUS_OK,
1964                         .expected_num_results   = 1,
1965                         .expected_delta_type_1  = NETR_DELTA_DOMAIN,
1966                         .comment                = "NULL DELTA by rid 544"
1967                 },
1968                 {
1969                         .rid                    = 544,
1970                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
1971                         .db_index               = SAM_DATABASE_BUILTIN,
1972                         .delta_type             = 0,
1973                         .sid                    = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
1974                         .name                   = NULL,
1975                         .expected_error         = NT_STATUS_OK,
1976                         .expected_num_results   = 1,
1977                         .expected_delta_type_1  = NETR_DELTA_DOMAIN,
1978                         .comment                = "NULL DELTA by rid 544 sid S-1-5-32-544 and flags"
1979                 },
1980                 {
1981                         .rid                    = 544,
1982                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
1983                         .db_index               = SAM_DATABASE_BUILTIN,
1984                         .delta_type             = NETR_DELTA_ALIAS,
1985                         .sid                    = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
1986                         .name                   = NULL,
1987                         .expected_error         = NT_STATUS_OK,
1988                         .expected_num_results   = 2,
1989                         .expected_delta_type_1  = NETR_DELTA_ALIAS,
1990                         .expected_delta_type_2  = NETR_DELTA_ALIAS_MEMBER,
1991                         .comment                = "NETR_DELTA_ALIAS by rid 544 and sid S-1-5-32-544 and flags"
1992                 },
1993                 {
1994                         .rid                    = 0,
1995                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
1996                         .db_index               = SAM_DATABASE_BUILTIN,
1997                         .delta_type             = NETR_DELTA_ALIAS,
1998                         .sid                    = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
1999                         .name                   = NULL,
2000                         .expected_error         = NT_STATUS_OK,
2001                         .expected_num_results   = 1,
2002                         .expected_delta_type_1  = NETR_DELTA_DELETE_ALIAS,
2003                         .comment                = "NETR_DELTA_ALIAS by sid S-1-5-32-544 and flags"
2004                 },
2005
2006                 /* SAM_DATABASE_PRIVS */
2007
2008                 {
2009                         .rid                    = 0,
2010                         .flags                  = 0,
2011                         .db_index               = SAM_DATABASE_PRIVS,
2012                         .delta_type             = 0,
2013                         .sid                    = null_sid,
2014                         .name                   = NULL,
2015                         .expected_error         = NT_STATUS_ACCESS_DENIED,
2016                         .expected_num_results   = 0,
2017                         .comment                = "NULL DELTA"
2018                 },
2019                 {
2020                         .rid                    = 0,
2021                         .flags                  = 0,
2022                         .db_index               = SAM_DATABASE_PRIVS,
2023                         .delta_type             = NETR_DELTA_MODIFY_COUNT,
2024                         .sid                    = null_sid,
2025                         .name                   = NULL,
2026                         .expected_error         = NT_STATUS_SYNCHRONIZATION_REQUIRED,
2027                         .expected_num_results   = 0,
2028                         .comment                = "NETR_DELTA_MODIFY_COUNT"
2029                 },
2030                 {
2031                         .rid                    = 0,
2032                         .flags                  = 0,
2033                         .db_index               = SAM_DATABASE_PRIVS,
2034                         .delta_type             = NETR_DELTA_POLICY,
2035                         .sid                    = null_sid,
2036                         .name                   = NULL,
2037                         .expected_error         = NT_STATUS_OK,
2038                         .expected_num_results   = 1,
2039                         .expected_delta_type_1  = NETR_DELTA_POLICY,
2040                         .comment                = "NETR_DELTA_POLICY"
2041                 },
2042                 {
2043                         .rid                    = 0,
2044                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
2045                         .db_index               = SAM_DATABASE_PRIVS,
2046                         .delta_type             = NETR_DELTA_POLICY,
2047                         .sid                    = null_sid,
2048                         .name                   = NULL,
2049                         .expected_error         = NT_STATUS_OK,
2050                         .expected_num_results   = 1,
2051                         .expected_delta_type_1  = NETR_DELTA_POLICY,
2052                         .comment                = "NETR_DELTA_POLICY by null sid and flags"
2053                 },
2054                 {
2055                         .rid                    = 0,
2056                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
2057                         .db_index               = SAM_DATABASE_PRIVS,
2058                         .delta_type             = NETR_DELTA_POLICY,
2059                         .sid                    = *dom_sid_parse_talloc(tctx, "S-1-5-32"),
2060                         .name                   = NULL,
2061                         .expected_error         = NT_STATUS_OK,
2062                         .expected_num_results   = 1,
2063                         .expected_delta_type_1  = NETR_DELTA_POLICY,
2064                         .comment                = "NETR_DELTA_POLICY by sid S-1-5-32 and flags"
2065                 },
2066                 {
2067                         .rid                    = DOMAIN_RID_ADMINISTRATOR,
2068                         .flags                  = 0,
2069                         .db_index               = SAM_DATABASE_PRIVS,
2070                         .delta_type             = NETR_DELTA_ACCOUNT,
2071                         .sid                    = null_sid,
2072                         .name                   = NULL,
2073                         .expected_error         = NT_STATUS_SYNCHRONIZATION_REQUIRED, /* strange */
2074                         .expected_num_results   = 0,
2075                         .comment                = "NETR_DELTA_ACCOUNT by rid 500"
2076                 },
2077                 {
2078                         .rid                    = 0,
2079                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
2080                         .db_index               = SAM_DATABASE_PRIVS,
2081                         .delta_type             = NETR_DELTA_ACCOUNT,
2082                         .sid                    = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
2083                         .name                   = NULL,
2084                         .expected_error         = NT_STATUS_OK,
2085                         .expected_num_results   = 1,
2086                         .expected_delta_type_1  = NETR_DELTA_ACCOUNT,
2087                         .comment                = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and flags"
2088                 },
2089                 {
2090                         .rid                    = 0,
2091                         .flags                  = NETR_CHANGELOG_SID_INCLUDED |
2092                                                   NETR_CHANGELOG_IMMEDIATE_REPL_REQUIRED,
2093                         .db_index               = SAM_DATABASE_PRIVS,
2094                         .delta_type             = NETR_DELTA_ACCOUNT,
2095                         .sid                    = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
2096                         .name                   = NULL,
2097                         .expected_error         = NT_STATUS_OK,
2098                         .expected_num_results   = 1,
2099                         .expected_delta_type_1  = NETR_DELTA_ACCOUNT,
2100                         .comment                = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and 2 flags"
2101                 },
2102                 {
2103                         .rid                    = 0,
2104                         .flags                  = NETR_CHANGELOG_SID_INCLUDED |
2105                                                   NETR_CHANGELOG_NAME_INCLUDED,
2106                         .db_index               = SAM_DATABASE_PRIVS,
2107                         .delta_type             = NETR_DELTA_ACCOUNT,
2108                         .sid                    = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
2109                         .name                   = NULL,
2110                         .expected_error         = NT_STATUS_INVALID_PARAMETER,
2111                         .expected_num_results   = 0,
2112                         .comment                = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and invalid flags"
2113                 },
2114                 {
2115                         .rid                    = DOMAIN_RID_ADMINISTRATOR,
2116                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
2117                         .db_index               = SAM_DATABASE_PRIVS,
2118                         .delta_type             = NETR_DELTA_ACCOUNT,
2119                         .sid                    = *sid,
2120                         .name                   = NULL,
2121                         .expected_error         = NT_STATUS_OK,
2122                         .expected_num_results   = 1,
2123                         .expected_delta_type_1  = NETR_DELTA_DELETE_ACCOUNT,
2124                         .comment                = "NETR_DELTA_ACCOUNT by rid 500, sid and flags"
2125                 },
2126                 {
2127                         .rid                    = 0,
2128                         .flags                  = NETR_CHANGELOG_NAME_INCLUDED,
2129                         .db_index               = SAM_DATABASE_PRIVS,
2130                         .delta_type             = NETR_DELTA_SECRET,
2131                         .sid                    = null_sid,
2132                         .name                   = "IsurelydontexistIhope",
2133                         .expected_error         = NT_STATUS_OK,
2134                         .expected_num_results   = 1,
2135                         .expected_delta_type_1  = NETR_DELTA_DELETE_SECRET,
2136                         .comment                = "NETR_DELTA_SECRET by name 'IsurelydontexistIhope' and flags"
2137                 },
2138                 {
2139                         .rid                    = 0,
2140                         .flags                  = NETR_CHANGELOG_NAME_INCLUDED,
2141                         .db_index               = SAM_DATABASE_PRIVS,
2142                         .delta_type             = NETR_DELTA_SECRET,
2143                         .sid                    = null_sid,
2144                         .name                   = "G$BCKUPKEY_P",
2145                         .expected_error         = NT_STATUS_OK,
2146                         .expected_num_results   = 1,
2147                         .expected_delta_type_1  = NETR_DELTA_SECRET,
2148                         .comment                = "NETR_DELTA_SECRET by name 'G$BCKUPKEY_P' and flags"
2149                 }
2150         };
2151
2152         ZERO_STRUCT(return_authenticator);
2153
2154         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2155         r.in.computername = TEST_MACHINE_NAME;
2156         r.in.return_authenticator = &return_authenticator;
2157         r.out.return_authenticator = &return_authenticator;
2158         r.out.delta_enum_array = &delta_enum_array;
2159
2160         for (d=0; d<3; d++) {
2161                 const char *database = NULL;
2162
2163                 switch (d) {
2164                 case 0:
2165                         database = "SAM";
2166                         break;
2167                 case 1:
2168                         database = "BUILTIN";
2169                         break;
2170                 case 2:
2171                         database = "LSA";
2172                         break;
2173                 default:
2174                         break;
2175                 }
2176
2177                 torture_comment(tctx, "Testing DatabaseRedo\n");
2178
2179                 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
2180                         return false;
2181                 }
2182
2183                 for (i=0;i<ARRAY_SIZE(changes);i++) {
2184
2185                         if (d != changes[i].db_index) {
2186                                 continue;
2187                         }
2188
2189                         netlogon_creds_client_authenticator(creds, &credential);
2190
2191                         r.in.credential = &credential;
2192
2193                         e.serial_number1        = 0;
2194                         e.serial_number2        = 0;
2195                         e.object_rid            = changes[i].rid;
2196                         e.flags                 = changes[i].flags;
2197                         e.db_index              = changes[i].db_index;
2198                         e.delta_type            = changes[i].delta_type;
2199
2200                         switch (changes[i].flags & (NETR_CHANGELOG_NAME_INCLUDED | NETR_CHANGELOG_SID_INCLUDED)) {
2201                         case NETR_CHANGELOG_SID_INCLUDED:
2202                                 e.object.object_sid             = changes[i].sid;
2203                                 break;
2204                         case NETR_CHANGELOG_NAME_INCLUDED:
2205                                 e.object.object_name            = changes[i].name;
2206                                 break;
2207                         default:
2208                                 break;
2209                         }
2210
2211                         r.in.change_log_entry = e;
2212
2213                         torture_comment(tctx, "Testing DatabaseRedo with database %s and %s\n",
2214                                 database, changes[i].comment);
2215
2216                         torture_assert_ntstatus_ok(tctx, dcerpc_netr_DatabaseRedo_r(b, tctx, &r),
2217                                 "DatabaseRedo failed");
2218                         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_SUPPORTED)) {
2219                                 return true;
2220                         }
2221
2222                         torture_assert_ntstatus_equal(tctx, r.out.result, changes[i].expected_error, changes[i].comment);
2223                         if (delta_enum_array) {
2224                                 torture_assert_int_equal(tctx,
2225                                         delta_enum_array->num_deltas,
2226                                         changes[i].expected_num_results,
2227                                         changes[i].comment);
2228                                 if (delta_enum_array->num_deltas > 0) {
2229                                         torture_assert_int_equal(tctx,
2230                                                 delta_enum_array->delta_enum[0].delta_type,
2231                                                 changes[i].expected_delta_type_1,
2232                                                 changes[i].comment);
2233                                 }
2234                                 if (delta_enum_array->num_deltas > 1) {
2235                                         torture_assert_int_equal(tctx,
2236                                                 delta_enum_array->delta_enum[1].delta_type,
2237                                                 changes[i].expected_delta_type_2,
2238                                                 changes[i].comment);
2239                                 }
2240                         }
2241
2242                         if (!netlogon_creds_client_check(creds, &return_authenticator.cred)) {
2243                                 torture_comment(tctx, "Credential chaining failed\n");
2244                                 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
2245                                         return false;
2246                                 }
2247                         }
2248                 }
2249         }
2250         }
2251
2252         return true;
2253 }
2254
2255 /*
2256   try a netlogon AccountDeltas
2257 */
2258 static bool test_AccountDeltas(struct torture_context *tctx,
2259                                struct dcerpc_pipe *p,
2260                                struct cli_credentials *machine_credentials)
2261 {
2262         struct netr_AccountDeltas r;
2263         struct netlogon_creds_CredentialState *creds;
2264
2265         struct netr_AccountBuffer buffer;
2266         uint32_t count_returned = 0;
2267         uint32_t total_entries = 0;
2268         struct netr_UAS_INFO_0 recordid;
2269         struct netr_Authenticator return_authenticator;
2270         struct dcerpc_binding_handle *b = p->binding_handle;
2271
2272         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
2273                 return false;
2274         }
2275
2276         ZERO_STRUCT(return_authenticator);
2277
2278         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2279         r.in.computername = TEST_MACHINE_NAME;
2280         r.in.return_authenticator = &return_authenticator;
2281         netlogon_creds_client_authenticator(creds, &r.in.credential);
2282         ZERO_STRUCT(r.in.uas);
2283         r.in.count=10;
2284         r.in.level=0;
2285         r.in.buffersize=100;
2286         r.out.buffer = &buffer;
2287         r.out.count_returned = &count_returned;
2288         r.out.total_entries = &total_entries;
2289         r.out.recordid = &recordid;
2290         r.out.return_authenticator = &return_authenticator;
2291
2292         /* w2k3 returns "NOT IMPLEMENTED" for this call */
2293         torture_assert_ntstatus_ok(tctx, dcerpc_netr_AccountDeltas_r(b, tctx, &r),
2294                 "AccountDeltas failed");
2295         torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_IMPLEMENTED, "AccountDeltas");
2296
2297         return true;
2298 }
2299
2300 /*
2301   try a netlogon AccountSync
2302 */
2303 static bool test_AccountSync(struct torture_context *tctx, struct dcerpc_pipe *p,
2304                              struct cli_credentials *machine_credentials)
2305 {
2306         struct netr_AccountSync r;
2307         struct netlogon_creds_CredentialState *creds;
2308
2309         struct netr_AccountBuffer buffer;
2310         uint32_t count_returned = 0;
2311         uint32_t total_entries = 0;
2312         uint32_t next_reference = 0;
2313         struct netr_UAS_INFO_0 recordid;
2314         struct netr_Authenticator return_authenticator;
2315         struct dcerpc_binding_handle *b = p->binding_handle;
2316
2317         ZERO_STRUCT(recordid);
2318         ZERO_STRUCT(return_authenticator);
2319
2320         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
2321                 return false;
2322         }
2323
2324         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2325         r.in.computername = TEST_MACHINE_NAME;
2326         r.in.return_authenticator = &return_authenticator;
2327         netlogon_creds_client_authenticator(creds, &r.in.credential);
2328         r.in.recordid = &recordid;
2329         r.in.reference=0;
2330         r.in.level=0;
2331         r.in.buffersize=100;
2332         r.out.buffer = &buffer;
2333         r.out.count_returned = &count_returned;
2334         r.out.total_entries = &total_entries;
2335         r.out.next_reference = &next_reference;
2336         r.out.recordid = &recordid;
2337         r.out.return_authenticator = &return_authenticator;
2338
2339         /* w2k3 returns "NOT IMPLEMENTED" for this call */
2340         torture_assert_ntstatus_ok(tctx, dcerpc_netr_AccountSync_r(b, tctx, &r),
2341                 "AccountSync failed");
2342         torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_IMPLEMENTED, "AccountSync");
2343
2344         return true;
2345 }
2346
2347 /*
2348   try a netlogon GetDcName
2349 */
2350 static bool test_GetDcName(struct torture_context *tctx,
2351                            struct dcerpc_pipe *p)
2352 {
2353         struct netr_GetDcName r;
2354         const char *dcname = NULL;
2355         struct dcerpc_binding_handle *b = p->binding_handle;
2356
2357         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2358         r.in.domainname = lpcfg_workgroup(tctx->lp_ctx);
2359         r.out.dcname = &dcname;
2360
2361         torture_assert_ntstatus_ok(tctx, dcerpc_netr_GetDcName_r(b, tctx, &r),
2362                 "GetDcName failed");
2363         torture_assert_werr_ok(tctx, r.out.result, "GetDcName failed");
2364
2365         torture_comment(tctx, "\tDC is at '%s'\n", dcname);
2366
2367         return true;
2368 }
2369
2370 static const char *function_code_str(TALLOC_CTX *mem_ctx,
2371                                      enum netr_LogonControlCode function_code)
2372 {
2373         switch (function_code) {
2374         case NETLOGON_CONTROL_QUERY:
2375                 return "NETLOGON_CONTROL_QUERY";
2376         case NETLOGON_CONTROL_REPLICATE:
2377                 return "NETLOGON_CONTROL_REPLICATE";
2378         case NETLOGON_CONTROL_SYNCHRONIZE:
2379                 return "NETLOGON_CONTROL_SYNCHRONIZE";
2380         case NETLOGON_CONTROL_PDC_REPLICATE:
2381                 return "NETLOGON_CONTROL_PDC_REPLICATE";
2382         case NETLOGON_CONTROL_REDISCOVER:
2383                 return "NETLOGON_CONTROL_REDISCOVER";
2384         case NETLOGON_CONTROL_TC_QUERY:
2385                 return "NETLOGON_CONTROL_TC_QUERY";
2386         case NETLOGON_CONTROL_TRANSPORT_NOTIFY:
2387                 return "NETLOGON_CONTROL_TRANSPORT_NOTIFY";
2388         case NETLOGON_CONTROL_FIND_USER:
2389                 return "NETLOGON_CONTROL_FIND_USER";
2390         case NETLOGON_CONTROL_CHANGE_PASSWORD:
2391                 return "NETLOGON_CONTROL_CHANGE_PASSWORD";
2392         case NETLOGON_CONTROL_TC_VERIFY:
2393                 return "NETLOGON_CONTROL_TC_VERIFY";
2394         case NETLOGON_CONTROL_FORCE_DNS_REG:
2395                 return "NETLOGON_CONTROL_FORCE_DNS_REG";
2396         case NETLOGON_CONTROL_QUERY_DNS_REG:
2397                 return "NETLOGON_CONTROL_QUERY_DNS_REG";
2398         case NETLOGON_CONTROL_BACKUP_CHANGE_LOG:
2399                 return "NETLOGON_CONTROL_BACKUP_CHANGE_LOG";
2400         case NETLOGON_CONTROL_TRUNCATE_LOG:
2401                 return "NETLOGON_CONTROL_TRUNCATE_LOG";
2402         case NETLOGON_CONTROL_SET_DBFLAG:
2403                 return "NETLOGON_CONTROL_SET_DBFLAG";
2404         case NETLOGON_CONTROL_BREAKPOINT:
2405                 return "NETLOGON_CONTROL_BREAKPOINT";
2406         default:
2407                 return talloc_asprintf(mem_ctx, "unknown function code: %d",
2408                                        function_code);
2409         }
2410 }
2411
2412
2413 /*
2414   try a netlogon LogonControl
2415 */
2416 static bool test_LogonControl(struct torture_context *tctx,
2417                               struct dcerpc_pipe *p,
2418                               struct cli_credentials *machine_credentials)
2419
2420 {
2421         NTSTATUS status;
2422         struct netr_LogonControl r;
2423         union netr_CONTROL_QUERY_INFORMATION query;
2424         int i,f;
2425         enum netr_SchannelType secure_channel_type = SEC_CHAN_NULL;
2426         struct dcerpc_binding_handle *b = p->binding_handle;
2427
2428         uint32_t function_codes[] = {
2429                 NETLOGON_CONTROL_QUERY,
2430                 NETLOGON_CONTROL_REPLICATE,
2431                 NETLOGON_CONTROL_SYNCHRONIZE,
2432                 NETLOGON_CONTROL_PDC_REPLICATE,
2433                 NETLOGON_CONTROL_REDISCOVER,
2434                 NETLOGON_CONTROL_TC_QUERY,
2435                 NETLOGON_CONTROL_TRANSPORT_NOTIFY,
2436                 NETLOGON_CONTROL_FIND_USER,
2437                 NETLOGON_CONTROL_CHANGE_PASSWORD,
2438                 NETLOGON_CONTROL_TC_VERIFY,
2439                 NETLOGON_CONTROL_FORCE_DNS_REG,
2440                 NETLOGON_CONTROL_QUERY_DNS_REG,
2441                 NETLOGON_CONTROL_BACKUP_CHANGE_LOG,
2442                 NETLOGON_CONTROL_TRUNCATE_LOG,
2443                 NETLOGON_CONTROL_SET_DBFLAG,
2444                 NETLOGON_CONTROL_BREAKPOINT
2445         };
2446
2447         if (machine_credentials) {
2448                 secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
2449         }
2450
2451         torture_comment(tctx, "Testing LogonControl with secure channel type: %d\n",
2452                 secure_channel_type);
2453
2454         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2455         r.in.function_code = 1;
2456         r.out.query = &query;
2457
2458         for (f=0;f<ARRAY_SIZE(function_codes); f++) {
2459         for (i=1;i<5;i++) {
2460
2461                 r.in.function_code = function_codes[f];
2462                 r.in.level = i;
2463
2464                 torture_comment(tctx, "Testing LogonControl function code %s (%d) level %d\n",
2465                                 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2466
2467                 status = dcerpc_netr_LogonControl_r(b, tctx, &r);
2468                 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
2469
2470                 switch (r.in.level) {
2471                 case 1:
2472                         switch (r.in.function_code) {
2473                         case NETLOGON_CONTROL_REPLICATE:
2474                         case NETLOGON_CONTROL_SYNCHRONIZE:
2475                         case NETLOGON_CONTROL_PDC_REPLICATE:
2476                         case NETLOGON_CONTROL_BREAKPOINT:
2477                         case NETLOGON_CONTROL_BACKUP_CHANGE_LOG:
2478                                 if ((secure_channel_type == SEC_CHAN_BDC) ||
2479                                     (secure_channel_type == SEC_CHAN_WKSTA)) {
2480                                         torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED,
2481                                                 "LogonControl returned unexpected error code");
2482                                 } else {
2483                                         torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
2484                                                 "LogonControl returned unexpected error code");
2485                                 }
2486                                 break;
2487
2488                         case NETLOGON_CONTROL_REDISCOVER:
2489                         case NETLOGON_CONTROL_TC_QUERY:
2490                         case NETLOGON_CONTROL_TRANSPORT_NOTIFY:
2491                         case NETLOGON_CONTROL_FIND_USER:
2492                         case NETLOGON_CONTROL_CHANGE_PASSWORD:
2493                         case NETLOGON_CONTROL_TC_VERIFY:
2494                         case NETLOGON_CONTROL_FORCE_DNS_REG:
2495                         case NETLOGON_CONTROL_QUERY_DNS_REG:
2496                         case NETLOGON_CONTROL_SET_DBFLAG:
2497                                 torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
2498                                         "LogonControl returned unexpected error code");
2499                                 break;
2500                         case NETLOGON_CONTROL_TRUNCATE_LOG:
2501                                 if ((secure_channel_type == SEC_CHAN_BDC) ||
2502                                     (secure_channel_type == SEC_CHAN_WKSTA)) {
2503                                         torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED,
2504                                                 "LogonControl returned unexpected error code");
2505                                 } else if (!W_ERROR_EQUAL(r.out.result, WERR_NOT_SUPPORTED)) {
2506                                         torture_assert_werr_ok(tctx, r.out.result,
2507                                                 "LogonControl returned unexpected result");
2508                                 }
2509                                 break;
2510                         default:
2511                                 torture_assert_werr_ok(tctx, r.out.result,
2512                                         "LogonControl returned unexpected result");
2513                                 break;
2514                         }
2515                         break;
2516                 case 2:
2517                         torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
2518                                 "LogonControl returned unexpected error code");
2519                         break;
2520                 default:
2521                         torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_LEVEL,
2522                                 "LogonControl returned unexpected error code");
2523                         break;
2524                 }
2525         }
2526         }
2527
2528         r.in.level = 52;
2529         torture_comment(tctx, "Testing LogonControl function code %s (%d) level %d\n",
2530                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2531         status = dcerpc_netr_LogonControl_r(b, tctx, &r);
2532         torture_assert_ntstatus_ok(tctx, status, "LogonControl");
2533         torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_LEVEL, "LogonControl");
2534
2535         return true;
2536 }
2537
2538
2539 /*
2540   try a netlogon GetAnyDCName
2541 */
2542 static bool test_GetAnyDCName(struct torture_context *tctx,
2543                               struct dcerpc_pipe *p)
2544 {
2545         NTSTATUS status;
2546         struct netr_GetAnyDCName r;
2547         const char *dcname = NULL;
2548         struct dcerpc_binding_handle *b = p->binding_handle;
2549
2550         r.in.domainname = lpcfg_workgroup(tctx->lp_ctx);
2551         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2552         r.out.dcname = &dcname;
2553
2554         status = dcerpc_netr_GetAnyDCName_r(b, tctx, &r);
2555         torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
2556         if ((!W_ERROR_IS_OK(r.out.result)) &&
2557             (!W_ERROR_EQUAL(r.out.result, WERR_NO_SUCH_DOMAIN))) {
2558                 return false;
2559         }
2560
2561         if (dcname) {
2562             torture_comment(tctx, "\tDC is at '%s'\n", dcname);
2563         }
2564
2565         r.in.domainname = NULL;
2566
2567         status = dcerpc_netr_GetAnyDCName_r(b, tctx, &r);
2568         torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
2569         if ((!W_ERROR_IS_OK(r.out.result)) &&
2570             (!W_ERROR_EQUAL(r.out.result, WERR_NO_SUCH_DOMAIN))) {
2571                 return false;
2572         }
2573
2574         r.in.domainname = "";
2575
2576         status = dcerpc_netr_GetAnyDCName_r(b, tctx, &r);
2577         torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
2578         if ((!W_ERROR_IS_OK(r.out.result)) &&
2579             (!W_ERROR_EQUAL(r.out.result, WERR_NO_SUCH_DOMAIN))) {
2580                 return false;
2581         }
2582
2583         return true;
2584 }
2585
2586
2587 /*
2588   try a netlogon LogonControl2
2589 */
2590 static bool test_LogonControl2(struct torture_context *tctx,
2591                                struct dcerpc_pipe *p,
2592                                struct cli_credentials *machine_credentials)
2593
2594 {
2595         NTSTATUS status;
2596         struct netr_LogonControl2 r;
2597         union netr_CONTROL_DATA_INFORMATION data;
2598         union netr_CONTROL_QUERY_INFORMATION query;
2599         enum netr_SchannelType secure_channel_type = SEC_CHAN_NULL;
2600         int i;
2601         struct dcerpc_binding_handle *b = p->binding_handle;
2602
2603         data.domain = lpcfg_workgroup(tctx->lp_ctx);
2604
2605         if (machine_credentials) {
2606                 secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
2607         }
2608
2609         torture_comment(tctx, "Testing LogonControl2 with secure channel type: %d\n",
2610                 secure_channel_type);
2611
2612         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2613
2614         r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
2615         r.in.data = &data;
2616         r.out.query = &query;
2617
2618         for (i=1;i<4;i++) {
2619                 r.in.level = i;
2620
2621                 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
2622                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2623
2624                 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
2625                 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
2626         }
2627
2628         data.domain = lpcfg_workgroup(tctx->lp_ctx);
2629
2630         r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
2631         r.in.data = &data;
2632
2633         for (i=1;i<4;i++) {
2634                 r.in.level = i;
2635
2636                 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
2637                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2638
2639                 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
2640                 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
2641         }
2642
2643         data.domain = lpcfg_workgroup(tctx->lp_ctx);
2644
2645         r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
2646         r.in.data = &data;
2647
2648         for (i=1;i<4;i++) {
2649                 r.in.level = i;
2650
2651                 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
2652                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2653
2654                 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
2655                 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
2656         }
2657
2658         data.debug_level = ~0;
2659
2660         r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
2661         r.in.data = &data;
2662
2663         for (i=1;i<4;i++) {
2664                 r.in.level = i;
2665
2666                 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
2667                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2668
2669                 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
2670                 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
2671         }
2672
2673         ZERO_STRUCT(data);
2674         r.in.function_code = 52;
2675         r.in.data = &data;
2676
2677         torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
2678                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2679
2680         status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
2681         torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
2682         switch (secure_channel_type) {
2683         case SEC_CHAN_NULL:
2684                 torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED, "LogonControl2");
2685                 break;
2686         default:
2687                 torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED, "LogonControl2");
2688                 break;
2689         }
2690         data.debug_level = ~0;
2691
2692         r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
2693         r.in.data = &data;
2694
2695         r.in.level = 52;
2696         torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
2697                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2698
2699         status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
2700         torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
2701         torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_LEVEL, "LogonControl2");
2702
2703         return true;
2704 }
2705
2706 /*
2707   try a netlogon DatabaseSync2
2708 */
2709 static bool test_DatabaseSync2(struct torture_context *tctx,
2710                                struct dcerpc_pipe *p,
2711                                struct cli_credentials *machine_credentials)
2712 {
2713         struct netr_DatabaseSync2 r;
2714         struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
2715         struct netr_Authenticator return_authenticator, credential;
2716
2717         struct netlogon_creds_CredentialState *creds;
2718         const uint32_t database_ids[] = {0, 1, 2};
2719         int i;
2720         struct dcerpc_binding_handle *b = p->binding_handle;
2721
2722         if (!test_SetupCredentials2(p, tctx, NETLOGON_NEG_AUTH2_FLAGS,
2723                                     machine_credentials,
2724                                     cli_credentials_get_secure_channel_type(machine_credentials),
2725                                     &creds)) {
2726                 return false;
2727         }
2728
2729         ZERO_STRUCT(return_authenticator);
2730
2731         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2732         r.in.computername = TEST_MACHINE_NAME;
2733         r.in.preferredmaximumlength = (uint32_t)-1;
2734         r.in.return_authenticator = &return_authenticator;
2735         r.out.return_authenticator = &return_authenticator;
2736         r.out.delta_enum_array = &delta_enum_array;
2737
2738         for (i=0;i<ARRAY_SIZE(database_ids);i++) {
2739
2740                 uint32_t sync_context = 0;
2741
2742                 r.in.database_id = database_ids[i];
2743                 r.in.sync_context = &sync_context;
2744                 r.out.sync_context = &sync_context;
2745                 r.in.restart_state = 0;
2746
2747                 torture_comment(tctx, "Testing DatabaseSync2 of id %d\n", r.in.database_id);
2748
2749                 do {
2750                         netlogon_creds_client_authenticator(creds, &credential);
2751
2752                         r.in.credential = &credential;
2753
2754                         torture_assert_ntstatus_ok(tctx, dcerpc_netr_DatabaseSync2_r(b, tctx, &r),
2755                                 "DatabaseSync2 failed");
2756                         if (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES))
2757                             break;
2758
2759                         /* Native mode servers don't do this */
2760                         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_SUPPORTED)) {
2761                                 return true;
2762                         }
2763
2764                         torture_assert_ntstatus_ok(tctx, r.out.result, "DatabaseSync2");
2765
2766                         if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
2767                                 torture_comment(tctx, "Credential chaining failed\n");
2768                         }
2769
2770                 } while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES));
2771         }
2772
2773         return true;
2774 }
2775
2776
2777 /*
2778   try a netlogon LogonControl2Ex
2779 */
2780 static bool test_LogonControl2Ex(struct torture_context *tctx,
2781                                  struct dcerpc_pipe *p,
2782                                  struct cli_credentials *machine_credentials)
2783
2784 {
2785         NTSTATUS status;
2786         struct netr_LogonControl2Ex r;
2787         union netr_CONTROL_DATA_INFORMATION data;
2788         union netr_CONTROL_QUERY_INFORMATION query;
2789         enum netr_SchannelType secure_channel_type = SEC_CHAN_NULL;
2790         int i;
2791         struct dcerpc_binding_handle *b = p->binding_handle;
2792
2793         data.domain = lpcfg_workgroup(tctx->lp_ctx);
2794
2795         if (machine_credentials) {
2796                 secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
2797         }
2798
2799         torture_comment(tctx, "Testing LogonControl2Ex with secure channel type: %d\n",
2800                 secure_channel_type);
2801
2802         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2803
2804         r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
2805         r.in.data = &data;
2806         r.out.query = &query;
2807
2808         for (i=1;i<4;i++) {
2809                 r.in.level = i;
2810
2811                 torture_comment(tctx, "Testing LogonControl2Ex function code %s (%d) level %d\n",
2812                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2813
2814                 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
2815                 torture_assert_ntstatus_ok(tctx, status, "LogonControl2Ex");
2816         }
2817
2818         data.domain = lpcfg_workgroup(tctx->lp_ctx);
2819
2820         r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
2821         r.in.data = &data;
2822
2823         for (i=1;i<4;i++) {
2824                 r.in.level = i;
2825
2826                 torture_comment(tctx, "Testing LogonControl2Ex function code %s (%d) level %d\n",
2827                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2828
2829                 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
2830                 torture_assert_ntstatus_ok(tctx, status, "LogonControl2Ex");
2831         }
2832
2833         data.domain = lpcfg_workgroup(tctx->lp_ctx);
2834
2835         r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
2836         r.in.data = &data;
2837
2838         for (i=1;i<4;i++) {
2839                 r.in.level = i;
2840
2841                 torture_comment(tctx, "Testing LogonControl2Ex function code %s (%d) level %d\n",
2842                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2843
2844                 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
2845                 torture_assert_ntstatus_ok(tctx, status, "LogonControl2Ex");
2846         }
2847
2848         data.debug_level = ~0;
2849
2850         r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
2851         r.in.data = &data;
2852
2853         for (i=1;i<4;i++) {
2854                 r.in.level = i;
2855
2856                 torture_comment(tctx, "Testing LogonControl2Ex 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