897283470fa7d3d96344ed863ed3a19eb2c258d5
[gd/samba/.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
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/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 "lib/ldb/include/ldb.h"
36 #include "lib/util/util_ldb.h"
37 #include "lib/ldb_wrap.h"
38
39 #define TEST_MACHINE_NAME "torturetest"
40 #define TEST_MACHINE_DNS_SUFFIX "torturedomain"
41
42 static bool test_LogonUasLogon(struct torture_context *tctx, 
43                                struct dcerpc_pipe *p)
44 {
45         NTSTATUS status;
46         struct netr_LogonUasLogon r;
47         struct netr_UasInfo *info = NULL;
48
49         r.in.server_name = NULL;
50         r.in.account_name = cli_credentials_get_username(cmdline_credentials);
51         r.in.workstation = TEST_MACHINE_NAME;
52         r.out.info = &info;
53
54         status = dcerpc_netr_LogonUasLogon(p, tctx, &r);
55         torture_assert_ntstatus_ok(tctx, status, "LogonUasLogon");
56
57         return true;
58 }
59
60 static bool test_LogonUasLogoff(struct torture_context *tctx,
61                                 struct dcerpc_pipe *p)
62 {
63         NTSTATUS status;
64         struct netr_LogonUasLogoff r;
65         struct netr_UasLogoffInfo info;
66
67         r.in.server_name = NULL;
68         r.in.account_name = cli_credentials_get_username(cmdline_credentials);
69         r.in.workstation = TEST_MACHINE_NAME;
70         r.out.info = &info;
71
72         status = dcerpc_netr_LogonUasLogoff(p, tctx, &r);
73         torture_assert_ntstatus_ok(tctx, status, "LogonUasLogoff");
74
75         return true;
76 }
77
78 bool test_SetupCredentials(struct dcerpc_pipe *p, struct torture_context *tctx,
79                                   struct cli_credentials *credentials,
80                                   struct netlogon_creds_CredentialState **creds_out)
81 {
82         NTSTATUS status;
83         struct netr_ServerReqChallenge r;
84         struct netr_ServerAuthenticate a;
85         struct netr_Credential credentials1, credentials2, credentials3;
86         struct netlogon_creds_CredentialState *creds;
87         const struct samr_Password *mach_password;
88         const char *machine_name;
89
90         mach_password = cli_credentials_get_nt_hash(credentials, tctx);
91         machine_name = cli_credentials_get_workstation(credentials);
92
93         torture_comment(tctx, "Testing ServerReqChallenge\n");
94
95         r.in.server_name = NULL;
96         r.in.computer_name = machine_name;
97         r.in.credentials = &credentials1;
98         r.out.return_credentials = &credentials2;
99
100         generate_random_buffer(credentials1.data, sizeof(credentials1.data));
101
102         status = dcerpc_netr_ServerReqChallenge(p, tctx, &r);
103         torture_assert_ntstatus_ok(tctx, status, "ServerReqChallenge");
104
105         a.in.server_name = NULL;
106         a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
107         a.in.secure_channel_type = cli_credentials_get_secure_channel_type(credentials);
108         a.in.computer_name = machine_name;
109         a.in.credentials = &credentials3;
110         a.out.return_credentials = &credentials3;
111
112         creds = netlogon_creds_client_init(tctx, a.in.account_name,
113                                            a.in.computer_name,
114                                            &credentials1, &credentials2, 
115                                            mach_password, &credentials3, 
116                                            0);
117         torture_assert(tctx, creds != NULL, "memory allocation");
118
119
120         torture_comment(tctx, "Testing ServerAuthenticate\n");
121
122         status = dcerpc_netr_ServerAuthenticate(p, tctx, &a);
123
124         /* This allows the tests to continue against the more fussy windows 2008 */
125         if (NT_STATUS_EQUAL(status, NT_STATUS_DOWNGRADE_DETECTED)) {
126                 return test_SetupCredentials2(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS, 
127                                               credentials,
128                                               cli_credentials_get_secure_channel_type(credentials),
129                                               creds_out);
130         }
131
132         torture_assert_ntstatus_ok(tctx, status, "ServerAuthenticate");
133
134         torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), 
135                        "Credential chaining failed");
136
137         *creds_out = creds;
138         return true;
139 }
140
141 bool test_SetupCredentials2(struct dcerpc_pipe *p, struct torture_context *tctx,
142                             uint32_t negotiate_flags,
143                             struct cli_credentials *machine_credentials,
144                             int sec_chan_type,
145                             struct netlogon_creds_CredentialState **creds_out)
146 {
147         NTSTATUS status;
148         struct netr_ServerReqChallenge r;
149         struct netr_ServerAuthenticate2 a;
150         struct netr_Credential credentials1, credentials2, credentials3;
151         struct netlogon_creds_CredentialState *creds;
152         const struct samr_Password *mach_password;
153         const char *machine_name;
154
155         mach_password = cli_credentials_get_nt_hash(machine_credentials, tctx);
156         machine_name = cli_credentials_get_workstation(machine_credentials);
157
158         torture_comment(tctx, "Testing ServerReqChallenge\n");
159
160
161         r.in.server_name = NULL;
162         r.in.computer_name = machine_name;
163         r.in.credentials = &credentials1;
164         r.out.return_credentials = &credentials2;
165
166         generate_random_buffer(credentials1.data, sizeof(credentials1.data));
167
168         status = dcerpc_netr_ServerReqChallenge(p, tctx, &r);
169         torture_assert_ntstatus_ok(tctx, status, "ServerReqChallenge");
170
171         a.in.server_name = NULL;
172         a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
173         a.in.secure_channel_type = sec_chan_type;
174         a.in.computer_name = machine_name;
175         a.in.negotiate_flags = &negotiate_flags;
176         a.out.negotiate_flags = &negotiate_flags;
177         a.in.credentials = &credentials3;
178         a.out.return_credentials = &credentials3;
179
180         creds = netlogon_creds_client_init(tctx, a.in.account_name,
181                                            a.in.computer_name, 
182                                            &credentials1, &credentials2, 
183                                            mach_password, &credentials3, 
184                                            negotiate_flags);
185
186         torture_assert(tctx, creds != NULL, "memory allocation");
187
188         torture_comment(tctx, "Testing ServerAuthenticate2\n");
189
190         status = dcerpc_netr_ServerAuthenticate2(p, tctx, &a);
191         torture_assert_ntstatus_ok(tctx, status, "ServerAuthenticate2");
192
193         torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), 
194                 "Credential chaining failed");
195
196         torture_comment(tctx, "negotiate_flags=0x%08x\n", negotiate_flags);
197
198         *creds_out = creds;
199         return true;
200 }
201
202
203 static bool test_SetupCredentials3(struct dcerpc_pipe *p, struct torture_context *tctx,
204                             uint32_t negotiate_flags,
205                             struct cli_credentials *machine_credentials,
206                             struct netlogon_creds_CredentialState **creds_out)
207 {
208         NTSTATUS status;
209         struct netr_ServerReqChallenge r;
210         struct netr_ServerAuthenticate3 a;
211         struct netr_Credential credentials1, credentials2, credentials3;
212         struct netlogon_creds_CredentialState *creds;
213         struct samr_Password mach_password;
214         uint32_t rid;
215         const char *machine_name;
216         const char *plain_pass;
217
218         machine_name = cli_credentials_get_workstation(machine_credentials);
219         plain_pass = cli_credentials_get_password(machine_credentials);
220
221         torture_comment(tctx, "Testing ServerReqChallenge\n");
222
223         r.in.server_name = NULL;
224         r.in.computer_name = machine_name;
225         r.in.credentials = &credentials1;
226         r.out.return_credentials = &credentials2;
227
228         generate_random_buffer(credentials1.data, sizeof(credentials1.data));
229
230         status = dcerpc_netr_ServerReqChallenge(p, tctx, &r);
231         torture_assert_ntstatus_ok(tctx, status, "ServerReqChallenge");
232
233         E_md4hash(plain_pass, mach_password.hash);
234
235         a.in.server_name = NULL;
236         a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
237         a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
238         a.in.computer_name = machine_name;
239         a.in.negotiate_flags = &negotiate_flags;
240         a.in.credentials = &credentials3;
241         a.out.return_credentials = &credentials3;
242         a.out.negotiate_flags = &negotiate_flags;
243         a.out.rid = &rid;
244
245         creds = netlogon_creds_client_init(tctx, a.in.account_name,
246                                            a.in.computer_name,
247                                            &credentials1, &credentials2, 
248                                            &mach_password, &credentials3,
249                                            negotiate_flags);
250         
251         torture_assert(tctx, creds != NULL, "memory allocation");
252
253         torture_comment(tctx, "Testing ServerAuthenticate3\n");
254
255         status = dcerpc_netr_ServerAuthenticate3(p, tctx, &a);
256         torture_assert_ntstatus_ok(tctx, status, "ServerAuthenticate3");
257         torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
258
259         torture_comment(tctx, "negotiate_flags=0x%08x\n", negotiate_flags);
260         
261         /* Prove that requesting a challenge again won't break it */
262         status = dcerpc_netr_ServerReqChallenge(p, tctx, &r);
263         torture_assert_ntstatus_ok(tctx, status, "ServerReqChallenge");
264
265         *creds_out = creds;
266         return true;
267 }
268
269 /*
270   try a change password for our machine account
271 */
272 static bool test_SetPassword(struct torture_context *tctx, 
273                              struct dcerpc_pipe *p,
274                              struct cli_credentials *machine_credentials)
275 {
276         NTSTATUS status;
277         struct netr_ServerPasswordSet r;
278         const char *password;
279         struct netlogon_creds_CredentialState *creds;
280         struct netr_Authenticator credential, return_authenticator;
281         struct samr_Password new_password;
282
283         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
284                 return false;
285         }
286
287         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
288         r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
289         r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
290         r.in.computer_name = TEST_MACHINE_NAME;
291         r.in.credential = &credential;
292         r.in.new_password = &new_password;
293         r.out.return_authenticator = &return_authenticator;
294
295         password = generate_random_str(tctx, 8);
296         E_md4hash(password, new_password.hash);
297
298         netlogon_creds_des_encrypt(creds, &new_password);
299
300         torture_comment(tctx, "Testing ServerPasswordSet on machine account\n");
301         torture_comment(tctx, "Changing machine account password to '%s'\n", 
302                         password);
303
304         netlogon_creds_client_authenticator(creds, &credential);
305
306         status = dcerpc_netr_ServerPasswordSet(p, tctx, &r);
307         torture_assert_ntstatus_ok(tctx, status, "ServerPasswordSet");
308
309         if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
310                 torture_comment(tctx, "Credential chaining failed\n");
311         }
312
313         /* by changing the machine password twice we test the
314            credentials chaining fully, and we verify that the server
315            allows the password to be set to the same value twice in a
316            row (match win2k3) */
317         torture_comment(tctx, 
318                 "Testing a second ServerPasswordSet on machine account\n");
319         torture_comment(tctx, 
320                 "Changing machine account password to '%s' (same as previous run)\n", password);
321
322         netlogon_creds_client_authenticator(creds, &credential);
323
324         status = dcerpc_netr_ServerPasswordSet(p, tctx, &r);
325         torture_assert_ntstatus_ok(tctx, status, "ServerPasswordSet (2)");
326
327         if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
328                 torture_comment(tctx, "Credential chaining failed\n");
329         }
330
331         cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
332
333         torture_assert(tctx, 
334                 test_SetupCredentials(p, tctx, machine_credentials, &creds), 
335                 "ServerPasswordSet failed to actually change the password");
336
337         return true;
338 }
339
340 /*
341   try a change password for our machine account
342 */
343 static bool test_SetPassword_flags(struct torture_context *tctx,
344                                    struct dcerpc_pipe *p,
345                                    struct cli_credentials *machine_credentials,
346                                    uint32_t negotiate_flags)
347 {
348         NTSTATUS status;
349         struct netr_ServerPasswordSet r;
350         const char *password;
351         struct netlogon_creds_CredentialState *creds;
352         struct netr_Authenticator credential, return_authenticator;
353         struct samr_Password new_password;
354
355         if (!test_SetupCredentials2(p, tctx, negotiate_flags,
356                                     machine_credentials,
357                                     cli_credentials_get_secure_channel_type(machine_credentials),
358                                     &creds)) {
359                 return false;
360         }
361
362         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
363         r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
364         r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
365         r.in.computer_name = TEST_MACHINE_NAME;
366         r.in.credential = &credential;
367         r.in.new_password = &new_password;
368         r.out.return_authenticator = &return_authenticator;
369
370         password = generate_random_str(tctx, 8);
371         E_md4hash(password, new_password.hash);
372
373         netlogon_creds_des_encrypt(creds, &new_password);
374
375         torture_comment(tctx, "Testing ServerPasswordSet on machine account\n");
376         torture_comment(tctx, "Changing machine account password to '%s'\n",
377                         password);
378
379         netlogon_creds_client_authenticator(creds, &credential);
380
381         status = dcerpc_netr_ServerPasswordSet(p, tctx, &r);
382         torture_assert_ntstatus_ok(tctx, status, "ServerPasswordSet");
383
384         if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
385                 torture_comment(tctx, "Credential chaining failed\n");
386         }
387
388         /* by changing the machine password twice we test the
389            credentials chaining fully, and we verify that the server
390            allows the password to be set to the same value twice in a
391            row (match win2k3) */
392         torture_comment(tctx,
393                 "Testing a second ServerPasswordSet on machine account\n");
394         torture_comment(tctx,
395                 "Changing machine account password to '%s' (same as previous run)\n", password);
396
397         netlogon_creds_client_authenticator(creds, &credential);
398
399         status = dcerpc_netr_ServerPasswordSet(p, tctx, &r);
400         torture_assert_ntstatus_ok(tctx, status, "ServerPasswordSet (2)");
401
402         if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
403                 torture_comment(tctx, "Credential chaining failed\n");
404         }
405
406         cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
407
408         torture_assert(tctx,
409                 test_SetupCredentials(p, tctx, machine_credentials, &creds),
410                 "ServerPasswordSet failed to actually change the password");
411
412         return true;
413 }
414
415
416 /*
417   generate a random password for password change tests
418 */
419 static DATA_BLOB netlogon_very_rand_pass(TALLOC_CTX *mem_ctx, int len)
420 {
421         int i;
422         DATA_BLOB password = data_blob_talloc(mem_ctx, NULL, len * 2 /* number of unicode chars */);
423         generate_random_buffer(password.data, password.length);
424
425         for (i=0; i < len; i++) {
426                 if (((uint16_t *)password.data)[i] == 0) {
427                         ((uint16_t *)password.data)[i] = 1;
428                 }
429         }
430
431         return password;
432 }
433
434 /*
435   try a change password for our machine account
436 */
437 static bool test_SetPassword2(struct torture_context *tctx, 
438                               struct dcerpc_pipe *p, 
439                               struct cli_credentials *machine_credentials)
440 {
441         NTSTATUS status;
442         struct netr_ServerPasswordSet2 r;
443         const char *password;
444         DATA_BLOB new_random_pass;
445         struct netlogon_creds_CredentialState *creds;
446         struct samr_CryptPassword password_buf;
447         struct samr_Password nt_hash;
448         struct netr_Authenticator credential, return_authenticator;
449         struct netr_CryptPassword new_password;
450
451         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
452                 return false;
453         }
454
455         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
456         r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
457         r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
458         r.in.computer_name = TEST_MACHINE_NAME;
459         r.in.credential = &credential;
460         r.in.new_password = &new_password;
461         r.out.return_authenticator = &return_authenticator;
462
463         password = generate_random_str(tctx, 8);
464         encode_pw_buffer(password_buf.data, password, STR_UNICODE);
465         netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
466
467         memcpy(new_password.data, password_buf.data, 512);
468         new_password.length = IVAL(password_buf.data, 512);
469
470         torture_comment(tctx, "Testing ServerPasswordSet2 on machine account\n");
471         torture_comment(tctx, "Changing machine account password to '%s'\n", password);
472
473         netlogon_creds_client_authenticator(creds, &credential);
474
475         status = dcerpc_netr_ServerPasswordSet2(p, tctx, &r);
476         torture_assert_ntstatus_ok(tctx, status, "ServerPasswordSet2");
477
478         if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
479                 torture_comment(tctx, "Credential chaining failed\n");
480         }
481
482         cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
483
484         if (!torture_setting_bool(tctx, "dangerous", false)) {
485                 torture_comment(tctx, 
486                         "Not testing ability to set password to '', enable dangerous tests to perform this test\n");
487         } else {
488                 /* by changing the machine password to ""
489                  * we check if the server uses password restrictions
490                  * for ServerPasswordSet2
491                  * (win2k3 accepts "")
492                  */
493                 password = "";
494                 encode_pw_buffer(password_buf.data, password, STR_UNICODE);
495                 netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
496                 
497                 memcpy(new_password.data, password_buf.data, 512);
498                 new_password.length = IVAL(password_buf.data, 512);
499                 
500                 torture_comment(tctx, 
501                         "Testing ServerPasswordSet2 on machine account\n");
502                 torture_comment(tctx, 
503                         "Changing machine account password to '%s'\n", password);
504                 
505                 netlogon_creds_client_authenticator(creds, &credential);
506                 
507                 status = dcerpc_netr_ServerPasswordSet2(p, tctx, &r);
508                 torture_assert_ntstatus_ok(tctx, status, "ServerPasswordSet2");
509                 
510                 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
511                         torture_comment(tctx, "Credential chaining failed\n");
512                 }
513                 
514                 cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
515         }
516
517         torture_assert(tctx, test_SetupCredentials(p, tctx, machine_credentials, &creds), 
518                 "ServerPasswordSet failed to actually change the password");
519
520         /* now try a random password */
521         password = generate_random_str(tctx, 8);
522         encode_pw_buffer(password_buf.data, password, STR_UNICODE);
523         netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
524
525         memcpy(new_password.data, password_buf.data, 512);
526         new_password.length = IVAL(password_buf.data, 512);
527
528         torture_comment(tctx, "Testing second ServerPasswordSet2 on machine account\n");
529         torture_comment(tctx, "Changing machine account password to '%s'\n", password);
530
531         netlogon_creds_client_authenticator(creds, &credential);
532
533         status = dcerpc_netr_ServerPasswordSet2(p, tctx, &r);
534         torture_assert_ntstatus_ok(tctx, status, "ServerPasswordSet2 (2)");
535
536         if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
537                 torture_comment(tctx, "Credential chaining failed\n");
538         }
539
540         /* by changing the machine password twice we test the
541            credentials chaining fully, and we verify that the server
542            allows the password to be set to the same value twice in a
543            row (match win2k3) */
544         torture_comment(tctx, 
545                 "Testing a second ServerPasswordSet2 on machine account\n");
546         torture_comment(tctx, 
547                 "Changing machine account password to '%s' (same as previous run)\n", password);
548
549         netlogon_creds_client_authenticator(creds, &credential);
550
551         status = dcerpc_netr_ServerPasswordSet2(p, tctx, &r);
552         torture_assert_ntstatus_ok(tctx, status, "ServerPasswordSet (3)");
553
554         if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
555                 torture_comment(tctx, "Credential chaining failed\n");
556         }
557
558         cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
559
560         torture_assert (tctx, 
561                 test_SetupCredentials(p, tctx, machine_credentials, &creds), 
562                 "ServerPasswordSet failed to actually change the password");
563
564         new_random_pass = netlogon_very_rand_pass(tctx, 128);
565
566         /* now try a random stream of bytes for a password */
567         set_pw_in_buffer(password_buf.data, &new_random_pass);
568
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 a third ServerPasswordSet2 on machine account, with a compleatly random password\n");
576
577         netlogon_creds_client_authenticator(creds, &credential);
578
579         status = dcerpc_netr_ServerPasswordSet2(p, tctx, &r);
580         torture_assert_ntstatus_ok(tctx, status, "ServerPasswordSet (3)");
581
582         if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
583                 torture_comment(tctx, "Credential chaining failed\n");
584         }
585
586         mdfour(nt_hash.hash, new_random_pass.data, new_random_pass.length);
587
588         cli_credentials_set_password(machine_credentials, NULL, CRED_UNINITIALISED);
589         cli_credentials_set_nt_hash(machine_credentials, &nt_hash, CRED_SPECIFIED);
590
591         torture_assert (tctx, 
592                 test_SetupCredentials(p, tctx, machine_credentials, &creds), 
593                 "ServerPasswordSet failed to actually change the password");
594
595         return true;
596 }
597
598 static bool test_GetPassword(struct torture_context *tctx,
599                              struct dcerpc_pipe *p,
600                              struct cli_credentials *machine_credentials)
601 {
602         struct netr_ServerPasswordGet r;
603         struct netlogon_creds_CredentialState *creds;
604         struct netr_Authenticator credential;
605         NTSTATUS status;
606         struct netr_Authenticator return_authenticator;
607         struct samr_Password password;
608
609         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
610                 return false;
611         }
612
613         netlogon_creds_client_authenticator(creds, &credential);
614
615         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
616         r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
617         r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
618         r.in.computer_name = TEST_MACHINE_NAME;
619         r.in.credential = &credential;
620         r.out.return_authenticator = &return_authenticator;
621         r.out.password = &password;
622
623         status = dcerpc_netr_ServerPasswordGet(p, tctx, &r);
624         torture_assert_ntstatus_ok(tctx, status, "ServerPasswordGet");
625
626         return true;
627 }
628
629 static bool test_GetTrustPasswords(struct torture_context *tctx,
630                                    struct dcerpc_pipe *p,
631                                    struct cli_credentials *machine_credentials)
632 {
633         struct netr_ServerTrustPasswordsGet r;
634         struct netlogon_creds_CredentialState *creds;
635         struct netr_Authenticator credential;
636         NTSTATUS status;
637         struct netr_Authenticator return_authenticator;
638         struct samr_Password password, password2;
639
640         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
641                 return false;
642         }
643
644         netlogon_creds_client_authenticator(creds, &credential);
645
646         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
647         r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
648         r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
649         r.in.computer_name = TEST_MACHINE_NAME;
650         r.in.credential = &credential;
651         r.out.return_authenticator = &return_authenticator;
652         r.out.password = &password;
653         r.out.password2 = &password2;
654
655         status = dcerpc_netr_ServerTrustPasswordsGet(p, tctx, &r);
656         torture_assert_ntstatus_ok(tctx, status, "ServerTrustPasswordsGet");
657
658         return true;
659 }
660
661 /*
662   try a netlogon SamLogon
663 */
664 bool test_netlogon_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
665                               struct cli_credentials *credentials, 
666                               struct netlogon_creds_CredentialState *creds)
667 {
668         NTSTATUS status;
669         struct netr_LogonSamLogon r;
670         struct netr_Authenticator auth, auth2;
671         union netr_LogonLevel logon;
672         union netr_Validation validation;
673         uint8_t authoritative;
674         struct netr_NetworkInfo ninfo;
675         DATA_BLOB names_blob, chal, lm_resp, nt_resp;
676         int i;
677         int flags = CLI_CRED_NTLM_AUTH;
678         if (lp_client_lanman_auth(tctx->lp_ctx)) {
679                 flags |= CLI_CRED_LANMAN_AUTH;
680         }
681
682         if (lp_client_ntlmv2_auth(tctx->lp_ctx)) {
683                 flags |= CLI_CRED_NTLMv2_AUTH;
684         }
685
686         cli_credentials_get_ntlm_username_domain(cmdline_credentials, tctx, 
687                                                  &ninfo.identity_info.account_name.string,
688                                                  &ninfo.identity_info.domain_name.string);
689         
690         generate_random_buffer(ninfo.challenge, 
691                                sizeof(ninfo.challenge));
692         chal = data_blob_const(ninfo.challenge, 
693                                sizeof(ninfo.challenge));
694
695         names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(credentials), 
696                                                 cli_credentials_get_domain(credentials));
697
698         status = cli_credentials_get_ntlm_response(cmdline_credentials, tctx, 
699                                                    &flags, 
700                                                    chal,
701                                                    names_blob,
702                                                    &lm_resp, &nt_resp,
703                                                    NULL, NULL);
704         torture_assert_ntstatus_ok(tctx, status, "cli_credentials_get_ntlm_response failed");
705
706         ninfo.lm.data = lm_resp.data;
707         ninfo.lm.length = lm_resp.length;
708
709         ninfo.nt.data = nt_resp.data;
710         ninfo.nt.length = nt_resp.length;
711
712         ninfo.identity_info.parameter_control = 0;
713         ninfo.identity_info.logon_id_low = 0;
714         ninfo.identity_info.logon_id_high = 0;
715         ninfo.identity_info.workstation.string = cli_credentials_get_workstation(credentials);
716
717         logon.network = &ninfo;
718
719         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
720         r.in.computer_name = cli_credentials_get_workstation(credentials);
721         r.in.credential = &auth;
722         r.in.return_authenticator = &auth2;
723         r.in.logon_level = 2;
724         r.in.logon = &logon;
725         r.out.validation = &validation;
726         r.out.authoritative = &authoritative;
727
728         d_printf("Testing LogonSamLogon with name %s\n", ninfo.identity_info.account_name.string);
729         
730         for (i=2;i<3;i++) {
731                 ZERO_STRUCT(auth2);
732                 netlogon_creds_client_authenticator(creds, &auth);
733                 
734                 r.in.validation_level = i;
735                 
736                 status = dcerpc_netr_LogonSamLogon(p, tctx, &r);
737                 torture_assert_ntstatus_ok(tctx, status, "LogonSamLogon failed");
738                 
739                 torture_assert(tctx, netlogon_creds_client_check(creds, 
740                                                                  &r.out.return_authenticator->cred), 
741                         "Credential chaining failed");
742         }
743
744         r.in.credential = NULL;
745
746         for (i=2;i<=3;i++) {
747
748                 r.in.validation_level = i;
749
750                 torture_comment(tctx, "Testing SamLogon with validation level %d and a NULL credential\n", i);
751
752                 status = dcerpc_netr_LogonSamLogon(p, tctx, &r);
753                 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_INVALID_PARAMETER, 
754                         "LogonSamLogon expected INVALID_PARAMETER");
755
756         }
757
758         return true;
759 }
760
761 /*
762   try a netlogon SamLogon
763 */
764 static bool test_SamLogon(struct torture_context *tctx, 
765                           struct dcerpc_pipe *p,
766                           struct cli_credentials *credentials)
767 {
768         struct netlogon_creds_CredentialState *creds;
769
770         if (!test_SetupCredentials(p, tctx, credentials, &creds)) {
771                 return false;
772         }
773
774         return test_netlogon_ops(p, tctx, credentials, creds);
775 }
776
777 /* we remember the sequence numbers so we can easily do a DatabaseDelta */
778 static uint64_t sequence_nums[3];
779
780 /*
781   try a netlogon DatabaseSync
782 */
783 static bool test_DatabaseSync(struct torture_context *tctx, 
784                               struct dcerpc_pipe *p,
785                               struct cli_credentials *machine_credentials)
786 {
787         NTSTATUS status;
788         struct netr_DatabaseSync r;
789         struct netlogon_creds_CredentialState *creds;
790         const uint32_t database_ids[] = {SAM_DATABASE_DOMAIN, SAM_DATABASE_BUILTIN, SAM_DATABASE_PRIVS}; 
791         int i;
792         struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
793         struct netr_Authenticator credential, return_authenticator;
794
795         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
796                 return false;
797         }
798
799         ZERO_STRUCT(return_authenticator);
800
801         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
802         r.in.computername = TEST_MACHINE_NAME;
803         r.in.preferredmaximumlength = (uint32_t)-1;
804         r.in.return_authenticator = &return_authenticator;
805         r.out.delta_enum_array = &delta_enum_array;
806         r.out.return_authenticator = &return_authenticator;
807
808         for (i=0;i<ARRAY_SIZE(database_ids);i++) {
809
810                 uint32_t sync_context = 0;
811
812                 r.in.database_id = database_ids[i];
813                 r.in.sync_context = &sync_context;
814                 r.out.sync_context = &sync_context;
815
816                 torture_comment(tctx, "Testing DatabaseSync of id %d\n", r.in.database_id);
817
818                 do {
819                         netlogon_creds_client_authenticator(creds, &credential);
820
821                         r.in.credential = &credential;
822
823                         status = dcerpc_netr_DatabaseSync(p, tctx, &r);
824                         if (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
825                             break;
826
827                         /* Native mode servers don't do this */
828                         if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
829                                 return true;
830                         }
831                         torture_assert_ntstatus_ok(tctx, status, "DatabaseSync");
832
833                         if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
834                                 torture_comment(tctx, "Credential chaining failed\n");
835                         }
836
837                         if (delta_enum_array &&
838                             delta_enum_array->num_deltas > 0 &&
839                             delta_enum_array->delta_enum[0].delta_type == NETR_DELTA_DOMAIN &&
840                             delta_enum_array->delta_enum[0].delta_union.domain) {
841                                 sequence_nums[r.in.database_id] = 
842                                         delta_enum_array->delta_enum[0].delta_union.domain->sequence_num;
843                                 torture_comment(tctx, "\tsequence_nums[%d]=%llu\n",
844                                        r.in.database_id, 
845                                        (unsigned long long)sequence_nums[r.in.database_id]);
846                         }
847                 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
848         }
849
850         return true;
851 }
852
853
854 /*
855   try a netlogon DatabaseDeltas
856 */
857 static bool test_DatabaseDeltas(struct torture_context *tctx, 
858                                 struct dcerpc_pipe *p,
859                                 struct cli_credentials *machine_credentials)
860 {
861         NTSTATUS status;
862         struct netr_DatabaseDeltas r;
863         struct netlogon_creds_CredentialState *creds;
864         struct netr_Authenticator credential;
865         struct netr_Authenticator return_authenticator;
866         struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
867         const uint32_t database_ids[] = {0, 1, 2}; 
868         int i;
869
870         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
871                 return false;
872         }
873
874         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
875         r.in.computername = TEST_MACHINE_NAME;
876         r.in.preferredmaximumlength = (uint32_t)-1;
877         ZERO_STRUCT(r.in.return_authenticator);
878         r.out.return_authenticator = &return_authenticator;
879         r.out.delta_enum_array = &delta_enum_array;
880
881         for (i=0;i<ARRAY_SIZE(database_ids);i++) {
882                 r.in.database_id = database_ids[i];
883                 r.in.sequence_num = &sequence_nums[r.in.database_id];
884
885                 if (*r.in.sequence_num == 0) continue;
886
887                 *r.in.sequence_num -= 1;
888
889                 torture_comment(tctx, "Testing DatabaseDeltas of id %d at %llu\n", 
890                        r.in.database_id, (unsigned long long)*r.in.sequence_num);
891
892                 do {
893                         netlogon_creds_client_authenticator(creds, &credential);
894
895                         status = dcerpc_netr_DatabaseDeltas(p, tctx, &r);
896                         if (NT_STATUS_EQUAL(status, 
897                                              NT_STATUS_SYNCHRONIZATION_REQUIRED)) {
898                                 torture_comment(tctx, "not considering %s to be an error\n",
899                                        nt_errstr(status));
900                                 return true;
901                         }
902                         if (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) 
903                             break;
904
905                         torture_assert_ntstatus_ok(tctx, status, "DatabaseDeltas");
906
907                         if (!netlogon_creds_client_check(creds, &return_authenticator.cred)) {
908                                 torture_comment(tctx, "Credential chaining failed\n");
909                         }
910
911                         (*r.in.sequence_num)++;
912                 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
913         }
914
915         return true;
916 }
917
918 static bool test_DatabaseRedo(struct torture_context *tctx,
919                               struct dcerpc_pipe *p,
920                               struct cli_credentials *machine_credentials)
921 {
922         NTSTATUS status;
923         struct netr_DatabaseRedo r;
924         struct netlogon_creds_CredentialState *creds;
925         struct netr_Authenticator credential;
926         struct netr_Authenticator return_authenticator;
927         struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
928         struct netr_ChangeLogEntry e;
929         struct dom_sid null_sid, *sid;
930         int i,d;
931
932         ZERO_STRUCT(null_sid);
933
934         sid = dom_sid_parse_talloc(tctx, "S-1-5-21-1111111111-2222222222-333333333-500");
935
936         {
937
938         struct {
939                 uint32_t rid;
940                 uint16_t flags;
941                 uint8_t db_index;
942                 uint8_t delta_type;
943                 struct dom_sid sid;
944                 const char *name;
945                 NTSTATUS expected_error;
946                 uint32_t expected_num_results;
947                 uint8_t expected_delta_type_1;
948                 uint8_t expected_delta_type_2;
949                 const char *comment;
950         } changes[] = {
951
952                 /* SAM_DATABASE_DOMAIN */
953
954                 {
955                         .rid                    = 0,
956                         .flags                  = 0,
957                         .db_index               = SAM_DATABASE_DOMAIN,
958                         .delta_type             = NETR_DELTA_MODIFY_COUNT,
959                         .sid                    = null_sid,
960                         .name                   = NULL,
961                         .expected_error         = NT_STATUS_SYNCHRONIZATION_REQUIRED,
962                         .expected_num_results   = 0,
963                         .comment                = "NETR_DELTA_MODIFY_COUNT"
964                 },
965                 {
966                         .rid                    = 0,
967                         .flags                  = 0,
968                         .db_index               = SAM_DATABASE_DOMAIN,
969                         .delta_type             = 0,
970                         .sid                    = null_sid,
971                         .name                   = NULL,
972                         .expected_error         = NT_STATUS_OK,
973                         .expected_num_results   = 1,
974                         .expected_delta_type_1  = NETR_DELTA_DOMAIN,
975                         .comment                = "NULL DELTA"
976                 },
977                 {
978                         .rid                    = 0,
979                         .flags                  = 0,
980                         .db_index               = SAM_DATABASE_DOMAIN,
981                         .delta_type             = NETR_DELTA_DOMAIN,
982                         .sid                    = null_sid,
983                         .name                   = NULL,
984                         .expected_error         = NT_STATUS_OK,
985                         .expected_num_results   = 1,
986                         .expected_delta_type_1  = NETR_DELTA_DOMAIN,
987                         .comment                = "NETR_DELTA_DOMAIN"
988                 },
989                 {
990                         .rid                    = DOMAIN_RID_ADMINISTRATOR,
991                         .flags                  = 0,
992                         .db_index               = SAM_DATABASE_DOMAIN,
993                         .delta_type             = NETR_DELTA_USER,
994                         .sid                    = null_sid,
995                         .name                   = NULL,
996                         .expected_error         = NT_STATUS_OK,
997                         .expected_num_results   = 1,
998                         .expected_delta_type_1  = NETR_DELTA_USER,
999                         .comment                = "NETR_DELTA_USER by rid 500"
1000                 },
1001                 {
1002                         .rid                    = DOMAIN_RID_GUEST,
1003                         .flags                  = 0,
1004                         .db_index               = SAM_DATABASE_DOMAIN,
1005                         .delta_type             = NETR_DELTA_USER,
1006                         .sid                    = null_sid,
1007                         .name                   = NULL,
1008                         .expected_error         = NT_STATUS_OK,
1009                         .expected_num_results   = 1,
1010                         .expected_delta_type_1  = NETR_DELTA_USER,
1011                         .comment                = "NETR_DELTA_USER by rid 501"
1012                 },
1013                 {
1014                         .rid                    = 0,
1015                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
1016                         .db_index               = SAM_DATABASE_DOMAIN,
1017                         .delta_type             = NETR_DELTA_USER,
1018                         .sid                    = *sid,
1019                         .name                   = NULL,
1020                         .expected_error         = NT_STATUS_OK,
1021                         .expected_num_results   = 1,
1022                         .expected_delta_type_1  = NETR_DELTA_DELETE_USER,
1023                         .comment                = "NETR_DELTA_USER by sid and flags"
1024                 },
1025                 {
1026                         .rid                    = 0,
1027                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
1028                         .db_index               = SAM_DATABASE_DOMAIN,
1029                         .delta_type             = NETR_DELTA_USER,
1030                         .sid                    = null_sid,
1031                         .name                   = NULL,
1032                         .expected_error         = NT_STATUS_OK,
1033                         .expected_num_results   = 1,
1034                         .expected_delta_type_1  = NETR_DELTA_DELETE_USER,
1035                         .comment                = "NETR_DELTA_USER by null_sid and flags"
1036                 },
1037                 {
1038                         .rid                    = 0,
1039                         .flags                  = NETR_CHANGELOG_NAME_INCLUDED,
1040                         .db_index               = SAM_DATABASE_DOMAIN,
1041                         .delta_type             = NETR_DELTA_USER,
1042                         .sid                    = null_sid,
1043                         .name                   = "administrator",
1044                         .expected_error         = NT_STATUS_OK,
1045                         .expected_num_results   = 1,
1046                         .expected_delta_type_1  = NETR_DELTA_DELETE_USER,
1047                         .comment                = "NETR_DELTA_USER by name 'administrator'"
1048                 },
1049                 {
1050                         .rid                    = DOMAIN_RID_ADMINS,
1051                         .flags                  = 0,
1052                         .db_index               = SAM_DATABASE_DOMAIN,
1053                         .delta_type             = NETR_DELTA_GROUP,
1054                         .sid                    = null_sid,
1055                         .name                   = NULL,
1056                         .expected_error         = NT_STATUS_OK,
1057                         .expected_num_results   = 2,
1058                         .expected_delta_type_1  = NETR_DELTA_GROUP,
1059                         .expected_delta_type_2  = NETR_DELTA_GROUP_MEMBER,
1060                         .comment                = "NETR_DELTA_GROUP by rid 512"
1061                 },
1062                 {
1063                         .rid                    = DOMAIN_RID_ADMINS,
1064                         .flags                  = 0,
1065                         .db_index               = SAM_DATABASE_DOMAIN,
1066                         .delta_type             = NETR_DELTA_GROUP_MEMBER,
1067                         .sid                    = null_sid,
1068                         .name                   = NULL,
1069                         .expected_error         = NT_STATUS_OK,
1070                         .expected_num_results   = 2,
1071                         .expected_delta_type_1  = NETR_DELTA_GROUP,
1072                         .expected_delta_type_2  = NETR_DELTA_GROUP_MEMBER,
1073                         .comment                = "NETR_DELTA_GROUP_MEMBER by rid 512"
1074                 },
1075
1076
1077                 /* SAM_DATABASE_BUILTIN */
1078
1079                 {
1080                         .rid                    = 0,
1081                         .flags                  = 0,
1082                         .db_index               = SAM_DATABASE_BUILTIN,
1083                         .delta_type             = NETR_DELTA_MODIFY_COUNT,
1084                         .sid                    = null_sid,
1085                         .name                   = NULL,
1086                         .expected_error         = NT_STATUS_SYNCHRONIZATION_REQUIRED,
1087                         .expected_num_results   = 0,
1088                         .comment                = "NETR_DELTA_MODIFY_COUNT"
1089                 },
1090                 {
1091                         .rid                    = 0,
1092                         .flags                  = 0,
1093                         .db_index               = SAM_DATABASE_BUILTIN,
1094                         .delta_type             = NETR_DELTA_DOMAIN,
1095                         .sid                    = null_sid,
1096                         .name                   = NULL,
1097                         .expected_error         = NT_STATUS_OK,
1098                         .expected_num_results   = 1,
1099                         .expected_delta_type_1  = NETR_DELTA_DOMAIN,
1100                         .comment                = "NETR_DELTA_DOMAIN"
1101                 },
1102                 {
1103                         .rid                    = DOMAIN_RID_ADMINISTRATOR,
1104                         .flags                  = 0,
1105                         .db_index               = SAM_DATABASE_BUILTIN,
1106                         .delta_type             = NETR_DELTA_USER,
1107                         .sid                    = null_sid,
1108                         .name                   = NULL,
1109                         .expected_error         = NT_STATUS_OK,
1110                         .expected_num_results   = 1,
1111                         .expected_delta_type_1  = NETR_DELTA_DELETE_USER,
1112                         .comment                = "NETR_DELTA_USER by rid 500"
1113                 },
1114                 {
1115                         .rid                    = 0,
1116                         .flags                  = 0,
1117                         .db_index               = SAM_DATABASE_BUILTIN,
1118                         .delta_type             = NETR_DELTA_USER,
1119                         .sid                    = null_sid,
1120                         .name                   = NULL,
1121                         .expected_error         = NT_STATUS_OK,
1122                         .expected_num_results   = 1,
1123                         .expected_delta_type_1  = NETR_DELTA_DELETE_USER,
1124                         .comment                = "NETR_DELTA_USER"
1125                 },
1126                 {
1127                         .rid                    = 544,
1128                         .flags                  = 0,
1129                         .db_index               = SAM_DATABASE_BUILTIN,
1130                         .delta_type             = NETR_DELTA_ALIAS,
1131                         .sid                    = null_sid,
1132                         .name                   = NULL,
1133                         .expected_error         = NT_STATUS_OK,
1134                         .expected_num_results   = 2,
1135                         .expected_delta_type_1  = NETR_DELTA_ALIAS,
1136                         .expected_delta_type_2  = NETR_DELTA_ALIAS_MEMBER,
1137                         .comment                = "NETR_DELTA_ALIAS by rid 544"
1138                 },
1139                 {
1140                         .rid                    = 544,
1141                         .flags                  = 0,
1142                         .db_index               = SAM_DATABASE_BUILTIN,
1143                         .delta_type             = NETR_DELTA_ALIAS_MEMBER,
1144                         .sid                    = null_sid,
1145                         .name                   = NULL,
1146                         .expected_error         = NT_STATUS_OK,
1147                         .expected_num_results   = 2,
1148                         .expected_delta_type_1  = NETR_DELTA_ALIAS,
1149                         .expected_delta_type_2  = NETR_DELTA_ALIAS_MEMBER,
1150                         .comment                = "NETR_DELTA_ALIAS_MEMBER by rid 544"
1151                 },
1152                 {
1153                         .rid                    = 544,
1154                         .flags                  = 0,
1155                         .db_index               = SAM_DATABASE_BUILTIN,
1156                         .delta_type             = 0,
1157                         .sid                    = null_sid,
1158                         .name                   = NULL,
1159                         .expected_error         = NT_STATUS_OK,
1160                         .expected_num_results   = 1,
1161                         .expected_delta_type_1  = NETR_DELTA_DOMAIN,
1162                         .comment                = "NULL DELTA by rid 544"
1163                 },
1164                 {
1165                         .rid                    = 544,
1166                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
1167                         .db_index               = SAM_DATABASE_BUILTIN,
1168                         .delta_type             = 0,
1169                         .sid                    = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
1170                         .name                   = NULL,
1171                         .expected_error         = NT_STATUS_OK,
1172                         .expected_num_results   = 1,
1173                         .expected_delta_type_1  = NETR_DELTA_DOMAIN,
1174                         .comment                = "NULL DELTA by rid 544 sid S-1-5-32-544 and flags"
1175                 },
1176                 {
1177                         .rid                    = 544,
1178                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
1179                         .db_index               = SAM_DATABASE_BUILTIN,
1180                         .delta_type             = NETR_DELTA_ALIAS,
1181                         .sid                    = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
1182                         .name                   = NULL,
1183                         .expected_error         = NT_STATUS_OK,
1184                         .expected_num_results   = 2,
1185                         .expected_delta_type_1  = NETR_DELTA_ALIAS,
1186                         .expected_delta_type_2  = NETR_DELTA_ALIAS_MEMBER,
1187                         .comment                = "NETR_DELTA_ALIAS by rid 544 and sid S-1-5-32-544 and flags"
1188                 },
1189                 {
1190                         .rid                    = 0,
1191                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
1192                         .db_index               = SAM_DATABASE_BUILTIN,
1193                         .delta_type             = NETR_DELTA_ALIAS,
1194                         .sid                    = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
1195                         .name                   = NULL,
1196                         .expected_error         = NT_STATUS_OK,
1197                         .expected_num_results   = 1,
1198                         .expected_delta_type_1  = NETR_DELTA_DELETE_ALIAS,
1199                         .comment                = "NETR_DELTA_ALIAS by sid S-1-5-32-544 and flags"
1200                 },
1201
1202                 /* SAM_DATABASE_PRIVS */
1203
1204                 {
1205                         .rid                    = 0,
1206                         .flags                  = 0,
1207                         .db_index               = SAM_DATABASE_PRIVS,
1208                         .delta_type             = 0,
1209                         .sid                    = null_sid,
1210                         .name                   = NULL,
1211                         .expected_error         = NT_STATUS_ACCESS_DENIED,
1212                         .expected_num_results   = 0,
1213                         .comment                = "NULL DELTA"
1214                 },
1215                 {
1216                         .rid                    = 0,
1217                         .flags                  = 0,
1218                         .db_index               = SAM_DATABASE_PRIVS,
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_PRIVS,
1230                         .delta_type             = NETR_DELTA_POLICY,
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_POLICY,
1236                         .comment                = "NETR_DELTA_POLICY"
1237                 },
1238                 {
1239                         .rid                    = 0,
1240                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
1241                         .db_index               = SAM_DATABASE_PRIVS,
1242                         .delta_type             = NETR_DELTA_POLICY,
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_POLICY,
1248                         .comment                = "NETR_DELTA_POLICY by null sid and flags"
1249                 },
1250                 {
1251                         .rid                    = 0,
1252                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
1253                         .db_index               = SAM_DATABASE_PRIVS,
1254                         .delta_type             = NETR_DELTA_POLICY,
1255                         .sid                    = *dom_sid_parse_talloc(tctx, "S-1-5-32"),
1256                         .name                   = NULL,
1257                         .expected_error         = NT_STATUS_OK,
1258                         .expected_num_results   = 1,
1259                         .expected_delta_type_1  = NETR_DELTA_POLICY,
1260                         .comment                = "NETR_DELTA_POLICY by sid S-1-5-32 and flags"
1261                 },
1262                 {
1263                         .rid                    = DOMAIN_RID_ADMINISTRATOR,
1264                         .flags                  = 0,
1265                         .db_index               = SAM_DATABASE_PRIVS,
1266                         .delta_type             = NETR_DELTA_ACCOUNT,
1267                         .sid                    = null_sid,
1268                         .name                   = NULL,
1269                         .expected_error         = NT_STATUS_SYNCHRONIZATION_REQUIRED, /* strange */
1270                         .expected_num_results   = 0,
1271                         .comment                = "NETR_DELTA_ACCOUNT by rid 500"
1272                 },
1273                 {
1274                         .rid                    = 0,
1275                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
1276                         .db_index               = SAM_DATABASE_PRIVS,
1277                         .delta_type             = NETR_DELTA_ACCOUNT,
1278                         .sid                    = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
1279                         .name                   = NULL,
1280                         .expected_error         = NT_STATUS_OK,
1281                         .expected_num_results   = 1,
1282                         .expected_delta_type_1  = NETR_DELTA_ACCOUNT,
1283                         .comment                = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and flags"
1284                 },
1285                 {
1286                         .rid                    = 0,
1287                         .flags                  = NETR_CHANGELOG_SID_INCLUDED |
1288                                                   NETR_CHANGELOG_IMMEDIATE_REPL_REQUIRED,
1289                         .db_index               = SAM_DATABASE_PRIVS,
1290                         .delta_type             = NETR_DELTA_ACCOUNT,
1291                         .sid                    = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
1292                         .name                   = NULL,
1293                         .expected_error         = NT_STATUS_OK,
1294                         .expected_num_results   = 1,
1295                         .expected_delta_type_1  = NETR_DELTA_ACCOUNT,
1296                         .comment                = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and 2 flags"
1297                 },
1298                 {
1299                         .rid                    = 0,
1300                         .flags                  = NETR_CHANGELOG_SID_INCLUDED |
1301                                                   NETR_CHANGELOG_NAME_INCLUDED,
1302                         .db_index               = SAM_DATABASE_PRIVS,
1303                         .delta_type             = NETR_DELTA_ACCOUNT,
1304                         .sid                    = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
1305                         .name                   = NULL,
1306                         .expected_error         = NT_STATUS_INVALID_PARAMETER,
1307                         .expected_num_results   = 0,
1308                         .comment                = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and invalid flags"
1309                 },
1310                 {
1311                         .rid                    = DOMAIN_RID_ADMINISTRATOR,
1312                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
1313                         .db_index               = SAM_DATABASE_PRIVS,
1314                         .delta_type             = NETR_DELTA_ACCOUNT,
1315                         .sid                    = *sid,
1316                         .name                   = NULL,
1317                         .expected_error         = NT_STATUS_OK,
1318                         .expected_num_results   = 1,
1319                         .expected_delta_type_1  = NETR_DELTA_DELETE_ACCOUNT,
1320                         .comment                = "NETR_DELTA_ACCOUNT by rid 500, sid and flags"
1321                 },
1322                 {
1323                         .rid                    = 0,
1324                         .flags                  = NETR_CHANGELOG_NAME_INCLUDED,
1325                         .db_index               = SAM_DATABASE_PRIVS,
1326                         .delta_type             = NETR_DELTA_SECRET,
1327                         .sid                    = null_sid,
1328                         .name                   = "IsurelydontexistIhope",
1329                         .expected_error         = NT_STATUS_OK,
1330                         .expected_num_results   = 1,
1331                         .expected_delta_type_1  = NETR_DELTA_DELETE_SECRET,
1332                         .comment                = "NETR_DELTA_SECRET by name 'IsurelydontexistIhope' and flags"
1333                 },
1334                 {
1335                         .rid                    = 0,
1336                         .flags                  = NETR_CHANGELOG_NAME_INCLUDED,
1337                         .db_index               = SAM_DATABASE_PRIVS,
1338                         .delta_type             = NETR_DELTA_SECRET,
1339                         .sid                    = null_sid,
1340                         .name                   = "G$BCKUPKEY_P",
1341                         .expected_error         = NT_STATUS_OK,
1342                         .expected_num_results   = 1,
1343                         .expected_delta_type_1  = NETR_DELTA_SECRET,
1344                         .comment                = "NETR_DELTA_SECRET by name 'G$BCKUPKEY_P' and flags"
1345                 }
1346         };
1347
1348         ZERO_STRUCT(return_authenticator);
1349
1350         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1351         r.in.computername = TEST_MACHINE_NAME;
1352         r.in.return_authenticator = &return_authenticator;
1353         r.out.return_authenticator = &return_authenticator;
1354         r.out.delta_enum_array = &delta_enum_array;
1355
1356         for (d=0; d<3; d++) {
1357
1358                 const char *database;
1359
1360                 switch (d) {
1361                 case 0:
1362                         database = "SAM";
1363                         break;
1364                 case 1:
1365                         database = "BUILTIN";
1366                         break;
1367                 case 2:
1368                         database = "LSA";
1369                         break;
1370                 default:
1371                         break;
1372                 }
1373
1374                 torture_comment(tctx, "Testing DatabaseRedo\n");
1375
1376                 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1377                         return false;
1378                 }
1379
1380                 for (i=0;i<ARRAY_SIZE(changes);i++) {
1381
1382                         if (d != changes[i].db_index) {
1383                                 continue;
1384                         }
1385
1386                         netlogon_creds_client_authenticator(creds, &credential);
1387
1388                         r.in.credential = &credential;
1389
1390                         e.serial_number1        = 0;
1391                         e.serial_number2        = 0;
1392                         e.object_rid            = changes[i].rid;
1393                         e.flags                 = changes[i].flags;
1394                         e.db_index              = changes[i].db_index;
1395                         e.delta_type            = changes[i].delta_type;
1396
1397                         switch (changes[i].flags & (NETR_CHANGELOG_NAME_INCLUDED | NETR_CHANGELOG_SID_INCLUDED)) {
1398                         case NETR_CHANGELOG_SID_INCLUDED:
1399                                 e.object.object_sid             = changes[i].sid;
1400                                 break;
1401                         case NETR_CHANGELOG_NAME_INCLUDED:
1402                                 e.object.object_name            = changes[i].name;
1403                                 break;
1404                         default:
1405                                 break;
1406                         }
1407
1408                         r.in.change_log_entry = e;
1409
1410                         torture_comment(tctx, "Testing DatabaseRedo with database %s and %s\n",
1411                                 database, changes[i].comment);
1412
1413                         status = dcerpc_netr_DatabaseRedo(p, tctx, &r);
1414                         if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
1415                                 return true;
1416                         }
1417
1418                         torture_assert_ntstatus_equal(tctx, status, changes[i].expected_error, changes[i].comment);
1419                         if (delta_enum_array) {
1420                                 torture_assert_int_equal(tctx,
1421                                         delta_enum_array->num_deltas,
1422                                         changes[i].expected_num_results,
1423                                         changes[i].comment);
1424                                 if (delta_enum_array->num_deltas > 0) {
1425                                         torture_assert_int_equal(tctx,
1426                                                 delta_enum_array->delta_enum[0].delta_type,
1427                                                 changes[i].expected_delta_type_1,
1428                                                 changes[i].comment);
1429                                 }
1430                                 if (delta_enum_array->num_deltas > 1) {
1431                                         torture_assert_int_equal(tctx,
1432                                                 delta_enum_array->delta_enum[1].delta_type,
1433                                                 changes[i].expected_delta_type_2,
1434                                                 changes[i].comment);
1435                                 }
1436                         }
1437
1438                         if (!netlogon_creds_client_check(creds, &return_authenticator.cred)) {
1439                                 torture_comment(tctx, "Credential chaining failed\n");
1440                                 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1441                                         return false;
1442                                 }
1443                         }
1444                 }
1445         }
1446         }
1447
1448         return true;
1449 }
1450
1451 /*
1452   try a netlogon AccountDeltas
1453 */
1454 static bool test_AccountDeltas(struct torture_context *tctx, 
1455                                struct dcerpc_pipe *p,
1456                                struct cli_credentials *machine_credentials)
1457 {
1458         NTSTATUS status;
1459         struct netr_AccountDeltas r;
1460         struct netlogon_creds_CredentialState *creds;
1461
1462         struct netr_AccountBuffer buffer;
1463         uint32_t count_returned = 0;
1464         uint32_t total_entries = 0;
1465         struct netr_UAS_INFO_0 recordid;
1466         struct netr_Authenticator return_authenticator;
1467
1468         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1469                 return false;
1470         }
1471
1472         ZERO_STRUCT(return_authenticator);
1473
1474         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1475         r.in.computername = TEST_MACHINE_NAME;
1476         r.in.return_authenticator = &return_authenticator;
1477         netlogon_creds_client_authenticator(creds, &r.in.credential);
1478         ZERO_STRUCT(r.in.uas);
1479         r.in.count=10;
1480         r.in.level=0;
1481         r.in.buffersize=100;
1482         r.out.buffer = &buffer;
1483         r.out.count_returned = &count_returned;
1484         r.out.total_entries = &total_entries;
1485         r.out.recordid = &recordid;
1486         r.out.return_authenticator = &return_authenticator;
1487
1488         /* w2k3 returns "NOT IMPLEMENTED" for this call */
1489         status = dcerpc_netr_AccountDeltas(p, tctx, &r);
1490         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "AccountDeltas");
1491
1492         return true;
1493 }
1494
1495 /*
1496   try a netlogon AccountSync
1497 */
1498 static bool test_AccountSync(struct torture_context *tctx, struct dcerpc_pipe *p, 
1499                              struct cli_credentials *machine_credentials)
1500 {
1501         NTSTATUS status;
1502         struct netr_AccountSync r;
1503         struct netlogon_creds_CredentialState *creds;
1504
1505         struct netr_AccountBuffer buffer;
1506         uint32_t count_returned = 0;
1507         uint32_t total_entries = 0;
1508         uint32_t next_reference = 0;
1509         struct netr_UAS_INFO_0 recordid;
1510         struct netr_Authenticator return_authenticator;
1511
1512         ZERO_STRUCT(recordid);
1513         ZERO_STRUCT(return_authenticator);
1514
1515         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1516                 return false;
1517         }
1518
1519         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1520         r.in.computername = TEST_MACHINE_NAME;
1521         r.in.return_authenticator = &return_authenticator;
1522         netlogon_creds_client_authenticator(creds, &r.in.credential);
1523         r.in.recordid = &recordid;
1524         r.in.reference=0;
1525         r.in.level=0;
1526         r.in.buffersize=100;
1527         r.out.buffer = &buffer;
1528         r.out.count_returned = &count_returned;
1529         r.out.total_entries = &total_entries;
1530         r.out.next_reference = &next_reference;
1531         r.out.recordid = &recordid;
1532         r.out.return_authenticator = &return_authenticator;
1533
1534         /* w2k3 returns "NOT IMPLEMENTED" for this call */
1535         status = dcerpc_netr_AccountSync(p, tctx, &r);
1536         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "AccountSync");
1537
1538         return true;
1539 }
1540
1541 /*
1542   try a netlogon GetDcName
1543 */
1544 static bool test_GetDcName(struct torture_context *tctx, 
1545                            struct dcerpc_pipe *p)
1546 {
1547         NTSTATUS status;
1548         struct netr_GetDcName r;
1549         const char *dcname = NULL;
1550
1551         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1552         r.in.domainname = lp_workgroup(tctx->lp_ctx);
1553         r.out.dcname = &dcname;
1554
1555         status = dcerpc_netr_GetDcName(p, tctx, &r);
1556         torture_assert_ntstatus_ok(tctx, status, "GetDcName");
1557         torture_assert_werr_ok(tctx, r.out.result, "GetDcName");
1558
1559         torture_comment(tctx, "\tDC is at '%s'\n", dcname);
1560
1561         return true;
1562 }
1563
1564 static const char *function_code_str(TALLOC_CTX *mem_ctx,
1565                                      enum netr_LogonControlCode function_code)
1566 {
1567         switch (function_code) {
1568         case NETLOGON_CONTROL_QUERY:
1569                 return "NETLOGON_CONTROL_QUERY";
1570         case NETLOGON_CONTROL_REPLICATE:
1571                 return "NETLOGON_CONTROL_REPLICATE";
1572         case NETLOGON_CONTROL_SYNCHRONIZE:
1573                 return "NETLOGON_CONTROL_SYNCHRONIZE";
1574         case NETLOGON_CONTROL_PDC_REPLICATE:
1575                 return "NETLOGON_CONTROL_PDC_REPLICATE";
1576         case NETLOGON_CONTROL_REDISCOVER:
1577                 return "NETLOGON_CONTROL_REDISCOVER";
1578         case NETLOGON_CONTROL_TC_QUERY:
1579                 return "NETLOGON_CONTROL_TC_QUERY";
1580         case NETLOGON_CONTROL_TRANSPORT_NOTIFY:
1581                 return "NETLOGON_CONTROL_TRANSPORT_NOTIFY";
1582         case NETLOGON_CONTROL_FIND_USER:
1583                 return "NETLOGON_CONTROL_FIND_USER";
1584         case NETLOGON_CONTROL_CHANGE_PASSWORD:
1585                 return "NETLOGON_CONTROL_CHANGE_PASSWORD";
1586         case NETLOGON_CONTROL_TC_VERIFY:
1587                 return "NETLOGON_CONTROL_TC_VERIFY";
1588         case NETLOGON_CONTROL_FORCE_DNS_REG:
1589                 return "NETLOGON_CONTROL_FORCE_DNS_REG";
1590         case NETLOGON_CONTROL_QUERY_DNS_REG:
1591                 return "NETLOGON_CONTROL_QUERY_DNS_REG";
1592         case NETLOGON_CONTROL_BACKUP_CHANGE_LOG:
1593                 return "NETLOGON_CONTROL_BACKUP_CHANGE_LOG";
1594         case NETLOGON_CONTROL_TRUNCATE_LOG:
1595                 return "NETLOGON_CONTROL_TRUNCATE_LOG";
1596         case NETLOGON_CONTROL_SET_DBFLAG:
1597                 return "NETLOGON_CONTROL_SET_DBFLAG";
1598         case NETLOGON_CONTROL_BREAKPOINT:
1599                 return "NETLOGON_CONTROL_BREAKPOINT";
1600         default:
1601                 return talloc_asprintf(mem_ctx, "unknown function code: %d",
1602                                        function_code);
1603         }
1604 }
1605
1606
1607 /*
1608   try a netlogon LogonControl 
1609 */
1610 static bool test_LogonControl(struct torture_context *tctx, 
1611                               struct dcerpc_pipe *p,
1612                               struct cli_credentials *machine_credentials)
1613
1614 {
1615         NTSTATUS status;
1616         struct netr_LogonControl r;
1617         union netr_CONTROL_QUERY_INFORMATION query;
1618         int i,f;
1619         enum netr_SchannelType secure_channel_type = SEC_CHAN_NULL;
1620
1621         uint32_t function_codes[] = {
1622                 NETLOGON_CONTROL_QUERY,
1623                 NETLOGON_CONTROL_REPLICATE,
1624                 NETLOGON_CONTROL_SYNCHRONIZE,
1625                 NETLOGON_CONTROL_PDC_REPLICATE,
1626                 NETLOGON_CONTROL_REDISCOVER,
1627                 NETLOGON_CONTROL_TC_QUERY,
1628                 NETLOGON_CONTROL_TRANSPORT_NOTIFY,
1629                 NETLOGON_CONTROL_FIND_USER,
1630                 NETLOGON_CONTROL_CHANGE_PASSWORD,
1631                 NETLOGON_CONTROL_TC_VERIFY,
1632                 NETLOGON_CONTROL_FORCE_DNS_REG,
1633                 NETLOGON_CONTROL_QUERY_DNS_REG,
1634                 NETLOGON_CONTROL_BACKUP_CHANGE_LOG,
1635                 NETLOGON_CONTROL_TRUNCATE_LOG,
1636                 NETLOGON_CONTROL_SET_DBFLAG,
1637                 NETLOGON_CONTROL_BREAKPOINT
1638         };
1639
1640         if (machine_credentials) {
1641                 secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
1642         }
1643
1644         torture_comment(tctx, "testing LogonControl with secure channel type: %d\n",
1645                 secure_channel_type);
1646
1647         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1648         r.in.function_code = 1;
1649         r.out.query = &query;
1650
1651         for (f=0;f<ARRAY_SIZE(function_codes); f++) {
1652         for (i=1;i<5;i++) {
1653
1654                 r.in.function_code = function_codes[f];
1655                 r.in.level = i;
1656
1657                 torture_comment(tctx, "Testing LogonControl function code %s (%d) level %d\n",
1658                                 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
1659
1660                 status = dcerpc_netr_LogonControl(p, tctx, &r);
1661                 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1662
1663                 switch (r.in.level) {
1664                 case 1:
1665                         switch (r.in.function_code) {
1666                         case NETLOGON_CONTROL_REPLICATE:
1667                         case NETLOGON_CONTROL_SYNCHRONIZE:
1668                         case NETLOGON_CONTROL_PDC_REPLICATE:
1669                         case NETLOGON_CONTROL_BREAKPOINT:
1670                         case NETLOGON_CONTROL_BACKUP_CHANGE_LOG:
1671                                 if ((secure_channel_type == SEC_CHAN_BDC) ||
1672                                     (secure_channel_type == SEC_CHAN_WKSTA)) {
1673                                         torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED,
1674                                                 "LogonControl returned unexpected error code");
1675                                 } else {
1676                                         torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
1677                                                 "LogonControl returned unexpected error code");
1678                                 }
1679                                 break;
1680
1681                         case NETLOGON_CONTROL_REDISCOVER:
1682                         case NETLOGON_CONTROL_TC_QUERY:
1683                         case NETLOGON_CONTROL_TRANSPORT_NOTIFY:
1684                         case NETLOGON_CONTROL_FIND_USER:
1685                         case NETLOGON_CONTROL_CHANGE_PASSWORD:
1686                         case NETLOGON_CONTROL_TC_VERIFY:
1687                         case NETLOGON_CONTROL_FORCE_DNS_REG:
1688                         case NETLOGON_CONTROL_QUERY_DNS_REG:
1689                         case NETLOGON_CONTROL_SET_DBFLAG:
1690                                 torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
1691                                         "LogonControl returned unexpected error code");
1692                                 break;
1693                         case NETLOGON_CONTROL_TRUNCATE_LOG:
1694                                 if ((secure_channel_type == SEC_CHAN_BDC) ||
1695                                     (secure_channel_type == SEC_CHAN_WKSTA)) {
1696                                         torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED,
1697                                                 "LogonControl returned unexpected error code");
1698                                 } else {
1699                                         torture_assert_werr_ok(tctx, r.out.result,
1700                                                 "LogonControl returned unexpected result");
1701                                 }
1702                                 break;
1703                         default:
1704                                 torture_assert_werr_ok(tctx, r.out.result,
1705                                         "LogonControl returned unexpected result");
1706                                 break;
1707                         }
1708                         break;
1709                 case 2:
1710                         torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
1711                                 "LogonControl returned unexpected error code");
1712                         break;
1713                 default:
1714                         torture_assert_werr_equal(tctx, r.out.result, WERR_UNKNOWN_LEVEL,
1715                                 "LogonControl returned unexpected error code");
1716                         break;
1717                 }
1718         }
1719         }
1720
1721         return true;
1722 }
1723
1724
1725 /*
1726   try a netlogon GetAnyDCName
1727 */
1728 static bool test_GetAnyDCName(struct torture_context *tctx, 
1729                               struct dcerpc_pipe *p)
1730 {
1731         NTSTATUS status;
1732         struct netr_GetAnyDCName r;
1733         const char *dcname = NULL;
1734
1735         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1736         r.in.domainname = lp_workgroup(tctx->lp_ctx);
1737         r.out.dcname = &dcname;
1738
1739         status = dcerpc_netr_GetAnyDCName(p, tctx, &r);
1740         torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
1741         torture_assert_werr_ok(tctx, r.out.result, "GetAnyDCName");
1742
1743         if (dcname) {
1744             torture_comment(tctx, "\tDC is at '%s'\n", dcname);
1745         }
1746
1747         return true;
1748 }
1749
1750
1751 /*
1752   try a netlogon LogonControl2
1753 */
1754 static bool test_LogonControl2(struct torture_context *tctx, 
1755                                struct dcerpc_pipe *p,
1756                                struct cli_credentials *machine_credentials)
1757
1758 {
1759         NTSTATUS status;
1760         struct netr_LogonControl2 r;
1761         union netr_CONTROL_DATA_INFORMATION data;
1762         union netr_CONTROL_QUERY_INFORMATION query;
1763         int i;
1764
1765         data.domain = lp_workgroup(tctx->lp_ctx);
1766
1767         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1768
1769         r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
1770         r.in.data = &data;
1771         r.out.query = &query;
1772
1773         for (i=1;i<4;i++) {
1774                 r.in.level = i;
1775
1776                 torture_comment(tctx, "Testing LogonControl2 level %d function %d\n", 
1777                        i, r.in.function_code);
1778
1779                 status = dcerpc_netr_LogonControl2(p, tctx, &r);
1780                 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1781         }
1782
1783         data.domain = lp_workgroup(tctx->lp_ctx);
1784
1785         r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
1786         r.in.data = &data;
1787
1788         for (i=1;i<4;i++) {
1789                 r.in.level = i;
1790
1791                 torture_comment(tctx, "Testing LogonControl2 level %d function %d\n", 
1792                        i, r.in.function_code);
1793
1794                 status = dcerpc_netr_LogonControl2(p, tctx, &r);
1795                 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1796         }
1797
1798         data.domain = lp_workgroup(tctx->lp_ctx);
1799
1800         r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
1801         r.in.data = &data;
1802
1803         for (i=1;i<4;i++) {
1804                 r.in.level = i;
1805
1806                 torture_comment(tctx, "Testing LogonControl2 level %d function %d\n", 
1807                        i, r.in.function_code);
1808
1809                 status = dcerpc_netr_LogonControl2(p, tctx, &r);
1810                 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1811         }
1812
1813         data.debug_level = ~0;
1814
1815         r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
1816         r.in.data = &data;
1817
1818         for (i=1;i<4;i++) {
1819                 r.in.level = i;
1820
1821                 torture_comment(tctx, "Testing LogonControl2 level %d function %d\n", 
1822                        i, r.in.function_code);
1823
1824                 status = dcerpc_netr_LogonControl2(p, tctx, &r);
1825                 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1826         }
1827
1828         return true;
1829 }
1830
1831 /*
1832   try a netlogon DatabaseSync2
1833 */
1834 static bool test_DatabaseSync2(struct torture_context *tctx, 
1835                                struct dcerpc_pipe *p,
1836                                struct cli_credentials *machine_credentials)
1837 {
1838         NTSTATUS status;
1839         struct netr_DatabaseSync2 r;
1840         struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
1841         struct netr_Authenticator return_authenticator, credential;
1842
1843         struct netlogon_creds_CredentialState *creds;
1844         const uint32_t database_ids[] = {0, 1, 2}; 
1845         int i;
1846
1847         if (!test_SetupCredentials2(p, tctx, NETLOGON_NEG_AUTH2_FLAGS, 
1848                                     machine_credentials,
1849                                     cli_credentials_get_secure_channel_type(machine_credentials),
1850                                     &creds)) {
1851                 return false;
1852         }
1853
1854         ZERO_STRUCT(return_authenticator);
1855
1856         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1857         r.in.computername = TEST_MACHINE_NAME;
1858         r.in.preferredmaximumlength = (uint32_t)-1;
1859         r.in.return_authenticator = &return_authenticator;
1860         r.out.return_authenticator = &return_authenticator;
1861         r.out.delta_enum_array = &delta_enum_array;
1862
1863         for (i=0;i<ARRAY_SIZE(database_ids);i++) {
1864
1865                 uint32_t sync_context = 0;
1866
1867                 r.in.database_id = database_ids[i];
1868                 r.in.sync_context = &sync_context;
1869                 r.out.sync_context = &sync_context;
1870                 r.in.restart_state = 0;
1871
1872                 torture_comment(tctx, "Testing DatabaseSync2 of id %d\n", r.in.database_id);
1873
1874                 do {
1875                         netlogon_creds_client_authenticator(creds, &credential);
1876
1877                         r.in.credential = &credential;
1878
1879                         status = dcerpc_netr_DatabaseSync2(p, tctx, &r);
1880                         if (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
1881                             break;
1882
1883                         /* Native mode servers don't do this */
1884                         if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
1885                                 return true;
1886                         }
1887
1888                         torture_assert_ntstatus_ok(tctx, status, "DatabaseSync2");
1889
1890                         if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
1891                                 torture_comment(tctx, "Credential chaining failed\n");
1892                         }
1893
1894                 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
1895         }
1896
1897         return true;
1898 }
1899
1900
1901 /*
1902   try a netlogon LogonControl2Ex
1903 */
1904 static bool test_LogonControl2Ex(struct torture_context *tctx, 
1905                                  struct dcerpc_pipe *p,
1906                                  struct cli_credentials *machine_credentials)
1907
1908 {
1909         NTSTATUS status;
1910         struct netr_LogonControl2Ex r;
1911         union netr_CONTROL_DATA_INFORMATION data;
1912         union netr_CONTROL_QUERY_INFORMATION query;
1913         int i;
1914
1915         data.domain = lp_workgroup(tctx->lp_ctx);
1916
1917         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1918
1919         r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
1920         r.in.data = &data;
1921         r.out.query = &query;
1922
1923         for (i=1;i<4;i++) {
1924                 r.in.level = i;
1925
1926                 torture_comment(tctx, "Testing LogonControl2Ex level %d function %d\n", 
1927                        i, r.in.function_code);
1928
1929                 status = dcerpc_netr_LogonControl2Ex(p, tctx, &r);
1930                 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1931         }
1932
1933         data.domain = lp_workgroup(tctx->lp_ctx);
1934
1935         r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
1936         r.in.data = &data;
1937
1938         for (i=1;i<4;i++) {
1939                 r.in.level = i;
1940
1941                 torture_comment(tctx, "Testing LogonControl2Ex level %d function %d\n", 
1942                        i, r.in.function_code);
1943
1944                 status = dcerpc_netr_LogonControl2Ex(p, tctx, &r);
1945                 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1946         }
1947
1948         data.domain = lp_workgroup(tctx->lp_ctx);
1949
1950         r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
1951         r.in.data = &data;
1952
1953         for (i=1;i<4;i++) {
1954                 r.in.level = i;
1955
1956                 torture_comment(tctx, "Testing LogonControl2Ex level %d function %d\n", 
1957                        i, r.in.function_code);
1958
1959                 status = dcerpc_netr_LogonControl2Ex(p, tctx, &r);
1960                 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1961         }
1962
1963         data.debug_level = ~0;
1964
1965         r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
1966         r.in.data = &data;
1967
1968         for (i=1;i<4;i++) {
1969                 r.in.level = i;
1970
1971                 torture_comment(tctx, "Testing LogonControl2Ex level %d function %d\n", 
1972                        i, r.in.function_code);
1973
1974                 status = dcerpc_netr_LogonControl2Ex(p, tctx, &r);
1975                 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1976         }
1977
1978         return true;
1979 }
1980
1981 static bool test_netr_DsRGetForestTrustInformation(struct torture_context *tctx, 
1982                                                    struct dcerpc_pipe *p, const char *trusted_domain_name) 
1983 {
1984         NTSTATUS status;
1985         struct netr_DsRGetForestTrustInformation r;
1986         struct lsa_ForestTrustInformation info, *info_ptr;
1987
1988         info_ptr = &info;
1989
1990         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1991         r.in.trusted_domain_name = trusted_domain_name;
1992         r.in.flags = 0;
1993         r.out.forest_trust_info = &info_ptr;
1994
1995         torture_comment(tctx ,"Testing netr_DsRGetForestTrustInformation\n");
1996
1997         status = dcerpc_netr_DsRGetForestTrustInformation(p, tctx, &r);
1998         torture_assert_ntstatus_ok(tctx, status, "DsRGetForestTrustInformation");
1999         torture_assert_werr_ok(tctx, r.out.result, "DsRGetForestTrustInformation");
2000
2001         return true;
2002 }
2003
2004 /*
2005   try a netlogon netr_DsrEnumerateDomainTrusts
2006 */
2007 static bool test_DsrEnumerateDomainTrusts(struct torture_context *tctx, 
2008                                           struct dcerpc_pipe *p)
2009 {
2010         NTSTATUS status;
2011         struct netr_DsrEnumerateDomainTrusts r;
2012         struct netr_DomainTrustList trusts;
2013         int i;
2014
2015         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2016         r.in.trust_flags = 0x3f;
2017         r.out.trusts = &trusts;
2018
2019         status = dcerpc_netr_DsrEnumerateDomainTrusts(p, tctx, &r);
2020         torture_assert_ntstatus_ok(tctx, status, "DsrEnumerateDomaintrusts");
2021         torture_assert_werr_ok(tctx, r.out.result, "DsrEnumerateDomaintrusts");
2022
2023         /* when trusted_domain_name is NULL, netr_DsRGetForestTrustInformation
2024          * will show non-forest trusts and all UPN suffixes of the own forest
2025          * as LSA_FOREST_TRUST_TOP_LEVEL_NAME types */
2026
2027         if (r.out.trusts->count) {
2028                 if (!test_netr_DsRGetForestTrustInformation(tctx, p, NULL)) {
2029                         return false;
2030                 }
2031         }
2032
2033         for (i=0; i<r.out.trusts->count; i++) {
2034
2035                 /* get info for transitive forest trusts */
2036
2037                 if (r.out.trusts->array[i].trust_attributes & NETR_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) {
2038                         if (!test_netr_DsRGetForestTrustInformation(tctx, p, 
2039                                                                     r.out.trusts->array[i].dns_name)) {
2040                                 return false;
2041                         }
2042                 }
2043         }
2044
2045         return true;
2046 }
2047
2048 static bool test_netr_NetrEnumerateTrustedDomains(struct torture_context *tctx,
2049                                                   struct dcerpc_pipe *p)
2050 {
2051         NTSTATUS status;
2052         struct netr_NetrEnumerateTrustedDomains r;
2053         struct netr_Blob trusted_domains_blob;
2054
2055         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2056         r.out.trusted_domains_blob = &trusted_domains_blob;
2057
2058         status = dcerpc_netr_NetrEnumerateTrustedDomains(p, tctx, &r);
2059         torture_assert_ntstatus_ok(tctx, status, "netr_NetrEnumerateTrustedDomains");
2060         torture_assert_werr_ok(tctx, r.out.result, "NetrEnumerateTrustedDomains");
2061
2062         return true;
2063 }
2064
2065 static bool test_netr_NetrEnumerateTrustedDomainsEx(struct torture_context *tctx,
2066                                                     struct dcerpc_pipe *p)
2067 {
2068         NTSTATUS status;
2069         struct netr_NetrEnumerateTrustedDomainsEx r;
2070         struct netr_DomainTrustList dom_trust_list;
2071
2072         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2073         r.out.dom_trust_list = &dom_trust_list;
2074
2075         status = dcerpc_netr_NetrEnumerateTrustedDomainsEx(p, tctx, &r);
2076         torture_assert_ntstatus_ok(tctx, status, "netr_NetrEnumerateTrustedDomainsEx");
2077         torture_assert_werr_ok(tctx, r.out.result, "NetrEnumerateTrustedDomainsEx");
2078
2079         return true;
2080 }
2081
2082
2083 static bool test_netr_DsRGetSiteName(struct dcerpc_pipe *p, struct torture_context *tctx,
2084                                      const char *computer_name, 
2085                                      const char *expected_site) 
2086 {
2087         NTSTATUS status;
2088         struct netr_DsRGetSiteName r;
2089         const char *site = NULL;
2090
2091         if (torture_setting_bool(tctx, "samba4", false))
2092                 torture_skip(tctx, "skipping DsRGetSiteName test against Samba4");
2093
2094         r.in.computer_name              = computer_name;
2095         r.out.site                      = &site;
2096         torture_comment(tctx, "Testing netr_DsRGetSiteName\n");
2097
2098         status = dcerpc_netr_DsRGetSiteName(p, tctx, &r);
2099         torture_assert_ntstatus_ok(tctx, status, "DsRGetSiteName");
2100         torture_assert_werr_ok(tctx, r.out.result, "DsRGetSiteName");
2101         torture_assert_str_equal(tctx, expected_site, site, "netr_DsRGetSiteName");
2102
2103         r.in.computer_name              = talloc_asprintf(tctx, "\\\\%s", computer_name);
2104         torture_comment(tctx, 
2105                         "Testing netr_DsRGetSiteName with broken computer name: %s\n", r.in.computer_name);
2106
2107         status = dcerpc_netr_DsRGetSiteName(p, tctx, &r);
2108         torture_assert_ntstatus_ok(tctx, status, "DsRGetSiteName");
2109         torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_COMPUTERNAME, "netr_DsRGetSiteName");
2110
2111         return true;
2112 }
2113
2114 /*
2115   try a netlogon netr_DsRGetDCName
2116 */
2117 static bool test_netr_DsRGetDCName(struct torture_context *tctx, 
2118                                    struct dcerpc_pipe *p)
2119 {
2120         NTSTATUS status;
2121         struct netr_DsRGetDCName r;
2122         struct netr_DsRGetDCNameInfo *info = NULL;
2123
2124         r.in.server_unc         = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2125         r.in.domain_name        = lp_dnsdomain(tctx->lp_ctx);
2126         r.in.domain_guid        = NULL;
2127         r.in.site_guid          = NULL;
2128         r.in.flags              = DS_RETURN_DNS_NAME;
2129         r.out.info              = &info;
2130
2131         status = dcerpc_netr_DsRGetDCName(p, tctx, &r);
2132         torture_assert_ntstatus_ok(tctx, status, "DsRGetDCName");
2133         torture_assert_werr_ok(tctx, r.out.result, "DsRGetDCName");
2134         return test_netr_DsRGetSiteName(p, tctx, 
2135                                        info->dc_unc,
2136                                        info->dc_site_name);
2137 }
2138
2139 /*
2140   try a netlogon netr_DsRGetDCNameEx
2141 */
2142 static bool test_netr_DsRGetDCNameEx(struct torture_context *tctx, 
2143                                      struct dcerpc_pipe *p)
2144 {
2145         NTSTATUS status;
2146         struct netr_DsRGetDCNameEx r;
2147         struct netr_DsRGetDCNameInfo *info = NULL;
2148
2149         r.in.server_unc         = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2150         r.in.domain_name        = lp_dnsdomain(tctx->lp_ctx);
2151         r.in.domain_guid        = NULL;
2152         r.in.site_name          = NULL;
2153         r.in.flags              = DS_RETURN_DNS_NAME;
2154         r.out.info              = &info;
2155
2156         status = dcerpc_netr_DsRGetDCNameEx(p, tctx, &r);
2157         torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx");
2158         torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx");
2159
2160         return test_netr_DsRGetSiteName(p, tctx, info->dc_unc,
2161                                         info->dc_site_name);
2162 }
2163
2164 /*
2165   try a netlogon netr_DsRGetDCNameEx2
2166 */
2167 static bool test_netr_DsRGetDCNameEx2(struct torture_context *tctx, 
2168                                       struct dcerpc_pipe *p)
2169 {
2170         NTSTATUS status;
2171         struct netr_DsRGetDCNameEx2 r;
2172         struct netr_DsRGetDCNameInfo *info = NULL;
2173
2174         r.in.server_unc         = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2175         r.in.client_account     = NULL;
2176         r.in.mask               = 0x00000000;
2177         r.in.domain_name        = lp_dnsdomain(tctx->lp_ctx);
2178         r.in.domain_guid        = NULL;
2179         r.in.site_name          = NULL;
2180         r.in.flags              = DS_RETURN_DNS_NAME;
2181         r.out.info              = &info;
2182
2183         torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 without client account\n");
2184
2185         status = dcerpc_netr_DsRGetDCNameEx2(p, tctx, &r);
2186         torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
2187         torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
2188
2189         torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 with client acount\n");
2190         r.in.client_account     = TEST_MACHINE_NAME"$";
2191         r.in.mask               = ACB_SVRTRUST;
2192         r.in.flags              = DS_RETURN_FLAT_NAME;
2193         r.out.info              = &info;
2194
2195         status = dcerpc_netr_DsRGetDCNameEx2(p, tctx, &r);
2196         torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
2197         torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
2198         return test_netr_DsRGetSiteName(p, tctx, info->dc_unc,
2199                                         info->dc_site_name);
2200 }
2201
2202 static bool test_netr_DsrGetDcSiteCoverageW(struct torture_context *tctx, 
2203                                             struct dcerpc_pipe *p)
2204 {
2205         NTSTATUS status;
2206         struct netr_DsrGetDcSiteCoverageW r;
2207         struct DcSitesCtr *ctr = NULL;
2208
2209         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2210         r.out.ctr = &ctr;
2211
2212         status = dcerpc_netr_DsrGetDcSiteCoverageW(p, tctx, &r);
2213         torture_assert_ntstatus_ok(tctx, status, "failed");
2214         torture_assert_werr_ok(tctx, r.out.result, "failed");
2215
2216         return true;
2217 }
2218
2219 static bool test_netr_DsRAddressToSitenamesW(struct torture_context *tctx,
2220                                              struct dcerpc_pipe *p)
2221 {
2222         NTSTATUS status;
2223         struct netr_DsRAddressToSitenamesW r;
2224         struct netr_DsRAddress addr;
2225         struct netr_DsRAddressToSitenamesWCtr *ctr;
2226
2227         ctr = talloc(tctx, struct netr_DsRAddressToSitenamesWCtr);
2228
2229         addr.size = 16;
2230         addr.buffer = talloc_zero_array(tctx, uint8_t, addr.size);
2231
2232         addr.buffer[0] = 2; /* AF_INET */
2233         addr.buffer[4] = 127;
2234         addr.buffer[5] = 0;
2235         addr.buffer[6] = 0;
2236         addr.buffer[7] = 1;
2237
2238         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2239         r.in.count = 1;
2240         r.in.addresses = talloc_zero_array(tctx, struct netr_DsRAddress, r.in.count);
2241         r.in.addresses[0] = addr;
2242         r.out.ctr = &ctr;
2243
2244         status = dcerpc_netr_DsRAddressToSitenamesW(p, tctx, &r);
2245         torture_assert_ntstatus_ok(tctx, status, "failed");
2246         torture_assert_werr_ok(tctx, r.out.result, "failed");
2247
2248         return true;
2249 }
2250
2251 static bool test_netr_DsRAddressToSitenamesExW(struct torture_context *tctx,
2252                                                struct dcerpc_pipe *p)
2253 {
2254         NTSTATUS status;
2255         struct netr_DsRAddressToSitenamesExW r;
2256         struct netr_DsRAddress addr;
2257         struct netr_DsRAddressToSitenamesExWCtr *ctr;
2258
2259         ctr = talloc(tctx, struct netr_DsRAddressToSitenamesExWCtr);
2260
2261         addr.size = 16;
2262         addr.buffer = talloc_zero_array(tctx, uint8_t, addr.size);
2263
2264         addr.buffer[0] = 2; /* AF_INET */
2265         addr.buffer[4] = 127;
2266         addr.buffer[5] = 0;
2267         addr.buffer[6] = 0;
2268         addr.buffer[7] = 1;
2269
2270         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2271         r.in.count = 1;
2272         r.in.addresses = talloc_zero_array(tctx, struct netr_DsRAddress, r.in.count);
2273         r.in.addresses[0] = addr;
2274         r.out.ctr = &ctr;
2275
2276         status = dcerpc_netr_DsRAddressToSitenamesExW(p, tctx, &r);
2277         torture_assert_ntstatus_ok(tctx, status, "failed");
2278         torture_assert_werr_ok(tctx, r.out.result, "failed");
2279
2280         return true;
2281 }
2282
2283 static bool test_netr_ServerGetTrustInfo(struct torture_context *tctx,
2284                                          struct dcerpc_pipe *p,
2285                                          struct cli_credentials *machine_credentials)
2286 {
2287         NTSTATUS status;
2288         struct netr_ServerGetTrustInfo r;
2289
2290         struct netr_Authenticator a;
2291         struct netr_Authenticator return_authenticator;
2292         struct samr_Password new_owf_password;
2293         struct samr_Password old_owf_password;
2294         struct netr_TrustInfo *trust_info;
2295
2296         struct netlogon_creds_CredentialState *creds;
2297
2298         if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
2299                                     machine_credentials, &creds)) {
2300                 return false;
2301         }
2302
2303         netlogon_creds_client_authenticator(creds, &a);
2304
2305         r.in.server_name                = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2306         r.in.account_name               = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
2307         r.in.secure_channel_type        = cli_credentials_get_secure_channel_type(machine_credentials);
2308         r.in.computer_name              = TEST_MACHINE_NAME;
2309         r.in.credential                 = &a;
2310
2311         r.out.return_authenticator      = &return_authenticator;
2312         r.out.new_owf_password          = &new_owf_password;
2313         r.out.old_owf_password          = &old_owf_password;
2314         r.out.trust_info                = &trust_info;
2315
2316         status = dcerpc_netr_ServerGetTrustInfo(p, tctx, &r);
2317         torture_assert_ntstatus_ok(tctx, status, "failed");
2318         torture_assert(tctx, netlogon_creds_client_check(creds, &return_authenticator.cred), "Credential chaining failed");
2319
2320         return true;
2321 }
2322
2323
2324 static bool test_GetDomainInfo(struct torture_context *tctx, 
2325                                struct dcerpc_pipe *p,
2326                                struct cli_credentials *machine_credentials)
2327 {
2328         NTSTATUS status;
2329         struct netr_LogonGetDomainInfo r;
2330         struct netr_WorkstationInformation q1;
2331         struct netr_Authenticator a;
2332         struct netlogon_creds_CredentialState *creds;
2333         struct netr_OsVersion os;
2334         union netr_WorkstationInfo query;
2335         union netr_DomainInfo info;
2336         const char* const attrs[] = { "dNSHostName", "operatingSystem",
2337                 "operatingSystemServicePack", "operatingSystemVersion",
2338                 "servicePrincipalName", NULL };
2339         char *url;
2340         struct ldb_context *sam_ctx = NULL;
2341         struct ldb_message **res;
2342         struct ldb_message_element *spn_el;
2343         int ret, i;
2344         char *version_str;
2345         const char *old_dnsname = NULL;
2346         char **spns = NULL;
2347         int num_spns = 0;
2348         char *temp_str;
2349
2350         torture_comment(tctx, "Testing netr_LogonGetDomainInfo\n");
2351
2352         if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS, 
2353                                     machine_credentials, &creds)) {
2354                 return false;
2355         }
2356
2357         /* We won't double-check this when we are over 'local' transports */
2358         if (dcerpc_server_name(p)) {
2359                 /* Set up connection to SAMDB on DC */
2360                 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
2361                 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
2362                                            NULL,
2363                                            cmdline_credentials,
2364                                            0);
2365                 
2366                 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
2367         }
2368
2369         torture_comment(tctx, "Testing netr_LogonGetDomainInfo 1st call (no variation of DNS hostname)\n");
2370         netlogon_creds_client_authenticator(creds, &a);
2371
2372         ZERO_STRUCT(r);
2373         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2374         r.in.computer_name = TEST_MACHINE_NAME;
2375         r.in.credential = &a;
2376         r.in.level = 1;
2377         r.in.return_authenticator = &a;
2378         r.in.query = &query;
2379         r.out.return_authenticator = &a;
2380         r.out.info = &info;
2381
2382         ZERO_STRUCT(os);
2383         os.os.MajorVersion = 123;
2384         os.os.MinorVersion = 456;
2385         os.os.BuildNumber = 789;
2386         os.os.CSDVersion = "Service Pack 10";
2387         os.os.ServicePackMajor = 10;
2388         os.os.ServicePackMinor = 1;
2389         os.os.SuiteMask = NETR_VER_SUITE_SINGLEUSERTS;
2390         os.os.ProductType = NETR_VER_NT_SERVER;
2391         os.os.Reserved = 0;
2392
2393         version_str = talloc_asprintf(tctx, "%d.%d (%d)", os.os.MajorVersion,
2394                 os.os.MinorVersion, os.os.BuildNumber);
2395
2396         ZERO_STRUCT(q1);
2397         q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
2398                 TEST_MACHINE_DNS_SUFFIX);
2399         q1.sitename = "Default-First-Site-Name";
2400         q1.os_version.os = &os;
2401         q1.os_name.string = talloc_asprintf(tctx,
2402                                             "Tortured by Samba4 RPC-NETLOGON: %s",
2403                                             timestring(tctx, time(NULL)));
2404
2405         /* The workstation handles the "servicePrincipalName" and DNS hostname
2406            updates */
2407         q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
2408
2409         query.workstation_info = &q1;
2410
2411         if (sam_ctx) {
2412                 /* Gets back the old DNS hostname in AD */
2413                 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
2414                                    "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
2415                 old_dnsname =
2416                         ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL);
2417                 
2418                 /* Gets back the "servicePrincipalName"s in AD */
2419                 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
2420                 if (spn_el != NULL) {
2421                         for (i=0; i < spn_el->num_values; i++) {
2422                                 spns = talloc_realloc(tctx, spns, char *, i + 1);
2423                                 spns[i] = (char *) spn_el->values[i].data;
2424                         }
2425                         num_spns = i;
2426                 }
2427         }
2428
2429         status = dcerpc_netr_LogonGetDomainInfo(p, tctx, &r);
2430         torture_assert_ntstatus_ok(tctx, status, "netr_LogonGetDomainInfo");
2431         torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
2432
2433         msleep(250);
2434
2435         if (sam_ctx) {
2436                 /* AD workstation infos entry check */
2437                 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
2438                                    "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
2439                 torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
2440                 torture_assert_str_equal(tctx,
2441                                          ldb_msg_find_attr_as_string(res[0], "operatingSystem", NULL),
2442                                          q1.os_name.string, "'operatingSystem' wrong!");
2443                 torture_assert_str_equal(tctx,
2444                                          ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL),
2445                                          os.os.CSDVersion, "'operatingSystemServicePack' wrong!");
2446                 torture_assert_str_equal(tctx,
2447                                          ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL),
2448                                          version_str, "'operatingSystemVersion' wrong!");
2449
2450                 if (old_dnsname != NULL) {
2451                         /* If before a DNS hostname was set then it should remain
2452                            the same in combination with the "servicePrincipalName"s.
2453                            The DNS hostname should also be returned by our
2454                            "LogonGetDomainInfo" call (in the domain info structure). */
2455                         
2456                         torture_assert_str_equal(tctx,
2457                                                  ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL),
2458                                                  old_dnsname, "'DNS hostname' was not set!");
2459                         
2460                         spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
2461                         torture_assert(tctx, ((spns != NULL) && (spn_el != NULL)),
2462                                        "'servicePrincipalName's not set!");
2463                         torture_assert(tctx, spn_el->num_values == num_spns,
2464                                        "'servicePrincipalName's incorrect!");
2465                         for (i=0; (i < spn_el->num_values) && (i < num_spns); i++)
2466                                 torture_assert_str_equal(tctx,
2467                                                          (char *) spn_el->values[i].data,
2468                                 spns[i], "'servicePrincipalName's incorrect!");
2469
2470                         torture_assert_str_equal(tctx,
2471                                                  info.domain_info->dns_hostname.string,
2472                                                  old_dnsname,
2473                                                  "Out 'DNS hostname' doesn't match the old one!");
2474                 } else {
2475                         /* If no DNS hostname was set then also now none should be set,
2476                            the "servicePrincipalName"s should remain empty and no DNS
2477                            hostname should be returned by our "LogonGetDomainInfo"
2478                            call (in the domain info structure). */
2479                         
2480                         torture_assert(tctx,
2481                                        ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL) == NULL,
2482                                        "'DNS hostname' was set!");
2483                         
2484                         spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
2485                         torture_assert(tctx, ((spns == NULL) && (spn_el == NULL)),
2486                                        "'servicePrincipalName's were set!");
2487                         
2488                         torture_assert(tctx,
2489                                        info.domain_info->dns_hostname.string == NULL,
2490                                        "Out 'DNS host name' was set!");
2491                 }
2492         }
2493
2494         /* Checks "workstation flags" */
2495         torture_assert(tctx,
2496                 info.domain_info->workstation_flags
2497                 == NETR_WS_FLAG_HANDLES_SPN_UPDATE,
2498                 "Out 'workstation flags' don't match!");
2499
2500
2501         torture_comment(tctx, "Testing netr_LogonGetDomainInfo 2nd call (variation of DNS hostname)\n");
2502         netlogon_creds_client_authenticator(creds, &a);
2503
2504         /* Wipe out the osVersion, and prove which values still 'stick' */
2505         q1.os_version.os = NULL;
2506
2507         /* Change also the DNS hostname to test differences in behaviour */
2508         q1.dns_hostname = talloc_asprintf(tctx, "%s.newdomain",
2509                 TEST_MACHINE_NAME);
2510
2511         /* Let the DC handle the "servicePrincipalName" and DNS hostname
2512            updates */
2513         q1.workstation_flags = 0;
2514
2515         status = dcerpc_netr_LogonGetDomainInfo(p, tctx, &r);
2516         torture_assert_ntstatus_ok(tctx, status, "netr_LogonGetDomainInfo");
2517         torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
2518
2519         msleep(250);
2520
2521         if (sam_ctx) {
2522                 /* AD workstation infos entry check */
2523                 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
2524                                    "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
2525                 torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
2526                 torture_assert_str_equal(tctx,
2527                                          ldb_msg_find_attr_as_string(res[0], "operatingSystem", NULL),
2528                                          q1.os_name.string, "'operatingSystem' should stick!");
2529                 torture_assert(tctx,
2530                                ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL) == NULL,
2531                                "'operatingSystemServicePack' shouldn't stick!");
2532                 torture_assert(tctx,
2533                                ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL) == NULL,
2534                                "'operatingSystemVersion' shouldn't stick!");
2535                 
2536                 /* The DNS host name should have been updated now by the server */
2537                 torture_assert_str_equal(tctx,
2538                                          ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL),
2539                                          q1.dns_hostname, "'DNS host name' didn't change!");
2540                 
2541                 /* Find the two "servicePrincipalName"s which the DC should have been
2542                    updated (HOST/<Netbios name> and HOST/<FQDN name>) - see MS-NRPC
2543                    3.5.4.3.9 */
2544                 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
2545                 torture_assert(tctx, spn_el != NULL,
2546                                "There should exist 'servicePrincipalName's in AD!");
2547                 temp_str = talloc_asprintf(tctx, "HOST/%s", TEST_MACHINE_NAME);
2548                 for (i=0; i < spn_el->num_values; i++)
2549                         if (strcmp((char *) spn_el->values[i].data, temp_str) == 0)
2550                                 break;
2551                 torture_assert(tctx, i != spn_el->num_values,
2552                                "'servicePrincipalName' HOST/<Netbios name> not found!");
2553                 temp_str = talloc_asprintf(tctx, "HOST/%s", q1.dns_hostname);
2554                 for (i=0; i < spn_el->num_values; i++)
2555                         if (strcmp((char *) spn_el->values[i].data, temp_str) == 0)
2556                                 break;
2557                 torture_assert(tctx, i != spn_el->num_values,
2558                                "'servicePrincipalName' HOST/<FQDN name> not found!");
2559                 
2560                 /* Check that the out DNS hostname was set properly */
2561                 torture_assert_str_equal(tctx, info.domain_info->dns_hostname.string,
2562                                          old_dnsname, "Out 'DNS hostname' doesn't match the old one!");
2563         }
2564
2565         /* Checks "workstation flags" */
2566         torture_assert(tctx,
2567                 info.domain_info->workstation_flags == 0,
2568                 "Out 'workstation flags' don't match!");
2569
2570
2571         torture_comment(tctx, "Testing netr_LogonGetDomainInfo 3rd call (verification of DNS hostname and check for trusted domains)\n");
2572         netlogon_creds_client_authenticator(creds, &a);
2573
2574         /* The workstation handles the "servicePrincipalName" and DNS hostname
2575            updates */
2576         q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
2577
2578         status = dcerpc_netr_LogonGetDomainInfo(p, tctx, &r);
2579         torture_assert_ntstatus_ok(tctx, status, "netr_LogonGetDomainInfo");
2580         torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
2581
2582         msleep(250);
2583
2584         /* Now the in/out DNS hostnames should be the same */
2585         torture_assert_str_equal(tctx,
2586                 info.domain_info->dns_hostname.string,
2587                 query.workstation_info->dns_hostname,
2588                 "In/Out 'DNS hostnames' don't match!");
2589
2590         /* Checks "workstation flags" */
2591         torture_assert(tctx,
2592                 info.domain_info->workstation_flags
2593                 == NETR_WS_FLAG_HANDLES_SPN_UPDATE,
2594                 "Out 'workstation flags' don't match!");
2595
2596         /* Checks for trusted domains */
2597         torture_assert(tctx,
2598                 (info.domain_info->trusted_domain_count != 0)
2599                 && (info.domain_info->trusted_domains != NULL),
2600                 "Trusted domains have been requested!");
2601
2602
2603         torture_comment(tctx, "Testing netr_LogonGetDomainInfo 4th call (check for trusted domains)\n");
2604         netlogon_creds_client_authenticator(creds, &a);
2605
2606         /* The workstation handles the "servicePrincipalName" and DNS hostname
2607            updates and requests inbound trusts */
2608         q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE
2609                 | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS;
2610
2611         status = dcerpc_netr_LogonGetDomainInfo(p, tctx, &r);
2612         torture_assert_ntstatus_ok(tctx, status, "netr_LogonGetDomainInfo");
2613         torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
2614
2615         msleep(250);
2616
2617         /* Checks "workstation flags" */
2618         torture_assert(tctx,
2619                 info.domain_info->workstation_flags
2620                 == (NETR_WS_FLAG_HANDLES_SPN_UPDATE
2621                         | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS),
2622                 "Out 'workstation flags' don't match!");
2623
2624         /* Checks for trusted domains */
2625         torture_assert(tctx,
2626                 (info.domain_info->trusted_domain_count != 0)
2627                 && (info.domain_info->trusted_domains != NULL),
2628                 "Trusted domains have been requested!");
2629
2630         return true;
2631 }
2632
2633
2634 static void async_callback(struct rpc_request *req)
2635 {
2636         int *counter = (int *)req->async.private_data;
2637         if (NT_STATUS_IS_OK(req->status)) {
2638                 (*counter)++;
2639         }
2640 }
2641
2642 static bool test_GetDomainInfo_async(struct torture_context *tctx, 
2643                                      struct dcerpc_pipe *p,
2644                                      struct cli_credentials *machine_credentials)
2645 {
2646         NTSTATUS status;
2647         struct netr_LogonGetDomainInfo r;
2648         struct netr_WorkstationInformation q1;
2649         struct netr_Authenticator a;
2650 #define ASYNC_COUNT 100
2651         struct netlogon_creds_CredentialState *creds;
2652         struct netlogon_creds_CredentialState *creds_async[ASYNC_COUNT];
2653         struct rpc_request *req[ASYNC_COUNT];
2654         int i;
2655         int *async_counter = talloc(tctx, int);
2656         union netr_WorkstationInfo query;
2657         union netr_DomainInfo info;
2658
2659         torture_comment(tctx, "Testing netr_LogonGetDomainInfo - async count %d\n", ASYNC_COUNT);
2660
2661         if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS, 
2662                                     machine_credentials, &creds)) {
2663                 return false;
2664         }
2665
2666         ZERO_STRUCT(r);
2667         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2668         r.in.computer_name = TEST_MACHINE_NAME;
2669         r.in.credential = &a;
2670         r.in.level = 1;
2671         r.in.return_authenticator = &a;
2672         r.in.query = &query;
2673         r.out.return_authenticator = &a;
2674         r.out.info = &info;
2675
2676         ZERO_STRUCT(q1);
2677         q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
2678                 TEST_MACHINE_DNS_SUFFIX);
2679         q1.sitename = "Default-First-Site-Name";
2680         q1.os_name.string = "UNIX/Linux or similar";
2681
2682         query.workstation_info = &q1;
2683
2684         *async_counter = 0;
2685
2686         for (i=0;i<ASYNC_COUNT;i++) {
2687                 netlogon_creds_client_authenticator(creds, &a);
2688
2689                 creds_async[i] = (struct netlogon_creds_CredentialState *)talloc_memdup(creds, creds, sizeof(*creds));
2690                 req[i] = dcerpc_netr_LogonGetDomainInfo_send(p, tctx, &r);
2691
2692                 req[i]->async.callback = async_callback;
2693                 req[i]->async.private_data = async_counter;
2694
2695                 /* even with this flush per request a w2k3 server seems to 
2696                    clag with multiple outstanding requests. bleergh. */
2697                 torture_assert_int_equal(tctx, event_loop_once(dcerpc_event_context(p)), 0, 
2698                                          "event_loop_once failed");
2699         }
2700
2701         for (i=0;i<ASYNC_COUNT;i++) {
2702                 status = dcerpc_ndr_request_recv(req[i]);
2703
2704                 torture_assert_ntstatus_ok(tctx, status, "netr_LogonGetDomainInfo_async");
2705                 torture_assert_ntstatus_ok(tctx, r.out.result, "netr_LogonGetDomainInfo_async"); 
2706
2707                 torture_assert(tctx, netlogon_creds_client_check(creds_async[i], &a.cred), 
2708                         "Credential chaining failed at async");
2709         }
2710
2711         torture_comment(tctx, 
2712                         "Testing netr_LogonGetDomainInfo - async count %d OK\n", *async_counter);
2713
2714         torture_assert_int_equal(tctx, (*async_counter), ASYNC_COUNT, "int");
2715
2716         return true;
2717 }
2718
2719 static bool test_ManyGetDCName(struct torture_context *tctx, 
2720                                struct dcerpc_pipe *p)
2721 {
2722         NTSTATUS status;
2723         struct dcerpc_pipe *p2;
2724         struct lsa_ObjectAttribute attr;
2725         struct lsa_QosInfo qos;
2726         struct lsa_OpenPolicy2 o;
2727         struct policy_handle lsa_handle;
2728         struct lsa_DomainList domains;
2729
2730         struct lsa_EnumTrustDom t;
2731         uint32_t resume_handle = 0;
2732         struct netr_GetAnyDCName d;
2733         const char *dcname = NULL;
2734
2735         int i;
2736
2737         if (p->conn->transport.transport != NCACN_NP) {
2738                 return true;
2739         }
2740
2741         torture_comment(tctx, "Torturing GetDCName\n");
2742
2743         status = dcerpc_secondary_connection(p, &p2, p->binding);
2744         torture_assert_ntstatus_ok(tctx, status, "Failed to create secondary connection");
2745
2746         status = dcerpc_bind_auth_none(p2, &ndr_table_lsarpc);
2747         torture_assert_ntstatus_ok(tctx, status, "Failed to create bind on secondary connection");
2748
2749         qos.len = 0;
2750         qos.impersonation_level = 2;
2751         qos.context_mode = 1;
2752         qos.effective_only = 0;
2753
2754         attr.len = 0;
2755         attr.root_dir = NULL;
2756         attr.object_name = NULL;
2757         attr.attributes = 0;
2758         attr.sec_desc = NULL;
2759         attr.sec_qos = &qos;
2760
2761         o.in.system_name = "\\";
2762         o.in.attr = &attr;
2763         o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2764         o.out.handle = &lsa_handle;
2765
2766         status = dcerpc_lsa_OpenPolicy2(p2, tctx, &o);
2767         torture_assert_ntstatus_ok(tctx, status, "OpenPolicy2 failed");
2768
2769         t.in.handle = &lsa_handle;
2770         t.in.resume_handle = &resume_handle;
2771         t.in.max_size = 1000;
2772         t.out.domains = &domains;
2773         t.out.resume_handle = &resume_handle;
2774
2775         status = dcerpc_lsa_EnumTrustDom(p2, tctx, &t);
2776
2777         if ((!NT_STATUS_IS_OK(status) &&
2778              (!NT_STATUS_EQUAL(status, NT_STATUS_NO_MORE_ENTRIES))))
2779                 torture_fail(tctx, "Could not list domains");
2780
2781         talloc_free(p2);
2782
2783         d.in.logon_server = talloc_asprintf(tctx, "\\\\%s",
2784                                             dcerpc_server_name(p));
2785         d.out.dcname = &dcname;
2786
2787         for (i=0; i<domains.count * 4; i++) {
2788                 struct lsa_DomainInfo *info =
2789                         &domains.domains[rand()%domains.count];
2790
2791                 d.in.domainname = info->name.string;
2792
2793                 status = dcerpc_netr_GetAnyDCName(p, tctx, &d);
2794                 torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
2795
2796                 torture_comment(tctx, "\tDC for domain %s is %s\n", info->name.string,
2797                        dcname ? dcname : "unknown");
2798         }
2799
2800         return true;
2801 }
2802
2803 static bool test_SetPassword_with_flags(struct torture_context *tctx,
2804                                         struct dcerpc_pipe *p,
2805                                         struct cli_credentials *machine_credentials)
2806 {
2807         uint32_t flags[] = { 0, NETLOGON_NEG_STRONG_KEYS };
2808         struct netlogon_creds_CredentialState *creds;
2809         int i;
2810
2811         if (!test_SetupCredentials2(p, tctx, 0,
2812                                     machine_credentials,
2813                                     cli_credentials_get_secure_channel_type(machine_credentials),
2814                                     &creds)) {
2815                 torture_skip(tctx, "DC does not support negotiation of 64bit session keys");
2816         }
2817
2818         for (i=0; i < ARRAY_SIZE(flags); i++) {
2819                 torture_assert(tctx,
2820                         test_SetPassword_flags(tctx, p, machine_credentials, flags[i]),
2821                         talloc_asprintf(tctx, "failed to test SetPassword negotiating with 0x%08x flags", flags[i]));
2822         }
2823
2824         return true;
2825 }
2826
2827 struct torture_suite *torture_rpc_netlogon(TALLOC_CTX *mem_ctx)
2828 {
2829         struct torture_suite *suite = torture_suite_create(mem_ctx, "NETLOGON");
2830         struct torture_rpc_tcase *tcase;
2831         struct torture_test *test;
2832
2833         tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netlogon",
2834                                                   &ndr_table_netlogon, TEST_MACHINE_NAME);
2835
2836         torture_rpc_tcase_add_test(tcase, "LogonUasLogon", test_LogonUasLogon);
2837         torture_rpc_tcase_add_test(tcase, "LogonUasLogoff", test_LogonUasLogoff);
2838         torture_rpc_tcase_add_test_creds(tcase, "SamLogon", test_SamLogon);
2839         torture_rpc_tcase_add_test_creds(tcase, "SetPassword", test_SetPassword);
2840         torture_rpc_tcase_add_test_creds(tcase, "SetPassword2", test_SetPassword2);
2841         torture_rpc_tcase_add_test_creds(tcase, "GetPassword", test_GetPassword);
2842         torture_rpc_tcase_add_test_creds(tcase, "GetTrustPasswords", test_GetTrustPasswords);
2843         torture_rpc_tcase_add_test_creds(tcase, "GetDomainInfo", test_GetDomainInfo);
2844         torture_rpc_tcase_add_test_creds(tcase, "DatabaseSync", test_DatabaseSync);
2845         torture_rpc_tcase_add_test_creds(tcase, "DatabaseDeltas", test_DatabaseDeltas);
2846         torture_rpc_tcase_add_test_creds(tcase, "DatabaseRedo", test_DatabaseRedo);
2847         torture_rpc_tcase_add_test_creds(tcase, "AccountDeltas", test_AccountDeltas);
2848         torture_rpc_tcase_add_test_creds(tcase, "AccountSync", test_AccountSync);
2849         torture_rpc_tcase_add_test(tcase, "GetDcName", test_GetDcName);
2850         torture_rpc_tcase_add_test(tcase, "ManyGetDCName", test_ManyGetDCName);
2851         torture_rpc_tcase_add_test(tcase, "GetAnyDCName", test_GetAnyDCName);
2852         torture_rpc_tcase_add_test_creds(tcase, "DatabaseSync2", test_DatabaseSync2);
2853         torture_rpc_tcase_add_test(tcase, "DsrEnumerateDomainTrusts", test_DsrEnumerateDomainTrusts);
2854         torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomains", test_netr_NetrEnumerateTrustedDomains);
2855         torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomainsEx", test_netr_NetrEnumerateTrustedDomainsEx);
2856         test = torture_rpc_tcase_add_test_creds(tcase, "GetDomainInfo_async", test_GetDomainInfo_async);
2857         test->dangerous = true;
2858         torture_rpc_tcase_add_test(tcase, "DsRGetDCName", test_netr_DsRGetDCName);
2859         torture_rpc_tcase_add_test(tcase, "DsRGetDCNameEx", test_netr_DsRGetDCNameEx);
2860         torture_rpc_tcase_add_test(tcase, "DsRGetDCNameEx2", test_netr_DsRGetDCNameEx2);
2861         torture_rpc_tcase_add_test(tcase, "DsrGetDcSiteCoverageW", test_netr_DsrGetDcSiteCoverageW);
2862         torture_rpc_tcase_add_test(tcase, "DsRAddressToSitenamesW", test_netr_DsRAddressToSitenamesW);
2863         torture_rpc_tcase_add_test(tcase, "DsRAddressToSitenamesExW", test_netr_DsRAddressToSitenamesExW);
2864         torture_rpc_tcase_add_test_creds(tcase, "ServerGetTrustInfo", test_netr_ServerGetTrustInfo);
2865
2866         return suite;
2867 }
2868
2869 struct torture_suite *torture_rpc_netlogon_s3(TALLOC_CTX *mem_ctx)
2870 {
2871         struct torture_suite *suite = torture_suite_create(mem_ctx, "NETLOGON-S3");
2872         struct torture_rpc_tcase *tcase;
2873
2874         tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netlogon",
2875                                                   &ndr_table_netlogon, TEST_MACHINE_NAME);
2876
2877         torture_rpc_tcase_add_test_creds(tcase, "SamLogon", test_SamLogon);
2878         torture_rpc_tcase_add_test_creds(tcase, "SetPassword", test_SetPassword);
2879         torture_rpc_tcase_add_test_creds(tcase, "SetPassword_with_flags", test_SetPassword_with_flags);
2880         torture_rpc_tcase_add_test_creds(tcase, "SetPassword2", test_SetPassword2);
2881         torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomains", test_netr_NetrEnumerateTrustedDomains);
2882
2883         return suite;
2884 }
2885
2886 struct torture_suite *torture_rpc_netlogon_admin(TALLOC_CTX *mem_ctx)
2887 {
2888         struct torture_suite *suite = torture_suite_create(mem_ctx, "NETLOGON-ADMIN");
2889         struct torture_rpc_tcase *tcase;
2890
2891         tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netlogon",
2892                                                   &ndr_table_netlogon, TEST_MACHINE_NAME);
2893         torture_rpc_tcase_add_test_creds(tcase, "LogonControl", test_LogonControl);
2894         torture_rpc_tcase_add_test_creds(tcase, "LogonControl2", test_LogonControl2);
2895         torture_rpc_tcase_add_test_creds(tcase, "LogonControl2Ex", test_LogonControl2Ex);
2896
2897         tcase = torture_suite_add_machine_workstation_rpc_iface_tcase(suite, "netlogon",
2898                                                   &ndr_table_netlogon, TEST_MACHINE_NAME);
2899         torture_rpc_tcase_add_test_creds(tcase, "LogonControl", test_LogonControl);
2900         torture_rpc_tcase_add_test_creds(tcase, "LogonControl2", test_LogonControl2);
2901         torture_rpc_tcase_add_test_creds(tcase, "LogonControl2Ex", test_LogonControl2Ex);
2902
2903         tcase = torture_suite_add_rpc_iface_tcase(suite, "netlogon",
2904                                                   &ndr_table_netlogon);
2905         torture_rpc_tcase_add_test_creds(tcase, "LogonControl", test_LogonControl);
2906         torture_rpc_tcase_add_test_creds(tcase, "LogonControl2", test_LogonControl2);
2907         torture_rpc_tcase_add_test_creds(tcase, "LogonControl2Ex", test_LogonControl2Ex);
2908
2909         return suite;
2910 }