2 Unix SMB/CIFS implementation.
4 Test code to simulate an XP logon.
6 Copyright (C) Volker Lendecke 2004
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.
24 #include "libcli/auth/credentials.h"
25 #include "libcli/raw/libcliraw.h"
26 #include "librpc/gen_ndr/ndr_samr.h"
27 #include "librpc/gen_ndr/ndr_netlogon.h"
28 #include "librpc/gen_ndr/ndr_srvsvc.h"
29 #include "libcli/composite/composite.h"
32 static NTSTATUS after_negprot(struct smbcli_transport **dst_transport,
33 const char *dest_host, uint16_t port,
36 struct smbcli_socket *sock;
37 struct smbcli_transport *transport;
40 sock = smbcli_sock_init(NULL, NULL);
42 return NT_STATUS_NO_MEMORY;
44 if (!smbcli_sock_connect_byname(sock, dest_host, port)) {
46 DEBUG(2,("Failed to establish socket connection - %s\n",
48 return NT_STATUS_UNSUCCESSFUL;
51 transport = smbcli_transport_init(sock, NULL, True);
52 if (transport == NULL)
53 return NT_STATUS_NO_MEMORY;
56 struct nbt_name calling;
57 struct nbt_name called;
59 /* send a NBT session request, if applicable */
60 make_nbt_name_client(&calling, my_name);
62 nbt_choose_called_name(transport, &called, dest_host, NBT_NAME_SERVER);
64 if (!smbcli_transport_connect(transport, &calling, &called)) {
65 talloc_free(transport);
66 return NT_STATUS_NO_MEMORY;
70 /* negotiate protocol options with the server */
71 status = smb_raw_negotiate(transport, lp_maxprotocol());
72 if (!NT_STATUS_IS_OK(status)) {
73 talloc_free(transport);
74 return NT_STATUS_UNSUCCESSFUL;
77 *dst_transport = transport;
82 static int destroy_session(void *ptr)
84 struct smbcli_session *session = ptr;
85 smb_raw_ulogoff(session);
89 static int destroy_tree_and_session(void *ptr)
91 struct smbcli_tree *tree = ptr;
92 smb_tree_disconnect(tree);
93 talloc_free(tree->session);
97 static NTSTATUS anon_ipc(struct smbcli_transport *transport,
98 struct smbcli_tree **dst_tree)
100 struct smbcli_tree *tree;
101 struct smbcli_session *session;
102 struct smb_composite_sesssetup setup;
107 session = smbcli_session_init(transport, NULL, True);
109 return NT_STATUS_NO_MEMORY;
111 mem_ctx = talloc_init("session_init");
112 if (mem_ctx == NULL) {
113 talloc_free(session);
114 return NT_STATUS_NO_MEMORY;
117 /* prepare a session setup to establish a security context */
118 setup.in.sesskey = transport->negotiate.sesskey;
119 setup.in.capabilities = transport->negotiate.capabilities;
120 setup.in.capabilities &= ~CAP_EXTENDED_SECURITY;
122 setup.in.credentials = cli_credentials_init(mem_ctx);
123 cli_credentials_set_anonymous(setup.in.credentials);
125 status = smb_composite_sesssetup(session, &setup);
126 if (!NT_STATUS_IS_OK(status)) {
127 talloc_free(session);
128 talloc_free(mem_ctx);
129 return NT_STATUS_UNSUCCESSFUL;
132 session->vuid = setup.out.vuid;
134 talloc_set_destructor(session, destroy_session);
136 tree = smbcli_tree_init(session, NULL, True);
138 talloc_free(mem_ctx);
139 return NT_STATUS_NO_MEMORY;
142 tcon.generic.level = RAW_TCON_TCONX;
143 tcon.tconx.in.flags = 0;
144 tcon.tconx.in.password = data_blob(NULL, 0);
145 tcon.tconx.in.path = talloc_asprintf(mem_ctx, "\\\\%s\\IPC$",
146 transport->called.name);
147 tcon.tconx.in.device = "IPC";
149 status = smb_tree_connect(tree, mem_ctx, &tcon);
151 if (!NT_STATUS_IS_OK(status)) {
153 talloc_free(mem_ctx);
154 return NT_STATUS_UNSUCCESSFUL;
157 tree->tid = tcon.tconx.out.tid;
159 if (tcon.tconx.out.dev_type != NULL)
160 tree->device = talloc_strdup(tree, tcon.tconx.out.dev_type);
162 if (tcon.tconx.out.fs_type != NULL)
163 tree->fs_type = talloc_strdup(tree, tcon.tconx.out.fs_type);
165 talloc_set_destructor(tree, destroy_tree_and_session);
167 talloc_free(mem_ctx);
174 static NTSTATUS connect_to_pipe(struct dcerpc_pipe **pp,
176 struct smbcli_transport *transport,
177 const char *pipe_name,
178 const char *pipe_uuid,
179 uint32_t pipe_version)
181 const char *binding = lp_parm_string(-1, "torture", "binding");
182 struct dcerpc_binding *b;
184 struct dcerpc_pipe *p;
186 struct smbcli_tree *tree;
188 if (!NT_STATUS_IS_OK(status = anon_ipc(transport, &tree)))
192 return NT_STATUS_INVALID_PARAMETER;
194 p = dcerpc_pipe_init(mem_ctx);
196 return NT_STATUS_NO_MEMORY;
198 tmp_ctx = talloc_new(p);
200 status = dcerpc_parse_binding(tmp_ctx, binding, &b);
201 if (!NT_STATUS_IS_OK(status)) {
202 DEBUG(0,("Failed to parse dcerpc binding '%s'\n", binding));
207 DEBUG(3,("Using binding %s\n", dcerpc_binding_string(tmp_ctx, b)));
209 /* Look up identifier using the epmapper */
211 status = dcerpc_epm_map_binding(tmp_ctx, b, pipe_uuid, pipe_version);
212 if (!NT_STATUS_IS_OK(status)) {
213 DEBUG(0,("Failed to map DCERPC/TCP NCACN_NP pipe for '%s' - %s\n",
214 pipe_uuid, nt_errstr(status)));
218 DEBUG(1,("Mapped to DCERPC/NP pipe %s\n", b->endpoint));
221 pipe_name = b->endpoint;
224 status = dcerpc_pipe_open_smb(p->conn, tree, pipe_name);
226 if (!NT_STATUS_IS_OK(status)) {
231 talloc_free(tmp_ctx);
237 static NTSTATUS test_enumtrusts(struct smbcli_transport *transport)
239 struct policy_handle handle;
240 struct lsa_EnumTrustDom r2;
241 uint32_t resume_handle = 0;
242 struct lsa_ObjectAttribute attr;
243 struct lsa_OpenPolicy2 r1;
244 struct lsa_DomainList domains;
247 struct dcerpc_pipe *p;
249 mem_ctx = talloc_init("test_enumtrusts");
251 return NT_STATUS_NO_MEMORY;
253 status = connect_to_pipe(&p, mem_ctx, transport, DCERPC_LSARPC_NAME,
255 DCERPC_LSARPC_VERSION);
257 if (!NT_STATUS_IS_OK(status)) {
258 talloc_free(mem_ctx);
262 status = dcerpc_bind_auth_none(p, DCERPC_LSARPC_UUID,
263 DCERPC_LSARPC_VERSION);
265 if (!NT_STATUS_IS_OK(status))
268 printf("\ntesting OpenPolicy2\n");
271 attr.root_dir = NULL;
272 attr.object_name = NULL;
274 attr.sec_desc = NULL;
277 r1.in.system_name = talloc_asprintf(mem_ctx,
278 "\\\\%s", dcerpc_server_name(p));
280 r1.in.access_mask = 1;
281 r1.out.handle = &handle;
283 status = dcerpc_lsa_OpenPolicy2(p, mem_ctx, &r1);
284 if (!NT_STATUS_IS_OK(status)) {
285 printf("OpenPolicy2 failed - %s\n", nt_errstr(status));
289 printf("\nTesting EnumTrustDom\n");
291 r2.in.handle = &handle;
292 r2.in.resume_handle = &resume_handle;
293 r2.in.max_size = 1000;
294 r2.out.domains = &domains;
295 r2.out.resume_handle = &resume_handle;
297 status = dcerpc_lsa_EnumTrustDom(p, mem_ctx, &r2);
299 if (!NT_STATUS_IS_OK(status) &&
300 !NT_STATUS_EQUAL(status, NT_STATUS_NO_MORE_ENTRIES))
305 talloc_free(mem_ctx);
310 static NTSTATUS test_lookupnames(struct smbcli_transport *transport,
313 struct policy_handle handle;
314 struct lsa_ObjectAttribute attr;
315 struct lsa_OpenPolicy2 r1;
318 struct dcerpc_pipe *p;
320 mem_ctx = talloc_init("test_lookupnames");
322 return NT_STATUS_NO_MEMORY;
324 status = connect_to_pipe(&p, mem_ctx, transport, DCERPC_LSARPC_NAME,
326 DCERPC_LSARPC_VERSION);
328 if (!NT_STATUS_IS_OK(status)) {
329 talloc_free(mem_ctx);
333 status = dcerpc_bind_auth_none(p, DCERPC_LSARPC_UUID,
334 DCERPC_LSARPC_VERSION);
336 if (!NT_STATUS_IS_OK(status))
340 attr.root_dir = NULL;
341 attr.object_name = NULL;
343 attr.sec_desc = NULL;
346 r1.in.system_name = talloc_asprintf(mem_ctx,
347 "\\\\%s", dcerpc_server_name(p));
349 r1.in.access_mask = 0x801;
350 r1.out.handle = &handle;
352 status = dcerpc_lsa_OpenPolicy2(p, mem_ctx, &r1);
353 if (!NT_STATUS_IS_OK(status)) {
354 printf("OpenPolicy2 failed - %s\n", nt_errstr(status));
359 struct lsa_LookupNames l;
360 struct lsa_TransSidArray sids;
361 struct lsa_String lsaname;
367 lsaname.string = name;
369 l.in.handle = &handle;
371 l.in.names = &lsaname;
375 l.out.count = &count;
378 status = dcerpc_lsa_LookupNames(p, mem_ctx, &l);
379 if (!NT_STATUS_IS_OK(status) &&
380 !NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
381 printf("LookupNames failed - %s\n", nt_errstr(status));
383 talloc_free(mem_ctx);
390 struct policy_handle handle2;
392 c.in.handle = &handle;
393 c.out.handle = &handle2;
395 status = dcerpc_lsa_Close(p, mem_ctx, &c);
396 if (!NT_STATUS_IS_OK(status)) {
397 printf("Close failed - %s\n", nt_errstr(status));
404 talloc_free(mem_ctx);
409 static NTSTATUS setup_netlogon_creds(struct smbcli_transport *transport,
410 struct dcerpc_pipe **p,
411 const char *machine_name,
413 const char *machine_pwd,
414 struct creds_CredentialState *creds)
418 struct netr_ServerReqChallenge r;
419 struct netr_ServerAuthenticate2 a;
420 struct netr_Credential credentials1, credentials2, credentials3;
421 const char *plain_pass;
422 struct samr_Password mach_password;
423 uint32_t negotiate_flags = NETLOGON_NEG_AUTH2_FLAGS;
426 mem_ctx = talloc_init("torture_rpc_login");
429 return NT_STATUS_NO_MEMORY;
431 status = connect_to_pipe(p, mem_ctx, transport, DCERPC_NETLOGON_NAME,
432 DCERPC_NETLOGON_UUID,
433 DCERPC_NETLOGON_VERSION);
435 if (!NT_STATUS_IS_OK(status)) {
436 talloc_free(mem_ctx);
440 status = dcerpc_bind_auth_none(*p, DCERPC_NETLOGON_UUID,
441 DCERPC_NETLOGON_VERSION);
443 if (!NT_STATUS_IS_OK(status))
446 printf("Testing ServerReqChallenge\n");
448 r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s",
449 dcerpc_server_name(*p));
450 r.in.computer_name = machine_name;
451 r.in.credentials = &credentials1;
452 r.out.credentials = &credentials2;
454 generate_random_buffer(credentials1.data, sizeof(credentials1.data));
456 status = dcerpc_netr_ServerReqChallenge(*p, mem_ctx, &r);
457 if (!NT_STATUS_IS_OK(status)) {
458 printf("ServerReqChallenge - %s\n", nt_errstr(status));
462 plain_pass = machine_pwd;
464 printf("Unable to fetch machine password!\n");
468 E_md4hash(plain_pass, mach_password.hash);
470 a.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s",
471 dcerpc_server_name(*p));
472 a.in.account_name = talloc_asprintf(mem_ctx, "%s$", machine_name);
473 a.in.secure_channel_type = SEC_CHAN_WKSTA;
474 a.in.computer_name = machine_name;
475 a.in.negotiate_flags = &negotiate_flags;
476 a.out.negotiate_flags = &negotiate_flags;
477 a.in.credentials = &credentials3;
478 a.out.credentials = &credentials3;
480 creds_client_init(creds, &credentials1, &credentials2,
481 &mach_password, &credentials3,
484 printf("Testing ServerAuthenticate2\n");
486 status = dcerpc_netr_ServerAuthenticate2(*p, mem_ctx, &a);
487 if (!NT_STATUS_IS_OK(status)) {
488 printf("ServerAuthenticate2 - %s\n", nt_errstr(status));
492 if (!creds_client_check(creds, &credentials3)) {
493 printf("Credential chaining failed\n");
497 printf("negotiate_flags=0x%08x\n", negotiate_flags);
499 talloc_free(mem_ctx);
503 static NTSTATUS torture_samlogon(struct dcerpc_pipe *p,
504 struct creds_CredentialState *netlogon_creds,
505 const char *workstation,
507 const char *username,
508 const char *password)
511 struct netr_LogonSamLogon log;
512 struct netr_NetworkInfo ninfo;
513 struct netr_Authenticator auth, auth2;
514 uint8_t user_session_key[16];
515 DATA_BLOB ntlmv2_response = data_blob(NULL, 0);
516 DATA_BLOB lmv2_response = data_blob(NULL, 0);
517 DATA_BLOB names_blob;
521 mem_ctx = talloc_init("torture_samlogon");
523 ZERO_STRUCT(user_session_key);
525 printf("testing netr_LogonSamLogon\n");
527 log.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s",
528 dcerpc_server_name(p));
529 log.in.workstation = workstation;
530 log.in.credential = &auth;
531 log.in.return_authenticator = &auth2;
532 log.in.validation_level = 3;
533 log.in.logon_level = 2;
534 log.in.logon.network = &ninfo;
536 chall = data_blob_talloc(mem_ctx, NULL, 8);
537 generate_random_buffer(chall.data, 8);
539 names_blob = NTLMv2_generate_names_blob(mem_ctx, workstation,
541 ZERO_STRUCT(user_session_key);
543 if (!SMBNTLMv2encrypt(username, domain, password,
545 &lmv2_response, &ntlmv2_response,
547 data_blob_free(&names_blob);
548 talloc_free(mem_ctx);
549 return NT_STATUS_UNSUCCESSFUL;
551 data_blob_free(&names_blob);
553 ninfo.identity_info.domain_name.string = domain;
554 ninfo.identity_info.parameter_control = 0;
555 ninfo.identity_info.logon_id_low = 0;
556 ninfo.identity_info.logon_id_high = 0;
557 ninfo.identity_info.account_name.string = username;
558 ninfo.identity_info.workstation.string = workstation;
559 memcpy(ninfo.challenge, chall.data, 8);
560 ninfo.nt.data = ntlmv2_response.data;
561 ninfo.nt.length = ntlmv2_response.length;
562 ninfo.lm.data = NULL;
566 creds_client_authenticator(netlogon_creds, &auth);
568 log.out.return_authenticator = NULL;
569 status = dcerpc_netr_LogonSamLogon(p, mem_ctx, &log);
570 talloc_free(mem_ctx);
571 data_blob_free(&lmv2_response);
572 data_blob_free(&ntlmv2_response);
576 static NTSTATUS test_getgroups(struct smbcli_transport *transport,
581 struct dcerpc_pipe *p;
583 struct samr_Connect4 r4;
584 struct policy_handle connect_handle, domain_handle, user_handle;
586 mem_ctx = talloc_init("test_lookupnames");
588 return NT_STATUS_NO_MEMORY;
590 status = connect_to_pipe(&p, mem_ctx, transport, DCERPC_SAMR_NAME,
592 DCERPC_SAMR_VERSION);
594 if (!NT_STATUS_IS_OK(status)) {
595 talloc_free(mem_ctx);
599 status = dcerpc_bind_auth_none(p, DCERPC_SAMR_UUID,
600 DCERPC_SAMR_VERSION);
602 if (!NT_STATUS_IS_OK(status))
605 r4.in.system_name = talloc_asprintf(mem_ctx, "\\\\%s",
606 dcerpc_server_name(p));
608 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
609 r4.out.connect_handle = &connect_handle;
611 status = dcerpc_samr_Connect4(p, mem_ctx, &r4);
612 if (!NT_STATUS_IS_OK(status))
616 struct samr_EnumDomains e;
617 uint32_t resume_handle = 0;
620 e.in.connect_handle = &connect_handle;
621 e.in.resume_handle = &resume_handle;
622 e.in.buf_size = (uint32_t)-1;
623 e.out.resume_handle = &resume_handle;
624 status = dcerpc_samr_EnumDomains(p, mem_ctx, &e);
625 if (!NT_STATUS_IS_OK(status))
628 for (i=0; i<e.out.sam->count; i++) {
630 struct samr_LookupDomain l;
631 struct samr_OpenDomain o;
633 if (strcmp(e.out.sam->entries[i].name.string,
637 l.in.connect_handle = &connect_handle;
638 l.in.domain_name = &e.out.sam->entries[i].name;
640 status = dcerpc_samr_LookupDomain(p, mem_ctx, &l);
642 if (!NT_STATUS_IS_OK(status))
645 o.in.connect_handle = &connect_handle;
646 o.in.access_mask = 0x200;
647 o.in.sid = l.out.sid;
648 o.out.domain_handle = &domain_handle;
650 status = dcerpc_samr_OpenDomain(p, mem_ctx, &o);
652 if (!NT_STATUS_IS_OK(status))
660 struct samr_LookupNames l;
661 struct samr_String samr_name;
662 struct samr_OpenUser o;
664 samr_name.string = name;
666 l.in.domain_handle = &domain_handle;
668 l.in.names = &samr_name;
670 status = dcerpc_samr_LookupNames(p, mem_ctx, &l);
672 if (!NT_STATUS_IS_OK(status))
675 o.in.domain_handle = &domain_handle;
676 o.in.rid = l.out.rids.ids[0];
677 o.in.access_mask = 0x100;
678 o.out.user_handle = &user_handle;
680 status = dcerpc_samr_OpenUser(p, mem_ctx, &o);
682 if (!NT_STATUS_IS_OK(status))
687 struct samr_GetGroupsForUser g;
688 struct samr_LookupRids l;
691 g.in.user_handle = &user_handle;
693 status = dcerpc_samr_GetGroupsForUser(p, mem_ctx, &g);
694 if (!NT_STATUS_IS_OK(status))
697 l.in.domain_handle = &domain_handle;
698 l.in.num_rids = g.out.rids->count;
699 l.in.rids = talloc_array(mem_ctx, uint32_t, g.out.rids->count);
701 for (i=0; i<g.out.rids->count; i++)
702 l.in.rids[i] = g.out.rids->rids[i].rid;
704 status = dcerpc_samr_LookupRids(p, mem_ctx, &l);
705 if (!NT_STATUS_IS_OK(status)) {
706 talloc_free(mem_ctx);
714 c.in.handle = &user_handle;
715 c.out.handle = &user_handle;
716 dcerpc_samr_Close(p, mem_ctx, &c);
718 c.in.handle = &domain_handle;
719 c.out.handle = &domain_handle;
720 dcerpc_samr_Close(p, mem_ctx, &c);
722 c.in.handle = &connect_handle;
723 c.out.handle = &connect_handle;
724 dcerpc_samr_Close(p, mem_ctx, &c);
728 talloc_free(mem_ctx);
733 static NTSTATUS test_getallsids(struct smbcli_transport *transport,
734 const char *name, BOOL includeDomain)
738 struct dcerpc_pipe *p;
740 struct samr_Connect4 r4;
741 struct policy_handle connect_handle, user_handle;
742 struct policy_handle builtin_handle, domain_handle;
743 struct dom_sid *domain_sid = NULL;
745 struct dom_sid *user_sid;
746 struct dom_sid *primary_group_sid;
747 struct samr_GetGroupsForUser g;
750 mem_ctx = talloc_init("test_getallsids");
752 return NT_STATUS_NO_MEMORY;
754 status = connect_to_pipe(&p, mem_ctx, transport, DCERPC_SAMR_NAME,
756 DCERPC_SAMR_VERSION);
758 if (!NT_STATUS_IS_OK(status)) {
759 talloc_free(mem_ctx);
763 status = dcerpc_bind_auth_none(p, DCERPC_SAMR_UUID,
764 DCERPC_SAMR_VERSION);
766 if (!NT_STATUS_IS_OK(status))
769 r4.in.system_name = talloc_asprintf(mem_ctx, "\\\\%s",
770 dcerpc_server_name(p));
772 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
773 r4.out.connect_handle = &connect_handle;
775 status = dcerpc_samr_Connect4(p, mem_ctx, &r4);
776 if (!NT_STATUS_IS_OK(status))
780 struct samr_EnumDomains e;
781 struct samr_OpenDomain o;
782 uint32_t resume_handle = 0;
785 e.in.connect_handle = &connect_handle;
786 e.in.resume_handle = &resume_handle;
787 e.in.buf_size = (uint32_t)-1;
788 e.out.resume_handle = &resume_handle;
789 status = dcerpc_samr_EnumDomains(p, mem_ctx, &e);
790 if (!NT_STATUS_IS_OK(status))
793 for (i=0; i<e.out.sam->count; i++) {
795 struct samr_LookupDomain l;
797 if (strcmp(e.out.sam->entries[i].name.string,
801 l.in.connect_handle = &connect_handle;
802 l.in.domain_name = &e.out.sam->entries[i].name;
804 status = dcerpc_samr_LookupDomain(p, mem_ctx, &l);
806 if (!NT_STATUS_IS_OK(status))
809 o.in.connect_handle = &connect_handle;
810 o.in.access_mask = 0x280;
811 domain_sid = l.out.sid;
812 o.in.sid = l.out.sid;
813 o.out.domain_handle = &domain_handle;
815 status = dcerpc_samr_OpenDomain(p, mem_ctx, &o);
817 if (!NT_STATUS_IS_OK(status))
821 o.in.connect_handle = &connect_handle;
822 o.in.access_mask = 0x280;
823 o.in.sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32");
824 o.out.domain_handle = &builtin_handle;
826 status = dcerpc_samr_OpenDomain(p, mem_ctx, &o);
828 if (!NT_STATUS_IS_OK(status))
833 struct samr_LookupNames l;
834 struct samr_String samr_name;
835 struct samr_OpenUser o;
837 samr_name.string = name;
839 l.in.domain_handle = &domain_handle;
841 l.in.names = &samr_name;
843 status = dcerpc_samr_LookupNames(p, mem_ctx, &l);
845 if (!NT_STATUS_IS_OK(status))
848 o.in.domain_handle = &domain_handle;
849 o.in.rid = l.out.rids.ids[0];
850 o.in.access_mask = 0x100;
851 o.out.user_handle = &user_handle;
853 status = dcerpc_samr_OpenUser(p, mem_ctx, &o);
855 if (!NT_STATUS_IS_OK(status))
860 struct samr_QueryUserInfo q;
862 q.in.user_handle = &user_handle;
865 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
867 if (!NT_STATUS_IS_OK(status))
870 user_sid = dom_sid_add_rid(mem_ctx, domain_sid,
871 q.out.info->info21.rid);
872 primary_group_sid = dom_sid_add_rid(mem_ctx, domain_sid,
873 q.out.info->info21.primary_gid);
876 g.in.user_handle = &user_handle;
878 status = dcerpc_samr_GetGroupsForUser(p, mem_ctx, &g);
879 if (!NT_STATUS_IS_OK(status))
883 struct lsa_SidArray sids;
884 struct samr_Ids rids;
885 struct samr_GetAliasMembership ga;
888 ga.in.domain_handle = &builtin_handle;
890 sids.num_sids = g.out.rids->count+2;
891 sids.sids = talloc_array(mem_ctx, struct lsa_SidPtr,
892 g.out.rids->count+2);
893 sids.sids[0].sid = user_sid;
894 sids.sids[1].sid = primary_group_sid;
895 for (i=0; i<g.out.rids->count; i++) {
896 sids.sids[i+2].sid = dom_sid_add_rid(mem_ctx,
898 g.out.rids->rids[i].rid);
903 status = dcerpc_samr_GetAliasMembership(p, mem_ctx, &ga);
904 if (!NT_STATUS_IS_OK(status))
908 ga.in.domain_handle = &domain_handle;
909 status = dcerpc_samr_GetAliasMembership(p, mem_ctx,
911 if (!NT_STATUS_IS_OK(status))
919 c.in.handle = &user_handle;
920 c.out.handle = &user_handle;
921 dcerpc_samr_Close(p, mem_ctx, &c);
923 c.in.handle = &domain_handle;
924 c.out.handle = &domain_handle;
925 dcerpc_samr_Close(p, mem_ctx, &c);
927 c.in.handle = &builtin_handle;
928 c.out.handle = &builtin_handle;
929 dcerpc_samr_Close(p, mem_ctx, &c);
931 c.in.handle = &connect_handle;
932 c.out.handle = &connect_handle;
933 dcerpc_samr_Close(p, mem_ctx, &c);
937 talloc_free(mem_ctx);
942 static NTSTATUS test_remoteTOD(struct smbcli_transport *transport)
946 struct dcerpc_pipe *p;
947 struct srvsvc_NetRemoteTOD r;
949 mem_ctx = talloc_init("test_lookupnames");
951 return NT_STATUS_NO_MEMORY;
953 status = connect_to_pipe(&p, mem_ctx, transport, DCERPC_SRVSVC_NAME,
955 DCERPC_SRVSVC_VERSION);
957 if (!NT_STATUS_IS_OK(status)) {
958 talloc_free(mem_ctx);
962 status = dcerpc_bind_auth_none(p, DCERPC_SRVSVC_UUID,
963 DCERPC_SRVSVC_VERSION);
965 if (!NT_STATUS_IS_OK(status))
968 r.in.server_unc = talloc_asprintf(mem_ctx,"\\\\%s",dcerpc_server_name(p));
971 status = dcerpc_srvsvc_NetRemoteTOD(p, mem_ctx, &r);
972 talloc_free(mem_ctx);
977 static BOOL xp_login(const char *dcname, const char *wksname,
978 const char *domain, const char *wkspwd,
979 const char *user1name, const char *user1pw,
980 const char *user2name, const char *user2pw)
986 struct smbcli_transport *transport;
988 struct dcerpc_pipe *netlogon_pipe;
989 struct creds_CredentialState *netlogon_creds;
991 struct dcerpc_pipe *netlogon_schannel_pipe;
993 talloc_enable_leak_report();
995 mem_ctx = talloc_init("rpc_login");
1000 netlogon_creds = talloc(mem_ctx, struct creds_CredentialState);
1001 if (!netlogon_creds) {
1005 if (!NT_STATUS_IS_OK(after_negprot(&transport, dcname, 139,
1009 if (!NT_STATUS_IS_OK(setup_netlogon_creds(transport, &netlogon_pipe,
1010 wksname, domain, wkspwd,
1014 if (!NT_STATUS_IS_OK(test_enumtrusts(transport)))
1017 user1dom = talloc_asprintf(mem_ctx, "%s\\%s", domain, user1name);
1019 if (!NT_STATUS_IS_OK(test_lookupnames(transport, user1dom)))
1022 status = connect_to_pipe(&netlogon_schannel_pipe,
1023 mem_ctx, transport, DCERPC_NETLOGON_NAME,
1024 DCERPC_NETLOGON_UUID,
1025 DCERPC_NETLOGON_VERSION);
1027 if (!NT_STATUS_IS_OK(status))
1030 netlogon_schannel_pipe->conn->flags |= DCERPC_SEAL;
1032 status = dcerpc_bind_auth_password(netlogon_schannel_pipe,
1033 DCERPC_NETLOGON_UUID,
1034 DCERPC_NETLOGON_VERSION,
1037 if (!NT_STATUS_IS_OK(status))
1040 status = torture_samlogon(netlogon_schannel_pipe,
1041 netlogon_creds, wksname, domain,
1042 user1name, user1pw);
1044 if (!NT_STATUS_IS_OK(status))
1047 talloc_free(netlogon_pipe);
1049 status = torture_samlogon(netlogon_schannel_pipe,
1050 netlogon_creds, wksname, domain,
1051 user2name, user2pw);
1053 if (!NT_STATUS_IS_OK(status))
1056 status = test_getgroups(transport, user2name);
1058 if (!NT_STATUS_IS_OK(status))
1061 status = test_remoteTOD(transport);
1063 if (!NT_STATUS_IS_OK(status))
1066 status = test_remoteTOD(transport);
1068 if (!NT_STATUS_IS_OK(status))
1071 status = test_getallsids(transport, user2name, False);
1073 if (!NT_STATUS_IS_OK(status))
1076 status = test_getgroups(transport, user2name);
1078 if (!NT_STATUS_IS_OK(status))
1081 status = test_getallsids(transport, user2name, True);
1083 if (!NT_STATUS_IS_OK(status))
1086 talloc_free(netlogon_schannel_pipe);
1088 talloc_free(transport);
1090 talloc_free(mem_ctx);
1098 const char *username;
1099 const char *password;
1102 static const struct user_pw users[] = {
1103 { "username1", "password1" },
1104 { "username2", "password2" }
1107 static const struct user_pw machines[] = {
1108 { "machine1", "mpw1" },
1109 { "machine2", "mpw2" }
1112 BOOL torture_rpc_login(void)
1115 const char *pdcname = "pdcname";
1116 const char *domainname = "domain";
1119 int useridx1 = rand() % ARRAY_SIZE(users);
1120 int useridx2 = rand() % ARRAY_SIZE(users);
1121 int machidx = rand() % ARRAY_SIZE(machines);
1122 printf("machine: %s user1: %s user2: %s\n",
1123 machines[machidx].username,
1124 users[useridx1].username,
1125 users[useridx2].username);
1128 return xp_login(pdcname, machines[machidx].username,
1129 domainname, machines[machidx].password,
1130 users[useridx1].username,
1131 users[useridx1].password,
1132 users[useridx2].username,
1133 users[useridx2].password);