s4-torture: pass down netlogon flags in netr_ServerPasswordSet2 tests.
[obnox/samba/samba-obnox.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                                            &credentials1, &credentials2,
177                                            mach_password, &credentials3,
178                                            0);
179         torture_assert(tctx, creds != NULL, "memory allocation");
180
181
182         torture_comment(tctx, "Testing ServerAuthenticate\n");
183
184         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate_r(b, tctx, &a),
185                 "ServerAuthenticate failed");
186
187         /* This allows the tests to continue against the more fussy windows 2008 */
188         if (NT_STATUS_EQUAL(a.out.result, NT_STATUS_DOWNGRADE_DETECTED)) {
189                 return test_SetupCredentials2(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
190                                               credentials,
191                                               cli_credentials_get_secure_channel_type(credentials),
192                                               creds_out);
193         }
194
195         torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate");
196
197         torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3),
198                        "Credential chaining failed");
199
200         *creds_out = creds;
201         return true;
202 }
203
204 bool test_SetupCredentials2(struct dcerpc_pipe *p, struct torture_context *tctx,
205                             uint32_t negotiate_flags,
206                             struct cli_credentials *machine_credentials,
207                             enum netr_SchannelType sec_chan_type,
208                             struct netlogon_creds_CredentialState **creds_out)
209 {
210         struct netr_ServerReqChallenge r;
211         struct netr_ServerAuthenticate2 a;
212         struct netr_Credential credentials1, credentials2, credentials3;
213         struct netlogon_creds_CredentialState *creds;
214         const struct samr_Password *mach_password;
215         const char *machine_name;
216         struct dcerpc_binding_handle *b = p->binding_handle;
217
218         mach_password = cli_credentials_get_nt_hash(machine_credentials, tctx);
219         machine_name = cli_credentials_get_workstation(machine_credentials);
220
221         torture_comment(tctx, "Testing ServerReqChallenge\n");
222
223
224         r.in.server_name = NULL;
225         r.in.computer_name = machine_name;
226         r.in.credentials = &credentials1;
227         r.out.return_credentials = &credentials2;
228
229         generate_random_buffer(credentials1.data, sizeof(credentials1.data));
230
231         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
232                 "ServerReqChallenge failed");
233         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
234
235         a.in.server_name = NULL;
236         a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
237         a.in.secure_channel_type = sec_chan_type;
238         a.in.computer_name = machine_name;
239         a.in.negotiate_flags = &negotiate_flags;
240         a.out.negotiate_flags = &negotiate_flags;
241         a.in.credentials = &credentials3;
242         a.out.return_credentials = &credentials3;
243
244         creds = netlogon_creds_client_init(tctx, a.in.account_name,
245                                            a.in.computer_name,
246                                            &credentials1, &credentials2,
247                                            mach_password, &credentials3,
248                                            negotiate_flags);
249
250         torture_assert(tctx, creds != NULL, "memory allocation");
251
252         torture_comment(tctx, "Testing ServerAuthenticate2\n");
253
254         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate2_r(b, tctx, &a),
255                 "ServerAuthenticate2 failed");
256         torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate2 failed");
257
258         torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3),
259                 "Credential chaining failed");
260
261         torture_comment(tctx, "negotiate_flags=0x%08x\n", negotiate_flags);
262
263         *creds_out = creds;
264         return true;
265 }
266
267
268 bool test_SetupCredentials3(struct dcerpc_pipe *p, struct torture_context *tctx,
269                             uint32_t negotiate_flags,
270                             struct cli_credentials *machine_credentials,
271                             struct netlogon_creds_CredentialState **creds_out)
272 {
273         struct netr_ServerReqChallenge r;
274         struct netr_ServerAuthenticate3 a;
275         struct netr_Credential credentials1, credentials2, credentials3;
276         struct netlogon_creds_CredentialState *creds;
277         struct samr_Password mach_password;
278         uint32_t rid;
279         const char *machine_name;
280         const char *plain_pass;
281         struct dcerpc_binding_handle *b = p->binding_handle;
282
283         machine_name = cli_credentials_get_workstation(machine_credentials);
284         plain_pass = cli_credentials_get_password(machine_credentials);
285
286         torture_comment(tctx, "Testing ServerReqChallenge\n");
287
288         r.in.server_name = NULL;
289         r.in.computer_name = machine_name;
290         r.in.credentials = &credentials1;
291         r.out.return_credentials = &credentials2;
292
293         generate_random_buffer(credentials1.data, sizeof(credentials1.data));
294
295         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
296                 "ServerReqChallenge failed");
297         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
298
299         E_md4hash(plain_pass, mach_password.hash);
300
301         a.in.server_name = NULL;
302         a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
303         a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
304         a.in.computer_name = machine_name;
305         a.in.negotiate_flags = &negotiate_flags;
306         a.in.credentials = &credentials3;
307         a.out.return_credentials = &credentials3;
308         a.out.negotiate_flags = &negotiate_flags;
309         a.out.rid = &rid;
310
311         creds = netlogon_creds_client_init(tctx, a.in.account_name,
312                                            a.in.computer_name,
313                                            &credentials1, &credentials2,
314                                            &mach_password, &credentials3,
315                                            negotiate_flags);
316
317         torture_assert(tctx, creds != NULL, "memory allocation");
318
319         torture_comment(tctx, "Testing ServerAuthenticate3\n");
320
321         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b, tctx, &a),
322                 "ServerAuthenticate3 failed");
323         torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate3 failed");
324         torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
325
326         torture_comment(tctx, "negotiate_flags=0x%08x\n", negotiate_flags);
327
328         /* Prove that requesting a challenge again won't break it */
329         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
330                 "ServerReqChallenge failed");
331         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
332
333         *creds_out = creds;
334         return true;
335 }
336
337 /*
338   try a change password for our machine account
339 */
340 static bool test_SetPassword(struct torture_context *tctx,
341                              struct dcerpc_pipe *p,
342                              struct cli_credentials *machine_credentials)
343 {
344         struct netr_ServerPasswordSet r;
345         const char *password;
346         struct netlogon_creds_CredentialState *creds;
347         struct netr_Authenticator credential, return_authenticator;
348         struct samr_Password new_password;
349         struct dcerpc_binding_handle *b = p->binding_handle;
350
351         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
352                 return false;
353         }
354
355         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
356         r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
357         r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
358         r.in.computer_name = TEST_MACHINE_NAME;
359         r.in.credential = &credential;
360         r.in.new_password = &new_password;
361         r.out.return_authenticator = &return_authenticator;
362
363         password = generate_random_password(tctx, 8, 255);
364         E_md4hash(password, new_password.hash);
365
366         netlogon_creds_des_encrypt(creds, &new_password);
367
368         torture_comment(tctx, "Testing ServerPasswordSet on machine account\n");
369         torture_comment(tctx, "Changing machine account password to '%s'\n",
370                         password);
371
372         netlogon_creds_client_authenticator(creds, &credential);
373
374         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet_r(b, tctx, &r),
375                 "ServerPasswordSet failed");
376         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet failed");
377
378         if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
379                 torture_comment(tctx, "Credential chaining failed\n");
380         }
381
382         /* by changing the machine password twice we test the
383            credentials chaining fully, and we verify that the server
384            allows the password to be set to the same value twice in a
385            row (match win2k3) */
386         torture_comment(tctx,
387                 "Testing a second ServerPasswordSet on machine account\n");
388         torture_comment(tctx,
389                 "Changing machine account password to '%s' (same as previous run)\n", password);
390
391         netlogon_creds_client_authenticator(creds, &credential);
392
393         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet_r(b, tctx, &r),
394                 "ServerPasswordSet (2) failed");
395         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet (2) failed");
396
397         if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
398                 torture_comment(tctx, "Credential chaining failed\n");
399         }
400
401         cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
402
403         torture_assert(tctx,
404                 test_SetupCredentials(p, tctx, machine_credentials, &creds),
405                 "ServerPasswordSet failed to actually change the password");
406
407         return true;
408 }
409
410 /*
411   try a change password for our machine account
412 */
413 static bool test_SetPassword_flags(struct torture_context *tctx,
414                                    struct dcerpc_pipe *p,
415                                    struct cli_credentials *machine_credentials,
416                                    uint32_t negotiate_flags)
417 {
418         struct netr_ServerPasswordSet r;
419         const char *password;
420         struct netlogon_creds_CredentialState *creds;
421         struct netr_Authenticator credential, return_authenticator;
422         struct samr_Password new_password;
423         struct dcerpc_binding_handle *b = p->binding_handle;
424
425         if (!test_SetupCredentials2(p, tctx, negotiate_flags,
426                                     machine_credentials,
427                                     cli_credentials_get_secure_channel_type(machine_credentials),
428                                     &creds)) {
429                 return false;
430         }
431
432         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
433         r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
434         r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
435         r.in.computer_name = TEST_MACHINE_NAME;
436         r.in.credential = &credential;
437         r.in.new_password = &new_password;
438         r.out.return_authenticator = &return_authenticator;
439
440         password = generate_random_password(tctx, 8, 255);
441         E_md4hash(password, new_password.hash);
442
443         netlogon_creds_des_encrypt(creds, &new_password);
444
445         torture_comment(tctx, "Testing ServerPasswordSet on machine account\n");
446         torture_comment(tctx, "Changing machine account password to '%s'\n",
447                         password);
448
449         netlogon_creds_client_authenticator(creds, &credential);
450
451         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet_r(b, tctx, &r),
452                 "ServerPasswordSet failed");
453         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet failed");
454
455         if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
456                 torture_comment(tctx, "Credential chaining failed\n");
457         }
458
459         /* by changing the machine password twice we test the
460            credentials chaining fully, and we verify that the server
461            allows the password to be set to the same value twice in a
462            row (match win2k3) */
463         torture_comment(tctx,
464                 "Testing a second ServerPasswordSet on machine account\n");
465         torture_comment(tctx,
466                 "Changing machine account password to '%s' (same as previous run)\n", password);
467
468         netlogon_creds_client_authenticator(creds, &credential);
469
470         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet_r(b, tctx, &r),
471                 "ServerPasswordSet (2) failed");
472         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet (2) failed");
473
474         if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
475                 torture_comment(tctx, "Credential chaining failed\n");
476         }
477
478         cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
479
480         torture_assert(tctx,
481                 test_SetupCredentials(p, tctx, machine_credentials, &creds),
482                 "ServerPasswordSet failed to actually change the password");
483
484         return true;
485 }
486
487
488 /*
489   generate a random password for password change tests
490 */
491 static DATA_BLOB netlogon_very_rand_pass(TALLOC_CTX *mem_ctx, int len)
492 {
493         int i;
494         DATA_BLOB password = data_blob_talloc(mem_ctx, NULL, len * 2 /* number of unicode chars */);
495         generate_random_buffer(password.data, password.length);
496
497         for (i=0; i < len; i++) {
498                 if (((uint16_t *)password.data)[i] == 0) {
499                         ((uint16_t *)password.data)[i] = 1;
500                 }
501         }
502
503         return password;
504 }
505
506 /*
507   try a change password for our machine account
508 */
509 static bool test_SetPassword2_with_flags(struct torture_context *tctx,
510                                          struct dcerpc_pipe *p,
511                                          struct cli_credentials *machine_credentials,
512                                          uint32_t flags)
513 {
514         struct netr_ServerPasswordSet2 r;
515         const char *password;
516         DATA_BLOB new_random_pass;
517         struct netlogon_creds_CredentialState *creds;
518         struct samr_CryptPassword password_buf;
519         struct samr_Password nt_hash;
520         struct netr_Authenticator credential, return_authenticator;
521         struct netr_CryptPassword new_password;
522         struct dcerpc_binding_handle *b = p->binding_handle;
523
524         if (!test_SetupCredentials2(p, tctx, flags, machine_credentials, cli_credentials_get_secure_channel_type(machine_credentials), &creds)) {
525                 return false;
526         }
527
528         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
529         r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
530         r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
531         r.in.computer_name = TEST_MACHINE_NAME;
532         r.in.credential = &credential;
533         r.in.new_password = &new_password;
534         r.out.return_authenticator = &return_authenticator;
535
536         password = generate_random_password(tctx, 8, 255);
537         encode_pw_buffer(password_buf.data, password, STR_UNICODE);
538         netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
539
540         memcpy(new_password.data, password_buf.data, 512);
541         new_password.length = IVAL(password_buf.data, 512);
542
543         torture_comment(tctx, "Testing ServerPasswordSet2 on machine account\n");
544         torture_comment(tctx, "Changing machine account password to '%s'\n", password);
545
546         netlogon_creds_client_authenticator(creds, &credential);
547
548         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
549                 "ServerPasswordSet2 failed");
550         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet2 failed");
551
552         if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
553                 torture_comment(tctx, "Credential chaining failed\n");
554         }
555
556         cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
557
558         if (!torture_setting_bool(tctx, "dangerous", false)) {
559                 torture_comment(tctx,
560                         "Not testing ability to set password to '', enable dangerous tests to perform this test\n");
561         } else {
562                 /* by changing the machine password to ""
563                  * we check if the server uses password restrictions
564                  * for ServerPasswordSet2
565                  * (win2k3 accepts "")
566                  */
567                 password = "";
568                 encode_pw_buffer(password_buf.data, password, STR_UNICODE);
569                 netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
570
571                 memcpy(new_password.data, password_buf.data, 512);
572                 new_password.length = IVAL(password_buf.data, 512);
573
574                 torture_comment(tctx,
575                         "Testing ServerPasswordSet2 on machine account\n");
576                 torture_comment(tctx,
577                         "Changing machine account password to '%s'\n", password);
578
579                 netlogon_creds_client_authenticator(creds, &credential);
580
581                 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
582                         "ServerPasswordSet2 failed");
583                 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet2 failed");
584
585                 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
586                         torture_comment(tctx, "Credential chaining failed\n");
587                 }
588
589                 cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
590         }
591
592         torture_assert(tctx, test_SetupCredentials(p, tctx, machine_credentials, &creds),
593                 "ServerPasswordSet failed to actually change the password");
594
595         /* now try a random password */
596         password = generate_random_password(tctx, 8, 255);
597         encode_pw_buffer(password_buf.data, password, STR_UNICODE);
598         netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
599
600         memcpy(new_password.data, password_buf.data, 512);
601         new_password.length = IVAL(password_buf.data, 512);
602
603         torture_comment(tctx, "Testing second ServerPasswordSet2 on machine account\n");
604         torture_comment(tctx, "Changing machine account password to '%s'\n", password);
605
606         netlogon_creds_client_authenticator(creds, &credential);
607
608         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
609                 "ServerPasswordSet2 (2) failed");
610         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet2 (2) failed");
611
612         if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
613                 torture_comment(tctx, "Credential chaining failed\n");
614         }
615
616         /* by changing the machine password twice we test the
617            credentials chaining fully, and we verify that the server
618            allows the password to be set to the same value twice in a
619            row (match win2k3) */
620         torture_comment(tctx,
621                 "Testing a second ServerPasswordSet2 on machine account\n");
622         torture_comment(tctx,
623                 "Changing machine account password to '%s' (same as previous run)\n", password);
624
625         netlogon_creds_client_authenticator(creds, &credential);
626
627         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
628                 "ServerPasswordSet (3) failed");
629         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet (3) failed");
630
631         if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
632                 torture_comment(tctx, "Credential chaining failed\n");
633         }
634
635         cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
636
637         torture_assert (tctx,
638                 test_SetupCredentials(p, tctx, machine_credentials, &creds),
639                 "ServerPasswordSet failed to actually change the password");
640
641         new_random_pass = netlogon_very_rand_pass(tctx, 128);
642
643         /* now try a random stream of bytes for a password */
644         set_pw_in_buffer(password_buf.data, &new_random_pass);
645
646         netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
647
648         memcpy(new_password.data, password_buf.data, 512);
649         new_password.length = IVAL(password_buf.data, 512);
650
651         torture_comment(tctx,
652                 "Testing a third ServerPasswordSet2 on machine account, with a completely random password\n");
653
654         netlogon_creds_client_authenticator(creds, &credential);
655
656         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
657                 "ServerPasswordSet (3) failed");
658         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet (3) failed");
659
660         if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
661                 torture_comment(tctx, "Credential chaining failed\n");
662         }
663
664         mdfour(nt_hash.hash, new_random_pass.data, new_random_pass.length);
665
666         cli_credentials_set_password(machine_credentials, NULL, CRED_UNINITIALISED);
667         cli_credentials_set_nt_hash(machine_credentials, &nt_hash, CRED_SPECIFIED);
668
669         torture_assert (tctx,
670                 test_SetupCredentials(p, tctx, machine_credentials, &creds),
671                 "ServerPasswordSet failed to actually change the password");
672
673         return true;
674 }
675
676 static bool test_SetPassword2(struct torture_context *tctx,
677                               struct dcerpc_pipe *p,
678                               struct cli_credentials *machine_credentials)
679 {
680         return test_SetPassword2_with_flags(tctx, p, machine_credentials, NETLOGON_NEG_AUTH2_ADS_FLAGS);
681 }
682
683 static bool test_GetPassword(struct torture_context *tctx,
684                              struct dcerpc_pipe *p,
685                              struct cli_credentials *machine_credentials)
686 {
687         struct netr_ServerPasswordGet r;
688         struct netlogon_creds_CredentialState *creds;
689         struct netr_Authenticator credential;
690         NTSTATUS status;
691         struct netr_Authenticator return_authenticator;
692         struct samr_Password password;
693         struct dcerpc_binding_handle *b = p->binding_handle;
694
695         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
696                 return false;
697         }
698
699         netlogon_creds_client_authenticator(creds, &credential);
700
701         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
702         r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
703         r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
704         r.in.computer_name = TEST_MACHINE_NAME;
705         r.in.credential = &credential;
706         r.out.return_authenticator = &return_authenticator;
707         r.out.password = &password;
708
709         status = dcerpc_netr_ServerPasswordGet_r(b, tctx, &r);
710         torture_assert_ntstatus_ok(tctx, status, "ServerPasswordGet");
711
712         return true;
713 }
714
715 static bool test_GetTrustPasswords(struct torture_context *tctx,
716                                    struct dcerpc_pipe *p,
717                                    struct cli_credentials *machine_credentials)
718 {
719         struct netr_ServerTrustPasswordsGet r;
720         struct netlogon_creds_CredentialState *creds;
721         struct netr_Authenticator credential;
722         struct netr_Authenticator return_authenticator;
723         struct samr_Password password, password2;
724         struct dcerpc_binding_handle *b = p->binding_handle;
725
726         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
727                 return false;
728         }
729
730         netlogon_creds_client_authenticator(creds, &credential);
731
732         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
733         r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
734         r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
735         r.in.computer_name = TEST_MACHINE_NAME;
736         r.in.credential = &credential;
737         r.out.return_authenticator = &return_authenticator;
738         r.out.password = &password;
739         r.out.password2 = &password2;
740
741         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerTrustPasswordsGet_r(b, tctx, &r),
742                 "ServerTrustPasswordsGet failed");
743         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerTrustPasswordsGet failed");
744
745         return true;
746 }
747
748 /*
749   try a netlogon SamLogon
750 */
751 static bool test_netlogon_ops_args(struct dcerpc_pipe *p, struct torture_context *tctx,
752                                    struct cli_credentials *credentials,
753                                    struct netlogon_creds_CredentialState *creds,
754                                    bool null_domain)
755 {
756         NTSTATUS status;
757         struct netr_LogonSamLogon r;
758         struct netr_Authenticator auth, auth2;
759         static const struct netr_Authenticator auth_zero;
760         union netr_LogonLevel logon;
761         union netr_Validation validation;
762         uint8_t authoritative;
763         struct netr_NetworkInfo ninfo;
764         DATA_BLOB names_blob, chal, lm_resp, nt_resp;
765         int i;
766         struct dcerpc_binding_handle *b = p->binding_handle;
767         int flags = CLI_CRED_NTLM_AUTH;
768         if (lpcfg_client_lanman_auth(tctx->lp_ctx)) {
769                 flags |= CLI_CRED_LANMAN_AUTH;
770         }
771
772         if (lpcfg_client_ntlmv2_auth(tctx->lp_ctx) && !null_domain) {
773                 flags |= CLI_CRED_NTLMv2_AUTH;
774         }
775
776         cli_credentials_get_ntlm_username_domain(cmdline_credentials, tctx,
777                                                  &ninfo.identity_info.account_name.string,
778                                                  &ninfo.identity_info.domain_name.string);
779
780         if (null_domain) {
781                 ninfo.identity_info.domain_name.string = NULL;
782         }
783
784         generate_random_buffer(ninfo.challenge,
785                                sizeof(ninfo.challenge));
786         chal = data_blob_const(ninfo.challenge,
787                                sizeof(ninfo.challenge));
788
789         names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(credentials),
790                                                 cli_credentials_get_domain(credentials));
791
792         status = cli_credentials_get_ntlm_response(cmdline_credentials, tctx,
793                                                    &flags,
794                                                    chal,
795                                                    names_blob,
796                                                    &lm_resp, &nt_resp,
797                                                    NULL, NULL);
798         torture_assert_ntstatus_ok(tctx, status, "cli_credentials_get_ntlm_response failed");
799
800         ninfo.lm.data = lm_resp.data;
801         ninfo.lm.length = lm_resp.length;
802
803         ninfo.nt.data = nt_resp.data;
804         ninfo.nt.length = nt_resp.length;
805
806         ninfo.identity_info.parameter_control = 0;
807         ninfo.identity_info.logon_id_low = 0;
808         ninfo.identity_info.logon_id_high = 0;
809         ninfo.identity_info.workstation.string = cli_credentials_get_workstation(credentials);
810
811         logon.network = &ninfo;
812
813         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
814         r.in.computer_name = cli_credentials_get_workstation(credentials);
815         r.in.credential = &auth;
816         r.in.return_authenticator = &auth2;
817         r.in.logon_level = 2;
818         r.in.logon = &logon;
819         r.out.validation = &validation;
820         r.out.authoritative = &authoritative;
821
822         d_printf("Testing LogonSamLogon with name %s\n", ninfo.identity_info.account_name.string);
823
824         for (i=2;i<=3;i++) {
825                 ZERO_STRUCT(auth2);
826                 netlogon_creds_client_authenticator(creds, &auth);
827
828                 r.in.validation_level = i;
829
830                 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
831                         "LogonSamLogon failed");
832                 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonSamLogon failed");
833
834                 torture_assert(tctx, netlogon_creds_client_check(creds,
835                                                                  &r.out.return_authenticator->cred),
836                         "Credential chaining failed");
837                 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
838                                          "LogonSamLogon invalid  *r.out.authoritative");
839         }
840
841         /* this makes sure we get the unmarshalling right for invalid levels */
842         for (i=52;i<53;i++) {
843                 ZERO_STRUCT(auth2);
844                 /* the authenticator should be ignored by the server */
845                 generate_random_buffer((uint8_t *) &auth, sizeof(auth));
846
847                 r.in.validation_level = i;
848
849                 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
850                                            "LogonSamLogon failed");
851                 torture_assert_ntstatus_equal(tctx, r.out.result,
852                                               NT_STATUS_INVALID_INFO_CLASS,
853                                               "LogonSamLogon failed");
854
855                 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
856                                          "LogonSamLogon invalid  *r.out.authoritative");
857                 torture_assert(tctx,
858                                memcmp(&auth2, &auth_zero, sizeof(auth2)) == 0,
859                                "Return authenticator non zero");
860         }
861
862         for (i=2;i<=3;i++) {
863                 ZERO_STRUCT(auth2);
864                 netlogon_creds_client_authenticator(creds, &auth);
865
866                 r.in.validation_level = i;
867
868                 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
869                         "LogonSamLogon failed");
870                 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonSamLogon failed");
871
872                 torture_assert(tctx, netlogon_creds_client_check(creds,
873                                                                  &r.out.return_authenticator->cred),
874                         "Credential chaining failed");
875                 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
876                                          "LogonSamLogon invalid  *r.out.authoritative");
877         }
878
879         r.in.logon_level = 52;
880
881         for (i=2;i<=3;i++) {
882                 ZERO_STRUCT(auth2);
883                 /* the authenticator should be ignored by the server */
884                 generate_random_buffer((uint8_t *) &auth, sizeof(auth));
885
886                 r.in.validation_level = i;
887
888                 torture_comment(tctx, "Testing SamLogon with validation level %d and a NULL credential\n", i);
889
890                 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
891                         "LogonSamLogon failed");
892                 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_INVALID_PARAMETER,
893                         "LogonSamLogon expected INVALID_PARAMETER");
894
895                 torture_assert(tctx,
896                                memcmp(&auth2, &auth_zero, sizeof(auth2)) == 0,
897                                "Return authenticator non zero");
898                 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
899                                          "LogonSamLogon invalid  *r.out.authoritative");
900         }
901
902         r.in.credential = NULL;
903
904         for (i=2;i<=3;i++) {
905                 ZERO_STRUCT(auth2);
906
907                 r.in.validation_level = i;
908
909                 torture_comment(tctx, "Testing SamLogon with validation level %d and a NULL credential\n", i);
910
911                 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
912                         "LogonSamLogon failed");
913                 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_INVALID_PARAMETER,
914                         "LogonSamLogon expected INVALID_PARAMETER");
915
916                 torture_assert(tctx,
917                                memcmp(&auth2, &auth_zero, sizeof(auth2)) == 0,
918                                "Return authenticator non zero");
919                 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
920                                          "LogonSamLogon invalid  *r.out.authoritative");
921         }
922
923         r.in.logon_level = 2;
924         r.in.credential = &auth;
925
926         for (i=2;i<=3;i++) {
927                 ZERO_STRUCT(auth2);
928                 netlogon_creds_client_authenticator(creds, &auth);
929
930                 r.in.validation_level = i;
931
932                 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
933                         "LogonSamLogon failed");
934                 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonSamLogon failed");
935
936                 torture_assert(tctx, netlogon_creds_client_check(creds,
937                                                                  &r.out.return_authenticator->cred),
938                         "Credential chaining failed");
939                 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
940                                          "LogonSamLogon invalid  *r.out.authoritative");
941         }
942
943         return true;
944 }
945
946 bool test_netlogon_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
947                        struct cli_credentials *credentials,
948                        struct netlogon_creds_CredentialState *creds)
949 {
950         return test_netlogon_ops_args(p, tctx, credentials, creds, false);
951 }
952
953 /*
954   try a netlogon GetCapabilities
955 */
956 bool test_netlogon_capabilities(struct dcerpc_pipe *p, struct torture_context *tctx,
957                                 struct cli_credentials *credentials,
958                                 struct netlogon_creds_CredentialState *creds)
959 {
960         NTSTATUS status;
961         struct netr_LogonGetCapabilities r;
962         union netr_Capabilities capabilities;
963         struct netr_Authenticator auth, return_auth;
964         struct netlogon_creds_CredentialState tmp_creds;
965         struct dcerpc_binding_handle *b = p->binding_handle;
966
967         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
968         r.in.computer_name = cli_credentials_get_workstation(credentials);
969         r.in.credential = &auth;
970         r.in.return_authenticator = &return_auth;
971         r.in.query_level = 1;
972         r.out.capabilities = &capabilities;
973         r.out.return_authenticator = &return_auth;
974
975         torture_comment(tctx, "Testing LogonGetCapabilities\n");
976
977         ZERO_STRUCT(return_auth);
978
979         /*
980          * we need to operate on a temporary copy of creds
981          * because dcerpc_netr_LogonGetCapabilities was
982          * dcerpc_netr_DummyFunction and returns NT_STATUS_NOT_IMPLEMENTED
983          * without looking a the authenticator.
984          */
985         tmp_creds = *creds;
986         netlogon_creds_client_authenticator(&tmp_creds, &auth);
987
988         status = dcerpc_netr_LogonGetCapabilities_r(b, tctx, &r);
989         torture_assert_ntstatus_ok(tctx, status, "LogonGetCapabilities failed");
990         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_IMPLEMENTED)) {
991                 return true;
992         }
993
994         *creds = tmp_creds;
995
996         torture_assert(tctx, netlogon_creds_client_check(creds,
997                                                          &r.out.return_authenticator->cred),
998                        "Credential chaining failed");
999
1000         torture_assert_int_equal(tctx, creds->negotiate_flags,
1001                                  capabilities.server_capabilities,
1002                                  "negotiate flags");
1003
1004         return true;
1005 }
1006
1007 /*
1008   try a netlogon SamLogon
1009 */
1010 static bool test_SamLogon(struct torture_context *tctx,
1011                           struct dcerpc_pipe *p,
1012                           struct cli_credentials *credentials)
1013 {
1014         struct netlogon_creds_CredentialState *creds;
1015
1016         if (!test_SetupCredentials(p, tctx, credentials, &creds)) {
1017                 return false;
1018         }
1019
1020         return test_netlogon_ops(p, tctx, credentials, creds);
1021 }
1022
1023 static bool test_SamLogon_NULL_domain(struct torture_context *tctx,
1024                                       struct dcerpc_pipe *p,
1025                                       struct cli_credentials *credentials)
1026 {
1027         struct netlogon_creds_CredentialState *creds;
1028
1029         if (!test_SetupCredentials(p, tctx, credentials, &creds)) {
1030                 return false;
1031         }
1032
1033         return test_netlogon_ops_args(p, tctx, credentials, creds, true);
1034 }
1035
1036 /* we remember the sequence numbers so we can easily do a DatabaseDelta */
1037 static uint64_t sequence_nums[3];
1038
1039 /*
1040   try a netlogon DatabaseSync
1041 */
1042 static bool test_DatabaseSync(struct torture_context *tctx,
1043                               struct dcerpc_pipe *p,
1044                               struct cli_credentials *machine_credentials)
1045 {
1046         struct netr_DatabaseSync r;
1047         struct netlogon_creds_CredentialState *creds;
1048         const uint32_t database_ids[] = {SAM_DATABASE_DOMAIN, SAM_DATABASE_BUILTIN, SAM_DATABASE_PRIVS};
1049         int i;
1050         struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
1051         struct netr_Authenticator credential, return_authenticator;
1052         struct dcerpc_binding_handle *b = p->binding_handle;
1053
1054         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1055                 return false;
1056         }
1057
1058         ZERO_STRUCT(return_authenticator);
1059
1060         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1061         r.in.computername = TEST_MACHINE_NAME;
1062         r.in.preferredmaximumlength = (uint32_t)-1;
1063         r.in.return_authenticator = &return_authenticator;
1064         r.out.delta_enum_array = &delta_enum_array;
1065         r.out.return_authenticator = &return_authenticator;
1066
1067         for (i=0;i<ARRAY_SIZE(database_ids);i++) {
1068
1069                 uint32_t sync_context = 0;
1070
1071                 r.in.database_id = database_ids[i];
1072                 r.in.sync_context = &sync_context;
1073                 r.out.sync_context = &sync_context;
1074
1075                 torture_comment(tctx, "Testing DatabaseSync of id %d\n", r.in.database_id);
1076
1077                 do {
1078                         netlogon_creds_client_authenticator(creds, &credential);
1079
1080                         r.in.credential = &credential;
1081
1082                         torture_assert_ntstatus_ok(tctx, dcerpc_netr_DatabaseSync_r(b, tctx, &r),
1083                                 "DatabaseSync failed");
1084                         if (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES))
1085                             break;
1086
1087                         /* Native mode servers don't do this */
1088                         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_SUPPORTED)) {
1089                                 return true;
1090                         }
1091                         torture_assert_ntstatus_ok(tctx, r.out.result, "DatabaseSync");
1092
1093                         if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
1094                                 torture_comment(tctx, "Credential chaining failed\n");
1095                         }
1096
1097                         if (delta_enum_array &&
1098                             delta_enum_array->num_deltas > 0 &&
1099                             delta_enum_array->delta_enum[0].delta_type == NETR_DELTA_DOMAIN &&
1100                             delta_enum_array->delta_enum[0].delta_union.domain) {
1101                                 sequence_nums[r.in.database_id] =
1102                                         delta_enum_array->delta_enum[0].delta_union.domain->sequence_num;
1103                                 torture_comment(tctx, "\tsequence_nums[%d]=%llu\n",
1104                                        r.in.database_id,
1105                                        (unsigned long long)sequence_nums[r.in.database_id]);
1106                         }
1107                 } while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES));
1108         }
1109
1110         return true;
1111 }
1112
1113
1114 /*
1115   try a netlogon DatabaseDeltas
1116 */
1117 static bool test_DatabaseDeltas(struct torture_context *tctx,
1118                                 struct dcerpc_pipe *p,
1119                                 struct cli_credentials *machine_credentials)
1120 {
1121         struct netr_DatabaseDeltas r;
1122         struct netlogon_creds_CredentialState *creds;
1123         struct netr_Authenticator credential;
1124         struct netr_Authenticator return_authenticator;
1125         struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
1126         const uint32_t database_ids[] = {0, 1, 2};
1127         int i;
1128         struct dcerpc_binding_handle *b = p->binding_handle;
1129
1130         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1131                 return false;
1132         }
1133
1134         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1135         r.in.computername = TEST_MACHINE_NAME;
1136         r.in.preferredmaximumlength = (uint32_t)-1;
1137         ZERO_STRUCT(r.in.return_authenticator);
1138         r.out.return_authenticator = &return_authenticator;
1139         r.out.delta_enum_array = &delta_enum_array;
1140
1141         for (i=0;i<ARRAY_SIZE(database_ids);i++) {
1142                 r.in.database_id = database_ids[i];
1143                 r.in.sequence_num = &sequence_nums[r.in.database_id];
1144
1145                 if (*r.in.sequence_num == 0) continue;
1146
1147                 *r.in.sequence_num -= 1;
1148
1149                 torture_comment(tctx, "Testing DatabaseDeltas of id %d at %llu\n",
1150                        r.in.database_id, (unsigned long long)*r.in.sequence_num);
1151
1152                 do {
1153                         netlogon_creds_client_authenticator(creds, &credential);
1154
1155                         torture_assert_ntstatus_ok(tctx, dcerpc_netr_DatabaseDeltas_r(b, tctx, &r),
1156                                 "DatabaseDeltas failed");
1157                         if (NT_STATUS_EQUAL(r.out.result,
1158                                              NT_STATUS_SYNCHRONIZATION_REQUIRED)) {
1159                                 torture_comment(tctx, "not considering %s to be an error\n",
1160                                        nt_errstr(r.out.result));
1161                                 return true;
1162                         }
1163                         if (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES))
1164                             break;
1165
1166                         torture_assert_ntstatus_ok(tctx, r.out.result, "DatabaseDeltas");
1167
1168                         if (!netlogon_creds_client_check(creds, &return_authenticator.cred)) {
1169                                 torture_comment(tctx, "Credential chaining failed\n");
1170                         }
1171
1172                         (*r.in.sequence_num)++;
1173                 } while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES));
1174         }
1175
1176         return true;
1177 }
1178
1179 static bool test_DatabaseRedo(struct torture_context *tctx,
1180                               struct dcerpc_pipe *p,
1181                               struct cli_credentials *machine_credentials)
1182 {
1183         struct netr_DatabaseRedo r;
1184         struct netlogon_creds_CredentialState *creds;
1185         struct netr_Authenticator credential;
1186         struct netr_Authenticator return_authenticator;
1187         struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
1188         struct netr_ChangeLogEntry e;
1189         struct dom_sid null_sid, *sid;
1190         int i,d;
1191         struct dcerpc_binding_handle *b = p->binding_handle;
1192
1193         ZERO_STRUCT(null_sid);
1194
1195         sid = dom_sid_parse_talloc(tctx, "S-1-5-21-1111111111-2222222222-333333333-500");
1196
1197         {
1198
1199         struct {
1200                 uint32_t rid;
1201                 uint16_t flags;
1202                 uint8_t db_index;
1203                 uint8_t delta_type;
1204                 struct dom_sid sid;
1205                 const char *name;
1206                 NTSTATUS expected_error;
1207                 uint32_t expected_num_results;
1208                 uint8_t expected_delta_type_1;
1209                 uint8_t expected_delta_type_2;
1210                 const char *comment;
1211         } changes[] = {
1212
1213                 /* SAM_DATABASE_DOMAIN */
1214
1215                 {
1216                         .rid                    = 0,
1217                         .flags                  = 0,
1218                         .db_index               = SAM_DATABASE_DOMAIN,
1219                         .delta_type             = NETR_DELTA_MODIFY_COUNT,
1220                         .sid                    = null_sid,
1221                         .name                   = NULL,
1222                         .expected_error         = NT_STATUS_SYNCHRONIZATION_REQUIRED,
1223                         .expected_num_results   = 0,
1224                         .comment                = "NETR_DELTA_MODIFY_COUNT"
1225                 },
1226                 {
1227                         .rid                    = 0,
1228                         .flags                  = 0,
1229                         .db_index               = SAM_DATABASE_DOMAIN,
1230                         .delta_type             = 0,
1231                         .sid                    = null_sid,
1232                         .name                   = NULL,
1233                         .expected_error         = NT_STATUS_OK,
1234                         .expected_num_results   = 1,
1235                         .expected_delta_type_1  = NETR_DELTA_DOMAIN,
1236                         .comment                = "NULL DELTA"
1237                 },
1238                 {
1239                         .rid                    = 0,
1240                         .flags                  = 0,
1241                         .db_index               = SAM_DATABASE_DOMAIN,
1242                         .delta_type             = NETR_DELTA_DOMAIN,
1243                         .sid                    = null_sid,
1244                         .name                   = NULL,
1245                         .expected_error         = NT_STATUS_OK,
1246                         .expected_num_results   = 1,
1247                         .expected_delta_type_1  = NETR_DELTA_DOMAIN,
1248                         .comment                = "NETR_DELTA_DOMAIN"
1249                 },
1250                 {
1251                         .rid                    = DOMAIN_RID_ADMINISTRATOR,
1252                         .flags                  = 0,
1253                         .db_index               = SAM_DATABASE_DOMAIN,
1254                         .delta_type             = NETR_DELTA_USER,
1255                         .sid                    = null_sid,
1256                         .name                   = NULL,
1257                         .expected_error         = NT_STATUS_OK,
1258                         .expected_num_results   = 1,
1259                         .expected_delta_type_1  = NETR_DELTA_USER,
1260                         .comment                = "NETR_DELTA_USER by rid 500"
1261                 },
1262                 {
1263                         .rid                    = DOMAIN_RID_GUEST,
1264                         .flags                  = 0,
1265                         .db_index               = SAM_DATABASE_DOMAIN,
1266                         .delta_type             = NETR_DELTA_USER,
1267                         .sid                    = null_sid,
1268                         .name                   = NULL,
1269                         .expected_error         = NT_STATUS_OK,
1270                         .expected_num_results   = 1,
1271                         .expected_delta_type_1  = NETR_DELTA_USER,
1272                         .comment                = "NETR_DELTA_USER by rid 501"
1273                 },
1274                 {
1275                         .rid                    = 0,
1276                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
1277                         .db_index               = SAM_DATABASE_DOMAIN,
1278                         .delta_type             = NETR_DELTA_USER,
1279                         .sid                    = *sid,
1280                         .name                   = NULL,
1281                         .expected_error         = NT_STATUS_OK,
1282                         .expected_num_results   = 1,
1283                         .expected_delta_type_1  = NETR_DELTA_DELETE_USER,
1284                         .comment                = "NETR_DELTA_USER by sid and flags"
1285                 },
1286                 {
1287                         .rid                    = 0,
1288                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
1289                         .db_index               = SAM_DATABASE_DOMAIN,
1290                         .delta_type             = NETR_DELTA_USER,
1291                         .sid                    = null_sid,
1292                         .name                   = NULL,
1293                         .expected_error         = NT_STATUS_OK,
1294                         .expected_num_results   = 1,
1295                         .expected_delta_type_1  = NETR_DELTA_DELETE_USER,
1296                         .comment                = "NETR_DELTA_USER by null_sid and flags"
1297                 },
1298                 {
1299                         .rid                    = 0,
1300                         .flags                  = NETR_CHANGELOG_NAME_INCLUDED,
1301                         .db_index               = SAM_DATABASE_DOMAIN,
1302                         .delta_type             = NETR_DELTA_USER,
1303                         .sid                    = null_sid,
1304                         .name                   = "administrator",
1305                         .expected_error         = NT_STATUS_OK,
1306                         .expected_num_results   = 1,
1307                         .expected_delta_type_1  = NETR_DELTA_DELETE_USER,
1308                         .comment                = "NETR_DELTA_USER by name 'administrator'"
1309                 },
1310                 {
1311                         .rid                    = DOMAIN_RID_ADMINS,
1312                         .flags                  = 0,
1313                         .db_index               = SAM_DATABASE_DOMAIN,
1314                         .delta_type             = NETR_DELTA_GROUP,
1315                         .sid                    = null_sid,
1316                         .name                   = NULL,
1317                         .expected_error         = NT_STATUS_OK,
1318                         .expected_num_results   = 2,
1319                         .expected_delta_type_1  = NETR_DELTA_GROUP,
1320                         .expected_delta_type_2  = NETR_DELTA_GROUP_MEMBER,
1321                         .comment                = "NETR_DELTA_GROUP by rid 512"
1322                 },
1323                 {
1324                         .rid                    = DOMAIN_RID_ADMINS,
1325                         .flags                  = 0,
1326                         .db_index               = SAM_DATABASE_DOMAIN,
1327                         .delta_type             = NETR_DELTA_GROUP_MEMBER,
1328                         .sid                    = null_sid,
1329                         .name                   = NULL,
1330                         .expected_error         = NT_STATUS_OK,
1331                         .expected_num_results   = 2,
1332                         .expected_delta_type_1  = NETR_DELTA_GROUP,
1333                         .expected_delta_type_2  = NETR_DELTA_GROUP_MEMBER,
1334                         .comment                = "NETR_DELTA_GROUP_MEMBER by rid 512"
1335                 },
1336
1337
1338                 /* SAM_DATABASE_BUILTIN */
1339
1340                 {
1341                         .rid                    = 0,
1342                         .flags                  = 0,
1343                         .db_index               = SAM_DATABASE_BUILTIN,
1344                         .delta_type             = NETR_DELTA_MODIFY_COUNT,
1345                         .sid                    = null_sid,
1346                         .name                   = NULL,
1347                         .expected_error         = NT_STATUS_SYNCHRONIZATION_REQUIRED,
1348                         .expected_num_results   = 0,
1349                         .comment                = "NETR_DELTA_MODIFY_COUNT"
1350                 },
1351                 {
1352                         .rid                    = 0,
1353                         .flags                  = 0,
1354                         .db_index               = SAM_DATABASE_BUILTIN,
1355                         .delta_type             = NETR_DELTA_DOMAIN,
1356                         .sid                    = null_sid,
1357                         .name                   = NULL,
1358                         .expected_error         = NT_STATUS_OK,
1359                         .expected_num_results   = 1,
1360                         .expected_delta_type_1  = NETR_DELTA_DOMAIN,
1361                         .comment                = "NETR_DELTA_DOMAIN"
1362                 },
1363                 {
1364                         .rid                    = DOMAIN_RID_ADMINISTRATOR,
1365                         .flags                  = 0,
1366                         .db_index               = SAM_DATABASE_BUILTIN,
1367                         .delta_type             = NETR_DELTA_USER,
1368                         .sid                    = null_sid,
1369                         .name                   = NULL,
1370                         .expected_error         = NT_STATUS_OK,
1371                         .expected_num_results   = 1,
1372                         .expected_delta_type_1  = NETR_DELTA_DELETE_USER,
1373                         .comment                = "NETR_DELTA_USER by rid 500"
1374                 },
1375                 {
1376                         .rid                    = 0,
1377                         .flags                  = 0,
1378                         .db_index               = SAM_DATABASE_BUILTIN,
1379                         .delta_type             = NETR_DELTA_USER,
1380                         .sid                    = null_sid,
1381                         .name                   = NULL,
1382                         .expected_error         = NT_STATUS_OK,
1383                         .expected_num_results   = 1,
1384                         .expected_delta_type_1  = NETR_DELTA_DELETE_USER,
1385                         .comment                = "NETR_DELTA_USER"
1386                 },
1387                 {
1388                         .rid                    = 544,
1389                         .flags                  = 0,
1390                         .db_index               = SAM_DATABASE_BUILTIN,
1391                         .delta_type             = NETR_DELTA_ALIAS,
1392                         .sid                    = null_sid,
1393                         .name                   = NULL,
1394                         .expected_error         = NT_STATUS_OK,
1395                         .expected_num_results   = 2,
1396                         .expected_delta_type_1  = NETR_DELTA_ALIAS,
1397                         .expected_delta_type_2  = NETR_DELTA_ALIAS_MEMBER,
1398                         .comment                = "NETR_DELTA_ALIAS by rid 544"
1399                 },
1400                 {
1401                         .rid                    = 544,
1402                         .flags                  = 0,
1403                         .db_index               = SAM_DATABASE_BUILTIN,
1404                         .delta_type             = NETR_DELTA_ALIAS_MEMBER,
1405                         .sid                    = null_sid,
1406                         .name                   = NULL,
1407                         .expected_error         = NT_STATUS_OK,
1408                         .expected_num_results   = 2,
1409                         .expected_delta_type_1  = NETR_DELTA_ALIAS,
1410                         .expected_delta_type_2  = NETR_DELTA_ALIAS_MEMBER,
1411                         .comment                = "NETR_DELTA_ALIAS_MEMBER by rid 544"
1412                 },
1413                 {
1414                         .rid                    = 544,
1415                         .flags                  = 0,
1416                         .db_index               = SAM_DATABASE_BUILTIN,
1417                         .delta_type             = 0,
1418                         .sid                    = null_sid,
1419                         .name                   = NULL,
1420                         .expected_error         = NT_STATUS_OK,
1421                         .expected_num_results   = 1,
1422                         .expected_delta_type_1  = NETR_DELTA_DOMAIN,
1423                         .comment                = "NULL DELTA by rid 544"
1424                 },
1425                 {
1426                         .rid                    = 544,
1427                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
1428                         .db_index               = SAM_DATABASE_BUILTIN,
1429                         .delta_type             = 0,
1430                         .sid                    = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
1431                         .name                   = NULL,
1432                         .expected_error         = NT_STATUS_OK,
1433                         .expected_num_results   = 1,
1434                         .expected_delta_type_1  = NETR_DELTA_DOMAIN,
1435                         .comment                = "NULL DELTA by rid 544 sid S-1-5-32-544 and flags"
1436                 },
1437                 {
1438                         .rid                    = 544,
1439                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
1440                         .db_index               = SAM_DATABASE_BUILTIN,
1441                         .delta_type             = NETR_DELTA_ALIAS,
1442                         .sid                    = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
1443                         .name                   = NULL,
1444                         .expected_error         = NT_STATUS_OK,
1445                         .expected_num_results   = 2,
1446                         .expected_delta_type_1  = NETR_DELTA_ALIAS,
1447                         .expected_delta_type_2  = NETR_DELTA_ALIAS_MEMBER,
1448                         .comment                = "NETR_DELTA_ALIAS by rid 544 and sid S-1-5-32-544 and flags"
1449                 },
1450                 {
1451                         .rid                    = 0,
1452                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
1453                         .db_index               = SAM_DATABASE_BUILTIN,
1454                         .delta_type             = NETR_DELTA_ALIAS,
1455                         .sid                    = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
1456                         .name                   = NULL,
1457                         .expected_error         = NT_STATUS_OK,
1458                         .expected_num_results   = 1,
1459                         .expected_delta_type_1  = NETR_DELTA_DELETE_ALIAS,
1460                         .comment                = "NETR_DELTA_ALIAS by sid S-1-5-32-544 and flags"
1461                 },
1462
1463                 /* SAM_DATABASE_PRIVS */
1464
1465                 {
1466                         .rid                    = 0,
1467                         .flags                  = 0,
1468                         .db_index               = SAM_DATABASE_PRIVS,
1469                         .delta_type             = 0,
1470                         .sid                    = null_sid,
1471                         .name                   = NULL,
1472                         .expected_error         = NT_STATUS_ACCESS_DENIED,
1473                         .expected_num_results   = 0,
1474                         .comment                = "NULL DELTA"
1475                 },
1476                 {
1477                         .rid                    = 0,
1478                         .flags                  = 0,
1479                         .db_index               = SAM_DATABASE_PRIVS,
1480                         .delta_type             = NETR_DELTA_MODIFY_COUNT,
1481                         .sid                    = null_sid,
1482                         .name                   = NULL,
1483                         .expected_error         = NT_STATUS_SYNCHRONIZATION_REQUIRED,
1484                         .expected_num_results   = 0,
1485                         .comment                = "NETR_DELTA_MODIFY_COUNT"
1486                 },
1487                 {
1488                         .rid                    = 0,
1489                         .flags                  = 0,
1490                         .db_index               = SAM_DATABASE_PRIVS,
1491                         .delta_type             = NETR_DELTA_POLICY,
1492                         .sid                    = null_sid,
1493                         .name                   = NULL,
1494                         .expected_error         = NT_STATUS_OK,
1495                         .expected_num_results   = 1,
1496                         .expected_delta_type_1  = NETR_DELTA_POLICY,
1497                         .comment                = "NETR_DELTA_POLICY"
1498                 },
1499                 {
1500                         .rid                    = 0,
1501                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
1502                         .db_index               = SAM_DATABASE_PRIVS,
1503                         .delta_type             = NETR_DELTA_POLICY,
1504                         .sid                    = null_sid,
1505                         .name                   = NULL,
1506                         .expected_error         = NT_STATUS_OK,
1507                         .expected_num_results   = 1,
1508                         .expected_delta_type_1  = NETR_DELTA_POLICY,
1509                         .comment                = "NETR_DELTA_POLICY by null sid and flags"
1510                 },
1511                 {
1512                         .rid                    = 0,
1513                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
1514                         .db_index               = SAM_DATABASE_PRIVS,
1515                         .delta_type             = NETR_DELTA_POLICY,
1516                         .sid                    = *dom_sid_parse_talloc(tctx, "S-1-5-32"),
1517                         .name                   = NULL,
1518                         .expected_error         = NT_STATUS_OK,
1519                         .expected_num_results   = 1,
1520                         .expected_delta_type_1  = NETR_DELTA_POLICY,
1521                         .comment                = "NETR_DELTA_POLICY by sid S-1-5-32 and flags"
1522                 },
1523                 {
1524                         .rid                    = DOMAIN_RID_ADMINISTRATOR,
1525                         .flags                  = 0,
1526                         .db_index               = SAM_DATABASE_PRIVS,
1527                         .delta_type             = NETR_DELTA_ACCOUNT,
1528                         .sid                    = null_sid,
1529                         .name                   = NULL,
1530                         .expected_error         = NT_STATUS_SYNCHRONIZATION_REQUIRED, /* strange */
1531                         .expected_num_results   = 0,
1532                         .comment                = "NETR_DELTA_ACCOUNT by rid 500"
1533                 },
1534                 {
1535                         .rid                    = 0,
1536                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
1537                         .db_index               = SAM_DATABASE_PRIVS,
1538                         .delta_type             = NETR_DELTA_ACCOUNT,
1539                         .sid                    = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
1540                         .name                   = NULL,
1541                         .expected_error         = NT_STATUS_OK,
1542                         .expected_num_results   = 1,
1543                         .expected_delta_type_1  = NETR_DELTA_ACCOUNT,
1544                         .comment                = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and flags"
1545                 },
1546                 {
1547                         .rid                    = 0,
1548                         .flags                  = NETR_CHANGELOG_SID_INCLUDED |
1549                                                   NETR_CHANGELOG_IMMEDIATE_REPL_REQUIRED,
1550                         .db_index               = SAM_DATABASE_PRIVS,
1551                         .delta_type             = NETR_DELTA_ACCOUNT,
1552                         .sid                    = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
1553                         .name                   = NULL,
1554                         .expected_error         = NT_STATUS_OK,
1555                         .expected_num_results   = 1,
1556                         .expected_delta_type_1  = NETR_DELTA_ACCOUNT,
1557                         .comment                = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and 2 flags"
1558                 },
1559                 {
1560                         .rid                    = 0,
1561                         .flags                  = NETR_CHANGELOG_SID_INCLUDED |
1562                                                   NETR_CHANGELOG_NAME_INCLUDED,
1563                         .db_index               = SAM_DATABASE_PRIVS,
1564                         .delta_type             = NETR_DELTA_ACCOUNT,
1565                         .sid                    = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
1566                         .name                   = NULL,
1567                         .expected_error         = NT_STATUS_INVALID_PARAMETER,
1568                         .expected_num_results   = 0,
1569                         .comment                = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and invalid flags"
1570                 },
1571                 {
1572                         .rid                    = DOMAIN_RID_ADMINISTRATOR,
1573                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
1574                         .db_index               = SAM_DATABASE_PRIVS,
1575                         .delta_type             = NETR_DELTA_ACCOUNT,
1576                         .sid                    = *sid,
1577                         .name                   = NULL,
1578                         .expected_error         = NT_STATUS_OK,
1579                         .expected_num_results   = 1,
1580                         .expected_delta_type_1  = NETR_DELTA_DELETE_ACCOUNT,
1581                         .comment                = "NETR_DELTA_ACCOUNT by rid 500, sid and flags"
1582                 },
1583                 {
1584                         .rid                    = 0,
1585                         .flags                  = NETR_CHANGELOG_NAME_INCLUDED,
1586                         .db_index               = SAM_DATABASE_PRIVS,
1587                         .delta_type             = NETR_DELTA_SECRET,
1588                         .sid                    = null_sid,
1589                         .name                   = "IsurelydontexistIhope",
1590                         .expected_error         = NT_STATUS_OK,
1591                         .expected_num_results   = 1,
1592                         .expected_delta_type_1  = NETR_DELTA_DELETE_SECRET,
1593                         .comment                = "NETR_DELTA_SECRET by name 'IsurelydontexistIhope' and flags"
1594                 },
1595                 {
1596                         .rid                    = 0,
1597                         .flags                  = NETR_CHANGELOG_NAME_INCLUDED,
1598                         .db_index               = SAM_DATABASE_PRIVS,
1599                         .delta_type             = NETR_DELTA_SECRET,
1600                         .sid                    = null_sid,
1601                         .name                   = "G$BCKUPKEY_P",
1602                         .expected_error         = NT_STATUS_OK,
1603                         .expected_num_results   = 1,
1604                         .expected_delta_type_1  = NETR_DELTA_SECRET,
1605                         .comment                = "NETR_DELTA_SECRET by name 'G$BCKUPKEY_P' and flags"
1606                 }
1607         };
1608
1609         ZERO_STRUCT(return_authenticator);
1610
1611         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1612         r.in.computername = TEST_MACHINE_NAME;
1613         r.in.return_authenticator = &return_authenticator;
1614         r.out.return_authenticator = &return_authenticator;
1615         r.out.delta_enum_array = &delta_enum_array;
1616
1617         for (d=0; d<3; d++) {
1618                 const char *database = NULL;
1619
1620                 switch (d) {
1621                 case 0:
1622                         database = "SAM";
1623                         break;
1624                 case 1:
1625                         database = "BUILTIN";
1626                         break;
1627                 case 2:
1628                         database = "LSA";
1629                         break;
1630                 default:
1631                         break;
1632                 }
1633
1634                 torture_comment(tctx, "Testing DatabaseRedo\n");
1635
1636                 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1637                         return false;
1638                 }
1639
1640                 for (i=0;i<ARRAY_SIZE(changes);i++) {
1641
1642                         if (d != changes[i].db_index) {
1643                                 continue;
1644                         }
1645
1646                         netlogon_creds_client_authenticator(creds, &credential);
1647
1648                         r.in.credential = &credential;
1649
1650                         e.serial_number1        = 0;
1651                         e.serial_number2        = 0;
1652                         e.object_rid            = changes[i].rid;
1653                         e.flags                 = changes[i].flags;
1654                         e.db_index              = changes[i].db_index;
1655                         e.delta_type            = changes[i].delta_type;
1656
1657                         switch (changes[i].flags & (NETR_CHANGELOG_NAME_INCLUDED | NETR_CHANGELOG_SID_INCLUDED)) {
1658                         case NETR_CHANGELOG_SID_INCLUDED:
1659                                 e.object.object_sid             = changes[i].sid;
1660                                 break;
1661                         case NETR_CHANGELOG_NAME_INCLUDED:
1662                                 e.object.object_name            = changes[i].name;
1663                                 break;
1664                         default:
1665                                 break;
1666                         }
1667
1668                         r.in.change_log_entry = e;
1669
1670                         torture_comment(tctx, "Testing DatabaseRedo with database %s and %s\n",
1671                                 database, changes[i].comment);
1672
1673                         torture_assert_ntstatus_ok(tctx, dcerpc_netr_DatabaseRedo_r(b, tctx, &r),
1674                                 "DatabaseRedo failed");
1675                         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_SUPPORTED)) {
1676                                 return true;
1677                         }
1678
1679                         torture_assert_ntstatus_equal(tctx, r.out.result, changes[i].expected_error, changes[i].comment);
1680                         if (delta_enum_array) {
1681                                 torture_assert_int_equal(tctx,
1682                                         delta_enum_array->num_deltas,
1683                                         changes[i].expected_num_results,
1684                                         changes[i].comment);
1685                                 if (delta_enum_array->num_deltas > 0) {
1686                                         torture_assert_int_equal(tctx,
1687                                                 delta_enum_array->delta_enum[0].delta_type,
1688                                                 changes[i].expected_delta_type_1,
1689                                                 changes[i].comment);
1690                                 }
1691                                 if (delta_enum_array->num_deltas > 1) {
1692                                         torture_assert_int_equal(tctx,
1693                                                 delta_enum_array->delta_enum[1].delta_type,
1694                                                 changes[i].expected_delta_type_2,
1695                                                 changes[i].comment);
1696                                 }
1697                         }
1698
1699                         if (!netlogon_creds_client_check(creds, &return_authenticator.cred)) {
1700                                 torture_comment(tctx, "Credential chaining failed\n");
1701                                 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1702                                         return false;
1703                                 }
1704                         }
1705                 }
1706         }
1707         }
1708
1709         return true;
1710 }
1711
1712 /*
1713   try a netlogon AccountDeltas
1714 */
1715 static bool test_AccountDeltas(struct torture_context *tctx,
1716                                struct dcerpc_pipe *p,
1717                                struct cli_credentials *machine_credentials)
1718 {
1719         struct netr_AccountDeltas r;
1720         struct netlogon_creds_CredentialState *creds;
1721
1722         struct netr_AccountBuffer buffer;
1723         uint32_t count_returned = 0;
1724         uint32_t total_entries = 0;
1725         struct netr_UAS_INFO_0 recordid;
1726         struct netr_Authenticator return_authenticator;
1727         struct dcerpc_binding_handle *b = p->binding_handle;
1728
1729         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1730                 return false;
1731         }
1732
1733         ZERO_STRUCT(return_authenticator);
1734
1735         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1736         r.in.computername = TEST_MACHINE_NAME;
1737         r.in.return_authenticator = &return_authenticator;
1738         netlogon_creds_client_authenticator(creds, &r.in.credential);
1739         ZERO_STRUCT(r.in.uas);
1740         r.in.count=10;
1741         r.in.level=0;
1742         r.in.buffersize=100;
1743         r.out.buffer = &buffer;
1744         r.out.count_returned = &count_returned;
1745         r.out.total_entries = &total_entries;
1746         r.out.recordid = &recordid;
1747         r.out.return_authenticator = &return_authenticator;
1748
1749         /* w2k3 returns "NOT IMPLEMENTED" for this call */
1750         torture_assert_ntstatus_ok(tctx, dcerpc_netr_AccountDeltas_r(b, tctx, &r),
1751                 "AccountDeltas failed");
1752         torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_IMPLEMENTED, "AccountDeltas");
1753
1754         return true;
1755 }
1756
1757 /*
1758   try a netlogon AccountSync
1759 */
1760 static bool test_AccountSync(struct torture_context *tctx, struct dcerpc_pipe *p,
1761                              struct cli_credentials *machine_credentials)
1762 {
1763         struct netr_AccountSync r;
1764         struct netlogon_creds_CredentialState *creds;
1765
1766         struct netr_AccountBuffer buffer;
1767         uint32_t count_returned = 0;
1768         uint32_t total_entries = 0;
1769         uint32_t next_reference = 0;
1770         struct netr_UAS_INFO_0 recordid;
1771         struct netr_Authenticator return_authenticator;
1772         struct dcerpc_binding_handle *b = p->binding_handle;
1773
1774         ZERO_STRUCT(recordid);
1775         ZERO_STRUCT(return_authenticator);
1776
1777         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1778                 return false;
1779         }
1780
1781         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1782         r.in.computername = TEST_MACHINE_NAME;
1783         r.in.return_authenticator = &return_authenticator;
1784         netlogon_creds_client_authenticator(creds, &r.in.credential);
1785         r.in.recordid = &recordid;
1786         r.in.reference=0;
1787         r.in.level=0;
1788         r.in.buffersize=100;
1789         r.out.buffer = &buffer;
1790         r.out.count_returned = &count_returned;
1791         r.out.total_entries = &total_entries;
1792         r.out.next_reference = &next_reference;
1793         r.out.recordid = &recordid;
1794         r.out.return_authenticator = &return_authenticator;
1795
1796         /* w2k3 returns "NOT IMPLEMENTED" for this call */
1797         torture_assert_ntstatus_ok(tctx, dcerpc_netr_AccountSync_r(b, tctx, &r),
1798                 "AccountSync failed");
1799         torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_IMPLEMENTED, "AccountSync");
1800
1801         return true;
1802 }
1803
1804 /*
1805   try a netlogon GetDcName
1806 */
1807 static bool test_GetDcName(struct torture_context *tctx,
1808                            struct dcerpc_pipe *p)
1809 {
1810         struct netr_GetDcName r;
1811         const char *dcname = NULL;
1812         struct dcerpc_binding_handle *b = p->binding_handle;
1813
1814         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1815         r.in.domainname = lpcfg_workgroup(tctx->lp_ctx);
1816         r.out.dcname = &dcname;
1817
1818         torture_assert_ntstatus_ok(tctx, dcerpc_netr_GetDcName_r(b, tctx, &r),
1819                 "GetDcName failed");
1820         torture_assert_werr_ok(tctx, r.out.result, "GetDcName failed");
1821
1822         torture_comment(tctx, "\tDC is at '%s'\n", dcname);
1823
1824         return true;
1825 }
1826
1827 static const char *function_code_str(TALLOC_CTX *mem_ctx,
1828                                      enum netr_LogonControlCode function_code)
1829 {
1830         switch (function_code) {
1831         case NETLOGON_CONTROL_QUERY:
1832                 return "NETLOGON_CONTROL_QUERY";
1833         case NETLOGON_CONTROL_REPLICATE:
1834                 return "NETLOGON_CONTROL_REPLICATE";
1835         case NETLOGON_CONTROL_SYNCHRONIZE:
1836                 return "NETLOGON_CONTROL_SYNCHRONIZE";
1837         case NETLOGON_CONTROL_PDC_REPLICATE:
1838                 return "NETLOGON_CONTROL_PDC_REPLICATE";
1839         case NETLOGON_CONTROL_REDISCOVER:
1840                 return "NETLOGON_CONTROL_REDISCOVER";
1841         case NETLOGON_CONTROL_TC_QUERY:
1842                 return "NETLOGON_CONTROL_TC_QUERY";
1843         case NETLOGON_CONTROL_TRANSPORT_NOTIFY:
1844                 return "NETLOGON_CONTROL_TRANSPORT_NOTIFY";
1845         case NETLOGON_CONTROL_FIND_USER:
1846                 return "NETLOGON_CONTROL_FIND_USER";
1847         case NETLOGON_CONTROL_CHANGE_PASSWORD:
1848                 return "NETLOGON_CONTROL_CHANGE_PASSWORD";
1849         case NETLOGON_CONTROL_TC_VERIFY:
1850                 return "NETLOGON_CONTROL_TC_VERIFY";
1851         case NETLOGON_CONTROL_FORCE_DNS_REG:
1852                 return "NETLOGON_CONTROL_FORCE_DNS_REG";
1853         case NETLOGON_CONTROL_QUERY_DNS_REG:
1854                 return "NETLOGON_CONTROL_QUERY_DNS_REG";
1855         case NETLOGON_CONTROL_BACKUP_CHANGE_LOG:
1856                 return "NETLOGON_CONTROL_BACKUP_CHANGE_LOG";
1857         case NETLOGON_CONTROL_TRUNCATE_LOG:
1858                 return "NETLOGON_CONTROL_TRUNCATE_LOG";
1859         case NETLOGON_CONTROL_SET_DBFLAG:
1860                 return "NETLOGON_CONTROL_SET_DBFLAG";
1861         case NETLOGON_CONTROL_BREAKPOINT:
1862                 return "NETLOGON_CONTROL_BREAKPOINT";
1863         default:
1864                 return talloc_asprintf(mem_ctx, "unknown function code: %d",
1865                                        function_code);
1866         }
1867 }
1868
1869
1870 /*
1871   try a netlogon LogonControl
1872 */
1873 static bool test_LogonControl(struct torture_context *tctx,
1874                               struct dcerpc_pipe *p,
1875                               struct cli_credentials *machine_credentials)
1876
1877 {
1878         NTSTATUS status;
1879         struct netr_LogonControl r;
1880         union netr_CONTROL_QUERY_INFORMATION query;
1881         int i,f;
1882         enum netr_SchannelType secure_channel_type = SEC_CHAN_NULL;
1883         struct dcerpc_binding_handle *b = p->binding_handle;
1884
1885         uint32_t function_codes[] = {
1886                 NETLOGON_CONTROL_QUERY,
1887                 NETLOGON_CONTROL_REPLICATE,
1888                 NETLOGON_CONTROL_SYNCHRONIZE,
1889                 NETLOGON_CONTROL_PDC_REPLICATE,
1890                 NETLOGON_CONTROL_REDISCOVER,
1891                 NETLOGON_CONTROL_TC_QUERY,
1892                 NETLOGON_CONTROL_TRANSPORT_NOTIFY,
1893                 NETLOGON_CONTROL_FIND_USER,
1894                 NETLOGON_CONTROL_CHANGE_PASSWORD,
1895                 NETLOGON_CONTROL_TC_VERIFY,
1896                 NETLOGON_CONTROL_FORCE_DNS_REG,
1897                 NETLOGON_CONTROL_QUERY_DNS_REG,
1898                 NETLOGON_CONTROL_BACKUP_CHANGE_LOG,
1899                 NETLOGON_CONTROL_TRUNCATE_LOG,
1900                 NETLOGON_CONTROL_SET_DBFLAG,
1901                 NETLOGON_CONTROL_BREAKPOINT
1902         };
1903
1904         if (machine_credentials) {
1905                 secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
1906         }
1907
1908         torture_comment(tctx, "Testing LogonControl with secure channel type: %d\n",
1909                 secure_channel_type);
1910
1911         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1912         r.in.function_code = 1;
1913         r.out.query = &query;
1914
1915         for (f=0;f<ARRAY_SIZE(function_codes); f++) {
1916         for (i=1;i<5;i++) {
1917
1918                 r.in.function_code = function_codes[f];
1919                 r.in.level = i;
1920
1921                 torture_comment(tctx, "Testing LogonControl function code %s (%d) level %d\n",
1922                                 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
1923
1924                 status = dcerpc_netr_LogonControl_r(b, tctx, &r);
1925                 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1926
1927                 switch (r.in.level) {
1928                 case 1:
1929                         switch (r.in.function_code) {
1930                         case NETLOGON_CONTROL_REPLICATE:
1931                         case NETLOGON_CONTROL_SYNCHRONIZE:
1932                         case NETLOGON_CONTROL_PDC_REPLICATE:
1933                         case NETLOGON_CONTROL_BREAKPOINT:
1934                         case NETLOGON_CONTROL_BACKUP_CHANGE_LOG:
1935                                 if ((secure_channel_type == SEC_CHAN_BDC) ||
1936                                     (secure_channel_type == SEC_CHAN_WKSTA)) {
1937                                         torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED,
1938                                                 "LogonControl returned unexpected error code");
1939                                 } else {
1940                                         torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
1941                                                 "LogonControl returned unexpected error code");
1942                                 }
1943                                 break;
1944
1945                         case NETLOGON_CONTROL_REDISCOVER:
1946                         case NETLOGON_CONTROL_TC_QUERY:
1947                         case NETLOGON_CONTROL_TRANSPORT_NOTIFY:
1948                         case NETLOGON_CONTROL_FIND_USER:
1949                         case NETLOGON_CONTROL_CHANGE_PASSWORD:
1950                         case NETLOGON_CONTROL_TC_VERIFY:
1951                         case NETLOGON_CONTROL_FORCE_DNS_REG:
1952                         case NETLOGON_CONTROL_QUERY_DNS_REG:
1953                         case NETLOGON_CONTROL_SET_DBFLAG:
1954                                 torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
1955                                         "LogonControl returned unexpected error code");
1956                                 break;
1957                         case NETLOGON_CONTROL_TRUNCATE_LOG:
1958                                 if ((secure_channel_type == SEC_CHAN_BDC) ||
1959                                     (secure_channel_type == SEC_CHAN_WKSTA)) {
1960                                         torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED,
1961                                                 "LogonControl returned unexpected error code");
1962                                 } else {
1963                                         torture_assert_werr_ok(tctx, r.out.result,
1964                                                 "LogonControl returned unexpected result");
1965                                 }
1966                                 break;
1967                         default:
1968                                 torture_assert_werr_ok(tctx, r.out.result,
1969                                         "LogonControl returned unexpected result");
1970                                 break;
1971                         }
1972                         break;
1973                 case 2:
1974                         torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
1975                                 "LogonControl returned unexpected error code");
1976                         break;
1977                 default:
1978                         torture_assert_werr_equal(tctx, r.out.result, WERR_UNKNOWN_LEVEL,
1979                                 "LogonControl returned unexpected error code");
1980                         break;
1981                 }
1982         }
1983         }
1984
1985         r.in.level = 52;
1986         torture_comment(tctx, "Testing LogonControl function code %s (%d) level %d\n",
1987                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
1988         status = dcerpc_netr_LogonControl_r(b, tctx, &r);
1989         torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1990         torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_LEVEL, "LogonControl");
1991
1992         return true;
1993 }
1994
1995
1996 /*
1997   try a netlogon GetAnyDCName
1998 */
1999 static bool test_GetAnyDCName(struct torture_context *tctx,
2000                               struct dcerpc_pipe *p)
2001 {
2002         NTSTATUS status;
2003         struct netr_GetAnyDCName r;
2004         const char *dcname = NULL;
2005         struct dcerpc_binding_handle *b = p->binding_handle;
2006
2007         r.in.domainname = lpcfg_workgroup(tctx->lp_ctx);
2008         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2009         r.out.dcname = &dcname;
2010
2011         status = dcerpc_netr_GetAnyDCName_r(b, tctx, &r);
2012         torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
2013         if ((!W_ERROR_IS_OK(r.out.result)) &&
2014             (!W_ERROR_EQUAL(r.out.result, WERR_NO_SUCH_DOMAIN))) {
2015                 return false;
2016         }
2017
2018         if (dcname) {
2019             torture_comment(tctx, "\tDC is at '%s'\n", dcname);
2020         }
2021
2022         r.in.domainname = NULL;
2023
2024         status = dcerpc_netr_GetAnyDCName_r(b, tctx, &r);
2025         torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
2026         if ((!W_ERROR_IS_OK(r.out.result)) &&
2027             (!W_ERROR_EQUAL(r.out.result, WERR_NO_SUCH_DOMAIN))) {
2028                 return false;
2029         }
2030
2031         r.in.domainname = "";
2032
2033         status = dcerpc_netr_GetAnyDCName_r(b, tctx, &r);
2034         torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
2035         if ((!W_ERROR_IS_OK(r.out.result)) &&
2036             (!W_ERROR_EQUAL(r.out.result, WERR_NO_SUCH_DOMAIN))) {
2037                 return false;
2038         }
2039
2040         return true;
2041 }
2042
2043
2044 /*
2045   try a netlogon LogonControl2
2046 */
2047 static bool test_LogonControl2(struct torture_context *tctx,
2048                                struct dcerpc_pipe *p,
2049                                struct cli_credentials *machine_credentials)
2050
2051 {
2052         NTSTATUS status;
2053         struct netr_LogonControl2 r;
2054         union netr_CONTROL_DATA_INFORMATION data;
2055         union netr_CONTROL_QUERY_INFORMATION query;
2056         int i;
2057         struct dcerpc_binding_handle *b = p->binding_handle;
2058
2059         data.domain = lpcfg_workgroup(tctx->lp_ctx);
2060
2061         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2062
2063         r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
2064         r.in.data = &data;
2065         r.out.query = &query;
2066
2067         for (i=1;i<4;i++) {
2068                 r.in.level = i;
2069
2070                 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
2071                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2072
2073                 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
2074                 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
2075         }
2076
2077         data.domain = lpcfg_workgroup(tctx->lp_ctx);
2078
2079         r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
2080         r.in.data = &data;
2081
2082         for (i=1;i<4;i++) {
2083                 r.in.level = i;
2084
2085                 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
2086                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2087
2088                 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
2089                 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
2090         }
2091
2092         data.domain = lpcfg_workgroup(tctx->lp_ctx);
2093
2094         r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
2095         r.in.data = &data;
2096
2097         for (i=1;i<4;i++) {
2098                 r.in.level = i;
2099
2100                 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
2101                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2102
2103                 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
2104                 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
2105         }
2106
2107         data.debug_level = ~0;
2108
2109         r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
2110         r.in.data = &data;
2111
2112         for (i=1;i<4;i++) {
2113                 r.in.level = i;
2114
2115                 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
2116                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2117
2118                 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
2119                 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
2120         }
2121
2122         ZERO_STRUCT(data);
2123         r.in.function_code = 52;
2124         r.in.data = &data;
2125
2126         torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
2127                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2128
2129         status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
2130         torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
2131         torture_assert_werr_equal(tctx, r.out.result, WERR_UNKNOWN_LEVEL, "LogonControl2");
2132
2133         data.debug_level = ~0;
2134
2135         r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
2136         r.in.data = &data;
2137
2138         r.in.level = 52;
2139         torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
2140                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2141
2142         status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
2143         torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
2144         torture_assert_werr_equal(tctx, r.out.result, WERR_UNKNOWN_LEVEL, "LogonControl2");
2145
2146         return true;
2147 }
2148
2149 /*
2150   try a netlogon DatabaseSync2
2151 */
2152 static bool test_DatabaseSync2(struct torture_context *tctx,
2153                                struct dcerpc_pipe *p,
2154                                struct cli_credentials *machine_credentials)
2155 {
2156         struct netr_DatabaseSync2 r;
2157         struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
2158         struct netr_Authenticator return_authenticator, credential;
2159
2160         struct netlogon_creds_CredentialState *creds;
2161         const uint32_t database_ids[] = {0, 1, 2};
2162         int i;
2163         struct dcerpc_binding_handle *b = p->binding_handle;
2164
2165         if (!test_SetupCredentials2(p, tctx, NETLOGON_NEG_AUTH2_FLAGS,
2166                                     machine_credentials,
2167                                     cli_credentials_get_secure_channel_type(machine_credentials),
2168                                     &creds)) {
2169                 return false;
2170         }
2171
2172         ZERO_STRUCT(return_authenticator);
2173
2174         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2175         r.in.computername = TEST_MACHINE_NAME;
2176         r.in.preferredmaximumlength = (uint32_t)-1;
2177         r.in.return_authenticator = &return_authenticator;
2178         r.out.return_authenticator = &return_authenticator;
2179         r.out.delta_enum_array = &delta_enum_array;
2180
2181         for (i=0;i<ARRAY_SIZE(database_ids);i++) {
2182
2183                 uint32_t sync_context = 0;
2184
2185                 r.in.database_id = database_ids[i];
2186                 r.in.sync_context = &sync_context;
2187                 r.out.sync_context = &sync_context;
2188                 r.in.restart_state = 0;
2189
2190                 torture_comment(tctx, "Testing DatabaseSync2 of id %d\n", r.in.database_id);
2191
2192                 do {
2193                         netlogon_creds_client_authenticator(creds, &credential);
2194
2195                         r.in.credential = &credential;
2196
2197                         torture_assert_ntstatus_ok(tctx, dcerpc_netr_DatabaseSync2_r(b, tctx, &r),
2198                                 "DatabaseSync2 failed");
2199                         if (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES))
2200                             break;
2201
2202                         /* Native mode servers don't do this */
2203                         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_SUPPORTED)) {
2204                                 return true;
2205                         }
2206
2207                         torture_assert_ntstatus_ok(tctx, r.out.result, "DatabaseSync2");
2208
2209                         if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
2210                                 torture_comment(tctx, "Credential chaining failed\n");
2211                         }
2212
2213                 } while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES));
2214         }
2215
2216         return true;
2217 }
2218
2219
2220 /*
2221   try a netlogon LogonControl2Ex
2222 */
2223 static bool test_LogonControl2Ex(struct torture_context *tctx,
2224                                  struct dcerpc_pipe *p,
2225                                  struct cli_credentials *machine_credentials)
2226
2227 {
2228         NTSTATUS status;
2229         struct netr_LogonControl2Ex r;
2230         union netr_CONTROL_DATA_INFORMATION data;
2231         union netr_CONTROL_QUERY_INFORMATION query;
2232         int i;
2233         struct dcerpc_binding_handle *b = p->binding_handle;
2234
2235         data.domain = lpcfg_workgroup(tctx->lp_ctx);
2236
2237         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2238
2239         r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
2240         r.in.data = &data;
2241         r.out.query = &query;
2242
2243         for (i=1;i<4;i++) {
2244                 r.in.level = i;
2245
2246                 torture_comment(tctx, "Testing LogonControl2Ex level %d function %d\n",
2247                        i, r.in.function_code);
2248
2249                 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
2250                 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
2251         }
2252
2253         data.domain = lpcfg_workgroup(tctx->lp_ctx);
2254
2255         r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
2256         r.in.data = &data;
2257
2258         for (i=1;i<4;i++) {
2259                 r.in.level = i;
2260
2261                 torture_comment(tctx, "Testing LogonControl2Ex level %d function %d\n",
2262                        i, r.in.function_code);
2263
2264                 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
2265                 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
2266         }
2267
2268         data.domain = lpcfg_workgroup(tctx->lp_ctx);
2269
2270         r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
2271         r.in.data = &data;
2272
2273         for (i=1;i<4;i++) {
2274                 r.in.level = i;
2275
2276                 torture_comment(tctx, "Testing LogonControl2Ex level %d function %d\n",
2277                        i, r.in.function_code);
2278
2279                 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
2280                 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
2281         }
2282
2283         data.debug_level = ~0;
2284
2285         r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
2286         r.in.data = &data;
2287
2288         for (i=1;i<4;i++) {
2289                 r.in.level = i;
2290
2291                 torture_comment(tctx, "Testing LogonControl2Ex level %d function %d\n",
2292                        i, r.in.function_code);
2293
2294                 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
2295                 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
2296         }
2297
2298         return true;
2299 }
2300
2301 static bool test_netr_GetForestTrustInformation(struct torture_context *tctx,
2302                                                 struct dcerpc_pipe *p,
2303                                                 struct cli_credentials *machine_credentials)
2304 {
2305         struct netr_GetForestTrustInformation r;
2306         struct netlogon_creds_CredentialState *creds;
2307         struct netr_Authenticator a;
2308         struct netr_Authenticator return_authenticator;
2309         struct lsa_ForestTrustInformation *forest_trust_info;
2310         struct dcerpc_binding_handle *b = p->binding_handle;
2311
2312         if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
2313                                     machine_credentials, &creds)) {
2314                 return false;
2315         }
2316
2317         netlogon_creds_client_authenticator(creds, &a);
2318
2319         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2320         r.in.computer_name = TEST_MACHINE_NAME;
2321         r.in.credential = &a;
2322         r.in.flags = 0;
2323         r.out.return_authenticator = &return_authenticator;
2324         r.out.forest_trust_info = &forest_trust_info;
2325
2326         torture_assert_ntstatus_ok(tctx,
2327                 dcerpc_netr_GetForestTrustInformation_r(b, tctx, &r),
2328                 "netr_GetForestTrustInformation failed");
2329         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_IMPLEMENTED)) {
2330                 torture_comment(tctx, "not considering NT_STATUS_NOT_IMPLEMENTED as an error\n");
2331         } else {
2332                 torture_assert_ntstatus_ok(tctx, r.out.result,
2333                         "netr_GetForestTrustInformation failed");
2334         }
2335
2336         torture_assert(tctx,
2337                 netlogon_creds_client_check(creds, &return_authenticator.cred),
2338                 "Credential chaining failed");
2339
2340         return true;
2341 }
2342
2343 static bool test_netr_DsRGetForestTrustInformation(struct torture_context *tctx,
2344                                                    struct dcerpc_pipe *p, const char *trusted_domain_name)
2345 {
2346         NTSTATUS status;
2347         struct netr_DsRGetForestTrustInformation r;
2348         struct lsa_ForestTrustInformation info, *info_ptr;
2349         struct dcerpc_binding_handle *b = p->binding_handle;
2350
2351         info_ptr = &info;
2352
2353         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2354         r.in.trusted_domain_name = trusted_domain_name;
2355         r.in.flags = 0;
2356         r.out.forest_trust_info = &info_ptr;
2357
2358         torture_comment(tctx ,"Testing netr_DsRGetForestTrustInformation\n");
2359
2360         status = dcerpc_netr_DsRGetForestTrustInformation_r(b, tctx, &r);
2361         torture_assert_ntstatus_ok(tctx, status, "DsRGetForestTrustInformation");
2362         torture_assert_werr_ok(tctx, r.out.result, "DsRGetForestTrustInformation");
2363
2364         return true;
2365 }
2366
2367 /*
2368   try a netlogon netr_DsrEnumerateDomainTrusts
2369 */
2370 static bool test_DsrEnumerateDomainTrusts(struct torture_context *tctx,
2371                                           struct dcerpc_pipe *p)
2372 {
2373         NTSTATUS status;
2374         struct netr_DsrEnumerateDomainTrusts r;
2375         struct netr_DomainTrustList trusts;
2376         int i;
2377         struct dcerpc_binding_handle *b = p->binding_handle;
2378
2379         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2380         r.in.trust_flags = 0x3f;
2381         r.out.trusts = &trusts;
2382
2383         status = dcerpc_netr_DsrEnumerateDomainTrusts_r(b, tctx, &r);
2384         torture_assert_ntstatus_ok(tctx, status, "DsrEnumerateDomaintrusts");
2385         torture_assert_werr_ok(tctx, r.out.result, "DsrEnumerateDomaintrusts");
2386
2387         /* when trusted_domain_name is NULL, netr_DsRGetForestTrustInformation
2388          * will show non-forest trusts and all UPN suffixes of the own forest
2389          * as LSA_FOREST_TRUST_TOP_LEVEL_NAME types */
2390
2391         if (r.out.trusts->count) {
2392                 if (!test_netr_DsRGetForestTrustInformation(tctx, p, NULL)) {
2393                         return false;
2394                 }
2395         }
2396
2397         for (i=0; i<r.out.trusts->count; i++) {
2398
2399                 /* get info for transitive forest trusts */
2400
2401                 if (r.out.trusts->array[i].trust_attributes & NETR_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) {
2402                         if (!test_netr_DsRGetForestTrustInformation(tctx, p,
2403                                                                     r.out.trusts->array[i].dns_name)) {
2404                                 return false;
2405                         }
2406                 }
2407         }
2408
2409         return true;
2410 }
2411
2412 static bool test_netr_NetrEnumerateTrustedDomains(struct torture_context *tctx,
2413                                                   struct dcerpc_pipe *p)
2414 {
2415         NTSTATUS status;
2416         struct netr_NetrEnumerateTrustedDomains r;
2417         struct netr_Blob trusted_domains_blob;
2418         struct dcerpc_binding_handle *b = p->binding_handle;
2419
2420         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2421         r.out.trusted_domains_blob = &trusted_domains_blob;
2422
2423         status = dcerpc_netr_NetrEnumerateTrustedDomains_r(b, tctx, &r);
2424         torture_assert_ntstatus_ok(tctx, status, "netr_NetrEnumerateTrustedDomains");
2425         torture_assert_ntstatus_ok(tctx, r.out.result, "NetrEnumerateTrustedDomains");
2426
2427         return true;
2428 }
2429
2430 static bool test_netr_NetrEnumerateTrustedDomainsEx(struct torture_context *tctx,
2431                                                     struct dcerpc_pipe *p)
2432 {
2433         NTSTATUS status;
2434         struct netr_NetrEnumerateTrustedDomainsEx r;
2435         struct netr_DomainTrustList dom_trust_list;
2436         struct dcerpc_binding_handle *b = p->binding_handle;
2437
2438         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2439         r.out.dom_trust_list = &dom_trust_list;
2440
2441         status = dcerpc_netr_NetrEnumerateTrustedDomainsEx_r(b, tctx, &r);
2442         torture_assert_ntstatus_ok(tctx, status, "netr_NetrEnumerateTrustedDomainsEx");
2443         torture_assert_werr_ok(tctx, r.out.result, "NetrEnumerateTrustedDomainsEx");
2444
2445         return true;
2446 }
2447
2448
2449 static bool test_netr_DsRGetSiteName(struct dcerpc_pipe *p, struct torture_context *tctx,
2450                                      const char *computer_name,
2451                                      const char *expected_site)
2452 {
2453         NTSTATUS status;
2454         struct netr_DsRGetSiteName r;
2455         const char *site = NULL;
2456         struct dcerpc_binding_handle *b = p->binding_handle;
2457
2458         r.in.computer_name              = computer_name;
2459         r.out.site                      = &site;
2460         torture_comment(tctx, "Testing netr_DsRGetSiteName\n");
2461
2462         status = dcerpc_netr_DsRGetSiteName_r(b, tctx, &r);
2463         torture_assert_ntstatus_ok(tctx, status, "DsRGetSiteName");
2464         torture_assert_werr_ok(tctx, r.out.result, "DsRGetSiteName");
2465         torture_assert_str_equal(tctx, expected_site, site, "netr_DsRGetSiteName");
2466
2467         return true;
2468 }
2469
2470 /*
2471   try a netlogon netr_DsRGetDCName
2472 */
2473 static bool test_netr_DsRGetDCName(struct torture_context *tctx,
2474                                    struct dcerpc_pipe *p)
2475 {
2476         NTSTATUS status;
2477         struct netr_DsRGetDCName r;
2478         struct netr_DsRGetDCNameInfo *info = NULL;
2479         struct dcerpc_binding_handle *b = p->binding_handle;
2480
2481         r.in.server_unc         = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2482         r.in.domain_name        = lpcfg_dnsdomain(tctx->lp_ctx);
2483         r.in.domain_guid        = NULL;
2484         r.in.site_guid          = NULL;
2485         r.in.flags              = DS_RETURN_DNS_NAME;
2486         r.out.info              = &info;
2487
2488         status = dcerpc_netr_DsRGetDCName_r(b, tctx, &r);
2489         torture_assert_ntstatus_ok(tctx, status, "DsRGetDCName");
2490         torture_assert_werr_ok(tctx, r.out.result, "DsRGetDCName");
2491
2492         torture_assert_int_equal(tctx,
2493                                  (info->dc_flags & (DS_DNS_CONTROLLER)),
2494                                  DS_DNS_CONTROLLER,
2495                                  "DsRGetDCName");
2496         torture_assert_int_equal(tctx,
2497                                  (info->dc_flags & (DS_DNS_DOMAIN)),
2498                                  DS_DNS_DOMAIN,
2499                                  "DsRGetDCName");
2500         torture_assert_int_equal(tctx,
2501                                  (info->dc_flags & (DS_DNS_FOREST_ROOT)),
2502                                  DS_DNS_FOREST_ROOT,
2503                                  "DsRGetDCName");
2504
2505         r.in.domain_name        = lpcfg_workgroup(tctx->lp_ctx);
2506         r.in.flags              = 0;
2507
2508         status = dcerpc_netr_DsRGetDCName_r(b, tctx, &r);
2509         torture_assert_ntstatus_ok(tctx, status, "DsRGetDCName");
2510         torture_assert_werr_ok(tctx, r.out.result, "DsRGetDCName");
2511
2512         torture_assert_int_equal(tctx,
2513                                  (info->dc_flags & (DS_DNS_CONTROLLER)), 0,
2514                                  "DsRGetDCName");
2515         torture_assert_int_equal(tctx,
2516                                  (info->dc_flags & (DS_DNS_DOMAIN)), 0,
2517                                  "DsRGetDCName");
2518         torture_assert_int_equal(tctx,
2519                                  (info->dc_flags & (DS_DNS_FOREST_ROOT)),
2520                                  DS_DNS_FOREST_ROOT,
2521                                  "DsRGetDCName");
2522
2523         if (strcasecmp(info->dc_site_name, info->client_site_name) == 0) {
2524                 torture_assert_int_equal(tctx,
2525                                          (info->dc_flags & (DS_SERVER_CLOSEST)),
2526                                          DS_SERVER_CLOSEST,
2527                                          "DsRGetDCName");
2528         }
2529
2530         return test_netr_DsRGetSiteName(p, tctx,
2531                                        info->dc_unc,
2532                                        info->dc_site_name);
2533 }
2534
2535 /*
2536   try a netlogon netr_DsRGetDCNameEx
2537 */
2538 static bool test_netr_DsRGetDCNameEx(struct torture_context *tctx,
2539                                      struct dcerpc_pipe *p)
2540 {
2541         NTSTATUS status;
2542         struct netr_DsRGetDCNameEx r;
2543         struct netr_DsRGetDCNameInfo *info = NULL;
2544         struct dcerpc_binding_handle *b = p->binding_handle;
2545
2546         r.in.server_unc         = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2547         r.in.domain_name        = lpcfg_dnsdomain(tctx->lp_ctx);
2548         r.in.domain_guid        = NULL;
2549         r.in.site_name          = NULL;
2550         r.in.flags              = DS_RETURN_DNS_NAME;
2551         r.out.info              = &info;
2552
2553         status = dcerpc_netr_DsRGetDCNameEx_r(b, tctx, &r);
2554         torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx");
2555         torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx");
2556
2557         torture_assert_int_equal(tctx,
2558                                  (info->dc_flags & (DS_DNS_CONTROLLER)),
2559                                  DS_DNS_CONTROLLER,
2560                                  "DsRGetDCNameEx");
2561         torture_assert_int_equal(tctx,
2562                                  (info->dc_flags & (DS_DNS_DOMAIN)),
2563                                  DS_DNS_DOMAIN,
2564                                  "DsRGetDCNameEx");
2565         torture_assert_int_equal(tctx,
2566                                  (info->dc_flags & (DS_DNS_FOREST_ROOT)),
2567                                  DS_DNS_FOREST_ROOT,
2568                                  "DsRGetDCNameEx");
2569
2570         r.in.domain_name        = lpcfg_workgroup(tctx->lp_ctx);
2571         r.in.flags              = 0;
2572
2573         status = dcerpc_netr_DsRGetDCNameEx_r(b, tctx, &r);
2574         torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx");
2575         torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx");
2576
2577         torture_assert_int_equal(tctx,
2578                                  (info->dc_flags & (DS_DNS_CONTROLLER)), 0,
2579                                  "DsRGetDCNameEx");
2580         torture_assert_int_equal(tctx,
2581                                  (info->dc_flags & (DS_DNS_DOMAIN)), 0,
2582                                  "DsRGetDCNameEx");
2583         torture_assert_int_equal(tctx,
2584                                  (info->dc_flags & (DS_DNS_FOREST_ROOT)),
2585                                  DS_DNS_FOREST_ROOT,
2586                                  "DsRGetDCNameEx");
2587
2588         if (strcasecmp(info->dc_site_name, info->client_site_name) == 0) {
2589                 torture_assert_int_equal(tctx,
2590                                          (info->dc_flags & (DS_SERVER_CLOSEST)),
2591                                          DS_SERVER_CLOSEST,
2592                                          "DsRGetDCNameEx");
2593         }
2594
2595         return test_netr_DsRGetSiteName(p, tctx, info->dc_unc,
2596                                         info->dc_site_name);
2597 }
2598
2599 /*
2600   try a netlogon netr_DsRGetDCNameEx2
2601 */
2602 static bool test_netr_DsRGetDCNameEx2(struct torture_context *tctx,
2603                                       struct dcerpc_pipe *p)
2604 {
2605         NTSTATUS status;
2606         struct netr_DsRGetDCNameEx2 r;
2607         struct netr_DsRGetDCNameInfo *info = NULL;
2608         struct dcerpc_binding_handle *b = p->binding_handle;
2609
2610         torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 with no inputs\n");
2611         ZERO_STRUCT(r.in);
2612         r.in.flags              = DS_RETURN_DNS_NAME;
2613         r.out.info              = &info;
2614
2615         status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
2616         torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
2617         torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
2618
2619         torture_assert_int_equal(tctx,
2620                                  (info->dc_flags & (DS_DNS_CONTROLLER)),
2621                                  DS_DNS_CONTROLLER,
2622                                  "DsRGetDCNameEx2");
2623         torture_assert_int_equal(tctx,
2624                                  (info->dc_flags & (DS_DNS_DOMAIN)),
2625                                  DS_DNS_DOMAIN,
2626                                  "DsRGetDCNameEx2");
2627         torture_assert_int_equal(tctx,
2628                                  (info->dc_flags & (DS_DNS_FOREST_ROOT)),
2629                                  DS_DNS_FOREST_ROOT,
2630                                  "DsRGetDCNameEx2");
2631
2632         r.in.server_unc         = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2633         r.in.client_account     = NULL;
2634         r.in.mask               = 0x00000000;
2635         r.in.domain_name        = lpcfg_dnsdomain(tctx->lp_ctx);
2636         r.in.domain_guid        = NULL;
2637         r.in.site_name          = NULL;
2638         r.in.flags              = DS_RETURN_DNS_NAME;
2639         r.out.info              = &info;
2640
2641         torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 without client account\n");
2642
2643         status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
2644         torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
2645         torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
2646
2647         r.in.domain_name        = lpcfg_workgroup(tctx->lp_ctx);
2648         r.in.flags              = 0;
2649
2650         status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
2651         torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
2652         torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
2653
2654         torture_assert_int_equal(tctx,
2655                                  (info->dc_flags & (DS_DNS_CONTROLLER)), 0,
2656                                  "DsRGetDCNameEx2");
2657         torture_assert_int_equal(tctx,
2658                                  (info->dc_flags & (DS_DNS_DOMAIN)), 0,
2659                                  "DsRGetDCNameEx2");
2660         torture_assert_int_equal(tctx,
2661                                  (info->dc_flags & (DS_DNS_FOREST_ROOT)),
2662                                  DS_DNS_FOREST_ROOT,
2663                                  "DsRGetDCNameEx2");
2664
2665         if (strcasecmp(info->dc_site_name, info->client_site_name) == 0) {
2666                 torture_assert_int_equal(tctx,
2667                                          (info->dc_flags & (DS_SERVER_CLOSEST)),
2668                                          DS_SERVER_CLOSEST,
2669                                          "DsRGetDCNameEx2");
2670         }
2671
2672         torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 with client account\n");
2673         r.in.client_account     = TEST_MACHINE_NAME"$";
2674         r.in.mask               = ACB_SVRTRUST;
2675         r.in.flags              = DS_RETURN_FLAT_NAME;
2676         r.out.info              = &info;
2677
2678         status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
2679         torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
2680         torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
2681
2682         return test_netr_DsRGetSiteName(p, tctx, info->dc_unc,
2683                                         info->dc_site_name);
2684 }
2685
2686 /* This is a substitution for "samdb_server_site_name" which relies on the
2687  * correct "lp_ctx" and therefore can't be used here. */
2688 static const char *server_site_name(struct torture_context *tctx,
2689                                     struct ldb_context *ldb)
2690 {
2691         TALLOC_CTX *tmp_ctx;
2692         struct ldb_dn *dn, *server_dn;
2693         const struct ldb_val *site_name_val;
2694         const char *server_dn_str, *site_name;
2695
2696         tmp_ctx = talloc_new(ldb);
2697         if (tmp_ctx == NULL) {
2698                 goto failed;
2699         }
2700
2701         dn = ldb_dn_new(tmp_ctx, ldb, "");
2702         if (dn == NULL) {
2703                 goto failed;
2704         }
2705
2706         server_dn_str = samdb_search_string(ldb, tmp_ctx, dn, "serverName",
2707                                             NULL);
2708         if (server_dn_str == NULL) {
2709                 goto failed;
2710         }
2711
2712         server_dn = ldb_dn_new(tmp_ctx, ldb, server_dn_str);
2713         if (server_dn == NULL) {
2714                 goto failed;
2715         }
2716
2717         /* CN=<Server name>, CN=Servers, CN=<Site name>, CN=Sites, ... */
2718         site_name_val = ldb_dn_get_component_val(server_dn, 2);
2719         if (site_name_val == NULL) {
2720                 goto failed;
2721         }
2722
2723         site_name = (const char *) site_name_val->data;
2724
2725         talloc_steal(tctx, site_name);
2726         talloc_free(tmp_ctx);
2727
2728         return site_name;
2729
2730 failed:
2731         talloc_free(tmp_ctx);
2732         return NULL;
2733 }
2734
2735 static bool test_netr_DsrGetDcSiteCoverageW(struct torture_context *tctx,
2736                                             struct dcerpc_pipe *p)
2737 {
2738         char *url;
2739         struct ldb_context *sam_ctx = NULL;
2740         NTSTATUS status;
2741         struct netr_DsrGetDcSiteCoverageW r;
2742         struct DcSitesCtr *ctr = NULL;
2743         struct dcerpc_binding_handle *b = p->binding_handle;
2744
2745         torture_comment(tctx, "This does only pass with the default site\n");
2746
2747         /* We won't double-check this when we are over 'local' transports */
2748         if (dcerpc_server_name(p)) {
2749                 /* Set up connection to SAMDB on DC */
2750                 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
2751                 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
2752                                            NULL,
2753                                            cmdline_credentials,
2754                                            0);
2755
2756                 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
2757         }
2758
2759         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2760         r.out.ctr = &ctr;
2761
2762         status = dcerpc_netr_DsrGetDcSiteCoverageW_r(b, tctx, &r);
2763         torture_assert_ntstatus_ok(tctx, status, "failed");
2764         torture_assert_werr_ok(tctx, r.out.result, "failed");
2765
2766         torture_assert(tctx, ctr->num_sites == 1,
2767                        "we should per default only get the default site");
2768         if (sam_ctx != NULL) {
2769                 torture_assert_casestr_equal(tctx, ctr->sites[0].string,
2770                                              server_site_name(tctx, sam_ctx),
2771                                              "didn't return default site");
2772         }
2773
2774         return true;
2775 }
2776
2777 static bool test_netr_DsRAddressToSitenamesW(struct torture_context *tctx,
2778                                              struct dcerpc_pipe *p)
2779 {
2780         char *url;
2781         struct ldb_context *sam_ctx = NULL;
2782         NTSTATUS status;
2783         struct netr_DsRAddressToSitenamesW r;
2784         struct netr_DsRAddress addrs[6];
2785         struct sockaddr_in *addr;
2786 #ifdef HAVE_IPV6
2787         struct sockaddr_in6 *addr6;
2788 #endif
2789         struct netr_DsRAddressToSitenamesWCtr *ctr;
2790         struct dcerpc_binding_handle *b = p->binding_handle;
2791         uint32_t i;
2792         int ret;
2793
2794         torture_comment(tctx, "This does only pass with the default site\n");
2795
2796         /* We won't double-check this when we are over 'local' transports */
2797         if (dcerpc_server_name(p)) {
2798                 /* Set up connection to SAMDB on DC */
2799                 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
2800                 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
2801                                            NULL,
2802                                            cmdline_credentials,
2803                                            0);
2804
2805                 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
2806         }
2807
2808         /* First try valid IP addresses */
2809
2810         addrs[0].size = sizeof(struct sockaddr_in);
2811         addrs[0].buffer = talloc_zero_array(tctx, uint8_t, addrs[0].size);
2812         addr = (struct sockaddr_in *) addrs[0].buffer;
2813         addrs[0].buffer[0] = AF_INET;
2814         ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
2815         torture_assert(tctx, ret > 0, "inet_pton failed");
2816
2817         addrs[1].size = sizeof(struct sockaddr_in);
2818         addrs[1].buffer = talloc_zero_array(tctx, uint8_t, addrs[1].size);
2819         addr = (struct sockaddr_in *) addrs[1].buffer;
2820         addrs[1].buffer[0] = AF_INET;
2821         ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
2822         torture_assert(tctx, ret > 0, "inet_pton failed");
2823
2824         addrs[2].size = sizeof(struct sockaddr_in);
2825         addrs[2].buffer = talloc_zero_array(tctx, uint8_t, addrs[2].size);
2826         addr = (struct sockaddr_in *) addrs[2].buffer;
2827         addrs[2].buffer[0] = AF_INET;
2828         ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
2829         torture_assert(tctx, ret > 0, "inet_pton failed");
2830
2831 #ifdef HAVE_IPV6
2832         addrs[3].size = sizeof(struct sockaddr_in6);
2833         addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
2834         addr6 = (struct sockaddr_in6 *) addrs[3].buffer;
2835         addrs[3].buffer[0] = AF_INET6;
2836         ret = inet_pton(AF_INET6, "::1", &addr6->sin6_addr);
2837         torture_assert(tctx, ret > 0, "inet_pton failed");
2838
2839         addrs[4].size = sizeof(struct sockaddr_in6);
2840         addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
2841         addr6 = (struct sockaddr_in6 *) addrs[4].buffer;
2842         addrs[4].buffer[0] = AF_INET6;
2843         ret = inet_pton(AF_INET6, "::", &addr6->sin6_addr);
2844         torture_assert(tctx, ret > 0, "inet_pton failed");
2845
2846         addrs[5].size = sizeof(struct sockaddr_in6);
2847         addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
2848         addr6 = (struct sockaddr_in6 *) addrs[5].buffer;
2849         addrs[5].buffer[0] = AF_INET6;
2850         ret = inet_pton(AF_INET6, "ff02::1", &addr6->sin6_addr);
2851         torture_assert(tctx, ret > 0, "inet_pton failed");
2852 #else
2853         /* the test cases are repeated to have exactly 6. This is for
2854          * compatibility with IPv4-only machines */
2855         addrs[3].size = sizeof(struct sockaddr_in);
2856         addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
2857         addr = (struct sockaddr_in *) addrs[3].buffer;
2858         addrs[3].buffer[0] = AF_INET;
2859         ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
2860         torture_assert(tctx, ret > 0, "inet_pton failed");
2861
2862         addrs[4].size = sizeof(struct sockaddr_in);
2863         addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
2864         addr = (struct sockaddr_in *) addrs[4].buffer;
2865         addrs[4].buffer[0] = AF_INET;
2866         ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
2867         torture_assert(tctx, ret > 0, "inet_pton failed");
2868
2869         addrs[5].size = sizeof(struct sockaddr_in);
2870         addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
2871         addr = (struct sockaddr_in *) addrs[5].buffer;
2872         addrs[5].buffer[0] = AF_INET;
2873         ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
2874         torture_assert(tctx, ret > 0, "inet_pton failed");
2875 #endif
2876
2877         ctr = talloc(tctx, struct netr_DsRAddressToSitenamesWCtr);
2878
2879         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2880         r.in.count = 6;
2881         r.in.addresses = addrs;
2882         r.out.ctr = &ctr;
2883
2884         status = dcerpc_netr_DsRAddressToSitenamesW_r(b, tctx, &r);
2885         torture_assert_ntstatus_ok(tctx, status, "failed");
2886         torture_assert_werr_ok(tctx, r.out.result, "failed");
2887
2888         if (sam_ctx != NULL) {
2889                 for (i = 0; i < 3; i++) {
2890                         torture_assert_casestr_equal(tctx,
2891                                                      ctr->sitename[i].string,
2892                                                      server_site_name(tctx, sam_ctx),
2893                                                      "didn't return default site");
2894                 }
2895                 for (i = 3; i < 6; i++) {
2896                         /* Windows returns "NULL" for the sitename if it isn't
2897                          * IPv6 configured */
2898                         if (torture_setting_bool(tctx, "samba4", false)) {
2899                                 torture_assert_casestr_equal(tctx,
2900                                                              ctr->sitename[i].string,
2901                                                              server_site_name(tctx, sam_ctx),
2902                                                              "didn't return default site");
2903                         }
2904                 }
2905         }
2906
2907         /* Now try invalid ones (too short buffers) */
2908
2909         addrs[0].size = 0;
2910         addrs[1].size = 1;
2911         addrs[2].size = 4;
2912
2913         addrs[3].size = 0;
2914         addrs[4].size = 1;
2915         addrs[5].size = 4;
2916
2917         status = dcerpc_netr_DsRAddressToSitenamesW_r(b, tctx, &r);
2918         torture_assert_ntstatus_ok(tctx, status, "failed");
2919         torture_assert_werr_ok(tctx, r.out.result, "failed");
2920
2921         for (i = 0; i < 6; i++) {
2922                 torture_assert(tctx, ctr->sitename[i].string == NULL,
2923                                "sitename should be null");
2924         }
2925
2926         /* Now try invalid ones (wrong address types) */
2927
2928         addrs[0].size = 10;
2929         addrs[0].buffer[0] = AF_UNSPEC;
2930         addrs[1].size = 10;
2931         addrs[1].buffer[0] = AF_UNIX; /* AF_LOCAL = AF_UNIX */
2932         addrs[2].size = 10;
2933         addrs[2].buffer[0] = AF_UNIX;
2934
2935         addrs[3].size = 10;
2936         addrs[3].buffer[0] = 250;
2937         addrs[4].size = 10;
2938         addrs[4].buffer[0] = 251;
2939         addrs[5].size = 10;
2940         addrs[5].buffer[0] = 252;
2941
2942         status = dcerpc_netr_DsRAddressToSitenamesW_r(b, tctx, &r);
2943         torture_assert_ntstatus_ok(tctx, status, "failed");
2944         torture_assert_werr_ok(tctx, r.out.result, "failed");
2945
2946         for (i = 0; i < 6; i++) {
2947                 torture_assert(tctx, ctr->sitename[i].string == NULL,
2948                                "sitename should be null");
2949         }
2950
2951         return true;
2952 }
2953
2954 static bool test_netr_DsRAddressToSitenamesExW(struct torture_context *tctx,
2955                                                struct dcerpc_pipe *p)
2956 {
2957         char *url;
2958         struct ldb_context *sam_ctx = NULL;
2959         NTSTATUS status;
2960         struct netr_DsRAddressToSitenamesExW r;
2961         struct netr_DsRAddress addrs[6];
2962         struct sockaddr_in *addr;
2963 #ifdef HAVE_IPV6
2964         struct sockaddr_in6 *addr6;
2965 #endif
2966         struct netr_DsRAddressToSitenamesExWCtr *ctr;
2967         struct dcerpc_binding_handle *b = p->binding_handle;
2968         uint32_t i;
2969         int ret;
2970
2971         torture_comment(tctx, "This does pass with the default site\n");
2972
2973         /* We won't double-check this when we are over 'local' transports */
2974         if (dcerpc_server_name(p)) {
2975                 /* Set up connection to SAMDB on DC */
2976                 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
2977                 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
2978                                            NULL,
2979                                            cmdline_credentials,
2980                                            0);
2981
2982                 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
2983         }
2984
2985         /* First try valid IP addresses */
2986
2987         addrs[0].size = sizeof(struct sockaddr_in);
2988         addrs[0].buffer = talloc_zero_array(tctx, uint8_t, addrs[0].size);
2989         addr = (struct sockaddr_in *) addrs[0].buffer;
2990         addrs[0].buffer[0] = AF_INET;
2991         ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
2992         torture_assert(tctx, ret > 0, "inet_pton failed");
2993
2994         addrs[1].size = sizeof(struct sockaddr_in);
2995         addrs[1].buffer = talloc_zero_array(tctx, uint8_t, addrs[1].size);
2996         addr = (struct sockaddr_in *) addrs[1].buffer;
2997         addrs[1].buffer[0] = AF_INET;
2998         ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
2999         torture_assert(tctx, ret > 0, "inet_pton failed");
3000
3001         addrs[2].size = sizeof(struct sockaddr_in);
3002         addrs[2].buffer = talloc_zero_array(tctx, uint8_t, addrs[2].size);
3003         addr = (struct sockaddr_in *) addrs[2].buffer;
3004         addrs[2].buffer[0] = AF_INET;
3005         ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
3006         torture_assert(tctx, ret > 0, "inet_pton failed");
3007
3008 #ifdef HAVE_IPV6
3009         addrs[3].size = sizeof(struct sockaddr_in6);
3010         addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
3011         addr6 = (struct sockaddr_in6 *) addrs[3].buffer;
3012         addrs[3].buffer[0] = AF_INET6;
3013         ret = inet_pton(AF_INET6, "::1", &addr6->sin6_addr);
3014         torture_assert(tctx, ret > 0, "inet_pton failed");
3015
3016         addrs[4].size = sizeof(struct sockaddr_in6);
3017         addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
3018         addr6 = (struct sockaddr_in6 *) addrs[4].buffer;
3019         addrs[4].buffer[0] = AF_INET6;
3020         ret = inet_pton(AF_INET6, "::", &addr6->sin6_addr);
3021         torture_assert(tctx, ret > 0, "inet_pton failed");
3022
3023         addrs[5].size = sizeof(struct sockaddr_in6);
3024         addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
3025         addr6 = (struct sockaddr_in6 *) addrs[5].buffer;
3026         addrs[5].buffer[0] = AF_INET6;
3027         ret = inet_pton(AF_INET6, "ff02::1", &addr6->sin6_addr);
3028         torture_assert(tctx, ret > 0, "inet_pton failed");
3029 #else
3030         /* the test cases are repeated to have exactly 6. This is for
3031          * compatibility with IPv4-only machines */
3032         addrs[3].size = sizeof(struct sockaddr_in);
3033         addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
3034         addr = (struct sockaddr_in *) addrs[3].buffer;
3035         addrs[3].buffer[0] = AF_INET;
3036         ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
3037         torture_assert(tctx, ret > 0, "inet_pton failed");
3038
3039         addrs[4].size = sizeof(struct sockaddr_in);
3040         addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
3041         addr = (struct sockaddr_in *) addrs[4].buffer;
3042         addrs[4].buffer[0] = AF_INET;
3043         ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
3044         torture_assert(tctx, ret > 0, "inet_pton failed");
3045
3046         addrs[5].size = sizeof(struct sockaddr_in);
3047         addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
3048         addr = (struct sockaddr_in *) addrs[5].buffer;
3049         addrs[5].buffer[0] = AF_INET;
3050         ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
3051         torture_assert(tctx, ret > 0, "inet_pton failed");
3052 #endif
3053
3054         ctr = talloc(tctx, struct netr_DsRAddressToSitenamesExWCtr);
3055
3056         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3057         r.in.count = 6;
3058         r.in.addresses = addrs;
3059         r.out.ctr = &ctr;
3060
3061         status = dcerpc_netr_DsRAddressToSitenamesExW_r(b, tctx, &r);
3062         torture_assert_ntstatus_ok(tctx, status, "failed");
3063         torture_assert_werr_ok(tctx, r.out.result, "failed");
3064
3065         if (sam_ctx != NULL) {
3066                 for (i = 0; i < 3; i++) {
3067                         torture_assert_casestr_equal(tctx,
3068                                                      ctr->sitename[i].string,
3069                                                      server_site_name(tctx, sam_ctx),
3070                                                      "didn't return default site");
3071                         torture_assert(tctx, ctr->subnetname[i].string == NULL,
3072                                        "subnet should be null");
3073                 }
3074                 for (i = 3; i < 6; i++) {
3075                         /* Windows returns "NULL" for the sitename if it isn't
3076                          * IPv6 configured */
3077                         if (torture_setting_bool(tctx, "samba4", false)) {
3078                                 torture_assert_casestr_equal(tctx,
3079                                                              ctr->sitename[i].string,
3080                                                              server_site_name(tctx, sam_ctx),
3081                                                              "didn't return default site");
3082                         }
3083                         torture_assert(tctx, ctr->subnetname[i].string == NULL,
3084                                        "subnet should be null");
3085                 }
3086         }
3087
3088         /* Now try invalid ones (too short buffers) */
3089
3090         addrs[0].size = 0;
3091         addrs[1].size = 1;
3092         addrs[2].size = 4;
3093
3094         addrs[3].size = 0;
3095         addrs[4].size = 1;
3096         addrs[5].size = 4;
3097
3098         status = dcerpc_netr_DsRAddressToSitenamesExW_r(b, tctx, &r);
3099         torture_assert_ntstatus_ok(tctx, status, "failed");
3100         torture_assert_werr_ok(tctx, r.out.result, "failed");
3101
3102         for (i = 0; i < 6; i++) {
3103                 torture_assert(tctx, ctr->sitename[i].string == NULL,
3104                                "sitename should be null");
3105                 torture_assert(tctx, ctr->subnetname[i].string == NULL,
3106                                "subnet should be null");
3107         }
3108
3109         addrs[0].size = 10;
3110         addrs[0].buffer[0] = AF_UNSPEC;
3111         addrs[1].size = 10;
3112         addrs[1].buffer[0] = AF_UNIX; /* AF_LOCAL = AF_UNIX */
3113         addrs[2].size = 10;
3114         addrs[2].buffer[0] = AF_UNIX;
3115
3116         addrs[3].size = 10;
3117         addrs[3].buffer[0] = 250;
3118         addrs[4].size = 10;
3119         addrs[4].buffer[0] = 251;
3120         addrs[5].size = 10;
3121         addrs[5].buffer[0] = 252;
3122
3123         status = dcerpc_netr_DsRAddressToSitenamesExW_r(b, tctx, &r);
3124         torture_assert_ntstatus_ok(tctx, status, "failed");
3125         torture_assert_werr_ok(tctx, r.out.result, "failed");
3126
3127         for (i = 0; i < 6; i++) {
3128                 torture_assert(tctx, ctr->sitename[i].string == NULL,
3129                                "sitename should be null");
3130                 torture_assert(tctx, ctr->subnetname[i].string == NULL,
3131                                "subnet should be null");
3132         }
3133
3134         return true;
3135 }
3136
3137 static bool test_netr_ServerGetTrustInfo(struct torture_context *tctx,
3138                                          struct dcerpc_pipe *p,
3139                                          struct cli_credentials *machine_credentials)
3140 {
3141         struct netr_ServerGetTrustInfo r;
3142
3143         struct netr_Authenticator a;
3144         struct netr_Authenticator return_authenticator;
3145         struct samr_Password new_owf_password;
3146         struct samr_Password old_owf_password;
3147         struct netr_TrustInfo *trust_info;
3148
3149         struct netlogon_creds_CredentialState *creds;
3150         struct dcerpc_binding_handle *b = p->binding_handle;
3151
3152         if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
3153                                     machine_credentials, &creds)) {
3154                 return false;
3155         }
3156
3157         netlogon_creds_client_authenticator(creds, &a);
3158
3159         r.in.server_name                = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3160         r.in.account_name               = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
3161         r.in.secure_channel_type        = cli_credentials_get_secure_channel_type(machine_credentials);
3162         r.in.computer_name              = TEST_MACHINE_NAME;
3163         r.in.credential                 = &a;
3164
3165         r.out.return_authenticator      = &return_authenticator;
3166         r.out.new_owf_password          = &new_owf_password;
3167         r.out.old_owf_password          = &old_owf_password;
3168         r.out.trust_info                = &trust_info;
3169
3170         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerGetTrustInfo_r(b, tctx, &r),
3171                 "ServerGetTrustInfo failed");
3172         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerGetTrustInfo failed");
3173         torture_assert(tctx, netlogon_creds_client_check(creds, &return_authenticator.cred), "Credential chaining failed");
3174
3175         return true;
3176 }
3177
3178
3179 static bool test_GetDomainInfo(struct torture_context *tctx,
3180                                struct dcerpc_pipe *p,
3181                                struct cli_credentials *machine_credentials)
3182 {
3183         struct netr_LogonGetDomainInfo r;
3184         struct netr_WorkstationInformation q1;
3185         struct netr_Authenticator a;
3186         struct netlogon_creds_CredentialState *creds;
3187         struct netr_OsVersion os;
3188         union netr_WorkstationInfo query;
3189         union netr_DomainInfo info;
3190         const char* const attrs[] = { "dNSHostName", "operatingSystem",
3191                 "operatingSystemServicePack", "operatingSystemVersion",
3192                 "servicePrincipalName", NULL };
3193         char *url;
3194         struct ldb_context *sam_ctx = NULL;
3195         struct ldb_message **res;
3196         struct ldb_message_element *spn_el;
3197         int ret, i;
3198         char *version_str;
3199         const char *old_dnsname = NULL;
3200         char **spns = NULL;
3201         int num_spns = 0;
3202         char *temp_str;
3203         struct dcerpc_binding_handle *b = p->binding_handle;
3204
3205         torture_comment(tctx, "Testing netr_LogonGetDomainInfo\n");
3206
3207         if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
3208                                     machine_credentials, &creds)) {
3209                 return false;
3210         }
3211
3212         /* We won't double-check this when we are over 'local' transports */
3213         if (dcerpc_server_name(p)) {
3214                 /* Set up connection to SAMDB on DC */
3215                 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
3216                 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
3217                                            NULL,
3218                                            cmdline_credentials,
3219                                            0);
3220
3221                 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
3222         }
3223
3224         torture_comment(tctx, "Testing netr_LogonGetDomainInfo 1st call (no variation of DNS hostname)\n");
3225         netlogon_creds_client_authenticator(creds, &a);
3226
3227         ZERO_STRUCT(r);
3228         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3229         r.in.computer_name = TEST_MACHINE_NAME;
3230         r.in.credential = &a;
3231         r.in.level = 1;
3232         r.in.return_authenticator = &a;
3233         r.in.query = &query;
3234         r.out.return_authenticator = &a;
3235         r.out.info = &info;
3236
3237         ZERO_STRUCT(os);
3238         os.os.MajorVersion = 123;
3239         os.os.MinorVersion = 456;
3240         os.os.BuildNumber = 789;
3241         os.os.CSDVersion = "Service Pack 10";
3242         os.os.ServicePackMajor = 10;
3243         os.os.ServicePackMinor = 1;
3244         os.os.SuiteMask = NETR_VER_SUITE_SINGLEUSERTS;
3245         os.os.ProductType = NETR_VER_NT_SERVER;
3246         os.os.Reserved = 0;
3247
3248         version_str = talloc_asprintf(tctx, "%d.%d (%d)", os.os.MajorVersion,
3249                 os.os.MinorVersion, os.os.BuildNumber);
3250
3251         ZERO_STRUCT(q1);
3252         q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
3253                 lpcfg_dnsdomain(tctx->lp_ctx));
3254         q1.sitename = "Default-First-Site-Name";
3255         q1.os_version.os = &os;
3256         q1.os_name.string = talloc_asprintf(tctx,
3257                                             "Tortured by Samba4 RPC-NETLOGON: %s",
3258                                             timestring(tctx, time(NULL)));
3259
3260         /* The workstation handles the "servicePrincipalName" and DNS hostname
3261            updates */
3262         q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
3263
3264         query.workstation_info = &q1;
3265
3266         if (sam_ctx) {
3267                 /* Gets back the old DNS hostname in AD */
3268                 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
3269                                    "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
3270                 old_dnsname =
3271                         ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL);
3272
3273                 /* Gets back the "servicePrincipalName"s in AD */
3274                 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
3275                 if (spn_el != NULL) {
3276                         for (i=0; i < spn_el->num_values; i++) {
3277                                 spns = talloc_realloc(tctx, spns, char *, i + 1);
3278                                 spns[i] = (char *) spn_el->values[i].data;
3279                         }
3280                         num_spns = i;
3281                 }
3282         }
3283
3284         torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3285                 "LogonGetDomainInfo failed");
3286         torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3287         torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3288
3289         smb_msleep(250);
3290
3291         if (sam_ctx) {
3292                 /* AD workstation infos entry check */
3293                 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
3294                                    "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
3295                 torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
3296                 torture_assert_str_equal(tctx,
3297                                          ldb_msg_find_attr_as_string(res[0], "operatingSystem", NULL),
3298                                          q1.os_name.string, "'operatingSystem' wrong!");
3299                 torture_assert_str_equal(tctx,
3300                                          ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL),
3301                                          os.os.CSDVersion, "'operatingSystemServicePack' wrong!");
3302                 torture_assert_str_equal(tctx,
3303                                          ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL),
3304                                          version_str, "'operatingSystemVersion' wrong!");
3305
3306                 if (old_dnsname != NULL) {
3307                         /* If before a DNS hostname was set then it should remain
3308                            the same in combination with the "servicePrincipalName"s.
3309                            The DNS hostname should also be returned by our
3310                            "LogonGetDomainInfo" call (in the domain info structure). */
3311
3312                         torture_assert_str_equal(tctx,
3313                                                  ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL),
3314                                                  old_dnsname, "'DNS hostname' was not set!");
3315
3316                         spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
3317                         torture_assert(tctx, ((spns != NULL) && (spn_el != NULL)),
3318                                        "'servicePrincipalName's not set!");
3319                         torture_assert(tctx, spn_el->num_values == num_spns,
3320                                        "'servicePrincipalName's incorrect!");
3321                         for (i=0; (i < spn_el->num_values) && (i < num_spns); i++)
3322                                 torture_assert_str_equal(tctx,
3323                                                          (char *) spn_el->values[i].data,
3324                                 spns[i], "'servicePrincipalName's incorrect!");
3325
3326                         torture_assert_str_equal(tctx,
3327                                                  info.domain_info->dns_hostname.string,
3328                                                  old_dnsname,
3329                                                  "Out 'DNS hostname' doesn't match the old one!");
3330                 } else {
3331                         /* If no DNS hostname was set then also now none should be set,
3332                            the "servicePrincipalName"s should remain empty and no DNS
3333                            hostname should be returned by our "LogonGetDomainInfo"
3334                            call (in the domain info structure). */
3335
3336                         torture_assert(tctx,
3337                                        ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL) == NULL,
3338                                        "'DNS hostname' was set!");
3339
3340                         spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
3341                         torture_assert(tctx, ((spns == NULL) && (spn_el == NULL)),
3342                                        "'servicePrincipalName's were set!");
3343
3344                         torture_assert(tctx,
3345                                        info.domain_info->dns_hostname.string == NULL,
3346                                        "Out 'DNS host name' was set!");
3347                 }
3348         }
3349
3350         /* Checks "workstation flags" */
3351         torture_assert(tctx,
3352                 info.domain_info->workstation_flags
3353                 == NETR_WS_FLAG_HANDLES_SPN_UPDATE,
3354                 "Out 'workstation flags' don't match!");
3355
3356
3357         torture_comment(tctx, "Testing netr_LogonGetDomainInfo 2nd call (variation of DNS hostname doesn't work)\n");
3358         netlogon_creds_client_authenticator(creds, &a);
3359
3360         /* Wipe out the osVersion, and prove which values still 'stick' */
3361         q1.os_version.os = NULL;
3362
3363         /* Change also the DNS hostname to test differences in behaviour */
3364         talloc_free(discard_const_p(char, q1.dns_hostname));
3365         q1.dns_hostname = talloc_asprintf(tctx, "%s2.%s", TEST_MACHINE_NAME,
3366                 lpcfg_dnsdomain(tctx->lp_ctx));
3367
3368         /* The workstation handles the "servicePrincipalName" and DNS hostname
3369            updates */
3370         q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
3371
3372         torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3373                 "LogonGetDomainInfo failed");
3374         torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3375
3376         torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3377
3378         smb_msleep(250);
3379
3380         if (sam_ctx) {
3381                 /* AD workstation infos entry check */
3382                 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
3383                                    "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
3384                 torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
3385
3386                 torture_assert_str_equal(tctx,
3387                                          ldb_msg_find_attr_as_string(res[0], "operatingSystem", NULL),
3388                                          q1.os_name.string, "'operatingSystem' should stick!");
3389                 torture_assert(tctx,
3390                                ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL) == NULL,
3391                                "'operatingSystemServicePack' shouldn't stick!");
3392                 torture_assert(tctx,
3393                                ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL) == NULL,
3394                                "'operatingSystemVersion' shouldn't stick!");
3395
3396                 /* The DNS host name shouldn't have been updated by the server */
3397
3398                 torture_assert_str_equal(tctx,
3399                                          ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL),
3400                                          old_dnsname, "'DNS host name' did change!");
3401
3402                 /* Find the two "servicePrincipalName"s which the DC shouldn't have been
3403                    updated (HOST/<Netbios name> and HOST/<FQDN name>) - see MS-NRPC
3404                    3.5.4.3.9 */
3405                 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
3406                 torture_assert(tctx, spn_el != NULL,
3407                                "There should exist 'servicePrincipalName's in AD!");
3408                 temp_str = talloc_asprintf(tctx, "HOST/%s", TEST_MACHINE_NAME);
3409                 for (i=0; i < spn_el->num_values; i++)
3410                         if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
3411                                 break;
3412                 torture_assert(tctx, i != spn_el->num_values,
3413                                "'servicePrincipalName' HOST/<Netbios name> not found!");
3414                 temp_str = talloc_asprintf(tctx, "HOST/%s", old_dnsname);
3415                 for (i=0; i < spn_el->num_values; i++)
3416                         if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
3417                                 break;
3418                 torture_assert(tctx, i != spn_el->num_values,
3419                                "'servicePrincipalName' HOST/<FQDN name> not found!");
3420
3421                 /* Check that the out DNS hostname was set properly */
3422                 torture_assert_str_equal(tctx, info.domain_info->dns_hostname.string,
3423                                          old_dnsname, "Out 'DNS hostname' doesn't match the old one!");
3424         }
3425
3426         /* Checks "workstation flags" */
3427         torture_assert(tctx,
3428                 info.domain_info->workstation_flags == NETR_WS_FLAG_HANDLES_SPN_UPDATE,
3429                 "Out 'workstation flags' don't match!");
3430
3431
3432         /* Now try the same but the workstation flags set to 0 */
3433
3434         torture_comment(tctx, "Testing netr_LogonGetDomainInfo 3rd call (variation of DNS hostname doesn't work)\n");
3435         netlogon_creds_client_authenticator(creds, &a);
3436
3437         /* Change also the DNS hostname to test differences in behaviour */
3438         talloc_free(discard_const_p(char, q1.dns_hostname));
3439         q1.dns_hostname = talloc_asprintf(tctx, "%s2.%s", TEST_MACHINE_NAME,
3440                 lpcfg_dnsdomain(tctx->lp_ctx));
3441
3442         /* Wipe out the osVersion, and prove which values still 'stick' */
3443         q1.os_version.os = NULL;
3444
3445         /* Let the DC handle the "servicePrincipalName" and DNS hostname
3446            updates */
3447         q1.workstation_flags = 0;
3448
3449         torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3450                 "LogonGetDomainInfo failed");
3451         torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3452         torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3453
3454         smb_msleep(250);
3455
3456         if (sam_ctx) {
3457                 /* AD workstation infos entry check */
3458                 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
3459                                    "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
3460                 torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
3461
3462                 torture_assert_str_equal(tctx,
3463                                          ldb_msg_find_attr_as_string(res[0], "operatingSystem", NULL),
3464                                          q1.os_name.string, "'operatingSystem' should stick!");
3465                 torture_assert(tctx,
3466                                ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL) == NULL,
3467                                "'operatingSystemServicePack' shouldn't stick!");
3468                 torture_assert(tctx,
3469                                ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL) == NULL,
3470                                "'operatingSystemVersion' shouldn't stick!");
3471
3472                 /* The DNS host name shouldn't have been updated by the server */
3473
3474                 torture_assert_str_equal(tctx,
3475                                          ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL),
3476                                          old_dnsname, "'DNS host name' did change!");
3477
3478                 /* Find the two "servicePrincipalName"s which the DC shouldn't have been
3479                    updated (HOST/<Netbios name> and HOST/<FQDN name>) - see MS-NRPC
3480                    3.5.4.3.9 */
3481                 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
3482                 torture_assert(tctx, spn_el != NULL,
3483                                "There should exist 'servicePrincipalName's in AD!");
3484                 temp_str = talloc_asprintf(tctx, "HOST/%s", TEST_MACHINE_NAME);
3485                 for (i=0; i < spn_el->num_values; i++)
3486                         if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
3487                                 break;
3488                 torture_assert(tctx, i != spn_el->num_values,
3489                                "'servicePrincipalName' HOST/<Netbios name> not found!");
3490                 temp_str = talloc_asprintf(tctx, "HOST/%s", old_dnsname);
3491                 for (i=0; i < spn_el->num_values; i++)
3492                         if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
3493                                 break;
3494                 torture_assert(tctx, i != spn_el->num_values,
3495                                "'servicePrincipalName' HOST/<FQDN name> not found!");
3496
3497                 /* Here the server gives us NULL as the out DNS hostname */
3498                 torture_assert(tctx, info.domain_info->dns_hostname.string == NULL,
3499                                "Out 'DNS hostname' should be NULL!");
3500         }
3501
3502         /* Checks "workstation flags" */
3503         torture_assert(tctx,
3504                 info.domain_info->workstation_flags == 0,
3505                 "Out 'workstation flags' don't match!");
3506
3507
3508         torture_comment(tctx, "Testing netr_LogonGetDomainInfo 4th call (verification of DNS hostname and check for trusted domains)\n");
3509         netlogon_creds_client_authenticator(creds, &a);
3510
3511         /* Put the DNS hostname back */
3512         talloc_free(discard_const_p(char, q1.dns_hostname));
3513         q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
3514                 lpcfg_dnsdomain(tctx->lp_ctx));
3515
3516         /* The workstation handles the "servicePrincipalName" and DNS hostname
3517            updates */
3518         q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
3519
3520         torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3521                 "LogonGetDomainInfo failed");
3522         torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3523         torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3524
3525         smb_msleep(250);
3526
3527         /* Now the in/out DNS hostnames should be the same */
3528         torture_assert_str_equal(tctx,
3529                 info.domain_info->dns_hostname.string,
3530                 query.workstation_info->dns_hostname,
3531                 "In/Out 'DNS hostnames' don't match!");
3532         old_dnsname = info.domain_info->dns_hostname.string;
3533
3534         /* Checks "workstation flags" */
3535         torture_assert(tctx,
3536                 info.domain_info->workstation_flags
3537                 == NETR_WS_FLAG_HANDLES_SPN_UPDATE,
3538                 "Out 'workstation flags' don't match!");
3539
3540         /* Checks for trusted domains */
3541         torture_assert(tctx,
3542                 (info.domain_info->trusted_domain_count != 0)
3543                 && (info.domain_info->trusted_domains != NULL),
3544                 "Trusted domains have been requested!");
3545
3546
3547         torture_comment(tctx, "Testing netr_LogonGetDomainInfo 5th call (check for trusted domains)\n");
3548         netlogon_creds_client_authenticator(creds, &a);
3549
3550         /* The workstation handles the "servicePrincipalName" and DNS hostname
3551            updates and requests inbound trusts */
3552         q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE
3553                 | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS;
3554
3555         torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3556                 "LogonGetDomainInfo failed");
3557         torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3558         torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3559
3560         smb_msleep(250);
3561
3562         /* Checks "workstation flags" */
3563         torture_assert(tctx,
3564                 info.domain_info->workstation_flags
3565                 == (NETR_WS_FLAG_HANDLES_SPN_UPDATE
3566                         | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS),
3567                 "Out 'workstation flags' don't match!");
3568
3569         /* Checks for trusted domains */
3570         torture_assert(tctx,
3571                 (info.domain_info->trusted_domain_count != 0)
3572                 && (info.domain_info->trusted_domains != NULL),
3573                 "Trusted domains have been requested!");
3574
3575
3576         torture_comment(tctx, "Testing netr_LogonGetDomainInfo 6th call (no DNS hostname)\n");
3577         netlogon_creds_client_authenticator(creds, &a);
3578
3579         query.workstation_info->dns_hostname = NULL;
3580
3581         torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3582                 "LogonGetDomainInfo failed");
3583         torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3584         torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3585
3586         /* The old DNS hostname should stick */
3587         torture_assert_str_equal(tctx,
3588                 info.domain_info->dns_hostname.string,
3589                 old_dnsname,
3590                 "'DNS hostname' changed!");
3591
3592         torture_comment(tctx, "Testing netr_LogonGetDomainInfo 7th call (extra workstation flags)\n");
3593         netlogon_creds_client_authenticator(creds, &a);
3594
3595         q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE
3596                 | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS | 0x4;
3597
3598         /* Put the DNS hostname back */
3599         talloc_free(discard_const_p(char, q1.dns_hostname));
3600         q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
3601                 lpcfg_dnsdomain(tctx->lp_ctx));
3602
3603         torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3604                 "LogonGetDomainInfo failed");
3605         torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3606         torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3607
3608         /* Checks "workstation flags" */
3609         torture_assert(tctx,
3610                 info.domain_info->workstation_flags
3611                 == (NETR_WS_FLAG_HANDLES_SPN_UPDATE
3612                         | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS),
3613                 "Out 'workstation flags' don't match!");
3614
3615         if (!torture_setting_bool(tctx, "dangerous", false)) {
3616                 torture_comment(tctx, "Not testing netr_LogonGetDomainInfo 8th call (no workstation info) - enable dangerous tests in order to do so\n");
3617         } else {
3618                 /* Try a call without the workstation information structure */
3619
3620                 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 8th call (no workstation info)\n");
3621                 netlogon_creds_client_authenticator(creds, &a);
3622
3623                 query.workstation_info = NULL;
3624
3625                 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3626                         "LogonGetDomainInfo failed");
3627                 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3628                 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3629         }
3630
3631         return true;
3632 }
3633
3634 static bool test_GetDomainInfo_async(struct torture_context *tctx,
3635                                      struct dcerpc_pipe *p,
3636                                      struct cli_credentials *machine_credentials)
3637 {
3638         NTSTATUS status;
3639         struct netr_LogonGetDomainInfo r;
3640         struct netr_WorkstationInformation q1;
3641         struct netr_Authenticator a;
3642 #define ASYNC_COUNT 100
3643         struct netlogon_creds_CredentialState *creds;
3644         struct netlogon_creds_CredentialState *creds_async[ASYNC_COUNT];
3645         struct tevent_req *req[ASYNC_COUNT];
3646         int i;
3647         union netr_WorkstationInfo query;
3648         union netr_DomainInfo info;
3649
3650         torture_comment(tctx, "Testing netr_LogonGetDomainInfo - async count %d\n", ASYNC_COUNT);
3651
3652         if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
3653                                     machine_credentials, &creds)) {
3654                 return false;
3655         }
3656
3657         ZERO_STRUCT(r);
3658         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3659         r.in.computer_name = TEST_MACHINE_NAME;
3660         r.in.credential = &a;
3661         r.in.level = 1;
3662         r.in.return_authenticator = &a;
3663         r.in.query = &query;
3664         r.out.return_authenticator = &a;
3665         r.out.info = &info;
3666
3667         ZERO_STRUCT(q1);
3668         q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
3669                 lpcfg_dnsdomain(tctx->lp_ctx));
3670         q1.sitename = "Default-First-Site-Name";
3671         q1.os_name.string = "UNIX/Linux or similar";
3672
3673         query.workstation_info = &q1;
3674
3675         for (i=0;i<ASYNC_COUNT;i++) {
3676                 netlogon_creds_client_authenticator(creds, &a);
3677
3678                 creds_async[i] = (struct netlogon_creds_CredentialState *)talloc_memdup(creds, creds, sizeof(*creds));
3679                 req[i] = dcerpc_netr_LogonGetDomainInfo_r_send(tctx, tctx->ev, p->binding_handle, &r);
3680
3681                 /* even with this flush per request a w2k3 server seems to
3682                    clag with multiple outstanding requests. bleergh. */
3683                 torture_assert_int_equal(tctx, tevent_loop_once(dcerpc_event_context(p)), 0,
3684                                          "tevent_loop_once failed");
3685         }
3686
3687         for (i=0;i<ASYNC_COUNT;i++) {
3688                 torture_assert_int_equal(tctx, tevent_req_poll(req[i], tctx->ev), true,
3689                                          "tevent_req_poll() failed");
3690
3691                 status = dcerpc_netr_LogonGetDomainInfo_r_recv(req[i], tctx);
3692
3693                 torture_assert_ntstatus_ok(tctx, status, "netr_LogonGetDomainInfo_async");
3694                 torture_assert_ntstatus_ok(tctx, r.out.result, "netr_LogonGetDomainInfo_async");
3695
3696                 torture_assert(tctx, netlogon_creds_client_check(creds_async[i], &a.cred),
3697                         "Credential chaining failed at async");
3698         }
3699
3700         torture_comment(tctx,
3701                         "Testing netr_LogonGetDomainInfo - async count %d OK\n", ASYNC_COUNT);
3702
3703         return true;
3704 }
3705
3706 static bool test_ManyGetDCName(struct torture_context *tctx,
3707                                struct dcerpc_pipe *p)
3708 {
3709         NTSTATUS status;
3710         struct dcerpc_pipe *p2;
3711         struct lsa_ObjectAttribute attr;
3712         struct lsa_QosInfo qos;
3713         struct lsa_OpenPolicy2 o;
3714         struct policy_handle lsa_handle;
3715         struct lsa_DomainList domains;
3716
3717         struct lsa_EnumTrustDom t;
3718         uint32_t resume_handle = 0;
3719         struct netr_GetAnyDCName d;
3720         const char *dcname = NULL;
3721         struct dcerpc_binding_handle *b = p->binding_handle;
3722         struct dcerpc_binding_handle *b2;
3723
3724         int i;
3725
3726         if (p->conn->transport.transport != NCACN_NP) {
3727                 return true;
3728         }
3729
3730         torture_comment(tctx, "Torturing GetDCName\n");
3731
3732         status = dcerpc_secondary_connection(p, &p2, p->binding);
3733         torture_assert_ntstatus_ok(tctx, status, "Failed to create secondary connection");
3734
3735         status = dcerpc_bind_auth_none(p2, &ndr_table_lsarpc);
3736         torture_assert_ntstatus_ok(tctx, status, "Failed to create bind on secondary connection");
3737         b2 = p2->binding_handle;
3738
3739         qos.len = 0;
3740         qos.impersonation_level = 2;
3741         qos.context_mode = 1;
3742         qos.effective_only = 0;
3743
3744         attr.len = 0;
3745         attr.root_dir = NULL;
3746         attr.object_name = NULL;
3747         attr.attributes = 0;
3748         attr.sec_desc = NULL;
3749         attr.sec_qos = &qos;
3750
3751         o.in.system_name = "\\";
3752         o.in.attr = &attr;
3753         o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3754         o.out.handle = &lsa_handle;
3755
3756         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenPolicy2_r(b2, tctx, &o),
3757                 "OpenPolicy2 failed");
3758         torture_assert_ntstatus_ok(tctx, o.out.result, "OpenPolicy2 failed");
3759
3760         t.in.handle = &lsa_handle;
3761         t.in.resume_handle = &resume_handle;
3762         t.in.max_size = 1000;
3763         t.out.domains = &domains;
3764         t.out.resume_handle = &resume_handle;
3765
3766         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumTrustDom_r(b2, tctx, &t),
3767                 "EnumTrustDom failed");
3768
3769         if ((!NT_STATUS_IS_OK(t.out.result) &&
3770              (!NT_STATUS_EQUAL(t.out.result, NT_STATUS_NO_MORE_ENTRIES))))
3771                 torture_fail(tctx, "Could not list domains");
3772
3773         talloc_free(p2);
3774
3775         d.in.logon_server = talloc_asprintf(tctx, "\\\\%s",
3776                                             dcerpc_server_name(p));
3777         d.out.dcname = &dcname;
3778
3779         for (i=0; i<domains.count * 4; i++) {
3780                 struct lsa_DomainInfo *info =
3781                         &domains.domains[rand()%domains.count];
3782
3783                 d.in.domainname = info->name.string;
3784
3785                 status = dcerpc_netr_GetAnyDCName_r(b, tctx, &d);
3786                 torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
3787
3788                 torture_comment(tctx, "\tDC for domain %s is %s\n", info->name.string,
3789                        dcname ? dcname : "unknown");
3790         }
3791
3792         return true;
3793 }
3794
3795 static bool test_SetPassword_with_flags(struct torture_context *tctx,
3796                                         struct dcerpc_pipe *p,
3797                                         struct cli_credentials *machine_credentials)
3798 {
3799         uint32_t flags[] = { 0, NETLOGON_NEG_STRONG_KEYS };
3800         struct netlogon_creds_CredentialState *creds;
3801         int i;
3802
3803         if (!test_SetupCredentials2(p, tctx, 0,
3804                                     machine_credentials,
3805                                     cli_credentials_get_secure_channel_type(machine_credentials),
3806                                     &creds)) {
3807                 torture_skip(tctx, "DC does not support negotiation of 64bit session keys");
3808         }
3809
3810         for (i=0; i < ARRAY_SIZE(flags); i++) {
3811                 torture_assert(tctx,
3812                         test_SetPassword_flags(tctx, p, machine_credentials, flags[i]),
3813                         talloc_asprintf(tctx, "failed to test SetPassword negotiating with 0x%08x flags", flags[i]));
3814         }
3815
3816         return true;
3817 }
3818
3819 struct torture_suite *torture_rpc_netlogon(TALLOC_CTX *mem_ctx)
3820 {
3821         struct torture_suite *suite = torture_suite_create(mem_ctx, "netlogon");
3822         struct torture_rpc_tcase *tcase;
3823         struct torture_test *test;
3824
3825         tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netlogon",
3826                                                   &ndr_table_netlogon, TEST_MACHINE_NAME);
3827
3828         torture_rpc_tcase_add_test(tcase, "Broken RPC binding handle",
3829                                    test_netr_broken_binding_handle);
3830
3831         torture_rpc_tcase_add_test(tcase, "LogonUasLogon", test_LogonUasLogon);
3832         torture_rpc_tcase_add_test(tcase, "LogonUasLogoff", test_LogonUasLogoff);
3833         torture_rpc_tcase_add_test_creds(tcase, "SamLogon", test_SamLogon);
3834         torture_rpc_tcase_add_test_creds(tcase, "SetPassword", test_SetPassword);
3835         torture_rpc_tcase_add_test_creds(tcase, "SetPassword2", test_SetPassword2);
3836         torture_rpc_tcase_add_test_creds(tcase, "GetPassword", test_GetPassword);
3837         torture_rpc_tcase_add_test_creds(tcase, "GetTrustPasswords", test_GetTrustPasswords);
3838         torture_rpc_tcase_add_test_creds(tcase, "GetDomainInfo", test_GetDomainInfo);
3839         torture_rpc_tcase_add_test_creds(tcase, "DatabaseSync", test_DatabaseSync);
3840         torture_rpc_tcase_add_test_creds(tcase, "DatabaseDeltas", test_DatabaseDeltas);
3841         torture_rpc_tcase_add_test_creds(tcase, "DatabaseRedo", test_DatabaseRedo);
3842         torture_rpc_tcase_add_test_creds(tcase, "AccountDeltas", test_AccountDeltas);
3843         torture_rpc_tcase_add_test_creds(tcase, "AccountSync", test_AccountSync);
3844         torture_rpc_tcase_add_test(tcase, "GetDcName", test_GetDcName);
3845         torture_rpc_tcase_add_test(tcase, "ManyGetDCName", test_ManyGetDCName);
3846         torture_rpc_tcase_add_test(tcase, "GetAnyDCName", test_GetAnyDCName);
3847         torture_rpc_tcase_add_test_creds(tcase, "DatabaseSync2", test_DatabaseSync2);
3848         torture_rpc_tcase_add_test(tcase, "DsrEnumerateDomainTrusts", test_DsrEnumerateDomainTrusts);
3849         torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomains", test_netr_NetrEnumerateTrustedDomains);
3850         torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomainsEx", test_netr_NetrEnumerateTrustedDomainsEx);
3851         test = torture_rpc_tcase_add_test_creds(tcase, "GetDomainInfo_async", test_GetDomainInfo_async);
3852         test->dangerous = true;
3853         torture_rpc_tcase_add_test(tcase, "DsRGetDCName", test_netr_DsRGetDCName);
3854         torture_rpc_tcase_add_test(tcase, "DsRGetDCNameEx", test_netr_DsRGetDCNameEx);
3855         torture_rpc_tcase_add_test(tcase, "DsRGetDCNameEx2", test_netr_DsRGetDCNameEx2);
3856         torture_rpc_tcase_add_test(tcase, "DsrGetDcSiteCoverageW", test_netr_DsrGetDcSiteCoverageW);
3857         torture_rpc_tcase_add_test(tcase, "DsRAddressToSitenamesW", test_netr_DsRAddressToSitenamesW);
3858         torture_rpc_tcase_add_test(tcase, "DsRAddressToSitenamesExW", test_netr_DsRAddressToSitenamesExW);
3859         torture_rpc_tcase_add_test_creds(tcase, "ServerGetTrustInfo", test_netr_ServerGetTrustInfo);
3860         torture_rpc_tcase_add_test_creds(tcase, "GetForestTrustInformation", test_netr_GetForestTrustInformation);
3861
3862         return suite;
3863 }
3864
3865 struct torture_suite *torture_rpc_netlogon_s3(TALLOC_CTX *mem_ctx)
3866 {
3867         struct torture_suite *suite = torture_suite_create(mem_ctx, "netlogon-s3");
3868         struct torture_rpc_tcase *tcase;
3869
3870         tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netlogon",
3871                                                   &ndr_table_netlogon, TEST_MACHINE_NAME);
3872
3873         torture_rpc_tcase_add_test_creds(tcase, "SamLogon", test_SamLogon);
3874         torture_rpc_tcase_add_test_creds(tcase, "SamLogon_NULL_domain", test_SamLogon_NULL_domain);
3875         torture_rpc_tcase_add_test_creds(tcase, "SetPassword", test_SetPassword);
3876         torture_rpc_tcase_add_test_creds(tcase, "SetPassword_with_flags", test_SetPassword_with_flags);
3877         torture_rpc_tcase_add_test_creds(tcase, "SetPassword2", test_SetPassword2);
3878         torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomains", test_netr_NetrEnumerateTrustedDomains);
3879
3880         return suite;
3881 }
3882
3883 struct torture_suite *torture_rpc_netlogon_admin(TALLOC_CTX *mem_ctx)
3884 {
3885         struct torture_suite *suite = torture_suite_create(mem_ctx, "netlogon.admin");
3886         struct torture_rpc_tcase *tcase;
3887
3888         tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netlogon",
3889                                                   &ndr_table_netlogon, TEST_MACHINE_NAME);
3890         torture_rpc_tcase_add_test_creds(tcase, "LogonControl", test_LogonControl);
3891         torture_rpc_tcase_add_test_creds(tcase, "LogonControl2", test_LogonControl2);
3892         torture_rpc_tcase_add_test_creds(tcase, "LogonControl2Ex", test_LogonControl2Ex);
3893
3894         tcase = torture_suite_add_machine_workstation_rpc_iface_tcase(suite, "netlogon",
3895                                                   &ndr_table_netlogon, TEST_MACHINE_NAME);
3896         torture_rpc_tcase_add_test_creds(tcase, "LogonControl", test_LogonControl);
3897         torture_rpc_tcase_add_test_creds(tcase, "LogonControl2", test_LogonControl2);
3898         torture_rpc_tcase_add_test_creds(tcase, "LogonControl2Ex", test_LogonControl2Ex);
3899
3900         tcase = torture_suite_add_rpc_iface_tcase(suite, "netlogon",
3901                                                   &ndr_table_netlogon);
3902         torture_rpc_tcase_add_test_creds(tcase, "LogonControl", test_LogonControl);
3903         torture_rpc_tcase_add_test_creds(tcase, "LogonControl2", test_LogonControl2);
3904         torture_rpc_tcase_add_test_creds(tcase, "LogonControl2Ex", test_LogonControl2Ex);
3905
3906         return suite;
3907 }