[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,
 					 &timestamp, &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