2 Unix SMB/CIFS implementation.
4 test suite for netlogon rpc operations
6 Copyright (C) Andrew Tridgell 2003
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 static BOOL test_LogonUasLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
29 struct netr_LogonUasLogon r;
31 r.in.server_name = NULL;
32 r.in.username = lp_parm_string(-1, "torture", "username");
33 r.in.workstation = lp_netbios_name();
35 printf("Testing LogonUasLogon\n");
37 status = dcerpc_netr_LogonUasLogon(p, mem_ctx, &r);
38 if (!NT_STATUS_IS_OK(status)) {
39 printf("LogonUasLogon - %s\n", nt_errstr(status));
47 static BOOL test_LogonUasLogoff(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
50 struct netr_LogonUasLogoff r;
52 r.in.server_name = NULL;
53 r.in.username = lp_parm_string(-1, "torture", "username");
54 r.in.workstation = lp_netbios_name();
56 printf("Testing LogonUasLogoff\n");
58 status = dcerpc_netr_LogonUasLogoff(p, mem_ctx, &r);
59 if (!NT_STATUS_IS_OK(status)) {
60 printf("LogonUasLogoff - %s\n", nt_errstr(status));
68 static BOOL test_SetupCredentials(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
69 struct netr_CredentialState *creds)
72 struct netr_ServerReqChallenge r;
73 struct netr_ServerAuthenticate a;
74 const char *plain_pass;
77 printf("Testing ServerReqChallenge\n");
79 r.in.server_name = NULL;
80 r.in.computer_name = lp_netbios_name();
81 generate_random_buffer(r.in.credentials.data, sizeof(r.in.credentials.data), False);
83 status = dcerpc_netr_ServerReqChallenge(p, mem_ctx, &r);
84 if (!NT_STATUS_IS_OK(status)) {
85 printf("ServerReqChallenge - %s\n", nt_errstr(status));
89 plain_pass = secrets_fetch_machine_password();
91 printf("Unable to fetch machine password!\n");
95 E_md4hash(plain_pass, mach_pwd);
97 creds_client_init(creds, &r.in.credentials, &r.out.credentials, mach_pwd,
100 a.in.server_name = NULL;
101 a.in.username = talloc_asprintf(mem_ctx, "%s$", lp_netbios_name());
102 a.in.secure_channel_type = SEC_CHAN_BDC;
103 a.in.computer_name = lp_netbios_name();
105 printf("Testing ServerAuthenticate\n");
107 status = dcerpc_netr_ServerAuthenticate(p, mem_ctx, &a);
108 if (!NT_STATUS_IS_OK(status)) {
109 printf("ServerAuthenticate - %s\n", nt_errstr(status));
113 if (!creds_client_check(creds, &a.out.credentials)) {
114 printf("Credential chaining failed\n");
121 static BOOL test_SetupCredentials2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
122 struct netr_CredentialState *creds)
125 struct netr_ServerReqChallenge r;
126 struct netr_ServerAuthenticate2 a;
127 const char *plain_pass;
129 uint32 negotiate_flags = 0;
131 printf("Testing ServerReqChallenge\n");
133 r.in.server_name = NULL;
134 r.in.computer_name = lp_netbios_name();
135 generate_random_buffer(r.in.credentials.data, sizeof(r.in.credentials.data), False);
137 status = dcerpc_netr_ServerReqChallenge(p, mem_ctx, &r);
138 if (!NT_STATUS_IS_OK(status)) {
139 printf("ServerReqChallenge - %s\n", nt_errstr(status));
143 plain_pass = secrets_fetch_machine_password();
145 printf("Unable to fetch machine password!\n");
149 E_md4hash(plain_pass, mach_pwd);
151 creds_client_init(creds, &r.in.credentials, &r.out.credentials, mach_pwd,
154 a.in.server_name = NULL;
155 a.in.username = talloc_asprintf(mem_ctx, "%s$", lp_netbios_name());
156 a.in.secure_channel_type = SEC_CHAN_BDC;
157 a.in.computer_name = lp_netbios_name();
158 a.in.negotiate_flags = &negotiate_flags;
159 a.out.negotiate_flags = &negotiate_flags;
161 printf("Testing ServerAuthenticate2\n");
163 status = dcerpc_netr_ServerAuthenticate2(p, mem_ctx, &a);
164 if (!NT_STATUS_IS_OK(status)) {
165 printf("ServerAuthenticate2 - %s\n", nt_errstr(status));
169 if (!creds_client_check(creds, &a.out.credentials)) {
170 printf("Credential chaining failed\n");
174 printf("negotiate_flags=0x%08x\n", negotiate_flags);
180 try a netlogon SamLogon
182 static BOOL test_SamLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
185 struct netr_LogonSamLogon r;
186 struct netr_Authenticator auth, auth2;
187 struct netr_NetworkInfo ninfo;
188 const char *username = lp_parm_string(-1, "torture", "username");
189 const char *password = lp_parm_string(-1, "torture", "password");
190 struct netr_CredentialState creds;
192 if (!test_SetupCredentials2(p, mem_ctx, &creds)) {
196 ninfo.logon_info.domain_name.string = lp_workgroup();
197 ninfo.logon_info.parameter_control = 0;
198 ninfo.logon_info.logon_id_low = 0;
199 ninfo.logon_info.logon_id_high = 0;
200 ninfo.logon_info.username.string = username;
201 ninfo.logon_info.workstation.string = lp_netbios_name();
202 generate_random_buffer(ninfo.challenge,
203 sizeof(ninfo.challenge), False);
204 ninfo.nt.length = 24;
205 ninfo.nt.data = talloc(mem_ctx, 24);
206 SMBNTencrypt(password, ninfo.challenge, ninfo.nt.data);
207 ninfo.lm.length = 24;
208 ninfo.lm.data = talloc(mem_ctx, 24);
209 SMBencrypt(password, ninfo.challenge, ninfo.lm.data);
213 creds_client_authenticator(&creds, &auth);
215 r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
216 r.in.workstation = lp_netbios_name();
217 r.in.credential = &auth;
218 r.in.authenticator = &auth2;
219 r.in.logon_level = 2;
220 r.in.logon.network = &ninfo;
221 r.in.validation_level = 2;
223 printf("Testing SamLogon\n");
225 status = dcerpc_netr_LogonSamLogon(p, mem_ctx, &r);
226 if (!NT_STATUS_IS_OK(status)) {
227 printf("LogonSamLogon - %s\n", nt_errstr(status));
231 if (!creds_client_check(&creds, &r.out.authenticator->cred)) {
232 printf("Credential chaining failed\n");
240 try a change password for our machine account
242 static BOOL test_SetPassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
245 struct netr_ServerPasswordSet r;
246 const char *password;
247 struct netr_CredentialState creds;
249 if (!test_SetupCredentials(p, mem_ctx, &creds)) {
253 r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
254 r.in.username = talloc_asprintf(mem_ctx, "%s$", lp_netbios_name());
255 r.in.secure_channel_type = SEC_CHAN_BDC;
256 r.in.computer_name = lp_netbios_name();
258 password = generate_random_str(8);
259 E_md4hash(password, r.in.new_password.data);
261 creds_client_encrypt(&creds, &r.in.new_password);
263 printf("Testing ServerPasswordSet on machine account\n");
265 creds_client_authenticator(&creds, &r.in.credential);
267 status = dcerpc_netr_ServerPasswordSet(p, mem_ctx, &r);
268 if (!NT_STATUS_IS_OK(status)) {
269 printf("ServerPasswordSet - %s\n", nt_errstr(status));
273 if (!secrets_store_machine_password(password)) {
274 printf("Failed to save machine password\n");
277 if (!creds_client_check(&creds, &r.out.return_authenticator.cred)) {
278 printf("Credential chaining failed\n");
281 /* by changing the machine password twice we test the credentials
283 printf("Testing a second ServerPasswordSet on machine account\n");
285 creds_client_authenticator(&creds, &r.in.credential);
287 status = dcerpc_netr_ServerPasswordSet(p, mem_ctx, &r);
288 if (!NT_STATUS_IS_OK(status)) {
289 printf("ServerPasswordSet - %s\n", nt_errstr(status));
293 if (!creds_client_check(&creds, &r.out.return_authenticator.cred)) {
294 printf("Credential chaining failed\n");
301 /* we remember the sequence numbers so we can easily do a DatabaseDelta */
302 static struct ULONG8 sequence_nums[3];
305 try a netlogon DatabaseSync
307 static BOOL test_DatabaseSync(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
310 struct netr_DatabaseSync r;
311 struct netr_CredentialState creds;
312 const uint32 database_ids[] = {0, 1, 2};
316 if (!test_SetupCredentials(p, mem_ctx, &creds)) {
320 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
321 r.in.computername = lp_netbios_name();
322 r.in.preferredmaximumlength = (uint32)-1;
323 ZERO_STRUCT(r.in.return_authenticator);
325 for (i=0;i<ARRAY_SIZE(database_ids);i++) {
326 r.in.sync_context = 0;
327 r.in.database_id = database_ids[i];
329 printf("Testing DatabaseSync of id %d\n", r.in.database_id);
332 creds_client_authenticator(&creds, &r.in.credential);
334 status = dcerpc_netr_DatabaseSync(p, mem_ctx, &r);
335 if (!NT_STATUS_IS_OK(status) &&
336 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
337 printf("DatabaseSync - %s\n", nt_errstr(status));
342 if (!creds_client_check(&creds, &r.out.return_authenticator.cred)) {
343 printf("Credential chaining failed\n");
346 r.in.sync_context = r.out.sync_context;
348 if (r.out.delta_enum_array &&
349 r.out.delta_enum_array->num_deltas > 0 &&
350 r.out.delta_enum_array->delta_enum[0].delta_type == 1 &&
351 r.out.delta_enum_array->delta_enum[0].delta_union.domain) {
352 sequence_nums[r.in.database_id] =
353 r.out.delta_enum_array->delta_enum[0].delta_union.domain->sequence_num;
354 printf("\tsequence_nums[%d]=0x%08x%08x\n",
356 sequence_nums[r.in.database_id].high,
357 sequence_nums[r.in.database_id].low);
359 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
367 try a netlogon DatabaseDeltas
369 static BOOL test_DatabaseDeltas(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
372 struct netr_DatabaseDeltas r;
373 struct netr_CredentialState creds;
374 const uint32 database_ids[] = {0, 1, 2};
378 if (!test_SetupCredentials(p, mem_ctx, &creds)) {
382 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
383 r.in.computername = lp_netbios_name();
384 r.in.preferredmaximumlength = (uint32)-1;
385 ZERO_STRUCT(r.in.return_authenticator);
387 for (i=0;i<ARRAY_SIZE(database_ids);i++) {
388 r.in.database_id = database_ids[i];
389 r.in.sequence_num = sequence_nums[r.in.database_id];
390 r.in.sequence_num.low -= 1;
392 printf("Testing DatabaseDeltas of id %d at %d\n",
393 r.in.database_id, r.in.sequence_num.low);
396 creds_client_authenticator(&creds, &r.in.credential);
398 status = dcerpc_netr_DatabaseDeltas(p, mem_ctx, &r);
399 if (!NT_STATUS_IS_OK(status) &&
400 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
401 printf("DatabaseDeltas - %s\n", nt_errstr(status));
406 if (!creds_client_check(&creds, &r.out.return_authenticator.cred)) {
407 printf("Credential chaining failed\n");
410 r.in.sequence_num.low++;
411 r.in.sequence_num.high = 0;
412 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
420 try a netlogon AccountDeltas
422 static BOOL test_AccountDeltas(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
425 struct netr_AccountDeltas r;
426 struct netr_CredentialState creds;
429 if (!test_SetupCredentials(p, mem_ctx, &creds)) {
433 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
434 r.in.computername = lp_netbios_name();
435 ZERO_STRUCT(r.in.return_authenticator);
436 creds_client_authenticator(&creds, &r.in.credential);
437 ZERO_STRUCT(r.in.uas);
442 printf("Testing AccountDeltas\n");
444 /* w2k3 returns "NOT IMPLEMENTED" for this call */
445 status = dcerpc_netr_AccountDeltas(p, mem_ctx, &r);
446 if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
447 printf("AccountDeltas - %s\n", nt_errstr(status));
455 try a netlogon AccountSync
457 static BOOL test_AccountSync(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
460 struct netr_AccountSync r;
461 struct netr_CredentialState creds;
464 if (!test_SetupCredentials(p, mem_ctx, &creds)) {
468 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
469 r.in.computername = lp_netbios_name();
470 ZERO_STRUCT(r.in.return_authenticator);
471 creds_client_authenticator(&creds, &r.in.credential);
472 ZERO_STRUCT(r.in.recordid);
477 printf("Testing AccountSync\n");
479 /* w2k3 returns "NOT IMPLEMENTED" for this call */
480 status = dcerpc_netr_AccountSync(p, mem_ctx, &r);
481 if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
482 printf("AccountSync - %s\n", nt_errstr(status));
490 try a netlogon GetDcName
492 static BOOL test_GetDcName(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
495 struct netr_GetDcName r;
497 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
498 r.in.domainname = lp_workgroup();
500 printf("Testing GetDcName\n");
502 status = dcerpc_netr_GetDcName(p, mem_ctx, &r);
503 if (!NT_STATUS_IS_OK(status)) {
504 printf("GetDcName - %s\n", nt_errstr(status));
508 printf("\tDC is at '%s'\n", r.out.dcname);
514 try a netlogon LogonControl
516 static BOOL test_LogonControl(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
519 struct netr_LogonControl r;
523 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
524 r.in.function_code = 1;
529 printf("Testing LogonControl level %d\n", i);
531 status = dcerpc_netr_LogonControl(p, mem_ctx, &r);
532 if (!NT_STATUS_IS_OK(status)) {
533 printf("LogonControl - %s\n", nt_errstr(status));
543 try a netlogon GetAnyDCName
545 static BOOL test_GetAnyDCName(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
548 struct netr_GetAnyDCName r;
550 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
551 r.in.domainname = lp_workgroup();
553 printf("Testing GetAnyDCName\n");
555 status = dcerpc_netr_GetAnyDCName(p, mem_ctx, &r);
556 if (!NT_STATUS_IS_OK(status)) {
557 printf("GetAnyDCName - %s\n", nt_errstr(status));
562 printf("\tDC is at '%s'\n", r.out.dcname);
570 try a netlogon LogonControl2
572 static BOOL test_LogonControl2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
575 struct netr_LogonControl2 r;
579 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
581 r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
582 r.in.data.domain = lp_workgroup();
587 printf("Testing LogonControl2 level %d function %d\n",
588 i, r.in.function_code);
590 status = dcerpc_netr_LogonControl2(p, mem_ctx, &r);
591 if (!NT_STATUS_IS_OK(status)) {
592 printf("LogonControl - %s\n", nt_errstr(status));
597 r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
598 r.in.data.domain = lp_workgroup();
603 printf("Testing LogonControl2 level %d function %d\n",
604 i, r.in.function_code);
606 status = dcerpc_netr_LogonControl2(p, mem_ctx, &r);
607 if (!NT_STATUS_IS_OK(status)) {
608 printf("LogonControl - %s\n", nt_errstr(status));
613 r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
614 r.in.data.domain = lp_workgroup();
619 printf("Testing LogonControl2 level %d function %d\n",
620 i, r.in.function_code);
622 status = dcerpc_netr_LogonControl2(p, mem_ctx, &r);
623 if (!NT_STATUS_IS_OK(status)) {
624 printf("LogonControl - %s\n", nt_errstr(status));
629 r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
630 r.in.data.debug_level = ~0;
635 printf("Testing LogonControl2 level %d function %d\n",
636 i, r.in.function_code);
638 status = dcerpc_netr_LogonControl2(p, mem_ctx, &r);
639 if (!NT_STATUS_IS_OK(status)) {
640 printf("LogonControl - %s\n", nt_errstr(status));
649 try a netlogon DatabaseSync2
651 static BOOL test_DatabaseSync2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
654 struct netr_DatabaseSync2 r;
655 struct netr_CredentialState creds;
656 const uint32 database_ids[] = {0, 1, 2};
660 if (!test_SetupCredentials2(p, mem_ctx, &creds)) {
664 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
665 r.in.computername = lp_netbios_name();
666 r.in.preferredmaximumlength = (uint32)-1;
667 ZERO_STRUCT(r.in.return_authenticator);
669 for (i=0;i<ARRAY_SIZE(database_ids);i++) {
670 r.in.sync_context = 0;
671 r.in.database_id = database_ids[i];
672 r.in.restart_state = 0;
674 printf("Testing DatabaseSync2 of id %d\n", r.in.database_id);
677 creds_client_authenticator(&creds, &r.in.credential);
679 status = dcerpc_netr_DatabaseSync2(p, mem_ctx, &r);
680 if (!NT_STATUS_IS_OK(status) &&
681 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
682 printf("DatabaseSync2 - %s\n", nt_errstr(status));
687 if (!creds_client_check(&creds, &r.out.return_authenticator.cred)) {
688 printf("Credential chaining failed\n");
691 r.in.sync_context = r.out.sync_context;
692 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
700 try a netlogon LogonControl2Ex
702 static BOOL test_LogonControl2Ex(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
705 struct netr_LogonControl2Ex r;
709 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
711 r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
712 r.in.data.domain = lp_workgroup();
717 printf("Testing LogonControl2Ex level %d function %d\n",
718 i, r.in.function_code);
720 status = dcerpc_netr_LogonControl2Ex(p, mem_ctx, &r);
721 if (!NT_STATUS_IS_OK(status)) {
722 printf("LogonControl - %s\n", nt_errstr(status));
727 r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
728 r.in.data.domain = lp_workgroup();
733 printf("Testing LogonControl2Ex level %d function %d\n",
734 i, r.in.function_code);
736 status = dcerpc_netr_LogonControl2Ex(p, mem_ctx, &r);
737 if (!NT_STATUS_IS_OK(status)) {
738 printf("LogonControl - %s\n", nt_errstr(status));
743 r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
744 r.in.data.domain = lp_workgroup();
749 printf("Testing LogonControl2Ex level %d function %d\n",
750 i, r.in.function_code);
752 status = dcerpc_netr_LogonControl2Ex(p, mem_ctx, &r);
753 if (!NT_STATUS_IS_OK(status)) {
754 printf("LogonControl - %s\n", nt_errstr(status));
759 r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
760 r.in.data.debug_level = ~0;
765 printf("Testing LogonControl2Ex level %d function %d\n",
766 i, r.in.function_code);
768 status = dcerpc_netr_LogonControl2Ex(p, mem_ctx, &r);
769 if (!NT_STATUS_IS_OK(status)) {
770 printf("LogonControl - %s\n", nt_errstr(status));
780 BOOL torture_rpc_netlogon(int dummy)
783 struct dcerpc_pipe *p;
787 mem_ctx = talloc_init("torture_rpc_netlogon");
789 status = torture_rpc_connection(&p,
790 DCERPC_NETLOGON_NAME,
791 DCERPC_NETLOGON_UUID,
792 DCERPC_NETLOGON_VERSION);
793 if (!NT_STATUS_IS_OK(status)) {
797 p->flags |= DCERPC_DEBUG_PRINT_BOTH;
799 if (!test_LogonUasLogon(p, mem_ctx)) {
803 if (!test_LogonUasLogoff(p, mem_ctx)) {
807 if (!test_SetPassword(p, mem_ctx)) {
811 if (!test_SamLogon(p, mem_ctx)) {
815 if (!test_DatabaseSync(p, mem_ctx)) {
819 if (!test_DatabaseDeltas(p, mem_ctx)) {
823 if (!test_AccountDeltas(p, mem_ctx)) {
827 if (!test_AccountSync(p, mem_ctx)) {
831 if (!test_GetDcName(p, mem_ctx)) {
835 if (!test_LogonControl(p, mem_ctx)) {
839 if (!test_GetAnyDCName(p, mem_ctx)) {
843 if (!test_LogonControl2(p, mem_ctx)) {
847 if (!test_DatabaseSync2(p, mem_ctx)) {
851 if (!test_LogonControl2Ex(p, mem_ctx)) {
855 torture_rpc_close(p);