From 3703bca4d9e494aec0b40243add3e076cf353601 Mon Sep 17 00:00:00 2001 From: Uri Simchoni Date: Sun, 1 Nov 2015 22:28:46 +0200 Subject: [PATCH] vfs_shadow_copy2: add shadow_copy2_do_convert() Add a new routine shadow_copy2_do_convert() which is like shadow_copy2_convert(), but beside calculating the path of the snapshot file, it also returns the minimum length of the subpath which is both inside the share and inside the same snapshot as the file in question, i.e. (at least in the classical case) the subdirectory of the the snapshot file's snapshot directory that corresponds to the file's share root. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11580 Signed-off-by: Uri Simchoni Reviewed-by: Michael Adam --- source3/modules/vfs_shadow_copy2.c | 39 +++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 4 deletions(-) diff --git a/source3/modules/vfs_shadow_copy2.c b/source3/modules/vfs_shadow_copy2.c index 93bca9c3da1..19d71ecb027 100644 --- a/source3/modules/vfs_shadow_copy2.c +++ b/source3/modules/vfs_shadow_copy2.c @@ -434,10 +434,13 @@ static char *shadow_copy2_find_mount_point(TALLOC_CTX *mem_ctx, * Convert from a name as handed in via the SMB layer * and a timestamp into the local path of the snapshot * of the provided file at the provided time. + * Also return the path in the snapshot corresponding + * to the file's share root. */ -static char *shadow_copy2_convert(TALLOC_CTX *mem_ctx, - struct vfs_handle_struct *handle, - const char *name, time_t timestamp) +static char *shadow_copy2_do_convert(TALLOC_CTX *mem_ctx, + struct vfs_handle_struct *handle, + const char *name, time_t timestamp, + size_t *snaproot_len) { struct smb_filename converted_fname; char *result = NULL; @@ -447,10 +450,11 @@ static char *shadow_copy2_convert(TALLOC_CTX *mem_ctx, size_t pathlen; char *insert = NULL; char *converted = NULL; - size_t insertlen; + size_t insertlen, connectlen = 0; int i, saved_errno; size_t min_offset; struct shadow_copy2_config *config; + size_t in_share_offset = 0; SMB_VFS_HANDLE_GET_DATA(handle, config, struct shadow_copy2_config, return NULL); @@ -492,6 +496,13 @@ static char *shadow_copy2_convert(TALLOC_CTX *mem_ctx, DEBUG(10, ("Found %s\n", converted)); result = converted; converted = NULL; + if (snaproot_len != NULL) { + *snaproot_len = strlen(snapshot_path); + if (config->rel_connectpath != NULL) { + *snaproot_len += + strlen(config->rel_connectpath) + 1; + } + } goto fail; } else { errno = ENOENT; @@ -500,6 +511,7 @@ static char *shadow_copy2_convert(TALLOC_CTX *mem_ctx, /* never reached ... */ } + connectlen = strlen(handle->conn->connectpath); if (name[0] == 0) { path = talloc_strdup(mem_ctx, handle->conn->connectpath); } else { @@ -575,6 +587,10 @@ static char *shadow_copy2_convert(TALLOC_CTX *mem_ctx, goto fail; } + if (offset >= connectlen) { + in_share_offset = offset; + } + memcpy(converted+offset, insert, insertlen); offset += insertlen; @@ -588,6 +604,9 @@ static char *shadow_copy2_convert(TALLOC_CTX *mem_ctx, ret, ret == 0 ? "ok" : strerror(errno))); if (ret == 0) { /* success */ + if (snaproot_len != NULL) { + *snaproot_len = in_share_offset + insertlen; + } break; } if (errno == ENOTDIR) { @@ -624,6 +643,18 @@ fail: return result; } +/** + * Convert from a name as handed in via the SMB layer + * and a timestamp into the local path of the snapshot + * of the provided file at the provided time. + */ +static char *shadow_copy2_convert(TALLOC_CTX *mem_ctx, + struct vfs_handle_struct *handle, + const char *name, time_t timestamp) +{ + return shadow_copy2_do_convert(mem_ctx, handle, name, timestamp, NULL); +} + /* modify a sbuf return to ensure that inodes in the shadow directory are different from those in the main directory -- 2.34.1