[SCM] Samba Shared Repository - branch v4-9-test updated
Karolin Seeger
kseeger at samba.org
Mon Mar 11 12:26:03 UTC 2019
The branch, v4-9-test has been updated
via 43957ab96e7 libcli/security: fix handling of deny type ACEs in access_check_max_allowed()
via 4fe9eff4dd6 s4:torture: Add test_deny1().
via 824a058aa92 s4:torture: Add test_owner_rights_deny1().
via b4289aa34ae libcli/security: correct access check and maximum access calculation for Owner Rights ACEs
via f801b824815 s4:torture: Add test_owner_rights_deny().
via b1ce4d436a1 s4:torture: Fix the test_owner_rights() test to show permissions are additive.
via 8f9858671fd libcli/security: add "Owner Rights" calculation to access_check_max_allowed()
via 2a7e1bb9c03 s4:torture: add a Maximum Access check with an Owner Rights ACE
via 953039c7a78 s4:libcli: remember return code from maximum access
via 9dc374fee03 sambaundoguididx: use the right escaped oder unescaped sam ldb files
via f8748b8bfc2 s4-server: Open and close a transaction on sam.ldb at startup
from 47fb4ba84f3 vfs_ceph: remove ceph_fallocate/ceph_ftruncate fallback
https://git.samba.org/?p=samba.git;a=shortlog;h=v4-9-test
- Log -----------------------------------------------------------------
commit 43957ab96e7f62c83fe3e46e7467b974ea44f99b
Author: Ralph Boehme <slow at samba.org>
Date: Fri Mar 1 18:57:23 2019 +0100
libcli/security: fix handling of deny type ACEs in access_check_max_allowed()
Deny ACEs must always be evaluated against explicitly granted rights
from previous ACEs.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13812
Signed-off-by: Ralph Boehme <slow at samba.org>
Reviewed-by: Jeremy Allison <jra at samba.org>
(cherry picked from commit 8d355dd9769e8990ce998b4c9f28977669b43616)
Autobuild-User(v4-9-test): Karolin Seeger <kseeger at samba.org>
Autobuild-Date(v4-9-test): Mon Mar 11 12:25:05 UTC 2019 on sn-devel-144
commit 4fe9eff4dd63cd7aca4caa63057e27399cc3b929
Author: Ralph Boehme <slow at samba.org>
Date: Sun Mar 3 08:33:51 2019 +0100
s4:torture: Add test_deny1().
Creates a 2-element ALLOW + DENY ACE showing that when calculating
effective permissions and maximum access already seen allow bits are not
removed.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13812
Signed-off-by: Ralph Boehme <slow at samba.org>
Reviewed-by: Jeremy Allison <jra at samba.org>
(cherry picked from commit b205d695d769e910a91bec87451dec189ec33740)
commit 824a058aa92a379fb4c0078e8f4594724419d1ae
Author: Jeremy Allison <jra at samba.org>
Date: Thu Feb 28 14:59:01 2019 -0800
s4:torture: Add test_owner_rights_deny1().
Creates a 3-element ALLOW + ALLOW + DENY ACE showing that when
calculating maximum access already seen allow bits are not removed.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13812
Signed-off-by: Jeremy Allison <jra at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
(cherry picked from commit 0ebd8c99aed28a0ba43a22c429837f66f7e94409)
commit b4289aa34ae88c28a4b68214e33c57abc98e2f7a
Author: Ralph Boehme <slow at samba.org>
Date: Fri Mar 1 18:20:35 2019 +0100
libcli/security: correct access check and maximum access calculation for Owner Rights ACEs
We basically must process the Owner Rights ACEs as any other ACE wrt to the
order of adding granted permissions and checking denied permissions. According
to MS-DTYP 2.5.3.2 Owner Rights ACEs must be evaluated in the main loop over
the ACEs in an ACL and the corresponding access_mask must be directly applied
to bits_remaining. We currently defer this to after the loop over the ACEs in
ACL, this is wrong.
We just have to do some initial magic to determine if an ACL contains and
Owner Rights ACEs, and in case it doesn't we grant SEC_STD_WRITE_DAC |
SEC_STD_READ_CONTROL at the *beginning*. MS-DTYP:
-- the owner of an object is always granted READ_CONTROL and WRITE_DAC.
CALL SidInToken(Token, SecurityDescriptor.Owner, PrincipalSelfSubst)
IF SidInToken returns True THEN
IF DACL does not contain ACEs from object owner THEN
Remove READ_CONTROL and WRITE_DAC from RemainingAccess
Set GrantedAccess to GrantedAccess or READ_CONTROL or WRITE_OWNER
END IF
END IF
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13812
Signed-off-by: Ralph Boehme <slow at samba.org>
Reviewed-by: Jeremy Allison <jra at samba.org>
(cherry picked from commit 9722f75757c0e38c7f42c7cc310d56aa6eaf6392)
commit f801b824815ca310731dd9243ab091af3a2d9802
Author: Jeremy Allison <jra at samba.org>
Date: Thu Feb 28 14:37:09 2019 -0800
s4:torture: Add test_owner_rights_deny().
Shows that owner and SID_OWNER_RIGHTS ACE
entries interact in max permissions requests.
Tested against Windows.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13812
Signed-off-by: Jeremy Allison <jra at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
(cherry picked from commit fadc4c1bc5fcc3b2d9daea44ef8daf8a8ae0fbe2)
commit b1ce4d436a122e0fc15bc41219839fd74941b87c
Author: Jeremy Allison <jra at samba.org>
Date: Thu Feb 28 13:55:31 2019 -0800
s4:torture: Fix the test_owner_rights() test to show permissions are additive.
Tested against Windows.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13812
Signed-off-by: Jeremy Allison <jra at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
(cherry picked from commit 2e181e34c48c879235c5dc64bd7ab2b59781810c)
commit 8f9858671fd720f9fe67754eb4b39f786840b824
Author: Ralph Boehme <slow at samba.org>
Date: Wed Feb 27 18:07:03 2019 +0100
libcli/security: add "Owner Rights" calculation to access_check_max_allowed()
This was missing in 44590c1b70c0a24f853c02d5fcdb3c609401e2ca.
Bug: https://bugzilla.samba.org/show_bug.cgi?id=13812
Signed-off-by: Ralph Boehme <slow at samba.org>
Reviewed-by: David Disseldorp <ddiss at samba.org>
Autobuild-User(master): David Disseldorp <ddiss at samba.org>
Autobuild-Date(master): Thu Feb 28 19:18:16 UTC 2019 on sn-devel-144
(cherry picked from commit 5cf0764bc4b65dbc59d8626760dbe946a2234833)
commit 2a7e1bb9c0344d71de1ab4bb841046b764bedc17
Author: Ralph Boehme <slow at samba.org>
Date: Thu Feb 28 14:48:02 2019 +0100
s4:torture: add a Maximum Access check with an Owner Rights ACE
Bug: https://bugzilla.samba.org/show_bug.cgi?id=13812
Signed-off-by: Ralph Boehme <slow at samba.org>
Reviewed-by: David Disseldorp <ddiss at samba.org>
(cherry picked from commit 3ca38d2cd1189a5040e13ddab016063280be2b4d)
commit 953039c7a78ffdd1f4f66492b89f10f19aeaee9e
Author: Ralph Boehme <slow at samba.org>
Date: Thu Feb 28 14:47:18 2019 +0100
s4:libcli: remember return code from maximum access
Bug: https://bugzilla.samba.org/show_bug.cgi?id=13812
Signed-off-by: Ralph Boehme <slow at samba.org>
Reviewed-by: David Disseldorp <ddiss at samba.org>
(cherry picked from commit 9f4ee05295827c9a607e1f63694a17906f777176)
commit 9dc374fee03a2468912c9eabdfa1637c0cea6bf3
Author: Björn Jacke <bj at sernet.de>
Date: Wed Jan 23 14:01:26 2019 +0100
sambaundoguididx: use the right escaped oder unescaped sam ldb files
the correct filename is taken from the partition database before, we should not
unescape that because this can result in a new unescaped ldb file being created
and the script not to work at all.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13759
Signed-off-by: Bjoern Jacke <bjacke at samba.org>
Reviewed-by: Andreas Schneider <asn at samba.org>
(cherry picked from commit cd1ac3668cd164bd5f7cadf7b59df9541aaef83e)
commit f8748b8bfc20ab67bc53a8324495fa7b4f49a794
Author: Andrew Bartlett <abartlet at samba.org>
Date: Tue Mar 5 01:38:41 2019 +0000
s4-server: Open and close a transaction on sam.ldb at startup
This fixes upgrading from 4.7 and earlier releases, and makes the DB
reindexing more transparent. It should also make it easier to handle
future normalisation rule changes, e.g. if we change the pack-format
of integer indexes in a future release.
Without this change, the should have still handled reindexing the
database. We don't know why exactly this wasn't happening correctly,
but opening a transaction early in the samba process startup should
now guarantee that the DB is correctly reindexed by the time the main
samba code runs.
An alternative fix would have been to open a transaction in the the
DSDB module stack every time we connect to the database. However, this
would add an extra write lock every time we open the DB, whereas
starting samba happens much more infrequently.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13760
Signed-off-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Tim Beale <timbeale at catalyst.net.nz>
Reviewed-by: Gary Lockyer <gary at catalyst.net.nz>
Autobuild-User(master): Andrew Bartlett <abartlet at samba.org>
Autobuild-Date(master): Thu Mar 7 04:58:42 UTC 2019 on sn-devel-144
(cherry picked from commit 8b18da27cf261b0283fe66d2b827cab542488ac7)
-----------------------------------------------------------------------
Summary of changes:
libcli/security/access_check.c | 127 +++++---
source4/libcli/raw/interfaces.h | 1 +
source4/libcli/smb2/create.c | 4 +-
source4/scripting/bin/sambaundoguididx | 3 +-
source4/smbd/server.c | 42 +++
source4/torture/smb2/acls.c | 558 +++++++++++++++++++++++++++++++++
6 files changed, 682 insertions(+), 53 deletions(-)
Changeset truncated at 500 lines:
diff --git a/libcli/security/access_check.c b/libcli/security/access_check.c
index 03a7dca4adf..322f4fdb0c6 100644
--- a/libcli/security/access_check.c
+++ b/libcli/security/access_check.c
@@ -109,24 +109,61 @@ static uint32_t access_check_max_allowed(const struct security_descriptor *sd,
const struct security_token *token)
{
uint32_t denied = 0, granted = 0;
+ bool am_owner = false;
+ bool have_owner_rights_ace = false;
unsigned i;
+ if (sd->dacl == NULL) {
+ if (security_token_has_sid(token, sd->owner_sid)) {
+ granted |= SEC_STD_WRITE_DAC | SEC_STD_READ_CONTROL;
+ }
+ return granted;
+ }
+
if (security_token_has_sid(token, sd->owner_sid)) {
- granted |= SEC_STD_WRITE_DAC | SEC_STD_READ_CONTROL;
+ /*
+ * Check for explicit owner rights: if there are none, we remove
+ * the default owner right SEC_STD_WRITE_DAC|SEC_STD_READ_CONTROL
+ * from remaining_access. Otherwise we just process the
+ * explicitly granted rights when processing the ACEs.
+ */
+ am_owner = true;
+
+ for (i=0; i < sd->dacl->num_aces; i++) {
+ struct security_ace *ace = &sd->dacl->aces[i];
+
+ if (ace->flags & SEC_ACE_FLAG_INHERIT_ONLY) {
+ continue;
+ }
+
+ have_owner_rights_ace = dom_sid_equal(
+ &ace->trustee, &global_sid_Owner_Rights);
+ if (have_owner_rights_ace) {
+ break;
+ }
+ }
}
- if (sd->dacl == NULL) {
- return granted & ~denied;
+ if (am_owner && !have_owner_rights_ace) {
+ granted |= SEC_STD_WRITE_DAC|SEC_STD_READ_CONTROL;
}
for (i = 0;i<sd->dacl->num_aces; i++) {
struct security_ace *ace = &sd->dacl->aces[i];
+ bool is_owner_rights_ace = false;
if (ace->flags & SEC_ACE_FLAG_INHERIT_ONLY) {
continue;
}
- if (!security_token_has_sid(token, &ace->trustee)) {
+ if (am_owner) {
+ is_owner_rights_ace = dom_sid_equal(
+ &ace->trustee, &global_sid_Owner_Rights);
+ }
+
+ if (!is_owner_rights_ace &&
+ !security_token_has_sid(token, &ace->trustee))
+ {
continue;
}
@@ -136,7 +173,7 @@ static uint32_t access_check_max_allowed(const struct security_descriptor *sd,
break;
case SEC_ACE_TYPE_ACCESS_DENIED:
case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT:
- denied |= ace->access_mask;
+ denied |= ~granted & ace->access_mask;
break;
default: /* Other ACE types not handled/supported */
break;
@@ -159,16 +196,8 @@ NTSTATUS se_access_check(const struct security_descriptor *sd,
uint32_t i;
uint32_t bits_remaining;
uint32_t explicitly_denied_bits = 0;
- /*
- * Up until Windows Server 2008, owner always had these rights. Now
- * we have to use Owner Rights perms if they are on the file.
- *
- * In addition we have to accumulate these bits and apply them
- * correctly. See bug #8795
- */
- uint32_t owner_rights_allowed = 0;
- uint32_t owner_rights_denied = 0;
- bool owner_rights_default = true;
+ bool am_owner = false;
+ bool have_owner_rights_ace = false;
*access_granted = access_desired;
bits_remaining = access_desired;
@@ -198,35 +227,50 @@ NTSTATUS se_access_check(const struct security_descriptor *sd,
goto done;
}
+ if (security_token_has_sid(token, sd->owner_sid)) {
+ /*
+ * Check for explicit owner rights: if there are none, we remove
+ * the default owner right SEC_STD_WRITE_DAC|SEC_STD_READ_CONTROL
+ * from remaining_access. Otherwise we just process the
+ * explicitly granted rights when processing the ACEs.
+ */
+ am_owner = true;
+
+ for (i=0; i < sd->dacl->num_aces; i++) {
+ struct security_ace *ace = &sd->dacl->aces[i];
+
+ if (ace->flags & SEC_ACE_FLAG_INHERIT_ONLY) {
+ continue;
+ }
+
+ have_owner_rights_ace = dom_sid_equal(
+ &ace->trustee, &global_sid_Owner_Rights);
+ if (have_owner_rights_ace) {
+ break;
+ }
+ }
+ }
+ if (am_owner && !have_owner_rights_ace) {
+ bits_remaining &= ~(SEC_STD_WRITE_DAC | SEC_STD_READ_CONTROL);
+ }
+
/* check each ace in turn. */
for (i=0; bits_remaining && i < sd->dacl->num_aces; i++) {
struct security_ace *ace = &sd->dacl->aces[i];
+ bool is_owner_rights_ace = false;
if (ace->flags & SEC_ACE_FLAG_INHERIT_ONLY) {
continue;
}
- /*
- * We need the Owner Rights permissions to ensure we
- * give or deny the correct permissions to the owner. Replace
- * owner_rights with the perms here if it is present.
- *
- * We don't care if we are not the owner because that is taken
- * care of below when we check if our token has the owner SID.
- *
- */
- if (dom_sid_equal(&ace->trustee, &global_sid_Owner_Rights)) {
- if (ace->type == SEC_ACE_TYPE_ACCESS_ALLOWED) {
- owner_rights_allowed |= ace->access_mask;
- owner_rights_default = false;
- } else if (ace->type == SEC_ACE_TYPE_ACCESS_DENIED) {
- owner_rights_denied |= (bits_remaining & ace->access_mask);
- owner_rights_default = false;
- }
- continue;
+ if (am_owner) {
+ is_owner_rights_ace = dom_sid_equal(
+ &ace->trustee, &global_sid_Owner_Rights);
}
- if (!security_token_has_sid(token, &ace->trustee)) {
+ if (!is_owner_rights_ace &&
+ !security_token_has_sid(token, &ace->trustee))
+ {
continue;
}
@@ -246,21 +290,6 @@ NTSTATUS se_access_check(const struct security_descriptor *sd,
/* Explicitly denied bits always override */
bits_remaining |= explicitly_denied_bits;
- /* The owner always gets owner rights as defined above. */
- if (security_token_has_sid(token, sd->owner_sid)) {
- if (owner_rights_default) {
- /*
- * Just remove them, no need to check if they are
- * there.
- */
- bits_remaining &= ~(SEC_STD_WRITE_DAC |
- SEC_STD_READ_CONTROL);
- } else {
- bits_remaining &= ~owner_rights_allowed;
- bits_remaining |= owner_rights_denied;
- }
- }
-
/*
* We check privileges here because they override even DENY entries.
*/
diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h
index 732ba1512dc..43a53f834df 100644
--- a/source4/libcli/raw/interfaces.h
+++ b/source4/libcli/raw/interfaces.h
@@ -1779,6 +1779,7 @@ union smb_open {
/* uint32_t blob_size; */
/* optional return values matching tagged values in the call */
+ uint32_t maximal_access_status;
uint32_t maximal_access;
uint8_t on_disk_id[32];
struct smb2_lease lease_response;
diff --git a/source4/libcli/smb2/create.c b/source4/libcli/smb2/create.c
index 550069a6cea..eb0f6a421cd 100644
--- a/source4/libcli/smb2/create.c
+++ b/source4/libcli/smb2/create.c
@@ -360,12 +360,12 @@ NTSTATUS smb2_create_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, struct
/* pull out the parsed blobs */
for (i=0;i<io->out.blobs.num_blobs;i++) {
if (strcmp(io->out.blobs.blobs[i].tag, SMB2_CREATE_TAG_MXAC) == 0) {
- /* TODO: this also contains a status field in
- first 4 bytes */
if (io->out.blobs.blobs[i].data.length != 8) {
smb2_request_destroy(req);
return NT_STATUS_INVALID_NETWORK_RESPONSE;
}
+ io->out.maximal_access_status =
+ IVAL(io->out.blobs.blobs[i].data.data, 0);
io->out.maximal_access = IVAL(io->out.blobs.blobs[i].data.data, 4);
}
if (strcmp(io->out.blobs.blobs[i].tag, SMB2_CREATE_TAG_QFID) == 0) {
diff --git a/source4/scripting/bin/sambaundoguididx b/source4/scripting/bin/sambaundoguididx
index 24a95e20d7f..41d2030e075 100755
--- a/source4/scripting/bin/sambaundoguididx
+++ b/source4/scripting/bin/sambaundoguididx
@@ -57,8 +57,7 @@ privatedir = os.path.dirname(url)
dbs = []
for part in partitions[0]['partition']:
- file_quoted = part.split(":")[1]
- tdbname = urllib.unquote(file_quoted)
+ tdbname = part.split(":")[1]
tdbpath = os.path.join(privatedir, tdbname)
db = ldb.Ldb(url=tdbpath, options=["modules:"])
diff --git a/source4/smbd/server.c b/source4/smbd/server.c
index db570710ca9..e0255523824 100644
--- a/source4/smbd/server.c
+++ b/source4/smbd/server.c
@@ -230,6 +230,41 @@ _NORETURN_ static void max_runtime_handler(struct tevent_context *ev,
exit(0);
}
+/*
+ * When doing an in-place upgrade of Samba, the database format may have
+ * changed between versions. E.g. between 4.7 and 4.8 the DB changed from
+ * DN-based indexes to GUID-based indexes, so we have to re-index the DB after
+ * upgrading.
+ * This function handles migrating an older samba DB to a new Samba release.
+ * Note that we have to maintain DB compatibility between *all* older versions
+ * of Samba, not just the ones still under maintenance support.
+ */
+static int handle_inplace_db_upgrade(struct ldb_context *ldb_ctx)
+{
+ int ret;
+
+ /*
+ * The DSDB stack will handle reindexing the DB (if needed) upon the first
+ * DB write. Open and close a transaction on the DB now to trigger a
+ * reindex if required, rather than waiting for the first write.
+ * We do this here to guarantee that the DB will have been re-indexed by
+ * the time the main samba code runs.
+ * Refer to dsdb_schema_set_indices_and_attributes() for the actual reindexing
+ * code, called from
+ * source4/dsdb/samdb/ldb_modules/schema_load.c:schema_load_start_transaction()
+ */
+ ret = ldb_transaction_start(ldb_ctx);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+
+ ret = ldb_transaction_commit(ldb_ctx);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+ return LDB_SUCCESS;
+}
+
/*
pre-open the key databases. This saves a lot of time in child
processes
@@ -262,6 +297,13 @@ static int prime_ldb_databases(struct tevent_context *event_ctx, bool *am_backup
talloc_free(db_context);
return LDB_ERR_OPERATIONS_ERROR;
}
+
+ ret = handle_inplace_db_upgrade(ldb_ctx);
+ if (ret != LDB_SUCCESS) {
+ talloc_free(db_context);
+ return ret;
+ }
+
pdb = privilege_connect(db_context, cmdline_lp_ctx);
if (pdb == NULL) {
talloc_free(db_context);
diff --git a/source4/torture/smb2/acls.c b/source4/torture/smb2/acls.c
index 6178e211034..7bccce803f0 100644
--- a/source4/torture/smb2/acls.c
+++ b/source4/torture/smb2/acls.c
@@ -2363,6 +2363,557 @@ done:
return ret;
}
+/*
+ * test Owner Rights, S-1-3-4
+ */
+static bool test_owner_rights(struct torture_context *tctx,
+ struct smb2_tree *tree)
+{
+ const char *fname = BASEDIR "\\owner_right.txt";
+ struct smb2_create cr;
+ struct smb2_handle handle = {{0}};
+ union smb_fileinfo gi;
+ union smb_setfileinfo si;
+ struct security_descriptor *sd_orig = NULL;
+ struct security_descriptor *sd = NULL;
+ const char *owner_sid = NULL;
+ NTSTATUS mxac_status;
+ NTSTATUS status;
+ bool ret = true;
+
+ smb2_deltree(tree, BASEDIR);
+
+ ret = smb2_util_setup_dir(tctx, tree, BASEDIR);
+ torture_assert_goto(tctx, ret, ret, done,
+ "smb2_util_setup_dir failed\n");
+
+ torture_comment(tctx, "TESTING OWNER RIGHTS\n");
+
+ cr = (struct smb2_create) {
+ .in.desired_access = SEC_STD_READ_CONTROL |
+ SEC_STD_WRITE_DAC |SEC_STD_WRITE_OWNER,
+ .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
+ .in.share_access = NTCREATEX_SHARE_ACCESS_MASK,
+ .in.create_disposition = NTCREATEX_DISP_OPEN_IF,
+ .in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS,
+ .in.fname = fname,
+ };
+
+ status = smb2_create(tree, tctx, &cr);
+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
+ "smb2_create failed\n");
+ handle = cr.out.file.handle;
+
+ torture_comment(tctx, "get the original sd\n");
+
+ gi = (union smb_fileinfo) {
+ .query_secdesc.level = RAW_FILEINFO_SEC_DESC,
+ .query_secdesc.in.file.handle = handle,
+ .query_secdesc.in.secinfo_flags = SECINFO_DACL|SECINFO_OWNER,
+ };
+
+ status = smb2_getinfo_file(tree, tctx, &gi);
+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
+ "smb2_getinfo_file failed\n");
+
+ sd_orig = gi.query_secdesc.out.sd;
+ owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
+
+ /*
+ * Add a 2 element ACL
+ * SEC_RIGHTS_FILE_READ for the owner,
+ * SEC_FILE_WRITE_DATA for SID_OWNER_RIGHTS.
+ *
+ * Proves that the owner and SID_OWNER_RIGHTS
+ * ACE entries are additive.
+ */
+ sd = security_descriptor_dacl_create(tctx, 0, NULL, NULL,
+ owner_sid,
+ SEC_ACE_TYPE_ACCESS_ALLOWED,
+ SEC_RIGHTS_FILE_READ,
+ 0,
+ SID_OWNER_RIGHTS,
+ SEC_ACE_TYPE_ACCESS_ALLOWED,
+ SEC_FILE_WRITE_DATA,
+ 0,
+ NULL);
+ torture_assert_not_null_goto(tctx, sd, ret, done,
+ "SD create failed\n");
+
+ si = (union smb_setfileinfo) {
+ .set_secdesc.level = RAW_SFILEINFO_SEC_DESC,
+ .set_secdesc.in.file.handle = handle,
+ .set_secdesc.in.secinfo_flags = SECINFO_DACL,
+ .set_secdesc.in.sd = sd,
+ };
+
+ status = smb2_setinfo_file(tree, &si);
+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
+ "smb2_setinfo_file failed\n");
+
+ status = smb2_util_close(tree, handle);
+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
+ "smb2_util_close failed\n");
+ ZERO_STRUCT(handle);
+
+ cr = (struct smb2_create) {
+ .in.desired_access = SEC_STD_READ_CONTROL,
+ .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
+ .in.share_access = NTCREATEX_SHARE_ACCESS_MASK,
+ .in.create_disposition = NTCREATEX_DISP_OPEN_IF,
+ .in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS,
+ .in.query_maximal_access = true,
+ .in.fname = fname,
+ };
+
+ status = smb2_create(tree, tctx, &cr);
+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
+ "smb2_setinfo_file failed\n");
+ handle = cr.out.file.handle;
+
+ mxac_status = NT_STATUS(cr.out.maximal_access_status);
+ torture_assert_ntstatus_ok_goto(tctx, mxac_status, ret, done,
+ "smb2_setinfo_file failed\n");
+
+ /*
+ * For some reasons Windows 2016 doesn't set SEC_STD_DELETE but we
+ * do. Mask it out so the test passes against Samba and Windows.
+ */
+ torture_assert_int_equal_goto(tctx,
+ cr.out.maximal_access & ~SEC_STD_DELETE,
+ SEC_RIGHTS_FILE_READ |
+ SEC_FILE_WRITE_DATA,
+ ret, done,
+ "Wrong maximum access\n");
+
+ status = smb2_util_close(tree, handle);
+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
+ "smb2_util_close failed\n");
+ ZERO_STRUCT(handle);
+
+done:
+ if (!smb2_util_handle_empty(handle)) {
+ smb2_util_close(tree, handle);
+ }
+ smb2_deltree(tree, BASEDIR);
+ return ret;
+}
+
+/*
+ * test Owner Rights with a leading DENY ACE, S-1-3-4
+ */
+static bool test_owner_rights_deny(struct torture_context *tctx,
+ struct smb2_tree *tree)
+{
+ const char *fname = BASEDIR "\\owner_right_deny.txt";
+ struct smb2_create cr;
+ struct smb2_handle handle = {{0}};
+ union smb_fileinfo gi;
+ union smb_setfileinfo si;
+ struct security_descriptor *sd_orig = NULL;
+ struct security_descriptor *sd = NULL;
+ const char *owner_sid = NULL;
+ NTSTATUS mxac_status;
+ NTSTATUS status;
+ bool ret = true;
+
+ smb2_deltree(tree, BASEDIR);
+
+ ret = smb2_util_setup_dir(tctx, tree, BASEDIR);
+ torture_assert_goto(tctx, ret, ret, done,
+ "smb2_util_setup_dir failed\n");
+
+ torture_comment(tctx, "TESTING OWNER RIGHTS DENY\n");
+
+ cr = (struct smb2_create) {
+ .in.desired_access = SEC_STD_READ_CONTROL |
+ SEC_STD_WRITE_DAC |SEC_STD_WRITE_OWNER,
+ .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
+ .in.share_access = NTCREATEX_SHARE_ACCESS_MASK,
+ .in.create_disposition = NTCREATEX_DISP_OPEN_IF,
+ .in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS,
+ .in.fname = fname,
+ };
+
+ status = smb2_create(tree, tctx, &cr);
+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
+ "smb2_create failed\n");
+ handle = cr.out.file.handle;
+
+ torture_comment(tctx, "get the original sd\n");
+
+ gi = (union smb_fileinfo) {
+ .query_secdesc.level = RAW_FILEINFO_SEC_DESC,
+ .query_secdesc.in.file.handle = handle,
+ .query_secdesc.in.secinfo_flags = SECINFO_DACL|SECINFO_OWNER,
+ };
+
+ status = smb2_getinfo_file(tree, tctx, &gi);
+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
+ "smb2_getinfo_file failed\n");
+
+ sd_orig = gi.query_secdesc.out.sd;
+ owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
+
+ /*
+ * Add a 2 element ACL
+ * DENY SEC_FILE_DATA_READ for SID_OWNER_RIGHTS
+ * SEC_FILE_READ_DATA for the owner.
+ *
--
Samba Shared Repository
More information about the samba-cvs
mailing list