summaryrefslogtreecommitdiff
path: root/source4
diff options
context:
space:
mode:
authorDavid Mulder <dmulder@suse.com>2019-12-10 07:47:12 -0700
committerJeremy Allison <jra@samba.org>2019-12-20 22:01:28 +0000
commit946beafb621c6a5353a87c40264f53a253249c52 (patch)
treef603d8824610423542ce84509330fabecb139b23 /source4
parent670205acab186448e175433225bfebacf3500900 (diff)
downloadsamba-946beafb621c6a5353a87c40264f53a253249c52.tar.gz
Convert samba4.base.*attr tests to smb2
Signed-off-by: David Mulder <dmulder@suse.com> Reviewed-by: Ralph Böhme <slow@samba.org> Reviewed-by: Jeremy Allison <jra@samba.org>
Diffstat (limited to 'source4')
-rw-r--r--source4/libcli/smb2/util.c46
-rw-r--r--source4/torture/smb2/attr.c496
-rw-r--r--source4/torture/smb2/smb2.c2
-rw-r--r--source4/torture/smb2/wscript_build1
4 files changed, 545 insertions, 0 deletions
diff --git a/source4/libcli/smb2/util.c b/source4/libcli/smb2/util.c
index 94072bee3ea..882dcb9468b 100644
--- a/source4/libcli/smb2/util.c
+++ b/source4/libcli/smb2/util.c
@@ -99,6 +99,52 @@ NTSTATUS smb2_util_setatr(struct smb2_tree *tree, const char *name, uint32_t att
}
+/*
+ get file attribute with SMB2
+*/
+NTSTATUS smb2_util_getatr(struct smb2_tree *tree, const char *fname,
+ uint16_t *attr, size_t *size, time_t *t)
+{
+ union smb_fileinfo parms;
+ NTSTATUS status;
+ struct smb2_create create_io = {0};
+
+ create_io.in.desired_access = SEC_FILE_READ_ATTRIBUTE;
+ create_io.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
+ create_io.in.create_disposition = FILE_OPEN;
+ create_io.in.fname = fname;
+ status = smb2_create(tree, tree, &create_io);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ ZERO_STRUCT(parms);
+ parms.all_info2.level = RAW_FILEINFO_SMB2_ALL_INFORMATION;
+ parms.all_info2.in.file.handle = create_io.out.file.handle;
+ status = smb2_getinfo_file(tree, tree, &parms);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ status = smb2_util_close(tree, create_io.out.file.handle);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ if (size) {
+ *size = parms.all_info2.out.size;
+ }
+
+ if (t) {
+ *t = parms.all_info2.out.write_time;
+ }
+
+ if (attr) {
+ *attr = parms.all_info2.out.attrib;
+ }
+
+ return status;
+}
/*
diff --git a/source4/torture/smb2/attr.c b/source4/torture/smb2/attr.c
new file mode 100644
index 00000000000..5947997c05f
--- /dev/null
+++ b/source4/torture/smb2/attr.c
@@ -0,0 +1,496 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ openattr tester
+
+ Copyright (C) Andrew Tridgell 2003
+ Copyright (C) David Mulder 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 "includes.h"
+#include "libcli/smb2/smb2.h"
+#include "libcli/smb2/smb2_calls.h"
+#include "torture/torture.h"
+#include "libcli/security/security_descriptor.h"
+#include "torture/smb2/proto.h"
+
+static const uint32_t open_attrs_table[] = {
+ FILE_ATTRIBUTE_NORMAL,
+ FILE_ATTRIBUTE_ARCHIVE,
+ FILE_ATTRIBUTE_READONLY,
+ FILE_ATTRIBUTE_HIDDEN,
+ FILE_ATTRIBUTE_SYSTEM,
+
+ FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
+ FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
+ FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
+ FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
+ FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
+ FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
+
+ FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
+ FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
+ FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
+ FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
+};
+
+struct trunc_open_results {
+ unsigned int num;
+ uint32_t init_attr;
+ uint32_t trunc_attr;
+ uint32_t result_attr;
+};
+
+static const struct trunc_open_results attr_results[] = {
+ { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
+ { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
+ { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
+ { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
+ { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
+ { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
+ { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
+ { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
+ { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
+ { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
+ { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
+ { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
+ { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
+ { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
+ { 104, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
+ { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
+ { 119, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
+ { 121, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
+ { 170, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_HIDDEN },
+ { 173, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM },
+ { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
+ { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
+ { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
+ { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
+ { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
+ { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
+};
+
+static NTSTATUS smb2_setatr(struct smb2_tree *tree, const char *name,
+ uint32_t attrib)
+{
+ NTSTATUS status;
+ struct smb2_create create_io = {0};
+ union smb_setfileinfo io;
+
+ create_io.in.desired_access = SEC_FILE_READ_DATA |
+ SEC_FILE_WRITE_ATTRIBUTE;
+ create_io.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
+ create_io.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
+ create_io.in.create_disposition = NTCREATEX_DISP_OPEN;
+ create_io.in.fname = name;
+ status = smb2_create(tree, tree, &create_io);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ ZERO_STRUCT(io);
+ io.basic_info.level = RAW_SFILEINFO_BASIC_INFORMATION;
+ io.basic_info.in.file.handle = create_io.out.file.handle;
+ io.basic_info.in.attrib = attrib;
+ status = smb2_setinfo_file(tree, &io);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ status = smb2_util_close(tree, create_io.out.file.handle);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ return status;
+}
+
+bool torture_smb2_openattrtest(struct torture_context *tctx,
+ struct smb2_tree *tree)
+{
+ NTSTATUS status;
+ const char *fname = "openattr.file";
+ uint16_t attr;
+ unsigned int i, j, k, l;
+ int ret = true;
+
+ for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32_t); i++) {
+ struct smb2_create create_io = {0};
+ smb2_setatr(tree, fname, FILE_ATTRIBUTE_NORMAL);
+ smb2_util_unlink(tree, fname);
+ create_io.in.create_flags = 0;
+ create_io.in.desired_access = SEC_FILE_WRITE_DATA;
+ create_io.in.file_attributes = open_attrs_table[i];
+ create_io.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
+ create_io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
+ create_io.in.create_options = 0;
+ create_io.in.security_flags = 0;
+ create_io.in.fname = fname;
+ status = smb2_create(tree, tctx, &create_io);
+ torture_assert_ntstatus_ok_goto(tctx, status, ret, error_exit,
+ talloc_asprintf(tctx, "open %d (1) of %s failed (%s)",
+ i, fname, nt_errstr(status)));
+
+ status = smb2_util_close(tree, create_io.out.file.handle);
+ torture_assert_ntstatus_ok_goto(tctx, status, ret, error_exit,
+ talloc_asprintf(tctx, "close %d (1) of %s failed (%s)",
+ i, fname, nt_errstr(status)));
+
+ for (j = 0; j < ARRAY_SIZE(open_attrs_table); j++) {
+ create_io = (struct smb2_create){0};
+ create_io.in.create_flags = 0;
+ create_io.in.desired_access = SEC_FILE_READ_DATA|
+ SEC_FILE_WRITE_DATA;
+ create_io.in.file_attributes = open_attrs_table[j];
+ create_io.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
+ create_io.in.create_disposition = NTCREATEX_DISP_OVERWRITE;
+ create_io.in.create_options = 0;
+ create_io.in.security_flags = 0;
+ create_io.in.fname = fname;
+ status = smb2_create(tree, tctx, &create_io);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ for (l = 0; l < ARRAY_SIZE(attr_results); l++) {
+ torture_assert_goto(tctx,
+ attr_results[l].num != k,
+ ret, error_exit,
+ talloc_asprintf(tctx,
+ "[%d] trunc open 0x%x "
+ "-> 0x%x of %s failed "
+ "- should have "
+ "succeeded !(%s)",
+ k, open_attrs_table[i],
+ open_attrs_table[j],
+ fname,
+ nt_errstr(status)));
+ }
+ torture_assert_ntstatus_equal_goto(tctx,
+ status, NT_STATUS_ACCESS_DENIED,
+ ret, error_exit,
+ talloc_asprintf(tctx,
+ "[%d] trunc open 0x%x "
+ "-> 0x%x failed with "
+ "wrong error code %s",
+ k, open_attrs_table[i],
+ open_attrs_table[j],
+ nt_errstr(status)));
+ k++;
+ continue;
+ }
+
+ status = smb2_util_close(tree, create_io.out.file.handle);
+ torture_assert_ntstatus_ok_goto(tctx, status, ret,
+ error_exit, talloc_asprintf(tctx,
+ "close %d (2) of %s failed (%s)", j,
+ fname, nt_errstr(status)));
+
+ status = smb2_util_getatr(tree, fname, &attr, NULL, NULL);
+ torture_assert_ntstatus_ok_goto(tctx, status, ret,
+ error_exit, talloc_asprintf(tctx,
+ "getatr(2) failed (%s)",
+ nt_errstr(status)));
+
+ for (l = 0; l < ARRAY_SIZE(attr_results); l++) {
+ if (attr_results[l].num == k) {
+ if (attr != attr_results[l].result_attr ||
+ open_attrs_table[i] != attr_results[l].init_attr ||
+ open_attrs_table[j] != attr_results[l].trunc_attr) {
+ ret = false;
+ torture_fail_goto(tctx, error_exit,
+ talloc_asprintf(tctx,
+ "[%d] getatr check "
+ "failed. [0x%x] trunc "
+ "[0x%x] got attr 0x%x,"
+ " should be 0x%x",
+ k, open_attrs_table[i],
+ open_attrs_table[j],
+ (unsigned int)attr,
+ attr_results[l].result_attr));
+ }
+ break;
+ }
+ }
+ k++;
+ }
+ }
+error_exit:
+ smb2_setatr(tree, fname, FILE_ATTRIBUTE_NORMAL);
+ smb2_util_unlink(tree, fname);
+
+
+ return ret;
+}
+
+bool torture_smb2_winattrtest(struct torture_context *tctx,
+ struct smb2_tree *tree)
+{
+ const char *fname = "winattr1.file";
+ const char *dname = "winattr1.dir";
+ uint16_t attr;
+ uint16_t j;
+ uint32_t aceno;
+ bool ret = true;
+ union smb_fileinfo query, query_org;
+ NTSTATUS status;
+ struct security_descriptor *sd1 = NULL, *sd2 = NULL;
+ struct smb2_create create_io = {0};
+ ZERO_STRUCT(query);
+ ZERO_STRUCT(query_org);
+
+ /* Test winattrs for file */
+ smb2_util_unlink(tree, fname);
+
+ /* Open a file*/
+ create_io.in.create_flags = 0;
+ create_io.in.desired_access = SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA;
+ create_io.in.file_attributes = 0;
+ create_io.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
+ create_io.in.create_disposition = FILE_SUPERSEDE;
+ create_io.in.create_options = 0;
+ create_io.in.security_flags = 0;
+ create_io.in.fname = fname;
+ status = smb2_create(tree, tctx, &create_io);
+ torture_assert_ntstatus_ok_goto(tctx, status, ret, error_exit,
+ talloc_asprintf(tctx, "open(1) of %s failed (%s)\n",
+ fname, nt_errstr(status)));
+
+ /* Get security descriptor and store it*/
+ query_org.generic.level = RAW_FILEINFO_SEC_DESC;
+ query_org.generic.in.file.handle = create_io.out.file.handle;
+ status = smb2_getinfo_file(tree, NULL, &query_org);
+ if(!NT_STATUS_IS_OK(status)){
+ NTSTATUS s = smb2_util_close(tree, create_io.out.file.handle);
+ torture_assert_ntstatus_ok_goto(tctx, s, ret, error_exit,
+ talloc_asprintf(tctx,
+ "close(1) of %s failed (%s)\n",
+ fname, nt_errstr(s)));
+ ret = false;
+ torture_fail_goto(tctx, error_exit, talloc_asprintf(tctx,
+ "smb2_getinfo_file(1) of %s failed (%s)\n",
+ fname, nt_errstr(status)));
+ }
+ sd1 = query_org.query_secdesc.out.sd;
+
+ status = smb2_util_close(tree, create_io.out.file.handle);
+ torture_assert_ntstatus_ok_goto(tctx, status, ret, error_exit,
+ talloc_asprintf(tctx, "close(1) of %s failed (%s)\n",
+ fname, nt_errstr(status)));
+
+ /*Set and get attributes*/
+ for (j = 0; j < ARRAY_SIZE(open_attrs_table); j++) {
+ status = smb2_setatr(tree, fname, open_attrs_table[j]);
+ torture_assert_ntstatus_ok_goto(tctx, status, ret,
+ error_exit,
+ talloc_asprintf(tctx, "setatr(2) failed (%s)",
+ nt_errstr(status)));
+
+ status = smb2_util_getatr(tree, fname, &attr, NULL, NULL);
+ torture_assert_ntstatus_ok_goto(tctx, status, ret,
+ error_exit,
+ talloc_asprintf(tctx, "getatr(2) failed (%s)",
+ nt_errstr(status)));
+
+ /* Check the result */
+ torture_assert_goto(tctx, attr == open_attrs_table[j], ret,
+ error_exit, talloc_asprintf(tctx,
+ "getatr check failed. \
+ Attr applied [0x%x],got attr 0x%x, \
+ should be 0x%x ", open_attrs_table[j],
+ (uint16_t)attr, open_attrs_table[j]));
+
+ create_io = (struct smb2_create){0};
+ create_io.in.create_flags = 0;
+ create_io.in.desired_access = SEC_FILE_READ_ATTRIBUTE;
+ create_io.in.file_attributes = 0;
+ create_io.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
+ create_io.in.create_disposition = FILE_OPEN_IF;
+ create_io.in.create_options = 0;
+ create_io.in.security_flags = 0;
+ create_io.in.fname = fname;
+ status = smb2_create(tree, tctx, &create_io);
+ torture_assert_ntstatus_ok_goto(tctx, status, ret,
+ error_exit,
+ talloc_asprintf(tctx, "open(2) of %s failed (%s)\n",
+ fname, nt_errstr(status)));
+ /*Get security descriptor */
+ query.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
+ query.query_secdesc.in.file.handle = create_io.out.file.handle;
+ status = smb2_getinfo_file(tree, tctx, &query);
+ if(!NT_STATUS_IS_OK(status)){
+ NTSTATUS s = smb2_util_close(tree, create_io.out.file.handle);
+ torture_assert_ntstatus_ok_goto(tctx, s, ret,
+ error_exit,
+ talloc_asprintf(tctx,
+ "close(2) of %s failed (%s)\n",
+ fname, nt_errstr(s)));
+ ret = false;
+ torture_fail_goto(tctx, error_exit,
+ talloc_asprintf(tctx,
+ "smb2_getinfo_file(2) of %s failed (%s)\n",
+ fname, nt_errstr(status)));
+ }
+ sd2 = query.query_secdesc.out.sd;
+
+ status = smb2_util_close(tree, create_io.out.file.handle);
+ torture_assert_ntstatus_ok_goto(tctx, status, ret, error_exit,
+ talloc_asprintf(tctx, "close(2) of %s failed (%s)\n",
+ fname, nt_errstr(status)));
+
+ /*Compare security descriptors -- Must be same*/
+ for (aceno=0;(sd1->dacl&&aceno < sd1->dacl->num_aces);aceno++){
+ struct security_ace *ace1 = &sd1->dacl->aces[aceno];
+ struct security_ace *ace2 = &sd2->dacl->aces[aceno];
+
+ torture_assert_goto(tctx, security_ace_equal(ace1, ace2),
+ ret, error_exit,
+ "ACLs changed! Not expected!\n");
+ }
+
+ torture_comment(tctx, "[%d] setattr = [0x%x] got attr 0x%x\n",
+ j, open_attrs_table[j], attr );
+
+ }
+
+
+/* Check for Directory. */
+
+ smb2_deltree(tree, dname);
+ smb2_util_rmdir(tree, dname);
+
+ /* Open a directory */
+ create_io = (struct smb2_create){0};
+ create_io.in.create_flags = 0;
+ create_io.in.desired_access = SEC_RIGHTS_DIR_ALL;
+ create_io.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
+ create_io.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
+ create_io.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
+ create_io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
+ create_io.in.security_flags = 0;
+ create_io.in.fname = dname;
+ status = smb2_create(tree, tctx, &create_io);
+
+ torture_assert_ntstatus_ok_goto(tctx, status, ret, error_exit,
+ talloc_asprintf(tctx,
+ "open (1) of %s failed (%s)",
+ dname, nt_errstr(status)));
+
+
+ /* Get Security Descriptor */
+ query_org.generic.level = RAW_FILEINFO_SEC_DESC;
+ query_org.generic.in.file.handle = create_io.out.file.handle;
+ status = smb2_getinfo_file(tree, tctx, &query_org);
+ if(!NT_STATUS_IS_OK(status)){
+ NTSTATUS s = smb2_util_close(tree, create_io.out.file.handle);
+ torture_assert_ntstatus_ok_goto(tctx, s, ret, error_exit,
+ talloc_asprintf(tctx,
+ "close(1) of %s failed (%s)\n",
+ dname, nt_errstr(s)));
+ ret = false;
+ torture_fail_goto(tctx, error_exit, talloc_asprintf(tctx,
+ "smb2_getinfo_file(1) of %s failed (%s)\n", dname,
+ nt_errstr(status)));
+ }
+ sd1 = query_org.query_secdesc.out.sd;
+
+ status = smb2_util_close(tree, create_io.out.file.handle);
+ torture_assert_ntstatus_ok_goto(tctx, status, ret, error_exit,
+ talloc_asprintf(tctx,
+ "close (1) of %s failed (%s)", dname,
+ nt_errstr(status)));
+
+ /* Set and get win attributes*/
+ for (j = 1; j < ARRAY_SIZE(open_attrs_table); j++) {
+
+ status = smb2_setatr(tree, dname, open_attrs_table[j]);
+ torture_assert_ntstatus_ok_goto(tctx, status, ret, error_exit,
+ talloc_asprintf(tctx, "setatr(2) failed (%s)",
+ nt_errstr(status)));
+
+ status = smb2_util_getatr(tree, dname, &attr, NULL, NULL);
+ torture_assert_ntstatus_ok_goto(tctx, status, ret, error_exit,
+ talloc_asprintf(tctx, "getatr(2) failed (%s)",
+ nt_errstr(status)));
+
+ torture_comment(tctx, "[%d] setatt = [0x%x] got attr 0x%x\n",
+ j, open_attrs_table[j], attr );
+
+ /* Check the result */
+ torture_assert_goto(tctx,
+ attr == (open_attrs_table[j]|FILE_ATTRIBUTE_DIRECTORY),
+ ret, error_exit, talloc_asprintf(tctx,
+ "getatr check failed. set attr "
+ "[0x%x], got attr 0x%x, should be 0x%x\n",
+ open_attrs_table[j], (uint16_t)attr,
+ (unsigned int)(open_attrs_table[j]|FILE_ATTRIBUTE_DIRECTORY)));
+
+ create_io = (struct smb2_create){0};
+ create_io.in.create_flags = 0;
+ create_io.in.desired_access = SEC_RIGHTS_DIR_READ;
+ create_io.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
+ create_io.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
+ create_io.in.create_disposition = NTCREATEX_DISP_OPEN;
+ create_io.in.create_options = 0;
+ create_io.in.security_flags = 0;
+ create_io.in.fname = dname;
+ status = smb2_create(tree, tctx, &create_io);
+
+ torture_assert_ntstatus_ok_goto(tctx, status, ret, error_exit,
+ talloc_asprintf(tctx,
+ "open (2) of %s failed (%s)",
+ dname, nt_errstr(status)));
+ /* Get security descriptor */
+ query.generic.level = RAW_FILEINFO_SEC_DESC;
+ query.generic.in.file.handle = create_io.out.file.handle;
+ status = smb2_getinfo_file(tree, tctx, &query);
+ if(!NT_STATUS_IS_OK(status)){
+ NTSTATUS s = smb2_util_close(tree, create_io.out.file.handle);
+ torture_assert_ntstatus_ok_goto(tctx, s, ret, error_exit,
+ talloc_asprintf(tctx,
+ "close (2) of %s failed (%s)", dname,
+ nt_errstr(s)));
+ ret = false;
+ torture_fail_goto(tctx, error_exit,
+ talloc_asprintf(tctx,
+ "smb2_getinfo_file(2) of %s failed(%s)\n",
+ dname, nt_errstr(status)));
+ }
+ sd2 = query.query_secdesc.out.sd;
+ status = smb2_util_close(tree, create_io.out.file.handle);
+ torture_assert_ntstatus_ok_goto(tctx, status, ret, error_exit,
+ talloc_asprintf(tctx,
+ "close (2) of %s failed (%s)", dname,
+ nt_errstr(status)));
+
+ /* Security descriptor must be same*/
+ for (aceno=0;(sd1->dacl&&aceno < sd1->dacl->num_aces);aceno++){
+ struct security_ace *ace1 = &sd1->dacl->aces[aceno];
+ struct security_ace *ace2 = &sd2->dacl->aces[aceno];
+
+ torture_assert_goto(tctx, security_ace_equal(ace1, ace2),
+ ret, error_exit,
+ "ACLs changed! Not expected!\n");
+ }
+
+ }
+
+error_exit:
+ smb2_setatr(tree, fname, FILE_ATTRIBUTE_NORMAL);
+ smb2_util_unlink(tree, fname);
+ smb2_deltree(tree, dname);
+ smb2_util_rmdir(tree, dname);
+
+ return ret;
+}
diff --git a/source4/torture/smb2/smb2.c b/source4/torture/smb2/smb2.c
index e4341c80358..4f42ffacf87 100644
--- a/source4/torture/smb2/smb2.c
+++ b/source4/torture/smb2/smb2.c
@@ -198,6 +198,8 @@ NTSTATUS torture_smb2_init(TALLOC_CTX *ctx)
torture_suite_add_suite(suite, torture_smb2_multichannel_init(suite));
torture_suite_add_suite(suite, torture_smb2_samba3misc_init(suite));
torture_suite_add_suite(suite, torture_smb2_timestamps_init(suite));
+ torture_suite_add_1smb2_test(suite, "openattr", torture_smb2_openattrtest);
+ torture_suite_add_1smb2_test(suite, "winattr", torture_smb2_winattrtest);
suite->description = talloc_strdup(suite, "SMB2-specific tests");
diff --git a/source4/torture/smb2/wscript_build b/source4/torture/smb2/wscript_build
index d0232503e90..d1c2e04af71 100644
--- a/source4/torture/smb2/wscript_build
+++ b/source4/torture/smb2/wscript_build
@@ -3,6 +3,7 @@
bld.SAMBA_MODULE('TORTURE_SMB2',
source='''
acls.c
+ attr.c
block.c
compound.c
connect.c