[SCM] Samba Shared Repository - branch v4-4-test updated

Karolin Seeger kseeger at samba.org
Wed Feb 15 14:15:06 UTC 2017


The branch, v4-4-test has been updated
       via  878f56f s3:librpc: remove bigendian argument from dcerpc_pull_ncacn_packet()
       via  81231af s3: VFS: Don't allow symlink, link or rename on already converted paths.
       via  eeef5e4 s3: VFS: shadow_copy2: Fix usage of saved_errno to only set errno on error.
       via  79c2349 s3: VFS: shadow_copy2: Fix a memory leak in the connectpath function.
       via  eef845b s3: VFS: shadow_copy2: Fix module to work with variable current working directory.
       via  7a83181 s3: VFS: Add utility function check_for_converted_path().
       via  50d3a70 s3: VFS: Ensure shadow:format cannot contain a / path separator.
       via  52439d7 s3: VFS: Allow shadow_copy2_connectpath() to return the cached path derived from $cwd.
       via  0d1a281 s3: VFS: shadow_copy2: Fix chdir to store off the needed private variables.
       via  173bd07 s3: VFS: shadow_copy2: Add two currently unused functions to make pathnames absolute or relative to $cwd.
       via  d9acfc4 s3: VFS: shadow_copy2: Change a parameter name.
       via  6cc2fdb s3: VFS: shadow_copy2: Add a wrapper function to call the original shadow_copy2_strip_snapshot().
       via  aa3a11a s3: VFS: shadow_copy2: Add two new variables to the config data. Not yet used.
       via  65c38d7 s3: VFS: shadow_copy2: Fix length comparison to ensure we don't overstep a length.
       via  0d159a2 s3: VFS: shadow_copy2: Ensure pathnames for parameters are correctly relative and terminated.
       via  847a266 s3: VFS: shadow_copy2: Correctly initialize timestamp and stripped variables.
       via  f9edf3e s3: smbd: Make set_conn_connectpath() call canonicalize_absolute_path().
       via  163234d s3: smbtorture: Add new local test LOCAL-CANONICALIZE-PATH
       via  40f3664 s3: lib: Fix two old, old bugs in set_conn_connectpath(), now in canonicalize_absolute_path().
       via  38e2f4b s3: lib: Add canonicalize_absolute_path().
       via  e3816bb s3: smbd: Correctly canonicalize any incoming shadow copy path.
       via  c808b73 waf: backport finding of pkg-config
      from  1b6b200 s3: VFS: vfs_streams_xattr.c: Make streams_xattr_open() store the same path as streams_xattr_recheck().

https://git.samba.org/?p=samba.git;a=shortlog;h=v4-4-test


- Log -----------------------------------------------------------------
commit 878f56ff3d48e401e8c7ed005b2df7f585df64c3
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Oct 28 12:16:05 2015 +0100

    s3:librpc: remove bigendian argument from dcerpc_pull_ncacn_packet()
    
    We should get this from the packet itself.
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Günther Deschner <gd at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>
    (cherry picked from commit 1bfba2c5161c0e27f8c27301f258360aedf1b018)
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=12581
    smbclient fails on bad endianess when listing shares from Solaris kernel SMB
    server on SPARC
    
    Autobuild-User(v4-4-test): Karolin Seeger <kseeger at samba.org>
    Autobuild-Date(v4-4-test): Wed Feb 15 15:14:04 CET 2017 on sn-devel-144

commit 81231afc2f968582fb1998b227713b34e74d9a7f
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
    
    (backported from commit 0e1deb77f2b310ad7e5dd784174207adacf1c981)

commit eeef5e408ba03815cf175539f5c83c34cb05aa24
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>
    (backported from commit cda6764f1a8db96182bfd1855440bc6a1ba1abee)

commit 79c2349c2d57068a34356918a8db285515a23812
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>
    (backported from commit 4d339a88851f601fae195ac8ff0691cbd3504f41)

commit eef845bfeff709dab07609590955efde54c4b377
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>
    (backported from commit 128d5f27cd42b0c7efcbe3d28fe3eee881e0734b)

commit 7a831814592505d004f83ac49ec25b02f4f2d374
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>
    (backported from commit b94dc85d339c9a10496edd07b85bdd7808d2e332)

commit 50d3a7011237fcb36bf9b53f7db8846e854453d4
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>
    (backported from commit cd4f940162b17e4f7345d392326a31ae478230fa)

