Work on SMB3 persistent handles

Michael Adam obnox at samba.org
Mon Oct 23 22:58:11 UTC 2017


On 2017-10-23 at 13:17 -0500, Christopher R. Hertel wrote:
> Michael:  Thanks for calling my attention to this thread.
> 
> You wrote:
> > Maybe, if appropriate, someone could summarize the latest
> > state of the discussions/design/prototyping...
> 
> I can summarize my own status:
> 
> * I have done the work necessary to negotiate Persistent Handle support in
> the Session Setup.  Similarly, I have added per-share configuration to
> support Continuous Availability in the Tree Connect.  Both of these
> additions work nicely.
> 
> * Internally to Samba, I have added fields and flags that identify a share
> as being CA, and a file handle as being Persistent.
> 
> Those are basic steps needed to negotiate Continuous Availability on the
> wire, and to signal internally that CA is in use.
> 
> In theory, given the way that Durable Handle data is stored, we *should* be
> able to pass Persistent Handle tests in this configuration.  As long as the
> Samba node that owns the handle does not actually go down (that is, as long
> as the test is performed by dropping the network connection), the data
> should be maintained and we should be able to re-establish the Persistent
> Handle.
> 
> I'm not quite there yet.  I am not yet sending back the correct blob
> following the recovery.  This *should* be an easy fix.

Since we've been talking about this a bit now, I've revived the
patches that Metze and I had in our WIP branches since 2012, have
rebased them on top of current master and made them work again.
It's mainly the protocol boilerplate code. I.e. there is no
persistence of the DBs or records, also the subtleties of how
persistent handles are different from durable handles in semantic
are not all covered yet, in particular no calling of
SMB_VFS_DURABLE_DISCONNECT() under other circumstances than
before, but for a start it does survive our (smbtorture's)
durable-v2-open test (against nt4_dc) including the persistent
open tests. Nothing fancy yet but just for comparing.

https://git.samba.org/?p=obnox/samba/samba-obnox.git;a=shortlog;h=refs/heads/persistent-wip

Also attached for convenience.

Cheers - Michael




> Once that all works, the next step is to actually make the handle data
> persistent.  My first attempt at doing this was to modify the Open calls on
> four [C]TDB databases that store the handle state.  Doing so *should* have
> made the data persistent, but instead it caused Samba to crash with the
> stack trace showing errors generated in libtevent.
> 
> As Michael mentioned, my hope is that we can expose the calls that are
> needed to store and retrieve the Durable/Persistent handle data in such a
> way that individual vendors (like VMware) can leverage their own product's
> features.
> 
> So... That's an introduction.  Let me know if there are questions I can answer.
> 
> Chris -)-----
> 
> On 10/20/2017 07:46 AM, Michael Adam wrote:
> > Hi all,
> > 
> > recently, the topic of implementing SMB3 persistent handles
> > in Samba has been taking on some traction again. Mainly
> > driven by Chris Hertel. We need to make sure that we have
> > a general purpose implementation that works on any file system,
> > but we should also make sure to offer hooks that allow
> > special file systems in the back-end to expose some features
> > of making handle info persistent. It was originally Chris who
> > raised this requirement.
> > 
> > Now I have recently talked to the nice folks from vmware
> > (copied in this mail) who are very interested in implementing
> > persistent handles in Samba with a similar file-system support,
> > and would like to get involved in the development process.
> > 
> > Hence we though I'd start this thread in the open so that we
> > can align our efforts and hopefully come up with a good set
> > of changes that are generic enough to satisfy the various
> > backend storage solutions. So I copied samba-technical
> > as well as explicitly the Samba people who have recently been
> > looking into persistent handles most actively. (Apologies
> > if I forgot anyone..)
> > So Chris, Ralph, Metze, samba folks, meet Rick, Wenguang,
> > Albert, and Satish.
> > 
> > Maybe, if appropriate, someone could summarize the latest
> > state of the discussions/design/prototyping...
> > 
> > Cheers - Michael
> 
-------------- next part --------------
From 4fbc11e5bb3c5620616d6d1ede1e0ebf227b8201 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Sat, 30 Jun 2012 12:31:28 +0200
Subject: [PATCH 1/9] TODO smbXsrv_open_global idl: add persistent

