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->conn, 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->conn, 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->conn, 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->conn, 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->conn, 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->conn, 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 failed - %s\n", nt_errstr(status));
1463 talloc_free(tmp_ctx);
1467 result = dom_sid_add_rid(mem_ctx, l.out.domains->domains[0].sid,
1468 l.out.sids->sids[0].rid);
1470 c.in.handle = &handle;
1471 c.out.handle = &handle;
1473 status = dcerpc_lsa_Close(p, tmp_ctx, &c);
1474 if (!NT_STATUS_IS_OK(status)) {
1475 printf("dcerpc_lsa_Close failed - %s\n", nt_errstr(status));
1476 talloc_free(tmp_ctx);
1480 talloc_free(tmp_ctx);
1485 * Find out the user SID on this connection
1488 static struct dom_sid *whoami(TALLOC_CTX *mem_ctx, struct smbcli_tree *tree)
1490 struct dcerpc_pipe *lsa;
1491 struct lsa_GetUserName r;
1493 struct lsa_StringPointer authority_name_p;
1494 struct dom_sid *result;
1496 status = pipe_bind_smb(mem_ctx, tree, "\\pipe\\lsarpc",
1497 &dcerpc_table_lsarpc, &lsa);
1498 if (!NT_STATUS_IS_OK(status)) {
1499 d_printf("(%s) Could not bind to LSA: %s\n",
1500 __location__, nt_errstr(status));
1504 r.in.system_name = "\\";
1505 r.in.account_name = NULL;
1506 authority_name_p.string = NULL;
1507 r.in.authority_name = &authority_name_p;
1509 status = dcerpc_lsa_GetUserName(lsa, mem_ctx, &r);
1511 if (!NT_STATUS_IS_OK(status)) {
1512 printf("(%s) GetUserName failed - %s\n",
1513 __location__, nt_errstr(status));
1518 result = name2sid(mem_ctx, lsa, r.out.account_name->string,
1519 r.out.authority_name->string->string);
1526 * Do a tcon, given a session
1529 NTSTATUS secondary_tcon(TALLOC_CTX *mem_ctx,
1530 struct smbcli_session *session,
1531 const char *sharename,
1532 struct smbcli_tree **res)
1534 struct smbcli_tree *result;
1535 TALLOC_CTX *tmp_ctx;
1536 union smb_tcon tcon;
1539 if (!(tmp_ctx = talloc_new(mem_ctx))) {
1540 return NT_STATUS_NO_MEMORY;
1543 if (!(result = smbcli_tree_init(session, mem_ctx, False))) {
1544 talloc_free(tmp_ctx);
1545 return NT_STATUS_NO_MEMORY;
1548 tcon.generic.level = RAW_TCON_TCONX;
1549 tcon.tconx.in.flags = 0;
1550 tcon.tconx.in.password = data_blob(NULL, 0);
1551 tcon.tconx.in.path = sharename;
1552 tcon.tconx.in.device = "?????";
1554 status = smb_raw_tcon(result, tmp_ctx, &tcon);
1555 if (!NT_STATUS_IS_OK(status)) {
1556 d_printf("(%s) smb_raw_tcon failed: %s\n", __location__,
1558 talloc_free(tmp_ctx);
1562 result->tid = tcon.tconx.out.tid;
1563 result = talloc_steal(mem_ctx, result);
1564 talloc_free(tmp_ctx);
1566 return NT_STATUS_OK;
1570 * Test the getusername behaviour
1573 BOOL torture_samba3_rpc_getusername(struct torture_context *torture)
1576 struct smbcli_state *cli;
1577 TALLOC_CTX *mem_ctx;
1579 struct dom_sid *user_sid;
1580 struct dom_sid *created_sid;
1581 struct cli_credentials *anon_creds;
1582 struct cli_credentials *user_creds;
1585 if (!(mem_ctx = talloc_new(torture))) {
1589 status = smbcli_full_connection(
1590 mem_ctx, &cli, torture_setting_string(torture, "host", NULL),
1591 "IPC$", NULL, cmdline_credentials, NULL);
1592 if (!NT_STATUS_IS_OK(status)) {
1593 d_printf("(%s) smbcli_full_connection failed: %s\n",
1594 __location__, nt_errstr(status));
1599 if (!(user_sid = whoami(mem_ctx, cli->tree))) {
1600 d_printf("(%s) whoami on auth'ed connection failed\n",
1607 if (!(anon_creds = create_anon_creds(mem_ctx))) {
1608 d_printf("(%s) create_anon_creds failed\n", __location__);
1613 status = smbcli_full_connection(
1614 mem_ctx, &cli, torture_setting_string(torture, "host", NULL),
1615 "IPC$", NULL, anon_creds, NULL);
1616 if (!NT_STATUS_IS_OK(status)) {
1617 d_printf("(%s) anon smbcli_full_connection failed: %s\n",
1618 __location__, nt_errstr(status));
1623 if (!(user_sid = whoami(mem_ctx, cli->tree))) {
1624 d_printf("(%s) whoami on anon connection failed\n",
1630 if (!dom_sid_equal(user_sid,
1631 dom_sid_parse_talloc(mem_ctx, "s-1-5-7"))) {
1632 d_printf("(%s) Anon lsa_GetUserName returned %s, expected "
1633 "S-1-5-7", __location__,
1634 dom_sid_string(mem_ctx, user_sid));
1638 if (!(user_creds = cli_credentials_init(mem_ctx))) {
1639 d_printf("(%s) cli_credentials_init failed\n", __location__);
1644 cli_credentials_set_conf(user_creds);
1645 cli_credentials_set_username(user_creds, "torture_username",
1647 cli_credentials_set_password(user_creds,
1648 generate_random_str(user_creds, 8),
1651 if (!create_user(mem_ctx, cli, cmdline_credentials,
1652 cli_credentials_get_username(user_creds),
1653 cli_credentials_get_password(user_creds),
1654 &domain_name, &created_sid)) {
1655 d_printf("(%s) create_user failed\n", __location__);
1660 cli_credentials_set_domain(user_creds, domain_name,
1664 struct smbcli_session *session2;
1665 struct smb_composite_sesssetup setup;
1666 struct smbcli_tree *tree;
1668 session2 = smbcli_session_init(cli->transport, mem_ctx, False);
1669 if (session2 == NULL) {
1670 d_printf("(%s) smbcli_session_init failed\n",
1675 setup.in.sesskey = cli->transport->negotiate.sesskey;
1676 setup.in.capabilities = cli->transport->negotiate.capabilities;
1677 setup.in.workgroup = "";
1678 setup.in.credentials = user_creds;
1680 status = smb_composite_sesssetup(session2, &setup);
1681 if (!NT_STATUS_IS_OK(status)) {
1682 d_printf("(%s) session setup with new user failed: "
1683 "%s\n", __location__, nt_errstr(status));
1687 session2->vuid = setup.out.vuid;
1689 if (!NT_STATUS_IS_OK(secondary_tcon(mem_ctx, session2,
1691 d_printf("(%s) secondary_tcon failed\n",
1697 if (!(user_sid = whoami(mem_ctx, tree))) {
1698 d_printf("(%s) whoami on user connection failed\n",
1707 d_printf("Created %s, found %s\n",
1708 dom_sid_string(mem_ctx, created_sid),
1709 dom_sid_string(mem_ctx, user_sid));
1711 if (!dom_sid_equal(created_sid, user_sid)) {
1716 if (!delete_user(cli, cmdline_credentials,
1717 cli_credentials_get_username(user_creds))) {
1718 d_printf("(%s) delete_user failed\n", __location__);
1723 talloc_free(mem_ctx);
1727 static BOOL test_NetShareGetInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1728 const char *sharename)
1731 struct srvsvc_NetShareGetInfo r;
1732 uint32_t levels[] = { 0, 1, 2, 501, 502, 1004, 1005, 1006, 1007, 1501 };
1736 r.in.server_unc = talloc_asprintf(mem_ctx, "\\\\%s",
1737 dcerpc_server_name(p));
1738 r.in.share_name = sharename;
1740 for (i=0;i<ARRAY_SIZE(levels);i++) {
1741 r.in.level = levels[i];
1745 printf("testing NetShareGetInfo level %u on share '%s'\n",
1746 r.in.level, r.in.share_name);
1748 status = dcerpc_srvsvc_NetShareGetInfo(p, mem_ctx, &r);
1749 if (!NT_STATUS_IS_OK(status)) {
1750 printf("NetShareGetInfo level %u on share '%s' failed"
1751 " - %s\n", r.in.level, r.in.share_name,
1756 if (!W_ERROR_IS_OK(r.out.result)) {
1757 printf("NetShareGetInfo level %u on share '%s' failed "
1758 "- %s\n", r.in.level, r.in.share_name,
1759 win_errstr(r.out.result));
1768 static BOOL test_NetShareEnum(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1769 const char **one_sharename)
1772 struct srvsvc_NetShareEnum r;
1773 struct srvsvc_NetShareCtr0 c0;
1774 uint32_t levels[] = { 0, 1, 2, 501, 502, 1004, 1005, 1006, 1007 };
1778 r.in.server_unc = talloc_asprintf(mem_ctx,"\\\\%s",dcerpc_server_name(p));
1779 r.in.ctr.ctr0 = &c0;
1780 r.in.ctr.ctr0->count = 0;
1781 r.in.ctr.ctr0->array = NULL;
1782 r.in.max_buffer = (uint32_t)-1;
1783 r.in.resume_handle = NULL;
1785 for (i=0;i<ARRAY_SIZE(levels);i++) {
1786 r.in.level = levels[i];
1790 printf("testing NetShareEnum level %u\n", r.in.level);
1791 status = dcerpc_srvsvc_NetShareEnum(p, mem_ctx, &r);
1792 if (!NT_STATUS_IS_OK(status)) {
1793 printf("NetShareEnum level %u failed - %s\n",
1794 r.in.level, nt_errstr(status));
1798 if (!W_ERROR_IS_OK(r.out.result)) {
1799 printf("NetShareEnum level %u failed - %s\n",
1800 r.in.level, win_errstr(r.out.result));
1803 if (r.in.level == 0) {
1804 struct srvsvc_NetShareCtr0 *ctr = r.out.ctr.ctr0;
1805 if (ctr->count > 0) {
1806 *one_sharename = ctr->array[0].name;
1814 BOOL torture_samba3_rpc_srvsvc(struct torture_context *torture)
1816 struct dcerpc_pipe *p;
1817 TALLOC_CTX *mem_ctx;
1819 const char *sharename = NULL;
1820 struct smbcli_state *cli;
1823 if (!(mem_ctx = talloc_new(torture))) {
1827 if (!(torture_open_connection_share(
1828 mem_ctx, &cli, torture_setting_string(torture, "host", NULL),
1830 talloc_free(mem_ctx);
1834 status = pipe_bind_smb(mem_ctx, cli->tree, "\\pipe\\srvsvc",
1835 &dcerpc_table_srvsvc, &p);
1836 if (!NT_STATUS_IS_OK(status)) {
1837 d_printf("(%s) could not bind to srvsvc pipe: %s\n",
1838 __location__, nt_errstr(status));
1843 ret &= test_NetShareEnum(p, mem_ctx, &sharename);
1844 if (sharename == NULL) {
1845 printf("did not get sharename\n");
1847 ret &= test_NetShareGetInfo(p, mem_ctx, sharename);
1851 talloc_free(mem_ctx);
1855 static struct security_descriptor *get_sharesec(TALLOC_CTX *mem_ctx,
1856 struct smbcli_session *sess,
1857 const char *sharename)
1859 struct smbcli_tree *tree;
1860 TALLOC_CTX *tmp_ctx;
1861 struct dcerpc_pipe *p;
1863 struct srvsvc_NetShareGetInfo r;
1864 struct security_descriptor *result;
1866 if (!(tmp_ctx = talloc_new(mem_ctx))) {
1867 d_printf("talloc_new failed\n");
1871 if (!NT_STATUS_IS_OK(secondary_tcon(tmp_ctx, sess, "IPC$", &tree))) {
1872 d_printf("secondary_tcon failed\n");
1873 talloc_free(tmp_ctx);
1877 status = pipe_bind_smb(mem_ctx, tree, "\\pipe\\srvsvc",
1878 &dcerpc_table_srvsvc, &p);
1879 if (!NT_STATUS_IS_OK(status)) {
1880 d_printf("(%s) could not bind to srvsvc pipe: %s\n",
1881 __location__, nt_errstr(status));
1882 talloc_free(tmp_ctx);
1887 p->conn->flags |= DCERPC_DEBUG_PRINT_IN | DCERPC_DEBUG_PRINT_OUT;
1890 r.in.server_unc = talloc_asprintf(tmp_ctx, "\\\\%s",
1891 dcerpc_server_name(p));
1892 r.in.share_name = sharename;
1895 status = dcerpc_srvsvc_NetShareGetInfo(p, tmp_ctx, &r);
1896 if (!NT_STATUS_IS_OK(status)) {
1897 d_printf("srvsvc_NetShareGetInfo failed: %s\n",
1899 talloc_free(tmp_ctx);
1903 result = talloc_steal(mem_ctx, r.out.info.info502->sd);
1904 talloc_free(tmp_ctx);
1908 static NTSTATUS set_sharesec(TALLOC_CTX *mem_ctx,
1909 struct smbcli_session *sess,
1910 const char *sharename,
1911 struct security_descriptor *sd)
1913 struct smbcli_tree *tree;
1914 TALLOC_CTX *tmp_ctx;
1915 struct dcerpc_pipe *p;
1917 struct sec_desc_buf i;
1918 struct srvsvc_NetShareSetInfo r;
1921 if (!(tmp_ctx = talloc_new(mem_ctx))) {
1922 d_printf("talloc_new failed\n");
1923 return NT_STATUS_NO_MEMORY;
1926 if (!NT_STATUS_IS_OK(secondary_tcon(tmp_ctx, sess, "IPC$", &tree))) {
1927 d_printf("secondary_tcon failed\n");
1928 talloc_free(tmp_ctx);
1929 return NT_STATUS_UNSUCCESSFUL;
1932 status = pipe_bind_smb(mem_ctx, tree, "\\pipe\\srvsvc",
1933 &dcerpc_table_srvsvc, &p);
1934 if (!NT_STATUS_IS_OK(status)) {
1935 d_printf("(%s) could not bind to srvsvc pipe: %s\n",
1936 __location__, nt_errstr(status));
1937 talloc_free(tmp_ctx);
1938 return NT_STATUS_UNSUCCESSFUL;
1942 p->conn->flags |= DCERPC_DEBUG_PRINT_IN | DCERPC_DEBUG_PRINT_OUT;
1945 r.in.server_unc = talloc_asprintf(tmp_ctx, "\\\\%s",
1946 dcerpc_server_name(p));
1947 r.in.share_name = sharename;
1950 r.in.info.info1501 = &i;
1951 r.in.parm_error = &error;
1953 status = dcerpc_srvsvc_NetShareSetInfo(p, tmp_ctx, &r);
1954 if (!NT_STATUS_IS_OK(status)) {
1955 d_printf("srvsvc_NetShareGetInfo failed: %s\n",
1959 talloc_free(tmp_ctx);
1963 BOOL try_tcon(TALLOC_CTX *mem_ctx,
1964 struct security_descriptor *orig_sd,
1965 struct smbcli_session *session,
1966 const char *sharename, const struct dom_sid *user_sid,
1967 unsigned int access_mask, NTSTATUS expected_tcon,
1968 NTSTATUS expected_mkdir)
1970 TALLOC_CTX *tmp_ctx;
1971 struct smbcli_tree *rmdir_tree, *tree;
1972 struct dom_sid *domain_sid;
1974 struct security_descriptor *sd;
1978 if (!(tmp_ctx = talloc_new(mem_ctx))) {
1979 d_printf("talloc_new failed\n");
1983 status = secondary_tcon(tmp_ctx, session, sharename, &rmdir_tree);
1984 if (!NT_STATUS_IS_OK(status)) {
1985 d_printf("first tcon to delete dir failed\n");
1986 talloc_free(tmp_ctx);
1990 smbcli_rmdir(rmdir_tree, "sharesec_testdir");
1992 if (!NT_STATUS_IS_OK(dom_sid_split_rid(tmp_ctx, user_sid,
1993 &domain_sid, &rid))) {
1994 d_printf("dom_sid_split_rid failed\n");
1995 talloc_free(tmp_ctx);
1999 sd = security_descriptor_create(
2000 tmp_ctx, "S-1-5-32-544",
2001 dom_sid_string(mem_ctx, dom_sid_add_rid(mem_ctx, domain_sid,
2003 dom_sid_string(mem_ctx, user_sid),
2004 SEC_ACE_TYPE_ACCESS_ALLOWED, access_mask, 0, NULL);
2006 d_printf("security_descriptor_create failed\n");
2007 talloc_free(tmp_ctx);
2011 status = set_sharesec(mem_ctx, session, sharename, sd);
2012 if (!NT_STATUS_IS_OK(status)) {
2013 d_printf("custom set_sharesec failed: %s\n",
2015 talloc_free(tmp_ctx);
2019 status = secondary_tcon(tmp_ctx, session, sharename, &tree);
2020 if (!NT_STATUS_EQUAL(status, expected_tcon)) {
2021 d_printf("Expected %s, got %s\n", nt_errstr(expected_tcon),
2027 if (!NT_STATUS_IS_OK(status)) {
2028 /* An expected non-access, no point in trying to write */
2032 status = smbcli_mkdir(tree, "sharesec_testdir");
2033 if (!NT_STATUS_EQUAL(status, expected_mkdir)) {
2034 d_printf("Expected %s, got %s\n", nt_errstr(expected_mkdir),
2040 smbcli_rmdir(rmdir_tree, "sharesec_testdir");
2042 status = set_sharesec(mem_ctx, session, sharename, orig_sd);
2043 if (!NT_STATUS_IS_OK(status)) {
2044 d_printf("custom set_sharesec failed: %s\n",
2046 talloc_free(tmp_ctx);
2050 talloc_free(tmp_ctx);
2054 BOOL torture_samba3_rpc_sharesec(struct torture_context *torture)
2056 TALLOC_CTX *mem_ctx;
2058 struct smbcli_state *cli;
2059 struct security_descriptor *sd;
2060 struct dom_sid *user_sid;
2062 if (!(mem_ctx = talloc_new(torture))) {
2066 if (!(torture_open_connection_share(
2067 mem_ctx, &cli, torture_setting_string(torture, "host", NULL),
2069 d_printf("IPC$ connection failed\n");
2070 talloc_free(mem_ctx);
2074 if (!(user_sid = whoami(mem_ctx, cli->tree))) {
2075 d_printf("whoami failed\n");
2076 talloc_free(mem_ctx);
2080 sd = get_sharesec(mem_ctx, cli->session, torture_setting_string(torture,
2083 ret &= try_tcon(mem_ctx, sd, cli->session,
2084 torture_setting_string(torture, "share", NULL),
2085 user_sid, 0, NT_STATUS_ACCESS_DENIED, NT_STATUS_OK);
2087 ret &= try_tcon(mem_ctx, sd, cli->session,
2088 torture_setting_string(torture, "share", NULL),
2089 user_sid, SEC_FILE_READ_DATA, NT_STATUS_OK,
2090 NT_STATUS_NETWORK_ACCESS_DENIED);
2092 ret &= try_tcon(mem_ctx, sd, cli->session,
2093 torture_setting_string(torture, "share", NULL),
2094 user_sid, SEC_FILE_ALL, NT_STATUS_OK, NT_STATUS_OK);
2096 talloc_free(mem_ctx);
2100 BOOL torture_samba3_rpc_lsa(struct torture_context *torture)
2102 TALLOC_CTX *mem_ctx;
2104 struct smbcli_state *cli;
2105 struct dcerpc_pipe *p;
2106 struct policy_handle lsa_handle;
2108 struct dom_sid *domain_sid;
2110 if (!(mem_ctx = talloc_new(torture))) {
2114 if (!(torture_open_connection_share(
2115 mem_ctx, &cli, torture_setting_string(torture, "host", NULL),
2117 d_printf("IPC$ connection failed\n");
2118 talloc_free(mem_ctx);
2122 status = pipe_bind_smb(mem_ctx, cli->tree, "\\lsarpc",
2123 &dcerpc_table_lsarpc, &p);
2124 if (!NT_STATUS_IS_OK(status)) {
2125 d_printf("(%s) pipe_bind_smb failed: %s\n", __location__,
2127 talloc_free(mem_ctx);
2132 struct lsa_ObjectAttribute attr;
2133 struct lsa_OpenPolicy2 o;
2134 o.in.system_name = talloc_asprintf(
2135 mem_ctx, "\\\\%s", dcerpc_server_name(p));
2138 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2139 o.out.handle = &lsa_handle;
2140 status = dcerpc_lsa_OpenPolicy2(p, mem_ctx, &o);
2141 if (!NT_STATUS_IS_OK(status)) {
2142 d_printf("(%s) dcerpc_lsa_OpenPolicy2 failed: %s\n",
2143 __location__, nt_errstr(status));
2144 talloc_free(mem_ctx);
2150 p->conn->flags |= DCERPC_DEBUG_PRINT_IN | DCERPC_DEBUG_PRINT_OUT;
2155 int levels[] = { 2,3,5,6 };
2157 for (i=0; i<ARRAY_SIZE(levels); i++) {
2158 struct lsa_QueryInfoPolicy r;
2159 r.in.handle = &lsa_handle;
2160 r.in.level = levels[i];
2161 status = dcerpc_lsa_QueryInfoPolicy(p, mem_ctx, &r);
2162 if (!NT_STATUS_IS_OK(status)) {
2163 d_printf("(%s) dcerpc_lsa_QueryInfoPolicy %d "
2164 "failed: %s\n", __location__,
2165 levels[i], nt_errstr(status));
2166 talloc_free(mem_ctx);
2169 if (levels[i] == 5) {
2170 domain_sid = r.out.info->account_domain.sid;
2178 static NTSTATUS get_servername(TALLOC_CTX *mem_ctx, struct smbcli_tree *tree,
2181 struct rap_WserverGetInfo r;
2183 char servername[17];
2186 r.in.bufsize = 0xffff;
2188 status = smbcli_rap_netservergetinfo(tree, mem_ctx, &r);
2189 if (!NT_STATUS_IS_OK(status)) {
2193 memcpy(servername, r.out.info.info0.name, 16);
2194 servername[16] = '\0';
2196 if (pull_ascii_talloc(mem_ctx, name, servername) < 0) {
2197 return NT_STATUS_NO_MEMORY;
2200 return NT_STATUS_OK;
2204 static NTSTATUS find_printers(TALLOC_CTX *ctx, struct smbcli_tree *tree,
2205 const char ***printers, int *num_printers)
2207 TALLOC_CTX *mem_ctx;
2209 struct dcerpc_pipe *p;
2210 struct srvsvc_NetShareEnum r;
2211 struct srvsvc_NetShareCtr1 c1_in;
2212 struct srvsvc_NetShareCtr1 *c1;
2215 mem_ctx = talloc_new(ctx);
2216 if (mem_ctx == NULL) {
2217 return NT_STATUS_NO_MEMORY;
2220 status = pipe_bind_smb(mem_ctx, tree, "\\srvsvc", &dcerpc_table_srvsvc,
2222 if (!NT_STATUS_IS_OK(status)) {
2223 d_printf("could not bind to srvsvc pipe\n");
2224 talloc_free(mem_ctx);
2228 r.in.server_unc = talloc_asprintf(
2229 mem_ctx, "\\\\%s", dcerpc_server_name(p));
2232 r.in.ctr.ctr1 = &c1_in;
2233 r.in.max_buffer = (uint32_t)-1;
2234 r.in.resume_handle = NULL;
2236 status = dcerpc_srvsvc_NetShareEnum(p, mem_ctx, &r);
2237 if (!NT_STATUS_IS_OK(status)) {
2238 d_printf("NetShareEnum level %u failed - %s\n",
2239 r.in.level, nt_errstr(status));
2240 talloc_free(mem_ctx);
2246 c1 = r.out.ctr.ctr1;
2247 for (i=0; i<c1->count; i++) {
2248 if (c1->array[i].type != STYPE_PRINTQ) {
2251 if (!add_string_to_array(ctx, c1->array[i].name,
2252 printers, num_printers)) {
2254 return NT_STATUS_NO_MEMORY;
2258 talloc_free(mem_ctx);
2259 return NT_STATUS_OK;
2262 static BOOL enumprinters(TALLOC_CTX *mem_ctx, struct dcerpc_pipe *pipe,
2263 const char *servername, int level, int *num_printers)
2265 struct spoolss_EnumPrinters r;
2269 r.in.flags = PRINTER_ENUM_LOCAL;
2270 r.in.server = talloc_asprintf(mem_ctx, "\\\\%s", servername);
2275 status = dcerpc_spoolss_EnumPrinters(pipe, mem_ctx, &r);
2276 if (!NT_STATUS_IS_OK(status)) {
2277 d_printf("(%s) dcerpc_spoolss_EnumPrinters failed: %s\n",
2278 __location__, nt_errstr(status));
2282 if (!W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
2283 d_printf("(%s) EnumPrinters unexpected return code %s, should "
2284 "be WERR_INSUFFICIENT_BUFFER\n", __location__,
2285 win_errstr(r.out.result));
2289 blob = data_blob_talloc(mem_ctx, NULL, r.out.needed);
2290 if (blob.data == NULL) {
2291 d_printf("(%s) data_blob_talloc failed\n", __location__);
2295 r.in.buffer = &blob;
2296 r.in.offered = r.out.needed;
2298 status = dcerpc_spoolss_EnumPrinters(pipe, mem_ctx, &r);
2299 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
2300 d_printf("(%s) dcerpc_spoolss_EnumPrinters failed: %s, "
2301 "%s\n", __location__, nt_errstr(status),
2302 win_errstr(r.out.result));
2306 *num_printers = r.out.count;
2311 static NTSTATUS getprinterinfo(TALLOC_CTX *ctx, struct dcerpc_pipe *pipe,
2312 struct policy_handle *handle, int level,
2313 union spoolss_PrinterInfo **res)
2315 TALLOC_CTX *mem_ctx;
2316 struct spoolss_GetPrinter r;
2320 mem_ctx = talloc_new(ctx);
2321 if (mem_ctx == NULL) {
2322 return NT_STATUS_NO_MEMORY;
2325 r.in.handle = handle;
2330 status = dcerpc_spoolss_GetPrinter(pipe, mem_ctx, &r);
2331 if (!NT_STATUS_IS_OK(status)) {
2332 d_printf("(%s) dcerpc_spoolss_GetPrinter failed: %s\n",
2333 __location__, nt_errstr(status));
2334 talloc_free(mem_ctx);
2338 if (!W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
2339 printf("GetPrinter unexpected return code %s, should "
2340 "be WERR_INSUFFICIENT_BUFFER\n",
2341 win_errstr(r.out.result));
2342 talloc_free(mem_ctx);
2343 return NT_STATUS_UNSUCCESSFUL;
2346 r.in.handle = handle;
2348 blob = data_blob_talloc(mem_ctx, NULL, r.out.needed);
2349 if (blob.data == NULL) {
2350 talloc_free(mem_ctx);
2351 return NT_STATUS_NO_MEMORY;
2353 memset(blob.data, 0, blob.length);
2354 r.in.buffer = &blob;
2355 r.in.offered = r.out.needed;
2357 status = dcerpc_spoolss_GetPrinter(pipe, mem_ctx, &r);
2358 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
2359 d_printf("(%s) dcerpc_spoolss_GetPrinter failed: %s, "
2360 "%s\n", __location__, nt_errstr(status),
2361 win_errstr(r.out.result));
2362 talloc_free(mem_ctx);
2363 return NT_STATUS_IS_OK(status) ?
2364 NT_STATUS_UNSUCCESSFUL : status;
2368 *res = talloc_steal(ctx, r.out.info);
2371 talloc_free(mem_ctx);
2372 return NT_STATUS_OK;
2375 BOOL torture_samba3_rpc_spoolss(struct torture_context *torture)
2377 TALLOC_CTX *mem_ctx;
2379 struct smbcli_state *cli;
2380 struct dcerpc_pipe *p;
2382 struct policy_handle server_handle, printer_handle;
2383 const char **printers;
2385 struct spoolss_UserLevel1 userlevel1;
2388 if (!(mem_ctx = talloc_new(torture))) {
2392 if (!(torture_open_connection_share(
2393 mem_ctx, &cli, torture_setting_string(torture, "host", NULL),
2395 d_printf("IPC$ connection failed\n");
2396 talloc_free(mem_ctx);
2400 status = get_servername(mem_ctx, cli->tree, &servername);
2401 if (!NT_STATUS_IS_OK(status)) {
2402 d_fprintf(stderr, "(%s) get_servername returned %s\n",
2403 __location__, nt_errstr(status));
2404 talloc_free(mem_ctx);
2408 if (!NT_STATUS_IS_OK(find_printers(mem_ctx, cli->tree,
2409 &printers, &num_printers))) {
2410 talloc_free(mem_ctx);
2414 if (num_printers == 0) {
2415 d_printf("Did not find printers\n");
2416 talloc_free(mem_ctx);
2420 status = pipe_bind_smb(mem_ctx, cli->tree, "\\spoolss",
2421 &dcerpc_table_spoolss, &p);
2422 if (!NT_STATUS_IS_OK(status)) {
2423 d_printf("(%s) pipe_bind_smb failed: %s\n", __location__,
2425 talloc_free(mem_ctx);
2429 ZERO_STRUCT(userlevel1);
2430 userlevel1.client = talloc_asprintf(
2431 mem_ctx, "\\\\%s", lp_netbios_name());
2432 userlevel1.user = cli_credentials_get_username(cmdline_credentials);
2433 userlevel1.build = 2600;
2434 userlevel1.major = 3;
2435 userlevel1.minor = 0;
2436 userlevel1.processor = 0;
2439 struct spoolss_OpenPrinterEx r;
2442 r.in.printername = talloc_asprintf(mem_ctx, "\\\\%s",
2444 r.in.datatype = NULL;
2445 r.in.access_mask = 0;
2447 r.in.userlevel.level1 = &userlevel1;
2448 r.out.handle = &server_handle;
2450 status = dcerpc_spoolss_OpenPrinterEx(p, mem_ctx, &r);
2451 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
2452 d_printf("(%s) dcerpc_spoolss_OpenPrinterEx failed: "
2453 "%s, %s\n", __location__, nt_errstr(status),
2454 win_errstr(r.out.result));
2455 talloc_free(mem_ctx);
2461 struct spoolss_ClosePrinter r;
2463 r.in.handle = &server_handle;
2464 r.out.handle = &server_handle;
2466 status = dcerpc_spoolss_ClosePrinter(p, mem_ctx, &r);
2467 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
2468 d_printf("(%s) dcerpc_spoolss_ClosePrinter failed: "
2469 "%s, %s\n", __location__, nt_errstr(status),
2470 win_errstr(r.out.result));
2471 talloc_free(mem_ctx);
2477 struct spoolss_OpenPrinterEx r;
2480 r.in.printername = talloc_asprintf(
2481 mem_ctx, "\\\\%s\\%s", servername, printers[0]);
2482 r.in.datatype = NULL;
2483 r.in.access_mask = 0;
2485 r.in.userlevel.level1 = &userlevel1;
2486 r.out.handle = &printer_handle;
2488 status = dcerpc_spoolss_OpenPrinterEx(p, mem_ctx, &r);
2489 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
2490 d_printf("(%s) dcerpc_spoolss_OpenPrinterEx failed: "
2491 "%s, %s\n", __location__, nt_errstr(status),
2492 win_errstr(r.out.result));
2493 talloc_free(mem_ctx);
2501 for (i=0; i<8; i++) {
2502 status = getprinterinfo(mem_ctx, p, &printer_handle,
2504 if (!NT_STATUS_IS_OK(status)) {
2505 d_printf("(%s) getprinterinfo %d failed: %s\n",
2506 __location__, i, nt_errstr(status));
2513 struct spoolss_ClosePrinter r;
2515 r.in.handle = &printer_handle;
2516 r.out.handle = &printer_handle;
2518 status = dcerpc_spoolss_ClosePrinter(p, mem_ctx, &r);
2519 if (!NT_STATUS_IS_OK(status)) {
2520 d_printf("(%s) dcerpc_spoolss_ClosePrinter failed: "
2521 "%s\n", __location__, nt_errstr(status));
2522 talloc_free(mem_ctx);
2529 if (!enumprinters(mem_ctx, p, servername, 1,
2531 d_printf("(%s) enumprinters failed\n", __location__);
2532 talloc_free(mem_ctx);
2535 if (num_printers != num_enumerated) {
2536 d_printf("(%s) netshareenum gave %d printers, "
2537 "enumprinters lvl 1 gave %d\n", __location__,
2538 num_printers, num_enumerated);
2539 talloc_free(mem_ctx);
2546 if (!enumprinters(mem_ctx, p, servername, 2,
2548 d_printf("(%s) enumprinters failed\n", __location__);
2549 talloc_free(mem_ctx);
2552 if (num_printers != num_enumerated) {
2553 d_printf("(%s) netshareenum gave %d printers, "
2554 "enumprinters lvl 2 gave %d\n", __location__,
2555 num_printers, num_enumerated);
2556 talloc_free(mem_ctx);
2561 talloc_free(mem_ctx);
2566 BOOL torture_samba3_rpc_wkssvc(struct torture_context *torture)
2568 TALLOC_CTX *mem_ctx;
2569 struct smbcli_state *cli;
2570 struct dcerpc_pipe *p;
2574 if (!(mem_ctx = talloc_new(torture))) {
2578 if (!(torture_open_connection_share(
2579 mem_ctx, &cli, torture_setting_string(torture, "host", NULL),
2581 d_printf("IPC$ connection failed\n");
2582 talloc_free(mem_ctx);
2586 status = get_servername(mem_ctx, cli->tree, &servername);
2587 if (!NT_STATUS_IS_OK(status)) {
2588 d_fprintf(stderr, "(%s) get_servername returned %s\n",
2589 __location__, nt_errstr(status));
2590 talloc_free(mem_ctx);
2594 status = pipe_bind_smb(mem_ctx, cli->tree, "\\wkssvc",
2595 &dcerpc_table_wkssvc, &p);
2596 if (!NT_STATUS_IS_OK(status)) {
2597 d_printf("(%s) pipe_bind_smb failed: %s\n", __location__,
2599 talloc_free(mem_ctx);
2604 struct wkssvc_NetWkstaInfo100 wks100;
2605 union wkssvc_NetWkstaInfo info;
2606 struct wkssvc_NetWkstaGetInfo r;
2608 r.in.server_name = "\\foo";
2610 info.info100 = &wks100;
2613 status = dcerpc_wkssvc_NetWkstaGetInfo(p, mem_ctx, &r);
2614 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
2615 d_printf("(%s) dcerpc_wkssvc_NetWksGetInfo failed: "
2616 "%s, %s\n", __location__, nt_errstr(status),
2617 win_errstr(r.out.result));
2618 talloc_free(mem_ctx);
2622 if (strcmp(servername,
2623 r.out.info->info100->server_name) != 0) {
2624 d_printf("(%s) servername inconsistency: RAP=%s, "
2625 "dcerpc_wkssvc_NetWksGetInfo=%s",
2626 __location__, servername,
2627 r.out.info->info100->server_name);
2628 talloc_free(mem_ctx);
2633 talloc_free(mem_ctx);
2637 static NTSTATUS winreg_close(struct dcerpc_pipe *p,
2638 struct policy_handle *handle)
2640 struct winreg_CloseKey c;
2642 TALLOC_CTX *mem_ctx;
2644 c.in.handle = c.out.handle = handle;
2646 if (!(mem_ctx = talloc_new(p))) {
2647 return NT_STATUS_NO_MEMORY;
2650 status = dcerpc_winreg_CloseKey(p, mem_ctx, &c);
2651 talloc_free(mem_ctx);
2653 if (!NT_STATUS_IS_OK(status)) {
2657 if (!W_ERROR_IS_OK(c.out.result)) {
2658 return werror_to_ntstatus(c.out.result);
2661 return NT_STATUS_OK;
2664 static NTSTATUS enumvalues(struct dcerpc_pipe *p, struct policy_handle *handle,
2665 TALLOC_CTX *mem_ctx)
2667 uint32_t enum_index = 0;
2670 struct winreg_EnumValue r;
2671 struct winreg_StringBuf name;
2672 enum winreg_Type type = 0;
2675 uint32_t size, length;
2677 r.in.handle = handle;
2678 r.in.enum_index = enum_index;
2681 r.in.name = r.out.name = &name;
2687 r.in.length = &length;
2689 status = dcerpc_winreg_EnumValue(p, mem_ctx, &r);
2690 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
2691 return NT_STATUS_OK;
2697 static NTSTATUS enumkeys(struct dcerpc_pipe *p, struct policy_handle *handle,
2698 TALLOC_CTX *mem_ctx, int depth)
2700 struct winreg_EnumKey r;
2701 struct winreg_StringBuf class, name;
2706 return NT_STATUS_OK;
2712 r.in.handle = handle;
2713 r.in.enum_index = 0;
2715 r.in.keyclass = &class;
2717 r.in.last_changed_time = &t;
2720 TALLOC_CTX *tmp_ctx;
2721 struct winreg_OpenKey o;
2722 struct policy_handle key_handle;
2725 if (!(tmp_ctx = talloc_new(mem_ctx))) {
2726 return NT_STATUS_NO_MEMORY;
2732 status = dcerpc_winreg_EnumKey(p, tmp_ctx, &r);
2733 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
2734 /* We're done enumerating */
2735 talloc_free(tmp_ctx);
2736 return NT_STATUS_OK;
2739 for (i=0; i<10-depth; i++)
2741 printf("%s\n", r.out.name->name);
2744 o.in.parent_handle = handle;
2745 o.in.keyname.name = r.out.name->name;
2747 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2748 o.out.handle = &key_handle;
2750 status = dcerpc_winreg_OpenKey(p, tmp_ctx, &o);
2751 if (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(o.out.result)) {
2752 enumkeys(p, &key_handle, tmp_ctx, depth-1);
2753 enumvalues(p, &key_handle, tmp_ctx);
2754 status = winreg_close(p, &key_handle);
2755 if (!NT_STATUS_IS_OK(status)) {
2760 talloc_free(tmp_ctx);
2762 r.in.enum_index += 1;
2765 return NT_STATUS_OK;
2768 typedef NTSTATUS (*winreg_open_fn)(struct dcerpc_pipe *, TALLOC_CTX *, void *);
2770 static BOOL test_Open3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2771 const char *name, winreg_open_fn open_fn)
2773 struct policy_handle handle;
2774 struct winreg_OpenHKLM r;
2777 r.in.system_name = 0;
2778 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2779 r.out.handle = &handle;
2781 status = open_fn(p, mem_ctx, &r);
2782 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
2783 d_printf("(%s) %s failed: %s, %s\n", __location__, name,
2784 nt_errstr(status), win_errstr(r.out.result));
2788 enumkeys(p, &handle, mem_ctx, 4);
2790 status = winreg_close(p, &handle);
2791 if (!NT_STATUS_IS_OK(status)) {
2792 d_printf("(%s) dcerpc_CloseKey failed: %s\n",
2793 __location__, nt_errstr(status));
2800 BOOL torture_samba3_rpc_winreg(struct torture_context *torture)
2803 struct dcerpc_pipe *p;
2804 TALLOC_CTX *mem_ctx;
2810 {"OpenHKLM", (winreg_open_fn)dcerpc_winreg_OpenHKLM },
2811 {"OpenHKU", (winreg_open_fn)dcerpc_winreg_OpenHKU },
2812 {"OpenHKPD", (winreg_open_fn)dcerpc_winreg_OpenHKPD },
2813 {"OpenHKPT", (winreg_open_fn)dcerpc_winreg_OpenHKPT },
2814 {"OpenHKCR", (winreg_open_fn)dcerpc_winreg_OpenHKCR }};
2819 mem_ctx = talloc_init("torture_rpc_winreg");
2821 status = torture_rpc_connection(mem_ctx, &p, &dcerpc_table_winreg);
2823 if (!NT_STATUS_IS_OK(status)) {
2824 talloc_free(mem_ctx);
2829 ret = test_Open3(p, mem_ctx, open_fns[0].name, open_fns[0].fn);
2831 for (i = 0; i < ARRAY_SIZE(open_fns); i++) {
2832 if (!test_Open3(p, mem_ctx, open_fns[i].name, open_fns[i].fn))
2837 talloc_free(mem_ctx);