[PATCH] Overwriting hidden files fails

Ralph Boehme slow at samba.org
Thu Jun 23 18:46:10 UTC 2016


Hi!

Attached is a patch for bug
<https://bugzilla.samba.org/show_bug.cgi?id=11992>

The following description shamelessly copied from the bugreport:

Commit 2058ce246ea5008202e737f64fbdd9b586b2d7d4 for bug #11645
introduced a regression that causes attempts to overwrite hidden "hide
dot files" files to fail. Relevant log snippet:

[2016/06/09 00:27:40.720835,  5, pid=6756, effective(99, 99),
real(99,0)] ../source3/smbd/dosmode.c:70(dos_mode_debug_print)
  dos_mode_debug_print: get_ea_dos_attribute returning (0x22): "ha"  
[2016/06/09 00:27:40.721037,  5, pid=6756, effective(99, 99),
real(99,0)] ../source3/smbd/dosmode.c:70(dos_mode_debug_print)
  dos_mode_debug_print: dos_mode returning (0x22): "ha"
[2016/06/09 00:27:40.721171,  5, pid=6756, effective(99, 99),
real(99,0)] ../source3/smbd/open.c:2613(open_file_ntcreate)
  open_file_ntcreate: attributes missmatch for file .profile (22 0)
  (0100777, 0666)

The client's requested attributes are 0, but on the server we compute
"hidden" is set by calling dos_mode() which checks "hide dot
files". As a result open_match_attributes() fires and the open is
rejected with access denied.

Steps to reproduce:

smb.conf:
  store dos attributes = yes
  hide dot files = yes (the default)

$ ./bin/smbclient //localhost/normal                                                                                                                                                             
Enter slow's password: 
Domain=[SLOW] OS=[Windows 6.1] Server=[Samba 4.5.0pre1-DEVELOPERBUILD]
smb: \> put .file
putting file .file as \.file (0.0 kb/s) (average 0.0 kb/s)
smb: \> put .file
NT_STATUS_ACCESS_DENIED opening remote file \.file
smb: \>

Reverting this commit restores the behaviour that if a stored dos
attribute xattr is found, it overwrites the result of "hide dot
files". But that means that "hide dot files" doesn't work anymore and
overwriting a "hide files" file will still fail this way!

I have a patch that simply changes which attributes we check for
existing files: instead of calling dos_mode() that returns a munged
sum of stored attributes and computed attributes, just check the fetch
the stored attributes via the VFS function. This seems the right way
to do and behaviour looks good in manual testing. Adding a test is
next on my list.

I broke it so now I'm trying to be extra careful in the second
attempt. Detailed behaviour analysis below:

Common config:

    hide files = /.foo/
    map hidden = yes

1. Just revert 2058ce246ea5008202e737f64fbdd9b586b2d7d4:

1a) "store dos attributes = no"
Problem: overwriting any hidden file fails. [1]

1b) "store dos attributes = yes"
Problems: "hide dot files" doesn't work and overwriting a "hide files"
file fails. [2]


2. Instead of reverting use patch "s3/smbd: only use stored dos
attributes for open_match_attributes() check"

2a) "store dos attributes = no"
Everything works nicely: hidden attributes computation works in all
cases and overwriting file with computed hidden attribute works as
well. [3]

2b) "store dos attributes = yes"
Everything works nicely: hidden attributes computation works in all
cases, overwriting file with computed hidden attribute works,
overwriting of file with stored attribute still correctly fails. [4]


[1]
. and .. removed from smbclient ls output.

$ ./bin/smbclient -Uslow //localhost/normal
Enter slow's password: 
Domain=[SLOW] OS=[Windows 6.1] Server=[Samba 4.5.0pre1-DEVELOPERBUILD]
smb: \> put .file
putting file .file as \.file (0.0 kb/s) (average 0.0 kb/s)
smb: \> put .file
NT_STATUS_ACCESS_DENIED opening remote file \.file
smb: \> put .foo
putting file .foo as \.foo (0.0 kb/s) (average 0.0 kb/s)
smb: \> put .foo
NT_STATUS_ACCESS_DENIED opening remote file \.foo
smb: \> put file
NT_STATUS_ACCESS_DENIED opening remote file \file
smb: \> ls
  .file                              AH        0  Thu Jun 23 13:26:12
  2016
  file                               AH        0  Thu Jun 23 12:57:07
  2016
  .foo                               AH        0  Thu Jun 23 13:26:30
  2016


