torture: Add credentials downgrade and challenge reuse test to rpc.netlogon
[amitay/samba.git] / source4 / torture / rpc / netlogon.c
1 /*
2    Unix SMB/CIFS implementation.
3
4    test suite for netlogon rpc operations
5
6    Copyright (C) Andrew Tridgell 2003
7    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003-2004
8    Copyright (C) Tim Potter      2003
9    Copyright (C) Matthias Dieter Wallnöfer            2009-2010
10
11    This program is free software; you can redistribute it and/or modify
12    it under the terms of the GNU General Public License as published by
13    the Free Software Foundation; either version 3 of the License, or
14    (at your option) any later version.
15
16    This program is distributed in the hope that it will be useful,
17    but WITHOUT ANY WARRANTY; without even the implied warranty of
18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19    GNU General Public License for more details.
20
21    You should have received a copy of the GNU General Public License
22    along with this program.  If not, see <http://www.gnu.org/licenses/>.
23 */
24
25 #include "includes.h"
26 #include "lib/events/events.h"
27 #include "lib/cmdline/popt_common.h"
28 #include "torture/rpc/torture_rpc.h"
29 #include "../lib/crypto/crypto.h"
30 #include "libcli/auth/libcli_auth.h"
31 #include "librpc/gen_ndr/ndr_netlogon_c.h"
32 #include "librpc/gen_ndr/ndr_lsa_c.h"
33 #include "param/param.h"
34 #include "libcli/security/security.h"
35 #include <ldb.h>
36 #include "lib/util/util_ldb.h"
37 #include "ldb_wrap.h"
38 #include "lib/replace/system/network.h"
39 #include "dsdb/samdb/samdb.h"
40
41 #define TEST_MACHINE_NAME "torturetest"
42
43 static bool test_netr_broken_binding_handle(struct torture_context *tctx,
44                                             struct dcerpc_pipe *p)
45 {
46         NTSTATUS status;
47         struct netr_DsRGetSiteName r;
48         const char *site = NULL;
49         struct dcerpc_binding_handle *b = p->binding_handle;
50
51         r.in.computer_name      = talloc_asprintf(tctx, "\\\\%s",
52                                                   dcerpc_server_name(p));
53         r.out.site              = &site;
54
55         torture_comment(tctx,
56                         "Testing netlogon request with correct binding handle: %s\n",
57                         r.in.computer_name);
58
59         status = dcerpc_netr_DsRGetSiteName_r(b, tctx, &r);
60         torture_assert_ntstatus_ok(tctx, status,
61                                    "Netlogon request with broken binding handle");
62         torture_assert_werr_ok(tctx, r.out.result,
63                                "Netlogon request with broken binding handle");
64
65         if (torture_setting_bool(tctx, "samba3", false) ||
66             torture_setting_bool(tctx, "samba4", false)) {
67                 torture_skip(tctx,
68                              "Skipping broken binding handle check against Samba");
69         }
70
71         r.in.computer_name      = talloc_asprintf(tctx, "\\\\\\\\%s",
72                                                   dcerpc_server_name(p));
73
74         torture_comment(tctx,
75                         "Testing netlogon request with broken binding handle: %s\n",
76                         r.in.computer_name);
77
78         status = dcerpc_netr_DsRGetSiteName_r(b, tctx, &r);
79         torture_assert_ntstatus_ok(tctx, status,
80                                    "Netlogon request with broken binding handle");
81         torture_assert_werr_equal(tctx, r.out.result,
82                                   WERR_INVALID_COMPUTERNAME,
83                                   "Netlogon request with broken binding handle");
84
85         r.in.computer_name      = "\\\\\\\\THIS_IS_NOT_VALID";
86
87         torture_comment(tctx,
88                         "Testing netlogon request with broken binding handle: %s\n",
89                         r.in.computer_name);
90
91         status = dcerpc_netr_DsRGetSiteName_r(b, tctx, &r);
92         torture_assert_ntstatus_ok(tctx, status,
93                                    "Netlogon request with broken binding handle");
94         torture_assert_werr_equal(tctx, r.out.result,
95                                   WERR_INVALID_COMPUTERNAME,
96                                   "Netlogon request with broken binding handle");
97
98         return true;
99 }
100
101 static bool test_LogonUasLogon(struct torture_context *tctx,
102                                struct dcerpc_pipe *p)
103 {
104         NTSTATUS status;
105         struct netr_LogonUasLogon r;
106         struct netr_UasInfo *info = NULL;
107         struct dcerpc_binding_handle *b = p->binding_handle;
108
109         r.in.server_name = NULL;
110         r.in.account_name = cli_credentials_get_username(cmdline_credentials);
111         r.in.workstation = TEST_MACHINE_NAME;
112         r.out.info = &info;
113
114         status = dcerpc_netr_LogonUasLogon_r(b, tctx, &r);
115         torture_assert_ntstatus_ok(tctx, status, "LogonUasLogon");
116
117         return true;
118 }
119
120 static bool test_LogonUasLogoff(struct torture_context *tctx,
121                                 struct dcerpc_pipe *p)
122 {
123         NTSTATUS status;
124         struct netr_LogonUasLogoff r;
125         struct netr_UasLogoffInfo info;
126         struct dcerpc_binding_handle *b = p->binding_handle;
127
128         r.in.server_name = NULL;
129         r.in.account_name = cli_credentials_get_username(cmdline_credentials);
130         r.in.workstation = TEST_MACHINE_NAME;
131         r.out.info = &info;
132
133         status = dcerpc_netr_LogonUasLogoff_r(b, tctx, &r);
134         torture_assert_ntstatus_ok(tctx, status, "LogonUasLogoff");
135
136         return true;
137 }
138
139 bool test_SetupCredentials(struct dcerpc_pipe *p, struct torture_context *tctx,
140                                   struct cli_credentials *credentials,
141                                   struct netlogon_creds_CredentialState **creds_out)
142 {
143         struct netr_ServerReqChallenge r;
144         struct netr_ServerAuthenticate a;
145         struct netr_Credential credentials1, credentials2, credentials3;
146         struct netlogon_creds_CredentialState *creds;
147         const struct samr_Password *mach_password;
148         const char *machine_name;
149         struct dcerpc_binding_handle *b = p->binding_handle;
150
151         mach_password = cli_credentials_get_nt_hash(credentials, tctx);
152         machine_name = cli_credentials_get_workstation(credentials);
153
154         torture_comment(tctx, "Testing ServerReqChallenge\n");
155
156         r.in.server_name = NULL;
157         r.in.computer_name = machine_name;
158         r.in.credentials = &credentials1;
159         r.out.return_credentials = &credentials2;
160
161         generate_random_buffer(credentials1.data, sizeof(credentials1.data));
162
163         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
164                 "ServerReqChallenge failed");
165         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
166
167         a.in.server_name = NULL;
168         a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
169         a.in.secure_channel_type = cli_credentials_get_secure_channel_type(credentials);
170         a.in.computer_name = machine_name;
171         a.in.credentials = &credentials3;
172         a.out.return_credentials = &credentials3;
173
174         creds = netlogon_creds_client_init(tctx, a.in.account_name,
175                                            a.in.computer_name,
176                                            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 static bool test_SamLogon_NULL_domain(struct torture_context *tctx,
1310                                       struct dcerpc_pipe *p,
1311                                       struct cli_credentials *credentials)
1312 {
1313         struct netlogon_creds_CredentialState *creds;
1314
1315         if (!test_SetupCredentials(p, tctx, credentials, &creds)) {
1316                 return false;
1317         }
1318
1319         return test_netlogon_ops_args(p, tctx, credentials, creds, true);
1320 }
1321
1322 /* we remember the sequence numbers so we can easily do a DatabaseDelta */
1323 static uint64_t sequence_nums[3];
1324
1325 /*
1326   try a netlogon DatabaseSync
1327 */
1328 static bool test_DatabaseSync(struct torture_context *tctx,
1329                               struct dcerpc_pipe *p,
1330                               struct cli_credentials *machine_credentials)
1331 {
1332         struct netr_DatabaseSync r;
1333         struct netlogon_creds_CredentialState *creds;
1334         const uint32_t database_ids[] = {SAM_DATABASE_DOMAIN, SAM_DATABASE_BUILTIN, SAM_DATABASE_PRIVS};
1335         int i;
1336         struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
1337         struct netr_Authenticator credential, return_authenticator;
1338         struct dcerpc_binding_handle *b = p->binding_handle;
1339
1340         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1341                 return false;
1342         }
1343
1344         ZERO_STRUCT(return_authenticator);
1345
1346         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1347         r.in.computername = TEST_MACHINE_NAME;
1348         r.in.preferredmaximumlength = (uint32_t)-1;
1349         r.in.return_authenticator = &return_authenticator;
1350         r.out.delta_enum_array = &delta_enum_array;
1351         r.out.return_authenticator = &return_authenticator;
1352
1353         for (i=0;i<ARRAY_SIZE(database_ids);i++) {
1354
1355                 uint32_t sync_context = 0;
1356
1357                 r.in.database_id = database_ids[i];
1358                 r.in.sync_context = &sync_context;
1359                 r.out.sync_context = &sync_context;
1360
1361                 torture_comment(tctx, "Testing DatabaseSync of id %d\n", r.in.database_id);
1362
1363                 do {
1364                         netlogon_creds_client_authenticator(creds, &credential);
1365
1366                         r.in.credential = &credential;
1367
1368                         torture_assert_ntstatus_ok(tctx, dcerpc_netr_DatabaseSync_r(b, tctx, &r),
1369                                 "DatabaseSync failed");
1370                         if (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES))
1371                             break;
1372
1373                         /* Native mode servers don't do this */
1374                         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_SUPPORTED)) {
1375                                 return true;
1376                         }
1377                         torture_assert_ntstatus_ok(tctx, r.out.result, "DatabaseSync");
1378
1379                         if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
1380                                 torture_comment(tctx, "Credential chaining failed\n");
1381                         }
1382
1383                         if (delta_enum_array &&
1384                             delta_enum_array->num_deltas > 0 &&
1385                             delta_enum_array->delta_enum[0].delta_type == NETR_DELTA_DOMAIN &&
1386                             delta_enum_array->delta_enum[0].delta_union.domain) {
1387                                 sequence_nums[r.in.database_id] =
1388                                         delta_enum_array->delta_enum[0].delta_union.domain->sequence_num;
1389                                 torture_comment(tctx, "\tsequence_nums[%d]=%llu\n",
1390                                        r.in.database_id,
1391                                        (unsigned long long)sequence_nums[r.in.database_id]);
1392                         }
1393                 } while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES));
1394         }
1395
1396         return true;
1397 }
1398
1399
1400 /*
1401   try a netlogon DatabaseDeltas
1402 */
1403 static bool test_DatabaseDeltas(struct torture_context *tctx,
1404                                 struct dcerpc_pipe *p,
1405                                 struct cli_credentials *machine_credentials)
1406 {
1407         struct netr_DatabaseDeltas r;
1408         struct netlogon_creds_CredentialState *creds;
1409         struct netr_Authenticator credential;
1410         struct netr_Authenticator return_authenticator;
1411         struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
1412         const uint32_t database_ids[] = {0, 1, 2};
1413         int i;
1414         struct dcerpc_binding_handle *b = p->binding_handle;
1415
1416         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1417                 return false;
1418         }
1419
1420         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1421         r.in.computername = TEST_MACHINE_NAME;
1422         r.in.preferredmaximumlength = (uint32_t)-1;
1423         ZERO_STRUCT(r.in.return_authenticator);
1424         r.out.return_authenticator = &return_authenticator;
1425         r.out.delta_enum_array = &delta_enum_array;
1426
1427         for (i=0;i<ARRAY_SIZE(database_ids);i++) {
1428                 r.in.database_id = database_ids[i];
1429                 r.in.sequence_num = &sequence_nums[r.in.database_id];
1430
1431                 if (*r.in.sequence_num == 0) continue;
1432
1433                 *r.in.sequence_num -= 1;
1434
1435                 torture_comment(tctx, "Testing DatabaseDeltas of id %d at %llu\n",
1436                        r.in.database_id, (unsigned long long)*r.in.sequence_num);
1437
1438                 do {
1439                         netlogon_creds_client_authenticator(creds, &credential);
1440
1441                         torture_assert_ntstatus_ok(tctx, dcerpc_netr_DatabaseDeltas_r(b, tctx, &r),
1442                                 "DatabaseDeltas failed");
1443                         if (NT_STATUS_EQUAL(r.out.result,
1444                                              NT_STATUS_SYNCHRONIZATION_REQUIRED)) {
1445                                 torture_comment(tctx, "not considering %s to be an error\n",
1446                                        nt_errstr(r.out.result));
1447                                 return true;
1448                         }
1449                         if (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES))
1450                             break;
1451
1452                         torture_assert_ntstatus_ok(tctx, r.out.result, "DatabaseDeltas");
1453
1454                         if (!netlogon_creds_client_check(creds, &return_authenticator.cred)) {
1455                                 torture_comment(tctx, "Credential chaining failed\n");
1456                         }
1457
1458                         (*r.in.sequence_num)++;
1459                 } while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES));
1460         }
1461
1462         return true;
1463 }
1464
1465 static bool test_DatabaseRedo(struct torture_context *tctx,
1466                               struct dcerpc_pipe *p,
1467                               struct cli_credentials *machine_credentials)
1468 {
1469         struct netr_DatabaseRedo r;
1470         struct netlogon_creds_CredentialState *creds;
1471         struct netr_Authenticator credential;
1472         struct netr_Authenticator return_authenticator;
1473         struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
1474         struct netr_ChangeLogEntry e;
1475         struct dom_sid null_sid, *sid;
1476         int i,d;
1477         struct dcerpc_binding_handle *b = p->binding_handle;
1478
1479         ZERO_STRUCT(null_sid);
1480
1481         sid = dom_sid_parse_talloc(tctx, "S-1-5-21-1111111111-2222222222-333333333-500");
1482
1483         {
1484
1485         struct {
1486                 uint32_t rid;
1487                 uint16_t flags;
1488                 uint8_t db_index;
1489                 uint8_t delta_type;
1490                 struct dom_sid sid;
1491                 const char *name;
1492                 NTSTATUS expected_error;
1493                 uint32_t expected_num_results;
1494                 uint8_t expected_delta_type_1;
1495                 uint8_t expected_delta_type_2;
1496                 const char *comment;
1497         } changes[] = {
1498
1499                 /* SAM_DATABASE_DOMAIN */
1500
1501                 {
1502                         .rid                    = 0,
1503                         .flags                  = 0,
1504                         .db_index               = SAM_DATABASE_DOMAIN,
1505                         .delta_type             = NETR_DELTA_MODIFY_COUNT,
1506                         .sid                    = null_sid,
1507                         .name                   = NULL,
1508                         .expected_error         = NT_STATUS_SYNCHRONIZATION_REQUIRED,
1509                         .expected_num_results   = 0,
1510                         .comment                = "NETR_DELTA_MODIFY_COUNT"
1511                 },
1512                 {
1513                         .rid                    = 0,
1514                         .flags                  = 0,
1515                         .db_index               = SAM_DATABASE_DOMAIN,
1516                         .delta_type             = 0,
1517                         .sid                    = null_sid,
1518                         .name                   = NULL,
1519                         .expected_error         = NT_STATUS_OK,
1520                         .expected_num_results   = 1,
1521                         .expected_delta_type_1  = NETR_DELTA_DOMAIN,
1522                         .comment                = "NULL DELTA"
1523                 },
1524                 {
1525                         .rid                    = 0,
1526                         .flags                  = 0,
1527                         .db_index               = SAM_DATABASE_DOMAIN,
1528                         .delta_type             = NETR_DELTA_DOMAIN,
1529                         .sid                    = null_sid,
1530                         .name                   = NULL,
1531                         .expected_error         = NT_STATUS_OK,
1532                         .expected_num_results   = 1,
1533                         .expected_delta_type_1  = NETR_DELTA_DOMAIN,
1534                         .comment                = "NETR_DELTA_DOMAIN"
1535                 },
1536                 {
1537                         .rid                    = DOMAIN_RID_ADMINISTRATOR,
1538                         .flags                  = 0,
1539                         .db_index               = SAM_DATABASE_DOMAIN,
1540                         .delta_type             = NETR_DELTA_USER,
1541                         .sid                    = null_sid,
1542                         .name                   = NULL,
1543                         .expected_error         = NT_STATUS_OK,
1544                         .expected_num_results   = 1,
1545                         .expected_delta_type_1  = NETR_DELTA_USER,
1546                         .comment                = "NETR_DELTA_USER by rid 500"
1547                 },
1548                 {
1549                         .rid                    = DOMAIN_RID_GUEST,
1550                         .flags                  = 0,
1551                         .db_index               = SAM_DATABASE_DOMAIN,
1552                         .delta_type             = NETR_DELTA_USER,
1553                         .sid                    = null_sid,
1554                         .name                   = NULL,
1555                         .expected_error         = NT_STATUS_OK,
1556                         .expected_num_results   = 1,
1557                         .expected_delta_type_1  = NETR_DELTA_USER,
1558                         .comment                = "NETR_DELTA_USER by rid 501"
1559                 },
1560                 {
1561                         .rid                    = 0,
1562                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
1563                         .db_index               = SAM_DATABASE_DOMAIN,
1564                         .delta_type             = NETR_DELTA_USER,
1565                         .sid                    = *sid,
1566                         .name                   = NULL,
1567                         .expected_error         = NT_STATUS_OK,
1568                         .expected_num_results   = 1,
1569                         .expected_delta_type_1  = NETR_DELTA_DELETE_USER,
1570                         .comment                = "NETR_DELTA_USER by sid and flags"
1571                 },
1572                 {
1573                         .rid                    = 0,
1574                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
1575                         .db_index               = SAM_DATABASE_DOMAIN,
1576                         .delta_type             = NETR_DELTA_USER,
1577                         .sid                    = null_sid,
1578                         .name                   = NULL,
1579                         .expected_error         = NT_STATUS_OK,
1580                         .expected_num_results   = 1,
1581                         .expected_delta_type_1  = NETR_DELTA_DELETE_USER,
1582                         .comment                = "NETR_DELTA_USER by null_sid and flags"
1583                 },
1584                 {
1585                         .rid                    = 0,
1586                         .flags                  = NETR_CHANGELOG_NAME_INCLUDED,
1587                         .db_index               = SAM_DATABASE_DOMAIN,
1588                         .delta_type             = NETR_DELTA_USER,
1589                         .sid                    = null_sid,
1590                         .name                   = "administrator",
1591                         .expected_error         = NT_STATUS_OK,
1592                         .expected_num_results   = 1,
1593                         .expected_delta_type_1  = NETR_DELTA_DELETE_USER,
1594                         .comment                = "NETR_DELTA_USER by name 'administrator'"
1595                 },
1596                 {
1597                         .rid                    = DOMAIN_RID_ADMINS,
1598                         .flags                  = 0,
1599                         .db_index               = SAM_DATABASE_DOMAIN,
1600                         .delta_type             = NETR_DELTA_GROUP,
1601                         .sid                    = null_sid,
1602                         .name                   = NULL,
1603                         .expected_error         = NT_STATUS_OK,
1604                         .expected_num_results   = 2,
1605                         .expected_delta_type_1  = NETR_DELTA_GROUP,
1606                         .expected_delta_type_2  = NETR_DELTA_GROUP_MEMBER,
1607                         .comment                = "NETR_DELTA_GROUP by rid 512"
1608                 },
1609                 {
1610                         .rid                    = DOMAIN_RID_ADMINS,
1611                         .flags                  = 0,
1612                         .db_index               = SAM_DATABASE_DOMAIN,
1613                         .delta_type             = NETR_DELTA_GROUP_MEMBER,
1614                         .sid                    = null_sid,
1615                         .name                   = NULL,
1616                         .expected_error         = NT_STATUS_OK,
1617                         .expected_num_results   = 2,
1618                         .expected_delta_type_1  = NETR_DELTA_GROUP,
1619                         .expected_delta_type_2  = NETR_DELTA_GROUP_MEMBER,
1620                         .comment                = "NETR_DELTA_GROUP_MEMBER by rid 512"
1621                 },
1622
1623
1624                 /* SAM_DATABASE_BUILTIN */
1625
1626                 {
1627                         .rid                    = 0,
1628                         .flags                  = 0,
1629                         .db_index               = SAM_DATABASE_BUILTIN,
1630                         .delta_type             = NETR_DELTA_MODIFY_COUNT,
1631                         .sid                    = null_sid,
1632                         .name                   = NULL,
1633                         .expected_error         = NT_STATUS_SYNCHRONIZATION_REQUIRED,
1634                         .expected_num_results   = 0,
1635                         .comment                = "NETR_DELTA_MODIFY_COUNT"
1636                 },
1637                 {
1638                         .rid                    = 0,
1639                         .flags                  = 0,
1640                         .db_index               = SAM_DATABASE_BUILTIN,
1641                         .delta_type             = NETR_DELTA_DOMAIN,
1642                         .sid                    = null_sid,
1643                         .name                   = NULL,
1644                         .expected_error         = NT_STATUS_OK,
1645                         .expected_num_results   = 1,
1646                         .expected_delta_type_1  = NETR_DELTA_DOMAIN,
1647                         .comment                = "NETR_DELTA_DOMAIN"
1648                 },
1649                 {
1650                         .rid                    = DOMAIN_RID_ADMINISTRATOR,
1651                         .flags                  = 0,
1652                         .db_index               = SAM_DATABASE_BUILTIN,
1653                         .delta_type             = NETR_DELTA_USER,
1654                         .sid                    = null_sid,
1655                         .name                   = NULL,
1656                         .expected_error         = NT_STATUS_OK,
1657                         .expected_num_results   = 1,
1658                         .expected_delta_type_1  = NETR_DELTA_DELETE_USER,
1659                         .comment                = "NETR_DELTA_USER by rid 500"
1660                 },
1661                 {
1662                         .rid                    = 0,
1663                         .flags                  = 0,
1664                         .db_index               = SAM_DATABASE_BUILTIN,
1665                         .delta_type             = NETR_DELTA_USER,
1666                         .sid                    = null_sid,
1667                         .name                   = NULL,
1668                         .expected_error         = NT_STATUS_OK,
1669                         .expected_num_results   = 1,
1670                         .expected_delta_type_1  = NETR_DELTA_DELETE_USER,
1671                         .comment                = "NETR_DELTA_USER"
1672                 },
1673                 {
1674                         .rid                    = 544,
1675                         .flags                  = 0,
1676                         .db_index               = SAM_DATABASE_BUILTIN,
1677                         .delta_type             = NETR_DELTA_ALIAS,
1678                         .sid                    = null_sid,
1679                         .name                   = NULL,
1680                         .expected_error         = NT_STATUS_OK,
1681                         .expected_num_results   = 2,
1682                         .expected_delta_type_1  = NETR_DELTA_ALIAS,
1683                         .expected_delta_type_2  = NETR_DELTA_ALIAS_MEMBER,
1684                         .comment                = "NETR_DELTA_ALIAS by rid 544"
1685                 },
1686                 {
1687                         .rid                    = 544,
1688                         .flags                  = 0,
1689                         .db_index               = SAM_DATABASE_BUILTIN,
1690                         .delta_type             = NETR_DELTA_ALIAS_MEMBER,
1691                         .sid                    = null_sid,
1692                         .name                   = NULL,
1693                         .expected_error         = NT_STATUS_OK,
1694                         .expected_num_results   = 2,
1695                         .expected_delta_type_1  = NETR_DELTA_ALIAS,
1696                         .expected_delta_type_2  = NETR_DELTA_ALIAS_MEMBER,
1697                         .comment                = "NETR_DELTA_ALIAS_MEMBER by rid 544"
1698                 },
1699                 {
1700                         .rid                    = 544,
1701                         .flags                  = 0,
1702                         .db_index               = SAM_DATABASE_BUILTIN,
1703                         .delta_type             = 0,
1704                         .sid                    = null_sid,
1705                         .name                   = NULL,
1706                         .expected_error         = NT_STATUS_OK,
1707                         .expected_num_results   = 1,
1708                         .expected_delta_type_1  = NETR_DELTA_DOMAIN,
1709                         .comment                = "NULL DELTA by rid 544"
1710                 },
1711                 {
1712                         .rid                    = 544,
1713                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
1714                         .db_index               = SAM_DATABASE_BUILTIN,
1715                         .delta_type             = 0,
1716                         .sid                    = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
1717                         .name                   = NULL,
1718                         .expected_error         = NT_STATUS_OK,
1719                         .expected_num_results   = 1,
1720                         .expected_delta_type_1  = NETR_DELTA_DOMAIN,
1721                         .comment                = "NULL DELTA by rid 544 sid S-1-5-32-544 and flags"
1722                 },
1723                 {
1724                         .rid                    = 544,
1725                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
1726                         .db_index               = SAM_DATABASE_BUILTIN,
1727                         .delta_type             = NETR_DELTA_ALIAS,
1728                         .sid                    = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
1729                         .name                   = NULL,
1730                         .expected_error         = NT_STATUS_OK,
1731                         .expected_num_results   = 2,
1732                         .expected_delta_type_1  = NETR_DELTA_ALIAS,
1733                         .expected_delta_type_2  = NETR_DELTA_ALIAS_MEMBER,
1734                         .comment                = "NETR_DELTA_ALIAS by rid 544 and sid S-1-5-32-544 and flags"
1735                 },
1736                 {
1737                         .rid                    = 0,
1738                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
1739                         .db_index               = SAM_DATABASE_BUILTIN,
1740                         .delta_type             = NETR_DELTA_ALIAS,
1741                         .sid                    = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
1742                         .name                   = NULL,
1743                         .expected_error         = NT_STATUS_OK,
1744                         .expected_num_results   = 1,
1745                         .expected_delta_type_1  = NETR_DELTA_DELETE_ALIAS,
1746                         .comment                = "NETR_DELTA_ALIAS by sid S-1-5-32-544 and flags"
1747                 },
1748
1749                 /* SAM_DATABASE_PRIVS */
1750
1751                 {
1752                         .rid                    = 0,
1753                         .flags                  = 0,
1754                         .db_index               = SAM_DATABASE_PRIVS,
1755                         .delta_type             = 0,
1756                         .sid                    = null_sid,
1757                         .name                   = NULL,
1758                         .expected_error         = NT_STATUS_ACCESS_DENIED,
1759                         .expected_num_results   = 0,
1760                         .comment                = "NULL DELTA"
1761                 },
1762                 {
1763                         .rid                    = 0,
1764                         .flags                  = 0,
1765                         .db_index               = SAM_DATABASE_PRIVS,
1766                         .delta_type             = NETR_DELTA_MODIFY_COUNT,
1767                         .sid                    = null_sid,
1768                         .name                   = NULL,
1769                         .expected_error         = NT_STATUS_SYNCHRONIZATION_REQUIRED,
1770                         .expected_num_results   = 0,
1771                         .comment                = "NETR_DELTA_MODIFY_COUNT"
1772                 },
1773                 {
1774                         .rid                    = 0,
1775                         .flags                  = 0,
1776                         .db_index               = SAM_DATABASE_PRIVS,
1777                         .delta_type             = NETR_DELTA_POLICY,
1778                         .sid                    = null_sid,
1779                         .name                   = NULL,
1780                         .expected_error         = NT_STATUS_OK,
1781                         .expected_num_results   = 1,
1782                         .expected_delta_type_1  = NETR_DELTA_POLICY,
1783                         .comment                = "NETR_DELTA_POLICY"
1784                 },
1785                 {
1786                         .rid                    = 0,
1787                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
1788                         .db_index               = SAM_DATABASE_PRIVS,
1789                         .delta_type             = NETR_DELTA_POLICY,
1790                         .sid                    = null_sid,
1791                         .name                   = NULL,
1792                         .expected_error         = NT_STATUS_OK,
1793                         .expected_num_results   = 1,
1794                         .expected_delta_type_1  = NETR_DELTA_POLICY,
1795                         .comment                = "NETR_DELTA_POLICY by null sid and flags"
1796                 },
1797                 {
1798                         .rid                    = 0,
1799                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
1800                         .db_index               = SAM_DATABASE_PRIVS,
1801                         .delta_type             = NETR_DELTA_POLICY,
1802                         .sid                    = *dom_sid_parse_talloc(tctx, "S-1-5-32"),
1803                         .name                   = NULL,
1804                         .expected_error         = NT_STATUS_OK,
1805                         .expected_num_results   = 1,
1806                         .expected_delta_type_1  = NETR_DELTA_POLICY,
1807                         .comment                = "NETR_DELTA_POLICY by sid S-1-5-32 and flags"
1808                 },
1809                 {
1810                         .rid                    = DOMAIN_RID_ADMINISTRATOR,
1811                         .flags                  = 0,
1812                         .db_index               = SAM_DATABASE_PRIVS,
1813                         .delta_type             = NETR_DELTA_ACCOUNT,
1814                         .sid                    = null_sid,
1815                         .name                   = NULL,
1816                         .expected_error         = NT_STATUS_SYNCHRONIZATION_REQUIRED, /* strange */
1817                         .expected_num_results   = 0,
1818                         .comment                = "NETR_DELTA_ACCOUNT by rid 500"
1819                 },
1820                 {
1821                         .rid                    = 0,
1822                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
1823                         .db_index               = SAM_DATABASE_PRIVS,
1824                         .delta_type             = NETR_DELTA_ACCOUNT,
1825                         .sid                    = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
1826                         .name                   = NULL,
1827                         .expected_error         = NT_STATUS_OK,
1828                         .expected_num_results   = 1,
1829                         .expected_delta_type_1  = NETR_DELTA_ACCOUNT,
1830                         .comment                = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and flags"
1831                 },
1832                 {
1833                         .rid                    = 0,
1834                         .flags                  = NETR_CHANGELOG_SID_INCLUDED |
1835                                                   NETR_CHANGELOG_IMMEDIATE_REPL_REQUIRED,
1836                         .db_index               = SAM_DATABASE_PRIVS,
1837                         .delta_type             = NETR_DELTA_ACCOUNT,
1838                         .sid                    = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
1839                         .name                   = NULL,
1840                         .expected_error         = NT_STATUS_OK,
1841                         .expected_num_results   = 1,
1842                         .expected_delta_type_1  = NETR_DELTA_ACCOUNT,
1843                         .comment                = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and 2 flags"
1844                 },
1845                 {
1846                         .rid                    = 0,
1847                         .flags                  = NETR_CHANGELOG_SID_INCLUDED |
1848                                                   NETR_CHANGELOG_NAME_INCLUDED,
1849                         .db_index               = SAM_DATABASE_PRIVS,
1850                         .delta_type             = NETR_DELTA_ACCOUNT,
1851                         .sid                    = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
1852                         .name                   = NULL,
1853                         .expected_error         = NT_STATUS_INVALID_PARAMETER,
1854                         .expected_num_results   = 0,
1855                         .comment                = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and invalid flags"
1856                 },
1857                 {
1858                         .rid                    = DOMAIN_RID_ADMINISTRATOR,
1859                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
1860                         .db_index               = SAM_DATABASE_PRIVS,
1861                         .delta_type             = NETR_DELTA_ACCOUNT,
1862                         .sid                    = *sid,
1863                         .name                   = NULL,
1864                         .expected_error         = NT_STATUS_OK,
1865                         .expected_num_results   = 1,
1866                         .expected_delta_type_1  = NETR_DELTA_DELETE_ACCOUNT,
1867                         .comment                = "NETR_DELTA_ACCOUNT by rid 500, sid and flags"
1868                 },
1869                 {
1870                         .rid                    = 0,
1871                         .flags                  = NETR_CHANGELOG_NAME_INCLUDED,
1872                         .db_index               = SAM_DATABASE_PRIVS,
1873                         .delta_type             = NETR_DELTA_SECRET,
1874                         .sid                    = null_sid,
1875                         .name                   = "IsurelydontexistIhope",
1876                         .expected_error         = NT_STATUS_OK,
1877                         .expected_num_results   = 1,
1878                         .expected_delta_type_1  = NETR_DELTA_DELETE_SECRET,
1879                         .comment                = "NETR_DELTA_SECRET by name 'IsurelydontexistIhope' and flags"
1880                 },
1881                 {
1882                         .rid                    = 0,
1883                         .flags                  = NETR_CHANGELOG_NAME_INCLUDED,
1884                         .db_index               = SAM_DATABASE_PRIVS,
1885                         .delta_type             = NETR_DELTA_SECRET,
1886                         .sid                    = null_sid,
1887                         .name                   = "G$BCKUPKEY_P",
1888                         .expected_error         = NT_STATUS_OK,
1889                         .expected_num_results   = 1,
1890                         .expected_delta_type_1  = NETR_DELTA_SECRET,
1891                         .comment                = "NETR_DELTA_SECRET by name 'G$BCKUPKEY_P' and flags"
1892                 }
1893         };
1894
1895         ZERO_STRUCT(return_authenticator);
1896
1897         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1898         r.in.computername = TEST_MACHINE_NAME;
1899         r.in.return_authenticator = &return_authenticator;
1900         r.out.return_authenticator = &return_authenticator;
1901         r.out.delta_enum_array = &delta_enum_array;
1902
1903         for (d=0; d<3; d++) {
1904                 const char *database = NULL;
1905
1906                 switch (d) {
1907                 case 0:
1908                         database = "SAM";
1909                         break;
1910                 case 1:
1911                         database = "BUILTIN";
1912                         break;
1913                 case 2:
1914                         database = "LSA";
1915                         break;
1916                 default:
1917                         break;
1918                 }
1919
1920                 torture_comment(tctx, "Testing DatabaseRedo\n");
1921
1922                 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1923                         return false;
1924                 }
1925
1926                 for (i=0;i<ARRAY_SIZE(changes);i++) {
1927
1928                         if (d != changes[i].db_index) {
1929                                 continue;
1930                         }
1931
1932                         netlogon_creds_client_authenticator(creds, &credential);
1933
1934                         r.in.credential = &credential;
1935
1936                         e.serial_number1        = 0;
1937                         e.serial_number2        = 0;
1938                         e.object_rid            = changes[i].rid;
1939                         e.flags                 = changes[i].flags;
1940                         e.db_index              = changes[i].db_index;
1941                         e.delta_type            = changes[i].delta_type;
1942
1943                         switch (changes[i].flags & (NETR_CHANGELOG_NAME_INCLUDED | NETR_CHANGELOG_SID_INCLUDED)) {
1944                         case NETR_CHANGELOG_SID_INCLUDED:
1945                                 e.object.object_sid             = changes[i].sid;
1946                                 break;
1947                         case NETR_CHANGELOG_NAME_INCLUDED:
1948                                 e.object.object_name            = changes[i].name;
1949                                 break;
1950                         default:
1951                                 break;
1952                         }
1953
1954                         r.in.change_log_entry = e;
1955
1956                         torture_comment(tctx, "Testing DatabaseRedo with database %s and %s\n",
1957                                 database, changes[i].comment);
1958
1959                         torture_assert_ntstatus_ok(tctx, dcerpc_netr_DatabaseRedo_r(b, tctx, &r),
1960                                 "DatabaseRedo failed");
1961                         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_SUPPORTED)) {
1962                                 return true;
1963                         }
1964
1965                         torture_assert_ntstatus_equal(tctx, r.out.result, changes[i].expected_error, changes[i].comment);
1966                         if (delta_enum_array) {
1967                                 torture_assert_int_equal(tctx,
1968                                         delta_enum_array->num_deltas,
1969                                         changes[i].expected_num_results,
1970                                         changes[i].comment);
1971                                 if (delta_enum_array->num_deltas > 0) {
1972                                         torture_assert_int_equal(tctx,
1973                                                 delta_enum_array->delta_enum[0].delta_type,
1974                                                 changes[i].expected_delta_type_1,
1975                                                 changes[i].comment);
1976                                 }
1977                                 if (delta_enum_array->num_deltas > 1) {
1978                                         torture_assert_int_equal(tctx,
1979                                                 delta_enum_array->delta_enum[1].delta_type,
1980                                                 changes[i].expected_delta_type_2,
1981                                                 changes[i].comment);
1982                                 }
1983                         }
1984
1985                         if (!netlogon_creds_client_check(creds, &return_authenticator.cred)) {
1986                                 torture_comment(tctx, "Credential chaining failed\n");
1987                                 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1988                                         return false;
1989                                 }
1990                         }
1991                 }
1992         }
1993         }
1994
1995         return true;
1996 }
1997
1998 /*
1999   try a netlogon AccountDeltas
2000 */
2001 static bool test_AccountDeltas(struct torture_context *tctx,
2002                                struct dcerpc_pipe *p,
2003                                struct cli_credentials *machine_credentials)
2004 {
2005         struct netr_AccountDeltas r;
2006         struct netlogon_creds_CredentialState *creds;
2007
2008         struct netr_AccountBuffer buffer;
2009         uint32_t count_returned = 0;
2010         uint32_t total_entries = 0;
2011         struct netr_UAS_INFO_0 recordid;
2012         struct netr_Authenticator return_authenticator;
2013         struct dcerpc_binding_handle *b = p->binding_handle;
2014
2015         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
2016                 return false;
2017         }
2018
2019         ZERO_STRUCT(return_authenticator);
2020
2021         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2022         r.in.computername = TEST_MACHINE_NAME;
2023         r.in.return_authenticator = &return_authenticator;
2024         netlogon_creds_client_authenticator(creds, &r.in.credential);
2025         ZERO_STRUCT(r.in.uas);
2026         r.in.count=10;
2027         r.in.level=0;
2028         r.in.buffersize=100;
2029         r.out.buffer = &buffer;
2030         r.out.count_returned = &count_returned;
2031         r.out.total_entries = &total_entries;
2032         r.out.recordid = &recordid;
2033         r.out.return_authenticator = &return_authenticator;
2034
2035         /* w2k3 returns "NOT IMPLEMENTED" for this call */
2036         torture_assert_ntstatus_ok(tctx, dcerpc_netr_AccountDeltas_r(b, tctx, &r),
2037                 "AccountDeltas failed");
2038         torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_IMPLEMENTED, "AccountDeltas");
2039
2040         return true;
2041 }
2042
2043 /*
2044   try a netlogon AccountSync
2045 */
2046 static bool test_AccountSync(struct torture_context *tctx, struct dcerpc_pipe *p,
2047                              struct cli_credentials *machine_credentials)
2048 {
2049         struct netr_AccountSync r;
2050         struct netlogon_creds_CredentialState *creds;
2051
2052         struct netr_AccountBuffer buffer;
2053         uint32_t count_returned = 0;
2054         uint32_t total_entries = 0;
2055         uint32_t next_reference = 0;
2056         struct netr_UAS_INFO_0 recordid;
2057         struct netr_Authenticator return_authenticator;
2058         struct dcerpc_binding_handle *b = p->binding_handle;
2059
2060         ZERO_STRUCT(recordid);
2061         ZERO_STRUCT(return_authenticator);
2062
2063         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
2064                 return false;
2065         }
2066
2067         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2068         r.in.computername = TEST_MACHINE_NAME;
2069         r.in.return_authenticator = &return_authenticator;
2070         netlogon_creds_client_authenticator(creds, &r.in.credential);
2071         r.in.recordid = &recordid;
2072         r.in.reference=0;
2073         r.in.level=0;
2074         r.in.buffersize=100;
2075         r.out.buffer = &buffer;
2076         r.out.count_returned = &count_returned;
2077         r.out.total_entries = &total_entries;
2078         r.out.next_reference = &next_reference;
2079         r.out.recordid = &recordid;
2080         r.out.return_authenticator = &return_authenticator;
2081
2082         /* w2k3 returns "NOT IMPLEMENTED" for this call */
2083         torture_assert_ntstatus_ok(tctx, dcerpc_netr_AccountSync_r(b, tctx, &r),
2084                 "AccountSync failed");
2085         torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_IMPLEMENTED, "AccountSync");
2086
2087         return true;
2088 }
2089
2090 /*
2091   try a netlogon GetDcName
2092 */
2093 static bool test_GetDcName(struct torture_context *tctx,
2094                            struct dcerpc_pipe *p)
2095 {
2096         struct netr_GetDcName r;
2097         const char *dcname = NULL;
2098         struct dcerpc_binding_handle *b = p->binding_handle;
2099
2100         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2101         r.in.domainname = lpcfg_workgroup(tctx->lp_ctx);
2102         r.out.dcname = &dcname;
2103
2104         torture_assert_ntstatus_ok(tctx, dcerpc_netr_GetDcName_r(b, tctx, &r),
2105                 "GetDcName failed");
2106         torture_assert_werr_ok(tctx, r.out.result, "GetDcName failed");
2107
2108         torture_comment(tctx, "\tDC is at '%s'\n", dcname);
2109
2110         return true;
2111 }
2112
2113 static const char *function_code_str(TALLOC_CTX *mem_ctx,
2114                                      enum netr_LogonControlCode function_code)
2115 {
2116         switch (function_code) {
2117         case NETLOGON_CONTROL_QUERY:
2118                 return "NETLOGON_CONTROL_QUERY";
2119         case NETLOGON_CONTROL_REPLICATE:
2120                 return "NETLOGON_CONTROL_REPLICATE";
2121         case NETLOGON_CONTROL_SYNCHRONIZE:
2122                 return "NETLOGON_CONTROL_SYNCHRONIZE";
2123         case NETLOGON_CONTROL_PDC_REPLICATE:
2124                 return "NETLOGON_CONTROL_PDC_REPLICATE";
2125         case NETLOGON_CONTROL_REDISCOVER:
2126                 return "NETLOGON_CONTROL_REDISCOVER";
2127         case NETLOGON_CONTROL_TC_QUERY:
2128                 return "NETLOGON_CONTROL_TC_QUERY";
2129         case NETLOGON_CONTROL_TRANSPORT_NOTIFY:
2130                 return "NETLOGON_CONTROL_TRANSPORT_NOTIFY";
2131         case NETLOGON_CONTROL_FIND_USER:
2132                 return "NETLOGON_CONTROL_FIND_USER";
2133         case NETLOGON_CONTROL_CHANGE_PASSWORD:
2134                 return "NETLOGON_CONTROL_CHANGE_PASSWORD";
2135         case NETLOGON_CONTROL_TC_VERIFY:
2136                 return "NETLOGON_CONTROL_TC_VERIFY";
2137         case NETLOGON_CONTROL_FORCE_DNS_REG:
2138                 return "NETLOGON_CONTROL_FORCE_DNS_REG";
2139         case NETLOGON_CONTROL_QUERY_DNS_REG:
2140                 return "NETLOGON_CONTROL_QUERY_DNS_REG";
2141         case NETLOGON_CONTROL_BACKUP_CHANGE_LOG:
2142                 return "NETLOGON_CONTROL_BACKUP_CHANGE_LOG";
2143         case NETLOGON_CONTROL_TRUNCATE_LOG:
2144                 return "NETLOGON_CONTROL_TRUNCATE_LOG";
2145         case NETLOGON_CONTROL_SET_DBFLAG:
2146                 return "NETLOGON_CONTROL_SET_DBFLAG";
2147         case NETLOGON_CONTROL_BREAKPOINT:
2148                 return "NETLOGON_CONTROL_BREAKPOINT";
2149         default:
2150                 return talloc_asprintf(mem_ctx, "unknown function code: %d",
2151                                        function_code);
2152         }
2153 }
2154
2155
2156 /*
2157   try a netlogon LogonControl
2158 */
2159 static bool test_LogonControl(struct torture_context *tctx,
2160                               struct dcerpc_pipe *p,
2161                               struct cli_credentials *machine_credentials)
2162
2163 {
2164         NTSTATUS status;
2165         struct netr_LogonControl r;
2166         union netr_CONTROL_QUERY_INFORMATION query;
2167         int i,f;
2168         enum netr_SchannelType secure_channel_type = SEC_CHAN_NULL;
2169         struct dcerpc_binding_handle *b = p->binding_handle;
2170
2171         uint32_t function_codes[] = {
2172                 NETLOGON_CONTROL_QUERY,
2173                 NETLOGON_CONTROL_REPLICATE,
2174                 NETLOGON_CONTROL_SYNCHRONIZE,
2175                 NETLOGON_CONTROL_PDC_REPLICATE,
2176                 NETLOGON_CONTROL_REDISCOVER,
2177                 NETLOGON_CONTROL_TC_QUERY,
2178                 NETLOGON_CONTROL_TRANSPORT_NOTIFY,
2179                 NETLOGON_CONTROL_FIND_USER,
2180                 NETLOGON_CONTROL_CHANGE_PASSWORD,
2181                 NETLOGON_CONTROL_TC_VERIFY,
2182                 NETLOGON_CONTROL_FORCE_DNS_REG,
2183                 NETLOGON_CONTROL_QUERY_DNS_REG,
2184                 NETLOGON_CONTROL_BACKUP_CHANGE_LOG,
2185                 NETLOGON_CONTROL_TRUNCATE_LOG,
2186                 NETLOGON_CONTROL_SET_DBFLAG,
2187                 NETLOGON_CONTROL_BREAKPOINT
2188         };
2189
2190         if (machine_credentials) {
2191                 secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
2192         }
2193
2194         torture_comment(tctx, "Testing LogonControl with secure channel type: %d\n",
2195                 secure_channel_type);
2196
2197         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2198         r.in.function_code = 1;
2199         r.out.query = &query;
2200
2201         for (f=0;f<ARRAY_SIZE(function_codes); f++) {
2202         for (i=1;i<5;i++) {
2203
2204                 r.in.function_code = function_codes[f];
2205                 r.in.level = i;
2206
2207                 torture_comment(tctx, "Testing LogonControl function code %s (%d) level %d\n",
2208                                 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2209
2210                 status = dcerpc_netr_LogonControl_r(b, tctx, &r);
2211                 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
2212
2213                 switch (r.in.level) {
2214                 case 1:
2215                         switch (r.in.function_code) {
2216                         case NETLOGON_CONTROL_REPLICATE:
2217                         case NETLOGON_CONTROL_SYNCHRONIZE:
2218                         case NETLOGON_CONTROL_PDC_REPLICATE:
2219                         case NETLOGON_CONTROL_BREAKPOINT:
2220                         case NETLOGON_CONTROL_BACKUP_CHANGE_LOG:
2221                                 if ((secure_channel_type == SEC_CHAN_BDC) ||
2222                                     (secure_channel_type == SEC_CHAN_WKSTA)) {
2223                                         torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED,
2224                                                 "LogonControl returned unexpected error code");
2225                                 } else {
2226                                         torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
2227                                                 "LogonControl returned unexpected error code");
2228                                 }
2229                                 break;
2230
2231                         case NETLOGON_CONTROL_REDISCOVER:
2232                         case NETLOGON_CONTROL_TC_QUERY:
2233                         case NETLOGON_CONTROL_TRANSPORT_NOTIFY:
2234                         case NETLOGON_CONTROL_FIND_USER:
2235                         case NETLOGON_CONTROL_CHANGE_PASSWORD:
2236                         case NETLOGON_CONTROL_TC_VERIFY:
2237                         case NETLOGON_CONTROL_FORCE_DNS_REG:
2238                         case NETLOGON_CONTROL_QUERY_DNS_REG:
2239                         case NETLOGON_CONTROL_SET_DBFLAG:
2240                                 torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
2241                                         "LogonControl returned unexpected error code");
2242                                 break;
2243                         case NETLOGON_CONTROL_TRUNCATE_LOG:
2244                                 if ((secure_channel_type == SEC_CHAN_BDC) ||
2245                                     (secure_channel_type == SEC_CHAN_WKSTA)) {
2246                                         torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED,
2247                                                 "LogonControl returned unexpected error code");
2248                                 } else if (!W_ERROR_EQUAL(r.out.result, WERR_NOT_SUPPORTED)) {
2249                                         torture_assert_werr_ok(tctx, r.out.result,
2250                                                 "LogonControl returned unexpected result");
2251                                 }
2252                                 break;
2253                         default:
2254                                 torture_assert_werr_ok(tctx, r.out.result,
2255                                         "LogonControl returned unexpected result");
2256                                 break;
2257                         }
2258                         break;
2259                 case 2:
2260                         torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
2261                                 "LogonControl returned unexpected error code");
2262                         break;
2263                 default:
2264                         torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_LEVEL,
2265                                 "LogonControl returned unexpected error code");
2266                         break;
2267                 }
2268         }
2269         }
2270
2271         r.in.level = 52;
2272         torture_comment(tctx, "Testing LogonControl function code %s (%d) level %d\n",
2273                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2274         status = dcerpc_netr_LogonControl_r(b, tctx, &r);
2275         torture_assert_ntstatus_ok(tctx, status, "LogonControl");
2276         torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_LEVEL, "LogonControl");
2277
2278         return true;
2279 }
2280
2281
2282 /*
2283   try a netlogon GetAnyDCName
2284 */
2285 static bool test_GetAnyDCName(struct torture_context *tctx,
2286                               struct dcerpc_pipe *p)
2287 {
2288         NTSTATUS status;
2289         struct netr_GetAnyDCName r;
2290         const char *dcname = NULL;
2291         struct dcerpc_binding_handle *b = p->binding_handle;
2292
2293         r.in.domainname = lpcfg_workgroup(tctx->lp_ctx);
2294         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2295         r.out.dcname = &dcname;
2296
2297         status = dcerpc_netr_GetAnyDCName_r(b, tctx, &r);
2298         torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
2299         if ((!W_ERROR_IS_OK(r.out.result)) &&
2300             (!W_ERROR_EQUAL(r.out.result, WERR_NO_SUCH_DOMAIN))) {
2301                 return false;
2302         }
2303
2304         if (dcname) {
2305             torture_comment(tctx, "\tDC is at '%s'\n", dcname);
2306         }
2307
2308         r.in.domainname = NULL;
2309
2310         status = dcerpc_netr_GetAnyDCName_r(b, tctx, &r);
2311         torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
2312         if ((!W_ERROR_IS_OK(r.out.result)) &&
2313             (!W_ERROR_EQUAL(r.out.result, WERR_NO_SUCH_DOMAIN))) {
2314                 return false;
2315         }
2316
2317         r.in.domainname = "";
2318
2319         status = dcerpc_netr_GetAnyDCName_r(b, tctx, &r);
2320         torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
2321         if ((!W_ERROR_IS_OK(r.out.result)) &&
2322             (!W_ERROR_EQUAL(r.out.result, WERR_NO_SUCH_DOMAIN))) {
2323                 return false;
2324         }
2325
2326         return true;
2327 }
2328
2329
2330 /*
2331   try a netlogon LogonControl2
2332 */
2333 static bool test_LogonControl2(struct torture_context *tctx,
2334                                struct dcerpc_pipe *p,
2335                                struct cli_credentials *machine_credentials)
2336
2337 {
2338         NTSTATUS status;
2339         struct netr_LogonControl2 r;
2340         union netr_CONTROL_DATA_INFORMATION data;
2341         union netr_CONTROL_QUERY_INFORMATION query;
2342         enum netr_SchannelType secure_channel_type = SEC_CHAN_NULL;
2343         int i;
2344         struct dcerpc_binding_handle *b = p->binding_handle;
2345
2346         data.domain = lpcfg_workgroup(tctx->lp_ctx);
2347
2348         if (machine_credentials) {
2349                 secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
2350         }
2351
2352         torture_comment(tctx, "Testing LogonControl2 with secure channel type: %d\n",
2353                 secure_channel_type);
2354
2355         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2356
2357         r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
2358         r.in.data = &data;
2359         r.out.query = &query;
2360
2361         for (i=1;i<4;i++) {
2362                 r.in.level = i;
2363
2364                 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
2365                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2366
2367                 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
2368                 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
2369         }
2370
2371         data.domain = lpcfg_workgroup(tctx->lp_ctx);
2372
2373         r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
2374         r.in.data = &data;
2375
2376         for (i=1;i<4;i++) {
2377                 r.in.level = i;
2378
2379                 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
2380                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2381
2382                 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
2383                 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
2384         }
2385
2386         data.domain = lpcfg_workgroup(tctx->lp_ctx);
2387
2388         r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
2389         r.in.data = &data;
2390
2391         for (i=1;i<4;i++) {
2392                 r.in.level = i;
2393
2394                 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
2395                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2396
2397                 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
2398                 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
2399         }
2400
2401         data.debug_level = ~0;
2402
2403         r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
2404         r.in.data = &data;
2405
2406         for (i=1;i<4;i++) {
2407                 r.in.level = i;
2408
2409                 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
2410                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2411
2412                 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
2413                 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
2414         }
2415
2416         ZERO_STRUCT(data);
2417         r.in.function_code = 52;
2418         r.in.data = &data;
2419
2420         torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
2421                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2422
2423         status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
2424         torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
2425         switch (secure_channel_type) {
2426         case SEC_CHAN_NULL:
2427                 torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED, "LogonControl2");
2428                 break;
2429         default:
2430                 torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED, "LogonControl2");
2431                 break;
2432         }
2433         data.debug_level = ~0;
2434
2435         r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
2436         r.in.data = &data;
2437
2438         r.in.level = 52;
2439         torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
2440                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2441
2442         status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
2443         torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
2444         torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_LEVEL, "LogonControl2");
2445
2446         return true;
2447 }
2448
2449 /*
2450   try a netlogon DatabaseSync2
2451 */
2452 static bool test_DatabaseSync2(struct torture_context *tctx,
2453                                struct dcerpc_pipe *p,
2454                                struct cli_credentials *machine_credentials)
2455 {
2456         struct netr_DatabaseSync2 r;
2457         struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
2458         struct netr_Authenticator return_authenticator, credential;
2459
2460         struct netlogon_creds_CredentialState *creds;
2461         const uint32_t database_ids[] = {0, 1, 2};
2462         int i;
2463         struct dcerpc_binding_handle *b = p->binding_handle;
2464
2465         if (!test_SetupCredentials2(p, tctx, NETLOGON_NEG_AUTH2_FLAGS,
2466                                     machine_credentials,
2467                                     cli_credentials_get_secure_channel_type(machine_credentials),
2468                                     &creds)) {
2469                 return false;
2470         }
2471
2472         ZERO_STRUCT(return_authenticator);
2473
2474         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2475         r.in.computername = TEST_MACHINE_NAME;
2476         r.in.preferredmaximumlength = (uint32_t)-1;
2477         r.in.return_authenticator = &return_authenticator;
2478         r.out.return_authenticator = &return_authenticator;
2479         r.out.delta_enum_array = &delta_enum_array;
2480
2481         for (i=0;i<ARRAY_SIZE(database_ids);i++) {
2482
2483                 uint32_t sync_context = 0;
2484
2485                 r.in.database_id = database_ids[i];
2486                 r.in.sync_context = &sync_context;
2487                 r.out.sync_context = &sync_context;
2488                 r.in.restart_state = 0;
2489
2490                 torture_comment(tctx, "Testing DatabaseSync2 of id %d\n", r.in.database_id);
2491
2492                 do {
2493                         netlogon_creds_client_authenticator(creds, &credential);
2494
2495                         r.in.credential = &credential;
2496
2497                         torture_assert_ntstatus_ok(tctx, dcerpc_netr_DatabaseSync2_r(b, tctx, &r),
2498                                 "DatabaseSync2 failed");
2499                         if (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES))
2500                             break;
2501
2502                         /* Native mode servers don't do this */
2503                         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_SUPPORTED)) {
2504                                 return true;
2505                         }
2506
2507                         torture_assert_ntstatus_ok(tctx, r.out.result, "DatabaseSync2");
2508
2509                         if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
2510                                 torture_comment(tctx, "Credential chaining failed\n");
2511                         }
2512
2513                 } while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES));
2514         }
2515
2516         return true;
2517 }
2518
2519
2520 /*
2521   try a netlogon LogonControl2Ex
2522 */
2523 static bool test_LogonControl2Ex(struct torture_context *tctx,
2524                                  struct dcerpc_pipe *p,
2525                                  struct cli_credentials *machine_credentials)
2526
2527 {
2528         NTSTATUS status;
2529         struct netr_LogonControl2Ex r;
2530         union netr_CONTROL_DATA_INFORMATION data;
2531         union netr_CONTROL_QUERY_INFORMATION query;
2532         enum netr_SchannelType secure_channel_type = SEC_CHAN_NULL;
2533         int i;
2534         struct dcerpc_binding_handle *b = p->binding_handle;
2535
2536         data.domain = lpcfg_workgroup(tctx->lp_ctx);
2537
2538         if (machine_credentials) {
2539                 secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
2540         }
2541
2542         torture_comment(tctx, "Testing LogonControl2Ex with secure channel type: %d\n",
2543                 secure_channel_type);
2544
2545         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2546
2547         r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
2548         r.in.data = &data;
2549         r.out.query = &query;
2550
2551         for (i=1;i<4;i++) {
2552                 r.in.level = i;
2553
2554                 torture_comment(tctx, "Testing LogonControl2Ex function code %s (%d) level %d\n",
2555                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2556
2557                 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
2558                 torture_assert_ntstatus_ok(tctx, status, "LogonControl2Ex");
2559         }
2560
2561         data.domain = lpcfg_workgroup(tctx->lp_ctx);
2562
2563         r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
2564         r.in.data = &data;
2565
2566         for (i=1;i<4;i++) {
2567                 r.in.level = i;
2568
2569                 torture_comment(tctx, "Testing LogonControl2Ex function code %s (%d) level %d\n",
2570                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2571
2572                 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
2573                 torture_assert_ntstatus_ok(tctx, status, "LogonControl2Ex");
2574         }
2575
2576         data.domain = lpcfg_workgroup(tctx->lp_ctx);
2577
2578         r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
2579         r.in.data = &data;
2580
2581         for (i=1;i<4;i++) {
2582                 r.in.level = i;
2583
2584                 torture_comment(tctx, "Testing LogonControl2Ex function code %s (%d) level %d\n",
2585                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2586
2587                 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
2588                 torture_assert_ntstatus_ok(tctx, status, "LogonControl2Ex");
2589         }
2590
2591         data.debug_level = ~0;
2592
2593         r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
2594         r.in.data = &data;
2595
2596         for (i=1;i<4;i++) {
2597                 r.in.level = i;
2598
2599                 torture_comment(tctx, "Testing LogonControl2Ex function code %s (%d) level %d\n",
2600                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2601
2602                 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
2603                 torture_assert_ntstatus_ok(tctx, status, "LogonControl2Ex");
2604         }
2605
2606         ZERO_STRUCT(data);
2607         r.in.function_code = 52;
2608         r.in.data = &data;
2609
2610         torture_comment(tctx, "Testing LogonControl2Ex function code %s (%d) level %d\n",
2611                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2612
2613         status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
2614         torture_assert_ntstatus_ok(tctx, status, "LogonControl2Ex");
2615         switch (secure_channel_type) {
2616         case SEC_CHAN_NULL:
2617                 torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED, "LogonControl2Ex");
2618                 break;
2619         default:
2620                 torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED, "LogonControl2Ex");
2621                 break;
2622         }
2623         data.debug_level = ~0;
2624
2625         r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
2626         r.in.data = &data;
2627
2628         r.in.level = 52;
2629         torture_comment(tctx, "Testing LogonControl2Ex function code %s (%d) level %d\n",
2630                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2631
2632         status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
2633         torture_assert_ntstatus_ok(tctx, status, "LogonControl2Ex");
2634         torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_LEVEL, "LogonControl2Ex");
2635
2636         return true;
2637 }
2638
2639 static bool test_netr_GetForestTrustInformation(struct torture_context *tctx,
2640                                                 struct dcerpc_pipe *p1,
2641                                                 struct cli_credentials *machine_credentials)
2642 {
2643         struct netr_GetForestTrustInformation r;
2644         struct netlogon_creds_CredentialState *creds;
2645         struct netr_Authenticator a;
2646         struct netr_Authenticator return_authenticator;
2647         struct lsa_ForestTrustInformation *forest_trust_info;
2648         struct dcerpc_pipe *p = NULL;
2649         struct dcerpc_binding_handle *b = NULL;
2650
2651         if (!test_SetupCredentials3(p1, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
2652                                     machine_credentials, &creds)) {
2653                 return false;
2654         }
2655         if (!test_SetupCredentialsPipe(p1, tctx, machine_credentials, creds,
2656                                        DCERPC_SIGN | DCERPC_SEAL, &p)) {
2657                 return false;
2658         }
2659         b = p->binding_handle;
2660
2661         netlogon_creds_client_authenticator(creds, &a);
2662
2663         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2664         r.in.computer_name = TEST_MACHINE_NAME;
2665         r.in.credential = &a;
2666         r.in.flags = 0;
2667         r.out.return_authenticator = &return_authenticator;
2668         r.out.forest_trust_info = &forest_trust_info;
2669
2670         torture_assert_ntstatus_ok(tctx,
2671                 dcerpc_netr_GetForestTrustInformation_r(b, tctx, &r),
2672                 "netr_GetForestTrustInformation failed");
2673         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_IMPLEMENTED)) {
2674                 torture_comment(tctx, "not considering NT_STATUS_NOT_IMPLEMENTED as an error\n");
2675         } else {
2676                 torture_assert_ntstatus_ok(tctx, r.out.result,
2677                         "netr_GetForestTrustInformation failed");
2678         }
2679
2680         torture_assert(tctx,
2681                 netlogon_creds_client_check(creds, &return_authenticator.cred),
2682                 "Credential chaining failed");
2683
2684         return true;
2685 }
2686
2687 static bool test_netr_DsRGetForestTrustInformation(struct torture_context *tctx,
2688                                                    struct dcerpc_pipe *p, const char *trusted_domain_name)
2689 {
2690         NTSTATUS status;
2691         struct netr_DsRGetForestTrustInformation r;
2692         struct lsa_ForestTrustInformation info, *info_ptr;
2693         struct dcerpc_binding_handle *b = p->binding_handle;
2694
2695         info_ptr = &info;
2696
2697         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2698         r.in.trusted_domain_name = trusted_domain_name;
2699         r.in.flags = 0;
2700         r.out.forest_trust_info = &info_ptr;
2701
2702         torture_comment(tctx ,"Testing netr_DsRGetForestTrustInformation\n");
2703
2704         status = dcerpc_netr_DsRGetForestTrustInformation_r(b, tctx, &r);
2705         torture_assert_ntstatus_ok(tctx, status, "DsRGetForestTrustInformation");
2706         torture_assert_werr_ok(tctx, r.out.result, "DsRGetForestTrustInformation");
2707
2708         return true;
2709 }
2710
2711 /*
2712   try a netlogon netr_DsrEnumerateDomainTrusts
2713 */
2714 static bool test_DsrEnumerateDomainTrusts(struct torture_context *tctx,
2715                                           struct dcerpc_pipe *p)
2716 {
2717         NTSTATUS status;
2718         struct netr_DsrEnumerateDomainTrusts r;
2719         struct netr_DomainTrustList trusts;
2720         int i;
2721         struct dcerpc_binding_handle *b = p->binding_handle;
2722
2723         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2724         r.in.trust_flags = 0x3f;
2725         r.out.trusts = &trusts;
2726
2727         status = dcerpc_netr_DsrEnumerateDomainTrusts_r(b, tctx, &r);
2728         torture_assert_ntstatus_ok(tctx, status, "DsrEnumerateDomaintrusts");
2729         torture_assert_werr_ok(tctx, r.out.result, "DsrEnumerateDomaintrusts");
2730
2731         /* when trusted_domain_name is NULL, netr_DsRGetForestTrustInformation
2732          * will show non-forest trusts and all UPN suffixes of the own forest
2733          * as LSA_FOREST_TRUST_TOP_LEVEL_NAME types */
2734
2735         if (r.out.trusts->count) {
2736                 if (!test_netr_DsRGetForestTrustInformation(tctx, p, NULL)) {
2737                         return false;
2738                 }
2739         }
2740
2741         for (i=0; i<r.out.trusts->count; i++) {
2742
2743                 /* get info for transitive forest trusts */
2744
2745                 if (r.out.trusts->array[i].trust_attributes & LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) {
2746                         if (!test_netr_DsRGetForestTrustInformation(tctx, p,
2747                                                                     r.out.trusts->array[i].dns_name)) {
2748                                 return false;
2749                         }
2750                 }
2751         }
2752
2753         return true;
2754 }
2755
2756 static bool test_netr_NetrEnumerateTrustedDomains(struct torture_context *tctx,
2757                                                   struct dcerpc_pipe *p)
2758 {
2759         NTSTATUS status;
2760         struct netr_NetrEnumerateTrustedDomains r;
2761         struct netr_Blob trusted_domains_blob;
2762         struct dcerpc_binding_handle *b = p->binding_handle;
2763
2764         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2765         r.out.trusted_domains_blob = &trusted_domains_blob;
2766
2767         status = dcerpc_netr_NetrEnumerateTrustedDomains_r(b, tctx, &r);
2768         torture_assert_ntstatus_ok(tctx, status, "netr_NetrEnumerateTrustedDomains");
2769         torture_assert_ntstatus_ok(tctx, r.out.result, "NetrEnumerateTrustedDomains");
2770
2771         return true;
2772 }
2773
2774 static bool test_netr_NetrEnumerateTrustedDomainsEx(struct torture_context *tctx,
2775                                                     struct dcerpc_pipe *p)
2776 {
2777         NTSTATUS status;
2778         struct netr_NetrEnumerateTrustedDomainsEx r;
2779         struct netr_DomainTrustList dom_trust_list;
2780         struct dcerpc_binding_handle *b = p->binding_handle;
2781
2782         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2783         r.out.dom_trust_list = &dom_trust_list;
2784
2785         status = dcerpc_netr_NetrEnumerateTrustedDomainsEx_r(b, tctx, &r);
2786         torture_assert_ntstatus_ok(tctx, status, "netr_NetrEnumerateTrustedDomainsEx");
2787         torture_assert_werr_ok(tctx, r.out.result, "NetrEnumerateTrustedDomainsEx");
2788
2789         return true;
2790 }
2791
2792
2793 static bool test_netr_DsRGetSiteName(struct dcerpc_pipe *p, struct torture_context *tctx,
2794                                      const char *computer_name,
2795                                      const char *expected_site)
2796 {
2797         NTSTATUS status;
2798         struct netr_DsRGetSiteName r;
2799         const char *site = NULL;
2800         struct dcerpc_binding_handle *b = p->binding_handle;
2801
2802         r.in.computer_name              = computer_name;
2803         r.out.site                      = &site;
2804         torture_comment(tctx, "Testing netr_DsRGetSiteName\n");
2805
2806         status = dcerpc_netr_DsRGetSiteName_r(b, tctx, &r);
2807         torture_assert_ntstatus_ok(tctx, status, "DsRGetSiteName");
2808         torture_assert_werr_ok(tctx, r.out.result, "DsRGetSiteName");
2809         torture_assert_str_equal(tctx, expected_site, site, "netr_DsRGetSiteName");
2810
2811         return true;
2812 }
2813
2814 /*
2815   try a netlogon netr_DsRGetDCName
2816 */
2817 static bool test_netr_DsRGetDCName(struct torture_context *tctx,
2818                                    struct dcerpc_pipe *p)
2819 {
2820         NTSTATUS status;
2821         struct netr_DsRGetDCName r;
2822         struct netr_DsRGetDCNameInfo *info = NULL;
2823         struct dcerpc_binding_handle *b = p->binding_handle;
2824
2825         r.in.server_unc         = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2826         r.in.domain_name        = lpcfg_dnsdomain(tctx->lp_ctx);
2827         r.in.domain_guid        = NULL;
2828         r.in.site_guid          = NULL;
2829         r.in.flags              = DS_RETURN_DNS_NAME;
2830         r.out.info              = &info;
2831
2832         status = dcerpc_netr_DsRGetDCName_r(b, tctx, &r);
2833         torture_assert_ntstatus_ok(tctx, status, "DsRGetDCName");
2834         torture_assert_werr_ok(tctx, r.out.result, "DsRGetDCName");
2835
2836         torture_assert_int_equal(tctx,
2837                                  (info->dc_flags & (DS_DNS_CONTROLLER)),
2838                                  DS_DNS_CONTROLLER,
2839                                  "DsRGetDCName");
2840         torture_assert_int_equal(tctx,
2841                                  (info->dc_flags & (DS_DNS_DOMAIN)),
2842                                  DS_DNS_DOMAIN,
2843                                  "DsRGetDCName");
2844         torture_assert_int_equal(tctx,
2845                                  (info->dc_flags & (DS_DNS_FOREST_ROOT)),
2846                                  DS_DNS_FOREST_ROOT,
2847                                  "DsRGetDCName");
2848
2849         r.in.domain_name        = lpcfg_workgroup(tctx->lp_ctx);
2850         r.in.flags              = 0;
2851
2852         status = dcerpc_netr_DsRGetDCName_r(b, tctx, &r);
2853         torture_assert_ntstatus_ok(tctx, status, "DsRGetDCName");
2854         torture_assert_werr_ok(tctx, r.out.result, "DsRGetDCName");
2855
2856         torture_assert_int_equal(tctx,
2857                                  (info->dc_flags & (DS_DNS_CONTROLLER)), 0,
2858                                  "DsRGetDCName");
2859         torture_assert_int_equal(tctx,
2860                                  (info->dc_flags & (DS_DNS_DOMAIN)), 0,
2861                                  "DsRGetDCName");
2862         torture_assert_int_equal(tctx,
2863                                  (info->dc_flags & (DS_DNS_FOREST_ROOT)),
2864                                  DS_DNS_FOREST_ROOT,
2865                                  "DsRGetDCName");
2866
2867         if (strcasecmp(info->dc_site_name, info->client_site_name) == 0) {
2868                 torture_assert_int_equal(tctx,
2869                                          (info->dc_flags & (DS_SERVER_CLOSEST)),
2870                                          DS_SERVER_CLOSEST,
2871                                          "DsRGetDCName");
2872         }
2873
2874         return test_netr_DsRGetSiteName(p, tctx,
2875                                        info->dc_unc,
2876                                        info->dc_site_name);
2877 }
2878
2879 /*
2880   try a netlogon netr_DsRGetDCNameEx
2881 */
2882 static bool test_netr_DsRGetDCNameEx(struct torture_context *tctx,
2883                                      struct dcerpc_pipe *p)
2884 {
2885         NTSTATUS status;
2886         struct netr_DsRGetDCNameEx r;
2887         struct netr_DsRGetDCNameInfo *info = NULL;
2888         struct dcerpc_binding_handle *b = p->binding_handle;
2889
2890         r.in.server_unc         = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2891         r.in.domain_name        = lpcfg_dnsdomain(tctx->lp_ctx);
2892         r.in.domain_guid        = NULL;
2893         r.in.site_name          = NULL;
2894         r.in.flags              = DS_RETURN_DNS_NAME;
2895         r.out.info              = &info;
2896
2897         status = dcerpc_netr_DsRGetDCNameEx_r(b, tctx, &r);
2898         torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx");
2899         torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx");
2900
2901         torture_assert_int_equal(tctx,
2902                                  (info->dc_flags & (DS_DNS_CONTROLLER)),
2903                                  DS_DNS_CONTROLLER,
2904                                  "DsRGetDCNameEx");
2905         torture_assert_int_equal(tctx,
2906                                  (info->dc_flags & (DS_DNS_DOMAIN)),
2907                                  DS_DNS_DOMAIN,
2908                                  "DsRGetDCNameEx");
2909         torture_assert_int_equal(tctx,
2910                                  (info->dc_flags & (DS_DNS_FOREST_ROOT)),
2911                                  DS_DNS_FOREST_ROOT,
2912                                  "DsRGetDCNameEx");
2913
2914         r.in.domain_name        = lpcfg_workgroup(tctx->lp_ctx);
2915         r.in.flags              = 0;
2916
2917         status = dcerpc_netr_DsRGetDCNameEx_r(b, tctx, &r);
2918         torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx");
2919         torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx");
2920
2921         torture_assert_int_equal(tctx,
2922                                  (info->dc_flags & (DS_DNS_CONTROLLER)), 0,
2923                                  "DsRGetDCNameEx");
2924         torture_assert_int_equal(tctx,
2925                                  (info->dc_flags & (DS_DNS_DOMAIN)), 0,
2926                                  "DsRGetDCNameEx");
2927         torture_assert_int_equal(tctx,
2928                                  (info->dc_flags & (DS_DNS_FOREST_ROOT)),
2929                                  DS_DNS_FOREST_ROOT,
2930                                  "DsRGetDCNameEx");
2931
2932         if (strcasecmp(info->dc_site_name, info->client_site_name) == 0) {
2933                 torture_assert_int_equal(tctx,
2934                                          (info->dc_flags & (DS_SERVER_CLOSEST)),
2935                                          DS_SERVER_CLOSEST,
2936                                          "DsRGetDCNameEx");
2937         }
2938
2939         return test_netr_DsRGetSiteName(p, tctx, info->dc_unc,
2940                                         info->dc_site_name);
2941 }
2942
2943 /*
2944   try a netlogon netr_DsRGetDCNameEx2
2945 */
2946 static bool test_netr_DsRGetDCNameEx2(struct torture_context *tctx,
2947                                       struct dcerpc_pipe *p)
2948 {
2949         NTSTATUS status;
2950         struct netr_DsRGetDCNameEx2 r;
2951         struct netr_DsRGetDCNameInfo *info = NULL;
2952         struct dcerpc_binding_handle *b = p->binding_handle;
2953
2954         torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 with no inputs\n");
2955         ZERO_STRUCT(r.in);
2956         r.in.flags              = DS_RETURN_DNS_NAME;
2957         r.out.info              = &info;
2958
2959         status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
2960         torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
2961         torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
2962
2963         torture_assert_int_equal(tctx,
2964                                  (info->dc_flags & (DS_DNS_CONTROLLER)),
2965                                  DS_DNS_CONTROLLER,
2966                                  "DsRGetDCNameEx2");
2967         torture_assert_int_equal(tctx,
2968                                  (info->dc_flags & (DS_DNS_DOMAIN)),
2969                                  DS_DNS_DOMAIN,
2970                                  "DsRGetDCNameEx2");
2971         torture_assert_int_equal(tctx,
2972                                  (info->dc_flags & (DS_DNS_FOREST_ROOT)),
2973                                  DS_DNS_FOREST_ROOT,
2974                                  "DsRGetDCNameEx2");
2975
2976         r.in.server_unc         = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2977         r.in.client_account     = NULL;
2978         r.in.mask               = 0x00000000;
2979         r.in.domain_name        = lpcfg_dnsdomain(tctx->lp_ctx);
2980         r.in.domain_guid        = NULL;
2981         r.in.site_name          = NULL;
2982         r.in.flags              = DS_RETURN_DNS_NAME;
2983         r.out.info              = &info;
2984
2985         torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 without client account\n");
2986
2987         status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
2988         torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
2989         torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
2990
2991         r.in.domain_name        = lpcfg_workgroup(tctx->lp_ctx);
2992         r.in.flags              = 0;
2993
2994         status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
2995         torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
2996         torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
2997
2998         torture_assert_int_equal(tctx,
2999                                  (info->dc_flags & (DS_DNS_CONTROLLER)), 0,
3000                                  "DsRGetDCNameEx2");
3001         torture_assert_int_equal(tctx,
3002                                  (info->dc_flags & (DS_DNS_DOMAIN)), 0,
3003                                  "DsRGetDCNameEx2");
3004         torture_assert_int_equal(tctx,
3005                                  (info->dc_flags & (DS_DNS_FOREST_ROOT)),
3006                                  DS_DNS_FOREST_ROOT,
3007                                  "DsRGetDCNameEx2");
3008
3009         if (strcasecmp(info->dc_site_name, info->client_site_name) == 0) {
3010                 torture_assert_int_equal(tctx,
3011                                          (info->dc_flags & (DS_SERVER_CLOSEST)),
3012                                          DS_SERVER_CLOSEST,
3013                                          "DsRGetDCNameEx2");
3014         }
3015
3016         torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 with client account\n");
3017         r.in.client_account     = TEST_MACHINE_NAME"$";
3018         r.in.mask               = ACB_SVRTRUST;
3019         r.in.flags              = DS_RETURN_FLAT_NAME;
3020         r.out.info              = &info;
3021
3022         status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
3023         torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
3024         torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
3025
3026         return test_netr_DsRGetSiteName(p, tctx, info->dc_unc,
3027                                         info->dc_site_name);
3028 }
3029
3030 /* This is a substitution for "samdb_server_site_name" which relies on the
3031  * correct "lp_ctx" and therefore can't be used here. */
3032 static const char *server_site_name(struct torture_context *tctx,
3033                                     struct ldb_context *ldb)
3034 {
3035         TALLOC_CTX *tmp_ctx;
3036         struct ldb_dn *dn, *server_dn;
3037         const struct ldb_val *site_name_val;
3038         const char *server_dn_str, *site_name;
3039
3040         tmp_ctx = talloc_new(ldb);
3041         if (tmp_ctx == NULL) {
3042                 goto failed;
3043         }
3044
3045         dn = ldb_dn_new(tmp_ctx, ldb, "");
3046         if (dn == NULL) {
3047                 goto failed;
3048         }
3049
3050         server_dn_str = samdb_search_string(ldb, tmp_ctx, dn, "serverName",
3051                                             NULL);
3052         if (server_dn_str == NULL) {
3053                 goto failed;
3054         }
3055
3056         server_dn = ldb_dn_new(tmp_ctx, ldb, server_dn_str);
3057         if (server_dn == NULL) {
3058                 goto failed;
3059         }
3060
3061         /* CN=<Server name>, CN=Servers, CN=<Site name>, CN=Sites, ... */
3062         site_name_val = ldb_dn_get_component_val(server_dn, 2);
3063         if (site_name_val == NULL) {
3064                 goto failed;
3065         }
3066
3067         site_name = (const char *) site_name_val->data;
3068
3069         talloc_steal(tctx, site_name);
3070         talloc_free(tmp_ctx);
3071
3072         return site_name;
3073
3074 failed:
3075         talloc_free(tmp_ctx);
3076         return NULL;
3077 }
3078
3079 static bool test_netr_DsrGetDcSiteCoverageW(struct torture_context *tctx,
3080                                             struct dcerpc_pipe *p)
3081 {
3082         char *url;
3083         struct ldb_context *sam_ctx = NULL;
3084         NTSTATUS status;
3085         struct netr_DsrGetDcSiteCoverageW r;
3086         struct DcSitesCtr *ctr = NULL;
3087         struct dcerpc_binding_handle *b = p->binding_handle;
3088
3089         torture_comment(tctx, "This does only pass with the default site\n");
3090
3091         /* We won't double-check this when we are over 'local' transports */
3092         if (dcerpc_server_name(p)) {
3093                 /* Set up connection to SAMDB on DC */
3094                 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
3095                 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
3096                                            NULL,
3097                                            cmdline_credentials,
3098                                            0);
3099
3100                 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
3101         }
3102
3103         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3104         r.out.ctr = &ctr;
3105
3106         status = dcerpc_netr_DsrGetDcSiteCoverageW_r(b, tctx, &r);
3107         torture_assert_ntstatus_ok(tctx, status, "failed");
3108         torture_assert_werr_ok(tctx, r.out.result, "failed");
3109
3110         torture_assert(tctx, ctr->num_sites == 1,
3111                        "we should per default only get the default site");
3112         if (sam_ctx != NULL) {
3113                 torture_assert_casestr_equal(tctx, ctr->sites[0].string,
3114                                              server_site_name(tctx, sam_ctx),
3115                                              "didn't return default site");
3116         }
3117
3118         return true;
3119 }
3120
3121 static bool test_netr_DsRAddressToSitenamesW(struct torture_context *tctx,
3122                                              struct dcerpc_pipe *p)
3123 {
3124         char *url;
3125         struct ldb_context *sam_ctx = NULL;
3126         NTSTATUS status;
3127         struct netr_DsRAddressToSitenamesW r;
3128         struct netr_DsRAddress addrs[6];
3129         struct sockaddr_in *addr;
3130 #ifdef HAVE_IPV6
3131         struct sockaddr_in6 *addr6;
3132 #endif
3133         struct netr_DsRAddressToSitenamesWCtr *ctr;
3134         struct dcerpc_binding_handle *b = p->binding_handle;
3135         uint32_t i;
3136         int ret;
3137
3138         torture_comment(tctx, "This does only pass with the default site\n");
3139
3140         /* We won't double-check this when we are over 'local' transports */
3141         if (dcerpc_server_name(p)) {
3142                 /* Set up connection to SAMDB on DC */
3143                 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
3144                 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
3145                                            NULL,
3146                                            cmdline_credentials,
3147                                            0);
3148
3149                 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
3150         }
3151
3152         /* First try valid IP addresses */
3153
3154         addrs[0].size = sizeof(struct sockaddr_in);
3155         addrs[0].buffer = talloc_zero_array(tctx, uint8_t, addrs[0].size);
3156         addr = (struct sockaddr_in *) addrs[0].buffer;
3157         addrs[0].buffer[0] = AF_INET;
3158         ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
3159         torture_assert(tctx, ret > 0, "inet_pton failed");
3160
3161         addrs[1].size = sizeof(struct sockaddr_in);
3162         addrs[1].buffer = talloc_zero_array(tctx, uint8_t, addrs[1].size);
3163         addr = (struct sockaddr_in *) addrs[1].buffer;
3164         addrs[1].buffer[0] = AF_INET;
3165         ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
3166         torture_assert(tctx, ret > 0, "inet_pton failed");
3167
3168         addrs[2].size = sizeof(struct sockaddr_in);
3169         addrs[2].buffer = talloc_zero_array(tctx, uint8_t, addrs[2].size);
3170         addr = (struct sockaddr_in *) addrs[2].buffer;
3171         addrs[2].buffer[0] = AF_INET;
3172         ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
3173         torture_assert(tctx, ret > 0, "inet_pton failed");
3174
3175 #ifdef HAVE_IPV6
3176         addrs[3].size = sizeof(struct sockaddr_in6);
3177         addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
3178         addr6 = (struct sockaddr_in6 *) addrs[3].buffer;
3179         addrs[3].buffer[0] = AF_INET6;
3180         ret = inet_pton(AF_INET6, "::1", &addr6->sin6_addr);
3181         torture_assert(tctx, ret > 0, "inet_pton failed");
3182
3183         addrs[4].size = sizeof(struct sockaddr_in6);
3184         addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
3185         addr6 = (struct sockaddr_in6 *) addrs[4].buffer;
3186         addrs[4].buffer[0] = AF_INET6;
3187         ret = inet_pton(AF_INET6, "::", &addr6->sin6_addr);
3188         torture_assert(tctx, ret > 0, "inet_pton failed");
3189
3190         addrs[5].size = sizeof(struct sockaddr_in6);
3191         addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
3192         addr6 = (struct sockaddr_in6 *) addrs[5].buffer;
3193         addrs[5].buffer[0] = AF_INET6;
3194         ret = inet_pton(AF_INET6, "ff02::1", &addr6->sin6_addr);
3195         torture_assert(tctx, ret > 0, "inet_pton failed");
3196 #else
3197         /* the test cases are repeated to have exactly 6. This is for
3198          * compatibility with IPv4-only machines */
3199         addrs[3].size = sizeof(struct sockaddr_in);
3200         addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
3201         addr = (struct sockaddr_in *) addrs[3].buffer;
3202         addrs[3].buffer[0] = AF_INET;
3203         ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
3204         torture_assert(tctx, ret > 0, "inet_pton failed");
3205
3206         addrs[4].size = sizeof(struct sockaddr_in);
3207         addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
3208         addr = (struct sockaddr_in *) addrs[4].buffer;
3209         addrs[4].buffer[0] = AF_INET;
3210         ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
3211         torture_assert(tctx, ret > 0, "inet_pton failed");
3212
3213         addrs[5].size = sizeof(struct sockaddr_in);
3214         addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
3215         addr = (struct sockaddr_in *) addrs[5].buffer;
3216         addrs[5].buffer[0] = AF_INET;
3217         ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
3218         torture_assert(tctx, ret > 0, "inet_pton failed");
3219 #endif
3220
3221         ctr = talloc(tctx, struct netr_DsRAddressToSitenamesWCtr);
3222
3223         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3224         r.in.count = 6;
3225         r.in.addresses = addrs;
3226         r.out.ctr = &ctr;
3227
3228         status = dcerpc_netr_DsRAddressToSitenamesW_r(b, tctx, &r);
3229         torture_assert_ntstatus_ok(tctx, status, "failed");
3230         torture_assert_werr_ok(tctx, r.out.result, "failed");
3231
3232         if (sam_ctx != NULL) {
3233                 for (i = 0; i < 3; i++) {
3234                         torture_assert_casestr_equal(tctx,
3235                                                      ctr->sitename[i].string,
3236                                                      server_site_name(tctx, sam_ctx),
3237                                                      "didn't return default site");
3238                 }
3239                 for (i = 3; i < 6; i++) {
3240                         /* Windows returns "NULL" for the sitename if it isn't
3241                          * IPv6 configured */
3242                         if (torture_setting_bool(tctx, "samba4", false)) {
3243                                 torture_assert_casestr_equal(tctx,
3244                                                              ctr->sitename[i].string,
3245                                                              server_site_name(tctx, sam_ctx),
3246                                                              "didn't return default site");
3247                         }
3248                 }
3249         }
3250
3251         /* Now try invalid ones (too short buffers) */
3252
3253         addrs[0].size = 0;
3254         addrs[1].size = 1;
3255         addrs[2].size = 4;
3256
3257         addrs[3].size = 0;
3258         addrs[4].size = 1;
3259         addrs[5].size = 4;
3260
3261         status = dcerpc_netr_DsRAddressToSitenamesW_r(b, tctx, &r);
3262         torture_assert_ntstatus_ok(tctx, status, "failed");
3263         torture_assert_werr_ok(tctx, r.out.result, "failed");
3264
3265         for (i = 0; i < 6; i++) {
3266                 torture_assert(tctx, ctr->sitename[i].string == NULL,
3267                                "sitename should be null");
3268         }
3269
3270         /* Now try invalid ones (wrong address types) */
3271
3272         addrs[0].size = 10;
3273         addrs[0].buffer[0] = AF_UNSPEC;
3274         addrs[1].size = 10;
3275         addrs[1].buffer[0] = AF_UNIX; /* AF_LOCAL = AF_UNIX */
3276         addrs[2].size = 10;
3277         addrs[2].buffer[0] = AF_UNIX;
3278
3279         addrs[3].size = 10;
3280         addrs[3].buffer[0] = 250;
3281         addrs[4].size = 10;
3282         addrs[4].buffer[0] = 251;
3283         addrs[5].size = 10;
3284         addrs[5].buffer[0] = 252;
3285
3286         status = dcerpc_netr_DsRAddressToSitenamesW_r(b, tctx, &r);
3287         torture_assert_ntstatus_ok(tctx, status, "failed");
3288         torture_assert_werr_ok(tctx, r.out.result, "failed");
3289
3290         for (i = 0; i < 6; i++) {
3291                 torture_assert(tctx, ctr->sitename[i].string == NULL,
3292                                "sitename should be null");
3293         }
3294
3295         return true;
3296 }
3297
3298 static bool test_netr_DsRAddressToSitenamesExW(struct torture_context *tctx,
3299                                                struct dcerpc_pipe *p)
3300 {
3301         char *url;
3302         struct ldb_context *sam_ctx = NULL;
3303         NTSTATUS status;
3304         struct netr_DsRAddressToSitenamesExW r;
3305         struct netr_DsRAddress addrs[6];
3306         struct sockaddr_in *addr;
3307 #ifdef HAVE_IPV6
3308         struct sockaddr_in6 *addr6;
3309 #endif
3310         struct netr_DsRAddressToSitenamesExWCtr *ctr;
3311         struct dcerpc_binding_handle *b = p->binding_handle;
3312         uint32_t i;
3313         int ret;
3314
3315         torture_comment(tctx, "This does pass with the default site\n");
3316
3317         /* We won't double-check this when we are over 'local' transports */
3318         if (dcerpc_server_name(p)) {
3319                 /* Set up connection to SAMDB on DC */
3320                 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
3321                 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
3322                                            NULL,
3323                                            cmdline_credentials,
3324                                            0);
3325
3326                 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
3327         }
3328
3329         /* First try valid IP addresses */
3330
3331         addrs[0].size = sizeof(struct sockaddr_in);
3332         addrs[0].buffer = talloc_zero_array(tctx, uint8_t, addrs[0].size);
3333         addr = (struct sockaddr_in *) addrs[0].buffer;
3334         addrs[0].buffer[0] = AF_INET;
3335         ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
3336         torture_assert(tctx, ret > 0, "inet_pton failed");
3337
3338         addrs[1].size = sizeof(struct sockaddr_in);
3339         addrs[1].buffer = talloc_zero_array(tctx, uint8_t, addrs[1].size);
3340         addr = (struct sockaddr_in *) addrs[1].buffer;
3341         addrs[1].buffer[0] = AF_INET;
3342         ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
3343         torture_assert(tctx, ret > 0, "inet_pton failed");
3344
3345         addrs[2].size = sizeof(struct sockaddr_in);
3346         addrs[2].buffer = talloc_zero_array(tctx, uint8_t, addrs[2].size);
3347         addr = (struct sockaddr_in *) addrs[2].buffer;
3348         addrs[2].buffer[0] = AF_INET;
3349         ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
3350         torture_assert(tctx, ret > 0, "inet_pton failed");
3351
3352 #ifdef HAVE_IPV6
3353         addrs[3].size = sizeof(struct sockaddr_in6);
3354         addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
3355         addr6 = (struct sockaddr_in6 *) addrs[3].buffer;
3356         addrs[3].buffer[0] = AF_INET6;
3357         ret = inet_pton(AF_INET6, "::1", &addr6->sin6_addr);
3358         torture_assert(tctx, ret > 0, "inet_pton failed");
3359
3360         addrs[4].size = sizeof(struct sockaddr_in6);
3361         addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
3362         addr6 = (struct sockaddr_in6 *) addrs[4].buffer;
3363         addrs[4].buffer[0] = AF_INET6;
3364         ret = inet_pton(AF_INET6, "::", &addr6->sin6_addr);
3365         torture_assert(tctx, ret > 0, "inet_pton failed");
3366
3367         addrs[5].size = sizeof(struct sockaddr_in6);
3368         addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
3369         addr6 = (struct sockaddr_in6 *) addrs[5].buffer;
3370         addrs[5].buffer[0] = AF_INET6;
3371         ret = inet_pton(AF_INET6, "ff02::1", &addr6->sin6_addr);
3372         torture_assert(tctx, ret > 0, "inet_pton failed");
3373 #else
3374         /* the test cases are repeated to have exactly 6. This is for
3375          * compatibility with IPv4-only machines */
3376         addrs[3].size = sizeof(struct sockaddr_in);
3377         addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
3378         addr = (struct sockaddr_in *) addrs[3].buffer;
3379         addrs[3].buffer[0] = AF_INET;
3380         ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
3381         torture_assert(tctx, ret > 0, "inet_pton failed");
3382
3383         addrs[4].size = sizeof(struct sockaddr_in);
3384         addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
3385         addr = (struct sockaddr_in *) addrs[4].buffer;
3386         addrs[4].buffer[0] = AF_INET;
3387         ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
3388         torture_assert(tctx, ret > 0, "inet_pton failed");
3389
3390         addrs[5].size = sizeof(struct sockaddr_in);
3391         addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
3392         addr = (struct sockaddr_in *) addrs[5].buffer;
3393         addrs[5].buffer[0] = AF_INET;
3394         ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
3395         torture_assert(tctx, ret > 0, "inet_pton failed");
3396 #endif
3397
3398         ctr = talloc(tctx, struct netr_DsRAddressToSitenamesExWCtr);
3399
3400         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3401         r.in.count = 6;
3402         r.in.addresses = addrs;
3403         r.out.ctr = &ctr;
3404
3405         status = dcerpc_netr_DsRAddressToSitenamesExW_r(b, tctx, &r);
3406         torture_assert_ntstatus_ok(tctx, status, "failed");
3407         torture_assert_werr_ok(tctx, r.out.result, "failed");
3408
3409         if (sam_ctx != NULL) {
3410                 for (i = 0; i < 3; i++) {
3411                         torture_assert_casestr_equal(tctx,
3412                                                      ctr->sitename[i].string,
3413                                                      server_site_name(tctx, sam_ctx),
3414                                                      "didn't return default site");
3415                         torture_assert(tctx, ctr->subnetname[i].string == NULL,
3416                                        "subnet should be null");
3417                 }
3418                 for (i = 3; i < 6; i++) {
3419                         /* Windows returns "NULL" for the sitename if it isn't
3420                          * IPv6 configured */
3421                         if (torture_setting_bool(tctx, "samba4", false)) {
3422                                 torture_assert_casestr_equal(tctx,
3423                                                              ctr->sitename[i].string,
3424                                                              server_site_name(tctx, sam_ctx),
3425                                                              "didn't return default site");
3426                         }
3427                         torture_assert(tctx, ctr->subnetname[i].string == NULL,
3428                                        "subnet should be null");
3429                 }
3430         }
3431
3432         /* Now try invalid ones (too short buffers) */
3433
3434         addrs[0].size = 0;
3435         addrs[1].size = 1;
3436         addrs[2].size = 4;
3437
3438         addrs[3].size = 0;
3439         addrs[4].size = 1;
3440         addrs[5].size = 4;
3441
3442         status = dcerpc_netr_DsRAddressToSitenamesExW_r(b, tctx, &r);
3443         torture_assert_ntstatus_ok(tctx, status, "failed");
3444         torture_assert_werr_ok(tctx, r.out.result, "failed");
3445
3446         for (i = 0; i < 6; i++) {
3447                 torture_assert(tctx, ctr->sitename[i].string == NULL,
3448                                "sitename should be null");
3449                 torture_assert(tctx, ctr->subnetname[i].string == NULL,
3450                                "subnet should be null");
3451         }
3452
3453         addrs[0].size = 10;
3454         addrs[0].buffer[0] = AF_UNSPEC;
3455         addrs[1].size = 10;
3456         addrs[1].buffer[0] = AF_UNIX; /* AF_LOCAL = AF_UNIX */
3457         addrs[2].size = 10;
3458         addrs[2].buffer[0] = AF_UNIX;
3459
3460         addrs[3].size = 10;
3461         addrs[3].buffer[0] = 250;
3462         addrs[4].size = 10;
3463         addrs[4].buffer[0] = 251;
3464         addrs[5].size = 10;
3465         addrs[5].buffer[0] = 252;
3466
3467         status = dcerpc_netr_DsRAddressToSitenamesExW_r(b, tctx, &r);
3468         torture_assert_ntstatus_ok(tctx, status, "failed");
3469         torture_assert_werr_ok(tctx, r.out.result, "failed");
3470
3471         for (i = 0; i < 6; i++) {
3472                 torture_assert(tctx, ctr->sitename[i].string == NULL,
3473                                "sitename should be null");
3474                 torture_assert(tctx, ctr->subnetname[i].string == NULL,
3475                                "subnet should be null");
3476         }
3477
3478         return true;
3479 }
3480
3481 static bool test_netr_ServerGetTrustInfo_flags(struct torture_context *tctx,
3482                                                struct dcerpc_pipe *p1,
3483                                                struct cli_credentials *machine_credentials,
3484                                                uint32_t negotiate_flags)
3485 {
3486         struct netr_ServerGetTrustInfo r;
3487
3488         struct netr_Authenticator a;
3489         struct netr_Authenticator return_authenticator;
3490         struct samr_Password new_owf_password;
3491         struct samr_Password old_owf_password;
3492         struct netr_TrustInfo *trust_info;
3493
3494         struct netlogon_creds_CredentialState *creds;
3495         struct dcerpc_pipe *p = NULL;
3496         struct dcerpc_binding_handle *b = NULL;
3497
3498         struct samr_Password nt_hash;
3499
3500         if (!test_SetupCredentials3(p1, tctx, negotiate_flags,
3501                                     machine_credentials, &creds)) {
3502                 return false;
3503         }
3504         if (!test_SetupCredentialsPipe(p1, tctx, machine_credentials, creds,
3505                                        DCERPC_SIGN | DCERPC_SEAL, &p)) {
3506                 return false;
3507         }
3508         b = p->binding_handle;
3509
3510         netlogon_creds_client_authenticator(creds, &a);
3511
3512         r.in.server_name                = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3513         r.in.account_name               = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
3514         r.in.secure_channel_type        = cli_credentials_get_secure_channel_type(machine_credentials);
3515         r.in.computer_name              = TEST_MACHINE_NAME;
3516         r.in.credential                 = &a;
3517
3518         r.out.return_authenticator      = &return_authenticator;
3519         r.out.new_owf_password          = &new_owf_password;
3520         r.out.old_owf_password          = &old_owf_password;
3521         r.out.trust_info                = &trust_info;
3522
3523         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerGetTrustInfo_r(b, tctx, &r),
3524                 "ServerGetTrustInfo failed");
3525         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerGetTrustInfo failed");
3526         torture_assert(tctx, netlogon_creds_client_check(creds, &return_authenticator.cred), "Credential chaining failed");
3527
3528         E_md4hash(cli_credentials_get_password(machine_credentials), nt_hash.hash);
3529
3530         netlogon_creds_des_decrypt(creds, &new_owf_password);
3531
3532         dump_data(1, new_owf_password.hash, 16);
3533         dump_data(1, nt_hash.hash, 16);
3534
3535         torture_assert_mem_equal(tctx, new_owf_password.hash, nt_hash.hash, 16,
3536                 "received unexpected owf password\n");
3537
3538         return true;
3539 }
3540
3541 static bool test_netr_ServerGetTrustInfo(struct torture_context *tctx,
3542                                          struct dcerpc_pipe *p,
3543                                          struct cli_credentials *machine_credentials)
3544 {
3545         return test_netr_ServerGetTrustInfo_flags(tctx, p, machine_credentials,
3546                                                   NETLOGON_NEG_AUTH2_ADS_FLAGS);
3547 }
3548
3549 static bool test_netr_ServerGetTrustInfo_AES(struct torture_context *tctx,
3550                                              struct dcerpc_pipe *p,
3551                                              struct cli_credentials *machine_credentials)
3552 {
3553         return test_netr_ServerGetTrustInfo_flags(tctx, p, machine_credentials,
3554                                                   NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES);
3555 }
3556
3557 static bool test_GetDomainInfo(struct torture_context *tctx,
3558                                struct dcerpc_pipe *p1,
3559                                struct cli_credentials *machine_credentials)
3560 {
3561         struct netr_LogonGetDomainInfo r;
3562         struct netr_WorkstationInformation q1;
3563         struct netr_Authenticator a;
3564         struct netlogon_creds_CredentialState *creds;
3565         struct netr_OsVersion os;
3566         union netr_WorkstationInfo query;
3567         union netr_DomainInfo info;
3568         const char* const attrs[] = { "dNSHostName", "operatingSystem",
3569                 "operatingSystemServicePack", "operatingSystemVersion",
3570                 "servicePrincipalName", NULL };
3571         char *url;
3572         struct ldb_context *sam_ctx = NULL;
3573         struct ldb_message **res;
3574         struct ldb_message_element *spn_el;
3575         int ret, i;
3576         char *version_str;
3577         const char *old_dnsname = NULL;
3578         char **spns = NULL;
3579         int num_spns = 0;
3580         char *temp_str;
3581         struct dcerpc_pipe *p = NULL;
3582         struct dcerpc_binding_handle *b = NULL;
3583
3584         torture_comment(tctx, "Testing netr_LogonGetDomainInfo\n");
3585
3586         if (!test_SetupCredentials3(p1, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
3587                                     machine_credentials, &creds)) {
3588                 return false;
3589         }
3590         if (!test_SetupCredentialsPipe(p1, tctx, machine_credentials, creds,
3591                                        DCERPC_SIGN | DCERPC_SEAL, &p)) {
3592                 return false;
3593         }
3594         b = p->binding_handle;
3595
3596         /* We won't double-check this when we are over 'local' transports */
3597         if (dcerpc_server_name(p)) {
3598                 /* Set up connection to SAMDB on DC */
3599                 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
3600                 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
3601                                            NULL,
3602                                            cmdline_credentials,
3603                                            0);
3604
3605                 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
3606         }
3607
3608         torture_comment(tctx, "Testing netr_LogonGetDomainInfo 1st call (no variation of DNS hostname)\n");
3609         netlogon_creds_client_authenticator(creds, &a);
3610
3611         ZERO_STRUCT(r);
3612         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3613         r.in.computer_name = TEST_MACHINE_NAME;
3614         r.in.credential = &a;
3615         r.in.level = 1;
3616         r.in.return_authenticator = &a;
3617         r.in.query = &query;
3618         r.out.return_authenticator = &a;
3619         r.out.info = &info;
3620
3621         ZERO_STRUCT(os);
3622         os.os.MajorVersion = 123;
3623         os.os.MinorVersion = 456;
3624         os.os.BuildNumber = 789;
3625         os.os.CSDVersion = "Service Pack 10";
3626         os.os.ServicePackMajor = 10;
3627         os.os.ServicePackMinor = 1;
3628         os.os.SuiteMask = NETR_VER_SUITE_SINGLEUSERTS;
3629         os.os.ProductType = NETR_VER_NT_SERVER;
3630         os.os.Reserved = 0;
3631
3632         version_str = talloc_asprintf(tctx, "%d.%d (%d)", os.os.MajorVersion,
3633                 os.os.MinorVersion, os.os.BuildNumber);
3634
3635         ZERO_STRUCT(q1);
3636         q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
3637                 lpcfg_dnsdomain(tctx->lp_ctx));
3638         q1.sitename = "Default-First-Site-Name";
3639         q1.os_version.os = &os;
3640         q1.os_name.string = talloc_asprintf(tctx,
3641                                             "Tortured by Samba4 RPC-NETLOGON: %s",
3642                                             timestring(tctx, time(NULL)));
3643
3644         /* The workstation handles the "servicePrincipalName" and DNS hostname
3645            updates */
3646         q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
3647
3648         query.workstation_info = &q1;
3649
3650         if (sam_ctx) {
3651                 /* Gets back the old DNS hostname in AD */
3652                 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
3653                                    "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
3654                 old_dnsname =
3655                         ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL);
3656
3657                 /* Gets back the "servicePrincipalName"s in AD */
3658                 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
3659                 if (spn_el != NULL) {
3660                         for (i=0; i < spn_el->num_values; i++) {
3661                                 spns = talloc_realloc(tctx, spns, char *, i + 1);
3662                                 spns[i] = (char *) spn_el->values[i].data;
3663                         }
3664                         num_spns = i;
3665                 }
3666         }
3667
3668         torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3669                 "LogonGetDomainInfo failed");
3670         torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3671         torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3672
3673         smb_msleep(250);
3674
3675         if (sam_ctx) {
3676                 /* AD workstation infos entry check */
3677                 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
3678                                    "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
3679                 torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
3680                 torture_assert_str_equal(tctx,
3681                                          ldb_msg_find_attr_as_string(res[0], "operatingSystem", NULL),
3682                                          q1.os_name.string, "'operatingSystem' wrong!");
3683                 torture_assert_str_equal(tctx,
3684                                          ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL),
3685                                          os.os.CSDVersion, "'operatingSystemServicePack' wrong!");
3686                 torture_assert_str_equal(tctx,
3687                                          ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL),
3688                                          version_str, "'operatingSystemVersion' wrong!");
3689
3690                 if (old_dnsname != NULL) {
3691                         /* If before a DNS hostname was set then it should remain
3692                            the same in combination with the "servicePrincipalName"s.
3693                            The DNS hostname should also be returned by our
3694                            "LogonGetDomainInfo" call (in the domain info structure). */
3695
3696                         torture_assert_str_equal(tctx,
3697                                                  ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL),
3698                                                  old_dnsname, "'DNS hostname' was not set!");
3699
3700                         spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
3701                         torture_assert(tctx, ((spns != NULL) && (spn_el != NULL)),
3702                                        "'servicePrincipalName's not set!");
3703                         torture_assert(tctx, spn_el->num_values == num_spns,
3704                                        "'servicePrincipalName's incorrect!");
3705                         for (i=0; (i < spn_el->num_values) && (i < num_spns); i++)
3706                                 torture_assert_str_equal(tctx,
3707                                                          (char *) spn_el->values[i].data,
3708                                 spns[i], "'servicePrincipalName's incorrect!");
3709
3710                         torture_assert_str_equal(tctx,
3711                                                  info.domain_info->dns_hostname.string,
3712                                                  old_dnsname,
3713                                                  "Out 'DNS hostname' doesn't match the old one!");
3714                 } else {
3715                         /* If no DNS hostname was set then also now none should be set,
3716                            the "servicePrincipalName"s should remain empty and no DNS
3717                            hostname should be returned by our "LogonGetDomainInfo"
3718                            call (in the domain info structure). */
3719
3720                         torture_assert(tctx,
3721                                        ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL) == NULL,
3722                                        "'DNS hostname' was set!");
3723
3724                         spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
3725                         torture_assert(tctx, ((spns == NULL) && (spn_el == NULL)),
3726                                        "'servicePrincipalName's were set!");
3727
3728                         torture_assert(tctx,
3729                                        info.domain_info->dns_hostname.string == NULL,
3730                                        "Out 'DNS host name' was set!");
3731                 }
3732         }
3733
3734         /* Checks "workstation flags" */
3735         torture_assert(tctx,
3736                 info.domain_info->workstation_flags
3737                 == NETR_WS_FLAG_HANDLES_SPN_UPDATE,
3738                 "Out 'workstation flags' don't match!");
3739
3740
3741         torture_comment(tctx, "Testing netr_LogonGetDomainInfo 2nd call (variation of DNS hostname doesn't work)\n");
3742         netlogon_creds_client_authenticator(creds, &a);
3743
3744         /* Wipe out the osVersion, and prove which values still 'stick' */
3745         q1.os_version.os = NULL;
3746
3747         /* Change also the DNS hostname to test differences in behaviour */
3748         talloc_free(discard_const_p(char, q1.dns_hostname));
3749         q1.dns_hostname = talloc_asprintf(tctx, "%s2.%s", TEST_MACHINE_NAME,
3750                 lpcfg_dnsdomain(tctx->lp_ctx));
3751
3752         /* The workstation handles the "servicePrincipalName" and DNS hostname
3753            updates */
3754         q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
3755
3756         torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3757                 "LogonGetDomainInfo failed");
3758         torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3759
3760         torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3761
3762         smb_msleep(250);
3763
3764         if (sam_ctx) {
3765                 /* AD workstation infos entry check */
3766                 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
3767                                    "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
3768                 torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
3769
3770                 torture_assert_str_equal(tctx,
3771                                          ldb_msg_find_attr_as_string(res[0], "operatingSystem", NULL),
3772                                          q1.os_name.string, "'operatingSystem' should stick!");
3773                 torture_assert(tctx,
3774                                ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL) == NULL,
3775                                "'operatingSystemServicePack' shouldn't stick!");
3776                 torture_assert(tctx,
3777                                ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL) == NULL,
3778                                "'operatingSystemVersion' shouldn't stick!");
3779
3780                 /* The DNS host name shouldn't have been updated by the server */
3781
3782                 torture_assert_str_equal(tctx,
3783                                          ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL),
3784                                          old_dnsname, "'DNS host name' did change!");
3785
3786                 /* Find the two "servicePrincipalName"s which the DC shouldn't have been
3787                    updated (HOST/<Netbios name> and HOST/<FQDN name>) - see MS-NRPC
3788                    3.5.4.3.9 */
3789                 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
3790                 torture_assert(tctx, spn_el != NULL,
3791                                "There should exist 'servicePrincipalName's in AD!");
3792                 temp_str = talloc_asprintf(tctx, "HOST/%s", TEST_MACHINE_NAME);
3793                 for (i=0; i < spn_el->num_values; i++)
3794                         if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
3795                                 break;
3796                 torture_assert(tctx, i != spn_el->num_values,
3797                                "'servicePrincipalName' HOST/<Netbios name> not found!");
3798                 temp_str = talloc_asprintf(tctx, "HOST/%s", old_dnsname);
3799                 for (i=0; i < spn_el->num_values; i++)
3800                         if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
3801                                 break;
3802                 torture_assert(tctx, i != spn_el->num_values,
3803                                "'servicePrincipalName' HOST/<FQDN name> not found!");
3804
3805                 /* Check that the out DNS hostname was set properly */
3806                 torture_assert_str_equal(tctx, info.domain_info->dns_hostname.string,
3807                                          old_dnsname, "Out 'DNS hostname' doesn't match the old one!");
3808         }
3809
3810         /* Checks "workstation flags" */
3811         torture_assert(tctx,
3812                 info.domain_info->workstation_flags == NETR_WS_FLAG_HANDLES_SPN_UPDATE,
3813                 "Out 'workstation flags' don't match!");
3814
3815
3816         /* Now try the same but the workstation flags set to 0 */
3817
3818         torture_comment(tctx, "Testing netr_LogonGetDomainInfo 3rd call (variation of DNS hostname doesn't work)\n");
3819         netlogon_creds_client_authenticator(creds, &a);
3820
3821         /* Change also the DNS hostname to test differences in behaviour */
3822         talloc_free(discard_const_p(char, q1.dns_hostname));
3823         q1.dns_hostname = talloc_asprintf(tctx, "%s2.%s", TEST_MACHINE_NAME,
3824                 lpcfg_dnsdomain(tctx->lp_ctx));
3825
3826         /* Wipe out the osVersion, and prove which values still 'stick' */
3827         q1.os_version.os = NULL;
3828
3829         /* Let the DC handle the "servicePrincipalName" and DNS hostname
3830            updates */
3831         q1.workstation_flags = 0;
3832
3833         torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3834                 "LogonGetDomainInfo failed");
3835         torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3836         torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3837
3838         smb_msleep(250);
3839
3840         if (sam_ctx) {
3841                 /* AD workstation infos entry check */
3842                 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
3843                                    "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
3844                 torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
3845
3846                 torture_assert_str_equal(tctx,
3847                                          ldb_msg_find_attr_as_string(res[0], "operatingSystem", NULL),
3848                                          q1.os_name.string, "'operatingSystem' should stick!");
3849                 torture_assert(tctx,
3850                                ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL) == NULL,
3851                                "'operatingSystemServicePack' shouldn't stick!");
3852                 torture_assert(tctx,
3853                                ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL) == NULL,
3854                                "'operatingSystemVersion' shouldn't stick!");
3855
3856                 /* The DNS host name shouldn't have been updated by the server */
3857
3858                 torture_assert_str_equal(tctx,
3859                                          ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL),
3860                                          old_dnsname, "'DNS host name' did change!");
3861
3862                 /* Find the two "servicePrincipalName"s which the DC shouldn't have been
3863                    updated (HOST/<Netbios name> and HOST/<FQDN name>) - see MS-NRPC
3864                    3.5.4.3.9 */
3865                 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
3866                 torture_assert(tctx, spn_el != NULL,
3867                                "There should exist 'servicePrincipalName's in AD!");
3868                 temp_str = talloc_asprintf(tctx, "HOST/%s", TEST_MACHINE_NAME);
3869                 for (i=0; i < spn_el->num_values; i++)
3870                         if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
3871                                 break;
3872                 torture_assert(tctx, i != spn_el->num_values,
3873                                "'servicePrincipalName' HOST/<Netbios name> not found!");
3874                 temp_str = talloc_asprintf(tctx, "HOST/%s", old_dnsname);
3875                 for (i=0; i < spn_el->num_values; i++)
3876                         if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
3877                                 break;
3878                 torture_assert(tctx, i != spn_el->num_values,
3879                                "'servicePrincipalName' HOST/<FQDN name> not found!");
3880
3881                 /* Here the server gives us NULL as the out DNS hostname */
3882                 torture_assert(tctx, info.domain_info->dns_hostname.string == NULL,
3883                                "Out 'DNS hostname' should be NULL!");
3884         }
3885
3886         /* Checks "workstation flags" */
3887         torture_assert(tctx,
3888                 info.domain_info->workstation_flags == 0,
3889                 "Out 'workstation flags' don't match!");
3890
3891
3892         torture_comment(tctx, "Testing netr_LogonGetDomainInfo 4th call (verification of DNS hostname and check for trusted domains)\n");
3893         netlogon_creds_client_authenticator(creds, &a);
3894
3895         /* Put the DNS hostname back */
3896         talloc_free(discard_const_p(char, q1.dns_hostname));
3897         q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
3898                 lpcfg_dnsdomain(tctx->lp_ctx));
3899
3900         /* The workstation handles the "servicePrincipalName" and DNS hostname
3901            updates */
3902         q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
3903
3904         torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3905                 "LogonGetDomainInfo failed");
3906         torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3907         torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3908
3909         smb_msleep(250);
3910
3911         /* Now the in/out DNS hostnames should be the same */
3912         torture_assert_str_equal(tctx,
3913                 info.domain_info->dns_hostname.string,
3914                 query.workstation_info->dns_hostname,
3915                 "In/Out 'DNS hostnames' don't match!");
3916         old_dnsname = info.domain_info->dns_hostname.string;
3917
3918         /* Checks "workstation flags" */
3919         torture_assert(tctx,
3920                 info.domain_info->workstation_flags
3921                 == NETR_WS_FLAG_HANDLES_SPN_UPDATE,
3922                 "Out 'workstation flags' don't match!");
3923
3924         /* Checks for trusted domains */
3925         torture_assert(tctx,
3926                 (info.domain_info->trusted_domain_count != 0)
3927                 && (info.domain_info->trusted_domains != NULL),
3928                 "Trusted domains have been requested!");
3929
3930
3931         torture_comment(tctx, "Testing netr_LogonGetDomainInfo 5th call (check for trusted domains)\n");
3932         netlogon_creds_client_authenticator(creds, &a);
3933
3934         /* The workstation handles the "servicePrincipalName" and DNS hostname
3935            updates and requests inbound trusts */
3936         q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE
3937                 | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS;
3938
3939         torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3940                 "LogonGetDomainInfo failed");
3941         torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3942         torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3943
3944         smb_msleep(250);
3945
3946         /* Checks "workstation flags" */
3947         torture_assert(tctx,
3948                 info.domain_info->workstation_flags
3949                 == (NETR_WS_FLAG_HANDLES_SPN_UPDATE
3950                         | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS),
3951                 "Out 'workstation flags' don't match!");
3952
3953         /* Checks for trusted domains */
3954         torture_assert(tctx,
3955                 (info.domain_info->trusted_domain_count != 0)
3956                 && (info.domain_info->trusted_domains != NULL),
3957                 "Trusted domains have been requested!");
3958
3959
3960         torture_comment(tctx, "Testing netr_LogonGetDomainInfo 6th call (no DNS hostname)\n");
3961         netlogon_creds_client_authenticator(creds, &a);
3962
3963         query.workstation_info->dns_hostname = NULL;
3964
3965         torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3966                 "LogonGetDomainInfo failed");
3967         torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3968         torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3969
3970         /* The old DNS hostname should stick */
3971         torture_assert_str_equal(tctx,
3972                 info.domain_info->dns_hostname.string,
3973                 old_dnsname,
3974                 "'DNS hostname' changed!");
3975
3976         torture_comment(tctx, "Testing netr_LogonGetDomainInfo 7th call (extra workstation flags)\n");
3977         netlogon_creds_client_authenticator(creds, &a);
3978
3979         q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE
3980                 | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS | 0x4;
3981
3982         /* Put the DNS hostname back */
3983         talloc_free(discard_const_p(char, q1.dns_hostname));
3984         q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
3985                 lpcfg_dnsdomain(tctx->lp_ctx));
3986
3987         torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3988                 "LogonGetDomainInfo failed");
3989         torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3990         torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3991
3992         /* Checks "workstation flags" */
3993         torture_assert(tctx,
3994                 info.domain_info->workstation_flags
3995                 == (NETR_WS_FLAG_HANDLES_SPN_UPDATE
3996                         | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS),
3997                 "Out 'workstation flags' don't match!");
3998
3999         if (!torture_setting_bool(tctx, "dangerous", false)) {
4000                 torture_comment(tctx, "Not testing netr_LogonGetDomainInfo 8th call (no workstation info) - enable dangerous tests in order to do so\n");
4001         } else {
4002                 /* Try a call without the workstation information structure */
4003
4004                 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 8th call (no workstation info)\n");
4005                 netlogon_creds_client_authenticator(creds, &a);
4006
4007                 query.workstation_info = NULL;
4008
4009                 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
4010                         "LogonGetDomainInfo failed");
4011                 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
4012                 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
4013         }
4014
4015         return true;
4016 }
4017
4018 static bool test_GetDomainInfo_async(struct torture_context *tctx,
4019                                      struct dcerpc_pipe *p1,
4020                                      struct cli_credentials *machine_credentials)
4021 {
4022         NTSTATUS status;
4023         struct netr_LogonGetDomainInfo r;
4024         struct netr_WorkstationInformation q1;
4025         struct netr_Authenticator a;
4026 #define ASYNC_COUNT 100
4027         struct netlogon_creds_CredentialState *creds;
4028         struct netlogon_creds_CredentialState *creds_async[ASYNC_COUNT];
4029         struct tevent_req *req[ASYNC_COUNT];
4030         int i;
4031         union netr_WorkstationInfo query;
4032         union netr_DomainInfo info;
4033         struct dcerpc_pipe *p = NULL;
4034
4035         torture_comment(tctx, "Testing netr_LogonGetDomainInfo - async count %d\n", ASYNC_COUNT);
4036
4037         if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
4038                                     machine_credentials, &creds)) {
4039                 return false;
4040         }
4041         if (!test_SetupCredentialsPipe(p1, tctx, machine_credentials, creds,
4042                                        DCERPC_SIGN | DCERPC_SEAL, &p)) {
4043                 return false;
4044         }
4045
4046         ZERO_STRUCT(r);
4047         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
4048         r.in.computer_name = TEST_MACHINE_NAME;
4049         r.in.credential = &a;
4050         r.in.level = 1;
4051         r.in.return_authenticator = &a;
4052         r.in.query = &query;
4053         r.out.return_authenticator = &a;
4054         r.out.info = &info;
4055
4056         ZERO_STRUCT(q1);
4057         q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
4058                 lpcfg_dnsdomain(tctx->lp_ctx));
4059         q1.sitename = "Default-First-Site-Name";
4060         q1.os_name.string = "UNIX/Linux or similar";
4061
4062         query.workstation_info = &q1;
4063
4064         for (i=0;i<ASYNC_COUNT;i++) {
4065                 netlogon_creds_client_authenticator(creds, &a);
4066
4067                 creds_async[i] = (struct netlogon_creds_CredentialState *)talloc_memdup(creds, creds, sizeof(*creds));
4068                 req[i] = dcerpc_netr_LogonGetDomainInfo_r_send(tctx, tctx->ev, p->binding_handle, &r);
4069
4070                 /* even with this flush per request a w2k3 server seems to
4071                    clag with multiple outstanding requests. bleergh. */
4072                 torture_assert_int_equal(tctx, tevent_loop_once(tctx->ev), 0,
4073                                          "tevent_loop_once failed");
4074         }
4075
4076         for (i=0;i<ASYNC_COUNT;i++) {
4077                 torture_assert_int_equal(tctx, tevent_req_poll(req[i], tctx->ev), true,
4078                                          "tevent_req_poll() failed");
4079
4080                 status = dcerpc_netr_LogonGetDomainInfo_r_recv(req[i], tctx);
4081
4082                 torture_assert_ntstatus_ok(tctx, status, "netr_LogonGetDomainInfo_async");
4083                 torture_assert_ntstatus_ok(tctx, r.out.result, "netr_LogonGetDomainInfo_async");
4084
4085                 torture_assert(tctx, netlogon_creds_client_check(creds_async[i], &a.cred),
4086                         "Credential chaining failed at async");
4087         }
4088
4089         torture_comment(tctx,
4090                         "Testing netr_LogonGetDomainInfo - async count %d OK\n", ASYNC_COUNT);
4091
4092         return true;
4093 }
4094
4095 static bool test_ManyGetDCName(struct torture_context *tctx,
4096                                struct dcerpc_pipe *p)
4097 {
4098         NTSTATUS status;
4099         struct cli_credentials *anon_creds;
4100         struct dcerpc_binding *binding2;
4101         struct dcerpc_pipe *p2;
4102         struct lsa_ObjectAttribute attr;
4103         struct lsa_QosInfo qos;
4104         struct lsa_OpenPolicy2 o;
4105         struct policy_handle lsa_handle;
4106         struct lsa_DomainList domains;
4107
4108         struct lsa_EnumTrustDom t;
4109         uint32_t resume_handle = 0;
4110         struct netr_GetAnyDCName d;
4111         const char *dcname = NULL;
4112         struct dcerpc_binding_handle *b = p->binding_handle;
4113         struct dcerpc_binding_handle *b2;
4114
4115         int i;
4116
4117         if (p->conn->transport.transport != NCACN_NP) {
4118                 torture_skip(tctx, "test_ManyGetDCName works only with NCACN_NP");
4119         }
4120
4121         torture_comment(tctx, "Torturing GetDCName\n");
4122
4123         anon_creds = cli_credentials_init_anon(tctx);
4124         torture_assert(tctx, anon_creds != NULL, "cli_credentials_init_anon failed");
4125
4126         binding2 = dcerpc_binding_dup(tctx, p->binding);
4127         /* Swap the binding details from NETLOGON to LSA */
4128         status = dcerpc_epm_map_binding(tctx, binding2, &ndr_table_lsarpc, tctx->ev, tctx->lp_ctx);
4129         dcerpc_binding_set_assoc_group_id(binding2, 0);
4130         torture_assert_ntstatus_ok(tctx, status, "epm map");
4131
4132         status = dcerpc_secondary_auth_connection(p, binding2, &ndr_table_lsarpc,
4133                                                   anon_creds, tctx->lp_ctx,
4134                                                   tctx, &p2);
4135         torture_assert_ntstatus_ok(tctx, status, "Failed to create secondary connection");
4136         b2 = p2->binding_handle;
4137
4138         qos.len = 0;
4139         qos.impersonation_level = 2;
4140         qos.context_mode = 1;
4141         qos.effective_only = 0;
4142
4143         attr.len = 0;
4144         attr.root_dir = NULL;
4145         attr.object_name = NULL;
4146         attr.attributes = 0;
4147         attr.sec_desc = NULL;
4148         attr.sec_qos = &qos;
4149
4150         o.in.system_name = "\\";
4151         o.in.attr = &attr;
4152         o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4153         o.out.handle = &lsa_handle;
4154
4155         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenPolicy2_r(b2, tctx, &o),
4156                 "OpenPolicy2 failed");
4157         torture_assert_ntstatus_ok(tctx, o.out.result, "OpenPolicy2 failed");
4158
4159         t.in.handle = &lsa_handle;
4160         t.in.resume_handle = &resume_handle;
4161         t.in.max_size = 1000;
4162         t.out.domains = &domains;
4163         t.out.resume_handle = &resume_handle;
4164
4165         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumTrustDom_r(b2, tctx, &t),
4166                 "EnumTrustDom failed");
4167
4168         if ((!NT_STATUS_IS_OK(t.out.result) &&
4169              (!NT_STATUS_EQUAL(t.out.result, NT_STATUS_NO_MORE_ENTRIES))))
4170                 torture_fail(tctx, "Could not list domains");
4171
4172         talloc_free(p2);
4173
4174         d.in.logon_server = talloc_asprintf(tctx, "\\\\%s",
4175                                             dcerpc_server_name(p));
4176         d.out.dcname = &dcname;
4177
4178         for (i=0; i<domains.count * 4; i++) {
4179                 struct lsa_DomainInfo *info =
4180                         &domains.domains[rand()%domains.count];
4181
4182                 d.in.domainname = info->name.string;
4183
4184                 status = dcerpc_netr_GetAnyDCName_r(b, tctx, &d);
4185                 torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
4186
4187                 torture_comment(tctx, "\tDC for domain %s is %s\n", info->name.string,
4188                        dcname ? dcname : "unknown");
4189         }
4190
4191         return true;
4192 }
4193
4194 static bool test_lsa_over_netlogon(struct torture_context *tctx,
4195                                    struct dcerpc_pipe *p)
4196 {
4197         NTSTATUS status;
4198         struct cli_credentials *anon_creds;
4199         const struct dcerpc_binding *binding2;
4200         struct dcerpc_pipe *p2;
4201         struct lsa_ObjectAttribute attr;
4202         struct lsa_QosInfo qos;
4203         struct lsa_OpenPolicy2 o;
4204         struct policy_handle lsa_handle;
4205
4206         struct dcerpc_binding_handle *b2;
4207
4208
4209         if (p->conn->transport.transport != NCACN_NP) {
4210                 torture_skip(tctx, "test_lsa_over_netlogon works only with NCACN_NP");
4211         }
4212
4213         torture_comment(tctx, "Testing if we can access the LSA server over\n"
4214                         " \\\\pipe\\netlogon rather than \\\\pipe\\lsarpc\n");
4215
4216         anon_creds = cli_credentials_init_anon(tctx);
4217         torture_assert(tctx, anon_creds != NULL, "cli_credentials_init_anon failed");
4218
4219         binding2 = p->binding;
4220
4221         status = dcerpc_secondary_auth_connection(p, binding2, &ndr_table_lsarpc,
4222                                                   anon_creds, tctx->lp_ctx,
4223                                                   tctx, &p2);
4224         torture_assert_ntstatus_ok(tctx, status, "Failed to create secondary connection");
4225         b2 = p2->binding_handle;
4226
4227         qos.len = 0;
4228         qos.impersonation_level = 2;
4229         qos.context_mode = 1;
4230         qos.effective_only = 0;
4231
4232         attr.len = 0;
4233         attr.root_dir = NULL;
4234         attr.object_name = NULL;
4235         attr.attributes = 0;
4236         attr.sec_desc = NULL;
4237         attr.sec_qos = &qos;
4238
4239         o.in.system_name = "\\";
4240         o.in.attr = &attr;
4241         o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4242         o.out.handle = &lsa_handle;
4243
4244         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenPolicy2_r(b2, tctx, &o),
4245                 "OpenPolicy2 failed");
4246         torture_assert_ntstatus_ok(tctx, o.out.result, "OpenPolicy2 failed");
4247
4248         talloc_free(p2);
4249
4250         return true;
4251 }
4252
4253 static bool test_SetPassword_with_flags(struct torture_context *tctx,
4254                                         struct dcerpc_pipe *p,
4255                                         struct cli_credentials *machine_credentials)
4256 {
4257         uint32_t flags[] = { 0, NETLOGON_NEG_STRONG_KEYS };
4258         struct netlogon_creds_CredentialState *creds;
4259         int i;
4260
4261         if (!test_SetupCredentials2(p, tctx, 0,
4262                                     machine_credentials,
4263                                     cli_credentials_get_secure_channel_type(machine_credentials),
4264                                     &creds)) {
4265                 torture_skip(tctx, "DC does not support negotiation of 64bit session keys");
4266         }
4267
4268         for (i=0; i < ARRAY_SIZE(flags); i++) {
4269                 torture_assert(tctx,
4270                         test_SetPassword_flags(tctx, p, machine_credentials, flags[i]),
4271                         talloc_asprintf(tctx, "failed to test SetPassword negotiating with 0x%08x flags", flags[i]));
4272         }
4273
4274         return true;
4275 }
4276
4277 struct torture_suite *torture_rpc_netlogon(TALLOC_CTX *mem_ctx)
4278 {
4279         struct torture_suite *suite = torture_suite_create(mem_ctx, "netlogon");
4280         struct torture_rpc_tcase *tcase;
4281         struct torture_test *test;
4282
4283         tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netlogon",
4284                                                   &ndr_table_netlogon, TEST_MACHINE_NAME);
4285
4286         torture_rpc_tcase_add_test(tcase, "Broken RPC binding handle",
4287                                    test_netr_broken_binding_handle);
4288
4289         torture_rpc_tcase_add_test(tcase, "LogonUasLogon", test_LogonUasLogon);
4290         torture_rpc_tcase_add_test(tcase, "LogonUasLogoff", test_LogonUasLogoff);
4291         torture_rpc_tcase_add_test_creds(tcase, "SamLogon", test_SamLogon);
4292         torture_rpc_tcase_add_test_creds(tcase, "invalidAuthenticate2", test_invalidAuthenticate2);
4293         torture_rpc_tcase_add_test_creds(tcase, "ServerReqChallengeGlobal", test_ServerReqChallengeGlobal);
4294         torture_rpc_tcase_add_test_creds(tcase, "SetPassword", test_SetPassword);
4295         torture_rpc_tcase_add_test_creds(tcase, "SetPassword2", test_SetPassword2);
4296         torture_rpc_tcase_add_test_creds(tcase, "SetPassword2_AES", test_SetPassword2_AES);
4297         torture_rpc_tcase_add_test_creds(tcase, "GetPassword", test_GetPassword);
4298         torture_rpc_tcase_add_test_creds(tcase, "GetTrustPasswords", test_GetTrustPasswords);
4299         torture_rpc_tcase_add_test_creds(tcase, "GetDomainInfo", test_GetDomainInfo);
4300         torture_rpc_tcase_add_test_creds(tcase, "DatabaseSync", test_DatabaseSync);
4301         torture_rpc_tcase_add_test_creds(tcase, "DatabaseDeltas", test_DatabaseDeltas);
4302         torture_rpc_tcase_add_test_creds(tcase, "DatabaseRedo", test_DatabaseRedo);
4303         torture_rpc_tcase_add_test_creds(tcase, "AccountDeltas", test_AccountDeltas);
4304         torture_rpc_tcase_add_test_creds(tcase, "AccountSync", test_AccountSync);
4305         torture_rpc_tcase_add_test(tcase, "GetDcName", test_GetDcName);
4306         torture_rpc_tcase_add_test(tcase, "ManyGetDCName", test_ManyGetDCName);
4307         torture_rpc_tcase_add_test(tcase, "GetAnyDCName", test_GetAnyDCName);
4308         torture_rpc_tcase_add_test_creds(tcase, "DatabaseSync2", test_DatabaseSync2);
4309         torture_rpc_tcase_add_test(tcase, "DsrEnumerateDomainTrusts", test_DsrEnumerateDomainTrusts);
4310         torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomains", test_netr_NetrEnumerateTrustedDomains);
4311         torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomainsEx", test_netr_NetrEnumerateTrustedDomainsEx);
4312         test = torture_rpc_tcase_add_test_creds(tcase, "GetDomainInfo_async", test_GetDomainInfo_async);
4313         test->dangerous = true;
4314         torture_rpc_tcase_add_test(tcase, "DsRGetDCName", test_netr_DsRGetDCName);
4315         torture_rpc_tcase_add_test(tcase, "DsRGetDCNameEx", test_netr_DsRGetDCNameEx);
4316         torture_rpc_tcase_add_test(tcase, "DsRGetDCNameEx2", test_netr_DsRGetDCNameEx2);
4317         torture_rpc_tcase_add_test(tcase, "DsrGetDcSiteCoverageW", test_netr_DsrGetDcSiteCoverageW);
4318         torture_rpc_tcase_add_test(tcase, "DsRAddressToSitenamesW", test_netr_DsRAddressToSitenamesW);
4319         torture_rpc_tcase_add_test(tcase, "DsRAddressToSitenamesExW", test_netr_DsRAddressToSitenamesExW);
4320         torture_rpc_tcase_add_test_creds(tcase, "ServerGetTrustInfo", test_netr_ServerGetTrustInfo);
4321         torture_rpc_tcase_add_test_creds(tcase, "ServerGetTrustInfo_AES", test_netr_ServerGetTrustInfo_AES);
4322         torture_rpc_tcase_add_test_creds(tcase, "GetForestTrustInformation", test_netr_GetForestTrustInformation);
4323
4324         torture_rpc_tcase_add_test(tcase, "lsa_over_netlogon", test_lsa_over_netlogon);
4325         torture_rpc_tcase_add_test_creds(tcase, "SetupCredentialsDowngrade", test_SetupCredentialsDowngrade);
4326
4327         return suite;
4328 }
4329
4330 struct torture_suite *torture_rpc_netlogon_s3(TALLOC_CTX *mem_ctx)
4331 {
4332         struct torture_suite *suite = torture_suite_create(mem_ctx, "netlogon-s3");
4333         struct torture_rpc_tcase *tcase;
4334
4335         tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netlogon",
4336                                                   &ndr_table_netlogon, TEST_MACHINE_NAME);
4337
4338         torture_rpc_tcase_add_test_creds(tcase, "SamLogon", test_SamLogon);
4339         torture_rpc_tcase_add_test_creds(tcase, "SamLogon_NULL_domain", test_SamLogon_NULL_domain);
4340         torture_rpc_tcase_add_test_creds(tcase, "SetPassword", test_SetPassword);
4341         torture_rpc_tcase_add_test_creds(tcase, "SetPassword_with_flags", test_SetPassword_with_flags);
4342         torture_rpc_tcase_add_test_creds(tcase, "SetPassword2", test_SetPassword2);
4343         torture_rpc_tcase_add_test_creds(tcase, "SetPassword2_AES", test_SetPassword2_AES);
4344         torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomains", test_netr_NetrEnumerateTrustedDomains);
4345
4346         return suite;
4347 }
4348
4349 struct torture_suite *torture_rpc_netlogon_admin(TALLOC_CTX *mem_ctx)
4350 {
4351         struct torture_suite *suite = torture_suite_create(mem_ctx, "netlogon.admin");
4352         struct torture_rpc_tcase *tcase;
4353
4354         tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "bdc",
4355                                                   &ndr_table_netlogon, TEST_MACHINE_NAME);
4356         torture_rpc_tcase_add_test_creds(tcase, "LogonControl", test_LogonControl);
4357         torture_rpc_tcase_add_test_creds(tcase, "LogonControl2", test_LogonControl2);
4358         torture_rpc_tcase_add_test_creds(tcase, "LogonControl2Ex", test_LogonControl2Ex);
4359
4360         tcase = torture_suite_add_machine_workstation_rpc_iface_tcase(suite, "wkst",
4361                                                   &ndr_table_netlogon, TEST_MACHINE_NAME);
4362         torture_rpc_tcase_add_test_creds(tcase, "LogonControl", test_LogonControl);
4363         torture_rpc_tcase_add_test_creds(tcase, "LogonControl2", test_LogonControl2);
4364         torture_rpc_tcase_add_test_creds(tcase, "LogonControl2Ex", test_LogonControl2Ex);
4365
4366         tcase = torture_suite_add_rpc_iface_tcase(suite, "admin",
4367                                                   &ndr_table_netlogon);
4368         torture_rpc_tcase_add_test_creds(tcase, "LogonControl", test_LogonControl);
4369         torture_rpc_tcase_add_test_creds(tcase, "LogonControl2", test_LogonControl2);
4370         torture_rpc_tcase_add_test_creds(tcase, "LogonControl2Ex", test_LogonControl2Ex);
4371
4372         return suite;
4373 }