s4:torture/rpc/netlogon - Fix uninitialised variable
[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                 const char *database = NULL;
1358
1359                 switch (d) {
1360                 case 0:
1361                         database = "SAM";
1362                         break;
1363                 case 1:
1364                         database = "BUILTIN";
1365                         break;
1366                 case 2:
1367                         database = "LSA";
1368                         break;
1369                 default:
1370                         break;
1371                 }
1372
1373                 torture_comment(tctx, "Testing DatabaseRedo\n");
1374
1375                 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1376                         return false;
1377                 }
1378
1379                 for (i=0;i<ARRAY_SIZE(changes);i++) {
1380
1381                         if (d != changes[i].db_index) {
1382                                 continue;
1383                         }
1384
1385                         netlogon_creds_client_authenticator(creds, &credential);
1386
1387                         r.in.credential = &credential;
1388
1389                         e.serial_number1        = 0;
1390                         e.serial_number2        = 0;
1391                         e.object_rid            = changes[i].rid;
1392                         e.flags                 = changes[i].flags;
1393                         e.db_index              = changes[i].db_index;
1394                         e.delta_type            = changes[i].delta_type;
1395
1396                         switch (changes[i].flags & (NETR_CHANGELOG_NAME_INCLUDED | NETR_CHANGELOG_SID_INCLUDED)) {
1397                         case NETR_CHANGELOG_SID_INCLUDED:
1398                                 e.object.object_sid             = changes[i].sid;
1399                                 break;
1400                         case NETR_CHANGELOG_NAME_INCLUDED:
1401                                 e.object.object_name            = changes[i].name;
1402                                 break;
1403                         default:
1404                                 break;
1405                         }
1406
1407                         r.in.change_log_entry = e;
1408
1409                         torture_comment(tctx, "Testing DatabaseRedo with database %s and %s\n",
1410                                 database, changes[i].comment);
1411
1412                         status = dcerpc_netr_DatabaseRedo(p, tctx, &r);
1413                         if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
1414                                 return true;
1415                         }
1416
1417                         torture_assert_ntstatus_equal(tctx, status, changes[i].expected_error, changes[i].comment);
1418                         if (delta_enum_array) {
1419                                 torture_assert_int_equal(tctx,
1420                                         delta_enum_array->num_deltas,
1421                                         changes[i].expected_num_results,
1422                                         changes[i].comment);
1423                                 if (delta_enum_array->num_deltas > 0) {
1424                                         torture_assert_int_equal(tctx,
1425                                                 delta_enum_array->delta_enum[0].delta_type,
1426                                                 changes[i].expected_delta_type_1,
1427                                                 changes[i].comment);
1428                                 }
1429                                 if (delta_enum_array->num_deltas > 1) {
1430                                         torture_assert_int_equal(tctx,
1431                                                 delta_enum_array->delta_enum[1].delta_type,
1432                                                 changes[i].expected_delta_type_2,
1433                                                 changes[i].comment);
1434                                 }
1435                         }
1436
1437                         if (!netlogon_creds_client_check(creds, &return_authenticator.cred)) {
1438                                 torture_comment(tctx, "Credential chaining failed\n");
1439                                 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1440                                         return false;
1441                                 }
1442                         }
1443                 }
1444         }
1445         }
1446
1447         return true;
1448 }
1449
1450 /*
1451   try a netlogon AccountDeltas
1452 */
1453 static bool test_AccountDeltas(struct torture_context *tctx, 
1454                                struct dcerpc_pipe *p,
1455                                struct cli_credentials *machine_credentials)
1456 {
1457         NTSTATUS status;
1458         struct netr_AccountDeltas r;
1459         struct netlogon_creds_CredentialState *creds;
1460
1461         struct netr_AccountBuffer buffer;
1462         uint32_t count_returned = 0;
1463         uint32_t total_entries = 0;
1464         struct netr_UAS_INFO_0 recordid;
1465         struct netr_Authenticator return_authenticator;
1466
1467         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1468                 return false;
1469         }
1470
1471         ZERO_STRUCT(return_authenticator);
1472
1473         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1474         r.in.computername = TEST_MACHINE_NAME;
1475         r.in.return_authenticator = &return_authenticator;
1476         netlogon_creds_client_authenticator(creds, &r.in.credential);
1477         ZERO_STRUCT(r.in.uas);
1478         r.in.count=10;
1479         r.in.level=0;
1480         r.in.buffersize=100;
1481         r.out.buffer = &buffer;
1482         r.out.count_returned = &count_returned;
1483         r.out.total_entries = &total_entries;
1484         r.out.recordid = &recordid;
1485         r.out.return_authenticator = &return_authenticator;
1486
1487         /* w2k3 returns "NOT IMPLEMENTED" for this call */
1488         status = dcerpc_netr_AccountDeltas(p, tctx, &r);
1489         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "AccountDeltas");
1490
1491         return true;
1492 }
1493
1494 /*
1495   try a netlogon AccountSync
1496 */
1497 static bool test_AccountSync(struct torture_context *tctx, struct dcerpc_pipe *p, 
1498                              struct cli_credentials *machine_credentials)
1499 {
1500         NTSTATUS status;
1501         struct netr_AccountSync r;
1502         struct netlogon_creds_CredentialState *creds;
1503
1504         struct netr_AccountBuffer buffer;
1505         uint32_t count_returned = 0;
1506         uint32_t total_entries = 0;
1507         uint32_t next_reference = 0;
1508         struct netr_UAS_INFO_0 recordid;
1509         struct netr_Authenticator return_authenticator;
1510
1511         ZERO_STRUCT(recordid);
1512         ZERO_STRUCT(return_authenticator);
1513
1514         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1515                 return false;
1516         }
1517
1518         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1519         r.in.computername = TEST_MACHINE_NAME;
1520         r.in.return_authenticator = &return_authenticator;
1521         netlogon_creds_client_authenticator(creds, &r.in.credential);
1522         r.in.recordid = &recordid;
1523         r.in.reference=0;
1524         r.in.level=0;
1525         r.in.buffersize=100;
1526         r.out.buffer = &buffer;
1527         r.out.count_returned = &count_returned;
1528         r.out.total_entries = &total_entries;
1529         r.out.next_reference = &next_reference;
1530         r.out.recordid = &recordid;
1531         r.out.return_authenticator = &return_authenticator;
1532
1533         /* w2k3 returns "NOT IMPLEMENTED" for this call */
1534         status = dcerpc_netr_AccountSync(p, tctx, &r);
1535         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "AccountSync");
1536
1537         return true;
1538 }
1539
1540 /*
1541   try a netlogon GetDcName
1542 */
1543 static bool test_GetDcName(struct torture_context *tctx, 
1544                            struct dcerpc_pipe *p)
1545 {
1546         NTSTATUS status;
1547         struct netr_GetDcName r;
1548         const char *dcname = NULL;
1549
1550         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1551         r.in.domainname = lp_workgroup(tctx->lp_ctx);
1552         r.out.dcname = &dcname;
1553
1554         status = dcerpc_netr_GetDcName(p, tctx, &r);
1555         torture_assert_ntstatus_ok(tctx, status, "GetDcName");
1556         torture_assert_werr_ok(tctx, r.out.result, "GetDcName");
1557
1558         torture_comment(tctx, "\tDC is at '%s'\n", dcname);
1559
1560         return true;
1561 }
1562
1563 static const char *function_code_str(TALLOC_CTX *mem_ctx,
1564                                      enum netr_LogonControlCode function_code)
1565 {
1566         switch (function_code) {
1567         case NETLOGON_CONTROL_QUERY:
1568                 return "NETLOGON_CONTROL_QUERY";
1569         case NETLOGON_CONTROL_REPLICATE:
1570                 return "NETLOGON_CONTROL_REPLICATE";
1571         case NETLOGON_CONTROL_SYNCHRONIZE:
1572                 return "NETLOGON_CONTROL_SYNCHRONIZE";
1573         case NETLOGON_CONTROL_PDC_REPLICATE:
1574                 return "NETLOGON_CONTROL_PDC_REPLICATE";
1575         case NETLOGON_CONTROL_REDISCOVER:
1576                 return "NETLOGON_CONTROL_REDISCOVER";
1577         case NETLOGON_CONTROL_TC_QUERY:
1578                 return "NETLOGON_CONTROL_TC_QUERY";
1579         case NETLOGON_CONTROL_TRANSPORT_NOTIFY:
1580                 return "NETLOGON_CONTROL_TRANSPORT_NOTIFY";
1581         case NETLOGON_CONTROL_FIND_USER:
1582                 return "NETLOGON_CONTROL_FIND_USER";
1583         case NETLOGON_CONTROL_CHANGE_PASSWORD:
1584                 return "NETLOGON_CONTROL_CHANGE_PASSWORD";
1585         case NETLOGON_CONTROL_TC_VERIFY:
1586                 return "NETLOGON_CONTROL_TC_VERIFY";
1587         case NETLOGON_CONTROL_FORCE_DNS_REG:
1588                 return "NETLOGON_CONTROL_FORCE_DNS_REG";
1589         case NETLOGON_CONTROL_QUERY_DNS_REG:
1590                 return "NETLOGON_CONTROL_QUERY_DNS_REG";
1591         case NETLOGON_CONTROL_BACKUP_CHANGE_LOG:
1592                 return "NETLOGON_CONTROL_BACKUP_CHANGE_LOG";
1593         case NETLOGON_CONTROL_TRUNCATE_LOG:
1594                 return "NETLOGON_CONTROL_TRUNCATE_LOG";
1595         case NETLOGON_CONTROL_SET_DBFLAG:
1596                 return "NETLOGON_CONTROL_SET_DBFLAG";
1597         case NETLOGON_CONTROL_BREAKPOINT:
1598                 return "NETLOGON_CONTROL_BREAKPOINT";
1599         default:
1600                 return talloc_asprintf(mem_ctx, "unknown function code: %d",
1601                                        function_code);
1602         }
1603 }
1604
1605
1606 /*
1607   try a netlogon LogonControl 
1608 */
1609 static bool test_LogonControl(struct torture_context *tctx, 
1610                               struct dcerpc_pipe *p,
1611                               struct cli_credentials *machine_credentials)
1612
1613 {
1614         NTSTATUS status;
1615         struct netr_LogonControl r;
1616         union netr_CONTROL_QUERY_INFORMATION query;
1617         int i,f;
1618         enum netr_SchannelType secure_channel_type = SEC_CHAN_NULL;
1619
1620         uint32_t function_codes[] = {
1621                 NETLOGON_CONTROL_QUERY,
1622                 NETLOGON_CONTROL_REPLICATE,
1623                 NETLOGON_CONTROL_SYNCHRONIZE,
1624                 NETLOGON_CONTROL_PDC_REPLICATE,
1625                 NETLOGON_CONTROL_REDISCOVER,
1626                 NETLOGON_CONTROL_TC_QUERY,
1627                 NETLOGON_CONTROL_TRANSPORT_NOTIFY,
1628                 NETLOGON_CONTROL_FIND_USER,
1629                 NETLOGON_CONTROL_CHANGE_PASSWORD,
1630                 NETLOGON_CONTROL_TC_VERIFY,
1631                 NETLOGON_CONTROL_FORCE_DNS_REG,
1632                 NETLOGON_CONTROL_QUERY_DNS_REG,
1633                 NETLOGON_CONTROL_BACKUP_CHANGE_LOG,
1634                 NETLOGON_CONTROL_TRUNCATE_LOG,
1635                 NETLOGON_CONTROL_SET_DBFLAG,
1636                 NETLOGON_CONTROL_BREAKPOINT
1637         };
1638
1639         if (machine_credentials) {
1640                 secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
1641         }
1642
1643         torture_comment(tctx, "testing LogonControl with secure channel type: %d\n",
1644                 secure_channel_type);
1645
1646         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1647         r.in.function_code = 1;
1648         r.out.query = &query;
1649
1650         for (f=0;f<ARRAY_SIZE(function_codes); f++) {
1651         for (i=1;i<5;i++) {
1652
1653                 r.in.function_code = function_codes[f];
1654                 r.in.level = i;
1655
1656                 torture_comment(tctx, "Testing LogonControl function code %s (%d) level %d\n",
1657                                 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
1658
1659                 status = dcerpc_netr_LogonControl(p, tctx, &r);
1660                 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1661
1662                 switch (r.in.level) {
1663                 case 1:
1664                         switch (r.in.function_code) {
1665                         case NETLOGON_CONTROL_REPLICATE:
1666                         case NETLOGON_CONTROL_SYNCHRONIZE:
1667                         case NETLOGON_CONTROL_PDC_REPLICATE:
1668                         case NETLOGON_CONTROL_BREAKPOINT:
1669                         case NETLOGON_CONTROL_BACKUP_CHANGE_LOG:
1670                                 if ((secure_channel_type == SEC_CHAN_BDC) ||
1671                                     (secure_channel_type == SEC_CHAN_WKSTA)) {
1672                                         torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED,
1673                                                 "LogonControl returned unexpected error code");
1674                                 } else {
1675                                         torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
1676                                                 "LogonControl returned unexpected error code");
1677                                 }
1678                                 break;
1679
1680                         case NETLOGON_CONTROL_REDISCOVER:
1681                         case NETLOGON_CONTROL_TC_QUERY:
1682                         case NETLOGON_CONTROL_TRANSPORT_NOTIFY:
1683                         case NETLOGON_CONTROL_FIND_USER:
1684                         case NETLOGON_CONTROL_CHANGE_PASSWORD:
1685                         case NETLOGON_CONTROL_TC_VERIFY:
1686                         case NETLOGON_CONTROL_FORCE_DNS_REG:
1687                         case NETLOGON_CONTROL_QUERY_DNS_REG:
1688                         case NETLOGON_CONTROL_SET_DBFLAG:
1689                                 torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
1690                                         "LogonControl returned unexpected error code");
1691                                 break;
1692                         case NETLOGON_CONTROL_TRUNCATE_LOG:
1693                                 if ((secure_channel_type == SEC_CHAN_BDC) ||
1694                                     (secure_channel_type == SEC_CHAN_WKSTA)) {
1695                                         torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED,
1696                                                 "LogonControl returned unexpected error code");
1697                                 } else {
1698                                         torture_assert_werr_ok(tctx, r.out.result,
1699                                                 "LogonControl returned unexpected result");
1700                                 }
1701                                 break;
1702                         default:
1703                                 torture_assert_werr_ok(tctx, r.out.result,
1704                                         "LogonControl returned unexpected result");
1705                                 break;
1706                         }
1707                         break;
1708                 case 2:
1709                         torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
1710                                 "LogonControl returned unexpected error code");
1711                         break;
1712                 default:
1713                         torture_assert_werr_equal(tctx, r.out.result, WERR_UNKNOWN_LEVEL,
1714                                 "LogonControl returned unexpected error code");
1715                         break;
1716                 }
1717         }
1718         }
1719
1720         return true;
1721 }
1722
1723
1724 /*
1725   try a netlogon GetAnyDCName
1726 */
1727 static bool test_GetAnyDCName(struct torture_context *tctx, 
1728                               struct dcerpc_pipe *p)
1729 {
1730         NTSTATUS status;
1731         struct netr_GetAnyDCName r;
1732         const char *dcname = NULL;
1733
1734         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1735         r.in.domainname = lp_workgroup(tctx->lp_ctx);
1736         r.out.dcname = &dcname;
1737
1738         status = dcerpc_netr_GetAnyDCName(p, tctx, &r);
1739         torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
1740         torture_assert_werr_ok(tctx, r.out.result, "GetAnyDCName");
1741
1742         if (dcname) {
1743             torture_comment(tctx, "\tDC is at '%s'\n", dcname);
1744         }
1745
1746         return true;
1747 }
1748
1749
1750 /*
1751   try a netlogon LogonControl2
1752 */
1753 static bool test_LogonControl2(struct torture_context *tctx, 
1754                                struct dcerpc_pipe *p,
1755                                struct cli_credentials *machine_credentials)
1756
1757 {
1758         NTSTATUS status;
1759         struct netr_LogonControl2 r;
1760         union netr_CONTROL_DATA_INFORMATION data;
1761         union netr_CONTROL_QUERY_INFORMATION query;
1762         int i;
1763
1764         data.domain = lp_workgroup(tctx->lp_ctx);
1765
1766         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1767
1768         r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
1769         r.in.data = &data;
1770         r.out.query = &query;
1771
1772         for (i=1;i<4;i++) {
1773                 r.in.level = i;
1774
1775                 torture_comment(tctx, "Testing LogonControl2 level %d function %d\n", 
1776                        i, r.in.function_code);
1777
1778                 status = dcerpc_netr_LogonControl2(p, tctx, &r);
1779                 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1780         }
1781
1782         data.domain = lp_workgroup(tctx->lp_ctx);
1783
1784         r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
1785         r.in.data = &data;
1786
1787         for (i=1;i<4;i++) {
1788                 r.in.level = i;
1789
1790                 torture_comment(tctx, "Testing LogonControl2 level %d function %d\n", 
1791                        i, r.in.function_code);
1792
1793                 status = dcerpc_netr_LogonControl2(p, tctx, &r);
1794                 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1795         }
1796
1797         data.domain = lp_workgroup(tctx->lp_ctx);
1798
1799         r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
1800         r.in.data = &data;
1801
1802         for (i=1;i<4;i++) {
1803                 r.in.level = i;
1804
1805                 torture_comment(tctx, "Testing LogonControl2 level %d function %d\n", 
1806                        i, r.in.function_code);
1807
1808                 status = dcerpc_netr_LogonControl2(p, tctx, &r);
1809                 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1810         }
1811
1812         data.debug_level = ~0;
1813
1814         r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
1815         r.in.data = &data;
1816
1817         for (i=1;i<4;i++) {
1818                 r.in.level = i;
1819
1820                 torture_comment(tctx, "Testing LogonControl2 level %d function %d\n", 
1821                        i, r.in.function_code);
1822
1823                 status = dcerpc_netr_LogonControl2(p, tctx, &r);
1824                 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1825         }
1826
1827         return true;
1828 }
1829
1830 /*
1831   try a netlogon DatabaseSync2
1832 */
1833 static bool test_DatabaseSync2(struct torture_context *tctx, 
1834                                struct dcerpc_pipe *p,
1835                                struct cli_credentials *machine_credentials)
1836 {
1837         NTSTATUS status;
1838         struct netr_DatabaseSync2 r;
1839         struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
1840         struct netr_Authenticator return_authenticator, credential;
1841
1842         struct netlogon_creds_CredentialState *creds;
1843         const uint32_t database_ids[] = {0, 1, 2}; 
1844         int i;
1845
1846         if (!test_SetupCredentials2(p, tctx, NETLOGON_NEG_AUTH2_FLAGS, 
1847                                     machine_credentials,
1848                                     cli_credentials_get_secure_channel_type(machine_credentials),
1849                                     &creds)) {
1850                 return false;
1851         }
1852
1853         ZERO_STRUCT(return_authenticator);
1854
1855         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1856         r.in.computername = TEST_MACHINE_NAME;
1857         r.in.preferredmaximumlength = (uint32_t)-1;
1858         r.in.return_authenticator = &return_authenticator;
1859         r.out.return_authenticator = &return_authenticator;
1860         r.out.delta_enum_array = &delta_enum_array;
1861
1862         for (i=0;i<ARRAY_SIZE(database_ids);i++) {
1863
1864                 uint32_t sync_context = 0;
1865
1866                 r.in.database_id = database_ids[i];
1867                 r.in.sync_context = &sync_context;
1868                 r.out.sync_context = &sync_context;
1869                 r.in.restart_state = 0;
1870
1871                 torture_comment(tctx, "Testing DatabaseSync2 of id %d\n", r.in.database_id);
1872
1873                 do {
1874                         netlogon_creds_client_authenticator(creds, &credential);
1875
1876                         r.in.credential = &credential;
1877
1878                         status = dcerpc_netr_DatabaseSync2(p, tctx, &r);
1879                         if (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
1880                             break;
1881
1882                         /* Native mode servers don't do this */
1883                         if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
1884                                 return true;
1885                         }
1886
1887                         torture_assert_ntstatus_ok(tctx, status, "DatabaseSync2");
1888
1889                         if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
1890                                 torture_comment(tctx, "Credential chaining failed\n");
1891                         }
1892
1893                 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
1894         }
1895
1896         return true;
1897 }
1898
1899
1900 /*
1901   try a netlogon LogonControl2Ex
1902 */
1903 static bool test_LogonControl2Ex(struct torture_context *tctx, 
1904                                  struct dcerpc_pipe *p,
1905                                  struct cli_credentials *machine_credentials)
1906
1907 {
1908         NTSTATUS status;
1909         struct netr_LogonControl2Ex r;
1910         union netr_CONTROL_DATA_INFORMATION data;
1911         union netr_CONTROL_QUERY_INFORMATION query;
1912         int i;
1913
1914         data.domain = lp_workgroup(tctx->lp_ctx);
1915
1916         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1917
1918         r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
1919         r.in.data = &data;
1920         r.out.query = &query;
1921
1922         for (i=1;i<4;i++) {
1923                 r.in.level = i;
1924
1925                 torture_comment(tctx, "Testing LogonControl2Ex level %d function %d\n", 
1926                        i, r.in.function_code);
1927
1928                 status = dcerpc_netr_LogonControl2Ex(p, tctx, &r);
1929                 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1930         }
1931
1932         data.domain = lp_workgroup(tctx->lp_ctx);
1933
1934         r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
1935         r.in.data = &data;
1936
1937         for (i=1;i<4;i++) {
1938                 r.in.level = i;
1939
1940                 torture_comment(tctx, "Testing LogonControl2Ex level %d function %d\n", 
1941                        i, r.in.function_code);
1942
1943                 status = dcerpc_netr_LogonControl2Ex(p, tctx, &r);
1944                 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1945         }
1946
1947         data.domain = lp_workgroup(tctx->lp_ctx);
1948
1949         r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
1950         r.in.data = &data;
1951
1952         for (i=1;i<4;i++) {
1953                 r.in.level = i;
1954
1955                 torture_comment(tctx, "Testing LogonControl2Ex level %d function %d\n", 
1956                        i, r.in.function_code);
1957
1958                 status = dcerpc_netr_LogonControl2Ex(p, tctx, &r);
1959                 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1960         }
1961
1962         data.debug_level = ~0;
1963
1964         r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
1965         r.in.data = &data;
1966
1967         for (i=1;i<4;i++) {
1968                 r.in.level = i;
1969
1970                 torture_comment(tctx, "Testing LogonControl2Ex level %d function %d\n", 
1971                        i, r.in.function_code);
1972
1973                 status = dcerpc_netr_LogonControl2Ex(p, tctx, &r);
1974                 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1975         }
1976
1977         return true;
1978 }
1979
1980 static bool test_netr_DsRGetForestTrustInformation(struct torture_context *tctx, 
1981                                                    struct dcerpc_pipe *p, const char *trusted_domain_name) 
1982 {
1983         NTSTATUS status;
1984         struct netr_DsRGetForestTrustInformation r;
1985         struct lsa_ForestTrustInformation info, *info_ptr;
1986
1987         info_ptr = &info;
1988
1989         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1990         r.in.trusted_domain_name = trusted_domain_name;
1991         r.in.flags = 0;
1992         r.out.forest_trust_info = &info_ptr;
1993
1994         torture_comment(tctx ,"Testing netr_DsRGetForestTrustInformation\n");
1995
1996         status = dcerpc_netr_DsRGetForestTrustInformation(p, tctx, &r);
1997         torture_assert_ntstatus_ok(tctx, status, "DsRGetForestTrustInformation");
1998         torture_assert_werr_ok(tctx, r.out.result, "DsRGetForestTrustInformation");
1999
2000         return true;
2001 }
2002
2003 /*
2004   try a netlogon netr_DsrEnumerateDomainTrusts
2005 */
2006 static bool test_DsrEnumerateDomainTrusts(struct torture_context *tctx, 
2007                                           struct dcerpc_pipe *p)
2008 {
2009         NTSTATUS status;
2010         struct netr_DsrEnumerateDomainTrusts r;
2011         struct netr_DomainTrustList trusts;
2012         int i;
2013
2014         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2015         r.in.trust_flags = 0x3f;
2016         r.out.trusts = &trusts;
2017
2018         status = dcerpc_netr_DsrEnumerateDomainTrusts(p, tctx, &r);
2019         torture_assert_ntstatus_ok(tctx, status, "DsrEnumerateDomaintrusts");
2020         torture_assert_werr_ok(tctx, r.out.result, "DsrEnumerateDomaintrusts");
2021
2022         /* when trusted_domain_name is NULL, netr_DsRGetForestTrustInformation
2023          * will show non-forest trusts and all UPN suffixes of the own forest
2024          * as LSA_FOREST_TRUST_TOP_LEVEL_NAME types */
2025
2026         if (r.out.trusts->count) {
2027                 if (!test_netr_DsRGetForestTrustInformation(tctx, p, NULL)) {
2028                         return false;
2029                 }
2030         }
2031
2032         for (i=0; i<r.out.trusts->count; i++) {
2033
2034                 /* get info for transitive forest trusts */
2035
2036                 if (r.out.trusts->array[i].trust_attributes & NETR_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) {
2037                         if (!test_netr_DsRGetForestTrustInformation(tctx, p, 
2038                                                                     r.out.trusts->array[i].dns_name)) {
2039                                 return false;
2040                         }
2041                 }
2042         }
2043
2044         return true;
2045 }
2046
2047 static bool test_netr_NetrEnumerateTrustedDomains(struct torture_context *tctx,
2048                                                   struct dcerpc_pipe *p)
2049 {
2050         NTSTATUS status;
2051         struct netr_NetrEnumerateTrustedDomains r;
2052         struct netr_Blob trusted_domains_blob;
2053
2054         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2055         r.out.trusted_domains_blob = &trusted_domains_blob;
2056
2057         status = dcerpc_netr_NetrEnumerateTrustedDomains(p, tctx, &r);
2058         torture_assert_ntstatus_ok(tctx, status, "netr_NetrEnumerateTrustedDomains");
2059         torture_assert_werr_ok(tctx, r.out.result, "NetrEnumerateTrustedDomains");
2060
2061         return true;
2062 }
2063
2064 static bool test_netr_NetrEnumerateTrustedDomainsEx(struct torture_context *tctx,
2065                                                     struct dcerpc_pipe *p)
2066 {
2067         NTSTATUS status;
2068         struct netr_NetrEnumerateTrustedDomainsEx r;
2069         struct netr_DomainTrustList dom_trust_list;
2070
2071         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2072         r.out.dom_trust_list = &dom_trust_list;
2073
2074         status = dcerpc_netr_NetrEnumerateTrustedDomainsEx(p, tctx, &r);
2075         torture_assert_ntstatus_ok(tctx, status, "netr_NetrEnumerateTrustedDomainsEx");
2076         torture_assert_werr_ok(tctx, r.out.result, "NetrEnumerateTrustedDomainsEx");
2077
2078         return true;
2079 }
2080
2081
2082 static bool test_netr_DsRGetSiteName(struct dcerpc_pipe *p, struct torture_context *tctx,
2083                                      const char *computer_name, 
2084                                      const char *expected_site) 
2085 {
2086         NTSTATUS status;
2087         struct netr_DsRGetSiteName r;
2088         const char *site = NULL;
2089
2090         if (torture_setting_bool(tctx, "samba4", false))
2091                 torture_skip(tctx, "skipping DsRGetSiteName test against Samba4");
2092
2093         r.in.computer_name              = computer_name;
2094         r.out.site                      = &site;
2095         torture_comment(tctx, "Testing netr_DsRGetSiteName\n");
2096
2097         status = dcerpc_netr_DsRGetSiteName(p, tctx, &r);
2098         torture_assert_ntstatus_ok(tctx, status, "DsRGetSiteName");
2099         torture_assert_werr_ok(tctx, r.out.result, "DsRGetSiteName");
2100         torture_assert_str_equal(tctx, expected_site, site, "netr_DsRGetSiteName");
2101
2102         r.in.computer_name              = talloc_asprintf(tctx, "\\\\%s", computer_name);
2103         torture_comment(tctx, 
2104                         "Testing netr_DsRGetSiteName with broken computer name: %s\n", r.in.computer_name);
2105
2106         status = dcerpc_netr_DsRGetSiteName(p, tctx, &r);
2107         torture_assert_ntstatus_ok(tctx, status, "DsRGetSiteName");
2108         torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_COMPUTERNAME, "netr_DsRGetSiteName");
2109
2110         return true;
2111 }
2112
2113 /*
2114   try a netlogon netr_DsRGetDCName
2115 */
2116 static bool test_netr_DsRGetDCName(struct torture_context *tctx, 
2117                                    struct dcerpc_pipe *p)
2118 {
2119         NTSTATUS status;
2120         struct netr_DsRGetDCName r;
2121         struct netr_DsRGetDCNameInfo *info = NULL;
2122
2123         r.in.server_unc         = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2124         r.in.domain_name        = lp_dnsdomain(tctx->lp_ctx);
2125         r.in.domain_guid        = NULL;
2126         r.in.site_guid          = NULL;
2127         r.in.flags              = DS_RETURN_DNS_NAME;
2128         r.out.info              = &info;
2129
2130         status = dcerpc_netr_DsRGetDCName(p, tctx, &r);
2131         torture_assert_ntstatus_ok(tctx, status, "DsRGetDCName");
2132         torture_assert_werr_ok(tctx, r.out.result, "DsRGetDCName");
2133         return test_netr_DsRGetSiteName(p, tctx, 
2134                                        info->dc_unc,
2135                                        info->dc_site_name);
2136 }
2137
2138 /*
2139   try a netlogon netr_DsRGetDCNameEx
2140 */
2141 static bool test_netr_DsRGetDCNameEx(struct torture_context *tctx, 
2142                                      struct dcerpc_pipe *p)
2143 {
2144         NTSTATUS status;
2145         struct netr_DsRGetDCNameEx r;
2146         struct netr_DsRGetDCNameInfo *info = NULL;
2147
2148         r.in.server_unc         = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2149         r.in.domain_name        = lp_dnsdomain(tctx->lp_ctx);
2150         r.in.domain_guid        = NULL;
2151         r.in.site_name          = NULL;
2152         r.in.flags              = DS_RETURN_DNS_NAME;
2153         r.out.info              = &info;
2154
2155         status = dcerpc_netr_DsRGetDCNameEx(p, tctx, &r);
2156         torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx");
2157         torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx");
2158
2159         return test_netr_DsRGetSiteName(p, tctx, info->dc_unc,
2160                                         info->dc_site_name);
2161 }
2162
2163 /*
2164   try a netlogon netr_DsRGetDCNameEx2
2165 */
2166 static bool test_netr_DsRGetDCNameEx2(struct torture_context *tctx, 
2167                                       struct dcerpc_pipe *p)
2168 {
2169         NTSTATUS status;
2170         struct netr_DsRGetDCNameEx2 r;
2171         struct netr_DsRGetDCNameInfo *info = NULL;
2172
2173         r.in.server_unc         = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2174         r.in.client_account     = NULL;
2175         r.in.mask               = 0x00000000;
2176         r.in.domain_name        = lp_dnsdomain(tctx->lp_ctx);
2177         r.in.domain_guid        = NULL;
2178         r.in.site_name          = NULL;
2179         r.in.flags              = DS_RETURN_DNS_NAME;
2180         r.out.info              = &info;
2181
2182         torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 without client account\n");
2183
2184         status = dcerpc_netr_DsRGetDCNameEx2(p, tctx, &r);
2185         torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
2186         torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
2187
2188         torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 with client acount\n");
2189         r.in.client_account     = TEST_MACHINE_NAME"$";
2190         r.in.mask               = ACB_SVRTRUST;
2191         r.in.flags              = DS_RETURN_FLAT_NAME;
2192         r.out.info              = &info;
2193
2194         status = dcerpc_netr_DsRGetDCNameEx2(p, tctx, &r);
2195         torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
2196         torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
2197         return test_netr_DsRGetSiteName(p, tctx, info->dc_unc,
2198                                         info->dc_site_name);
2199 }
2200
2201 static bool test_netr_DsrGetDcSiteCoverageW(struct torture_context *tctx, 
2202                                             struct dcerpc_pipe *p)
2203 {
2204         NTSTATUS status;
2205         struct netr_DsrGetDcSiteCoverageW r;
2206         struct DcSitesCtr *ctr = NULL;
2207
2208         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2209         r.out.ctr = &ctr;
2210
2211         status = dcerpc_netr_DsrGetDcSiteCoverageW(p, tctx, &r);
2212         torture_assert_ntstatus_ok(tctx, status, "failed");
2213         torture_assert_werr_ok(tctx, r.out.result, "failed");
2214
2215         return true;
2216 }
2217
2218 static bool test_netr_DsRAddressToSitenamesW(struct torture_context *tctx,
2219                                              struct dcerpc_pipe *p)
2220 {
2221         NTSTATUS status;
2222         struct netr_DsRAddressToSitenamesW r;
2223         struct netr_DsRAddress addr;
2224         struct netr_DsRAddressToSitenamesWCtr *ctr;
2225
2226         ctr = talloc(tctx, struct netr_DsRAddressToSitenamesWCtr);
2227
2228         addr.size = 16;
2229         addr.buffer = talloc_zero_array(tctx, uint8_t, addr.size);
2230
2231         addr.buffer[0] = 2; /* AF_INET */
2232         addr.buffer[4] = 127;
2233         addr.buffer[5] = 0;
2234         addr.buffer[6] = 0;
2235         addr.buffer[7] = 1;
2236
2237         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2238         r.in.count = 1;
2239         r.in.addresses = talloc_zero_array(tctx, struct netr_DsRAddress, r.in.count);
2240         r.in.addresses[0] = addr;
2241         r.out.ctr = &ctr;
2242
2243         status = dcerpc_netr_DsRAddressToSitenamesW(p, tctx, &r);
2244         torture_assert_ntstatus_ok(tctx, status, "failed");
2245         torture_assert_werr_ok(tctx, r.out.result, "failed");
2246
2247         return true;
2248 }
2249
2250 static bool test_netr_DsRAddressToSitenamesExW(struct torture_context *tctx,
2251                                                struct dcerpc_pipe *p)
2252 {
2253         NTSTATUS status;
2254         struct netr_DsRAddressToSitenamesExW r;
2255         struct netr_DsRAddress addr;
2256         struct netr_DsRAddressToSitenamesExWCtr *ctr;
2257
2258         ctr = talloc(tctx, struct netr_DsRAddressToSitenamesExWCtr);
2259
2260         addr.size = 16;
2261         addr.buffer = talloc_zero_array(tctx, uint8_t, addr.size);
2262
2263         addr.buffer[0] = 2; /* AF_INET */
2264         addr.buffer[4] = 127;
2265         addr.buffer[5] = 0;
2266         addr.buffer[6] = 0;
2267         addr.buffer[7] = 1;
2268
2269         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2270         r.in.count = 1;
2271         r.in.addresses = talloc_zero_array(tctx, struct netr_DsRAddress, r.in.count);
2272         r.in.addresses[0] = addr;
2273         r.out.ctr = &ctr;
2274
2275         status = dcerpc_netr_DsRAddressToSitenamesExW(p, tctx, &r);
2276         torture_assert_ntstatus_ok(tctx, status, "failed");
2277         torture_assert_werr_ok(tctx, r.out.result, "failed");
2278
2279         return true;
2280 }
2281
2282 static bool test_netr_ServerGetTrustInfo(struct torture_context *tctx,
2283                                          struct dcerpc_pipe *p,
2284                                          struct cli_credentials *machine_credentials)
2285 {
2286         NTSTATUS status;
2287         struct netr_ServerGetTrustInfo r;
2288
2289         struct netr_Authenticator a;
2290         struct netr_Authenticator return_authenticator;
2291         struct samr_Password new_owf_password;
2292         struct samr_Password old_owf_password;
2293         struct netr_TrustInfo *trust_info;
2294
2295         struct netlogon_creds_CredentialState *creds;
2296
2297         if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
2298                                     machine_credentials, &creds)) {
2299                 return false;
2300         }
2301
2302         netlogon_creds_client_authenticator(creds, &a);
2303
2304         r.in.server_name                = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2305         r.in.account_name               = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
2306         r.in.secure_channel_type        = cli_credentials_get_secure_channel_type(machine_credentials);
2307         r.in.computer_name              = TEST_MACHINE_NAME;
2308         r.in.credential                 = &a;
2309
2310         r.out.return_authenticator      = &return_authenticator;
2311         r.out.new_owf_password          = &new_owf_password;
2312         r.out.old_owf_password          = &old_owf_password;
2313         r.out.trust_info                = &trust_info;
2314
2315         status = dcerpc_netr_ServerGetTrustInfo(p, tctx, &r);
2316         torture_assert_ntstatus_ok(tctx, status, "failed");
2317         torture_assert(tctx, netlogon_creds_client_check(creds, &return_authenticator.cred), "Credential chaining failed");
2318
2319         return true;
2320 }
2321
2322
2323 static bool test_GetDomainInfo(struct torture_context *tctx, 
2324                                struct dcerpc_pipe *p,
2325                                struct cli_credentials *machine_credentials)
2326 {
2327         NTSTATUS status;
2328         struct netr_LogonGetDomainInfo r;
2329         struct netr_WorkstationInformation q1;
2330         struct netr_Authenticator a;
2331         struct netlogon_creds_CredentialState *creds;
2332         struct netr_OsVersion os;
2333         union netr_WorkstationInfo query;
2334         union netr_DomainInfo info;
2335         const char* const attrs[] = { "dNSHostName", "operatingSystem",
2336                 "operatingSystemServicePack", "operatingSystemVersion",
2337                 "servicePrincipalName", NULL };
2338         char *url;
2339         struct ldb_context *sam_ctx = NULL;
2340         struct ldb_message **res;
2341         struct ldb_message_element *spn_el;
2342         int ret, i;
2343         char *version_str;
2344         const char *old_dnsname = NULL;
2345         char **spns = NULL;
2346         int num_spns = 0;
2347         char *temp_str;
2348
2349         torture_comment(tctx, "Testing netr_LogonGetDomainInfo\n");
2350
2351         if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS, 
2352                                     machine_credentials, &creds)) {
2353                 return false;
2354         }
2355
2356         /* We won't double-check this when we are over 'local' transports */
2357         if (dcerpc_server_name(p)) {
2358                 /* Set up connection to SAMDB on DC */
2359                 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
2360                 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
2361                                            NULL,
2362                                            cmdline_credentials,
2363                                            0);
2364                 
2365                 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
2366         }
2367
2368         torture_comment(tctx, "Testing netr_LogonGetDomainInfo 1st call (no variation of DNS hostname)\n");
2369         netlogon_creds_client_authenticator(creds, &a);
2370
2371         ZERO_STRUCT(r);
2372         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2373         r.in.computer_name = TEST_MACHINE_NAME;
2374         r.in.credential = &a;
2375         r.in.level = 1;
2376         r.in.return_authenticator = &a;
2377         r.in.query = &query;
2378         r.out.return_authenticator = &a;
2379         r.out.info = &info;
2380
2381         ZERO_STRUCT(os);
2382         os.os.MajorVersion = 123;
2383         os.os.MinorVersion = 456;
2384         os.os.BuildNumber = 789;
2385         os.os.CSDVersion = "Service Pack 10";
2386         os.os.ServicePackMajor = 10;
2387         os.os.ServicePackMinor = 1;
2388         os.os.SuiteMask = NETR_VER_SUITE_SINGLEUSERTS;
2389         os.os.ProductType = NETR_VER_NT_SERVER;
2390         os.os.Reserved = 0;
2391
2392         version_str = talloc_asprintf(tctx, "%d.%d (%d)", os.os.MajorVersion,
2393                 os.os.MinorVersion, os.os.BuildNumber);
2394
2395         ZERO_STRUCT(q1);
2396         q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
2397                 TEST_MACHINE_DNS_SUFFIX);
2398         q1.sitename = "Default-First-Site-Name";
2399         q1.os_version.os = &os;
2400         q1.os_name.string = talloc_asprintf(tctx,
2401                                             "Tortured by Samba4 RPC-NETLOGON: %s",
2402                                             timestring(tctx, time(NULL)));
2403
2404         /* The workstation handles the "servicePrincipalName" and DNS hostname
2405            updates */
2406         q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
2407
2408         query.workstation_info = &q1;
2409
2410         if (sam_ctx) {
2411                 /* Gets back the old DNS hostname in AD */
2412                 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
2413                                    "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
2414                 old_dnsname =
2415                         ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL);
2416                 
2417                 /* Gets back the "servicePrincipalName"s in AD */
2418                 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
2419                 if (spn_el != NULL) {
2420                         for (i=0; i < spn_el->num_values; i++) {
2421                                 spns = talloc_realloc(tctx, spns, char *, i + 1);
2422                                 spns[i] = (char *) spn_el->values[i].data;
2423                         }
2424                         num_spns = i;
2425                 }
2426         }
2427
2428         status = dcerpc_netr_LogonGetDomainInfo(p, tctx, &r);
2429         torture_assert_ntstatus_ok(tctx, status, "netr_LogonGetDomainInfo");
2430         torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
2431
2432         msleep(250);
2433
2434         if (sam_ctx) {
2435                 /* AD workstation infos entry check */
2436                 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
2437                                    "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
2438                 torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
2439                 torture_assert_str_equal(tctx,
2440                                          ldb_msg_find_attr_as_string(res[0], "operatingSystem", NULL),
2441                                          q1.os_name.string, "'operatingSystem' wrong!");
2442                 torture_assert_str_equal(tctx,
2443                                          ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL),
2444                                          os.os.CSDVersion, "'operatingSystemServicePack' wrong!");
2445                 torture_assert_str_equal(tctx,
2446                                          ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL),
2447                                          version_str, "'operatingSystemVersion' wrong!");
2448
2449                 if (old_dnsname != NULL) {
2450                         /* If before a DNS hostname was set then it should remain
2451                            the same in combination with the "servicePrincipalName"s.
2452                            The DNS hostname should also be returned by our
2453                            "LogonGetDomainInfo" call (in the domain info structure). */
2454                         
2455                         torture_assert_str_equal(tctx,
2456                                                  ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL),
2457                                                  old_dnsname, "'DNS hostname' was not set!");
2458                         
2459                         spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
2460                         torture_assert(tctx, ((spns != NULL) && (spn_el != NULL)),
2461                                        "'servicePrincipalName's not set!");
2462                         torture_assert(tctx, spn_el->num_values == num_spns,
2463                                        "'servicePrincipalName's incorrect!");
2464                         for (i=0; (i < spn_el->num_values) && (i < num_spns); i++)
2465                                 torture_assert_str_equal(tctx,
2466                                                          (char *) spn_el->values[i].data,
2467                                 spns[i], "'servicePrincipalName's incorrect!");
2468
2469                         torture_assert_str_equal(tctx,
2470                                                  info.domain_info->dns_hostname.string,
2471                                                  old_dnsname,
2472                                                  "Out 'DNS hostname' doesn't match the old one!");
2473                 } else {
2474                         /* If no DNS hostname was set then also now none should be set,
2475                            the "servicePrincipalName"s should remain empty and no DNS
2476                            hostname should be returned by our "LogonGetDomainInfo"
2477                            call (in the domain info structure). */
2478                         
2479                         torture_assert(tctx,
2480                                        ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL) == NULL,
2481                                        "'DNS hostname' was set!");
2482                         
2483                         spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
2484                         torture_assert(tctx, ((spns == NULL) && (spn_el == NULL)),
2485                                        "'servicePrincipalName's were set!");
2486                         
2487                         torture_assert(tctx,
2488                                        info.domain_info->dns_hostname.string == NULL,
2489                                        "Out 'DNS host name' was set!");
2490                 }
2491         }
2492
2493         /* Checks "workstation flags" */
2494         torture_assert(tctx,
2495                 info.domain_info->workstation_flags
2496                 == NETR_WS_FLAG_HANDLES_SPN_UPDATE,
2497                 "Out 'workstation flags' don't match!");
2498
2499
2500         torture_comment(tctx, "Testing netr_LogonGetDomainInfo 2nd call (variation of DNS hostname)\n");
2501         netlogon_creds_client_authenticator(creds, &a);
2502
2503         /* Wipe out the osVersion, and prove which values still 'stick' */
2504         q1.os_version.os = NULL;
2505
2506         /* Change also the DNS hostname to test differences in behaviour */
2507         q1.dns_hostname = talloc_asprintf(tctx, "%s.newdomain",
2508                 TEST_MACHINE_NAME);
2509
2510         /* Let the DC handle the "servicePrincipalName" and DNS hostname
2511            updates */
2512         q1.workstation_flags = 0;
2513
2514         status = dcerpc_netr_LogonGetDomainInfo(p, tctx, &r);
2515         torture_assert_ntstatus_ok(tctx, status, "netr_LogonGetDomainInfo");
2516         torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
2517
2518         msleep(250);
2519
2520         if (sam_ctx) {
2521                 /* AD workstation infos entry check */
2522                 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
2523                                    "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
2524                 torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
2525                 torture_assert_str_equal(tctx,
2526                                          ldb_msg_find_attr_as_string(res[0], "operatingSystem", NULL),
2527                                          q1.os_name.string, "'operatingSystem' should stick!");
2528                 torture_assert(tctx,
2529                                ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL) == NULL,
2530                                "'operatingSystemServicePack' shouldn't stick!");
2531                 torture_assert(tctx,
2532                                ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL) == NULL,
2533                                "'operatingSystemVersion' shouldn't stick!");
2534                 
2535                 /* The DNS host name should have been updated now by the server */
2536                 torture_assert_str_equal(tctx,
2537                                          ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL),
2538                                          q1.dns_hostname, "'DNS host name' didn't change!");
2539                 
2540                 /* Find the two "servicePrincipalName"s which the DC should have been
2541                    updated (HOST/<Netbios name> and HOST/<FQDN name>) - see MS-NRPC
2542                    3.5.4.3.9 */
2543                 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
2544                 torture_assert(tctx, spn_el != NULL,
2545                                "There should exist 'servicePrincipalName's in AD!");
2546                 temp_str = talloc_asprintf(tctx, "HOST/%s", TEST_MACHINE_NAME);
2547                 for (i=0; i < spn_el->num_values; i++)
2548                         if (strcmp((char *) spn_el->values[i].data, temp_str) == 0)
2549                                 break;
2550                 torture_assert(tctx, i != spn_el->num_values,
2551                                "'servicePrincipalName' HOST/<Netbios name> not found!");
2552                 temp_str = talloc_asprintf(tctx, "HOST/%s", q1.dns_hostname);
2553                 for (i=0; i < spn_el->num_values; i++)
2554                         if (strcmp((char *) spn_el->values[i].data, temp_str) == 0)
2555                                 break;
2556                 torture_assert(tctx, i != spn_el->num_values,
2557                                "'servicePrincipalName' HOST/<FQDN name> not found!");
2558                 
2559                 /* Check that the out DNS hostname was set properly */
2560                 torture_assert_str_equal(tctx, info.domain_info->dns_hostname.string,
2561                                          old_dnsname, "Out 'DNS hostname' doesn't match the old one!");
2562         }
2563
2564         /* Checks "workstation flags" */
2565         torture_assert(tctx,
2566                 info.domain_info->workstation_flags == 0,
2567                 "Out 'workstation flags' don't match!");
2568
2569
2570         torture_comment(tctx, "Testing netr_LogonGetDomainInfo 3rd call (verification of DNS hostname and check for trusted domains)\n");
2571         netlogon_creds_client_authenticator(creds, &a);
2572
2573         /* The workstation handles the "servicePrincipalName" and DNS hostname
2574            updates */
2575         q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
2576
2577         status = dcerpc_netr_LogonGetDomainInfo(p, tctx, &r);
2578         torture_assert_ntstatus_ok(tctx, status, "netr_LogonGetDomainInfo");
2579         torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
2580
2581         msleep(250);
2582
2583         /* Now the in/out DNS hostnames should be the same */
2584         torture_assert_str_equal(tctx,
2585                 info.domain_info->dns_hostname.string,
2586                 query.workstation_info->dns_hostname,
2587                 "In/Out 'DNS hostnames' don't match!");
2588
2589         /* Checks "workstation flags" */
2590         torture_assert(tctx,
2591                 info.domain_info->workstation_flags
2592                 == NETR_WS_FLAG_HANDLES_SPN_UPDATE,
2593                 "Out 'workstation flags' don't match!");
2594
2595         /* Checks for trusted domains */
2596         torture_assert(tctx,
2597                 (info.domain_info->trusted_domain_count != 0)
2598                 && (info.domain_info->trusted_domains != NULL),
2599                 "Trusted domains have been requested!");
2600
2601
2602         torture_comment(tctx, "Testing netr_LogonGetDomainInfo 4th call (check for trusted domains)\n");
2603         netlogon_creds_client_authenticator(creds, &a);
2604
2605         /* The workstation handles the "servicePrincipalName" and DNS hostname
2606            updates and requests inbound trusts */
2607         q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE
2608                 | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS;
2609
2610         status = dcerpc_netr_LogonGetDomainInfo(p, tctx, &r);
2611         torture_assert_ntstatus_ok(tctx, status, "netr_LogonGetDomainInfo");
2612         torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
2613
2614         msleep(250);
2615
2616         /* Checks "workstation flags" */
2617         torture_assert(tctx,
2618                 info.domain_info->workstation_flags
2619                 == (NETR_WS_FLAG_HANDLES_SPN_UPDATE
2620                         | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS),
2621                 "Out 'workstation flags' don't match!");
2622
2623         /* Checks for trusted domains */
2624         torture_assert(tctx,
2625                 (info.domain_info->trusted_domain_count != 0)
2626                 && (info.domain_info->trusted_domains != NULL),
2627                 "Trusted domains have been requested!");
2628
2629         return true;
2630 }
2631
2632
2633 static void async_callback(struct rpc_request *req)
2634 {
2635         int *counter = (int *)req->async.private_data;
2636         if (NT_STATUS_IS_OK(req->status)) {
2637                 (*counter)++;
2638         }
2639 }
2640
2641 static bool test_GetDomainInfo_async(struct torture_context *tctx, 
2642                                      struct dcerpc_pipe *p,
2643                                      struct cli_credentials *machine_credentials)
2644 {
2645         NTSTATUS status;
2646         struct netr_LogonGetDomainInfo r;
2647         struct netr_WorkstationInformation q1;
2648         struct netr_Authenticator a;
2649 #define ASYNC_COUNT 100
2650         struct netlogon_creds_CredentialState *creds;
2651         struct netlogon_creds_CredentialState *creds_async[ASYNC_COUNT];
2652         struct rpc_request *req[ASYNC_COUNT];
2653         int i;
2654         int *async_counter = talloc(tctx, int);
2655         union netr_WorkstationInfo query;
2656         union netr_DomainInfo info;
2657
2658         torture_comment(tctx, "Testing netr_LogonGetDomainInfo - async count %d\n", ASYNC_COUNT);
2659
2660         if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS, 
2661                                     machine_credentials, &creds)) {
2662                 return false;
2663         }
2664
2665         ZERO_STRUCT(r);
2666         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2667         r.in.computer_name = TEST_MACHINE_NAME;
2668         r.in.credential = &a;
2669         r.in.level = 1;
2670         r.in.return_authenticator = &a;
2671         r.in.query = &query;
2672         r.out.return_authenticator = &a;
2673         r.out.info = &info;
2674
2675         ZERO_STRUCT(q1);
2676         q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
2677                 TEST_MACHINE_DNS_SUFFIX);
2678         q1.sitename = "Default-First-Site-Name";
2679         q1.os_name.string = "UNIX/Linux or similar";
2680
2681         query.workstation_info = &q1;
2682
2683         *async_counter = 0;
2684
2685         for (i=0;i<ASYNC_COUNT;i++) {
2686                 netlogon_creds_client_authenticator(creds, &a);
2687
2688                 creds_async[i] = (struct netlogon_creds_CredentialState *)talloc_memdup(creds, creds, sizeof(*creds));
2689                 req[i] = dcerpc_netr_LogonGetDomainInfo_send(p, tctx, &r);
2690
2691                 req[i]->async.callback = async_callback;
2692                 req[i]->async.private_data = async_counter;
2693
2694                 /* even with this flush per request a w2k3 server seems to 
2695                    clag with multiple outstanding requests. bleergh. */
2696                 torture_assert_int_equal(tctx, event_loop_once(dcerpc_event_context(p)), 0, 
2697                                          "event_loop_once failed");
2698         }
2699
2700         for (i=0;i<ASYNC_COUNT;i++) {
2701                 status = dcerpc_ndr_request_recv(req[i]);
2702
2703                 torture_assert_ntstatus_ok(tctx, status, "netr_LogonGetDomainInfo_async");
2704                 torture_assert_ntstatus_ok(tctx, r.out.result, "netr_LogonGetDomainInfo_async"); 
2705
2706                 torture_assert(tctx, netlogon_creds_client_check(creds_async[i], &a.cred), 
2707                         "Credential chaining failed at async");
2708         }
2709
2710         torture_comment(tctx, 
2711                         "Testing netr_LogonGetDomainInfo - async count %d OK\n", *async_counter);
2712
2713         torture_assert_int_equal(tctx, (*async_counter), ASYNC_COUNT, "int");
2714
2715         return true;
2716 }
2717
2718 static bool test_ManyGetDCName(struct torture_context *tctx, 
2719                                struct dcerpc_pipe *p)
2720 {
2721         NTSTATUS status;
2722         struct dcerpc_pipe *p2;
2723         struct lsa_ObjectAttribute attr;
2724         struct lsa_QosInfo qos;
2725         struct lsa_OpenPolicy2 o;
2726         struct policy_handle lsa_handle;
2727         struct lsa_DomainList domains;
2728
2729         struct lsa_EnumTrustDom t;
2730         uint32_t resume_handle = 0;
2731         struct netr_GetAnyDCName d;
2732         const char *dcname = NULL;
2733
2734         int i;
2735
2736         if (p->conn->transport.transport != NCACN_NP) {
2737                 return true;
2738         }
2739
2740         torture_comment(tctx, "Torturing GetDCName\n");
2741
2742         status = dcerpc_secondary_connection(p, &p2, p->binding);
2743         torture_assert_ntstatus_ok(tctx, status, "Failed to create secondary connection");
2744
2745         status = dcerpc_bind_auth_none(p2, &ndr_table_lsarpc);
2746         torture_assert_ntstatus_ok(tctx, status, "Failed to create bind on secondary connection");
2747
2748         qos.len = 0;
2749         qos.impersonation_level = 2;
2750         qos.context_mode = 1;
2751         qos.effective_only = 0;
2752
2753         attr.len = 0;
2754         attr.root_dir = NULL;
2755         attr.object_name = NULL;
2756         attr.attributes = 0;
2757         attr.sec_desc = NULL;
2758         attr.sec_qos = &qos;
2759
2760         o.in.system_name = "\\";
2761         o.in.attr = &attr;
2762         o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2763         o.out.handle = &lsa_handle;
2764
2765         status = dcerpc_lsa_OpenPolicy2(p2, tctx, &o);
2766         torture_assert_ntstatus_ok(tctx, status, "OpenPolicy2 failed");
2767
2768         t.in.handle = &lsa_handle;
2769         t.in.resume_handle = &resume_handle;
2770         t.in.max_size = 1000;
2771         t.out.domains = &domains;
2772         t.out.resume_handle = &resume_handle;
2773
2774         status = dcerpc_lsa_EnumTrustDom(p2, tctx, &t);
2775
2776         if ((!NT_STATUS_IS_OK(status) &&
2777              (!NT_STATUS_EQUAL(status, NT_STATUS_NO_MORE_ENTRIES))))
2778                 torture_fail(tctx, "Could not list domains");
2779
2780         talloc_free(p2);
2781
2782         d.in.logon_server = talloc_asprintf(tctx, "\\\\%s",
2783                                             dcerpc_server_name(p));
2784         d.out.dcname = &dcname;
2785
2786         for (i=0; i<domains.count * 4; i++) {
2787                 struct lsa_DomainInfo *info =
2788                         &domains.domains[rand()%domains.count];
2789
2790                 d.in.domainname = info->name.string;
2791
2792                 status = dcerpc_netr_GetAnyDCName(p, tctx, &d);
2793                 torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
2794
2795                 torture_comment(tctx, "\tDC for domain %s is %s\n", info->name.string,
2796                        dcname ? dcname : "unknown");
2797         }
2798
2799         return true;
2800 }
2801
2802 static bool test_SetPassword_with_flags(struct torture_context *tctx,
2803                                         struct dcerpc_pipe *p,
2804                                         struct cli_credentials *machine_credentials)
2805 {
2806         uint32_t flags[] = { 0, NETLOGON_NEG_STRONG_KEYS };
2807         struct netlogon_creds_CredentialState *creds;
2808         int i;
2809
2810         if (!test_SetupCredentials2(p, tctx, 0,
2811                                     machine_credentials,
2812                                     cli_credentials_get_secure_channel_type(machine_credentials),
2813                                     &creds)) {
2814                 torture_skip(tctx, "DC does not support negotiation of 64bit session keys");
2815         }
2816
2817         for (i=0; i < ARRAY_SIZE(flags); i++) {
2818                 torture_assert(tctx,
2819                         test_SetPassword_flags(tctx, p, machine_credentials, flags[i]),
2820                         talloc_asprintf(tctx, "failed to test SetPassword negotiating with 0x%08x flags", flags[i]));
2821         }
2822
2823         return true;
2824 }
2825
2826 struct torture_suite *torture_rpc_netlogon(TALLOC_CTX *mem_ctx)
2827 {
2828         struct torture_suite *suite = torture_suite_create(mem_ctx, "NETLOGON");
2829         struct torture_rpc_tcase *tcase;
2830         struct torture_test *test;
2831
2832         tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netlogon",
2833                                                   &ndr_table_netlogon, TEST_MACHINE_NAME);
2834
2835         torture_rpc_tcase_add_test(tcase, "LogonUasLogon", test_LogonUasLogon);
2836         torture_rpc_tcase_add_test(tcase, "LogonUasLogoff", test_LogonUasLogoff);
2837         torture_rpc_tcase_add_test_creds(tcase, "SamLogon", test_SamLogon);
2838         torture_rpc_tcase_add_test_creds(tcase, "SetPassword", test_SetPassword);
2839         torture_rpc_tcase_add_test_creds(tcase, "SetPassword2", test_SetPassword2);
2840         torture_rpc_tcase_add_test_creds(tcase, "GetPassword", test_GetPassword);
2841         torture_rpc_tcase_add_test_creds(tcase, "GetTrustPasswords", test_GetTrustPasswords);
2842         torture_rpc_tcase_add_test_creds(tcase, "GetDomainInfo", test_GetDomainInfo);
2843         torture_rpc_tcase_add_test_creds(tcase, "DatabaseSync", test_DatabaseSync);
2844         torture_rpc_tcase_add_test_creds(tcase, "DatabaseDeltas", test_DatabaseDeltas);
2845         torture_rpc_tcase_add_test_creds(tcase, "DatabaseRedo", test_DatabaseRedo);
2846         torture_rpc_tcase_add_test_creds(tcase, "AccountDeltas", test_AccountDeltas);
2847         torture_rpc_tcase_add_test_creds(tcase, "AccountSync", test_AccountSync);
2848         torture_rpc_tcase_add_test(tcase, "GetDcName", test_GetDcName);
2849         torture_rpc_tcase_add_test(tcase, "ManyGetDCName", test_ManyGetDCName);
2850         torture_rpc_tcase_add_test(tcase, "GetAnyDCName", test_GetAnyDCName);
2851         torture_rpc_tcase_add_test_creds(tcase, "DatabaseSync2", test_DatabaseSync2);
2852         torture_rpc_tcase_add_test(tcase, "DsrEnumerateDomainTrusts", test_DsrEnumerateDomainTrusts);
2853         torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomains", test_netr_NetrEnumerateTrustedDomains);
2854         torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomainsEx", test_netr_NetrEnumerateTrustedDomainsEx);
2855         test = torture_rpc_tcase_add_test_creds(tcase, "GetDomainInfo_async", test_GetDomainInfo_async);
2856         test->dangerous = true;
2857         torture_rpc_tcase_add_test(tcase, "DsRGetDCName", test_netr_DsRGetDCName);
2858         torture_rpc_tcase_add_test(tcase, "DsRGetDCNameEx", test_netr_DsRGetDCNameEx);
2859         torture_rpc_tcase_add_test(tcase, "DsRGetDCNameEx2", test_netr_DsRGetDCNameEx2);
2860         torture_rpc_tcase_add_test(tcase, "DsrGetDcSiteCoverageW", test_netr_DsrGetDcSiteCoverageW);
2861         torture_rpc_tcase_add_test(tcase, "DsRAddressToSitenamesW", test_netr_DsRAddressToSitenamesW);
2862         torture_rpc_tcase_add_test(tcase, "DsRAddressToSitenamesExW", test_netr_DsRAddressToSitenamesExW);
2863         torture_rpc_tcase_add_test_creds(tcase, "ServerGetTrustInfo", test_netr_ServerGetTrustInfo);
2864
2865         return suite;
2866 }
2867
2868 struct torture_suite *torture_rpc_netlogon_s3(TALLOC_CTX *mem_ctx)
2869 {
2870         struct torture_suite *suite = torture_suite_create(mem_ctx, "NETLOGON-S3");
2871         struct torture_rpc_tcase *tcase;
2872
2873         tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netlogon",
2874                                                   &ndr_table_netlogon, TEST_MACHINE_NAME);
2875
2876         torture_rpc_tcase_add_test_creds(tcase, "SamLogon", test_SamLogon);
2877         torture_rpc_tcase_add_test_creds(tcase, "SetPassword", test_SetPassword);
2878         torture_rpc_tcase_add_test_creds(tcase, "SetPassword_with_flags", test_SetPassword_with_flags);
2879         torture_rpc_tcase_add_test_creds(tcase, "SetPassword2", test_SetPassword2);
2880         torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomains", test_netr_NetrEnumerateTrustedDomains);
2881
2882         return suite;
2883 }
2884
2885 struct torture_suite *torture_rpc_netlogon_admin(TALLOC_CTX *mem_ctx)
2886 {
2887         struct torture_suite *suite = torture_suite_create(mem_ctx, "NETLOGON-ADMIN");
2888         struct torture_rpc_tcase *tcase;
2889
2890         tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netlogon",
2891                                                   &ndr_table_netlogon, TEST_MACHINE_NAME);
2892         torture_rpc_tcase_add_test_creds(tcase, "LogonControl", test_LogonControl);
2893         torture_rpc_tcase_add_test_creds(tcase, "LogonControl2", test_LogonControl2);
2894         torture_rpc_tcase_add_test_creds(tcase, "LogonControl2Ex", test_LogonControl2Ex);
2895
2896         tcase = torture_suite_add_machine_workstation_rpc_iface_tcase(suite, "netlogon",
2897                                                   &ndr_table_netlogon, TEST_MACHINE_NAME);
2898         torture_rpc_tcase_add_test_creds(tcase, "LogonControl", test_LogonControl);
2899         torture_rpc_tcase_add_test_creds(tcase, "LogonControl2", test_LogonControl2);
2900         torture_rpc_tcase_add_test_creds(tcase, "LogonControl2Ex", test_LogonControl2Ex);
2901
2902         tcase = torture_suite_add_rpc_iface_tcase(suite, "netlogon",
2903                                                   &ndr_table_netlogon);
2904         torture_rpc_tcase_add_test_creds(tcase, "LogonControl", test_LogonControl);
2905         torture_rpc_tcase_add_test_creds(tcase, "LogonControl2", test_LogonControl2);
2906         torture_rpc_tcase_add_test_creds(tcase, "LogonControl2Ex", test_LogonControl2Ex);
2907
2908         return suite;
2909 }