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