diff options
author | Christof Schmitt <cs@samba.org> | 2019-07-17 10:49:47 -0700 |
---|---|---|
committer | Karolin Seeger <kseeger@samba.org> | 2019-08-26 10:23:28 +0000 |
commit | 657f79f859492be9f9b21481cb9326fc2c9914a7 (patch) | |
tree | da8fa4833ac104799574154dcf13c201d4de4c17 | |
parent | d297f347dd15407cee0e2d18a27a54caaa4047ab (diff) | |
download | samba-657f79f859492be9f9b21481cb9326fc2c9914a7.tar.gz |
nfs4_acls: Add additional owner entry when mapping to NFS4 ACL with IDMAP_TYPE_BOTH
With IDMAP_TYPE_BOTH, all entries have to be mapped to group entries.
In order to have the file system reflect the owner permissions in the
POSIX modebits, create a second entry for the user. This will be mapped
to the "special owner" entry.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14032
Signed-off-by: Christof Schmitt <cs@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
(cherry picked from commit b796119e2df38d1935064556934dd10da6f3d339)
-rw-r--r-- | source3/modules/nfs4_acls.c | 37 | ||||
-rw-r--r-- | source3/modules/test_nfs4_acls.c | 39 |
2 files changed, 69 insertions, 7 deletions
diff --git a/source3/modules/nfs4_acls.c b/source3/modules/nfs4_acls.c index d169377295a..70d725eb937 100644 --- a/source3/modules/nfs4_acls.c +++ b/source3/modules/nfs4_acls.c @@ -719,6 +719,9 @@ static int smbacl4_fill_ace4( { struct dom_sid_buf buf; SMB_ACE4PROP_T nfs4_ace = { 0 }; + SMB_ACE4PROP_T nfs4_ace_2 = { 0 }; + bool add_ace2 = false; + int ret; DEBUG(10, ("got ace for %s\n", dom_sid_str_buf(&ace_nt->trustee, &buf))); @@ -789,6 +792,29 @@ static int smbacl4_fill_ace4( case ID_TYPE_BOTH: nfs4_ace.aceFlags |= SMB_ACE4_IDENTIFIER_GROUP; nfs4_ace.who.gid = unixid.id; + + if (ownerUID == unixid.id && + !nfs_ace_is_inherit(&nfs4_ace)) + { + /* + * IDMAP_TYPE_BOTH for owner. Add + * additional user entry, which can be + * mapped to special:owner to reflect + * the permissions in the modebits. + * + * This only applies to non-inheriting + * entries as only these are replaced + * with SPECIAL_OWNER in nfs4:mode=simple. + */ + nfs4_ace_2 = (SMB_ACE4PROP_T) { + .who.uid = unixid.id, + .aceFlags = (nfs4_ace.aceFlags & + ~SMB_ACE4_IDENTIFIER_GROUP), + .aceMask = nfs4_ace.aceMask, + .aceType = nfs4_ace.aceType, + }; + add_ace2 = true; + } break; case ID_TYPE_GID: nfs4_ace.aceFlags |= SMB_ACE4_IDENTIFIER_GROUP; @@ -805,7 +831,16 @@ static int smbacl4_fill_ace4( } } - return nfs4_acl_add_ace(params->acedup, nfs4_acl, &nfs4_ace); + ret = nfs4_acl_add_ace(params->acedup, nfs4_acl, &nfs4_ace); + if (ret != 0) { + return -1; + } + + if (!add_ace2) { + return 0; + } + + return nfs4_acl_add_ace(params->acedup, nfs4_acl, &nfs4_ace_2); } static int smbacl4_substitute_special( diff --git a/source3/modules/test_nfs4_acls.c b/source3/modules/test_nfs4_acls.c index d7152a0737a..170a397579a 100644 --- a/source3/modules/test_nfs4_acls.c +++ b/source3/modules/test_nfs4_acls.c @@ -1671,6 +1671,7 @@ struct dacl_to_nfs4_idmap_both { uint32_t nfs4_flags; uint32_t nfs4_ace_flags; uint32_t nfs4_id; + int num_nfs4_aces; }; /* @@ -1684,13 +1685,17 @@ static void test_dacl_to_nfs4_idmap_type_both(void **state) struct dacl_to_nfs4_idmap_both dacl_to_nfs4_idmap_both[] = { { &sids[2], 0, - SMB_ACE4_ID_SPECIAL, SMB_ACE4_IDENTIFIER_GROUP, SMB_ACE4_WHO_GROUP }, + SMB_ACE4_ID_SPECIAL, SMB_ACE4_IDENTIFIER_GROUP, SMB_ACE4_WHO_GROUP, + 2 }, { &sids[2], SEC_ACE_FLAG_OBJECT_INHERIT, - 0, SMB_ACE4_IDENTIFIER_GROUP|SMB_ACE4_FILE_INHERIT_ACE, 1002 }, + 0, SMB_ACE4_IDENTIFIER_GROUP|SMB_ACE4_FILE_INHERIT_ACE, 1002, + 1 }, { &sids[6], 0, - 0, SMB_ACE4_IDENTIFIER_GROUP, 1005 }, + 0, SMB_ACE4_IDENTIFIER_GROUP, 1005, + 1 }, { &sids[6], SEC_ACE_FLAG_OBJECT_INHERIT, - 0, SMB_ACE4_IDENTIFIER_GROUP|SMB_ACE4_FILE_INHERIT_ACE, 1005 }, + 0, SMB_ACE4_IDENTIFIER_GROUP|SMB_ACE4_FILE_INHERIT_ACE, 1005, + 1 }, }; for (i = 0; i < ARRAY_SIZE(dacl_to_nfs4_idmap_both); i++) { @@ -1720,11 +1725,11 @@ static void test_dacl_to_nfs4_idmap_type_both(void **state) assert_non_null(nfs4_acl); assert_int_equal(smbacl4_get_controlflags(nfs4_acl), SEC_DESC_SELF_RELATIVE); - assert_int_equal(smb_get_naces(nfs4_acl), 1); + assert_int_equal(smb_get_naces(nfs4_acl), + dacl_to_nfs4_idmap_both[i].num_nfs4_aces); nfs4_ace_container = smb_first_ace4(nfs4_acl); assert_non_null(nfs4_ace_container); - assert_null(smb_next_ace4(nfs4_ace_container)); nfs4_ace = smb_get_ace4(nfs4_ace_container); assert_int_equal(nfs4_ace->flags, @@ -1744,6 +1749,28 @@ static void test_dacl_to_nfs4_idmap_type_both(void **state) assert_int_equal(nfs4_ace->aceType, SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE); assert_int_equal(nfs4_ace->aceMask, SMB_ACE4_READ_DATA); + + if (dacl_to_nfs4_idmap_both[i].num_nfs4_aces == 2) { + nfs4_ace_container = smb_next_ace4(nfs4_ace_container); + assert_non_null(nfs4_ace_container); + + nfs4_ace = smb_get_ace4(nfs4_ace_container); + assert_int_equal(nfs4_ace->flags, + dacl_to_nfs4_idmap_both[i].nfs4_flags); + assert_int_equal(nfs4_ace->aceFlags, + dacl_to_nfs4_idmap_both[i].nfs4_ace_flags & + ~SMB_ACE4_IDENTIFIER_GROUP); + if (nfs4_ace->flags & SMB_ACE4_ID_SPECIAL) { + assert_int_equal(nfs4_ace->who.special_id, + SMB_ACE4_WHO_OWNER); + } else { + assert_int_equal(nfs4_ace->who.uid, + dacl_to_nfs4_idmap_both[i].nfs4_id); + } + assert_int_equal(nfs4_ace->aceType, + SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE); + assert_int_equal(nfs4_ace->aceMask, SMB_ACE4_READ_DATA); + } } TALLOC_FREE(frame); |