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