summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/modules/vfs_shadow_copy2.c81
1 files changed, 68 insertions, 13 deletions
diff --git a/source3/modules/vfs_shadow_copy2.c b/source3/modules/vfs_shadow_copy2.c
index c03bf465f4a..5b1685db1a7 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");
+ }
+ DBG_DEBUG("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) {
+ DBG_DEBUG("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;
}