[SCM] Samba Shared Repository - branch master updated

Andrew Bartlett abartlet at samba.org
Fri Jul 5 05:03:01 UTC 2019


The branch, master has been updated
       via  b1fc6e435b4 s3:tests: Add test for manual smbtorture zero-data
       via  e1bb3d34d90 smbtorture: Add smb2.ioctl.zero_data
       via  aa199696b9c smbtorture: Add smb2.ioctl.sparse_set_sparse
       via  7425a8fbbe3 winexe: Add support for connecting to a host on an alternate port
       via  f31333d40e6 s4 heimdal_build: Fix static heimdal builds with replacement closefrom()
       via  17d267e9578 winexe: Fix translation of the winexesvc binaries to C
      from  9d90ac352d4 util: Fix off-by-one error in message about overflow

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit b1fc6e435b455533edecc0985dbf882d974e7acd
Author: Christof Schmitt <cs at samba.org>
Date:   Wed May 22 15:09:59 2019 -0700

    s3:tests: Add test for manual smbtorture zero-data
    
    Ensure that these tests keep working.
    
    Signed-off-by: Christof Schmitt <cs at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    
    Autobuild-User(master): Andrew Bartlett <abartlet at samba.org>
    Autobuild-Date(master): Fri Jul  5 05:02:12 UTC 2019 on sn-devel-184

commit e1bb3d34d900730c71ceaf2a1fba23823342f94e
Author: Christof Schmitt <cs at samba.org>
Date:   Fri Sep 28 16:37:51 2018 -0700

    smbtorture: Add smb2.ioctl.zero_data
    
    Allow to manually issue the FSCTL_ZERO_DATA call and verify the
    state of the file in the file system.
    
    Signed-off-by: Christof Schmitt <cs at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit aa199696b9cf16660a7f8f2bcc2940153a855c41
Author: Christof Schmitt <cs at samba.org>
Date:   Fri Sep 28 16:08:22 2018 -0700

    smbtorture: Add smb2.ioctl.sparse_set_sparse
    
    This allows for manual testing of changing the sparse setting on a file
    and verifying the flag in the file system.
    
    Signed-off-by: Christof Schmitt <cs at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 7425a8fbbe358c389f863a7295a95dff023f52dc
Author: Karl Lenz <xorangekiller at gmail.com>
Date:   Thu Jul 4 20:28:33 2019 -0400

    winexe: Add support for connecting to a host on an alternate port
    
    This commit allows an optional port number to be specified after the
    hostname on the winexe command line. If no port is given, it defaults
    to port 445, just like it used before. Although this is probably a
    pretty uncommon use-case, it allows port-forwarding the service through
    a firewall to an alternate port, which can occassionally be helpful.
    
    $ ./bin/winexe -U karl%password1 //127.0.0.1:5445 cmd.exe
    Microsoft Windows [Version 6.1.7601]
    Copyright (c) 2009 Microsoft Corporation.  All rights reserved.
    
    C:\Windows\system32>
    
    Signed-off-by: Karl Lenz <xorangekiller at gmail.com>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Gary Lockyer <gary at catalyst.net.nz>