MAYBE squash with "smbXsrv_open_global idl: add more SMB 2.10/3.00 stuff TODO: more"
---
 source3/librpc/idl/smbXsrv.idl | 1 +
 1 file changed, 1 insertion(+)

diff --git a/source3/librpc/idl/smbXsrv.idl b/source3/librpc/idl/smbXsrv.idl
index 1bfa51ea912..36b1e8dcff1 100644
--- a/source3/librpc/idl/smbXsrv.idl
+++ b/source3/librpc/idl/smbXsrv.idl
@@ -429,6 +429,7 @@ interface smbXsrv
 		NTTIME					disconnect_time;
 		uint32					durable_timeout_msec;
 		boolean8				durable;
+		boolean8				persistent;
 		DATA_BLOB				backend_cookie;
 		hyper					channel_sequence;
 	} smbXsrv_open_global0;
-- 
2.13.6


From 1bfc532cf01754412c72120e6ee94e249d929a35 Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Fri, 15 Jun 2012 13:39:36 +0200
Subject: [PATCH 2/9] TODO: s3:smbd:SMB3: add basic support for persistent
 handles in smb2_create code. (default: no)

add "smbd:persistent handles" option (default: false)

TODO: pass to vfs layer

Pair-Programmed-With: Stefan Metzmacher <metze at samba.org>
---
 source3/smbd/smb2_create.c | 37 +++++++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/source3/smbd/smb2_create.c b/source3/smbd/smb2_create.c
index c4fe2477bad..47638dcb462 100644
--- a/source3/smbd/smb2_create.c
+++ b/source3/smbd/smb2_create.c
@@ -676,6 +676,11 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
 #if 0
 		struct smb2_create_blob *svhdx = NULL;
 #endif
+		bool persistent_requested = false;
+		bool persistent_support = lp_parm_bool(SNUM(smb1req->conn),
+						       "smbd",
+						       "persistent handles",
+						       false);
 
 		exta = smb2_create_blob_find(&in_context_blobs,
 					     SMB2_CREATE_TAG_EXTA);
@@ -788,6 +793,7 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
 		if (dh2q) {
 			const uint8_t *p = dh2q->data.data;
 			uint32_t durable_v2_timeout = 0;
+			uint32_t dh2q_flags;
 			DATA_BLOB create_guid_blob;
 			const uint8_t *hdr;
 			uint32_t flags;
@@ -803,6 +809,7 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
 			}
 
 			durable_v2_timeout = IVAL(p, 0);
+			dh2q_flags = IVAL(p, 4);
 			create_guid_blob = data_blob_const(p + 16, 16);
 
 			status = GUID_from_ndr_blob(&create_guid_blob,
@@ -836,6 +843,10 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
 				durable_timeout_msec = (60*1000);
 			}
 
+			if (dh2q_flags & SMB2_DHANDLE_FLAG_PERSISTENT) {
+				persistent_requested = true;
+			}
+
 			/*
 			 * Check for replay operation.
 			 * Only consider it when we have dh2q.
@@ -878,9 +889,11 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
 		if (dh2c) {
 			const uint8_t *p = dh2c->data.data;
 			DATA_BLOB create_guid_blob;
+			uint32_t dh2c_flags;
 
 			persistent_id = BVAL(p, 0);
 			create_guid_blob = data_blob_const(p + 16, 16);
+			dh2c_flags = SVAL(p, 32);
 
 			status = GUID_from_ndr_blob(&create_guid_blob,
 						    &_create_guid);
@@ -889,6 +902,18 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
 			}
 			create_guid = &_create_guid;
 
+			if (dh2c_flags & SMB2_DHANDLE_FLAG_PERSISTENT) {
+				persistent_requested = true;
+			}
+
+			/*
+			 * TODO: can it happen that the persistent flag
+			 * in the reconnect is different from the original open?
+			 *
+			 * check
+			 * op->global->persistent == persistent_requested;
+			 */
+
 			do_durable_reconnect = true;
 		}
 
