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