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