@@ -1227,6 +1252,7 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
 		if (!replay_operation && durable_requested &&
 		    (fsp_lease_type(result) & SMB2_LEASE_HANDLE))
 		{
+			//TODO pass resilient/persistent flags
 			status = SMB_VFS_DURABLE_COOKIE(result,
 						op,
 						&op->global->backend_cookie);
@@ -1240,6 +1266,13 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
 
 			op->global->durable = true;
 			op->global->durable_timeout_msec = durable_timeout_msec;
+
+			if (persistent_support) {
+				//TODO let the backend decide
+				op->global->persistent = persistent_requested;
+			} else {
+				op->global->persistent = false;
+			}
 		}
 
 		if (update_open) {
@@ -1288,6 +1321,10 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
 			DATA_BLOB blob = data_blob_const(p, sizeof(p));
 			uint32_t durable_v2_response_flags = 0;
 
+			if (op->global->persistent) {
+				durable_v2_response_flags |= SMB2_DHANDLE_FLAG_PERSISTENT;
+			}
+
 			SIVAL(p, 0, op->global->durable_timeout_msec);
 			SIVAL(p, 4, durable_v2_response_flags);
 
-- 
2.13.6


From 46835bd4af3508d60628c163655097acf835489a Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 26 Jul 2012 02:49:16 +0200
Subject: [PATCH 3/9] TODO: s3:smb2_negprot: announce persistent handle support
 (default: no)

add "smbd:announce persistent handles" option (default: false)

metze
---
 source3/smbd/smb2_negprot.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/source3/smbd/smb2_negprot.c b/source3/smbd/smb2_negprot.c
index d9ccdbeea8e..45e0896a0c7 100644
--- a/source3/smbd/smb2_negprot.c
+++ b/source3/smbd/smb2_negprot.c
@@ -520,6 +520,14 @@ NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req)
 		}
 	}
 
+	if (protocol >= PROTOCOL_SMB2_22 &&
+	    lp_parm_bool(-1, "smbd", "announce persistent handles", false))
+	{
+		if (in_capabilities & SMB2_CAP_PERSISTENT_HANDLES) {
+			capabilities |= SMB2_CAP_PERSISTENT_HANDLES;
+		}
+	}
+
 	security_offset = SMB2_HDR_BODY + 0x40;
 
 #if 1
-- 
2.13.6


From 3780690e83757222363e593634b21ff0ab6859fe Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Tue, 31 Jul 2012 08:55:20 +0200
Subject: [PATCH 4/9] TODO smb2_tcon: add some share flags/capabilities options
 (Default:off)

---
 source3/smbd/smb2_tcon.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/source3/smbd/smb2_tcon.c b/source3/smbd/smb2_tcon.c
index 914eb87aa8c..cff014dbac1 100644
--- a/source3/smbd/smb2_tcon.c
+++ b/source3/smbd/smb2_tcon.c
@@ -378,6 +378,28 @@ static NTSTATUS smbd_smb2_tree_connect(struct smbd_smb2_request *req,
 		*out_share_flags |= SMB2_SHAREFLAG_ENCRYPT_DATA;
 	}
 
