[PATCHES] s3-shadow-copy2 fixes

Christof Schmitt cs at samba.org
Thu Jun 26 14:19:29 MDT 2014


>From a1dc2b96e5778e9374919c5cf309bacffef10a22 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Mon, 15 Oct 2012 18:13:33 +0200
Subject: [PATCH 1/6] s3-shadow-copy2: Add extreme debug output to shadow_copy2_strip_snapshot

This is sooo hairy to debug when things go wrong :-(

Signed-off-by: Volker Lendecke <vl at samba.org>
Reviewed-by: Christof Schmitt <cs at samba.org>
---
 source3/modules/vfs_shadow_copy2.c |    8 ++++++++
 1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/source3/modules/vfs_shadow_copy2.c b/source3/modules/vfs_shadow_copy2.c
index 30eaaa4..1b3c484 100644
--- a/source3/modules/vfs_shadow_copy2.c
+++ b/source3/modules/vfs_shadow_copy2.c
@@ -243,19 +243,24 @@ static bool shadow_copy2_strip_snapshot(TALLOC_CTX *mem_ctx,
 
 	p = strstr_m(name, "@GMT-");
 	if (p == NULL) {
+		DEBUG(11, ("@GMT not found\n"));
 		goto no_snapshot;
 	}
 	if ((p > name) && (p[-1] != '/')) {
 		/* the GMT-token does not start a path-component */
+		DEBUG(10, ("not at start, p=%p, name=%p, p[-1]=%d\n",
+			   p, name, (int)p[-1]));
 		goto no_snapshot;
 	}
 	q = strptime(p, GMT_FORMAT, &tm);
 	if (q == NULL) {
+		DEBUG(10, ("strptime failed\n"));
 		goto no_snapshot;
 	}
 	tm.tm_isdst = -1;
 	timestamp = timegm(&tm);
 	if (timestamp == (time_t)-1) {
+		DEBUG(10, ("timestamp==-1\n"));
 		goto no_snapshot;
 	}
 	if ((p == name) && (q[0] == '\0')) {
@@ -279,6 +284,7 @@ static bool shadow_copy2_strip_snapshot(TALLOC_CTX *mem_ctx,
 		 * TODO: Is this correct? Or would the GMT tag as the
 		 * last component be a valid input?
 		 */
+		DEBUG(10, ("q[0] = %d\n", (int)q[0]));
 		goto no_snapshot;
 	}
 	q += 1;
@@ -301,6 +307,8 @@ static bool shadow_copy2_strip_snapshot(TALLOC_CTX *mem_ctx,
 			   "insert string '%s'\n", name, insert));
 
 		have_insert = (strstr(name, insert+1) != NULL);
+		DEBUG(10, ("have_insert=%d, name=%s, insert+1=%s\n",
+			   (int)have_insert, name, insert+1));
 		if (have_insert) {
 			DEBUG(10, (__location__ ": insert string '%s' found in "
 				   "path '%s' found in snapdirseverywhere mode "
-- 
1.7.1


>From 58dcf45fcdcd28d9447284e5610d309455221ea6 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Mon, 15 Oct 2012 18:16:44 +0200
Subject: [PATCH 2/6] s3-shadow-copy2: Fix dir/@GMT-2012.10.15-13.48.43 form of paths

The previous clause in shadow_copy2_strip_snapshot would only handle @GMT-
at the end of a pathname if it was the *only* pathname component. XP
seems to send @GMT- at the end under certain circumstances even with a
path prefix.

Signed-off-by: Volker Lendecke <vl at samba.org>
Reviewed-by: Christof Schmitt <cs at samba.org>
---
 source3/modules/vfs_shadow_copy2.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/source3/modules/vfs_shadow_copy2.c b/source3/modules/vfs_shadow_copy2.c
index 1b3c484..82149f2 100644
--- a/source3/modules/vfs_shadow_copy2.c
+++ b/source3/modules/vfs_shadow_copy2.c
@@ -263,10 +263,10 @@ static bool shadow_copy2_strip_snapshot(TALLOC_CTX *mem_ctx,
 		DEBUG(10, ("timestamp==-1\n"));
 		goto no_snapshot;
 	}
-	if ((p == name) && (q[0] == '\0')) {
+	if (q[0] == '\0') {
 		/* the name consists of only the GMT token */
 		if (pstripped != NULL) {
-			stripped = talloc_strdup(mem_ctx, "");
+			stripped = talloc_strndup(mem_ctx, name, p - name);
 			if (stripped == NULL) {
 				return false;
 			}
-- 
1.7.1


>From 71faac47c1d2cdc468fb8fecfc13ea250b884e70 Mon Sep 17 00:00:00 2001
From: Christof Schmitt <cs at samba.org>
Date: Thu, 26 Jun 2014 12:43:03 -0700
Subject: [PATCH 3/6] s3-shadow-copy2: Remove TODO and fix comments

The patch "s3-shadow-copy2: Fix dir/@GMT-2012.10.15-13.48.43 form of
paths" takes care of a case marked as TODO, remove it and adjust the
comments accordingly.

Signed-off-by: Christof Schmitt <cs at samba.org>
---
 source3/modules/vfs_shadow_copy2.c |   15 ++++++++-------
 1 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/source3/modules/vfs_shadow_copy2.c b/source3/modules/vfs_shadow_copy2.c
index 82149f2..029b155 100644
--- a/source3/modules/vfs_shadow_copy2.c
+++ b/source3/modules/vfs_shadow_copy2.c
@@ -264,7 +264,12 @@ static bool shadow_copy2_strip_snapshot(TALLOC_CTX *mem_ctx,
 		goto no_snapshot;
 	}
 	if (q[0] == '\0') {
-		/* the name consists of only the GMT token */
+		/*
+		 * The name consists of only the GMT token or the GMT
+		 * token is at the end of the path. XP seems to send
+		 * @GMT- at the end under certain circumstances even
+		 * with a path prefix.
+		 */
 		if (pstripped != NULL) {
 			stripped = talloc_strndup(mem_ctx, name, p - name);
 			if (stripped == NULL) {
@@ -277,12 +282,8 @@ static bool shadow_copy2_strip_snapshot(TALLOC_CTX *mem_ctx,
 	}
 	if (q[0] != '/') {
 		/*
-		 * The GMT token is either at the end of the path
-		 * or it is not a complete path component, i.e. the
-		 * path component continues after the gmt-token.
-		 *
-		 * TODO: Is this correct? Or would the GMT tag as the
-		 * last component be a valid input?
+		 * It is not a complete path component, i.e. the path
+		 * component continues after the gmt-token.
 		 */
 		DEBUG(10, ("q[0] = %d\n", (int)q[0]));
 		goto no_snapshot;
-- 
1.7.1


>From 07bac0b6ba48bafc75cf1a7ee075f250f192ca88 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Wed, 17 Oct 2012 12:08:26 +0200
Subject: [PATCH 4/6] s3-shadow-copy2: Fix incorrect case submounts

Signed-off-by: Volker Lendecke <vl at samba.org>
Reviewed-by: Christof Schmitt <cs at samba.org>
---
 source3/modules/vfs_shadow_copy2.c |   16 ++++++----------
 1 files changed, 6 insertions(+), 10 deletions(-)

diff --git a/source3/modules/vfs_shadow_copy2.c b/source3/modules/vfs_shadow_copy2.c
index 029b155..e7a8a9d 100644
--- a/source3/modules/vfs_shadow_copy2.c
+++ b/source3/modules/vfs_shadow_copy2.c
@@ -472,8 +472,12 @@ static char *shadow_copy2_convert(TALLOC_CTX *mem_ctx,
 		/* never reached ... */
 	}
 
-	path = talloc_asprintf(mem_ctx, "%s/%s", handle->conn->connectpath,
-			       name);
+	if (name[0] == 0) {
+		path = talloc_strdup(mem_ctx, handle->conn->connectpath);
+	} else {
+		path = talloc_asprintf(
+			mem_ctx, "%s/%s", handle->conn->connectpath, name);
+	}
 	if (path == NULL) {
 		errno = ENOMEM;
 		goto fail;
@@ -1677,14 +1681,6 @@ static int shadow_copy2_get_real_filename(struct vfs_handle_struct *handle,
 		return SMB_VFS_NEXT_GET_REAL_FILENAME(handle, path, name,
 						      mem_ctx, found_name);
 	}
-	if (stripped[0] == '\0') {
-		*found_name = talloc_strdup(mem_ctx, name);
-		if (*found_name == NULL) {
-			errno = ENOMEM;
-			return -1;
-		}
-		return 0;
-	}
 	conv = shadow_copy2_convert(talloc_tos(), handle, stripped, timestamp);
 	TALLOC_FREE(stripped);
 	if (conv == NULL) {
-- 
1.7.1


>From 32777e692492bd388be170692c36eb595b6c652d Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Wed, 17 Oct 2012 12:11:37 +0200
Subject: [PATCH 5/6] s3-shadow-copy2: Add more debugs

Signed-off-by: Volker Lendecke <vl at samba.org>
Reviewed-by: Christof Schmitt <cs at samba.org>
---
 source3/modules/vfs_shadow_copy2.c |    9 +++++++++
 1 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/source3/modules/vfs_shadow_copy2.c b/source3/modules/vfs_shadow_copy2.c
index e7a8a9d..30f67e2 100644
--- a/source3/modules/vfs_shadow_copy2.c
+++ b/source3/modules/vfs_shadow_copy2.c
@@ -1673,21 +1673,30 @@ static int shadow_copy2_get_real_filename(struct vfs_handle_struct *handle,
 	int saved_errno;
 	char *conv;
 
+	DEBUG(10, ("shadow_copy2_get_real_filename called for path=[%s], "
+		   "name=[%s]\n", path, name));
+
 	if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, path,
 					 &timestamp, &stripped)) {
+		DEBUG(10, ("shadow_copy2_strip_snapshot failed\n"));
 		return -1;
 	}
 	if (timestamp == 0) {
+		DEBUG(10, ("timestamp == 0\n"));
 		return SMB_VFS_NEXT_GET_REAL_FILENAME(handle, path, name,
 						      mem_ctx, found_name);
 	}
 	conv = shadow_copy2_convert(talloc_tos(), handle, stripped, timestamp);
 	TALLOC_FREE(stripped);
 	if (conv == NULL) {
+		DEBUG(10, ("shadow_copy2_convert failed\n"));
 		return -1;
 	}
+	DEBUG(10, ("Calling NEXT_GET_REAL_FILE_NAME for conv=[%s], "
+		   "name=[%s]\n", conv, name));
 	ret = SMB_VFS_NEXT_GET_REAL_FILENAME(handle, conv, name,
 					     mem_ctx, found_name);
+	DEBUG(10, ("NEXT_REAL_FILE_NAME returned %d\n", (int)ret));
 	saved_errno = errno;
 	TALLOC_FREE(conv);
 	errno = saved_errno;
-- 
1.7.1


>From 201496f058eacdb35473d12bcc3e91d1d95be1be Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Thu, 18 Oct 2012 15:24:39 +0200
Subject: [PATCH 6/6] s3-shadow-copy2: Protect against already converted names

Signed-off-by: Volker Lendecke <vl at samba.org>
Reviewed-by: Christof Schmitt <cs at samba.org>
---
 source3/modules/vfs_shadow_copy2.c |   28 ++++++++++++++++++++++++++++
 1 files changed, 28 insertions(+), 0 deletions(-)

diff --git a/source3/modules/vfs_shadow_copy2.c b/source3/modules/vfs_shadow_copy2.c
index 30f67e2..439df5d 100644
--- a/source3/modules/vfs_shadow_copy2.c
+++ b/source3/modules/vfs_shadow_copy2.c
@@ -235,6 +235,9 @@ static bool shadow_copy2_strip_snapshot(TALLOC_CTX *mem_ctx,
 	char *stripped;
 	size_t rest_len, dst_len;
 	struct shadow_copy2_config *config;
+	const char *snapdir;
+	ssize_t snapdirlen;
+	ptrdiff_t len_before_gmt;
 
 	SMB_VFS_HANDLE_GET_DATA(handle, config, struct shadow_copy2_config,
 				return false);
@@ -252,6 +255,31 @@ static bool shadow_copy2_strip_snapshot(TALLOC_CTX *mem_ctx,
 			   p, name, (int)p[-1]));
 		goto no_snapshot;
 	}
+
+	/*
+	 * Figure out whether we got an already converted string. One
+	 * case where this happens is in a smb2 create call with the
+	 * mxac create blob set. We do the get_acl call on
+	 * fsp->fsp_name, which is already converted. We are converted
+	 * if we got a file name of the form ".snapshots/@GMT-",
+	 * i.e. ".snapshots/" precedes "p".
+	 */
+
+	snapdir = lp_parm_const_string(SNUM(handle->conn), "shadow", "snapdir",
+				       ".snapshots");
+	snapdirlen = strlen(snapdir);
+	len_before_gmt = p - name;
+
+	if ((len_before_gmt >= (snapdirlen + 1)) && (p[-1] == '/')) {
+		const char *parent_snapdir = p - (snapdirlen+1);
+
+		DEBUG(10, ("parent_snapdir = %s\n", parent_snapdir));
+
+		if (strncmp(parent_snapdir, snapdir, snapdirlen) == 0) {
+			DEBUG(10, ("name=%s is already converted\n", name));
+			goto no_snapshot;
+		}
+	}
 	q = strptime(p, GMT_FORMAT, &tm);
 	if (q == NULL) {
 		DEBUG(10, ("strptime failed\n"));
-- 
1.7.1



More information about the samba-technical mailing list