commit f31333d40e6fa38daa32a3ebb32d5a317c06fc62
Author: Karl Lenz <xorangekiller at gmail.com>
Date:   Thu Jul 4 20:27:46 2019 -0400

    s4 heimdal_build: Fix static heimdal builds with replacement closefrom()
    
    If Samba was configured with "--nonshared-binary=winexe" to build
    winexe as a static binary, and the replacement closefrom() function
    was used (which is default on most GNU/Linux systems without the libbsd
    development package installed), then winexe would fail to link with the
    error message shown below.
    
    [2631/3059] Linking bin/default/examples/winexe/winexe
    source4/heimdal/lib/roken/closefrom.c.1.o: In function `rep_closefrom':
    closefrom.c:(.text+0x0): multiple definition of `rep_closefrom'
    lib/replace/closefrom.c.2.o:closefrom.c:(.text+0x292): first defined here
    collect2: error: ld returned 1 exit status
    
    The real problem here was not with the winexe build itself - that was
    merely the application that I was attempting to build statically when I
    encountered it. As Andrew Bartlett very helpfully pointed out to me, this
    regression was introduced when "lib/replace/closefrom.c" was added in
    commit 55529d0f and, more to the point, when the heimdal build started
    using it in commit 3a7ebd0e. From that point on, any time that Samba's
    embedded copy of heimdal was statically linked into an application, it
    would fail to link because heimdal's own rep_closefrom() function in its
    "roken" library would conflict with the rep_closefrom() function in the
    "replace" library used elsewhere in Samba - a library which the "roken"
    library itself depends on. To further compound the problem, heimdal's
    own "roken" library is also compiled for the host (a necessary
    distinction for cross-compiled builds) and linked into a small number of
    utility applications used during the heimdal build. However, they can't
    link directly against the "replace" library, unlike the main "roken"
    library build which carries that dependency, because the "replace"
    library is _not_ built for the host.
    
    I solved this problem by eliminating heimdal's version of rep_closefrom()
    and making it use the one from "lib/replace" everywhere. That wasn't a
    problem for the main heimdal library that is built for the target because
    it was already linking in "lib/replace" (that's what caused this problem
    in the first place!), but to solve the aforementioned issue with
    "lib/replace" not being built for the host, I added
    "lib/replace/closefrom.c" to the list of "source4/heimdal/lib/roken"
    sources to be built for the host to satisfy heimdal's host utilities.
    Everyone wins, I think.
    
    Signed-off-by: Karl Lenz <xorangekiller at gmail.com>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Gary Lockyer <gary at catalyst.net.nz>

commit 17d267e9578299b9ccfd0227e522b79152b00a27
Author: Karl Lenz <xorangekiller at gmail.com>
Date:   Thu Jul 4 18:30:44 2019 -0400

    winexe: Fix translation of the winexesvc binaries to C
    
    Two small Windows binaries that winexe uses to execute commands on a
    remote system, winexesvc32.exe and winexesvc64.exe, are compiled then
    translated into a C byte array as hex so that they can be embedded into
    the winexe binary. Although the winexesvc binaries were built properly,
    the Python method that does the translation to C tried to open them in
    text mode, which would have worked in Python 2 before the concept of
    bytearrays was introduced, but instead raises an exception in Python 3.
    The exception was unfortunately suppressed, so the build didn't stop,
    and the winexe binary that was produced was effectively useless because
    it didn't contain either winexesvc binary as expected. After winexe
    successfully authenticated with a Windows host, it showed the error
    message below rather than executing the given command on the remote
    system.
    
    $ ./bin/winexe -U karl%password1 -d 2 //192.168.56.3 cmd
    winexe_svc_install: dcerpc_svcctl_StartServiceW failed: WERR_BAD_EXE_FORMAT
    main: winexe_svc_install failed: NT_STATUS_BAD_INITIAL_PC
    
    This commit fixes that problem by opening the winexesvc binaries in
    binary mode rather than text mode when the winexe build script reads
    them to translate them to C. Furthermore it adds an additional
    sanity check that will cause the winexesvc binary generator commands to
    fail if the winexesvc binaries cannot be opened or read correctly to
    guarantee that the build does not silently "succeed" if something like
    this ever happens again.
    
    Signed-off-by: Karl Lenz <xorangekiller at gmail.com>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Gary Lockyer <gary at catalyst.net.nz>

-----------------------------------------------------------------------

