1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-25 23:21:54 +03:00
samba-mirror/source4/torture/vfs/acl_xattr.c
Ralph Boehme b72287514c vfs_acl_xattr|tdb: enforced settings when ignore system acls=yes
When "ignore system acls" is set to "yes, we need to ensure filesystem
permission always grant access so that when doing our own access checks
we don't run into situations where we grant access but the filesystem
doesn't.

Bug: https://bugzilla.samba.org/show_bug.cgi?id=12181

Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>

Autobuild-User(master): Ralph Böhme <slow@samba.org>
Autobuild-Date(master): Wed Aug 31 18:41:20 CEST 2016 on sn-devel-144
2016-08-31 18:41:20 +02:00

315 lines
10 KiB
C

/*
Unix SMB/CIFS implementation.
Copyright (C) Ralph Boehme 2016
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 "includes.h"
#include "lib/cmdline/popt_common.h"
#include "libcli/smb2/smb2.h"
#include "libcli/smb2/smb2_calls.h"
#include "libcli/smb/smbXcli_base.h"
#include "torture/torture.h"
#include "torture/vfs/proto.h"
#include "libcli/resolve/resolve.h"
#include "torture/util.h"
#include "torture/smb2/proto.h"
#include "libcli/security/security.h"
#include "librpc/gen_ndr/ndr_security.h"
#include "lib/param/param.h"
#define BASEDIR "smb2-testsd"
#define CHECK_SECURITY_DESCRIPTOR(_sd1, _sd2) do { \
if (!security_descriptor_equal(_sd1, _sd2)) { \
torture_warning(tctx, "security descriptors don't match!\n"); \
torture_warning(tctx, "got:\n"); \
NDR_PRINT_DEBUG(security_descriptor, _sd1); \
torture_warning(tctx, "expected:\n"); \
NDR_PRINT_DEBUG(security_descriptor, _sd2); \
torture_result(tctx, TORTURE_FAIL, \
"%s: security descriptors don't match!\n", \
__location__); \
ret = false; \
} \
} while (0)
/**
* SMB2 connect with explicit share
**/
static bool torture_smb2_con_share(struct torture_context *tctx,
const char *share,
struct smb2_tree **tree)
{
struct smbcli_options options;
NTSTATUS status;
const char *host = torture_setting_string(tctx, "host", NULL);
struct cli_credentials *credentials = cmdline_credentials;
lpcfg_smbcli_options(tctx->lp_ctx, &options);
status = smb2_connect_ext(tctx,
host,
lpcfg_smb_ports(tctx->lp_ctx),
share,
lpcfg_resolve_context(tctx->lp_ctx),
credentials,
0,
tree,
tctx->ev,
&options,
lpcfg_socket_options(tctx->lp_ctx),
lpcfg_gensec_settings(tctx, tctx->lp_ctx)
);
if (!NT_STATUS_IS_OK(status)) {
printf("Failed to connect to SMB2 share \\\\%s\\%s - %s\n",
host, share, nt_errstr(status));
return false;
}
return true;
}
static bool test_default_acl_posix(struct torture_context *tctx,
struct smb2_tree *tree_unused)
{
struct smb2_tree *tree = NULL;
NTSTATUS status;
bool ok;
bool ret = true;
const char *dname = BASEDIR "\\testdir";
const char *fname = BASEDIR "\\testdir\\testfile";
struct smb2_handle fhandle, dhandle;
union smb_fileinfo q;
union smb_setfileinfo set;
struct security_descriptor *sd = NULL;
struct security_descriptor *exp_sd = NULL;
char *owner_sid = NULL;
char *group_sid = NULL;
ok = torture_smb2_con_share(tctx, "acl_xattr_ign_sysacl_posix", &tree);
torture_assert_goto(tctx, ok == true, ret, done,
"Unable to connect to 'acl_xattr_ign_sysacl_posix'\n");
ok = smb2_util_setup_dir(tctx, tree, BASEDIR);
torture_assert_goto(tctx, ok == true, ret, done, "Unable to setup testdir\n");
ZERO_STRUCT(dhandle);
status = torture_smb2_testdir(tree, dname, &dhandle);
torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir\n");
torture_comment(tctx, "Get the original sd\n");
ZERO_STRUCT(q);
q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
q.query_secdesc.in.file.handle = dhandle;
q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER | SECINFO_GROUP;
status = smb2_getinfo_file(tree, tctx, &q);
torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_getinfo_file\n");
sd = q.query_secdesc.out.sd;
owner_sid = dom_sid_string(tctx, sd->owner_sid);
group_sid = dom_sid_string(tctx, sd->group_sid);
torture_comment(tctx, "owner [%s] group [%s]\n", owner_sid, group_sid);
torture_comment(tctx, "Set ACL with no inheritable ACE\n");
sd = security_descriptor_dacl_create(tctx,
0, NULL, NULL,
owner_sid,
SEC_ACE_TYPE_ACCESS_ALLOWED,
SEC_RIGHTS_DIR_ALL,
0,
NULL);
ZERO_STRUCT(set);
set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
set.set_secdesc.in.file.handle = dhandle;
set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
set.set_secdesc.in.sd = sd;
status = smb2_setinfo_file(tree, &set);
torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_setinfo_file\n");
TALLOC_FREE(sd);
smb2_util_close(tree, dhandle);
torture_comment(tctx, "Create file\n");
ZERO_STRUCT(fhandle);
status = torture_smb2_testfile(tree, fname, &fhandle);
torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create_complex_file\n");
torture_comment(tctx, "Query file SD\n");
ZERO_STRUCT(q);
q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
q.query_secdesc.in.file.handle = fhandle;
q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER | SECINFO_GROUP;
status = smb2_getinfo_file(tree, tctx, &q);
torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_getinfo_file\n");
sd = q.query_secdesc.out.sd;
smb2_util_close(tree, fhandle);
ZERO_STRUCT(fhandle);
torture_comment(tctx, "Checking actual file SD against expected SD\n");
exp_sd = security_descriptor_dacl_create(
tctx, 0, owner_sid, group_sid,
owner_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_RIGHTS_FILE_ALL, 0,
group_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, FILE_GENERIC_READ|FILE_GENERIC_WRITE|FILE_GENERIC_EXECUTE, 0,
SID_WORLD, SEC_ACE_TYPE_ACCESS_ALLOWED, FILE_GENERIC_READ|FILE_GENERIC_WRITE|FILE_GENERIC_EXECUTE, 0,
SID_NT_SYSTEM, SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_RIGHTS_FILE_ALL, 0,
NULL);
CHECK_SECURITY_DESCRIPTOR(sd, exp_sd);
done:
if (!smb2_util_handle_empty(fhandle)) {
smb2_util_close(tree, fhandle);
}
if (!smb2_util_handle_empty(dhandle)) {
smb2_util_close(tree, dhandle);
}
if (tree != NULL) {
smb2_deltree(tree, BASEDIR);
smb2_tdis(tree);
}
return ret;
}
static bool test_default_acl_win(struct torture_context *tctx,
struct smb2_tree *tree_unused)
{
struct smb2_tree *tree = NULL;
NTSTATUS status;
bool ok;
bool ret = true;
const char *dname = BASEDIR "\\testdir";
const char *fname = BASEDIR "\\testdir\\testfile";
struct smb2_handle fhandle, dhandle;
union smb_fileinfo q;
union smb_setfileinfo set;
struct security_descriptor *sd = NULL;
struct security_descriptor *exp_sd = NULL;
char *owner_sid = NULL;
char *group_sid = NULL;
ok = torture_smb2_con_share(tctx, "acl_xattr_ign_sysacl_windows", &tree);
torture_assert_goto(tctx, ok == true, ret, done,
"Unable to connect to 'acl_xattr_ign_sysacl_windows'\n");
ok = smb2_util_setup_dir(tctx, tree, BASEDIR);
torture_assert_goto(tctx, ok == true, ret, done, "Unable to setup testdir\n");
ZERO_STRUCT(dhandle);
status = torture_smb2_testdir(tree, dname, &dhandle);
torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir\n");
torture_comment(tctx, "Get the original sd\n");
ZERO_STRUCT(q);
q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
q.query_secdesc.in.file.handle = dhandle;
q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER | SECINFO_GROUP;
status = smb2_getinfo_file(tree, tctx, &q);
torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_getinfo_file\n");
sd = q.query_secdesc.out.sd;
owner_sid = dom_sid_string(tctx, sd->owner_sid);
group_sid = dom_sid_string(tctx, sd->group_sid);
torture_comment(tctx, "owner [%s] group [%s]\n", owner_sid, group_sid);
torture_comment(tctx, "Set ACL with no inheritable ACE\n");
sd = security_descriptor_dacl_create(tctx,
0, NULL, NULL,
owner_sid,
SEC_ACE_TYPE_ACCESS_ALLOWED,
SEC_RIGHTS_DIR_ALL,
0,
NULL);
ZERO_STRUCT(set);
set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
set.set_secdesc.in.file.handle = dhandle;
set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
set.set_secdesc.in.sd = sd;
status = smb2_setinfo_file(tree, &set);
torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_setinfo_file\n");
TALLOC_FREE(sd);
smb2_util_close(tree, dhandle);
torture_comment(tctx, "Create file\n");
ZERO_STRUCT(fhandle);
status = torture_smb2_testfile(tree, fname, &fhandle);
torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create_complex_file\n");
torture_comment(tctx, "Query file SD\n");
ZERO_STRUCT(q);
q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
q.query_secdesc.in.file.handle = fhandle;
q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER | SECINFO_GROUP;
status = smb2_getinfo_file(tree, tctx, &q);
torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_getinfo_file\n");
sd = q.query_secdesc.out.sd;
smb2_util_close(tree, fhandle);
ZERO_STRUCT(fhandle);
torture_comment(tctx, "Checking actual file SD against expected SD\n");
exp_sd = security_descriptor_dacl_create(
tctx, 0, owner_sid, group_sid,
owner_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_RIGHTS_FILE_ALL, 0,
SID_NT_SYSTEM, SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_RIGHTS_FILE_ALL, 0,
NULL);
CHECK_SECURITY_DESCRIPTOR(sd, exp_sd);
done:
if (!smb2_util_handle_empty(fhandle)) {
smb2_util_close(tree, fhandle);
}
if (!smb2_util_handle_empty(dhandle)) {
smb2_util_close(tree, dhandle);
}
if (tree != NULL) {
smb2_deltree(tree, BASEDIR);
smb2_tdis(tree);
}
return ret;
}
/*
basic testing of vfs_acl_xattr
*/
struct torture_suite *torture_acl_xattr(void)
{
struct torture_suite *suite = torture_suite_create(talloc_autofree_context(), "acl_xattr");
torture_suite_add_1smb2_test(suite, "default-acl-style-posix", test_default_acl_posix);
torture_suite_add_1smb2_test(suite, "default-acl-style-windows", test_default_acl_win);
suite->description = talloc_strdup(suite, "vfs_acl_xattr tests");
return suite;
}