2 Unix SMB/CIFS implementation.
4 dcerpc torture tests, designed to walk Samba3 code paths
6 Copyright (C) Volker Lendecke 2006
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/raw/libcliraw.h"
25 #include "libcli/rap/rap.h"
26 #include "torture/torture.h"
27 #include "torture/util.h"
28 #include "torture/rap/proto.h"
29 #include "librpc/gen_ndr/ndr_lsa.h"
30 #include "librpc/gen_ndr/ndr_lsa_c.h"
31 #include "librpc/gen_ndr/ndr_samr.h"
32 #include "librpc/gen_ndr/ndr_samr_c.h"
33 #include "librpc/gen_ndr/ndr_netlogon.h"
34 #include "librpc/gen_ndr/ndr_netlogon_c.h"
35 #include "librpc/gen_ndr/ndr_srvsvc.h"
36 #include "librpc/gen_ndr/ndr_srvsvc_c.h"
37 #include "librpc/gen_ndr/ndr_spoolss.h"
38 #include "librpc/gen_ndr/ndr_spoolss_c.h"
39 #include "librpc/gen_ndr/ndr_winreg.h"
40 #include "librpc/gen_ndr/ndr_winreg_c.h"
41 #include "librpc/gen_ndr/ndr_wkssvc.h"
42 #include "librpc/gen_ndr/ndr_wkssvc_c.h"
43 #include "lib/cmdline/popt_common.h"
44 #include "librpc/rpc/dcerpc.h"
45 #include "torture/rpc/rpc.h"
46 #include "libcli/libcli.h"
47 #include "libcli/composite/composite.h"
48 #include "libcli/smb_composite/smb_composite.h"
49 #include "libcli/auth/libcli_auth.h"
50 #include "lib/crypto/crypto.h"
51 #include "libcli/security/proto.h"
53 static struct cli_credentials *create_anon_creds(TALLOC_CTX *mem_ctx)
55 struct cli_credentials *result;
57 if (!(result = cli_credentials_init(mem_ctx))) {
61 cli_credentials_set_conf(result);
62 cli_credentials_set_anonymous(result);
68 * This tests a RPC call using an invalid vuid
71 BOOL torture_bind_authcontext(struct torture_context *torture)
76 struct lsa_ObjectAttribute objectattr;
77 struct lsa_OpenPolicy2 openpolicy;
78 struct policy_handle handle;
79 struct lsa_Close close_handle;
80 struct smbcli_session *tmp;
81 struct smbcli_session *session2;
82 struct smbcli_state *cli;
83 struct dcerpc_pipe *lsa_pipe;
84 struct cli_credentials *anon_creds;
85 struct smb_composite_sesssetup setup;
87 mem_ctx = talloc_init("torture_bind_authcontext");
89 if (mem_ctx == NULL) {
90 d_printf("talloc_init failed\n");
94 status = smbcli_full_connection(mem_ctx, &cli,
95 torture_setting_string(torture, "host", NULL),
96 "IPC$", NULL, cmdline_credentials,
98 if (!NT_STATUS_IS_OK(status)) {
99 d_printf("smbcli_full_connection failed: %s\n",
104 lsa_pipe = dcerpc_pipe_init(mem_ctx, cli->transport->socket->event.ctx);
105 if (lsa_pipe == NULL) {
106 d_printf("dcerpc_pipe_init failed\n");
110 status = dcerpc_pipe_open_smb(lsa_pipe, cli->tree, "\\lsarpc");
111 if (!NT_STATUS_IS_OK(status)) {
112 d_printf("dcerpc_pipe_open_smb failed: %s\n",
117 status = dcerpc_bind_auth_none(lsa_pipe, &dcerpc_table_lsarpc);
118 if (!NT_STATUS_IS_OK(status)) {
119 d_printf("dcerpc_bind_auth_none failed: %s\n",
124 openpolicy.in.system_name =talloc_asprintf(
125 mem_ctx, "\\\\%s", dcerpc_server_name(lsa_pipe));
126 ZERO_STRUCT(objectattr);
127 openpolicy.in.attr = &objectattr;
128 openpolicy.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
129 openpolicy.out.handle = &handle;
131 status = dcerpc_lsa_OpenPolicy2(lsa_pipe, mem_ctx, &openpolicy);
133 if (!NT_STATUS_IS_OK(status)) {
134 d_printf("dcerpc_lsa_OpenPolicy2 failed: %s\n",
139 close_handle.in.handle = &handle;
140 close_handle.out.handle = &handle;
142 status = dcerpc_lsa_Close(lsa_pipe, mem_ctx, &close_handle);
143 if (!NT_STATUS_IS_OK(status)) {
144 d_printf("dcerpc_lsa_Close failed: %s\n",
149 session2 = smbcli_session_init(cli->transport, mem_ctx, False);
150 if (session2 == NULL) {
151 d_printf("smbcli_session_init failed\n");
155 if (!(anon_creds = create_anon_creds(mem_ctx))) {
156 d_printf("create_anon_creds failed\n");
160 setup.in.sesskey = cli->transport->negotiate.sesskey;
161 setup.in.capabilities = cli->transport->negotiate.capabilities;
162 setup.in.workgroup = "";
163 setup.in.credentials = anon_creds;
165 status = smb_composite_sesssetup(session2, &setup);
166 if (!NT_STATUS_IS_OK(status)) {
167 d_printf("anon session setup failed: %s\n",
171 session2->vuid = setup.out.vuid;
173 tmp = cli->tree->session;
174 cli->tree->session = session2;
176 status = dcerpc_lsa_OpenPolicy2(lsa_pipe, mem_ctx, &openpolicy);
178 cli->tree->session = tmp;
179 talloc_free(lsa_pipe);
182 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) {
183 d_printf("dcerpc_lsa_OpenPolicy2 with wrong vuid gave %s, "
184 "expected NT_STATUS_INVALID_HANDLE\n",
191 talloc_free(mem_ctx);
196 * Bind to lsa using a specific auth method
199 static BOOL bindtest(struct smbcli_state *cli,
200 struct cli_credentials *credentials,
201 uint8_t auth_type, uint8_t auth_level)
207 struct dcerpc_pipe *lsa_pipe;
208 struct lsa_ObjectAttribute objectattr;
209 struct lsa_OpenPolicy2 openpolicy;
210 struct lsa_QueryInfoPolicy query;
211 struct policy_handle handle;
212 struct lsa_Close close_handle;
214 if ((mem_ctx = talloc_init("bindtest")) == NULL) {
215 d_printf("talloc_init failed\n");
219 lsa_pipe = dcerpc_pipe_init(mem_ctx,
220 cli->transport->socket->event.ctx);
221 if (lsa_pipe == NULL) {
222 d_printf("dcerpc_pipe_init failed\n");
226 status = dcerpc_pipe_open_smb(lsa_pipe, cli->tree, "\\lsarpc");
227 if (!NT_STATUS_IS_OK(status)) {
228 d_printf("dcerpc_pipe_open_smb failed: %s\n",
233 status = dcerpc_bind_auth(lsa_pipe, &dcerpc_table_lsarpc,
234 credentials, auth_type, auth_level,
236 if (!NT_STATUS_IS_OK(status)) {
237 d_printf("dcerpc_bind_auth failed: %s\n", nt_errstr(status));
241 openpolicy.in.system_name =talloc_asprintf(
242 mem_ctx, "\\\\%s", dcerpc_server_name(lsa_pipe));
243 ZERO_STRUCT(objectattr);
244 openpolicy.in.attr = &objectattr;
245 openpolicy.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
246 openpolicy.out.handle = &handle;
248 status = dcerpc_lsa_OpenPolicy2(lsa_pipe, mem_ctx, &openpolicy);
250 if (!NT_STATUS_IS_OK(status)) {
251 d_printf("dcerpc_lsa_OpenPolicy2 failed: %s\n",
256 query.in.handle = &handle;
257 query.in.level = LSA_POLICY_INFO_DOMAIN;
259 status = dcerpc_lsa_QueryInfoPolicy(lsa_pipe, mem_ctx, &query);
260 if (!NT_STATUS_IS_OK(status)) {
261 d_printf("dcerpc_lsa_QueryInfoPolicy failed: %s\n",
266 close_handle.in.handle = &handle;
267 close_handle.out.handle = &handle;
269 status = dcerpc_lsa_Close(lsa_pipe, mem_ctx, &close_handle);
270 if (!NT_STATUS_IS_OK(status)) {
271 d_printf("dcerpc_lsa_Close failed: %s\n",
278 talloc_free(mem_ctx);
283 * test authenticated RPC binds with the variants Samba3 does support
286 BOOL torture_bind_samba3(struct torture_context *torture)
291 struct smbcli_state *cli;
293 mem_ctx = talloc_init("torture_bind_authcontext");
295 if (mem_ctx == NULL) {
296 d_printf("talloc_init failed\n");
300 status = smbcli_full_connection(mem_ctx, &cli,
301 torture_setting_string(torture, "host", NULL),
302 "IPC$", NULL, cmdline_credentials,
304 if (!NT_STATUS_IS_OK(status)) {
305 d_printf("smbcli_full_connection failed: %s\n",
312 ret &= bindtest(cli, cmdline_credentials, DCERPC_AUTH_TYPE_NTLMSSP,
313 DCERPC_AUTH_LEVEL_INTEGRITY);
314 ret &= bindtest(cli, cmdline_credentials, DCERPC_AUTH_TYPE_NTLMSSP,
315 DCERPC_AUTH_LEVEL_PRIVACY);
316 ret &= bindtest(cli, cmdline_credentials, DCERPC_AUTH_TYPE_SPNEGO,
317 DCERPC_AUTH_LEVEL_INTEGRITY);
318 ret &= bindtest(cli, cmdline_credentials, DCERPC_AUTH_TYPE_SPNEGO,
319 DCERPC_AUTH_LEVEL_PRIVACY);
322 talloc_free(mem_ctx);
327 * Lookup or create a user and return all necessary info
330 static NTSTATUS get_usr_handle(struct smbcli_state *cli,
332 struct cli_credentials *admin_creds,
335 const char *username,
337 struct dcerpc_pipe **result_pipe,
338 struct policy_handle **result_handle,
339 struct dom_sid **sid)
341 struct dcerpc_pipe *samr_pipe;
343 struct policy_handle conn_handle;
344 struct policy_handle domain_handle;
345 struct policy_handle *user_handle;
346 struct samr_Connect2 conn;
347 struct samr_EnumDomains enumdom;
348 uint32_t resume_handle = 0;
349 struct samr_LookupDomain l;
351 struct lsa_String domain_name;
352 struct lsa_String user_name;
353 struct samr_OpenDomain o;
354 struct samr_CreateUser2 c;
355 uint32_t user_rid,access_granted;
357 samr_pipe = dcerpc_pipe_init(mem_ctx,
358 cli->transport->socket->event.ctx);
359 if (samr_pipe == NULL) {
360 d_printf("dcerpc_pipe_init failed\n");
361 status = NT_STATUS_NO_MEMORY;
365 status = dcerpc_pipe_open_smb(samr_pipe, cli->tree, "\\samr");
366 if (!NT_STATUS_IS_OK(status)) {
367 d_printf("dcerpc_pipe_open_smb failed: %s\n",
372 if (admin_creds != NULL) {
373 status = dcerpc_bind_auth(samr_pipe, &dcerpc_table_samr,
374 admin_creds, auth_type, auth_level,
376 if (!NT_STATUS_IS_OK(status)) {
377 d_printf("dcerpc_bind_auth failed: %s\n",
382 /* We must have an authenticated SMB connection */
383 status = dcerpc_bind_auth_none(samr_pipe, &dcerpc_table_samr);
384 if (!NT_STATUS_IS_OK(status)) {
385 d_printf("dcerpc_bind_auth_none failed: %s\n",
391 conn.in.system_name = talloc_asprintf(
392 mem_ctx, "\\\\%s", dcerpc_server_name(samr_pipe));
393 conn.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
394 conn.out.connect_handle = &conn_handle;
396 status = dcerpc_samr_Connect2(samr_pipe, mem_ctx, &conn);
397 if (!NT_STATUS_IS_OK(status)) {
398 d_printf("samr_Connect2 failed: %s\n", nt_errstr(status));
402 enumdom.in.connect_handle = &conn_handle;
403 enumdom.in.resume_handle = &resume_handle;
404 enumdom.in.buf_size = (uint32_t)-1;
405 enumdom.out.resume_handle = &resume_handle;
407 status = dcerpc_samr_EnumDomains(samr_pipe, mem_ctx, &enumdom);
408 if (!NT_STATUS_IS_OK(status)) {
409 d_printf("samr_EnumDomains failed: %s\n", nt_errstr(status));
413 if (enumdom.out.num_entries != 2) {
414 d_printf("samr_EnumDomains returned %d entries, expected 2\n",
415 enumdom.out.num_entries);
416 status = NT_STATUS_UNSUCCESSFUL;
420 dom_idx = strequal(enumdom.out.sam->entries[0].name.string,
423 l.in.connect_handle = &conn_handle;
424 domain_name.string = enumdom.out.sam->entries[0].name.string;
425 *domain = talloc_strdup(mem_ctx, domain_name.string);
426 l.in.domain_name = &domain_name;
428 status = dcerpc_samr_LookupDomain(samr_pipe, mem_ctx, &l);
429 if (!NT_STATUS_IS_OK(status)) {
430 d_printf("samr_LookupDomain failed: %s\n", nt_errstr(status));
434 o.in.connect_handle = &conn_handle;
435 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
436 o.in.sid = l.out.sid;
437 o.out.domain_handle = &domain_handle;
439 status = dcerpc_samr_OpenDomain(samr_pipe, mem_ctx, &o);
440 if (!NT_STATUS_IS_OK(status)) {
441 d_printf("samr_OpenDomain failed: %s\n", nt_errstr(status));
445 c.in.domain_handle = &domain_handle;
446 user_name.string = username;
447 c.in.account_name = &user_name;
448 c.in.acct_flags = ACB_NORMAL;
449 c.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
450 user_handle = talloc(mem_ctx, struct policy_handle);
451 c.out.user_handle = user_handle;
452 c.out.access_granted = &access_granted;
453 c.out.rid = &user_rid;
455 status = dcerpc_samr_CreateUser2(samr_pipe, mem_ctx, &c);
457 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
458 struct samr_LookupNames ln;
459 struct samr_OpenUser ou;
461 ln.in.domain_handle = &domain_handle;
463 ln.in.names = &user_name;
465 status = dcerpc_samr_LookupNames(samr_pipe, mem_ctx, &ln);
466 if (!NT_STATUS_IS_OK(status)) {
467 d_printf("samr_LookupNames failed: %s\n",
472 ou.in.domain_handle = &domain_handle;
473 ou.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
474 user_rid = ou.in.rid = ln.out.rids.ids[0];
475 ou.out.user_handle = user_handle;
477 status = dcerpc_samr_OpenUser(samr_pipe, mem_ctx, &ou);
478 if (!NT_STATUS_IS_OK(status)) {
479 d_printf("samr_OpenUser failed: %s\n",
485 if (!NT_STATUS_IS_OK(status)) {
486 d_printf("samr_CreateUser failed: %s\n", nt_errstr(status));
490 *result_pipe = samr_pipe;
491 *result_handle = user_handle;
493 *sid = dom_sid_add_rid(mem_ctx, l.out.sid, user_rid);
505 static BOOL create_user(TALLOC_CTX *mem_ctx, struct smbcli_state *cli,
506 struct cli_credentials *admin_creds,
507 const char *username, const char *password,
509 struct dom_sid **user_sid)
513 struct dcerpc_pipe *samr_pipe;
514 struct policy_handle *wks_handle;
517 if (!(tmp_ctx = talloc_new(mem_ctx))) {
518 d_printf("talloc_init failed\n");
522 status = get_usr_handle(cli, tmp_ctx, admin_creds,
523 DCERPC_AUTH_TYPE_NTLMSSP,
524 DCERPC_AUTH_LEVEL_INTEGRITY,
525 username, domain_name, &samr_pipe, &wks_handle,
527 if (!NT_STATUS_IS_OK(status)) {
528 d_printf("get_wks_handle failed: %s\n", nt_errstr(status));
533 struct samr_SetUserInfo2 sui2;
534 struct samr_SetUserInfo sui;
535 struct samr_QueryUserInfo qui;
536 union samr_UserInfo u_info;
537 DATA_BLOB session_key;
539 encode_pw_buffer(u_info.info24.password.data, password,
541 u_info.info24.pw_len = strlen_m(password)*2;
543 status = dcerpc_fetch_session_key(samr_pipe, &session_key);
544 if (!NT_STATUS_IS_OK(status)) {
545 d_printf("dcerpc_fetch_session_key failed\n");
548 arcfour_crypt_blob(u_info.info24.password.data, 516,
550 sui2.in.user_handle = wks_handle;
551 sui2.in.info = &u_info;
554 status = dcerpc_samr_SetUserInfo2(samr_pipe, tmp_ctx, &sui2);
555 if (!NT_STATUS_IS_OK(status)) {
556 d_printf("samr_SetUserInfo(24) failed: %s\n",
561 u_info.info16.acct_flags = ACB_NORMAL;
562 sui.in.user_handle = wks_handle;
563 sui.in.info = &u_info;
566 status = dcerpc_samr_SetUserInfo(samr_pipe, tmp_ctx, &sui);
567 if (!NT_STATUS_IS_OK(status)) {
568 d_printf("samr_SetUserInfo(16) failed\n");
572 qui.in.user_handle = wks_handle;
575 status = dcerpc_samr_QueryUserInfo(samr_pipe, tmp_ctx, &qui);
576 if (!NT_STATUS_IS_OK(status)) {
577 d_printf("samr_QueryUserInfo(21) failed\n");
581 qui.out.info->info21.allow_password_change = 0;
582 qui.out.info->info21.force_password_change = 0;
583 qui.out.info->info21.account_name.string = NULL;
584 qui.out.info->info21.rid = 0;
585 qui.out.info->info21.fields_present = 0x81827fa; /* copy usrmgr.exe */
587 u_info.info21 = qui.out.info->info21;
588 sui.in.user_handle = wks_handle;
589 sui.in.info = &u_info;
592 status = dcerpc_samr_SetUserInfo(samr_pipe, tmp_ctx, &sui);
593 if (!NT_STATUS_IS_OK(status)) {
594 d_printf("samr_SetUserInfo(21) failed\n");
599 *domain_name= talloc_steal(mem_ctx, *domain_name);
600 *user_sid = talloc_steal(mem_ctx, *user_sid);
603 talloc_free(tmp_ctx);
611 static BOOL delete_user(struct smbcli_state *cli,
612 struct cli_credentials *admin_creds,
613 const char *username)
618 struct dcerpc_pipe *samr_pipe;
619 struct policy_handle *user_handle;
622 if ((mem_ctx = talloc_init("leave")) == NULL) {
623 d_printf("talloc_init failed\n");
627 status = get_usr_handle(cli, mem_ctx, admin_creds,
628 DCERPC_AUTH_TYPE_NTLMSSP,
629 DCERPC_AUTH_LEVEL_INTEGRITY,
630 username, &dom_name, &samr_pipe,
633 if (!NT_STATUS_IS_OK(status)) {
634 d_printf("get_wks_handle failed: %s\n", nt_errstr(status));
639 struct samr_DeleteUser d;
641 d.in.user_handle = user_handle;
642 d.out.user_handle = user_handle;
644 status = dcerpc_samr_DeleteUser(samr_pipe, mem_ctx, &d);
645 if (!NT_STATUS_IS_OK(status)) {
646 d_printf("samr_DeleteUser failed\n");
654 talloc_free(mem_ctx);
659 * Do a Samba3-style join
662 static BOOL join3(struct smbcli_state *cli,
664 struct cli_credentials *admin_creds,
665 struct cli_credentials *wks_creds)
670 struct dcerpc_pipe *samr_pipe;
671 struct policy_handle *wks_handle;
674 if ((mem_ctx = talloc_init("join3")) == NULL) {
675 d_printf("talloc_init failed\n");
679 status = get_usr_handle(
680 cli, mem_ctx, admin_creds,
681 DCERPC_AUTH_TYPE_NTLMSSP,
682 DCERPC_AUTH_LEVEL_PRIVACY,
683 talloc_asprintf(mem_ctx, "%s$",
684 cli_credentials_get_workstation(wks_creds)),
685 &dom_name, &samr_pipe, &wks_handle, NULL);
687 if (!NT_STATUS_IS_OK(status)) {
688 d_printf("get_wks_handle failed: %s\n", nt_errstr(status));
692 cli_credentials_set_domain(wks_creds, dom_name, CRED_SPECIFIED);
695 struct samr_SetUserInfo2 sui2;
696 union samr_UserInfo u_info;
697 struct samr_UserInfo21 *i21 = &u_info.info25.info;
698 DATA_BLOB session_key;
699 DATA_BLOB confounded_session_key = data_blob_talloc(
701 struct MD5Context ctx;
702 uint8_t confounder[16];
706 i21->full_name.string = talloc_asprintf(
708 cli_credentials_get_workstation(wks_creds));
709 i21->acct_flags = ACB_WSTRUST;
710 i21->fields_present = SAMR_FIELD_FULL_NAME |
711 SAMR_FIELD_ACCT_FLAGS | SAMR_FIELD_PASSWORD;
713 encode_pw_buffer(u_info.info25.password.data,
714 cli_credentials_get_password(wks_creds),
716 status = dcerpc_fetch_session_key(samr_pipe, &session_key);
717 if (!NT_STATUS_IS_OK(status)) {
718 d_printf("dcerpc_fetch_session_key failed: %s\n",
722 generate_random_buffer((uint8_t *)confounder, 16);
725 MD5Update(&ctx, confounder, 16);
726 MD5Update(&ctx, session_key.data, session_key.length);
727 MD5Final(confounded_session_key.data, &ctx);
729 arcfour_crypt_blob(u_info.info25.password.data, 516,
730 &confounded_session_key);
731 memcpy(&u_info.info25.password.data[516], confounder, 16);
733 sui2.in.user_handle = wks_handle;
735 sui2.in.info = &u_info;
737 status = dcerpc_samr_SetUserInfo2(samr_pipe, mem_ctx, &sui2);
738 if (!NT_STATUS_IS_OK(status)) {
739 d_printf("samr_SetUserInfo2(25) failed: %s\n",
744 struct samr_SetUserInfo2 sui2;
745 struct samr_SetUserInfo sui;
746 union samr_UserInfo u_info;
747 DATA_BLOB session_key;
749 encode_pw_buffer(u_info.info24.password.data,
750 cli_credentials_get_password(wks_creds),
752 u_info.info24.pw_len =
753 strlen_m(cli_credentials_get_password(wks_creds))*2;
755 status = dcerpc_fetch_session_key(samr_pipe, &session_key);
756 if (!NT_STATUS_IS_OK(status)) {
757 d_printf("dcerpc_fetch_session_key failed\n");
760 arcfour_crypt_blob(u_info.info24.password.data, 516,
762 sui2.in.user_handle = wks_handle;
763 sui2.in.info = &u_info;
766 status = dcerpc_samr_SetUserInfo2(samr_pipe, mem_ctx, &sui2);
767 if (!NT_STATUS_IS_OK(status)) {
768 d_printf("samr_SetUserInfo(24) failed: %s\n",
773 u_info.info16.acct_flags = ACB_WSTRUST;
774 sui.in.user_handle = wks_handle;
775 sui.in.info = &u_info;
778 status = dcerpc_samr_SetUserInfo(samr_pipe, mem_ctx, &sui);
779 if (!NT_STATUS_IS_OK(status)) {
780 d_printf("samr_SetUserInfo(16) failed\n");
788 talloc_free(mem_ctx);
793 * Do a ReqChallenge/Auth2 and get the wks creds
796 static BOOL auth2(struct smbcli_state *cli,
797 struct cli_credentials *wks_cred)
800 struct dcerpc_pipe *net_pipe;
803 struct netr_ServerReqChallenge r;
804 struct netr_Credential netr_cli_creds;
805 struct netr_Credential netr_srv_creds;
806 uint32_t negotiate_flags;
807 struct netr_ServerAuthenticate2 a;
808 struct creds_CredentialState *creds_state;
809 struct netr_Credential netr_cred;
810 struct samr_Password mach_pw;
812 mem_ctx = talloc_new(NULL);
813 if (mem_ctx == NULL) {
814 d_printf("talloc_new failed\n");
818 net_pipe = dcerpc_pipe_init(mem_ctx,
819 cli->transport->socket->event.ctx);
820 if (net_pipe == NULL) {
821 d_printf("dcerpc_pipe_init failed\n");
825 status = dcerpc_pipe_open_smb(net_pipe, cli->tree, "\\netlogon");
826 if (!NT_STATUS_IS_OK(status)) {
827 d_printf("dcerpc_pipe_open_smb failed: %s\n",
832 status = dcerpc_bind_auth_none(net_pipe, &dcerpc_table_netlogon);
833 if (!NT_STATUS_IS_OK(status)) {
834 d_printf("dcerpc_bind_auth_none failed: %s\n",
839 r.in.computer_name = cli_credentials_get_workstation(wks_cred);
840 r.in.server_name = talloc_asprintf(
841 mem_ctx, "\\\\%s", dcerpc_server_name(net_pipe));
842 if (r.in.server_name == NULL) {
843 d_printf("talloc_asprintf failed\n");
846 generate_random_buffer(netr_cli_creds.data,
847 sizeof(netr_cli_creds.data));
848 r.in.credentials = &netr_cli_creds;
849 r.out.credentials = &netr_srv_creds;
851 status = dcerpc_netr_ServerReqChallenge(net_pipe, mem_ctx, &r);
852 if (!NT_STATUS_IS_OK(status)) {
853 d_printf("netr_ServerReqChallenge failed: %s\n",
858 negotiate_flags = NETLOGON_NEG_AUTH2_FLAGS;
859 E_md4hash(cli_credentials_get_password(wks_cred), mach_pw.hash);
861 creds_state = talloc(mem_ctx, struct creds_CredentialState);
862 creds_client_init(creds_state, r.in.credentials,
863 r.out.credentials, &mach_pw,
864 &netr_cred, negotiate_flags);
866 a.in.server_name = talloc_asprintf(
867 mem_ctx, "\\\\%s", dcerpc_server_name(net_pipe));
868 a.in.account_name = talloc_asprintf(
869 mem_ctx, "%s$", cli_credentials_get_workstation(wks_cred));
870 a.in.computer_name = cli_credentials_get_workstation(wks_cred);
871 a.in.secure_channel_type = SEC_CHAN_WKSTA;
872 a.in.negotiate_flags = &negotiate_flags;
873 a.out.negotiate_flags = &negotiate_flags;
874 a.in.credentials = &netr_cred;
875 a.out.credentials = &netr_cred;
877 status = dcerpc_netr_ServerAuthenticate2(net_pipe, mem_ctx, &a);
878 if (!NT_STATUS_IS_OK(status)) {
879 d_printf("netr_ServerServerAuthenticate2 failed: %s\n",
884 if (!creds_client_check(creds_state, a.out.credentials)) {
885 d_printf("creds_client_check failed\n");
889 cli_credentials_set_netlogon_creds(wks_cred, creds_state);
894 talloc_free(mem_ctx);
899 * Do a couple of schannel protected Netlogon ops: Interactive and Network
900 * login, and change the wks password
903 static BOOL schan(struct smbcli_state *cli,
904 struct cli_credentials *wks_creds,
905 struct cli_credentials *user_creds)
910 struct dcerpc_pipe *net_pipe;
913 mem_ctx = talloc_new(NULL);
914 if (mem_ctx == NULL) {
915 d_printf("talloc_new failed\n");
919 net_pipe = dcerpc_pipe_init(mem_ctx,
920 cli->transport->socket->event.ctx);
921 if (net_pipe == NULL) {
922 d_printf("dcerpc_pipe_init failed\n");
926 status = dcerpc_pipe_open_smb(net_pipe, cli->tree, "\\netlogon");
927 if (!NT_STATUS_IS_OK(status)) {
928 d_printf("dcerpc_pipe_open_smb failed: %s\n",
934 net_pipe->conn->flags |= DCERPC_DEBUG_PRINT_IN |
935 DCERPC_DEBUG_PRINT_OUT;
938 net_pipe->conn->flags |= (DCERPC_SIGN | DCERPC_SEAL);
939 status = dcerpc_bind_auth(net_pipe, &dcerpc_table_netlogon,
940 wks_creds, DCERPC_AUTH_TYPE_SCHANNEL,
941 DCERPC_AUTH_LEVEL_PRIVACY,
944 status = dcerpc_bind_auth_none(net_pipe, &dcerpc_table_netlogon);
946 if (!NT_STATUS_IS_OK(status)) {
947 d_printf("schannel bind failed: %s\n", nt_errstr(status));
952 for (i=2; i<4; i++) {
954 DATA_BLOB chal, nt_resp, lm_resp, names_blob, session_key;
955 struct creds_CredentialState *creds_state;
956 struct netr_Authenticator netr_auth, netr_auth2;
957 struct netr_NetworkInfo ninfo;
958 struct netr_PasswordInfo pinfo;
959 struct netr_LogonSamLogon r;
961 flags = CLI_CRED_LANMAN_AUTH | CLI_CRED_NTLM_AUTH |
962 CLI_CRED_NTLMv2_AUTH;
964 chal = data_blob_talloc(mem_ctx, NULL, 8);
965 if (chal.data == NULL) {
966 d_printf("data_blob_talloc failed\n");
970 generate_random_buffer(chal.data, chal.length);
971 names_blob = NTLMv2_generate_names_blob(
972 mem_ctx, cli_credentials_get_workstation(user_creds),
973 cli_credentials_get_domain(user_creds));
974 status = cli_credentials_get_ntlm_response(
975 user_creds, mem_ctx, &flags, chal, names_blob,
976 &lm_resp, &nt_resp, NULL, NULL);
977 if (!NT_STATUS_IS_OK(status)) {
978 d_printf("cli_credentials_get_ntlm_response failed:"
979 " %s\n", nt_errstr(status));
983 creds_state = cli_credentials_get_netlogon_creds(wks_creds);
984 creds_client_authenticator(creds_state, &netr_auth);
986 ninfo.identity_info.account_name.string =
987 cli_credentials_get_username(user_creds);
988 ninfo.identity_info.domain_name.string =
989 cli_credentials_get_domain(user_creds);
990 ninfo.identity_info.parameter_control = 0;
991 ninfo.identity_info.logon_id_low = 0;
992 ninfo.identity_info.logon_id_high = 0;
993 ninfo.identity_info.workstation.string =
994 cli_credentials_get_workstation(user_creds);
995 memcpy(ninfo.challenge, chal.data, sizeof(ninfo.challenge));
996 ninfo.nt.length = nt_resp.length;
997 ninfo.nt.data = nt_resp.data;
998 ninfo.lm.length = lm_resp.length;
999 ninfo.lm.data = lm_resp.data;
1001 r.in.server_name = talloc_asprintf(
1002 mem_ctx, "\\\\%s", dcerpc_server_name(net_pipe));
1003 ZERO_STRUCT(netr_auth2);
1004 r.in.computer_name =
1005 cli_credentials_get_workstation(wks_creds);
1006 r.in.credential = &netr_auth;
1007 r.in.return_authenticator = &netr_auth2;
1008 r.in.logon_level = 2;
1009 r.in.validation_level = i;
1010 r.in.logon.network = &ninfo;
1011 r.out.return_authenticator = NULL;
1013 status = dcerpc_netr_LogonSamLogon(net_pipe, mem_ctx, &r);
1014 if (!NT_STATUS_IS_OK(status)) {
1015 d_printf("netr_LogonSamLogon failed: %s\n",
1020 if ((r.out.return_authenticator == NULL) ||
1021 (!creds_client_check(creds_state,
1022 &r.out.return_authenticator->cred))) {
1023 d_printf("Credentials check failed!\n");
1027 creds_client_authenticator(creds_state, &netr_auth);
1029 pinfo.identity_info = ninfo.identity_info;
1030 ZERO_STRUCT(pinfo.lmpassword.hash);
1031 E_md4hash(cli_credentials_get_password(user_creds),
1032 pinfo.ntpassword.hash);
1033 session_key = data_blob_talloc(mem_ctx,
1034 creds_state->session_key, 16);
1035 arcfour_crypt_blob(pinfo.ntpassword.hash,
1036 sizeof(pinfo.ntpassword.hash),
1039 r.in.logon_level = 1;
1040 r.in.logon.password = &pinfo;
1041 r.out.return_authenticator = NULL;
1043 status = dcerpc_netr_LogonSamLogon(net_pipe, mem_ctx, &r);
1044 if (!NT_STATUS_IS_OK(status)) {
1045 d_printf("netr_LogonSamLogon failed: %s\n",
1050 if ((r.out.return_authenticator == NULL) ||
1051 (!creds_client_check(creds_state,
1052 &r.out.return_authenticator->cred))) {
1053 d_printf("Credentials check failed!\n");
1059 struct netr_ServerPasswordSet s;
1060 char *password = generate_random_str(wks_creds, 8);
1061 struct creds_CredentialState *creds_state;
1063 s.in.server_name = talloc_asprintf(
1064 mem_ctx, "\\\\%s", dcerpc_server_name(net_pipe));
1065 s.in.computer_name = cli_credentials_get_workstation(wks_creds);
1066 s.in.account_name = talloc_asprintf(
1067 mem_ctx, "%s$", s.in.computer_name);
1068 s.in.secure_channel_type = SEC_CHAN_WKSTA;
1069 E_md4hash(password, s.in.new_password.hash);
1071 creds_state = cli_credentials_get_netlogon_creds(wks_creds);
1072 creds_des_encrypt(creds_state, &s.in.new_password);
1073 creds_client_authenticator(creds_state, &s.in.credential);
1075 status = dcerpc_netr_ServerPasswordSet(net_pipe, mem_ctx, &s);
1076 if (!NT_STATUS_IS_OK(status)) {
1077 printf("ServerPasswordSet - %s\n", nt_errstr(status));
1081 if (!creds_client_check(creds_state,
1082 &s.out.return_authenticator.cred)) {
1083 printf("Credential chaining failed\n");
1086 cli_credentials_set_password(wks_creds, password,
1092 talloc_free(mem_ctx);
1097 * Delete the wks account again
1100 static BOOL leave(struct smbcli_state *cli,
1101 struct cli_credentials *admin_creds,
1102 struct cli_credentials *wks_creds)
1104 char *wks_name = talloc_asprintf(
1105 NULL, "%s$", cli_credentials_get_workstation(wks_creds));
1108 ret = delete_user(cli, admin_creds, wks_name);
1109 talloc_free(wks_name);
1114 * Test the Samba3 DC code a bit. Join, do some schan netlogon ops, leave
1117 BOOL torture_netlogon_samba3(struct torture_context *torture)
1119 TALLOC_CTX *mem_ctx;
1122 struct smbcli_state *cli;
1123 struct cli_credentials *anon_creds;
1124 struct cli_credentials *wks_creds;
1125 const char *wks_name;
1128 wks_name = torture_setting_string(torture, "wksname", NULL);
1129 if (wks_name == NULL) {
1130 wks_name = get_myname();
1133 mem_ctx = talloc_init("torture_bind_authcontext");
1135 if (mem_ctx == NULL) {
1136 d_printf("talloc_init failed\n");
1140 if (!(anon_creds = create_anon_creds(mem_ctx))) {
1141 d_printf("create_anon_creds failed\n");
1145 status = smbcli_full_connection(mem_ctx, &cli,
1146 torture_setting_string(torture, "host", NULL),
1147 "IPC$", NULL, anon_creds, NULL);
1148 if (!NT_STATUS_IS_OK(status)) {
1149 d_printf("smbcli_full_connection failed: %s\n",
1154 wks_creds = cli_credentials_init(mem_ctx);
1155 if (wks_creds == NULL) {
1156 d_printf("cli_credentials_init failed\n");
1160 cli_credentials_set_conf(wks_creds);
1161 cli_credentials_set_secure_channel_type(wks_creds, SEC_CHAN_WKSTA);
1162 cli_credentials_set_username(wks_creds, wks_name, CRED_SPECIFIED);
1163 cli_credentials_set_workstation(wks_creds, wks_name, CRED_SPECIFIED);
1164 cli_credentials_set_password(wks_creds,
1165 generate_random_str(wks_creds, 8),
1168 if (!join3(cli, False, cmdline_credentials, wks_creds)) {
1169 d_printf("join failed\n");
1173 cli_credentials_set_domain(
1174 cmdline_credentials, cli_credentials_get_domain(wks_creds),
1177 for (i=0; i<2; i++) {
1179 /* Do this more than once, the routine "schan" changes
1180 * the workstation password using the netlogon
1181 * password change routine */
1185 if (!auth2(cli, wks_creds)) {
1186 d_printf("auth2 failed\n");
1190 for (j=0; j<2; j++) {
1191 if (!schan(cli, wks_creds, cmdline_credentials)) {
1192 d_printf("schan failed\n");
1198 if (!leave(cli, cmdline_credentials, wks_creds)) {
1199 d_printf("leave failed\n");
1206 talloc_free(mem_ctx);
1211 * Do a simple join, testjoin and leave using specified smb and samr
1215 static BOOL test_join3(TALLOC_CTX *mem_ctx,
1217 struct cli_credentials *smb_creds,
1218 struct cli_credentials *samr_creds,
1219 const char *wks_name)
1223 struct smbcli_state *cli;
1224 struct cli_credentials *wks_creds;
1226 status = smbcli_full_connection(mem_ctx, &cli,
1227 lp_parm_string(-1, "torture", "host"),
1228 "IPC$", NULL, smb_creds, NULL);
1229 if (!NT_STATUS_IS_OK(status)) {
1230 d_printf("smbcli_full_connection failed: %s\n",
1235 wks_creds = cli_credentials_init(cli);
1236 if (wks_creds == NULL) {
1237 d_printf("cli_credentials_init failed\n");
1241 cli_credentials_set_conf(wks_creds);
1242 cli_credentials_set_secure_channel_type(wks_creds, SEC_CHAN_WKSTA);
1243 cli_credentials_set_username(wks_creds, wks_name, CRED_SPECIFIED);
1244 cli_credentials_set_workstation(wks_creds, wks_name, CRED_SPECIFIED);
1245 cli_credentials_set_password(wks_creds,
1246 generate_random_str(wks_creds, 8),
1249 if (!join3(cli, use_level25, samr_creds, wks_creds)) {
1250 d_printf("join failed\n");
1254 cli_credentials_set_domain(
1255 cmdline_credentials, cli_credentials_get_domain(wks_creds),
1258 if (!auth2(cli, wks_creds)) {
1259 d_printf("auth2 failed\n");
1263 if (!leave(cli, samr_creds, wks_creds)) {
1264 d_printf("leave failed\n");
1277 * Test the different session key variants. Do it by joining, this uses the
1278 * session key in the setpassword routine. Test the join by doing the auth2.
1281 BOOL torture_samba3_sessionkey(struct torture_context *torture)
1283 TALLOC_CTX *mem_ctx;
1285 struct cli_credentials *anon_creds;
1286 const char *wks_name;
1288 wks_name = torture_setting_string(torture, "wksname", get_myname());
1290 mem_ctx = talloc_init("torture_samba3_sessionkey");
1292 if (mem_ctx == NULL) {
1293 d_printf("talloc_init failed\n");
1297 if (!(anon_creds = create_anon_creds(mem_ctx))) {
1298 d_printf("create_anon_creds failed\n");
1304 if (!torture_setting_bool(torture, "samba3", False)) {
1306 /* Samba3 in the build farm right now does this happily. Need
1309 if (test_join3(mem_ctx, False, anon_creds, NULL, wks_name)) {
1310 d_printf("join using anonymous bind on an anonymous smb "
1311 "connection succeeded -- HUH??\n");
1316 if (!test_join3(mem_ctx, False, anon_creds, cmdline_credentials,
1318 d_printf("join using ntlmssp bind on an anonymous smb "
1319 "connection failed\n");
1323 if (!test_join3(mem_ctx, False, cmdline_credentials, NULL, wks_name)) {
1324 d_printf("join using anonymous bind on an authenticated smb "
1325 "connection failed\n");
1329 if (!test_join3(mem_ctx, False, cmdline_credentials,
1330 cmdline_credentials,
1332 d_printf("join using ntlmssp bind on an authenticated smb "
1333 "connection failed\n");
1338 * The following two are tests for setuserinfolevel 25
1341 if (!test_join3(mem_ctx, True, anon_creds, cmdline_credentials,
1343 d_printf("join using ntlmssp bind on an anonymous smb "
1344 "connection failed\n");
1348 if (!test_join3(mem_ctx, True, cmdline_credentials, NULL, wks_name)) {
1349 d_printf("join using anonymous bind on an authenticated smb "
1350 "connection failed\n");
1360 * open pipe and bind, given an IPC$ context
1363 static NTSTATUS pipe_bind_smb(TALLOC_CTX *mem_ctx,
1364 struct smbcli_tree *tree,
1365 const char *pipe_name,
1366 const struct dcerpc_interface_table *iface,
1367 struct dcerpc_pipe **p)
1369 struct dcerpc_pipe *result;
1372 if (!(result = dcerpc_pipe_init(
1373 mem_ctx, tree->session->transport->socket->event.ctx))) {
1374 return NT_STATUS_NO_MEMORY;
1377 status = dcerpc_pipe_open_smb(result, tree, pipe_name);
1378 if (!NT_STATUS_IS_OK(status)) {
1379 d_printf("dcerpc_pipe_open_smb failed: %s\n",
1381 talloc_free(result);
1385 status = dcerpc_bind_auth_none(result, iface);
1386 if (!NT_STATUS_IS_OK(status)) {
1387 d_printf("schannel bind failed: %s\n", nt_errstr(status));
1388 talloc_free(result);
1393 return NT_STATUS_OK;
1397 * Sane wrapper around lsa_LookupNames
1400 static struct dom_sid *name2sid(TALLOC_CTX *mem_ctx,
1401 struct dcerpc_pipe *p,
1405 struct lsa_ObjectAttribute attr;
1406 struct lsa_QosInfo qos;
1407 struct lsa_OpenPolicy2 r;
1410 struct policy_handle handle;
1411 struct lsa_LookupNames l;
1412 struct lsa_TransSidArray sids;
1413 struct lsa_String lsa_name;
1415 struct dom_sid *result;
1416 TALLOC_CTX *tmp_ctx;
1418 if (!(tmp_ctx = talloc_new(mem_ctx))) {
1423 qos.impersonation_level = 2;
1424 qos.context_mode = 1;
1425 qos.effective_only = 0;
1428 attr.root_dir = NULL;
1429 attr.object_name = NULL;
1430 attr.attributes = 0;
1431 attr.sec_desc = NULL;
1432 attr.sec_qos = &qos;
1434 r.in.system_name = "\\";
1436 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1437 r.out.handle = &handle;
1439 status = dcerpc_lsa_OpenPolicy2(p, tmp_ctx, &r);
1440 if (!NT_STATUS_IS_OK(status)) {
1441 printf("OpenPolicy2 failed - %s\n", nt_errstr(status));
1442 talloc_free(tmp_ctx);
1449 lsa_name.string = talloc_asprintf(tmp_ctx, "%s\\%s", domain, name);
1451 l.in.handle = &handle;
1453 l.in.names = &lsa_name;
1456 l.in.count = &count;
1457 l.out.count = &count;
1460 status = dcerpc_lsa_LookupNames(p, tmp_ctx, &l);
1461 if (!NT_STATUS_IS_OK(status)) {
1462 printf("LookupNames of %s failed - %s\n", lsa_name.string,
1464 talloc_free(tmp_ctx);
1468 result = dom_sid_add_rid(mem_ctx, l.out.domains->domains[0].sid,
1469 l.out.sids->sids[0].rid);
1471 c.in.handle = &handle;
1472 c.out.handle = &handle;
1474 status = dcerpc_lsa_Close(p, tmp_ctx, &c);
1475 if (!NT_STATUS_IS_OK(status)) {
1476 printf("dcerpc_lsa_Close failed - %s\n", nt_errstr(status));
1477 talloc_free(tmp_ctx);
1481 talloc_free(tmp_ctx);
1486 * Find out the user SID on this connection
1489 static struct dom_sid *whoami(TALLOC_CTX *mem_ctx, struct smbcli_tree *tree)
1491 struct dcerpc_pipe *lsa;
1492 struct lsa_GetUserName r;
1494 struct lsa_StringPointer authority_name_p;
1495 struct dom_sid *result;
1497 status = pipe_bind_smb(mem_ctx, tree, "\\pipe\\lsarpc",
1498 &dcerpc_table_lsarpc, &lsa);
1499 if (!NT_STATUS_IS_OK(status)) {
1500 d_printf("(%s) Could not bind to LSA: %s\n",
1501 __location__, nt_errstr(status));
1505 r.in.system_name = "\\";
1506 r.in.account_name = NULL;
1507 authority_name_p.string = NULL;
1508 r.in.authority_name = &authority_name_p;
1510 status = dcerpc_lsa_GetUserName(lsa, mem_ctx, &r);
1512 if (!NT_STATUS_IS_OK(status)) {
1513 printf("(%s) GetUserName failed - %s\n",
1514 __location__, nt_errstr(status));
1519 result = name2sid(mem_ctx, lsa, r.out.account_name->string,
1520 r.out.authority_name->string->string);
1527 * Do a tcon, given a session
1530 NTSTATUS secondary_tcon(TALLOC_CTX *mem_ctx,
1531 struct smbcli_session *session,
1532 const char *sharename,
1533 struct smbcli_tree **res)
1535 struct smbcli_tree *result;
1536 TALLOC_CTX *tmp_ctx;
1537 union smb_tcon tcon;
1540 if (!(tmp_ctx = talloc_new(mem_ctx))) {
1541 return NT_STATUS_NO_MEMORY;
1544 if (!(result = smbcli_tree_init(session, mem_ctx, False))) {
1545 talloc_free(tmp_ctx);
1546 return NT_STATUS_NO_MEMORY;
1549 tcon.generic.level = RAW_TCON_TCONX;
1550 tcon.tconx.in.flags = 0;
1551 tcon.tconx.in.password = data_blob(NULL, 0);
1552 tcon.tconx.in.path = sharename;
1553 tcon.tconx.in.device = "?????";
1555 status = smb_raw_tcon(result, tmp_ctx, &tcon);
1556 if (!NT_STATUS_IS_OK(status)) {
1557 d_printf("(%s) smb_raw_tcon failed: %s\n", __location__,
1559 talloc_free(tmp_ctx);
1563 result->tid = tcon.tconx.out.tid;
1564 result = talloc_steal(mem_ctx, result);
1565 talloc_free(tmp_ctx);
1567 return NT_STATUS_OK;
1571 * Test the getusername behaviour
1574 BOOL torture_samba3_rpc_getusername(struct torture_context *torture)
1577 struct smbcli_state *cli;
1578 TALLOC_CTX *mem_ctx;
1580 struct dom_sid *user_sid;
1581 struct dom_sid *created_sid;
1582 struct cli_credentials *anon_creds;
1583 struct cli_credentials *user_creds;
1586 if (!(mem_ctx = talloc_new(torture))) {
1590 status = smbcli_full_connection(
1591 mem_ctx, &cli, torture_setting_string(torture, "host", NULL),
1592 "IPC$", NULL, cmdline_credentials, NULL);
1593 if (!NT_STATUS_IS_OK(status)) {
1594 d_printf("(%s) smbcli_full_connection failed: %s\n",
1595 __location__, nt_errstr(status));
1600 if (!(user_sid = whoami(mem_ctx, cli->tree))) {
1601 d_printf("(%s) whoami on auth'ed connection failed\n",
1608 if (!(anon_creds = create_anon_creds(mem_ctx))) {
1609 d_printf("(%s) create_anon_creds failed\n", __location__);
1614 status = smbcli_full_connection(
1615 mem_ctx, &cli, torture_setting_string(torture, "host", NULL),
1616 "IPC$", NULL, anon_creds, NULL);
1617 if (!NT_STATUS_IS_OK(status)) {
1618 d_printf("(%s) anon smbcli_full_connection failed: %s\n",
1619 __location__, nt_errstr(status));
1624 if (!(user_sid = whoami(mem_ctx, cli->tree))) {
1625 d_printf("(%s) whoami on anon connection failed\n",
1631 if (!dom_sid_equal(user_sid,
1632 dom_sid_parse_talloc(mem_ctx, "s-1-5-7"))) {
1633 d_printf("(%s) Anon lsa_GetUserName returned %s, expected "
1634 "S-1-5-7", __location__,
1635 dom_sid_string(mem_ctx, user_sid));
1639 if (!(user_creds = cli_credentials_init(mem_ctx))) {
1640 d_printf("(%s) cli_credentials_init failed\n", __location__);
1645 cli_credentials_set_conf(user_creds);
1646 cli_credentials_set_username(user_creds, "torture_username",
1648 cli_credentials_set_password(user_creds,
1649 generate_random_str(user_creds, 8),
1652 if (!create_user(mem_ctx, cli, cmdline_credentials,
1653 cli_credentials_get_username(user_creds),
1654 cli_credentials_get_password(user_creds),
1655 &domain_name, &created_sid)) {
1656 d_printf("(%s) create_user failed\n", __location__);
1661 cli_credentials_set_domain(user_creds, domain_name,
1665 struct smbcli_session *session2;
1666 struct smb_composite_sesssetup setup;
1667 struct smbcli_tree *tree;
1669 session2 = smbcli_session_init(cli->transport, mem_ctx, False);
1670 if (session2 == NULL) {
1671 d_printf("(%s) smbcli_session_init failed\n",
1676 setup.in.sesskey = cli->transport->negotiate.sesskey;
1677 setup.in.capabilities = cli->transport->negotiate.capabilities;
1678 setup.in.workgroup = "";
1679 setup.in.credentials = user_creds;
1681 status = smb_composite_sesssetup(session2, &setup);
1682 if (!NT_STATUS_IS_OK(status)) {
1683 d_printf("(%s) session setup with new user failed: "
1684 "%s\n", __location__, nt_errstr(status));
1688 session2->vuid = setup.out.vuid;
1690 if (!NT_STATUS_IS_OK(secondary_tcon(mem_ctx, session2,
1692 d_printf("(%s) secondary_tcon failed\n",
1698 if (!(user_sid = whoami(mem_ctx, tree))) {
1699 d_printf("(%s) whoami on user connection failed\n",
1708 d_printf("Created %s, found %s\n",
1709 dom_sid_string(mem_ctx, created_sid),
1710 dom_sid_string(mem_ctx, user_sid));
1712 if (!dom_sid_equal(created_sid, user_sid)) {
1717 if (!delete_user(cli, cmdline_credentials,
1718 cli_credentials_get_username(user_creds))) {
1719 d_printf("(%s) delete_user failed\n", __location__);
1724 talloc_free(mem_ctx);
1728 static BOOL test_NetShareGetInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1729 const char *sharename)
1732 struct srvsvc_NetShareGetInfo r;
1733 uint32_t levels[] = { 0, 1, 2, 501, 502, 1004, 1005, 1006, 1007, 1501 };
1737 r.in.server_unc = talloc_asprintf(mem_ctx, "\\\\%s",
1738 dcerpc_server_name(p));
1739 r.in.share_name = sharename;
1741 for (i=0;i<ARRAY_SIZE(levels);i++) {
1742 r.in.level = levels[i];
1746 printf("testing NetShareGetInfo level %u on share '%s'\n",
1747 r.in.level, r.in.share_name);
1749 status = dcerpc_srvsvc_NetShareGetInfo(p, mem_ctx, &r);
1750 if (!NT_STATUS_IS_OK(status)) {
1751 printf("NetShareGetInfo level %u on share '%s' failed"
1752 " - %s\n", r.in.level, r.in.share_name,
1757 if (!W_ERROR_IS_OK(r.out.result)) {
1758 printf("NetShareGetInfo level %u on share '%s' failed "
1759 "- %s\n", r.in.level, r.in.share_name,
1760 win_errstr(r.out.result));
1769 static BOOL test_NetShareEnum(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1770 const char **one_sharename)
1773 struct srvsvc_NetShareEnum r;
1774 struct srvsvc_NetShareCtr0 c0;
1775 uint32_t levels[] = { 0, 1, 2, 501, 502, 1004, 1005, 1006, 1007 };
1779 r.in.server_unc = talloc_asprintf(mem_ctx,"\\\\%s",dcerpc_server_name(p));
1780 r.in.ctr.ctr0 = &c0;
1781 r.in.ctr.ctr0->count = 0;
1782 r.in.ctr.ctr0->array = NULL;
1783 r.in.max_buffer = (uint32_t)-1;
1784 r.in.resume_handle = NULL;
1786 for (i=0;i<ARRAY_SIZE(levels);i++) {
1787 r.in.level = levels[i];
1791 printf("testing NetShareEnum level %u\n", r.in.level);
1792 status = dcerpc_srvsvc_NetShareEnum(p, mem_ctx, &r);
1793 if (!NT_STATUS_IS_OK(status)) {
1794 printf("NetShareEnum level %u failed - %s\n",
1795 r.in.level, nt_errstr(status));
1799 if (!W_ERROR_IS_OK(r.out.result)) {
1800 printf("NetShareEnum level %u failed - %s\n",
1801 r.in.level, win_errstr(r.out.result));
1804 if (r.in.level == 0) {
1805 struct srvsvc_NetShareCtr0 *ctr = r.out.ctr.ctr0;
1806 if (ctr->count > 0) {
1807 *one_sharename = ctr->array[0].name;
1815 BOOL torture_samba3_rpc_srvsvc(struct torture_context *torture)
1817 struct dcerpc_pipe *p;
1818 TALLOC_CTX *mem_ctx;
1820 const char *sharename = NULL;
1821 struct smbcli_state *cli;
1824 if (!(mem_ctx = talloc_new(torture))) {
1828 if (!(torture_open_connection_share(
1829 mem_ctx, &cli, torture_setting_string(torture, "host", NULL),
1831 talloc_free(mem_ctx);
1835 status = pipe_bind_smb(mem_ctx, cli->tree, "\\pipe\\srvsvc",
1836 &dcerpc_table_srvsvc, &p);
1837 if (!NT_STATUS_IS_OK(status)) {
1838 d_printf("(%s) could not bind to srvsvc pipe: %s\n",
1839 __location__, nt_errstr(status));
1844 ret &= test_NetShareEnum(p, mem_ctx, &sharename);
1845 if (sharename == NULL) {
1846 printf("did not get sharename\n");
1848 ret &= test_NetShareGetInfo(p, mem_ctx, sharename);
1852 talloc_free(mem_ctx);
1856 static struct security_descriptor *get_sharesec(TALLOC_CTX *mem_ctx,
1857 struct smbcli_session *sess,
1858 const char *sharename)
1860 struct smbcli_tree *tree;
1861 TALLOC_CTX *tmp_ctx;
1862 struct dcerpc_pipe *p;
1864 struct srvsvc_NetShareGetInfo r;
1865 struct security_descriptor *result;
1867 if (!(tmp_ctx = talloc_new(mem_ctx))) {
1868 d_printf("talloc_new failed\n");
1872 if (!NT_STATUS_IS_OK(secondary_tcon(tmp_ctx, sess, "IPC$", &tree))) {
1873 d_printf("secondary_tcon failed\n");
1874 talloc_free(tmp_ctx);
1878 status = pipe_bind_smb(mem_ctx, tree, "\\pipe\\srvsvc",
1879 &dcerpc_table_srvsvc, &p);
1880 if (!NT_STATUS_IS_OK(status)) {
1881 d_printf("(%s) could not bind to srvsvc pipe: %s\n",
1882 __location__, nt_errstr(status));
1883 talloc_free(tmp_ctx);
1888 p->conn->flags |= DCERPC_DEBUG_PRINT_IN | DCERPC_DEBUG_PRINT_OUT;
1891 r.in.server_unc = talloc_asprintf(tmp_ctx, "\\\\%s",
1892 dcerpc_server_name(p));
1893 r.in.share_name = sharename;
1896 status = dcerpc_srvsvc_NetShareGetInfo(p, tmp_ctx, &r);
1897 if (!NT_STATUS_IS_OK(status)) {
1898 d_printf("srvsvc_NetShareGetInfo failed: %s\n",
1900 talloc_free(tmp_ctx);
1904 result = talloc_steal(mem_ctx, r.out.info.info502->sd);
1905 talloc_free(tmp_ctx);
1909 static NTSTATUS set_sharesec(TALLOC_CTX *mem_ctx,
1910 struct smbcli_session *sess,
1911 const char *sharename,
1912 struct security_descriptor *sd)
1914 struct smbcli_tree *tree;
1915 TALLOC_CTX *tmp_ctx;
1916 struct dcerpc_pipe *p;
1918 struct sec_desc_buf i;
1919 struct srvsvc_NetShareSetInfo r;
1922 if (!(tmp_ctx = talloc_new(mem_ctx))) {
1923 d_printf("talloc_new failed\n");
1924 return NT_STATUS_NO_MEMORY;
1927 if (!NT_STATUS_IS_OK(secondary_tcon(tmp_ctx, sess, "IPC$", &tree))) {
1928 d_printf("secondary_tcon failed\n");
1929 talloc_free(tmp_ctx);
1930 return NT_STATUS_UNSUCCESSFUL;
1933 status = pipe_bind_smb(mem_ctx, tree, "\\pipe\\srvsvc",
1934 &dcerpc_table_srvsvc, &p);
1935 if (!NT_STATUS_IS_OK(status)) {
1936 d_printf("(%s) could not bind to srvsvc pipe: %s\n",
1937 __location__, nt_errstr(status));
1938 talloc_free(tmp_ctx);
1939 return NT_STATUS_UNSUCCESSFUL;
1943 p->conn->flags |= DCERPC_DEBUG_PRINT_IN | DCERPC_DEBUG_PRINT_OUT;
1946 r.in.server_unc = talloc_asprintf(tmp_ctx, "\\\\%s",
1947 dcerpc_server_name(p));
1948 r.in.share_name = sharename;
1951 r.in.info.info1501 = &i;
1952 r.in.parm_error = &error;
1954 status = dcerpc_srvsvc_NetShareSetInfo(p, tmp_ctx, &r);
1955 if (!NT_STATUS_IS_OK(status)) {
1956 d_printf("srvsvc_NetShareGetInfo failed: %s\n",
1960 talloc_free(tmp_ctx);
1964 BOOL try_tcon(TALLOC_CTX *mem_ctx,
1965 struct security_descriptor *orig_sd,
1966 struct smbcli_session *session,
1967 const char *sharename, const struct dom_sid *user_sid,
1968 unsigned int access_mask, NTSTATUS expected_tcon,
1969 NTSTATUS expected_mkdir)
1971 TALLOC_CTX *tmp_ctx;
1972 struct smbcli_tree *rmdir_tree, *tree;
1973 struct dom_sid *domain_sid;
1975 struct security_descriptor *sd;
1979 if (!(tmp_ctx = talloc_new(mem_ctx))) {
1980 d_printf("talloc_new failed\n");
1984 status = secondary_tcon(tmp_ctx, session, sharename, &rmdir_tree);
1985 if (!NT_STATUS_IS_OK(status)) {
1986 d_printf("first tcon to delete dir failed\n");
1987 talloc_free(tmp_ctx);
1991 smbcli_rmdir(rmdir_tree, "sharesec_testdir");
1993 if (!NT_STATUS_IS_OK(dom_sid_split_rid(tmp_ctx, user_sid,
1994 &domain_sid, &rid))) {
1995 d_printf("dom_sid_split_rid failed\n");
1996 talloc_free(tmp_ctx);
2000 sd = security_descriptor_create(
2001 tmp_ctx, "S-1-5-32-544",
2002 dom_sid_string(mem_ctx, dom_sid_add_rid(mem_ctx, domain_sid,
2004 dom_sid_string(mem_ctx, user_sid),
2005 SEC_ACE_TYPE_ACCESS_ALLOWED, access_mask, 0, NULL);
2007 d_printf("security_descriptor_create failed\n");
2008 talloc_free(tmp_ctx);
2012 status = set_sharesec(mem_ctx, session, sharename, sd);
2013 if (!NT_STATUS_IS_OK(status)) {
2014 d_printf("custom set_sharesec failed: %s\n",
2016 talloc_free(tmp_ctx);
2020 status = secondary_tcon(tmp_ctx, session, sharename, &tree);
2021 if (!NT_STATUS_EQUAL(status, expected_tcon)) {
2022 d_printf("Expected %s, got %s\n", nt_errstr(expected_tcon),
2028 if (!NT_STATUS_IS_OK(status)) {
2029 /* An expected non-access, no point in trying to write */
2033 status = smbcli_mkdir(tree, "sharesec_testdir");
2034 if (!NT_STATUS_EQUAL(status, expected_mkdir)) {
2035 d_printf("(%s) Expected %s, got %s\n", __location__,
2036 nt_errstr(expected_mkdir), nt_errstr(status));
2041 smbcli_rmdir(rmdir_tree, "sharesec_testdir");
2043 status = set_sharesec(mem_ctx, session, sharename, orig_sd);
2044 if (!NT_STATUS_IS_OK(status)) {
2045 d_printf("custom set_sharesec failed: %s\n",
2047 talloc_free(tmp_ctx);
2051 talloc_free(tmp_ctx);
2055 BOOL torture_samba3_rpc_sharesec(struct torture_context *torture)
2057 TALLOC_CTX *mem_ctx;
2059 struct smbcli_state *cli;
2060 struct security_descriptor *sd;
2061 struct dom_sid *user_sid;
2063 if (!(mem_ctx = talloc_new(torture))) {
2067 if (!(torture_open_connection_share(
2068 mem_ctx, &cli, torture_setting_string(torture, "host", NULL),
2070 d_printf("IPC$ connection failed\n");
2071 talloc_free(mem_ctx);
2075 if (!(user_sid = whoami(mem_ctx, cli->tree))) {
2076 d_printf("whoami failed\n");
2077 talloc_free(mem_ctx);
2081 sd = get_sharesec(mem_ctx, cli->session, torture_setting_string(torture,
2084 ret &= try_tcon(mem_ctx, sd, cli->session,
2085 torture_setting_string(torture, "share", NULL),
2086 user_sid, 0, NT_STATUS_ACCESS_DENIED, NT_STATUS_OK);
2088 ret &= try_tcon(mem_ctx, sd, cli->session,
2089 torture_setting_string(torture, "share", NULL),
2090 user_sid, SEC_FILE_READ_DATA, NT_STATUS_OK,
2091 NT_STATUS_MEDIA_WRITE_PROTECTED);
2093 ret &= try_tcon(mem_ctx, sd, cli->session,
2094 torture_setting_string(torture, "share", NULL),
2095 user_sid, SEC_FILE_ALL, NT_STATUS_OK, NT_STATUS_OK);
2097 talloc_free(mem_ctx);
2101 BOOL torture_samba3_rpc_lsa(struct torture_context *torture)
2103 TALLOC_CTX *mem_ctx;
2105 struct smbcli_state *cli;
2106 struct dcerpc_pipe *p;
2107 struct policy_handle lsa_handle;
2109 struct dom_sid *domain_sid;
2111 if (!(mem_ctx = talloc_new(torture))) {
2115 if (!(torture_open_connection_share(
2116 mem_ctx, &cli, torture_setting_string(torture, "host", NULL),
2118 d_printf("IPC$ connection failed\n");
2119 talloc_free(mem_ctx);
2123 status = pipe_bind_smb(mem_ctx, cli->tree, "\\lsarpc",
2124 &dcerpc_table_lsarpc, &p);
2125 if (!NT_STATUS_IS_OK(status)) {
2126 d_printf("(%s) pipe_bind_smb failed: %s\n", __location__,
2128 talloc_free(mem_ctx);
2133 struct lsa_ObjectAttribute attr;
2134 struct lsa_OpenPolicy2 o;
2135 o.in.system_name = talloc_asprintf(
2136 mem_ctx, "\\\\%s", dcerpc_server_name(p));
2139 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2140 o.out.handle = &lsa_handle;
2141 status = dcerpc_lsa_OpenPolicy2(p, mem_ctx, &o);
2142 if (!NT_STATUS_IS_OK(status)) {
2143 d_printf("(%s) dcerpc_lsa_OpenPolicy2 failed: %s\n",
2144 __location__, nt_errstr(status));
2145 talloc_free(mem_ctx);
2151 p->conn->flags |= DCERPC_DEBUG_PRINT_IN | DCERPC_DEBUG_PRINT_OUT;
2156 int levels[] = { 2,3,5,6 };
2158 for (i=0; i<ARRAY_SIZE(levels); i++) {
2159 struct lsa_QueryInfoPolicy r;
2160 r.in.handle = &lsa_handle;
2161 r.in.level = levels[i];
2162 status = dcerpc_lsa_QueryInfoPolicy(p, mem_ctx, &r);
2163 if (!NT_STATUS_IS_OK(status)) {
2164 d_printf("(%s) dcerpc_lsa_QueryInfoPolicy %d "
2165 "failed: %s\n", __location__,
2166 levels[i], nt_errstr(status));
2167 talloc_free(mem_ctx);
2170 if (levels[i] == 5) {
2171 domain_sid = r.out.info->account_domain.sid;
2179 static NTSTATUS get_servername(TALLOC_CTX *mem_ctx, struct smbcli_tree *tree,
2182 struct rap_WserverGetInfo r;
2184 char servername[17];
2187 r.in.bufsize = 0xffff;
2189 status = smbcli_rap_netservergetinfo(tree, mem_ctx, &r);
2190 if (!NT_STATUS_IS_OK(status)) {
2194 memcpy(servername, r.out.info.info0.name, 16);
2195 servername[16] = '\0';
2197 if (pull_ascii_talloc(mem_ctx, name, servername) < 0) {
2198 return NT_STATUS_NO_MEMORY;
2201 return NT_STATUS_OK;
2205 static NTSTATUS find_printers(TALLOC_CTX *ctx, struct smbcli_tree *tree,
2206 const char ***printers, int *num_printers)
2208 TALLOC_CTX *mem_ctx;
2210 struct dcerpc_pipe *p;
2211 struct srvsvc_NetShareEnum r;
2212 struct srvsvc_NetShareCtr1 c1_in;
2213 struct srvsvc_NetShareCtr1 *c1;
2216 mem_ctx = talloc_new(ctx);
2217 if (mem_ctx == NULL) {
2218 return NT_STATUS_NO_MEMORY;
2221 status = pipe_bind_smb(mem_ctx, tree, "\\srvsvc", &dcerpc_table_srvsvc,
2223 if (!NT_STATUS_IS_OK(status)) {
2224 d_printf("could not bind to srvsvc pipe\n");
2225 talloc_free(mem_ctx);
2229 r.in.server_unc = talloc_asprintf(
2230 mem_ctx, "\\\\%s", dcerpc_server_name(p));
2233 r.in.ctr.ctr1 = &c1_in;
2234 r.in.max_buffer = (uint32_t)-1;
2235 r.in.resume_handle = NULL;
2237 status = dcerpc_srvsvc_NetShareEnum(p, mem_ctx, &r);
2238 if (!NT_STATUS_IS_OK(status)) {
2239 d_printf("NetShareEnum level %u failed - %s\n",
2240 r.in.level, nt_errstr(status));
2241 talloc_free(mem_ctx);
2247 c1 = r.out.ctr.ctr1;
2248 for (i=0; i<c1->count; i++) {
2249 if (c1->array[i].type != STYPE_PRINTQ) {
2252 if (!add_string_to_array(ctx, c1->array[i].name,
2253 printers, num_printers)) {
2255 return NT_STATUS_NO_MEMORY;
2259 talloc_free(mem_ctx);
2260 return NT_STATUS_OK;
2263 static BOOL enumprinters(TALLOC_CTX *mem_ctx, struct dcerpc_pipe *pipe,
2264 const char *servername, int level, int *num_printers)
2266 struct spoolss_EnumPrinters r;
2270 r.in.flags = PRINTER_ENUM_LOCAL;
2271 r.in.server = talloc_asprintf(mem_ctx, "\\\\%s", servername);
2276 status = dcerpc_spoolss_EnumPrinters(pipe, mem_ctx, &r);
2277 if (!NT_STATUS_IS_OK(status)) {
2278 d_printf("(%s) dcerpc_spoolss_EnumPrinters failed: %s\n",
2279 __location__, nt_errstr(status));
2283 if (!W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
2284 d_printf("(%s) EnumPrinters unexpected return code %s, should "
2285 "be WERR_INSUFFICIENT_BUFFER\n", __location__,
2286 win_errstr(r.out.result));
2290 blob = data_blob_talloc(mem_ctx, NULL, r.out.needed);
2291 if (blob.data == NULL) {
2292 d_printf("(%s) data_blob_talloc failed\n", __location__);
2296 r.in.buffer = &blob;
2297 r.in.offered = r.out.needed;
2299 status = dcerpc_spoolss_EnumPrinters(pipe, mem_ctx, &r);
2300 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
2301 d_printf("(%s) dcerpc_spoolss_EnumPrinters failed: %s, "
2302 "%s\n", __location__, nt_errstr(status),
2303 win_errstr(r.out.result));
2307 *num_printers = r.out.count;
2312 static NTSTATUS getprinterinfo(TALLOC_CTX *ctx, struct dcerpc_pipe *pipe,
2313 struct policy_handle *handle, int level,
2314 union spoolss_PrinterInfo **res)
2316 TALLOC_CTX *mem_ctx;
2317 struct spoolss_GetPrinter r;
2321 mem_ctx = talloc_new(ctx);
2322 if (mem_ctx == NULL) {
2323 return NT_STATUS_NO_MEMORY;
2326 r.in.handle = handle;
2331 status = dcerpc_spoolss_GetPrinter(pipe, mem_ctx, &r);
2332 if (!NT_STATUS_IS_OK(status)) {
2333 d_printf("(%s) dcerpc_spoolss_GetPrinter failed: %s\n",
2334 __location__, nt_errstr(status));
2335 talloc_free(mem_ctx);
2339 if (!W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
2340 printf("GetPrinter unexpected return code %s, should "
2341 "be WERR_INSUFFICIENT_BUFFER\n",
2342 win_errstr(r.out.result));
2343 talloc_free(mem_ctx);
2344 return NT_STATUS_UNSUCCESSFUL;
2347 r.in.handle = handle;
2349 blob = data_blob_talloc(mem_ctx, NULL, r.out.needed);
2350 if (blob.data == NULL) {
2351 talloc_free(mem_ctx);
2352 return NT_STATUS_NO_MEMORY;
2354 memset(blob.data, 0, blob.length);
2355 r.in.buffer = &blob;
2356 r.in.offered = r.out.needed;
2358 status = dcerpc_spoolss_GetPrinter(pipe, mem_ctx, &r);
2359 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
2360 d_printf("(%s) dcerpc_spoolss_GetPrinter failed: %s, "
2361 "%s\n", __location__, nt_errstr(status),
2362 win_errstr(r.out.result));
2363 talloc_free(mem_ctx);
2364 return NT_STATUS_IS_OK(status) ?
2365 NT_STATUS_UNSUCCESSFUL : status;
2369 *res = talloc_steal(ctx, r.out.info);
2372 talloc_free(mem_ctx);
2373 return NT_STATUS_OK;
2376 BOOL torture_samba3_rpc_spoolss(struct torture_context *torture)
2378 TALLOC_CTX *mem_ctx;
2380 struct smbcli_state *cli;
2381 struct dcerpc_pipe *p;
2383 struct policy_handle server_handle, printer_handle;
2384 const char **printers;
2386 struct spoolss_UserLevel1 userlevel1;
2389 if (!(mem_ctx = talloc_new(torture))) {
2393 if (!(torture_open_connection_share(
2394 mem_ctx, &cli, torture_setting_string(torture, "host", NULL),
2396 d_printf("IPC$ connection failed\n");
2397 talloc_free(mem_ctx);
2401 status = get_servername(mem_ctx, cli->tree, &servername);
2402 if (!NT_STATUS_IS_OK(status)) {
2403 d_fprintf(stderr, "(%s) get_servername returned %s\n",
2404 __location__, nt_errstr(status));
2405 talloc_free(mem_ctx);
2409 if (!NT_STATUS_IS_OK(find_printers(mem_ctx, cli->tree,
2410 &printers, &num_printers))) {
2411 talloc_free(mem_ctx);
2415 if (num_printers == 0) {
2416 d_printf("Did not find printers\n");
2417 talloc_free(mem_ctx);
2421 status = pipe_bind_smb(mem_ctx, cli->tree, "\\spoolss",
2422 &dcerpc_table_spoolss, &p);
2423 if (!NT_STATUS_IS_OK(status)) {
2424 d_printf("(%s) pipe_bind_smb failed: %s\n", __location__,
2426 talloc_free(mem_ctx);
2430 ZERO_STRUCT(userlevel1);
2431 userlevel1.client = talloc_asprintf(
2432 mem_ctx, "\\\\%s", lp_netbios_name());
2433 userlevel1.user = cli_credentials_get_username(cmdline_credentials);
2434 userlevel1.build = 2600;
2435 userlevel1.major = 3;
2436 userlevel1.minor = 0;
2437 userlevel1.processor = 0;
2440 struct spoolss_OpenPrinterEx r;
2443 r.in.printername = talloc_asprintf(mem_ctx, "\\\\%s",
2445 r.in.datatype = NULL;
2446 r.in.access_mask = 0;
2448 r.in.userlevel.level1 = &userlevel1;
2449 r.out.handle = &server_handle;
2451 status = dcerpc_spoolss_OpenPrinterEx(p, mem_ctx, &r);
2452 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
2453 d_printf("(%s) dcerpc_spoolss_OpenPrinterEx failed: "
2454 "%s, %s\n", __location__, nt_errstr(status),
2455 win_errstr(r.out.result));
2456 talloc_free(mem_ctx);
2462 struct spoolss_ClosePrinter r;
2464 r.in.handle = &server_handle;
2465 r.out.handle = &server_handle;
2467 status = dcerpc_spoolss_ClosePrinter(p, mem_ctx, &r);
2468 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
2469 d_printf("(%s) dcerpc_spoolss_ClosePrinter failed: "
2470 "%s, %s\n", __location__, nt_errstr(status),
2471 win_errstr(r.out.result));
2472 talloc_free(mem_ctx);
2478 struct spoolss_OpenPrinterEx r;
2481 r.in.printername = talloc_asprintf(
2482 mem_ctx, "\\\\%s\\%s", servername, printers[0]);
2483 r.in.datatype = NULL;
2484 r.in.access_mask = 0;
2486 r.in.userlevel.level1 = &userlevel1;
2487 r.out.handle = &printer_handle;
2489 status = dcerpc_spoolss_OpenPrinterEx(p, mem_ctx, &r);
2490 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
2491 d_printf("(%s) dcerpc_spoolss_OpenPrinterEx failed: "
2492 "%s, %s\n", __location__, nt_errstr(status),
2493 win_errstr(r.out.result));
2494 talloc_free(mem_ctx);
2502 for (i=0; i<8; i++) {
2503 status = getprinterinfo(mem_ctx, p, &printer_handle,
2505 if (!NT_STATUS_IS_OK(status)) {
2506 d_printf("(%s) getprinterinfo %d failed: %s\n",
2507 __location__, i, nt_errstr(status));
2514 struct spoolss_ClosePrinter r;
2516 r.in.handle = &printer_handle;
2517 r.out.handle = &printer_handle;
2519 status = dcerpc_spoolss_ClosePrinter(p, mem_ctx, &r);
2520 if (!NT_STATUS_IS_OK(status)) {
2521 d_printf("(%s) dcerpc_spoolss_ClosePrinter failed: "
2522 "%s\n", __location__, nt_errstr(status));
2523 talloc_free(mem_ctx);
2530 if (!enumprinters(mem_ctx, p, servername, 1,
2532 d_printf("(%s) enumprinters failed\n", __location__);
2533 talloc_free(mem_ctx);
2536 if (num_printers != num_enumerated) {
2537 d_printf("(%s) netshareenum gave %d printers, "
2538 "enumprinters lvl 1 gave %d\n", __location__,
2539 num_printers, num_enumerated);
2540 talloc_free(mem_ctx);
2547 if (!enumprinters(mem_ctx, p, servername, 2,
2549 d_printf("(%s) enumprinters failed\n", __location__);
2550 talloc_free(mem_ctx);
2553 if (num_printers != num_enumerated) {
2554 d_printf("(%s) netshareenum gave %d printers, "
2555 "enumprinters lvl 2 gave %d\n", __location__,
2556 num_printers, num_enumerated);
2557 talloc_free(mem_ctx);
2562 talloc_free(mem_ctx);
2567 BOOL torture_samba3_rpc_wkssvc(struct torture_context *torture)
2569 TALLOC_CTX *mem_ctx;
2570 struct smbcli_state *cli;
2571 struct dcerpc_pipe *p;
2575 if (!(mem_ctx = talloc_new(torture))) {
2579 if (!(torture_open_connection_share(
2580 mem_ctx, &cli, torture_setting_string(torture, "host", NULL),
2582 d_printf("IPC$ connection failed\n");
2583 talloc_free(mem_ctx);
2587 status = get_servername(mem_ctx, cli->tree, &servername);
2588 if (!NT_STATUS_IS_OK(status)) {
2589 d_fprintf(stderr, "(%s) get_servername returned %s\n",
2590 __location__, nt_errstr(status));
2591 talloc_free(mem_ctx);
2595 status = pipe_bind_smb(mem_ctx, cli->tree, "\\wkssvc",
2596 &dcerpc_table_wkssvc, &p);
2597 if (!NT_STATUS_IS_OK(status)) {
2598 d_printf("(%s) pipe_bind_smb failed: %s\n", __location__,
2600 talloc_free(mem_ctx);
2605 struct wkssvc_NetWkstaInfo100 wks100;
2606 union wkssvc_NetWkstaInfo info;
2607 struct wkssvc_NetWkstaGetInfo r;
2609 r.in.server_name = "\\foo";
2611 info.info100 = &wks100;
2614 status = dcerpc_wkssvc_NetWkstaGetInfo(p, mem_ctx, &r);
2615 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
2616 d_printf("(%s) dcerpc_wkssvc_NetWksGetInfo failed: "
2617 "%s, %s\n", __location__, nt_errstr(status),
2618 win_errstr(r.out.result));
2619 talloc_free(mem_ctx);
2623 if (strcmp(servername,
2624 r.out.info->info100->server_name) != 0) {
2625 d_printf("(%s) servername inconsistency: RAP=%s, "
2626 "dcerpc_wkssvc_NetWksGetInfo=%s",
2627 __location__, servername,
2628 r.out.info->info100->server_name);
2629 talloc_free(mem_ctx);
2634 talloc_free(mem_ctx);
2638 static NTSTATUS winreg_close(struct dcerpc_pipe *p,
2639 struct policy_handle *handle)
2641 struct winreg_CloseKey c;
2643 TALLOC_CTX *mem_ctx;
2645 c.in.handle = c.out.handle = handle;
2647 if (!(mem_ctx = talloc_new(p))) {
2648 return NT_STATUS_NO_MEMORY;
2651 status = dcerpc_winreg_CloseKey(p, mem_ctx, &c);
2652 talloc_free(mem_ctx);
2654 if (!NT_STATUS_IS_OK(status)) {
2658 if (!W_ERROR_IS_OK(c.out.result)) {
2659 return werror_to_ntstatus(c.out.result);
2662 return NT_STATUS_OK;
2665 static NTSTATUS enumvalues(struct dcerpc_pipe *p, struct policy_handle *handle,
2666 TALLOC_CTX *mem_ctx)
2668 uint32_t enum_index = 0;
2671 struct winreg_EnumValue r;
2672 struct winreg_StringBuf name;
2673 enum winreg_Type type = 0;
2676 uint32_t size, length;
2678 r.in.handle = handle;
2679 r.in.enum_index = enum_index;
2682 r.in.name = r.out.name = &name;
2688 r.in.length = &length;
2690 status = dcerpc_winreg_EnumValue(p, mem_ctx, &r);
2691 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
2692 return NT_STATUS_OK;
2698 static NTSTATUS enumkeys(struct dcerpc_pipe *p, struct policy_handle *handle,
2699 TALLOC_CTX *mem_ctx, int depth)
2701 struct winreg_EnumKey r;
2702 struct winreg_StringBuf class, name;
2707 return NT_STATUS_OK;
2713 r.in.handle = handle;
2714 r.in.enum_index = 0;
2716 r.in.keyclass = &class;
2718 r.in.last_changed_time = &t;
2721 TALLOC_CTX *tmp_ctx;
2722 struct winreg_OpenKey o;
2723 struct policy_handle key_handle;
2726 if (!(tmp_ctx = talloc_new(mem_ctx))) {
2727 return NT_STATUS_NO_MEMORY;
2733 status = dcerpc_winreg_EnumKey(p, tmp_ctx, &r);
2734 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
2735 /* We're done enumerating */
2736 talloc_free(tmp_ctx);
2737 return NT_STATUS_OK;
2740 for (i=0; i<10-depth; i++)
2742 printf("%s\n", r.out.name->name);
2745 o.in.parent_handle = handle;
2746 o.in.keyname.name = r.out.name->name;
2748 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2749 o.out.handle = &key_handle;
2751 status = dcerpc_winreg_OpenKey(p, tmp_ctx, &o);
2752 if (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(o.out.result)) {
2753 enumkeys(p, &key_handle, tmp_ctx, depth-1);
2754 enumvalues(p, &key_handle, tmp_ctx);
2755 status = winreg_close(p, &key_handle);
2756 if (!NT_STATUS_IS_OK(status)) {
2761 talloc_free(tmp_ctx);
2763 r.in.enum_index += 1;
2766 return NT_STATUS_OK;
2769 typedef NTSTATUS (*winreg_open_fn)(struct dcerpc_pipe *, TALLOC_CTX *, void *);
2771 static BOOL test_Open3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2772 const char *name, winreg_open_fn open_fn)
2774 struct policy_handle handle;
2775 struct winreg_OpenHKLM r;
2778 r.in.system_name = 0;
2779 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2780 r.out.handle = &handle;
2782 status = open_fn(p, mem_ctx, &r);
2783 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
2784 d_printf("(%s) %s failed: %s, %s\n", __location__, name,
2785 nt_errstr(status), win_errstr(r.out.result));
2789 enumkeys(p, &handle, mem_ctx, 4);
2791 status = winreg_close(p, &handle);
2792 if (!NT_STATUS_IS_OK(status)) {
2793 d_printf("(%s) dcerpc_CloseKey failed: %s\n",
2794 __location__, nt_errstr(status));
2801 BOOL torture_samba3_rpc_winreg(struct torture_context *torture)
2804 struct dcerpc_pipe *p;
2805 TALLOC_CTX *mem_ctx;
2811 {"OpenHKLM", (winreg_open_fn)dcerpc_winreg_OpenHKLM },
2812 {"OpenHKU", (winreg_open_fn)dcerpc_winreg_OpenHKU },
2813 {"OpenHKPD", (winreg_open_fn)dcerpc_winreg_OpenHKPD },
2814 {"OpenHKPT", (winreg_open_fn)dcerpc_winreg_OpenHKPT },
2815 {"OpenHKCR", (winreg_open_fn)dcerpc_winreg_OpenHKCR }};
2820 mem_ctx = talloc_init("torture_rpc_winreg");
2822 status = torture_rpc_connection(mem_ctx, &p, &dcerpc_table_winreg);
2824 if (!NT_STATUS_IS_OK(status)) {
2825 talloc_free(mem_ctx);
2830 ret = test_Open3(p, mem_ctx, open_fns[0].name, open_fns[0].fn);
2832 for (i = 0; i < ARRAY_SIZE(open_fns); i++) {
2833 if (!test_Open3(p, mem_ctx, open_fns[i].name, open_fns[i].fn))
2838 talloc_free(mem_ctx);