s4: Change constant to comply with the merged build
[mat/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
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 "version.h"
27 #include "torture/torture.h"
28 #include "lib/events/events.h"
29 #include "auth/auth.h"
30 #include "auth/gensec/gensec.h"
31 #include "lib/cmdline/popt_common.h"
32 #include "torture/rpc/rpc.h"
33 #include "torture/rpc/netlogon.h"
34 #include "../lib/crypto/crypto.h"
35 #include "libcli/auth/libcli_auth.h"
36 #include "librpc/gen_ndr/ndr_netlogon_c.h"
37 #include "librpc/gen_ndr/ndr_netlogon.h"
38 #include "librpc/gen_ndr/ndr_lsa_c.h"
39 #include "param/param.h"
40 #include "libcli/security/security.h"
41 #include "lib/ldb/include/ldb.h"
42 #include "lib/util/util_ldb.h"
43 #include "lib/ldb_wrap.h"
44
45 #define TEST_MACHINE_NAME "torturetest"
46 #define TEST_MACHINE_DNS_SUFFIX "torturedomain"
47
48 static bool test_LogonUasLogon(struct torture_context *tctx, 
49                                struct dcerpc_pipe *p)
50 {
51         NTSTATUS status;
52         struct netr_LogonUasLogon r;
53         struct netr_UasInfo *info = NULL;
54
55         r.in.server_name = NULL;
56         r.in.account_name = cli_credentials_get_username(cmdline_credentials);
57         r.in.workstation = TEST_MACHINE_NAME;
58         r.out.info = &info;
59
60         status = dcerpc_netr_LogonUasLogon(p, tctx, &r);
61         torture_assert_ntstatus_ok(tctx, status, "LogonUasLogon");
62
63         return true;
64 }
65
66 static bool test_LogonUasLogoff(struct torture_context *tctx,
67                                 struct dcerpc_pipe *p)
68 {
69         NTSTATUS status;
70         struct netr_LogonUasLogoff r;
71         struct netr_UasLogoffInfo info;
72
73         r.in.server_name = NULL;
74         r.in.account_name = cli_credentials_get_username(cmdline_credentials);
75         r.in.workstation = TEST_MACHINE_NAME;
76         r.out.info = &info;
77
78         status = dcerpc_netr_LogonUasLogoff(p, tctx, &r);
79         torture_assert_ntstatus_ok(tctx, status, "LogonUasLogoff");
80
81         return true;
82 }
83
84 bool test_SetupCredentials(struct dcerpc_pipe *p, struct torture_context *tctx,
85                                   struct cli_credentials *credentials,
86                                   struct netlogon_creds_CredentialState **creds_out)
87 {
88         NTSTATUS status;
89         struct netr_ServerReqChallenge r;
90         struct netr_ServerAuthenticate a;
91         struct netr_Credential credentials1, credentials2, credentials3;
92         struct netlogon_creds_CredentialState *creds;
93         const struct samr_Password *mach_password;
94         const char *machine_name;
95
96         mach_password = cli_credentials_get_nt_hash(credentials, tctx);
97         machine_name = cli_credentials_get_workstation(credentials);
98
99         torture_comment(tctx, "Testing ServerReqChallenge\n");
100
101         r.in.server_name = NULL;
102         r.in.computer_name = machine_name;
103         r.in.credentials = &credentials1;
104         r.out.return_credentials = &credentials2;
105
106         generate_random_buffer(credentials1.data, sizeof(credentials1.data));
107
108         status = dcerpc_netr_ServerReqChallenge(p, tctx, &r);
109         torture_assert_ntstatus_ok(tctx, status, "ServerReqChallenge");
110
111         a.in.server_name = NULL;
112         a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
113         a.in.secure_channel_type = SEC_CHAN_BDC;
114         a.in.computer_name = machine_name;
115         a.in.credentials = &credentials3;
116         a.out.return_credentials = &credentials3;
117
118         creds = netlogon_creds_client_init(tctx, a.in.account_name,
119                                            a.in.computer_name,
120                                            &credentials1, &credentials2, 
121                                            mach_password, &credentials3, 
122                                            0);
123         torture_assert(tctx, creds != NULL, "memory allocation");
124
125
126         torture_comment(tctx, "Testing ServerAuthenticate\n");
127
128         status = dcerpc_netr_ServerAuthenticate(p, tctx, &a);
129
130         /* This allows the tests to continue against the more fussy windows 2008 */
131         if (NT_STATUS_EQUAL(status, NT_STATUS_DOWNGRADE_DETECTED)) {
132                 return test_SetupCredentials2(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS, 
133                                               credentials, SEC_CHAN_BDC, creds_out);
134         }
135
136         torture_assert_ntstatus_ok(tctx, status, "ServerAuthenticate");
137
138         torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), 
139                        "Credential chaining failed");
140
141         *creds_out = creds;
142         return true;
143 }
144
145 bool test_SetupCredentials2(struct dcerpc_pipe *p, struct torture_context *tctx,
146                             uint32_t negotiate_flags,
147                             struct cli_credentials *machine_credentials,
148                             int sec_chan_type,
149                             struct netlogon_creds_CredentialState **creds_out)
150 {
151         NTSTATUS status;
152         struct netr_ServerReqChallenge r;
153         struct netr_ServerAuthenticate2 a;
154         struct netr_Credential credentials1, credentials2, credentials3;
155         struct netlogon_creds_CredentialState *creds;
156         const struct samr_Password *mach_password;
157         const char *machine_name;
158
159         mach_password = cli_credentials_get_nt_hash(machine_credentials, tctx);
160         machine_name = cli_credentials_get_workstation(machine_credentials);
161
162         torture_comment(tctx, "Testing ServerReqChallenge\n");
163
164
165         r.in.server_name = NULL;
166         r.in.computer_name = machine_name;
167         r.in.credentials = &credentials1;
168         r.out.return_credentials = &credentials2;
169
170         generate_random_buffer(credentials1.data, sizeof(credentials1.data));
171
172         status = dcerpc_netr_ServerReqChallenge(p, tctx, &r);
173         torture_assert_ntstatus_ok(tctx, status, "ServerReqChallenge");
174
175         a.in.server_name = NULL;
176         a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
177         a.in.secure_channel_type = sec_chan_type;
178         a.in.computer_name = machine_name;
179         a.in.negotiate_flags = &negotiate_flags;
180         a.out.negotiate_flags = &negotiate_flags;
181         a.in.credentials = &credentials3;
182         a.out.return_credentials = &credentials3;
183
184         creds = netlogon_creds_client_init(tctx, a.in.account_name,
185                                            a.in.computer_name, 
186                                            &credentials1, &credentials2, 
187                                            mach_password, &credentials3, 
188                                            negotiate_flags);
189
190         torture_assert(tctx, creds != NULL, "memory allocation");
191
192         torture_comment(tctx, "Testing ServerAuthenticate2\n");
193
194         status = dcerpc_netr_ServerAuthenticate2(p, tctx, &a);
195         torture_assert_ntstatus_ok(tctx, status, "ServerAuthenticate2");
196
197         torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), 
198                 "Credential chaining failed");
199
200         torture_comment(tctx, "negotiate_flags=0x%08x\n", negotiate_flags);
201
202         *creds_out = creds;
203         return true;
204 }
205
206
207 static bool test_SetupCredentials3(struct dcerpc_pipe *p, struct torture_context *tctx,
208                             uint32_t negotiate_flags,
209                             struct cli_credentials *machine_credentials,
210                             struct netlogon_creds_CredentialState **creds_out)
211 {
212         NTSTATUS status;
213         struct netr_ServerReqChallenge r;
214         struct netr_ServerAuthenticate3 a;
215         struct netr_Credential credentials1, credentials2, credentials3;
216         struct netlogon_creds_CredentialState *creds;
217         struct samr_Password mach_password;
218         uint32_t rid;
219         const char *machine_name;
220         const char *plain_pass;
221
222         machine_name = cli_credentials_get_workstation(machine_credentials);
223         plain_pass = cli_credentials_get_password(machine_credentials);
224
225         torture_comment(tctx, "Testing ServerReqChallenge\n");
226
227         r.in.server_name = NULL;
228         r.in.computer_name = machine_name;
229         r.in.credentials = &credentials1;
230         r.out.return_credentials = &credentials2;
231
232         generate_random_buffer(credentials1.data, sizeof(credentials1.data));
233
234         status = dcerpc_netr_ServerReqChallenge(p, tctx, &r);
235         torture_assert_ntstatus_ok(tctx, status, "ServerReqChallenge");
236
237         E_md4hash(plain_pass, mach_password.hash);
238
239         a.in.server_name = NULL;
240         a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
241         a.in.secure_channel_type = SEC_CHAN_BDC;
242         a.in.computer_name = machine_name;
243         a.in.negotiate_flags = &negotiate_flags;
244         a.in.credentials = &credentials3;
245         a.out.return_credentials = &credentials3;
246         a.out.negotiate_flags = &negotiate_flags;
247         a.out.rid = &rid;
248
249         creds = netlogon_creds_client_init(tctx, a.in.account_name,
250                                            a.in.computer_name,
251                                            &credentials1, &credentials2, 
252                                            &mach_password, &credentials3,
253                                            negotiate_flags);
254         
255         torture_assert(tctx, creds != NULL, "memory allocation");
256
257         torture_comment(tctx, "Testing ServerAuthenticate3\n");
258
259         status = dcerpc_netr_ServerAuthenticate3(p, tctx, &a);
260         torture_assert_ntstatus_ok(tctx, status, "ServerAuthenticate3");
261         torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
262
263         torture_comment(tctx, "negotiate_flags=0x%08x\n", negotiate_flags);
264         
265         /* Prove that requesting a challenge again won't break it */
266         status = dcerpc_netr_ServerReqChallenge(p, tctx, &r);
267         torture_assert_ntstatus_ok(tctx, status, "ServerReqChallenge");
268
269         *creds_out = creds;
270         return true;
271 }
272
273 /*
274   try a change password for our machine account
275 */
276 static bool test_SetPassword(struct torture_context *tctx, 
277                              struct dcerpc_pipe *p,
278                              struct cli_credentials *machine_credentials)
279 {
280         NTSTATUS status;
281         struct netr_ServerPasswordSet r;
282         const char *password;
283         struct netlogon_creds_CredentialState *creds;
284         struct netr_Authenticator credential, return_authenticator;
285         struct samr_Password new_password;
286
287         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
288                 return false;
289         }
290
291         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
292         r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
293         r.in.secure_channel_type = SEC_CHAN_BDC;
294         r.in.computer_name = TEST_MACHINE_NAME;
295         r.in.credential = &credential;
296         r.in.new_password = &new_password;
297         r.out.return_authenticator = &return_authenticator;
298
299         password = generate_random_str(tctx, 8);
300         E_md4hash(password, new_password.hash);
301
302         netlogon_creds_des_encrypt(creds, &new_password);
303
304         torture_comment(tctx, "Testing ServerPasswordSet on machine account\n");
305         torture_comment(tctx, "Changing machine account password to '%s'\n", 
306                         password);
307
308         netlogon_creds_client_authenticator(creds, &credential);
309
310         status = dcerpc_netr_ServerPasswordSet(p, tctx, &r);
311         torture_assert_ntstatus_ok(tctx, status, "ServerPasswordSet");
312
313         if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
314                 torture_comment(tctx, "Credential chaining failed\n");
315         }
316
317         /* by changing the machine password twice we test the
318            credentials chaining fully, and we verify that the server
319            allows the password to be set to the same value twice in a
320            row (match win2k3) */
321         torture_comment(tctx, 
322                 "Testing a second ServerPasswordSet on machine account\n");
323         torture_comment(tctx, 
324                 "Changing machine account password to '%s' (same as previous run)\n", password);
325
326         netlogon_creds_client_authenticator(creds, &credential);
327
328         status = dcerpc_netr_ServerPasswordSet(p, tctx, &r);
329         torture_assert_ntstatus_ok(tctx, status, "ServerPasswordSet (2)");
330
331         if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
332                 torture_comment(tctx, "Credential chaining failed\n");
333         }
334
335         cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
336
337         torture_assert(tctx, 
338                 test_SetupCredentials(p, tctx, machine_credentials, &creds), 
339                 "ServerPasswordSet failed to actually change the password");
340
341         return true;
342 }
343
344 /*
345   generate a random password for password change tests
346 */
347 static DATA_BLOB netlogon_very_rand_pass(TALLOC_CTX *mem_ctx, int len)
348 {
349         int i;
350         DATA_BLOB password = data_blob_talloc(mem_ctx, NULL, len * 2 /* number of unicode chars */);
351         generate_random_buffer(password.data, password.length);
352
353         for (i=0; i < len; i++) {
354                 if (((uint16_t *)password.data)[i] == 0) {
355                         ((uint16_t *)password.data)[i] = 1;
356                 }
357         }
358
359         return password;
360 }
361
362 /*
363   try a change password for our machine account
364 */
365 static bool test_SetPassword2(struct torture_context *tctx, 
366                               struct dcerpc_pipe *p, 
367                               struct cli_credentials *machine_credentials)
368 {
369         NTSTATUS status;
370         struct netr_ServerPasswordSet2 r;
371         const char *password;
372         DATA_BLOB new_random_pass;
373         struct netlogon_creds_CredentialState *creds;
374         struct samr_CryptPassword password_buf;
375         struct samr_Password nt_hash;
376         struct netr_Authenticator credential, return_authenticator;
377         struct netr_CryptPassword new_password;
378
379         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
380                 return false;
381         }
382
383         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
384         r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
385         r.in.secure_channel_type = SEC_CHAN_BDC;
386         r.in.computer_name = TEST_MACHINE_NAME;
387         r.in.credential = &credential;
388         r.in.new_password = &new_password;
389         r.out.return_authenticator = &return_authenticator;
390
391         password = generate_random_str(tctx, 8);
392         encode_pw_buffer(password_buf.data, password, STR_UNICODE);
393         netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
394
395         memcpy(new_password.data, password_buf.data, 512);
396         new_password.length = IVAL(password_buf.data, 512);
397
398         torture_comment(tctx, "Testing ServerPasswordSet2 on machine account\n");
399         torture_comment(tctx, "Changing machine account password to '%s'\n", password);
400
401         netlogon_creds_client_authenticator(creds, &credential);
402
403         status = dcerpc_netr_ServerPasswordSet2(p, tctx, &r);
404         torture_assert_ntstatus_ok(tctx, status, "ServerPasswordSet2");
405
406         if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
407                 torture_comment(tctx, "Credential chaining failed\n");
408         }
409
410         cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
411
412         if (!torture_setting_bool(tctx, "dangerous", false)) {
413                 torture_comment(tctx, 
414                         "Not testing ability to set password to '', enable dangerous tests to perform this test\n");
415         } else {
416                 /* by changing the machine password to ""
417                  * we check if the server uses password restrictions
418                  * for ServerPasswordSet2
419                  * (win2k3 accepts "")
420                  */
421                 password = "";
422                 encode_pw_buffer(password_buf.data, password, STR_UNICODE);
423                 netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
424                 
425                 memcpy(new_password.data, password_buf.data, 512);
426                 new_password.length = IVAL(password_buf.data, 512);
427                 
428                 torture_comment(tctx, 
429                         "Testing ServerPasswordSet2 on machine account\n");
430                 torture_comment(tctx, 
431                         "Changing machine account password to '%s'\n", password);
432                 
433                 netlogon_creds_client_authenticator(creds, &credential);
434                 
435                 status = dcerpc_netr_ServerPasswordSet2(p, tctx, &r);
436                 torture_assert_ntstatus_ok(tctx, status, "ServerPasswordSet2");
437                 
438                 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
439                         torture_comment(tctx, "Credential chaining failed\n");
440                 }
441                 
442                 cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
443         }
444
445         torture_assert(tctx, test_SetupCredentials(p, tctx, machine_credentials, &creds), 
446                 "ServerPasswordSet failed to actually change the password");
447
448         /* now try a random password */
449         password = generate_random_str(tctx, 8);
450         encode_pw_buffer(password_buf.data, password, STR_UNICODE);
451         netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
452
453         memcpy(new_password.data, password_buf.data, 512);
454         new_password.length = IVAL(password_buf.data, 512);
455
456         torture_comment(tctx, "Testing second ServerPasswordSet2 on machine account\n");
457         torture_comment(tctx, "Changing machine account password to '%s'\n", password);
458
459         netlogon_creds_client_authenticator(creds, &credential);
460
461         status = dcerpc_netr_ServerPasswordSet2(p, tctx, &r);
462         torture_assert_ntstatus_ok(tctx, status, "ServerPasswordSet2 (2)");
463
464         if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
465                 torture_comment(tctx, "Credential chaining failed\n");
466         }
467
468         /* by changing the machine password twice we test the
469            credentials chaining fully, and we verify that the server
470            allows the password to be set to the same value twice in a
471            row (match win2k3) */
472         torture_comment(tctx, 
473                 "Testing a second ServerPasswordSet2 on machine account\n");
474         torture_comment(tctx, 
475                 "Changing machine account password to '%s' (same as previous run)\n", password);
476
477         netlogon_creds_client_authenticator(creds, &credential);
478
479         status = dcerpc_netr_ServerPasswordSet2(p, tctx, &r);
480         torture_assert_ntstatus_ok(tctx, status, "ServerPasswordSet (3)");
481
482         if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
483                 torture_comment(tctx, "Credential chaining failed\n");
484         }
485
486         cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
487
488         torture_assert (tctx, 
489                 test_SetupCredentials(p, tctx, machine_credentials, &creds), 
490                 "ServerPasswordSet failed to actually change the password");
491
492         new_random_pass = netlogon_very_rand_pass(tctx, 128);
493
494         /* now try a random stream of bytes for a password */
495         set_pw_in_buffer(password_buf.data, &new_random_pass);
496
497         netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
498
499         memcpy(new_password.data, password_buf.data, 512);
500         new_password.length = IVAL(password_buf.data, 512);
501
502         torture_comment(tctx, 
503                 "Testing a third ServerPasswordSet2 on machine account, with a compleatly random password\n");
504
505         netlogon_creds_client_authenticator(creds, &credential);
506
507         status = dcerpc_netr_ServerPasswordSet2(p, tctx, &r);
508         torture_assert_ntstatus_ok(tctx, status, "ServerPasswordSet (3)");
509
510         if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
511                 torture_comment(tctx, "Credential chaining failed\n");
512         }
513
514         mdfour(nt_hash.hash, new_random_pass.data, new_random_pass.length);
515
516         cli_credentials_set_password(machine_credentials, NULL, CRED_UNINITIALISED);
517         cli_credentials_set_nt_hash(machine_credentials, &nt_hash, CRED_SPECIFIED);
518
519         torture_assert (tctx, 
520                 test_SetupCredentials(p, tctx, machine_credentials, &creds), 
521                 "ServerPasswordSet failed to actually change the password");
522
523         return true;
524 }
525
526 static bool test_GetPassword(struct torture_context *tctx,
527                              struct dcerpc_pipe *p,
528                              struct cli_credentials *machine_credentials)
529 {
530         struct netr_ServerPasswordGet r;
531         struct netlogon_creds_CredentialState *creds;
532         struct netr_Authenticator credential;
533         NTSTATUS status;
534         struct netr_Authenticator return_authenticator;
535         struct samr_Password password;
536
537         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
538                 return false;
539         }
540
541         netlogon_creds_client_authenticator(creds, &credential);
542
543         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
544         r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
545         r.in.secure_channel_type = SEC_CHAN_BDC;
546         r.in.computer_name = TEST_MACHINE_NAME;
547         r.in.credential = &credential;
548         r.out.return_authenticator = &return_authenticator;
549         r.out.password = &password;
550
551         status = dcerpc_netr_ServerPasswordGet(p, tctx, &r);
552         torture_assert_ntstatus_ok(tctx, status, "ServerPasswordGet");
553
554         return true;
555 }
556
557 static bool test_GetTrustPasswords(struct torture_context *tctx,
558                                    struct dcerpc_pipe *p,
559                                    struct cli_credentials *machine_credentials)
560 {
561         struct netr_ServerTrustPasswordsGet r;
562         struct netlogon_creds_CredentialState *creds;
563         struct netr_Authenticator credential;
564         NTSTATUS status;
565         struct netr_Authenticator return_authenticator;
566         struct samr_Password password, password2;
567
568         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
569                 return false;
570         }
571
572         netlogon_creds_client_authenticator(creds, &credential);
573
574         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
575         r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
576         r.in.secure_channel_type = SEC_CHAN_BDC;
577         r.in.computer_name = TEST_MACHINE_NAME;
578         r.in.credential = &credential;
579         r.out.return_authenticator = &return_authenticator;
580         r.out.password = &password;
581         r.out.password2 = &password2;
582
583         status = dcerpc_netr_ServerTrustPasswordsGet(p, tctx, &r);
584         torture_assert_ntstatus_ok(tctx, status, "ServerTrustPasswordsGet");
585
586         return true;
587 }
588
589 /*
590   try a netlogon SamLogon
591 */
592 bool test_netlogon_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
593                               struct cli_credentials *credentials, 
594                               struct netlogon_creds_CredentialState *creds)
595 {
596         NTSTATUS status;
597         struct netr_LogonSamLogon r;
598         struct netr_Authenticator auth, auth2;
599         union netr_LogonLevel logon;
600         union netr_Validation validation;
601         uint8_t authoritative;
602         struct netr_NetworkInfo ninfo;
603         DATA_BLOB names_blob, chal, lm_resp, nt_resp;
604         int i;
605         int flags = CLI_CRED_NTLM_AUTH;
606         if (lp_client_lanman_auth(tctx->lp_ctx)) {
607                 flags |= CLI_CRED_LANMAN_AUTH;
608         }
609
610         if (lp_client_ntlmv2_auth(tctx->lp_ctx)) {
611                 flags |= CLI_CRED_NTLMv2_AUTH;
612         }
613
614         cli_credentials_get_ntlm_username_domain(cmdline_credentials, tctx, 
615                                                  &ninfo.identity_info.account_name.string,
616                                                  &ninfo.identity_info.domain_name.string);
617         
618         generate_random_buffer(ninfo.challenge, 
619                                sizeof(ninfo.challenge));
620         chal = data_blob_const(ninfo.challenge, 
621                                sizeof(ninfo.challenge));
622
623         names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(credentials), 
624                                                 cli_credentials_get_domain(credentials));
625
626         status = cli_credentials_get_ntlm_response(cmdline_credentials, tctx, 
627                                                    &flags, 
628                                                    chal,
629                                                    names_blob,
630                                                    &lm_resp, &nt_resp,
631                                                    NULL, NULL);
632         torture_assert_ntstatus_ok(tctx, status, "cli_credentials_get_ntlm_response failed");
633
634         ninfo.lm.data = lm_resp.data;
635         ninfo.lm.length = lm_resp.length;
636
637         ninfo.nt.data = nt_resp.data;
638         ninfo.nt.length = nt_resp.length;
639
640         ninfo.identity_info.parameter_control = 0;
641         ninfo.identity_info.logon_id_low = 0;
642         ninfo.identity_info.logon_id_high = 0;
643         ninfo.identity_info.workstation.string = cli_credentials_get_workstation(credentials);
644
645         logon.network = &ninfo;
646
647         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
648         r.in.computer_name = cli_credentials_get_workstation(credentials);
649         r.in.credential = &auth;
650         r.in.return_authenticator = &auth2;
651         r.in.logon_level = 2;
652         r.in.logon = &logon;
653         r.out.validation = &validation;
654         r.out.authoritative = &authoritative;
655
656         d_printf("Testing LogonSamLogon with name %s\n", ninfo.identity_info.account_name.string);
657         
658         for (i=2;i<3;i++) {
659                 ZERO_STRUCT(auth2);
660                 netlogon_creds_client_authenticator(creds, &auth);
661                 
662                 r.in.validation_level = i;
663                 
664                 status = dcerpc_netr_LogonSamLogon(p, tctx, &r);
665                 torture_assert_ntstatus_ok(tctx, status, "LogonSamLogon failed");
666                 
667                 torture_assert(tctx, netlogon_creds_client_check(creds, 
668                                                                  &r.out.return_authenticator->cred), 
669                         "Credential chaining failed");
670         }
671
672         r.in.credential = NULL;
673
674         for (i=2;i<=3;i++) {
675
676                 r.in.validation_level = i;
677
678                 torture_comment(tctx, "Testing SamLogon with validation level %d and a NULL credential\n", i);
679
680                 status = dcerpc_netr_LogonSamLogon(p, tctx, &r);
681                 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_INVALID_PARAMETER, 
682                         "LogonSamLogon expected INVALID_PARAMETER");
683
684         }
685
686         return true;
687 }
688
689 /*
690   try a netlogon SamLogon
691 */
692 static bool test_SamLogon(struct torture_context *tctx, 
693                           struct dcerpc_pipe *p,
694                           struct cli_credentials *credentials)
695 {
696         struct netlogon_creds_CredentialState *creds;
697
698         if (!test_SetupCredentials(p, tctx, credentials, &creds)) {
699                 return false;
700         }
701
702         return test_netlogon_ops(p, tctx, credentials, creds);
703 }
704
705 /* we remember the sequence numbers so we can easily do a DatabaseDelta */
706 static uint64_t sequence_nums[3];
707
708 /*
709   try a netlogon DatabaseSync
710 */
711 static bool test_DatabaseSync(struct torture_context *tctx, 
712                               struct dcerpc_pipe *p,
713                               struct cli_credentials *machine_credentials)
714 {
715         NTSTATUS status;
716         struct netr_DatabaseSync r;
717         struct netlogon_creds_CredentialState *creds;
718         const uint32_t database_ids[] = {SAM_DATABASE_DOMAIN, SAM_DATABASE_BUILTIN, SAM_DATABASE_PRIVS}; 
719         int i;
720         struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
721         struct netr_Authenticator credential, return_authenticator;
722
723         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
724                 return false;
725         }
726
727         ZERO_STRUCT(return_authenticator);
728
729         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
730         r.in.computername = TEST_MACHINE_NAME;
731         r.in.preferredmaximumlength = (uint32_t)-1;
732         r.in.return_authenticator = &return_authenticator;
733         r.out.delta_enum_array = &delta_enum_array;
734         r.out.return_authenticator = &return_authenticator;
735
736         for (i=0;i<ARRAY_SIZE(database_ids);i++) {
737
738                 uint32_t sync_context = 0;
739
740                 r.in.database_id = database_ids[i];
741                 r.in.sync_context = &sync_context;
742                 r.out.sync_context = &sync_context;
743
744                 torture_comment(tctx, "Testing DatabaseSync of id %d\n", r.in.database_id);
745
746                 do {
747                         netlogon_creds_client_authenticator(creds, &credential);
748
749                         r.in.credential = &credential;
750
751                         status = dcerpc_netr_DatabaseSync(p, tctx, &r);
752                         if (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
753                             break;
754
755                         /* Native mode servers don't do this */
756                         if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
757                                 return true;
758                         }
759                         torture_assert_ntstatus_ok(tctx, status, "DatabaseSync");
760
761                         if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
762                                 torture_comment(tctx, "Credential chaining failed\n");
763                         }
764
765                         if (delta_enum_array &&
766                             delta_enum_array->num_deltas > 0 &&
767                             delta_enum_array->delta_enum[0].delta_type == NETR_DELTA_DOMAIN &&
768                             delta_enum_array->delta_enum[0].delta_union.domain) {
769                                 sequence_nums[r.in.database_id] = 
770                                         delta_enum_array->delta_enum[0].delta_union.domain->sequence_num;
771                                 torture_comment(tctx, "\tsequence_nums[%d]=%llu\n",
772                                        r.in.database_id, 
773                                        (unsigned long long)sequence_nums[r.in.database_id]);
774                         }
775                 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
776         }
777
778         return true;
779 }
780
781
782 /*
783   try a netlogon DatabaseDeltas
784 */
785 static bool test_DatabaseDeltas(struct torture_context *tctx, 
786                                 struct dcerpc_pipe *p,
787                                 struct cli_credentials *machine_credentials)
788 {
789         NTSTATUS status;
790         struct netr_DatabaseDeltas r;
791         struct netlogon_creds_CredentialState *creds;
792         struct netr_Authenticator credential;
793         struct netr_Authenticator return_authenticator;
794         struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
795         const uint32_t database_ids[] = {0, 1, 2}; 
796         int i;
797
798         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
799                 return false;
800         }
801
802         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
803         r.in.computername = TEST_MACHINE_NAME;
804         r.in.preferredmaximumlength = (uint32_t)-1;
805         ZERO_STRUCT(r.in.return_authenticator);
806         r.out.return_authenticator = &return_authenticator;
807         r.out.delta_enum_array = &delta_enum_array;
808
809         for (i=0;i<ARRAY_SIZE(database_ids);i++) {
810                 r.in.database_id = database_ids[i];
811                 r.in.sequence_num = &sequence_nums[r.in.database_id];
812
813                 if (*r.in.sequence_num == 0) continue;
814
815                 *r.in.sequence_num -= 1;
816
817                 torture_comment(tctx, "Testing DatabaseDeltas of id %d at %llu\n", 
818                        r.in.database_id, (unsigned long long)*r.in.sequence_num);
819
820                 do {
821                         netlogon_creds_client_authenticator(creds, &credential);
822
823                         status = dcerpc_netr_DatabaseDeltas(p, tctx, &r);
824                         if (NT_STATUS_EQUAL(status, 
825                                              NT_STATUS_SYNCHRONIZATION_REQUIRED)) {
826                                 torture_comment(tctx, "not considering %s to be an error\n",
827                                        nt_errstr(status));
828                                 return true;
829                         }
830                         if (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) 
831                             break;
832
833                         torture_assert_ntstatus_ok(tctx, status, "DatabaseDeltas");
834
835                         if (!netlogon_creds_client_check(creds, &return_authenticator.cred)) {
836                                 torture_comment(tctx, "Credential chaining failed\n");
837                         }
838
839                         (*r.in.sequence_num)++;
840                 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
841         }
842
843         return true;
844 }
845
846 static bool test_DatabaseRedo(struct torture_context *tctx,
847                               struct dcerpc_pipe *p,
848                               struct cli_credentials *machine_credentials)
849 {
850         NTSTATUS status;
851         struct netr_DatabaseRedo r;
852         struct netlogon_creds_CredentialState *creds;
853         struct netr_Authenticator credential;
854         struct netr_Authenticator return_authenticator;
855         struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
856         struct netr_ChangeLogEntry e;
857         struct dom_sid null_sid, *sid;
858         int i,d;
859
860         ZERO_STRUCT(null_sid);
861
862         sid = dom_sid_parse_talloc(tctx, "S-1-5-21-1111111111-2222222222-333333333-500");
863
864         {
865
866         struct {
867                 uint32_t rid;
868                 uint16_t flags;
869                 uint8_t db_index;
870                 uint8_t delta_type;
871                 struct dom_sid sid;
872                 const char *name;
873                 NTSTATUS expected_error;
874                 uint32_t expected_num_results;
875                 uint8_t expected_delta_type_1;
876                 uint8_t expected_delta_type_2;
877                 const char *comment;
878         } changes[] = {
879
880                 /* SAM_DATABASE_DOMAIN */
881
882                 {
883                         .rid                    = 0,
884                         .flags                  = 0,
885                         .db_index               = SAM_DATABASE_DOMAIN,
886                         .delta_type             = NETR_DELTA_MODIFY_COUNT,
887                         .sid                    = null_sid,
888                         .name                   = NULL,
889                         .expected_error         = NT_STATUS_SYNCHRONIZATION_REQUIRED,
890                         .expected_num_results   = 0,
891                         .comment                = "NETR_DELTA_MODIFY_COUNT"
892                 },
893                 {
894                         .rid                    = 0,
895                         .flags                  = 0,
896                         .db_index               = SAM_DATABASE_DOMAIN,
897                         .delta_type             = 0,
898                         .sid                    = null_sid,
899                         .name                   = NULL,
900                         .expected_error         = NT_STATUS_OK,
901                         .expected_num_results   = 1,
902                         .expected_delta_type_1  = NETR_DELTA_DOMAIN,
903                         .comment                = "NULL DELTA"
904                 },
905                 {
906                         .rid                    = 0,
907                         .flags                  = 0,
908                         .db_index               = SAM_DATABASE_DOMAIN,
909                         .delta_type             = NETR_DELTA_DOMAIN,
910                         .sid                    = null_sid,
911                         .name                   = NULL,
912                         .expected_error         = NT_STATUS_OK,
913                         .expected_num_results   = 1,
914                         .expected_delta_type_1  = NETR_DELTA_DOMAIN,
915                         .comment                = "NETR_DELTA_DOMAIN"
916                 },
917                 {
918                         .rid                    = DOMAIN_RID_ADMINISTRATOR,
919                         .flags                  = 0,
920                         .db_index               = SAM_DATABASE_DOMAIN,
921                         .delta_type             = NETR_DELTA_USER,
922                         .sid                    = null_sid,
923                         .name                   = NULL,
924                         .expected_error         = NT_STATUS_OK,
925                         .expected_num_results   = 1,
926                         .expected_delta_type_1  = NETR_DELTA_USER,
927                         .comment                = "NETR_DELTA_USER by rid 500"
928                 },
929                 {
930                         .rid                    = DOMAIN_RID_GUEST,
931                         .flags                  = 0,
932                         .db_index               = SAM_DATABASE_DOMAIN,
933                         .delta_type             = NETR_DELTA_USER,
934                         .sid                    = null_sid,
935                         .name                   = NULL,
936                         .expected_error         = NT_STATUS_OK,
937                         .expected_num_results   = 1,
938                         .expected_delta_type_1  = NETR_DELTA_USER,
939                         .comment                = "NETR_DELTA_USER by rid 501"
940                 },
941                 {
942                         .rid                    = 0,
943                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
944                         .db_index               = SAM_DATABASE_DOMAIN,
945                         .delta_type             = NETR_DELTA_USER,
946                         .sid                    = *sid,
947                         .name                   = NULL,
948                         .expected_error         = NT_STATUS_OK,
949                         .expected_num_results   = 1,
950                         .expected_delta_type_1  = NETR_DELTA_DELETE_USER,
951                         .comment                = "NETR_DELTA_USER by sid and flags"
952                 },
953                 {
954                         .rid                    = 0,
955                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
956                         .db_index               = SAM_DATABASE_DOMAIN,
957                         .delta_type             = NETR_DELTA_USER,
958                         .sid                    = null_sid,
959                         .name                   = NULL,
960                         .expected_error         = NT_STATUS_OK,
961                         .expected_num_results   = 1,
962                         .expected_delta_type_1  = NETR_DELTA_DELETE_USER,
963                         .comment                = "NETR_DELTA_USER by null_sid and flags"
964                 },
965                 {
966                         .rid                    = 0,
967                         .flags                  = NETR_CHANGELOG_NAME_INCLUDED,
968                         .db_index               = SAM_DATABASE_DOMAIN,
969                         .delta_type             = NETR_DELTA_USER,
970                         .sid                    = null_sid,
971                         .name                   = "administrator",
972                         .expected_error         = NT_STATUS_OK,
973                         .expected_num_results   = 1,
974                         .expected_delta_type_1  = NETR_DELTA_DELETE_USER,
975                         .comment                = "NETR_DELTA_USER by name 'administrator'"
976                 },
977                 {
978                         .rid                    = DOMAIN_RID_ADMINS,
979                         .flags                  = 0,
980                         .db_index               = SAM_DATABASE_DOMAIN,
981                         .delta_type             = NETR_DELTA_GROUP,
982                         .sid                    = null_sid,
983                         .name                   = NULL,
984                         .expected_error         = NT_STATUS_OK,
985                         .expected_num_results   = 2,
986                         .expected_delta_type_1  = NETR_DELTA_GROUP,
987                         .expected_delta_type_2  = NETR_DELTA_GROUP_MEMBER,
988                         .comment                = "NETR_DELTA_GROUP by rid 512"
989                 },
990                 {
991                         .rid                    = DOMAIN_RID_ADMINS,
992                         .flags                  = 0,
993                         .db_index               = SAM_DATABASE_DOMAIN,
994                         .delta_type             = NETR_DELTA_GROUP_MEMBER,
995                         .sid                    = null_sid,
996                         .name                   = NULL,
997                         .expected_error         = NT_STATUS_OK,
998                         .expected_num_results   = 2,
999                         .expected_delta_type_1  = NETR_DELTA_GROUP,
1000                         .expected_delta_type_2  = NETR_DELTA_GROUP_MEMBER,
1001                         .comment                = "NETR_DELTA_GROUP_MEMBER by rid 512"
1002                 },
1003
1004
1005                 /* SAM_DATABASE_BUILTIN */
1006
1007                 {
1008                         .rid                    = 0,
1009                         .flags                  = 0,
1010                         .db_index               = SAM_DATABASE_BUILTIN,
1011                         .delta_type             = NETR_DELTA_MODIFY_COUNT,
1012                         .sid                    = null_sid,
1013                         .name                   = NULL,
1014                         .expected_error         = NT_STATUS_SYNCHRONIZATION_REQUIRED,
1015                         .expected_num_results   = 0,
1016                         .comment                = "NETR_DELTA_MODIFY_COUNT"
1017                 },
1018                 {
1019                         .rid                    = 0,
1020                         .flags                  = 0,
1021                         .db_index               = SAM_DATABASE_BUILTIN,
1022                         .delta_type             = NETR_DELTA_DOMAIN,
1023                         .sid                    = null_sid,
1024                         .name                   = NULL,
1025                         .expected_error         = NT_STATUS_OK,
1026                         .expected_num_results   = 1,
1027                         .expected_delta_type_1  = NETR_DELTA_DOMAIN,
1028                         .comment                = "NETR_DELTA_DOMAIN"
1029                 },
1030                 {
1031                         .rid                    = DOMAIN_RID_ADMINISTRATOR,
1032                         .flags                  = 0,
1033                         .db_index               = SAM_DATABASE_BUILTIN,
1034                         .delta_type             = NETR_DELTA_USER,
1035                         .sid                    = null_sid,
1036                         .name                   = NULL,
1037                         .expected_error         = NT_STATUS_OK,
1038                         .expected_num_results   = 1,
1039                         .expected_delta_type_1  = NETR_DELTA_DELETE_USER,
1040                         .comment                = "NETR_DELTA_USER by rid 500"
1041                 },
1042                 {
1043                         .rid                    = 0,
1044                         .flags                  = 0,
1045                         .db_index               = SAM_DATABASE_BUILTIN,
1046                         .delta_type             = NETR_DELTA_USER,
1047                         .sid                    = null_sid,
1048                         .name                   = NULL,
1049                         .expected_error         = NT_STATUS_OK,
1050                         .expected_num_results   = 1,
1051                         .expected_delta_type_1  = NETR_DELTA_DELETE_USER,
1052                         .comment                = "NETR_DELTA_USER"
1053                 },
1054                 {
1055                         .rid                    = 544,
1056                         .flags                  = 0,
1057                         .db_index               = SAM_DATABASE_BUILTIN,
1058                         .delta_type             = NETR_DELTA_ALIAS,
1059                         .sid                    = null_sid,
1060                         .name                   = NULL,
1061                         .expected_error         = NT_STATUS_OK,
1062                         .expected_num_results   = 2,
1063                         .expected_delta_type_1  = NETR_DELTA_ALIAS,
1064                         .expected_delta_type_2  = NETR_DELTA_ALIAS_MEMBER,
1065                         .comment                = "NETR_DELTA_ALIAS by rid 544"
1066                 },
1067                 {
1068                         .rid                    = 544,
1069                         .flags                  = 0,
1070                         .db_index               = SAM_DATABASE_BUILTIN,
1071                         .delta_type             = NETR_DELTA_ALIAS_MEMBER,
1072                         .sid                    = null_sid,
1073                         .name                   = NULL,
1074                         .expected_error         = NT_STATUS_OK,
1075                         .expected_num_results   = 2,
1076                         .expected_delta_type_1  = NETR_DELTA_ALIAS,
1077                         .expected_delta_type_2  = NETR_DELTA_ALIAS_MEMBER,
1078                         .comment                = "NETR_DELTA_ALIAS_MEMBER by rid 544"
1079                 },
1080                 {
1081                         .rid                    = 544,
1082                         .flags                  = 0,
1083                         .db_index               = SAM_DATABASE_BUILTIN,
1084                         .delta_type             = 0,
1085                         .sid                    = null_sid,
1086                         .name                   = NULL,
1087                         .expected_error         = NT_STATUS_OK,
1088                         .expected_num_results   = 1,
1089                         .expected_delta_type_1  = NETR_DELTA_DOMAIN,
1090                         .comment                = "NULL DELTA by rid 544"
1091                 },
1092                 {
1093                         .rid                    = 544,
1094                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
1095                         .db_index               = SAM_DATABASE_BUILTIN,
1096                         .delta_type             = 0,
1097                         .sid                    = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
1098                         .name                   = NULL,
1099                         .expected_error         = NT_STATUS_OK,
1100                         .expected_num_results   = 1,
1101                         .expected_delta_type_1  = NETR_DELTA_DOMAIN,
1102                         .comment                = "NULL DELTA by rid 544 sid S-1-5-32-544 and flags"
1103                 },
1104                 {
1105                         .rid                    = 544,
1106                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
1107                         .db_index               = SAM_DATABASE_BUILTIN,
1108                         .delta_type             = NETR_DELTA_ALIAS,
1109                         .sid                    = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
1110                         .name                   = NULL,
1111                         .expected_error         = NT_STATUS_OK,
1112                         .expected_num_results   = 2,
1113                         .expected_delta_type_1  = NETR_DELTA_ALIAS,
1114                         .expected_delta_type_2  = NETR_DELTA_ALIAS_MEMBER,
1115                         .comment                = "NETR_DELTA_ALIAS by rid 544 and sid S-1-5-32-544 and flags"
1116                 },
1117                 {
1118                         .rid                    = 0,
1119                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
1120                         .db_index               = SAM_DATABASE_BUILTIN,
1121                         .delta_type             = NETR_DELTA_ALIAS,
1122                         .sid                    = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
1123                         .name                   = NULL,
1124                         .expected_error         = NT_STATUS_OK,
1125                         .expected_num_results   = 1,
1126                         .expected_delta_type_1  = NETR_DELTA_DELETE_ALIAS,
1127                         .comment                = "NETR_DELTA_ALIAS by sid S-1-5-32-544 and flags"
1128                 },
1129
1130                 /* SAM_DATABASE_PRIVS */
1131
1132                 {
1133                         .rid                    = 0,
1134                         .flags                  = 0,
1135                         .db_index               = SAM_DATABASE_PRIVS,
1136                         .delta_type             = 0,
1137                         .sid                    = null_sid,
1138                         .name                   = NULL,
1139                         .expected_error         = NT_STATUS_ACCESS_DENIED,
1140                         .expected_num_results   = 0,
1141                         .comment                = "NULL DELTA"
1142                 },
1143                 {
1144                         .rid                    = 0,
1145                         .flags                  = 0,
1146                         .db_index               = SAM_DATABASE_PRIVS,
1147                         .delta_type             = NETR_DELTA_MODIFY_COUNT,
1148                         .sid                    = null_sid,
1149                         .name                   = NULL,
1150                         .expected_error         = NT_STATUS_SYNCHRONIZATION_REQUIRED,
1151                         .expected_num_results   = 0,
1152                         .comment                = "NETR_DELTA_MODIFY_COUNT"
1153                 },
1154                 {
1155                         .rid                    = 0,
1156                         .flags                  = 0,
1157                         .db_index               = SAM_DATABASE_PRIVS,
1158                         .delta_type             = NETR_DELTA_POLICY,
1159                         .sid                    = null_sid,
1160                         .name                   = NULL,
1161                         .expected_error         = NT_STATUS_OK,
1162                         .expected_num_results   = 1,
1163                         .expected_delta_type_1  = NETR_DELTA_POLICY,
1164                         .comment                = "NETR_DELTA_POLICY"
1165                 },
1166                 {
1167                         .rid                    = 0,
1168                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
1169                         .db_index               = SAM_DATABASE_PRIVS,
1170                         .delta_type             = NETR_DELTA_POLICY,
1171                         .sid                    = null_sid,
1172                         .name                   = NULL,
1173                         .expected_error         = NT_STATUS_OK,
1174                         .expected_num_results   = 1,
1175                         .expected_delta_type_1  = NETR_DELTA_POLICY,
1176                         .comment                = "NETR_DELTA_POLICY by null sid and flags"
1177                 },
1178                 {
1179                         .rid                    = 0,
1180                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
1181                         .db_index               = SAM_DATABASE_PRIVS,
1182                         .delta_type             = NETR_DELTA_POLICY,
1183                         .sid                    = *dom_sid_parse_talloc(tctx, "S-1-5-32"),
1184                         .name                   = NULL,
1185                         .expected_error         = NT_STATUS_OK,
1186                         .expected_num_results   = 1,
1187                         .expected_delta_type_1  = NETR_DELTA_POLICY,
1188                         .comment                = "NETR_DELTA_POLICY by sid S-1-5-32 and flags"
1189                 },
1190                 {
1191                         .rid                    = DOMAIN_RID_ADMINISTRATOR,
1192                         .flags                  = 0,
1193                         .db_index               = SAM_DATABASE_PRIVS,
1194                         .delta_type             = NETR_DELTA_ACCOUNT,
1195                         .sid                    = null_sid,
1196                         .name                   = NULL,
1197                         .expected_error         = NT_STATUS_SYNCHRONIZATION_REQUIRED, /* strange */
1198                         .expected_num_results   = 0,
1199                         .comment                = "NETR_DELTA_ACCOUNT by rid 500"
1200                 },
1201                 {
1202                         .rid                    = 0,
1203                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
1204                         .db_index               = SAM_DATABASE_PRIVS,
1205                         .delta_type             = NETR_DELTA_ACCOUNT,
1206                         .sid                    = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
1207                         .name                   = NULL,
1208                         .expected_error         = NT_STATUS_OK,
1209                         .expected_num_results   = 1,
1210                         .expected_delta_type_1  = NETR_DELTA_ACCOUNT,
1211                         .comment                = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and flags"
1212                 },
1213                 {
1214                         .rid                    = 0,
1215                         .flags                  = NETR_CHANGELOG_SID_INCLUDED |
1216                                                   NETR_CHANGELOG_IMMEDIATE_REPL_REQUIRED,
1217                         .db_index               = SAM_DATABASE_PRIVS,
1218                         .delta_type             = NETR_DELTA_ACCOUNT,
1219                         .sid                    = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
1220                         .name                   = NULL,
1221                         .expected_error         = NT_STATUS_OK,
1222                         .expected_num_results   = 1,
1223                         .expected_delta_type_1  = NETR_DELTA_ACCOUNT,
1224                         .comment                = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and 2 flags"
1225                 },
1226                 {
1227                         .rid                    = 0,
1228                         .flags                  = NETR_CHANGELOG_SID_INCLUDED |
1229                                                   NETR_CHANGELOG_NAME_INCLUDED,
1230                         .db_index               = SAM_DATABASE_PRIVS,
1231                         .delta_type             = NETR_DELTA_ACCOUNT,
1232                         .sid                    = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
1233                         .name                   = NULL,
1234                         .expected_error         = NT_STATUS_INVALID_PARAMETER,
1235                         .expected_num_results   = 0,
1236                         .comment                = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and invalid flags"
1237                 },
1238                 {
1239                         .rid                    = DOMAIN_RID_ADMINISTRATOR,
1240                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
1241                         .db_index               = SAM_DATABASE_PRIVS,
1242                         .delta_type             = NETR_DELTA_ACCOUNT,
1243                         .sid                    = *sid,
1244                         .name                   = NULL,
1245                         .expected_error         = NT_STATUS_OK,
1246                         .expected_num_results   = 1,
1247                         .expected_delta_type_1  = NETR_DELTA_DELETE_ACCOUNT,
1248                         .comment                = "NETR_DELTA_ACCOUNT by rid 500, sid and flags"
1249                 },
1250                 {
1251                         .rid                    = 0,
1252                         .flags                  = NETR_CHANGELOG_NAME_INCLUDED,
1253                         .db_index               = SAM_DATABASE_PRIVS,
1254                         .delta_type             = NETR_DELTA_SECRET,
1255                         .sid                    = null_sid,
1256                         .name                   = "IsurelydontexistIhope",
1257                         .expected_error         = NT_STATUS_OK,
1258                         .expected_num_results   = 1,
1259                         .expected_delta_type_1  = NETR_DELTA_DELETE_SECRET,
1260                         .comment                = "NETR_DELTA_SECRET by name 'IsurelydontexistIhope' and flags"
1261                 },
1262                 {
1263                         .rid                    = 0,
1264                         .flags                  = NETR_CHANGELOG_NAME_INCLUDED,
1265                         .db_index               = SAM_DATABASE_PRIVS,
1266                         .delta_type             = NETR_DELTA_SECRET,
1267                         .sid                    = null_sid,
1268                         .name                   = "G$BCKUPKEY_P",
1269                         .expected_error         = NT_STATUS_OK,
1270                         .expected_num_results   = 1,
1271                         .expected_delta_type_1  = NETR_DELTA_SECRET,
1272                         .comment                = "NETR_DELTA_SECRET by name 'G$BCKUPKEY_P' and flags"
1273                 }
1274         };
1275
1276         ZERO_STRUCT(return_authenticator);
1277
1278         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1279         r.in.computername = TEST_MACHINE_NAME;
1280         r.in.return_authenticator = &return_authenticator;
1281         r.out.return_authenticator = &return_authenticator;
1282         r.out.delta_enum_array = &delta_enum_array;
1283
1284         for (d=0; d<3; d++) {
1285
1286                 const char *database;
1287
1288                 switch (d) {
1289                 case 0:
1290                         database = "SAM";
1291                         break;
1292                 case 1:
1293                         database = "BUILTIN";
1294                         break;
1295                 case 2:
1296                         database = "LSA";
1297                         break;
1298                 default:
1299                         break;
1300                 }
1301
1302                 torture_comment(tctx, "Testing DatabaseRedo\n");
1303
1304                 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1305                         return false;
1306                 }
1307
1308                 for (i=0;i<ARRAY_SIZE(changes);i++) {
1309
1310                         if (d != changes[i].db_index) {
1311                                 continue;
1312                         }
1313
1314                         netlogon_creds_client_authenticator(creds, &credential);
1315
1316                         r.in.credential = &credential;
1317
1318                         e.serial_number1        = 0;
1319                         e.serial_number2        = 0;
1320                         e.object_rid            = changes[i].rid;
1321                         e.flags                 = changes[i].flags;
1322                         e.db_index              = changes[i].db_index;
1323                         e.delta_type            = changes[i].delta_type;
1324
1325                         switch (changes[i].flags & (NETR_CHANGELOG_NAME_INCLUDED | NETR_CHANGELOG_SID_INCLUDED)) {
1326                         case NETR_CHANGELOG_SID_INCLUDED:
1327                                 e.object.object_sid             = changes[i].sid;
1328                                 break;
1329                         case NETR_CHANGELOG_NAME_INCLUDED:
1330                                 e.object.object_name            = changes[i].name;
1331                                 break;
1332                         default:
1333                                 break;
1334                         }
1335
1336                         r.in.change_log_entry = e;
1337
1338                         torture_comment(tctx, "Testing DatabaseRedo with database %s and %s\n",
1339                                 database, changes[i].comment);
1340
1341                         status = dcerpc_netr_DatabaseRedo(p, tctx, &r);
1342                         if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
1343                                 return true;
1344                         }
1345
1346                         torture_assert_ntstatus_equal(tctx, status, changes[i].expected_error, changes[i].comment);
1347                         if (delta_enum_array) {
1348                                 torture_assert_int_equal(tctx,
1349                                         delta_enum_array->num_deltas,
1350                                         changes[i].expected_num_results,
1351                                         changes[i].comment);
1352                                 if (delta_enum_array->num_deltas > 0) {
1353                                         torture_assert_int_equal(tctx,
1354                                                 delta_enum_array->delta_enum[0].delta_type,
1355                                                 changes[i].expected_delta_type_1,
1356                                                 changes[i].comment);
1357                                 }
1358                                 if (delta_enum_array->num_deltas > 1) {
1359                                         torture_assert_int_equal(tctx,
1360                                                 delta_enum_array->delta_enum[1].delta_type,
1361                                                 changes[i].expected_delta_type_2,
1362                                                 changes[i].comment);
1363                                 }
1364                         }
1365
1366                         if (!netlogon_creds_client_check(creds, &return_authenticator.cred)) {
1367                                 torture_comment(tctx, "Credential chaining failed\n");
1368                                 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1369                                         return false;
1370                                 }
1371                         }
1372                 }
1373         }
1374         }
1375
1376         return true;
1377 }
1378
1379 /*
1380   try a netlogon AccountDeltas
1381 */
1382 static bool test_AccountDeltas(struct torture_context *tctx, 
1383                                struct dcerpc_pipe *p,
1384                                struct cli_credentials *machine_credentials)
1385 {
1386         NTSTATUS status;
1387         struct netr_AccountDeltas r;
1388         struct netlogon_creds_CredentialState *creds;
1389
1390         struct netr_AccountBuffer buffer;
1391         uint32_t count_returned = 0;
1392         uint32_t total_entries = 0;
1393         struct netr_UAS_INFO_0 recordid;
1394         struct netr_Authenticator return_authenticator;
1395
1396         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1397                 return false;
1398         }
1399
1400         ZERO_STRUCT(return_authenticator);
1401
1402         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1403         r.in.computername = TEST_MACHINE_NAME;
1404         r.in.return_authenticator = &return_authenticator;
1405         netlogon_creds_client_authenticator(creds, &r.in.credential);
1406         ZERO_STRUCT(r.in.uas);
1407         r.in.count=10;
1408         r.in.level=0;
1409         r.in.buffersize=100;
1410         r.out.buffer = &buffer;
1411         r.out.count_returned = &count_returned;
1412         r.out.total_entries = &total_entries;
1413         r.out.recordid = &recordid;
1414         r.out.return_authenticator = &return_authenticator;
1415
1416         /* w2k3 returns "NOT IMPLEMENTED" for this call */
1417         status = dcerpc_netr_AccountDeltas(p, tctx, &r);
1418         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "AccountDeltas");
1419
1420         return true;
1421 }
1422
1423 /*
1424   try a netlogon AccountSync
1425 */
1426 static bool test_AccountSync(struct torture_context *tctx, struct dcerpc_pipe *p, 
1427                              struct cli_credentials *machine_credentials)
1428 {
1429         NTSTATUS status;
1430         struct netr_AccountSync r;
1431         struct netlogon_creds_CredentialState *creds;
1432
1433         struct netr_AccountBuffer buffer;
1434         uint32_t count_returned = 0;
1435         uint32_t total_entries = 0;
1436         uint32_t next_reference = 0;
1437         struct netr_UAS_INFO_0 recordid;
1438         struct netr_Authenticator return_authenticator;
1439
1440         ZERO_STRUCT(recordid);
1441         ZERO_STRUCT(return_authenticator);
1442
1443         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1444                 return false;
1445         }
1446
1447         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1448         r.in.computername = TEST_MACHINE_NAME;
1449         r.in.return_authenticator = &return_authenticator;
1450         netlogon_creds_client_authenticator(creds, &r.in.credential);
1451         r.in.recordid = &recordid;
1452         r.in.reference=0;
1453         r.in.level=0;
1454         r.in.buffersize=100;
1455         r.out.buffer = &buffer;
1456         r.out.count_returned = &count_returned;
1457         r.out.total_entries = &total_entries;
1458         r.out.next_reference = &next_reference;
1459         r.out.recordid = &recordid;
1460         r.out.return_authenticator = &return_authenticator;
1461
1462         /* w2k3 returns "NOT IMPLEMENTED" for this call */
1463         status = dcerpc_netr_AccountSync(p, tctx, &r);
1464         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "AccountSync");
1465
1466         return true;
1467 }
1468
1469 /*
1470   try a netlogon GetDcName
1471 */
1472 static bool test_GetDcName(struct torture_context *tctx, 
1473                            struct dcerpc_pipe *p)
1474 {
1475         NTSTATUS status;
1476         struct netr_GetDcName r;
1477         const char *dcname = NULL;
1478
1479         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1480         r.in.domainname = lp_workgroup(tctx->lp_ctx);
1481         r.out.dcname = &dcname;
1482
1483         status = dcerpc_netr_GetDcName(p, tctx, &r);
1484         torture_assert_ntstatus_ok(tctx, status, "GetDcName");
1485         torture_assert_werr_ok(tctx, r.out.result, "GetDcName");
1486
1487         torture_comment(tctx, "\tDC is at '%s'\n", dcname);
1488
1489         return true;
1490 }
1491
1492 /*
1493   try a netlogon LogonControl 
1494 */
1495 static bool test_LogonControl(struct torture_context *tctx, 
1496                               struct dcerpc_pipe *p)
1497 {
1498         NTSTATUS status;
1499         struct netr_LogonControl r;
1500         union netr_CONTROL_QUERY_INFORMATION query;
1501         int i;
1502
1503         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1504         r.in.function_code = 1;
1505         r.out.query = &query;
1506
1507         for (i=1;i<4;i++) {
1508                 r.in.level = i;
1509
1510                 torture_comment(tctx, "Testing LogonControl level %d\n", i);
1511
1512                 status = dcerpc_netr_LogonControl(p, tctx, &r);
1513                 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1514         }
1515
1516         return true;
1517 }
1518
1519
1520 /*
1521   try a netlogon GetAnyDCName
1522 */
1523 static bool test_GetAnyDCName(struct torture_context *tctx, 
1524                               struct dcerpc_pipe *p)
1525 {
1526         NTSTATUS status;
1527         struct netr_GetAnyDCName r;
1528         const char *dcname = NULL;
1529
1530         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1531         r.in.domainname = lp_workgroup(tctx->lp_ctx);
1532         r.out.dcname = &dcname;
1533
1534         status = dcerpc_netr_GetAnyDCName(p, tctx, &r);
1535         torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
1536         torture_assert_werr_ok(tctx, r.out.result, "GetAnyDCName");
1537
1538         if (dcname) {
1539             torture_comment(tctx, "\tDC is at '%s'\n", dcname);
1540         }
1541
1542         return true;
1543 }
1544
1545
1546 /*
1547   try a netlogon LogonControl2
1548 */
1549 static bool test_LogonControl2(struct torture_context *tctx, 
1550                                struct dcerpc_pipe *p)
1551 {
1552         NTSTATUS status;
1553         struct netr_LogonControl2 r;
1554         union netr_CONTROL_DATA_INFORMATION data;
1555         union netr_CONTROL_QUERY_INFORMATION query;
1556         int i;
1557
1558         data.domain = lp_workgroup(tctx->lp_ctx);
1559
1560         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1561
1562         r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
1563         r.in.data = &data;
1564         r.out.query = &query;
1565
1566         for (i=1;i<4;i++) {
1567                 r.in.level = i;
1568
1569                 torture_comment(tctx, "Testing LogonControl2 level %d function %d\n", 
1570                        i, r.in.function_code);
1571
1572                 status = dcerpc_netr_LogonControl2(p, tctx, &r);
1573                 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1574         }
1575
1576         data.domain = lp_workgroup(tctx->lp_ctx);
1577
1578         r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
1579         r.in.data = &data;
1580
1581         for (i=1;i<4;i++) {
1582                 r.in.level = i;
1583
1584                 torture_comment(tctx, "Testing LogonControl2 level %d function %d\n", 
1585                        i, r.in.function_code);
1586
1587                 status = dcerpc_netr_LogonControl2(p, tctx, &r);
1588                 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1589         }
1590
1591         data.domain = lp_workgroup(tctx->lp_ctx);
1592
1593         r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
1594         r.in.data = &data;
1595
1596         for (i=1;i<4;i++) {
1597                 r.in.level = i;
1598
1599                 torture_comment(tctx, "Testing LogonControl2 level %d function %d\n", 
1600                        i, r.in.function_code);
1601
1602                 status = dcerpc_netr_LogonControl2(p, tctx, &r);
1603                 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1604         }
1605
1606         data.debug_level = ~0;
1607
1608         r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
1609         r.in.data = &data;
1610
1611         for (i=1;i<4;i++) {
1612                 r.in.level = i;
1613
1614                 torture_comment(tctx, "Testing LogonControl2 level %d function %d\n", 
1615                        i, r.in.function_code);
1616
1617                 status = dcerpc_netr_LogonControl2(p, tctx, &r);
1618                 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1619         }
1620
1621         return true;
1622 }
1623
1624 /*
1625   try a netlogon DatabaseSync2
1626 */
1627 static bool test_DatabaseSync2(struct torture_context *tctx, 
1628                                struct dcerpc_pipe *p,
1629                                struct cli_credentials *machine_credentials)
1630 {
1631         NTSTATUS status;
1632         struct netr_DatabaseSync2 r;
1633         struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
1634         struct netr_Authenticator return_authenticator, credential;
1635
1636         struct netlogon_creds_CredentialState *creds;
1637         const uint32_t database_ids[] = {0, 1, 2}; 
1638         int i;
1639
1640         if (!test_SetupCredentials2(p, tctx, NETLOGON_NEG_AUTH2_FLAGS, 
1641                                     machine_credentials,
1642                                     SEC_CHAN_BDC, &creds)) {
1643                 return false;
1644         }
1645
1646         ZERO_STRUCT(return_authenticator);
1647
1648         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1649         r.in.computername = TEST_MACHINE_NAME;
1650         r.in.preferredmaximumlength = (uint32_t)-1;
1651         r.in.return_authenticator = &return_authenticator;
1652         r.out.return_authenticator = &return_authenticator;
1653         r.out.delta_enum_array = &delta_enum_array;
1654
1655         for (i=0;i<ARRAY_SIZE(database_ids);i++) {
1656
1657                 uint32_t sync_context = 0;
1658
1659                 r.in.database_id = database_ids[i];
1660                 r.in.sync_context = &sync_context;
1661                 r.out.sync_context = &sync_context;
1662                 r.in.restart_state = 0;
1663
1664                 torture_comment(tctx, "Testing DatabaseSync2 of id %d\n", r.in.database_id);
1665
1666                 do {
1667                         netlogon_creds_client_authenticator(creds, &credential);
1668
1669                         r.in.credential = &credential;
1670
1671                         status = dcerpc_netr_DatabaseSync2(p, tctx, &r);
1672                         if (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
1673                             break;
1674
1675                         /* Native mode servers don't do this */
1676                         if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
1677                                 return true;
1678                         }
1679
1680                         torture_assert_ntstatus_ok(tctx, status, "DatabaseSync2");
1681
1682                         if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
1683                                 torture_comment(tctx, "Credential chaining failed\n");
1684                         }
1685
1686                 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
1687         }
1688
1689         return true;
1690 }
1691
1692
1693 /*
1694   try a netlogon LogonControl2Ex
1695 */
1696 static bool test_LogonControl2Ex(struct torture_context *tctx, 
1697                                  struct dcerpc_pipe *p)
1698 {
1699         NTSTATUS status;
1700         struct netr_LogonControl2Ex r;
1701         union netr_CONTROL_DATA_INFORMATION data;
1702         union netr_CONTROL_QUERY_INFORMATION query;
1703         int i;
1704
1705         data.domain = lp_workgroup(tctx->lp_ctx);
1706
1707         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1708
1709         r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
1710         r.in.data = &data;
1711         r.out.query = &query;
1712
1713         for (i=1;i<4;i++) {
1714                 r.in.level = i;
1715
1716                 torture_comment(tctx, "Testing LogonControl2Ex level %d function %d\n", 
1717                        i, r.in.function_code);
1718
1719                 status = dcerpc_netr_LogonControl2Ex(p, tctx, &r);
1720                 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1721         }
1722
1723         data.domain = lp_workgroup(tctx->lp_ctx);
1724
1725         r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
1726         r.in.data = &data;
1727
1728         for (i=1;i<4;i++) {
1729                 r.in.level = i;
1730
1731                 torture_comment(tctx, "Testing LogonControl2Ex level %d function %d\n", 
1732                        i, r.in.function_code);
1733
1734                 status = dcerpc_netr_LogonControl2Ex(p, tctx, &r);
1735                 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1736         }
1737
1738         data.domain = lp_workgroup(tctx->lp_ctx);
1739
1740         r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
1741         r.in.data = &data;
1742
1743         for (i=1;i<4;i++) {
1744                 r.in.level = i;
1745
1746                 torture_comment(tctx, "Testing LogonControl2Ex level %d function %d\n", 
1747                        i, r.in.function_code);
1748
1749                 status = dcerpc_netr_LogonControl2Ex(p, tctx, &r);
1750                 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1751         }
1752
1753         data.debug_level = ~0;
1754
1755         r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
1756         r.in.data = &data;
1757
1758         for (i=1;i<4;i++) {
1759                 r.in.level = i;
1760
1761                 torture_comment(tctx, "Testing LogonControl2Ex level %d function %d\n", 
1762                        i, r.in.function_code);
1763
1764                 status = dcerpc_netr_LogonControl2Ex(p, tctx, &r);
1765                 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1766         }
1767
1768         return true;
1769 }
1770
1771 static bool test_netr_DsRGetForestTrustInformation(struct torture_context *tctx, 
1772                                                    struct dcerpc_pipe *p, const char *trusted_domain_name) 
1773 {
1774         NTSTATUS status;
1775         struct netr_DsRGetForestTrustInformation r;
1776         struct lsa_ForestTrustInformation info, *info_ptr;
1777
1778         info_ptr = &info;
1779
1780         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1781         r.in.trusted_domain_name = trusted_domain_name;
1782         r.in.flags = 0;
1783         r.out.forest_trust_info = &info_ptr;
1784
1785         torture_comment(tctx ,"Testing netr_DsRGetForestTrustInformation\n");
1786
1787         status = dcerpc_netr_DsRGetForestTrustInformation(p, tctx, &r);
1788         torture_assert_ntstatus_ok(tctx, status, "DsRGetForestTrustInformation");
1789         torture_assert_werr_ok(tctx, r.out.result, "DsRGetForestTrustInformation");
1790
1791         return true;
1792 }
1793
1794 /*
1795   try a netlogon netr_DsrEnumerateDomainTrusts
1796 */
1797 static bool test_DsrEnumerateDomainTrusts(struct torture_context *tctx, 
1798                                           struct dcerpc_pipe *p)
1799 {
1800         NTSTATUS status;
1801         struct netr_DsrEnumerateDomainTrusts r;
1802         struct netr_DomainTrustList trusts;
1803         int i;
1804
1805         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1806         r.in.trust_flags = 0x3f;
1807         r.out.trusts = &trusts;
1808
1809         status = dcerpc_netr_DsrEnumerateDomainTrusts(p, tctx, &r);
1810         torture_assert_ntstatus_ok(tctx, status, "DsrEnumerateDomaintrusts");
1811         torture_assert_werr_ok(tctx, r.out.result, "DsrEnumerateDomaintrusts");
1812
1813         /* when trusted_domain_name is NULL, netr_DsRGetForestTrustInformation
1814          * will show non-forest trusts and all UPN suffixes of the own forest
1815          * as LSA_FOREST_TRUST_TOP_LEVEL_NAME types */
1816
1817         if (r.out.trusts->count) {
1818                 if (!test_netr_DsRGetForestTrustInformation(tctx, p, NULL)) {
1819                         return false;
1820                 }
1821         }
1822
1823         for (i=0; i<r.out.trusts->count; i++) {
1824
1825                 /* get info for transitive forest trusts */
1826
1827                 if (r.out.trusts->array[i].trust_attributes & NETR_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) {
1828                         if (!test_netr_DsRGetForestTrustInformation(tctx, p, 
1829                                                                     r.out.trusts->array[i].dns_name)) {
1830                                 return false;
1831                         }
1832                 }
1833         }
1834
1835         return true;
1836 }
1837
1838 static bool test_netr_NetrEnumerateTrustedDomains(struct torture_context *tctx,
1839                                                   struct dcerpc_pipe *p)
1840 {
1841         NTSTATUS status;
1842         struct netr_NetrEnumerateTrustedDomains r;
1843         struct netr_Blob trusted_domains_blob;
1844
1845         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1846         r.out.trusted_domains_blob = &trusted_domains_blob;
1847
1848         status = dcerpc_netr_NetrEnumerateTrustedDomains(p, tctx, &r);
1849         torture_assert_ntstatus_ok(tctx, status, "netr_NetrEnumerateTrustedDomains");
1850         torture_assert_werr_ok(tctx, r.out.result, "NetrEnumerateTrustedDomains");
1851
1852         return true;
1853 }
1854
1855 static bool test_netr_NetrEnumerateTrustedDomainsEx(struct torture_context *tctx,
1856                                                     struct dcerpc_pipe *p)
1857 {
1858         NTSTATUS status;
1859         struct netr_NetrEnumerateTrustedDomainsEx r;
1860         struct netr_DomainTrustList dom_trust_list;
1861
1862         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1863         r.out.dom_trust_list = &dom_trust_list;
1864
1865         status = dcerpc_netr_NetrEnumerateTrustedDomainsEx(p, tctx, &r);
1866         torture_assert_ntstatus_ok(tctx, status, "netr_NetrEnumerateTrustedDomainsEx");
1867         torture_assert_werr_ok(tctx, r.out.result, "NetrEnumerateTrustedDomainsEx");
1868
1869         return true;
1870 }
1871
1872
1873 static bool test_netr_DsRGetSiteName(struct dcerpc_pipe *p, struct torture_context *tctx,
1874                                      const char *computer_name, 
1875                                      const char *expected_site) 
1876 {
1877         NTSTATUS status;
1878         struct netr_DsRGetSiteName r;
1879         const char *site = NULL;
1880
1881         if (torture_setting_bool(tctx, "samba4", false))
1882                 torture_skip(tctx, "skipping DsRGetSiteName test against Samba4");
1883
1884         r.in.computer_name              = computer_name;
1885         r.out.site                      = &site;
1886         torture_comment(tctx, "Testing netr_DsRGetSiteName\n");
1887
1888         status = dcerpc_netr_DsRGetSiteName(p, tctx, &r);
1889         torture_assert_ntstatus_ok(tctx, status, "DsRGetSiteName");
1890         torture_assert_werr_ok(tctx, r.out.result, "DsRGetSiteName");
1891         torture_assert_str_equal(tctx, expected_site, site, "netr_DsRGetSiteName");
1892
1893         r.in.computer_name              = talloc_asprintf(tctx, "\\\\%s", computer_name);
1894         torture_comment(tctx, 
1895                         "Testing netr_DsRGetSiteName with broken computer name: %s\n", r.in.computer_name);
1896
1897         status = dcerpc_netr_DsRGetSiteName(p, tctx, &r);
1898         torture_assert_ntstatus_ok(tctx, status, "DsRGetSiteName");
1899         torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_COMPUTERNAME, "netr_DsRGetSiteName");
1900
1901         return true;
1902 }
1903
1904 /*
1905   try a netlogon netr_DsRGetDCName
1906 */
1907 static bool test_netr_DsRGetDCName(struct torture_context *tctx, 
1908                                    struct dcerpc_pipe *p)
1909 {
1910         NTSTATUS status;
1911         struct netr_DsRGetDCName r;
1912         struct netr_DsRGetDCNameInfo *info = NULL;
1913
1914         r.in.server_unc         = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1915         r.in.domain_name        = talloc_asprintf(tctx, "%s", lp_realm(tctx->lp_ctx));
1916         r.in.domain_guid        = NULL;
1917         r.in.site_guid          = NULL;
1918         r.in.flags              = DS_RETURN_DNS_NAME;
1919         r.out.info              = &info;
1920
1921         status = dcerpc_netr_DsRGetDCName(p, tctx, &r);
1922         torture_assert_ntstatus_ok(tctx, status, "DsRGetDCName");
1923         torture_assert_werr_ok(tctx, r.out.result, "DsRGetDCName");
1924         return test_netr_DsRGetSiteName(p, tctx, 
1925                                        info->dc_unc,
1926                                        info->dc_site_name);
1927 }
1928
1929 /*
1930   try a netlogon netr_DsRGetDCNameEx
1931 */
1932 static bool test_netr_DsRGetDCNameEx(struct torture_context *tctx, 
1933                                      struct dcerpc_pipe *p)
1934 {
1935         NTSTATUS status;
1936         struct netr_DsRGetDCNameEx r;
1937         struct netr_DsRGetDCNameInfo *info = NULL;
1938
1939         r.in.server_unc         = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1940         r.in.domain_name        = talloc_asprintf(tctx, "%s", lp_realm(tctx->lp_ctx));
1941         r.in.domain_guid        = NULL;
1942         r.in.site_name          = NULL;
1943         r.in.flags              = DS_RETURN_DNS_NAME;
1944         r.out.info              = &info;
1945
1946         status = dcerpc_netr_DsRGetDCNameEx(p, tctx, &r);
1947         torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx");
1948         torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx");
1949
1950         return test_netr_DsRGetSiteName(p, tctx, info->dc_unc,
1951                                         info->dc_site_name);
1952 }
1953
1954 /*
1955   try a netlogon netr_DsRGetDCNameEx2
1956 */
1957 static bool test_netr_DsRGetDCNameEx2(struct torture_context *tctx, 
1958                                       struct dcerpc_pipe *p)
1959 {
1960         NTSTATUS status;
1961         struct netr_DsRGetDCNameEx2 r;
1962         struct netr_DsRGetDCNameInfo *info = NULL;
1963
1964         r.in.server_unc         = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1965         r.in.client_account     = NULL;
1966         r.in.mask               = 0x00000000;
1967         r.in.domain_name        = talloc_asprintf(tctx, "%s", lp_realm(tctx->lp_ctx));
1968         r.in.domain_guid        = NULL;
1969         r.in.site_name          = NULL;
1970         r.in.flags              = DS_RETURN_DNS_NAME;
1971         r.out.info              = &info;
1972
1973         torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 without client account\n");
1974
1975         status = dcerpc_netr_DsRGetDCNameEx2(p, tctx, &r);
1976         torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
1977         torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
1978
1979         torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 with client acount\n");
1980         r.in.client_account     = TEST_MACHINE_NAME"$";
1981         r.in.mask               = ACB_SVRTRUST;
1982         r.in.flags              = DS_RETURN_FLAT_NAME;
1983         r.out.info              = &info;
1984
1985         status = dcerpc_netr_DsRGetDCNameEx2(p, tctx, &r);
1986         torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
1987         torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
1988         return test_netr_DsRGetSiteName(p, tctx, info->dc_unc,
1989                                         info->dc_site_name);
1990 }
1991
1992 static bool test_netr_DsrGetDcSiteCoverageW(struct torture_context *tctx, 
1993                                             struct dcerpc_pipe *p)
1994 {
1995         NTSTATUS status;
1996         struct netr_DsrGetDcSiteCoverageW r;
1997         struct DcSitesCtr *ctr = NULL;
1998
1999         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2000         r.out.ctr = &ctr;
2001
2002         status = dcerpc_netr_DsrGetDcSiteCoverageW(p, tctx, &r);
2003         torture_assert_ntstatus_ok(tctx, status, "failed");
2004         torture_assert_werr_ok(tctx, r.out.result, "failed");
2005
2006         return true;
2007 }
2008
2009 static bool test_netr_DsRAddressToSitenamesW(struct torture_context *tctx,
2010                                              struct dcerpc_pipe *p)
2011 {
2012         NTSTATUS status;
2013         struct netr_DsRAddressToSitenamesW r;
2014         struct netr_DsRAddress addr;
2015         struct netr_DsRAddressToSitenamesWCtr *ctr;
2016
2017         ctr = talloc(tctx, struct netr_DsRAddressToSitenamesWCtr);
2018
2019         addr.size = 16;
2020         addr.buffer = talloc_zero_array(tctx, uint8_t, addr.size);
2021
2022         addr.buffer[0] = 2; /* AF_INET */
2023         addr.buffer[4] = 127;
2024         addr.buffer[5] = 0;
2025         addr.buffer[6] = 0;
2026         addr.buffer[7] = 1;
2027
2028         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2029         r.in.count = 1;
2030         r.in.addresses = talloc_zero_array(tctx, struct netr_DsRAddress, r.in.count);
2031         r.in.addresses[0] = addr;
2032         r.out.ctr = &ctr;
2033
2034         status = dcerpc_netr_DsRAddressToSitenamesW(p, tctx, &r);
2035         torture_assert_ntstatus_ok(tctx, status, "failed");
2036         torture_assert_werr_ok(tctx, r.out.result, "failed");
2037
2038         return true;
2039 }
2040
2041 static bool test_netr_DsRAddressToSitenamesExW(struct torture_context *tctx,
2042                                                struct dcerpc_pipe *p)
2043 {
2044         NTSTATUS status;
2045         struct netr_DsRAddressToSitenamesExW r;
2046         struct netr_DsRAddress addr;
2047         struct netr_DsRAddressToSitenamesExWCtr *ctr;
2048
2049         ctr = talloc(tctx, struct netr_DsRAddressToSitenamesExWCtr);
2050
2051         addr.size = 16;
2052         addr.buffer = talloc_zero_array(tctx, uint8_t, addr.size);
2053
2054         addr.buffer[0] = 2; /* AF_INET */
2055         addr.buffer[4] = 127;
2056         addr.buffer[5] = 0;
2057         addr.buffer[6] = 0;
2058         addr.buffer[7] = 1;
2059
2060         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2061         r.in.count = 1;
2062         r.in.addresses = talloc_zero_array(tctx, struct netr_DsRAddress, r.in.count);
2063         r.in.addresses[0] = addr;
2064         r.out.ctr = &ctr;
2065
2066         status = dcerpc_netr_DsRAddressToSitenamesExW(p, tctx, &r);
2067         torture_assert_ntstatus_ok(tctx, status, "failed");
2068         torture_assert_werr_ok(tctx, r.out.result, "failed");
2069
2070         return true;
2071 }
2072
2073 static bool test_netr_ServerGetTrustInfo(struct torture_context *tctx,
2074                                          struct dcerpc_pipe *p,
2075                                          struct cli_credentials *machine_credentials)
2076 {
2077         NTSTATUS status;
2078         struct netr_ServerGetTrustInfo r;
2079
2080         struct netr_Authenticator a;
2081         struct netr_Authenticator return_authenticator;
2082         struct samr_Password new_owf_password;
2083         struct samr_Password old_owf_password;
2084         struct netr_TrustInfo *trust_info;
2085
2086         struct netlogon_creds_CredentialState *creds;
2087
2088         if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
2089                                     machine_credentials, &creds)) {
2090                 return false;
2091         }
2092
2093         netlogon_creds_client_authenticator(creds, &a);
2094
2095         r.in.server_name                = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2096         r.in.account_name               = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
2097         r.in.secure_channel_type        = SEC_CHAN_BDC;
2098         r.in.computer_name              = TEST_MACHINE_NAME;
2099         r.in.credential                 = &a;
2100
2101         r.out.return_authenticator      = &return_authenticator;
2102         r.out.new_owf_password          = &new_owf_password;
2103         r.out.old_owf_password          = &old_owf_password;
2104         r.out.trust_info                = &trust_info;
2105
2106         status = dcerpc_netr_ServerGetTrustInfo(p, tctx, &r);
2107         torture_assert_ntstatus_ok(tctx, status, "failed");
2108         torture_assert(tctx, netlogon_creds_client_check(creds, &return_authenticator.cred), "Credential chaining failed");
2109
2110         return true;
2111 }
2112
2113
2114 static bool test_GetDomainInfo(struct torture_context *tctx, 
2115                                struct dcerpc_pipe *p,
2116                                struct cli_credentials *machine_credentials)
2117 {
2118         NTSTATUS status;
2119         struct netr_LogonGetDomainInfo r;
2120         struct netr_WorkstationInformation q1;
2121         struct netr_Authenticator a;
2122         struct netlogon_creds_CredentialState *creds;
2123         struct netr_OsVersion os;
2124         union netr_WorkstationInfo query;
2125         union netr_DomainInfo info;
2126         const char* const attrs[] = { "dNSHostName", "operatingSystem",
2127                 "operatingSystemServicePack", "operatingSystemVersion",
2128                 "servicePrincipalName", NULL };
2129         char *url;
2130         struct ldb_context *sam_ctx;
2131         struct ldb_message **res;
2132         struct ldb_message_element *spn_el;
2133         int ret, i;
2134         char *version_str;
2135         const char *old_dnsname;
2136         char **spns = NULL;
2137         int num_spns = 0;
2138         char *temp_str;
2139
2140         torture_comment(tctx, "Testing netr_LogonGetDomainInfo\n");
2141
2142         if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS, 
2143                                     machine_credentials, &creds)) {
2144                 return false;
2145         }
2146
2147         /* Set up connection to SAMDB on DC */
2148         url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
2149         sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
2150                                    NULL,
2151                                    cmdline_credentials,
2152                                    0, NULL);
2153
2154         torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
2155
2156
2157         torture_comment(tctx, "Testing netr_LogonGetDomainInfo 1st call (no variation of DNS hostname)\n");
2158         netlogon_creds_client_authenticator(creds, &a);
2159
2160         ZERO_STRUCT(r);
2161         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2162         r.in.computer_name = TEST_MACHINE_NAME;
2163         r.in.credential = &a;
2164         r.in.level = 1;
2165         r.in.return_authenticator = &a;
2166         r.in.query = &query;
2167         r.out.return_authenticator = &a;
2168         r.out.info = &info;
2169
2170         ZERO_STRUCT(os);
2171         os.os.MajorVersion = SAMBA_VERSION_MAJOR;
2172         os.os.MinorVersion = SAMBA_VERSION_MINOR;
2173         os.os.BuildNumber = SAMBA_VERSION_RELEASE;
2174         os.os.CSDVersion = "Service Pack 1";
2175         os.os.ServicePackMajor = 1;
2176         os.os.ServicePackMinor = 0;
2177         os.os.SuiteMask = NETR_VER_SUITE_SINGLEUSERTS;
2178         os.os.ProductType = NETR_VER_NT_SERVER;
2179         os.os.Reserved = 0;
2180
2181         version_str = talloc_asprintf(tctx, "%d.%d (%d)", os.os.MajorVersion,
2182                 os.os.MinorVersion, os.os.BuildNumber);
2183
2184         ZERO_STRUCT(q1);
2185         q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
2186                 TEST_MACHINE_DNS_SUFFIX);
2187         q1.sitename = "Default-First-Site-Name";
2188         q1.os_version.os = &os;
2189         q1.os_name.string = "UNIX/Linux or similar";
2190
2191         /* The workstation handles the "servicePrincipalName" and DNS hostname
2192            updates */
2193         q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
2194
2195         query.workstation_info = &q1;
2196
2197         /* Gets back the old DNS hostname in AD */
2198         ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
2199                 "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
2200         old_dnsname =
2201                 ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL);
2202
2203         /* Gets back the "servicePrincipalName"s in AD */
2204         spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
2205         if (spn_el != NULL) {
2206                 for (i=0; i < spn_el->num_values; i++) {
2207                         spns = talloc_realloc(tctx, spns, char *, i + 1);
2208                         spns[i] = (char *) spn_el->values[i].data;
2209                 }
2210                 num_spns = i;
2211         }
2212
2213         status = dcerpc_netr_LogonGetDomainInfo(p, tctx, &r);
2214         torture_assert_ntstatus_ok(tctx, status, "netr_LogonGetDomainInfo");
2215         torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
2216
2217         msleep(250);
2218
2219         /* AD workstation infos entry check */
2220         ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
2221                 "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
2222         torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
2223         torture_assert_str_equal(tctx,
2224                 ldb_msg_find_attr_as_string(res[0], "operatingSystem", NULL),
2225                 q1.os_name.string, "'operatingSystem' wrong!");
2226         torture_assert_str_equal(tctx,
2227                 ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL),
2228                 os.os.CSDVersion, "'operatingSystemServicePack' wrong!");
2229         torture_assert_str_equal(tctx,
2230                 ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL),
2231                 version_str, "'operatingSystemVersion' wrong!");
2232
2233         if (old_dnsname != NULL) {
2234                 /* If before a DNS hostname was set then it should remain
2235                    the same in combination with the "servicePrincipalName"s.
2236                    The DNS hostname should also be returned by our
2237                    "LogonGetDomainInfo" call (in the domain info structure). */
2238
2239                 torture_assert_str_equal(tctx,
2240                         ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL),
2241                         old_dnsname, "'DNS hostname' was not set!");
2242
2243                 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
2244                 torture_assert(tctx, ((spns != NULL) && (spn_el != NULL)),
2245                         "'servicePrincipalName's not set!");
2246                 torture_assert(tctx, spn_el->num_values == num_spns,
2247                         "'servicePrincipalName's incorrect!");
2248                 for (i=0; (i < spn_el->num_values) && (i < num_spns); i++)
2249                         torture_assert_str_equal(tctx,
2250                                 (char *) spn_el->values[i].data,
2251                                 spns[i], "'servicePrincipalName's incorrect!");
2252
2253                 torture_assert_str_equal(tctx,
2254                         info.domain_info->dns_hostname.string,
2255                         old_dnsname,
2256                         "Out 'DNS hostname' doesn't match the old one!");
2257         } else {
2258                 /* If no DNS hostname was set then also now none should be set,
2259                    the "servicePrincipalName"s should remain empty and no DNS
2260                    hostname should be returned by our "LogonGetDomainInfo"
2261                    call (in the domain info structure). */
2262
2263                 torture_assert(tctx,
2264                         ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL) == NULL,
2265                         "'DNS hostname' was set!");
2266
2267                 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
2268                 torture_assert(tctx, ((spns == NULL) && (spn_el == NULL)),
2269                         "'servicePrincipalName's were set!");
2270
2271                 torture_assert(tctx,
2272                         info.domain_info->dns_hostname.string == NULL,
2273                         "Out 'DNS host name' was set!");
2274         }
2275
2276         /* Checks "workstation flags" */
2277         torture_assert(tctx,
2278                 info.domain_info->workstation_flags
2279                 == NETR_WS_FLAG_HANDLES_SPN_UPDATE,
2280                 "Out 'workstation flags' don't match!");
2281
2282
2283         torture_comment(tctx, "Testing netr_LogonGetDomainInfo 2nd call (variation of DNS hostname)\n");
2284         netlogon_creds_client_authenticator(creds, &a);
2285
2286         /* Wipe out the osVersion, and prove which values still 'stick' */
2287         q1.os_version.os = NULL;
2288
2289         /* Change also the DNS hostname to test differences in behaviour */
2290         q1.dns_hostname = talloc_asprintf(tctx, "%s.newdomain",
2291                 TEST_MACHINE_NAME);
2292
2293         /* Let the DC handle the "servicePrincipalName" and DNS hostname
2294            updates */
2295         q1.workstation_flags = 0;
2296
2297         status = dcerpc_netr_LogonGetDomainInfo(p, tctx, &r);
2298         torture_assert_ntstatus_ok(tctx, status, "netr_LogonGetDomainInfo");
2299         torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
2300
2301         msleep(250);
2302
2303         /* AD workstation infos entry check */
2304         ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
2305                 "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
2306         torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
2307         torture_assert_str_equal(tctx,
2308                 ldb_msg_find_attr_as_string(res[0], "operatingSystem", NULL),
2309                 q1.os_name.string, "'operatingSystem' should stick!");
2310         torture_assert(tctx,
2311                 ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL) == NULL,
2312                  "'operatingSystemServicePack' shouldn't stick!");
2313         torture_assert(tctx,
2314                 ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL) == NULL,
2315                 "'operatingSystemVersion' shouldn't stick!");
2316
2317         /* The DNS host name should have been updated now by the server */
2318         torture_assert_str_equal(tctx,
2319                 ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL),
2320                 q1.dns_hostname, "'DNS host name' didn't change!");
2321
2322         /* Find the two "servicePrincipalName"s which the DC should have been
2323            updated (HOST/<Netbios name> and HOST/<FQDN name>) - see MS-NRPC
2324            3.5.4.3.9 */
2325         spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
2326         torture_assert(tctx, spn_el != NULL,
2327                 "There should exist 'servicePrincipalName's in AD!");
2328         temp_str = talloc_asprintf(tctx, "HOST/%s", TEST_MACHINE_NAME);
2329         for (i=0; i < spn_el->num_values; i++)
2330                 if (strcmp((char *) spn_el->values[i].data, temp_str) == 0)
2331                         break;
2332         torture_assert(tctx, i != spn_el->num_values,
2333                 "'servicePrincipalName' HOST/<Netbios name> not found!");
2334         temp_str = talloc_asprintf(tctx, "HOST/%s", q1.dns_hostname);
2335         for (i=0; i < spn_el->num_values; i++)
2336                 if (strcmp((char *) spn_el->values[i].data, temp_str) == 0)
2337                         break;
2338         torture_assert(tctx, i != spn_el->num_values,
2339                 "'servicePrincipalName' HOST/<FQDN name> not found!");
2340
2341         /* Check that the out DNS hostname was set properly */
2342         torture_assert_str_equal(tctx, info.domain_info->dns_hostname.string,
2343                 old_dnsname, "Out 'DNS hostname' doesn't match the old one!");
2344
2345         /* Checks "workstation flags" */
2346         torture_assert(tctx,
2347                 info.domain_info->workstation_flags == 0,
2348                 "Out 'workstation flags' don't match!");
2349
2350
2351         torture_comment(tctx, "Testing netr_LogonGetDomainInfo 3rd call (verification of DNS hostname and check for trusted domains)\n");
2352         netlogon_creds_client_authenticator(creds, &a);
2353
2354         /* The workstation handles the "servicePrincipalName" and DNS hostname
2355            updates */
2356         q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
2357
2358         status = dcerpc_netr_LogonGetDomainInfo(p, tctx, &r);
2359         torture_assert_ntstatus_ok(tctx, status, "netr_LogonGetDomainInfo");
2360         torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
2361
2362         msleep(250);
2363
2364         /* Now the in/out DNS hostnames should be the same */
2365         torture_assert_str_equal(tctx,
2366                 info.domain_info->dns_hostname.string,
2367                 query.workstation_info->dns_hostname,
2368                 "In/Out 'DNS hostnames' don't match!");
2369
2370         /* Checks "workstation flags" */
2371         torture_assert(tctx,
2372                 info.domain_info->workstation_flags
2373                 == NETR_WS_FLAG_HANDLES_SPN_UPDATE,
2374                 "Out 'workstation flags' don't match!");
2375
2376         /* Checks for trusted domains */
2377         torture_assert(tctx,
2378                 (info.domain_info->trusted_domain_count != 0)
2379                 && (info.domain_info->trusted_domains != NULL),
2380                 "Trusted domains have been requested!");
2381
2382
2383         torture_comment(tctx, "Testing netr_LogonGetDomainInfo 4th call (check for trusted domains)\n");
2384         netlogon_creds_client_authenticator(creds, &a);
2385
2386         /* The workstation handles the "servicePrincipalName" and DNS hostname
2387            updates and requests inbound trusts */
2388         q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE
2389                 | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS;
2390
2391         status = dcerpc_netr_LogonGetDomainInfo(p, tctx, &r);
2392         torture_assert_ntstatus_ok(tctx, status, "netr_LogonGetDomainInfo");
2393         torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
2394
2395         msleep(250);
2396
2397         /* Checks "workstation flags" */
2398         torture_assert(tctx,
2399                 info.domain_info->workstation_flags
2400                 == (NETR_WS_FLAG_HANDLES_SPN_UPDATE
2401                         | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS),
2402                 "Out 'workstation flags' don't match!");
2403
2404         /* Checks for trusted domains */
2405         torture_assert(tctx,
2406                 (info.domain_info->trusted_domain_count != 0)
2407                 && (info.domain_info->trusted_domains != NULL),
2408                 "Trusted domains have been requested!");
2409
2410         return true;
2411 }
2412
2413
2414 static void async_callback(struct rpc_request *req)
2415 {
2416         int *counter = (int *)req->async.private_data;
2417         if (NT_STATUS_IS_OK(req->status)) {
2418                 (*counter)++;
2419         }
2420 }
2421
2422 static bool test_GetDomainInfo_async(struct torture_context *tctx, 
2423                                      struct dcerpc_pipe *p,
2424                                      struct cli_credentials *machine_credentials)
2425 {
2426         NTSTATUS status;
2427         struct netr_LogonGetDomainInfo r;
2428         struct netr_WorkstationInformation q1;
2429         struct netr_Authenticator a;
2430 #define ASYNC_COUNT 100
2431         struct netlogon_creds_CredentialState *creds;
2432         struct netlogon_creds_CredentialState *creds_async[ASYNC_COUNT];
2433         struct rpc_request *req[ASYNC_COUNT];
2434         int i;
2435         int *async_counter = talloc(tctx, int);
2436         union netr_WorkstationInfo query;
2437         union netr_DomainInfo info;
2438
2439         torture_comment(tctx, "Testing netr_LogonGetDomainInfo - async count %d\n", ASYNC_COUNT);
2440
2441         if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS, 
2442                                     machine_credentials, &creds)) {
2443                 return false;
2444         }
2445
2446         ZERO_STRUCT(r);
2447         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2448         r.in.computer_name = TEST_MACHINE_NAME;
2449         r.in.credential = &a;
2450         r.in.level = 1;
2451         r.in.return_authenticator = &a;
2452         r.in.query = &query;
2453         r.out.return_authenticator = &a;
2454         r.out.info = &info;
2455
2456         ZERO_STRUCT(q1);
2457         q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
2458                 TEST_MACHINE_DNS_SUFFIX);
2459         q1.sitename = "Default-First-Site-Name";
2460         q1.os_name.string = "UNIX/Linux or similar";
2461
2462         query.workstation_info = &q1;
2463
2464         *async_counter = 0;
2465
2466         for (i=0;i<ASYNC_COUNT;i++) {
2467                 netlogon_creds_client_authenticator(creds, &a);
2468
2469                 creds_async[i] = (struct netlogon_creds_CredentialState *)talloc_memdup(creds, creds, sizeof(*creds));
2470                 req[i] = dcerpc_netr_LogonGetDomainInfo_send(p, tctx, &r);
2471
2472                 req[i]->async.callback = async_callback;
2473                 req[i]->async.private_data = async_counter;
2474
2475                 /* even with this flush per request a w2k3 server seems to 
2476                    clag with multiple outstanding requests. bleergh. */
2477                 torture_assert_int_equal(tctx, event_loop_once(dcerpc_event_context(p)), 0, 
2478                                          "event_loop_once failed");
2479         }
2480
2481         for (i=0;i<ASYNC_COUNT;i++) {
2482                 status = dcerpc_ndr_request_recv(req[i]);
2483
2484                 torture_assert_ntstatus_ok(tctx, status, "netr_LogonGetDomainInfo_async");
2485                 torture_assert_ntstatus_ok(tctx, r.out.result, "netr_LogonGetDomainInfo_async"); 
2486
2487                 torture_assert(tctx, netlogon_creds_client_check(creds_async[i], &a.cred), 
2488                         "Credential chaining failed at async");
2489         }
2490
2491         torture_comment(tctx, 
2492                         "Testing netr_LogonGetDomainInfo - async count %d OK\n", *async_counter);
2493
2494         torture_assert_int_equal(tctx, (*async_counter), ASYNC_COUNT, "int");
2495
2496         return true;
2497 }
2498
2499 static bool test_ManyGetDCName(struct torture_context *tctx, 
2500                                struct dcerpc_pipe *p)
2501 {
2502         NTSTATUS status;
2503         struct dcerpc_pipe *p2;
2504         struct lsa_ObjectAttribute attr;
2505         struct lsa_QosInfo qos;
2506         struct lsa_OpenPolicy2 o;
2507         struct policy_handle lsa_handle;
2508         struct lsa_DomainList domains;
2509
2510         struct lsa_EnumTrustDom t;
2511         uint32_t resume_handle = 0;
2512         struct netr_GetAnyDCName d;
2513         const char *dcname = NULL;
2514
2515         int i;
2516
2517         if (p->conn->transport.transport != NCACN_NP) {
2518                 return true;
2519         }
2520
2521         torture_comment(tctx, "Torturing GetDCName\n");
2522
2523         status = dcerpc_secondary_connection(p, &p2, p->binding);
2524         torture_assert_ntstatus_ok(tctx, status, "Failed to create secondary connection");
2525
2526         status = dcerpc_bind_auth_none(p2, &ndr_table_lsarpc);
2527         torture_assert_ntstatus_ok(tctx, status, "Failed to create bind on secondary connection");
2528
2529         qos.len = 0;
2530         qos.impersonation_level = 2;
2531         qos.context_mode = 1;
2532         qos.effective_only = 0;
2533
2534         attr.len = 0;
2535         attr.root_dir = NULL;
2536         attr.object_name = NULL;
2537         attr.attributes = 0;
2538         attr.sec_desc = NULL;
2539         attr.sec_qos = &qos;
2540
2541         o.in.system_name = "\\";
2542         o.in.attr = &attr;
2543         o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2544         o.out.handle = &lsa_handle;
2545
2546         status = dcerpc_lsa_OpenPolicy2(p2, tctx, &o);
2547         torture_assert_ntstatus_ok(tctx, status, "OpenPolicy2 failed");
2548
2549         t.in.handle = &lsa_handle;
2550         t.in.resume_handle = &resume_handle;
2551         t.in.max_size = 1000;
2552         t.out.domains = &domains;
2553         t.out.resume_handle = &resume_handle;
2554
2555         status = dcerpc_lsa_EnumTrustDom(p2, tctx, &t);
2556
2557         if ((!NT_STATUS_IS_OK(status) &&
2558              (!NT_STATUS_EQUAL(status, NT_STATUS_NO_MORE_ENTRIES))))
2559                 torture_fail(tctx, "Could not list domains");
2560
2561         talloc_free(p2);
2562
2563         d.in.logon_server = talloc_asprintf(tctx, "\\\\%s",
2564                                             dcerpc_server_name(p));
2565         d.out.dcname = &dcname;
2566
2567         for (i=0; i<domains.count * 4; i++) {
2568                 struct lsa_DomainInfo *info =
2569                         &domains.domains[rand()%domains.count];
2570
2571                 d.in.domainname = info->name.string;
2572
2573                 status = dcerpc_netr_GetAnyDCName(p, tctx, &d);
2574                 torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
2575
2576                 torture_comment(tctx, "\tDC for domain %s is %s\n", info->name.string,
2577                        dcname ? dcname : "unknown");
2578         }
2579
2580         return true;
2581 }
2582
2583 struct torture_suite *torture_rpc_netlogon(TALLOC_CTX *mem_ctx)
2584 {
2585         struct torture_suite *suite = torture_suite_create(mem_ctx, "NETLOGON");
2586         struct torture_rpc_tcase *tcase;
2587         struct torture_test *test;
2588
2589         tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netlogon",
2590                                                   &ndr_table_netlogon, TEST_MACHINE_NAME);
2591
2592         torture_rpc_tcase_add_test(tcase, "LogonUasLogon", test_LogonUasLogon);
2593         torture_rpc_tcase_add_test(tcase, "LogonUasLogoff", test_LogonUasLogoff);
2594         torture_rpc_tcase_add_test_creds(tcase, "SamLogon", test_SamLogon);
2595         torture_rpc_tcase_add_test_creds(tcase, "SetPassword", test_SetPassword);
2596         torture_rpc_tcase_add_test_creds(tcase, "SetPassword2", test_SetPassword2);
2597         torture_rpc_tcase_add_test_creds(tcase, "GetPassword", test_GetPassword);
2598         torture_rpc_tcase_add_test_creds(tcase, "GetTrustPasswords", test_GetTrustPasswords);
2599         torture_rpc_tcase_add_test_creds(tcase, "GetDomainInfo", test_GetDomainInfo);
2600         torture_rpc_tcase_add_test_creds(tcase, "DatabaseSync", test_DatabaseSync);
2601         torture_rpc_tcase_add_test_creds(tcase, "DatabaseDeltas", test_DatabaseDeltas);
2602         torture_rpc_tcase_add_test_creds(tcase, "DatabaseRedo", test_DatabaseRedo);
2603         torture_rpc_tcase_add_test_creds(tcase, "AccountDeltas", test_AccountDeltas);
2604         torture_rpc_tcase_add_test_creds(tcase, "AccountSync", test_AccountSync);
2605         torture_rpc_tcase_add_test(tcase, "GetDcName", test_GetDcName);
2606         torture_rpc_tcase_add_test(tcase, "ManyGetDCName", test_ManyGetDCName);
2607         torture_rpc_tcase_add_test(tcase, "LogonControl", test_LogonControl);
2608         torture_rpc_tcase_add_test(tcase, "GetAnyDCName", test_GetAnyDCName);
2609         torture_rpc_tcase_add_test(tcase, "LogonControl2", test_LogonControl2);
2610         torture_rpc_tcase_add_test_creds(tcase, "DatabaseSync2", test_DatabaseSync2);
2611         torture_rpc_tcase_add_test(tcase, "LogonControl2Ex", test_LogonControl2Ex);
2612         torture_rpc_tcase_add_test(tcase, "DsrEnumerateDomainTrusts", test_DsrEnumerateDomainTrusts);
2613         torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomains", test_netr_NetrEnumerateTrustedDomains);
2614         torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomainsEx", test_netr_NetrEnumerateTrustedDomainsEx);
2615         test = torture_rpc_tcase_add_test_creds(tcase, "GetDomainInfo_async", test_GetDomainInfo_async);
2616         test->dangerous = true;
2617         torture_rpc_tcase_add_test(tcase, "DsRGetDCName", test_netr_DsRGetDCName);
2618         torture_rpc_tcase_add_test(tcase, "DsRGetDCNameEx", test_netr_DsRGetDCNameEx);
2619         torture_rpc_tcase_add_test(tcase, "DsRGetDCNameEx2", test_netr_DsRGetDCNameEx2);
2620         torture_rpc_tcase_add_test(tcase, "DsrGetDcSiteCoverageW", test_netr_DsrGetDcSiteCoverageW);
2621         torture_rpc_tcase_add_test(tcase, "DsRAddressToSitenamesW", test_netr_DsRAddressToSitenamesW);
2622         torture_rpc_tcase_add_test(tcase, "DsRAddressToSitenamesExW", test_netr_DsRAddressToSitenamesExW);
2623         torture_rpc_tcase_add_test_creds(tcase, "ServerGetTrustInfo", test_netr_ServerGetTrustInfo);
2624
2625         return suite;
2626 }