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