The Samba-Bugzilla – Attachment 12189 Details for
Bug 11983
samba-4.0 only: share-ACLs won't restrict users in changing file-ACLs
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
recreate this bug
0001-torture-recreate-a-share-security-issue-for-samba-4.patch (text/plain), 13.34 KB, created by
Peter Somogyi
on 2016-06-20 12:57:41 UTC
(
hide
)
Description:
recreate this bug
Filename:
MIME Type:
Creator:
Peter Somogyi
Created:
2016-06-20 12:57:41 UTC
Size:
13.34 KB
patch
obsolete
>From f6aaa61a47d343144e9e10500bd4606d39d3ce68 Mon Sep 17 00:00:00 2001 >From: Peter Somogyi <psomogyi@hu.ibm.com> >Date: Tue, 14 Jun 2016 17:48:59 +0200 >Subject: [PATCH] [SIGNED-OFF] torture: recreate a share security issue for samba-4.0 > > >Signed-off-by: Peter Somogyi <psomogyi@hu.ibm.com> >--- > source4/torture/rpc/samba3rpc.c | 369 ++++++++++++++++++++++++++++++++++++++- > 1 files changed, 367 insertions(+), 2 deletions(-) > >diff --git a/source4/torture/rpc/samba3rpc.c b/source4/torture/rpc/samba3rpc.c >index 9da6b54..6141489 100644 >--- a/source4/torture/rpc/samba3rpc.c >+++ b/source4/torture/rpc/samba3rpc.c >@@ -2176,13 +2176,18 @@ static struct security_descriptor *get_sharesec(struct torture_context *tctx, > struct srvsvc_NetShareGetInfo r; > union srvsvc_NetShareInfo info; > struct security_descriptor *result; >+ char *path_ipc; > > if (!(tmp_ctx = talloc_new(mem_ctx))) { > torture_comment(tctx, "talloc_new failed\n"); > return NULL; > } > >- if (!NT_STATUS_IS_OK(secondary_tcon(tctx, tmp_ctx, sess, "IPC$", &tree))) { >+ /* Win 2012 works only when host or IP given as a prefix */ >+ path_ipc = talloc_asprintf(tctx, "\\\\%s\\IPC$", >+ torture_setting_string(tctx, "host", NULL)); >+ if (!NT_STATUS_IS_OK(secondary_tcon(tctx, tmp_ctx, >+ sess, path_ipc, &tree))) { > torture_comment(tctx, "secondary_tcon failed\n"); > talloc_free(tmp_ctx); > return NULL; >@@ -2241,6 +2246,7 @@ static NTSTATUS set_sharesec(struct torture_context *tctx, > struct sec_desc_buf i; > struct srvsvc_NetShareSetInfo r; > union srvsvc_NetShareInfo info; >+ char *path_ipc; > uint32_t error = 0; > > if (!(tmp_ctx = talloc_new(mem_ctx))) { >@@ -2248,7 +2254,10 @@ static NTSTATUS set_sharesec(struct torture_context *tctx, > return NT_STATUS_NO_MEMORY; > } > >- if (!NT_STATUS_IS_OK(secondary_tcon(tctx, tmp_ctx, sess, "IPC$", &tree))) { >+ path_ipc = talloc_asprintf(tctx, "\\\\%s\\IPC$", >+ torture_setting_string(tctx, "host", NULL)); >+ >+ if (!NT_STATUS_IS_OK(secondary_tcon(tctx, tmp_ctx, sess, path_ipc, &tree))) { > torture_comment(tctx, "secondary_tcon failed\n"); > talloc_free(tmp_ctx); > return NT_STATUS_UNSUCCESSFUL; >@@ -2517,6 +2526,361 @@ static bool torture_samba3_rpc_sharesec(struct torture_context *torture) > return true; > } > >+ >+static NTSTATUS torture_open_connection2(struct torture_context *tctx, >+ struct smbcli_state **cli, >+ struct cli_credentials *credentials) >+{ >+ NTSTATUS status; >+ struct smbcli_options options; >+ struct smbcli_session_options session_options; >+ >+ lpcfg_smbcli_options(tctx->lp_ctx, &options); >+ lpcfg_smbcli_session_options(tctx->lp_ctx, &session_options); >+ >+ status = smbcli_full_connection(tctx, >+ cli, >+ torture_setting_string(tctx, "host", NULL), >+ lpcfg_smb_ports(tctx->lp_ctx), >+ torture_setting_string(tctx, "share", NULL), >+ NULL, >+ lpcfg_socket_options(tctx->lp_ctx), >+ credentials, >+ lpcfg_resolve_context(tctx->lp_ctx), >+ tctx->ev, &options, &session_options, >+ lpcfg_gensec_settings(tctx, tctx->lp_ctx)); >+ if (!NT_STATUS_IS_OK(status)) { >+ printf("Failed to open connection - %s\n", nt_errstr(status)); >+ } >+ return status; >+} >+ >+static NTSTATUS torture_open_connection_smb2(struct torture_context *tctx, >+ struct smb2_tree **tree, >+ struct cli_credentials *credentials) >+{ >+ struct smbcli_options options; >+ >+ lpcfg_smbcli_options(tctx->lp_ctx, &options); >+ >+ return smb2_connect(tctx, >+ torture_setting_string(tctx, "host", NULL), >+ lpcfg_smb_ports(tctx->lp_ctx), >+ torture_setting_string(tctx, "share", NULL), >+ lpcfg_resolve_context(tctx->lp_ctx), >+ credentials, >+ tree, >+ tctx->ev, >+ &options, >+ lpcfg_socket_options(tctx->lp_ctx), >+ lpcfg_gensec_settings(tctx, tctx->lp_ctx) >+ ); >+} >+ >+static NTSTATUS set_sharesec2(struct torture_context *tctx, >+ TALLOC_CTX *mem_ctx, >+ struct smbcli_state *cli_admin, >+ const char *username, >+ uint32_t access_mask) >+{ >+ struct security_descriptor *sd = NULL; >+ >+ sd = security_descriptor_dacl_create( >+ mem_ctx, 0, NULL, NULL, SID_WORLD, >+ SEC_ACE_TYPE_ACCESS_ALLOWED, access_mask, 0, NULL); >+ if (sd == NULL) { >+ torture_comment(tctx, "security_descriptor_dacl_create " >+ "failed\n"); >+ return NT_STATUS_NO_MEMORY; >+ } >+ >+ return set_sharesec(tctx, mem_ctx, >+ cli_admin->session, >+ torture_setting_string(tctx, "share", NULL), >+ sd); >+} >+ >+static bool try_sharesec_setacl(struct torture_context *tctx, >+ TALLOC_CTX *mem_ctx, >+ struct smb2_tree *tree, >+ struct smb2_handle handle, >+ bool expect_setacl) >+{ >+ union smb_setfileinfo set; >+ NTSTATUS status; >+ >+ torture_comment(tctx, "try to set ACL allow everything" >+ "for users\n"); >+ >+ set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC; >+ set.set_secdesc.in.file.handle = handle; >+ set.set_secdesc.in.secinfo_flags = SECINFO_DACL; >+ >+ set.set_secdesc.in.sd = security_descriptor_dacl_create(mem_ctx, >+ 0, NULL, NULL, >+ SID_NT_AUTHENTICATED_USERS, >+ SEC_ACE_TYPE_ACCESS_ALLOWED, >+ SEC_GENERIC_ALL, >+ 0, >+ NULL); >+ >+ status = smb2_setinfo_file(tree, &set); >+ if (expect_setacl) { >+ if (!NT_STATUS_EQUAL(status, NT_STATUS_OK)) { >+ torture_comment(tctx, >+ "expected setacl to succeed but " >+ "failed with %s\n", >+ nt_errstr(status)); >+ } >+ } else { >+ if (!NT_STATUS_EQUAL(status, NT_STATUS_MEDIA_WRITE_PROTECTED) >+ && !NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) { >+ torture_comment(tctx, >+ "expected setacl to fail but succeeded!\n"); >+ return false; >+ } >+ } >+ >+ return true; >+} >+ >+static bool try_sharesec_createfile_setacl(struct torture_context *tctx, >+ TALLOC_CTX *mem_ctx, >+ struct smb2_tree *tree, >+ const char *fname, >+ uint32_t desired_access, >+ bool expect_open, >+ bool try_setacl, bool expect_setacl) >+{ >+ struct smb2_create io; >+ struct smb2_handle handle; >+ NTSTATUS status; >+ bool result = true; >+ >+ ZERO_STRUCT(io); >+ io.level = RAW_OPEN_SMB2; >+ io.in.create_flags = 0; >+ io.in.desired_access = desired_access; >+ io.in.create_options = 0; >+ io.in.file_attributes = FILE_ATTRIBUTE_NORMAL; >+ io.in.share_access = 0; >+ io.in.alloc_size = 0; >+ io.in.create_disposition = NTCREATEX_DISP_OPEN_IF; >+ io.in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS; >+ io.in.security_flags = 0; >+ io.in.fname = fname; >+ >+ torture_comment(tctx, "create(%s, 0x%.8x)\n", fname, desired_access); >+ status = smb2_create(tree, mem_ctx, &io); >+ if (expect_open) { >+ torture_assert_ntstatus_ok(tctx, status, "try smb2_create"); >+ handle = io.out.file.handle; >+ >+ if (try_setacl) { >+ result = try_sharesec_setacl(tctx, mem_ctx, tree, >+ handle, expect_setacl); >+ } >+ >+ smb2_util_close(tree, handle); >+ >+ } else { >+ if (!NT_STATUS_EQUAL(status, NT_STATUS_MEDIA_WRITE_PROTECTED) >+ && !NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) >+ { >+ torture_comment(tctx, "expected open to be denied " >+ "but result is %s !\n", >+ nt_errstr(status)); >+ return false; >+ } >+ >+ if (try_setacl) { >+ torture_comment(tctx, "invalid scene\n"); >+ return false; >+ } >+ } >+ >+ >+ return result; >+} >+ >+/* >+ * This scenario tests whether a share-ACL is effectively denying setting ACLs >+ * found as a samba-4.0 only bug (till todays samba-4.3 present) >+ */ >+static bool torture_samba3_rpc_sharesec2(struct torture_context *tctx) >+{ >+ struct smbcli_state *cli_admin = NULL; >+ struct smb2_tree *tree_testuser = NULL; >+ struct cli_credentials *test_credentials = NULL; >+ const char *test_username = NULL; >+ const char *test_password = NULL; >+ const char *fname = "testfile.txt"; >+ int fail_cnt = 0; >+ NTSTATUS status; >+ TALLOC_CTX *mem_ctx = NULL; >+ struct security_descriptor *sd_orig = NULL; >+ bool result = false; >+ uint32_t desired_access; >+ >+ torture_comment(tctx, "Init...\n"); >+ >+ if (!(mem_ctx = talloc_new(mem_ctx))) { >+ torture_comment(tctx, "talloc_new failed\n"); >+ return false; >+ } >+ >+ test_username = torture_setting_string(tctx, "extra_user1", NULL); >+ torture_assert(tctx, (test_username != NULL), >+ "extra_user1 torture param missing"); >+ test_password = torture_setting_string(tctx, "extra_password1", NULL); >+ torture_assert(tctx, (test_password != NULL), >+ "extra_password1 torture param missing"); >+ >+ test_credentials = cli_credentials_init(tctx); >+ cli_credentials_set_workstation(test_credentials, >+ "localhost", CRED_SPECIFIED); >+ cli_credentials_set_domain(test_credentials, >+ lpcfg_workgroup(tctx->lp_ctx), >+ CRED_SPECIFIED); >+ cli_credentials_set_username(test_credentials, test_username, >+ CRED_SPECIFIED); >+ cli_credentials_set_password(test_credentials, test_password, >+ CRED_SPECIFIED); >+ >+ status = torture_open_connection2(tctx, &cli_admin, >+ cmdline_credentials); >+ torture_assert_ntstatus_ok_goto(tctx, status, result, done, >+ "connection#admin failed"); >+ >+ status = smbcli_unlink(cli_admin->tree, fname); >+ if (!NT_STATUS_EQUAL(status, NT_STATUS_OK) && >+ !NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND) && >+ !NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { >+ torture_comment(tctx, "failed to cleanup %s (%s)\n", >+ fname, nt_errstr(status)); >+ goto done; >+ } >+ >+ sd_orig = get_sharesec(tctx, mem_ctx, cli_admin->session, >+ torture_setting_string(tctx, "share", NULL)); >+ if (sd_orig == NULL) { >+ torture_comment(tctx, "failed to get original sd\n"); >+ goto done; >+ } >+ >+ torture_comment(tctx, "Set sharesec to \"FULL\"\n"); >+ status = set_sharesec2(tctx, mem_ctx, cli_admin, test_username, >+ SEC_RIGHTS_FILE_ALL); >+ torture_assert_ntstatus_ok_goto(tctx, status, result, done, >+ "set_sharesec failed!"); >+ >+ torture_comment(tctx, "Test that user can open file as RW" >+ " + can setacl - while sharesec is \"FULL\"\n"); >+ >+ status = torture_open_connection_smb2(tctx, &tree_testuser, >+ test_credentials); >+ torture_assert_ntstatus_ok_goto(tctx, status, result, done, >+ "open connection for testuser#1"); >+ >+ if (!try_sharesec_createfile_setacl(tctx, mem_ctx, tree_testuser, >+ fname, >+ SEC_STD_READ_CONTROL | >+ SEC_FILE_WRITE_DATA | >+ SEC_STD_WRITE_DAC, >+ true, >+ true, true)) { >+ torture_comment(tctx, "RW test FAILED\n"); >+ fail_cnt++; >+ } >+ >+ talloc_free(tree_testuser); >+ >+ torture_comment(tctx, "Set sharesec to \"READ\"\n"); >+ status = set_sharesec2(tctx, mem_ctx, cli_admin, test_username, >+ SEC_RIGHTS_DIR_READ|SEC_DIR_TRAVERSE); >+ torture_assert_ntstatus_ok_goto(tctx, status, result, done, >+ "set_sharesec failed!"); >+ >+ status = torture_open_connection_smb2(tctx, &tree_testuser, >+ test_credentials); >+ torture_assert_ntstatus_ok_goto(tctx, status, result, done, >+ "open connection for testuser#2"); >+ >+ torture_comment(tctx, "Test that user can't write\n"); >+ if (!try_sharesec_createfile_setacl(tctx, mem_ctx, tree_testuser, >+ fname, >+ SEC_FILE_WRITE_DATA, false, >+ false, false)) { >+ torture_comment(tctx, "RO test FAILED\n"); >+ fail_cnt++; >+ } >+ >+ talloc_free(tree_testuser); >+ >+ torture_comment(tctx, "Set sharesec to \"CHANGE\"" >+ " (= no setacl allowed)\n"); >+ status = set_sharesec2(tctx, mem_ctx, >+ cli_admin, >+ test_username, >+ SEC_RIGHTS_DIR_READ|SEC_STD_DELETE| >+ SEC_RIGHTS_DIR_WRITE|SEC_DIR_TRAVERSE); >+ torture_assert_ntstatus_ok_goto(tctx, status, result, done, >+ "set_sharesec failed!"); >+ >+ status = torture_open_connection_smb2(tctx, &tree_testuser, >+ test_credentials); >+ torture_assert_ntstatus_ok_goto(tctx, status, result, done, >+ "open connection for testuser"); >+ >+ torture_comment(tctx, "Test that user can't set acl\n"); >+ if (!try_sharesec_createfile_setacl(tctx, mem_ctx, tree_testuser, >+ fname, >+ SEC_STD_READ_CONTROL | >+ SEC_FILE_WRITE_DATA | >+ SEC_STD_WRITE_DAC, >+ false, >+ false, false)) { >+ torture_comment(tctx, "WRITE_DAC#1 test FAILED\n"); >+ fail_cnt++; >+ } >+ >+ torture_comment(tctx, "Test that user can'tctx set acl after " >+ "opened without desired flags\n"); >+ if (!try_sharesec_createfile_setacl(tctx, mem_ctx, tree_testuser, >+ fname, >+ SEC_STD_READ_CONTROL | >+ SEC_FILE_WRITE_DATA, >+ true, >+ true, false)) { >+ torture_comment(tctx, "WRITE_DAC#2 test FAILED\n"); >+ fail_cnt++; >+ } >+ >+ torture_comment(tctx, "Fail counter: %d\n", fail_cnt); >+ result = (fail_cnt==0) ? true : false; >+ >+done: >+ if (cli_admin!=NULL) { >+ if (sd_orig != NULL) { >+ status = set_sharesec(tctx, mem_ctx, >+ cli_admin->session, >+ torture_setting_string(tctx, >+ "share", >+ NULL), >+ sd_orig); >+ if (!NT_STATUS_EQUAL(status, NT_STATUS_OK)) { >+ torture_comment(tctx, >+ "failed to restore sd_orig\n"); >+ } >+ } >+ talloc_free(cli_admin); >+ } >+ talloc_free(tree_testuser); >+ talloc_free(mem_ctx); >+ >+ return result; >+} >+ > static bool torture_samba3_rpc_lsa(struct torture_context *torture) > { > struct dcerpc_pipe *p; >@@ -4544,6 +4908,7 @@ struct torture_suite *torture_rpc_samba3(TALLOC_CTX *mem_ctx) > torture_suite_add_simple_test(suite, "sessionkey", torture_samba3_sessionkey); > torture_suite_add_simple_test(suite, "srvsvc", torture_samba3_rpc_srvsvc); > torture_suite_add_simple_test(suite, "sharesec", torture_samba3_rpc_sharesec); >+ torture_suite_add_simple_test(suite, "sharesec2", torture_samba3_rpc_sharesec2); > torture_suite_add_simple_test(suite, "getusername", torture_samba3_rpc_getusername); > torture_suite_add_simple_test(suite, "randomauth2", torture_samba3_rpc_randomauth2); > torture_suite_add_simple_test(suite, "lsa", torture_samba3_rpc_lsa); >-- >1.7.1 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 11983
:
12188
| 12189