Subject: [PATCH 14/35] s3: VFS: shadow_copy2: Fix chdir to store off the needed private variables.

From: Jeremy Allison <[email-masked]>
Date: Fri, 20 Jan 2017 12:06:55 -0800

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 <[email-masked]>
Reviewed-by: Uri Simchoni <[email-masked]>
(backported from commit 27340df4b52e4341f134667c59d71656a7a1fdae)
Signed-off-by: Arvid Requate <[email-masked]>
---
 source3/modules/vfs_shadow_copy2.c | 81 ++++++++++++++++++++++++++++++++------
 1 file changed, 68 insertions(+), 13 deletions(-)

diff --git a/source3/modules/vfs_shadow_copy2.c b/source3/modules/vfs_shadow_copy2.c
index a04b642..dc84835 100644
--- a/source3/modules/vfs_shadow_copy2.c
+++ b/source3/modules/vfs_shadow_copy2.c
@@ -1080,30 +1080,85 @@ static int shadow_copy2_chown(vfs_handle_struct *handle, const char *fname,
 	return ret;
 }
 
+static void store_cwd_data(vfs_handle_struct *handle,
+				const char *connectpath)
+{
+	struct shadow_copy2_config *config = NULL;
+	char *cwd = NULL;
+
+	SMB_VFS_HANDLE_GET_DATA(handle, config, struct shadow_copy2_config,
+				return);
+
+	TALLOC_FREE(config->shadow_cwd);
+	cwd = SMB_VFS_NEXT_GETWD(handle);
+	if (cwd == NULL) {
+		smb_panic("getwd failed\n");
+	}
+	DEBUG(10,("shadow cwd = %s\n", cwd));
+	config->shadow_cwd = talloc_strdup(config, cwd);
+	SAFE_FREE(cwd);
+	if (config->shadow_cwd == NULL) {
+		smb_panic("talloc failed\n");
+	}
+	TALLOC_FREE(config->shadow_connectpath);
+	if (connectpath) {
+		DEBUG(10,("shadow conectpath = %s\n", connectpath));
+		config->shadow_connectpath = talloc_strdup(config, connectpath);
+		if (config->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;
 }
 
-- 
2.1.4