commit 52439d70d766062ee74d64aeeccf9838c6c9ae74
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>
    (backported from commit 42bd1acad75a6b5ea81fe4b30c067dd82623c042)

commit 0d1a281140a17fd4317fdfaddc7f14784e3154eb
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>
    (backported from commit 27340df4b52e4341f134667c59d71656a7a1fdae)

commit 173bd073004352d8564485c56a19b167596b1fd5
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>
    (backported from commit 9d65107b8f2864dba8d41b3316c483b3f36d0697)

commit d9acfc47aad6d0870c9deb1e2385aff0c8e4a7a5
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>
    (backported from commit 2887465108aef5e2e7c64417437ecb86c7460e16)

commit 6cc2fdbf91d1f549360a9d9aa1aa50decbbce40e
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>
    (backported from commit 5aa1ea95157475dfd2d056f0158b14b2b90895a9)

commit aa3a11a95bdcf91230dddb435b30033eb12068b3
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 config 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>
    (backported from commit 72fe2b62e3ee7462e5be855b01943f28b26c36c1)

commit 65c38d7f256cf5fdb44b9945aae4be9f3df14543
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>
    (backported from commit 37ef8d3f65bd1215717eb51b2e1cdb84a7bed348)

commit 0d159a21294782aecfebd36109c8f3aec4f35fc8
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>
    (backported from commit 979e39252bcc88e8aacb543b8bf322dd6f17fe7f)

commit 847a2662396ff03449cd85b8d7ba15ef56caec3f
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>
    (backported from commit 0a190f4dd950c947d47c42163d11ea4bd6e6e508)

commit f9edf3e0c9561a4198b93f81742e4c8ec35b8e6d
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>
    (backported from commit d650d65488761b30fa34d42cb1ab400618a78c33)

commit 163234d5aec15f56648436a18073cac8368367a2
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>
    (backported from commit a51363309a4330b65e34ae941ec99d180bdbab56)

commit 40f3664bfb86053d3550809f883793db54116b23
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>
    (backported from commit 82979afc46cc5e466bdd999a94080e7a5df95518)

commit 38e2f4bf1b14e2ea514437e91bd1e34466094698
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>
    (backported from commit 02599c39337c3049762a6b0bd6290577817ee5a5)

commit e3816bb04a761202747a73f282e193cb294c41e1
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>
    (backported from commit 39678ed6af708fb6f2760bfb51051add11e3c498)

commit c808b732fbfcf88bb64a48978dd98345b99feabe
Author: Uri Simchoni <uri at samba.org>
Date:   Thu Jan 19 07:46:57 2017 +0200

    waf: backport finding of pkg-config
    
    Allow the builder to customize the location of pkg-config
    utility by setting PKGCONFIG environment variable.
    
    This is backported from upstream waf.
    
    Thanks to Zentaro Kavanagh <zentaro at google.com> for
    pointing that out and proposing the fix.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=12529
    
    Signed-off-by: Uri Simchoni <uri at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    
    Autobuild-User(master): Jeremy Allison <jra at samba.org>
    Autobuild-Date(master): Wed Jan 25 04:23:00 CET 2017 on sn-devel-144
    
    (cherry picked from commit 2cf141ed45b4f7b7754cb9525d987ff38495d789)

-----------------------------------------------------------------------

Summary of changes:
 source3/lib/util_path.c                    | 139 +++++
 source3/lib/util_path.h                    |   1 +
 source3/librpc/rpc/dcerpc.h                |   3 +-
 source3/librpc/rpc/dcerpc_helpers.c        |   9 +-
 source3/modules/vfs_shadow_copy2.c         | 918 +++++++++++++++++++++--------
 source3/rpc_client/cli_pipe.c              |   3 +-
 source3/selftest/tests.py                  |   1 +
 source3/smbd/filename.c                    | 150 +++++
 source3/smbd/service.c                     | 103 +---
 source3/torture/torture.c                  |  44 ++
 third_party/waf/wafadmin/Tools/config_c.py |   4 +-
 11 files changed, 1011 insertions(+), 364 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/librpc/rpc/dcerpc.h b/source3/librpc/rpc/dcerpc.h
