From 28883b2ba088726a18def0942f9f9cb35f29a451 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 9 Oct 2015 15:08:05 -0700 Subject: [PATCH 1/2] lib: cli: Add accessor function smb2cli_tcon_flags() to get tcon flags. https://bugzilla.samba.org/show_bug.cgi?id=10252 Signed-off-by: Jeremy Allison --- libcli/smb/smbXcli_base.c | 5 +++++ libcli/smb/smbXcli_base.h | 1 + 2 files changed, 6 insertions(+) diff --git a/libcli/smb/smbXcli_base.c b/libcli/smb/smbXcli_base.c index c1e9e58..6fe4816 100644 --- a/libcli/smb/smbXcli_base.c +++ b/libcli/smb/smbXcli_base.c @@ -5991,6 +5991,11 @@ uint32_t smb2cli_tcon_capabilities(struct smbXcli_tcon *tcon) return tcon->smb2.capabilities; } +uint32_t smb2cli_tcon_flags(struct smbXcli_tcon *tcon) +{ + return tcon->smb2.flags; +} + void smb2cli_tcon_set_values(struct smbXcli_tcon *tcon, struct smbXcli_session *session, uint32_t tcon_id, diff --git a/libcli/smb/smbXcli_base.h b/libcli/smb/smbXcli_base.h index cf93135..e4cfb10 100644 --- a/libcli/smb/smbXcli_base.h +++ b/libcli/smb/smbXcli_base.h @@ -442,6 +442,7 @@ bool smb1cli_tcon_set_values(struct smbXcli_tcon *tcon, const char *fs_type); uint32_t smb2cli_tcon_current_id(struct smbXcli_tcon *tcon); uint32_t smb2cli_tcon_capabilities(struct smbXcli_tcon *tcon); +uint32_t smb2cli_tcon_flags(struct smbXcli_tcon *tcon); void smb2cli_tcon_set_values(struct smbXcli_tcon *tcon, struct smbXcli_session *session, uint32_t tcon_id, -- 2.6.0.rc2.230.g3dd15c0 From 0095908a307a45c4b6f422317101520eea52428e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 9 Oct 2015 15:08:59 -0700 Subject: [PATCH 2/2] s4: torture: SMB2 test for access-based enumeration. https://bugzilla.samba.org/show_bug.cgi?id=10252 Signed-off-by: Jeremy Allison --- source4/torture/smb2/acls.c | 164 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 164 insertions(+) diff --git a/source4/torture/smb2/acls.c b/source4/torture/smb2/acls.c index 37052c6..9e3951b 100644 --- a/source4/torture/smb2/acls.c +++ b/source4/torture/smb2/acls.c @@ -22,6 +22,7 @@ #include "includes.h" #include "libcli/smb2/smb2.h" #include "libcli/smb2/smb2_calls.h" +#include "libcli/smb/smbXcli_base.h" #include "torture/torture.h" #include "torture/util.h" #include "torture/smb2/proto.h" @@ -1855,6 +1856,168 @@ done: } #endif +static bool test_access_based(struct torture_context *tctx, + struct smb2_tree *tree) +{ + NTSTATUS status; + struct smb2_create io; + const char *fname = BASEDIR "\\testfile"; + bool ret = true; + struct smb2_handle fhandle, dhandle; + union smb_fileinfo q; + union smb_setfileinfo set; + struct security_descriptor *sd, *sd_orig=NULL; + const char *owner_sid; + uint32_t flags = smb2cli_tcon_flags(tree->smbXcli); + /* + * Can't test without SEC_STD_READ_CONTROL as we + * own the file and implicitly have SEC_STD_READ_CONTROL. + */ + uint32_t access_masks[] = { + /* Full READ access. */ + SEC_STD_READ_CONTROL|FILE_READ_DATA| + FILE_READ_ATTRIBUTES|FILE_READ_EA, + + /* Missing FILE_READ_EA. */ + SEC_STD_READ_CONTROL|FILE_READ_DATA| + FILE_READ_ATTRIBUTES, + + /* Missing FILE_READ_ATTRIBUTES. */ + SEC_STD_READ_CONTROL|FILE_READ_DATA| + FILE_READ_EA, + + /* Missing FILE_READ_DATA. */ + SEC_STD_READ_CONTROL| + FILE_READ_ATTRIBUTES|FILE_READ_EA, + }; + unsigned int i; + unsigned int count; + struct smb2_find f; + union smb_search_data *d; + + ZERO_STRUCT(fhandle); + ZERO_STRUCT(dhandle); + + smb2_util_unlink(tree, fname); + smb2_deltree(tree, BASEDIR); + + torture_comment(tctx, "TESTING ACCESS BASED ENUMERATION\n"); + + if ((flags & SMB2_SHAREFLAG_ACCESS_BASED_DIRECTORY_ENUM)==0) { + torture_comment(tctx, "No access enumeration on this share\n"); + return true; + } + + if (!smb2_util_setup_dir(tctx, tree, BASEDIR)) { + torture_result(tctx, TORTURE_FAIL, "(%s) Unable to setup %s\n", + __location__, BASEDIR); + ret = false; + goto done; + } + + /* Get a handle to the BASEDIR directory. */ + status = torture_smb2_testdir(tree, BASEDIR, &dhandle); + CHECK_STATUS(status, NT_STATUS_OK); + + ZERO_STRUCT(io); + io.level = RAW_OPEN_SMB2; + io.in.create_flags = 0; + io.in.desired_access = SEC_RIGHTS_FILE_ALL; + 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_CREATE; + io.in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS; + io.in.security_flags = 0; + io.in.fname = fname; + + status = smb2_create(tree, tctx, &io); + CHECK_STATUS(status, NT_STATUS_OK); + fhandle = io.out.file.handle; + + torture_comment(tctx, "get the original sd\n"); + q.query_secdesc.level = RAW_FILEINFO_SEC_DESC; + q.query_secdesc.in.file.handle = fhandle; + q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER; + status = smb2_getinfo_file(tree, tctx, &q); + CHECK_STATUS(status, NT_STATUS_OK); + sd_orig = q.query_secdesc.out.sd; + + owner_sid = dom_sid_string(tctx, sd_orig->owner_sid); + + torture_comment(tctx, "owner_sid is %s\n", owner_sid); + + /* Setup for the search. */ + ZERO_STRUCT(f); + f.in.file.handle = dhandle; + f.in.pattern = "testfile"; + f.in.continue_flags = 0; + f.in.max_response_size = 0x100; + f.in.level = SMB2_FIND_DIRECTORY_INFO; + + for (i = 0; i < ARRAY_SIZE(access_masks); i++) { + + sd = security_descriptor_dacl_create(tctx, + 0, NULL, NULL, + owner_sid, + SEC_ACE_TYPE_ACCESS_ALLOWED, + access_masks[i], + 0, + NULL); + + set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC; + set.set_secdesc.in.file.handle = fhandle; + set.set_secdesc.in.secinfo_flags = SECINFO_DACL; + set.set_secdesc.in.sd = sd; + status = smb2_setinfo_file(tree, &set); + CHECK_STATUS(status, NT_STATUS_OK); + + /* Now see if we can see the file in a directory listing. */ + + count = 0; + d = NULL; + status = smb2_find_level(tree, tree, &f, &count, &d); + TALLOC_FREE(d); + + if (i == 0) { + /* We should see the first sd. */ + CHECK_STATUS(status, NT_STATUS_OK); + if (count != 1) { + torture_result(tctx, TORTURE_FAIL, + "(%s) Normal SD - Unable " + "to see file %s\n", + __location__, + BASEDIR); + ret = false; + goto done; + } + } else { + /* But no others. */ + CHECK_STATUS(status, STATUS_NO_MORE_FILES); + if (count != 0) { + torture_result(tctx, TORTURE_FAIL, + "(%s) SD 0x%x - can " + "see file %s\n", + __location__, + access_masks[i], + BASEDIR); + ret = false; + goto done; + } + } + } + +done: + smb2_util_close(tree, fhandle); + smb2_util_close(tree, dhandle); + smb2_util_unlink(tree, fname); + smb2_deltree(tree, BASEDIR); + smb2_tdis(tree); + smb2_logoff(tree->session); + return ret; +} + /* basic testing of SMB2 ACLs */ @@ -1872,6 +2035,7 @@ struct torture_suite *torture_smb2_acls_init(void) /* XXX This test does not work against XP or Vista. */ torture_suite_add_1smb2_test(suite, "GETSET", test_sd_get_set); #endif + torture_suite_add_1smb2_test(suite, "ACCESSBASED", test_access_based); suite->description = talloc_strdup(suite, "SMB2-ACLS tests"); -- 2.6.0.rc2.230.g3dd15c0