[PATCH] smbd: Fix snapshot query on shares with DFS enabled

Jeremy Allison jra at samba.org
Thu Aug 18 21:51:50 UTC 2016


On Thu, Aug 18, 2016 at 11:32:35AM -0700, Jeremy Allison wrote:
> 
> We still have the problem that when we create the paths previous
> versions path to query the SMB1 server returns NT_STATUS_OBJECT_PATH_NOT_FOUND,
> due to the fact we're not setting the flags2 FLAGS2_REPARSE_PATH
> bit in the request when we're doing the path query. We don't
> currently have capabilities to do that, so I'm going to create
> another bug and add create fixes for all these things.

OK, here is a patchset that fixes enumerating and accessing
shadow copy paths from smbclient and libsmbclient.

It looks a bigger patchset than it is :-).

Overview:

01	- Add missing FLAGS2_REPARSE_PATH flag definitions.
02 - 04 - Add additional_flags2 arg to internal cli_XXX() functions
	  that need to pass paths that might contain @GMT- tokens.
05	- Add clistr_is_previous_version_path() function that checks
	  for a valid @GMT- path.
06 - 21 - For all cli_XX() functions that take a pathname, call
	  clistr_is_previous_version_path() and add in the
	  FLAGS2_REPARSE_PATH to the additional_flags2 parameter
	  if it maches.

	  Only function not fixed is cli_set_ea_path(), which
	  uses the sync versions of cli_trans() which I didn't
	  change to add additional_flags2 arg. As this is a 'set'
	  function I don't think this works with a @GMT- path.
	  Patch 20 is a reminder to change cli_set_ea_path()
	  to use the async cli_trans_send()/cli_trans_recv()
	  if we ever need to fix this.

22	- Fix wrong size in cli_shadow_copy_data_send() params.
23	- Harden cli_shadow_copy_data_recv() parsing in case
	  of bad server. Only crash bug here, nothing worse.
24	- Fix smbclient to use cli_shadow_copy_data() correctly
	  over SMB1.

Using this I can do an 'allinfo' against a Windows server
with shadow copies, and see them available to smbclient.

Please review and push if happy ! Passes local samba3.blackbox.shadow_copy2
tests.

Once this is in I'll do the same fix for accessing shadow
copies over SMB2.

Cheers,

	Jeremy.
-------------- next part --------------
From 21df13dbef6b718c58ce5fc39ff9b8e2c8ddeb61 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Wed, 17 Aug 2016 14:33:00 -0700
Subject: [PATCH 01/24] s3: SMB1: Add missing FLAGS2 definitions from MS-SMB.

https://bugzilla.samba.org/show_bug.cgi?id=12165

Signed-off-by: Jeremy Allison <jra at samba.org>
---
 libcli/smb/smb_constants.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/libcli/smb/smb_constants.h b/libcli/smb/smb_constants.h
index e03e843..2fcb590 100644
--- a/libcli/smb/smb_constants.h
+++ b/libcli/smb/smb_constants.h
@@ -309,8 +309,10 @@ enum csc_policy {
 #define FLAGS2_LONG_PATH_COMPONENTS    0x0001
 #define FLAGS2_EXTENDED_ATTRIBUTES     0x0002
 #define FLAGS2_SMB_SECURITY_SIGNATURES 0x0004
+#define FLAGS2_COMPRESSED              0x0008 /* MS-SMB */
 #define FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED 0x0010
 #define FLAGS2_IS_LONG_NAME            0x0040
+#define FLAGS2_REPARSE_PATH            0x0400 /* MS-SMB @GMT- path. */
 #define FLAGS2_EXTENDED_SECURITY       0x0800
 #define FLAGS2_DFS_PATHNAMES           0x1000
 #define FLAGS2_READ_PERMIT_EXECUTE     0x2000
-- 
2.8.0.rc3.226.g39d4020


From 21b4ed38ef3340fc57ff95e4f9b690b07a7071c5 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Thu, 18 Aug 2016 12:20:25 -0700
Subject: [PATCH 02/24] s3: libsmb: Add uint16_t additional_flags2 arg to
 cli_smb_send().

Not yet used.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=12165

Signed-off-by: Jeremy Allison <jra at samba.org>
---
 source3/include/async_smb.h |  4 +++-
 source3/libsmb/async_smb.c  |  2 +-
 source3/libsmb/cliconnect.c | 14 +++++++-------
 source3/libsmb/clientgen.c  |  2 +-
 source3/libsmb/clifile.c    | 32 ++++++++++++++++----------------
 source3/libsmb/clilist.c    |  6 +++---
 source3/libsmb/climessage.c |  6 +++---
 source3/libsmb/clioplock.c  |  2 +-
 8 files changed, 35 insertions(+), 33 deletions(-)

diff --git a/source3/include/async_smb.h b/source3/include/async_smb.h
index 00c2313..6765749 100644
--- a/source3/include/async_smb.h
+++ b/source3/include/async_smb.h
@@ -32,7 +32,9 @@ struct tevent_req *cli_smb_req_create(TALLOC_CTX *mem_ctx,
 				      struct iovec *bytes_iov);
 struct tevent_req *cli_smb_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
 				struct cli_state *cli,
-				uint8_t smb_command, uint8_t additional_flags,
+				uint8_t smb_command,
+				uint8_t additional_flags,
+				uint16_t additional_flags2,
 				uint8_t wct, uint16_t *vwv,
 				uint32_t num_bytes,
 				const uint8_t *bytes);
