From 26a23214a93e0bbacc77f8f5947632a4e5fd3b66 Mon Sep 17 00:00:00 2001 From: Uri Simchoni Date: Wed, 24 Aug 2016 14:42:23 +0300 Subject: [PATCH] vfs_shadow_copy: handle non-existant files and wildcards During path checking, the vfs connectpath_fn is called to determine the share's root, relative to the file being queried (for example, in snapshot file this may be other than the share's "usual" root directory). connectpath_fn must be able to answer this question even if the path does not exist and its parent does exist. The convention in this case is that this refers to a yet-uncreated file under the parent and all queries are relative to the parent. This also serves as a workaround for the case where connectpath_fn has to handle wildcards, as with the case of SMB1 trans2 findfirst. BUG: https://bugzilla.samba.org/show_bug.cgi?id=12172 Signed-off-by: Uri Simchoni Reviewed-by: Jeremy Allison Autobuild-User(master): Jeremy Allison Autobuild-Date(master): Thu Aug 25 05:35:29 CEST 2016 on sn-devel-144 (cherry picked from commit f41f439335efb352d03a842c370212a0af77262a) --- selftest/knownfail | 2 -- source3/modules/vfs_shadow_copy2.c | 31 +++++++++++++++++++++++++++++- 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/selftest/knownfail b/selftest/knownfail index 68bd08201b0..40ac69657b4 100644 --- a/selftest/knownfail +++ b/selftest/knownfail @@ -344,5 +344,3 @@ ^samba4.smb2.read.access #ntvfs server blocks copychunk with execute access on read handle ^samba4.smb2.ioctl.copy_chunk_bad_access -#new snapshot dir listing test fails on SMB1 -^samba3.blackbox.shadow_copy2(?!.*wide links).*- list directory diff --git a/source3/modules/vfs_shadow_copy2.c b/source3/modules/vfs_shadow_copy2.c index 7ecdda585e7..1f38b85fabd 100644 --- a/source3/modules/vfs_shadow_copy2.c +++ b/source3/modules/vfs_shadow_copy2.c @@ -1793,6 +1793,7 @@ static const char *shadow_copy2_connectpath(struct vfs_handle_struct *handle, char *stripped = NULL; char *tmp = NULL; char *result = NULL; + char *parent_dir = NULL; int saved_errno; size_t rootpath_len = 0; @@ -1809,7 +1810,34 @@ static const char *shadow_copy2_connectpath(struct vfs_handle_struct *handle, tmp = shadow_copy2_do_convert(talloc_tos(), handle, stripped, timestamp, &rootpath_len); if (tmp == NULL) { - goto done; + if (errno != ENOENT) { + goto done; + } + + /* + * If the converted path does not exist, and converting + * the parent yields something that does exist, then + * this path refers to something that has not been + * created yet, relative to the parent path. + * The snapshot finding is relative to the parent. + * (usually snapshots are read/only but this is not + * necessarily true). + * This code also covers getting a wildcard in the + * last component, because this function is called + * prior to sanitizing the path, and in SMB1 we may + * get wildcards in path names. + */ + if (!parent_dirname(talloc_tos(), stripped, &parent_dir, + NULL)) { + errno = ENOMEM; + goto done; + } + + tmp = shadow_copy2_do_convert(talloc_tos(), handle, parent_dir, + timestamp, &rootpath_len); + if (tmp == NULL) { + goto done; + } } DBG_DEBUG("converted path is [%s] root path is [%.*s]\n", tmp, @@ -1827,6 +1855,7 @@ done: saved_errno = errno; TALLOC_FREE(tmp); TALLOC_FREE(stripped); + TALLOC_FREE(parent_dir); errno = saved_errno; return result; } -- 2.47.2