1
0
mirror of https://github.com/samba-team/samba.git synced 2025-02-26 21:57:41 +03:00

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>
This commit is contained in:
Christof Schmitt 2019-07-17 10:49:47 -07:00
parent aa46441936
commit b796119e2d
2 changed files with 69 additions and 7 deletions

View File

@ -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 void smbacl4_substitute_special(struct SMB4ACL_T *acl,

View File

@ -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);