[2]
$ ./bin/smbclient -Uslow //localhost/normal
Enter slow's password: 
Domain=[SLOW] OS=[Windows 6.1] Server=[Samba 4.5.0pre1-DEVELOPERBUILD]
smb: \> ls
  file                                N        0  Thu Jun 23 13:32:14
  2016
smb: \> setmode file +h
smb: \> put file
NT_STATUS_ACCESS_DENIED opening remote file \file
smb: \> put .file
putting file .file as \.file (0.0 kb/s) (average 0.0 kb/s)
smb: \> put .file
putting file .file as \.file (0.0 kb/s) (average 0.0 kb/s)
smb: \> put .foo
putting file .foo as \.foo (0.0 kb/s) (average 0.0 kb/s)
smb: \> put .foo
NT_STATUS_ACCESS_DENIED opening remote file \.foo
smb: \> ls
  .file                               A        0  Thu Jun 23 13:33:38
  2016
  file                                H        0  Thu Jun 23 13:32:14
  2016
  .foo                               AH        0  Thu Jun 23 13:33:42
  2016


[3]
$ ./bin/smbclient -Uslow //localhost/normal
Enter slow's password: 
Domain=[SLOW] OS=[Windows 6.1] Server=[Samba 4.5.0pre1-DEVELOPERBUILD]
smb: \> ls
  file                               AH        0  Wed Jun 22 21:45:17
  2016
smb: \> put file
putting file file as \file (0.0 kb/s) (average 0.0 kb/s)
smb: \> put .file
putting file .file as \.file (0.0 kb/s) (average 0.0 kb/s)
smb: \> put .file
putting file .file as \.file (0.0 kb/s) (average 0.0 kb/s)
smb: \> put .foo
putting file .foo as \.foo (0.0 kb/s) (average 0.0 kb/s)
smb: \> put .foo
putting file .foo as \.foo (0.0 kb/s) (average 0.0 kb/s)
smb: \> ls
  .file                              AH        0  Thu Jun 23 12:49:05
  2016
  file                                A        0  Thu Jun 23 12:48:47
  2016
  .foo                               AH        0  Thu Jun 23 12:49:10
  2016


[4]
$ ./bin/smbclient -Uslow //localhost/normal
Enter slow's password: 
Domain=[SLOW] OS=[Windows 6.1] Server=[Samba 4.5.0pre1-DEVELOPERBUILD]
smb: \> ls
  file                                A        0  Thu Jun 23 12:48:47
  2016
smb: \> put .file
putting file .file as \.file (0.0 kb/s) (average 0.0 kb/s)
smb: \> put .file
putting file .file as \.file (0.0 kb/s) (average 0.0 kb/s)
smb: \> put .foo
putting file .foo as \.foo (0.0 kb/s) (average 0.0 kb/s)
smb: \> put .foo
putting file .foo as \.foo (0.0 kb/s) (average 0.0 kb/s)
smb: \> ls
  .file                              AH        0  Thu Jun 23 12:51:56
  2016
  file                                A        0  Thu Jun 23 12:48:47
  2016
  .foo                               AH        0  Thu Jun 23 12:51:59
  2016
smb: \> put file
putting file file as \file (0.0 kb/s) (average 0.0 kb/s)
smb: \> setmode file +h
smb: \> put file
NT_STATUS_ACCESS_DENIED opening remote file \file
smb: \>

Please review&push if ok. Thanks!

Cheerio!
-slow
-------------- next part --------------
From 9b8febfb4468b683455337ac8c3620d099e1211a Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Thu, 23 Jun 2016 12:23:33 +0200
Subject: [PATCH 1/5] s3/smbd: add helper func dos_mode_from_name()