Summary of changes:
 examples/winexe/winexe.c               |  26 +++++++-
 examples/winexe/wscript_build          |  30 +++++++--
 selftest/skip                          |   4 ++
 source3/script/tests/test_zero_data.sh |  52 ++++++++++++++++
 source3/selftest/tests.py              |   3 +
 source4/heimdal/lib/roken/closefrom.c  |  57 -----------------
 source4/heimdal_build/wscript_build    |  10 +--
 source4/torture/smb2/ioctl.c           | 110 +++++++++++++++++++++++++++++++++
 source4/torture/smb2/smb2.c            |   4 ++
 9 files changed, 228 insertions(+), 68 deletions(-)
 create mode 100755 source3/script/tests/test_zero_data.sh
 delete mode 100644 source4/heimdal/lib/roken/closefrom.c


Changeset truncated at 500 lines:

diff --git a/examples/winexe/winexe.c b/examples/winexe/winexe.c
index b2257852272..22f748b1d45 100644
--- a/examples/winexe/winexe.c
+++ b/examples/winexe/winexe.c
@@ -58,6 +58,7 @@ static const char version_message_fmt[] = "winexe version %d.%d\n"
 
 struct program_options {
 	char *hostname;
+	int port;
 	char *cmd;
 	struct cli_credentials *credentials;
 	char *runas;
@@ -77,6 +78,9 @@ static void parse_args(int argc, const char *argv[],
 	int argc_new;
 	char **argv_new;
 
+	int port = 445;
+	char *port_str = NULL;
+
 	int flag_interactive = SVC_IGNORE_INTERACTIVE;
 	int flag_ostype = 2;
 	int flag_reinstall = 0;
@@ -212,7 +216,7 @@ static void parse_args(int argc, const char *argv[],
 	pc = poptGetContext(argv[0], argc, (const char **) argv, long_options,
 			    0);
 
-	poptSetOtherOptionHelp(pc, "[OPTION]... //HOST COMMAND\nOptions:");
+	poptSetOtherOptionHelp(pc, "[OPTION]... //HOST[:PORT] COMMAND\nOptions:");
 
 	if (((opt = poptGetNextOpt(pc)) != -1) || flag_help || flag_version) {
 		fprintf(stderr, version_message_fmt, SAMBA_VERSION_MAJOR,
@@ -244,6 +248,17 @@ static void parse_args(int argc, const char *argv[],
 		exit(1);
 	}
 
+	port_str = strchr(argv_new[0], ':');
+	if (port_str) {
+		if (sscanf(port_str + 1, "%d", &port) != 1 || port <= 0) {
+			fprintf(stderr, version_message_fmt,
+				SAMBA_VERSION_MAJOR, SAMBA_VERSION_MINOR);
+			poptPrintHelp(pc, stdout, 0);
+			exit(1);
+		}
+		*port_str = '\0';
+	}
+
 	if (opt_debuglevel) {
 		lp_set_cmdline("log level", opt_debuglevel);
 	}
@@ -304,6 +319,7 @@ static void parse_args(int argc, const char *argv[],
 	options->credentials = cred;
 
 	options->hostname = argv_new[0] + 2;
+	options->port = port;
 	options->cmd = argv_new[1];
 
 	options->flags = flag_interactive;
@@ -323,6 +339,7 @@ static void parse_args(int argc, const char *argv[],
 
 static NTSTATUS winexe_svc_upload(
 	const char *hostname,
+	int port,
 	const char *service_filename,
 	const DATA_BLOB *svc32_exe,
 	const DATA_BLOB *svc64_exe,
@@ -339,7 +356,7 @@ static NTSTATUS winexe_svc_upload(
 		NULL,
 		hostname,
 		NULL,
-		445,
+		port,
 		"ADMIN$",
 		"?????",
 		credentials,
@@ -421,6 +438,7 @@ done:
 static NTSTATUS winexe_svc_install(
 	struct cli_state *cli,
 	const char *hostname,
+	int port,
 	const char *service_name,
 	const char *service_filename,
 	const DATA_BLOB *svc32_exe,
@@ -628,6 +646,7 @@ static NTSTATUS winexe_svc_install(
 	if (need_start) {
 		status = winexe_svc_upload(
 			hostname,
+			port,
 			service_filename,
 			svc32_exe,
 			svc64_exe,
@@ -1894,7 +1913,7 @@ int main(int argc, const char *argv[])
 		NULL,
 		options.hostname,
 		NULL,
-		445,
+		options.port,
 		"IPC$",
 		"?????",
 		options.credentials,
@@ -1910,6 +1929,7 @@ int main(int argc, const char *argv[])
 	status = winexe_svc_install(
 		cli,
 		options.hostname,
+		options.port,
 		service_name,
 		service_filename,
 		winexesvc32_exe,
diff --git a/examples/winexe/wscript_build b/examples/winexe/wscript_build
index ecad3772461..43c09717e3d 100644
--- a/examples/winexe/wscript_build
+++ b/examples/winexe/wscript_build
@@ -3,10 +3,18 @@
 import samba_utils
 
 def generate_winexesvc_c_from_exe(t):
+    '''generate a C source file with the contents of the given binary'''
     src = t.inputs[0].bldpath(t.env)
     tgt = t.outputs[0].bldpath(t.env)
     fn = t.env.SAMBA_GENERATOR_VARS['WINEXE_FN']
-    src_blob = samba_utils.load_file(src)
+
+    try:
+        with open(src, 'rb') as f:
+            src_blob = f.read()
+            f.close()
+    except:
+        print('Failed to read %s to convert to C array' % (src))
+        return -1
 
     def c_array(src):
         N = 0
@@ -14,11 +22,23 @@ def generate_winexesvc_c_from_exe(t):
         while src:
             l = src[:8]
             src = src[8:]
-            h = ' '.join(["0x%02X," % ord(x) for x in l])
+            # Even files opened in binary mode are read as type "str" in
+            # Python 2, so we need to get the integer ordinal of each
+            # character in the string before we try to convert it to hex.
+            if isinstance(l, str):
+                h = ' '.join(["0x%02X," % ord(x) for x in l])
+            # Files opened in binary mode are read as type "bytes" in
+            # Python 3, so we can convert each individual integer in the
+            # array of bytes to hex directly.
+            else:
+                h = ' '.join(["0x%02X," % x for x in l])
             result += "\t\t%s\n" % (h)
         return result
 
     src_array = c_array(src_blob)
+    if len(src_array) <= 0:
+        print('Failed to convert %s to C array' % (src))
+        return -1
 
     contents = '''
 #include "replace.h"
@@ -38,8 +58,10 @@ const DATA_BLOB *%s(void)
 }
 ''' % (fn, fn, src_array)
 
-    ret = samba_utils.save_file(tgt, contents)
-    assert(ret == True)
+    if not samba_utils.save_file(tgt, contents):
+        print('Failed to write C source file %s' % (tgt))
+        return -1
+    return 0
 
 winexesvc_binaries = ''
 
diff --git a/selftest/skip b/selftest/skip
index 43f65c3f1bd..1e7448acb9f 100644
--- a/selftest/skip
+++ b/selftest/skip
@@ -70,6 +70,8 @@
 ^samba3.smb2.hold-oplock                # Not a test, but a way to block other clients for a test
 ^samba3.smb2.hold-sharemode             # Not a test, but a way to block other clients for a test
 ^samba3.smb2.check-sharemode            # Not a test, but a way to test sharemodes outside of Samba
+^samba3.smb2.set-sparse-ioctl           # For manual testing, needs additional parameters.
+^samba3.smb2.zero-data-ioctl            # For manual testing, needs additional parameters.
 ^samba3.smb2.durable-open-disconnect    # Not a test, but a way to create a disconnected durable
 ^samba3.smb2.scan                       # No tests
 ^samba3.smb2.oplock.levelii501		# No test yet
@@ -83,6 +85,8 @@
 ^samba4.smb2.hold-oplock 		# Not a test, but a way to block other clients for a test
 ^samba4.smb2.hold-sharemode 		# Not a test, but a way to block other clients for a test
 ^samba4.smb2.check-sharemode            # Not a test, but a way to test sharemodes outside of Samba
+^samba4.smb2.set-sparse-ioctl           # For manual testing, needs additional parameters.
+^samba4.smb2.zero-data-ioctl            # For manual testing, needs additional parameters.
 ^samba4.raw.ping.pong		# Needs second server to test
 ^samba4.rpc.samr.accessmask
 ^samba4.rpc.samr.passwords.*ncacn_np\(ad_dc_ntvfs\) # currently fails, possibly config issue
diff --git a/source3/script/tests/test_zero_data.sh b/source3/script/tests/test_zero_data.sh
new file mode 100755
index 00000000000..6b965b57ba5
--- /dev/null
+++ b/source3/script/tests/test_zero_data.sh
@@ -0,0 +1,52 @@
+#!/bin/sh
+#
+# Verify that smbtorture tests for manually testing ZERO_DATA
+#
+# Copyright (C) 2019 Christof Schmitt
+
+if [ $# -lt 4 ]; then
+cat <<EOF
+Usage: test_zero_data.sh SERVER_IP USERNAME PASSWORD LOCAL_PATH
+EOF
+exit 1;
+fi
+
+SERVER=${1}
+USERNAME=${2}
+PASSWORD=${3}
+LOCAL_PATH=${4}
+
+. $(dirname $0)/../../../testprogs/blackbox/subunit.sh
+failed=0
+
+TESTDIR=$LOCAL_PATH/zero_data
+
+mkdir -p $TESTDIR
+chmod 777 p $TESTDIR
+
+dd if=/dev/urandom of=$TESTDIR/testfile bs=1024 count=128
+chmod 777 $TESTDIR/testfile
+
+alloc_kb=$(du -k $TESTDIR/testfile | sed -e 's/\t.*//')
+testit "check allocation before zero-data" test $alloc_kb -eq 128 ||
+	failed=$(expr $failed + 1)
+
+testit "set-sparse" $VALGRIND $BINDIR/smbtorture //$SERVER_IP/tmp \
+       -U$USERNAME%$PASSWORD smb2.set-sparse-ioctl \
+       --option=torture:filename=zero_data/testfile ||
+	failed=$(expr $failed + 1)
+
+testit "zero-data" $VALGRIND $BINDIR/smbtorture //$SERVER_IP/tmp \
+       -U$USERNAME%$PASSWORD smb2.zero-data-ioctl \
+       --option=torture:filename=zero_data/testfile \
+       --option=torture:offset=0 \
+       --option=torture:beyond_final_zero=131072 ||
+	failed=$(expr $failed + 1)
+
+alloc_kb=$(du -k $TESTDIR/testfile | sed -e 's/\t.*//')
+testit "check allocation after zero-data" test $alloc_kb -eq 0 ||
+	failed=$(expr $failed + 1)
+
+rm -rf $TESTDIR
+
+testok $0 $failed
diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py
index 1394dc456b2..78f58bdb30c 100755
--- a/source3/selftest/tests.py
+++ b/source3/selftest/tests.py
@@ -341,6 +341,9 @@ for env in ["fileserver"]:
     plantestsuite("samba3.blackbox.force_group_change", env,
 		[os.path.join(samba3srcdir, "script/tests/test_force_group_change.sh"),
 		'$SERVER', '$USERNAME', '$PASSWORD', '$LOCAL_PATH', smbclient3, smbcontrol])
+    plantestsuite("samba3.blackbox.zero-data", env,
+                  [os.path.join(samba3srcdir, "script/tests/test_zero_data.sh"),
+                   '$SERVER_IP', '$USERNAME', '$PASSWORD', '$LOCAL_PATH'])
 
     #
     # tar command tests
diff --git a/source4/heimdal/lib/roken/closefrom.c b/source4/heimdal/lib/roken/closefrom.c
deleted file mode 100644
index 770eb2c67ac..00000000000
--- a/source4/heimdal/lib/roken/closefrom.c
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (c) 2005 Kungliga Tekniska Högskolan
- * (Royal Institute of Technology, Stockholm, Sweden).
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * 3. Neither the name of the Institute nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <config.h>
-
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#include "roken.h"
-
-ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL
-closefrom(int fd)
-{
-    int num = getdtablesize();
-
-    if (num < 0)
-	num = 1024; /* XXX */
-
-    for (; fd <= num; fd++)
-	close(fd);
-
-    return 0;
-}
diff --git a/source4/heimdal_build/wscript_build b/source4/heimdal_build/wscript_build
index bedc130e07a..163b622fca9 100644
--- a/source4/heimdal_build/wscript_build
+++ b/source4/heimdal_build/wscript_build
@@ -376,7 +376,7 @@ if not bld.CONFIG_SET('USING_SYSTEM_ROKEN'):
             target = '../heimdal/lib/roken/err.h',
             )
 
-    ROKEN_HOSTCC_SOURCE = '''
+    ROKEN_COMMON_SOURCE = '''
         lib/roken/base64.c
         lib/roken/ct.c
         lib/roken/hex.c
@@ -411,11 +411,13 @@ if not bld.CONFIG_SET('USING_SYSTEM_ROKEN'):
     '''
 
     if not bld.CONFIG_SET('HAVE_CLOSEFROM'):
-        ROKEN_HOSTCC_SOURCE += '''
-            lib/roken/closefrom.c
+        ROKEN_HOSTCC_SOURCE = ROKEN_COMMON_SOURCE + '''
+            ../../lib/replace/closefrom.c
         '''
+    else:
+        ROKEN_HOSTCC_SOURCE = ROKEN_COMMON_SOURCE
 
-    ROKEN_SOURCE = ROKEN_HOSTCC_SOURCE + '''
+    ROKEN_SOURCE = ROKEN_COMMON_SOURCE + '''
         lib/roken/resolve.c
         lib/roken/socket.c
         lib/roken/roken_gethostby.c
diff --git a/source4/torture/smb2/ioctl.c b/source4/torture/smb2/ioctl.c
index 302ca4418f1..eed81d1f598 100644
--- a/source4/torture/smb2/ioctl.c
+++ b/source4/torture/smb2/ioctl.c
@@ -3235,6 +3235,55 @@ static NTSTATUS test_sparse_get(struct torture_context *torture,
 	return status;
 }
 
+/*
+ * Manually test setting and clearing sparse flag. Intended for file system
+ * specifc tests to toggle the flag through SMB and check the status in the
+ * file system.
+ */
+bool test_ioctl_set_sparse(struct torture_context *tctx)
+{
+	bool set, ret = true;
+	const char *filename = NULL;
+	struct smb2_create create = { };
+	struct smb2_tree *tree = NULL;
+	NTSTATUS status;
+
+	set = torture_setting_bool(tctx, "set_sparse", true);
+	filename = torture_setting_string(tctx, "filename", NULL);
+
+	if (filename == NULL) {
+		torture_fail(tctx, "Need to provide filename through "
+			     "--option=torture:filename=testfile\n");
+		return false;
+	}
+
+	if (!torture_smb2_connection(tctx, &tree)) {
+		torture_comment(tctx, "Initializing smb2 connection failed.\n");
+		return false;
+	}
+
+	create.in.desired_access = SEC_RIGHTS_DIR_ALL;
+	create.in.create_options = 0;
+	create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
+	create.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
+		NTCREATEX_SHARE_ACCESS_WRITE |
+		NTCREATEX_SHARE_ACCESS_DELETE;
+	create.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
+	create.in.fname = filename;
+
+	status = smb2_create(tree, tctx, &create);
+	torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
+					"CREATE failed.\n");
+
+	status = test_ioctl_sparse_req(tctx, tctx, tree,
+				       create.out.file.handle, set);
+	torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
+					"FSCTL_SET_SPARSE failed.\n");
+done:
+
+	return ret;
+}
+
 static bool test_ioctl_sparse_file_flag(struct torture_context *torture,
 					struct smb2_tree *tree)
 {
@@ -3845,6 +3894,67 @@ err_out:
 	return status;
 }
 
+bool test_ioctl_zero_data(struct torture_context *tctx)
+{
+	bool ret = true;
+	int offset, beyond_final_zero;
+	const char *filename;
+	NTSTATUS status;
+	struct smb2_create create = { };
+	struct smb2_tree *tree = NULL;
+
+	offset = torture_setting_int(tctx, "offset", -1);
+
+	if (offset < 0) {
+		torture_fail(tctx, "Need to provide non-negative offset "
+			     "through --option=torture:offset=NNN\n");
+		return false;
+	}
+
+	beyond_final_zero = torture_setting_int(tctx, "beyond_final_zero",
+						-1);
+	if (beyond_final_zero < 0) {
+		torture_fail(tctx, "Need to provide non-negative "
+			     "'beyond final zero' through "
+			     "--option=torture:beyond_final_zero=NNN\n");
+		return false;
+	}
+	filename = torture_setting_string(tctx, "filename", NULL);
+	if (filename == NULL) {
+		torture_fail(tctx, "Need to provide filename through "
+			     "--option=torture:filename=testfile\n");
+		return false;
+	}
+
+	if (!torture_smb2_connection(tctx, &tree)) {
+		torture_comment(tctx, "Initializing smb2 connection failed.\n");
+		return false;
+	}
+
+	create.in.desired_access = SEC_RIGHTS_DIR_ALL;
+	create.in.create_options = 0;
+	create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
+	create.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
+		NTCREATEX_SHARE_ACCESS_WRITE |
+		NTCREATEX_SHARE_ACCESS_DELETE;
+	create.in.create_disposition = NTCREATEX_DISP_OPEN;
+	create.in.fname = filename;
+
+	status = smb2_create(tree, tctx, &create);
+	torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
+					"CREATE failed.\n");
+
+	status = test_ioctl_zdata_req(tctx, tctx, tree,
+				      create.out.file.handle,
+				      offset,
+				      beyond_final_zero);
+	torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
+					"FSCTL_ZERO_DATA failed.\n");
+
+done:
+	return ret;
+}
+
 static bool test_ioctl_sparse_punch(struct torture_context *torture,
 				    struct smb2_tree *tree)
 {
diff --git a/source4/torture/smb2/smb2.c b/source4/torture/smb2/smb2.c
index 2a465a55ba2..f495c19d251 100644
--- a/source4/torture/smb2/smb2.c
+++ b/source4/torture/smb2/smb2.c
@@ -175,6 +175,10 @@ NTSTATUS torture_smb2_init(TALLOC_CTX *ctx)
 	torture_suite_add_suite(suite, torture_smb2_kernel_oplocks_init(suite));
 	torture_suite_add_suite(suite, torture_smb2_streams_init(suite));
 	torture_suite_add_suite(suite, torture_smb2_ioctl_init(suite));
+	torture_suite_add_simple_test(suite, "set-sparse-ioctl",
+				      test_ioctl_set_sparse);
+	torture_suite_add_simple_test(suite, "zero-data-ioctl",
+				      test_ioctl_zero_data);
 	torture_suite_add_suite(suite, torture_smb2_rename_init(suite));
 	torture_suite_add_1smb2_test(suite, "bench-oplock", test_smb2_bench_oplock);
 	torture_suite_add_suite(suite, torture_smb2_sharemode_init(suite));


-- 
Samba Shared Repository



More information about the samba-cvs mailing list