summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristof Schmitt <cs@samba.org>2019-07-17 10:49:47 -0700
committerKarolin Seeger <kseeger@samba.org>2019-08-26 10:23:28 +0000
commit657f79f859492be9f9b21481cb9326fc2c9914a7 (patch)
treeda8fa4833ac104799574154dcf13c201d4de4c17
parentd297f347dd15407cee0e2d18a27a54caaa4047ab (diff)
downloadsamba-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.c37
-rw-r--r--source3/modules/test_nfs4_acls.c39
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);