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