The Samba-Bugzilla – Attachment 14722 Details for
Bug 13688
Windows 2016 fails to restore previous version of a file from a shadow_copy2 snapshot
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch for 4.8 backported from master
bug13688-v48.patch (text/plain), 22.62 KB, created by
Ralph Böhme
on 2018-12-06 11:28:36 UTC
(
hide
)
Description:
Patch for 4.8 backported from master
Filename:
MIME Type:
Creator:
Ralph Böhme
Created:
2018-12-06 11:28:36 UTC
Size:
22.62 KB
patch
obsolete
>From 4ac6ce73a9a77103cbc8fc5a38171261f14d7e72 Mon Sep 17 00:00:00 2001 >From: Ralph Boehme <slow@samba.org> >Date: Fri, 23 Nov 2018 10:07:29 +0100 >Subject: [PATCH 1/7] vfs_error_inject: add pwrite > >Bug: https://bugzilla.samba.org/show_bug.cgi?id=13688 > >Signed-off-by: Ralph Boehme <slow@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit 55a82f907f6410ff478e82b0cf7f1caeacaf5ddd) >--- > source3/modules/vfs_error_inject.c | 18 ++++++++++++++++++ > 1 file changed, 18 insertions(+) > >diff --git a/source3/modules/vfs_error_inject.c b/source3/modules/vfs_error_inject.c >index bb5477a449f..9f0a25fb73f 100644 >--- a/source3/modules/vfs_error_inject.c >+++ b/source3/modules/vfs_error_inject.c >@@ -88,8 +88,26 @@ static int vfs_error_inject_chdir(vfs_handle_struct *handle, > return SMB_VFS_NEXT_CHDIR(handle, smb_fname); > } > >+static ssize_t vfs_error_inject_pwrite(vfs_handle_struct *handle, >+ files_struct *fsp, >+ const void *data, >+ size_t n, >+ off_t offset) >+{ >+ int error; >+ >+ error = inject_unix_error("pwrite", handle); >+ if (error != 0) { >+ errno = error; >+ return -1; >+ } >+ >+ return SMB_VFS_NEXT_PWRITE(handle, fsp, data, n, offset); >+} >+ > static struct vfs_fn_pointers vfs_error_inject_fns = { > .chdir_fn = vfs_error_inject_chdir, >+ .pwrite_fn = vfs_error_inject_pwrite, > }; > > static_decl_vfs; >-- >2.17.2 > > >From 37782e1093f5d2e6e6ea303bd51f8d6aba37f76f Mon Sep 17 00:00:00 2001 >From: Ralph Boehme <slow@samba.org> >Date: Fri, 23 Nov 2018 10:18:10 +0100 >Subject: [PATCH 2/7] vfs_error_inject: add EBADF error > >Bug: https://bugzilla.samba.org/show_bug.cgi?id=13688 > >Signed-off-by: Ralph Boehme <slow@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit 523a9b312c9f09178a5afefb48343e684e41d817) >--- > source3/modules/vfs_error_inject.c | 1 + > 1 file changed, 1 insertion(+) > >diff --git a/source3/modules/vfs_error_inject.c b/source3/modules/vfs_error_inject.c >index 9f0a25fb73f..c8c3ea4701f 100644 >--- a/source3/modules/vfs_error_inject.c >+++ b/source3/modules/vfs_error_inject.c >@@ -28,6 +28,7 @@ struct unix_error_map { > int error; > } unix_error_map_array[] = { > { "ESTALE", ESTALE }, >+ { "EBADF", EBADF }, > }; > > static int find_unix_error_from_string(const char *err_str) >-- >2.17.2 > > >From d2c5610297666d12770a7a219ba71af7bfe72c80 Mon Sep 17 00:00:00 2001 >From: Ralph Boehme <slow@samba.org> >Date: Wed, 14 Nov 2018 13:45:11 +0100 >Subject: [PATCH 3/7] s4:torture: add a test-suite for VSS > >This test will not be run from the main torture test runner in selftest, >as there we don't pass the required arguments 'twrp_file' and >'twrp_snapshot'. > >The test needs a carefully prepared environment with provisioned >snapshot data, so the test will be started from a blackbox test >script. That comes next. > >Bug: https://bugzilla.samba.org/show_bug.cgi?id=13688 > >Signed-off-by: Ralph Boehme <slow@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit 48ddb87a32ca44c2fcc5aac0cc28c5527dc7eade) >--- > source4/torture/smb2/create.c | 87 +++++++++++++++++++++++++++++++++++ > source4/torture/smb2/smb2.c | 1 + > 2 files changed, 88 insertions(+) > >diff --git a/source4/torture/smb2/create.c b/source4/torture/smb2/create.c >index ead56eb5c40..68447935bd0 100644 >--- a/source4/torture/smb2/create.c >+++ b/source4/torture/smb2/create.c >@@ -1733,6 +1733,82 @@ static bool test_dir_alloc_size(struct torture_context *tctx, > return ret; > } > >+static bool test_twrp_write(struct torture_context *tctx, struct smb2_tree *tree) >+{ >+ struct smb2_create io; >+ struct smb2_handle h1 = {{0}}; >+ NTSTATUS status; >+ bool ret = true; >+ char *p = NULL; >+ struct tm tm; >+ time_t t; >+ uint64_t nttime; >+ const char *file = NULL; >+ const char *snapshot = NULL; >+ >+ file = torture_setting_string(tctx, "twrp_file", NULL); >+ if (file == NULL) { >+ torture_skip(tctx, "missing 'twrp_file' option\n"); >+ } >+ >+ snapshot = torture_setting_string(tctx, "twrp_snapshot", NULL); >+ if (snapshot == NULL) { >+ torture_skip(tctx, "missing 'twrp_snapshot' option\n"); >+ } >+ >+ torture_comment(tctx, "Testing timewarp (%s) (%s)\n", file, snapshot); >+ >+ setenv("TZ", "GMT", 1); >+ p = strptime(snapshot, "@GMT-%Y.%m.%d-%H.%M.%S", &tm); >+ torture_assert_goto(tctx, p != NULL, ret, done, "strptime\n"); >+ torture_assert_goto(tctx, *p == '\0', ret, done, "strptime\n"); >+ >+ t = mktime(&tm); >+ unix_to_nt_time(&nttime, t); >+ >+ io = (struct smb2_create) { >+ .in.desired_access = SEC_FILE_READ_DATA, >+ .in.file_attributes = FILE_ATTRIBUTE_NORMAL, >+ .in.create_disposition = NTCREATEX_DISP_OPEN, >+ .in.share_access = NTCREATEX_SHARE_ACCESS_MASK, >+ .in.fname = file, >+ .in.query_maximal_access = true, >+ .in.timewarp = nttime, >+ }; >+ >+ status = smb2_create(tree, tctx, &io); >+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done, >+ "smb2_create\n"); >+ smb2_util_close(tree, io.out.file.handle); >+ >+ ret = io.out.maximal_access & (SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA); >+ torture_assert_goto(tctx, ret, ret, done, "Bad access\n"); >+ >+ io = (struct smb2_create) { >+ .in.desired_access = SEC_FILE_READ_DATA|SEC_FILE_WRITE_DATA, >+ .in.file_attributes = FILE_ATTRIBUTE_NORMAL, >+ .in.create_disposition = NTCREATEX_DISP_OPEN, >+ .in.share_access = NTCREATEX_SHARE_ACCESS_MASK, >+ .in.fname = file, >+ .in.timewarp = nttime, >+ }; >+ >+ status = smb2_create(tree, tctx, &io); >+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done, >+ "smb2_create\n"); >+ h1 = io.out.file.handle; >+ >+ status = smb2_util_write(tree, h1, "123", 0, 3); >+ torture_assert_ntstatus_equal_goto(tctx, status, >+ NT_STATUS_MEDIA_WRITE_PROTECTED, >+ ret, done, "smb2_create\n"); >+ >+ smb2_util_close(tree, h1); >+ >+done: >+ return ret; >+} >+ > /* > basic testing of SMB2 read > */ >@@ -1758,3 +1834,14 @@ struct torture_suite *torture_smb2_create_init(TALLOC_CTX *ctx) > > return suite; > } >+ >+struct torture_suite *torture_smb2_twrp_init(TALLOC_CTX *ctx) >+{ >+ struct torture_suite *suite = torture_suite_create(ctx, "twrp"); >+ >+ torture_suite_add_1smb2_test(suite, "write", test_twrp_write); >+ >+ suite->description = talloc_strdup(suite, "SMB2-TWRP tests"); >+ >+ return suite; >+} >diff --git a/source4/torture/smb2/smb2.c b/source4/torture/smb2/smb2.c >index 6f9884e3c27..a835dc7c050 100644 >--- a/source4/torture/smb2/smb2.c >+++ b/source4/torture/smb2/smb2.c >@@ -154,6 +154,7 @@ NTSTATUS torture_smb2_init(TALLOC_CTX *ctx) > torture_suite_add_suite(suite, torture_smb2_read_init(suite)); > torture_suite_add_suite(suite, torture_smb2_aio_delay_init(suite)); > torture_suite_add_suite(suite, torture_smb2_create_init(suite)); >+ torture_suite_add_suite(suite, torture_smb2_twrp_init(suite)); > torture_suite_add_suite(suite, torture_smb2_acls_init(suite)); > torture_suite_add_suite(suite, torture_smb2_notify_init(suite)); > torture_suite_add_suite(suite, torture_smb2_notify_inotify_init(suite)); >-- >2.17.2 > > >From 8a24c59e8896c1f4b74a6a3f7f36b0e44325acd5 Mon Sep 17 00:00:00 2001 >From: Ralph Boehme <slow@samba.org> >Date: Fri, 23 Nov 2018 10:18:44 +0100 >Subject: [PATCH 4/7] s3:script/tests: add a test for VSS write behaviour > >Bug: https://bugzilla.samba.org/show_bug.cgi?id=13688 > >Signed-off-by: Ralph Boehme <slow@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(backported from commit 12778f015988f7e8755016c72c26939998758dae) >--- > selftest/knownfail.d/samba3.blackbox | 1 + > selftest/target/Samba3.pm | 9 +++ > .../script/tests/test_shadow_copy_torture.sh | 76 +++++++++++++++++++ > source3/selftest/tests.py | 1 + > 4 files changed, 87 insertions(+) > create mode 100644 selftest/knownfail.d/samba3.blackbox > create mode 100755 source3/script/tests/test_shadow_copy_torture.sh > >diff --git a/selftest/knownfail.d/samba3.blackbox b/selftest/knownfail.d/samba3.blackbox >new file mode 100644 >index 00000000000..16537e58aeb >--- /dev/null >+++ b/selftest/knownfail.d/samba3.blackbox >@@ -0,0 +1 @@ >+^samba3.blackbox.shadow_copy_torture.writing to shadow copy of a file\(fileserver\) >diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm >index 3747a1e087e..02060f1e0f6 100755 >--- a/selftest/target/Samba3.pm >+++ b/selftest/target/Samba3.pm >@@ -2158,6 +2158,15 @@ sub provision($$$$$$$$$) > vfs objects = shadow_copy2 > shadow:mountpoint = $shadow_mntdir > wide links = yes >+ >+[shadow_write] >+ path = $shadow_tstdir >+ comment = previous versions snapshots under mount point >+ vfs objects = shadow_copy2 error_inject >+ aio write size = 0 >+ error_inject:pwrite = EBADF >+ shadow:mountpoint = $shadow_tstdir >+ > [dfq] > path = $shrdir/dfree > vfs objects = acl_xattr fake_acls xattr_tdb fake_dfq >diff --git a/source3/script/tests/test_shadow_copy_torture.sh b/source3/script/tests/test_shadow_copy_torture.sh >new file mode 100755 >index 00000000000..d47cd512a20 >--- /dev/null >+++ b/source3/script/tests/test_shadow_copy_torture.sh >@@ -0,0 +1,76 @@ >+#!/bin/bash >+# >+# Blackbox test for shadow_copy2 VFS. >+# >+ >+if [ $# -lt 7 ]; then >+cat <<EOF >+Usage: test_shadow_copy SERVER SERVER_IP DOMAIN USERNAME PASSWORD WORKDIR SMBTORTURE >+EOF >+exit 1; >+fi >+ >+SERVER=${1} >+SERVER_IP=${2} >+DOMAIN=${3} >+USERNAME=${4} >+PASSWORD=${5} >+WORKDIR=${6} >+SMBTORTURE="$VALGRIND ${7}" >+shift 7 >+ >+incdir=`dirname $0`/../../../testprogs/blackbox >+. $incdir/subunit.sh >+ >+SNAPSHOT="@GMT-2015.10.31-19.40.30" >+ >+failed=0 >+ >+# build a hierarchy of files, symlinks, and directories >+build_files() >+{ >+ local destdir >+ destdir=$1 >+ >+ echo "$content" > $destdir/foo >+} >+ >+# build a snapshots directory >+build_snapshots() >+{ >+ local snapdir >+ >+ snapdir=$WORKDIR/.snapshots >+ >+ mkdir -p $snapdir >+ mkdir $snapdir/$SNAPSHOT >+ >+ build_files $snapdir/$SNAPSHOT >+} >+ >+test_shadow_copy_write() >+{ >+ local msg >+ >+ msg=$1 >+ >+ #delete snapshots from previous tests >+ find $WORKDIR -name ".snapshots" -exec rm -rf {} \; 1>/dev/null 2>&1 >+ build_snapshots >+ >+ testit "writing to shadow copy of a file" \ >+ $SMBTORTURE \ >+ -U$USERNAME%$PASSWORD \ >+ "//$SERVER/shadow_write" \ >+ --option="torture:twrp_file=foo" \ >+ --option="torture:twrp_snapshot=$SNAPSHOT" \ >+ smb2.twrp.write || \ >+ failed=`expr $failed + 1` >+} >+ >+build_files $WORKDIR >+ >+# test open for writing and write behaviour of snapshoted files >+test_shadow_copy_write "write behaviour of snapshoted files" >+ >+exit $failed >diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py >index 7b3552a31b9..afdc32437af 100755 >--- a/source3/selftest/tests.py >+++ b/source3/selftest/tests.py >@@ -275,6 +275,7 @@ plantestsuite("samba3.blackbox.smbclient_ntlm.plain (%s)" % env, env, [os.path.j > plantestsuite("samba3.blackbox.offline (%s)" % env, env, [os.path.join(samba3srcdir, "script/tests/test_offline.sh"), '$SERVER', '$SERVER_IP', '$DOMAIN', '$USERNAME', '$PASSWORD', '$LOCAL_PATH/offline', smbclient3]) > plantestsuite("samba3.blackbox.shadow_copy2 NT1 (%s)" % env, env, [os.path.join(samba3srcdir, "script/tests/test_shadow_copy.sh"), '$SERVER', '$SERVER_IP', '$DOMAIN', '$USERNAME', '$PASSWORD', '$LOCAL_PATH/shadow', smbclient3, '-m', 'NT1']) > plantestsuite("samba3.blackbox.shadow_copy2 SMB3 (%s)" % env, env, [os.path.join(samba3srcdir, "script/tests/test_shadow_copy.sh"), '$SERVER', '$SERVER_IP', '$DOMAIN', '$USERNAME', '$PASSWORD', '$LOCAL_PATH/shadow', smbclient3, '-m', 'SMB3']) >+ plantestsuite("samba3.blackbox.shadow_copy_torture", env, [os.path.join(samba3srcdir, "script/tests/test_shadow_copy_torture.sh"), '$SERVER', '$SERVER_IP', '$DOMAIN', '$USERNAME', '$PASSWORD', '$LOCAL_PATH/shadow', smbtorture4]) > plantestsuite("samba3.blackbox.smbclient.forceuser_validusers (%s)" % env, env, [os.path.join(samba3srcdir, "script/tests/test_forceuser_validusers.sh"), '$SERVER', '$DOMAIN', '$USERNAME', '$PASSWORD', '$LOCAL_PATH', smbclient3]) > plantestsuite("samba3.blackbox.smbget (%s)" % env, env, [os.path.join(samba3srcdir, "script/tests/test_smbget.sh"), '$SERVER', '$SERVER_IP', '$DOMAIN', 'smbget_user', '$PASSWORD', '$LOCAL_PATH/smbget', smbget]) > plantestsuite("samba3.blackbox.netshareenum (%s)" % env, env, [os.path.join(samba3srcdir, "script/tests/test_shareenum.sh"), '$SERVER', '$USERNAME', '$PASSWORD', rpcclient]) >-- >2.17.2 > > >From 7685d437ee21bc1d3519800794bc056f960fac49 Mon Sep 17 00:00:00 2001 >From: Ralph Boehme <slow@samba.org> >Date: Thu, 22 Nov 2018 11:02:24 +0100 >Subject: [PATCH 5/7] vfs_shadow_copy2: add _already_converted arg to > shadow_copy2_strip_snapshot_internal() > >Not used for now, all existing callers pass NULL. > >Bug: https://bugzilla.samba.org/show_bug.cgi?id=13688 > >Signed-off-by: Ralph Boehme <slow@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit 87bf06ed790dad8a4f650c0cd1b6781864666cbf) >--- > source3/modules/vfs_shadow_copy2.c | 32 ++++++++++++++++++++++-------- > 1 file changed, 24 insertions(+), 8 deletions(-) > >diff --git a/source3/modules/vfs_shadow_copy2.c b/source3/modules/vfs_shadow_copy2.c >index b6745cf169b..604423d6d80 100644 >--- a/source3/modules/vfs_shadow_copy2.c >+++ b/source3/modules/vfs_shadow_copy2.c >@@ -587,7 +587,8 @@ static bool shadow_copy2_strip_snapshot_internal(TALLOC_CTX *mem_ctx, > const char *orig_name, > time_t *ptimestamp, > char **pstripped, >- char **psnappath) >+ char **psnappath, >+ bool *_already_converted) > { > struct tm tm; > time_t timestamp = 0; >@@ -608,6 +609,10 @@ static bool shadow_copy2_strip_snapshot_internal(TALLOC_CTX *mem_ctx, > > DEBUG(10, (__location__ ": enter path '%s'\n", name)); > >+ if (_already_converted != NULL) { >+ *_already_converted = false; >+ } >+ > abs_path = make_path_absolute(mem_ctx, priv, name); > if (abs_path == NULL) { > ret = false; >@@ -630,6 +635,9 @@ static bool shadow_copy2_strip_snapshot_internal(TALLOC_CTX *mem_ctx, > } > > if (already_converted) { >+ if (_already_converted != NULL) { >+ *_already_converted = true; >+ } > goto out; > } > >@@ -759,6 +767,7 @@ static bool shadow_copy2_strip_snapshot(TALLOC_CTX *mem_ctx, > orig_name, > ptimestamp, > pstripped, >+ NULL, > NULL); > } > >@@ -1119,12 +1128,14 @@ static int shadow_copy2_rename(vfs_handle_struct *handle, > > if (!shadow_copy2_strip_snapshot_internal(talloc_tos(), handle, > smb_fname_src->base_name, >- ×tamp_src, NULL, &snappath_src)) { >+ ×tamp_src, NULL, &snappath_src, >+ NULL)) { > return -1; > } > if (!shadow_copy2_strip_snapshot_internal(talloc_tos(), handle, > smb_fname_dst->base_name, >- ×tamp_dst, NULL, &snappath_dst)) { >+ ×tamp_dst, NULL, &snappath_dst, >+ NULL)) { > return -1; > } > if (timestamp_src != 0) { >@@ -1163,7 +1174,8 @@ static int shadow_copy2_symlink(vfs_handle_struct *handle, > link_contents, > ×tamp_old, > NULL, >- &snappath_old)) { >+ &snappath_old, >+ NULL)) { > return -1; > } > if (!shadow_copy2_strip_snapshot_internal(talloc_tos(), >@@ -1171,7 +1183,8 @@ static int shadow_copy2_symlink(vfs_handle_struct *handle, > new_smb_fname->base_name, > ×tamp_new, > NULL, >- &snappath_new)) { >+ &snappath_new, >+ NULL)) { > return -1; > } > if ((timestamp_old != 0) || (timestamp_new != 0)) { >@@ -1202,7 +1215,8 @@ static int shadow_copy2_link(vfs_handle_struct *handle, > old_smb_fname->base_name, > ×tamp_old, > NULL, >- &snappath_old)) { >+ &snappath_old, >+ NULL)) { > return -1; > } > if (!shadow_copy2_strip_snapshot_internal(talloc_tos(), >@@ -1210,7 +1224,8 @@ static int shadow_copy2_link(vfs_handle_struct *handle, > new_smb_fname->base_name, > ×tamp_new, > NULL, >- &snappath_new)) { >+ &snappath_new, >+ NULL)) { > return -1; > } > if ((timestamp_old != 0) || (timestamp_new != 0)) { >@@ -1566,7 +1581,8 @@ static int shadow_copy2_chdir(vfs_handle_struct *handle, > smb_fname->base_name, > ×tamp, > &stripped, >- &snappath)) { >+ &snappath, >+ NULL)) { > return -1; > } > if (stripped != NULL) { >-- >2.17.2 > > >From 7f8528759d64e995d027258f53576f2c183084bf Mon Sep 17 00:00:00 2001 >From: Ralph Boehme <slow@samba.org> >Date: Thu, 22 Nov 2018 11:04:54 +0100 >Subject: [PATCH 6/7] vfs_shadow_copy2: add > shadow_copy2_strip_snapshot_converted > >Can be used by callers to determine if a path is in fact pointing at a >file in a snapshot. Will be used in the next commit. > >Bug: https://bugzilla.samba.org/show_bug.cgi?id=13688 > >Signed-off-by: Ralph Boehme <slow@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit 14d6488d355e960ab02e72c414cbbc316f1db718) >--- > source3/modules/vfs_shadow_copy2.c | 16 ++++++++++++++++ > 1 file changed, 16 insertions(+) > >diff --git a/source3/modules/vfs_shadow_copy2.c b/source3/modules/vfs_shadow_copy2.c >index 604423d6d80..ebda08678ea 100644 >--- a/source3/modules/vfs_shadow_copy2.c >+++ b/source3/modules/vfs_shadow_copy2.c >@@ -771,6 +771,22 @@ static bool shadow_copy2_strip_snapshot(TALLOC_CTX *mem_ctx, > NULL); > } > >+static bool shadow_copy2_strip_snapshot_converted(TALLOC_CTX *mem_ctx, >+ struct vfs_handle_struct *handle, >+ const char *orig_name, >+ time_t *ptimestamp, >+ char **pstripped, >+ bool *is_converted) >+{ >+ return shadow_copy2_strip_snapshot_internal(mem_ctx, >+ handle, >+ orig_name, >+ ptimestamp, >+ pstripped, >+ NULL, >+ is_converted); >+} >+ > static char *shadow_copy2_find_mount_point(TALLOC_CTX *mem_ctx, > vfs_handle_struct *handle) > { >-- >2.17.2 > > >From 4fcf956077210dc758a9714b0199db8b65874e9a Mon Sep 17 00:00:00 2001 >From: Ralph Boehme <slow@samba.org> >Date: Fri, 23 Nov 2018 14:08:15 +0100 >Subject: [PATCH 7/7] vfs_shadow_copy2: nicely deal with attempts to open > previous version for writing > >Bug: https://bugzilla.samba.org/show_bug.cgi?id=13688 > >Signed-off-by: Ralph Boehme <slow@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit cf95756235f718478e556ce1fbf7c032f9c9acfb) >--- > selftest/knownfail.d/samba3.blackbox | 1 - > source3/modules/vfs_shadow_copy2.c | 124 ++++++++++++++++++++++++++- > 2 files changed, 122 insertions(+), 3 deletions(-) > delete mode 100644 selftest/knownfail.d/samba3.blackbox > >diff --git a/selftest/knownfail.d/samba3.blackbox b/selftest/knownfail.d/samba3.blackbox >deleted file mode 100644 >index 16537e58aeb..00000000000 >--- a/selftest/knownfail.d/samba3.blackbox >+++ /dev/null >@@ -1 +0,0 @@ >-^samba3.blackbox.shadow_copy_torture.writing to shadow copy of a file\(fileserver\) >diff --git a/source3/modules/vfs_shadow_copy2.c b/source3/modules/vfs_shadow_copy2.c >index ebda08678ea..a88930b1c02 100644 >--- a/source3/modules/vfs_shadow_copy2.c >+++ b/source3/modules/vfs_shadow_copy2.c >@@ -36,6 +36,8 @@ > #include "include/ntioctl.h" > #include "util_tdb.h" > #include "lib/util_path.h" >+#include "libcli/security/security.h" >+#include "lib/util/tevent_unix.h" > > struct shadow_copy2_config { > char *gmt_format; >@@ -1376,15 +1378,27 @@ static int shadow_copy2_open(vfs_handle_struct *handle, > time_t timestamp = 0; > char *stripped = NULL; > char *tmp; >+ bool is_converted = false; > int saved_errno = 0; > int ret; > >- if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, >+ if (!shadow_copy2_strip_snapshot_converted(talloc_tos(), handle, > smb_fname->base_name, >- ×tamp, &stripped)) { >+ ×tamp, &stripped, >+ &is_converted)) { > return -1; > } > if (timestamp == 0) { >+ if (is_converted) { >+ /* >+ * Just pave over the user requested mode and use >+ * O_RDONLY. Later attempts by the client to write on >+ * the handle will fail in the pwrite() syscall with >+ * EINVAL which we carefully map to EROFS. In sum, this >+ * matches Windows behaviour. >+ */ >+ flags = O_RDONLY; >+ } > return SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode); > } > >@@ -1398,6 +1412,14 @@ static int shadow_copy2_open(vfs_handle_struct *handle, > return -1; > } > >+ /* >+ * Just pave over the user requested mode and use O_RDONLY. Later >+ * attempts by the client to write on the handle will fail in the >+ * pwrite() syscall with EINVAL which we carefully map to EROFS. In sum, >+ * this matches Windows behaviour. >+ */ >+ flags = O_RDONLY; >+ > ret = SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode); > if (ret == -1) { > saved_errno = errno; >@@ -2935,6 +2957,101 @@ static int shadow_copy2_get_quota(vfs_handle_struct *handle, > return ret; > } > >+static ssize_t shadow_copy2_pwrite(vfs_handle_struct *handle, >+ files_struct *fsp, >+ const void *data, >+ size_t n, >+ off_t offset) >+{ >+ ssize_t nwritten; >+ >+ nwritten = SMB_VFS_NEXT_PWRITE(handle, fsp, data, n, offset); >+ if (nwritten == -1) { >+ if (errno == EBADF && fsp->can_write) { >+ errno = EROFS; >+ } >+ } >+ >+ return nwritten; >+} >+ >+struct shadow_copy2_pwrite_state { >+ vfs_handle_struct *handle; >+ files_struct *fsp; >+ ssize_t ret; >+ struct vfs_aio_state vfs_aio_state; >+}; >+ >+static void shadow_copy2_pwrite_done(struct tevent_req *subreq); >+ >+static struct tevent_req *shadow_copy2_pwrite_send( >+ struct vfs_handle_struct *handle, TALLOC_CTX *mem_ctx, >+ struct tevent_context *ev, struct files_struct *fsp, >+ const void *data, size_t n, off_t offset) >+{ >+ struct tevent_req *req = NULL, *subreq = NULL; >+ struct shadow_copy2_pwrite_state *state = NULL; >+ >+ req = tevent_req_create(mem_ctx, &state, >+ struct shadow_copy2_pwrite_state); >+ if (req == NULL) { >+ return NULL; >+ } >+ state->handle = handle; >+ state->fsp = fsp; >+ >+ subreq = SMB_VFS_NEXT_PWRITE_SEND(state, >+ ev, >+ handle, >+ fsp, >+ data, >+ n, >+ offset); >+ if (tevent_req_nomem(subreq, req)) { >+ return tevent_req_post(req, ev); >+ } >+ tevent_req_set_callback(subreq, shadow_copy2_pwrite_done, req); >+ >+ return req; >+} >+ >+static void shadow_copy2_pwrite_done(struct tevent_req *subreq) >+{ >+ struct tevent_req *req = tevent_req_callback_data( >+ subreq, struct tevent_req); >+ struct shadow_copy2_pwrite_state *state = tevent_req_data( >+ req, struct shadow_copy2_pwrite_state); >+ >+ state->ret = SMB_VFS_PWRITE_RECV(subreq, &state->vfs_aio_state); >+ TALLOC_FREE(subreq); >+ if (state->ret == -1) { >+ tevent_req_error(req, state->vfs_aio_state.error); >+ return; >+ } >+ >+ tevent_req_done(req); >+} >+ >+static ssize_t shadow_copy2_pwrite_recv(struct tevent_req *req, >+ struct vfs_aio_state *vfs_aio_state) >+{ >+ struct shadow_copy2_pwrite_state *state = tevent_req_data( >+ req, struct shadow_copy2_pwrite_state); >+ >+ if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) { >+ if ((vfs_aio_state->error == EBADF) && >+ state->fsp->can_write) >+ { >+ vfs_aio_state->error = EROFS; >+ errno = EROFS; >+ } >+ return -1; >+ } >+ >+ *vfs_aio_state = state->vfs_aio_state; >+ return state->ret; >+} >+ > static int shadow_copy2_connect(struct vfs_handle_struct *handle, > const char *service, const char *user) > { >@@ -3298,6 +3415,9 @@ static struct vfs_fn_pointers vfs_shadow_copy2_fns = { > .chmod_acl_fn = shadow_copy2_chmod_acl, > .chflags_fn = shadow_copy2_chflags, > .get_real_filename_fn = shadow_copy2_get_real_filename, >+ .pwrite_fn = shadow_copy2_pwrite, >+ .pwrite_send_fn = shadow_copy2_pwrite_send, >+ .pwrite_recv_fn = shadow_copy2_pwrite_recv, > .connectpath_fn = shadow_copy2_connectpath, > }; > >-- >2.17.2 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Flags:
jra
:
review+
Actions:
View
Attachments on
bug 13688
:
14671
|
14713
| 14722