s3: VFS: shadow_copy2: Fix chdir to store off the needed private variables.
authorJeremy Allison <jra@samba.org>
Fri, 20 Jan 2017 20:06:55 +0000 (12:06 -0800)
committerJeremy Allison <jra@samba.org>
Mon, 30 Jan 2017 17:39:19 +0000 (18:39 +0100)
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12531

This is not yet used, the users of this will be added later.

Signed-off-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Uri Simchoni <uri@samba.org>
source3/modules/vfs_shadow_copy2.c

index d3179de992829e515ffe81aeab3a51cd45b7cd27..2d1b1e67fdb847f983bb709a1e1824c8d50ee891 100644 (file)
@@ -1328,30 +1328,85 @@ static int shadow_copy2_chown(vfs_handle_struct *handle,
        return ret;
 }
 
+static void store_cwd_data(vfs_handle_struct *handle,
+                               const char *connectpath)
+{
+       struct shadow_copy2_private *priv = NULL;
+       char *cwd = NULL;
+
+       SMB_VFS_HANDLE_GET_DATA(handle, priv, struct shadow_copy2_private,
+                               return);
+
+       TALLOC_FREE(priv->shadow_cwd);
+       cwd = SMB_VFS_NEXT_GETWD(handle);
+       if (cwd == NULL) {
+               smb_panic("getwd failed\n");
+       }
+       DBG_DEBUG("shadow cwd = %s\n", cwd);
+       priv->shadow_cwd = talloc_strdup(priv, cwd);
+       SAFE_FREE(cwd);
+       if (priv->shadow_cwd == NULL) {
+               smb_panic("talloc failed\n");
+       }
+       TALLOC_FREE(priv->shadow_connectpath);
+       if (connectpath) {
+               DBG_DEBUG("shadow conectpath = %s\n", connectpath);
+               priv->shadow_connectpath = talloc_strdup(priv, connectpath);
+               if (priv->shadow_connectpath == NULL) {
+                       smb_panic("talloc failed\n");
+               }
+       }
+}
+
 static int shadow_copy2_chdir(vfs_handle_struct *handle,
                              const char *fname)
 {
        time_t timestamp = 0;
        char *stripped = NULL;
-       int ret, saved_errno;
-       char *conv;
+       char *snappath = NULL;
+       int ret = -1;
+       int saved_errno = 0;
+       char *conv = NULL;
+       size_t rootpath_len = 0;
 
-       if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, fname,
-                                        &timestamp, &stripped)) {
+       if (!shadow_copy2_strip_snapshot_internal(talloc_tos(), handle, fname,
+                                       &timestamp, &stripped, &snappath)) {
                return -1;
        }
-       if (timestamp == 0) {
-               return SMB_VFS_NEXT_CHDIR(handle, fname);
+       if (stripped != NULL) {
+               conv = shadow_copy2_do_convert(talloc_tos(),
+                                               handle,
+                                               stripped,
+                                               timestamp,
+                                               &rootpath_len);
+               TALLOC_FREE(stripped);
+               if (conv == NULL) {
+                       return -1;
+               }
+               fname = conv;
        }
-       conv = shadow_copy2_convert(talloc_tos(), handle, stripped, timestamp);
-       TALLOC_FREE(stripped);
-       if (conv == NULL) {
-               return -1;
+
+       ret = SMB_VFS_NEXT_CHDIR(handle, fname);
+       if (ret == -1) {
+               saved_errno = errno;
        }
-       ret = SMB_VFS_NEXT_CHDIR(handle, conv);
-       saved_errno = errno;
+
+       if (ret == 0) {
+               if (conv != NULL && rootpath_len != 0) {
+                       conv[rootpath_len] = '\0';
+               } else if (snappath != 0) {
+                       TALLOC_FREE(conv);
+                       conv = snappath;
+               }
+               store_cwd_data(handle, conv);
+       }
+
+       TALLOC_FREE(stripped);
        TALLOC_FREE(conv);
-       errno = saved_errno;
+
+       if (saved_errno != 0) {
+               errno = saved_errno;
+       }
        return ret;
 }