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 <[email protected]>
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 <[email protected]>
    Reviewed-by: Ralph Boehme <[email protected]>
    
    Autobuild-User(master): Ralph Böhme <[email protected]>
    Autobuild-Date(master): Wed May  6 11:58:42 UTC 2020 on sn-devel-184

commit a3d1ac2a597e2441d6855db566306298ae5db99b
Author: Ralph Boehme <[email protected]>
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 <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>

commit aa5f19ddf1dec1ac4386441929bca94727f30ee6
Author: Ralph Boehme <[email protected]>
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 <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>

commit 6557777c86d72a185b3fe4061a8b5791fd748924
Author: Ralph Boehme <[email protected]>
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 <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>

commit 1b74a4a3bb697afca3d330b8b110d4c1e1d92130
Author: Ralph Boehme <[email protected]>
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 <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>

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

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

Reply via email to