455fce611aed8f3296d6bec83443c3e4571576b6
[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(cmdline_credentials);
111         r.in.workstation = TEST_MACHINE_NAME;
112         r.out.info = &info;
113
114         status = dcerpc_netr_LogonUasLogon_r(b, tctx, &r);
115         torture_assert_ntstatus_ok(tctx, status, "LogonUasLogon");
116
117         return true;
118 }
119
120 static bool test_LogonUasLogoff(struct torture_context *tctx,
121                                 struct dcerpc_pipe *p)
122 {
123         NTSTATUS status;
124         struct netr_LogonUasLogoff r;
125         struct netr_UasLogoffInfo info;
126         struct dcerpc_binding_handle *b = p->binding_handle;
127
128         r.in.server_name = NULL;
129         r.in.account_name = cli_credentials_get_username(cmdline_credentials);
130         r.in.workstation = TEST_MACHINE_NAME;
131         r.out.info = &info;
132
133         status = dcerpc_netr_LogonUasLogoff_r(b, tctx, &r);
134         torture_assert_ntstatus_ok(tctx, status, "LogonUasLogoff");
135
136         return true;
137 }
138
139 bool test_SetupCredentials(struct dcerpc_pipe *p, struct torture_context *tctx,
140                                   struct cli_credentials *credentials,
141                                   struct netlogon_creds_CredentialState **creds_out)
142 {
143         struct netr_ServerReqChallenge r;
144         struct netr_ServerAuthenticate a;
145         struct netr_Credential credentials1, credentials2, credentials3;
146         struct netlogon_creds_CredentialState *creds;
147         const struct samr_Password *mach_password;
148         const char *machine_name;
149         struct dcerpc_binding_handle *b = p->binding_handle;
150
151         mach_password = cli_credentials_get_nt_hash(credentials, tctx);
152         machine_name = cli_credentials_get_workstation(credentials);
153
154         torture_comment(tctx, "Testing ServerReqChallenge\n");
155
156         r.in.server_name = NULL;
157         r.in.computer_name = machine_name;
158         r.in.credentials = &credentials1;
159         r.out.return_credentials = &credentials2;
160
161         generate_random_buffer(credentials1.data, sizeof(credentials1.data));
162
163         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
164                 "ServerReqChallenge failed");
165         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
166
167         a.in.server_name = NULL;
168         a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
169         a.in.secure_channel_type = cli_credentials_get_secure_channel_type(credentials);
170         a.in.computer_name = machine_name;
171         a.in.credentials = &credentials3;
172         a.out.return_credentials = &credentials3;
173
174         creds = netlogon_creds_client_init(tctx, a.in.account_name,
175                                            a.in.computer_name,
176                                            a.in.secure_channel_type,
177                                            &credentials1, &credentials2,
178                                            mach_password, &credentials3,
179                                            0);
180         torture_assert(tctx, creds != NULL, "memory allocation");
181
182
183         torture_comment(tctx, "Testing ServerAuthenticate\n");
184
185         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate_r(b, tctx, &a),
186                 "ServerAuthenticate failed");
187
188         /* This allows the tests to continue against the more fussy windows 2008 */
189         if (NT_STATUS_EQUAL(a.out.result, NT_STATUS_DOWNGRADE_DETECTED)) {
190                 return test_SetupCredentials2(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
191                                               credentials,
192                                               cli_credentials_get_secure_channel_type(credentials),
193                                               creds_out);
194         }
195
196         torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate");
197
198         torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3),
199                        "Credential chaining failed");
200
201         *creds_out = creds;
202         return true;
203 }
204
205 bool test_SetupCredentials2ex(struct dcerpc_pipe *p, struct torture_context *tctx,
206                               uint32_t negotiate_flags,
207                               struct cli_credentials *machine_credentials,
208                               const char *computer_name,
209                               enum netr_SchannelType sec_chan_type,
210                               NTSTATUS expected_result,
211                               struct netlogon_creds_CredentialState **creds_out)
212 {
213         struct netr_ServerReqChallenge r;
214         struct netr_ServerAuthenticate2 a;
215         struct netr_Credential credentials1, credentials2, credentials3;
216         struct netlogon_creds_CredentialState *creds;
217         const struct samr_Password *mach_password;
218         struct dcerpc_binding_handle *b = p->binding_handle;
219         const char *account_name = cli_credentials_get_username(machine_credentials);
220
221         mach_password = cli_credentials_get_nt_hash(machine_credentials, tctx);
222
223         torture_comment(tctx, "Testing ServerReqChallenge\n");
224
225         r.in.server_name = NULL;
226         r.in.computer_name = computer_name;
227         r.in.credentials = &credentials1;
228         r.out.return_credentials = &credentials2;
229
230         generate_random_buffer(credentials1.data, sizeof(credentials1.data));
231
232         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
233                 "ServerReqChallenge failed");
234         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
235
236         a.in.server_name = NULL;
237         a.in.account_name = account_name;
238         a.in.secure_channel_type = sec_chan_type;
239         a.in.computer_name = computer_name;
240         a.in.negotiate_flags = &negotiate_flags;
241         a.out.negotiate_flags = &negotiate_flags;
242         a.in.credentials = &credentials3;
243         a.out.return_credentials = &credentials3;
244
245         creds = netlogon_creds_client_init(tctx, a.in.account_name,
246                                            a.in.computer_name,
247                                            a.in.secure_channel_type,
248                                            &credentials1, &credentials2,
249                                            mach_password, &credentials3,
250                                            negotiate_flags);
251
252         torture_assert(tctx, creds != NULL, "memory allocation");
253
254         torture_comment(tctx, "Testing ServerAuthenticate2\n");
255
256         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate2_r(b, tctx, &a),
257                 "ServerAuthenticate2 failed");
258         torture_assert_ntstatus_equal(tctx, a.out.result, expected_result,
259                                       "ServerAuthenticate2 unexpected");
260
261         if (NT_STATUS_IS_OK(expected_result)) {
262                 torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3),
263                                "Credential chaining failed");
264         } else {
265                 torture_assert(tctx, !netlogon_creds_client_check(creds, &credentials3),
266                                "Credential chaining passed unexptected");
267         }
268
269         torture_comment(tctx, "negotiate_flags=0x%08x\n", negotiate_flags);
270
271         *creds_out = creds;
272         return true;
273 }
274
275 bool test_SetupCredentials2(struct dcerpc_pipe *p, struct torture_context *tctx,
276                             uint32_t negotiate_flags,
277                             struct cli_credentials *machine_credentials,
278                             enum netr_SchannelType sec_chan_type,
279                             struct netlogon_creds_CredentialState **creds_out)
280 {
281         const char *computer_name =
282                 cli_credentials_get_workstation(machine_credentials);
283
284         return test_SetupCredentials2ex(p, tctx, negotiate_flags,
285                                         machine_credentials,
286                                         computer_name,
287                                         sec_chan_type,
288                                         NT_STATUS_OK,
289                                         creds_out);
290 }
291
292 bool test_SetupCredentials3(struct dcerpc_pipe *p, struct torture_context *tctx,
293                             uint32_t negotiate_flags,
294                             struct cli_credentials *machine_credentials,
295                             struct netlogon_creds_CredentialState **creds_out)
296 {
297         struct netr_ServerReqChallenge r;
298         struct netr_ServerAuthenticate3 a;
299         struct netr_Credential credentials1, credentials2, credentials3;
300         struct netlogon_creds_CredentialState *creds;
301         struct samr_Password mach_password;
302         uint32_t rid;
303         const char *machine_name;
304         const char *plain_pass;
305         struct dcerpc_binding_handle *b = p->binding_handle;
306
307         machine_name = cli_credentials_get_workstation(machine_credentials);
308         plain_pass = cli_credentials_get_password(machine_credentials);
309
310         torture_comment(tctx, "Testing ServerReqChallenge\n");
311
312         r.in.server_name = NULL;
313         r.in.computer_name = machine_name;
314         r.in.credentials = &credentials1;
315         r.out.return_credentials = &credentials2;
316
317         generate_random_buffer(credentials1.data, sizeof(credentials1.data));
318
319         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
320                 "ServerReqChallenge failed");
321         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
322
323         E_md4hash(plain_pass, mach_password.hash);
324
325         a.in.server_name = NULL;
326         a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
327         a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
328         a.in.computer_name = machine_name;
329         a.in.negotiate_flags = &negotiate_flags;
330         a.in.credentials = &credentials3;
331         a.out.return_credentials = &credentials3;
332         a.out.negotiate_flags = &negotiate_flags;
333         a.out.rid = &rid;
334
335         creds = netlogon_creds_client_init(tctx, a.in.account_name,
336                                            a.in.computer_name,
337                                            a.in.secure_channel_type,
338                                            &credentials1, &credentials2,
339                                            &mach_password, &credentials3,
340                                            negotiate_flags);
341
342         torture_assert(tctx, creds != NULL, "memory allocation");
343
344         torture_comment(tctx, "Testing ServerAuthenticate3\n");
345
346         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b, tctx, &a),
347                 "ServerAuthenticate3 failed");
348         torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate3 failed");
349         torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
350
351         torture_comment(tctx, "negotiate_flags=0x%08x\n", negotiate_flags);
352
353         /* Prove that requesting a challenge again won't break it */
354         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
355                 "ServerReqChallenge failed");
356         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
357
358         *creds_out = creds;
359         return true;
360 }
361
362 bool test_SetupCredentialsDowngrade(struct torture_context *tctx,
363                                         struct dcerpc_pipe *p,
364                                         struct cli_credentials *machine_credentials)
365 {
366         struct netr_ServerReqChallenge r;
367         struct netr_ServerAuthenticate3 a;
368         struct netr_Credential credentials1, credentials2, credentials3;
369         struct netlogon_creds_CredentialState *creds;
370         struct samr_Password mach_password;
371         uint32_t rid;
372         const char *machine_name;
373         const char *plain_pass;
374         struct dcerpc_binding_handle *b = p->binding_handle;
375         uint32_t negotiate_flags = 0;
376
377         machine_name = cli_credentials_get_workstation(machine_credentials);
378         plain_pass = cli_credentials_get_password(machine_credentials);
379
380         torture_comment(tctx, "Testing ServerReqChallenge\n");
381
382         r.in.server_name = NULL;
383         r.in.computer_name = machine_name;
384         r.in.credentials = &credentials1;
385         r.out.return_credentials = &credentials2;
386
387         generate_random_buffer(credentials1.data, sizeof(credentials1.data));
388
389         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
390                 "ServerReqChallenge failed");
391         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
392
393         E_md4hash(plain_pass, mach_password.hash);
394
395         a.in.server_name = NULL;
396         a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
397         a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
398         a.in.computer_name = machine_name;
399         a.in.negotiate_flags = &negotiate_flags;
400         a.in.credentials = &credentials3;
401         a.out.return_credentials = &credentials3;
402         a.out.negotiate_flags = &negotiate_flags;
403         a.out.rid = &rid;
404
405         creds = netlogon_creds_client_init(tctx, a.in.account_name,
406                                            a.in.computer_name,
407                                            a.in.secure_channel_type,
408                                            &credentials1, &credentials2,
409                                            &mach_password, &credentials3,
410                                            negotiate_flags);
411
412         torture_assert(tctx, creds != NULL, "memory allocation");
413
414         torture_comment(tctx, "Testing ServerAuthenticate3\n");
415
416         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b, tctx, &a),
417                 "ServerAuthenticate3 failed");
418         torture_assert_ntstatus_equal(tctx, a.out.result, NT_STATUS_DOWNGRADE_DETECTED, "ServerAuthenticate3 should have failed");
419
420         negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
421         creds = netlogon_creds_client_init(tctx, a.in.account_name,
422                                            a.in.computer_name,
423                                            a.in.secure_channel_type,
424                                            &credentials1, &credentials2,
425                                            &mach_password, &credentials3,
426                                            negotiate_flags);
427
428         torture_assert(tctx, creds != NULL, "memory allocation");
429
430         torture_comment(tctx, "Testing ServerAuthenticate3\n");
431
432         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b, tctx, &a),
433                 "ServerAuthenticate3 failed");
434         torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate3 should succeed");
435
436         torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
437
438         torture_comment(tctx, "negotiate_flags=0x%08x\n", negotiate_flags);
439
440         /* Prove that requesting a challenge again won't break it */
441         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
442                 "ServerReqChallenge failed");
443         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
444
445         return true;
446 }
447
448 bool test_SetupCredentialsPipe(const struct dcerpc_pipe *p1,
449                                struct torture_context *tctx,
450                                struct cli_credentials *machine_credentials,
451                                struct netlogon_creds_CredentialState *creds,
452                                uint32_t additional_flags,
453                                struct dcerpc_pipe **_p2)
454 {
455         NTSTATUS status;
456         struct dcerpc_binding *b2 = NULL;
457         struct dcerpc_pipe *p2 = NULL;
458
459         b2 = dcerpc_binding_dup(tctx, p1->binding);
460         torture_assert(tctx, b2 != NULL, "dcerpc_binding_dup");
461         dcerpc_binding_set_flags(b2,
462                                  DCERPC_SCHANNEL | additional_flags,
463                                  DCERPC_AUTH_OPTIONS);
464
465         cli_credentials_set_netlogon_creds(machine_credentials, creds);
466         status = dcerpc_pipe_connect_b(tctx, &p2, b2,
467                                        &ndr_table_netlogon,
468                                        machine_credentials,
469                                        tctx->ev, tctx->lp_ctx);
470         cli_credentials_set_netlogon_creds(machine_credentials, NULL);
471         torture_assert_ntstatus_ok(tctx, status, "dcerpc_pipe_connect_b schannel");
472
473         *_p2 = p2;
474         return true;
475 }
476
477 /*
478   try a change password for our machine account
479 */
480 static bool test_SetPassword(struct torture_context *tctx,
481                              struct dcerpc_pipe *p,
482                              struct cli_credentials *machine_credentials)
483 {
484         struct netr_ServerPasswordSet r;
485         const char *password;
486         struct netlogon_creds_CredentialState *creds;
487         struct netr_Authenticator credential, return_authenticator;
488         struct samr_Password new_password;
489         struct dcerpc_binding_handle *b = p->binding_handle;
490
491         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
492                 return false;
493         }
494
495         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
496         r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
497         r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
498         r.in.computer_name = TEST_MACHINE_NAME;
499         r.in.credential = &credential;
500         r.in.new_password = &new_password;
501         r.out.return_authenticator = &return_authenticator;
502
503         password = generate_random_password(tctx, 8, 255);
504         E_md4hash(password, new_password.hash);
505
506         netlogon_creds_des_encrypt(creds, &new_password);
507
508         torture_comment(tctx, "Testing ServerPasswordSet on machine account\n");
509         torture_comment(tctx, "Changing machine account password to '%s'\n",
510                         password);
511
512         netlogon_creds_client_authenticator(creds, &credential);
513
514         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet_r(b, tctx, &r),
515                 "ServerPasswordSet failed");
516         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet failed");
517
518         if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
519                 torture_comment(tctx, "Credential chaining failed\n");
520         }
521
522         /* by changing the machine password twice we test the
523            credentials chaining fully, and we verify that the server
524            allows the password to be set to the same value twice in a
525            row (match win2k3) */
526         torture_comment(tctx,
527                 "Testing a second ServerPasswordSet on machine account\n");
528         torture_comment(tctx,
529                 "Changing machine account password to '%s' (same as previous run)\n", password);
530
531         netlogon_creds_client_authenticator(creds, &credential);
532
533         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet_r(b, tctx, &r),
534                 "ServerPasswordSet (2) failed");
535         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet (2) failed");
536
537         if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
538                 torture_comment(tctx, "Credential chaining failed\n");
539         }
540
541         cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
542
543         torture_assert(tctx,
544                 test_SetupCredentials(p, tctx, machine_credentials, &creds),
545                 "ServerPasswordSet failed to actually change the password");
546
547         return true;
548 }
549
550 /*
551   try a change password for our machine account
552 */
553 static bool test_SetPassword_flags(struct torture_context *tctx,
554                                    struct dcerpc_pipe *p1,
555                                    struct cli_credentials *machine_credentials,
556                                    uint32_t negotiate_flags)
557 {
558         struct netr_ServerPasswordSet r;
559         const char *password;
560         struct netlogon_creds_CredentialState *creds;
561         struct netr_Authenticator credential, return_authenticator;
562         struct samr_Password new_password;
563         struct dcerpc_pipe *p = NULL;
564         struct dcerpc_binding_handle *b = NULL;
565
566         if (!test_SetupCredentials2(p1, tctx, negotiate_flags,
567                                     machine_credentials,
568                                     cli_credentials_get_secure_channel_type(machine_credentials),
569                                     &creds)) {
570                 return false;
571         }
572         if (!test_SetupCredentialsPipe(p1, tctx, machine_credentials, creds,
573                                        DCERPC_SIGN | DCERPC_SEAL, &p)) {
574                 return false;
575         }
576         b = p->binding_handle;
577
578         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
579         r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
580         r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
581         r.in.computer_name = TEST_MACHINE_NAME;
582         r.in.credential = &credential;
583         r.in.new_password = &new_password;
584         r.out.return_authenticator = &return_authenticator;
585
586         password = generate_random_password(tctx, 8, 255);
587         E_md4hash(password, new_password.hash);
588
589         netlogon_creds_des_encrypt(creds, &new_password);
590
591         torture_comment(tctx, "Testing ServerPasswordSet on machine account\n");
592         torture_comment(tctx, "Changing machine account password to '%s'\n",
593                         password);
594
595         netlogon_creds_client_authenticator(creds, &credential);
596
597         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet_r(b, tctx, &r),
598                 "ServerPasswordSet failed");
599         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet failed");
600
601         if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
602                 torture_comment(tctx, "Credential chaining failed\n");
603         }
604
605         /* by changing the machine password twice we test the
606            credentials chaining fully, and we verify that the server
607            allows the password to be set to the same value twice in a
608            row (match win2k3) */
609         torture_comment(tctx,
610                 "Testing a second ServerPasswordSet on machine account\n");
611         torture_comment(tctx,
612                 "Changing machine account password to '%s' (same as previous run)\n", password);
613
614         netlogon_creds_client_authenticator(creds, &credential);
615
616         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet_r(b, tctx, &r),
617                 "ServerPasswordSet (2) failed");
618         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet (2) failed");
619
620         if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
621                 torture_comment(tctx, "Credential chaining failed\n");
622         }
623
624         cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
625
626         torture_assert(tctx,
627                 test_SetupCredentials(p, tctx, machine_credentials, &creds),
628                 "ServerPasswordSet failed to actually change the password");
629
630         return true;
631 }
632
633
634 /*
635   generate a random password for password change tests
636 */
637 static DATA_BLOB netlogon_very_rand_pass(TALLOC_CTX *mem_ctx, int len)
638 {
639         int i;
640         DATA_BLOB password = data_blob_talloc(mem_ctx, NULL, len * 2 /* number of unicode chars */);
641         generate_random_buffer(password.data, password.length);
642
643         for (i=0; i < len; i++) {
644                 if (((uint16_t *)password.data)[i] == 0) {
645                         ((uint16_t *)password.data)[i] = 1;
646                 }
647         }
648
649         return password;
650 }
651
652 /*
653   try a change password for our machine account
654 */
655 static bool test_SetPassword2_with_flags(struct torture_context *tctx,
656                                          struct dcerpc_pipe *p1,
657                                          struct cli_credentials *machine_credentials,
658                                          uint32_t flags)
659 {
660         struct netr_ServerPasswordSet2 r;
661         const char *password;
662         DATA_BLOB new_random_pass;
663         struct netlogon_creds_CredentialState *creds;
664         struct samr_CryptPassword password_buf;
665         struct samr_Password nt_hash;
666         struct netr_Authenticator credential, return_authenticator;
667         struct netr_CryptPassword new_password;
668         struct dcerpc_pipe *p = NULL;
669         struct dcerpc_binding_handle *b = NULL;
670
671         if (!test_SetupCredentials2(p1, tctx, flags, machine_credentials,
672                                     cli_credentials_get_secure_channel_type(machine_credentials),
673                                     &creds)) {
674                 return false;
675         }
676         if (!test_SetupCredentialsPipe(p1, tctx, machine_credentials, creds,
677                                        DCERPC_SIGN | DCERPC_SEAL, &p)) {
678                 return false;
679         }
680         b = p->binding_handle;
681
682         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
683         r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
684         r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
685         r.in.computer_name = TEST_MACHINE_NAME;
686         r.in.credential = &credential;
687         r.in.new_password = &new_password;
688         r.out.return_authenticator = &return_authenticator;
689
690         password = generate_random_password(tctx, 8, 255);
691         encode_pw_buffer(password_buf.data, password, STR_UNICODE);
692         if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
693                 netlogon_creds_aes_encrypt(creds, password_buf.data, 516);
694         } else {
695                 netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
696         }
697
698         memcpy(new_password.data, password_buf.data, 512);
699         new_password.length = IVAL(password_buf.data, 512);
700
701         torture_comment(tctx, "Testing ServerPasswordSet2 on machine account\n");
702         torture_comment(tctx, "Changing machine account password to '%s'\n", password);
703
704         netlogon_creds_client_authenticator(creds, &credential);
705
706         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
707                 "ServerPasswordSet2 failed");
708         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet2 failed");
709
710         if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
711                 torture_comment(tctx, "Credential chaining failed\n");
712         }
713
714         cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
715
716         if (!torture_setting_bool(tctx, "dangerous", false)) {
717                 torture_comment(tctx,
718                         "Not testing ability to set password to '', enable dangerous tests to perform this test\n");
719         } else {
720                 /* by changing the machine password to ""
721                  * we check if the server uses password restrictions
722                  * for ServerPasswordSet2
723                  * (win2k3 accepts "")
724                  */
725                 password = "";
726                 encode_pw_buffer(password_buf.data, password, STR_UNICODE);
727                 if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
728                         netlogon_creds_aes_encrypt(creds, password_buf.data, 516);
729                 } else {
730                         netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
731                 }
732                 memcpy(new_password.data, password_buf.data, 512);
733                 new_password.length = IVAL(password_buf.data, 512);
734
735                 torture_comment(tctx,
736                         "Testing ServerPasswordSet2 on machine account\n");
737                 torture_comment(tctx,
738                         "Changing machine account password to '%s'\n", password);
739
740                 netlogon_creds_client_authenticator(creds, &credential);
741
742                 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
743                         "ServerPasswordSet2 failed");
744                 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet2 failed");
745
746                 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
747                         torture_comment(tctx, "Credential chaining failed\n");
748                 }
749
750                 cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
751         }
752
753         torture_assert(tctx, test_SetupCredentials(p, tctx, machine_credentials, &creds),
754                 "ServerPasswordSet failed to actually change the password");
755
756         /* now try a random password */
757         password = generate_random_password(tctx, 8, 255);
758         encode_pw_buffer(password_buf.data, password, STR_UNICODE);
759         if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
760                 netlogon_creds_aes_encrypt(creds, password_buf.data, 516);
761         } else {
762                 netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
763         }
764         memcpy(new_password.data, password_buf.data, 512);
765         new_password.length = IVAL(password_buf.data, 512);
766
767         torture_comment(tctx, "Testing second ServerPasswordSet2 on machine account\n");
768         torture_comment(tctx, "Changing machine account password to '%s'\n", password);
769
770         netlogon_creds_client_authenticator(creds, &credential);
771
772         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
773                 "ServerPasswordSet2 (2) failed");
774         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet2 (2) failed");
775
776         if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
777                 torture_comment(tctx, "Credential chaining failed\n");
778         }
779
780         /* by changing the machine password twice we test the
781            credentials chaining fully, and we verify that the server
782            allows the password to be set to the same value twice in a
783            row (match win2k3) */
784         torture_comment(tctx,
785                 "Testing a second ServerPasswordSet2 on machine account\n");
786         torture_comment(tctx,
787                 "Changing machine account password to '%s' (same as previous run)\n", password);
788
789         netlogon_creds_client_authenticator(creds, &credential);
790
791         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
792                 "ServerPasswordSet (3) failed");
793         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet (3) failed");
794
795         if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
796                 torture_comment(tctx, "Credential chaining failed\n");
797         }
798
799         cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
800
801         torture_assert (tctx,
802                 test_SetupCredentials(p, tctx, machine_credentials, &creds),
803                 "ServerPasswordSet failed to actually change the password");
804
805         new_random_pass = netlogon_very_rand_pass(tctx, 128);
806
807         /* now try a random stream of bytes for a password */
808         set_pw_in_buffer(password_buf.data, &new_random_pass);
809
810         if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
811                 netlogon_creds_aes_encrypt(creds, password_buf.data, 516);
812         } else {
813                 netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
814         }
815
816         memcpy(new_password.data, password_buf.data, 512);
817         new_password.length = IVAL(password_buf.data, 512);
818
819         torture_comment(tctx,
820                 "Testing a third ServerPasswordSet2 on machine account, with a completely random password\n");
821
822         netlogon_creds_client_authenticator(creds, &credential);
823
824         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
825                 "ServerPasswordSet (3) failed");
826         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet (3) failed");
827
828         if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
829                 torture_comment(tctx, "Credential chaining failed\n");
830         }
831
832         mdfour(nt_hash.hash, new_random_pass.data, new_random_pass.length);
833
834         cli_credentials_set_password(machine_credentials, NULL, CRED_UNINITIALISED);
835         cli_credentials_set_nt_hash(machine_credentials, &nt_hash, CRED_SPECIFIED);
836
837         torture_assert (tctx,
838                 test_SetupCredentials(p, tctx, machine_credentials, &creds),
839                 "ServerPasswordSet failed to actually change the password");
840
841         return true;
842 }
843
844 static bool test_SetPassword2(struct torture_context *tctx,
845                               struct dcerpc_pipe *p,
846                               struct cli_credentials *machine_credentials)
847 {
848         return test_SetPassword2_with_flags(tctx, p, machine_credentials, NETLOGON_NEG_AUTH2_ADS_FLAGS);
849 }
850
851 static bool test_SetPassword2_AES(struct torture_context *tctx,
852                                   struct dcerpc_pipe *p,
853                                   struct cli_credentials *machine_credentials)
854 {
855         return test_SetPassword2_with_flags(tctx, p, machine_credentials, NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES);
856 }
857
858 static bool test_GetPassword(struct torture_context *tctx,
859                              struct dcerpc_pipe *p,
860                              struct cli_credentials *machine_credentials)
861 {
862         struct netr_ServerPasswordGet r;
863         struct netlogon_creds_CredentialState *creds;
864         struct netr_Authenticator credential;
865         NTSTATUS status;
866         struct netr_Authenticator return_authenticator;
867         struct samr_Password password;
868         struct dcerpc_binding_handle *b = p->binding_handle;
869
870         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
871                 return false;
872         }
873
874         netlogon_creds_client_authenticator(creds, &credential);
875
876         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
877         r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
878         r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
879         r.in.computer_name = TEST_MACHINE_NAME;
880         r.in.credential = &credential;
881         r.out.return_authenticator = &return_authenticator;
882         r.out.password = &password;
883
884         status = dcerpc_netr_ServerPasswordGet_r(b, tctx, &r);
885         torture_assert_ntstatus_ok(tctx, status, "ServerPasswordGet");
886         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordGet");
887
888         return true;
889 }
890
891 static bool test_GetTrustPasswords(struct torture_context *tctx,
892                                    struct dcerpc_pipe *p,
893                                    struct cli_credentials *machine_credentials)
894 {
895         struct netr_ServerTrustPasswordsGet r;
896         struct netlogon_creds_CredentialState *creds;
897         struct netr_Authenticator credential;
898         struct netr_Authenticator return_authenticator;
899         struct samr_Password password, password2;
900         struct dcerpc_binding_handle *b = p->binding_handle;
901
902         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
903                 return false;
904         }
905
906         netlogon_creds_client_authenticator(creds, &credential);
907
908         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
909         r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
910         r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
911         r.in.computer_name = TEST_MACHINE_NAME;
912         r.in.credential = &credential;
913         r.out.return_authenticator = &return_authenticator;
914         r.out.new_owf_password = &password;
915         r.out.old_owf_password = &password2;
916
917         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerTrustPasswordsGet_r(b, tctx, &r),
918                 "ServerTrustPasswordsGet failed");
919         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerTrustPasswordsGet failed");
920
921         return true;
922 }
923
924 /*
925   try a netlogon SamLogon
926 */
927 static bool test_netlogon_ops_args(struct dcerpc_pipe *p, struct torture_context *tctx,
928                                    struct cli_credentials *credentials,
929                                    struct netlogon_creds_CredentialState *creds,
930                                    bool null_domain)
931 {
932         NTSTATUS status;
933         struct netr_LogonSamLogon r;
934         struct netr_Authenticator auth, auth2;
935         union netr_LogonLevel logon;
936         union netr_Validation validation;
937         uint8_t authoritative;
938         struct netr_NetworkInfo ninfo;
939         DATA_BLOB names_blob, chal, lm_resp, nt_resp;
940         int i;
941         struct dcerpc_binding_handle *b = p->binding_handle;
942         int flags = CLI_CRED_NTLM_AUTH;
943         if (lpcfg_client_lanman_auth(tctx->lp_ctx)) {
944                 flags |= CLI_CRED_LANMAN_AUTH;
945         }
946
947         if (lpcfg_client_ntlmv2_auth(tctx->lp_ctx) && !null_domain) {
948                 flags |= CLI_CRED_NTLMv2_AUTH;
949         }
950
951         cli_credentials_get_ntlm_username_domain(cmdline_credentials, tctx,
952                                                  &ninfo.identity_info.account_name.string,
953                                                  &ninfo.identity_info.domain_name.string);
954
955         if (null_domain) {
956                 ninfo.identity_info.domain_name.string = NULL;
957         }
958
959         generate_random_buffer(ninfo.challenge,
960                                sizeof(ninfo.challenge));
961         chal = data_blob_const(ninfo.challenge,
962                                sizeof(ninfo.challenge));
963
964         names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(credentials),
965                                                 cli_credentials_get_domain(credentials));
966
967         status = cli_credentials_get_ntlm_response(cmdline_credentials, tctx,
968                                                    &flags,
969                                                    chal,
970                                                    NULL, /* server_timestamp */
971                                                    names_blob,
972                                                    &lm_resp, &nt_resp,
973                                                    NULL, NULL);
974         torture_assert_ntstatus_ok(tctx, status, "cli_credentials_get_ntlm_response failed");
975
976         ninfo.lm.data = lm_resp.data;
977         ninfo.lm.length = lm_resp.length;
978
979         ninfo.nt.data = nt_resp.data;
980         ninfo.nt.length = nt_resp.length;
981
982         ninfo.identity_info.parameter_control = 0;
983         ninfo.identity_info.logon_id_low = 0;
984         ninfo.identity_info.logon_id_high = 0;
985         ninfo.identity_info.workstation.string = cli_credentials_get_workstation(credentials);
986
987         logon.network = &ninfo;
988
989         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
990         r.in.computer_name = cli_credentials_get_workstation(credentials);
991         r.in.credential = &auth;
992         r.in.return_authenticator = &auth2;
993         r.in.logon_level = NetlogonNetworkInformation;
994         r.in.logon = &logon;
995         r.out.validation = &validation;
996         r.out.authoritative = &authoritative;
997
998         d_printf("Testing LogonSamLogon with name %s\n", ninfo.identity_info.account_name.string);
999
1000         for (i=2;i<=3;i++) {
1001                 ZERO_STRUCT(auth2);
1002                 netlogon_creds_client_authenticator(creds, &auth);
1003
1004                 r.in.validation_level = i;
1005
1006                 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
1007                         "LogonSamLogon failed");
1008                 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonSamLogon failed");
1009
1010                 torture_assert(tctx, netlogon_creds_client_check(creds,
1011                                                                  &r.out.return_authenticator->cred),
1012                         "Credential chaining failed");
1013                 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
1014                                          "LogonSamLogon invalid  *r.out.authoritative");
1015         }
1016
1017         /* this makes sure we get the unmarshalling right for invalid levels */
1018         for (i=52;i<53;i++) {
1019                 ZERO_STRUCT(auth2);
1020                 /* the authenticator should be ignored by the server */
1021                 generate_random_buffer((uint8_t *) &auth, sizeof(auth));
1022
1023                 r.in.validation_level = i;
1024
1025                 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
1026                                            "LogonSamLogon failed");
1027                 torture_assert_ntstatus_equal(tctx, r.out.result,
1028                                               NT_STATUS_INVALID_INFO_CLASS,
1029                                               "LogonSamLogon failed");
1030
1031                 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
1032                                          "LogonSamLogon invalid  *r.out.authoritative");
1033                 torture_assert(tctx,
1034                                all_zero((uint8_t *)&auth2, sizeof(auth2)),
1035                                "Return authenticator non zero");
1036         }
1037
1038         for (i=2;i<=3;i++) {
1039                 ZERO_STRUCT(auth2);
1040                 netlogon_creds_client_authenticator(creds, &auth);
1041
1042                 r.in.validation_level = i;
1043
1044                 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
1045                         "LogonSamLogon failed");
1046                 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonSamLogon failed");
1047
1048                 torture_assert(tctx, netlogon_creds_client_check(creds,
1049                                                                  &r.out.return_authenticator->cred),
1050                         "Credential chaining failed");
1051                 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
1052                                          "LogonSamLogon invalid  *r.out.authoritative");
1053         }
1054
1055         r.in.logon_level = 52;
1056
1057         for (i=2;i<=3;i++) {
1058                 ZERO_STRUCT(auth2);
1059                 /* the authenticator should be ignored by the server */
1060                 generate_random_buffer((uint8_t *) &auth, sizeof(auth));
1061
1062                 r.in.validation_level = i;
1063
1064                 torture_comment(tctx, "Testing SamLogon with validation level %d and a NULL credential\n", i);
1065
1066                 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
1067                         "LogonSamLogon failed");
1068                 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_INVALID_PARAMETER,
1069                         "LogonSamLogon expected INVALID_PARAMETER");
1070
1071                 torture_assert(tctx,
1072                                all_zero((uint8_t *)&auth2, sizeof(auth2)),
1073                                "Return authenticator non zero");
1074                 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
1075                                          "LogonSamLogon invalid  *r.out.authoritative");
1076         }
1077
1078         r.in.credential = NULL;
1079
1080         for (i=2;i<=3;i++) {
1081                 ZERO_STRUCT(auth2);
1082
1083                 r.in.validation_level = i;
1084
1085                 torture_comment(tctx, "Testing SamLogon with validation level %d and a NULL credential\n", i);
1086
1087                 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
1088                         "LogonSamLogon failed");
1089                 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_INVALID_PARAMETER,
1090                         "LogonSamLogon expected INVALID_PARAMETER");
1091
1092                 torture_assert(tctx,
1093                                all_zero((uint8_t *)&auth2, sizeof(auth2)),
1094                                "Return authenticator non zero");
1095                 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
1096                                          "LogonSamLogon invalid  *r.out.authoritative");
1097         }
1098
1099         r.in.logon_level = NetlogonNetworkInformation;
1100         r.in.credential = &auth;
1101
1102         for (i=2;i<=3;i++) {
1103                 ZERO_STRUCT(auth2);
1104                 netlogon_creds_client_authenticator(creds, &auth);
1105
1106                 r.in.validation_level = i;
1107
1108                 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
1109                         "LogonSamLogon failed");
1110                 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonSamLogon failed");
1111
1112                 torture_assert(tctx, netlogon_creds_client_check(creds,
1113                                                                  &r.out.return_authenticator->cred),
1114                         "Credential chaining failed");
1115                 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
1116                                          "LogonSamLogon invalid  *r.out.authoritative");
1117         }
1118
1119         return true;
1120 }
1121
1122 bool test_netlogon_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
1123                        struct cli_credentials *credentials,
1124                        struct netlogon_creds_CredentialState *creds)
1125 {
1126         return test_netlogon_ops_args(p, tctx, credentials, creds, false);
1127 }
1128
1129 /*
1130   try a netlogon GetCapabilities
1131 */
1132 bool test_netlogon_capabilities(struct dcerpc_pipe *p, struct torture_context *tctx,
1133                                 struct cli_credentials *credentials,
1134                                 struct netlogon_creds_CredentialState *creds)
1135 {
1136         NTSTATUS status;
1137         struct netr_LogonGetCapabilities r;
1138         union netr_Capabilities capabilities;
1139         struct netr_Authenticator auth, return_auth;
1140         struct netlogon_creds_CredentialState tmp_creds;
1141         struct dcerpc_binding_handle *b = p->binding_handle;
1142
1143         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1144         r.in.computer_name = cli_credentials_get_workstation(credentials);
1145         r.in.credential = &auth;
1146         r.in.return_authenticator = &return_auth;
1147         r.in.query_level = 1;
1148         r.out.capabilities = &capabilities;
1149         r.out.return_authenticator = &return_auth;
1150
1151         torture_comment(tctx, "Testing LogonGetCapabilities\n");
1152
1153         ZERO_STRUCT(return_auth);
1154
1155         /*
1156          * we need to operate on a temporary copy of creds
1157          * because dcerpc_netr_LogonGetCapabilities was
1158          * dcerpc_netr_DummyFunction and returns NT_STATUS_NOT_IMPLEMENTED
1159          * without looking a the authenticator.
1160          */
1161         tmp_creds = *creds;
1162         netlogon_creds_client_authenticator(&tmp_creds, &auth);
1163
1164         status = dcerpc_netr_LogonGetCapabilities_r(b, tctx, &r);
1165         torture_assert_ntstatus_ok(tctx, status, "LogonGetCapabilities failed");
1166         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_IMPLEMENTED)) {
1167                 return true;
1168         }
1169
1170         *creds = tmp_creds;
1171
1172         torture_assert(tctx, netlogon_creds_client_check(creds,
1173                                                          &r.out.return_authenticator->cred),
1174                        "Credential chaining failed");
1175
1176         torture_assert_int_equal(tctx, creds->negotiate_flags,
1177                                  capabilities.server_capabilities,
1178                                  "negotiate flags");
1179
1180         return true;
1181 }
1182
1183 /*
1184   try a netlogon SamLogon
1185 */
1186 static bool test_SamLogon(struct torture_context *tctx,
1187                           struct dcerpc_pipe *p,
1188                           struct cli_credentials *credentials)
1189 {
1190         struct netlogon_creds_CredentialState *creds;
1191
1192         if (!test_SetupCredentials(p, tctx, credentials, &creds)) {
1193                 return false;
1194         }
1195
1196         return test_netlogon_ops(p, tctx, credentials, creds);
1197 }
1198
1199 static bool test_invalidAuthenticate2(struct torture_context *tctx,
1200                                       struct dcerpc_pipe *p,
1201                                       struct cli_credentials *credentials)
1202 {
1203         struct netlogon_creds_CredentialState *creds;
1204         uint32_t flags = NETLOGON_NEG_AUTH2_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
1205
1206         torture_comment(tctx, "Testing invalidAuthenticate2\n");
1207
1208         if (!test_SetupCredentials2(p, tctx, flags,
1209                                     credentials,
1210                                     cli_credentials_get_secure_channel_type(credentials),
1211                                     &creds)) {
1212                 return false;
1213         }
1214
1215         if (!test_SetupCredentials2ex(p, tctx, flags,
1216                                       credentials,
1217                                       "1234567890123456",
1218                                       cli_credentials_get_secure_channel_type(credentials),
1219                                       STATUS_BUFFER_OVERFLOW,
1220                                       &creds)) {
1221                 return false;
1222         }
1223
1224         if (!test_SetupCredentials2ex(p, tctx, flags,
1225                                       credentials,
1226                                       "123456789012345",
1227                                       cli_credentials_get_secure_channel_type(credentials),
1228                                       NT_STATUS_OK,
1229                                       &creds)) {
1230                 return false;
1231         }
1232
1233         return true;
1234 }
1235
1236 static bool test_ServerReqChallengeGlobal(struct torture_context *tctx,
1237                                           struct dcerpc_pipe *p1,
1238                                           struct cli_credentials *machine_credentials)
1239 {
1240         uint32_t flags = NETLOGON_NEG_AUTH2_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
1241         struct netr_ServerReqChallenge r;
1242         struct netr_ServerAuthenticate3 a;
1243         struct netr_Credential credentials1, credentials2, credentials3;
1244         struct netlogon_creds_CredentialState *creds;
1245         struct samr_Password mach_password;
1246         uint32_t rid;
1247         const char *machine_name;
1248         const char *plain_pass;
1249         struct dcerpc_binding_handle *b1 = p1->binding_handle;
1250         struct dcerpc_pipe *p2 = NULL;
1251         struct dcerpc_binding_handle *b2 = NULL;
1252
1253         machine_name = cli_credentials_get_workstation(machine_credentials);
1254         plain_pass = cli_credentials_get_password(machine_credentials);
1255
1256         torture_comment(tctx, "Testing ServerReqChallenge on b1\n");
1257
1258         torture_assert_ntstatus_ok(tctx,
1259                 dcerpc_pipe_connect_b(tctx, &p2, p1->binding,
1260                                       &ndr_table_netlogon,
1261                                       machine_credentials,
1262                                       tctx->ev, tctx->lp_ctx),
1263                 "dcerpc_pipe_connect_b failed");
1264         b2 = p2->binding_handle;
1265
1266         r.in.server_name = NULL;
1267         r.in.computer_name = machine_name;
1268         r.in.credentials = &credentials1;
1269         r.out.return_credentials = &credentials2;
1270
1271         generate_random_buffer(credentials1.data, sizeof(credentials1.data));
1272
1273         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b1, tctx, &r),
1274                 "ServerReqChallenge failed on b1");
1275         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed on b1");
1276
1277         E_md4hash(plain_pass, mach_password.hash);
1278
1279         a.in.server_name = NULL;
1280         a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
1281         a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
1282         a.in.computer_name = machine_name;
1283         a.in.negotiate_flags = &flags;
1284         a.in.credentials = &credentials3;
1285         a.out.return_credentials = &credentials3;
1286         a.out.negotiate_flags = &flags;
1287         a.out.rid = &rid;
1288
1289         creds = netlogon_creds_client_init(tctx, a.in.account_name,
1290                                            a.in.computer_name,
1291                                            a.in.secure_channel_type,
1292                                            &credentials1, &credentials2,
1293                                            &mach_password, &credentials3,
1294                                            flags);
1295
1296         torture_assert(tctx, creds != NULL, "memory allocation");
1297
1298         torture_comment(tctx, "Testing ServerAuthenticate3 on b2\n");
1299
1300         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b2, tctx, &a),
1301                 "ServerAuthenticate3 failed on b2");
1302         torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate3 failed on b2");
1303         torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
1304
1305         return true;
1306 }
1307
1308 /*
1309  * Test the re-use of the challenge is not possible on a third
1310  * connection, after first useing it second one.
1311  */
1312
1313 static bool test_ServerReqChallengeReuseGlobal(struct torture_context *tctx,
1314                                           struct dcerpc_pipe *p1,
1315                                           struct cli_credentials *machine_credentials)
1316 {
1317         uint32_t flags = NETLOGON_NEG_AUTH2_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
1318         struct netr_ServerReqChallenge r;
1319         struct netr_ServerAuthenticate3 a;
1320         struct netr_Credential credentials1, credentials2, credentials3;
1321         struct netlogon_creds_CredentialState *creds;
1322         struct samr_Password mach_password;
1323         uint32_t rid;
1324         const char *machine_name;
1325         const char *plain_pass;
1326         struct dcerpc_binding_handle *b1 = p1->binding_handle;
1327         struct dcerpc_pipe *p2 = NULL;
1328         struct dcerpc_binding_handle *b2 = NULL;
1329         struct dcerpc_pipe *p3 = NULL;
1330         struct dcerpc_binding_handle *b3 = NULL;
1331
1332         machine_name = cli_credentials_get_workstation(machine_credentials);
1333         plain_pass = cli_credentials_get_password(machine_credentials);
1334
1335         torture_comment(tctx, "Testing ServerReqChallenge on b1\n");
1336
1337         torture_assert_ntstatus_ok(tctx,
1338                 dcerpc_pipe_connect_b(tctx, &p2, p1->binding,
1339                                       &ndr_table_netlogon,
1340                                       machine_credentials,
1341                                       tctx->ev, tctx->lp_ctx),
1342                 "dcerpc_pipe_connect_b failed");
1343         b2 = p2->binding_handle;
1344
1345         torture_assert_ntstatus_ok(tctx,
1346                 dcerpc_pipe_connect_b(tctx, &p3, p1->binding,
1347                                       &ndr_table_netlogon,
1348                                       machine_credentials,
1349                                       tctx->ev, tctx->lp_ctx),
1350                 "dcerpc_pipe_connect_b failed");
1351         b3 = p3->binding_handle;
1352
1353         r.in.server_name = NULL;
1354         r.in.computer_name = machine_name;
1355         r.in.credentials = &credentials1;
1356         r.out.return_credentials = &credentials2;
1357
1358         generate_random_buffer(credentials1.data, sizeof(credentials1.data));
1359
1360         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b1, tctx, &r),
1361                 "ServerReqChallenge failed on b1");
1362         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed on b1");
1363
1364         E_md4hash(plain_pass, mach_password.hash);
1365
1366         a.in.server_name = NULL;
1367         a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
1368         a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
1369         a.in.computer_name = machine_name;
1370         a.in.negotiate_flags = &flags;
1371         a.in.credentials = &credentials3;
1372         a.out.return_credentials = &credentials3;
1373         a.out.negotiate_flags = &flags;
1374         a.out.rid = &rid;
1375
1376         creds = netlogon_creds_client_init(tctx, a.in.account_name,
1377                                            a.in.computer_name,
1378                                            a.in.secure_channel_type,
1379                                            &credentials1, &credentials2,
1380                                            &mach_password, &credentials3,
1381                                            flags);
1382
1383         torture_assert(tctx, creds != NULL, "memory allocation");
1384
1385         torture_comment(tctx, "Testing ServerAuthenticate3 on b2\n");
1386
1387         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b2, tctx, &a),
1388                 "ServerAuthenticate3 failed on b2");
1389         torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate3 failed on b2");
1390         torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
1391
1392         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b3, tctx, &a),
1393                 "ServerAuthenticate3 failed on b3");
1394         torture_assert_ntstatus_equal(tctx, a.out.result, NT_STATUS_ACCESS_DENIED,
1395                                       "ServerAuthenticate3 should have failed on b3, due to credential reuse");
1396         return true;
1397 }
1398
1399 /*
1400  * Test if use of the per-pipe challenge will wipe out the globally cached challenge
1401  */
1402 static bool test_ServerReqChallengeReuseGlobal2(struct torture_context *tctx,
1403                                                 struct dcerpc_pipe *p1,
1404                                                 struct cli_credentials *machine_credentials)
1405 {
1406         uint32_t flags = NETLOGON_NEG_AUTH2_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
1407         struct netr_ServerReqChallenge r;
1408         struct netr_ServerAuthenticate3 a;
1409         struct netr_Credential credentials1, credentials2, credentials3;
1410         struct netlogon_creds_CredentialState *creds;
1411         struct samr_Password mach_password;
1412         uint32_t rid;
1413         const char *machine_name;
1414         const char *plain_pass;
1415         struct dcerpc_binding_handle *b1 = p1->binding_handle;
1416         struct dcerpc_pipe *p2 = NULL;
1417         struct dcerpc_binding_handle *b2 = NULL;
1418
1419         machine_name = cli_credentials_get_workstation(machine_credentials);
1420         plain_pass = cli_credentials_get_password(machine_credentials);
1421
1422         torture_comment(tctx, "Testing ServerReqChallenge on b1\n");
1423
1424         torture_assert_ntstatus_ok(tctx,
1425                 dcerpc_pipe_connect_b(tctx, &p2, p1->binding,
1426                                       &ndr_table_netlogon,
1427                                       machine_credentials,
1428                                       tctx->ev, tctx->lp_ctx),
1429                 "dcerpc_pipe_connect_b failed");
1430         b2 = p2->binding_handle;
1431
1432         r.in.server_name = NULL;
1433         r.in.computer_name = machine_name;
1434         r.in.credentials = &credentials1;
1435         r.out.return_credentials = &credentials2;
1436
1437         generate_random_buffer(credentials1.data, sizeof(credentials1.data));
1438
1439         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b1, tctx, &r),
1440                 "ServerReqChallenge failed on b1");
1441         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed on b1");
1442
1443         E_md4hash(plain_pass, mach_password.hash);
1444
1445         a.in.server_name = NULL;
1446         a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
1447         a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
1448         a.in.computer_name = machine_name;
1449         a.in.negotiate_flags = &flags;
1450         a.in.credentials = &credentials3;
1451         a.out.return_credentials = &credentials3;
1452         a.out.negotiate_flags = &flags;
1453         a.out.rid = &rid;
1454
1455         creds = netlogon_creds_client_init(tctx, a.in.account_name,
1456                                            a.in.computer_name,
1457                                            a.in.secure_channel_type,
1458                                            &credentials1, &credentials2,
1459                                            &mach_password, &credentials3,
1460                                            flags);
1461
1462         torture_assert(tctx, creds != NULL, "memory allocation");
1463
1464         torture_comment(tctx, "Testing ServerAuthenticate3 on b2\n");
1465
1466         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b1, tctx, &a),
1467                 "ServerAuthenticate3 failed on b");
1468         torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate3 failed on b");
1469         torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
1470
1471         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b2, tctx, &a),
1472                 "ServerAuthenticate3 failed on b2");
1473         torture_assert_ntstatus_equal(tctx, a.out.result, NT_STATUS_ACCESS_DENIED,
1474                                       "ServerAuthenticate3 should have failed on b2, due to credential reuse");
1475         return true;
1476 }
1477
1478 static bool test_ServerReqChallengeReuse(struct torture_context *tctx,
1479                                          struct dcerpc_pipe *p,
1480                                          struct cli_credentials *machine_credentials)
1481 {
1482         uint32_t flags = NETLOGON_NEG_AUTH2_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
1483         struct netr_ServerReqChallenge r;
1484         struct netr_ServerAuthenticate3 a;
1485         struct netr_Credential credentials1, credentials2, credentials3;
1486         struct netlogon_creds_CredentialState *creds;
1487         struct samr_Password mach_password;
1488         uint32_t rid;
1489         const char *machine_name;
1490         const char *plain_pass;
1491         struct dcerpc_binding_handle *b = p->binding_handle;
1492
1493         machine_name = cli_credentials_get_workstation(machine_credentials);
1494         plain_pass = cli_credentials_get_password(machine_credentials);
1495
1496         torture_comment(tctx, "Testing ServerReqChallenge on b1\n");
1497
1498         r.in.server_name = NULL;
1499         r.in.computer_name = machine_name;
1500         r.in.credentials = &credentials1;
1501         r.out.return_credentials = &credentials2;
1502
1503         generate_random_buffer(credentials1.data, sizeof(credentials1.data));
1504
1505         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
1506                 "ServerReqChallenge");
1507         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed on b1");
1508
1509         E_md4hash(plain_pass, mach_password.hash);
1510
1511         a.in.server_name = NULL;
1512         a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
1513         a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
1514         a.in.computer_name = machine_name;
1515         a.in.negotiate_flags = &flags;
1516         a.in.credentials = &credentials3;
1517         a.out.return_credentials = &credentials3;
1518         a.out.negotiate_flags = &flags;
1519         a.out.rid = &rid;
1520
1521         creds = netlogon_creds_client_init(tctx, a.in.account_name,
1522                                            a.in.computer_name,
1523                                            a.in.secure_channel_type,
1524                                            &credentials1, &credentials2,
1525                                            &mach_password, &credentials3,
1526                                            flags);
1527
1528         torture_assert(tctx, creds != NULL, "memory allocation");
1529
1530         torture_comment(tctx, "Testing ServerAuthenticate3\n");
1531
1532         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b, tctx, &a),
1533                 "ServerAuthenticate3 failed");
1534         torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate3 failed");
1535         torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
1536
1537         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b, tctx, &a),
1538                 "ServerAuthenticate3 failed");
1539         torture_assert_ntstatus_equal(tctx, a.out.result, NT_STATUS_ACCESS_DENIED,
1540                                       "ServerAuthenticate3 should have failed on b3, due to credential reuse");
1541
1542         ZERO_STRUCT(credentials1.data);
1543         ZERO_STRUCT(credentials2.data);
1544         creds = netlogon_creds_client_init(tctx, a.in.account_name,
1545                                            a.in.computer_name,
1546                                            a.in.secure_channel_type,
1547                                            &credentials1, &credentials2,
1548                                            &mach_password, &credentials3,
1549                                            flags);
1550
1551         torture_assert(tctx, creds != NULL, "memory allocation");
1552
1553         torture_comment(tctx, "Testing ServerAuthenticate3 with zero'ed challenge\n");
1554
1555         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b, tctx, &a),
1556                 "ServerAuthenticate3 failed");
1557         torture_assert_ntstatus_equal(tctx, a.out.result, NT_STATUS_ACCESS_DENIED,
1558                                       "ServerAuthenticate3 should have failed on b3, due to credential reuse");
1559         return true;
1560 }
1561
1562 static bool test_SamLogon_NULL_domain(struct torture_context *tctx,
1563                                       struct dcerpc_pipe *p,
1564                                       struct cli_credentials *credentials)
1565 {
1566         struct netlogon_creds_CredentialState *creds;
1567
1568         if (!test_SetupCredentials(p, tctx, credentials, &creds)) {
1569                 return false;
1570         }
1571
1572         return test_netlogon_ops_args(p, tctx, credentials, creds, true);
1573 }
1574
1575 /* we remember the sequence numbers so we can easily do a DatabaseDelta */
1576 static uint64_t sequence_nums[3];
1577
1578 /*
1579   try a netlogon DatabaseSync
1580 */
1581 static bool test_DatabaseSync(struct torture_context *tctx,
1582                               struct dcerpc_pipe *p,
1583                               struct cli_credentials *machine_credentials)
1584 {
1585         struct netr_DatabaseSync r;
1586         struct netlogon_creds_CredentialState *creds;
1587         const uint32_t database_ids[] = {SAM_DATABASE_DOMAIN, SAM_DATABASE_BUILTIN, SAM_DATABASE_PRIVS};
1588         int i;
1589         struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
1590         struct netr_Authenticator credential, return_authenticator;
1591         struct dcerpc_binding_handle *b = p->binding_handle;
1592
1593         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1594                 return false;
1595         }
1596
1597         ZERO_STRUCT(return_authenticator);
1598
1599         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1600         r.in.computername = TEST_MACHINE_NAME;
1601         r.in.preferredmaximumlength = (uint32_t)-1;
1602         r.in.return_authenticator = &return_authenticator;
1603         r.out.delta_enum_array = &delta_enum_array;
1604         r.out.return_authenticator = &return_authenticator;
1605
1606         for (i=0;i<ARRAY_SIZE(database_ids);i++) {
1607
1608                 uint32_t sync_context = 0;
1609
1610                 r.in.database_id = database_ids[i];
1611                 r.in.sync_context = &sync_context;
1612                 r.out.sync_context = &sync_context;
1613
1614                 torture_comment(tctx, "Testing DatabaseSync of id %d\n", r.in.database_id);
1615
1616                 do {
1617                         netlogon_creds_client_authenticator(creds, &credential);
1618
1619                         r.in.credential = &credential;
1620
1621                         torture_assert_ntstatus_ok(tctx, dcerpc_netr_DatabaseSync_r(b, tctx, &r),
1622                                 "DatabaseSync failed");
1623                         if (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES))
1624                             break;
1625
1626                         /* Native mode servers don't do this */
1627                         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_SUPPORTED)) {
1628                                 return true;
1629                         }
1630                         torture_assert_ntstatus_ok(tctx, r.out.result, "DatabaseSync");
1631
1632                         if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
1633                                 torture_comment(tctx, "Credential chaining failed\n");
1634                         }
1635
1636                         if (delta_enum_array &&
1637                             delta_enum_array->num_deltas > 0 &&
1638                             delta_enum_array->delta_enum[0].delta_type == NETR_DELTA_DOMAIN &&
1639                             delta_enum_array->delta_enum[0].delta_union.domain) {
1640                                 sequence_nums[r.in.database_id] =
1641                                         delta_enum_array->delta_enum[0].delta_union.domain->sequence_num;
1642                                 torture_comment(tctx, "\tsequence_nums[%d]=%llu\n",
1643                                        r.in.database_id,
1644                                        (unsigned long long)sequence_nums[r.in.database_id]);
1645                         }
1646                 } while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES));
1647         }
1648
1649         return true;
1650 }
1651
1652
1653 /*
1654   try a netlogon DatabaseDeltas
1655 */
1656 static bool test_DatabaseDeltas(struct torture_context *tctx,
1657                                 struct dcerpc_pipe *p,
1658                                 struct cli_credentials *machine_credentials)
1659 {
1660         struct netr_DatabaseDeltas r;
1661         struct netlogon_creds_CredentialState *creds;
1662         struct netr_Authenticator credential;
1663         struct netr_Authenticator return_authenticator;
1664         struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
1665         const uint32_t database_ids[] = {0, 1, 2};
1666         int i;
1667         struct dcerpc_binding_handle *b = p->binding_handle;
1668
1669         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1670                 return false;
1671         }
1672
1673         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1674         r.in.computername = TEST_MACHINE_NAME;
1675         r.in.preferredmaximumlength = (uint32_t)-1;
1676         ZERO_STRUCT(r.in.return_authenticator);
1677         r.out.return_authenticator = &return_authenticator;
1678         r.out.delta_enum_array = &delta_enum_array;
1679
1680         for (i=0;i<ARRAY_SIZE(database_ids);i++) {
1681                 r.in.database_id = database_ids[i];
1682                 r.in.sequence_num = &sequence_nums[r.in.database_id];
1683
1684                 if (*r.in.sequence_num == 0) continue;
1685
1686                 *r.in.sequence_num -= 1;
1687
1688                 torture_comment(tctx, "Testing DatabaseDeltas of id %d at %llu\n",
1689                        r.in.database_id, (unsigned long long)*r.in.sequence_num);
1690
1691                 do {
1692                         netlogon_creds_client_authenticator(creds, &credential);
1693
1694                         torture_assert_ntstatus_ok(tctx, dcerpc_netr_DatabaseDeltas_r(b, tctx, &r),
1695                                 "DatabaseDeltas failed");
1696                         if (NT_STATUS_EQUAL(r.out.result,
1697                                              NT_STATUS_SYNCHRONIZATION_REQUIRED)) {
1698                                 torture_comment(tctx, "not considering %s to be an error\n",
1699                                        nt_errstr(r.out.result));
1700                                 return true;
1701                         }
1702                         if (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES))
1703                             break;
1704
1705                         torture_assert_ntstatus_ok(tctx, r.out.result, "DatabaseDeltas");
1706
1707                         if (!netlogon_creds_client_check(creds, &return_authenticator.cred)) {
1708                                 torture_comment(tctx, "Credential chaining failed\n");
1709                         }
1710
1711                         (*r.in.sequence_num)++;
1712                 } while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES));
1713         }
1714
1715         return true;
1716 }
1717
1718 static bool test_DatabaseRedo(struct torture_context *tctx,
1719                               struct dcerpc_pipe *p,
1720                               struct cli_credentials *machine_credentials)
1721 {
1722         struct netr_DatabaseRedo r;
1723         struct netlogon_creds_CredentialState *creds;
1724         struct netr_Authenticator credential;
1725         struct netr_Authenticator return_authenticator;
1726         struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
1727         struct netr_ChangeLogEntry e;
1728         struct dom_sid null_sid, *sid;
1729         int i,d;
1730         struct dcerpc_binding_handle *b = p->binding_handle;
1731
1732         ZERO_STRUCT(null_sid);
1733
1734         sid = dom_sid_parse_talloc(tctx, "S-1-5-21-1111111111-2222222222-333333333-500");
1735
1736         {
1737
1738         struct {
1739                 uint32_t rid;
1740                 uint16_t flags;
1741                 uint8_t db_index;
1742                 uint8_t delta_type;
1743                 struct dom_sid sid;
1744                 const char *name;
1745                 NTSTATUS expected_error;
1746                 uint32_t expected_num_results;
1747                 uint8_t expected_delta_type_1;
1748                 uint8_t expected_delta_type_2;
1749                 const char *comment;
1750         } changes[] = {
1751
1752                 /* SAM_DATABASE_DOMAIN */
1753
1754                 {
1755                         .rid                    = 0,
1756                         .flags                  = 0,
1757                         .db_index               = SAM_DATABASE_DOMAIN,
1758                         .delta_type             = NETR_DELTA_MODIFY_COUNT,
1759                         .sid                    = null_sid,
1760                         .name                   = NULL,
1761                         .expected_error         = NT_STATUS_SYNCHRONIZATION_REQUIRED,
1762                         .expected_num_results   = 0,
1763                         .comment                = "NETR_DELTA_MODIFY_COUNT"
1764                 },
1765                 {
1766                         .rid                    = 0,
1767                         .flags                  = 0,
1768                         .db_index               = SAM_DATABASE_DOMAIN,
1769                         .delta_type             = 0,
1770                         .sid                    = null_sid,
1771                         .name                   = NULL,
1772                         .expected_error         = NT_STATUS_OK,
1773                         .expected_num_results   = 1,
1774                         .expected_delta_type_1  = NETR_DELTA_DOMAIN,
1775                         .comment                = "NULL DELTA"
1776                 },
1777                 {
1778                         .rid                    = 0,
1779                         .flags                  = 0,
1780                         .db_index               = SAM_DATABASE_DOMAIN,
1781                         .delta_type             = NETR_DELTA_DOMAIN,
1782                         .sid                    = null_sid,
1783                         .name                   = NULL,
1784                         .expected_error         = NT_STATUS_OK,
1785                         .expected_num_results   = 1,
1786                         .expected_delta_type_1  = NETR_DELTA_DOMAIN,
1787                         .comment                = "NETR_DELTA_DOMAIN"
1788                 },
1789                 {
1790                         .rid                    = DOMAIN_RID_ADMINISTRATOR,
1791                         .flags                  = 0,
1792                         .db_index               = SAM_DATABASE_DOMAIN,
1793                         .delta_type             = NETR_DELTA_USER,
1794                         .sid                    = null_sid,
1795                         .name                   = NULL,
1796                         .expected_error         = NT_STATUS_OK,
1797                         .expected_num_results   = 1,
1798                         .expected_delta_type_1  = NETR_DELTA_USER,
1799                         .comment                = "NETR_DELTA_USER by rid 500"
1800                 },
1801                 {
1802                         .rid                    = DOMAIN_RID_GUEST,
1803                         .flags                  = 0,
1804                         .db_index               = SAM_DATABASE_DOMAIN,
1805                         .delta_type             = NETR_DELTA_USER,
1806                         .sid                    = null_sid,
1807                         .name                   = NULL,
1808                         .expected_error         = NT_STATUS_OK,
1809                         .expected_num_results   = 1,
1810                         .expected_delta_type_1  = NETR_DELTA_USER,
1811                         .comment                = "NETR_DELTA_USER by rid 501"
1812                 },
1813                 {
1814                         .rid                    = 0,
1815                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
1816                         .db_index               = SAM_DATABASE_DOMAIN,
1817                         .delta_type             = NETR_DELTA_USER,
1818                         .sid                    = *sid,
1819                         .name                   = NULL,
1820                         .expected_error         = NT_STATUS_OK,
1821                         .expected_num_results   = 1,
1822                         .expected_delta_type_1  = NETR_DELTA_DELETE_USER,
1823                         .comment                = "NETR_DELTA_USER by sid and flags"
1824                 },
1825                 {
1826                         .rid                    = 0,
1827                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
1828                         .db_index               = SAM_DATABASE_DOMAIN,
1829                         .delta_type             = NETR_DELTA_USER,
1830                         .sid                    = null_sid,
1831                         .name                   = NULL,
1832                         .expected_error         = NT_STATUS_OK,
1833                         .expected_num_results   = 1,
1834                         .expected_delta_type_1  = NETR_DELTA_DELETE_USER,
1835                         .comment                = "NETR_DELTA_USER by null_sid and flags"
1836                 },
1837                 {
1838                         .rid                    = 0,
1839                         .flags                  = NETR_CHANGELOG_NAME_INCLUDED,
1840                         .db_index               = SAM_DATABASE_DOMAIN,
1841                         .delta_type             = NETR_DELTA_USER,
1842                         .sid                    = null_sid,
1843                         .name                   = "administrator",
1844                         .expected_error         = NT_STATUS_OK,
1845                         .expected_num_results   = 1,
1846                         .expected_delta_type_1  = NETR_DELTA_DELETE_USER,
1847                         .comment                = "NETR_DELTA_USER by name 'administrator'"
1848                 },
1849                 {
1850                         .rid                    = DOMAIN_RID_ADMINS,
1851                         .flags                  = 0,
1852                         .db_index               = SAM_DATABASE_DOMAIN,
1853                         .delta_type             = NETR_DELTA_GROUP,
1854                         .sid                    = null_sid,
1855                         .name                   = NULL,
1856                         .expected_error         = NT_STATUS_OK,
1857                         .expected_num_results   = 2,
1858                         .expected_delta_type_1  = NETR_DELTA_GROUP,
1859                         .expected_delta_type_2  = NETR_DELTA_GROUP_MEMBER,
1860                         .comment                = "NETR_DELTA_GROUP by rid 512"
1861                 },
1862                 {
1863                         .rid                    = DOMAIN_RID_ADMINS,
1864                         .flags                  = 0,
1865                         .db_index               = SAM_DATABASE_DOMAIN,
1866                         .delta_type             = NETR_DELTA_GROUP_MEMBER,
1867                         .sid                    = null_sid,
1868                         .name                   = NULL,
1869                         .expected_error         = NT_STATUS_OK,
1870                         .expected_num_results   = 2,
1871                         .expected_delta_type_1  = NETR_DELTA_GROUP,
1872                         .expected_delta_type_2  = NETR_DELTA_GROUP_MEMBER,
1873                         .comment                = "NETR_DELTA_GROUP_MEMBER by rid 512"
1874                 },
1875
1876
1877                 /* SAM_DATABASE_BUILTIN */
1878
1879                 {
1880                         .rid                    = 0,
1881                         .flags                  = 0,
1882                         .db_index               = SAM_DATABASE_BUILTIN,
1883                         .delta_type             = NETR_DELTA_MODIFY_COUNT,
1884                         .sid                    = null_sid,
1885                         .name                   = NULL,
1886                         .expected_error         = NT_STATUS_SYNCHRONIZATION_REQUIRED,
1887                         .expected_num_results   = 0,
1888                         .comment                = "NETR_DELTA_MODIFY_COUNT"
1889                 },
1890                 {
1891                         .rid                    = 0,
1892                         .flags                  = 0,
1893                         .db_index               = SAM_DATABASE_BUILTIN,
1894                         .delta_type             = NETR_DELTA_DOMAIN,
1895                         .sid                    = null_sid,
1896                         .name                   = NULL,
1897                         .expected_error         = NT_STATUS_OK,
1898                         .expected_num_results   = 1,
1899                         .expected_delta_type_1  = NETR_DELTA_DOMAIN,
1900                         .comment                = "NETR_DELTA_DOMAIN"
1901                 },
1902                 {
1903                         .rid                    = DOMAIN_RID_ADMINISTRATOR,
1904                         .flags                  = 0,
1905                         .db_index               = SAM_DATABASE_BUILTIN,
1906                         .delta_type             = NETR_DELTA_USER,
1907                         .sid                    = null_sid,
1908                         .name                   = NULL,
1909                         .expected_error         = NT_STATUS_OK,
1910                         .expected_num_results   = 1,
1911                         .expected_delta_type_1  = NETR_DELTA_DELETE_USER,
1912                         .comment                = "NETR_DELTA_USER by rid 500"
1913                 },
1914                 {
1915                         .rid                    = 0,
1916                         .flags                  = 0,
1917                         .db_index               = SAM_DATABASE_BUILTIN,
1918                         .delta_type             = NETR_DELTA_USER,
1919                         .sid                    = null_sid,
1920                         .name                   = NULL,
1921                         .expected_error         = NT_STATUS_OK,
1922                         .expected_num_results   = 1,
1923                         .expected_delta_type_1  = NETR_DELTA_DELETE_USER,
1924                         .comment                = "NETR_DELTA_USER"
1925                 },
1926                 {
1927                         .rid                    = 544,
1928                         .flags                  = 0,
1929                         .db_index               = SAM_DATABASE_BUILTIN,
1930                         .delta_type             = NETR_DELTA_ALIAS,
1931                         .sid                    = null_sid,
1932                         .name                   = NULL,
1933                         .expected_error         = NT_STATUS_OK,
1934                         .expected_num_results   = 2,
1935                         .expected_delta_type_1  = NETR_DELTA_ALIAS,
1936                         .expected_delta_type_2  = NETR_DELTA_ALIAS_MEMBER,
1937                         .comment                = "NETR_DELTA_ALIAS by rid 544"
1938                 },
1939                 {
1940                         .rid                    = 544,
1941                         .flags                  = 0,
1942                         .db_index               = SAM_DATABASE_BUILTIN,
1943                         .delta_type             = NETR_DELTA_ALIAS_MEMBER,
1944                         .sid                    = null_sid,
1945                         .name                   = NULL,
1946                         .expected_error         = NT_STATUS_OK,
1947                         .expected_num_results   = 2,
1948                         .expected_delta_type_1  = NETR_DELTA_ALIAS,
1949                         .expected_delta_type_2  = NETR_DELTA_ALIAS_MEMBER,
1950                         .comment                = "NETR_DELTA_ALIAS_MEMBER by rid 544"
1951                 },
1952                 {
1953                         .rid                    = 544,
1954                         .flags                  = 0,
1955                         .db_index               = SAM_DATABASE_BUILTIN,
1956                         .delta_type             = 0,
1957                         .sid                    = null_sid,
1958                         .name                   = NULL,
1959                         .expected_error         = NT_STATUS_OK,
1960                         .expected_num_results   = 1,
1961                         .expected_delta_type_1  = NETR_DELTA_DOMAIN,
1962                         .comment                = "NULL DELTA by rid 544"
1963                 },
1964                 {
1965                         .rid                    = 544,
1966                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
1967                         .db_index               = SAM_DATABASE_BUILTIN,
1968                         .delta_type             = 0,
1969                         .sid                    = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
1970                         .name                   = NULL,
1971                         .expected_error         = NT_STATUS_OK,
1972                         .expected_num_results   = 1,
1973                         .expected_delta_type_1  = NETR_DELTA_DOMAIN,
1974                         .comment                = "NULL DELTA by rid 544 sid S-1-5-32-544 and flags"
1975                 },
1976                 {
1977                         .rid                    = 544,
1978                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
1979                         .db_index               = SAM_DATABASE_BUILTIN,
1980                         .delta_type             = NETR_DELTA_ALIAS,
1981                         .sid                    = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
1982                         .name                   = NULL,
1983                         .expected_error         = NT_STATUS_OK,
1984                         .expected_num_results   = 2,
1985                         .expected_delta_type_1  = NETR_DELTA_ALIAS,
1986                         .expected_delta_type_2  = NETR_DELTA_ALIAS_MEMBER,
1987                         .comment                = "NETR_DELTA_ALIAS by rid 544 and sid S-1-5-32-544 and flags"
1988                 },
1989                 {
1990                         .rid                    = 0,
1991                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
1992                         .db_index               = SAM_DATABASE_BUILTIN,
1993                         .delta_type             = NETR_DELTA_ALIAS,
1994                         .sid                    = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
1995                         .name                   = NULL,
1996                         .expected_error         = NT_STATUS_OK,
1997                         .expected_num_results   = 1,
1998                         .expected_delta_type_1  = NETR_DELTA_DELETE_ALIAS,
1999                         .comment                = "NETR_DELTA_ALIAS by sid S-1-5-32-544 and flags"
2000                 },
2001
2002                 /* SAM_DATABASE_PRIVS */
2003
2004                 {
2005                         .rid                    = 0,
2006                         .flags                  = 0,
2007                         .db_index               = SAM_DATABASE_PRIVS,
2008                         .delta_type             = 0,
2009                         .sid                    = null_sid,
2010                         .name                   = NULL,
2011                         .expected_error         = NT_STATUS_ACCESS_DENIED,
2012                         .expected_num_results   = 0,
2013                         .comment                = "NULL DELTA"
2014                 },
2015                 {
2016                         .rid                    = 0,
2017                         .flags                  = 0,
2018                         .db_index               = SAM_DATABASE_PRIVS,
2019                         .delta_type             = NETR_DELTA_MODIFY_COUNT,
2020                         .sid                    = null_sid,
2021                         .name                   = NULL,
2022                         .expected_error         = NT_STATUS_SYNCHRONIZATION_REQUIRED,
2023                         .expected_num_results   = 0,
2024                         .comment                = "NETR_DELTA_MODIFY_COUNT"
2025                 },
2026                 {
2027                         .rid                    = 0,
2028                         .flags                  = 0,
2029                         .db_index               = SAM_DATABASE_PRIVS,
2030                         .delta_type             = NETR_DELTA_POLICY,
2031                         .sid                    = null_sid,
2032                         .name                   = NULL,
2033                         .expected_error         = NT_STATUS_OK,
2034                         .expected_num_results   = 1,
2035                         .expected_delta_type_1  = NETR_DELTA_POLICY,
2036                         .comment                = "NETR_DELTA_POLICY"
2037                 },
2038                 {
2039                         .rid                    = 0,
2040                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
2041                         .db_index               = SAM_DATABASE_PRIVS,
2042                         .delta_type             = NETR_DELTA_POLICY,
2043                         .sid                    = null_sid,
2044                         .name                   = NULL,
2045                         .expected_error         = NT_STATUS_OK,
2046                         .expected_num_results   = 1,
2047                         .expected_delta_type_1  = NETR_DELTA_POLICY,
2048                         .comment                = "NETR_DELTA_POLICY by null sid and flags"
2049                 },
2050                 {
2051                         .rid                    = 0,
2052                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
2053                         .db_index               = SAM_DATABASE_PRIVS,
2054                         .delta_type             = NETR_DELTA_POLICY,
2055                         .sid                    = *dom_sid_parse_talloc(tctx, "S-1-5-32"),
2056                         .name                   = NULL,
2057                         .expected_error         = NT_STATUS_OK,
2058                         .expected_num_results   = 1,
2059                         .expected_delta_type_1  = NETR_DELTA_POLICY,
2060                         .comment                = "NETR_DELTA_POLICY by sid S-1-5-32 and flags"
2061                 },
2062                 {
2063                         .rid                    = DOMAIN_RID_ADMINISTRATOR,
2064                         .flags                  = 0,
2065                         .db_index               = SAM_DATABASE_PRIVS,
2066                         .delta_type             = NETR_DELTA_ACCOUNT,
2067                         .sid                    = null_sid,
2068                         .name                   = NULL,
2069                         .expected_error         = NT_STATUS_SYNCHRONIZATION_REQUIRED, /* strange */
2070                         .expected_num_results   = 0,
2071                         .comment                = "NETR_DELTA_ACCOUNT by rid 500"
2072                 },
2073                 {
2074                         .rid                    = 0,
2075                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
2076                         .db_index               = SAM_DATABASE_PRIVS,
2077                         .delta_type             = NETR_DELTA_ACCOUNT,
2078                         .sid                    = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
2079                         .name                   = NULL,
2080                         .expected_error         = NT_STATUS_OK,
2081                         .expected_num_results   = 1,
2082                         .expected_delta_type_1  = NETR_DELTA_ACCOUNT,
2083                         .comment                = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and flags"
2084                 },
2085                 {
2086                         .rid                    = 0,
2087                         .flags                  = NETR_CHANGELOG_SID_INCLUDED |
2088                                                   NETR_CHANGELOG_IMMEDIATE_REPL_REQUIRED,
2089                         .db_index               = SAM_DATABASE_PRIVS,
2090                         .delta_type             = NETR_DELTA_ACCOUNT,
2091                         .sid                    = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
2092                         .name                   = NULL,
2093                         .expected_error         = NT_STATUS_OK,
2094                         .expected_num_results   = 1,
2095                         .expected_delta_type_1  = NETR_DELTA_ACCOUNT,
2096                         .comment                = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and 2 flags"
2097                 },
2098                 {
2099                         .rid                    = 0,
2100                         .flags                  = NETR_CHANGELOG_SID_INCLUDED |
2101                                                   NETR_CHANGELOG_NAME_INCLUDED,
2102                         .db_index               = SAM_DATABASE_PRIVS,
2103                         .delta_type             = NETR_DELTA_ACCOUNT,
2104                         .sid                    = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
2105                         .name                   = NULL,
2106                         .expected_error         = NT_STATUS_INVALID_PARAMETER,
2107                         .expected_num_results   = 0,
2108                         .comment                = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and invalid flags"
2109                 },
2110                 {
2111                         .rid                    = DOMAIN_RID_ADMINISTRATOR,
2112                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
2113                         .db_index               = SAM_DATABASE_PRIVS,
2114                         .delta_type             = NETR_DELTA_ACCOUNT,
2115                         .sid                    = *sid,
2116                         .name                   = NULL,
2117                         .expected_error         = NT_STATUS_OK,
2118                         .expected_num_results   = 1,
2119                         .expected_delta_type_1  = NETR_DELTA_DELETE_ACCOUNT,
2120                         .comment                = "NETR_DELTA_ACCOUNT by rid 500, sid and flags"
2121                 },
2122                 {
2123                         .rid                    = 0,
2124                         .flags                  = NETR_CHANGELOG_NAME_INCLUDED,
2125                         .db_index               = SAM_DATABASE_PRIVS,
2126                         .delta_type             = NETR_DELTA_SECRET,
2127                         .sid                    = null_sid,
2128                         .name                   = "IsurelydontexistIhope",
2129                         .expected_error         = NT_STATUS_OK,
2130                         .expected_num_results   = 1,
2131                         .expected_delta_type_1  = NETR_DELTA_DELETE_SECRET,
2132                         .comment                = "NETR_DELTA_SECRET by name 'IsurelydontexistIhope' and flags"
2133                 },
2134                 {
2135                         .rid                    = 0,
2136                         .flags                  = NETR_CHANGELOG_NAME_INCLUDED,
2137                         .db_index               = SAM_DATABASE_PRIVS,
2138                         .delta_type             = NETR_DELTA_SECRET,
2139                         .sid                    = null_sid,
2140                         .name                   = "G$BCKUPKEY_P",
2141                         .expected_error         = NT_STATUS_OK,
2142                         .expected_num_results   = 1,
2143                         .expected_delta_type_1  = NETR_DELTA_SECRET,
2144                         .comment                = "NETR_DELTA_SECRET by name 'G$BCKUPKEY_P' and flags"
2145                 }
2146         };
2147
2148         ZERO_STRUCT(return_authenticator);
2149
2150         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2151         r.in.computername = TEST_MACHINE_NAME;
2152         r.in.return_authenticator = &return_authenticator;
2153         r.out.return_authenticator = &return_authenticator;
2154         r.out.delta_enum_array = &delta_enum_array;
2155
2156         for (d=0; d<3; d++) {
2157                 const char *database = NULL;
2158
2159                 switch (d) {
2160                 case 0:
2161                         database = "SAM";
2162                         break;
2163                 case 1:
2164                         database = "BUILTIN";
2165                         break;
2166                 case 2:
2167                         database = "LSA";
2168                         break;
2169                 default:
2170                         break;
2171                 }
2172
2173                 torture_comment(tctx, "Testing DatabaseRedo\n");
2174
2175                 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
2176                         return false;
2177                 }
2178
2179                 for (i=0;i<ARRAY_SIZE(changes);i++) {
2180
2181                         if (d != changes[i].db_index) {
2182                                 continue;
2183                         }
2184
2185                         netlogon_creds_client_authenticator(creds, &credential);
2186
2187                         r.in.credential = &credential;
2188
2189                         e.serial_number1        = 0;
2190                         e.serial_number2        = 0;
2191                         e.object_rid            = changes[i].rid;
2192                         e.flags                 = changes[i].flags;
2193                         e.db_index              = changes[i].db_index;
2194                         e.delta_type            = changes[i].delta_type;
2195
2196                         switch (changes[i].flags & (NETR_CHANGELOG_NAME_INCLUDED | NETR_CHANGELOG_SID_INCLUDED)) {
2197                         case NETR_CHANGELOG_SID_INCLUDED:
2198                                 e.object.object_sid             = changes[i].sid;
2199                                 break;
2200                         case NETR_CHANGELOG_NAME_INCLUDED:
2201                                 e.object.object_name            = changes[i].name;
2202                                 break;
2203                         default:
2204                                 break;
2205                         }
2206
2207                         r.in.change_log_entry = e;
2208
2209                         torture_comment(tctx, "Testing DatabaseRedo with database %s and %s\n",
2210                                 database, changes[i].comment);
2211
2212                         torture_assert_ntstatus_ok(tctx, dcerpc_netr_DatabaseRedo_r(b, tctx, &r),
2213                                 "DatabaseRedo failed");
2214                         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_SUPPORTED)) {
2215                                 return true;
2216                         }
2217
2218                         torture_assert_ntstatus_equal(tctx, r.out.result, changes[i].expected_error, changes[i].comment);
2219                         if (delta_enum_array) {
2220                                 torture_assert_int_equal(tctx,
2221                                         delta_enum_array->num_deltas,
2222                                         changes[i].expected_num_results,
2223                                         changes[i].comment);
2224                                 if (delta_enum_array->num_deltas > 0) {
2225                                         torture_assert_int_equal(tctx,
2226                                                 delta_enum_array->delta_enum[0].delta_type,
2227                                                 changes[i].expected_delta_type_1,
2228                                                 changes[i].comment);
2229                                 }
2230                                 if (delta_enum_array->num_deltas > 1) {
2231                                         torture_assert_int_equal(tctx,
2232                                                 delta_enum_array->delta_enum[1].delta_type,
2233                                                 changes[i].expected_delta_type_2,
2234                                                 changes[i].comment);
2235                                 }
2236                         }
2237
2238                         if (!netlogon_creds_client_check(creds, &return_authenticator.cred)) {
2239                                 torture_comment(tctx, "Credential chaining failed\n");
2240                                 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
2241                                         return false;
2242                                 }
2243                         }
2244                 }
2245         }
2246         }
2247
2248         return true;
2249 }
2250
2251 /*
2252   try a netlogon AccountDeltas
2253 */
2254 static bool test_AccountDeltas(struct torture_context *tctx,
2255                                struct dcerpc_pipe *p,
2256                                struct cli_credentials *machine_credentials)
2257 {
2258         struct netr_AccountDeltas r;
2259         struct netlogon_creds_CredentialState *creds;
2260
2261         struct netr_AccountBuffer buffer;
2262         uint32_t count_returned = 0;
2263         uint32_t total_entries = 0;
2264         struct netr_UAS_INFO_0 recordid;
2265         struct netr_Authenticator return_authenticator;
2266         struct dcerpc_binding_handle *b = p->binding_handle;
2267
2268         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
2269                 return false;
2270         }
2271
2272         ZERO_STRUCT(return_authenticator);
2273
2274         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2275         r.in.computername = TEST_MACHINE_NAME;
2276         r.in.return_authenticator = &return_authenticator;
2277         netlogon_creds_client_authenticator(creds, &r.in.credential);
2278         ZERO_STRUCT(r.in.uas);
2279         r.in.count=10;
2280         r.in.level=0;
2281         r.in.buffersize=100;
2282         r.out.buffer = &buffer;
2283         r.out.count_returned = &count_returned;
2284         r.out.total_entries = &total_entries;
2285         r.out.recordid = &recordid;
2286         r.out.return_authenticator = &return_authenticator;
2287
2288         /* w2k3 returns "NOT IMPLEMENTED" for this call */
2289         torture_assert_ntstatus_ok(tctx, dcerpc_netr_AccountDeltas_r(b, tctx, &r),
2290                 "AccountDeltas failed");
2291         torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_IMPLEMENTED, "AccountDeltas");
2292
2293         return true;
2294 }
2295
2296 /*
2297   try a netlogon AccountSync
2298 */
2299 static bool test_AccountSync(struct torture_context *tctx, struct dcerpc_pipe *p,
2300                              struct cli_credentials *machine_credentials)
2301 {
2302         struct netr_AccountSync r;
2303         struct netlogon_creds_CredentialState *creds;
2304
2305         struct netr_AccountBuffer buffer;
2306         uint32_t count_returned = 0;
2307         uint32_t total_entries = 0;
2308         uint32_t next_reference = 0;
2309         struct netr_UAS_INFO_0 recordid;
2310         struct netr_Authenticator return_authenticator;
2311         struct dcerpc_binding_handle *b = p->binding_handle;
2312
2313         ZERO_STRUCT(recordid);
2314         ZERO_STRUCT(return_authenticator);
2315
2316         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
2317                 return false;
2318         }
2319
2320         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2321         r.in.computername = TEST_MACHINE_NAME;
2322         r.in.return_authenticator = &return_authenticator;
2323         netlogon_creds_client_authenticator(creds, &r.in.credential);
2324         r.in.recordid = &recordid;
2325         r.in.reference=0;
2326         r.in.level=0;
2327         r.in.buffersize=100;
2328         r.out.buffer = &buffer;
2329         r.out.count_returned = &count_returned;
2330         r.out.total_entries = &total_entries;
2331         r.out.next_reference = &next_reference;
2332         r.out.recordid = &recordid;
2333         r.out.return_authenticator = &return_authenticator;
2334
2335         /* w2k3 returns "NOT IMPLEMENTED" for this call */
2336         torture_assert_ntstatus_ok(tctx, dcerpc_netr_AccountSync_r(b, tctx, &r),
2337                 "AccountSync failed");
2338         torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_IMPLEMENTED, "AccountSync");
2339
2340         return true;
2341 }
2342
2343 /*
2344   try a netlogon GetDcName
2345 */
2346 static bool test_GetDcName(struct torture_context *tctx,
2347                            struct dcerpc_pipe *p)
2348 {
2349         struct netr_GetDcName r;
2350         const char *dcname = NULL;
2351         struct dcerpc_binding_handle *b = p->binding_handle;
2352
2353         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2354         r.in.domainname = lpcfg_workgroup(tctx->lp_ctx);
2355         r.out.dcname = &dcname;
2356
2357         torture_assert_ntstatus_ok(tctx, dcerpc_netr_GetDcName_r(b, tctx, &r),
2358                 "GetDcName failed");
2359         torture_assert_werr_ok(tctx, r.out.result, "GetDcName failed");
2360
2361         torture_comment(tctx, "\tDC is at '%s'\n", dcname);
2362
2363         return true;
2364 }
2365
2366 static const char *function_code_str(TALLOC_CTX *mem_ctx,
2367                                      enum netr_LogonControlCode function_code)
2368 {
2369         switch (function_code) {
2370         case NETLOGON_CONTROL_QUERY:
2371                 return "NETLOGON_CONTROL_QUERY";
2372         case NETLOGON_CONTROL_REPLICATE:
2373                 return "NETLOGON_CONTROL_REPLICATE";
2374         case NETLOGON_CONTROL_SYNCHRONIZE:
2375                 return "NETLOGON_CONTROL_SYNCHRONIZE";
2376         case NETLOGON_CONTROL_PDC_REPLICATE:
2377                 return "NETLOGON_CONTROL_PDC_REPLICATE";
2378         case NETLOGON_CONTROL_REDISCOVER:
2379                 return "NETLOGON_CONTROL_REDISCOVER";
2380         case NETLOGON_CONTROL_TC_QUERY:
2381                 return "NETLOGON_CONTROL_TC_QUERY";
2382         case NETLOGON_CONTROL_TRANSPORT_NOTIFY:
2383                 return "NETLOGON_CONTROL_TRANSPORT_NOTIFY";
2384         case NETLOGON_CONTROL_FIND_USER:
2385                 return "NETLOGON_CONTROL_FIND_USER";
2386         case NETLOGON_CONTROL_CHANGE_PASSWORD:
2387                 return "NETLOGON_CONTROL_CHANGE_PASSWORD";
2388         case NETLOGON_CONTROL_TC_VERIFY:
2389                 return "NETLOGON_CONTROL_TC_VERIFY";
2390         case NETLOGON_CONTROL_FORCE_DNS_REG:
2391                 return "NETLOGON_CONTROL_FORCE_DNS_REG";
2392         case NETLOGON_CONTROL_QUERY_DNS_REG:
2393                 return "NETLOGON_CONTROL_QUERY_DNS_REG";
2394         case NETLOGON_CONTROL_BACKUP_CHANGE_LOG:
2395                 return "NETLOGON_CONTROL_BACKUP_CHANGE_LOG";
2396         case NETLOGON_CONTROL_TRUNCATE_LOG:
2397                 return "NETLOGON_CONTROL_TRUNCATE_LOG";
2398         case NETLOGON_CONTROL_SET_DBFLAG:
2399                 return "NETLOGON_CONTROL_SET_DBFLAG";
2400         case NETLOGON_CONTROL_BREAKPOINT:
2401                 return "NETLOGON_CONTROL_BREAKPOINT";
2402         default:
2403                 return talloc_asprintf(mem_ctx, "unknown function code: %d",
2404                                        function_code);
2405         }
2406 }
2407
2408
2409 /*
2410   try a netlogon LogonControl
2411 */
2412 static bool test_LogonControl(struct torture_context *tctx,
2413                               struct dcerpc_pipe *p,
2414                               struct cli_credentials *machine_credentials)
2415
2416 {
2417         NTSTATUS status;
2418         struct netr_LogonControl r;
2419         union netr_CONTROL_QUERY_INFORMATION query;
2420         int i,f;
2421         enum netr_SchannelType secure_channel_type = SEC_CHAN_NULL;
2422         struct dcerpc_binding_handle *b = p->binding_handle;
2423
2424         uint32_t function_codes[] = {
2425                 NETLOGON_CONTROL_QUERY,
2426                 NETLOGON_CONTROL_REPLICATE,
2427                 NETLOGON_CONTROL_SYNCHRONIZE,
2428                 NETLOGON_CONTROL_PDC_REPLICATE,
2429                 NETLOGON_CONTROL_REDISCOVER,
2430                 NETLOGON_CONTROL_TC_QUERY,
2431                 NETLOGON_CONTROL_TRANSPORT_NOTIFY,
2432                 NETLOGON_CONTROL_FIND_USER,
2433                 NETLOGON_CONTROL_CHANGE_PASSWORD,
2434                 NETLOGON_CONTROL_TC_VERIFY,
2435                 NETLOGON_CONTROL_FORCE_DNS_REG,
2436                 NETLOGON_CONTROL_QUERY_DNS_REG,
2437                 NETLOGON_CONTROL_BACKUP_CHANGE_LOG,
2438                 NETLOGON_CONTROL_TRUNCATE_LOG,
2439                 NETLOGON_CONTROL_SET_DBFLAG,
2440                 NETLOGON_CONTROL_BREAKPOINT
2441         };
2442
2443         if (machine_credentials) {
2444                 secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
2445         }
2446
2447         torture_comment(tctx, "Testing LogonControl with secure channel type: %d\n",
2448                 secure_channel_type);
2449
2450         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2451         r.in.function_code = 1;
2452         r.out.query = &query;
2453
2454         for (f=0;f<ARRAY_SIZE(function_codes); f++) {
2455         for (i=1;i<5;i++) {
2456
2457                 r.in.function_code = function_codes[f];
2458                 r.in.level = i;
2459
2460                 torture_comment(tctx, "Testing LogonControl function code %s (%d) level %d\n",
2461                                 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2462
2463                 status = dcerpc_netr_LogonControl_r(b, tctx, &r);
2464                 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
2465
2466                 switch (r.in.level) {
2467                 case 1:
2468                         switch (r.in.function_code) {
2469                         case NETLOGON_CONTROL_REPLICATE:
2470                         case NETLOGON_CONTROL_SYNCHRONIZE:
2471                         case NETLOGON_CONTROL_PDC_REPLICATE:
2472                         case NETLOGON_CONTROL_BREAKPOINT:
2473                         case NETLOGON_CONTROL_BACKUP_CHANGE_LOG:
2474                                 if ((secure_channel_type == SEC_CHAN_BDC) ||
2475                                     (secure_channel_type == SEC_CHAN_WKSTA)) {
2476                                         torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED,
2477                                                 "LogonControl returned unexpected error code");
2478                                 } else {
2479                                         torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
2480                                                 "LogonControl returned unexpected error code");
2481                                 }
2482                                 break;
2483
2484                         case NETLOGON_CONTROL_REDISCOVER:
2485                         case NETLOGON_CONTROL_TC_QUERY:
2486                         case NETLOGON_CONTROL_TRANSPORT_NOTIFY:
2487                         case NETLOGON_CONTROL_FIND_USER:
2488                         case NETLOGON_CONTROL_CHANGE_PASSWORD:
2489                         case NETLOGON_CONTROL_TC_VERIFY:
2490                         case NETLOGON_CONTROL_FORCE_DNS_REG:
2491                         case NETLOGON_CONTROL_QUERY_DNS_REG:
2492                         case NETLOGON_CONTROL_SET_DBFLAG:
2493                                 torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
2494                                         "LogonControl returned unexpected error code");
2495                                 break;
2496                         case NETLOGON_CONTROL_TRUNCATE_LOG:
2497                                 if ((secure_channel_type == SEC_CHAN_BDC) ||
2498                                     (secure_channel_type == SEC_CHAN_WKSTA)) {
2499                                         torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED,
2500                                                 "LogonControl returned unexpected error code");
2501                                 } else if (!W_ERROR_EQUAL(r.out.result, WERR_NOT_SUPPORTED)) {
2502                                         torture_assert_werr_ok(tctx, r.out.result,
2503                                                 "LogonControl returned unexpected result");
2504                                 }
2505                                 break;
2506                         default:
2507                                 torture_assert_werr_ok(tctx, r.out.result,
2508                                         "LogonControl returned unexpected result");
2509                                 break;
2510                         }
2511                         break;
2512                 case 2:
2513                         torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
2514                                 "LogonControl returned unexpected error code");
2515                         break;
2516                 default:
2517                         torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_LEVEL,
2518                                 "LogonControl returned unexpected error code");
2519                         break;
2520                 }
2521         }
2522         }
2523
2524         r.in.level = 52;
2525         torture_comment(tctx, "Testing LogonControl function code %s (%d) level %d\n",
2526                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2527         status = dcerpc_netr_LogonControl_r(b, tctx, &r);
2528         torture_assert_ntstatus_ok(tctx, status, "LogonControl");
2529         torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_LEVEL, "LogonControl");
2530
2531         return true;
2532 }
2533
2534
2535 /*
2536   try a netlogon GetAnyDCName
2537 */
2538 static bool test_GetAnyDCName(struct torture_context *tctx,
2539                               struct dcerpc_pipe *p)
2540 {
2541         NTSTATUS status;
2542         struct netr_GetAnyDCName r;
2543         const char *dcname = NULL;
2544         struct dcerpc_binding_handle *b = p->binding_handle;
2545
2546         r.in.domainname = lpcfg_workgroup(tctx->lp_ctx);
2547         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2548         r.out.dcname = &dcname;
2549
2550         status = dcerpc_netr_GetAnyDCName_r(b, tctx, &r);
2551         torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
2552         if ((!W_ERROR_IS_OK(r.out.result)) &&
2553             (!W_ERROR_EQUAL(r.out.result, WERR_NO_SUCH_DOMAIN))) {
2554                 return false;
2555         }
2556
2557         if (dcname) {
2558             torture_comment(tctx, "\tDC is at '%s'\n", dcname);
2559         }
2560
2561         r.in.domainname = NULL;
2562
2563         status = dcerpc_netr_GetAnyDCName_r(b, tctx, &r);
2564         torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
2565         if ((!W_ERROR_IS_OK(r.out.result)) &&
2566             (!W_ERROR_EQUAL(r.out.result, WERR_NO_SUCH_DOMAIN))) {
2567                 return false;
2568         }
2569
2570         r.in.domainname = "";
2571
2572         status = dcerpc_netr_GetAnyDCName_r(b, tctx, &r);
2573         torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
2574         if ((!W_ERROR_IS_OK(r.out.result)) &&
2575             (!W_ERROR_EQUAL(r.out.result, WERR_NO_SUCH_DOMAIN))) {
2576                 return false;
2577         }
2578
2579         return true;
2580 }
2581
2582
2583 /*
2584   try a netlogon LogonControl2
2585 */
2586 static bool test_LogonControl2(struct torture_context *tctx,
2587                                struct dcerpc_pipe *p,
2588                                struct cli_credentials *machine_credentials)
2589
2590 {
2591         NTSTATUS status;
2592         struct netr_LogonControl2 r;
2593         union netr_CONTROL_DATA_INFORMATION data;
2594         union netr_CONTROL_QUERY_INFORMATION query;
2595         enum netr_SchannelType secure_channel_type = SEC_CHAN_NULL;
2596         int i;
2597         struct dcerpc_binding_handle *b = p->binding_handle;
2598
2599         data.domain = lpcfg_workgroup(tctx->lp_ctx);
2600
2601         if (machine_credentials) {
2602                 secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
2603         }
2604
2605         torture_comment(tctx, "Testing LogonControl2 with secure channel type: %d\n",
2606                 secure_channel_type);
2607
2608         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2609
2610         r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
2611         r.in.data = &data;
2612         r.out.query = &query;
2613
2614         for (i=1;i<4;i++) {
2615                 r.in.level = i;
2616
2617                 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
2618                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2619
2620                 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
2621                 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
2622         }
2623
2624         data.domain = lpcfg_workgroup(tctx->lp_ctx);
2625
2626         r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
2627         r.in.data = &data;
2628
2629         for (i=1;i<4;i++) {
2630                 r.in.level = i;
2631
2632                 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
2633                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2634
2635                 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
2636                 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
2637         }
2638
2639         data.domain = lpcfg_workgroup(tctx->lp_ctx);
2640
2641         r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
2642         r.in.data = &data;
2643
2644         for (i=1;i<4;i++) {
2645                 r.in.level = i;
2646
2647                 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
2648                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2649
2650                 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
2651                 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
2652         }
2653
2654         data.debug_level = ~0;
2655
2656         r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
2657         r.in.data = &data;
2658
2659         for (i=1;i<4;i++) {
2660                 r.in.level = i;
2661
2662                 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
2663                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2664
2665                 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
2666                 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
2667         }
2668
2669         ZERO_STRUCT(data);
2670         r.in.function_code = 52;
2671         r.in.data = &data;
2672
2673         torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
2674                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2675
2676         status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
2677         torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
2678         switch (secure_channel_type) {
2679         case SEC_CHAN_NULL:
2680                 torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED, "LogonControl2");
2681                 break;
2682         default:
2683                 torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED, "LogonControl2");
2684                 break;
2685         }
2686         data.debug_level = ~0;
2687
2688         r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
2689         r.in.data = &data;
2690
2691         r.in.level = 52;
2692         torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
2693                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2694
2695         status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
2696         torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
2697         torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_LEVEL, "LogonControl2");
2698
2699         return true;
2700 }
2701
2702 /*
2703   try a netlogon DatabaseSync2
2704 */
2705 static bool test_DatabaseSync2(struct torture_context *tctx,
2706                                struct dcerpc_pipe *p,
2707                                struct cli_credentials *machine_credentials)
2708 {
2709         struct netr_DatabaseSync2 r;
2710         struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
2711         struct netr_Authenticator return_authenticator, credential;
2712
2713         struct netlogon_creds_CredentialState *creds;
2714         const uint32_t database_ids[] = {0, 1, 2};
2715         int i;
2716         struct dcerpc_binding_handle *b = p->binding_handle;
2717
2718         if (!test_SetupCredentials2(p, tctx, NETLOGON_NEG_AUTH2_FLAGS,
2719                                     machine_credentials,
2720                                     cli_credentials_get_secure_channel_type(machine_credentials),
2721                                     &creds)) {
2722                 return false;
2723         }
2724
2725         ZERO_STRUCT(return_authenticator);
2726
2727         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2728         r.in.computername = TEST_MACHINE_NAME;
2729         r.in.preferredmaximumlength = (uint32_t)-1;
2730         r.in.return_authenticator = &return_authenticator;
2731         r.out.return_authenticator = &return_authenticator;
2732         r.out.delta_enum_array = &delta_enum_array;
2733
2734         for (i=0;i<ARRAY_SIZE(database_ids);i++) {
2735
2736                 uint32_t sync_context = 0;
2737
2738                 r.in.database_id = database_ids[i];
2739                 r.in.sync_context = &sync_context;
2740                 r.out.sync_context = &sync_context;
2741                 r.in.restart_state = 0;
2742
2743                 torture_comment(tctx, "Testing DatabaseSync2 of id %d\n", r.in.database_id);
2744
2745                 do {
2746                         netlogon_creds_client_authenticator(creds, &credential);
2747
2748                         r.in.credential = &credential;
2749
2750                         torture_assert_ntstatus_ok(tctx, dcerpc_netr_DatabaseSync2_r(b, tctx, &r),
2751                                 "DatabaseSync2 failed");
2752                         if (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES))
2753                             break;
2754
2755                         /* Native mode servers don't do this */
2756                         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_SUPPORTED)) {
2757                                 return true;
2758                         }
2759
2760                         torture_assert_ntstatus_ok(tctx, r.out.result, "DatabaseSync2");
2761
2762                         if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
2763                                 torture_comment(tctx, "Credential chaining failed\n");
2764                         }
2765
2766                 } while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES));
2767         }
2768
2769         return true;
2770 }
2771
2772
2773 /*
2774   try a netlogon LogonControl2Ex
2775 */
2776 static bool test_LogonControl2Ex(struct torture_context *tctx,
2777                                  struct dcerpc_pipe *p,
2778                                  struct cli_credentials *machine_credentials)
2779
2780 {
2781         NTSTATUS status;
2782         struct netr_LogonControl2Ex r;
2783         union netr_CONTROL_DATA_INFORMATION data;
2784         union netr_CONTROL_QUERY_INFORMATION query;
2785         enum netr_SchannelType secure_channel_type = SEC_CHAN_NULL;
2786         int i;
2787         struct dcerpc_binding_handle *b = p->binding_handle;
2788
2789         data.domain = lpcfg_workgroup(tctx->lp_ctx);
2790
2791         if (machine_credentials) {
2792                 secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
2793         }
2794
2795         torture_comment(tctx, "Testing LogonControl2Ex with secure channel type: %d\n",
2796                 secure_channel_type);
2797
2798         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2799
2800         r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
2801         r.in.data = &data;
2802         r.out.query = &query;
2803
2804         for (i=1;i<4;i++) {
2805                 r.in.level = i;
2806
2807                 torture_comment(tctx, "Testing LogonControl2Ex function code %s (%d) level %d\n",
2808                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2809
2810                 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
2811                 torture_assert_ntstatus_ok(tctx, status, "LogonControl2Ex");
2812         }
2813
2814         data.domain = lpcfg_workgroup(tctx->lp_ctx);
2815
2816         r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
2817         r.in.data = &data;
2818
2819         for (i=1;i<4;i++) {
2820                 r.in.level = i;
2821
2822                 torture_comment(tctx, "Testing LogonControl2Ex function code %s (%d) level %d\n",
2823                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2824
2825                 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
2826                 torture_assert_ntstatus_ok(tctx, status, "LogonControl2Ex");
2827         }
2828
2829         data.domain = lpcfg_workgroup(tctx->lp_ctx);
2830
2831         r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
2832         r.in.data = &data;
2833
2834         for (i=1;i<4;i++) {
2835                 r.in.level = i;
2836
2837                 torture_comment(tctx, "Testing LogonControl2Ex function code %s (%d) level %d\n",
2838                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2839
2840                 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
2841                 torture_assert_ntstatus_ok(tctx, status, "LogonControl2Ex");
2842         }
2843
2844         data.debug_level = ~0;
2845
2846         r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
2847         r.in.data = &data;
2848
2849         for (i=1;i<4;i++) {
2850                 r.in.level = i;
2851
2852                 torture_comment(tctx, "Testing LogonControl2Ex function code %s (%d) level %d\n",
2853                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2854
2855                 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
2856                 torture_assert_ntstatus_ok(tctx, status, "LogonControl2Ex");
2857         }
2858
2859         ZERO_STRUCT(data);
2860         r.in.function_code = 52;
2861         r.in.data = &data;
2862
2863         torture_comment(tctx, "Testing LogonControl2Ex function code %s (%d) level %d\n",
2864                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2865
2866         status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
2867         torture_assert_ntstatus_ok(tctx, status, "LogonControl2Ex");
2868         switch (secure_channel_type) {
2869         case SEC_CHAN_NULL:
2870                 torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED, "LogonControl2Ex");
2871                 break;
2872         default:
2873                 torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED, "LogonControl2Ex");
2874                 break;
2875         }
2876         data.debug_level = ~0;
2877
2878         r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
2879         r.in.data = &data;
2880
2881         r.in.level = 52;
2882         torture_comment(tctx, "Testing LogonControl2Ex function code %s (%d) level %d\n",
2883                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2884
2885         status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
2886         torture_assert_ntstatus_ok(tctx, status, "LogonControl2Ex");
2887         torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_LEVEL, "LogonControl2Ex");
2888
2889         return true;
2890 }
2891
2892 static bool test_netr_GetForestTrustInformation(struct torture_context *tctx,
2893                                                 struct dcerpc_pipe *p1,
2894                                                 struct cli_credentials *machine_credentials)
2895 {
2896         struct netr_GetForestTrustInformation r;
2897         struct netlogon_creds_CredentialState *creds;
2898         struct netr_Authenticator a;
2899         struct netr_Authenticator return_authenticator;
2900         struct lsa_ForestTrustInformation *forest_trust_info;
2901         struct dcerpc_pipe *p = NULL;
2902         struct dcerpc_binding_handle *b = NULL;
2903
2904         if (!test_SetupCredentials3(p1, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
2905                                     machine_credentials, &creds)) {
2906                 return false;
2907         }
2908         if (!test_SetupCredentialsPipe(p1, tctx, machine_credentials, creds,
2909                                        DCERPC_SIGN | DCERPC_SEAL, &p)) {
2910                 return false;
2911         }
2912         b = p->binding_handle;
2913
2914         netlogon_creds_client_authenticator(creds, &a);
2915
2916         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2917         r.in.computer_name = TEST_MACHINE_NAME;
2918         r.in.credential = &a;
2919         r.in.flags = 0;
2920         r.out.return_authenticator = &return_authenticator;
2921         r.out.forest_trust_info = &forest_trust_info;
2922
2923         torture_assert_ntstatus_ok(tctx,
2924                 dcerpc_netr_GetForestTrustInformation_r(b, tctx, &r),
2925                 "netr_GetForestTrustInformation failed");
2926         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_IMPLEMENTED)) {
2927                 torture_comment(tctx, "not considering NT_STATUS_NOT_IMPLEMENTED as an error\n");
2928         } else {
2929                 torture_assert_ntstatus_ok(tctx, r.out.result,
2930                         "netr_GetForestTrustInformation failed");
2931         }
2932
2933         torture_assert(tctx,
2934                 netlogon_creds_client_check(creds, &return_authenticator.cred),
2935                 "Credential chaining failed");
2936
2937         return true;
2938 }
2939
2940 static bool test_netr_DsRGetForestTrustInformation(struct torture_context *tctx,
2941                                                    struct dcerpc_pipe *p, const char *trusted_domain_name)
2942 {
2943         NTSTATUS status;
2944         struct netr_DsRGetForestTrustInformation r;
2945         struct lsa_ForestTrustInformation info, *info_ptr;
2946         struct dcerpc_binding_handle *b = p->binding_handle;
2947
2948         info_ptr = &info;
2949
2950         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2951         r.in.trusted_domain_name = trusted_domain_name;
2952         r.in.flags = 0;
2953         r.out.forest_trust_info = &info_ptr;
2954
2955         torture_comment(tctx ,"Testing netr_DsRGetForestTrustInformation\n");
2956
2957         status = dcerpc_netr_DsRGetForestTrustInformation_r(b, tctx, &r);
2958         torture_assert_ntstatus_ok(tctx, status, "DsRGetForestTrustInformation");
2959         torture_assert_werr_ok(tctx, r.out.result, "DsRGetForestTrustInformation");
2960
2961         return true;
2962 }
2963
2964 /*
2965   try a netlogon netr_DsrEnumerateDomainTrusts
2966 */
2967 static bool test_DsrEnumerateDomainTrusts(struct torture_context *tctx,
2968                                           struct dcerpc_pipe *p)
2969 {
2970         NTSTATUS status;
2971         struct netr_DsrEnumerateDomainTrusts r;
2972         struct netr_DomainTrustList trusts;
2973         int i;
2974         struct dcerpc_binding_handle *b = p->binding_handle;
2975
2976         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2977         r.in.trust_flags = 0x3f;
2978         r.out.trusts = &trusts;
2979
2980         status = dcerpc_netr_DsrEnumerateDomainTrusts_r(b, tctx, &r);
2981         torture_assert_ntstatus_ok(tctx, status, "DsrEnumerateDomaintrusts");
2982         torture_assert_werr_ok(tctx, r.out.result, "DsrEnumerateDomaintrusts");
2983
2984         /* when trusted_domain_name is NULL, netr_DsRGetForestTrustInformation
2985          * will show non-forest trusts and all UPN suffixes of the own forest
2986          * as LSA_FOREST_TRUST_TOP_LEVEL_NAME types */
2987
2988         if (r.out.trusts->count) {
2989                 if (!test_netr_DsRGetForestTrustInformation(tctx, p, NULL)) {
2990                         return false;
2991                 }
2992         }
2993
2994         for (i=0; i<r.out.trusts->count; i++) {
2995
2996                 /* get info for transitive forest trusts */
2997
2998                 if (r.out.trusts->array[i].trust_attributes & LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) {
2999                         if (!test_netr_DsRGetForestTrustInformation(tctx, p,
3000                                                                     r.out.trusts->array[i].dns_name)) {
3001                                 return false;
3002                         }
3003                 }
3004         }
3005
3006         return true;
3007 }
3008
3009 static bool test_netr_NetrEnumerateTrustedDomains(struct torture_context *tctx,
3010                                                   struct dcerpc_pipe *p)
3011 {
3012         NTSTATUS status;
3013         struct netr_NetrEnumerateTrustedDomains r;
3014         struct netr_Blob trusted_domains_blob;
3015         struct dcerpc_binding_handle *b = p->binding_handle;
3016
3017         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3018         r.out.trusted_domains_blob = &trusted_domains_blob;
3019
3020         status = dcerpc_netr_NetrEnumerateTrustedDomains_r(b, tctx, &r);
3021         torture_assert_ntstatus_ok(tctx, status, "netr_NetrEnumerateTrustedDomains");
3022         torture_assert_ntstatus_ok(tctx, r.out.result, "NetrEnumerateTrustedDomains");
3023
3024         return true;
3025 }
3026
3027 static bool test_netr_NetrEnumerateTrustedDomainsEx(struct torture_context *tctx,
3028                                                     struct dcerpc_pipe *p)
3029 {
3030         NTSTATUS status;
3031         struct netr_NetrEnumerateTrustedDomainsEx r;
3032         struct netr_DomainTrustList dom_trust_list;
3033         struct dcerpc_binding_handle *b = p->binding_handle;
3034
3035         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3036         r.out.dom_trust_list = &dom_trust_list;
3037
3038         status = dcerpc_netr_NetrEnumerateTrustedDomainsEx_r(b, tctx, &r);
3039         torture_assert_ntstatus_ok(tctx, status, "netr_NetrEnumerateTrustedDomainsEx");
3040         torture_assert_werr_ok(tctx, r.out.result, "NetrEnumerateTrustedDomainsEx");
3041
3042         return true;
3043 }
3044
3045
3046 static bool test_netr_DsRGetSiteName(struct dcerpc_pipe *p, struct torture_context *tctx,
3047                                      const char *computer_name,
3048                                      const char *expected_site)
3049 {
3050         NTSTATUS status;
3051         struct netr_DsRGetSiteName r;
3052         const char *site = NULL;
3053         struct dcerpc_binding_handle *b = p->binding_handle;
3054
3055         r.in.computer_name              = computer_name;
3056         r.out.site                      = &site;
3057         torture_comment(tctx, "Testing netr_DsRGetSiteName\n");
3058
3059         status = dcerpc_netr_DsRGetSiteName_r(b, tctx, &r);
3060         torture_assert_ntstatus_ok(tctx, status, "DsRGetSiteName");
3061         torture_assert_werr_ok(tctx, r.out.result, "DsRGetSiteName");
3062         torture_assert_str_equal(tctx, expected_site, site, "netr_DsRGetSiteName");
3063
3064         return true;
3065 }
3066
3067 /*
3068   try a netlogon netr_DsRGetDCName
3069 */
3070 static bool test_netr_DsRGetDCName(struct torture_context *tctx,
3071                                    struct dcerpc_pipe *p)
3072 {
3073         NTSTATUS status;
3074         struct netr_DsRGetDCName r;
3075         struct netr_DsRGetDCNameInfo *info = NULL;
3076         struct dcerpc_binding_handle *b = p->binding_handle;
3077
3078         r.in.server_unc         = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3079         r.in.domain_name        = lpcfg_dnsdomain(tctx->lp_ctx);
3080         r.in.domain_guid        = NULL;
3081         r.in.site_guid          = NULL;
3082         r.in.flags              = DS_RETURN_DNS_NAME;
3083         r.out.info              = &info;
3084
3085         status = dcerpc_netr_DsRGetDCName_r(b, tctx, &r);
3086         torture_assert_ntstatus_ok(tctx, status, "DsRGetDCName");
3087         torture_assert_werr_ok(tctx, r.out.result, "DsRGetDCName");
3088
3089         torture_assert_int_equal(tctx,
3090                                  (info->dc_flags & (DS_DNS_CONTROLLER)),
3091                                  DS_DNS_CONTROLLER,
3092                                  "DsRGetDCName");
3093         torture_assert_int_equal(tctx,
3094                                  (info->dc_flags & (DS_DNS_DOMAIN)),
3095                                  DS_DNS_DOMAIN,
3096                                  "DsRGetDCName");
3097         torture_assert_int_equal(tctx,
3098                                  (info->dc_flags & (DS_DNS_FOREST_ROOT)),
3099                                  DS_DNS_FOREST_ROOT,
3100                                  "DsRGetDCName");
3101
3102         r.in.domain_name        = lpcfg_workgroup(tctx->lp_ctx);
3103         r.in.flags              = 0;
3104
3105         status = dcerpc_netr_DsRGetDCName_r(b, tctx, &r);
3106         torture_assert_ntstatus_ok(tctx, status, "DsRGetDCName");
3107         torture_assert_werr_ok(tctx, r.out.result, "DsRGetDCName");
3108
3109         torture_assert_int_equal(tctx,
3110                                  (info->dc_flags & (DS_DNS_CONTROLLER)), 0,
3111                                  "DsRGetDCName");
3112         torture_assert_int_equal(tctx,
3113                                  (info->dc_flags & (DS_DNS_DOMAIN)), 0,
3114                                  "DsRGetDCName");
3115         torture_assert_int_equal(tctx,
3116                                  (info->dc_flags & (DS_DNS_FOREST_ROOT)),
3117                                  DS_DNS_FOREST_ROOT,
3118                                  "DsRGetDCName");
3119
3120         if (strcasecmp(info->dc_site_name, info->client_site_name) == 0) {
3121                 torture_assert_int_equal(tctx,
3122                                          (info->dc_flags & (DS_SERVER_CLOSEST)),
3123                                          DS_SERVER_CLOSEST,
3124                                          "DsRGetDCName");
3125         }
3126
3127         return test_netr_DsRGetSiteName(p, tctx,
3128                                        info->dc_unc,
3129                                        info->dc_site_name);
3130 }
3131
3132 /*
3133   try a netlogon netr_DsRGetDCNameEx
3134 */
3135 static bool test_netr_DsRGetDCNameEx(struct torture_context *tctx,
3136                                      struct dcerpc_pipe *p)
3137 {
3138         NTSTATUS status;
3139         struct netr_DsRGetDCNameEx r;
3140         struct netr_DsRGetDCNameInfo *info = NULL;
3141         struct dcerpc_binding_handle *b = p->binding_handle;
3142
3143         r.in.server_unc         = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3144         r.in.domain_name        = lpcfg_dnsdomain(tctx->lp_ctx);
3145         r.in.domain_guid        = NULL;
3146         r.in.site_name          = NULL;
3147         r.in.flags              = DS_RETURN_DNS_NAME;
3148         r.out.info              = &info;
3149
3150         status = dcerpc_netr_DsRGetDCNameEx_r(b, tctx, &r);
3151         torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx");
3152         torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx");
3153
3154         torture_assert_int_equal(tctx,
3155                                  (info->dc_flags & (DS_DNS_CONTROLLER)),
3156                                  DS_DNS_CONTROLLER,
3157                                  "DsRGetDCNameEx");
3158         torture_assert_int_equal(tctx,
3159                                  (info->dc_flags & (DS_DNS_DOMAIN)),
3160                                  DS_DNS_DOMAIN,
3161                                  "DsRGetDCNameEx");
3162         torture_assert_int_equal(tctx,
3163                                  (info->dc_flags & (DS_DNS_FOREST_ROOT)),
3164                                  DS_DNS_FOREST_ROOT,
3165                                  "DsRGetDCNameEx");
3166
3167         r.in.domain_name        = lpcfg_workgroup(tctx->lp_ctx);
3168         r.in.flags              = 0;
3169
3170         status = dcerpc_netr_DsRGetDCNameEx_r(b, tctx, &r);
3171         torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx");
3172         torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx");
3173
3174         torture_assert_int_equal(tctx,
3175                                  (info->dc_flags & (DS_DNS_CONTROLLER)), 0,
3176                                  "DsRGetDCNameEx");
3177         torture_assert_int_equal(tctx,
3178                                  (info->dc_flags & (DS_DNS_DOMAIN)), 0,
3179                                  "DsRGetDCNameEx");
3180         torture_assert_int_equal(tctx,
3181                                  (info->dc_flags & (DS_DNS_FOREST_ROOT)),
3182                                  DS_DNS_FOREST_ROOT,
3183                                  "DsRGetDCNameEx");
3184
3185         if (strcasecmp(info->dc_site_name, info->client_site_name) == 0) {
3186                 torture_assert_int_equal(tctx,
3187                                          (info->dc_flags & (DS_SERVER_CLOSEST)),
3188                                          DS_SERVER_CLOSEST,
3189                                          "DsRGetDCNameEx");
3190         }
3191
3192         return test_netr_DsRGetSiteName(p, tctx, info->dc_unc,
3193                                         info->dc_site_name);
3194 }
3195
3196 /*
3197   try a netlogon netr_DsRGetDCNameEx2
3198 */
3199 static bool test_netr_DsRGetDCNameEx2(struct torture_context *tctx,
3200                                       struct dcerpc_pipe *p)
3201 {
3202         NTSTATUS status;
3203         struct netr_DsRGetDCNameEx2 r;
3204         struct netr_DsRGetDCNameInfo *info = NULL;
3205         struct dcerpc_binding_handle *b = p->binding_handle;
3206
3207         torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 with no inputs\n");
3208         ZERO_STRUCT(r.in);
3209         r.in.flags              = DS_RETURN_DNS_NAME;
3210         r.out.info              = &info;
3211
3212         status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
3213         torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
3214         torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
3215
3216         torture_assert_int_equal(tctx,
3217                                  (info->dc_flags & (DS_DNS_CONTROLLER)),
3218                                  DS_DNS_CONTROLLER,
3219                                  "DsRGetDCNameEx2");
3220         torture_assert_int_equal(tctx,
3221                                  (info->dc_flags & (DS_DNS_DOMAIN)),
3222                                  DS_DNS_DOMAIN,
3223                                  "DsRGetDCNameEx2");
3224         torture_assert_int_equal(tctx,
3225                                  (info->dc_flags & (DS_DNS_FOREST_ROOT)),
3226                                  DS_DNS_FOREST_ROOT,
3227                                  "DsRGetDCNameEx2");
3228
3229         r.in.server_unc         = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3230         r.in.client_account     = NULL;
3231         r.in.mask               = 0x00000000;
3232         r.in.domain_name        = lpcfg_dnsdomain(tctx->lp_ctx);
3233         r.in.domain_guid        = NULL;
3234         r.in.site_name          = NULL;
3235         r.in.flags              = DS_RETURN_DNS_NAME;
3236         r.out.info              = &info;
3237
3238         torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 without client account\n");
3239
3240         status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
3241         torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
3242         torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
3243
3244         r.in.domain_name        = lpcfg_workgroup(tctx->lp_ctx);
3245         r.in.flags              = 0;
3246
3247         status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
3248         torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
3249         torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
3250
3251         torture_assert_int_equal(tctx,
3252                                  (info->dc_flags & (DS_DNS_CONTROLLER)), 0,
3253                                  "DsRGetDCNameEx2");
3254         torture_assert_int_equal(tctx,
3255                                  (info->dc_flags & (DS_DNS_DOMAIN)), 0,
3256                                  "DsRGetDCNameEx2");
3257         torture_assert_int_equal(tctx,
3258                                  (info->dc_flags & (DS_DNS_FOREST_ROOT)),
3259                                  DS_DNS_FOREST_ROOT,
3260                                  "DsRGetDCNameEx2");
3261
3262         if (strcasecmp(info->dc_site_name, info->client_site_name) == 0) {
3263                 torture_assert_int_equal(tctx,
3264                                          (info->dc_flags & (DS_SERVER_CLOSEST)),
3265                                          DS_SERVER_CLOSEST,
3266                                          "DsRGetDCNameEx2");
3267         }
3268
3269         torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 with client account\n");
<