[SCM] Samba Shared Repository - branch master updated
Jeremy Allison
jra at samba.org
Mon Jan 30 21:27:02 UTC 2017
The branch, master has been updated
via 0e1deb7 s3: VFS: Don't allow symlink, link or rename on already converted paths.
via cda6764 s3: VFS: shadow_copy2: Fix usage of saved_errno to only set errno on error.
via 4d339a8 s3: VFS: shadow_copy2: Fix a memory leak in the connectpath function.
via 128d5f2 s3: VFS: shadow_copy2: Fix module to work with variable current working directory.
via b94dc85 s3: VFS: Add utility function check_for_converted_path().
via cd4f940 s3: VFS: Ensure shadow:format cannot contain a / path separator.
via 42bd1ac s3: VFS: Allow shadow_copy2_connectpath() to return the cached path derived from $cwd.
via 27340df s3: VFS: shadow_copy2: Fix chdir to store off the needed private variables.
via 9d65107 s3: VFS: shadow_copy2: Add two currently unused functions to make pathnames absolute or relative to $cwd.
via 2887465 s3: VFS: shadow_copy2: Change a parameter name.
via 5aa1ea9 s3: VFS: shadow_copy2: Add a wrapper function to call the original shadow_copy2_strip_snapshot().
via 72fe2b6 s3: VFS: shadow_copy2: Add two new variables to the private data. Not yet used.
via 37ef8d3 s3: VFS: shadow_copy2: Fix length comparison to ensure we don't overstep a length.
via 979e392 s3: VFS: shadow_copy2: Ensure pathnames for parameters are correctly relative and terminated.
via 0a190f4 s3: VFS: shadow_copy2: Correctly initialize timestamp and stripped variables.
via d650d65 s3: smbd: Make set_conn_connectpath() call canonicalize_absolute_path().
via a513633 s3: smbtorture: Add new local test LOCAL-CANONICALIZE-PATH
via 82979af s3: lib: Fix two old, old bugs in set_conn_connectpath(), now in canonicalize_absolute_path().
via 02599c3 s3: lib: Add canonicalize_absolute_path().
via 39678ed s3: smbd: Correctly canonicalize any incoming shadow copy path.
from 26ffc20 build: vfs_posix_eadb is only built with the AD DC enabled
https://git.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit 0e1deb77f2b310ad7e5dd784174207adacf1c981
Author: Jeremy Allison <jra at samba.org>
Date: Thu Jan 26 17:19:24 2017 -0800
s3: VFS: Don't allow symlink, link or rename on already converted paths.
Snapshot paths are a read-only filesystem.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12531
Signed-off-by: Jeremy Allison <jra at samba.org>
Reviewed-by: Uri Simchoni <uri at samba.org>
Autobuild-User(master): Jeremy Allison <jra at samba.org>
Autobuild-Date(master): Mon Jan 30 22:26:29 CET 2017 on sn-devel-144
commit cda6764f1a8db96182bfd1855440bc6a1ba1abee
Author: Jeremy Allison <jra at samba.org>
Date: Mon Jan 23 10:20:13 2017 -0800
s3: VFS: shadow_copy2: Fix usage of saved_errno to only set errno on error.
Rationale:
VFS calls must act like their POSIX equivalents, and the POSIX versions
*only* set errno on a failure. There is actually code in the upper smbd
layers that depends on errno being correct on a fail return from a VFS call.
For a compound VFS module like this, a common pattern is :
SMB_VFS_CALL_X()
{
int ret;
syscall1();
ret = syscall2();
syscall3();
return ret;
}
Where if *any* of the contained syscallX()'s fail, they'll set errno.
However, the actual errno we should return is *only* the one returned
if syscall2() fails (the others are lstat's checking for existence etc.).
So what we should do to correctly return only the errno from syscall2() is:
SMB_VFS_CALL_X()
{
int ret;
int saved_errno = 0;
syscall1()
ret = syscall2();
if (ret == -1) {
saved_errno = errno;
}
syscall3()
if (saved_errno != 0) {
errno = saved_errno;
}
return ret;
}
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12531
Signed-off-by: Jeremy Allison <jra at samba.org>
Reviewed-by: Uri Simchoni <uri at samba.org>
commit 4d339a88851f601fae195ac8ff0691cbd3504f41
Author: Jeremy Allison <jra at samba.org>
Date: Mon Jan 23 10:06:44 2017 -0800
s3: VFS: shadow_copy2: Fix a memory leak in the connectpath function.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12531
Signed-off-by: Jeremy Allison <jra at samba.org>
Reviewed-by: Uri Simchoni <uri at samba.org>
commit 128d5f27cd42b0c7efcbe3d28fe3eee881e0734b
Author: Jeremy Allison <jra at samba.org>
Date: Thu Jan 26 10:49:51 2017 -0800
s3: VFS: shadow_copy2: Fix module to work with variable current working directory.
Completely cleans up the horrible shadow_copy2_strip_snapshot()
and adds an explaination of what it's actually trying to do.
* This function does two things.
*
* 1). Checks if an incoming filename is already a
* snapshot converted pathname.
* If so, it returns the pathname truncated
* at the snapshot point which will be used
* as the connectpath, and then does an early return.
*
* 2). Checks if an incoming filename contains an
* SMB-layer @GMT- style timestamp.
* If so, it strips the timestamp, and returns
* both the timestamp and the stripped path
* (making it cwd-relative).
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12531
Signed-off-by: Jeremy Allison <jra at samba.org>
Reviewed-by: Uri Simchoni <uri at samba.org>
commit b94dc85d339c9a10496edd07b85bdd7808d2e332
Author: Jeremy Allison <jra at samba.org>
Date: Thu Jan 26 10:35:50 2017 -0800
s3: VFS: Add utility function check_for_converted_path().
Detects an already converted path. Not yet used.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12531
Signed-off-by: Jeremy Allison <jra at samba.org>
Reviewed-by: Uri Simchoni <uri at samba.org>
commit cd4f940162b17e4f7345d392326a31ae478230fa
Author: Jeremy Allison <jra at samba.org>
Date: Thu Jan 26 10:24:52 2017 -0800
s3: VFS: Ensure shadow:format cannot contain a / path separator.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12531
Signed-off-by: Jeremy Allison <jra at samba.org>
Reviewed-by: Uri Simchoni <uri at samba.org>
commit 42bd1acad75a6b5ea81fe4b30c067dd82623c042
Author: Jeremy Allison <jra at samba.org>
Date: Fri Jan 20 12:09:08 2017 -0800
s3: VFS: Allow shadow_copy2_connectpath() to return the cached path derived from $cwd.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12531
Signed-off-by: Jeremy Allison <jra at samba.org>
Reviewed-by: Uri Simchoni <uri at samba.org>
commit 27340df4b52e4341f134667c59d71656a7a1fdae
Author: Jeremy Allison <jra at samba.org>
Date: Fri Jan 20 12:06:55 2017 -0800
s3: VFS: shadow_copy2: Fix chdir to store off the needed private variables.
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 at samba.org>
Reviewed-by: Uri Simchoni <uri at samba.org>
commit 9d65107b8f2864dba8d41b3316c483b3f36d0697
Author: Jeremy Allison <jra at samba.org>
Date: Fri Jan 20 12:00:08 2017 -0800
s3: VFS: shadow_copy2: Add two currently unused functions to make pathnames absolute or relative to $cwd.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12531
Signed-off-by: Jeremy Allison <jra at samba.org>
Reviewed-by: Uri Simchoni <uri at samba.org>
commit 2887465108aef5e2e7c64417437ecb86c7460e16
Author: Jeremy Allison <jra at samba.org>
Date: Fri Jan 20 11:56:21 2017 -0800
s3: VFS: shadow_copy2: Change a parameter name.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12531
Allows easy substitution later.
Signed-off-by: Jeremy Allison <jra at samba.org>
Reviewed-by: Uri Simchoni <uri at samba.org>
commit 5aa1ea95157475dfd2d056f0158b14b2b90895a9
Author: Jeremy Allison <jra at samba.org>
Date: Fri Jan 20 11:54:56 2017 -0800
s3: VFS: shadow_copy2: Add a wrapper function to call the original shadow_copy2_strip_snapshot().
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12531
Allows an extra (currently unused) parameter to be added.
Signed-off-by: Jeremy Allison <jra at samba.org>
Reviewed-by: Uri Simchoni <uri at samba.org>
commit 72fe2b62e3ee7462e5be855b01943f28b26c36c1
Author: Jeremy Allison <jra at samba.org>
Date: Fri Jan 20 11:50:49 2017 -0800
s3: VFS: shadow_copy2: Add two new variables to the private data. Not yet used.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12531
Signed-off-by: Jeremy Allison <jra at samba.org>
Reviewed-by: Uri Simchoni <uri at samba.org>
commit 37ef8d3f65bd1215717eb51b2e1cdb84a7bed348
Author: Jeremy Allison <jra at samba.org>
Date: Fri Jan 20 11:48:40 2017 -0800
s3: VFS: shadow_copy2: Fix length comparison to ensure we don't overstep a length.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12531
Signed-off-by: Jeremy Allison <jra at samba.org>
Reviewed-by: Uri Simchoni <uri at samba.org>
commit 979e39252bcc88e8aacb543b8bf322dd6f17fe7f
Author: Jeremy Allison <jra at samba.org>
Date: Fri Jan 20 11:45:54 2017 -0800
s3: VFS: shadow_copy2: Ensure pathnames for parameters are correctly relative and terminated.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12531
Signed-off-by: Jeremy Allison <jra at samba.org>
Reviewed-by: Uri Simchoni <uri at samba.org>
commit 0a190f4dd950c947d47c42163d11ea4bd6e6e508
Author: Jeremy Allison <jra at samba.org>
Date: Fri Jan 20 11:42:39 2017 -0800
s3: VFS: shadow_copy2: Correctly initialize timestamp and stripped variables.
Allow the called functions to be fixed to not touch them on error.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12531
Signed-off-by: Jeremy Allison <jra at samba.org>
Reviewed-by: Uri Simchoni <uri at samba.org>
commit d650d65488761b30fa34d42cb1ab400618a78c33
Author: Jeremy Allison <jra at samba.org>
Date: Tue Jan 17 11:35:52 2017 -0800
s3: smbd: Make set_conn_connectpath() call canonicalize_absolute_path().
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12531
Signed-off-by: Jeremy Allison <jra at samba.org>
Reviewed-by: Uri Simchoni <uri at samba.org>
commit a51363309a4330b65e34ae941ec99d180bdbab56
Author: Jeremy Allison <jra at samba.org>
Date: Thu Jan 26 16:08:42 2017 -0800
s3: smbtorture: Add new local test LOCAL-CANONICALIZE-PATH
Tests new canonicalize_absolute_path() function.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12531
Signed-off-by: Jeremy Allison <jra at samba.org>
Reviewed-by: Uri Simchoni <uri at samba.org>
commit 82979afc46cc5e466bdd999a94080e7a5df95518
Author: Jeremy Allison <jra at samba.org>
Date: Thu Jan 19 15:18:41 2017 -0800
s3: lib: Fix two old, old bugs in set_conn_connectpath(), now in canonicalize_absolute_path().
Canonicalizing a path of /foo/bar/../baz would return /foo/barbaz
as moving forward 3 characters would delete the / character.
Canonicalizing /foo/.. would end up as '\0'.
Test to follow.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12531
Signed-off-by: Jeremy Allison <jra at samba.org>
Reviewed-by: Uri Simchoni <uri at samba.org>
commit 02599c39337c3049762a6b0bd6290577817ee5a5
Author: Jeremy Allison <jra at samba.org>
Date: Tue Jan 17 11:33:18 2017 -0800
s3: lib: Add canonicalize_absolute_path().
Resolves any invalid path components (.) (..)
in an absolute POSIX path.
We will be re-using this in several places.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12531
Signed-off-by: Jeremy Allison <jra at samba.org>
Reviewed-by: Uri Simchoni <uri at samba.org>
commit 39678ed6af708fb6f2760bfb51051add11e3c498
Author: Jeremy Allison <jra at samba.org>
Date: Wed Jan 11 16:30:38 2017 -0800
s3: smbd: Correctly canonicalize any incoming shadow copy path.
Converts to:
@GMT-token/path/last_component
from all incoming path types. Allows shadow_copy modules
to work when current directory is changed after removing
last component.
Ultimately when the VFS ABI is changed to add a timestamp
to struct smb_filename, this is where the parsing will be
done.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12531
Signed-off-by: Jeremy Allison <jra at samba.org>
Reviewed-by: Uri Simchoni <uri at samba.org>
-----------------------------------------------------------------------
Summary of changes:
source3/lib/util_path.c | 139 ++++++
source3/lib/util_path.h | 1 +
source3/modules/vfs_shadow_copy2.c | 909 ++++++++++++++++++++++++++-----------
source3/selftest/tests.py | 1 +
source3/smbd/filename.c | 150 ++++++
source3/smbd/service.c | 103 +----
source3/torture/torture.c | 44 ++
7 files changed, 994 insertions(+), 353 deletions(-)
Changeset truncated at 500 lines:
diff --git a/source3/lib/util_path.c b/source3/lib/util_path.c
index 509ba5f..6f58a03 100644
--- a/source3/lib/util_path.c
+++ b/source3/lib/util_path.c
@@ -93,3 +93,142 @@ char *cache_path(const char *name)
{
return xx_path(name, lp_cache_directory());
}
+
+/**
+ * @brief Removes any invalid path components in an absolute POSIX path.
+ *
+ * @param ctx Talloc context to return string.
+ *
+ * @param abs_path Absolute path string to process.
+ *
+ * @retval Pointer to a talloc'ed string containing the absolute full path.
+ **/
+
+char *canonicalize_absolute_path(TALLOC_CTX *ctx, const char *abs_path)
+{
+ char *destname;
+ char *d;
+ const char *s = abs_path;
+ bool start_of_name_component = true;
+
+ /* Allocate for strlen + '\0' + possible leading '/' */
+ destname = (char *)talloc_size(ctx, strlen(abs_path) + 2);
+ if (destname == NULL) {
+ return NULL;
+ }
+ d = destname;
+
+ *d++ = '/'; /* Always start with root. */
+
+ while (*s) {
+ if (*s == '/') {
+ /* Eat multiple '/' */
+ while (*s == '/') {
+ s++;
+ }
+ if ((d > destname + 1) && (*s != '\0')) {
+ *d++ = '/';
+ }
+ start_of_name_component = true;
+ continue;
+ }
+
+ if (start_of_name_component) {
+ if ((s[0] == '.') && (s[1] == '.') &&
+ (s[2] == '/' || s[2] == '\0')) {
+ /* Uh oh - "/../" or "/..\0" ! */
+
+ /* Go past the .. leaving us on the / or '\0' */
+ s += 2;
+
+ /* If we just added a '/' - delete it */
+ if ((d > destname) && (*(d-1) == '/')) {
+ *(d-1) = '\0';
+ d--;
+ }
+
+ /*
+ * Are we at the start ?
+ * Can't go back further if so.
+ */
+ if (d <= destname) {
+ *d++ = '/'; /* Can't delete root */
+ continue;
+ }
+ /* Go back one level... */
+ /*
+ * Decrement d first as d points to
+ * the *next* char to write into.
+ */
+ for (d--; d > destname; d--) {
+ if (*d == '/') {
+ break;
+ }
+ }
+
+ /*
+ * Are we at the start ?
+ * Can't go back further if so.
+ */
+ if (d <= destname) {
+ *d++ = '/'; /* Can't delete root */
+ continue;
+ }
+
+ /*
+ * We're still at the start of a name
+ * component, just the previous one.
+ */
+ continue;
+ } else if ((s[0] == '.') &&
+ ((s[1] == '\0') || s[1] == '/')) {
+ /*
+ * Component of pathname can't be "." only.
+ * Skip the '.' .
+ */
+ if (s[1] == '/') {
+ s += 2;
+ } else {
+ s++;
+ }
+ continue;
+ }
+ }
+
+ if (!(*s & 0x80)) {
+ *d++ = *s++;
+ } else {
+ size_t siz;
+ /* Get the size of the next MB character. */
+ next_codepoint(s,&siz);
+ switch(siz) {
+ case 5:
+ *d++ = *s++;
+ /*fall through*/
+ case 4:
+ *d++ = *s++;
+ /*fall through*/
+ case 3:
+ *d++ = *s++;
+ /*fall through*/
+ case 2:
+ *d++ = *s++;
+ /*fall through*/
+ case 1:
+ *d++ = *s++;
+ break;
+ default:
+ break;
+ }
+ }
+ start_of_name_component = false;
+ }
+ *d = '\0';
+
+ /* And must not end in '/' */
+ if (d > destname + 1 && (*(d-1) == '/')) {
+ *(d-1) = '\0';
+ }
+
+ return destname;
+}
diff --git a/source3/lib/util_path.h b/source3/lib/util_path.h
index 118a4be..16e2792 100644
--- a/source3/lib/util_path.h
+++ b/source3/lib/util_path.h
@@ -27,5 +27,6 @@
char *lock_path(const char *name);
char *state_path(const char *name);
char *cache_path(const char *name);
+char *canonicalize_absolute_path(TALLOC_CTX *ctx, const char *abs_path);
#endif
diff --git a/source3/modules/vfs_shadow_copy2.c b/source3/modules/vfs_shadow_copy2.c
index 6a25c87..402eb70 100644
--- a/source3/modules/vfs_shadow_copy2.c
+++ b/source3/modules/vfs_shadow_copy2.c
@@ -35,6 +35,7 @@
#include "system/filesys.h"
#include "include/ntioctl.h"
#include "util_tdb.h"
+#include "lib/util_path.h"
struct shadow_copy2_config {
char *gmt_format;
@@ -74,6 +75,11 @@ struct shadow_copy2_snaplist_info {
struct shadow_copy2_private {
struct shadow_copy2_config *config;
struct shadow_copy2_snaplist_info *snaps;
+ char *shadow_cwd; /* Absolute $cwd path. */
+ /* Absolute connectpath - can vary depending on $cwd. */
+ char *shadow_connectpath;
+ /* malloc'ed realpath return. */
+ char *shadow_realpath;
};
static int shadow_copy2_get_shadow_copy_data(
@@ -404,79 +410,254 @@ static char *shadow_copy2_snapshot_path(TALLOC_CTX *mem_ctx,
return result;
}
+static char *make_path_absolute(TALLOC_CTX *mem_ctx,
+ struct shadow_copy2_private *priv,
+ const char *name)
+{
+ char *newpath = NULL;
+ char *abs_path = NULL;
+
+ if (name[0] != '/') {
+ newpath = talloc_asprintf(mem_ctx,
+ "%s/%s",
+ priv->shadow_cwd,
+ name);
+ if (newpath == NULL) {
+ return NULL;
+ }
+ name = newpath;
+ }
+ abs_path = canonicalize_absolute_path(mem_ctx, name);
+ TALLOC_FREE(newpath);
+ return abs_path;
+}
+
+/* Return a $cwd-relative path. */
+static bool make_relative_path(const char *cwd, char *abs_path)
+{
+ size_t cwd_len = strlen(cwd);
+ size_t abs_len = strlen(abs_path);
+
+ if (abs_len < cwd_len) {
+ return false;
+ }
+ if (memcmp(abs_path, cwd, cwd_len) != 0) {
+ return false;
+ }
+ if (abs_path[cwd_len] != '/' && abs_path[cwd_len] != '\0') {
+ return false;
+ }
+ if (abs_path[cwd_len] == '/') {
+ cwd_len++;
+ }
+ memmove(abs_path, &abs_path[cwd_len], abs_len + 1 - cwd_len);
+ return true;
+}
+
+static bool shadow_copy2_snapshot_to_gmt(vfs_handle_struct *handle,
+ const char *name,
+ char *gmt, size_t gmt_len);
+
+/*
+ * Check if an incoming filename is already a snapshot converted pathname.
+ *
+ * If so, it returns the pathname truncated at the snapshot point which
+ * will be used as the connectpath.
+ */
+
+static int check_for_converted_path(TALLOC_CTX *mem_ctx,
+ struct vfs_handle_struct *handle,
+ struct shadow_copy2_private *priv,
+ char *abs_path,
+ bool *ppath_already_converted,
+ char **pconnectpath)
+{
+ size_t snapdirlen = 0;
+ char *p = strstr_m(abs_path, priv->config->snapdir);
+ char *q = NULL;
+ char *connect_path = NULL;
+ char snapshot[GMT_NAME_LEN+1];
+
+ *ppath_already_converted = false;
+
+ if (p == NULL) {
+ /* Must at least contain shadow:snapdir. */
+ return 0;
+ }
+
+ if (priv->config->snapdir[0] == '/' &&
+ p != abs_path) {
+ /* Absolute shadow:snapdir must be at the start. */
+ return 0;
+ }
+
+ snapdirlen = strlen(priv->config->snapdir);
+ if (p[snapdirlen] != '/') {
+ /* shadow:snapdir must end as a separate component. */
+ return 0;
+ }
+
+ if (p > abs_path && p[-1] != '/') {
+ /* shadow:snapdir must start as a separate component. */
+ return 0;
+ }
+
+ p += snapdirlen;
+ p++; /* Move past the / */
+
+ /*
+ * Need to return up to the next path
+ * component after the time.
+ * This will be used as the connectpath.
+ */
+ q = strchr(p, '/');
+ if (q == NULL) {
+ /*
+ * No next path component.
+ * Use entire string.
+ */
+ connect_path = talloc_strdup(mem_ctx,
+ abs_path);
+ } else {
+ connect_path = talloc_strndup(mem_ctx,
+ abs_path,
+ q - abs_path);
+ }
+ if (connect_path == NULL) {
+ return ENOMEM;
+ }
+
+ /*
+ * Point p at the same offset in connect_path as
+ * it is in abs_path.
+ */
+
+ p = &connect_path[p - abs_path];
+
+ /*
+ * Now ensure there is a time string at p.
+ * The SMB-format @GMT-token string is returned
+ * in snapshot.
+ */
+
+ if (!shadow_copy2_snapshot_to_gmt(handle,
+ p,
+ snapshot,
+ sizeof(snapshot))) {
+ TALLOC_FREE(connect_path);
+ return 0;
+ }
+
+ if (pconnectpath != NULL) {
+ *pconnectpath = connect_path;
+ }
+
+ *ppath_already_converted = true;
+
+ DBG_DEBUG("path |%s| is already converted. "
+ "connect path = |%s|\n",
+ abs_path,
+ connect_path);
+
+ return 0;
+}
+
/**
- * Strip a snapshot component from a filename as
- * handed in via the smb layer.
- * Returns the parsed timestamp and the stripped filename.
+ * This function does two things.
+ *
+ * 1). Checks if an incoming filename is already a
+ * snapshot converted pathname.
+ * If so, it returns the pathname truncated
+ * at the snapshot point which will be used
+ * as the connectpath, and then does an early return.
+ *
+ * 2). Checks if an incoming filename contains an
+ * SMB-layer @GMT- style timestamp.
+ * If so, it strips the timestamp, and returns
+ * both the timestamp and the stripped path
+ * (making it cwd-relative).
*/
-static bool shadow_copy2_strip_snapshot(TALLOC_CTX *mem_ctx,
+
+static bool shadow_copy2_strip_snapshot_internal(TALLOC_CTX *mem_ctx,
struct vfs_handle_struct *handle,
- const char *name,
+ const char *orig_name,
time_t *ptimestamp,
- char **pstripped)
+ char **pstripped,
+ char **psnappath)
{
struct tm tm;
- time_t timestamp;
+ time_t timestamp = 0;
const char *p;
char *q;
- char *stripped;
+ char *stripped = NULL;
size_t rest_len, dst_len;
struct shadow_copy2_private *priv;
- const char *snapdir;
- ssize_t snapdirlen;
ptrdiff_t len_before_gmt;
+ const char *name = orig_name;
+ char *abs_path = NULL;
+ bool ret = true;
+ bool already_converted = false;
+ int err = 0;
SMB_VFS_HANDLE_GET_DATA(handle, priv, struct shadow_copy2_private,
return false);
DEBUG(10, (__location__ ": enter path '%s'\n", name));
+ abs_path = make_path_absolute(mem_ctx, priv, name);
+ if (abs_path == NULL) {
+ ret = false;
+ goto out;
+ }
+ name = abs_path;
+
+ DEBUG(10, (__location__ ": abs path '%s'\n", name));
+
+ err = check_for_converted_path(mem_ctx,
+ handle,
+ priv,
+ abs_path,
+ &already_converted,
+ psnappath);
+ if (err != 0) {
+ /* error in conversion. */
+ ret = false;
+ goto out;
+ }
+
+ if (already_converted) {
+ goto out;
+ }
+
+ /*
+ * From here we're only looking to strip an
+ * SMB-layer @GMT- token.
+ */
+
p = strstr_m(name, "@GMT-");
if (p == NULL) {
DEBUG(11, ("@GMT not found\n"));
- goto no_snapshot;
+ goto out;
}
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;
+ goto out;
}
- /*
- * 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"));
- goto no_snapshot;
+ goto out;
}
tm.tm_isdst = -1;
timestamp = timegm(&tm);
if (timestamp == (time_t)-1) {
DEBUG(10, ("timestamp==-1\n"));
- goto no_snapshot;
+ goto out;
}
if (q[0] == '\0') {
/*
@@ -496,12 +677,24 @@ static bool shadow_copy2_strip_snapshot(TALLOC_CTX *mem_ctx,
stripped = talloc_strndup(mem_ctx, name,
len_before_gmt);
if (stripped == NULL) {
- return false;
+ ret = false;
+ goto out;
+ }
+ if (orig_name[0] != '/') {
+ if (make_relative_path(priv->shadow_cwd,
+ stripped) == false) {
+ DEBUG(10, (__location__ ": path '%s' "
+ "doesn't start with cwd '%s\n",
+ stripped, priv->shadow_cwd));
+ ret = false;
+ errno = ENOENT;
+ goto out;
+ }
}
*pstripped = stripped;
}
*ptimestamp = timestamp;
- return true;
+ goto out;
}
if (q[0] != '/') {
/*
--
Samba Shared Repository
More information about the samba-cvs
mailing list