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"
30 static int destroy_transport(void *ptr)
32 struct smbcli_transport *trans = ptr;
33 talloc_free(trans->socket);
37 static NTSTATUS after_negprot(struct smbcli_transport **dst_transport,
38 const char *dest_host, uint16_t port,
41 struct smbcli_socket *sock;
42 struct smbcli_transport *transport;
45 sock = smbcli_sock_init(NULL);
47 return NT_STATUS_NO_MEMORY;
49 if (!smbcli_sock_connect_byname(sock, dest_host, port)) {
51 DEBUG(2,("Failed to establish socket connection - %s\n",
53 return NT_STATUS_UNSUCCESSFUL;
56 transport = smbcli_transport_init(sock);
58 if (transport == NULL)
59 return NT_STATUS_NO_MEMORY;
61 talloc_set_destructor(transport, destroy_transport);
64 struct nmb_name calling;
65 struct nmb_name called;
67 /* send a NBT session request, if applicable */
68 make_nmb_name(&calling, my_name, 0x0);
69 choose_called_name(&called, dest_host, 0x20);
71 if (!smbcli_transport_connect(transport, &calling, &called)) {
72 talloc_free(transport);
73 return NT_STATUS_NO_MEMORY;
77 /* negotiate protocol options with the server */
78 status = smb_raw_negotiate(transport);
79 if (!NT_STATUS_IS_OK(status)) {
80 talloc_free(transport);
81 return NT_STATUS_UNSUCCESSFUL;
84 *dst_transport = transport;
89 static int destroy_session(void *ptr)
91 struct smbcli_session *session = ptr;
92 smb_raw_ulogoff(session);
96 static int destroy_tree_and_session(void *ptr)
98 struct smbcli_tree *tree = ptr;
99 smb_tree_disconnect(tree);
100 talloc_free(tree->session);
104 static NTSTATUS anon_ipc(struct smbcli_transport *transport,
105 struct smbcli_tree **dst_tree)
107 struct smbcli_tree *tree;
108 struct smbcli_session *session;
109 union smb_sesssetup setup;
114 session = smbcli_session_init(transport);
116 return NT_STATUS_NO_MEMORY;
118 mem_ctx = talloc_init("session_init");
119 if (mem_ctx == NULL) {
120 talloc_free(session);
121 return NT_STATUS_NO_MEMORY;
124 /* prepare a session setup to establish a security context */
125 setup.generic.level = RAW_SESSSETUP_GENERIC;
126 setup.generic.in.sesskey = transport->negotiate.sesskey;
127 setup.generic.in.capabilities = transport->negotiate.capabilities;
128 setup.generic.in.password = NULL;
129 setup.generic.in.user = "";
130 setup.generic.in.domain = "";
131 setup.generic.in.capabilities &= ~CAP_EXTENDED_SECURITY;
133 status = smb_raw_session_setup(session, mem_ctx, &setup);
134 if (!NT_STATUS_IS_OK(status)) {
135 talloc_free(session);
136 talloc_free(mem_ctx);
137 return NT_STATUS_UNSUCCESSFUL;
140 session->vuid = setup.generic.out.vuid;
142 talloc_set_destructor(session, destroy_session);
144 tree = smbcli_tree_init(session);
145 talloc_free(session);
147 talloc_free(mem_ctx);
148 return NT_STATUS_NO_MEMORY;
151 tcon.generic.level = RAW_TCON_TCONX;
152 tcon.tconx.in.flags = 0;
153 tcon.tconx.in.password = data_blob(NULL, 0);
154 tcon.tconx.in.path = talloc_asprintf(mem_ctx, "\\\\%s\\IPC$",
155 transport->called.name);
156 tcon.tconx.in.device = "IPC";
158 status = smb_tree_connect(tree, mem_ctx, &tcon);
160 if (!NT_STATUS_IS_OK(status)) {
162 talloc_free(mem_ctx);
163 return NT_STATUS_UNSUCCESSFUL;
166 tree->tid = tcon.tconx.out.cnum;
168 if (tcon.tconx.out.dev_type != NULL)
169 tree->device = talloc_strdup(tree, tcon.tconx.out.dev_type);
171 if (tcon.tconx.out.fs_type != NULL)
172 tree->fs_type = talloc_strdup(tree, tcon.tconx.out.fs_type);
174 talloc_set_destructor(tree, destroy_tree_and_session);
176 talloc_free(mem_ctx);
183 static int close_pipe(void *ptr)
185 struct dcerpc_pipe *p = ptr;
186 dcerpc_pipe_close(p);
190 static NTSTATUS connect_to_pipe(struct dcerpc_pipe **p,
191 struct smbcli_transport *transport,
192 const char *pipe_name,
193 const char *pipe_uuid,
194 uint32_t pipe_version)
196 const char *binding = lp_parm_string(-1, "torture", "binding");
197 struct dcerpc_binding b;
200 struct smbcli_tree *tree;
202 if (!NT_STATUS_IS_OK(status = anon_ipc(transport, &tree)))
206 return NT_STATUS_INVALID_PARAMETER;
208 mem_ctx = talloc_init("dcerpc_pipe_connect");
209 if (!mem_ctx) return NT_STATUS_NO_MEMORY;
211 status = dcerpc_parse_binding(mem_ctx, binding, &b);
212 if (!NT_STATUS_IS_OK(status)) {
213 DEBUG(0,("Failed to parse dcerpc binding '%s'\n", binding));
214 talloc_destroy(mem_ctx);
218 DEBUG(3,("Using binding %s\n", dcerpc_binding_string(mem_ctx, &b)));
220 if (b.endpoint == NULL) {
221 const struct dcerpc_interface_table *table =
222 idl_iface_by_uuid(pipe_uuid);
223 struct dcerpc_binding default_binding;
227 DEBUG(0,("Unknown interface endpoint '%s'\n",
229 talloc_destroy(mem_ctx);
230 return NT_STATUS_INVALID_PARAMETER;
233 /* Find one of the default pipes for this interface */
234 for (i = 0; i < table->endpoints->count; i++) {
235 const char * const *names = table->endpoints->names;
236 status = dcerpc_parse_binding(mem_ctx, names[i],
239 if (NT_STATUS_IS_OK(status) &&
240 default_binding.transport == NCACN_NP) {
241 pipe_name = default_binding.endpoint;
246 pipe_name = b.endpoint;
249 if (!strncasecmp(pipe_name, "/pipe/", 6) ||
250 !strncasecmp(pipe_name, "\\pipe\\", 6)) {
254 if (pipe_name[0] != '\\') {
255 pipe_name = talloc_asprintf(mem_ctx, "\\%s", pipe_name);
258 status = dcerpc_pipe_open_smb(p, tree, pipe_name);
260 if (!NT_STATUS_IS_OK(status))
263 talloc_destroy(mem_ctx);
265 talloc_set_destructor(*p, close_pipe);
266 talloc_steal(*p, tree);
271 static NTSTATUS test_enumtrusts(struct smbcli_transport *transport)
273 struct policy_handle handle;
274 struct lsa_EnumTrustDom r2;
275 uint32_t resume_handle = 0;
276 struct lsa_ObjectAttribute attr;
277 struct lsa_OpenPolicy2 r1;
278 struct lsa_DomainList domains;
281 struct dcerpc_pipe *p;
283 mem_ctx = talloc_init("test_enumtrusts");
285 return NT_STATUS_NO_MEMORY;
287 status = connect_to_pipe(&p, transport, DCERPC_LSARPC_NAME,
289 DCERPC_LSARPC_VERSION);
291 if (!NT_STATUS_IS_OK(status)) {
292 talloc_destroy(mem_ctx);
296 status = dcerpc_bind_auth_none(p, DCERPC_LSARPC_UUID,
297 DCERPC_LSARPC_VERSION);
299 if (!NT_STATUS_IS_OK(status))
302 printf("\ntesting OpenPolicy2\n");
305 attr.root_dir = NULL;
306 attr.object_name = NULL;
308 attr.sec_desc = NULL;
311 r1.in.system_name = talloc_asprintf(mem_ctx,
312 "\\\\%s", dcerpc_server_name(p));
314 r1.in.access_mask = 1;
315 r1.out.handle = &handle;
317 status = dcerpc_lsa_OpenPolicy2(p, mem_ctx, &r1);
318 if (!NT_STATUS_IS_OK(status)) {
319 printf("OpenPolicy2 failed - %s\n", nt_errstr(status));
323 printf("\nTesting EnumTrustDom\n");
325 r2.in.handle = &handle;
326 r2.in.resume_handle = &resume_handle;
327 r2.in.num_entries = 1000;
328 r2.out.domains = &domains;
329 r2.out.resume_handle = &resume_handle;
331 status = dcerpc_lsa_EnumTrustDom(p, mem_ctx, &r2);
333 if (!NT_STATUS_IS_OK(status) &&
334 !NT_STATUS_EQUAL(status, NT_STATUS_NO_MORE_ENTRIES))
339 talloc_destroy(mem_ctx);
344 static NTSTATUS test_lookupnames(struct smbcli_transport *transport,
347 struct policy_handle handle;
348 struct lsa_ObjectAttribute attr;
349 struct lsa_OpenPolicy2 r1;
352 struct dcerpc_pipe *p;
354 mem_ctx = talloc_init("test_lookupnames");
356 return NT_STATUS_NO_MEMORY;
358 status = connect_to_pipe(&p, transport, DCERPC_LSARPC_NAME,
360 DCERPC_LSARPC_VERSION);
362 if (!NT_STATUS_IS_OK(status)) {
363 talloc_destroy(mem_ctx);
367 status = dcerpc_bind_auth_none(p, DCERPC_LSARPC_UUID,
368 DCERPC_LSARPC_VERSION);
370 if (!NT_STATUS_IS_OK(status))
374 attr.root_dir = NULL;
375 attr.object_name = NULL;
377 attr.sec_desc = NULL;
380 r1.in.system_name = talloc_asprintf(mem_ctx,
381 "\\\\%s", dcerpc_server_name(p));
383 r1.in.access_mask = 0x801;
384 r1.out.handle = &handle;
386 status = dcerpc_lsa_OpenPolicy2(p, mem_ctx, &r1);
387 if (!NT_STATUS_IS_OK(status)) {
388 printf("OpenPolicy2 failed - %s\n", nt_errstr(status));
393 struct lsa_LookupNames l;
394 struct lsa_TransSidArray sids;
395 struct lsa_String lsaname;
401 lsaname.string = name;
403 l.in.handle = &handle;
405 l.in.names = &lsaname;
409 l.out.count = &count;
412 status = dcerpc_lsa_LookupNames(p, mem_ctx, &l);
413 if (!NT_STATUS_IS_OK(status) &&
414 !NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
415 printf("LookupNames failed - %s\n", nt_errstr(status));
417 talloc_destroy(mem_ctx);
424 struct policy_handle handle2;
426 c.in.handle = &handle;
427 c.out.handle = &handle2;
429 status = dcerpc_lsa_Close(p, mem_ctx, &c);
430 if (!NT_STATUS_IS_OK(status)) {
431 printf("Close failed - %s\n", nt_errstr(status));
438 talloc_destroy(mem_ctx);
443 static NTSTATUS setup_netlogon_creds(struct smbcli_transport *transport,
444 struct dcerpc_pipe **p,
445 const char *machine_name,
447 const char *machine_pwd,
448 struct creds_CredentialState *creds)
452 struct netr_ServerReqChallenge r;
453 struct netr_ServerAuthenticate2 a;
454 struct netr_Credential credentials1, credentials2, credentials3;
455 const char *plain_pass;
456 struct samr_Password mach_password;
457 uint32_t negotiate_flags = NETLOGON_NEG_AUTH2_FLAGS;
460 mem_ctx = talloc_init("torture_rpc_login");
463 return NT_STATUS_NO_MEMORY;
465 status = connect_to_pipe(p, transport, DCERPC_NETLOGON_NAME,
466 DCERPC_NETLOGON_UUID,
467 DCERPC_NETLOGON_VERSION);
469 if (!NT_STATUS_IS_OK(status)) {
470 talloc_destroy(mem_ctx);
474 status = dcerpc_bind_auth_none(*p, DCERPC_NETLOGON_UUID,
475 DCERPC_NETLOGON_VERSION);
477 if (!NT_STATUS_IS_OK(status))
480 printf("Testing ServerReqChallenge\n");
482 r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s",
483 dcerpc_server_name(*p));
484 r.in.computer_name = machine_name;
485 r.in.credentials = &credentials1;
486 r.out.credentials = &credentials2;
488 generate_random_buffer(credentials1.data, sizeof(credentials1.data));
490 status = dcerpc_netr_ServerReqChallenge(*p, mem_ctx, &r);
491 if (!NT_STATUS_IS_OK(status)) {
492 printf("ServerReqChallenge - %s\n", nt_errstr(status));
496 plain_pass = machine_pwd;
498 printf("Unable to fetch machine password!\n");
502 E_md4hash(plain_pass, mach_password.hash);
504 a.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s",
505 dcerpc_server_name(*p));
506 a.in.account_name = talloc_asprintf(mem_ctx, "%s$", machine_name);
507 a.in.secure_channel_type = SEC_CHAN_WKSTA;
508 a.in.computer_name = machine_name;
509 a.in.negotiate_flags = &negotiate_flags;
510 a.out.negotiate_flags = &negotiate_flags;
511 a.in.credentials = &credentials3;
512 a.out.credentials = &credentials3;
514 creds_client_init(creds, &credentials1, &credentials2,
515 &mach_password, &credentials3,
518 printf("Testing ServerAuthenticate2\n");
520 status = dcerpc_netr_ServerAuthenticate2(*p, mem_ctx, &a);
521 if (!NT_STATUS_IS_OK(status)) {
522 printf("ServerAuthenticate2 - %s\n", nt_errstr(status));
526 if (!creds_client_check(creds, &credentials3)) {
527 printf("Credential chaining failed\n");
531 printf("negotiate_flags=0x%08x\n", negotiate_flags);
533 talloc_free(mem_ctx);
537 static NTSTATUS torture_samlogon(struct dcerpc_pipe *p,
538 struct creds_CredentialState *netlogon_creds,
539 const char *workstation,
541 const char *username,
542 const char *password)
545 struct netr_LogonSamLogon log;
546 struct netr_NetworkInfo ninfo;
547 struct netr_Authenticator auth, auth2;
548 uint8_t user_session_key[16];
549 DATA_BLOB ntlmv2_response = data_blob(NULL, 0);
550 DATA_BLOB lmv2_response = data_blob(NULL, 0);
551 DATA_BLOB names_blob;
555 mem_ctx = talloc_init("torture_samlogon");
557 ZERO_STRUCT(user_session_key);
559 printf("testing netr_LogonSamLogon\n");
561 log.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s",
562 dcerpc_server_name(p));
563 log.in.workstation = workstation;
564 log.in.credential = &auth;
565 log.in.return_authenticator = &auth2;
566 log.in.validation_level = 3;
567 log.in.logon_level = 2;
568 log.in.logon.network = &ninfo;
570 chall = data_blob_talloc(mem_ctx, NULL, 8);
571 generate_random_buffer(chall.data, 8);
573 names_blob = NTLMv2_generate_names_blob(mem_ctx, workstation,
575 ZERO_STRUCT(user_session_key);
577 if (!SMBNTLMv2encrypt(username, domain, password,
579 &lmv2_response, &ntlmv2_response,
581 data_blob_free(&names_blob);
582 talloc_destroy(mem_ctx);
583 return NT_STATUS_UNSUCCESSFUL;
585 data_blob_free(&names_blob);
587 ninfo.identity_info.domain_name.string = domain;
588 ninfo.identity_info.parameter_control = 0;
589 ninfo.identity_info.logon_id_low = 0;
590 ninfo.identity_info.logon_id_high = 0;
591 ninfo.identity_info.account_name.string = username;
592 ninfo.identity_info.workstation.string = workstation;
593 memcpy(ninfo.challenge, chall.data, 8);
594 ninfo.nt.data = ntlmv2_response.data;
595 ninfo.nt.length = ntlmv2_response.length;
596 ninfo.lm.data = NULL;
600 creds_client_authenticator(netlogon_creds, &auth);
602 log.out.return_authenticator = NULL;
603 status = dcerpc_netr_LogonSamLogon(p, mem_ctx, &log);
604 talloc_destroy(mem_ctx);
605 data_blob_free(&lmv2_response);
606 data_blob_free(&ntlmv2_response);
610 static NTSTATUS test_getgroups(struct smbcli_transport *transport,
615 struct dcerpc_pipe *p;
617 struct samr_Connect4 r4;
618 struct policy_handle connect_handle, domain_handle, user_handle;
620 mem_ctx = talloc_init("test_lookupnames");
622 return NT_STATUS_NO_MEMORY;
624 status = connect_to_pipe(&p, transport, DCERPC_SAMR_NAME,
626 DCERPC_SAMR_VERSION);
628 if (!NT_STATUS_IS_OK(status)) {
629 talloc_destroy(mem_ctx);
633 status = dcerpc_bind_auth_none(p, DCERPC_SAMR_UUID,
634 DCERPC_SAMR_VERSION);
636 if (!NT_STATUS_IS_OK(status))
639 r4.in.system_name = talloc_asprintf(mem_ctx, "\\\\%s",
640 dcerpc_server_name(p));
642 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
643 r4.out.connect_handle = &connect_handle;
645 status = dcerpc_samr_Connect4(p, mem_ctx, &r4);
646 if (!NT_STATUS_IS_OK(status))
650 struct samr_EnumDomains e;
651 uint32_t resume_handle = 0;
654 e.in.connect_handle = &connect_handle;
655 e.in.resume_handle = &resume_handle;
656 e.in.buf_size = (uint32_t)-1;
657 e.out.resume_handle = &resume_handle;
658 status = dcerpc_samr_EnumDomains(p, mem_ctx, &e);
659 if (!NT_STATUS_IS_OK(status))
662 for (i=0; i<e.out.sam->count; i++) {
664 struct samr_LookupDomain l;
665 struct samr_OpenDomain o;
667 if (strcmp(e.out.sam->entries[i].name.string,
671 l.in.connect_handle = &connect_handle;
672 l.in.domain = &e.out.sam->entries[i].name;
674 status = dcerpc_samr_LookupDomain(p, mem_ctx, &l);
676 if (!NT_STATUS_IS_OK(status))
679 o.in.connect_handle = &connect_handle;
680 o.in.access_mask = 0x200;
681 o.in.sid = l.out.sid;
682 o.out.domain_handle = &domain_handle;
684 status = dcerpc_samr_OpenDomain(p, mem_ctx, &o);
686 if (!NT_STATUS_IS_OK(status))
694 struct samr_LookupNames l;
695 struct samr_String samr_name;
696 struct samr_OpenUser o;
698 samr_name.string = name;
700 l.in.domain_handle = &domain_handle;
702 l.in.names = &samr_name;
704 status = dcerpc_samr_LookupNames(p, mem_ctx, &l);
706 if (!NT_STATUS_IS_OK(status))
709 o.in.domain_handle = &domain_handle;
710 o.in.rid = l.out.rids.ids[0];
711 o.in.access_mask = 0x100;
712 o.out.user_handle = &user_handle;
714 status = dcerpc_samr_OpenUser(p, mem_ctx, &o);
716 if (!NT_STATUS_IS_OK(status))
721 struct samr_GetGroupsForUser g;
722 struct samr_LookupRids l;
725 g.in.user_handle = &user_handle;
727 status = dcerpc_samr_GetGroupsForUser(p, mem_ctx, &g);
728 if (!NT_STATUS_IS_OK(status))
731 l.in.domain_handle = &domain_handle;
732 l.in.num_rids = g.out.rids->count;
733 l.in.rids = talloc(mem_ctx,
734 g.out.rids->count * sizeof(uint32_t));
736 for (i=0; i<g.out.rids->count; i++)
737 l.in.rids[i] = g.out.rids->rid[i].rid;
739 status = dcerpc_samr_LookupRids(p, mem_ctx, &l);
740 if (!NT_STATUS_IS_OK(status)) {
741 talloc_destroy(mem_ctx);
749 c.in.handle = &user_handle;
750 c.out.handle = &user_handle;
751 dcerpc_samr_Close(p, mem_ctx, &c);
753 c.in.handle = &domain_handle;
754 c.out.handle = &domain_handle;
755 dcerpc_samr_Close(p, mem_ctx, &c);
757 c.in.handle = &connect_handle;
758 c.out.handle = &connect_handle;
759 dcerpc_samr_Close(p, mem_ctx, &c);
763 talloc_destroy(mem_ctx);
768 static NTSTATUS test_getallsids(struct smbcli_transport *transport,
769 const char *name, BOOL includeDomain)
773 struct dcerpc_pipe *p;
775 struct samr_Connect4 r4;
776 struct policy_handle connect_handle, user_handle;
777 struct policy_handle builtin_handle, domain_handle;
778 struct dom_sid *domain_sid = NULL;
780 struct dom_sid *user_sid;
781 struct dom_sid *primary_group_sid;
782 struct samr_GetGroupsForUser g;
785 mem_ctx = talloc_init("test_getallsids");
787 return NT_STATUS_NO_MEMORY;
789 status = connect_to_pipe(&p, transport, DCERPC_SAMR_NAME,
791 DCERPC_SAMR_VERSION);
793 if (!NT_STATUS_IS_OK(status)) {
794 talloc_destroy(mem_ctx);
798 status = dcerpc_bind_auth_none(p, DCERPC_SAMR_UUID,
799 DCERPC_SAMR_VERSION);
801 if (!NT_STATUS_IS_OK(status))
804 r4.in.system_name = talloc_asprintf(mem_ctx, "\\\\%s",
805 dcerpc_server_name(p));
807 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
808 r4.out.connect_handle = &connect_handle;
810 status = dcerpc_samr_Connect4(p, mem_ctx, &r4);
811 if (!NT_STATUS_IS_OK(status))
815 struct samr_EnumDomains e;
816 struct samr_OpenDomain o;
817 uint32_t resume_handle = 0;
820 e.in.connect_handle = &connect_handle;
821 e.in.resume_handle = &resume_handle;
822 e.in.buf_size = (uint32_t)-1;
823 e.out.resume_handle = &resume_handle;
824 status = dcerpc_samr_EnumDomains(p, mem_ctx, &e);
825 if (!NT_STATUS_IS_OK(status))
828 for (i=0; i<e.out.sam->count; i++) {
830 struct samr_LookupDomain l;
832 if (strcmp(e.out.sam->entries[i].name.string,
836 l.in.connect_handle = &connect_handle;
837 l.in.domain = &e.out.sam->entries[i].name;
839 status = dcerpc_samr_LookupDomain(p, mem_ctx, &l);
841 if (!NT_STATUS_IS_OK(status))
844 o.in.connect_handle = &connect_handle;
845 o.in.access_mask = 0x280;
846 domain_sid = l.out.sid;
847 o.in.sid = l.out.sid;
848 o.out.domain_handle = &domain_handle;
850 status = dcerpc_samr_OpenDomain(p, mem_ctx, &o);
852 if (!NT_STATUS_IS_OK(status))
856 o.in.connect_handle = &connect_handle;
857 o.in.access_mask = 0x280;
858 o.in.sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32");
859 o.out.domain_handle = &builtin_handle;
861 status = dcerpc_samr_OpenDomain(p, mem_ctx, &o);
863 if (!NT_STATUS_IS_OK(status))
868 struct samr_LookupNames l;
869 struct samr_String samr_name;
870 struct samr_OpenUser o;
872 samr_name.string = name;
874 l.in.domain_handle = &domain_handle;
876 l.in.names = &samr_name;
878 status = dcerpc_samr_LookupNames(p, mem_ctx, &l);
880 if (!NT_STATUS_IS_OK(status))
883 o.in.domain_handle = &domain_handle;
884 o.in.rid = l.out.rids.ids[0];
885 o.in.access_mask = 0x100;
886 o.out.user_handle = &user_handle;
888 status = dcerpc_samr_OpenUser(p, mem_ctx, &o);
890 if (!NT_STATUS_IS_OK(status))
895 struct samr_QueryUserInfo q;
897 q.in.user_handle = &user_handle;
900 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
902 if (!NT_STATUS_IS_OK(status))
905 user_sid = dom_sid_add_rid(mem_ctx, domain_sid,
906 q.out.info->info21.rid);
907 primary_group_sid = dom_sid_add_rid(mem_ctx, domain_sid,
908 q.out.info->info21.primary_gid);
911 g.in.user_handle = &user_handle;
913 status = dcerpc_samr_GetGroupsForUser(p, mem_ctx, &g);
914 if (!NT_STATUS_IS_OK(status))
918 struct lsa_SidArray sids;
919 struct samr_Ids rids;
920 struct samr_GetAliasMembership ga;
923 ga.in.domain_handle = &builtin_handle;
925 sids.num_sids = g.out.rids->count+2;
926 sids.sids = talloc_array_p(mem_ctx, struct lsa_SidPtr,
927 g.out.rids->count+2);
928 sids.sids[0].sid = user_sid;
929 sids.sids[1].sid = primary_group_sid;
930 for (i=0; i<g.out.rids->count; i++) {
931 sids.sids[i+2].sid = dom_sid_add_rid(mem_ctx,
933 g.out.rids->rid[i].rid);
938 status = dcerpc_samr_GetAliasMembership(p, mem_ctx, &ga);
939 if (!NT_STATUS_IS_OK(status))
943 ga.in.domain_handle = &domain_handle;
944 status = dcerpc_samr_GetAliasMembership(p, mem_ctx,
946 if (!NT_STATUS_IS_OK(status))
954 c.in.handle = &user_handle;
955 c.out.handle = &user_handle;
956 dcerpc_samr_Close(p, mem_ctx, &c);
958 c.in.handle = &domain_handle;
959 c.out.handle = &domain_handle;
960 dcerpc_samr_Close(p, mem_ctx, &c);
962 c.in.handle = &builtin_handle;
963 c.out.handle = &builtin_handle;
964 dcerpc_samr_Close(p, mem_ctx, &c);
966 c.in.handle = &connect_handle;
967 c.out.handle = &connect_handle;
968 dcerpc_samr_Close(p, mem_ctx, &c);
972 talloc_destroy(mem_ctx);
977 static NTSTATUS test_remoteTOD(struct smbcli_transport *transport)
981 struct dcerpc_pipe *p;
982 struct srvsvc_NetRemoteTOD r;
984 mem_ctx = talloc_init("test_lookupnames");
986 return NT_STATUS_NO_MEMORY;
988 status = connect_to_pipe(&p, transport, DCERPC_SRVSVC_NAME,
990 DCERPC_SRVSVC_VERSION);
992 if (!NT_STATUS_IS_OK(status)) {
993 talloc_destroy(mem_ctx);
997 status = dcerpc_bind_auth_none(p, DCERPC_SRVSVC_UUID,
998 DCERPC_SRVSVC_VERSION);
1000 if (!NT_STATUS_IS_OK(status))
1003 r.in.server_unc = talloc_asprintf(mem_ctx,"\\\\%s",dcerpc_server_name(p));
1006 status = dcerpc_srvsvc_NetRemoteTOD(p, mem_ctx, &r);
1007 talloc_destroy(mem_ctx);
1012 static BOOL xp_login(const char *dcname, const char *wksname,
1013 const char *domain, const char *wkspwd,
1014 const char *user1name, const char *user1pw,
1015 const char *user2name, const char *user2pw)
1018 TALLOC_CTX *mem_ctx;
1021 struct smbcli_transport *transport;
1023 struct dcerpc_pipe *netlogon_pipe;
1024 struct creds_CredentialState *netlogon_creds;
1026 struct dcerpc_pipe *netlogon_schannel_pipe;
1028 talloc_enable_leak_report();
1030 mem_ctx = talloc_init("rpc_login");
1032 if (mem_ctx == NULL)
1035 netlogon_creds = talloc_p(mem_ctx, struct creds_CredentialState);
1036 if (!netlogon_creds) {
1040 if (!NT_STATUS_IS_OK(after_negprot(&transport, dcname, 139,
1044 if (!NT_STATUS_IS_OK(setup_netlogon_creds(transport, &netlogon_pipe,
1045 wksname, domain, wkspwd,
1049 if (!NT_STATUS_IS_OK(test_enumtrusts(transport)))
1052 user1dom = talloc_asprintf(mem_ctx, "%s\\%s", domain, user1name);
1054 if (!NT_STATUS_IS_OK(test_lookupnames(transport, user1dom)))
1057 status = connect_to_pipe(&netlogon_schannel_pipe,
1058 transport, DCERPC_NETLOGON_NAME,
1059 DCERPC_NETLOGON_UUID,
1060 DCERPC_NETLOGON_VERSION);
1062 if (!NT_STATUS_IS_OK(status))
1065 netlogon_schannel_pipe->flags |= DCERPC_SEAL;
1067 status = dcerpc_bind_auth_schannel_withkey(netlogon_schannel_pipe,
1068 DCERPC_NETLOGON_UUID,
1069 DCERPC_NETLOGON_VERSION,
1073 if (!NT_STATUS_IS_OK(status))
1076 status = torture_samlogon(netlogon_schannel_pipe,
1077 netlogon_creds, wksname, domain,
1078 user1name, user1pw);
1080 if (!NT_STATUS_IS_OK(status))
1083 talloc_free(netlogon_pipe);
1085 status = torture_samlogon(netlogon_schannel_pipe,
1086 netlogon_creds, wksname, domain,
1087 user2name, user2pw);
1089 if (!NT_STATUS_IS_OK(status))
1092 status = test_getgroups(transport, user2name);
1094 if (!NT_STATUS_IS_OK(status))
1097 status = test_remoteTOD(transport);
1099 if (!NT_STATUS_IS_OK(status))
1102 status = test_remoteTOD(transport);
1104 if (!NT_STATUS_IS_OK(status))
1107 status = test_getallsids(transport, user2name, False);
1109 if (!NT_STATUS_IS_OK(status))
1112 status = test_getgroups(transport, user2name);
1114 if (!NT_STATUS_IS_OK(status))
1117 status = test_getallsids(transport, user2name, True);
1119 if (!NT_STATUS_IS_OK(status))
1122 talloc_free(netlogon_schannel_pipe);
1124 talloc_free(transport);
1126 talloc_destroy(mem_ctx);
1132 const char *username;
1133 const char *password;
1136 static const struct user_pw users[] = {
1137 { "username1", "password1" },
1138 { "username2", "password2" }
1141 static const struct user_pw machines[] = {
1142 { "machine1", "mpw1" },
1143 { "machine2", "mpw2" }
1146 BOOL torture_rpc_login(void)
1148 const char *pdcname = "pdcname";
1149 const char *domainname = "domain";
1151 int useridx1 = rand() % ARRAY_SIZE(users);
1152 int useridx2 = rand() % ARRAY_SIZE(users);
1153 int machidx = rand() % ARRAY_SIZE(machines);
1154 printf("machine: %s user1: %s user2: %s\n",
1155 machines[machidx].username,
1156 users[useridx1].username,
1157 users[useridx2].username);
1159 return xp_login(pdcname, machines[machidx].username,
1160 domainname, machines[machidx].password,
1161 users[useridx1].username,
1162 users[useridx1].password,
1163 users[useridx2].username,
1164 users[useridx2].password);