+	if (lp_parm_bool(SNUM(tcon->compat), "smbd", "announce branch cache v1", false)) {
+		*out_share_flags |= SMB2_SHAREFLAG_ENABLE_HASH_V1;
+	}
+	if (lp_parm_bool(SNUM(tcon->compat), "smbd", "announce branch cache v2", false)) {
+		*out_share_flags |= SMB2_SHAREFLAG_ENABLE_HASH_V2;
+	}
+	if (conn->protocol >= PROTOCOL_SMB2_22 &&
+	    lp_parm_bool(SNUM(tcon->compat), "smbd", "announce CA", false))
+	{
+		*out_capabilities |= SMB2_SHARE_CAP_CONTINUOUS_AVAILABILITY;
+	}
+	if (conn->protocol >= PROTOCOL_SMB2_22 &&
+	    lp_parm_bool(SNUM(tcon->compat), "smbd", "announce SO", false))
+	{
+		*out_capabilities |= SMB2_SHARE_CAP_SCALEOUT;
+	}
+	if (conn->protocol >= PROTOCOL_SMB2_22 &&
+	    lp_parm_bool(SNUM(tcon->compat), "smbd", "announce CLUSTER", false))
+	{
+		*out_capabilities |= SMB2_SHARE_CAP_CLUSTER;
+	}
+
 	*out_maximal_access = tcon->compat->share_access;
 
 	*out_tree_id = tcon->global->tcon_wire_id;
-- 
2.13.6


From 0ee687c56692c1cfcb146de97b08fc1cbc705720 Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Mon, 23 Oct 2017 23:51:01 +0200
Subject: [PATCH 5/9] TODO: selftest: enable CA/persistent in s3-selftest

Signed-off-by: Michael Adam <obnox at samba.org>
---
 selftest/target/Samba3.pm | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm
index f4d033d0c7a..87ccdd3d12a 100755
--- a/selftest/target/Samba3.pm
+++ b/selftest/target/Samba3.pm
@@ -1724,6 +1724,10 @@ sub provision($$$$$$$$$)
 
 	read only = no
 
+	smbd:announce persistent handles = yes
+	smbd:persistent handles = yes
+	smbd:announce CA = yes
+
 	smbd:sharedelay = 100000
 	smbd:writetimeupdatedelay = 500000
 	map hidden = no
-- 
2.13.6


From 4254fd6de5d5a4dc53bf251e226339caafd834ed Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Tue, 24 Oct 2017 00:35:46 +0200
Subject: [PATCH 6/9] TODO: smbd:smb2: grant a persistent open without a batch
 oplock.

persistent handles on CA (+scaleout) shares are granted
without the request for batch oplocks (or handle leases).

Signed-off-by: Michael Adam <obnox at samba.org>
---
 source3/smbd/smb2_create.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/source3/smbd/smb2_create.c b/source3/smbd/smb2_create.c
index 47638dcb462..0edd6d2059e 100644
--- a/source3/smbd/smb2_create.c
+++ b/source3/smbd/smb2_create.c
@@ -1249,8 +1249,10 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
 			}
 		}
 
