1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-23 17:34:34 +03:00
samba-mirror/source3/modules/test_nfs4_acls.c
Christof Schmitt 1a137a2f20 nfs4_acls: Add test for merging duplicates when mapping from NFS4 ACL to DACL
The previous patch introduced merging of duplicates on the mapping path
from NFS4 ACL entries to DACL entries. Add a testcase to verify the
expected behavior of this codepath.

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>
2019-07-23 18:27:27 +00:00

1899 lines
56 KiB
C

/*
* Unix SMB/CIFS implementation.
*
* Unit test for NFS4 ACL handling
*
* Copyright (C) Christof Schmitt 2019
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include "nfs4_acls.c"
#include "librpc/gen_ndr/idmap.h"
#include "idmap_cache.h"
#include <cmocka.h>
struct test_sids {
const char *sid_str;
struct unixid unix_id;
} test_sids[] = {
{ "S-1-5-2-123-456-789-100", { 1000, ID_TYPE_UID }},
{ "S-1-5-2-123-456-789-101", { 1001, ID_TYPE_GID }},
{ "S-1-5-2-123-456-789-102", { 1002, ID_TYPE_BOTH }},
{ SID_CREATOR_OWNER, { 1003, ID_TYPE_UID }},
{ SID_CREATOR_GROUP, { 1004, ID_TYPE_GID }},
{ "S-1-5-2-123-456-789-103", { 1000, ID_TYPE_GID }},
{ "S-1-5-2-123-456-789-104", { 1005, ID_TYPE_BOTH }},
{ "S-1-5-2-123-456-789-105", { 1006, ID_TYPE_BOTH }},
{ "S-1-5-2-123-456-789-106", { 1007, ID_TYPE_BOTH }},
};
static int group_setup(void **state)
{
struct dom_sid *sids = NULL;
int i;
sids = talloc_array(NULL, struct dom_sid, ARRAY_SIZE(test_sids));
assert_non_null(sids);
for (i = 0; i < ARRAY_SIZE(test_sids); i++) {
assert_true(dom_sid_parse(test_sids[i].sid_str, &sids[i]));
idmap_cache_set_sid2unixid(&sids[i], &test_sids[i].unix_id);
}
*state = sids;
return 0;
}
static int group_teardown(void **state)
{
struct dom_sid *sids = *state;
int i;
for (i = 0; i < ARRAY_SIZE(test_sids); i++) {
assert_true(idmap_cache_del_sid(&sids[i]));
}
TALLOC_FREE(sids);
*state = NULL;
return 0;
}
/*
* Run this as first test to verify that the id mappings used by other
* tests are available in the cache.
*/
static void test_cached_id_mappings(void **state)
{
struct dom_sid *sids = *state;
int i;
for (i = 0; i < ARRAY_SIZE(test_sids); i++) {
struct dom_sid *sid = &sids[i];
struct unixid *unix_id = &test_sids[i].unix_id;
uid_t uid;
gid_t gid;
switch(unix_id->type) {
case ID_TYPE_UID:
assert_true(sid_to_uid(sid, &uid));
assert_int_equal(uid, unix_id->id);
assert_false(sid_to_gid(sid, &gid));
break;
case ID_TYPE_GID:
assert_false(sid_to_uid(sid, &uid));
assert_true(sid_to_gid(sid, &gid));
assert_int_equal(gid, unix_id->id);
break;
case ID_TYPE_BOTH:
assert_true(sid_to_uid(sid, &uid));
assert_int_equal(uid, unix_id->id);
assert_true(sid_to_gid(sid, &gid));
assert_int_equal(gid, unix_id->id);
break;
default:
fail_msg("Unknown id type %d\n", unix_id->type);
break;
}
}
}
static void test_empty_nfs4_to_dacl(void **state)
{
struct dom_sid *sids = *state;
TALLOC_CTX *frame = talloc_stackframe();
struct SMB4ACL_T *nfs4_acl;
struct security_ace *dacl_aces;
int good_aces;
struct smbacl4_vfs_params params = {
.mode = e_simple,
.do_chown = true,
.acedup = e_merge,
.map_full_control = true,
};
nfs4_acl = smb_create_smb4acl(frame);
assert_non_null(nfs4_acl);
assert_true(smbacl4_nfs42win(frame, &params, nfs4_acl,
&sids[0], &sids[1], false,
&dacl_aces, &good_aces));
assert_int_equal(good_aces, 0);
assert_null(dacl_aces);
TALLOC_FREE(frame);
}
static void test_empty_dacl_to_nfs4(void **state)
{
TALLOC_CTX *frame = talloc_stackframe();
struct SMB4ACL_T *nfs4_acl;
struct security_acl *dacl;
struct smbacl4_vfs_params params = {
.mode = e_simple,
.do_chown = true,
.acedup = e_merge,
.map_full_control = true,
};
dacl = make_sec_acl(frame, SECURITY_ACL_REVISION_ADS, 0, NULL);
assert_non_null(dacl);
nfs4_acl = smbacl4_win2nfs4(frame, false, dacl, &params, 1001, 1002);
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), 0);
assert_null(smb_first_ace4(nfs4_acl));
}
struct ace_dacl_type_mapping {
uint32_t nfs4_type;
enum security_ace_type dacl_type;
} ace_dacl_type_mapping[] = {
{ SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE, SEC_ACE_TYPE_ACCESS_ALLOWED },
{ SMB_ACE4_ACCESS_DENIED_ACE_TYPE, SEC_ACE_TYPE_ACCESS_DENIED },
};
static void test_acl_type_nfs4_to_dacl(void **state)
{
struct dom_sid *sids = *state;
TALLOC_CTX *frame = talloc_stackframe();
int i;
for (i = 0; i < ARRAY_SIZE(ace_dacl_type_mapping); i++) {
struct SMB4ACL_T *nfs4_acl;
SMB_ACE4PROP_T nfs4_ace;
struct security_ace *dacl_aces;
int good_aces;
struct smbacl4_vfs_params params = {
.mode = e_simple,
.do_chown = true,
.acedup = e_merge,
.map_full_control = true,
};
nfs4_acl = smb_create_smb4acl(frame);
assert_non_null(nfs4_acl);
nfs4_ace = (SMB_ACE4PROP_T) {
.flags = 0,
.who.uid = 1000,
.aceType = ace_dacl_type_mapping[i].nfs4_type,
.aceFlags = 0,
.aceMask = SMB_ACE4_READ_DATA,
};
assert_non_null(smb_add_ace4(nfs4_acl, &nfs4_ace));
assert_true(smbacl4_nfs42win(frame, &params, nfs4_acl,
&sids[2], &sids[3], false,
&dacl_aces, &good_aces));
assert_int_equal(good_aces, 1);
assert_non_null(dacl_aces);
assert_int_equal(dacl_aces[0].type,
ace_dacl_type_mapping[i].dacl_type);
assert_int_equal(dacl_aces[0].flags, 0);
assert_int_equal(dacl_aces[0].access_mask, SEC_FILE_READ_DATA);
assert_true(dom_sid_equal(&dacl_aces[0].trustee, &sids[0]));
}
TALLOC_FREE(frame);
}
static void test_acl_type_dacl_to_nfs4(void **state)
{
struct dom_sid *sids = *state;
TALLOC_CTX *frame = talloc_stackframe();
int i;
for (i = 0; i < ARRAY_SIZE(ace_dacl_type_mapping); i++) {
struct SMB4ACL_T *nfs4_acl;
struct SMB4ACE_T *nfs4_ace_container;
SMB_ACE4PROP_T *nfs4_ace;
struct security_ace dacl_aces[1];
struct security_acl *dacl;
struct smbacl4_vfs_params params = {
.mode = e_simple,
.do_chown = true,
.acedup = e_merge,
.map_full_control = true,
};
init_sec_ace(&dacl_aces[0], &sids[0],
ace_dacl_type_mapping[i].dacl_type,
SEC_FILE_READ_DATA, 0);
dacl = make_sec_acl(frame, SECURITY_ACL_REVISION_ADS,
ARRAY_SIZE(dacl_aces), dacl_aces);
assert_non_null(dacl);
nfs4_acl = smbacl4_win2nfs4(frame, false, dacl, &params,
101, 102);
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);
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, 0);
assert_int_equal(nfs4_ace->who.uid, 1000);
assert_int_equal(nfs4_ace->aceFlags, 0);
assert_int_equal(nfs4_ace->aceType,
ace_dacl_type_mapping[i].nfs4_type);
assert_int_equal(nfs4_ace->aceMask, SMB_ACE4_READ_DATA);
}
TALLOC_FREE(frame);
}
struct ace_flag_mapping_nfs4_to_dacl {
bool is_directory;
uint32_t nfs4_flag;
uint32_t dacl_flag;
} ace_flags_nfs4_to_dacl[] = {
{ true, SMB_ACE4_FILE_INHERIT_ACE,
SEC_ACE_FLAG_OBJECT_INHERIT },
{ false, SMB_ACE4_FILE_INHERIT_ACE,
0 },
{ true, SMB_ACE4_DIRECTORY_INHERIT_ACE,
SEC_ACE_FLAG_CONTAINER_INHERIT },
{ false, SMB_ACE4_DIRECTORY_INHERIT_ACE,
0 },
{ true, SMB_ACE4_NO_PROPAGATE_INHERIT_ACE,
SEC_ACE_FLAG_NO_PROPAGATE_INHERIT },
{ false, SMB_ACE4_NO_PROPAGATE_INHERIT_ACE,
SEC_ACE_FLAG_NO_PROPAGATE_INHERIT },
{ true, SMB_ACE4_INHERIT_ONLY_ACE,
SEC_ACE_FLAG_INHERIT_ONLY },
{ false, SMB_ACE4_INHERIT_ONLY_ACE,
SEC_ACE_FLAG_INHERIT_ONLY },
{ true, SMB_ACE4_SUCCESSFUL_ACCESS_ACE_FLAG,
0 },
{ false, SMB_ACE4_SUCCESSFUL_ACCESS_ACE_FLAG,
0 },
{ true, SMB_ACE4_FAILED_ACCESS_ACE_FLAG,
0 },
{ false, SMB_ACE4_FAILED_ACCESS_ACE_FLAG,
0 },
{ true, SMB_ACE4_INHERITED_ACE,
SEC_ACE_FLAG_INHERITED_ACE },
{ false, SMB_ACE4_INHERITED_ACE,
SEC_ACE_FLAG_INHERITED_ACE },
};
static void test_ace_flags_nfs4_to_dacl(void **state)
{
struct dom_sid *sids = *state;
TALLOC_CTX *frame = talloc_stackframe();
SMB_ACE4PROP_T nfs4_ace;
int i;
for (i = 0; i < ARRAY_SIZE(ace_flags_nfs4_to_dacl); i++) {
struct SMB4ACL_T *nfs4_acl;
bool is_directory;
struct security_ace *dacl_aces;
int good_aces;
struct smbacl4_vfs_params params = {
.mode = e_simple,
.do_chown = true,
.acedup = e_merge,
.map_full_control = true,
};
nfs4_acl = smb_create_smb4acl(frame);
assert_non_null(nfs4_acl);
nfs4_ace = (SMB_ACE4PROP_T) {
.flags = 0,
.who.uid = 1000,
.aceType = SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE,
.aceFlags = ace_flags_nfs4_to_dacl[i].nfs4_flag,
.aceMask = SMB_ACE4_READ_DATA,
};
assert_non_null(smb_add_ace4(nfs4_acl, &nfs4_ace));
is_directory = ace_flags_nfs4_to_dacl[i].is_directory;
assert_true(smbacl4_nfs42win(frame, &params, nfs4_acl,
&sids[2], &sids[3], is_directory,
&dacl_aces, &good_aces));
assert_int_equal(good_aces, 1);
assert_non_null(dacl_aces);
assert_int_equal(dacl_aces[0].type,
SEC_ACE_TYPE_ACCESS_ALLOWED);
assert_int_equal(dacl_aces[0].flags,
ace_flags_nfs4_to_dacl[i].dacl_flag);
assert_int_equal(dacl_aces[0].access_mask, SEC_FILE_READ_DATA);
assert_true(dom_sid_equal(&dacl_aces[0].trustee, &sids[0]));
}
TALLOC_FREE(frame);
}
struct ace_flag_mapping_dacl_to_nfs4 {
bool is_directory;
uint32_t dacl_flag;
uint32_t nfs4_flag;
} ace_flags_dacl_to_nfs4[] = {
{ true, SEC_ACE_FLAG_OBJECT_INHERIT,
SMB_ACE4_FILE_INHERIT_ACE },
{ false, SEC_ACE_FLAG_OBJECT_INHERIT,
0 },
{ true, SEC_ACE_FLAG_CONTAINER_INHERIT,
SMB_ACE4_DIRECTORY_INHERIT_ACE },
{ false, SEC_ACE_FLAG_CONTAINER_INHERIT,
0 },
{ true, SEC_ACE_FLAG_NO_PROPAGATE_INHERIT,
SMB_ACE4_NO_PROPAGATE_INHERIT_ACE },
{ false, SEC_ACE_FLAG_NO_PROPAGATE_INHERIT,
0 },
{ true, SEC_ACE_FLAG_INHERIT_ONLY,
SMB_ACE4_INHERIT_ONLY_ACE },
{ false, SEC_ACE_FLAG_INHERIT_ONLY,
0 },
{ true, SEC_ACE_FLAG_INHERITED_ACE,
SMB_ACE4_INHERITED_ACE },
{ false, SEC_ACE_FLAG_INHERITED_ACE,
SMB_ACE4_INHERITED_ACE },
{ true, SEC_ACE_FLAG_SUCCESSFUL_ACCESS,
0 },
{ false, SEC_ACE_FLAG_SUCCESSFUL_ACCESS,
0 },
{ true, SEC_ACE_FLAG_FAILED_ACCESS,
0 },
{ false, SEC_ACE_FLAG_FAILED_ACCESS,
0 },
};
static void test_ace_flags_dacl_to_nfs4(void **state)
{
struct dom_sid *sids = *state;
TALLOC_CTX *frame = talloc_stackframe();
int i;
for (i = 0; i < ARRAY_SIZE(ace_flags_dacl_to_nfs4); i++) {
struct SMB4ACL_T *nfs4_acl;
struct SMB4ACE_T *nfs4_ace_container;
SMB_ACE4PROP_T *nfs4_ace;
bool is_directory;
struct security_ace dacl_aces[1];
struct security_acl *dacl;
struct smbacl4_vfs_params params = {
.mode = e_simple,
.do_chown = true,
.acedup = e_merge,
.map_full_control = true,
};
init_sec_ace(&dacl_aces[0], &sids[0],
SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_FILE_READ_DATA,
ace_flags_dacl_to_nfs4[i].dacl_flag);
dacl = make_sec_acl(frame, SECURITY_ACL_REVISION_ADS,
ARRAY_SIZE(dacl_aces), dacl_aces);
assert_non_null(dacl);
is_directory = ace_flags_dacl_to_nfs4[i].is_directory;
nfs4_acl = smbacl4_win2nfs4(frame, is_directory, dacl, &params,
101, 102);
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);
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, 0);
assert_int_equal(nfs4_ace->who.uid, 1000);
assert_int_equal(nfs4_ace->aceFlags,
ace_flags_dacl_to_nfs4[i].nfs4_flag);
assert_int_equal(nfs4_ace->aceMask, SMB_ACE4_READ_DATA);
}
TALLOC_FREE(frame);
}
struct ace_perm_mapping {
uint32_t nfs4_perm;
uint32_t dacl_perm;
} perm_table_nfs4_to_dacl[] = {
{ SMB_ACE4_READ_DATA, SEC_FILE_READ_DATA },
{ SMB_ACE4_LIST_DIRECTORY, SEC_DIR_LIST },
{ SMB_ACE4_WRITE_DATA, SEC_FILE_WRITE_DATA },
{ SMB_ACE4_ADD_FILE, SEC_DIR_ADD_FILE },
{ SMB_ACE4_APPEND_DATA, SEC_FILE_APPEND_DATA },
{ SMB_ACE4_ADD_SUBDIRECTORY, SEC_DIR_ADD_SUBDIR, },
{ SMB_ACE4_READ_NAMED_ATTRS, SEC_FILE_READ_EA },
{ SMB_ACE4_READ_NAMED_ATTRS, SEC_DIR_READ_EA },
{ SMB_ACE4_WRITE_NAMED_ATTRS, SEC_FILE_WRITE_EA },
{ SMB_ACE4_WRITE_NAMED_ATTRS, SEC_DIR_WRITE_EA },
{ SMB_ACE4_EXECUTE, SEC_FILE_EXECUTE },
{ SMB_ACE4_EXECUTE, SEC_DIR_TRAVERSE },
{ SMB_ACE4_DELETE_CHILD, SEC_DIR_DELETE_CHILD },
{ SMB_ACE4_READ_ATTRIBUTES, SEC_FILE_READ_ATTRIBUTE },
{ SMB_ACE4_READ_ATTRIBUTES, SEC_DIR_READ_ATTRIBUTE },
{ SMB_ACE4_WRITE_ATTRIBUTES, SEC_FILE_WRITE_ATTRIBUTE },
{ SMB_ACE4_WRITE_ATTRIBUTES, SEC_DIR_WRITE_ATTRIBUTE },
{ SMB_ACE4_DELETE, SEC_STD_DELETE },
{ SMB_ACE4_READ_ACL, SEC_STD_READ_CONTROL },
{ SMB_ACE4_WRITE_ACL, SEC_STD_WRITE_DAC, },
{ SMB_ACE4_WRITE_OWNER, SEC_STD_WRITE_OWNER },
{ SMB_ACE4_SYNCHRONIZE, SEC_STD_SYNCHRONIZE },
};
static void test_nfs4_permissions_to_dacl(void **state)
{
struct dom_sid *sids = *state;
TALLOC_CTX *frame = talloc_stackframe();
int i;
for (i = 0; i < ARRAY_SIZE(perm_table_nfs4_to_dacl); i++) {
struct SMB4ACL_T *nfs4_acl;
SMB_ACE4PROP_T nfs4_ace;
struct security_ace *dacl_aces;
int good_aces;
struct smbacl4_vfs_params params = {
.mode = e_simple,
.do_chown = true,
.acedup = e_merge,
.map_full_control = true,
};
nfs4_acl = smb_create_smb4acl(frame);
assert_non_null(nfs4_acl);
nfs4_ace = (SMB_ACE4PROP_T) {
.flags = 0,
.who.uid = 1000,
.aceType = SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE,
.aceFlags = 0,
.aceMask = perm_table_nfs4_to_dacl[i].nfs4_perm,
};
assert_non_null(smb_add_ace4(nfs4_acl, &nfs4_ace));
assert_true(smbacl4_nfs42win(frame, &params, nfs4_acl,
&sids[0], &sids[1], false,
&dacl_aces, &good_aces));
assert_int_equal(good_aces, 1);
assert_non_null(dacl_aces);
assert_int_equal(dacl_aces[0].type,
SEC_ACE_TYPE_ACCESS_ALLOWED);
assert_int_equal(dacl_aces[0].flags, 0);
assert_int_equal(dacl_aces[0].access_mask,
perm_table_nfs4_to_dacl[i].dacl_perm);
assert_true(dom_sid_equal(&dacl_aces[0].trustee, &sids[0]));
}
TALLOC_FREE(frame);
}
struct ace_perm_mapping_dacl_to_nfs4 {
uint32_t dacl_perm;
uint32_t nfs4_perm;
} perm_table_dacl_to_nfs4[] = {
{ SEC_FILE_READ_DATA, SMB_ACE4_READ_DATA, },
{ SEC_DIR_LIST, SMB_ACE4_LIST_DIRECTORY, },
{ SEC_FILE_WRITE_DATA, SMB_ACE4_WRITE_DATA, },
{ SEC_DIR_ADD_FILE, SMB_ACE4_ADD_FILE, },
{ SEC_FILE_APPEND_DATA, SMB_ACE4_APPEND_DATA, },
{ SEC_DIR_ADD_SUBDIR, SMB_ACE4_ADD_SUBDIRECTORY, },
{ SEC_FILE_READ_EA, SMB_ACE4_READ_NAMED_ATTRS, },
{ SEC_DIR_READ_EA, SMB_ACE4_READ_NAMED_ATTRS, },
{ SEC_FILE_WRITE_EA, SMB_ACE4_WRITE_NAMED_ATTRS, },
{ SEC_DIR_WRITE_EA, SMB_ACE4_WRITE_NAMED_ATTRS, },
{ SEC_FILE_EXECUTE, SMB_ACE4_EXECUTE, },
{ SEC_DIR_TRAVERSE, SMB_ACE4_EXECUTE, },
{ SEC_DIR_DELETE_CHILD, SMB_ACE4_DELETE_CHILD, },
{ SEC_FILE_READ_ATTRIBUTE, SMB_ACE4_READ_ATTRIBUTES, },
{ SEC_DIR_READ_ATTRIBUTE, SMB_ACE4_READ_ATTRIBUTES, },
{ SEC_FILE_WRITE_ATTRIBUTE, SMB_ACE4_WRITE_ATTRIBUTES, },
{ SEC_DIR_WRITE_ATTRIBUTE, SMB_ACE4_WRITE_ATTRIBUTES, },
{ SEC_STD_DELETE, SMB_ACE4_DELETE, },
{ SEC_STD_READ_CONTROL, SMB_ACE4_READ_ACL, },
{ SEC_STD_WRITE_DAC, SMB_ACE4_WRITE_ACL, },
{ SEC_STD_WRITE_OWNER, SMB_ACE4_WRITE_OWNER, },
{ SEC_STD_SYNCHRONIZE, SMB_ACE4_SYNCHRONIZE, },
{ SEC_GENERIC_READ, SMB_ACE4_READ_ACL|
SMB_ACE4_READ_DATA|
SMB_ACE4_READ_ATTRIBUTES|
SMB_ACE4_READ_NAMED_ATTRS|
SMB_ACE4_SYNCHRONIZE },
{ SEC_GENERIC_WRITE, SMB_ACE4_WRITE_ACL|
SMB_ACE4_WRITE_DATA|
SMB_ACE4_WRITE_ATTRIBUTES|
SMB_ACE4_WRITE_NAMED_ATTRS|
SMB_ACE4_SYNCHRONIZE },
{ SEC_GENERIC_EXECUTE, SMB_ACE4_READ_ACL|
SMB_ACE4_READ_ATTRIBUTES|
SMB_ACE4_EXECUTE|
SMB_ACE4_SYNCHRONIZE },
{ SEC_GENERIC_ALL, SMB_ACE4_DELETE|
SMB_ACE4_READ_ACL|
SMB_ACE4_WRITE_ACL|
SMB_ACE4_WRITE_OWNER|
SMB_ACE4_SYNCHRONIZE|
SMB_ACE4_WRITE_ATTRIBUTES|
SMB_ACE4_READ_ATTRIBUTES|
SMB_ACE4_EXECUTE|
SMB_ACE4_READ_NAMED_ATTRS|
SMB_ACE4_WRITE_NAMED_ATTRS|
SMB_ACE4_WRITE_DATA|
SMB_ACE4_APPEND_DATA|
SMB_ACE4_READ_DATA|
SMB_ACE4_DELETE_CHILD },
};
static void test_dacl_permissions_to_nfs4(void **state)
{
struct dom_sid *sids = *state;
TALLOC_CTX *frame = talloc_stackframe();
int i;
for (i = 0; i < ARRAY_SIZE(perm_table_nfs4_to_dacl); i++) {
struct SMB4ACL_T *nfs4_acl;
struct SMB4ACE_T *nfs4_ace_container;
SMB_ACE4PROP_T *nfs4_ace;
struct smbacl4_vfs_params params = {
.mode = e_simple,
.do_chown = true,
.acedup = e_merge,
.map_full_control = true,
};
struct security_ace dacl_aces[1];
struct security_acl *dacl;
init_sec_ace(&dacl_aces[0], &sids[0],
SEC_ACE_TYPE_ACCESS_ALLOWED,
perm_table_dacl_to_nfs4[i].dacl_perm, 0);
dacl = make_sec_acl(frame, SECURITY_ACL_REVISION_ADS,
ARRAY_SIZE(dacl_aces), dacl_aces);
assert_non_null(dacl);
nfs4_acl = smbacl4_win2nfs4(frame, false, dacl, &params,
101, 102);
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);
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, 0);
assert_int_equal(nfs4_ace->who.uid, 1000);
assert_int_equal(nfs4_ace->aceFlags, 0);
assert_int_equal(nfs4_ace->aceMask,
perm_table_dacl_to_nfs4[i].nfs4_perm);
}
TALLOC_FREE(frame);
}
/*
* Create NFS4 ACL with all possible "special" entries. Verify that
* the ones that should be mapped to a DACL are mapped and the other
* ones are ignored.
*/
static void test_special_nfs4_to_dacl(void **state)
{
struct dom_sid *sids = *state;
TALLOC_CTX *frame = talloc_stackframe();
struct SMB4ACL_T *nfs4_acl;
SMB_ACE4PROP_T nfs4_ace;
struct security_ace *dacl_aces;
int good_aces;
struct smbacl4_vfs_params params = {
.mode = e_simple,
.do_chown = true,
.acedup = e_merge,
.map_full_control = true,
};
nfs4_acl = smb_create_smb4acl(frame);
assert_non_null(nfs4_acl);
nfs4_ace = (SMB_ACE4PROP_T) {
.flags = SMB_ACE4_ID_SPECIAL,
.who.special_id = SMB_ACE4_WHO_OWNER,
.aceType = SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE,
.aceFlags = 0,
.aceMask = SMB_ACE4_READ_DATA,
};
assert_non_null(smb_add_ace4(nfs4_acl, &nfs4_ace));
nfs4_ace = (SMB_ACE4PROP_T) {
.flags = SMB_ACE4_ID_SPECIAL,
.who.special_id = SMB_ACE4_WHO_GROUP,
.aceType = SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE,
.aceFlags = 0,
.aceMask = SMB_ACE4_WRITE_DATA,
};
assert_non_null(smb_add_ace4(nfs4_acl, &nfs4_ace));
nfs4_ace = (SMB_ACE4PROP_T) {
.flags = SMB_ACE4_ID_SPECIAL,
.who.special_id = SMB_ACE4_WHO_EVERYONE,
.aceType = SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE,
.aceFlags = 0,
.aceMask = SMB_ACE4_APPEND_DATA,
};
assert_non_null(smb_add_ace4(nfs4_acl, &nfs4_ace));
nfs4_ace = (SMB_ACE4PROP_T) {
.flags = SMB_ACE4_ID_SPECIAL,
.who.special_id = SMB_ACE4_WHO_INTERACTIVE,
.aceType = SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE,
.aceFlags = 0,
.aceMask = SMB_ACE4_READ_NAMED_ATTRS,
};
assert_non_null(smb_add_ace4(nfs4_acl, &nfs4_ace));
nfs4_ace = (SMB_ACE4PROP_T) {
.flags = SMB_ACE4_ID_SPECIAL,
.who.special_id = SMB_ACE4_WHO_NETWORK,
.aceType = SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE,
.aceFlags = 0,
.aceMask = SMB_ACE4_WRITE_NAMED_ATTRS,
};
assert_non_null(smb_add_ace4(nfs4_acl, &nfs4_ace));
nfs4_ace = (SMB_ACE4PROP_T) {
.flags = SMB_ACE4_ID_SPECIAL,
.who.special_id = SMB_ACE4_WHO_DIALUP,
.aceType = SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE,
.aceFlags = 0,
.aceMask = SMB_ACE4_EXECUTE,
};
assert_non_null(smb_add_ace4(nfs4_acl, &nfs4_ace));
nfs4_ace = (SMB_ACE4PROP_T) {
.flags = SMB_ACE4_ID_SPECIAL,
.who.special_id = SMB_ACE4_WHO_BATCH,
.aceType = SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE,
.aceFlags = 0,
.aceMask = SMB_ACE4_READ_ATTRIBUTES,
};
assert_non_null(smb_add_ace4(nfs4_acl, &nfs4_ace));
nfs4_ace = (SMB_ACE4PROP_T) {
.flags = SMB_ACE4_ID_SPECIAL,
.who.special_id = SMB_ACE4_WHO_ANONYMOUS,
.aceType = SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE,
.aceFlags = 0,
.aceMask = SMB_ACE4_WRITE_ATTRIBUTES,
};
assert_non_null(smb_add_ace4(nfs4_acl, &nfs4_ace));
nfs4_ace = (SMB_ACE4PROP_T) {
.flags = SMB_ACE4_ID_SPECIAL,
.who.special_id = SMB_ACE4_WHO_AUTHENTICATED,
.aceType = SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE,
.aceFlags = 0,
.aceMask = SMB_ACE4_READ_ACL,
};
assert_non_null(smb_add_ace4(nfs4_acl, &nfs4_ace));
nfs4_ace = (SMB_ACE4PROP_T) {
.flags = SMB_ACE4_ID_SPECIAL,
.who.special_id = SMB_ACE4_WHO_SERVICE,
.aceType = SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE,
.aceFlags = 0,
.aceMask = SMB_ACE4_WRITE_ACL,
};
assert_non_null(smb_add_ace4(nfs4_acl, &nfs4_ace));
assert_true(smbacl4_nfs42win(frame, &params, nfs4_acl,
&sids[0], &sids[1], false,
&dacl_aces, &good_aces));
assert_int_equal(good_aces, 3);
assert_non_null(dacl_aces);
assert_int_equal(dacl_aces[0].type, SEC_ACE_TYPE_ACCESS_ALLOWED);
assert_int_equal(dacl_aces[0].flags, 0);
assert_int_equal(dacl_aces[0].access_mask, SEC_FILE_READ_DATA);
assert_true(dom_sid_equal(&dacl_aces[0].trustee, &sids[0]));
assert_int_equal(dacl_aces[1].type, SEC_ACE_TYPE_ACCESS_ALLOWED);
assert_int_equal(dacl_aces[1].flags, 0);
assert_int_equal(dacl_aces[1].access_mask, SEC_FILE_WRITE_DATA);
assert_true(dom_sid_equal(&dacl_aces[1].trustee, &sids[1]));
assert_int_equal(dacl_aces[2].type, SEC_ACE_TYPE_ACCESS_ALLOWED);
assert_int_equal(dacl_aces[2].flags, 0);
assert_int_equal(dacl_aces[2].access_mask, SEC_FILE_APPEND_DATA);
assert_true(dom_sid_equal(&dacl_aces[2].trustee, &global_sid_World));
TALLOC_FREE(frame);
}
static void test_dacl_to_special_nfs4(void **state)
{
struct dom_sid *sids = *state;
TALLOC_CTX *frame = talloc_stackframe();
struct SMB4ACL_T *nfs4_acl;
struct SMB4ACE_T *nfs4_ace_container;
SMB_ACE4PROP_T *nfs4_ace;
struct security_ace dacl_aces[6];
struct security_acl *dacl;
struct smbacl4_vfs_params params = {
.mode = e_simple,
.do_chown = true,
.acedup = e_dontcare,
.map_full_control = true,
};
/*
* global_Sid_World is mapped to EVERYONE.
*/
init_sec_ace(&dacl_aces[0], &global_sid_World,
SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_FILE_WRITE_DATA, 0);
/*
* global_sid_Unix_NFS is ignored.
*/
init_sec_ace(&dacl_aces[1], &global_sid_Unix_NFS,
SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_FILE_READ_DATA, 0);
/*
* Anything that maps to owner or owning group with inheritance flags
* is NOT mapped to special owner or special group.
*/
init_sec_ace(&dacl_aces[2], &sids[0],
SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_FILE_READ_DATA,
SEC_ACE_FLAG_OBJECT_INHERIT);
init_sec_ace(&dacl_aces[3], &sids[0],
SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_FILE_READ_DATA,
SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_INHERIT_ONLY);
init_sec_ace(&dacl_aces[4], &sids[1],
SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_FILE_READ_DATA,
SEC_ACE_FLAG_OBJECT_INHERIT);
init_sec_ace(&dacl_aces[5], &sids[1],
SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_FILE_READ_DATA,
SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_INHERIT_ONLY);
dacl = make_sec_acl(frame, SECURITY_ACL_REVISION_ADS,
ARRAY_SIZE(dacl_aces), dacl_aces);
assert_non_null(dacl);
nfs4_acl = smbacl4_win2nfs4(frame, true, dacl, &params, 1000, 1001);
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), 5);
nfs4_ace_container = smb_first_ace4(nfs4_acl);
assert_non_null(nfs4_ace_container);
nfs4_ace = smb_get_ace4(nfs4_ace_container);
assert_int_equal(nfs4_ace->flags, SMB_ACE4_ID_SPECIAL);
assert_int_equal(nfs4_ace->who.special_id, SMB_ACE4_WHO_EVERYONE);
assert_int_equal(nfs4_ace->aceFlags, 0);
assert_int_equal(nfs4_ace->aceMask, SMB_ACE4_WRITE_DATA);
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, 0);
assert_int_equal(nfs4_ace->who.uid, 1000);
assert_int_equal(nfs4_ace->aceFlags, SMB_ACE4_FILE_INHERIT_ACE);
assert_int_equal(nfs4_ace->aceMask, SMB_ACE4_READ_DATA);
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, 0);
assert_int_equal(nfs4_ace->who.uid, 1000);
assert_int_equal(nfs4_ace->aceFlags, SMB_ACE4_DIRECTORY_INHERIT_ACE|
SMB_ACE4_INHERIT_ONLY_ACE);
assert_int_equal(nfs4_ace->aceMask, SMB_ACE4_READ_DATA);
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, 0);
assert_int_equal(nfs4_ace->aceFlags, SMB_ACE4_IDENTIFIER_GROUP|
SMB_ACE4_FILE_INHERIT_ACE);
assert_int_equal(nfs4_ace->who.gid, 1001);
assert_int_equal(nfs4_ace->aceMask, SMB_ACE4_READ_DATA);
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, 0);
assert_int_equal(nfs4_ace->aceFlags, SMB_ACE4_IDENTIFIER_GROUP|
SMB_ACE4_DIRECTORY_INHERIT_ACE|
SMB_ACE4_INHERIT_ONLY_ACE);
assert_int_equal(nfs4_ace->who.gid, 1001);
assert_int_equal(nfs4_ace->aceMask, SMB_ACE4_READ_DATA);
assert_null(smb_next_ace4(nfs4_ace_container));
TALLOC_FREE(frame);
}
struct creator_ace_flags {
uint32_t dacl_flags;
uint32_t nfs4_flags;
} creator_ace_flags[] = {
{ 0, 0 },
{ SEC_ACE_FLAG_INHERIT_ONLY, 0 },
{ SEC_ACE_FLAG_CONTAINER_INHERIT, SMB_ACE4_DIRECTORY_INHERIT_ACE|
SMB_ACE4_INHERIT_ONLY_ACE },
{ SEC_ACE_FLAG_CONTAINER_INHERIT|
SEC_ACE_FLAG_INHERIT_ONLY, SMB_ACE4_DIRECTORY_INHERIT_ACE|
SMB_ACE4_INHERIT_ONLY_ACE },
{ SEC_ACE_FLAG_OBJECT_INHERIT, SMB_ACE4_FILE_INHERIT_ACE|
SMB_ACE4_INHERIT_ONLY_ACE },
{ SEC_ACE_FLAG_OBJECT_INHERIT|
SEC_ACE_FLAG_INHERIT_ONLY, SMB_ACE4_FILE_INHERIT_ACE|
SMB_ACE4_INHERIT_ONLY_ACE },
{ SEC_ACE_FLAG_CONTAINER_INHERIT|
SEC_ACE_FLAG_OBJECT_INHERIT, SMB_ACE4_DIRECTORY_INHERIT_ACE|
SMB_ACE4_FILE_INHERIT_ACE|
SMB_ACE4_INHERIT_ONLY_ACE },
{ SEC_ACE_FLAG_CONTAINER_INHERIT|
SEC_ACE_FLAG_OBJECT_INHERIT|
SEC_ACE_FLAG_INHERIT_ONLY, SMB_ACE4_DIRECTORY_INHERIT_ACE|
SMB_ACE4_FILE_INHERIT_ACE|
SMB_ACE4_INHERIT_ONLY_ACE },
};
static void test_dacl_creator_to_nfs4(void **state)
{
TALLOC_CTX *frame = talloc_stackframe();
int i;
for (i = 0; i < ARRAY_SIZE(creator_ace_flags); i++) {
struct SMB4ACL_T *nfs4_acl;
struct SMB4ACE_T *nfs4_ace_container;
SMB_ACE4PROP_T *nfs4_ace;
struct security_ace dacl_aces[2];
struct security_acl *dacl;
struct smbacl4_vfs_params params = {
.mode = e_simple,
.do_chown = true,
.acedup = e_merge,
.map_full_control = true,
};
init_sec_ace(&dacl_aces[0], &global_sid_Creator_Owner,
SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_FILE_READ_DATA,
creator_ace_flags[i].dacl_flags);
init_sec_ace(&dacl_aces[1], &global_sid_Creator_Group,
SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_FILE_READ_DATA,
creator_ace_flags[i].dacl_flags);
dacl = make_sec_acl(frame, SECURITY_ACL_REVISION_ADS,
ARRAY_SIZE(dacl_aces), dacl_aces);
assert_non_null(dacl);
nfs4_acl = smbacl4_win2nfs4(frame, true, dacl, &params,
101, 102);
assert_non_null(nfs4_acl);
assert_int_equal(smbacl4_get_controlflags(nfs4_acl),
SEC_DESC_SELF_RELATIVE);
if (creator_ace_flags[i].nfs4_flags == 0) {
/*
* CREATOR OWNER and CREATOR GROUP not mapped
* in thise case.
*/
assert_null(smb_first_ace4(nfs4_acl));
} else {
assert_int_equal(smb_get_naces(nfs4_acl), 2);
nfs4_ace_container = smb_first_ace4(nfs4_acl);
assert_non_null(nfs4_ace_container);
nfs4_ace = smb_get_ace4(nfs4_ace_container);
assert_non_null(nfs4_ace);
assert_int_equal(nfs4_ace->flags, SMB_ACE4_ID_SPECIAL);
assert_int_equal(nfs4_ace->who.special_id,
SMB_ACE4_WHO_OWNER);
assert_int_equal(nfs4_ace->aceFlags,
creator_ace_flags[i].nfs4_flags);
assert_int_equal(nfs4_ace->aceMask, SMB_ACE4_READ_DATA);
nfs4_ace_container = smb_next_ace4(nfs4_ace_container);
assert_non_null(nfs4_ace_container);
assert_null(smb_next_ace4(nfs4_ace_container));
nfs4_ace = smb_get_ace4(nfs4_ace_container);
assert_non_null(nfs4_ace);
assert_int_equal(nfs4_ace->flags, SMB_ACE4_ID_SPECIAL);
assert_int_equal(nfs4_ace->who.special_id,
SMB_ACE4_WHO_GROUP);
assert_int_equal(nfs4_ace->aceFlags,
creator_ace_flags[i].nfs4_flags);
assert_int_equal(nfs4_ace->aceMask, SMB_ACE4_READ_DATA);
}
}
TALLOC_FREE(frame);
}
struct creator_owner_nfs4_to_dacl {
uint32_t special_id;
uint32_t nfs4_ace_flags;
uint32_t dacl_ace_flags;
} creator_owner_nfs4_to_dacl[] = {
{ SMB_ACE4_WHO_OWNER,
SMB_ACE4_FILE_INHERIT_ACE,
SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_INHERIT_ONLY },
{ SMB_ACE4_WHO_OWNER,
SMB_ACE4_DIRECTORY_INHERIT_ACE,
SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_INHERIT_ONLY },
{ SMB_ACE4_WHO_OWNER,
SMB_ACE4_FILE_INHERIT_ACE|SMB_ACE4_DIRECTORY_INHERIT_ACE,
SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_CONTAINER_INHERIT|
SEC_ACE_FLAG_INHERIT_ONLY },
{ SMB_ACE4_WHO_GROUP,
SMB_ACE4_FILE_INHERIT_ACE,
SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_INHERIT_ONLY },
{ SMB_ACE4_WHO_GROUP,
SMB_ACE4_DIRECTORY_INHERIT_ACE,
SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_INHERIT_ONLY },
{ SMB_ACE4_WHO_GROUP,
SMB_ACE4_FILE_INHERIT_ACE|SMB_ACE4_DIRECTORY_INHERIT_ACE,
SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_CONTAINER_INHERIT|
SEC_ACE_FLAG_INHERIT_ONLY },
};
static void test_nfs4_to_dacl_creator(void **state)
{
struct dom_sid *sids = *state;
TALLOC_CTX *frame = talloc_stackframe();
int i;
for (i = 0; i < ARRAY_SIZE(creator_owner_nfs4_to_dacl); i++) {
struct SMB4ACL_T *nfs4_acl;
SMB_ACE4PROP_T nfs4_ace;
struct security_ace *dacl_aces, *creator_dacl_ace;
int good_aces;
struct smbacl4_vfs_params params = {
.mode = e_simple,
.do_chown = true,
.acedup = e_merge,
.map_full_control = true,
};
nfs4_acl = smb_create_smb4acl(frame);
assert_non_null(nfs4_acl);
nfs4_ace = (SMB_ACE4PROP_T) {
.flags = SMB_ACE4_ID_SPECIAL,
.who.special_id
= creator_owner_nfs4_to_dacl[i].special_id,
.aceType = SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE,
.aceFlags
= creator_owner_nfs4_to_dacl[i].nfs4_ace_flags,
.aceMask = SMB_ACE4_READ_DATA,
};
assert_non_null(smb_add_ace4(nfs4_acl, &nfs4_ace));
assert_true(smbacl4_nfs42win(frame, &params, nfs4_acl,
&sids[0], &sids[1], true,
&dacl_aces, &good_aces));
assert_non_null(dacl_aces);
if (creator_owner_nfs4_to_dacl[i].nfs4_ace_flags &
SMB_ACE4_INHERIT_ONLY_ACE) {
/*
* Only one ACE entry for the CREATOR ACE entry.
*/
assert_int_equal(good_aces, 1);
creator_dacl_ace = &dacl_aces[0];
} else {
/*
* This creates an additional ACE entry for
* the permissions on the current object.
*/
assert_int_equal(good_aces, 2);
assert_int_equal(dacl_aces[0].type,
SEC_ACE_TYPE_ACCESS_ALLOWED);
assert_int_equal(dacl_aces[0].flags, 0);
assert_int_equal(dacl_aces[0].access_mask,
SEC_FILE_READ_DATA);
if (creator_owner_nfs4_to_dacl[i].special_id ==
SMB_ACE4_WHO_OWNER) {
assert_true(dom_sid_equal(&dacl_aces[0].trustee,
&sids[0]));
}
if (creator_owner_nfs4_to_dacl[i].special_id ==
SMB_ACE4_WHO_GROUP) {
assert_true(dom_sid_equal(&dacl_aces[0].trustee,
&sids[1]));
}
creator_dacl_ace = &dacl_aces[1];
}
assert_int_equal(creator_dacl_ace->type,
SEC_ACE_TYPE_ACCESS_ALLOWED);
assert_int_equal(creator_dacl_ace->flags,
creator_owner_nfs4_to_dacl[i].dacl_ace_flags);
assert_int_equal(creator_dacl_ace->access_mask,
SEC_FILE_READ_DATA);
if (creator_owner_nfs4_to_dacl[i].special_id ==
SMB_ACE4_WHO_OWNER) {
assert_true(dom_sid_equal(&creator_dacl_ace->trustee,
&global_sid_Creator_Owner));
}
if (creator_owner_nfs4_to_dacl[i].special_id ==
SMB_ACE4_WHO_GROUP) {
assert_true(dom_sid_equal(&creator_dacl_ace->trustee,
&global_sid_Creator_Group));
}
}
TALLOC_FREE(frame);
}
struct nfs4_to_dacl_map_full_control{
bool is_dir;
bool config;
bool delete_child_added;
} nfs4_to_dacl_full_control[] = {
{ true, true, false },
{ true, false, false },
{ false, true, true },
{ false, false, false },
};
static void test_full_control_nfs4_to_dacl(void **state)
{
struct dom_sid *sids = *state;
TALLOC_CTX *frame = talloc_stackframe();
int i;
for (i = 0; i < ARRAY_SIZE(nfs4_to_dacl_full_control); i++) {
struct SMB4ACL_T *nfs4_acl;
SMB_ACE4PROP_T nfs4_ace;
struct security_ace *dacl_aces;
int good_aces;
struct smbacl4_vfs_params params = {
.mode = e_simple,
.do_chown = true,
.acedup = e_merge,
.map_full_control = nfs4_to_dacl_full_control[i].config,
};
const uint32_t nfs4_ace_mask_except_deletes =
SMB_ACE4_READ_DATA|SMB_ACE4_WRITE_DATA|
SMB_ACE4_APPEND_DATA|SMB_ACE4_READ_NAMED_ATTRS|
SMB_ACE4_WRITE_NAMED_ATTRS|SMB_ACE4_EXECUTE|
SMB_ACE4_READ_ATTRIBUTES|SMB_ACE4_WRITE_ATTRIBUTES|
SMB_ACE4_READ_ACL|SMB_ACE4_WRITE_ACL|
SMB_ACE4_WRITE_OWNER|SMB_ACE4_SYNCHRONIZE;
const uint32_t dacl_ace_mask_except_deletes =
SEC_FILE_READ_DATA|SEC_FILE_WRITE_DATA|
SEC_FILE_APPEND_DATA|SEC_FILE_READ_EA|
SEC_FILE_WRITE_EA|SEC_FILE_EXECUTE|
SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|
SEC_STD_READ_CONTROL|SEC_STD_WRITE_DAC|
SEC_STD_WRITE_OWNER|SEC_STD_SYNCHRONIZE;
nfs4_acl = smb_create_smb4acl(frame);
assert_non_null(nfs4_acl);
nfs4_ace = (SMB_ACE4PROP_T) {
.flags = 0,
.who.uid = 1000,
.aceType = SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE,
.aceFlags = 0,
.aceMask = nfs4_ace_mask_except_deletes,
};
assert_non_null(smb_add_ace4(nfs4_acl, &nfs4_ace));
assert_true(
smbacl4_nfs42win(frame, &params, nfs4_acl,
&sids[0], &sids[1],
nfs4_to_dacl_full_control[i].is_dir,
&dacl_aces, &good_aces));
assert_int_equal(good_aces, 1);
assert_non_null(dacl_aces);
assert_int_equal(dacl_aces[0].type,
SEC_ACE_TYPE_ACCESS_ALLOWED);
assert_int_equal(dacl_aces[0].flags, 0);
assert_true(dom_sid_equal(&dacl_aces[0].trustee, &sids[0]));
if (nfs4_to_dacl_full_control[i].delete_child_added) {
assert_int_equal(dacl_aces[0].access_mask,
dacl_ace_mask_except_deletes|
SEC_DIR_DELETE_CHILD);
} else {
assert_int_equal(dacl_aces[0].access_mask,
dacl_ace_mask_except_deletes);
}
}
TALLOC_FREE(frame);
}
struct acedup_settings {
enum smbacl4_acedup_enum setting;
} acedup_settings[] = {
{ e_dontcare },
{ e_reject },
{ e_ignore },
{ e_merge },
};
static void test_dacl_to_nfs4_acedup_settings(void **state)
{
struct dom_sid *sids = *state;
TALLOC_CTX *frame = talloc_stackframe();
int i;
for (i = 0; i < ARRAY_SIZE(acedup_settings); i++) {
struct SMB4ACL_T *nfs4_acl;
struct SMB4ACE_T *nfs4_ace_container;
SMB_ACE4PROP_T *nfs4_ace;
struct security_ace dacl_aces[2];
struct security_acl *dacl;
struct smbacl4_vfs_params params = {
.mode = e_simple,
.do_chown = true,
.acedup = acedup_settings[i].setting,
.map_full_control = true,
};
init_sec_ace(&dacl_aces[0], &sids[0],
SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_FILE_READ_DATA,
SEC_ACE_FLAG_OBJECT_INHERIT);
init_sec_ace(&dacl_aces[1], &sids[0],
SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_FILE_WRITE_DATA,
SEC_ACE_FLAG_OBJECT_INHERIT);
dacl = make_sec_acl(frame, SECURITY_ACL_REVISION_ADS,
ARRAY_SIZE(dacl_aces), dacl_aces);
assert_non_null(dacl);
nfs4_acl = smbacl4_win2nfs4(frame, true, dacl, &params,
101, 102);
switch(params.acedup) {
case e_dontcare:
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), 2);
nfs4_ace_container = smb_first_ace4(nfs4_acl);
assert_non_null(nfs4_ace_container);
nfs4_ace = smb_get_ace4(nfs4_ace_container);
assert_int_equal(nfs4_ace->flags, 0);
assert_int_equal(nfs4_ace->who.uid, 1000);
assert_int_equal(nfs4_ace->aceFlags,
SMB_ACE4_FILE_INHERIT_ACE);
assert_int_equal(nfs4_ace->aceMask, SMB_ACE4_READ_DATA);
nfs4_ace_container = smb_next_ace4(nfs4_ace_container);
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, 0);
assert_int_equal(nfs4_ace->who.uid, 1000);
assert_int_equal(nfs4_ace->aceFlags,
SMB_ACE4_FILE_INHERIT_ACE);
assert_int_equal(nfs4_ace->aceMask,
SMB_ACE4_WRITE_DATA);
break;
case e_reject:
assert_null(nfs4_acl);
assert_int_equal(errno, EINVAL);
break;
case e_ignore:
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);
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, 0);
assert_int_equal(nfs4_ace->who.uid, 1000);
assert_int_equal(nfs4_ace->aceFlags,
SMB_ACE4_FILE_INHERIT_ACE);
assert_int_equal(nfs4_ace->aceMask, SMB_ACE4_READ_DATA);
break;
case e_merge:
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);
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, 0);
assert_int_equal(nfs4_ace->who.uid, 1000);
assert_int_equal(nfs4_ace->aceFlags,
SMB_ACE4_FILE_INHERIT_ACE);
assert_int_equal(nfs4_ace->aceMask,
SMB_ACE4_READ_DATA|
SMB_ACE4_WRITE_DATA);
break;
default:
fail_msg("Unexpected value for acedup: %d\n",
params.acedup);
};
}
TALLOC_FREE(frame);
}
struct acedup_match {
int sid_idx1;
enum security_ace_type type1;
uint32_t ace_mask1;
uint8_t flag1;
int sid_idx2;
enum security_ace_type type2;
uint32_t ace_mask2;
uint8_t flag2;
bool match;
} acedup_match[] = {
{ 0, SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_FILE_READ_DATA,
SEC_ACE_FLAG_OBJECT_INHERIT,
0, SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_FILE_READ_DATA,
SEC_ACE_FLAG_OBJECT_INHERIT,
true },
{ 0, SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_FILE_READ_DATA,
SEC_ACE_FLAG_OBJECT_INHERIT,
1, SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_FILE_READ_DATA,
SEC_ACE_FLAG_OBJECT_INHERIT,
false },
{ 0, SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_FILE_READ_DATA,
SEC_ACE_FLAG_OBJECT_INHERIT,
0, SEC_ACE_TYPE_ACCESS_DENIED, SEC_FILE_READ_DATA,
SEC_ACE_FLAG_OBJECT_INHERIT,
false },
{ 0, SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_FILE_READ_DATA,
SEC_ACE_FLAG_OBJECT_INHERIT,
0, SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_FILE_WRITE_DATA,
SEC_ACE_FLAG_OBJECT_INHERIT,
true },
{ 0, SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_FILE_READ_DATA,
SEC_ACE_FLAG_OBJECT_INHERIT,
0, SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_FILE_READ_DATA,
SEC_ACE_FLAG_CONTAINER_INHERIT,
false },
{ 0, SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_FILE_READ_DATA,
SEC_ACE_FLAG_OBJECT_INHERIT,
5, SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_FILE_READ_DATA,
SEC_ACE_FLAG_OBJECT_INHERIT,
false },
};
static void test_dacl_to_nfs4_acedup_match(void **state)
{
struct dom_sid *sids = *state;
TALLOC_CTX *frame = talloc_stackframe();
int i;
for (i = 0; i < ARRAY_SIZE(acedup_match); i++) {
struct SMB4ACL_T *nfs4_acl;
struct SMB4ACE_T *nfs4_ace_container;
SMB_ACE4PROP_T *nfs4_ace;
struct security_ace dacl_aces[2];
struct security_acl *dacl;
struct smbacl4_vfs_params params = {
.mode = e_simple,
.do_chown = true,
.acedup = e_ignore,
.map_full_control = true,
};
init_sec_ace(&dacl_aces[0],
&sids[acedup_match[i].sid_idx1],
acedup_match[i].type1,
acedup_match[i].ace_mask1,
acedup_match[i].flag1);
init_sec_ace(&dacl_aces[1],
&sids[acedup_match[i].sid_idx2],
acedup_match[i].type2,
acedup_match[i].ace_mask2,
acedup_match[i].flag2);
dacl = make_sec_acl(frame, SECURITY_ACL_REVISION_ADS,
ARRAY_SIZE(dacl_aces), dacl_aces);
assert_non_null(dacl);
nfs4_acl = smbacl4_win2nfs4(frame, true, dacl, &params,
101, 102);
assert_non_null(nfs4_acl);
assert_int_equal(smbacl4_get_controlflags(nfs4_acl),
SEC_DESC_SELF_RELATIVE);
if (acedup_match[i].match) {
assert_int_equal(smb_get_naces(nfs4_acl), 1);
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, 0);
assert_int_equal(nfs4_ace->who.uid, 1000);
assert_int_equal(nfs4_ace->aceFlags,
SMB_ACE4_FILE_INHERIT_ACE);
assert_int_equal(nfs4_ace->aceMask, SMB_ACE4_READ_DATA);
} else {
assert_int_equal(smb_get_naces(nfs4_acl), 2);
nfs4_ace_container = smb_first_ace4(nfs4_acl);
assert_non_null(nfs4_ace_container);
nfs4_ace = smb_get_ace4(nfs4_ace_container);
assert_int_equal(nfs4_ace->flags, 0);
assert_int_equal(nfs4_ace->who.uid, 1000);
assert_int_equal(nfs4_ace->aceFlags,
SMB_ACE4_FILE_INHERIT_ACE);
assert_int_equal(nfs4_ace->aceMask, SMB_ACE4_READ_DATA);
nfs4_ace_container = smb_next_ace4(nfs4_ace_container);
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, 0);
}
}
TALLOC_FREE(frame);
}
static void test_dacl_to_nfs4_config_special(void **state)
{
struct dom_sid *sids = *state;
TALLOC_CTX *frame = talloc_stackframe();
struct SMB4ACL_T *nfs4_acl;
struct SMB4ACE_T *nfs4_ace_container;
SMB_ACE4PROP_T *nfs4_ace;
struct security_ace dacl_aces[6];
struct security_acl *dacl;
struct smbacl4_vfs_params params = {
.mode = e_special,
.do_chown = true,
.acedup = e_dontcare,
.map_full_control = true,
};
/*
* global_sid_Creator_Owner or global_sid_Special_Group is NOT mapped
* to SMB_ACE4_ID_SPECIAL.
*/
init_sec_ace(&dacl_aces[0], &global_sid_Creator_Owner,
SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_FILE_READ_DATA,
SEC_ACE_FLAG_OBJECT_INHERIT);
init_sec_ace(&dacl_aces[1], &global_sid_Creator_Group,
SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_FILE_WRITE_DATA,
SEC_ACE_FLAG_CONTAINER_INHERIT);
/*
* Anything that maps to owner or owning group with inheritance flags
* IS mapped to special owner or special group.
*/
init_sec_ace(&dacl_aces[2], &sids[0],
SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_FILE_READ_DATA,
SEC_ACE_FLAG_OBJECT_INHERIT);
init_sec_ace(&dacl_aces[3], &sids[0],
SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_FILE_READ_DATA,
SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_INHERIT_ONLY);
init_sec_ace(&dacl_aces[4], &sids[1],
SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_FILE_READ_DATA,
SEC_ACE_FLAG_OBJECT_INHERIT);
init_sec_ace(&dacl_aces[5], &sids[1],
SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_FILE_READ_DATA,
SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_INHERIT_ONLY);
dacl = make_sec_acl(frame, SECURITY_ACL_REVISION_ADS,
ARRAY_SIZE(dacl_aces), dacl_aces);
assert_non_null(dacl);
nfs4_acl = smbacl4_win2nfs4(frame, true, dacl, &params, 1000, 1001);
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), 6);
nfs4_ace_container = smb_first_ace4(nfs4_acl);
assert_non_null(nfs4_ace_container);
nfs4_ace = smb_get_ace4(nfs4_ace_container);
assert_int_equal(nfs4_ace->flags, 0);
assert_int_equal(nfs4_ace->aceFlags, SMB_ACE4_FILE_INHERIT_ACE);
assert_int_equal(nfs4_ace->who.uid, 1003);
assert_int_equal(nfs4_ace->aceMask, SMB_ACE4_READ_DATA);
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, 0);
assert_int_equal(nfs4_ace->aceFlags,
SMB_ACE4_IDENTIFIER_GROUP|
SMB_ACE4_DIRECTORY_INHERIT_ACE);
assert_int_equal(nfs4_ace->who.gid, 1004);
assert_int_equal(nfs4_ace->aceMask, SMB_ACE4_WRITE_DATA);
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, SMB_ACE4_ID_SPECIAL);
assert_int_equal(nfs4_ace->who.special_id, SMB_ACE4_WHO_OWNER);
assert_int_equal(nfs4_ace->aceFlags, SMB_ACE4_FILE_INHERIT_ACE);
assert_int_equal(nfs4_ace->aceMask, SMB_ACE4_READ_DATA);
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, SMB_ACE4_ID_SPECIAL);
assert_int_equal(nfs4_ace->aceFlags, SMB_ACE4_DIRECTORY_INHERIT_ACE|
SMB_ACE4_INHERIT_ONLY_ACE);
assert_int_equal(nfs4_ace->who.special_id, SMB_ACE4_WHO_OWNER);
assert_int_equal(nfs4_ace->aceMask, SMB_ACE4_READ_DATA);
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, SMB_ACE4_ID_SPECIAL);
assert_int_equal(nfs4_ace->aceFlags, SMB_ACE4_IDENTIFIER_GROUP|
SMB_ACE4_FILE_INHERIT_ACE);
assert_int_equal(nfs4_ace->who.special_id, SMB_ACE4_WHO_GROUP);
assert_int_equal(nfs4_ace->aceMask, SMB_ACE4_READ_DATA);
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, SMB_ACE4_ID_SPECIAL);
assert_int_equal(nfs4_ace->aceFlags, SMB_ACE4_IDENTIFIER_GROUP|
SMB_ACE4_DIRECTORY_INHERIT_ACE|
SMB_ACE4_INHERIT_ONLY_ACE);
assert_int_equal(nfs4_ace->who.special_id, SMB_ACE4_WHO_GROUP);
assert_int_equal(nfs4_ace->aceMask, SMB_ACE4_READ_DATA);
assert_null(smb_next_ace4(nfs4_ace_container));
TALLOC_FREE(frame);
}
static void test_nfs4_to_dacl_config_special(void **state)
{
struct dom_sid *sids = *state;
TALLOC_CTX *frame = talloc_stackframe();
struct SMB4ACL_T *nfs4_acl;
SMB_ACE4PROP_T nfs4_ace;
struct security_ace *dacl_aces;
int good_aces;
struct smbacl4_vfs_params params = {
.mode = e_special,
.do_chown = true,
.acedup = e_dontcare,
.map_full_control = true,
};
nfs4_acl = smb_create_smb4acl(frame);
assert_non_null(nfs4_acl);
/*
* In config mode special, this is not mapped to Creator Owner
*/
nfs4_ace = (SMB_ACE4PROP_T) {
.flags = SMB_ACE4_ID_SPECIAL,
.who.special_id = SMB_ACE4_WHO_OWNER,
.aceType = SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE,
.aceFlags = SMB_ACE4_FILE_INHERIT_ACE,
.aceMask = SMB_ACE4_READ_DATA,
};
assert_non_null(smb_add_ace4(nfs4_acl, &nfs4_ace));
/*
* In config mode special, this is not mapped to Creator Group
*/
nfs4_ace = (SMB_ACE4PROP_T) {
.flags = SMB_ACE4_ID_SPECIAL,
.who.special_id = SMB_ACE4_WHO_GROUP,
.aceType = SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE,
.aceFlags = SMB_ACE4_DIRECTORY_INHERIT_ACE,
.aceMask = SMB_ACE4_WRITE_DATA,
};
assert_non_null(smb_add_ace4(nfs4_acl, &nfs4_ace));
assert_true(smbacl4_nfs42win(frame, &params, nfs4_acl,
&sids[0], &sids[1], true,
&dacl_aces, &good_aces));
assert_int_equal(good_aces, 2);
assert_non_null(dacl_aces);
assert_int_equal(dacl_aces[0].type, SEC_ACE_TYPE_ACCESS_ALLOWED);
assert_int_equal(dacl_aces[0].flags, SEC_ACE_FLAG_OBJECT_INHERIT);
assert_int_equal(dacl_aces[0].access_mask, SEC_FILE_READ_DATA);
assert_true(dom_sid_equal(&dacl_aces[0].trustee, &sids[0]));
assert_int_equal(dacl_aces[1].type, SEC_ACE_TYPE_ACCESS_ALLOWED);
assert_int_equal(dacl_aces[1].flags, SEC_ACE_FLAG_CONTAINER_INHERIT);
assert_int_equal(dacl_aces[1].access_mask, SEC_FILE_WRITE_DATA);
assert_true(dom_sid_equal(&dacl_aces[1].trustee, &sids[1]));
TALLOC_FREE(frame);
}
struct nfs_to_dacl_idmap_both {
uint32_t nfs4_flags;
uint32_t nfs4_id;
struct dom_sid *sid;
};
static void test_nfs4_to_dacl_idmap_type_both(void **state)
{
struct dom_sid *sids = *state;
TALLOC_CTX *frame = talloc_stackframe();
int i;
struct nfs_to_dacl_idmap_both nfs_to_dacl_idmap_both[] = {
{ 0, 1002, &sids[2] },
{ SMB_ACE4_IDENTIFIER_GROUP, 1002, &sids[2] },
{ 0, 1005, &sids[6] },
{ SMB_ACE4_IDENTIFIER_GROUP, 1005, &sids[6] },
};
for (i = 0; i < ARRAY_SIZE(nfs_to_dacl_idmap_both); i++) {
struct SMB4ACL_T *nfs4_acl;
struct security_ace *dacl_aces;
SMB_ACE4PROP_T nfs4_ace;
int good_aces;
struct smbacl4_vfs_params params = {
.mode = e_simple,
.do_chown = true,
.acedup = e_merge,
.map_full_control = true,
};
nfs4_acl = smb_create_smb4acl(frame);
assert_non_null(nfs4_acl);
nfs4_ace = (SMB_ACE4PROP_T) {
.flags = 0,
.aceType = SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE,
.aceFlags = nfs_to_dacl_idmap_both[i].nfs4_flags,
.aceMask = SMB_ACE4_READ_DATA,
};
if (nfs_to_dacl_idmap_both[i].nfs4_flags &
SMB_ACE4_IDENTIFIER_GROUP) {
nfs4_ace.who.gid = nfs_to_dacl_idmap_both[i].nfs4_id;
} else {
nfs4_ace.who.uid = nfs_to_dacl_idmap_both[i].nfs4_id;
}
assert_non_null(smb_add_ace4(nfs4_acl, &nfs4_ace));
assert_true(smbacl4_nfs42win(frame, &params, nfs4_acl,
&sids[2], &sids[2],
false, &dacl_aces, &good_aces));
assert_int_equal(good_aces, 1);
assert_non_null(dacl_aces);
assert_int_equal(dacl_aces[0].type,
SEC_ACE_TYPE_ACCESS_ALLOWED);
assert_int_equal(dacl_aces[0].flags, 0);
assert_int_equal(dacl_aces[0].access_mask, SEC_FILE_READ_DATA);
assert_true(dom_sid_equal(&dacl_aces[0].trustee,
nfs_to_dacl_idmap_both[i].sid));
}
TALLOC_FREE(frame);
}
struct dacl_to_nfs4_idmap_both {
struct dom_sid *sid;
uint32_t dacl_flags;
uint32_t nfs4_flags;
uint32_t nfs4_ace_flags;
uint32_t nfs4_id;
int num_nfs4_aces;
};
/*
* IDMAP_TYPE_BOTH always creates group entries.
*/
static void test_dacl_to_nfs4_idmap_type_both(void **state)
{
struct dom_sid *sids = *state;
TALLOC_CTX *frame = talloc_stackframe();
int i;
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,
2 },
{ &sids[2], SEC_ACE_FLAG_OBJECT_INHERIT,
0, SMB_ACE4_IDENTIFIER_GROUP|SMB_ACE4_FILE_INHERIT_ACE, 1002,
1 },
{ &sids[6], 0,
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,
1 },
};
for (i = 0; i < ARRAY_SIZE(dacl_to_nfs4_idmap_both); i++) {
struct SMB4ACL_T *nfs4_acl;
struct SMB4ACE_T *nfs4_ace_container;
SMB_ACE4PROP_T *nfs4_ace;
struct security_ace dacl_aces[1];
struct security_acl *dacl;
struct smbacl4_vfs_params params = {
.mode = e_simple,
.do_chown = true,
.acedup = e_merge,
.map_full_control = true,
};
init_sec_ace(&dacl_aces[0], dacl_to_nfs4_idmap_both[i].sid,
SEC_ACE_TYPE_ACCESS_ALLOWED,
SEC_FILE_READ_DATA,
dacl_to_nfs4_idmap_both[i].dacl_flags);
dacl = make_sec_acl(frame, SECURITY_ACL_REVISION_ADS,
ARRAY_SIZE(dacl_aces), dacl_aces);
assert_non_null(dacl);
nfs4_acl = smbacl4_win2nfs4(frame, true, dacl, &params,
1002, 1002);
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),
dacl_to_nfs4_idmap_both[i].num_nfs4_aces);
nfs4_ace_container = smb_first_ace4(nfs4_acl);
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);
if (nfs4_ace->flags & SMB_ACE4_ID_SPECIAL) {
assert_int_equal(nfs4_ace->who.special_id,
dacl_to_nfs4_idmap_both[i].nfs4_id);
} else if (nfs4_ace->aceFlags & SMB_ACE4_IDENTIFIER_GROUP) {
assert_int_equal(nfs4_ace->who.gid,
dacl_to_nfs4_idmap_both[i].nfs4_id);
} 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);
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);
}
static void test_nfs4_to_dacl_remove_duplicate(void **state)
{
struct dom_sid *sids = *state;
TALLOC_CTX *frame = talloc_stackframe();
struct SMB4ACL_T *nfs4_acl;
SMB_ACE4PROP_T nfs4_ace;
struct security_ace *dacl_aces;
int good_aces;
struct smbacl4_vfs_params params = {
.mode = e_simple,
.do_chown = true,
.acedup = e_dontcare,
.map_full_control = true,
};
nfs4_acl = smb_create_smb4acl(frame);
assert_non_null(nfs4_acl);
nfs4_ace = (SMB_ACE4PROP_T) {
.flags = 0,
.who.uid = 1002,
.aceType = SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE,
.aceFlags = SMB_ACE4_INHERITED_ACE,
.aceMask = SMB_ACE4_WRITE_DATA,
};
assert_non_null(smb_add_ace4(nfs4_acl, &nfs4_ace));
nfs4_ace = (SMB_ACE4PROP_T) {
.flags = 0,
.who.gid = 1002,
.aceType = SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE,
.aceFlags = SMB_ACE4_IDENTIFIER_GROUP|
SMB_ACE4_INHERITED_ACE,
.aceMask = SMB_ACE4_WRITE_DATA,
};
assert_non_null(smb_add_ace4(nfs4_acl, &nfs4_ace));
nfs4_ace = (SMB_ACE4PROP_T) {
.flags = 0,
.who.gid = 1002,
.aceType = SMB_ACE4_ACCESS_DENIED_ACE_TYPE,
.aceFlags = SMB_ACE4_IDENTIFIER_GROUP|
SMB_ACE4_INHERITED_ACE,
.aceMask = SMB_ACE4_WRITE_DATA,
};
assert_non_null(smb_add_ace4(nfs4_acl, &nfs4_ace));
nfs4_ace = (SMB_ACE4PROP_T) {
.flags = 0,
.who.gid = 1002,
.aceType = SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE,
.aceFlags = SMB_ACE4_IDENTIFIER_GROUP|
SMB_ACE4_INHERITED_ACE,
.aceMask = SMB_ACE4_WRITE_DATA,
};
assert_non_null(smb_add_ace4(nfs4_acl, &nfs4_ace));
assert_true(smbacl4_nfs42win(frame, &params, nfs4_acl,
&sids[0], &sids[1], true,
&dacl_aces, &good_aces));
assert_int_equal(good_aces, 2);
assert_non_null(dacl_aces);
assert_int_equal(dacl_aces[0].type, SEC_ACE_TYPE_ACCESS_ALLOWED);
assert_int_equal(dacl_aces[0].flags, SEC_ACE_FLAG_INHERITED_ACE);
assert_int_equal(dacl_aces[0].access_mask, SEC_FILE_WRITE_DATA);
assert_true(dom_sid_equal(&dacl_aces[0].trustee, &sids[2]));
assert_int_equal(dacl_aces[1].type, SEC_ACE_TYPE_ACCESS_DENIED);
assert_int_equal(dacl_aces[1].flags, SEC_ACE_FLAG_INHERITED_ACE);
assert_int_equal(dacl_aces[1].access_mask, SEC_FILE_WRITE_DATA);
assert_true(dom_sid_equal(&dacl_aces[1].trustee, &sids[2]));
TALLOC_FREE(frame);
}
int main(int argc, char **argv)
{
const struct CMUnitTest tests[] = {
cmocka_unit_test(test_cached_id_mappings),
cmocka_unit_test(test_empty_nfs4_to_dacl),
cmocka_unit_test(test_empty_dacl_to_nfs4),
cmocka_unit_test(test_acl_type_nfs4_to_dacl),
cmocka_unit_test(test_acl_type_dacl_to_nfs4),
cmocka_unit_test(test_ace_flags_nfs4_to_dacl),
cmocka_unit_test(test_ace_flags_dacl_to_nfs4),
cmocka_unit_test(test_nfs4_permissions_to_dacl),
cmocka_unit_test(test_dacl_permissions_to_nfs4),
cmocka_unit_test(test_special_nfs4_to_dacl),
cmocka_unit_test(test_dacl_to_special_nfs4),
cmocka_unit_test(test_dacl_creator_to_nfs4),
cmocka_unit_test(test_nfs4_to_dacl_creator),
cmocka_unit_test(test_full_control_nfs4_to_dacl),
cmocka_unit_test(test_dacl_to_nfs4_acedup_settings),
cmocka_unit_test(test_dacl_to_nfs4_acedup_match),
cmocka_unit_test(test_dacl_to_nfs4_config_special),
cmocka_unit_test(test_nfs4_to_dacl_config_special),
cmocka_unit_test(test_nfs4_to_dacl_idmap_type_both),
cmocka_unit_test(test_dacl_to_nfs4_idmap_type_both),
cmocka_unit_test(test_nfs4_to_dacl_remove_duplicate),
};
cmocka_set_message_output(CM_OUTPUT_SUBUNIT);
if (argc != 2) {
print_error("Usage: %s smb.conf\n", argv[0]);
exit(1);
}
/*
* Initialize enough of the Samba internals to have the
* mappings tests work.
*/
talloc_stackframe();
lp_load_global(argv[1]);
return cmocka_run_group_tests(tests, group_setup, group_teardown);
}