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