-		if (!replay_operation && durable_requested &&
-		    (fsp_lease_type(result) & SMB2_LEASE_HANDLE))
+		if (!replay_operation &&
+		    (persistent_requested ||
+		     (durable_requested &&
+		      (fsp_lease_type(result) & SMB2_LEASE_HANDLE))))
 		{
 			//TODO pass resilient/persistent flags
 			status = SMB_VFS_DURABLE_COOKIE(result,
-- 
2.13.6


From 5d9638f88c6d0a0e51127368dca7a5d3949678f7 Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Tue, 24 Oct 2017 00:38:48 +0200
Subject: [PATCH 7/9] TODO: smbd:smb2: ignore the durable v2 timeout when
 persistent is not requested

This is according to [MS-SMB2], 3.3.5.9.10.

Signed-off-by: Michael Adam <obnox at samba.org>
---
 source3/smbd/smb2_create.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/source3/smbd/smb2_create.c b/source3/smbd/smb2_create.c
index 0edd6d2059e..c26448dc0ca 100644
--- a/source3/smbd/smb2_create.c
+++ b/source3/smbd/smb2_create.c
@@ -833,7 +833,7 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
 			 * durable handle v2 request processed below
 			 */
 			durable_requested = true;
-			durable_timeout_msec = durable_v2_timeout;
+
 			if (durable_timeout_msec == 0) {
 				/*
 				 * Set the timeout to 1 min as default.
-- 
2.13.6


From 4f642313f7b1d72831bf82647a8e6e7204777b0e Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Tue, 24 Oct 2017 00:23:23 +0200
Subject: [PATCH 8/9] TODO: fix durable-v2-test for timout (ignored for
 non-persistent open..)

---
 source4/torture/smb2/durable_v2_open.c | 21 +++++++++++----------
 1 file changed, 11 insertions(+), 10 deletions(-)

diff --git a/source4/torture/smb2/durable_v2_open.c b/source4/torture/smb2/durable_v2_open.c
index 3a0e0707d2c..3516f02844e 100644
--- a/source4/torture/smb2/durable_v2_open.c
+++ b/source4/torture/smb2/durable_v2_open.c
@@ -124,7 +124,8 @@ bool test_durable_v2_open_create_blob(struct torture_context *tctx,
 	CHECK_VAL(io.out.durable_open, false);
 	CHECK_VAL(io.out.durable_open_v2, true);
 	CHECK_VAL(io.out.persistent_open, false);
-	CHECK_VAL(io.out.timeout, io.in.timeout);
+	/* timeout is ignored for non-persistent handles */
+	CHECK_VAL(io.out.timeout, 0xea60);
 
 	/* disconnect */
 	TALLOC_FREE(tree);
@@ -548,7 +549,7 @@ bool test_durable_v2_open_reopen1(struct torture_context *tctx,
 	CHECK_VAL(io.out.durable_open, false);
 	CHECK_VAL(io.out.durable_open_v2, true);
 	CHECK_VAL(io.out.persistent_open, false);
-	CHECK_VAL(io.out.timeout, io.in.timeout);
+	CHECK_VAL(io.out.timeout, 0xea60);
 
 	/* try a durable reconnect while the file is still open */
 	ZERO_STRUCT(io);
@@ -624,7 +625,7 @@ bool test_durable_v2_open_reopen1a(struct torture_context *tctx,
 	CHECK_VAL(io.out.durable_open, false);
 	CHECK_VAL(io.out.durable_open_v2, true);
 	CHECK_VAL(io.out.persistent_open, false);
-	CHECK_VAL(io.out.timeout, io.in.timeout);
+	CHECK_VAL(io.out.timeout, 0xea60);
 
 	/*
 	 * a session reconnect on a second tcp connection
@@ -796,7 +797,7 @@ bool test_durable_v2_open_reopen1a_lease(struct torture_context *tctx,
 	CHECK_VAL(io.out.durable_open, false);
 	CHECK_VAL(io.out.durable_open_v2, true);
 	CHECK_VAL(io.out.persistent_open, false);
-	CHECK_VAL(io.out.timeout, io.in.timeout);
+	CHECK_VAL(io.out.timeout, 0xea60);
 	CHECK_VAL(io.out.oplock_level, SMB2_OPLOCK_LEVEL_LEASE);
 	CHECK_VAL(io.out.lease_response.lease_key.data[0], lease_key);
 	CHECK_VAL(io.out.lease_response.lease_key.data[1], ~lease_key);
@@ -962,7 +963,7 @@ bool test_durable_v2_open_reopen2(struct torture_context *tctx,
 	CHECK_VAL(io.out.durable_open, false);
 	CHECK_VAL(io.out.durable_open_v2, true);
 	CHECK_VAL(io.out.persistent_open, false);
-	CHECK_VAL(io.out.timeout, io.in.timeout);
+	CHECK_VAL(io.out.timeout, 0xea60);
 
 	/* disconnect, leaving the durable open */
 	TALLOC_FREE(tree);
@@ -1123,7 +1124,7 @@ bool test_durable_v2_open_reopen2b(struct torture_context *tctx,
 	CHECK_VAL(io.out.durable_open, false);
 	CHECK_VAL(io.out.durable_open_v2, true);
 	CHECK_VAL(io.out.persistent_open, false);
-	CHECK_VAL(io.out.timeout, io.in.timeout);
+	CHECK_VAL(io.out.timeout, 0xea60);
 
 	/* disconnect, leaving the durable open */
 	TALLOC_FREE(tree);
@@ -1295,7 +1296,7 @@ bool test_durable_v2_open_reopen2_lease(struct torture_context *tctx,
 	CHECK_VAL(io.out.durable_open, false);
 	CHECK_VAL(io.out.durable_open_v2, true);
 	CHECK_VAL(io.out.persistent_open, false);
-	CHECK_VAL(io.out.timeout, io.in.timeout);
+	CHECK_VAL(io.out.timeout, 0xea60);
 	CHECK_VAL(io.out.oplock_level, SMB2_OPLOCK_LEVEL_LEASE);
 	CHECK_VAL(io.out.lease_response.lease_key.data[0], lease_key);
 	CHECK_VAL(io.out.lease_response.lease_key.data[1], ~lease_key);
@@ -1542,7 +1543,7 @@ bool test_durable_v2_open_reopen2_lease_v2(struct torture_context *tctx,
 	CHECK_VAL(io.out.durable_open, false);
 	CHECK_VAL(io.out.durable_open_v2, true);
 	CHECK_VAL(io.out.persistent_open, false);
-	CHECK_VAL(io.out.timeout, io.in.timeout);
+	CHECK_VAL(io.out.timeout, 0xea60);
 	CHECK_VAL(io.out.oplock_level, SMB2_OPLOCK_LEVEL_LEASE);
 	CHECK_VAL(io.out.lease_response_v2.lease_key.data[0], lease_key);
 	CHECK_VAL(io.out.lease_response_v2.lease_key.data[1], ~lease_key);
@@ -1781,7 +1782,7 @@ bool test_durable_v2_open_app_instance(struct torture_context *tctx,
 	CHECK_VAL(io1.out.durable_open, false);
 	CHECK_VAL(io1.out.durable_open_v2, true);
 	CHECK_VAL(io1.out.persistent_open, false);
-	CHECK_VAL(io1.out.timeout, io1.in.timeout);
+	CHECK_VAL(io1.out.timeout, 0xea60);
 
 	/*
 	 * try to open the file as durable from a second tree with
@@ -1808,7 +1809,7 @@ bool test_durable_v2_open_app_instance(struct torture_context *tctx,
 	CHECK_VAL(io2.out.durable_open, false);
 	CHECK_VAL(io2.out.durable_open_v2, true);
 	CHECK_VAL(io2.out.persistent_open, false);
-	CHECK_VAL(io2.out.timeout, io2.in.timeout);
+	CHECK_VAL(io2.out.timeout, 0xea60);
 
 	CHECK_VAL(break_info.count, 0);
 
-- 
2.13.6


From 14000ba073e65f8c4c1f869cba24abd5309496fa Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Tue, 24 Oct 2017 00:39:38 +0200
Subject: [PATCH 9/9] TODO: smbd:smb2: honour the durable v2 timeout when
 persistent is requested

Signed-off-by: Michael Adam <obnox at samba.org>
---
 source3/smbd/smb2_create.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/source3/smbd/smb2_create.c b/source3/smbd/smb2_create.c
index c26448dc0ca..f42fe7751e3 100644
--- a/source3/smbd/smb2_create.c
+++ b/source3/smbd/smb2_create.c
@@ -834,6 +834,9 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
 			 */
 			durable_requested = true;
 
+			if (persistent_requested) {
+				durable_timeout_msec = durable_v2_timeout;
+			}
 			if (durable_timeout_msec == 0) {
 				/*
 				 * Set the timeout to 1 min as default.
-- 
2.13.6

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 163 bytes
Desc: not available
URL: <http://lists.samba.org/pipermail/samba-technical/attachments/20171024/17a1a614/signature.sig>


More information about the samba-technical mailing list