torture-netlogon: Use "all_zero" where appropriate
[kai/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");
3270         r.in.client_account     = TEST_MACHINE_NAME"$";
3271         r.in.mask               = ACB_SVRTRUST;
3272         r.in.flags              = DS_RETURN_FLAT_NAME;
3273         r.out.info              = &info;
3274
3275         status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
3276         torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
3277         torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
3278
3279         return test_netr_DsRGetSiteName(p, tctx, info->dc_unc,
3280                                         info->dc_site_name);
3281 }
3282
3283 /* This is a substitution for "samdb_server_site_name" which relies on the
3284  * correct "lp_ctx" and therefore can't be used here. */
3285 static const char *server_site_name(struct torture_context *tctx,
3286                                     struct ldb_context *ldb)
3287 {
3288         TALLOC_CTX *tmp_ctx;
3289         struct ldb_dn *dn, *server_dn;
3290         const struct ldb_val *site_name_val;
3291         const char *server_dn_str, *site_name;
3292
3293         tmp_ctx = talloc_new(ldb);
3294         if (tmp_ctx == NULL) {
3295                 goto failed;
3296         }
3297
3298         dn = ldb_dn_new(tmp_ctx, ldb, "");
3299         if (dn == NULL) {
3300                 goto failed;
3301         }
3302
3303         server_dn_str = samdb_search_string(ldb, tmp_ctx, dn, "serverName",
3304                                             NULL);
3305         if (server_dn_str == NULL) {
3306                 goto failed;
3307         }
3308
3309         server_dn = ldb_dn_new(tmp_ctx, ldb, server_dn_str);
3310         if (server_dn == NULL) {
3311                 goto failed;
3312         }
3313
3314         /* CN=<Server name>, CN=Servers, CN=<Site name>, CN=Sites, ... */
3315         site_name_val = ldb_dn_get_component_val(server_dn, 2);
3316         if (site_name_val == NULL) {
3317                 goto failed;
3318         }
3319
3320         site_name = (const char *) site_name_val->data;
3321
3322         talloc_steal(tctx, site_name);
3323         talloc_free(tmp_ctx);
3324
3325         return site_name;
3326
3327 failed:
3328         talloc_free(tmp_ctx);
3329         return NULL;
3330 }
3331
3332 static bool test_netr_DsrGetDcSiteCoverageW(struct torture_context *tctx,
3333                                             struct dcerpc_pipe *p)
3334 {
3335         char *url;
3336         struct ldb_context *sam_ctx = NULL;
3337         NTSTATUS status;
3338         struct netr_DsrGetDcSiteCoverageW r;
3339         struct DcSitesCtr *ctr = NULL;
3340         struct dcerpc_binding_handle *b = p->binding_handle;
3341
3342         torture_comment(tctx, "This does only pass with the default site\n");
3343
3344         /* We won't double-check this when we are over 'local' transports */
3345         if (dcerpc_server_name(p)) {
3346                 /* Set up connection to SAMDB on DC */
3347                 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
3348                 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
3349                                            NULL,
3350                                            cmdline_credentials,
3351                                            0);
3352
3353                 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
3354         }
3355
3356         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3357         r.out.ctr = &ctr;
3358
3359         status = dcerpc_netr_DsrGetDcSiteCoverageW_r(b, tctx, &r);
3360         torture_assert_ntstatus_ok(tctx, status, "failed");
3361         torture_assert_werr_ok(tctx, r.out.result, "failed");
3362
3363         torture_assert(tctx, ctr->num_sites == 1,
3364                        "we should per default only get the default site");
3365         if (sam_ctx != NULL) {
3366                 torture_assert_casestr_equal(tctx, ctr->sites[0].string,
3367                                              server_site_name(tctx, sam_ctx),
3368                                              "didn't return default site");
3369         }
3370
3371         return true;
3372 }
3373
3374 static bool test_netr_DsRAddressToSitenamesW(struct torture_context *tctx,
3375                                              struct dcerpc_pipe *p)
3376 {
3377         char *url;
3378         struct ldb_context *sam_ctx = NULL;
3379         NTSTATUS status;
3380         struct netr_DsRAddressToSitenamesW r;
3381         struct netr_DsRAddress addrs[6];
3382         struct sockaddr_in *addr;
3383 #ifdef HAVE_IPV6
3384         struct sockaddr_in6 *addr6;
3385 #endif
3386         struct netr_DsRAddressToSitenamesWCtr *ctr;
3387         struct dcerpc_binding_handle *b = p->binding_handle;
3388         uint32_t i;
3389         int ret;
3390
3391         torture_comment(tctx, "This does only pass with the default site\n");
3392
3393         /* We won't double-check this when we are over 'local' transports */
3394         if (dcerpc_server_name(p)) {
3395                 /* Set up connection to SAMDB on DC */
3396                 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
3397                 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
3398                                            NULL,
3399                                            cmdline_credentials,
3400                                            0);
3401
3402                 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
3403         }
3404
3405         /* First try valid IP addresses */
3406
3407         addrs[0].size = sizeof(struct sockaddr_in);
3408         addrs[0].buffer = talloc_zero_array(tctx, uint8_t, addrs[0].size);
3409         addr = (struct sockaddr_in *) addrs[0].buffer;
3410         addrs[0].buffer[0] = AF_INET;
3411         ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
3412         torture_assert(tctx, ret > 0, "inet_pton failed");
3413
3414         addrs[1].size = sizeof(struct sockaddr_in);
3415         addrs[1].buffer = talloc_zero_array(tctx, uint8_t, addrs[1].size);
3416         addr = (struct sockaddr_in *) addrs[1].buffer;
3417         addrs[1].buffer[0] = AF_INET;
3418         ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
3419         torture_assert(tctx, ret > 0, "inet_pton failed");
3420
3421         addrs[2].size = sizeof(struct sockaddr_in);
3422         addrs[2].buffer = talloc_zero_array(tctx, uint8_t, addrs[2].size);
3423         addr = (struct sockaddr_in *) addrs[2].buffer;
3424         addrs[2].buffer[0] = AF_INET;
3425         ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
3426         torture_assert(tctx, ret > 0, "inet_pton failed");
3427
3428 #ifdef HAVE_IPV6
3429         addrs[3].size = sizeof(struct sockaddr_in6);
3430         addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
3431         addr6 = (struct sockaddr_in6 *) addrs[3].buffer;
3432         addrs[3].buffer[0] = AF_INET6;
3433         ret = inet_pton(AF_INET6, "::1", &addr6->sin6_addr);
3434         torture_assert(tctx, ret > 0, "inet_pton failed");
3435
3436         addrs[4].size = sizeof(struct sockaddr_in6);
3437         addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
3438         addr6 = (struct sockaddr_in6 *) addrs[4].buffer;
3439         addrs[4].buffer[0] = AF_INET6;
3440         ret = inet_pton(AF_INET6, "::", &addr6->sin6_addr);
3441         torture_assert(tctx, ret > 0, "inet_pton failed");
3442
3443         addrs[5].size = sizeof(struct sockaddr_in6);
3444         addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
3445         addr6 = (struct sockaddr_in6 *) addrs[5].buffer;
3446         addrs[5].buffer[0] = AF_INET6;
3447         ret = inet_pton(AF_INET6, "ff02::1", &addr6->sin6_addr);
3448         torture_assert(tctx, ret > 0, "inet_pton failed");
3449 #else
3450         /* the test cases are repeated to have exactly 6. This is for
3451          * compatibility with IPv4-only machines */
3452         addrs[3].size = sizeof(struct sockaddr_in);
3453         addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
3454         addr = (struct sockaddr_in *) addrs[3].buffer;
3455         addrs[3].buffer[0] = AF_INET;
3456         ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
3457         torture_assert(tctx, ret > 0, "inet_pton failed");
3458
3459         addrs[4].size = sizeof(struct sockaddr_in);
3460         addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
3461         addr = (struct sockaddr_in *) addrs[4].buffer;
3462         addrs[4].buffer[0] = AF_INET;
3463         ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
3464         torture_assert(tctx, ret > 0, "inet_pton failed");
3465
3466         addrs[5].size = sizeof(struct sockaddr_in);
3467         addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
3468         addr = (struct sockaddr_in *) addrs[5].buffer;
3469         addrs[5].buffer[0] = AF_INET;
3470         ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
3471         torture_assert(tctx, ret > 0, "inet_pton failed");
3472 #endif
3473
3474         ctr = talloc(tctx, struct netr_DsRAddressToSitenamesWCtr);
3475
3476         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3477         r.in.count = 6;
3478         r.in.addresses = addrs;
3479         r.out.ctr = &ctr;
3480
3481         status = dcerpc_netr_DsRAddressToSitenamesW_r(b, tctx, &r);
3482         torture_assert_ntstatus_ok(tctx, status, "failed");
3483         torture_assert_werr_ok(tctx, r.out.result, "failed");
3484
3485         if (sam_ctx != NULL) {
3486                 for (i = 0; i < 3; i++) {
3487                         torture_assert_casestr_equal(tctx,
3488                                                      ctr->sitename[i].string,
3489                                                      server_site_name(tctx, sam_ctx),
3490                                                      "didn't return default site");
3491                 }
3492                 for (i = 3; i < 6; i++) {
3493                         /* Windows returns "NULL" for the sitename if it isn't
3494                          * IPv6 configured */
3495                         if (torture_setting_bool(tctx, "samba4", false)) {
3496                                 torture_assert_casestr_equal(tctx,
3497                                                              ctr->sitename[i].string,
3498                                                              server_site_name(tctx, sam_ctx),
3499                                                              "didn't return default site");
3500                         }
3501                 }
3502         }
3503
3504         /* Now try invalid ones (too short buffers) */
3505
3506         addrs[0].size = 0;
3507         addrs[1].size = 1;
3508         addrs[2].size = 4;
3509
3510         addrs[3].size = 0;
3511         addrs[4].size = 1;
3512         addrs[5].size = 4;
3513
3514         status = dcerpc_netr_DsRAddressToSitenamesW_r(b, tctx, &r);
3515         torture_assert_ntstatus_ok(tctx, status, "failed");
3516         torture_assert_werr_ok(tctx, r.out.result, "failed");
3517
3518         for (i = 0; i < 6; i++) {
3519                 torture_assert(tctx, ctr->sitename[i].string == NULL,
3520                                "sitename should be null");
3521         }
3522
3523         /* Now try invalid ones (wrong address types) */
3524
3525         addrs[0].size = 10;
3526         addrs[0].buffer[0] = AF_UNSPEC;
3527         addrs[1].size = 10;
3528         addrs[1].buffer[0] = AF_UNIX; /* AF_LOCAL = AF_UNIX */
3529         addrs[2].size = 10;
3530         addrs[2].buffer[0] = AF_UNIX;
3531
3532         addrs[3].size = 10;
3533         addrs[3].buffer[0] = 250;
3534         addrs[4].size = 10;
3535         addrs[4].buffer[0] = 251;
3536         addrs[5].size = 10;
3537         addrs[5].buffer[0] = 252;
3538
3539         status = dcerpc_netr_DsRAddressToSitenamesW_r(b, tctx, &r);
3540         torture_assert_ntstatus_ok(tctx, status, "failed");
3541         torture_assert_werr_ok(tctx, r.out.result, "failed");
3542
3543         for (i = 0; i < 6; i++) {
3544                 torture_assert(tctx, ctr->sitename[i].string == NULL,
3545                                "sitename should be null");
3546         }
3547
3548         return true;
3549 }
3550
3551 static bool test_netr_DsRAddressToSitenamesExW(struct torture_context *tctx,
3552                                                struct dcerpc_pipe *p)
3553 {
3554         char *url;
3555         struct ldb_context *sam_ctx = NULL;
3556         NTSTATUS status;
3557         struct netr_DsRAddressToSitenamesExW r;
3558         struct netr_DsRAddress addrs[6];
3559         struct sockaddr_in *addr;
3560 #ifdef HAVE_IPV6
3561         struct sockaddr_in6 *addr6;
3562 #endif
3563         struct netr_DsRAddressToSitenamesExWCtr *ctr;
3564         struct dcerpc_binding_handle *b = p->binding_handle;
3565         uint32_t i;
3566         int ret;
3567
3568         torture_comment(tctx, "This does pass with the default site\n");
3569
3570         /* We won't double-check this when we are over 'local' transports */
3571         if (dcerpc_server_name(p)) {
3572                 /* Set up connection to SAMDB on DC */
3573                 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
3574                 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
3575                                            NULL,
3576                                            cmdline_credentials,
3577                                            0);
3578
3579                 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
3580         }
3581
3582         /* First try valid IP addresses */
3583
3584         addrs[0].size = sizeof(struct sockaddr_in);
3585         addrs[0].buffer = talloc_zero_array(tctx, uint8_t, addrs[0].size);
3586         addr = (struct sockaddr_in *) addrs[0].buffer;
3587         addrs[0].buffer[0] = AF_INET;
3588         ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
3589         torture_assert(tctx, ret > 0, "inet_pton failed");
3590
3591         addrs[1].size = sizeof(struct sockaddr_in);
3592         addrs[1].buffer = talloc_zero_array(tctx, uint8_t, addrs[1].size);
3593         addr = (struct sockaddr_in *) addrs[1].buffer;
3594         addrs[1].buffer[0] = AF_INET;
3595         ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
3596         torture_assert(tctx, ret > 0, "inet_pton failed");
3597
3598         addrs[2].size = sizeof(struct sockaddr_in);
3599         addrs[2].buffer = talloc_zero_array(tctx, uint8_t, addrs[2].size);
3600         addr = (struct sockaddr_in *) addrs[2].buffer;
3601         addrs[2].buffer[0] = AF_INET;
3602         ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
3603         torture_assert(tctx, ret > 0, "inet_pton failed");
3604
3605 #ifdef HAVE_IPV6
3606         addrs[3].size = sizeof(struct sockaddr_in6);
3607         addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
3608         addr6 = (struct sockaddr_in6 *) addrs[3].buffer;
3609         addrs[3].buffer[0] = AF_INET6;
3610         ret = inet_pton(AF_INET6, "::1", &addr6->sin6_addr);
3611         torture_assert(tctx, ret > 0, "inet_pton failed");
3612
3613         addrs[4].size = sizeof(struct sockaddr_in6);
3614         addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
3615         addr6 = (struct sockaddr_in6 *) addrs[4].buffer;
3616         addrs[4].buffer[0] = AF_INET6;
3617         ret = inet_pton(AF_INET6, "::", &addr6->sin6_addr);
3618         torture_assert(tctx, ret > 0, "inet_pton failed");
3619
3620         addrs[5].size = sizeof(struct sockaddr_in6);
3621         addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
3622         addr6 = (struct sockaddr_in6 *) addrs[5].buffer;
3623         addrs[5].buffer[0] = AF_INET6;
3624         ret = inet_pton(AF_INET6, "ff02::1", &addr6->sin6_addr);
3625         torture_assert(tctx, ret > 0, "inet_pton failed");
3626 #else
3627         /* the test cases are repeated to have exactly 6. This is for
3628          * compatibility with IPv4-only machines */
3629         addrs[3].size = sizeof(struct sockaddr_in);
3630         addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
3631         addr = (struct sockaddr_in *) addrs[3].buffer;
3632         addrs[3].buffer[0] = AF_INET;
3633         ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
3634         torture_assert(tctx, ret > 0, "inet_pton failed");
3635
3636         addrs[4].size = sizeof(struct sockaddr_in);
3637         addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
3638         addr = (struct sockaddr_in *) addrs[4].buffer;
3639         addrs[4].buffer[0] = AF_INET;
3640         ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
3641         torture_assert(tctx, ret > 0, "inet_pton failed");
3642
3643         addrs[5].size = sizeof(struct sockaddr_in);
3644         addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
3645         addr = (struct sockaddr_in *) addrs[5].buffer;
3646         addrs[5].buffer[0] = AF_INET;
3647         ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
3648         torture_assert(tctx, ret > 0, "inet_pton failed");
3649 #endif
3650
3651         ctr = talloc(tctx, struct netr_DsRAddressToSitenamesExWCtr);
3652
3653         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3654         r.in.count = 6;
3655         r.in.addresses = addrs;
3656         r.out.ctr = &ctr;
3657
3658         status = dcerpc_netr_DsRAddressToSitenamesExW_r(b, tctx, &r);
3659         torture_assert_ntstatus_ok(tctx, status, "failed");
3660         torture_assert_werr_ok(tctx, r.out.result, "failed");
3661
3662         if (sam_ctx != NULL) {
3663                 for (i = 0; i < 3; i++) {
3664                         torture_assert_casestr_equal(tctx,
3665                                                      ctr->sitename[i].string,
3666                                                      server_site_name(tctx, sam_ctx),
3667                                                      "didn't return default site");
3668                         torture_assert(tctx, ctr->subnetname[i].string == NULL,
3669                                        "subnet should be null");
3670                 }
3671                 for (i = 3; i < 6; i++) {
3672                         /* Windows returns "NULL" for the sitename if it isn't
3673                          * IPv6 configured */
3674                         if (torture_setting_bool(tctx, "samba4", false)) {
3675                                 torture_assert_casestr_equal(tctx,
3676                                                              ctr->sitename[i].string,
3677                                                              server_site_name(tctx, sam_ctx),
3678                                                              "didn't return default site");
3679                         }
3680                         torture_assert(tctx, ctr->subnetname[i].string == NULL,
3681                                        "subnet should be null");
3682                 }
3683         }
3684
3685         /* Now try invalid ones (too short buffers) */
3686
3687         addrs[0].size = 0;
3688         addrs[1].size = 1;
3689         addrs[2].size = 4;
3690
3691         addrs[3].size = 0;
3692         addrs[4].size = 1;
3693         addrs[5].size = 4;
3694
3695         status = dcerpc_netr_DsRAddressToSitenamesExW_r(b, tctx, &r);
3696         torture_assert_ntstatus_ok(tctx, status, "failed");
3697         torture_assert_werr_ok(tctx, r.out.result, "failed");
3698
3699         for (i = 0; i < 6; i++) {
3700                 torture_assert(tctx, ctr->sitename[i].string == NULL,
3701                                "sitename should be null");
3702                 torture_assert(tctx, ctr->subnetname[i].string == NULL,
3703                                "subnet should be null");
3704         }
3705
3706         addrs[0].size = 10;
3707         addrs[0].buffer[0] = AF_UNSPEC;
3708         addrs[1].size = 10;
3709         addrs[1].buffer[0] = AF_UNIX; /* AF_LOCAL = AF_UNIX */
3710         addrs[2].size = 10;
3711         addrs[2].buffer[0] = AF_UNIX;
3712
3713         addrs[3].size = 10;
3714         addrs[3].buffer[0] = 250;
3715         addrs[4].size = 10;
3716         addrs[4].buffer[0] = 251;
3717         addrs[5].size = 10;
3718         addrs[5].buffer[0] = 252;
3719
3720         status = dcerpc_netr_DsRAddressToSitenamesExW_r(b, tctx, &r);
3721         torture_assert_ntstatus_ok(tctx, status, "failed");
3722         torture_assert_werr_ok(tctx, r.out.result, "failed");
3723
3724         for (i = 0; i < 6; i++) {
3725                 torture_assert(tctx, ctr->sitename[i].string == NULL,
3726                                "sitename should be null");
3727                 torture_assert(tctx, ctr->subnetname[i].string == NULL,
3728                                "subnet should be null");
3729         }
3730
3731         return true;
3732 }
3733
3734 static bool test_netr_ServerGetTrustInfo_flags(struct torture_context *tctx,
3735                                                struct dcerpc_pipe *p1,
3736                                                struct cli_credentials *machine_credentials,
3737                                                uint32_t negotiate_flags)
3738 {
3739         struct netr_ServerGetTrustInfo r;
3740
3741         struct netr_Authenticator a;
3742         struct netr_Authenticator return_authenticator;
3743         struct samr_Password new_owf_password;
3744         struct samr_Password old_owf_password;
3745         struct netr_TrustInfo *trust_info;
3746
3747         struct netlogon_creds_CredentialState *creds;
3748         struct dcerpc_pipe *p = NULL;
3749         struct dcerpc_binding_handle *b = NULL;
3750
3751         struct samr_Password nt_hash;
3752
3753         if (!test_SetupCredentials3(p1, tctx, negotiate_flags,
3754                                     machine_credentials, &creds)) {
3755                 return false;
3756         }
3757         if (!test_SetupCredentialsPipe(p1, tctx, machine_credentials, creds,
3758                                        DCERPC_SIGN | DCERPC_SEAL, &p)) {
3759                 return false;
3760         }
3761         b = p->binding_handle;
3762
3763         netlogon_creds_client_authenticator(creds, &a);
3764
3765         r.in.server_name                = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3766         r.in.account_name               = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
3767         r.in.secure_channel_type        = cli_credentials_get_secure_channel_type(machine_credentials);
3768         r.in.computer_name              = TEST_MACHINE_NAME;
3769         r.in.credential                 = &a;
3770
3771         r.out.return_authenticator      = &return_authenticator;
3772         r.out.new_owf_password          = &new_owf_password;
3773         r.out.old_owf_password          = &old_owf_password;
3774         r.out.trust_info                = &trust_info;
3775
3776         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerGetTrustInfo_r(b, tctx, &r),
3777                 "ServerGetTrustInfo failed");
3778         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerGetTrustInfo failed");
3779         torture_assert(tctx, netlogon_creds_client_check(creds, &return_authenticator.cred), "Credential chaining failed");
3780
3781         E_md4hash(cli_credentials_get_password(machine_credentials), nt_hash.hash);
3782
3783         netlogon_creds_des_decrypt(creds, &new_owf_password);
3784
3785         dump_data(1, new_owf_password.hash, 16);
3786         dump_data(1, nt_hash.hash, 16);
3787
3788         torture_assert_mem_equal(tctx, new_owf_password.hash, nt_hash.hash, 16,
3789                 "received unexpected owf password\n");
3790
3791         return true;
3792 }
3793
3794 static bool test_netr_ServerGetTrustInfo(struct torture_context *tctx,
3795                                          struct dcerpc_pipe *p,
3796                                          struct cli_credentials *machine_credentials)
3797 {
3798         return test_netr_ServerGetTrustInfo_flags(tctx, p, machine_credentials,
3799                                                   NETLOGON_NEG_AUTH2_ADS_FLAGS);
3800 }
3801
3802 static bool test_netr_ServerGetTrustInfo_AES(struct torture_context *tctx,
3803                                              struct dcerpc_pipe *p,
3804                                              struct cli_credentials *machine_credentials)
3805 {
3806         return test_netr_ServerGetTrustInfo_flags(tctx, p, machine_credentials,
3807                                                   NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES);
3808 }
3809
3810 static bool test_GetDomainInfo(struct torture_context *tctx,
3811                                struct dcerpc_pipe *p1,
3812                                struct cli_credentials *machine_credentials)
3813 {
3814         struct netr_LogonGetDomainInfo r;
3815         struct netr_WorkstationInformation q1;
3816         struct netr_Authenticator a;
3817         struct netlogon_creds_CredentialState *creds;
3818         struct netr_OsVersion os;
3819         union netr_WorkstationInfo query;
3820         union netr_DomainInfo info;
3821         const char* const attrs[] = { "dNSHostName", "operatingSystem",
3822                 "operatingSystemServicePack", "operatingSystemVersion",
3823                 "servicePrincipalName", NULL };
3824         char *url;
3825         struct ldb_context *sam_ctx = NULL;
3826         struct ldb_message **res;
3827         struct ldb_message_element *spn_el;
3828         int ret, i;
3829         char *version_str;
3830         const char *old_dnsname = NULL;
3831         char **spns = NULL;
3832         int num_spns = 0;
3833         char *temp_str;
3834         struct dcerpc_pipe *p = NULL;
3835         struct dcerpc_binding_handle *b = NULL;
3836
3837         torture_comment(tctx, "Testing netr_LogonGetDomainInfo\n");
3838
3839         if (!test_SetupCredentials3(p1, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
3840                                     machine_credentials, &creds)) {
3841                 return false;
3842         }
3843         if (!test_SetupCredentialsPipe(p1, tctx, machine_credentials, creds,
3844                                        DCERPC_SIGN | DCERPC_SEAL, &p)) {
3845                 return false;
3846         }
3847         b = p->binding_handle;
3848
3849         /* We won't double-check this when we are over 'local' transports */
3850         if (dcerpc_server_name(p)) {
3851                 /* Set up connection to SAMDB on DC */
3852                 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
3853                 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
3854                                            NULL,
3855                                            cmdline_credentials,
3856                                            0);
3857
3858                 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
3859         }
3860
3861         torture_comment(tctx, "Testing netr_LogonGetDomainInfo 1st call (no variation of DNS hostname)\n");
3862         netlogon_creds_client_authenticator(creds, &a);
3863
3864         ZERO_STRUCT(r);
3865         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3866         r.in.computer_name = TEST_MACHINE_NAME;
3867         r.in.credential = &a;
3868         r.in.level = 1;
3869         r.in.return_authenticator = &a;
3870         r.in.query = &query;
3871         r.out.return_authenticator = &a;
3872         r.out.info = &info;
3873
3874         ZERO_STRUCT(os);
3875         os.os.MajorVersion = 123;
3876         os.os.MinorVersion = 456;
3877         os.os.BuildNumber = 789;
3878         os.os.CSDVersion = "Service Pack 10";
3879         os.os.ServicePackMajor = 10;
3880         os.os.ServicePackMinor = 1;
3881         os.os.SuiteMask = NETR_VER_SUITE_SINGLEUSERTS;
3882         os.os.ProductType = NETR_VER_NT_SERVER;
3883         os.os.Reserved = 0;
3884
3885         version_str = talloc_asprintf(tctx, "%d.%d (%d)", os.os.MajorVersion,
3886                 os.os.MinorVersion, os.os.BuildNumber);
3887
3888         ZERO_STRUCT(q1);
3889         q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
3890                 lpcfg_dnsdomain(tctx->lp_ctx));
3891         q1.sitename = "Default-First-Site-Name";
3892         q1.os_version.os = &os;
3893         q1.os_name.string = talloc_asprintf(tctx,
3894                                             "Tortured by Samba4 RPC-NETLOGON: %s",
3895                                             timestring(tctx, time(NULL)));
3896
3897         /* The workstation handles the "servicePrincipalName" and DNS hostname
3898            updates */
3899         q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
3900
3901         query.workstation_info = &q1;
3902
3903         if (sam_ctx) {
3904                 /* Gets back the old DNS hostname in AD */
3905                 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
3906                                    "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
3907                 old_dnsname =
3908                         ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL);
3909
3910                 /* Gets back the "servicePrincipalName"s in AD */
3911                 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
3912                 if (spn_el != NULL) {
3913                         for (i=0; i < spn_el->num_values; i++) {
3914                                 spns = talloc_realloc(tctx, spns, char *, i + 1);
3915                                 spns[i] = (char *) spn_el->values[i].data;
3916                         }
3917                         num_spns = i;
3918                 }
3919         }
3920
3921         torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3922                 "LogonGetDomainInfo failed");
3923         torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3924         torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3925
3926         smb_msleep(250);
3927
3928         if (sam_ctx) {
3929                 /* AD workstation infos entry check */
3930                 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
3931                                    "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
3932                 torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
3933                 torture_assert_str_equal(tctx,
3934                                          ldb_msg_find_attr_as_string(res[0], "operatingSystem", NULL),
3935                                          q1.os_name.string, "'operatingSystem' wrong!");
3936                 torture_assert_str_equal(tctx,
3937                                          ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL),
3938                                          os.os.CSDVersion, "'operatingSystemServicePack' wrong!");
3939                 torture_assert_str_equal(tctx,
3940                                          ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL),
3941                                          version_str, "'operatingSystemVersion' wrong!");
3942
3943                 if (old_dnsname != NULL) {
3944                         /* If before a DNS hostname was set then it should remain
3945                            the same in combination with the "servicePrincipalName"s.
3946                            The DNS hostname should also be returned by our
3947                            "LogonGetDomainInfo" call (in the domain info structure). */
3948
3949                         torture_assert_str_equal(tctx,
3950                                                  ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL),
3951                                                  old_dnsname, "'DNS hostname' was not set!");
3952
3953                         spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
3954                         torture_assert(tctx, ((spns != NULL) && (spn_el != NULL)),
3955                                        "'servicePrincipalName's not set!");
3956                         torture_assert(tctx, spn_el->num_values == num_spns,
3957                                        "'servicePrincipalName's incorrect!");
3958                         for (i=0; (i < spn_el->num_values) && (i < num_spns); i++)
3959                                 torture_assert_str_equal(tctx,
3960                                                          (char *) spn_el->values[i].data,
3961                                 spns[i], "'servicePrincipalName's incorrect!");
3962
3963                         torture_assert_str_equal(tctx,
3964                                                  info.domain_info->dns_hostname.string,
3965                                                  old_dnsname,
3966                                                  "Out 'DNS hostname' doesn't match the old one!");
3967                 } else {
3968                         /* If no DNS hostname was set then also now none should be set,
3969                            the "servicePrincipalName"s should remain empty and no DNS
3970                            hostname should be returned by our "LogonGetDomainInfo"
3971                            call (in the domain info structure). */
3972
3973                         torture_assert(tctx,
3974                                        ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL) == NULL,
3975                                        "'DNS hostname' was set!");
3976
3977                         spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
3978                         torture_assert(tctx, ((spns == NULL) && (spn_el == NULL)),
3979                                        "'servicePrincipalName's were set!");
3980
3981                         torture_assert(tctx,
3982                                        info.domain_info->dns_hostname.string == NULL,
3983                                        "Out 'DNS host name' was set!");
3984                 }
3985         }
3986
3987         /* Checks "workstation flags" */
3988         torture_assert(tctx,
3989                 info.domain_info->workstation_flags
3990                 == NETR_WS_FLAG_HANDLES_SPN_UPDATE,
3991                 "Out 'workstation flags' don't match!");
3992
3993
3994         torture_comment(tctx, "Testing netr_LogonGetDomainInfo 2nd call (variation of DNS hostname doesn't work)\n");
3995         netlogon_creds_client_authenticator(creds, &a);
3996
3997         /* Wipe out the osVersion, and prove which values still 'stick' */
3998         q1.os_version.os = NULL;
3999
4000         /* Change also the DNS hostname to test differences in behaviour */
4001         talloc_free(discard_const_p(char, q1.dns_hostname));
4002         q1.dns_hostname = talloc_asprintf(tctx, "%s2.%s", TEST_MACHINE_NAME,
4003                 lpcfg_dnsdomain(tctx->lp_ctx));
4004
4005         /* The workstation handles the "servicePrincipalName" and DNS hostname
4006            updates */
4007         q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
4008
4009         torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
4010                 "LogonGetDomainInfo failed");
4011         torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
4012
4013         torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
4014
4015         smb_msleep(250);
4016
4017         if (sam_ctx) {
4018                 /* AD workstation infos entry check */
4019                 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
4020                                    "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
4021                 torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
4022
4023                 torture_assert_str_equal(tctx,
4024                                          ldb_msg_find_attr_as_string(res[0], "operatingSystem", NULL),
4025                                          q1.os_name.string, "'operatingSystem' should stick!");
4026                 torture_assert(tctx,
4027                                ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL) == NULL,
4028                                "'operatingSystemServicePack' shouldn't stick!");
4029                 torture_assert(tctx,
4030                                ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL) == NULL,
4031                                "'operatingSystemVersion' shouldn't stick!");
4032
4033                 /* The DNS host name shouldn't have been updated by the server */
4034
4035                 torture_assert_str_equal(tctx,
4036                                          ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL),
4037                                          old_dnsname, "'DNS host name' did change!");
4038
4039                 /* Find the two "servicePrincipalName"s which the DC shouldn't have been
4040                    updated (HOST/<Netbios name> and HOST/<FQDN name>) - see MS-NRPC
4041                    3.5.4.3.9 */
4042                 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
4043                 torture_assert(tctx, spn_el != NULL,
4044                                "There should exist 'servicePrincipalName's in AD!");
4045                 temp_str = talloc_asprintf(tctx, "HOST/%s", TEST_MACHINE_NAME);
4046                 for (i=0; i < spn_el->num_values; i++)
4047                         if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
4048                                 break;
4049                 torture_assert(tctx, i != spn_el->num_values,
4050                                "'servicePrincipalName' HOST/<Netbios name> not found!");
4051                 temp_str = talloc_asprintf(tctx, "HOST/%s", old_dnsname);
4052                 for (i=0; i < spn_el->num_values; i++)
4053                         if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
4054                                 break;
4055                 torture_assert(tctx, i != spn_el->num_values,
4056                                "'servicePrincipalName' HOST/<FQDN name> not found!");
4057
4058                 /* Check that the out DNS hostname was set properly */
4059                 torture_assert_str_equal(tctx, info.domain_info->dns_hostname.string,
4060                                          old_dnsname, "Out 'DNS hostname' doesn't match the old one!");
4061         }
4062
4063         /* Checks "workstation flags" */
4064         torture_assert(tctx,
4065                 info.domain_info->workstation_flags == NETR_WS_FLAG_HANDLES_SPN_UPDATE,
4066                 "Out 'workstation flags' don't match!");
4067
4068
4069         /* Now try the same but the workstation flags set to 0 */
4070
4071         torture_comment(tctx, "Testing netr_LogonGetDomainInfo 3rd call (variation of DNS hostname doesn't work)\n");
4072         netlogon_creds_client_authenticator(creds, &a);
4073
4074         /* Change also the DNS hostname to test differences in behaviour */
4075         talloc_free(discard_const_p(char, q1.dns_hostname));
4076         q1.dns_hostname = talloc_asprintf(tctx, "%s2.%s", TEST_MACHINE_NAME,
4077                 lpcfg_dnsdomain(tctx->lp_ctx));
4078
4079         /* Wipe out the osVersion, and prove which values still 'stick' */
4080         q1.os_version.os = NULL;
4081
4082         /* Let the DC handle the "servicePrincipalName" and DNS hostname
4083            updates */
4084         q1.workstation_flags = 0;
4085
4086         torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
4087                 "LogonGetDomainInfo failed");
4088         torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
4089         torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
4090
4091         smb_msleep(250);
4092
4093         if (sam_ctx) {
4094                 /* AD workstation infos entry check */
4095                 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
4096                                    "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
4097                 torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
4098
4099                 torture_assert_str_equal(tctx,
4100                                          ldb_msg_find_attr_as_string(res[0], "operatingSystem", NULL),
4101                                          q1.os_name.string, "'operatingSystem' should stick!");
4102                 torture_assert(tctx,
4103                                ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL) == NULL,
4104                                "'operatingSystemServicePack' shouldn't stick!");
4105                 torture_assert(tctx,
4106                                ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL) == NULL,
4107                                "'operatingSystemVersion' shouldn't stick!");
4108
4109                 /* The DNS host name shouldn't have been updated by the server */
4110
4111                 torture_assert_str_equal(tctx,
4112                                          ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL),
4113                                          old_dnsname, "'DNS host name' did change!");
4114
4115                 /* Find the two "servicePrincipalName"s which the DC shouldn't have been
4116                    updated (HOST/<Netbios name> and HOST/<FQDN name>) - see MS-NRPC
4117                    3.5.4.3.9 */
4118                 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
4119                 torture_assert(tctx, spn_el != NULL,
4120                                "There should exist 'servicePrincipalName's in AD!");
4121                 temp_str = talloc_asprintf(tctx, "HOST/%s", TEST_MACHINE_NAME);
4122                 for (i=0; i < spn_el->num_values; i++)
4123                         if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
4124                                 break;
4125                 torture_assert(tctx, i != spn_el->num_values,
4126                                "'servicePrincipalName' HOST/<Netbios name> not found!");
4127                 temp_str = talloc_asprintf(tctx, "HOST/%s", old_dnsname);
4128                 for (i=0; i < spn_el->num_values; i++)
4129                         if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
4130                                 break;
4131                 torture_assert(tctx, i != spn_el->num_values,
4132                                "'servicePrincipalName' HOST/<FQDN name> not found!");
4133
4134                 /* Here the server gives us NULL as the out DNS hostname */
4135                 torture_assert(tctx, info.domain_info->dns_hostname.string == NULL,
4136                                "Out 'DNS hostname' should be NULL!");
4137         }
4138
4139         /* Checks "workstation flags" */
4140         torture_assert(tctx,
4141                 info.domain_info->workstation_flags == 0,
4142                 "Out 'workstation flags' don't match!");
4143
4144
4145         torture_comment(tctx, "Testing netr_LogonGetDomainInfo 4th call (verification of DNS hostname and check for trusted domains)\n");
4146         netlogon_creds_client_authenticator(creds, &a);
4147
4148         /* Put the DNS hostname back */
4149         talloc_free(discard_const_p(char, q1.dns_hostname));
4150         q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
4151                 lpcfg_dnsdomain(tctx->lp_ctx));
4152
4153         /* The workstation handles the "servicePrincipalName" and DNS hostname
4154            updates */
4155         q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
4156
4157         torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
4158                 "LogonGetDomainInfo failed");
4159         torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
4160         torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
4161
4162         smb_msleep(250);
4163
4164         /* Now the in/out DNS hostnames should be the same */
4165         torture_assert_str_equal(tctx,
4166                 info.domain_info->dns_hostname.string,
4167                 query.workstation_info->dns_hostname,
4168                 "In/Out 'DNS hostnames' don't match!");
4169         old_dnsname = info.domain_info->dns_hostname.string;
4170
4171         /* Checks "workstation flags" */
4172         torture_assert(tctx,
4173                 info.domain_info->workstation_flags
4174                 == NETR_WS_FLAG_HANDLES_SPN_UPDATE,
4175                 "Out 'workstation flags' don't match!");
4176
4177         /* Checks for trusted domains */
4178         torture_assert(tctx,
4179                 (info.domain_info->trusted_domain_count != 0)
4180                 && (info.domain_info->trusted_domains != NULL),
4181                 "Trusted domains have been requested!");
4182
4183
4184         torture_comment(tctx, "Testing netr_LogonGetDomainInfo 5th call (check for trusted domains)\n");
4185         netlogon_creds_client_authenticator(creds, &a);
4186
4187         /* The workstation handles the "servicePrincipalName" and DNS hostname
4188            updates and requests inbound trusts */
4189         q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE
4190                 | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS;
4191
4192         torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
4193                 "LogonGetDomainInfo failed");
4194         torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
4195         torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
4196
4197         smb_msleep(250);
4198
4199         /* Checks "workstation flags" */
4200         torture_assert(tctx,
4201                 info.domain_info->workstation_flags
4202                 == (NETR_WS_FLAG_HANDLES_SPN_UPDATE
4203                         | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS),
4204                 "Out 'workstation flags' don't match!");
4205
4206         /* Checks for trusted domains */
4207         torture_assert(tctx,
4208                 (info.domain_info->trusted_domain_count != 0)
4209                 && (info.domain_info->trusted_domains != NULL),
4210                 "Trusted domains have been requested!");
4211
4212
4213         torture_comment(tctx, "Testing netr_LogonGetDomainInfo 6th call (no DNS hostname)\n");
4214         netlogon_creds_client_authenticator(creds, &a);
4215
4216         query.workstation_info->dns_hostname = NULL;
4217
4218         torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
4219                 "LogonGetDomainInfo failed");
4220         torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
4221         torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
4222
4223         /* The old DNS hostname should stick */
4224         torture_assert_str_equal(tctx,
4225                 info.domain_info->dns_hostname.string,
4226                 old_dnsname,
4227                 "'DNS hostname' changed!");
4228
4229         torture_comment(tctx, "Testing netr_LogonGetDomainInfo 7th call (extra workstation flags)\n");
4230         netlogon_creds_client_authenticator(creds, &a);
4231
4232         q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE
4233                 | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS | 0x4;
4234
4235         /* Put the DNS hostname back */
4236         talloc_free(discard_const_p(char, q1.dns_hostname));
4237         q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
4238                 lpcfg_dnsdomain(tctx->lp_ctx));
4239
4240         torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
4241                 "LogonGetDomainInfo failed");
4242         torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
4243         torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
4244
4245         /* Checks "workstation flags" */
4246         torture_assert(tctx,
4247                 info.domain_info->workstation_flags
4248                 == (NETR_WS_FLAG_HANDLES_SPN_UPDATE
4249                         | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS),
4250                 "Out 'workstation flags' don't match!");
4251
4252         if (!torture_setting_bool(tctx, "dangerous", false)) {
4253                 torture_comment(tctx, "Not testing netr_LogonGetDomainInfo 8th call (no workstation info) - enable dangerous tests in order to do so\n");
4254         } else {
4255                 /* Try a call without the workstation information structure */
4256
4257                 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 8th call (no workstation info)\n");
4258                 netlogon_creds_client_authenticator(creds, &a);
4259
4260                 query.workstation_info = NULL;
4261
4262                 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
4263                         "LogonGetDomainInfo failed");
4264                 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
4265                 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
4266         }
4267
4268         return true;
4269 }
4270
4271 static bool test_GetDomainInfo_async(struct torture_context *tctx,
4272                                      struct dcerpc_pipe *p1,
4273                                      struct cli_credentials *machine_credentials)
4274 {
4275         NTSTATUS status;
4276         struct netr_LogonGetDomainInfo r;
4277         struct netr_WorkstationInformation q1;
4278         struct netr_Authenticator a;
4279 #define ASYNC_COUNT 100
4280         struct netlogon_creds_CredentialState *creds;
4281         struct netlogon_creds_CredentialState *creds_async[ASYNC_COUNT];
4282         struct tevent_req *req[ASYNC_COUNT];
4283         int i;
4284         union netr_WorkstationInfo query;
4285         union netr_DomainInfo info;
4286         struct dcerpc_pipe *p = NULL;
4287
4288         torture_comment(tctx, "Testing netr_LogonGetDomainInfo - async count %d\n", ASYNC_COUNT);
4289
4290         if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
4291                                     machine_credentials, &creds)) {
4292                 return false;
4293         }
4294         if (!test_SetupCredentialsPipe(p1, tctx, machine_credentials, creds,
4295                                        DCERPC_SIGN | DCERPC_SEAL, &p)) {
4296                 return false;
4297         }
4298
4299         ZERO_STRUCT(r);
4300         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
4301         r.in.computer_name = TEST_MACHINE_NAME;
4302         r.in.credential = &a;
4303         r.in.level = 1;
4304         r.in.return_authenticator = &a;
4305         r.in.query = &query;
4306         r.out.return_authenticator = &a;
4307         r.out.info = &info;
4308
4309         ZERO_STRUCT(q1);
4310         q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
4311                 lpcfg_dnsdomain(tctx->lp_ctx));
4312         q1.sitename = "Default-First-Site-Name";
4313         q1.os_name.string = "UNIX/Linux or similar";
4314
4315         query.workstation_info = &q1;
4316
4317         for (i=0;i<ASYNC_COUNT;i++) {
4318                 netlogon_creds_client_authenticator(creds, &a);
4319
4320                 creds_async[i] = (struct netlogon_creds_CredentialState *)talloc_memdup(creds, creds, sizeof(*creds));
4321                 req[i] = dcerpc_netr_LogonGetDomainInfo_r_send(tctx, tctx->ev, p->binding_handle, &r);
4322
4323                 /* even with this flush per request a w2k3 server seems to
4324                    clag with multiple outstanding requests. bleergh. */
4325                 torture_assert_int_equal(tctx, tevent_loop_once(tctx->ev), 0,
4326                                          "tevent_loop_once failed");
4327         }
4328
4329         for (i=0;i<ASYNC_COUNT;i++) {
4330                 torture_assert_int_equal(tctx, tevent_req_poll(req[i], tctx->ev), true,
4331                                          "tevent_req_poll() failed");
4332
4333                 status = dcerpc_netr_LogonGetDomainInfo_r_recv(req[i], tctx);
4334
4335                 torture_assert_ntstatus_ok(tctx, status, "netr_LogonGetDomainInfo_async");
4336                 torture_assert_ntstatus_ok(tctx, r.out.result, "netr_LogonGetDomainInfo_async");
4337
4338                 torture_assert(tctx, netlogon_creds_client_check(creds_async[i], &a.cred),
4339                         "Credential chaining failed at async");
4340         }
4341
4342         torture_comment(tctx,
4343                         "Testing netr_LogonGetDomainInfo - async count %d OK\n", ASYNC_COUNT);
4344
4345         return true;
4346 }
4347
4348 static bool test_ManyGetDCName(struct torture_context *tctx,
4349                                struct dcerpc_pipe *p)
4350 {
4351         NTSTATUS status;
4352         struct cli_credentials *anon_creds;
4353         struct dcerpc_binding *binding2;
4354         struct dcerpc_pipe *p2;
4355         struct lsa_ObjectAttribute attr;
4356         struct lsa_QosInfo qos;
4357         struct lsa_OpenPolicy2 o;
4358         struct policy_handle lsa_handle;
4359         struct lsa_DomainList domains;
4360
4361         struct lsa_EnumTrustDom t;
4362         uint32_t resume_handle = 0;
4363         struct netr_GetAnyDCName d;
4364         const char *dcname = NULL;
4365         struct dcerpc_binding_handle *b = p->binding_handle;
4366         struct dcerpc_binding_handle *b2;
4367
4368         int i;
4369
4370         if (p->conn->transport.transport != NCACN_NP) {
4371                 torture_skip(tctx, "test_ManyGetDCName works only with NCACN_NP");
4372         }
4373
4374         torture_comment(tctx, "Torturing GetDCName\n");
4375
4376         anon_creds = cli_credentials_init_anon(tctx);
4377         torture_assert(tctx, anon_creds != NULL, "cli_credentials_init_anon failed");
4378
4379         binding2 = dcerpc_binding_dup(tctx, p->binding);
4380         /* Swap the binding details from NETLOGON to LSA */
4381         status = dcerpc_epm_map_binding(tctx, binding2, &ndr_table_lsarpc, tctx->ev, tctx->lp_ctx);
4382         dcerpc_binding_set_assoc_group_id(binding2, 0);
4383         torture_assert_ntstatus_ok(tctx, status, "epm map");
4384
4385         status = dcerpc_secondary_auth_connection(p, binding2, &ndr_table_lsarpc,
4386                                                   anon_creds, tctx->lp_ctx,
4387                                                   tctx, &p2);
4388         torture_assert_ntstatus_ok(tctx, status, "Failed to create secondary connection");
4389         b2 = p2->binding_handle;
4390
4391         qos.len = 0;
4392         qos.impersonation_level = 2;
4393         qos.context_mode = 1;
4394         qos.effective_only = 0;
4395
4396         attr.len = 0;
4397         attr.root_dir = NULL;
4398         attr.object_name = NULL;
4399         attr.attributes = 0;
4400         attr.sec_desc = NULL;
4401         attr.sec_qos = &qos;
4402
4403         o.in.system_name = "\\";
4404         o.in.attr = &attr;
4405         o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4406         o.out.handle = &lsa_handle;
4407
4408         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenPolicy2_r(b2, tctx, &o),
4409                 "OpenPolicy2 failed");
4410         torture_assert_ntstatus_ok(tctx, o.out.result, "OpenPolicy2 failed");
4411
4412         t.in.handle = &lsa_handle;
4413         t.in.resume_handle = &resume_handle;
4414         t.in.max_size = 1000;
4415         t.out.domains = &domains;
4416         t.out.resume_handle = &resume_handle;
4417
4418         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumTrustDom_r(b2, tctx, &t),
4419                 "EnumTrustDom failed");
4420
4421         if ((!NT_STATUS_IS_OK(t.out.result) &&
4422              (!NT_STATUS_EQUAL(t.out.result, NT_STATUS_NO_MORE_ENTRIES))))
4423                 torture_fail(tctx, "Could not list domains");
4424
4425         talloc_free(p2);
4426
4427         d.in.logon_server = talloc_asprintf(tctx, "\\\\%s",
4428                                             dcerpc_server_name(p));
4429         d.out.dcname = &dcname;
4430
4431         for (i=0; i<domains.count * 4; i++) {
4432                 struct lsa_DomainInfo *info =
4433                         &domains.domains[rand()%domains.count];
4434
4435                 d.in.domainname = info->name.string;
4436
4437                 status = dcerpc_netr_GetAnyDCName_r(b, tctx, &d);
4438                 torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
4439
4440                 torture_comment(tctx, "\tDC for domain %s is %s\n", info->name.string,
4441                        dcname ? dcname : "unknown");
4442         }
4443
4444         return true;
4445 }
4446
4447 static bool test_lsa_over_netlogon(struct torture_context *tctx,
4448                                    struct dcerpc_pipe *p)
4449 {
4450         NTSTATUS status;
4451         struct cli_credentials *anon_creds;
4452         const struct dcerpc_binding *binding2;
4453         struct dcerpc_pipe *p2;
4454         struct lsa_ObjectAttribute attr;
4455         struct lsa_QosInfo qos;
4456         struct lsa_OpenPolicy2 o;
4457         struct policy_handle lsa_handle;
4458
4459         struct dcerpc_binding_handle *b2;
4460
4461
4462         if (p->conn->transport.transport != NCACN_NP) {
4463                 torture_skip(tctx, "test_lsa_over_netlogon works only with NCACN_NP");
4464         }
4465
4466         torture_comment(tctx, "Testing if we can access the LSA server over\n"
4467                         " \\\\pipe\\netlogon rather than \\\\pipe\\lsarpc\n");
4468
4469         anon_creds = cli_credentials_init_anon(tctx);
4470         torture_assert(tctx, anon_creds != NULL, "cli_credentials_init_anon failed");
4471
4472         binding2 = p->binding;
4473
4474         status = dcerpc_secondary_auth_connection(p, binding2, &ndr_table_lsarpc,
4475                                                   anon_creds, tctx->lp_ctx,
4476                                                   tctx, &p2);
4477         torture_assert_ntstatus_ok(tctx, status, "Failed to create secondary connection");
4478         b2 = p2->binding_handle;
4479
4480         qos.len = 0;
4481         qos.impersonation_level = 2;
4482         qos.context_mode = 1;
4483         qos.effective_only = 0;
4484
4485         attr.len = 0;
4486         attr.root_dir = NULL;
4487         attr.object_name = NULL;
4488         attr.attributes = 0;
4489         attr.sec_desc = NULL;
4490         attr.sec_qos = &qos;
4491
4492         o.in.system_name = "\\";
4493         o.in.attr = &attr;
4494         o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4495         o.out.handle = &lsa_handle;
4496
4497         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenPolicy2_r(b2, tctx, &o),
4498                 "OpenPolicy2 failed");
4499         torture_assert_ntstatus_ok(tctx, o.out.result, "OpenPolicy2 failed");
4500
4501         talloc_free(p2);
4502
4503         return true;
4504 }
4505
4506 static bool test_SetPassword_with_flags(struct torture_context *tctx,
4507                                         struct dcerpc_pipe *p,
4508                                         struct cli_credentials *machine_credentials)
4509 {
4510         uint32_t flags[] = { 0, NETLOGON_NEG_STRONG_KEYS };
4511         struct netlogon_creds_CredentialState *creds;
4512         int i;
4513
4514         if (!test_SetupCredentials2(p, tctx, 0,
4515                                     machine_credentials,
4516                                     cli_credentials_get_secure_channel_type(machine_credentials),
4517                                     &creds)) {
4518                 torture_skip(tctx, "DC does not support negotiation of 64bit session keys");
4519         }
4520
4521         for (i=0; i < ARRAY_SIZE(flags); i++) {
4522                 torture_assert(tctx,
4523                         test_SetPassword_flags(tctx, p, machine_credentials, flags[i]),
4524                         talloc_asprintf(tctx, "failed to test SetPassword negotiating with 0x%08x flags", flags[i]));
4525         }
4526
4527         return true;
4528 }
4529
4530 struct torture_suite *torture_rpc_netlogon(TALLOC_CTX *mem_ctx)
4531 {
4532         struct torture_suite *suite = torture_suite_create(mem_ctx, "netlogon");
4533         struct torture_rpc_tcase *tcase;
4534         struct torture_test *test;
4535
4536         tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netlogon",
4537                                                   &ndr_table_netlogon, TEST_MACHINE_NAME);
4538
4539         torture_rpc_tcase_add_test(tcase, "Broken RPC binding handle",
4540                                    test_netr_broken_binding_handle);
4541
4542         torture_rpc_tcase_add_test(tcase, "LogonUasLogon", test_LogonUasLogon);
4543         torture_rpc_tcase_add_test(tcase, "LogonUasLogoff", test_LogonUasLogoff);
4544         torture_rpc_tcase_add_test_creds(tcase, "SamLogon", test_SamLogon);
4545         torture_rpc_tcase_add_test_creds(tcase, "invalidAuthenticate2", test_invalidAuthenticate2);
4546         torture_rpc_tcase_add_test_creds(tcase, "ServerReqChallengeGlobal", test_ServerReqChallengeGlobal);
4547         torture_rpc_tcase_add_test_creds(tcase, "ServerReqChallengeReuseGlobal", test_ServerReqChallengeReuseGlobal);
4548         torture_rpc_tcase_add_test_creds(tcase, "ServerReqChallengeReuseGlobal2", test_ServerReqChallengeReuseGlobal2);
4549         torture_rpc_tcase_add_test_creds(tcase, "ServerReqChallengeReuse", test_ServerReqChallengeReuse);
4550         torture_rpc_tcase_add_test_creds(tcase, "SetPassword", test_SetPassword);
4551         torture_rpc_tcase_add_test_creds(tcase, "SetPassword2", test_SetPassword2);
4552         torture_rpc_tcase_add_test_creds(tcase, "SetPassword2_AES", test_SetPassword2_AES);
4553         torture_rpc_tcase_add_test_creds(tcase, "GetPassword", test_GetPassword);
4554         torture_rpc_tcase_add_test_creds(tcase, "GetTrustPasswords", test_GetTrustPasswords);
4555         torture_rpc_tcase_add_test_creds(tcase, "GetDomainInfo", test_GetDomainInfo);
4556         torture_rpc_tcase_add_test_creds(tcase, "DatabaseSync", test_DatabaseSync);
4557         torture_rpc_tcase_add_test_creds(tcase, "DatabaseDeltas", test_DatabaseDeltas);
4558         torture_rpc_tcase_add_test_creds(tcase, "DatabaseRedo", test_DatabaseRedo);
4559         torture_rpc_tcase_add_test_creds(tcase, "AccountDeltas", test_AccountDeltas);
4560         torture_rpc_tcase_add_test_creds(tcase, "AccountSync", test_AccountSync);
4561         torture_rpc_tcase_add_test(tcase, "GetDcName", test_GetDcName);
4562         torture_rpc_tcase_add_test(tcase, "ManyGetDCName", test_ManyGetDCName);
4563         torture_rpc_tcase_add_test(tcase, "GetAnyDCName", test_GetAnyDCName);
4564         torture_rpc_tcase_add_test_creds(tcase, "DatabaseSync2", test_DatabaseSync2);
4565         torture_rpc_tcase_add_test(tcase, "DsrEnumerateDomainTrusts", test_DsrEnumerateDomainTrusts);
4566         torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomains", test_netr_NetrEnumerateTrustedDomains);
4567         torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomainsEx", test_netr_NetrEnumerateTrustedDomainsEx);
4568         test = torture_rpc_tcase_add_test_creds(tcase, "GetDomainInfo_async", test_GetDomainInfo_async);
4569         test->dangerous = true;
4570         torture_rpc_tcase_add_test(tcase, "DsRGetDCName", test_netr_DsRGetDCName);
4571         torture_rpc_tcase_add_test(tcase, "DsRGetDCNameEx", test_netr_DsRGetDCNameEx);
4572         torture_rpc_tcase_add_test(tcase, "DsRGetDCNameEx2", test_netr_DsRGetDCNameEx2);
4573         torture_rpc_tcase_add_test(tcase, "DsrGetDcSiteCoverageW", test_netr_DsrGetDcSiteCoverageW);
4574         torture_rpc_tcase_add_test(tcase, "DsRAddressToSitenamesW", test_netr_DsRAddressToSitenamesW);
4575         torture_rpc_tcase_add_test(tcase, "DsRAddressToSitenamesExW", test_netr_DsRAddressToSitenamesExW);
4576         torture_rpc_tcase_add_test_creds(tcase, "ServerGetTrustInfo", test_netr_ServerGetTrustInfo);
4577         torture_rpc_tcase_add_test_creds(tcase, "ServerGetTrustInfo_AES", test_netr_ServerGetTrustInfo_AES);
4578         torture_rpc_tcase_add_test_creds(tcase, "GetForestTrustInformation", test_netr_GetForestTrustInformation);
4579
4580         torture_rpc_tcase_add_test(tcase, "lsa_over_netlogon", test_lsa_over_netlogon);
4581         torture_rpc_tcase_add_test_creds(tcase, "SetupCredentialsDowngrade", test_SetupCredentialsDowngrade);
4582
4583         return suite;
4584 }
4585
4586 struct torture_suite *torture_rpc_netlogon_s3(TALLOC_CTX *mem_ctx)
4587 {
4588         struct torture_suite *suite = torture_suite_create(mem_ctx, "netlogon-s3");
4589         struct torture_rpc_tcase *tcase;
4590
4591         tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netlogon",
4592                                                   &ndr_table_netlogon, TEST_MACHINE_NAME);
4593
4594         torture_rpc_tcase_add_test_creds(tcase, "SamLogon", test_SamLogon);
4595         torture_rpc_tcase_add_test_creds(tcase, "SamLogon_NULL_domain", test_SamLogon_NULL_domain);
4596         torture_rpc_tcase_add_test_creds(tcase, "SetPassword", test_SetPassword);
4597         torture_rpc_tcase_add_test_creds(tcase, "SetPassword_with_flags", test_SetPassword_with_flags);
4598         torture_rpc_tcase_add_test_creds(tcase, "SetPassword2", test_SetPassword2);
4599         torture_rpc_tcase_add_test_creds(tcase, "SetPassword2_AES", test_SetPassword2_AES);
4600         torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomains", test_netr_NetrEnumerateTrustedDomains);
4601
4602         return suite;
4603 }
4604
4605 struct torture_suite *torture_rpc_netlogon_admin(TALLOC_CTX *mem_ctx)
4606 {
4607         struct torture_suite *suite = torture_suite_create(mem_ctx, "netlogon.admin");
4608         struct torture_rpc_tcase *tcase;
4609
4610         tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "bdc",
4611                                                   &ndr_table_netlogon, TEST_MACHINE_NAME);
4612         torture_rpc_tcase_add_test_creds(tcase, "LogonControl", test_LogonControl);
4613         torture_rpc_tcase_add_test_creds(tcase, "LogonControl2", test_LogonControl2);
4614         torture_rpc_tcase_add_test_creds(tcase, "LogonControl2Ex", test_LogonControl2Ex);
4615
4616         tcase = torture_suite_add_machine_workstation_rpc_iface_tcase(suite, "wkst",
4617                                                   &ndr_table_netlogon, TEST_MACHINE_NAME);
4618         torture_rpc_tcase_add_test_creds(tcase, "LogonControl", test_LogonControl);
4619         torture_rpc_tcase_add_test_creds(tcase, "LogonControl2", test_LogonControl2);
4620         torture_rpc_tcase_add_test_creds(tcase, "LogonControl2Ex", test_LogonControl2Ex);
4621
4622         tcase = torture_suite_add_rpc_iface_tcase(suite, "admin",
4623                                                   &ndr_table_netlogon);
4624         torture_rpc_tcase_add_test_creds(tcase, "LogonControl", test_LogonControl);
4625         torture_rpc_tcase_add_test_creds(tcase, "LogonControl2", test_LogonControl2);
4626         torture_rpc_tcase_add_test_creds(tcase, "LogonControl2Ex", test_LogonControl2Ex);
4627
4628         return suite;
4629 }