diff --git a/source3/libsmb/async_smb.c b/source3/libsmb/async_smb.c
index 8d5c3d4..5d9cce1 100644
--- a/source3/libsmb/async_smb.c
+++ b/source3/libsmb/async_smb.c
@@ -101,13 +101,13 @@ struct tevent_req *cli_smb_send(TALLOC_CTX *mem_ctx,
 				struct cli_state *cli,
 				uint8_t smb_command,
 				uint8_t additional_flags,
+				uint16_t additional_flags2,
 				uint8_t wct, uint16_t *vwv,
 				uint32_t num_bytes,
 				const uint8_t *bytes)
 {
 	struct cli_smb_req_state *state;
 	uint8_t clear_flags = 0;
-	uint16_t additional_flags2 = 0;
 	uint16_t clear_flags2 = 0;
 
 	state = talloc_zero(mem_ctx, struct cli_smb_req_state);
diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c
index 33759d9..4635cf8 100644
--- a/source3/libsmb/cliconnect.c
+++ b/source3/libsmb/cliconnect.c
@@ -204,7 +204,7 @@ static struct tevent_req *cli_session_setup_lanman2_send(
 		return tevent_req_post(req, ev);
 	}
 
-	subreq = cli_smb_send(state, ev, cli, SMBsesssetupX, 0, 10, vwv,
+	subreq = cli_smb_send(state, ev, cli, SMBsesssetupX, 0, 0, 10, vwv,
 			      talloc_get_size(bytes), bytes);
 	if (tevent_req_nomem(subreq, req)) {
 		return tevent_req_post(req, ev);
@@ -569,7 +569,7 @@ static struct tevent_req *cli_session_setup_plain_send(
 		return tevent_req_post(req, ev);
 	}
 
-	subreq = cli_smb_send(state, ev, cli, SMBsesssetupX, 0, 13, vwv,
+	subreq = cli_smb_send(state, ev, cli, SMBsesssetupX, 0, 0, 13, vwv,
 			      talloc_get_size(bytes), bytes);
 	if (tevent_req_nomem(subreq, req)) {
 		return tevent_req_post(req, ev);
@@ -880,7 +880,7 @@ static struct tevent_req *cli_session_setup_nt1_send(
 		return tevent_req_post(req, ev);
 	}
 
-	subreq = cli_smb_send(state, ev, cli, SMBsesssetupX, 0, 13, vwv,
+	subreq = cli_smb_send(state, ev, cli, SMBsesssetupX, 0, 0, 13, vwv,
 			      talloc_get_size(bytes), bytes);
 	if (tevent_req_nomem(subreq, req)) {
 		return tevent_req_post(req, ev);
@@ -1111,7 +1111,7 @@ static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state *state,
 	if (state->buf == NULL) {
 		return false;
 	}
-	subreq = cli_smb_send(state, state->ev, state->cli, SMBsesssetupX, 0,
+	subreq = cli_smb_send(state, state->ev, state->cli, SMBsesssetupX, 0, 0,
 			      12, state->vwv,
 			      talloc_get_size(state->buf), state->buf);
 	if (subreq == NULL) {
@@ -2331,7 +2331,7 @@ static struct tevent_req *cli_ulogoff_send(TALLOC_CTX *mem_ctx,
 	SCVAL(state->vwv+1, 0, 0);
 	SSVAL(state->vwv+2, 0, 0);
 
-	subreq = cli_smb_send(state, ev, cli, SMBulogoffX, 0, 2, state->vwv,
+	subreq = cli_smb_send(state, ev, cli, SMBulogoffX, 0, 0, 2, state->vwv,
 			      0, NULL);
 	if (tevent_req_nomem(subreq, req)) {
 		return tevent_req_post(req, ev);
@@ -2877,7 +2877,7 @@ static struct tevent_req *cli_tdis_send(TALLOC_CTX *mem_ctx,
 	}
 	state->cli = cli;
 
-	subreq = cli_smb_send(state, ev, cli, SMBtdis, 0, 0, NULL, 0, NULL);
+	subreq = cli_smb_send(state, ev, cli, SMBtdis, 0, 0, 0, NULL, 0, NULL);
 	if (tevent_req_nomem(subreq, req)) {
 		return tevent_req_post(req, ev);
 	}
@@ -3594,7 +3594,7 @@ static struct tevent_req *cli_raw_tcon_send(
 		return tevent_req_post(req, ev);
 	}
 
-	subreq = cli_smb_send(state, ev, cli, SMBtcon, 0, 0, NULL,
+	subreq = cli_smb_send(state, ev, cli, SMBtcon, 0, 0, 0, NULL,
 			      talloc_get_size(bytes), bytes);
 	if (tevent_req_nomem(subreq, req)) {
 		return tevent_req_post(req, ev);
diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c
index bf31bb1..bc5c1b1 100644
--- a/source3/libsmb/clientgen.c
+++ b/source3/libsmb/clientgen.c
@@ -592,7 +592,7 @@ NTSTATUS cli_smb(TALLOC_CTX *mem_ctx, struct cli_state *cli,
         if (ev == NULL) {
                 goto fail;
         }
-        req = cli_smb_send(mem_ctx, ev, cli, smb_command, additional_flags,
+        req = cli_smb_send(mem_ctx, ev, cli, smb_command, additional_flags, 0,
 			   wct, vwv, num_bytes, bytes);
         if (req == NULL) {
                 goto fail;
diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c
index 684f263..54d93a7 100644
--- a/source3/libsmb/clifile.c
+++ b/source3/libsmb/clifile.c
@@ -1160,7 +1160,7 @@ struct tevent_req *cli_rename_send(TALLOC_CTX *mem_ctx,
 		return tevent_req_post(req, ev);
 	}
 
-	subreq = cli_smb_send(state, ev, cli, SMBmv, additional_flags,
+	subreq = cli_smb_send(state, ev, cli, SMBmv, additional_flags, 0,
 			      1, state->vwv, talloc_get_size(bytes), bytes);
 	if (tevent_req_nomem(subreq, req)) {
 		return tevent_req_post(req, ev);
@@ -1289,7 +1289,7 @@ static struct tevent_req *cli_ntrename_internal_send(TALLOC_CTX *mem_ctx,
 		return tevent_req_post(req, ev);
 	}
 
-	subreq = cli_smb_send(state, ev, cli, SMBntrename, additional_flags,
+	subreq = cli_smb_send(state, ev, cli, SMBntrename, additional_flags, 0,
 			      4, state->vwv, talloc_get_size(bytes), bytes);
 	if (tevent_req_nomem(subreq, req)) {
 		return tevent_req_post(req, ev);
@@ -1475,7 +1475,7 @@ struct tevent_req *cli_unlink_send(TALLOC_CTX *mem_ctx,
 		return tevent_req_post(req, ev);
 	}
 
-	subreq = cli_smb_send(state, ev, cli, SMBunlink, additional_flags,
+	subreq = cli_smb_send(state, ev, cli, SMBunlink, additional_flags, 0,
 				1, state->vwv, talloc_get_size(bytes), bytes);
 	if (tevent_req_nomem(subreq, req)) {
 		return tevent_req_post(req, ev);
@@ -1584,7 +1584,7 @@ struct tevent_req *cli_mkdir_send(TALLOC_CTX *mem_ctx,
 		return tevent_req_post(req, ev);
 	}
 
-	subreq = cli_smb_send(state, ev, cli, SMBmkdir, additional_flags,
+	subreq = cli_smb_send(state, ev, cli, SMBmkdir, additional_flags, 0,
 			      0, NULL, talloc_get_size(bytes), bytes);
 	if (tevent_req_nomem(subreq, req)) {
 		return tevent_req_post(req, ev);
@@ -1693,7 +1693,7 @@ struct tevent_req *cli_rmdir_send(TALLOC_CTX *mem_ctx,
 		return tevent_req_post(req, ev);
 	}
 
-	subreq = cli_smb_send(state, ev, cli, SMBrmdir, additional_flags,
+	subreq = cli_smb_send(state, ev, cli, SMBrmdir, additional_flags, 0,
 			      0, NULL, talloc_get_size(bytes), bytes);
 	if (tevent_req_nomem(subreq, req)) {
 		return tevent_req_post(req, ev);
@@ -1948,7 +1948,7 @@ static struct tevent_req *cli_ntcreate1_send(TALLOC_CTX *mem_ctx,
 
 	SSVAL(vwv+2, 1, converted_len);
 
-	subreq = cli_smb_send(state, ev, cli, SMBntcreateX, 0, 24, vwv,
+	subreq = cli_smb_send(state, ev, cli, SMBntcreateX, 0, 0, 24, vwv,
 			      talloc_get_size(bytes), bytes);
 	if (tevent_req_nomem(subreq, req)) {
 		return tevent_req_post(req, ev);
@@ -3032,7 +3032,7 @@ struct tevent_req *cli_unlock_send(TALLOC_CTX *mem_ctx,
 	SIVAL(state->data, 2, offset);
 	SIVAL(state->data, 6, len);
 
-	subreq = cli_smb_send(state, ev, cli, SMBlockingX, additional_flags,
+	subreq = cli_smb_send(state, ev, cli, SMBlockingX, additional_flags, 0,
 				8, state->vwv, 10, state->data);
 	if (tevent_req_nomem(subreq, req)) {
 		return tevent_req_post(req, ev);
@@ -3196,7 +3196,7 @@ struct tevent_req *cli_unlock64_send(TALLOC_CTX *mem_ctx,
 	SOFF_T_R(state->data, 4, offset);
 	SOFF_T_R(state->data, 12, len);
 
-	subreq = cli_smb_send(state, ev, cli, SMBlockingX, additional_flags,
+	subreq = cli_smb_send(state, ev, cli, SMBlockingX, additional_flags, 0,
 				8, state->vwv, 20, state->data);
 	if (tevent_req_nomem(subreq, req)) {
 		return tevent_req_post(req, ev);
@@ -3536,7 +3536,7 @@ struct tevent_req *cli_getattrE_send(TALLOC_CTX *mem_ctx,
 	state->zone_offset = smb1cli_conn_server_time_zone(cli->conn);
 	SSVAL(state->vwv+0,0,fnum);
 
-	subreq = cli_smb_send(state, ev, cli, SMBgetattrE, additional_flags,
+	subreq = cli_smb_send(state, ev, cli, SMBgetattrE, additional_flags, 0,
 			      1, state->vwv, 0, NULL);
 	if (tevent_req_nomem(subreq, req)) {
 		return tevent_req_post(req, ev);
@@ -3706,7 +3706,7 @@ struct tevent_req *cli_getatr_send(TALLOC_CTX *mem_ctx,
 		return tevent_req_post(req, ev);
 	}
 
-	subreq = cli_smb_send(state, ev, cli, SMBgetatr, additional_flags,
+	subreq = cli_smb_send(state, ev, cli, SMBgetatr, additional_flags, 0,
 			      0, NULL, talloc_get_size(bytes), bytes);
 	if (tevent_req_nomem(subreq, req)) {
 		return tevent_req_post(req, ev);
@@ -3853,7 +3853,7 @@ struct tevent_req *cli_setattrE_send(TALLOC_CTX *mem_ctx,
 	push_dos_date2((uint8_t *)&state->vwv[5], 0, write_time,
 		       smb1cli_conn_server_time_zone(cli->conn));
 
-	subreq = cli_smb_send(state, ev, cli, SMBsetattrE, additional_flags,
+	subreq = cli_smb_send(state, ev, cli, SMBsetattrE, additional_flags, 0,
 			      7, state->vwv, 0, NULL);
 	if (tevent_req_nomem(subreq, req)) {
 		return tevent_req_post(req, ev);
@@ -3992,7 +3992,7 @@ struct tevent_req *cli_setatr_send(TALLOC_CTX *mem_ctx,
 		return tevent_req_post(req, ev);
 	}
 
-	subreq = cli_smb_send(state, ev, cli, SMBsetatr, additional_flags,
+	subreq = cli_smb_send(state, ev, cli, SMBsetatr, additional_flags, 0,
 			      8, state->vwv, talloc_get_size(bytes), bytes);
 	if (tevent_req_nomem(subreq, req)) {
 		return tevent_req_post(req, ev);
@@ -4107,7 +4107,7 @@ struct tevent_req *cli_chkpath_send(TALLOC_CTX *mem_ctx,
 		return tevent_req_post(req, ev);
 	}
 
-	subreq = cli_smb_send(state, ev, cli, SMBcheckpath, additional_flags,
+	subreq = cli_smb_send(state, ev, cli, SMBcheckpath, additional_flags, 0,
 			      0, NULL, talloc_get_size(bytes), bytes);
 	if (tevent_req_nomem(subreq, req)) {
 		return tevent_req_post(req, ev);
@@ -4213,7 +4213,7 @@ struct tevent_req *cli_dskattr_send(TALLOC_CTX *mem_ctx,
 		return NULL;
 	}
 
-	subreq = cli_smb_send(state, ev, cli, SMBdskattr, additional_flags,
+	subreq = cli_smb_send(state, ev, cli, SMBdskattr, additional_flags, 0,
 			      0, NULL, 0, NULL);
 	if (tevent_req_nomem(subreq, req)) {
 		return tevent_req_post(req, ev);
@@ -4412,7 +4412,7 @@ struct tevent_req *cli_ctemp_send(TALLOC_CTX *mem_ctx,
 		return tevent_req_post(req, ev);
 	}
 
-	subreq = cli_smb_send(state, ev, cli, SMBctemp, additional_flags,
+	subreq = cli_smb_send(state, ev, cli, SMBctemp, additional_flags, 0,
 			      3, state->vwv, talloc_get_size(bytes), bytes);
 	if (tevent_req_nomem(subreq, req)) {
 		return tevent_req_post(req, ev);
@@ -5814,7 +5814,7 @@ struct tevent_req *cli_flush_send(TALLOC_CTX *mem_ctx,
 	}
 	SSVAL(state->vwv + 0, 0, fnum);
 
-	subreq = cli_smb_send(state, ev, cli, SMBflush, 0, 1, state->vwv,
+	subreq = cli_smb_send(state, ev, cli, SMBflush, 0, 0, 1, state->vwv,
 			      0, NULL);
 	if (tevent_req_nomem(subreq, req)) {
 		return tevent_req_post(req, ev);
diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c
index 6438d3b..5f9f89e 100644
--- a/source3/libsmb/clilist.c
+++ b/source3/libsmb/clilist.c
@@ -334,8 +334,8 @@ static struct tevent_req *cli_list_old_send(TALLOC_CTX *mem_ctx,
 		return tevent_req_post(req, ev);
 	}
 
-	subreq = cli_smb_send(state, state->ev, state->cli, SMBsearch,
-			      0, 2, state->vwv, talloc_get_size(bytes), bytes);
+	subreq = cli_smb_send(state, state->ev, state->cli, SMBsearch, 0, 0,
+			2, state->vwv, talloc_get_size(bytes), bytes);
 	if (tevent_req_nomem(subreq, req)) {
 		return tevent_req_post(req, ev);
 	}
@@ -437,7 +437,7 @@ static void cli_list_old_done(struct tevent_req *subreq)
 	if (tevent_req_nomem(bytes, req)) {
 		return;
 	}
-	subreq = cli_smb_send(state, state->ev, state->cli, cmd, 0,
+	subreq = cli_smb_send(state, state->ev, state->cli, cmd, 0, 0,
 			      2, state->vwv, talloc_get_size(bytes), bytes);
 	if (tevent_req_nomem(subreq, req)) {
 		return;
diff --git a/source3/libsmb/climessage.c b/source3/libsmb/climessage.c
index 34fcc1a..5db0102 100644
--- a/source3/libsmb/climessage.c
+++ b/source3/libsmb/climessage.c
@@ -74,7 +74,7 @@ static struct tevent_req *cli_message_start_send(TALLOC_CTX *mem_ctx,
 	TALLOC_FREE(htmp);
 	TALLOC_FREE(utmp);
 
-	subreq = cli_smb_send(state, ev, cli, SMBsendstrt, 0, 0, NULL,
+	subreq = cli_smb_send(state, ev, cli, SMBsendstrt, 0, 0, 0, NULL,
 			      talloc_get_size(bytes), bytes);
 	if (tevent_req_nomem(subreq, req)) {
 		return tevent_req_post(req, ev);
@@ -175,7 +175,7 @@ static struct tevent_req *cli_message_text_send(TALLOC_CTX *mem_ctx,
 	memcpy(bytes+3, msg, msglen);
 	TALLOC_FREE(tmp);
 
-	subreq = cli_smb_send(state, ev, cli, SMBsendtxt, 0, 1, &state->vwv,
+	subreq = cli_smb_send(state, ev, cli, SMBsendtxt, 0, 0, 1, &state->vwv,
 			      talloc_get_size(bytes), bytes);
 	if (tevent_req_nomem(subreq, req)) {
 		return tevent_req_post(req, ev);
@@ -226,7 +226,7 @@ static struct tevent_req *cli_message_end_send(TALLOC_CTX *mem_ctx,
 
 	SSVAL(&state->vwv, 0, grp);
 
-	subreq = cli_smb_send(state, ev, cli, SMBsendend, 0, 1, &state->vwv,
+	subreq = cli_smb_send(state, ev, cli, SMBsendend, 0, 0, 1, &state->vwv,
 			      0, NULL);
 	if (tevent_req_nomem(subreq, req)) {
 		return tevent_req_post(req, ev);
diff --git a/source3/libsmb/clioplock.c b/source3/libsmb/clioplock.c
index 0b19748..fec40c0 100644
--- a/source3/libsmb/clioplock.c
+++ b/source3/libsmb/clioplock.c
@@ -146,7 +146,7 @@ struct tevent_req *cli_oplock_ack_send(TALLOC_CTX *mem_ctx,
 	SSVAL(state->vwv+6, 0, 0); /* unlockcount */
 	SSVAL(state->vwv+7, 0, 0); /* lockcount */
 
-	subreq = cli_smb_send(state, ev, cli, SMBlockingX, 0, 8, state->vwv,
+	subreq = cli_smb_send(state, ev, cli, SMBlockingX, 0, 0, 8, state->vwv,
 			      0, NULL);
 	if (tevent_req_nomem(subreq, req)) {
 		return tevent_req_post(req, ev);
-- 
2.8.0.rc3.226.g39d4020


From cae25878935c79839c9ce706ddd4599b53be6c6e Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Thu, 18 Aug 2016 12:45:32 -0700
Subject: [PATCH 03/24] s3: libsmb: Add uint16_t addtional_flags2 to
 cli_trans_send().

Not yet used.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=12165

Signed-off-by: Jeremy Allison <jra at samba.org>
---
 source3/libsmb/clifile.c    | 14 ++++++++++++--
 source3/libsmb/clifsinfo.c  |  7 ++++---
 source3/libsmb/clilist.c    |  4 ++--
 source3/libsmb/clisymlink.c |  4 ++--
 source3/libsmb/clitrans.c   |  3 +--
 source3/libsmb/proto.h      |  2 +-
 6 files changed, 22 insertions(+), 12 deletions(-)

diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c
index 54d93a7..21e978e 100644
--- a/source3/libsmb/clifile.c
+++ b/source3/libsmb/clifile.c
@@ -200,6 +200,7 @@ struct tevent_req *cli_setpathinfo_send(TALLOC_CTX *mem_ctx,
 		state,			/* mem ctx. */
 		ev,			/* event ctx. */
 		cli,			/* cli_state. */
+		0,			/* additional_flags2 */
 		SMBtrans2,		/* cmd. */
 		NULL,			/* pipe name. */
 		-1,			/* fid. */
@@ -1809,6 +1810,7 @@ struct tevent_req *cli_nt_delete_on_close_send(TALLOC_CTX *mem_ctx,
 	subreq = cli_trans_send(state,			/* mem ctx. */
 				ev,			/* event ctx. */
 				cli,			/* cli_state. */
+				0,			/* additional_flags2 */
 				SMBtrans2,		/* cmd. */
 				NULL,			/* pipe name. */
 				-1,			/* fid. */
@@ -2253,7 +2255,9 @@ struct tevent_req *cli_nttrans_create_send(TALLOC_CTX *mem_ctx,
 	SIVAL(param, 48, 0x02); /* ImpersonationLevel */
 	SCVAL(param, 52, SecurityFlags);
 
-	subreq = cli_trans_send(state, ev, cli, SMBnttrans,
+	subreq = cli_trans_send(state, ev, cli,
+				0, /* additional_flags2 */
+			 	SMBnttrans,
 				NULL, -1, /* name, fid */
 				NT_TRANSACT_CREATE, 0,
 				NULL, 0, 0, /* setup */
@@ -2860,6 +2864,7 @@ struct tevent_req *cli_ftruncate_send(TALLOC_CTX *mem_ctx,
 	subreq = cli_trans_send(state,			/* mem ctx. */
 				ev,			/* event ctx. */
 				cli,			/* cli_state. */
+				0,			/* additional_flags2 */
 				SMBtrans2,		/* cmd. */
 				NULL,			/* pipe name. */
 				-1,			/* fid. */
@@ -3344,6 +3349,7 @@ static struct tevent_req *cli_posix_lock_internal_send(TALLOC_CTX *mem_ctx,
 	subreq = cli_trans_send(state,                  /* mem ctx. */
 				ev,                     /* event ctx. */
 				cli,                    /* cli_state. */
+				0,			/* additional_flags2 */
 				SMBtrans2,              /* cmd. */
 				NULL,                   /* pipe name. */
 				-1,                     /* fid. */
@@ -5017,6 +5023,7 @@ static struct tevent_req *cli_posix_open_internal_send(TALLOC_CTX *mem_ctx,
 	subreq = cli_trans_send(state,			/* mem ctx. */
 				ev,			/* event ctx. */
 				cli,			/* cli_state. */
+				0,			/* additional_flags2 */
 				SMBtrans2,		/* cmd. */
 				NULL,			/* pipe name. */
 				-1,			/* fid. */
@@ -5372,6 +5379,7 @@ struct tevent_req *cli_notify_send(TALLOC_CTX *mem_ctx,
 		state,			/* mem ctx. */
 		ev,			/* event ctx. */
 		cli,			/* cli_state. */
+		0,			/* additional_flags2 */
 		SMBnttrans,		/* cmd. */
 		NULL,			/* pipe name. */
 		-1,			/* fid. */
@@ -5561,6 +5569,7 @@ struct tevent_req *cli_qpathinfo_send(TALLOC_CTX *mem_ctx,
 		state,			/* mem ctx. */
 		ev,			/* event ctx. */
 		cli,			/* cli_state. */
+		0,			/* additional_flags2 */
 		SMBtrans2,		/* cmd. */
 		NULL,			/* pipe name. */
 		-1,			/* fid. */
@@ -5691,6 +5700,7 @@ struct tevent_req *cli_qfileinfo_send(TALLOC_CTX *mem_ctx,
 		state,			/* mem ctx. */
 		ev,			/* event ctx. */
 		cli,			/* cli_state. */
+		0,			/* additional_flags2 */
 		SMBtrans2,		/* cmd. */
 		NULL,			/* pipe name. */
 		-1,			/* fid. */
@@ -5906,7 +5916,7 @@ struct tevent_req *cli_shadow_copy_data_send(TALLOC_CTX *mem_ctx,
 	SCVAL(state->setup + 3, 1, 0); /* compfilter, isFlags (WSSP) */
 
 	subreq = cli_trans_send(
-		state, ev, cli, SMBnttrans, NULL, 0, NT_TRANSACT_IOCTL, 0,
+		state, ev, cli, 0, SMBnttrans, NULL, 0, NT_TRANSACT_IOCTL, 0,
 		state->setup, ARRAY_SIZE(state->setup), 0,
 		NULL, 0, 0,
 		NULL, 0, ret_size);
diff --git a/source3/libsmb/clifsinfo.c b/source3/libsmb/clifsinfo.c
index 795d12b..ddc9efd 100644
--- a/source3/libsmb/clifsinfo.c
+++ b/source3/libsmb/clifsinfo.c
@@ -61,7 +61,7 @@ struct tevent_req *cli_unix_extensions_version_send(TALLOC_CTX *mem_ctx,
 	SSVAL(state->setup, 0, TRANSACT2_QFSINFO);
 	SSVAL(state->param, 0, SMB_QUERY_CIFS_UNIX_INFO);
 
-	subreq = cli_trans_send(state, ev, cli, SMBtrans2,
+	subreq = cli_trans_send(state, ev, cli, 0, SMBtrans2,
 				NULL, 0, 0, 0,
 				state->setup, 1, 0,
 				state->param, 2, 0,
@@ -198,7 +198,7 @@ struct tevent_req *cli_set_unix_extensions_capabilities_send(
 	SIVAL(state->data, 4, caplow);
 	SIVAL(state->data, 8, caphigh);
 
-	subreq = cli_trans_send(state, ev, cli, SMBtrans2,
+	subreq = cli_trans_send(state, ev, cli, 0, SMBtrans2,
 				NULL, 0, 0, 0,
 				state->setup, 1, 0,
 				state->param, 4, 0,
@@ -284,7 +284,7 @@ struct tevent_req *cli_get_fs_attr_info_send(TALLOC_CTX *mem_ctx,
 	SSVAL(state->setup+0, 0, TRANSACT2_QFSINFO);
 	SSVAL(state->param+0, 0, SMB_QUERY_FS_ATTRIBUTE_INFO);
 
-	subreq = cli_trans_send(state, ev, cli, SMBtrans2,
+	subreq = cli_trans_send(state, ev, cli, 0, SMBtrans2,
 				NULL, 0, 0, 0,
 				state->setup, 1, 0,
 				state->param, 2, 0,
@@ -815,6 +815,7 @@ struct tevent_req *cli_posix_whoami_send(TALLOC_CTX *mem_ctx,
 	subreq = cli_trans_send(state,                  /* mem ctx. */
 				ev,                     /* event ctx. */
 				cli,                    /* cli_state. */
+				0,			/* additional_flags2 */
 				SMBtrans2,              /* cmd. */
 				NULL,                   /* pipe name. */
 				-1,                     /* fid. */
diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c
index 5f9f89e..c563867 100644
--- a/source3/libsmb/clilist.c
+++ b/source3/libsmb/clilist.c
@@ -600,7 +600,7 @@ static struct tevent_req *cli_list_trans_send(TALLOC_CTX *mem_ctx,
 	}
 	param_len = talloc_get_size(state->param);
 
-	subreq = cli_trans_send(state, state->ev, state->cli,
+	subreq = cli_trans_send(state, state->ev, state->cli, 0,
 				SMBtrans2, NULL, -1, 0, 0,
 				state->setup, 1, 0,
 				state->param, param_len, 10,
@@ -785,7 +785,7 @@ static void cli_list_trans_done(struct tevent_req *subreq)
 	}
 	param_len = talloc_get_size(state->param);
 
-	subreq = cli_trans_send(state, state->ev, state->cli,
+	subreq = cli_trans_send(state, state->ev, state->cli, 0,
 				SMBtrans2, NULL, -1, 0, 0,
 				state->setup, 1, 0,
 				state->param, param_len, 10,
diff --git a/source3/libsmb/clisymlink.c b/source3/libsmb/clisymlink.c
index eacae85..496e3e1 100644
--- a/source3/libsmb/clisymlink.c
+++ b/source3/libsmb/clisymlink.c
@@ -108,7 +108,7 @@ static void cli_symlink_create_done(struct tevent_req *subreq)
 		return;
 	}
 
-	subreq = cli_trans_send(state, state->ev, state->cli, SMBnttrans,
+	subreq = cli_trans_send(state, state->ev, state->cli, 0, SMBnttrans,
 				NULL, -1, /* name, fid */
 				NT_TRANSACT_IOCTL, 0,
 				state->setup, 4, 0, /* setup */
@@ -286,7 +286,7 @@ static void cli_readlink_opened(struct tevent_req *subreq)
 	SCVAL(state->setup, 6, 1); /* IsFcntl */
 	SCVAL(state->setup, 7, 0); /* IsFlags */
 
-	subreq = cli_trans_send(state, state->ev, state->cli, SMBnttrans,
+	subreq = cli_trans_send(state, state->ev, state->cli, 0, SMBnttrans,
 				NULL, -1, /* name, fid */
 				NT_TRANSACT_IOCTL, 0,
 				state->setup, 4, 0, /* setup */
diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c
index 5462134..a96d8bf 100644
--- a/source3/libsmb/clitrans.c
+++ b/source3/libsmb/clitrans.c
@@ -50,7 +50,7 @@ static int cli_trans_state_ptr_destructor(struct cli_trans_state **ptr)
 
 struct tevent_req *cli_trans_send(
 	TALLOC_CTX *mem_ctx, struct tevent_context *ev,
-	struct cli_state *cli, uint8_t cmd,
+	struct cli_state *cli, uint16_t additional_flags2, uint8_t cmd,
 	const char *pipe_name, uint16_t fid, uint16_t function, int flags,
 	uint16_t *setup, uint8_t num_setup, uint8_t max_setup,
 	uint8_t *param, uint32_t num_param, uint32_t max_param,
@@ -59,7 +59,6 @@ struct tevent_req *cli_trans_send(
 	struct cli_trans_state *state;
 	uint8_t additional_flags = 0;
 	uint8_t clear_flags = 0;
-	uint16_t additional_flags2 = 0;
 	uint16_t clear_flags2 = 0;
 
 	state = talloc_zero(mem_ctx, struct cli_trans_state);
diff --git a/source3/libsmb/proto.h b/source3/libsmb/proto.h
index c5e74c9..31d9a11 100644
--- a/source3/libsmb/proto.h
+++ b/source3/libsmb/proto.h
@@ -873,7 +873,7 @@ size_t clistr_pull_talloc(TALLOC_CTX *ctx,
 
 struct tevent_req *cli_trans_send(
 	TALLOC_CTX *mem_ctx, struct tevent_context *ev,
-	struct cli_state *cli, uint8_t cmd,
+	struct cli_state *cli, uint16_t additional_flags2, uint8_t cmd,
 	const char *pipe_name, uint16_t fid, uint16_t function, int flags,
 	uint16_t *setup, uint8_t num_setup, uint8_t max_setup,
 	uint8_t *param, uint32_t num_param, uint32_t max_param,
-- 
2.8.0.rc3.226.g39d4020


From 27c473bb2e6f18e24d81515b4ef0558222192321 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Thu, 18 Aug 2016 13:45:35 -0700
Subject: [PATCH 04/24] s3: libsmb: Add uint16_t addtional_flags2 to
 cli_smb_req_create().

Not yet used.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=12165

Signed-off-by: Jeremy Allison <jra at samba.org>
---
 source3/include/async_smb.h   | 1 +
 source3/libsmb/async_smb.c    | 2 +-
 source3/libsmb/cliconnect.c   | 6 +++---
 source3/libsmb/clifile.c      | 6 +++---
 source3/libsmb/clireadwrite.c | 4 ++--
 5 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/source3/include/async_smb.h b/source3/include/async_smb.h
index 6765749..3c64d08 100644
--- a/source3/include/async_smb.h
+++ b/source3/include/async_smb.h
@@ -27,6 +27,7 @@ struct tevent_req *cli_smb_req_create(TALLOC_CTX *mem_ctx,
 				      struct cli_state *cli,
 				      uint8_t smb_command,
 				      uint8_t additional_flags,
+				      uint16_t additional_flags2,
 				      uint8_t wct, uint16_t *vwv,
 				      int iov_count,
 				      struct iovec *bytes_iov);
diff --git a/source3/libsmb/async_smb.c b/source3/libsmb/async_smb.c
index 5d9cce1..bcb24a4 100644
--- a/source3/libsmb/async_smb.c
+++ b/source3/libsmb/async_smb.c
@@ -54,13 +54,13 @@ struct tevent_req *cli_smb_req_create(TALLOC_CTX *mem_ctx,
 				      struct cli_state *cli,
 				      uint8_t smb_command,
 				      uint8_t additional_flags,
+				      uint16_t additional_flags2,
 				      uint8_t wct, uint16_t *vwv,
 				      int iov_count,
 				      struct iovec *bytes_iov)
 {
 	struct cli_smb_req_state *state;
 	uint8_t clear_flags = 0;
-	uint16_t additional_flags2 = 0;
 	uint16_t clear_flags2 = 0;
 
 	state = talloc_zero(mem_ctx, struct cli_smb_req_state);
diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c
index 4635cf8..9c8851f 100644
--- a/source3/libsmb/cliconnect.c
+++ b/source3/libsmb/cliconnect.c
@@ -386,8 +386,8 @@ struct tevent_req *cli_session_setup_guest_create(TALLOC_CTX *mem_ctx,
 	state->bytes.iov_base = (void *)bytes;
 	state->bytes.iov_len = talloc_get_size(bytes);
 
-	subreq = cli_smb_req_create(state, ev, cli, SMBsesssetupX, 0, 13, vwv,
-				    1, &state->bytes);
+	subreq = cli_smb_req_create(state, ev, cli, SMBsesssetupX, 0, 0, 13,
+			vwv, 1, &state->bytes);
 	if (subreq == NULL) {
 		TALLOC_FREE(req);
 		return NULL;
@@ -2549,7 +2549,7 @@ struct tevent_req *cli_tcon_andx_create(TALLOC_CTX *mem_ctx,
 	state->bytes.iov_base = (void *)bytes;
 	state->bytes.iov_len = talloc_get_size(bytes);
 
-	subreq = cli_smb_req_create(state, ev, cli, SMBtconX, 0, 4, vwv,
+	subreq = cli_smb_req_create(state, ev, cli, SMBtconX, 0, 0, 4, vwv,
 				    1, &state->bytes);
 	if (subreq == NULL) {
 		TALLOC_FREE(req);
diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c
index 21e978e..3d0746d 100644
--- a/source3/libsmb/clifile.c
+++ b/source3/libsmb/clifile.c
@@ -2464,7 +2464,7 @@ struct tevent_req *cli_openx_create(TALLOC_CTX *mem_ctx,
 	state->bytes.iov_len = talloc_get_size(bytes);
 
 	subreq = cli_smb_req_create(state, ev, cli, SMBopenX, additional_flags,
-				    15, state->vwv, 1, &state->bytes);
+				    0, 15, state->vwv, 1, &state->bytes);
 	if (subreq == NULL) {
 		TALLOC_FREE(req);
 		return NULL;
@@ -2726,8 +2726,8 @@ struct tevent_req *cli_close_create(TALLOC_CTX *mem_ctx,
 	SSVAL(state->vwv+0, 0, fnum);
 	SIVALS(state->vwv+1, 0, -1);
 
-	subreq = cli_smb_req_create(state, ev, cli, SMBclose, 0, 3, state->vwv,
-				    0, NULL);
+	subreq = cli_smb_req_create(state, ev, cli, SMBclose, 0, 0,
+				3, state->vwv, 0, NULL);
 	if (subreq == NULL) {
 		TALLOC_FREE(req);
 		return NULL;
diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c
index 3514154..1c32d2a 100644
--- a/source3/libsmb/clireadwrite.c
+++ b/source3/libsmb/clireadwrite.c
@@ -162,7 +162,7 @@ struct tevent_req *cli_read_andx_create(TALLOC_CTX *mem_ctx,
 		}
 	}
 
-	subreq = cli_smb_req_create(state, ev, cli, SMBreadX, 0, wct,
+	subreq = cli_smb_req_create(state, ev, cli, SMBreadX, 0, 0, wct,
 				    state->vwv, 0, NULL);
 	if (subreq == NULL) {
 		TALLOC_FREE(req);
@@ -863,7 +863,7 @@ struct tevent_req *cli_write_andx_create(TALLOC_CTX *mem_ctx,
 	state->iov[1].iov_base = discard_const_p(void, buf);
 	state->iov[1].iov_len = state->size;
 
-	subreq = cli_smb_req_create(state, ev, cli, SMBwriteX, 0, wct, vwv,
+	subreq = cli_smb_req_create(state, ev, cli, SMBwriteX, 0, 0, wct, vwv,
 				    2, state->iov);
 	if (tevent_req_nomem(subreq, req)) {
 		return tevent_req_post(req, ev);
-- 
2.8.0.rc3.226.g39d4020


From 84ac94fc658057f7c96c0a4e56804c27d5f63f29 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Thu, 18 Aug 2016 13:06:54 -0700
Subject: [PATCH 05/24] s3: libsmb: Add clistr_is_previous_version_path()

Looks for @GMT- token in pathname.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=12165

Signed-off-by: Jeremy Allison <jra at samba.org>
---
 source3/libsmb/clistr.c | 28 ++++++++++++++++++++++++++++
 source3/libsmb/proto.h  |  1 +
 2 files changed, 29 insertions(+)

diff --git a/source3/libsmb/clistr.c b/source3/libsmb/clistr.c
index f1264f6..c3611be 100644
--- a/source3/libsmb/clistr.c
+++ b/source3/libsmb/clistr.c
@@ -37,3 +37,31 @@ size_t clistr_pull_talloc(TALLOC_CTX *ctx,
 				  src_len,
 				  flags);
 }
+
+bool clistr_is_previous_version_path(const char *path)
+{
+	char *q;
+	time_t timestamp;
+	struct tm tm;
+	const char *p = strstr_m(path, "@GMT-");
+
+	if (p == NULL) {
+		return false;
+	}
+	if (p > path && (p[-1] != '\\')) {
+		return false;
+	}
+	q = strptime(p, GMT_FORMAT, &tm);
+	if (q == NULL) {
+		return false;
+	}
+	tm.tm_isdst = -1;
+	timestamp = timegm(&tm);
+	if (timestamp == (time_t)-1) {
+		return false;
+	}
+	if (q[0] != '\0' && q[0] != '\\') {
+		return false;
+	}
+	return true;
+}
diff --git a/source3/libsmb/proto.h b/source3/libsmb/proto.h
index 31d9a11..f9bb985 100644
--- a/source3/libsmb/proto.h
+++ b/source3/libsmb/proto.h
@@ -868,6 +868,7 @@ size_t clistr_pull_talloc(TALLOC_CTX *ctx,
 			  const void *src,
 			  int src_len,
 			  int flags);
+bool clistr_is_previous_version_path(const char *path);
 
 /* The following definitions come from libsmb/clitrans.c  */
 
-- 
2.8.0.rc3.226.g39d4020


From 3fb5e7255e374ef18cef4b425c19df27788a4c00 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Thu, 18 Aug 2016 13:12:22 -0700
Subject: [PATCH 06/24] s3: libsmb: Plumb in additional_flags2 =
 FLAGS2_REPARSE_PATH to cli_setpathinfo_send().

BUG: https://bugzilla.samba.org/show_bug.cgi?id=12165

Signed-off-by: Jeremy Allison <jra at samba.org>
---
 source3/libsmb/clifile.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c
index 3d0746d..c9f5036d 100644
--- a/source3/libsmb/clifile.c
+++ b/source3/libsmb/clifile.c
@@ -173,6 +173,7 @@ struct tevent_req *cli_setpathinfo_send(TALLOC_CTX *mem_ctx,
 {
 	struct tevent_req *req, *subreq;
 	struct cli_setpathinfo_state *state;
+	uint16_t additional_flags2 = 0;
 
 	req = tevent_req_create(mem_ctx, &state,
 				struct cli_setpathinfo_state);
@@ -196,11 +197,16 @@ struct tevent_req *cli_setpathinfo_send(TALLOC_CTX *mem_ctx,
 		return tevent_req_post(req, ev);
 	}
 
+	if (clistr_is_previous_version_path(path) &&
+			!INFO_LEVEL_IS_UNIX(level)) {
+		additional_flags2 = FLAGS2_REPARSE_PATH;
+	}
+
 	subreq = cli_trans_send(
 		state,			/* mem ctx. */
 		ev,			/* event ctx. */
 		cli,			/* cli_state. */
-		0,			/* additional_flags2 */
+		additional_flags2,	/* additional_flags2 */
 		SMBtrans2,		/* cmd. */
 		NULL,			/* pipe name. */
 		-1,			/* fid. */
-- 
2.8.0.rc3.226.g39d4020


From 9730f37b8994ba2cf651c18cc5214297d5739750 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Thu, 18 Aug 2016 13:17:49 -0700
Subject: [PATCH 07/24] s3: libsmb: Plumb in additional_flags2 =
 FLAGS2_REPARSE_PATH to cli_qpathinfo_send()

BUG: https://bugzilla.samba.org/show_bug.cgi?id=12165

Signed-off-by: Jeremy Allison <jra at samba.org>
---
 source3/libsmb/clifile.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c
index c9f5036d..3bdad2a 100644
--- a/source3/libsmb/clifile.c
+++ b/source3/libsmb/clifile.c
@@ -5552,6 +5552,7 @@ struct tevent_req *cli_qpathinfo_send(TALLOC_CTX *mem_ctx,
 {
 	struct tevent_req *req, *subreq;
 	struct cli_qpathinfo_state *state;
+	uint16_t additional_flags2 = 0;
 
 	req = tevent_req_create(mem_ctx, &state, struct cli_qpathinfo_state);
 	if (req == NULL) {
@@ -5571,11 +5572,16 @@ struct tevent_req *cli_qpathinfo_send(TALLOC_CTX *mem_ctx,
 		return tevent_req_post(req, ev);
 	}
 
+	if (clistr_is_previous_version_path(fname) &&
+			!INFO_LEVEL_IS_UNIX(level)) {
+		additional_flags2 = FLAGS2_REPARSE_PATH;
+	}
+
 	subreq = cli_trans_send(
 		state,			/* mem ctx. */
 		ev,			/* event ctx. */
 		cli,			/* cli_state. */
-		0,			/* additional_flags2 */
+		additional_flags2,	/* additional_flags2 */
 		SMBtrans2,		/* cmd. */
 		NULL,			/* pipe name. */
 		-1,			/* fid. */
-- 
2.8.0.rc3.226.g39d4020


From e196a13430746fedcdab6d8813af2f60ec5d665d Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Thu, 18 Aug 2016 13:26:59 -0700
Subject: [PATCH 08/24] s3: libsmb: s3: libsmb: Plumb in additional_flags2 =
 FLAGS2_REPARSE_PATH to cli_rename_send().

BUG: https://bugzilla.samba.org/show_bug.cgi?id=12165

Signed-off-by: Jeremy Allison <jra at samba.org>
---
 source3/libsmb/clifile.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c
index 3bdad2a..966f6cc 100644
--- a/source3/libsmb/clifile.c
+++ b/source3/libsmb/clifile.c
@@ -1134,6 +1134,7 @@ struct tevent_req *cli_rename_send(TALLOC_CTX *mem_ctx,
 	struct tevent_req *req = NULL, *subreq = NULL;
 	struct cli_rename_state *state = NULL;
 	uint8_t additional_flags = 0;
+	uint16_t additional_flags2 = 0;
 	uint8_t *bytes = NULL;
 
 	req = tevent_req_create(mem_ctx, &state, struct cli_rename_state);
@@ -1154,6 +1155,10 @@ struct tevent_req *cli_rename_send(TALLOC_CTX *mem_ctx,
 		return tevent_req_post(req, ev);
 	}
 
+	if (clistr_is_previous_version_path(fname_src)) {
+		additional_flags2 = FLAGS2_REPARSE_PATH;
+	}
+
 	bytes = talloc_realloc(state, bytes, uint8_t,
 			talloc_get_size(bytes)+1);
 	if (tevent_req_nomem(bytes, req)) {
@@ -1167,8 +1172,9 @@ struct tevent_req *cli_rename_send(TALLOC_CTX *mem_ctx,
 		return tevent_req_post(req, ev);
 	}
 
-	subreq = cli_smb_send(state, ev, cli, SMBmv, additional_flags, 0,
-			      1, state->vwv, talloc_get_size(bytes), bytes);
+	subreq = cli_smb_send(state, ev, cli, SMBmv, additional_flags,
+			additional_flags2,
+			1, state->vwv, talloc_get_size(bytes), bytes);
 	if (tevent_req_nomem(subreq, req)) {
 		return tevent_req_post(req, ev);
 	}
-- 
2.8.0.rc3.226.g39d4020


From de83cba27997ea52561d8305c06eac9513bcd789 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Thu, 18 Aug 2016 13:29:01 -0700
Subject: [PATCH 09/24] s3: libsmb: s3: libsmb: Plumb in additional_flags2 =
 FLAGS2_REPARSE_PATH to cli_ntrename_internal_send().

BUG: https://bugzilla.samba.org/show_bug.cgi?id=12165

Signed-off-by: Jeremy Allison <jra at samba.org>
---
 source3/libsmb/clifile.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c
index 966f6cc..4903873 100644
--- a/source3/libsmb/clifile.c
+++ b/source3/libsmb/clifile.c
@@ -1267,6 +1267,7 @@ static struct tevent_req *cli_ntrename_internal_send(TALLOC_CTX *mem_ctx,
 	struct tevent_req *req = NULL, *subreq = NULL;
 	struct cli_ntrename_internal_state *state = NULL;
 	uint8_t additional_flags = 0;
+	uint16_t additional_flags2 = 0;
 	uint8_t *bytes = NULL;
 
 	req = tevent_req_create(mem_ctx, &state,
@@ -1289,6 +1290,10 @@ static struct tevent_req *cli_ntrename_internal_send(TALLOC_CTX *mem_ctx,
 		return tevent_req_post(req, ev);
 	}
 
+	if (clistr_is_previous_version_path(fname_src)) {
+		additional_flags2 = FLAGS2_REPARSE_PATH;
+	}
+
 	bytes = talloc_realloc(state, bytes, uint8_t,
 			talloc_get_size(bytes)+1);
 	if (tevent_req_nomem(bytes, req)) {
@@ -1302,8 +1307,9 @@ static struct tevent_req *cli_ntrename_internal_send(TALLOC_CTX *mem_ctx,
 		return tevent_req_post(req, ev);
 	}
 
-	subreq = cli_smb_send(state, ev, cli, SMBntrename, additional_flags, 0,
-			      4, state->vwv, talloc_get_size(bytes), bytes);
+	subreq = cli_smb_send(state, ev, cli, SMBntrename, additional_flags,
+			additional_flags2,
+			4, state->vwv, talloc_get_size(bytes), bytes);
 	if (tevent_req_nomem(subreq, req)) {
 		return tevent_req_post(req, ev);
 	}
-- 
2.8.0.rc3.226.g39d4020


From 4b3e80645dd0aab0544033effcc1db951ac4db41 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Thu, 18 Aug 2016 13:32:03 -0700
Subject: [PATCH 10/24] s3: libsmb: s3: libsmb: Plumb in additional_flags2 =
 FLAGS2_REPARSE_PATH to cli_unlink_send().

BUG: https://bugzilla.samba.org/show_bug.cgi?id=12165

Signed-off-by: Jeremy Allison <jra at samba.org>
---
 source3/libsmb/clifile.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c
index 4903873..9d523ed 100644
--- a/source3/libsmb/clifile.c
+++ b/source3/libsmb/clifile.c
@@ -1473,6 +1473,7 @@ struct tevent_req *cli_unlink_send(TALLOC_CTX *mem_ctx,
 	struct tevent_req *req = NULL, *subreq = NULL;
 	struct cli_unlink_state *state = NULL;
 	uint8_t additional_flags = 0;
+	uint16_t additional_flags2 = 0;
 	uint8_t *bytes = NULL;
 
 	req = tevent_req_create(mem_ctx, &state, struct cli_unlink_state);
@@ -1494,7 +1495,12 @@ struct tevent_req *cli_unlink_send(TALLOC_CTX *mem_ctx,
 		return tevent_req_post(req, ev);
 	}
 
-	subreq = cli_smb_send(state, ev, cli, SMBunlink, additional_flags, 0,
+	if (clistr_is_previous_version_path(fname)) {
+		additional_flags2 = FLAGS2_REPARSE_PATH;
+	}
+
+	subreq = cli_smb_send(state, ev, cli, SMBunlink, additional_flags,
+				additional_flags2,
 				1, state->vwv, talloc_get_size(bytes), bytes);
 	if (tevent_req_nomem(subreq, req)) {
 		return tevent_req_post(req, ev);
-- 
2.8.0.rc3.226.g39d4020


From c87c5b50b85f74f1077cd19e53636d5313d5c360 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Thu, 18 Aug 2016 13:33:30 -0700
Subject: [PATCH 11/24] s3: libsmb: s3: libsmb: Plumb in additional_flags2 =
 FLAGS2_REPARSE_PATH to cli_mkdir_send().

BUG: https://bugzilla.samba.org/show_bug.cgi?id=12165

Signed-off-by: Jeremy Allison <jra at samba.org>
---
 source3/libsmb/clifile.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c
index 9d523ed..e8739d7 100644
--- a/source3/libsmb/clifile.c
+++ b/source3/libsmb/clifile.c
@@ -1590,6 +1590,7 @@ struct tevent_req *cli_mkdir_send(TALLOC_CTX *mem_ctx,
 	struct tevent_req *req = NULL, *subreq = NULL;
 	struct cli_mkdir_state *state = NULL;
 	uint8_t additional_flags = 0;
+	uint16_t additional_flags2 = 0;
 	uint8_t *bytes = NULL;
 
 	req = tevent_req_create(mem_ctx, &state, struct cli_mkdir_state);
@@ -1609,8 +1610,13 @@ struct tevent_req *cli_mkdir_send(TALLOC_CTX *mem_ctx,
 		return tevent_req_post(req, ev);
 	}
 
-	subreq = cli_smb_send(state, ev, cli, SMBmkdir, additional_flags, 0,
-			      0, NULL, talloc_get_size(bytes), bytes);
+	if (clistr_is_previous_version_path(dname)) {
+		additional_flags2 = FLAGS2_REPARSE_PATH;
+	}
+
+	subreq = cli_smb_send(state, ev, cli, SMBmkdir, additional_flags,
+			additional_flags2,
+			0, NULL, talloc_get_size(bytes), bytes);
 	if (tevent_req_nomem(subreq, req)) {
 		return tevent_req_post(req, ev);
 	}
-- 
2.8.0.rc3.226.g39d4020


From 236cfacf9e2fa9a4ab0cd094283ea0500444fea5 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Thu, 18 Aug 2016 13:34:44 -0700
Subject: [PATCH 12/24] s3: libsmb: Plumb in additional_flags2 =
 FLAGS2_REPARSE_PATH to cli_rmdir_send()

BUG: https://bugzilla.samba.org/show_bug.cgi?id=12165

Signed-off-by: Jeremy Allison <jra at samba.org>
---
 source3/libsmb/clifile.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c
index e8739d7..56bbcc1 100644
--- a/source3/libsmb/clifile.c
+++ b/source3/libsmb/clifile.c
@@ -1705,6 +1705,7 @@ struct tevent_req *cli_rmdir_send(TALLOC_CTX *mem_ctx,
 	struct tevent_req *req = NULL, *subreq = NULL;
 	struct cli_rmdir_state *state = NULL;
 	uint8_t additional_flags = 0;
+	uint16_t additional_flags2 = 0;
 	uint8_t *bytes = NULL;
 
 	req = tevent_req_create(mem_ctx, &state, struct cli_rmdir_state);
@@ -1724,8 +1725,13 @@ struct tevent_req *cli_rmdir_send(TALLOC_CTX *mem_ctx,
 		return tevent_req_post(req, ev);
 	}
 
-	subreq = cli_smb_send(state, ev, cli, SMBrmdir, additional_flags, 0,
-			      0, NULL, talloc_get_size(bytes), bytes);
+	if (clistr_is_previous_version_path(dname)) {
+		additional_flags2 = FLAGS2_REPARSE_PATH;
+	}
+
+	subreq = cli_smb_send(state, ev, cli, SMBrmdir, additional_flags,
+			additional_flags2,
+			0, NULL, talloc_get_size(bytes), bytes);
 	if (tevent_req_nomem(subreq, req)) {
 		return tevent_req_post(req, ev);
 	}
-- 
2.8.0.rc3.226.g39d4020


From 402a15fde12199c2c16a484cec01e41b08e3b796 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Thu, 18 Aug 2016 13:37:22 -0700
Subject: [PATCH 13/24] s3: libsmb: Plumb in additional_flags2 =
 FLAGS2_REPARSE_PATH to cli_ntcreate1_send().

BUG: https://bugzilla.samba.org/show_bug.cgi?id=12165

Signed-off-by: Jeremy Allison <jra at samba.org>
---
 source3/libsmb/clifile.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c
index 56bbcc1..22b0763 100644
--- a/source3/libsmb/clifile.c
+++ b/source3/libsmb/clifile.c
@@ -1943,6 +1943,7 @@ static struct tevent_req *cli_ntcreate1_send(TALLOC_CTX *mem_ctx,
 	uint16_t *vwv;
 	uint8_t *bytes;
 	size_t converted_len;
+	uint16_t additional_flags2 = 0;
 
 	req = tevent_req_create(mem_ctx, &state, struct cli_ntcreate1_state);
 	if (req == NULL) {
@@ -1977,6 +1978,10 @@ static struct tevent_req *cli_ntcreate1_send(TALLOC_CTX *mem_ctx,
 				   fname, strlen(fname)+1,
 				   &converted_len);
 
+	if (clistr_is_previous_version_path(fname)) {
+		additional_flags2 = FLAGS2_REPARSE_PATH;
+	}
+
 	/* sigh. this copes with broken netapp filer behaviour */
 	bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "", 1, NULL);
 
@@ -1986,8 +1991,9 @@ static struct tevent_req *cli_ntcreate1_send(TALLOC_CTX *mem_ctx,
 
 	SSVAL(vwv+2, 1, converted_len);
 
-	subreq = cli_smb_send(state, ev, cli, SMBntcreateX, 0, 0, 24, vwv,
-			      talloc_get_size(bytes), bytes);
+	subreq = cli_smb_send(state, ev, cli, SMBntcreateX, 0,
+			additional_flags2, 24, vwv,
+			talloc_get_size(bytes), bytes);
 	if (tevent_req_nomem(subreq, req)) {
 		return tevent_req_post(req, ev);
 	}
-- 
2.8.0.rc3.226.g39d4020


From 39b7e9101e8d3b143ed2f0a9fc33213f44f3b86d Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Thu, 18 Aug 2016 13:40:23 -0700
Subject: [PATCH 14/24] s3: libsmb: Plumb in additional_flags2 =
 FLAGS2_REPARSE_PATH to cli_nttrans_create_send().

BUG: https://bugzilla.samba.org/show_bug.cgi?id=12165

Signed-off-by: Jeremy Allison <jra at samba.org>
---
 source3/libsmb/clifile.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c
index 22b0763..f76bf22 100644
--- a/source3/libsmb/clifile.c
+++ b/source3/libsmb/clifile.c
@@ -2241,6 +2241,7 @@ struct tevent_req *cli_nttrans_create_send(TALLOC_CTX *mem_ctx,
 	size_t secdesc_len;
 	NTSTATUS status;
 	size_t converted_len;
+	uint16_t additional_flags2 = 0;
 
 	req = tevent_req_create(mem_ctx,
 				&state, struct cli_nttrans_create_state);
@@ -2281,6 +2282,10 @@ struct tevent_req *cli_nttrans_create_send(TALLOC_CTX *mem_ctx,
 		return tevent_req_post(req, ev);
 	}
 
+	if (clistr_is_previous_version_path(fname)) {
+		additional_flags2 = FLAGS2_REPARSE_PATH;
+	}
+
 	SIVAL(param, 0, CreatFlags);
 	SIVAL(param, 4, 0x0);	/* RootDirectoryFid */
 	SIVAL(param, 8, DesiredAccess);
@@ -2298,7 +2303,7 @@ struct tevent_req *cli_nttrans_create_send(TALLOC_CTX *mem_ctx,
 	SCVAL(param, 52, SecurityFlags);
 
 	subreq = cli_trans_send(state, ev, cli,
-				0, /* additional_flags2 */
+				additional_flags2, /* additional_flags2 */
 			 	SMBnttrans,
 				NULL, -1, /* name, fid */
 				NT_TRANSACT_CREATE, 0,
-- 
2.8.0.rc3.226.g39d4020


From 4437b6ddaa443c0f6e5547280906ba8c3d756847 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Thu, 18 Aug 2016 13:59:52 -0700
Subject: [PATCH 15/24] s3: libsmb: Plumb in additional_flags2 =
 FLAGS2_REPARSE_PATH to cli_openx_create().

BUG: https://bugzilla.samba.org/show_bug.cgi?id=12165

Signed-off-by: Jeremy Allison <jra at samba.org>
---
 source3/libsmb/clifile.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c
index f76bf22..cef5120 100644
--- a/source3/libsmb/clifile.c
+++ b/source3/libsmb/clifile.c
@@ -2440,6 +2440,7 @@ struct tevent_req *cli_openx_create(TALLOC_CTX *mem_ctx,
 	unsigned openfn;
 	unsigned accessmode;
 	uint8_t additional_flags;
+	uint16_t additional_flags2 = 0;
 	uint8_t *bytes;
 
 	req = tevent_req_create(mem_ctx, &state, struct cli_openx_state);
@@ -2507,11 +2508,15 @@ struct tevent_req *cli_openx_create(TALLOC_CTX *mem_ctx,
 		return tevent_req_post(req, ev);
 	}
 
+	if (clistr_is_previous_version_path(fname)) {
+		additional_flags2 = FLAGS2_REPARSE_PATH;
+	}
+
 	state->bytes.iov_base = (void *)bytes;
 	state->bytes.iov_len = talloc_get_size(bytes);
 
 	subreq = cli_smb_req_create(state, ev, cli, SMBopenX, additional_flags,
-				    0, 15, state->vwv, 1, &state->bytes);
+			additional_flags2, 15, state->vwv, 1, &state->bytes);
 	if (subreq == NULL) {
 		TALLOC_FREE(req);
 		return NULL;
-- 
2.8.0.rc3.226.g39d4020


From 6b86903ec9bc9fce2aa2908c51213aa39cfe3b88 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Thu, 18 Aug 2016 14:02:24 -0700
Subject: [PATCH 16/24] s3: libsmb: Plumb in additional_flags2 =
 FLAGS2_REPARSE_PATH to cli_getatr_send().

BUG: https://bugzilla.samba.org/show_bug.cgi?id=12165

Signed-off-by: Jeremy Allison <jra at samba.org>
---
 source3/libsmb/clifile.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c
index cef5120..a92262b 100644
--- a/source3/libsmb/clifile.c
+++ b/source3/libsmb/clifile.c
@@ -3743,6 +3743,7 @@ struct tevent_req *cli_getatr_send(TALLOC_CTX *mem_ctx,
 	struct tevent_req *req = NULL, *subreq = NULL;
 	struct cli_getatr_state *state = NULL;
 	uint8_t additional_flags = 0;
+	uint16_t additional_flags2 = 0;
 	uint8_t *bytes = NULL;
 
 	req = tevent_req_create(mem_ctx, &state, struct cli_getatr_state);
@@ -3764,8 +3765,13 @@ struct tevent_req *cli_getatr_send(TALLOC_CTX *mem_ctx,
 		return tevent_req_post(req, ev);
 	}
 
-	subreq = cli_smb_send(state, ev, cli, SMBgetatr, additional_flags, 0,
-			      0, NULL, talloc_get_size(bytes), bytes);
+	if (clistr_is_previous_version_path(fname)) {
+		additional_flags2 = FLAGS2_REPARSE_PATH;
+	}
+
+	subreq = cli_smb_send(state, ev, cli, SMBgetatr, additional_flags,
+			additional_flags2,
+			0, NULL, talloc_get_size(bytes), bytes);
 	if (tevent_req_nomem(subreq, req)) {
 		return tevent_req_post(req, ev);
 	}
-- 
2.8.0.rc3.226.g39d4020


From 54d455ae83b334f3e70f99bfff2026fbd5bd42b7 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Thu, 18 Aug 2016 14:04:05 -0700
Subject: [PATCH 17/24] s3: libsmb: Plumb in additional_flags2 =
 FLAGS2_REPARSE_PATH to cli_setatr_send().

BUG: https://bugzilla.samba.org/show_bug.cgi?id=12165

Signed-off-by: Jeremy Allison <jra at samba.org>
---
 source3/libsmb/clifile.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c
index a92262b..26aabad 100644
--- a/source3/libsmb/clifile.c
+++ b/source3/libsmb/clifile.c
@@ -4023,6 +4023,7 @@ struct tevent_req *cli_setatr_send(TALLOC_CTX *mem_ctx,
 	struct tevent_req *req = NULL, *subreq = NULL;
 	struct cli_setatr_state *state = NULL;
 	uint8_t additional_flags = 0;
+	uint16_t additional_flags2 = 0;
 	uint8_t *bytes = NULL;
 
 	req = tevent_req_create(mem_ctx, &state, struct cli_setatr_state);
@@ -4056,8 +4057,13 @@ struct tevent_req *cli_setatr_send(TALLOC_CTX *mem_ctx,
 		return tevent_req_post(req, ev);
 	}
 
-	subreq = cli_smb_send(state, ev, cli, SMBsetatr, additional_flags, 0,
-			      8, state->vwv, talloc_get_size(bytes), bytes);
+	if (clistr_is_previous_version_path(fname)) {
+		additional_flags2 = FLAGS2_REPARSE_PATH;
+	}
+
+	subreq = cli_smb_send(state, ev, cli, SMBsetatr, additional_flags,
+			additional_flags2,
+			8, state->vwv, talloc_get_size(bytes), bytes);
 	if (tevent_req_nomem(subreq, req)) {
 		return tevent_req_post(req, ev);
 	}
-- 
2.8.0.rc3.226.g39d4020


From b83354a480d72fbe1b8cff51b20548c86acbae3a Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Thu, 18 Aug 2016 14:05:33 -0700
Subject: [PATCH 18/24] s3: libsmb: Plumb in additional_flags2 =
 FLAGS2_REPARSE_PATH to cli_chkpath_send().

BUG: https://bugzilla.samba.org/show_bug.cgi?id=12165

Signed-off-by: Jeremy Allison <jra at samba.org>
---
 source3/libsmb/clifile.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c
index 26aabad..8bfec1e 100644
--- a/source3/libsmb/clifile.c
+++ b/source3/libsmb/clifile.c
@@ -4158,6 +4158,7 @@ struct tevent_req *cli_chkpath_send(TALLOC_CTX *mem_ctx,
 	struct tevent_req *req = NULL, *subreq = NULL;
 	struct cli_chkpath_state *state = NULL;
 	uint8_t additional_flags = 0;
+	uint16_t additional_flags2 = 0;
 	uint8_t *bytes = NULL;
 
 	req = tevent_req_create(mem_ctx, &state, struct cli_chkpath_state);
@@ -4177,8 +4178,13 @@ struct tevent_req *cli_chkpath_send(TALLOC_CTX *mem_ctx,
 		return tevent_req_post(req, ev);
 	}
 
-	subreq = cli_smb_send(state, ev, cli, SMBcheckpath, additional_flags, 0,
-			      0, NULL, talloc_get_size(bytes), bytes);
+	if (clistr_is_previous_version_path(fname)) {
+		additional_flags2 = FLAGS2_REPARSE_PATH;
+	}
+
+	subreq = cli_smb_send(state, ev, cli, SMBcheckpath, additional_flags,
+			additional_flags2,
+			0, NULL, talloc_get_size(bytes), bytes);
 	if (tevent_req_nomem(subreq, req)) {
 		return tevent_req_post(req, ev);
 	}
-- 
2.8.0.rc3.226.g39d4020


From b55a2695b13cae375d95172a68d14508aef97ee2 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Thu, 18 Aug 2016 14:07:17 -0700
Subject: [PATCH 19/24] s3: libsmb: Plumb in additional_flags2 =
 FLAGS2_REPARSE_PATH to cli_ctemp_send().

BUG: https://bugzilla.samba.org/show_bug.cgi?id=12165

Signed-off-by: Jeremy Allison <jra at samba.org>
---
 source3/libsmb/clifile.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c
index 8bfec1e..696aaed 100644
--- a/source3/libsmb/clifile.c
+++ b/source3/libsmb/clifile.c
@@ -4467,6 +4467,7 @@ struct tevent_req *cli_ctemp_send(TALLOC_CTX *mem_ctx,
 	struct tevent_req *req = NULL, *subreq = NULL;
 	struct ctemp_state *state = NULL;
 	uint8_t additional_flags = 0;
+	uint16_t additional_flags2 = 0;
 	uint8_t *bytes = NULL;
 
 	req = tevent_req_create(mem_ctx, &state, struct ctemp_state);
@@ -4488,8 +4489,13 @@ struct tevent_req *cli_ctemp_send(TALLOC_CTX *mem_ctx,
 		return tevent_req_post(req, ev);
 	}
 
-	subreq = cli_smb_send(state, ev, cli, SMBctemp, additional_flags, 0,
-			      3, state->vwv, talloc_get_size(bytes), bytes);
+	if (clistr_is_previous_version_path(path)) {
+		additional_flags2 = FLAGS2_REPARSE_PATH;
+	}
+
+	subreq = cli_smb_send(state, ev, cli, SMBctemp, additional_flags,
+			additional_flags2,
+			3, state->vwv, talloc_get_size(bytes), bytes);
 	if (tevent_req_nomem(subreq, req)) {
 		return tevent_req_post(req, ev);
 	}
-- 
2.8.0.rc3.226.g39d4020


From 16156c64cd70e33756d083cb9388270bea320963 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Thu, 18 Aug 2016 14:20:11 -0700
Subject: [PATCH 20/24] s3: libsmb: Make a comment note that cli_set_ea() needs
 some internal changes before cli_set_ea_path() can use previous path
 versions.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=12165

Signed-off-by: Jeremy Allison <jra at samba.org>
---
 source3/libsmb/clifile.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c
index 696aaed..fea1af9 100644
--- a/source3/libsmb/clifile.c
+++ b/source3/libsmb/clifile.c
@@ -4672,6 +4672,15 @@ static NTSTATUS cli_set_ea(struct cli_state *cli, uint16_t setup_val,
 		memcpy(p+4+ea_namelen+1, ea_val, ea_len);
 	}
 
+	/*
+	 * FIXME - if we want to do previous version path
+	 * processing on an EA set call we need to turn this
+	 * into calls to cli_trans_send()/cli_trans_recv()
+	 * with a temporary event context, as cli_trans_send()
+	 * have access to the additional_flags2 needed to
+	 * send @GMT- paths. JRA.
+	 */
+
 	status = cli_trans(talloc_tos(), cli, SMBtrans2, NULL, -1, 0, 0,
 			   setup, 1, 0,
 			   param, param_len, 2,
-- 
2.8.0.rc3.226.g39d4020


From f835a55292d52c2194aa1d5b0581d861dceac2df Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Thu, 18 Aug 2016 14:26:20 -0700
Subject: [PATCH 21/24] s3: libsmb: Plumb in additional_flags2 =
 FLAGS2_REPARSE_PATH to cli_list_trans_send().

BUG: https://bugzilla.samba.org/show_bug.cgi?id=12165

Signed-off-by: Jeremy Allison <jra at samba.org>
---
 source3/libsmb/clilist.c | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c
index c563867..d6116f0 100644
--- a/source3/libsmb/clilist.c
+++ b/source3/libsmb/clilist.c
@@ -557,6 +557,7 @@ static struct tevent_req *cli_list_trans_send(TALLOC_CTX *mem_ctx,
 	struct tevent_req *req, *subreq;
 	struct cli_list_trans_state *state;
 	size_t param_len;
+	uint16_t additional_flags2 = 0;
 
 	req = tevent_req_create(mem_ctx, &state,
 				struct cli_list_trans_state);
@@ -598,9 +599,14 @@ static struct tevent_req *cli_list_trans_send(TALLOC_CTX *mem_ctx,
 	if (tevent_req_nomem(state->param, req)) {
 		return tevent_req_post(req, ev);
 	}
+
+	if (clistr_is_previous_version_path(state->mask)) {
+		additional_flags2 = FLAGS2_REPARSE_PATH;
+	}
+
 	param_len = talloc_get_size(state->param);
 
-	subreq = cli_trans_send(state, state->ev, state->cli, 0,
+	subreq = cli_trans_send(state, state->ev, state->cli, additional_flags2,
 				SMBtrans2, NULL, -1, 0, 0,
 				state->setup, 1, 0,
 				state->param, param_len, 10,
@@ -636,6 +642,7 @@ static void cli_list_trans_done(struct tevent_req *subreq)
 	DATA_BLOB last_name_raw;
 	struct file_info *finfo = NULL;
 	size_t param_len;
+	uint16_t additional_flags2 = 0;
 
 	min_param = (state->first ? 6 : 4);
 
@@ -785,7 +792,11 @@ static void cli_list_trans_done(struct tevent_req *subreq)
 	}
 	param_len = talloc_get_size(state->param);
 
-	subreq = cli_trans_send(state, state->ev, state->cli, 0,
+	if (clistr_is_previous_version_path(state->mask)) {
+		additional_flags2 = FLAGS2_REPARSE_PATH;
+	}
+
+	subreq = cli_trans_send(state, state->ev, state->cli, additional_flags2,
 				SMBtrans2, NULL, -1, 0, 0,
 				state->setup, 1, 0,
 				state->param, param_len, 10,
-- 
2.8.0.rc3.226.g39d4020


From 421945bca534cb98a6f605a161620ac6f1993bc1 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Thu, 18 Aug 2016 14:33:01 -0700
Subject: [PATCH 22/24] s3: libsmb: Correctly set max_setup_size in
 FSCTL_GET_SHADOW_COPY_DATA nttrans ioctl.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=12165

Signed-off-by: Jeremy Allison <jra at samba.org>
---
 source3/libsmb/clifile.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c
index fea1af9..9c3357e 100644
--- a/source3/libsmb/clifile.c
+++ b/source3/libsmb/clifile.c
@@ -6008,7 +6008,8 @@ struct tevent_req *cli_shadow_copy_data_send(TALLOC_CTX *mem_ctx,
 
 	subreq = cli_trans_send(
 		state, ev, cli, 0, SMBnttrans, NULL, 0, NT_TRANSACT_IOCTL, 0,
-		state->setup, ARRAY_SIZE(state->setup), 0,
+		state->setup, ARRAY_SIZE(state->setup),
+		ARRAY_SIZE(state->setup),
 		NULL, 0, 0,
 		NULL, 0, ret_size);
 	if (tevent_req_nomem(subreq, req)) {
-- 
2.8.0.rc3.226.g39d4020


From 356d9ce19290544ef716822cf5c6400ded8d70f0 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Thu, 18 Aug 2016 12:06:23 -0700
Subject: [PATCH 23/24] s3: libsmb: Do some hardening in the receive processing
 of cli_shadow_copy_data_recv().

Protect against malicious servers.

Signed-off-by: Jeremy Allison <jra at samba.org>
---
 source3/libsmb/clifile.c | 35 ++++++++++++++++++++++++++++++-----
 1 file changed, 30 insertions(+), 5 deletions(-)

diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c
index 9c3357e..5c25c95 100644
--- a/source3/libsmb/clifile.c
+++ b/source3/libsmb/clifile.c
@@ -6043,36 +6043,61 @@ NTSTATUS cli_shadow_copy_data_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
 {
 	struct cli_shadow_copy_data_state *state = tevent_req_data(
 		req, struct cli_shadow_copy_data_state);
-	char **names;
-	int i, num_names;
+	char **names = NULL;
+	uint32_t i, num_names;
 	uint32_t dlength;
+	uint8_t *endp = NULL;
 	NTSTATUS status;
 
 	if (tevent_req_is_nterror(req, &status)) {
 		return status;
 	}
+
+	if (state->num_data < 16) {
+		return NT_STATUS_INVALID_NETWORK_RESPONSE;
+	}
+
 	num_names = IVAL(state->data, 4);
 	dlength = IVAL(state->data, 8);
 
+	if (num_names > 0x7FFFFFFF) {
+		return NT_STATUS_INVALID_NETWORK_RESPONSE;
+	}
+
 	if (!state->get_names) {
-		*pnum_names = num_names;
+		*pnum_names = (int)num_names;
 		return NT_STATUS_OK;
 	}
 
-	if (dlength+12 > state->num_data) {
+	if (dlength + 12 < 12) {
+		return NT_STATUS_INVALID_NETWORK_RESPONSE;
+	}
+	if (dlength + 12 > state->num_data) {
 		return NT_STATUS_INVALID_NETWORK_RESPONSE;
 	}
+	if (state->num_data + (2 * sizeof(SHADOW_COPY_LABEL)) <
+			state->num_data) {
+		return NT_STATUS_INVALID_NETWORK_RESPONSE;
+	}
+
 	names = talloc_array(mem_ctx, char *, num_names);
 	if (names == NULL) {
 		return NT_STATUS_NO_MEMORY;
 	}
 
+	endp = state->data + state->num_data;
+
 	for (i=0; i<num_names; i++) {
 		bool ret;
 		uint8_t *src;
 		size_t converted_size;
 
 		src = state->data + 12 + i * 2 * sizeof(SHADOW_COPY_LABEL);
+
+		if (src + (2 * sizeof(SHADOW_COPY_LABEL)) > endp) {
+			return NT_STATUS_INVALID_NETWORK_RESPONSE;
+		}
+
 		ret = convert_string_talloc(
 			names, CH_UTF16LE, CH_UNIX,
 			src, 2 * sizeof(SHADOW_COPY_LABEL),
@@ -6082,7 +6107,7 @@ NTSTATUS cli_shadow_copy_data_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
 			return NT_STATUS_INVALID_NETWORK_RESPONSE;
 		}
 	}
-	*pnum_names = num_names;
+	*pnum_names = (int)num_names;
 	*pnames = names;
 	return NT_STATUS_OK;
 }
-- 
2.8.0.rc3.226.g39d4020


From 537fbc1d04f67e94e0e4b83cb1d97f3672d0bd96 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Thu, 18 Aug 2016 14:36:50 -0700
Subject: [PATCH 24/24] s3: smbclient: In order to get shadow copy data over
 SMB1 we must call cli_shadow_copy_data() twice.

Once with 'get_names = false' to get the size, then again with 'get_names = true'
to get the data or a Windows server fails to return valid info. Samba doesn't have this bug.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=12165

Signed-off-by: Jeremy Allison <jra at samba.org>
---
 source3/client/client.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/source3/client/client.c b/source3/client/client.c
index 45dc11c..7fbfdf0 100644
--- a/source3/client/client.c
+++ b/source3/client/client.c
@@ -1782,6 +1782,20 @@ static int do_allinfo(const char *name)
 		 */
 		return 0;
 	}
+	/*
+	 * In order to get shadow copy data over SMB1 we
+	 * must call twice, once with 'get_names = false'
+	 * to get the size, then again with 'get_names = true'
+	 * to get the data or a Windows server fails to return
+	 * valid info. Samba doesn't have this bug. JRA.
+	 */
+
+	status = cli_shadow_copy_data(talloc_tos(), cli, fnum,
+				      false, &snapshots, &num_snapshots);
+	if (!NT_STATUS_IS_OK(status)) {
+		cli_close(cli, fnum);
+		return 0;
+	}
 	status = cli_shadow_copy_data(talloc_tos(), cli, fnum,
 				      true, &snapshots, &num_snapshots);
 	if (!NT_STATUS_IS_OK(status)) {
-- 
2.8.0.rc3.226.g39d4020



More information about the samba-technical mailing list