ab9ef02d39f00d639ab85576ef149dd56a9f2df5
[ira/wip.git] / source4 / torture / rpc / netlogon.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    test suite for netlogon rpc operations
5
6    Copyright (C) Andrew Tridgell 2003
7    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003-2004
8    Copyright (C) Tim Potter      2003
9    Copyright (C) Matthias Dieter Wallnöfer            2009-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         r.in.domain_name        = lpcfg_workgroup(tctx->lp_ctx);
2485
2486         status = dcerpc_netr_DsRGetDCName_r(b, tctx, &r);
2487         torture_assert_ntstatus_ok(tctx, status, "DsRGetDCName");
2488         torture_assert_werr_ok(tctx, r.out.result, "DsRGetDCName");
2489
2490         return test_netr_DsRGetSiteName(p, tctx, 
2491                                        info->dc_unc,
2492                                        info->dc_site_name);
2493 }
2494
2495 /*
2496   try a netlogon netr_DsRGetDCNameEx
2497 */
2498 static bool test_netr_DsRGetDCNameEx(struct torture_context *tctx, 
2499                                      struct dcerpc_pipe *p)
2500 {
2501         NTSTATUS status;
2502         struct netr_DsRGetDCNameEx r;
2503         struct netr_DsRGetDCNameInfo *info = NULL;
2504         struct dcerpc_binding_handle *b = p->binding_handle;
2505
2506         r.in.server_unc         = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2507         r.in.domain_name        = lpcfg_dnsdomain(tctx->lp_ctx);
2508         r.in.domain_guid        = NULL;
2509         r.in.site_name          = NULL;
2510         r.in.flags              = DS_RETURN_DNS_NAME;
2511         r.out.info              = &info;
2512
2513         status = dcerpc_netr_DsRGetDCNameEx_r(b, tctx, &r);
2514         torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx");
2515         torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx");
2516
2517         r.in.domain_name        = lpcfg_workgroup(tctx->lp_ctx);
2518
2519         status = dcerpc_netr_DsRGetDCNameEx_r(b, tctx, &r);
2520         torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx");
2521         torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx");
2522
2523         return test_netr_DsRGetSiteName(p, tctx, info->dc_unc,
2524                                         info->dc_site_name);
2525 }
2526
2527 /*
2528   try a netlogon netr_DsRGetDCNameEx2
2529 */
2530 static bool test_netr_DsRGetDCNameEx2(struct torture_context *tctx, 
2531                                       struct dcerpc_pipe *p)
2532 {
2533         NTSTATUS status;
2534         struct netr_DsRGetDCNameEx2 r;
2535         struct netr_DsRGetDCNameInfo *info = NULL;
2536         struct dcerpc_binding_handle *b = p->binding_handle;
2537
2538         torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 with no inputs\n");
2539         ZERO_STRUCT(r.in);
2540         r.in.flags              = DS_RETURN_DNS_NAME;
2541         r.out.info              = &info;
2542
2543         status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
2544         torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
2545         torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
2546
2547         r.in.server_unc         = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2548         r.in.client_account     = NULL;
2549         r.in.mask               = 0x00000000;
2550         r.in.domain_name        = lpcfg_dnsdomain(tctx->lp_ctx);
2551         r.in.domain_guid        = NULL;
2552         r.in.site_name          = NULL;
2553         r.in.flags              = DS_RETURN_DNS_NAME;
2554         r.out.info              = &info;
2555
2556         torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 without client account\n");
2557
2558         status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
2559         torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
2560         torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
2561
2562         r.in.domain_name        = lpcfg_workgroup(tctx->lp_ctx);
2563
2564         status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
2565         torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
2566         torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
2567
2568         torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 with client account\n");
2569         r.in.client_account     = TEST_MACHINE_NAME"$";
2570         r.in.mask               = ACB_SVRTRUST;
2571         r.in.flags              = DS_RETURN_FLAT_NAME;
2572         r.out.info              = &info;
2573
2574         status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
2575         torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
2576         torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
2577
2578         return test_netr_DsRGetSiteName(p, tctx, info->dc_unc,
2579                                         info->dc_site_name);
2580 }
2581
2582 /* This is a substitution for "samdb_server_site_name" which relies on the
2583  * correct "lp_ctx" and therefore can't be used here. */
2584 static const char *server_site_name(struct torture_context *tctx,
2585                                     struct ldb_context *ldb)
2586 {
2587         TALLOC_CTX *tmp_ctx;
2588         struct ldb_dn *dn, *server_dn;
2589         const struct ldb_val *site_name_val;
2590         const char *server_dn_str, *site_name;
2591
2592         tmp_ctx = talloc_new(ldb);
2593         if (tmp_ctx == NULL) {
2594                 goto failed;
2595         }
2596
2597         dn = ldb_dn_new(tmp_ctx, ldb, "");
2598         if (dn == NULL) {
2599                 goto failed;
2600         }
2601
2602         server_dn_str = samdb_search_string(ldb, tmp_ctx, dn, "serverName",
2603                                             NULL);
2604         if (server_dn_str == NULL) {
2605                 goto failed;
2606         }
2607
2608         server_dn = ldb_dn_new(tmp_ctx, ldb, server_dn_str);
2609         if (server_dn == NULL) {
2610                 goto failed;
2611         }
2612
2613         /* CN=<Server name>, CN=Servers, CN=<Site name>, CN=Sites, ... */
2614         site_name_val = ldb_dn_get_component_val(server_dn, 2);
2615         if (site_name_val == NULL) {
2616                 goto failed;
2617         }
2618
2619         site_name = (const char *) site_name_val->data;
2620
2621         talloc_steal(tctx, site_name);
2622         talloc_free(tmp_ctx);
2623
2624         return site_name;
2625
2626 failed:
2627         talloc_free(tmp_ctx);
2628         return NULL;
2629 }
2630
2631 static bool test_netr_DsrGetDcSiteCoverageW(struct torture_context *tctx, 
2632                                             struct dcerpc_pipe *p)
2633 {
2634         char *url;
2635         struct ldb_context *sam_ctx = NULL;
2636         NTSTATUS status;
2637         struct netr_DsrGetDcSiteCoverageW r;
2638         struct DcSitesCtr *ctr = NULL;
2639         struct dcerpc_binding_handle *b = p->binding_handle;
2640
2641         torture_comment(tctx, "This does only pass with the default site\n");
2642
2643         /* We won't double-check this when we are over 'local' transports */
2644         if (dcerpc_server_name(p)) {
2645                 /* Set up connection to SAMDB on DC */
2646                 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
2647                 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
2648                                            NULL,
2649                                            cmdline_credentials,
2650                                            0);
2651
2652                 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
2653         }
2654
2655         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2656         r.out.ctr = &ctr;
2657
2658         status = dcerpc_netr_DsrGetDcSiteCoverageW_r(b, tctx, &r);
2659         torture_assert_ntstatus_ok(tctx, status, "failed");
2660         torture_assert_werr_ok(tctx, r.out.result, "failed");
2661
2662         torture_assert(tctx, ctr->num_sites == 1,
2663                        "we should per default only get the default site");
2664         if (sam_ctx != NULL) {
2665                 torture_assert_casestr_equal(tctx, ctr->sites[0].string,
2666                                              server_site_name(tctx, sam_ctx),
2667                                              "didn't return default site");
2668         }
2669
2670         return true;
2671 }
2672
2673 static bool test_netr_DsRAddressToSitenamesW(struct torture_context *tctx,
2674                                              struct dcerpc_pipe *p)
2675 {
2676         char *url;
2677         struct ldb_context *sam_ctx = NULL;
2678         NTSTATUS status;
2679         struct netr_DsRAddressToSitenamesW r;
2680         struct netr_DsRAddress addrs[6];
2681         struct sockaddr_in *addr;
2682 #ifdef HAVE_IPV6
2683         struct sockaddr_in6 *addr6;
2684 #endif
2685         struct netr_DsRAddressToSitenamesWCtr *ctr;
2686         struct dcerpc_binding_handle *b = p->binding_handle;
2687         uint32_t i;
2688         int ret;
2689
2690         torture_comment(tctx, "This does only pass with the default site\n");
2691
2692         /* We won't double-check this when we are over 'local' transports */
2693         if (dcerpc_server_name(p)) {
2694                 /* Set up connection to SAMDB on DC */
2695                 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
2696                 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
2697                                            NULL,
2698                                            cmdline_credentials,
2699                                            0);
2700
2701                 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
2702         }
2703
2704         /* First try valid IP addresses */
2705
2706         addrs[0].size = sizeof(struct sockaddr_in);
2707         addrs[0].buffer = talloc_zero_array(tctx, uint8_t, addrs[0].size);
2708         addr = (struct sockaddr_in *) addrs[0].buffer;
2709         addrs[0].buffer[0] = AF_INET;
2710         ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
2711         torture_assert(tctx, ret > 0, "inet_pton failed");
2712
2713         addrs[1].size = sizeof(struct sockaddr_in);
2714         addrs[1].buffer = talloc_zero_array(tctx, uint8_t, addrs[1].size);
2715         addr = (struct sockaddr_in *) addrs[1].buffer;
2716         addrs[1].buffer[0] = AF_INET;
2717         ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
2718         torture_assert(tctx, ret > 0, "inet_pton failed");
2719
2720         addrs[2].size = sizeof(struct sockaddr_in);
2721         addrs[2].buffer = talloc_zero_array(tctx, uint8_t, addrs[2].size);
2722         addr = (struct sockaddr_in *) addrs[2].buffer;
2723         addrs[2].buffer[0] = AF_INET;
2724         ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
2725         torture_assert(tctx, ret > 0, "inet_pton failed");
2726
2727 #ifdef HAVE_IPV6
2728         addrs[3].size = sizeof(struct sockaddr_in6);
2729         addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
2730         addr6 = (struct sockaddr_in6 *) addrs[3].buffer;
2731         addrs[3].buffer[0] = AF_INET6;
2732         ret = inet_pton(AF_INET6, "::1", &addr6->sin6_addr);
2733         torture_assert(tctx, ret > 0, "inet_pton failed");
2734
2735         addrs[4].size = sizeof(struct sockaddr_in6);
2736         addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
2737         addr6 = (struct sockaddr_in6 *) addrs[4].buffer;
2738         addrs[4].buffer[0] = AF_INET6;
2739         ret = inet_pton(AF_INET6, "::", &addr6->sin6_addr);
2740         torture_assert(tctx, ret > 0, "inet_pton failed");
2741
2742         addrs[5].size = sizeof(struct sockaddr_in6);
2743         addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
2744         addr6 = (struct sockaddr_in6 *) addrs[5].buffer;
2745         addrs[5].buffer[0] = AF_INET6;
2746         ret = inet_pton(AF_INET6, "ff02::1", &addr6->sin6_addr);
2747         torture_assert(tctx, ret > 0, "inet_pton failed");
2748 #else
2749         /* the test cases are repeated to have exactly 6. This is for
2750          * compatibility with IPv4-only machines */
2751         addrs[3].size = sizeof(struct sockaddr_in);
2752         addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
2753         addr = (struct sockaddr_in *) addrs[3].buffer;
2754         addrs[3].buffer[0] = AF_INET;
2755         ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
2756         torture_assert(tctx, ret > 0, "inet_pton failed");
2757
2758         addrs[4].size = sizeof(struct sockaddr_in);
2759         addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
2760         addr = (struct sockaddr_in *) addrs[4].buffer;
2761         addrs[4].buffer[0] = AF_INET;
2762         ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
2763         torture_assert(tctx, ret > 0, "inet_pton failed");
2764
2765         addrs[5].size = sizeof(struct sockaddr_in);
2766         addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
2767         addr = (struct sockaddr_in *) addrs[5].buffer;
2768         addrs[5].buffer[0] = AF_INET;
2769         ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
2770         torture_assert(tctx, ret > 0, "inet_pton failed");
2771 #endif
2772
2773         ctr = talloc(tctx, struct netr_DsRAddressToSitenamesWCtr);
2774
2775         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2776         r.in.count = 6;
2777         r.in.addresses = addrs;
2778         r.out.ctr = &ctr;
2779
2780         status = dcerpc_netr_DsRAddressToSitenamesW_r(b, tctx, &r);
2781         torture_assert_ntstatus_ok(tctx, status, "failed");
2782         torture_assert_werr_ok(tctx, r.out.result, "failed");
2783
2784         if (sam_ctx != NULL) {
2785                 for (i = 0; i < 3; i++) {
2786                         torture_assert_casestr_equal(tctx,
2787                                                      ctr->sitename[i].string,
2788                                                      server_site_name(tctx, sam_ctx),
2789                                                      "didn't return default site");
2790                 }
2791                 for (i = 3; i < 6; i++) {
2792                         /* Windows returns "NULL" for the sitename if it isn't
2793                          * IPv6 configured */
2794                         if (torture_setting_bool(tctx, "samba4", false)) {
2795                                 torture_assert_casestr_equal(tctx,
2796                                                              ctr->sitename[i].string,
2797                                                              server_site_name(tctx, sam_ctx),
2798                                                              "didn't return default site");
2799                         }
2800                 }
2801         }
2802
2803         /* Now try invalid ones (too short buffers) */
2804
2805         addrs[0].size = 0;
2806         addrs[1].size = 1;
2807         addrs[2].size = 4;
2808
2809         addrs[3].size = 0;
2810         addrs[4].size = 1;
2811         addrs[5].size = 4;
2812
2813         status = dcerpc_netr_DsRAddressToSitenamesW_r(b, tctx, &r);
2814         torture_assert_ntstatus_ok(tctx, status, "failed");
2815         torture_assert_werr_ok(tctx, r.out.result, "failed");
2816
2817         for (i = 0; i < 6; i++) {
2818                 torture_assert(tctx, ctr->sitename[i].string == NULL,
2819                                "sitename should be null");
2820         }
2821
2822         /* Now try invalid ones (wrong address types) */
2823
2824         addrs[0].size = 10;
2825         addrs[0].buffer[0] = AF_UNSPEC;
2826         addrs[1].size = 10;
2827         addrs[1].buffer[0] = AF_UNIX; /* AF_LOCAL = AF_UNIX */
2828         addrs[2].size = 10;
2829         addrs[2].buffer[0] = AF_UNIX;
2830
2831         addrs[3].size = 10;
2832         addrs[3].buffer[0] = 250;
2833         addrs[4].size = 10;
2834         addrs[4].buffer[0] = 251;
2835         addrs[5].size = 10;
2836         addrs[5].buffer[0] = 252;
2837
2838         status = dcerpc_netr_DsRAddressToSitenamesW_r(b, tctx, &r);
2839         torture_assert_ntstatus_ok(tctx, status, "failed");
2840         torture_assert_werr_ok(tctx, r.out.result, "failed");
2841
2842         for (i = 0; i < 6; i++) {
2843                 torture_assert(tctx, ctr->sitename[i].string == NULL,
2844                                "sitename should be null");
2845         }
2846
2847         return true;
2848 }
2849
2850 static bool test_netr_DsRAddressToSitenamesExW(struct torture_context *tctx,
2851                                                struct dcerpc_pipe *p)
2852 {
2853         char *url;
2854         struct ldb_context *sam_ctx = NULL;
2855         NTSTATUS status;
2856         struct netr_DsRAddressToSitenamesExW r;
2857         struct netr_DsRAddress addrs[6];
2858         struct sockaddr_in *addr;
2859 #ifdef HAVE_IPV6
2860         struct sockaddr_in6 *addr6;
2861 #endif
2862         struct netr_DsRAddressToSitenamesExWCtr *ctr;
2863         struct dcerpc_binding_handle *b = p->binding_handle;
2864         uint32_t i;
2865         int ret;
2866
2867         torture_comment(tctx, "This does pass with the default site\n");
2868
2869         /* We won't double-check this when we are over 'local' transports */
2870         if (dcerpc_server_name(p)) {
2871                 /* Set up connection to SAMDB on DC */
2872                 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
2873                 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
2874                                            NULL,
2875                                            cmdline_credentials,
2876                                            0);
2877
2878                 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
2879         }
2880
2881         /* First try valid IP addresses */
2882
2883         addrs[0].size = sizeof(struct sockaddr_in);
2884         addrs[0].buffer = talloc_zero_array(tctx, uint8_t, addrs[0].size);
2885         addr = (struct sockaddr_in *) addrs[0].buffer;
2886         addrs[0].buffer[0] = AF_INET;
2887         ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
2888         torture_assert(tctx, ret > 0, "inet_pton failed");
2889
2890         addrs[1].size = sizeof(struct sockaddr_in);
2891         addrs[1].buffer = talloc_zero_array(tctx, uint8_t, addrs[1].size);
2892         addr = (struct sockaddr_in *) addrs[1].buffer;
2893         addrs[1].buffer[0] = AF_INET;
2894         ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
2895         torture_assert(tctx, ret > 0, "inet_pton failed");
2896
2897         addrs[2].size = sizeof(struct sockaddr_in);
2898         addrs[2].buffer = talloc_zero_array(tctx, uint8_t, addrs[2].size);
2899         addr = (struct sockaddr_in *) addrs[2].buffer;
2900         addrs[2].buffer[0] = AF_INET;
2901         ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
2902         torture_assert(tctx, ret > 0, "inet_pton failed");
2903
2904 #ifdef HAVE_IPV6
2905         addrs[3].size = sizeof(struct sockaddr_in6);
2906         addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
2907         addr6 = (struct sockaddr_in6 *) addrs[3].buffer;
2908         addrs[3].buffer[0] = AF_INET6;
2909         ret = inet_pton(AF_INET6, "::1", &addr6->sin6_addr);
2910         torture_assert(tctx, ret > 0, "inet_pton failed");
2911
2912         addrs[4].size = sizeof(struct sockaddr_in6);
2913         addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
2914         addr6 = (struct sockaddr_in6 *) addrs[4].buffer;
2915         addrs[4].buffer[0] = AF_INET6;
2916         ret = inet_pton(AF_INET6, "::", &addr6->sin6_addr);
2917         torture_assert(tctx, ret > 0, "inet_pton failed");
2918
2919         addrs[5].size = sizeof(struct sockaddr_in6);
2920         addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
2921         addr6 = (struct sockaddr_in6 *) addrs[5].buffer;
2922         addrs[5].buffer[0] = AF_INET6;
2923         ret = inet_pton(AF_INET6, "ff02::1", &addr6->sin6_addr);
2924         torture_assert(tctx, ret > 0, "inet_pton failed");
2925 #else
2926         /* the test cases are repeated to have exactly 6. This is for
2927          * compatibility with IPv4-only machines */
2928         addrs[3].size = sizeof(struct sockaddr_in);
2929         addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
2930         addr = (struct sockaddr_in *) addrs[3].buffer;
2931         addrs[3].buffer[0] = AF_INET;
2932         ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
2933         torture_assert(tctx, ret > 0, "inet_pton failed");
2934
2935         addrs[4].size = sizeof(struct sockaddr_in);
2936         addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
2937         addr = (struct sockaddr_in *) addrs[4].buffer;
2938         addrs[4].buffer[0] = AF_INET;
2939         ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
2940         torture_assert(tctx, ret > 0, "inet_pton failed");
2941
2942         addrs[5].size = sizeof(struct sockaddr_in);
2943         addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
2944         addr = (struct sockaddr_in *) addrs[5].buffer;
2945         addrs[5].buffer[0] = AF_INET;
2946         ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
2947         torture_assert(tctx, ret > 0, "inet_pton failed");
2948 #endif
2949
2950         ctr = talloc(tctx, struct netr_DsRAddressToSitenamesExWCtr);
2951
2952         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2953         r.in.count = 6;
2954         r.in.addresses = addrs;
2955         r.out.ctr = &ctr;
2956
2957         status = dcerpc_netr_DsRAddressToSitenamesExW_r(b, tctx, &r);
2958         torture_assert_ntstatus_ok(tctx, status, "failed");
2959         torture_assert_werr_ok(tctx, r.out.result, "failed");
2960
2961         if (sam_ctx != NULL) {
2962                 for (i = 0; i < 3; i++) {
2963                         torture_assert_casestr_equal(tctx,
2964                                                      ctr->sitename[i].string,
2965                                                      server_site_name(tctx, sam_ctx),
2966                                                      "didn't return default site");
2967                         torture_assert(tctx, ctr->subnetname[i].string == NULL,
2968                                        "subnet should be null");
2969                 }
2970                 for (i = 3; i < 6; i++) {
2971                         /* Windows returns "NULL" for the sitename if it isn't
2972                          * IPv6 configured */
2973                         if (torture_setting_bool(tctx, "samba4", false)) {
2974                                 torture_assert_casestr_equal(tctx,
2975                                                              ctr->sitename[i].string,
2976                                                              server_site_name(tctx, sam_ctx),
2977                                                              "didn't return default site");
2978                         }
2979                         torture_assert(tctx, ctr->subnetname[i].string == NULL,
2980                                        "subnet should be null");
2981                 }
2982         }
2983
2984         /* Now try invalid ones (too short buffers) */
2985
2986         addrs[0].size = 0;
2987         addrs[1].size = 1;
2988         addrs[2].size = 4;
2989
2990         addrs[3].size = 0;
2991         addrs[4].size = 1;
2992         addrs[5].size = 4;
2993
2994         status = dcerpc_netr_DsRAddressToSitenamesExW_r(b, tctx, &r);
2995         torture_assert_ntstatus_ok(tctx, status, "failed");
2996         torture_assert_werr_ok(tctx, r.out.result, "failed");
2997
2998         for (i = 0; i < 6; i++) {
2999                 torture_assert(tctx, ctr->sitename[i].string == NULL,
3000                                "sitename should be null");
3001                 torture_assert(tctx, ctr->subnetname[i].string == NULL,
3002                                "subnet should be null");
3003         }
3004
3005         addrs[0].size = 10;
3006         addrs[0].buffer[0] = AF_UNSPEC;
3007         addrs[1].size = 10;
3008         addrs[1].buffer[0] = AF_UNIX; /* AF_LOCAL = AF_UNIX */
3009         addrs[2].size = 10;
3010         addrs[2].buffer[0] = AF_UNIX;
3011
3012         addrs[3].size = 10;
3013         addrs[3].buffer[0] = 250;
3014         addrs[4].size = 10;
3015         addrs[4].buffer[0] = 251;
3016         addrs[5].size = 10;
3017         addrs[5].buffer[0] = 252;
3018
3019         status = dcerpc_netr_DsRAddressToSitenamesExW_r(b, tctx, &r);
3020         torture_assert_ntstatus_ok(tctx, status, "failed");
3021         torture_assert_werr_ok(tctx, r.out.result, "failed");
3022
3023         for (i = 0; i < 6; i++) {
3024                 torture_assert(tctx, ctr->sitename[i].string == NULL,
3025                                "sitename should be null");
3026                 torture_assert(tctx, ctr->subnetname[i].string == NULL,
3027                                "subnet should be null");
3028         }
3029
3030         return true;
3031 }
3032
3033 static bool test_netr_ServerGetTrustInfo(struct torture_context *tctx,
3034                                          struct dcerpc_pipe *p,
3035                                          struct cli_credentials *machine_credentials)
3036 {
3037         struct netr_ServerGetTrustInfo r;
3038
3039         struct netr_Authenticator a;
3040         struct netr_Authenticator return_authenticator;
3041         struct samr_Password new_owf_password;
3042         struct samr_Password old_owf_password;
3043         struct netr_TrustInfo *trust_info;
3044
3045         struct netlogon_creds_CredentialState *creds;
3046         struct dcerpc_binding_handle *b = p->binding_handle;
3047
3048         if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
3049                                     machine_credentials, &creds)) {
3050                 return false;
3051         }
3052
3053         netlogon_creds_client_authenticator(creds, &a);
3054
3055         r.in.server_name                = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3056         r.in.account_name               = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
3057         r.in.secure_channel_type        = cli_credentials_get_secure_channel_type(machine_credentials);
3058         r.in.computer_name              = TEST_MACHINE_NAME;
3059         r.in.credential                 = &a;
3060
3061         r.out.return_authenticator      = &return_authenticator;
3062         r.out.new_owf_password          = &new_owf_password;
3063         r.out.old_owf_password          = &old_owf_password;
3064         r.out.trust_info                = &trust_info;
3065
3066         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerGetTrustInfo_r(b, tctx, &r),
3067                 "ServerGetTrustInfo failed");
3068         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerGetTrustInfo failed");
3069         torture_assert(tctx, netlogon_creds_client_check(creds, &return_authenticator.cred), "Credential chaining failed");
3070
3071         return true;
3072 }
3073
3074
3075 static bool test_GetDomainInfo(struct torture_context *tctx, 
3076                                struct dcerpc_pipe *p,
3077                                struct cli_credentials *machine_credentials)
3078 {
3079         struct netr_LogonGetDomainInfo r;
3080         struct netr_WorkstationInformation q1;
3081         struct netr_Authenticator a;
3082         struct netlogon_creds_CredentialState *creds;
3083         struct netr_OsVersion os;
3084         union netr_WorkstationInfo query;
3085         union netr_DomainInfo info;
3086         const char* const attrs[] = { "dNSHostName", "operatingSystem",
3087                 "operatingSystemServicePack", "operatingSystemVersion",
3088                 "servicePrincipalName", NULL };
3089         char *url;
3090         struct ldb_context *sam_ctx = NULL;
3091         struct ldb_message **res;
3092         struct ldb_message_element *spn_el;
3093         int ret, i;
3094         char *version_str;
3095         const char *old_dnsname = NULL;
3096         char **spns = NULL;
3097         int num_spns = 0;
3098         char *temp_str;
3099         struct dcerpc_binding_handle *b = p->binding_handle;
3100
3101         torture_comment(tctx, "Testing netr_LogonGetDomainInfo\n");
3102
3103         if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS, 
3104                                     machine_credentials, &creds)) {
3105                 return false;
3106         }
3107
3108         /* We won't double-check this when we are over 'local' transports */
3109         if (dcerpc_server_name(p)) {
3110                 /* Set up connection to SAMDB on DC */
3111                 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
3112                 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
3113                                            NULL,
3114                                            cmdline_credentials,
3115                                            0);
3116                 
3117                 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
3118         }
3119
3120         torture_comment(tctx, "Testing netr_LogonGetDomainInfo 1st call (no variation of DNS hostname)\n");
3121         netlogon_creds_client_authenticator(creds, &a);
3122
3123         ZERO_STRUCT(r);
3124         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3125         r.in.computer_name = TEST_MACHINE_NAME;
3126         r.in.credential = &a;
3127         r.in.level = 1;
3128         r.in.return_authenticator = &a;
3129         r.in.query = &query;
3130         r.out.return_authenticator = &a;
3131         r.out.info = &info;
3132
3133         ZERO_STRUCT(os);
3134         os.os.MajorVersion = 123;
3135         os.os.MinorVersion = 456;
3136         os.os.BuildNumber = 789;
3137         os.os.CSDVersion = "Service Pack 10";
3138         os.os.ServicePackMajor = 10;
3139         os.os.ServicePackMinor = 1;
3140         os.os.SuiteMask = NETR_VER_SUITE_SINGLEUSERTS;
3141         os.os.ProductType = NETR_VER_NT_SERVER;
3142         os.os.Reserved = 0;
3143
3144         version_str = talloc_asprintf(tctx, "%d.%d (%d)", os.os.MajorVersion,
3145                 os.os.MinorVersion, os.os.BuildNumber);
3146
3147         ZERO_STRUCT(q1);
3148         q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
3149                 lpcfg_dnsdomain(tctx->lp_ctx));
3150         q1.sitename = "Default-First-Site-Name";
3151         q1.os_version.os = &os;
3152         q1.os_name.string = talloc_asprintf(tctx,
3153                                             "Tortured by Samba4 RPC-NETLOGON: %s",
3154                                             timestring(tctx, time(NULL)));
3155
3156         /* The workstation handles the "servicePrincipalName" and DNS hostname
3157            updates */
3158         q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
3159
3160         query.workstation_info = &q1;
3161
3162         if (sam_ctx) {
3163                 /* Gets back the old DNS hostname in AD */
3164                 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
3165                                    "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
3166                 old_dnsname =
3167                         ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL);
3168                 
3169                 /* Gets back the "servicePrincipalName"s in AD */
3170                 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
3171                 if (spn_el != NULL) {
3172                         for (i=0; i < spn_el->num_values; i++) {
3173                                 spns = talloc_realloc(tctx, spns, char *, i + 1);
3174                                 spns[i] = (char *) spn_el->values[i].data;
3175                         }
3176                         num_spns = i;
3177                 }
3178         }
3179
3180         torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3181                 "LogonGetDomainInfo failed");
3182         torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3183         torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3184
3185         smb_msleep(250);
3186
3187         if (sam_ctx) {
3188                 /* AD workstation infos entry check */
3189                 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
3190                                    "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
3191                 torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
3192                 torture_assert_str_equal(tctx,
3193                                          ldb_msg_find_attr_as_string(res[0], "operatingSystem", NULL),
3194                                          q1.os_name.string, "'operatingSystem' wrong!");
3195                 torture_assert_str_equal(tctx,
3196                                          ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL),
3197                                          os.os.CSDVersion, "'operatingSystemServicePack' wrong!");
3198                 torture_assert_str_equal(tctx,
3199                                          ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL),
3200                                          version_str, "'operatingSystemVersion' wrong!");
3201
3202                 if (old_dnsname != NULL) {
3203                         /* If before a DNS hostname was set then it should remain
3204                            the same in combination with the "servicePrincipalName"s.
3205                            The DNS hostname should also be returned by our
3206                            "LogonGetDomainInfo" call (in the domain info structure). */
3207                         
3208                         torture_assert_str_equal(tctx,
3209                                                  ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL),
3210                                                  old_dnsname, "'DNS hostname' was not set!");
3211                         
3212                         spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
3213                         torture_assert(tctx, ((spns != NULL) && (spn_el != NULL)),
3214                                        "'servicePrincipalName's not set!");
3215                         torture_assert(tctx, spn_el->num_values == num_spns,
3216                                        "'servicePrincipalName's incorrect!");
3217                         for (i=0; (i < spn_el->num_values) && (i < num_spns); i++)
3218                                 torture_assert_str_equal(tctx,
3219                                                          (char *) spn_el->values[i].data,
3220                                 spns[i], "'servicePrincipalName's incorrect!");
3221
3222                         torture_assert_str_equal(tctx,
3223                                                  info.domain_info->dns_hostname.string,
3224                                                  old_dnsname,
3225                                                  "Out 'DNS hostname' doesn't match the old one!");
3226                 } else {
3227                         /* If no DNS hostname was set then also now none should be set,
3228                            the "servicePrincipalName"s should remain empty and no DNS
3229                            hostname should be returned by our "LogonGetDomainInfo"
3230                            call (in the domain info structure). */
3231                         
3232                         torture_assert(tctx,
3233                                        ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL) == NULL,
3234                                        "'DNS hostname' was set!");
3235                         
3236                         spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
3237                         torture_assert(tctx, ((spns == NULL) && (spn_el == NULL)),
3238                                        "'servicePrincipalName's were set!");
3239                         
3240                         torture_assert(tctx,
3241                                        info.domain_info->dns_hostname.string == NULL,
3242                                        "Out 'DNS host name' was set!");
3243                 }
3244         }
3245
3246         /* Checks "workstation flags" */
3247         torture_assert(tctx,
3248                 info.domain_info->workstation_flags
3249                 == NETR_WS_FLAG_HANDLES_SPN_UPDATE,
3250                 "Out 'workstation flags' don't match!");
3251
3252
3253         torture_comment(tctx, "Testing netr_LogonGetDomainInfo 2nd call (variation of DNS hostname doesn't work)\n");
3254         netlogon_creds_client_authenticator(creds, &a);
3255
3256         /* Wipe out the osVersion, and prove which values still 'stick' */
3257         q1.os_version.os = NULL;
3258
3259         /* Change also the DNS hostname to test differences in behaviour */
3260         talloc_free(discard_const_p(char, q1.dns_hostname));
3261         q1.dns_hostname = talloc_asprintf(tctx, "%s2.%s", TEST_MACHINE_NAME,
3262                 lpcfg_dnsdomain(tctx->lp_ctx));
3263
3264         /* The workstation handles the "servicePrincipalName" and DNS hostname
3265            updates */
3266         q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
3267
3268         torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3269                 "LogonGetDomainInfo failed");
3270         torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3271
3272         torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3273
3274         smb_msleep(250);
3275
3276         if (sam_ctx) {
3277                 /* AD workstation infos entry check */
3278                 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
3279                                    "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
3280                 torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
3281
3282                 torture_assert_str_equal(tctx,
3283                                          ldb_msg_find_attr_as_string(res[0], "operatingSystem", NULL),
3284                                          q1.os_name.string, "'operatingSystem' should stick!");
3285                 torture_assert(tctx,
3286                                ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL) == NULL,
3287                                "'operatingSystemServicePack' shouldn't stick!");
3288                 torture_assert(tctx,
3289                                ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL) == NULL,
3290                                "'operatingSystemVersion' shouldn't stick!");
3291
3292                 /* The DNS host name shouldn't have been updated by the server */
3293
3294                 torture_assert_str_equal(tctx,
3295                                          ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL),
3296                                          old_dnsname, "'DNS host name' did change!");
3297                 
3298                 /* Find the two "servicePrincipalName"s which the DC shouldn't have been
3299                    updated (HOST/<Netbios name> and HOST/<FQDN name>) - see MS-NRPC
3300                    3.5.4.3.9 */
3301                 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
3302                 torture_assert(tctx, spn_el != NULL,
3303                                "There should exist 'servicePrincipalName's in AD!");
3304                 temp_str = talloc_asprintf(tctx, "HOST/%s", TEST_MACHINE_NAME);
3305                 for (i=0; i < spn_el->num_values; i++)
3306                         if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
3307                                 break;
3308                 torture_assert(tctx, i != spn_el->num_values,
3309                                "'servicePrincipalName' HOST/<Netbios name> not found!");
3310                 temp_str = talloc_asprintf(tctx, "HOST/%s", old_dnsname);
3311                 for (i=0; i < spn_el->num_values; i++)
3312                         if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
3313                                 break;
3314                 torture_assert(tctx, i != spn_el->num_values,
3315                                "'servicePrincipalName' HOST/<FQDN name> not found!");
3316                 
3317                 /* Check that the out DNS hostname was set properly */
3318                 torture_assert_str_equal(tctx, info.domain_info->dns_hostname.string,
3319                                          old_dnsname, "Out 'DNS hostname' doesn't match the old one!");
3320         }
3321
3322         /* Checks "workstation flags" */
3323         torture_assert(tctx,
3324                 info.domain_info->workstation_flags == NETR_WS_FLAG_HANDLES_SPN_UPDATE,
3325                 "Out 'workstation flags' don't match!");
3326
3327
3328         /* Now try the same but the workstation flags set to 0 */
3329
3330         torture_comment(tctx, "Testing netr_LogonGetDomainInfo 3rd call (variation of DNS hostname doesn't work)\n");
3331         netlogon_creds_client_authenticator(creds, &a);
3332
3333         /* Change also the DNS hostname to test differences in behaviour */
3334         talloc_free(discard_const_p(char, q1.dns_hostname));
3335         q1.dns_hostname = talloc_asprintf(tctx, "%s2.%s", TEST_MACHINE_NAME,
3336                 lpcfg_dnsdomain(tctx->lp_ctx));
3337
3338         /* Wipe out the osVersion, and prove which values still 'stick' */
3339         q1.os_version.os = NULL;
3340
3341         /* Let the DC handle the "servicePrincipalName" and DNS hostname
3342            updates */
3343         q1.workstation_flags = 0;
3344
3345         torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3346                 "LogonGetDomainInfo failed");
3347         torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3348         torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3349
3350         smb_msleep(250);
3351
3352         if (sam_ctx) {
3353                 /* AD workstation infos entry check */
3354                 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
3355                                    "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
3356                 torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
3357
3358                 torture_assert_str_equal(tctx,
3359                                          ldb_msg_find_attr_as_string(res[0], "operatingSystem", NULL),
3360                                          q1.os_name.string, "'operatingSystem' should stick!");
3361                 torture_assert(tctx,
3362                                ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL) == NULL,
3363                                "'operatingSystemServicePack' shouldn't stick!");
3364                 torture_assert(tctx,
3365                                ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL) == NULL,
3366                                "'operatingSystemVersion' shouldn't stick!");
3367
3368                 /* The DNS host name shouldn't have been updated by the server */
3369
3370                 torture_assert_str_equal(tctx,
3371                                          ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL),
3372                                          old_dnsname, "'DNS host name' did change!");
3373
3374                 /* Find the two "servicePrincipalName"s which the DC shouldn't have been
3375                    updated (HOST/<Netbios name> and HOST/<FQDN name>) - see MS-NRPC
3376                    3.5.4.3.9 */
3377                 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
3378                 torture_assert(tctx, spn_el != NULL,
3379                                "There should exist 'servicePrincipalName's in AD!");
3380                 temp_str = talloc_asprintf(tctx, "HOST/%s", TEST_MACHINE_NAME);
3381                 for (i=0; i < spn_el->num_values; i++)
3382                         if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
3383                                 break;
3384                 torture_assert(tctx, i != spn_el->num_values,
3385                                "'servicePrincipalName' HOST/<Netbios name> not found!");
3386                 temp_str = talloc_asprintf(tctx, "HOST/%s", old_dnsname);
3387                 for (i=0; i < spn_el->num_values; i++)
3388                         if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
3389                                 break;
3390                 torture_assert(tctx, i != spn_el->num_values,
3391                                "'servicePrincipalName' HOST/<FQDN name> not found!");
3392
3393                 /* Here the server gives us NULL as the out DNS hostname */
3394                 torture_assert(tctx, info.domain_info->dns_hostname.string == NULL,
3395                                "Out 'DNS hostname' should be NULL!");
3396         }
3397
3398         /* Checks "workstation flags" */
3399         torture_assert(tctx,
3400                 info.domain_info->workstation_flags == 0,
3401                 "Out 'workstation flags' don't match!");
3402
3403
3404         torture_comment(tctx, "Testing netr_LogonGetDomainInfo 4th call (verification of DNS hostname and check for trusted domains)\n");
3405         netlogon_creds_client_authenticator(creds, &a);
3406
3407         /* Put the DNS hostname back */
3408         talloc_free(discard_const_p(char, q1.dns_hostname));
3409         q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
3410                 lpcfg_dnsdomain(tctx->lp_ctx));
3411
3412         /* The workstation handles the "servicePrincipalName" and DNS hostname
3413            updates */
3414         q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
3415
3416         torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3417                 "LogonGetDomainInfo failed");
3418         torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3419         torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3420
3421         smb_msleep(250);
3422
3423         /* Now the in/out DNS hostnames should be the same */
3424         torture_assert_str_equal(tctx,
3425                 info.domain_info->dns_hostname.string,
3426                 query.workstation_info->dns_hostname,
3427                 "In/Out 'DNS hostnames' don't match!");
3428         old_dnsname = info.domain_info->dns_hostname.string;
3429
3430         /* Checks "workstation flags" */
3431         torture_assert(tctx,
3432                 info.domain_info->workstation_flags
3433                 == NETR_WS_FLAG_HANDLES_SPN_UPDATE,
3434                 "Out 'workstation flags' don't match!");
3435
3436         /* Checks for trusted domains */
3437         torture_assert(tctx,
3438                 (info.domain_info->trusted_domain_count != 0)
3439                 && (info.domain_info->trusted_domains != NULL),
3440                 "Trusted domains have been requested!");
3441
3442
3443         torture_comment(tctx, "Testing netr_LogonGetDomainInfo 5th call (check for trusted domains)\n");
3444         netlogon_creds_client_authenticator(creds, &a);
3445
3446         /* The workstation handles the "servicePrincipalName" and DNS hostname
3447            updates and requests inbound trusts */
3448         q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE
3449                 | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS;
3450
3451         torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3452                 "LogonGetDomainInfo failed");
3453         torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3454         torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3455
3456         smb_msleep(250);
3457
3458         /* Checks "workstation flags" */
3459         torture_assert(tctx,
3460                 info.domain_info->workstation_flags
3461                 == (NETR_WS_FLAG_HANDLES_SPN_UPDATE
3462                         | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS),
3463                 "Out 'workstation flags' don't match!");
3464
3465         /* Checks for trusted domains */
3466         torture_assert(tctx,
3467                 (info.domain_info->trusted_domain_count != 0)
3468                 && (info.domain_info->trusted_domains != NULL),
3469                 "Trusted domains have been requested!");
3470
3471
3472         torture_comment(tctx, "Testing netr_LogonGetDomainInfo 6th call (no DNS hostname)\n");
3473         netlogon_creds_client_authenticator(creds, &a);
3474
3475         query.workstation_info->dns_hostname = NULL;
3476
3477         torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3478                 "LogonGetDomainInfo failed");
3479         torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3480         torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3481
3482         /* The old DNS hostname should stick */
3483         torture_assert_str_equal(tctx,
3484                 info.domain_info->dns_hostname.string,
3485                 old_dnsname,
3486                 "'DNS hostname' changed!");
3487
3488
3489         if (!torture_setting_bool(tctx, "dangerous", false)) {
3490                 torture_comment(tctx, "Not testing netr_LogonGetDomainInfo 7th call (no workstation info) - enable dangerous tests in order to do so\n");
3491         } else {
3492                 /* Try a call without the workstation information structure */
3493
3494                 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 7th call (no workstation info)\n");
3495                 netlogon_creds_client_authenticator(creds, &a);
3496
3497                 query.workstation_info = NULL;
3498
3499                 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3500                         "LogonGetDomainInfo failed");
3501                 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3502                 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3503         }
3504
3505         return true;
3506 }
3507
3508 static bool test_GetDomainInfo_async(struct torture_context *tctx, 
3509                                      struct dcerpc_pipe *p,
3510                                      struct cli_credentials *machine_credentials)
3511 {
3512         NTSTATUS status;
3513         struct netr_LogonGetDomainInfo r;
3514         struct netr_WorkstationInformation q1;
3515         struct netr_Authenticator a;
3516 #define ASYNC_COUNT 100
3517         struct netlogon_creds_CredentialState *creds;
3518         struct netlogon_creds_CredentialState *creds_async[ASYNC_COUNT];
3519         struct tevent_req *req[ASYNC_COUNT];
3520         int i;
3521         union netr_WorkstationInfo query;
3522         union netr_DomainInfo info;
3523
3524         torture_comment(tctx, "Testing netr_LogonGetDomainInfo - async count %d\n", ASYNC_COUNT);
3525
3526         if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS, 
3527                                     machine_credentials, &creds)) {
3528                 return false;
3529         }
3530
3531         ZERO_STRUCT(r);
3532         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3533         r.in.computer_name = TEST_MACHINE_NAME;
3534         r.in.credential = &a;
3535         r.in.level = 1;
3536         r.in.return_authenticator = &a;
3537         r.in.query = &query;
3538         r.out.return_authenticator = &a;
3539         r.out.info = &info;
3540
3541         ZERO_STRUCT(q1);
3542         q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
3543                 lpcfg_dnsdomain(tctx->lp_ctx));
3544         q1.sitename = "Default-First-Site-Name";
3545         q1.os_name.string = "UNIX/Linux or similar";
3546
3547         query.workstation_info = &q1;
3548
3549         for (i=0;i<ASYNC_COUNT;i++) {
3550                 netlogon_creds_client_authenticator(creds, &a);
3551
3552                 creds_async[i] = (struct netlogon_creds_CredentialState *)talloc_memdup(creds, creds, sizeof(*creds));
3553                 req[i] = dcerpc_netr_LogonGetDomainInfo_r_send(tctx, tctx->ev, p->binding_handle, &r);
3554
3555                 /* even with this flush per request a w2k3 server seems to 
3556                    clag with multiple outstanding requests. bleergh. */
3557                 torture_assert_int_equal(tctx, tevent_loop_once(dcerpc_event_context(p)), 0, 
3558                                          "tevent_loop_once failed");
3559         }
3560
3561         for (i=0;i<ASYNC_COUNT;i++) {
3562                 torture_assert_int_equal(tctx, tevent_req_poll(req[i], tctx->ev), true,
3563                                          "tevent_req_poll() failed");
3564
3565                 status = dcerpc_netr_LogonGetDomainInfo_r_recv(req[i], tctx);
3566
3567                 torture_assert_ntstatus_ok(tctx, status, "netr_LogonGetDomainInfo_async");
3568                 torture_assert_ntstatus_ok(tctx, r.out.result, "netr_LogonGetDomainInfo_async"); 
3569
3570                 torture_assert(tctx, netlogon_creds_client_check(creds_async[i], &a.cred), 
3571                         "Credential chaining failed at async");
3572         }
3573
3574         torture_comment(tctx, 
3575                         "Testing netr_LogonGetDomainInfo - async count %d OK\n", ASYNC_COUNT);
3576
3577         return true;
3578 }
3579
3580 static bool test_ManyGetDCName(struct torture_context *tctx, 
3581                                struct dcerpc_pipe *p)
3582 {
3583         NTSTATUS status;
3584         struct dcerpc_pipe *p2;
3585         struct lsa_ObjectAttribute attr;
3586         struct lsa_QosInfo qos;
3587         struct lsa_OpenPolicy2 o;
3588         struct policy_handle lsa_handle;
3589         struct lsa_DomainList domains;
3590
3591         struct lsa_EnumTrustDom t;
3592         uint32_t resume_handle = 0;
3593         struct netr_GetAnyDCName d;
3594         const char *dcname = NULL;
3595         struct dcerpc_binding_handle *b = p->binding_handle;
3596         struct dcerpc_binding_handle *b2;
3597
3598         int i;
3599
3600         if (p->conn->transport.transport != NCACN_NP) {
3601                 return true;
3602         }
3603
3604         torture_comment(tctx, "Torturing GetDCName\n");
3605
3606         status = dcerpc_secondary_connection(p, &p2, p->binding);
3607         torture_assert_ntstatus_ok(tctx, status, "Failed to create secondary connection");
3608
3609         status = dcerpc_bind_auth_none(p2, &ndr_table_lsarpc);
3610         torture_assert_ntstatus_ok(tctx, status, "Failed to create bind on secondary connection");
3611         b2 = p2->binding_handle;
3612
3613         qos.len = 0;
3614         qos.impersonation_level = 2;
3615         qos.context_mode = 1;
3616         qos.effective_only = 0;
3617
3618         attr.len = 0;
3619         attr.root_dir = NULL;
3620         attr.object_name = NULL;
3621         attr.attributes = 0;
3622         attr.sec_desc = NULL;
3623         attr.sec_qos = &qos;
3624
3625         o.in.system_name = "\\";
3626         o.in.attr = &attr;
3627         o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3628         o.out.handle = &lsa_handle;
3629
3630         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenPolicy2_r(b2, tctx, &o),
3631                 "OpenPolicy2 failed");
3632         torture_assert_ntstatus_ok(tctx, o.out.result, "OpenPolicy2 failed");
3633
3634         t.in.handle = &lsa_handle;
3635         t.in.resume_handle = &resume_handle;
3636         t.in.max_size = 1000;
3637         t.out.domains = &domains;
3638         t.out.resume_handle = &resume_handle;
3639
3640         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumTrustDom_r(b2, tctx, &t),
3641                 "EnumTrustDom failed");
3642
3643         if ((!NT_STATUS_IS_OK(t.out.result) &&
3644              (!NT_STATUS_EQUAL(t.out.result, NT_STATUS_NO_MORE_ENTRIES))))
3645                 torture_fail(tctx, "Could not list domains");
3646
3647         talloc_free(p2);
3648
3649         d.in.logon_server = talloc_asprintf(tctx, "\\\\%s",
3650                                             dcerpc_server_name(p));
3651         d.out.dcname = &dcname;
3652
3653         for (i=0; i<domains.count * 4; i++) {
3654                 struct lsa_DomainInfo *info =
3655                         &domains.domains[rand()%domains.count];
3656
3657                 d.in.domainname = info->name.string;
3658
3659                 status = dcerpc_netr_GetAnyDCName_r(b, tctx, &d);
3660                 torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
3661
3662                 torture_comment(tctx, "\tDC for domain %s is %s\n", info->name.string,
3663                        dcname ? dcname : "unknown");
3664         }
3665
3666         return true;
3667 }
3668
3669 static bool test_SetPassword_with_flags(struct torture_context *tctx,
3670                                         struct dcerpc_pipe *p,
3671                                         struct cli_credentials *machine_credentials)
3672 {
3673         uint32_t flags[] = { 0, NETLOGON_NEG_STRONG_KEYS };
3674         struct netlogon_creds_CredentialState *creds;
3675         int i;
3676
3677         if (!test_SetupCredentials2(p, tctx, 0,
3678                                     machine_credentials,
3679                                     cli_credentials_get_secure_channel_type(machine_credentials),
3680                                     &creds)) {
3681                 torture_skip(tctx, "DC does not support negotiation of 64bit session keys");
3682         }
3683
3684         for (i=0; i < ARRAY_SIZE(flags); i++) {
3685                 torture_assert(tctx,
3686                         test_SetPassword_flags(tctx, p, machine_credentials, flags[i]),
3687                         talloc_asprintf(tctx, "failed to test SetPassword negotiating with 0x%08x flags", flags[i]));
3688         }
3689
3690         return true;
3691 }
3692
3693 struct torture_suite *torture_rpc_netlogon(TALLOC_CTX *mem_ctx)
3694 {
3695         struct torture_suite *suite = torture_suite_create(mem_ctx, "netlogon");
3696         struct torture_rpc_tcase *tcase;
3697         struct torture_test *test;
3698
3699         tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netlogon",
3700                                                   &ndr_table_netlogon, TEST_MACHINE_NAME);
3701
3702         torture_rpc_tcase_add_test(tcase, "Broken RPC binding handle",
3703                                    test_netr_broken_binding_handle);
3704
3705         torture_rpc_tcase_add_test(tcase, "LogonUasLogon", test_LogonUasLogon);
3706         torture_rpc_tcase_add_test(tcase, "LogonUasLogoff", test_LogonUasLogoff);
3707         torture_rpc_tcase_add_test_creds(tcase, "SamLogon", test_SamLogon);
3708         torture_rpc_tcase_add_test_creds(tcase, "SetPassword", test_SetPassword);
3709         torture_rpc_tcase_add_test_creds(tcase, "SetPassword2", test_SetPassword2);
3710         torture_rpc_tcase_add_test_creds(tcase, "GetPassword", test_GetPassword);
3711         torture_rpc_tcase_add_test_creds(tcase, "GetTrustPasswords", test_GetTrustPasswords);
3712         torture_rpc_tcase_add_test_creds(tcase, "GetDomainInfo", test_GetDomainInfo);
3713         torture_rpc_tcase_add_test_creds(tcase, "DatabaseSync", test_DatabaseSync);
3714         torture_rpc_tcase_add_test_creds(tcase, "DatabaseDeltas", test_DatabaseDeltas);
3715         torture_rpc_tcase_add_test_creds(tcase, "DatabaseRedo", test_DatabaseRedo);
3716         torture_rpc_tcase_add_test_creds(tcase, "AccountDeltas", test_AccountDeltas);
3717         torture_rpc_tcase_add_test_creds(tcase, "AccountSync", test_AccountSync);
3718         torture_rpc_tcase_add_test(tcase, "GetDcName", test_GetDcName);
3719         torture_rpc_tcase_add_test(tcase, "ManyGetDCName", test_ManyGetDCName);
3720         torture_rpc_tcase_add_test(tcase, "GetAnyDCName", test_GetAnyDCName);
3721         torture_rpc_tcase_add_test_creds(tcase, "DatabaseSync2", test_DatabaseSync2);
3722         torture_rpc_tcase_add_test(tcase, "DsrEnumerateDomainTrusts", test_DsrEnumerateDomainTrusts);
3723         torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomains", test_netr_NetrEnumerateTrustedDomains);
3724         torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomainsEx", test_netr_NetrEnumerateTrustedDomainsEx);
3725         test = torture_rpc_tcase_add_test_creds(tcase, "GetDomainInfo_async", test_GetDomainInfo_async);
3726         test->dangerous = true;
3727         torture_rpc_tcase_add_test(tcase, "DsRGetDCName", test_netr_DsRGetDCName);
3728         torture_rpc_tcase_add_test(tcase, "DsRGetDCNameEx", test_netr_DsRGetDCNameEx);
3729         torture_rpc_tcase_add_test(tcase, "DsRGetDCNameEx2", test_netr_DsRGetDCNameEx2);
3730         torture_rpc_tcase_add_test(tcase, "DsrGetDcSiteCoverageW", test_netr_DsrGetDcSiteCoverageW);
3731         torture_rpc_tcase_add_test(tcase, "DsRAddressToSitenamesW", test_netr_DsRAddressToSitenamesW);
3732         torture_rpc_tcase_add_test(tcase, "DsRAddressToSitenamesExW", test_netr_DsRAddressToSitenamesExW);
3733         torture_rpc_tcase_add_test_creds(tcase, "ServerGetTrustInfo", test_netr_ServerGetTrustInfo);
3734         torture_rpc_tcase_add_test_creds(tcase, "GetForestTrustInformation", test_netr_GetForestTrustInformation);
3735
3736         return suite;
3737 }
3738
3739 struct torture_suite *torture_rpc_netlogon_s3(TALLOC_CTX *mem_ctx)
3740 {
3741         struct torture_suite *suite = torture_suite_create(mem_ctx, "netlogon-s3");
3742         struct torture_rpc_tcase *tcase;
3743
3744         tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netlogon",
3745                                                   &ndr_table_netlogon, TEST_MACHINE_NAME);
3746
3747         torture_rpc_tcase_add_test_creds(tcase, "SamLogon", test_SamLogon);
3748         torture_rpc_tcase_add_test_creds(tcase, "SamLogon_NULL_domain", test_SamLogon_NULL_domain);
3749         torture_rpc_tcase_add_test_creds(tcase, "SetPassword", test_SetPassword);
3750         torture_rpc_tcase_add_test_creds(tcase, "SetPassword_with_flags", test_SetPassword_with_flags);
3751         torture_rpc_tcase_add_test_creds(tcase, "SetPassword2", test_SetPassword2);
3752         torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomains", test_netr_NetrEnumerateTrustedDomains);
3753
3754         return suite;
3755 }
3756
3757 struct torture_suite *torture_rpc_netlogon_admin(TALLOC_CTX *mem_ctx)
3758 {
3759         struct torture_suite *suite = torture_suite_create(mem_ctx, "netlogon.admin");
3760         struct torture_rpc_tcase *tcase;
3761
3762         tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netlogon",
3763                                                   &ndr_table_netlogon, TEST_MACHINE_NAME);
3764         torture_rpc_tcase_add_test_creds(tcase, "LogonControl", test_LogonControl);
3765         torture_rpc_tcase_add_test_creds(tcase, "LogonControl2", test_LogonControl2);
3766         torture_rpc_tcase_add_test_creds(tcase, "LogonControl2Ex", test_LogonControl2Ex);
3767
3768         tcase = torture_suite_add_machine_workstation_rpc_iface_tcase(suite, "netlogon",
3769                                                   &ndr_table_netlogon, TEST_MACHINE_NAME);
3770         torture_rpc_tcase_add_test_creds(tcase, "LogonControl", test_LogonControl);
3771         torture_rpc_tcase_add_test_creds(tcase, "LogonControl2", test_LogonControl2);
3772         torture_rpc_tcase_add_test_creds(tcase, "LogonControl2Ex", test_LogonControl2Ex);
3773
3774         tcase = torture_suite_add_rpc_iface_tcase(suite, "netlogon",
3775                                                   &ndr_table_netlogon);
3776         torture_rpc_tcase_add_test_creds(tcase, "LogonControl", test_LogonControl);
3777         torture_rpc_tcase_add_test_creds(tcase, "LogonControl2", test_LogonControl2);
3778         torture_rpc_tcase_add_test_creds(tcase, "LogonControl2Ex", test_LogonControl2Ex);
3779
3780         return suite;
3781 }