This just moves the computation of "hide dot files" files to a helper
functions without changing overall behaviour.

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

Signed-off-by: Ralph Boehme <slow at samba.org>
---
 source3/smbd/dosmode.c | 42 ++++++++++++++++++++++++++----------------
 1 file changed, 26 insertions(+), 16 deletions(-)

diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c
index f490e9a..463c43e 100644
--- a/source3/smbd/dosmode.c
+++ b/source3/smbd/dosmode.c
@@ -562,6 +562,31 @@ err_out:
 	return status;
 }
 
+static uint32_t dos_mode_from_name(connection_struct *conn,
+				   const struct smb_filename *smb_fname)
+{
+	const char *p = NULL;
+	uint32_t result = 0;
+
+	if (lp_hide_dot_files(SNUM(conn))) {
+		p = strrchr_m(smb_fname->base_name, '/');
+		if (p) {
+			p++;
+		} else {
+			p = smb_fname->base_name;
+		}
+
+		/* Only . and .. are not hidden. */
+		if ((p[0] == '.') &&
+		    !((p[1] == '\0') || (p[1] == '.' && p[2] == '\0')))
+		{
+			result |= FILE_ATTRIBUTE_HIDDEN;
+		}
+	}
+
+	return result;
+}
+
 /****************************************************************************
  Change a unix mode to a dos mode.
  May also read the create timespec into the stat struct in smb_fname
@@ -580,22 +605,7 @@ uint32_t dos_mode(connection_struct *conn, struct smb_filename *smb_fname)
 		return 0;
 	}
 
-	/* First do any modifications that depend on the path name. */
-	/* hide files with a name starting with a . */
-	if (lp_hide_dot_files(SNUM(conn))) {
-		const char *p = strrchr_m(smb_fname->base_name,'/');
-		if (p) {
-			p++;
-		} else {
-			p = smb_fname->base_name;
-		}
-
-		/* Only . and .. are not hidden. */
-		if (p[0] == '.' && !((p[1] == '\0') ||
-				(p[1] == '.' && p[2] == '\0'))) {
-			result |= FILE_ATTRIBUTE_HIDDEN;
-		}
-	}
+	result |= dos_mode_from_name(conn, smb_fname);
 
 	/* Get the DOS attributes via the VFS if we can */
 	status = SMB_VFS_GET_DOS_ATTRIBUTES(conn, smb_fname, &result);
-- 
2.5.0


From b5dbebe49acf966ad82102e44c0c8163c213051e Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Thu, 23 Jun 2016 16:40:15 +0200
Subject: [PATCH 2/5] s3/smbd: call dos_mode_from_name after
 SMB_VFS_GET_DOS_ATTRIBUTES()

This doesn't change overall behaviour in any way, it just prepares for
the next step where the IS_HIDDEN_PATH() stuff will be moved to the
function dos_mode_from_name().

It allows an optimisation by not checking "hide to files" patch if
FILE_ATTRIBUTE_HIDDEN was already set in the DOS xattr.

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

Signed-off-by: Ralph Boehme <slow at samba.org>
---
 source3/smbd/dosmode.c | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c
