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"
31 static NTSTATUS after_negprot(struct smbcli_transport **dst_transport,
32 const char *dest_host, uint16_t port,
35 struct smbcli_socket *sock;
36 struct smbcli_transport *transport;
39 sock = smbcli_sock_init(NULL, NULL);
41 return NT_STATUS_NO_MEMORY;
43 if (!smbcli_sock_connect_byname(sock, dest_host, port)) {
45 DEBUG(2,("Failed to establish socket connection - %s\n",
47 return NT_STATUS_UNSUCCESSFUL;
50 transport = smbcli_transport_init(sock, NULL, True);
51 if (transport == NULL)
52 return NT_STATUS_NO_MEMORY;
55 struct nbt_name calling;
56 struct nbt_name called;
58 /* send a NBT session request, if applicable */
59 calling.name = my_name;
60 calling.type = NBT_NAME_CLIENT;
63 nbt_choose_called_name(transport, &called, dest_host, NBT_NAME_SERVER);
65 if (!smbcli_transport_connect(transport, &calling, &called)) {
66 talloc_free(transport);
67 return NT_STATUS_NO_MEMORY;
71 /* negotiate protocol options with the server */
72 status = smb_raw_negotiate(transport, lp_maxprotocol());
73 if (!NT_STATUS_IS_OK(status)) {
74 talloc_free(transport);
75 return NT_STATUS_UNSUCCESSFUL;
78 *dst_transport = transport;
83 static int destroy_session(void *ptr)
85 struct smbcli_session *session = ptr;
86 smb_raw_ulogoff(session);
90 static int destroy_tree_and_session(void *ptr)
92 struct smbcli_tree *tree = ptr;
93 smb_tree_disconnect(tree);
94 talloc_free(tree->session);
98 static NTSTATUS anon_ipc(struct smbcli_transport *transport,
99 struct smbcli_tree **dst_tree)
101 struct smbcli_tree *tree;
102 struct smbcli_session *session;
103 struct smb_composite_sesssetup setup;
108 session = smbcli_session_init(transport, NULL, True);
110 return NT_STATUS_NO_MEMORY;
112 mem_ctx = talloc_init("session_init");
113 if (mem_ctx == NULL) {
114 talloc_free(session);
115 return NT_STATUS_NO_MEMORY;
118 /* prepare a session setup to establish a security context */
119 setup.in.sesskey = transport->negotiate.sesskey;
120 setup.in.capabilities = transport->negotiate.capabilities;
121 setup.in.password = NULL;
123 setup.in.domain = "";
124 setup.in.capabilities &= ~CAP_EXTENDED_SECURITY;
126 status = smb_composite_sesssetup(session, &setup);
127 if (!NT_STATUS_IS_OK(status)) {
128 talloc_free(session);
129 talloc_free(mem_ctx);
130 return NT_STATUS_UNSUCCESSFUL;
133 session->vuid = setup.out.vuid;
135 talloc_set_destructor(session, destroy_session);
137 tree = smbcli_tree_init(session, NULL, True);
139 talloc_free(mem_ctx);
140 return NT_STATUS_NO_MEMORY;
143 tcon.generic.level = RAW_TCON_TCONX;
144 tcon.tconx.in.flags = 0;
145 tcon.tconx.in.password = data_blob(NULL, 0);
146 tcon.tconx.in.path = talloc_asprintf(mem_ctx, "\\\\%s\\IPC$",
147 transport->called.name);
148 tcon.tconx.in.device = "IPC";
150 status = smb_tree_connect(tree, mem_ctx, &tcon);
152 if (!NT_STATUS_IS_OK(status)) {
154 talloc_free(mem_ctx);
155 return NT_STATUS_UNSUCCESSFUL;
158 tree->tid = tcon.tconx.out.tid;
160 if (tcon.tconx.out.dev_type != NULL)
161 tree->device = talloc_strdup(tree, tcon.tconx.out.dev_type);
163 if (tcon.tconx.out.fs_type != NULL)
164 tree->fs_type = talloc_strdup(tree, tcon.tconx.out.fs_type);
166 talloc_set_destructor(tree, destroy_tree_and_session);
168 talloc_free(mem_ctx);
175 static NTSTATUS connect_to_pipe(struct dcerpc_pipe **pp,
177 struct smbcli_transport *transport,
178 const char *pipe_name,
179 const char *pipe_uuid,
180 uint32_t pipe_version)
182 const char *binding = lp_parm_string(-1, "torture", "binding");
183 struct dcerpc_binding b;
185 struct dcerpc_pipe *p;
187 struct smbcli_tree *tree;
189 if (!NT_STATUS_IS_OK(status = anon_ipc(transport, &tree)))
193 return NT_STATUS_INVALID_PARAMETER;
195 p = dcerpc_pipe_init(mem_ctx);
197 return NT_STATUS_NO_MEMORY;
199 tmp_ctx = talloc_new(p);
201 status = dcerpc_parse_binding(tmp_ctx, binding, &b);
202 if (!NT_STATUS_IS_OK(status)) {
203 DEBUG(0,("Failed to parse dcerpc binding '%s'\n", binding));
208 DEBUG(3,("Using binding %s\n", dcerpc_binding_string(tmp_ctx, &b)));
210 if (b.endpoint == NULL) {
211 const struct dcerpc_interface_table *table =
212 idl_iface_by_uuid(pipe_uuid);
213 struct dcerpc_binding default_binding;
217 DEBUG(0,("Unknown interface endpoint '%s'\n",
219 talloc_free(tmp_ctx);
220 return NT_STATUS_INVALID_PARAMETER;
223 /* Find one of the default pipes for this interface */
224 for (i = 0; i < table->endpoints->count; i++) {
225 const char * const *names = table->endpoints->names;
226 status = dcerpc_parse_binding(tmp_ctx, names[i],
229 if (NT_STATUS_IS_OK(status) &&
230 default_binding.transport == NCACN_NP) {
231 pipe_name = default_binding.endpoint;
236 pipe_name = b.endpoint;
239 if (!strncasecmp(pipe_name, "/pipe/", 6) ||
240 !strncasecmp(pipe_name, "\\pipe\\", 6)) {
244 if (pipe_name[0] != '\\') {
245 pipe_name = talloc_asprintf(mem_ctx, "\\%s", pipe_name);
248 status = dcerpc_pipe_open_smb(p->conn, tree, pipe_name);
250 if (!NT_STATUS_IS_OK(status)) {
255 talloc_free(tmp_ctx);
261 static NTSTATUS test_enumtrusts(struct smbcli_transport *transport)
263 struct policy_handle handle;
264 struct lsa_EnumTrustDom r2;
265 uint32_t resume_handle = 0;
266 struct lsa_ObjectAttribute attr;
267 struct lsa_OpenPolicy2 r1;
268 struct lsa_DomainList domains;
271 struct dcerpc_pipe *p;
273 mem_ctx = talloc_init("test_enumtrusts");
275 return NT_STATUS_NO_MEMORY;
277 status = connect_to_pipe(&p, mem_ctx, transport, DCERPC_LSARPC_NAME,
279 DCERPC_LSARPC_VERSION);
281 if (!NT_STATUS_IS_OK(status)) {
282 talloc_free(mem_ctx);
286 status = dcerpc_bind_auth_none(p, DCERPC_LSARPC_UUID,
287 DCERPC_LSARPC_VERSION);
289 if (!NT_STATUS_IS_OK(status))
292 printf("\ntesting OpenPolicy2\n");
295 attr.root_dir = NULL;
296 attr.object_name = NULL;
298 attr.sec_desc = NULL;
301 r1.in.system_name = talloc_asprintf(mem_ctx,
302 "\\\\%s", dcerpc_server_name(p));
304 r1.in.access_mask = 1;
305 r1.out.handle = &handle;
307 status = dcerpc_lsa_OpenPolicy2(p, mem_ctx, &r1);
308 if (!NT_STATUS_IS_OK(status)) {
309 printf("OpenPolicy2 failed - %s\n", nt_errstr(status));
313 printf("\nTesting EnumTrustDom\n");
315 r2.in.handle = &handle;
316 r2.in.resume_handle = &resume_handle;
317 r2.in.max_size = 1000;
318 r2.out.domains = &domains;
319 r2.out.resume_handle = &resume_handle;
321 status = dcerpc_lsa_EnumTrustDom(p, mem_ctx, &r2);
323 if (!NT_STATUS_IS_OK(status) &&
324 !NT_STATUS_EQUAL(status, NT_STATUS_NO_MORE_ENTRIES))
329 talloc_free(mem_ctx);
334 static NTSTATUS test_lookupnames(struct smbcli_transport *transport,
337 struct policy_handle handle;
338 struct lsa_ObjectAttribute attr;
339 struct lsa_OpenPolicy2 r1;
342 struct dcerpc_pipe *p;
344 mem_ctx = talloc_init("test_lookupnames");
346 return NT_STATUS_NO_MEMORY;
348 status = connect_to_pipe(&p, mem_ctx, transport, DCERPC_LSARPC_NAME,
350 DCERPC_LSARPC_VERSION);
352 if (!NT_STATUS_IS_OK(status)) {
353 talloc_free(mem_ctx);
357 status = dcerpc_bind_auth_none(p, DCERPC_LSARPC_UUID,
358 DCERPC_LSARPC_VERSION);
360 if (!NT_STATUS_IS_OK(status))
364 attr.root_dir = NULL;
365 attr.object_name = NULL;
367 attr.sec_desc = NULL;
370 r1.in.system_name = talloc_asprintf(mem_ctx,
371 "\\\\%s", dcerpc_server_name(p));
373 r1.in.access_mask = 0x801;
374 r1.out.handle = &handle;
376 status = dcerpc_lsa_OpenPolicy2(p, mem_ctx, &r1);
377 if (!NT_STATUS_IS_OK(status)) {
378 printf("OpenPolicy2 failed - %s\n", nt_errstr(status));
383 struct lsa_LookupNames l;
384 struct lsa_TransSidArray sids;
385 struct lsa_String lsaname;
391 lsaname.string = name;
393 l.in.handle = &handle;
395 l.in.names = &lsaname;
399 l.out.count = &count;
402 status = dcerpc_lsa_LookupNames(p, mem_ctx, &l);
403 if (!NT_STATUS_IS_OK(status) &&
404 !NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
405 printf("LookupNames failed - %s\n", nt_errstr(status));
407 talloc_free(mem_ctx);
414 struct policy_handle handle2;
416 c.in.handle = &handle;
417 c.out.handle = &handle2;
419 status = dcerpc_lsa_Close(p, mem_ctx, &c);
420 if (!NT_STATUS_IS_OK(status)) {
421 printf("Close failed - %s\n", nt_errstr(status));
428 talloc_free(mem_ctx);
433 static NTSTATUS setup_netlogon_creds(struct smbcli_transport *transport,
434 struct dcerpc_pipe **p,
435 const char *machine_name,
437 const char *machine_pwd,
438 struct creds_CredentialState *creds)
442 struct netr_ServerReqChallenge r;
443 struct netr_ServerAuthenticate2 a;
444 struct netr_Credential credentials1, credentials2, credentials3;
445 const char *plain_pass;
446 struct samr_Password mach_password;
447 uint32_t negotiate_flags = NETLOGON_NEG_AUTH2_FLAGS;
450 mem_ctx = talloc_init("torture_rpc_login");
453 return NT_STATUS_NO_MEMORY;
455 status = connect_to_pipe(p, mem_ctx, transport, DCERPC_NETLOGON_NAME,
456 DCERPC_NETLOGON_UUID,
457 DCERPC_NETLOGON_VERSION);
459 if (!NT_STATUS_IS_OK(status)) {
460 talloc_free(mem_ctx);
464 status = dcerpc_bind_auth_none(*p, DCERPC_NETLOGON_UUID,
465 DCERPC_NETLOGON_VERSION);
467 if (!NT_STATUS_IS_OK(status))
470 printf("Testing ServerReqChallenge\n");
472 r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s",
473 dcerpc_server_name(*p));
474 r.in.computer_name = machine_name;
475 r.in.credentials = &credentials1;
476 r.out.credentials = &credentials2;
478 generate_random_buffer(credentials1.data, sizeof(credentials1.data));
480 status = dcerpc_netr_ServerReqChallenge(*p, mem_ctx, &r);
481 if (!NT_STATUS_IS_OK(status)) {
482 printf("ServerReqChallenge - %s\n", nt_errstr(status));
486 plain_pass = machine_pwd;
488 printf("Unable to fetch machine password!\n");
492 E_md4hash(plain_pass, mach_password.hash);
494 a.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s",
495 dcerpc_server_name(*p));
496 a.in.account_name = talloc_asprintf(mem_ctx, "%s$", machine_name);
497 a.in.secure_channel_type = SEC_CHAN_WKSTA;
498 a.in.computer_name = machine_name;
499 a.in.negotiate_flags = &negotiate_flags;
500 a.out.negotiate_flags = &negotiate_flags;
501 a.in.credentials = &credentials3;
502 a.out.credentials = &credentials3;
504 creds_client_init(creds, &credentials1, &credentials2,
505 &mach_password, &credentials3,
508 printf("Testing ServerAuthenticate2\n");
510 status = dcerpc_netr_ServerAuthenticate2(*p, mem_ctx, &a);
511 if (!NT_STATUS_IS_OK(status)) {
512 printf("ServerAuthenticate2 - %s\n", nt_errstr(status));
516 if (!creds_client_check(creds, &credentials3)) {
517 printf("Credential chaining failed\n");
521 printf("negotiate_flags=0x%08x\n", negotiate_flags);
523 talloc_free(mem_ctx);
527 static NTSTATUS torture_samlogon(struct dcerpc_pipe *p,
528 struct creds_CredentialState *netlogon_creds,
529 const char *workstation,
531 const char *username,
532 const char *password)
535 struct netr_LogonSamLogon log;
536 struct netr_NetworkInfo ninfo;
537 struct netr_Authenticator auth, auth2;
538 uint8_t user_session_key[16];
539 DATA_BLOB ntlmv2_response = data_blob(NULL, 0);
540 DATA_BLOB lmv2_response = data_blob(NULL, 0);
541 DATA_BLOB names_blob;
545 mem_ctx = talloc_init("torture_samlogon");
547 ZERO_STRUCT(user_session_key);
549 printf("testing netr_LogonSamLogon\n");
551 log.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s",
552 dcerpc_server_name(p));
553 log.in.workstation = workstation;
554 log.in.credential = &auth;
555 log.in.return_authenticator = &auth2;
556 log.in.validation_level = 3;
557 log.in.logon_level = 2;
558 log.in.logon.network = &ninfo;
560 chall = data_blob_talloc(mem_ctx, NULL, 8);
561 generate_random_buffer(chall.data, 8);
563 names_blob = NTLMv2_generate_names_blob(mem_ctx, workstation,
565 ZERO_STRUCT(user_session_key);
567 if (!SMBNTLMv2encrypt(username, domain, password,
569 &lmv2_response, &ntlmv2_response,
571 data_blob_free(&names_blob);
572 talloc_free(mem_ctx);
573 return NT_STATUS_UNSUCCESSFUL;
575 data_blob_free(&names_blob);
577 ninfo.identity_info.domain_name.string = domain;
578 ninfo.identity_info.parameter_control = 0;
579 ninfo.identity_info.logon_id_low = 0;
580 ninfo.identity_info.logon_id_high = 0;
581 ninfo.identity_info.account_name.string = username;
582 ninfo.identity_info.workstation.string = workstation;
583 memcpy(ninfo.challenge, chall.data, 8);
584 ninfo.nt.data = ntlmv2_response.data;
585 ninfo.nt.length = ntlmv2_response.length;
586 ninfo.lm.data = NULL;
590 creds_client_authenticator(netlogon_creds, &auth);
592 log.out.return_authenticator = NULL;
593 status = dcerpc_netr_LogonSamLogon(p, mem_ctx, &log);
594 talloc_free(mem_ctx);
595 data_blob_free(&lmv2_response);
596 data_blob_free(&ntlmv2_response);
600 static NTSTATUS test_getgroups(struct smbcli_transport *transport,
605 struct dcerpc_pipe *p;
607 struct samr_Connect4 r4;
608 struct policy_handle connect_handle, domain_handle, user_handle;
610 mem_ctx = talloc_init("test_lookupnames");
612 return NT_STATUS_NO_MEMORY;
614 status = connect_to_pipe(&p, mem_ctx, transport, DCERPC_SAMR_NAME,
616 DCERPC_SAMR_VERSION);
618 if (!NT_STATUS_IS_OK(status)) {
619 talloc_free(mem_ctx);
623 status = dcerpc_bind_auth_none(p, DCERPC_SAMR_UUID,
624 DCERPC_SAMR_VERSION);
626 if (!NT_STATUS_IS_OK(status))
629 r4.in.system_name = talloc_asprintf(mem_ctx, "\\\\%s",
630 dcerpc_server_name(p));
632 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
633 r4.out.connect_handle = &connect_handle;
635 status = dcerpc_samr_Connect4(p, mem_ctx, &r4);
636 if (!NT_STATUS_IS_OK(status))
640 struct samr_EnumDomains e;
641 uint32_t resume_handle = 0;
644 e.in.connect_handle = &connect_handle;
645 e.in.resume_handle = &resume_handle;
646 e.in.buf_size = (uint32_t)-1;
647 e.out.resume_handle = &resume_handle;
648 status = dcerpc_samr_EnumDomains(p, mem_ctx, &e);
649 if (!NT_STATUS_IS_OK(status))
652 for (i=0; i<e.out.sam->count; i++) {
654 struct samr_LookupDomain l;
655 struct samr_OpenDomain o;
657 if (strcmp(e.out.sam->entries[i].name.string,
661 l.in.connect_handle = &connect_handle;
662 l.in.domain = &e.out.sam->entries[i].name;
664 status = dcerpc_samr_LookupDomain(p, mem_ctx, &l);
666 if (!NT_STATUS_IS_OK(status))
669 o.in.connect_handle = &connect_handle;
670 o.in.access_mask = 0x200;
671 o.in.sid = l.out.sid;
672 o.out.domain_handle = &domain_handle;
674 status = dcerpc_samr_OpenDomain(p, mem_ctx, &o);
676 if (!NT_STATUS_IS_OK(status))
684 struct samr_LookupNames l;
685 struct samr_String samr_name;
686 struct samr_OpenUser o;
688 samr_name.string = name;
690 l.in.domain_handle = &domain_handle;
692 l.in.names = &samr_name;
694 status = dcerpc_samr_LookupNames(p, mem_ctx, &l);
696 if (!NT_STATUS_IS_OK(status))
699 o.in.domain_handle = &domain_handle;
700 o.in.rid = l.out.rids.ids[0];
701 o.in.access_mask = 0x100;
702 o.out.user_handle = &user_handle;
704 status = dcerpc_samr_OpenUser(p, mem_ctx, &o);
706 if (!NT_STATUS_IS_OK(status))
711 struct samr_GetGroupsForUser g;
712 struct samr_LookupRids l;
715 g.in.user_handle = &user_handle;
717 status = dcerpc_samr_GetGroupsForUser(p, mem_ctx, &g);
718 if (!NT_STATUS_IS_OK(status))
721 l.in.domain_handle = &domain_handle;
722 l.in.num_rids = g.out.rids->count;
723 l.in.rids = talloc_array(mem_ctx, uint32_t, g.out.rids->count);
725 for (i=0; i<g.out.rids->count; i++)
726 l.in.rids[i] = g.out.rids->rid[i].rid;
728 status = dcerpc_samr_LookupRids(p, mem_ctx, &l);
729 if (!NT_STATUS_IS_OK(status)) {
730 talloc_free(mem_ctx);
738 c.in.handle = &user_handle;
739 c.out.handle = &user_handle;
740 dcerpc_samr_Close(p, mem_ctx, &c);
742 c.in.handle = &domain_handle;
743 c.out.handle = &domain_handle;
744 dcerpc_samr_Close(p, mem_ctx, &c);
746 c.in.handle = &connect_handle;
747 c.out.handle = &connect_handle;
748 dcerpc_samr_Close(p, mem_ctx, &c);
752 talloc_free(mem_ctx);
757 static NTSTATUS test_getallsids(struct smbcli_transport *transport,
758 const char *name, BOOL includeDomain)
762 struct dcerpc_pipe *p;
764 struct samr_Connect4 r4;
765 struct policy_handle connect_handle, user_handle;
766 struct policy_handle builtin_handle, domain_handle;
767 struct dom_sid *domain_sid = NULL;
769 struct dom_sid *user_sid;
770 struct dom_sid *primary_group_sid;
771 struct samr_GetGroupsForUser g;
774 mem_ctx = talloc_init("test_getallsids");
776 return NT_STATUS_NO_MEMORY;
778 status = connect_to_pipe(&p, mem_ctx, transport, DCERPC_SAMR_NAME,
780 DCERPC_SAMR_VERSION);
782 if (!NT_STATUS_IS_OK(status)) {
783 talloc_free(mem_ctx);
787 status = dcerpc_bind_auth_none(p, DCERPC_SAMR_UUID,
788 DCERPC_SAMR_VERSION);
790 if (!NT_STATUS_IS_OK(status))
793 r4.in.system_name = talloc_asprintf(mem_ctx, "\\\\%s",
794 dcerpc_server_name(p));
796 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
797 r4.out.connect_handle = &connect_handle;
799 status = dcerpc_samr_Connect4(p, mem_ctx, &r4);
800 if (!NT_STATUS_IS_OK(status))
804 struct samr_EnumDomains e;
805 struct samr_OpenDomain o;
806 uint32_t resume_handle = 0;
809 e.in.connect_handle = &connect_handle;
810 e.in.resume_handle = &resume_handle;
811 e.in.buf_size = (uint32_t)-1;
812 e.out.resume_handle = &resume_handle;
813 status = dcerpc_samr_EnumDomains(p, mem_ctx, &e);
814 if (!NT_STATUS_IS_OK(status))
817 for (i=0; i<e.out.sam->count; i++) {
819 struct samr_LookupDomain l;
821 if (strcmp(e.out.sam->entries[i].name.string,
825 l.in.connect_handle = &connect_handle;
826 l.in.domain = &e.out.sam->entries[i].name;
828 status = dcerpc_samr_LookupDomain(p, mem_ctx, &l);
830 if (!NT_STATUS_IS_OK(status))
833 o.in.connect_handle = &connect_handle;
834 o.in.access_mask = 0x280;
835 domain_sid = l.out.sid;
836 o.in.sid = l.out.sid;
837 o.out.domain_handle = &domain_handle;
839 status = dcerpc_samr_OpenDomain(p, mem_ctx, &o);
841 if (!NT_STATUS_IS_OK(status))
845 o.in.connect_handle = &connect_handle;
846 o.in.access_mask = 0x280;
847 o.in.sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32");
848 o.out.domain_handle = &builtin_handle;
850 status = dcerpc_samr_OpenDomain(p, mem_ctx, &o);
852 if (!NT_STATUS_IS_OK(status))
857 struct samr_LookupNames l;
858 struct samr_String samr_name;
859 struct samr_OpenUser o;
861 samr_name.string = name;
863 l.in.domain_handle = &domain_handle;
865 l.in.names = &samr_name;
867 status = dcerpc_samr_LookupNames(p, mem_ctx, &l);
869 if (!NT_STATUS_IS_OK(status))
872 o.in.domain_handle = &domain_handle;
873 o.in.rid = l.out.rids.ids[0];
874 o.in.access_mask = 0x100;
875 o.out.user_handle = &user_handle;
877 status = dcerpc_samr_OpenUser(p, mem_ctx, &o);
879 if (!NT_STATUS_IS_OK(status))
884 struct samr_QueryUserInfo q;
886 q.in.user_handle = &user_handle;
889 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
891 if (!NT_STATUS_IS_OK(status))
894 user_sid = dom_sid_add_rid(mem_ctx, domain_sid,
895 q.out.info->info21.rid);
896 primary_group_sid = dom_sid_add_rid(mem_ctx, domain_sid,
897 q.out.info->info21.primary_gid);
900 g.in.user_handle = &user_handle;
902 status = dcerpc_samr_GetGroupsForUser(p, mem_ctx, &g);
903 if (!NT_STATUS_IS_OK(status))
907 struct lsa_SidArray sids;
908 struct samr_Ids rids;
909 struct samr_GetAliasMembership ga;
912 ga.in.domain_handle = &builtin_handle;
914 sids.num_sids = g.out.rids->count+2;
915 sids.sids = talloc_array(mem_ctx, struct lsa_SidPtr,
916 g.out.rids->count+2);
917 sids.sids[0].sid = user_sid;
918 sids.sids[1].sid = primary_group_sid;
919 for (i=0; i<g.out.rids->count; i++) {
920 sids.sids[i+2].sid = dom_sid_add_rid(mem_ctx,
922 g.out.rids->rid[i].rid);
927 status = dcerpc_samr_GetAliasMembership(p, mem_ctx, &ga);
928 if (!NT_STATUS_IS_OK(status))
932 ga.in.domain_handle = &domain_handle;
933 status = dcerpc_samr_GetAliasMembership(p, mem_ctx,
935 if (!NT_STATUS_IS_OK(status))
943 c.in.handle = &user_handle;
944 c.out.handle = &user_handle;
945 dcerpc_samr_Close(p, mem_ctx, &c);
947 c.in.handle = &domain_handle;
948 c.out.handle = &domain_handle;
949 dcerpc_samr_Close(p, mem_ctx, &c);
951 c.in.handle = &builtin_handle;
952 c.out.handle = &builtin_handle;
953 dcerpc_samr_Close(p, mem_ctx, &c);
955 c.in.handle = &connect_handle;
956 c.out.handle = &connect_handle;
957 dcerpc_samr_Close(p, mem_ctx, &c);
961 talloc_free(mem_ctx);
966 static NTSTATUS test_remoteTOD(struct smbcli_transport *transport)
970 struct dcerpc_pipe *p;
971 struct srvsvc_NetRemoteTOD r;
973 mem_ctx = talloc_init("test_lookupnames");
975 return NT_STATUS_NO_MEMORY;
977 status = connect_to_pipe(&p, mem_ctx, transport, DCERPC_SRVSVC_NAME,
979 DCERPC_SRVSVC_VERSION);
981 if (!NT_STATUS_IS_OK(status)) {
982 talloc_free(mem_ctx);
986 status = dcerpc_bind_auth_none(p, DCERPC_SRVSVC_UUID,
987 DCERPC_SRVSVC_VERSION);
989 if (!NT_STATUS_IS_OK(status))
992 r.in.server_unc = talloc_asprintf(mem_ctx,"\\\\%s",dcerpc_server_name(p));
995 status = dcerpc_srvsvc_NetRemoteTOD(p, mem_ctx, &r);
996 talloc_free(mem_ctx);
1001 static BOOL xp_login(const char *dcname, const char *wksname,
1002 const char *domain, const char *wkspwd,
1003 const char *user1name, const char *user1pw,
1004 const char *user2name, const char *user2pw)
1007 TALLOC_CTX *mem_ctx;
1010 struct smbcli_transport *transport;
1012 struct dcerpc_pipe *netlogon_pipe;
1013 struct creds_CredentialState *netlogon_creds;
1015 struct dcerpc_pipe *netlogon_schannel_pipe;
1017 talloc_enable_leak_report();
1019 mem_ctx = talloc_init("rpc_login");
1021 if (mem_ctx == NULL)
1024 netlogon_creds = talloc(mem_ctx, struct creds_CredentialState);
1025 if (!netlogon_creds) {
1029 if (!NT_STATUS_IS_OK(after_negprot(&transport, dcname, 139,
1033 if (!NT_STATUS_IS_OK(setup_netlogon_creds(transport, &netlogon_pipe,
1034 wksname, domain, wkspwd,
1038 if (!NT_STATUS_IS_OK(test_enumtrusts(transport)))
1041 user1dom = talloc_asprintf(mem_ctx, "%s\\%s", domain, user1name);
1043 if (!NT_STATUS_IS_OK(test_lookupnames(transport, user1dom)))
1046 status = connect_to_pipe(&netlogon_schannel_pipe,
1047 mem_ctx, transport, DCERPC_NETLOGON_NAME,
1048 DCERPC_NETLOGON_UUID,
1049 DCERPC_NETLOGON_VERSION);
1051 if (!NT_STATUS_IS_OK(status))
1054 netlogon_schannel_pipe->conn->flags |= DCERPC_SEAL;
1056 status = dcerpc_bind_auth_schannel_withkey(netlogon_schannel_pipe,
1057 DCERPC_NETLOGON_UUID,
1058 DCERPC_NETLOGON_VERSION,
1062 if (!NT_STATUS_IS_OK(status))
1065 status = torture_samlogon(netlogon_schannel_pipe,
1066 netlogon_creds, wksname, domain,
1067 user1name, user1pw);
1069 if (!NT_STATUS_IS_OK(status))
1072 talloc_free(netlogon_pipe);
1074 status = torture_samlogon(netlogon_schannel_pipe,
1075 netlogon_creds, wksname, domain,
1076 user2name, user2pw);
1078 if (!NT_STATUS_IS_OK(status))
1081 status = test_getgroups(transport, user2name);
1083 if (!NT_STATUS_IS_OK(status))
1086 status = test_remoteTOD(transport);
1088 if (!NT_STATUS_IS_OK(status))
1091 status = test_remoteTOD(transport);
1093 if (!NT_STATUS_IS_OK(status))
1096 status = test_getallsids(transport, user2name, False);
1098 if (!NT_STATUS_IS_OK(status))
1101 status = test_getgroups(transport, user2name);
1103 if (!NT_STATUS_IS_OK(status))
1106 status = test_getallsids(transport, user2name, True);
1108 if (!NT_STATUS_IS_OK(status))
1111 talloc_free(netlogon_schannel_pipe);
1113 talloc_free(transport);
1115 talloc_free(mem_ctx);
1121 const char *username;
1122 const char *password;
1125 static const struct user_pw users[] = {
1126 { "username1", "password1" },
1127 { "username2", "password2" }
1130 static const struct user_pw machines[] = {
1131 { "machine1", "mpw1" },
1132 { "machine2", "mpw2" }
1135 BOOL torture_rpc_login(void)
1137 const char *pdcname = "pdcname";
1138 const char *domainname = "domain";
1140 int useridx1 = rand() % ARRAY_SIZE(users);
1141 int useridx2 = rand() % ARRAY_SIZE(users);
1142 int machidx = rand() % ARRAY_SIZE(machines);
1143 printf("machine: %s user1: %s user2: %s\n",
1144 machines[machidx].username,
1145 users[useridx1].username,
1146 users[useridx2].username);
1148 return xp_login(pdcname, machines[machidx].username,
1149 domainname, machines[machidx].password,
1150 users[useridx1].username,
1151 users[useridx1].password,
1152 users[useridx2].username,
1153 users[useridx2].password);