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 NTSTATUS connect_to_pipe(struct dcerpc_pipe **pp,
185 struct smbcli_transport *transport,
186 const char *pipe_name,
187 const char *pipe_uuid,
188 uint32_t pipe_version)
190 const char *binding = lp_parm_string(-1, "torture", "binding");
191 struct dcerpc_binding b;
193 struct dcerpc_pipe *p;
195 struct smbcli_tree *tree;
197 if (!NT_STATUS_IS_OK(status = anon_ipc(transport, &tree)))
201 return NT_STATUS_INVALID_PARAMETER;
203 p = dcerpc_pipe_init(mem_ctx);
205 return NT_STATUS_NO_MEMORY;
207 tmp_ctx = talloc_new(p);
209 status = dcerpc_parse_binding(tmp_ctx, binding, &b);
210 if (!NT_STATUS_IS_OK(status)) {
211 DEBUG(0,("Failed to parse dcerpc binding '%s'\n", binding));
216 DEBUG(3,("Using binding %s\n", dcerpc_binding_string(tmp_ctx, &b)));
218 if (b.endpoint == NULL) {
219 const struct dcerpc_interface_table *table =
220 idl_iface_by_uuid(pipe_uuid);
221 struct dcerpc_binding default_binding;
225 DEBUG(0,("Unknown interface endpoint '%s'\n",
227 talloc_free(tmp_ctx);
228 return NT_STATUS_INVALID_PARAMETER;
231 /* Find one of the default pipes for this interface */
232 for (i = 0; i < table->endpoints->count; i++) {
233 const char * const *names = table->endpoints->names;
234 status = dcerpc_parse_binding(tmp_ctx, names[i],
237 if (NT_STATUS_IS_OK(status) &&
238 default_binding.transport == NCACN_NP) {
239 pipe_name = default_binding.endpoint;
244 pipe_name = b.endpoint;
247 if (!strncasecmp(pipe_name, "/pipe/", 6) ||
248 !strncasecmp(pipe_name, "\\pipe\\", 6)) {
252 if (pipe_name[0] != '\\') {
253 pipe_name = talloc_asprintf(mem_ctx, "\\%s", pipe_name);
256 status = dcerpc_pipe_open_smb(p->conn, tree, pipe_name);
258 if (!NT_STATUS_IS_OK(status)) {
263 talloc_free(tmp_ctx);
269 static NTSTATUS test_enumtrusts(struct smbcli_transport *transport)
271 struct policy_handle handle;
272 struct lsa_EnumTrustDom r2;
273 uint32_t resume_handle = 0;
274 struct lsa_ObjectAttribute attr;
275 struct lsa_OpenPolicy2 r1;
276 struct lsa_DomainList domains;
279 struct dcerpc_pipe *p;
281 mem_ctx = talloc_init("test_enumtrusts");
283 return NT_STATUS_NO_MEMORY;
285 status = connect_to_pipe(&p, mem_ctx, transport, DCERPC_LSARPC_NAME,
287 DCERPC_LSARPC_VERSION);
289 if (!NT_STATUS_IS_OK(status)) {
290 talloc_destroy(mem_ctx);
294 status = dcerpc_bind_auth_none(p, DCERPC_LSARPC_UUID,
295 DCERPC_LSARPC_VERSION);
297 if (!NT_STATUS_IS_OK(status))
300 printf("\ntesting OpenPolicy2\n");
303 attr.root_dir = NULL;
304 attr.object_name = NULL;
306 attr.sec_desc = NULL;
309 r1.in.system_name = talloc_asprintf(mem_ctx,
310 "\\\\%s", dcerpc_server_name(p));
312 r1.in.access_mask = 1;
313 r1.out.handle = &handle;
315 status = dcerpc_lsa_OpenPolicy2(p, mem_ctx, &r1);
316 if (!NT_STATUS_IS_OK(status)) {
317 printf("OpenPolicy2 failed - %s\n", nt_errstr(status));
321 printf("\nTesting EnumTrustDom\n");
323 r2.in.handle = &handle;
324 r2.in.resume_handle = &resume_handle;
325 r2.in.max_size = 1000;
326 r2.out.domains = &domains;
327 r2.out.resume_handle = &resume_handle;
329 status = dcerpc_lsa_EnumTrustDom(p, mem_ctx, &r2);
331 if (!NT_STATUS_IS_OK(status) &&
332 !NT_STATUS_EQUAL(status, NT_STATUS_NO_MORE_ENTRIES))
337 talloc_destroy(mem_ctx);
342 static NTSTATUS test_lookupnames(struct smbcli_transport *transport,
345 struct policy_handle handle;
346 struct lsa_ObjectAttribute attr;
347 struct lsa_OpenPolicy2 r1;
350 struct dcerpc_pipe *p;
352 mem_ctx = talloc_init("test_lookupnames");
354 return NT_STATUS_NO_MEMORY;
356 status = connect_to_pipe(&p, mem_ctx, transport, DCERPC_LSARPC_NAME,
358 DCERPC_LSARPC_VERSION);
360 if (!NT_STATUS_IS_OK(status)) {
361 talloc_destroy(mem_ctx);
365 status = dcerpc_bind_auth_none(p, DCERPC_LSARPC_UUID,
366 DCERPC_LSARPC_VERSION);
368 if (!NT_STATUS_IS_OK(status))
372 attr.root_dir = NULL;
373 attr.object_name = NULL;
375 attr.sec_desc = NULL;
378 r1.in.system_name = talloc_asprintf(mem_ctx,
379 "\\\\%s", dcerpc_server_name(p));
381 r1.in.access_mask = 0x801;
382 r1.out.handle = &handle;
384 status = dcerpc_lsa_OpenPolicy2(p, mem_ctx, &r1);
385 if (!NT_STATUS_IS_OK(status)) {
386 printf("OpenPolicy2 failed - %s\n", nt_errstr(status));
391 struct lsa_LookupNames l;
392 struct lsa_TransSidArray sids;
393 struct lsa_String lsaname;
399 lsaname.string = name;
401 l.in.handle = &handle;
403 l.in.names = &lsaname;
407 l.out.count = &count;
410 status = dcerpc_lsa_LookupNames(p, mem_ctx, &l);
411 if (!NT_STATUS_IS_OK(status) &&
412 !NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
413 printf("LookupNames failed - %s\n", nt_errstr(status));
415 talloc_destroy(mem_ctx);
422 struct policy_handle handle2;
424 c.in.handle = &handle;
425 c.out.handle = &handle2;
427 status = dcerpc_lsa_Close(p, mem_ctx, &c);
428 if (!NT_STATUS_IS_OK(status)) {
429 printf("Close failed - %s\n", nt_errstr(status));
436 talloc_destroy(mem_ctx);
441 static NTSTATUS setup_netlogon_creds(struct smbcli_transport *transport,
442 struct dcerpc_pipe **p,
443 const char *machine_name,
445 const char *machine_pwd,
446 struct creds_CredentialState *creds)
450 struct netr_ServerReqChallenge r;
451 struct netr_ServerAuthenticate2 a;
452 struct netr_Credential credentials1, credentials2, credentials3;
453 const char *plain_pass;
454 struct samr_Password mach_password;
455 uint32_t negotiate_flags = NETLOGON_NEG_AUTH2_FLAGS;
458 mem_ctx = talloc_init("torture_rpc_login");
461 return NT_STATUS_NO_MEMORY;
463 status = connect_to_pipe(p, mem_ctx, transport, DCERPC_NETLOGON_NAME,
464 DCERPC_NETLOGON_UUID,
465 DCERPC_NETLOGON_VERSION);
467 if (!NT_STATUS_IS_OK(status)) {
468 talloc_destroy(mem_ctx);
472 status = dcerpc_bind_auth_none(*p, DCERPC_NETLOGON_UUID,
473 DCERPC_NETLOGON_VERSION);
475 if (!NT_STATUS_IS_OK(status))
478 printf("Testing ServerReqChallenge\n");
480 r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s",
481 dcerpc_server_name(*p));
482 r.in.computer_name = machine_name;
483 r.in.credentials = &credentials1;
484 r.out.credentials = &credentials2;
486 generate_random_buffer(credentials1.data, sizeof(credentials1.data));
488 status = dcerpc_netr_ServerReqChallenge(*p, mem_ctx, &r);
489 if (!NT_STATUS_IS_OK(status)) {
490 printf("ServerReqChallenge - %s\n", nt_errstr(status));
494 plain_pass = machine_pwd;
496 printf("Unable to fetch machine password!\n");
500 E_md4hash(plain_pass, mach_password.hash);
502 a.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s",
503 dcerpc_server_name(*p));
504 a.in.account_name = talloc_asprintf(mem_ctx, "%s$", machine_name);
505 a.in.secure_channel_type = SEC_CHAN_WKSTA;
506 a.in.computer_name = machine_name;
507 a.in.negotiate_flags = &negotiate_flags;
508 a.out.negotiate_flags = &negotiate_flags;
509 a.in.credentials = &credentials3;
510 a.out.credentials = &credentials3;
512 creds_client_init(creds, &credentials1, &credentials2,
513 &mach_password, &credentials3,
516 printf("Testing ServerAuthenticate2\n");
518 status = dcerpc_netr_ServerAuthenticate2(*p, mem_ctx, &a);
519 if (!NT_STATUS_IS_OK(status)) {
520 printf("ServerAuthenticate2 - %s\n", nt_errstr(status));
524 if (!creds_client_check(creds, &credentials3)) {
525 printf("Credential chaining failed\n");
529 printf("negotiate_flags=0x%08x\n", negotiate_flags);
531 talloc_free(mem_ctx);
535 static NTSTATUS torture_samlogon(struct dcerpc_pipe *p,
536 struct creds_CredentialState *netlogon_creds,
537 const char *workstation,
539 const char *username,
540 const char *password)
543 struct netr_LogonSamLogon log;
544 struct netr_NetworkInfo ninfo;
545 struct netr_Authenticator auth, auth2;
546 uint8_t user_session_key[16];
547 DATA_BLOB ntlmv2_response = data_blob(NULL, 0);
548 DATA_BLOB lmv2_response = data_blob(NULL, 0);
549 DATA_BLOB names_blob;
553 mem_ctx = talloc_init("torture_samlogon");
555 ZERO_STRUCT(user_session_key);
557 printf("testing netr_LogonSamLogon\n");
559 log.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s",
560 dcerpc_server_name(p));
561 log.in.workstation = workstation;
562 log.in.credential = &auth;
563 log.in.return_authenticator = &auth2;
564 log.in.validation_level = 3;
565 log.in.logon_level = 2;
566 log.in.logon.network = &ninfo;
568 chall = data_blob_talloc(mem_ctx, NULL, 8);
569 generate_random_buffer(chall.data, 8);
571 names_blob = NTLMv2_generate_names_blob(mem_ctx, workstation,
573 ZERO_STRUCT(user_session_key);
575 if (!SMBNTLMv2encrypt(username, domain, password,
577 &lmv2_response, &ntlmv2_response,
579 data_blob_free(&names_blob);
580 talloc_destroy(mem_ctx);
581 return NT_STATUS_UNSUCCESSFUL;
583 data_blob_free(&names_blob);
585 ninfo.identity_info.domain_name.string = domain;
586 ninfo.identity_info.parameter_control = 0;
587 ninfo.identity_info.logon_id_low = 0;
588 ninfo.identity_info.logon_id_high = 0;
589 ninfo.identity_info.account_name.string = username;
590 ninfo.identity_info.workstation.string = workstation;
591 memcpy(ninfo.challenge, chall.data, 8);
592 ninfo.nt.data = ntlmv2_response.data;
593 ninfo.nt.length = ntlmv2_response.length;
594 ninfo.lm.data = NULL;
598 creds_client_authenticator(netlogon_creds, &auth);
600 log.out.return_authenticator = NULL;
601 status = dcerpc_netr_LogonSamLogon(p, mem_ctx, &log);
602 talloc_destroy(mem_ctx);
603 data_blob_free(&lmv2_response);
604 data_blob_free(&ntlmv2_response);
608 static NTSTATUS test_getgroups(struct smbcli_transport *transport,
613 struct dcerpc_pipe *p;
615 struct samr_Connect4 r4;
616 struct policy_handle connect_handle, domain_handle, user_handle;
618 mem_ctx = talloc_init("test_lookupnames");
620 return NT_STATUS_NO_MEMORY;
622 status = connect_to_pipe(&p, mem_ctx, transport, DCERPC_SAMR_NAME,
624 DCERPC_SAMR_VERSION);
626 if (!NT_STATUS_IS_OK(status)) {
627 talloc_destroy(mem_ctx);
631 status = dcerpc_bind_auth_none(p, DCERPC_SAMR_UUID,
632 DCERPC_SAMR_VERSION);
634 if (!NT_STATUS_IS_OK(status))
637 r4.in.system_name = talloc_asprintf(mem_ctx, "\\\\%s",
638 dcerpc_server_name(p));
640 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
641 r4.out.connect_handle = &connect_handle;
643 status = dcerpc_samr_Connect4(p, mem_ctx, &r4);
644 if (!NT_STATUS_IS_OK(status))
648 struct samr_EnumDomains e;
649 uint32_t resume_handle = 0;
652 e.in.connect_handle = &connect_handle;
653 e.in.resume_handle = &resume_handle;
654 e.in.buf_size = (uint32_t)-1;
655 e.out.resume_handle = &resume_handle;
656 status = dcerpc_samr_EnumDomains(p, mem_ctx, &e);
657 if (!NT_STATUS_IS_OK(status))
660 for (i=0; i<e.out.sam->count; i++) {
662 struct samr_LookupDomain l;
663 struct samr_OpenDomain o;
665 if (strcmp(e.out.sam->entries[i].name.string,
669 l.in.connect_handle = &connect_handle;
670 l.in.domain = &e.out.sam->entries[i].name;
672 status = dcerpc_samr_LookupDomain(p, mem_ctx, &l);
674 if (!NT_STATUS_IS_OK(status))
677 o.in.connect_handle = &connect_handle;
678 o.in.access_mask = 0x200;
679 o.in.sid = l.out.sid;
680 o.out.domain_handle = &domain_handle;
682 status = dcerpc_samr_OpenDomain(p, mem_ctx, &o);
684 if (!NT_STATUS_IS_OK(status))
692 struct samr_LookupNames l;
693 struct samr_String samr_name;
694 struct samr_OpenUser o;
696 samr_name.string = name;
698 l.in.domain_handle = &domain_handle;
700 l.in.names = &samr_name;
702 status = dcerpc_samr_LookupNames(p, mem_ctx, &l);
704 if (!NT_STATUS_IS_OK(status))
707 o.in.domain_handle = &domain_handle;
708 o.in.rid = l.out.rids.ids[0];
709 o.in.access_mask = 0x100;
710 o.out.user_handle = &user_handle;
712 status = dcerpc_samr_OpenUser(p, mem_ctx, &o);
714 if (!NT_STATUS_IS_OK(status))
719 struct samr_GetGroupsForUser g;
720 struct samr_LookupRids l;
723 g.in.user_handle = &user_handle;
725 status = dcerpc_samr_GetGroupsForUser(p, mem_ctx, &g);
726 if (!NT_STATUS_IS_OK(status))
729 l.in.domain_handle = &domain_handle;
730 l.in.num_rids = g.out.rids->count;
731 l.in.rids = talloc_array_p(mem_ctx, uint32_t, g.out.rids->count);
733 for (i=0; i<g.out.rids->count; i++)
734 l.in.rids[i] = g.out.rids->rid[i].rid;
736 status = dcerpc_samr_LookupRids(p, mem_ctx, &l);
737 if (!NT_STATUS_IS_OK(status)) {
738 talloc_destroy(mem_ctx);
746 c.in.handle = &user_handle;
747 c.out.handle = &user_handle;
748 dcerpc_samr_Close(p, mem_ctx, &c);
750 c.in.handle = &domain_handle;
751 c.out.handle = &domain_handle;
752 dcerpc_samr_Close(p, mem_ctx, &c);
754 c.in.handle = &connect_handle;
755 c.out.handle = &connect_handle;
756 dcerpc_samr_Close(p, mem_ctx, &c);
760 talloc_destroy(mem_ctx);
765 static NTSTATUS test_getallsids(struct smbcli_transport *transport,
766 const char *name, BOOL includeDomain)
770 struct dcerpc_pipe *p;
772 struct samr_Connect4 r4;
773 struct policy_handle connect_handle, user_handle;
774 struct policy_handle builtin_handle, domain_handle;
775 struct dom_sid *domain_sid = NULL;
777 struct dom_sid *user_sid;
778 struct dom_sid *primary_group_sid;
779 struct samr_GetGroupsForUser g;
782 mem_ctx = talloc_init("test_getallsids");
784 return NT_STATUS_NO_MEMORY;
786 status = connect_to_pipe(&p, mem_ctx, transport, DCERPC_SAMR_NAME,
788 DCERPC_SAMR_VERSION);
790 if (!NT_STATUS_IS_OK(status)) {
791 talloc_destroy(mem_ctx);
795 status = dcerpc_bind_auth_none(p, DCERPC_SAMR_UUID,
796 DCERPC_SAMR_VERSION);
798 if (!NT_STATUS_IS_OK(status))
801 r4.in.system_name = talloc_asprintf(mem_ctx, "\\\\%s",
802 dcerpc_server_name(p));
804 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
805 r4.out.connect_handle = &connect_handle;
807 status = dcerpc_samr_Connect4(p, mem_ctx, &r4);
808 if (!NT_STATUS_IS_OK(status))
812 struct samr_EnumDomains e;
813 struct samr_OpenDomain o;
814 uint32_t resume_handle = 0;
817 e.in.connect_handle = &connect_handle;
818 e.in.resume_handle = &resume_handle;
819 e.in.buf_size = (uint32_t)-1;
820 e.out.resume_handle = &resume_handle;
821 status = dcerpc_samr_EnumDomains(p, mem_ctx, &e);
822 if (!NT_STATUS_IS_OK(status))
825 for (i=0; i<e.out.sam->count; i++) {
827 struct samr_LookupDomain l;
829 if (strcmp(e.out.sam->entries[i].name.string,
833 l.in.connect_handle = &connect_handle;
834 l.in.domain = &e.out.sam->entries[i].name;
836 status = dcerpc_samr_LookupDomain(p, mem_ctx, &l);
838 if (!NT_STATUS_IS_OK(status))
841 o.in.connect_handle = &connect_handle;
842 o.in.access_mask = 0x280;
843 domain_sid = l.out.sid;
844 o.in.sid = l.out.sid;
845 o.out.domain_handle = &domain_handle;
847 status = dcerpc_samr_OpenDomain(p, mem_ctx, &o);
849 if (!NT_STATUS_IS_OK(status))
853 o.in.connect_handle = &connect_handle;
854 o.in.access_mask = 0x280;
855 o.in.sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32");
856 o.out.domain_handle = &builtin_handle;
858 status = dcerpc_samr_OpenDomain(p, mem_ctx, &o);
860 if (!NT_STATUS_IS_OK(status))
865 struct samr_LookupNames l;
866 struct samr_String samr_name;
867 struct samr_OpenUser o;
869 samr_name.string = name;
871 l.in.domain_handle = &domain_handle;
873 l.in.names = &samr_name;
875 status = dcerpc_samr_LookupNames(p, mem_ctx, &l);
877 if (!NT_STATUS_IS_OK(status))
880 o.in.domain_handle = &domain_handle;
881 o.in.rid = l.out.rids.ids[0];
882 o.in.access_mask = 0x100;
883 o.out.user_handle = &user_handle;
885 status = dcerpc_samr_OpenUser(p, mem_ctx, &o);
887 if (!NT_STATUS_IS_OK(status))
892 struct samr_QueryUserInfo q;
894 q.in.user_handle = &user_handle;
897 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
899 if (!NT_STATUS_IS_OK(status))
902 user_sid = dom_sid_add_rid(mem_ctx, domain_sid,
903 q.out.info->info21.rid);
904 primary_group_sid = dom_sid_add_rid(mem_ctx, domain_sid,
905 q.out.info->info21.primary_gid);
908 g.in.user_handle = &user_handle;
910 status = dcerpc_samr_GetGroupsForUser(p, mem_ctx, &g);
911 if (!NT_STATUS_IS_OK(status))
915 struct lsa_SidArray sids;
916 struct samr_Ids rids;
917 struct samr_GetAliasMembership ga;
920 ga.in.domain_handle = &builtin_handle;
922 sids.num_sids = g.out.rids->count+2;
923 sids.sids = talloc_array_p(mem_ctx, struct lsa_SidPtr,
924 g.out.rids->count+2);
925 sids.sids[0].sid = user_sid;
926 sids.sids[1].sid = primary_group_sid;
927 for (i=0; i<g.out.rids->count; i++) {
928 sids.sids[i+2].sid = dom_sid_add_rid(mem_ctx,
930 g.out.rids->rid[i].rid);
935 status = dcerpc_samr_GetAliasMembership(p, mem_ctx, &ga);
936 if (!NT_STATUS_IS_OK(status))
940 ga.in.domain_handle = &domain_handle;
941 status = dcerpc_samr_GetAliasMembership(p, mem_ctx,
943 if (!NT_STATUS_IS_OK(status))
951 c.in.handle = &user_handle;
952 c.out.handle = &user_handle;
953 dcerpc_samr_Close(p, mem_ctx, &c);
955 c.in.handle = &domain_handle;
956 c.out.handle = &domain_handle;
957 dcerpc_samr_Close(p, mem_ctx, &c);
959 c.in.handle = &builtin_handle;
960 c.out.handle = &builtin_handle;
961 dcerpc_samr_Close(p, mem_ctx, &c);
963 c.in.handle = &connect_handle;
964 c.out.handle = &connect_handle;
965 dcerpc_samr_Close(p, mem_ctx, &c);
969 talloc_destroy(mem_ctx);
974 static NTSTATUS test_remoteTOD(struct smbcli_transport *transport)
978 struct dcerpc_pipe *p;
979 struct srvsvc_NetRemoteTOD r;
981 mem_ctx = talloc_init("test_lookupnames");
983 return NT_STATUS_NO_MEMORY;
985 status = connect_to_pipe(&p, mem_ctx, transport, DCERPC_SRVSVC_NAME,
987 DCERPC_SRVSVC_VERSION);
989 if (!NT_STATUS_IS_OK(status)) {
990 talloc_destroy(mem_ctx);
994 status = dcerpc_bind_auth_none(p, DCERPC_SRVSVC_UUID,
995 DCERPC_SRVSVC_VERSION);
997 if (!NT_STATUS_IS_OK(status))
1000 r.in.server_unc = talloc_asprintf(mem_ctx,"\\\\%s",dcerpc_server_name(p));
1003 status = dcerpc_srvsvc_NetRemoteTOD(p, mem_ctx, &r);
1004 talloc_destroy(mem_ctx);
1009 static BOOL xp_login(const char *dcname, const char *wksname,
1010 const char *domain, const char *wkspwd,
1011 const char *user1name, const char *user1pw,
1012 const char *user2name, const char *user2pw)
1015 TALLOC_CTX *mem_ctx;
1018 struct smbcli_transport *transport;
1020 struct dcerpc_pipe *netlogon_pipe;
1021 struct creds_CredentialState *netlogon_creds;
1023 struct dcerpc_pipe *netlogon_schannel_pipe;
1025 talloc_enable_leak_report();
1027 mem_ctx = talloc_init("rpc_login");
1029 if (mem_ctx == NULL)
1032 netlogon_creds = talloc_p(mem_ctx, struct creds_CredentialState);
1033 if (!netlogon_creds) {
1037 if (!NT_STATUS_IS_OK(after_negprot(&transport, dcname, 139,
1041 if (!NT_STATUS_IS_OK(setup_netlogon_creds(transport, &netlogon_pipe,
1042 wksname, domain, wkspwd,
1046 if (!NT_STATUS_IS_OK(test_enumtrusts(transport)))
1049 user1dom = talloc_asprintf(mem_ctx, "%s\\%s", domain, user1name);
1051 if (!NT_STATUS_IS_OK(test_lookupnames(transport, user1dom)))
1054 status = connect_to_pipe(&netlogon_schannel_pipe,
1055 mem_ctx, transport, DCERPC_NETLOGON_NAME,
1056 DCERPC_NETLOGON_UUID,
1057 DCERPC_NETLOGON_VERSION);
1059 if (!NT_STATUS_IS_OK(status))
1062 netlogon_schannel_pipe->conn->flags |= DCERPC_SEAL;
1064 status = dcerpc_bind_auth_schannel_withkey(netlogon_schannel_pipe,
1065 DCERPC_NETLOGON_UUID,
1066 DCERPC_NETLOGON_VERSION,
1070 if (!NT_STATUS_IS_OK(status))
1073 status = torture_samlogon(netlogon_schannel_pipe,
1074 netlogon_creds, wksname, domain,
1075 user1name, user1pw);
1077 if (!NT_STATUS_IS_OK(status))
1080 talloc_free(netlogon_pipe);
1082 status = torture_samlogon(netlogon_schannel_pipe,
1083 netlogon_creds, wksname, domain,
1084 user2name, user2pw);
1086 if (!NT_STATUS_IS_OK(status))
1089 status = test_getgroups(transport, user2name);
1091 if (!NT_STATUS_IS_OK(status))
1094 status = test_remoteTOD(transport);
1096 if (!NT_STATUS_IS_OK(status))
1099 status = test_remoteTOD(transport);
1101 if (!NT_STATUS_IS_OK(status))
1104 status = test_getallsids(transport, user2name, False);
1106 if (!NT_STATUS_IS_OK(status))
1109 status = test_getgroups(transport, user2name);
1111 if (!NT_STATUS_IS_OK(status))
1114 status = test_getallsids(transport, user2name, True);
1116 if (!NT_STATUS_IS_OK(status))
1119 talloc_free(netlogon_schannel_pipe);
1121 talloc_free(transport);
1123 talloc_destroy(mem_ctx);
1129 const char *username;
1130 const char *password;
1133 static const struct user_pw users[] = {
1134 { "username1", "password1" },
1135 { "username2", "password2" }
1138 static const struct user_pw machines[] = {
1139 { "machine1", "mpw1" },
1140 { "machine2", "mpw2" }
1143 BOOL torture_rpc_login(void)
1145 const char *pdcname = "pdcname";
1146 const char *domainname = "domain";
1148 int useridx1 = rand() % ARRAY_SIZE(users);
1149 int useridx2 = rand() % ARRAY_SIZE(users);
1150 int machidx = rand() % ARRAY_SIZE(machines);
1151 printf("machine: %s user1: %s user2: %s\n",
1152 machines[machidx].username,
1153 users[useridx1].username,
1154 users[useridx2].username);
1156 return xp_login(pdcname, machines[machidx].username,
1157 domainname, machines[machidx].password,
1158 users[useridx1].username,
1159 users[useridx1].password,
1160 users[useridx2].username,
1161 users[useridx2].password);