index 463c43e..f59ed79 100644
--- a/source3/smbd/dosmode.c
+++ b/source3/smbd/dosmode.c
@@ -563,12 +563,15 @@ err_out:
 }
 
 static uint32_t dos_mode_from_name(connection_struct *conn,
-				   const struct smb_filename *smb_fname)
+				   const struct smb_filename *smb_fname,
+				   uint32_t dosmode)
 {
 	const char *p = NULL;
-	uint32_t result = 0;
+	uint32_t result = dosmode;
 
-	if (lp_hide_dot_files(SNUM(conn))) {
+	if (!(result & FILE_ATTRIBUTE_HIDDEN) &&
+	    lp_hide_dot_files(SNUM(conn)))
+	{
 		p = strrchr_m(smb_fname->base_name, '/');
 		if (p) {
 			p++;
@@ -605,8 +608,6 @@ uint32_t dos_mode(connection_struct *conn, struct smb_filename *smb_fname)
 		return 0;
 	}
 
-	result |= dos_mode_from_name(conn, smb_fname);
-
 	/* Get the DOS attributes via the VFS if we can */
 	status = SMB_VFS_GET_DOS_ATTRIBUTES(conn, smb_fname, &result);
 	if (!NT_STATUS_IS_OK(status)) {
@@ -627,6 +628,8 @@ uint32_t dos_mode(connection_struct *conn, struct smb_filename *smb_fname)
 		}
 	}
 
+	result |= dos_mode_from_name(conn, smb_fname, result);
+
 	/* Optimization : Only call is_hidden_path if it's not already
 	   hidden. */
 	if (!(result & FILE_ATTRIBUTE_HIDDEN) &&
-- 
2.5.0


From 581fc42d316e0ad5d7379e48b5fd13b50c0c8cda Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Thu, 23 Jun 2016 17:14:55 +0200
Subject: [PATCH 3/5] s3/smbd: move check for "hide files" to
 dos_mode_from_name()

Consolidate the "hide dot files" and "hide files" handling stuff in one
function. No change in overall behaviour.

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

Signed-off-by: Ralph Boehme <slow at samba.org>
---
 source3/smbd/dosmode.c | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c
index f59ed79..ef880e5 100644
--- a/source3/smbd/dosmode.c
+++ b/source3/smbd/dosmode.c
@@ -587,6 +587,12 @@ static uint32_t dos_mode_from_name(connection_struct *conn,
 		}
 	}
 
+	if (!(result & FILE_ATTRIBUTE_HIDDEN) &&
+	    IS_HIDDEN_PATH(conn, smb_fname->base_name))
+	{
+		result |= FILE_ATTRIBUTE_HIDDEN;
+	}
+
 	return result;
 }
 
@@ -630,13 +636,6 @@ uint32_t dos_mode(connection_struct *conn, struct smb_filename *smb_fname)
 
 	result |= dos_mode_from_name(conn, smb_fname, result);
 
-	/* Optimization : Only call is_hidden_path if it's not already
-	   hidden. */
-	if (!(result & FILE_ATTRIBUTE_HIDDEN) &&
-	    IS_HIDDEN_PATH(conn, smb_fname->base_name)) {
-		result |= FILE_ATTRIBUTE_HIDDEN;
-	}
-
 	if (result == 0) {
 		result = FILE_ATTRIBUTE_NORMAL;
 	}
-- 
2.5.0


From e2ac7d3497df2ed1b5cc410815e1b15d73f2062c Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Thu, 23 Jun 2016 12:24:33 +0200
Subject: [PATCH 4/5] s3/smbd: only use stored dos attributes for
 open_match_attributes() check

This changes the way we check for old vs new DOS attributes on open with
overwrite: only check against the DOS attributes actually set by a
client and stored in the DOS attributes xattr.

With this change "hide dot files" and "hide files" continue to work with
"store dos attributes = yes".

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

Signed-off-by: Ralph Boehme <slow at samba.org>
---
 source3/smbd/open.c | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index 0c46eb1..883c6ae 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -2535,7 +2535,18 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn,
 	if (!posix_open) {
 		new_dos_attributes &= SAMBA_ATTRIBUTES_MASK;
 		if (file_existed) {
-			existing_dos_attributes = dos_mode(conn, smb_fname);
+			/*
+			 * Only use strored DOS attributes for checks
+			 * against requested attributes (below via
+			 * open_match_attributes()), cf bug #11992
+			 * for details. -slow
+			 */
+			uint32_t attr = 0;
+
+			status = SMB_VFS_GET_DOS_ATTRIBUTES(conn, smb_fname, &attr);
+			if (NT_STATUS_IS_OK(status)) {
+				existing_dos_attributes = attr;
+			}
 		}
 	}
 
-- 
2.5.0


From 084ea8b1df3ae3185d3693b99264e86063c28a37 Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Thu, 23 Jun 2016 19:13:05 +0200
Subject: [PATCH 5/5] s4/torture: add a test for dosmode and hidden files

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

Signed-off-by: Ralph Boehme <slow at samba.org>
---
 selftest/target/Samba3.pm          |   7 ++
 source3/selftest/tests.py          |   2 +
 source4/selftest/tests.py          |   5 +-
 source4/torture/smb2/dosmode.c     | 183 +++++++++++++++++++++++++++++++++++++
 source4/torture/smb2/smb2.c        |   1 +
 source4/torture/smb2/wscript_build |   2 +-
 6 files changed, 197 insertions(+), 3 deletions(-)
 create mode 100644 source4/torture/smb2/dosmode.c

diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm
index 3f6fd1e..2ac953d 100755
--- a/selftest/target/Samba3.pm
+++ b/selftest/target/Samba3.pm
@@ -555,6 +555,13 @@ sub setup_simpleserver($$)
         vfs objects = aio_fork
         read only = no
         vfs_aio_fork:erratic_testing_mode=yes
+
+[dosmode]
+	path = $prefix_abs/share
+	vfs objects =
+	store dos attributes = yes
+	hide files = /hidefile/
+	hide dot files = yes
 ";
 
 	my $vars = $self->provision($path,
diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py
index cc635cd..371ec2a 100755
--- a/source3/selftest/tests.py
+++ b/source3/selftest/tests.py
@@ -408,6 +408,8 @@ for t in tests:
     elif t == "smb2.notify":
         plansmbtorture4testsuite(t, "nt4_dc", '//$SERVER_IP/tmp -U$USERNAME%$PASSWORD --signing=required')
         plansmbtorture4testsuite(t, "ad_dc", '//$SERVER/tmp -U$USERNAME%$PASSWORD --signing=required')
+    elif t == "smb2.dosmode":
+        plansmbtorture4testsuite(t, "simpleserver", '//$SERVER/dosmode -U$USERNAME%$PASSWORD')
     else:
         plansmbtorture4testsuite(t, "nt4_dc", '//$SERVER_IP/tmp -U$USERNAME%$PASSWORD')
         plansmbtorture4testsuite(t, "ad_dc", '//$SERVER/tmp -U$USERNAME%$PASSWORD')
diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py
index 844b93c..7372072 100755
--- a/source4/selftest/tests.py
+++ b/source4/selftest/tests.py
@@ -300,8 +300,9 @@ for t in nbt_tests:
 # Tests against the NTVFS POSIX backend
 ntvfsargs = ["--option=torture:sharedelay=100000", "--option=torture:oplocktimeout=3", "--option=torture:writetimeupdatedelay=500000"]
 
-# smb2.change_notify_disabled must only run against env fileserver-notify-disabled
-smb2 = filter(lambda x: "smb2.change_notify_disabled" not in x, smbtorture4_testsuites("smb2."))
+# Filter smb2 tests that should not run against ad_dc_ntvfs
+smb2_s3only = ["smb2.change_notify_disabled", "smb2.dosmode"]
+smb2 = [x for x in smbtorture4_testsuites("smb2.") if x not in smb2_s3only]
 
 #The QFILEINFO-IPC test needs to be on ipc$
 raw = filter(lambda x: "raw.qfileinfo.ipc" not in x, smbtorture4_testsuites("raw."))
diff --git a/source4/torture/smb2/dosmode.c b/source4/torture/smb2/dosmode.c
new file mode 100644
index 0000000..7808ca6
--- /dev/null
+++ b/source4/torture/smb2/dosmode.c
@@ -0,0 +1,183 @@
+/*
+   Unix SMB/CIFS implementation.
+
+   SMB2 setinfo individual test suite
+
+   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 "system/time.h"
+#include "libcli/smb2/smb2.h"
+#include "libcli/smb2/smb2_calls.h"
+
+#include "torture/torture.h"
+#include "torture/smb2/proto.h"
+
+/*
+  test dosmode and hidden files
+*/
+bool torture_smb2_dosmode(struct torture_context *tctx)
+{
+	bool ret = true;
+	NTSTATUS status;
+	struct smb2_tree *tree = NULL;
+	const char *dname = "torture_dosmode";
+	const char *fname = "torture_dosmode\\file";
+	const char *hidefile = "torture_dosmode\\hidefile";
+	const char *dotfile = "torture_dosmode\\.dotfile";
+	struct smb2_handle h1 = {{0}};
+	struct smb2_create io;
+	union smb_setfileinfo sfinfo;
+	union smb_fileinfo finfo2;
+
+	torture_comment(tctx, "Checking dosmode with \"hide files\" "
+			"and \"hide dot files\"\n");
+
+	if (!torture_smb2_connection(tctx, &tree)) {
+		return false;
+	}
+
+	smb2_deltree(tree, dname);
+
+	status = torture_smb2_testdir(tree, dname, &h1);
+	torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
+					"torture_smb2_testdir failed");
+
+	ZERO_STRUCT(io);
+	io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
+	io.in.file_attributes   = FILE_ATTRIBUTE_NORMAL;
+	io.in.create_disposition = NTCREATEX_DISP_CREATE;
+	io.in.create_options = 0;
+	io.in.fname = fname;
+
+	status = smb2_create(tree, tctx, &io);
+	torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
+					"smb2_create failed");
+
+	ZERO_STRUCT(sfinfo);
+	sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_HIDDEN;
+	sfinfo.generic.level = RAW_SFILEINFO_BASIC_INFORMATION;
+	sfinfo.generic.in.file.handle = io.out.file.handle;
+	status = smb2_setinfo_file(tree, &sfinfo);
+	torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
+					"smb2_setinfo_filefailed");
+
+	ZERO_STRUCT(finfo2);
+	finfo2.generic.level = RAW_FILEINFO_BASIC_INFORMATION;
+	finfo2.generic.in.file.handle = io.out.file.handle;
+	status = smb2_getinfo_file(tree, tctx, &finfo2);
+	torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
+					"smb2_getinfo_file failed");
+	torture_assert_int_equal_goto(tctx, finfo2.all_info2.out.attrib & FILE_ATTRIBUTE_HIDDEN,
+				      FILE_ATTRIBUTE_HIDDEN, ret, done,
+				      "FILE_ATTRIBUTE_HIDDEN is not set");
+
+	smb2_util_close(tree, io.out.file.handle);
+
+	/* This must fail with attribute mismatch */
+	ZERO_STRUCT(io);
+	io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
+	io.in.file_attributes   = FILE_ATTRIBUTE_NORMAL;
+	io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
+	io.in.create_options = 0;
+	io.in.fname = fname;
+
+	status = smb2_create(tree, tctx, &io);
+	torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_ACCESS_DENIED,
+					   ret, done,"smb2_create failed");
+
+	/* Create a file in "hide files" */
+	ZERO_STRUCT(io);
+	io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
+	io.in.file_attributes   = FILE_ATTRIBUTE_NORMAL;
+	io.in.create_disposition = NTCREATEX_DISP_CREATE;
+	io.in.create_options = 0;
+	io.in.fname = hidefile;
+
+	status = smb2_create(tree, tctx, &io);
+	torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
+					"smb2_create failed");
+
+	ZERO_STRUCT(finfo2);
+	finfo2.generic.level = RAW_FILEINFO_BASIC_INFORMATION;
+	finfo2.generic.in.file.handle = io.out.file.handle;
+	status = smb2_getinfo_file(tree, tctx, &finfo2);
+	torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
+					"smb2_getinfo_file failed");
+	torture_assert_int_equal_goto(tctx, finfo2.all_info2.out.attrib & FILE_ATTRIBUTE_HIDDEN,
+				      FILE_ATTRIBUTE_HIDDEN, ret, done,
+				      "FILE_ATTRIBUTE_HIDDEN is not set");
+
+	smb2_util_close(tree, io.out.file.handle);
+
+	/* Overwrite a file in "hide files", should pass */
+	ZERO_STRUCT(io);
+	io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
+	io.in.file_attributes   = FILE_ATTRIBUTE_NORMAL;
+	io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
+	io.in.create_options = 0;
+	io.in.fname = hidefile;
+
+	status = smb2_create(tree, tctx, &io);
+	torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
+					"smb2_create failed");
+	smb2_util_close(tree, io.out.file.handle);
+
+	/* Create a "hide dot files" */
+	ZERO_STRUCT(io);
+	io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
+	io.in.file_attributes   = FILE_ATTRIBUTE_NORMAL;
+	io.in.create_disposition = NTCREATEX_DISP_CREATE;
+	io.in.create_options = 0;
+	io.in.fname = dotfile;
+
+	status = smb2_create(tree, tctx, &io);
+	torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
+					"smb2_create failed");
+
+	ZERO_STRUCT(finfo2);
+	finfo2.generic.level = RAW_FILEINFO_BASIC_INFORMATION;
+	finfo2.generic.in.file.handle = io.out.file.handle;
+	status = smb2_getinfo_file(tree, tctx, &finfo2);
+	torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
+					"smb2_getinfo_file failed");
+	torture_assert_int_equal_goto(tctx, finfo2.all_info2.out.attrib & FILE_ATTRIBUTE_HIDDEN,
+				      FILE_ATTRIBUTE_HIDDEN, ret, done,
+				      "FILE_ATTRIBUTE_HIDDEN is not set");
+
+	smb2_util_close(tree, io.out.file.handle);
+
+	/* Overwrite a "hide dot files", should pass */
+	ZERO_STRUCT(io);
+	io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
+	io.in.file_attributes   = FILE_ATTRIBUTE_NORMAL;
+	io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
+	io.in.create_options = 0;
+	io.in.fname = dotfile;
+
+	status = smb2_create(tree, tctx, &io);
+	torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
+					"smb2_create failed");
+	smb2_util_close(tree, io.out.file.handle);
+
+done:
+	if (!smb2_util_handle_empty(h1)) {
+		smb2_util_close(tree, h1);
+	}
+	smb2_deltree(tree, dname);
+	return ret;
+}
diff --git a/source4/torture/smb2/smb2.c b/source4/torture/smb2/smb2.c
index 90029c7..be632cc 100644
--- a/source4/torture/smb2/smb2.c
+++ b/source4/torture/smb2/smb2.c
@@ -170,6 +170,7 @@ NTSTATUS torture_smb2_init(void)
 	torture_suite_add_1smb2_test(suite, "hold-oplock", test_smb2_hold_oplock);
 	torture_suite_add_suite(suite, torture_smb2_session_init());
 	torture_suite_add_suite(suite, torture_smb2_replay_init());
+	torture_suite_add_simple_test(suite, "dosmode", torture_smb2_dosmode);
 
 	torture_suite_add_suite(suite, torture_smb2_doc_init());
 
diff --git a/source4/torture/smb2/wscript_build b/source4/torture/smb2/wscript_build
index 1c593ef..f404356 100644
--- a/source4/torture/smb2/wscript_build
+++ b/source4/torture/smb2/wscript_build
@@ -4,7 +4,7 @@ bld.SAMBA_MODULE('TORTURE_SMB2',
 	source='''connect.c scan.c util.c getinfo.c setinfo.c lock.c notify.c
 	smb2.c durable_open.c durable_v2_open.c oplock.c dir.c lease.c create.c
 	acls.c read.c compound.c streams.c ioctl.c rename.c
-	session.c delete-on-close.c replay.c notify_disabled.c''',
+	session.c delete-on-close.c replay.c notify_disabled.c dosmode.c''',
 	subsystem='smbtorture',
 	deps='LIBCLI_SMB2 POPT_CREDENTIALS torture NDR_IOCTL',
 	internal_module=True,
-- 
2.5.0



More information about the samba-technical mailing list