smb2.acls.ownerrights failure
Jeremy Allison
jra at samba.org
Fri Nov 18 18:58:36 UTC 2016
On Fri, Nov 18, 2016 at 06:21:58PM +0530, Shilpa K wrote:
> Hello,
>
> We have a smbtorture test smb2.acls.onwerrights for testing for permissions
> for owner SID. Test case is given below. In one scenario, owner is denied
> WRITE_DAC and the administrator has full access. I am executing the test
> using administrator credentials. In one instance, create request is sent
> with access_mask SEC_RIGHTS_FILE_READ while the owner is denied WRITE_DAC.
> In Samba 4.5, this test case fails. Upon some investigation, I found the
> issue to be in:
Quick question - does your test case below work against a
Windows server ? If so what version of Windows did you test ?
Thanks,
Jeremy.
> /* The owner always gets owner rights as defined above. */
> if (security_token_has_sid(token, sd->owner_sid)) {
> if (owner_rights_default) {
> /*
> * Just remove them, no need to check if they are
> * there.
> */
> bits_remaining &= ~(SEC_STD_WRITE_DAC |
> SEC_STD_READ_CONTROL);
> } else {
> bits_remaining &= ~owner_rights_allowed;
> bits_remaining |= owner_rights_denied; ---> issue here
> }
> }
>
> Because I am executing the test administrator, bits_remaining becomes 0
> until the above code path is reached. At the following line, bits_remaining
> becomes 0x40000:
>
> bits_remaining |= owner_rights_denied;
>
> And following message is logged in the Samba log file:
>
> [2016/11/18 03:22:44.464327, 10, pid=9742, effective(586678772, 586678784),
> real(0, 0)] ../source3/smbd/open.c:168(smbd_check_access_rights)
> smbd_check_access_rights: file smb2-testsd/inheritance requesting 0x10000
> returning 0x40000 (NT_STATUS_ACCESS_DENIED)
>
> If I change the above code to below line, this issue is resolved:
>
> bits_remaining |= (owner_rights_denied & access_desired);
>
>
> Can you comment on the above fix?
>
> Thanks,
> Shilpa
>
> -----------------------------------------------------------------------------------------------------------------------------------
>
> /*
> test dynamic acl inheritance
> Note: This test was copied from raw/acls.c.
> */
> static bool test_owner_rights(struct torture_context *tctx,
> struct smb2_tree *tree)
> {
> NTSTATUS status;
> struct smb2_create io;
> const char *dname = BASEDIR "\\inheritance";
> const char *fname1 = BASEDIR "\\inheritance\\testfile";
> bool ret = true;
> struct smb2_handle handle, handle2;
> union smb_fileinfo q;
> union smb_setfileinfo set;
> struct security_descriptor *sd, *sd_orig=NULL;
> const char *owner_sid;
> const char *owner_rights_sid = "S-1-3-4";
>
> torture_comment(tctx, "TESTING DYNAMIC ACL INHERITANCE\n");
>
> if (!smb2_util_setup_dir(tctx, tree, BASEDIR))
> return false;
>
> 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 = NTCREATEX_OPTIONS_DIRECTORY;
> io.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
> 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 = dname;
>
> status = smb2_create(tree, tctx, &io);
> CHECK_STATUS(status, NT_STATUS_OK);
> handle = 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 = handle;
> 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);
> int i = 0;
> const struct {
> uint32_t owner_flags;
> uint32_t owner_rights;
> } test_perm[] = {
> {
> 0,
> 0
> },
> {
> SEC_ACE_TYPE_ACCESS_ALLOWED,
> SEC_STD_WRITE_DAC | SEC_STD_READ_CONTROL,
> },
> {
> SEC_ACE_TYPE_ACCESS_ALLOWED,
> SEC_STD_WRITE_DAC,
> },
> {
> SEC_ACE_TYPE_ACCESS_DENIED,
> SEC_STD_WRITE_DAC,
> },
> };
> for (i=0;i<ARRAY_SIZE(test_perm);i++) {
> sd = security_descriptor_dacl_create(tctx,
> 0, NULL, NULL,
> owner_rights_sid,
> test_perm[i].owner_flags,
> test_perm[i].owner_rights,
> 0,
> owner_sid,
> SEC_ACE_TYPE_ACCESS_ALLOWED,
> SEC_RIGHTS_FILE_ALL,
> 0,
> NULL);
> //sd->type |= SEC_DESC_DACL_AUTO_INHERITED |
> SEC_DESC_DACL_AUTO_INHERIT_REQ;
>
> 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 = sd;
> status = smb2_setinfo_file(tree, &set);
> printf("Iteration is %d\n", i);
> CHECK_STATUS(status, NT_STATUS_OK);
>
> q.query_secdesc.in.file.handle = handle;
> q.query_secdesc.in.secinfo_flags = SECINFO_DACL;
> status = smb2_getinfo_file(tree, tctx, &q);
> if (test_perm[i].owner_rights & (SEC_STD_WRITE_DAC |
> SEC_STD_READ_CONTROL)) {
> CHECK_STATUS(status, NT_STATUS_OK);
> } else if (test_perm[i].owner_rights & SEC_STD_WRITE_DAC) {
> CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
> }
>
> if((test_perm[i].owner_flags & SEC_ACE_TYPE_ACCESS_DENIED))
> {
> smb2_util_close(tree, handle);
> io.in.desired_access = 0x00020080;
> io.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
> status = smb2_create(tree, tctx, &io);
> CHECK_STATUS(status, NT_STATUS_OK);
> handle = io.out.file.handle;
>
> sd = q.query_secdesc.out.sd;
> sd->dacl->aces[1].access_mask =
> SEC_RIGHTS_FILE_READ;
> 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 = sd;
> status = smb2_setinfo_file(tree, &set);
> CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
> }
>
> }
> done:
> torture_comment(tctx, "put back original sd\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 = sd_orig;
> status = smb2_setinfo_file(tree, &set);
> smb2_util_close(tree, handle);
> smb2_util_rmdir(tree, dname);
> smb2_deltree(tree, BASEDIR);
> smb2_tdis(tree);
> smb2_logoff(tree->session);
>
> return ret;
> }
More information about the samba-technical
mailing list