[SCM] Samba Shared Repository - branch master updated
Ralph Böhme
slow at samba.org
Wed May 6 11:59:04 UTC 2020
The branch, master has been updated
via 04da0c344ea test: Make local.event.*.fd1 a bit less flapping
via a3d1ac2a597 vfs_shadow_copy2: implement case canonicalisation in shadow_copy2_get_real_filename()
via aa5f19ddf1d smbd: make get_real_filename_full_scan() public
via 6557777c86d CI: add two tests for shadow_copy2 VFS module
via 1b74a4a3bb6 vfs_shadow_copy2: log caller location in shadow_copy2_strip_snapshot()
from 23c2195e2c1 ctdb-build: Add messages_dgm build to ctdb
https://git.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit 04da0c344eab9878f2cf2197de7825873454d980
Author: Volker Lendecke <vl at samba.org>
Date: Tue May 5 15:07:49 2020 +0200
test: Make local.event.*.fd1 a bit less flapping
One millisecond seems not enough on slow machines, make the timeout 10 msec
Signed-off-by: Volker Lendecke <vl at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
Autobuild-User(master): Ralph Böhme <slow at samba.org>
Autobuild-Date(master): Wed May 6 11:58:42 UTC 2020 on sn-devel-184
commit a3d1ac2a597e2441d6855db566306298ae5db99b
Author: Ralph Boehme <slow at samba.org>
Date: Tue May 5 10:13:00 2020 +0200
vfs_shadow_copy2: implement case canonicalisation in shadow_copy2_get_real_filename()
unix_convert() can't do this for us in snapdirseverywhere mode, so we do it
ourselves.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14350
Signed-off-by: Ralph Boehme <slow at samba.org>
Reviewed-by: Jeremy Allison <jra at samba.org>
commit aa5f19ddf1dec1ac4386441929bca94727f30ee6
Author: Ralph Boehme <slow at samba.org>
Date: Thu Apr 23 16:09:16 2020 +0200
smbd: make get_real_filename_full_scan() public
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14350
Signed-off-by: Ralph Boehme <slow at samba.org>
Reviewed-by: Jeremy Allison <jra at samba.org>
commit 6557777c86d72a185b3fe4061a8b5791fd748924
Author: Ralph Boehme <slow at samba.org>
Date: Tue Apr 21 13:06:03 2020 +0200
CI: add two tests for shadow_copy2 VFS module
Note that the test "fetch a previous version of a regular file via non-canonical
basepath" doesn't fail by "luck" because it runs into the "creating file"
optimisation in unix_convert().
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14350
Signed-off-by: Ralph Boehme <slow at samba.org>
Reviewed-by: Jeremy Allison <jra at samba.org>
commit 1b74a4a3bb697afca3d330b8b110d4c1e1d92130
Author: Ralph Boehme <slow at samba.org>
Date: Tue May 5 10:09:01 2020 +0200
vfs_shadow_copy2: log caller location in shadow_copy2_strip_snapshot()
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14350
Signed-off-by: Ralph Boehme <slow at samba.org>
Reviewed-by: Jeremy Allison <jra at samba.org>
-----------------------------------------------------------------------
Summary of changes:
lib/tevent/testsuite.c | 2 +-
source3/modules/vfs_shadow_copy2.c | 121 +++++++++++++++++++++++++------
source3/script/tests/test_shadow_copy.sh | 12 +++
source3/smbd/filename.c | 10 ++-
source3/smbd/proto.h | 6 ++
5 files changed, 122 insertions(+), 29 deletions(-)
Changeset truncated at 500 lines:
diff --git a/lib/tevent/testsuite.c b/lib/tevent/testsuite.c
index ee4c2850230..3bf4bd7a574 100644
--- a/lib/tevent/testsuite.c
+++ b/lib/tevent/testsuite.c
@@ -423,7 +423,7 @@ static bool test_event_fd1(struct torture_context *tctx,
torture_assert(tctx, ret == 0, "socketpair() failed");
state.te = tevent_add_timer(state.ev, state.ev,
- timeval_current_ofs(0,1000),
+ timeval_current_ofs(0,10000),
test_event_fd1_finished, &state);
state.fde0 = tevent_add_fd(state.ev, state.ev,
state.sock[0], TEVENT_FD_WRITE,
diff --git a/source3/modules/vfs_shadow_copy2.c b/source3/modules/vfs_shadow_copy2.c
index 53fee915c37..f8f0f82e79e 100644
--- a/source3/modules/vfs_shadow_copy2.c
+++ b/source3/modules/vfs_shadow_copy2.c
@@ -584,13 +584,14 @@ static int check_for_converted_path(TALLOC_CTX *mem_ctx,
* (making it cwd-relative).
*/
-static bool shadow_copy2_strip_snapshot_internal(TALLOC_CTX *mem_ctx,
+static bool _shadow_copy2_strip_snapshot_internal(TALLOC_CTX *mem_ctx,
struct vfs_handle_struct *handle,
const struct smb_filename *smb_fname,
time_t *ptimestamp,
char **pstripped,
char **psnappath,
- bool *_already_converted)
+ bool *_already_converted,
+ const char *function)
{
char *stripped = NULL;
struct shadow_copy2_private *priv;
@@ -602,7 +603,8 @@ static bool shadow_copy2_strip_snapshot_internal(TALLOC_CTX *mem_ctx,
SMB_VFS_HANDLE_GET_DATA(handle, priv, struct shadow_copy2_private,
return false);
- DBG_DEBUG("Enter path '%s'\n", smb_fname_str_dbg(smb_fname));
+ DBG_DEBUG("[from %s()] Path '%s'\n",
+ function, smb_fname_str_dbg(smb_fname));
if (_already_converted != NULL) {
*_already_converted = false;
@@ -671,37 +673,57 @@ static bool shadow_copy2_strip_snapshot_internal(TALLOC_CTX *mem_ctx,
return ret;
}
-static bool shadow_copy2_strip_snapshot(TALLOC_CTX *mem_ctx,
- struct vfs_handle_struct *handle,
- const struct smb_filename *orig_name,
- time_t *ptimestamp,
- char **pstripped)
+#define shadow_copy2_strip_snapshot_internal(mem_ctx, handle, orig_name, \
+ ptimestamp, pstripped, psnappath, _already_converted) \
+ _shadow_copy2_strip_snapshot_internal((mem_ctx), (handle), (orig_name), \
+ (ptimestamp), (pstripped), (psnappath), (_already_converted), \
+ __FUNCTION__)
+
+static bool _shadow_copy2_strip_snapshot(TALLOC_CTX *mem_ctx,
+ struct vfs_handle_struct *handle,
+ const struct smb_filename *orig_name,
+ time_t *ptimestamp,
+ char **pstripped,
+ const char *function)
{
- return shadow_copy2_strip_snapshot_internal(mem_ctx,
+ return _shadow_copy2_strip_snapshot_internal(mem_ctx,
handle,
orig_name,
ptimestamp,
pstripped,
NULL,
- NULL);
+ NULL,
+ function);
}
-static bool shadow_copy2_strip_snapshot_converted(TALLOC_CTX *mem_ctx,
+#define shadow_copy2_strip_snapshot(mem_ctx, handle, orig_name, \
+ ptimestamp, pstripped) \
+ _shadow_copy2_strip_snapshot((mem_ctx), (handle), (orig_name), \
+ (ptimestamp), (pstripped), __FUNCTION__)
+
+static bool _shadow_copy2_strip_snapshot_converted(TALLOC_CTX *mem_ctx,
struct vfs_handle_struct *handle,
const struct smb_filename *orig_name,
time_t *ptimestamp,
char **pstripped,
- bool *is_converted)
+ bool *is_converted,
+ const char *function)
{
- return shadow_copy2_strip_snapshot_internal(mem_ctx,
+ return _shadow_copy2_strip_snapshot_internal(mem_ctx,
handle,
orig_name,
ptimestamp,
pstripped,
NULL,
- is_converted);
+ is_converted,
+ function);
}
+#define shadow_copy2_strip_snapshot_converted(mem_ctx, handle, orig_name, \
+ ptimestamp, pstripped, is_converted) \
+ _shadow_copy2_strip_snapshot_converted((mem_ctx), (handle), (orig_name), \
+ (ptimestamp), (pstripped), (is_converted), __FUNCTION__)
+
static char *shadow_copy2_find_mount_point(TALLOC_CTX *mem_ctx,
vfs_handle_struct *handle)
{
@@ -2389,6 +2411,8 @@ static int shadow_copy2_get_real_filename(struct vfs_handle_struct *handle,
char **found_name)
{
char *path = fname->base_name;
+ struct shadow_copy2_private *priv = NULL;
+ struct shadow_copy2_config *config = NULL;
time_t timestamp = 0;
char *stripped = NULL;
ssize_t ret;
@@ -2396,8 +2420,11 @@ static int shadow_copy2_get_real_filename(struct vfs_handle_struct *handle,
char *conv;
struct smb_filename conv_fname;
- DEBUG(10, ("shadow_copy2_get_real_filename called for path=[%s], "
- "name=[%s]\n", path, name));
+ SMB_VFS_HANDLE_GET_DATA(handle, priv, struct shadow_copy2_private,
+ return -1);
+ config = priv->config;
+
+ DBG_DEBUG("Path=[%s] name=[%s]\n", smb_fname_str_dbg(fname), name);
if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, fname,
×tamp, &stripped)) {
@@ -2409,11 +2436,37 @@ static int shadow_copy2_get_real_filename(struct vfs_handle_struct *handle,
return SMB_VFS_NEXT_GET_REAL_FILENAME(handle, fname, name,
mem_ctx, found_name);
}
+
+ /*
+ * Note that stripped may be an empty string "" if path was ".". As
+ * shadow_copy2_convert() combines "" with the shadow-copy tree connect
+ * root fullpath and get_real_filename_full_scan() has an explicit check
+ * for "" this works.
+ */
+ DBG_DEBUG("stripped [%s]\n", stripped);
+
conv = shadow_copy2_convert(talloc_tos(), handle, stripped, timestamp);
- TALLOC_FREE(stripped);
if (conv == NULL) {
- DEBUG(10, ("shadow_copy2_convert failed\n"));
- return -1;
+ if (!config->snapdirseverywhere) {
+ DBG_DEBUG("shadow_copy2_convert [%s] failed\n", stripped);
+ return -1;
+ }
+
+ /*
+ * We're called in the path traversal loop in unix_convert()
+ * walking down the directory hierarchy. shadow_copy2_convert()
+ * will fail if the snapshot directory is futher down in the
+ * hierachy. Set conv to the original stripped path and try to
+ * look it up in the filesystem with
+ * SMB_VFS_NEXT_GET_REAL_FILENAME() or
+ * get_real_filename_full_scan().
+ */
+ DBG_DEBUG("Use stripped [%s] as conv\n", stripped);
+ conv = talloc_strdup(talloc_tos(), stripped);
+ if (conv == NULL) {
+ TALLOC_FREE(stripped);
+ return -1;
+ }
}
conv_fname = (struct smb_filename) {
@@ -2425,14 +2478,34 @@ static int shadow_copy2_get_real_filename(struct vfs_handle_struct *handle,
ret = SMB_VFS_NEXT_GET_REAL_FILENAME(handle, &conv_fname, name,
mem_ctx, found_name);
DEBUG(10, ("NEXT_REAL_FILE_NAME returned %d\n", (int)ret));
- if (ret == -1) {
- saved_errno = errno;
+ if (ret == 0) {
+ return 0;
}
- TALLOC_FREE(conv);
- if (saved_errno != 0) {
+ if (errno != EOPNOTSUPP) {
+ TALLOC_FREE(conv);
+ errno = EOPNOTSUPP;
+ return -1;
+ }
+
+ ret = get_real_filename_full_scan(handle->conn,
+ conv,
+ name,
+ false,
+ mem_ctx,
+ found_name);
+ if (ret != 0) {
+ saved_errno = errno;
+ DBG_DEBUG("Scan [%s] for [%s] failed\n",
+ conv, name);
errno = saved_errno;
+ return -1;
}
- return ret;
+
+ DBG_DEBUG("Scan [%s] for [%s] returned [%s]\n",
+ conv, name, *found_name);
+
+ TALLOC_FREE(conv);
+ return 0;
}
static const char *shadow_copy2_connectpath(struct vfs_handle_struct *handle,
diff --git a/source3/script/tests/test_shadow_copy.sh b/source3/script/tests/test_shadow_copy.sh
index eba873f6525..fe4bcb8720e 100755
--- a/source3/script/tests/test_shadow_copy.sh
+++ b/source3/script/tests/test_shadow_copy.sh
@@ -333,6 +333,18 @@ test_shadow_copy_everywhere()
test_fetch_snap_file $share "bar/baz" 6 || \
failed=`expr $failed + 1`
+ testit "fetch a previous version of a regular file via non-canonical parent path" \
+ test_fetch_snap_file $share "BAR/baz" 6 || \
+ failed=`expr $failed + 1`
+
+ testit "fetch a previous version of a regular file via non-canonical basepath" \
+ test_fetch_snap_file $share "bar/BAZ" 6 || \
+ failed=`expr $failed + 1`
+
+ testit "fetch a previous version of a regular file via non-canonical path" \
+ test_fetch_snap_file $share "BAR/BAZ" 6 || \
+ failed=`expr $failed + 1`
+
testit_expect_failure "fetch a (non-existent) previous version of a symlink" \
test_fetch_snap_file $share "bar/lfoo" 6 || \
failed=`expr $failed + 1`
diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c
index daa4d9c3faa..1c5c57c70e2 100644
--- a/source3/smbd/filename.c
+++ b/source3/smbd/filename.c
@@ -1555,10 +1555,12 @@ static bool sname_equal(const char *name1, const char *name2,
If the name looks like a mangled name then try via the mangling functions
****************************************************************************/
-static int get_real_filename_full_scan(connection_struct *conn,
- const char *path, const char *name,
- bool mangled,
- TALLOC_CTX *mem_ctx, char **found_name)
+int get_real_filename_full_scan(connection_struct *conn,
+ const char *path,
+ const char *name,
+ bool mangled,
+ TALLOC_CTX *mem_ctx,
+ char **found_name)
{
struct smb_Dir *cur_dir;
const char *dname = NULL;
diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
index d34a7284796..98eb2843c07 100644
--- a/source3/smbd/proto.h
+++ b/source3/smbd/proto.h
@@ -375,6 +375,12 @@ int get_real_filename(connection_struct *conn,
const char *name,
TALLOC_CTX *mem_ctx,
char **found_name);
+int get_real_filename_full_scan(connection_struct *conn,
+ const char *path,
+ const char *name,
+ bool mangled,
+ TALLOC_CTX *mem_ctx,
+ char **found_name);
char *get_original_lcomp(TALLOC_CTX *ctx,
connection_struct *conn,
const char *filename_in,
--
Samba Shared Repository
More information about the samba-cvs
mailing list