index 1838012..f58ef4c 100644
--- a/source3/librpc/rpc/dcerpc.h
+++ b/source3/librpc/rpc/dcerpc.h
@@ -61,8 +61,7 @@ NTSTATUS dcerpc_push_ncacn_packet(TALLOC_CTX *mem_ctx,
 				  DATA_BLOB *blob);
 NTSTATUS dcerpc_pull_ncacn_packet(TALLOC_CTX *mem_ctx,
 				  const DATA_BLOB *blob,
-				  struct ncacn_packet *r,
-				  bool bigendian);
+				  struct ncacn_packet *r);
 NTSTATUS dcerpc_push_dcerpc_auth(TALLOC_CTX *mem_ctx,
 				 enum dcerpc_AuthType auth_type,
 				 enum dcerpc_AuthLevel auth_level,
diff --git a/source3/librpc/rpc/dcerpc_helpers.c b/source3/librpc/rpc/dcerpc_helpers.c
index aab43a1..11b445f 100644
--- a/source3/librpc/rpc/dcerpc_helpers.c
+++ b/source3/librpc/rpc/dcerpc_helpers.c
@@ -88,14 +88,12 @@ NTSTATUS dcerpc_push_ncacn_packet(TALLOC_CTX *mem_ctx,
 *			elements
 * @param blob		The blob of data to decode
 * @param r		An empty ncacn_packet, must not be NULL
-* @param bigendian	Whether the packet is bignedian encoded
 *
 * @return a NTSTATUS error code
 */
 NTSTATUS dcerpc_pull_ncacn_packet(TALLOC_CTX *mem_ctx,
 				  const DATA_BLOB *blob,
-				  struct ncacn_packet *r,
-				  bool bigendian)
+				  struct ncacn_packet *r)
 {
 	enum ndr_err_code ndr_err;
 	struct ndr_pull *ndr;
@@ -104,11 +102,12 @@ NTSTATUS dcerpc_pull_ncacn_packet(TALLOC_CTX *mem_ctx,
 	if (!ndr) {
 		return NT_STATUS_NO_MEMORY;
 	}
-	if (bigendian) {
+
+	if (!(CVAL(ndr->data, DCERPC_DREP_OFFSET) & DCERPC_DREP_LE)) {
 		ndr->flags |= LIBNDR_FLAG_BIGENDIAN;
 	}
 
-	if (CVAL(blob->data, DCERPC_PFC_OFFSET) & DCERPC_PFC_FLAG_OBJECT_UUID) {
+	if (CVAL(ndr->data, DCERPC_PFC_OFFSET) & DCERPC_PFC_FLAG_OBJECT_UUID) {
 		ndr->flags |= LIBNDR_FLAG_OBJECT_PRESENT;
 	}
 
diff --git a/source3/modules/vfs_shadow_copy2.c b/source3/modules/vfs_shadow_copy2.c
index 5750b65..1345ca2 100644
--- a/source3/modules/vfs_shadow_copy2.c
+++ b/source3/modules/vfs_shadow_copy2.c
@@ -34,6 +34,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;
@@ -48,6 +49,11 @@ struct shadow_copy2_config {
 	char *mount_point;
 	char *rel_connectpath; /* share root, relative to a snapshot root */
 	char *snapshot_basepath; /* the absolute version of snapdir */
+	char *shadow_cwd; /* Absolute $cwd path. */
+	/* Absolute connectpath - can vary depending on $cwd. */
+	char *shadow_connectpath;
+	/* malloc'ed realpath return. */
+	char *shadow_realpath;
 };
 
 static bool shadow_copy2_find_slashes(TALLOC_CTX *mem_ctx, const char *str,
@@ -216,79 +222,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_config *config,
+				const char *name)
+{
+	char *newpath = NULL;
+	char *abs_path = NULL;
+
+	if (name[0] != '/') {
+		newpath = talloc_asprintf(mem_ctx,
+					"%s/%s",
+					config->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_config *config,
+				char *abs_path,
+				bool *ppath_already_converted,
+				char **pconnectpath)
+{
+	size_t snapdirlen = 0;
+	char *p = strstr_m(abs_path, 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 (config->snapdir[0] == '/' &&
+			p != abs_path) {
+		/* Absolute shadow:snapdir must be at the start. */
+		return 0;
+	}
+
+	snapdirlen = strlen(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_config *config;
-	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, config, struct shadow_copy2_config,
 				return false);
 
 	DEBUG(10, (__location__ ": enter path '%s'\n", name));
 
+	abs_path = make_path_absolute(mem_ctx, config, 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,
+					config,
+					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);
-


-- 
Samba Shared Repository



More information about the samba-cvs mailing list