[PATCHES] to smb2.durable[-v2]-open tests
Jeremy Allison
jra at samba.org
Mon Mar 21 22:17:32 UTC 2016
On Thu, Mar 17, 2016 at 03:01:17AM +0100, Michael Adam wrote:
> ENOPATCH...
>
> On 2016-03-17 at 02:58 +0100, Michael Adam wrote:
> > Hi!
> >
> > Attached find a patchset that improves the
> > durable-[v2-]open.reopen1a tests and then
> > adds variants of these using leases,
> > durable-[v2-]open.reopen1a-lease.
> >
> > The speciality with leases is, that in contrast
> > to oplocks, the client_guid is checked upon
> > reconnect. This is the additional aspect that
> > these new tests verify. The improvement of the
> > original (oplock) reopen1a tests also proves
> > that for the oplock case, the client_guid is
> > irrelevant.
> >
> > Note: The reopen1a-lease tests were the ones that
> > had me provoke the smbd crash due to use-after-free
> > a patch for which I sent earlier.
> >
> > Review appreciated!
> >
> > Thanks - Michael
LGTM - pushed !
> From 5ea7b1c3f1994dd0154e61efb38aed228f7184b9 Mon Sep 17 00:00:00 2001
> From: Michael Adam <obnox at samba.org>
> Date: Tue, 15 Mar 2016 09:35:03 +0100
> Subject: [PATCH 01/10] torture:smb2: use assert, not warning in error case in
> durable-open.reopen1a
>
> Signed-off-by: Michael Adam <obnox at samba.org>
> ---
> source4/torture/smb2/durable_open.c | 10 +++-------
> 1 file changed, 3 insertions(+), 7 deletions(-)
>
> diff --git a/source4/torture/smb2/durable_open.c b/source4/torture/smb2/durable_open.c
> index fe0a326..11388ef 100644
> --- a/source4/torture/smb2/durable_open.c
> +++ b/source4/torture/smb2/durable_open.c
> @@ -464,13 +464,9 @@ static bool test_durable_open_reopen1a(struct torture_context *tctx,
>
> previous_session_id = smb2cli_session_current_id(tree->session->smbXcli);
>
> - if (!torture_smb2_connection_ext(tctx, previous_session_id,
> - &options, &tree2))
> - {
> - torture_warning(tctx, "couldn't reconnect, bailing\n");
> - ret = false;
> - goto done;
> - }
> + ret = torture_smb2_connection_ext(tctx, previous_session_id,
> + &options, &tree2);
> + torture_assert_goto(tctx, ret, ret, done, "could not reconnect");
>
> /*
> * check that this has deleted the old session
> --
> 2.5.0
>
>
> From cffa315509468b4b48e79e59cede1f7b6df231ec Mon Sep 17 00:00:00 2001
> From: Michael Adam <obnox at samba.org>
> Date: Fri, 4 Mar 2016 22:55:40 +0100
> Subject: [PATCH 02/10] torture:smb2: fix crashes in smb2.durable-open.reopen1a
> test
>
> If the test failed too early, we dereferenced tree2 which
> was still NULL.
>
> Signed-off-by: Michael Adam <obnox at samba.org>
> ---
> source4/torture/smb2/durable_open.c | 18 ++++++++++++------
> 1 file changed, 12 insertions(+), 6 deletions(-)
>
> diff --git a/source4/torture/smb2/durable_open.c b/source4/torture/smb2/durable_open.c
> index 11388ef..e8a82c0 100644
> --- a/source4/torture/smb2/durable_open.c
> +++ b/source4/torture/smb2/durable_open.c
> @@ -479,6 +479,8 @@ static bool test_durable_open_reopen1a(struct torture_context *tctx,
> status = smb2_create(tree, mem_ctx, &io2);
> CHECK_STATUS(status, NT_STATUS_USER_SESSION_DELETED);
>
> + TALLOC_FREE(tree);
> +
> /*
> * but a durable reconnect on the new session succeeds:
> */
> @@ -495,15 +497,19 @@ static bool test_durable_open_reopen1a(struct torture_context *tctx,
> h = &_h;
>
> done:
> - if (h != NULL) {
> - smb2_util_close(tree2, *h);
> + if (tree == NULL) {
> + tree = tree2;
> }
>
> - smb2_util_unlink(tree2, fname);
> -
> - talloc_free(tree2);
> + if (tree != NULL) {
> + if (h != NULL) {
> + smb2_util_close(tree, *h);
> + h = NULL;
> + }
> + smb2_util_unlink(tree, fname);
>
> - talloc_free(tree);
> + talloc_free(tree);
> + }
>
> talloc_free(mem_ctx);
>
> --
> 2.5.0
>
>
> From 5d1a534782c7a91425e06dfa292b6eabedd3192b Mon Sep 17 00:00:00 2001
> From: Michael Adam <obnox at samba.org>
> Date: Thu, 17 Mar 2016 02:45:16 +0100
> Subject: [PATCH 03/10] torture:smb2: durable-open.reopen1a only needs one io
> struct
>
> Using two is confusing.
>
> Signed-off-by: Michael Adam <obnox at samba.org>
> ---
> source4/torture/smb2/durable_open.c | 38 ++++++++++++++++++-------------------
> 1 file changed, 19 insertions(+), 19 deletions(-)
>
> diff --git a/source4/torture/smb2/durable_open.c b/source4/torture/smb2/durable_open.c
> index e8a82c0..584f046 100644
> --- a/source4/torture/smb2/durable_open.c
> +++ b/source4/torture/smb2/durable_open.c
> @@ -431,7 +431,7 @@ static bool test_durable_open_reopen1a(struct torture_context *tctx,
> char fname[256];
> struct smb2_handle _h;
> struct smb2_handle *h = NULL;
> - struct smb2_create io1, io2;
> + struct smb2_create io;
> bool ret = true;
> struct smb2_tree *tree2 = NULL;
> uint64_t previous_session_id;
> @@ -445,18 +445,18 @@ static bool test_durable_open_reopen1a(struct torture_context *tctx,
>
> smb2_util_unlink(tree, fname);
>
> - smb2_oplock_create_share(&io1, fname,
> + smb2_oplock_create_share(&io, fname,
> smb2_util_share_access(""),
> smb2_util_oplock_level("b"));
> - io1.in.durable_open = true;
> + io.in.durable_open = true;
>
> - status = smb2_create(tree, mem_ctx, &io1);
> + status = smb2_create(tree, mem_ctx, &io);
> CHECK_STATUS(status, NT_STATUS_OK);
> - _h = io1.out.file.handle;
> + _h = io.out.file.handle;
> h = &_h;
> - CHECK_CREATED(&io1, CREATED, FILE_ATTRIBUTE_ARCHIVE);
> - CHECK_VAL(io1.out.durable_open, true);
> - CHECK_VAL(io1.out.oplock_level, smb2_util_oplock_level("b"));
> + CHECK_CREATED(&io, CREATED, FILE_ATTRIBUTE_ARCHIVE);
> + CHECK_VAL(io.out.durable_open, true);
> + CHECK_VAL(io.out.oplock_level, smb2_util_oplock_level("b"));
>
> /*
> * a session reconnect on a second tcp connection
> @@ -472,11 +472,11 @@ static bool test_durable_open_reopen1a(struct torture_context *tctx,
> * check that this has deleted the old session
> */
>
> - ZERO_STRUCT(io2);
> - io2.in.fname = fname;
> - io2.in.durable_handle = h;
> + ZERO_STRUCT(io);
> + io.in.fname = fname;
> + io.in.durable_handle = h;
>
> - status = smb2_create(tree, mem_ctx, &io2);
> + status = smb2_create(tree, mem_ctx, &io);
> CHECK_STATUS(status, NT_STATUS_USER_SESSION_DELETED);
>
> TALLOC_FREE(tree);
> @@ -485,15 +485,15 @@ static bool test_durable_open_reopen1a(struct torture_context *tctx,
> * but a durable reconnect on the new session succeeds:
> */
>
> - ZERO_STRUCT(io2);
> - io2.in.fname = fname;
> - io2.in.durable_handle = h;
> + ZERO_STRUCT(io);
> + io.in.fname = fname;
> + io.in.durable_handle = h;
>
> - status = smb2_create(tree2, mem_ctx, &io2);
> + status = smb2_create(tree2, mem_ctx, &io);
> CHECK_STATUS(status, NT_STATUS_OK);
> - CHECK_CREATED(&io2, EXISTED, FILE_ATTRIBUTE_ARCHIVE);
> - CHECK_VAL(io2.out.oplock_level, smb2_util_oplock_level("b"));
> - _h = io2.out.file.handle;
> + CHECK_CREATED(&io, EXISTED, FILE_ATTRIBUTE_ARCHIVE);
> + CHECK_VAL(io.out.oplock_level, smb2_util_oplock_level("b"));
> + _h = io.out.file.handle;
> h = &_h;
>
> done:
> --
> 2.5.0
>
>
> From 0c5b17916f7da0d90b2f6b40b449f0247b781f80 Mon Sep 17 00:00:00 2001
> From: Michael Adam <obnox at samba.org>
> Date: Tue, 15 Mar 2016 08:59:53 +0100
> Subject: [PATCH 04/10] torture:smb2: for oplocks, durable reconnect works with
> different client guid
>
> in durabble-open.reopen1a test
>
> Try both original and a different client guid.
>
> Signed-off-by: Michael Adam <obnox at samba.org>
> ---
> source4/torture/smb2/durable_open.c | 51 +++++++++++++++++++++++++++++++++++++
> 1 file changed, 51 insertions(+)
>
> diff --git a/source4/torture/smb2/durable_open.c b/source4/torture/smb2/durable_open.c
> index 584f046..b74b5c5 100644
> --- a/source4/torture/smb2/durable_open.c
> +++ b/source4/torture/smb2/durable_open.c
> @@ -434,10 +434,13 @@ static bool test_durable_open_reopen1a(struct torture_context *tctx,
> struct smb2_create io;
> bool ret = true;
> struct smb2_tree *tree2 = NULL;
> + struct smb2_tree *tree3 = NULL;
> uint64_t previous_session_id;
> struct smbcli_options options;
> + struct GUID orig_client_guid;
>
> options = tree->session->transport->options;
> + orig_client_guid = options.client_guid;
>
> /* Choose a random name in case the state is left a little funky. */
> snprintf(fname, 256, "durable_open_reopen1a_%s.dat",
> @@ -464,6 +467,9 @@ static bool test_durable_open_reopen1a(struct torture_context *tctx,
>
> previous_session_id = smb2cli_session_current_id(tree->session->smbXcli);
>
> + /* for oplocks, the client guid can be different: */
> + options.client_guid = GUID_random();
> +
> ret = torture_smb2_connection_ext(tctx, previous_session_id,
> &options, &tree2);
> torture_assert_goto(tctx, ret, ret, done, "could not reconnect");
> @@ -496,11 +502,56 @@ static bool test_durable_open_reopen1a(struct torture_context *tctx,
> _h = io.out.file.handle;
> h = &_h;
>
> + /*
> + * a session reconnect on a second tcp connection
> + */
> +
> + previous_session_id = smb2cli_session_current_id(tree2->session->smbXcli);
> +
> + /* the original client_guid works just the same */
> + options.client_guid = orig_client_guid;
> +
> + ret = torture_smb2_connection_ext(tctx, previous_session_id,
> + &options, &tree3);
> + torture_assert_goto(tctx, ret, ret, done, "could not reconnect");
> +
> + /*
> + * check that this has deleted the old session
> + */
> +
> + ZERO_STRUCT(io);
> + io.in.fname = fname;
> + io.in.durable_handle = h;
> +
> + status = smb2_create(tree2, mem_ctx, &io);
> + CHECK_STATUS(status, NT_STATUS_USER_SESSION_DELETED);
> +
> + TALLOC_FREE(tree2);
> +
> + /*
> + * but a durable reconnect on the new session succeeds:
> + */
> +
> + ZERO_STRUCT(io);
> + io.in.fname = fname;
> + io.in.durable_handle = h;
> +
> + status = smb2_create(tree3, mem_ctx, &io);
> + CHECK_STATUS(status, NT_STATUS_OK);
> + CHECK_CREATED(&io, EXISTED, FILE_ATTRIBUTE_ARCHIVE);
> + CHECK_VAL(io.out.oplock_level, smb2_util_oplock_level("b"));
> + _h = io.out.file.handle;
> + h = &_h;
> +
> done:
> if (tree == NULL) {
> tree = tree2;
> }
>
> + if (tree == NULL) {
> + tree = tree3;
> + }
> +
> if (tree != NULL) {
> if (h != NULL) {
> smb2_util_close(tree, *h);
> --
> 2.5.0
>
>
> From 77f668434c5522255e361ee8852956a253e336fc Mon Sep 17 00:00:00 2001
> From: Michael Adam <obnox at samba.org>
> Date: Tue, 15 Mar 2016 10:02:14 +0100
> Subject: [PATCH 05/10] torture:smb2: add durable-open.reopen1a-lease
>
> Lease variant of the reopen1a test which tests the
> relevance of the client guid.
>
> Signed-off-by: Michael Adam <obnox at samba.org>
> ---
> selftest/knownfail | 1 +
> source4/torture/smb2/durable_open.c | 170 ++++++++++++++++++++++++++++++++++++
> 2 files changed, 171 insertions(+)
>
> diff --git a/selftest/knownfail b/selftest/knownfail
> index c15d263..8f2f139 100644
> --- a/selftest/knownfail
> +++ b/selftest/knownfail
> @@ -193,6 +193,7 @@
> ^samba3.smb2.notify.rec
> ^samba3.smb2.durable-open.delete_on_close2
> ^samba3.smb2.durable-v2-open.app-instance
> +^samba3.smb2.durable-open.reopen1a-lease\(ad_dc\)$
> ^samba4.smb2.ioctl.req_resume_key\(ad_dc_ntvfs\) # not supported by s4 ntvfs server
> ^samba4.smb2.ioctl.copy_chunk_\w*\(ad_dc_ntvfs\) # not supported by s4 ntvfs server
> ^samba3.smb2.dir.one
> diff --git a/source4/torture/smb2/durable_open.c b/source4/torture/smb2/durable_open.c
> index b74b5c5..7b59566 100644
> --- a/source4/torture/smb2/durable_open.c
> +++ b/source4/torture/smb2/durable_open.c
> @@ -568,6 +568,175 @@ done:
> }
>
> /**
> + * lease variant of reopen1a
> + *
> + * Basic test for doing a durable open and doing a session
> + * reconnect while the first session is still active and the
> + * handle is still open in the client.
> + * This closes the original session and a durable reconnect on
> + * the new session succeeds depending on the client guid:
> + *
> + * Durable reconnect on a session with a different client guid fails.
> + * Durable reconnect on a session with the original client guid succeeds.
> + */
> +bool test_durable_open_reopen1a_lease(struct torture_context *tctx,
> + struct smb2_tree *tree)
> +{
> + NTSTATUS status;
> + TALLOC_CTX *mem_ctx = talloc_new(tctx);
> + char fname[256];
> + struct smb2_handle _h;
> + struct smb2_handle *h = NULL;
> + struct smb2_create io;
> + struct smb2_lease ls;
> + uint64_t lease_key;
> + bool ret = true;
> + struct smb2_tree *tree2 = NULL;
> + struct smb2_tree *tree3 = NULL;
> + uint64_t previous_session_id;
> + struct smbcli_options options;
> + struct GUID orig_client_guid;
> +
> + options = tree->session->transport->options;
> + orig_client_guid = options.client_guid;
> +
> + /* Choose a random name in case the state is left a little funky. */
> + snprintf(fname, 256, "durable_v2_open_reopen1a_lease_%s.dat",
> + generate_random_str(tctx, 8));
> +
> + smb2_util_unlink(tree, fname);
> +
> + lease_key = random();
> + smb2_lease_create(&io, &ls, false /* dir */, fname,
> + lease_key, smb2_util_lease_state("RWH"));
> + io.in.durable_open = true;
> +
> + status = smb2_create(tree, mem_ctx, &io);
> + CHECK_STATUS(status, NT_STATUS_OK);
> + _h = io.out.file.handle;
> + h = &_h;
> + CHECK_CREATED(&io, CREATED, FILE_ATTRIBUTE_ARCHIVE);
> + CHECK_VAL(io.out.durable_open, true);
> + 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);
> + CHECK_VAL(io.out.lease_response.lease_state,
> + smb2_util_lease_state("RWH"));
> + CHECK_VAL(io.out.lease_response.lease_flags, 0);
> + CHECK_VAL(io.out.lease_response.lease_duration, 0);
> +
> + previous_session_id = smb2cli_session_current_id(tree->session->smbXcli);
> +
> + /*
> + * a session reconnect on a second tcp connection
> + * with a different client_guid does not allow
> + * the durable reconnect.
> + */
> +
> + options.client_guid = GUID_random();
> +
> + ret = torture_smb2_connection_ext(tctx, previous_session_id,
> + &options, &tree2);
> + torture_assert_goto(tctx, ret, ret, done, "couldn't reconnect");
> +
> + /*
> + * check that this has deleted the old session
> + */
> +
> + ZERO_STRUCT(io);
> + io.in.fname = fname;
> + io.in.durable_handle = h;
> + io.in.lease_request = &ls;
> + status = smb2_create(tree, mem_ctx, &io);
> + CHECK_STATUS(status, NT_STATUS_USER_SESSION_DELETED);
> + TALLOC_FREE(tree);
> +
> +
> + /*
> + * but a durable reconnect on the new session with the wrong
> + * client guid fails
> + */
> +
> + ZERO_STRUCT(io);
> + io.in.fname = fname;
> + io.in.durable_handle = h;
> + io.in.lease_request = &ls;
> + status = smb2_create(tree2, mem_ctx, &io);
> + CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
> +
> + /*
> + * now a session reconnect on a second tcp connection
> + * with original client_guid allows the durable reconnect.
> + */
> +
> + options.client_guid = orig_client_guid;
> +
> + ret = torture_smb2_connection_ext(tctx, previous_session_id,
> + &options, &tree3);
> + torture_assert_goto(tctx, ret, ret, done, "couldn't reconnect");
> +
> + /*
> + * check that this has deleted the old session
> + * In this case, a durable reconnect attempt with the
> + * correct client_guid yields a different error code.
> + */
> +
> + ZERO_STRUCT(io);
> + io.in.fname = fname;
> + io.in.durable_handle = h;
> + io.in.lease_request = &ls;
> + status = smb2_create(tree2, mem_ctx, &io);
> + CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
> + TALLOC_FREE(tree2);
> +
> + /*
> + * but a durable reconnect on the new session succeeds:
> + */
> +
> + ZERO_STRUCT(io);
> + io.in.fname = fname;
> + io.in.durable_handle = h;
> + io.in.lease_request = &ls;
> + status = smb2_create(tree3, mem_ctx, &io);
> + CHECK_STATUS(status, NT_STATUS_OK);
> + CHECK_CREATED(&io, EXISTED, FILE_ATTRIBUTE_ARCHIVE);
> + CHECK_VAL(io.out.durable_open, false); /* no dh response context... */
> + 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);
> + CHECK_VAL(io.out.lease_response.lease_state,
> + smb2_util_lease_state("RWH"));
> + CHECK_VAL(io.out.lease_response.lease_flags, 0);
> + CHECK_VAL(io.out.lease_response.lease_duration, 0);
> + _h = io.out.file.handle;
> + h = &_h;
> +
> +done:
> + if (tree == NULL) {
> + tree = tree2;
> + }
> +
> + if (tree == NULL) {
> + tree = tree3;
> + }
> +
> + if (tree != NULL) {
> + if (h != NULL) {
> + smb2_util_close(tree, *h);
> + }
> +
> + smb2_util_unlink(tree, fname);
> +
> + talloc_free(tree);
> + }
> +
> + talloc_free(mem_ctx);
> +
> + return ret;
> +}
> +
> +
> +/**
> * basic test for doing a durable open
> * tcp disconnect, reconnect, do a durable reopen (succeeds)
> */
> @@ -2589,6 +2758,7 @@ struct torture_suite *torture_smb2_durable_open_init(void)
> torture_suite_add_1smb2_test(suite, "open-lease", test_durable_open_open_lease);
> torture_suite_add_1smb2_test(suite, "reopen1", test_durable_open_reopen1);
> torture_suite_add_1smb2_test(suite, "reopen1a", test_durable_open_reopen1a);
> + torture_suite_add_1smb2_test(suite, "reopen1a-lease", test_durable_open_reopen1a_lease);
> torture_suite_add_1smb2_test(suite, "reopen2", test_durable_open_reopen2);
> torture_suite_add_1smb2_test(suite, "reopen2-lease", test_durable_open_reopen2_lease);
> torture_suite_add_1smb2_test(suite, "reopen2-lease-v2", test_durable_open_reopen2_lease_v2);
> --
> 2.5.0
>
>
> From c112967ab6036b0788f7e8d8805257bb569db77f Mon Sep 17 00:00:00 2001
> From: Michael Adam <obnox at samba.org>
> Date: Tue, 15 Mar 2016 09:39:43 +0100
> Subject: [PATCH 06/10] torture:smb2: use assert, not warning in error case in
> durable-v2-open.reopen1a
>
> Signed-off-by: Michael Adam <obnox at samba.org>
> ---
> source4/torture/smb2/durable_v2_open.c | 10 +++-------
> 1 file changed, 3 insertions(+), 7 deletions(-)
>
> diff --git a/source4/torture/smb2/durable_v2_open.c b/source4/torture/smb2/durable_v2_open.c
> index f3ec344..a80506a 100644
> --- a/source4/torture/smb2/durable_v2_open.c
> +++ b/source4/torture/smb2/durable_v2_open.c
> @@ -629,13 +629,9 @@ bool test_durable_v2_open_reopen1a(struct torture_context *tctx,
>
> previous_session_id = smb2cli_session_current_id(tree->session->smbXcli);
>
> - if (!torture_smb2_connection_ext(tctx, previous_session_id,
> - &options, &tree2))
> - {
> - torture_warning(tctx, "couldn't reconnect, bailing\n");
> - ret = false;
> - goto done;
> - }
> + ret = torture_smb2_connection_ext(tctx, previous_session_id,
> + &options, &tree2);
> + torture_assert_goto(tctx, ret, ret, done, "couldn't reconnect");
>
> /*
> * check that this has deleted the old session
> --
> 2.5.0
>
>
> From cd936d1fce36d91235a482a1de6598649fa8f828 Mon Sep 17 00:00:00 2001
> From: Michael Adam <obnox at samba.org>
> Date: Tue, 15 Mar 2016 09:44:06 +0100
> Subject: [PATCH 07/10] torture:smb2: fix crashes in
> smb2.durable-v2-open.reopen1a test
>
> If the test failed too early, we dereferenced tree2 which
> was still NULL.
>
> Signed-off-by: Michael Adam <obnox at samba.org>
> ---
> source4/torture/smb2/durable_v2_open.c | 16 ++++++++++++----
> 1 file changed, 12 insertions(+), 4 deletions(-)
>
> diff --git a/source4/torture/smb2/durable_v2_open.c b/source4/torture/smb2/durable_v2_open.c
> index a80506a..de24c8f 100644
> --- a/source4/torture/smb2/durable_v2_open.c
> +++ b/source4/torture/smb2/durable_v2_open.c
> @@ -644,6 +644,8 @@ bool test_durable_v2_open_reopen1a(struct torture_context *tctx,
> status = smb2_create(tree, mem_ctx, &io);
> CHECK_STATUS(status, NT_STATUS_USER_SESSION_DELETED);
>
> + TALLOC_FREE(tree);
> +
> /*
> * but a durable reconnect on the new session succeeds:
> */
> @@ -664,13 +666,19 @@ bool test_durable_v2_open_reopen1a(struct torture_context *tctx,
> h = &_h;
>
> done:
> - if (h != NULL) {
> - smb2_util_close(tree, *h);
> + if (tree == NULL) {
> + tree = tree2;
> }
>
> - smb2_util_unlink(tree, fname);
> + if (tree != NULL) {
> + if (h != NULL) {
> + smb2_util_close(tree, *h);
> + }
>
> - talloc_free(tree);
> + smb2_util_unlink(tree, fname);
> +
> + talloc_free(tree);
> + }
>
> talloc_free(mem_ctx);
>
> --
> 2.5.0
>
>
> From 6dd86cb2ee81e3c629bc87cc0c9cd050b3977f2f Mon Sep 17 00:00:00 2001
> From: Michael Adam <obnox at samba.org>
> Date: Thu, 17 Mar 2016 02:35:35 +0100
> Subject: [PATCH 08/10] torture:smb2: get rid of supefluous io2 var in
> durable-v2-open.reopen1a
>
> Signed-off-by: Michael Adam <obnox at samba.org>
> ---
> source4/torture/smb2/durable_v2_open.c | 26 +++++++++++++-------------
> 1 file changed, 13 insertions(+), 13 deletions(-)
>
> diff --git a/source4/torture/smb2/durable_v2_open.c b/source4/torture/smb2/durable_v2_open.c
> index de24c8f..2528187 100644
> --- a/source4/torture/smb2/durable_v2_open.c
> +++ b/source4/torture/smb2/durable_v2_open.c
> @@ -588,7 +588,7 @@ bool test_durable_v2_open_reopen1a(struct torture_context *tctx,
> char fname[256];
> struct smb2_handle _h;
> struct smb2_handle *h = NULL;
> - struct smb2_create io, io2;
> + struct smb2_create io;
> struct GUID create_guid = GUID_random();
> bool ret = true;
> struct smb2_tree *tree2 = NULL;
> @@ -650,19 +650,19 @@ bool test_durable_v2_open_reopen1a(struct torture_context *tctx,
> * but a durable reconnect on the new session succeeds:
> */
>
> - ZERO_STRUCT(io2);
> - io2.in.fname = "";
> - io2.in.durable_handle_v2 = h;
> - io2.in.create_guid = create_guid;
> - status = smb2_create(tree2, mem_ctx, &io2);
> + ZERO_STRUCT(io);
> + io.in.fname = "";
> + io.in.durable_handle_v2 = h;
> + io.in.create_guid = create_guid;
> + status = smb2_create(tree2, mem_ctx, &io);
> CHECK_STATUS(status, NT_STATUS_OK);
> - CHECK_CREATED(&io2, EXISTED, FILE_ATTRIBUTE_ARCHIVE);
> - CHECK_VAL(io2.out.oplock_level, smb2_util_oplock_level("b"));
> - CHECK_VAL(io2.out.durable_open, false);
> - CHECK_VAL(io2.out.durable_open_v2, false); /* no dh2q response blob */
> - CHECK_VAL(io2.out.persistent_open, false);
> - CHECK_VAL(io2.out.timeout, io.in.timeout);
> - _h = io2.out.file.handle;
> + CHECK_CREATED(&io, EXISTED, FILE_ATTRIBUTE_ARCHIVE);
> + CHECK_VAL(io.out.oplock_level, smb2_util_oplock_level("b"));
> + CHECK_VAL(io.out.durable_open, false);
> + CHECK_VAL(io.out.durable_open_v2, false); /* no dh2q response blob */
> + CHECK_VAL(io.out.persistent_open, false);
> + CHECK_VAL(io.out.timeout, io.in.timeout);
> + _h = io.out.file.handle;
> h = &_h;
>
> done:
> --
> 2.5.0
>
>
> From 784c6440f45cba1ca4c6cbecd2219f959ac9e8d7 Mon Sep 17 00:00:00 2001
> From: Michael Adam <obnox at samba.org>
> Date: Tue, 15 Mar 2016 09:02:28 +0100
> Subject: [PATCH 09/10] torture:smb2: for oplocks, durable reconnect works with
> different client-guid
>
> for durable-v2-open.reopen1a
>
> Try both different and original client guid.
>
> Signed-off-by: Michael Adam <obnox at samba.org>
> ---
> source4/torture/smb2/durable_v2_open.c | 54 ++++++++++++++++++++++++++++++++++
> 1 file changed, 54 insertions(+)
>
> diff --git a/source4/torture/smb2/durable_v2_open.c b/source4/torture/smb2/durable_v2_open.c
> index 2528187..e48fb9b 100644
> --- a/source4/torture/smb2/durable_v2_open.c
> +++ b/source4/torture/smb2/durable_v2_open.c
> @@ -592,10 +592,13 @@ bool test_durable_v2_open_reopen1a(struct torture_context *tctx,
> struct GUID create_guid = GUID_random();
> bool ret = true;
> struct smb2_tree *tree2 = NULL;
> + struct smb2_tree *tree3 = NULL;
> uint64_t previous_session_id;
> struct smbcli_options options;
> + struct GUID orig_client_guid;
>
> options = tree->session->transport->options;
> + orig_client_guid = options.client_guid;
>
> /* Choose a random name in case the state is left a little funky. */
> snprintf(fname, 256, "durable_v2_open_reopen1a_%s.dat",
> @@ -629,6 +632,9 @@ bool test_durable_v2_open_reopen1a(struct torture_context *tctx,
>
> previous_session_id = smb2cli_session_current_id(tree->session->smbXcli);
>
> + /* for oplocks, the client guid can be different: */
> + options.client_guid = GUID_random();
> +
> ret = torture_smb2_connection_ext(tctx, previous_session_id,
> &options, &tree2);
> torture_assert_goto(tctx, ret, ret, done, "couldn't reconnect");
> @@ -665,11 +671,59 @@ bool test_durable_v2_open_reopen1a(struct torture_context *tctx,
> _h = io.out.file.handle;
> h = &_h;
>
> + /*
> + * a session reconnect on a second tcp connection
> + */
> +
> + previous_session_id = smb2cli_session_current_id(tree2->session->smbXcli);
> +
> + /* it works the same with the original guid */
> + options.client_guid = orig_client_guid;
> +
> + ret = torture_smb2_connection_ext(tctx, previous_session_id,
> + &options, &tree3);
> + torture_assert_goto(tctx, ret, ret, done, "couldn't reconnect");
> +
> + /*
> + * check that this has deleted the old session
> + */
> +
> + ZERO_STRUCT(io);
> + io.in.fname = "";
> + io.in.durable_handle_v2 = h;
> + io.in.create_guid = create_guid;
> + status = smb2_create(tree2, mem_ctx, &io);
> + CHECK_STATUS(status, NT_STATUS_USER_SESSION_DELETED);
> + TALLOC_FREE(tree2);
> +
> + /*
> + * but a durable reconnect on the new session succeeds:
> + */
> +
> + ZERO_STRUCT(io);
> + io.in.fname = "";
> + io.in.durable_handle_v2 = h;
> + io.in.create_guid = create_guid;
> + status = smb2_create(tree3, mem_ctx, &io);
> + CHECK_STATUS(status, NT_STATUS_OK);
> + CHECK_CREATED(&io, EXISTED, FILE_ATTRIBUTE_ARCHIVE);
> + CHECK_VAL(io.out.oplock_level, smb2_util_oplock_level("b"));
> + CHECK_VAL(io.out.durable_open, false);
> + CHECK_VAL(io.out.durable_open_v2, false); /* no dh2q response blob */
> + CHECK_VAL(io.out.persistent_open, false);
> + CHECK_VAL(io.out.timeout, io.in.timeout);
> + _h = io.out.file.handle;
> + h = &_h;
> +
> done:
> if (tree == NULL) {
> tree = tree2;
> }
>
> + if (tree == NULL) {
> + tree = tree3;
> + }
> +
> if (tree != NULL) {
> if (h != NULL) {
> smb2_util_close(tree, *h);
> --
> 2.5.0
>
>
> From 55564b164a2bd24dff0c594315393b7ed9f3abba Mon Sep 17 00:00:00 2001
> From: Michael Adam <obnox at samba.org>
> Date: Tue, 15 Mar 2016 09:06:56 +0100
> Subject: [PATCH 10/10] torture:smb2: add durable-v2-open.reopen1a-lease
>
> Lease variant of the reopen1a test which tests the
> relevance of the client guid.
>
> Signed-off-by: Michael Adam <obnox at samba.org>
> ---
> selftest/knownfail | 1 +
> source4/torture/smb2/durable_v2_open.c | 183 +++++++++++++++++++++++++++++++++
> 2 files changed, 184 insertions(+)
>
> diff --git a/selftest/knownfail b/selftest/knownfail
> index 8f2f139..c296c0e 100644
> --- a/selftest/knownfail
> +++ b/selftest/knownfail
> @@ -194,6 +194,7 @@
> ^samba3.smb2.durable-open.delete_on_close2
> ^samba3.smb2.durable-v2-open.app-instance
> ^samba3.smb2.durable-open.reopen1a-lease\(ad_dc\)$
> +^samba3.smb2.durable-v2-open.reopen1a-lease\(ad_dc\)$
> ^samba4.smb2.ioctl.req_resume_key\(ad_dc_ntvfs\) # not supported by s4 ntvfs server
> ^samba4.smb2.ioctl.copy_chunk_\w*\(ad_dc_ntvfs\) # not supported by s4 ntvfs server
> ^samba3.smb2.dir.one
> diff --git a/source4/torture/smb2/durable_v2_open.c b/source4/torture/smb2/durable_v2_open.c
> index e48fb9b..b7d8920 100644
> --- a/source4/torture/smb2/durable_v2_open.c
> +++ b/source4/torture/smb2/durable_v2_open.c
> @@ -740,6 +740,188 @@ done:
> }
>
> /**
> + * lease variant of reopen1a
> + *
> + * Basic test for doing a durable open and doing a session
> + * reconnect while the first session is still active and the
> + * handle is still open in the client.
> + * This closes the original session and a durable reconnect on
> + * the new session succeeds depending on the client guid:
> + *
> + * Durable reconnect on a session with a different client guid fails.
> + * Durable reconnect on a session with the original client guid succeeds.
> + */
> +bool test_durable_v2_open_reopen1a_lease(struct torture_context *tctx,
> + struct smb2_tree *tree)
> +{
> + NTSTATUS status;
> + TALLOC_CTX *mem_ctx = talloc_new(tctx);
> + char fname[256];
> + struct smb2_handle _h;
> + struct smb2_handle *h = NULL;
> + struct smb2_create io;
> + struct GUID create_guid = GUID_random();
> + struct smb2_lease ls;
> + uint64_t lease_key;
> + bool ret = true;
> + struct smb2_tree *tree2 = NULL;
> + struct smb2_tree *tree3 = NULL;
> + uint64_t previous_session_id;
> + struct smbcli_options options;
> + struct GUID orig_client_guid;
> +
> + options = tree->session->transport->options;
> + orig_client_guid = options.client_guid;
> +
> + /* Choose a random name in case the state is left a little funky. */
> + snprintf(fname, 256, "durable_v2_open_reopen1a_lease_%s.dat",
> + generate_random_str(tctx, 8));
> +
> + smb2_util_unlink(tree, fname);
> +
> + lease_key = random();
> + smb2_lease_create(&io, &ls, false /* dir */, fname,
> + lease_key, smb2_util_lease_state("RWH"));
> + io.in.durable_open = false;
> + io.in.durable_open_v2 = true;
> + io.in.persistent_open = false;
> + io.in.create_guid = create_guid;
> + io.in.timeout = UINT32_MAX;
> +
> + status = smb2_create(tree, mem_ctx, &io);
> + CHECK_STATUS(status, NT_STATUS_OK);
> + _h = io.out.file.handle;
> + h = &_h;
> + CHECK_CREATED(&io, CREATED, FILE_ATTRIBUTE_ARCHIVE);
> + 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.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);
> + CHECK_VAL(io.out.lease_response.lease_state,
> + smb2_util_lease_state("RWH"));
> + CHECK_VAL(io.out.lease_response.lease_flags, 0);
> + CHECK_VAL(io.out.lease_response.lease_duration, 0);
> +
> + previous_session_id = smb2cli_session_current_id(tree->session->smbXcli);
> +
> + /*
> + * a session reconnect on a second tcp connection
> + * with a different client_guid does not allow
> + * the durable reconnect.
> + */
> +
> + options.client_guid = GUID_random();
> +
> + ret = torture_smb2_connection_ext(tctx, previous_session_id,
> + &options, &tree2);
> + torture_assert_goto(tctx, ret, ret, done, "couldn't reconnect");
> +
> + /*
> + * check that this has deleted the old session
> + */
> +
> + ZERO_STRUCT(io);
> + io.in.fname = fname;
> + io.in.durable_handle_v2 = h;
> + io.in.create_guid = create_guid;
> + io.in.lease_request = &ls;
> + status = smb2_create(tree, mem_ctx, &io);
> + CHECK_STATUS(status, NT_STATUS_USER_SESSION_DELETED);
> + TALLOC_FREE(tree);
> +
> + /*
> + * but a durable reconnect on the new session with the wrong
> + * client guid fails
> + */
> +
> + ZERO_STRUCT(io);
> + io.in.fname = fname;
> + io.in.durable_handle_v2 = h;
> + io.in.create_guid = create_guid;
> + io.in.lease_request = &ls;
> + status = smb2_create(tree2, mem_ctx, &io);
> + CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
> +
> +
> + /*
> + * now a session reconnect on a second tcp connection
> + * with original client_guid allows the durable reconnect.
> + */
> +
> + options.client_guid = orig_client_guid;
> + //options.client_guid = GUID_random();
> +
> + ret = torture_smb2_connection_ext(tctx, previous_session_id,
> + &options, &tree3);
> + torture_assert_goto(tctx, ret, ret, done, "couldn't reconnect");
> +
> + /*
> + * check that this has deleted the old session
> + */
> +
> + ZERO_STRUCT(io);
> + io.in.fname = fname;
> + io.in.durable_handle_v2 = h;
> + io.in.create_guid = create_guid;
> + io.in.lease_request = &ls;
> + status = smb2_create(tree2, mem_ctx, &io);
> + CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
> + TALLOC_FREE(tree2);
> +
> + /*
> + * but a durable reconnect on the new session succeeds:
> + */
> +
> + ZERO_STRUCT(io);
> + io.in.fname = fname;
> + io.in.durable_handle_v2 = h;
> + io.in.create_guid = create_guid;
> + io.in.lease_request = &ls;
> + status = smb2_create(tree3, mem_ctx, &io);
> + CHECK_STATUS(status, NT_STATUS_OK);
> + CHECK_CREATED(&io, EXISTED, FILE_ATTRIBUTE_ARCHIVE);
> + CHECK_VAL(io.out.durable_open, false);
> + CHECK_VAL(io.out.durable_open_v2, false); /* no dh2q response blob */
> + CHECK_VAL(io.out.persistent_open, false);
> + CHECK_VAL(io.out.timeout, io.in.timeout);
> + 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);
> + CHECK_VAL(io.out.lease_response.lease_state,
> + smb2_util_lease_state("RWH"));
> + CHECK_VAL(io.out.lease_response.lease_flags, 0);
> + CHECK_VAL(io.out.lease_response.lease_duration, 0);
> + _h = io.out.file.handle;
> + h = &_h;
> +
> +done:
> + if (tree == NULL) {
> + tree = tree2;
> + }
> +
> + if (tree == NULL) {
> + tree = tree3;
> + }
> +
> + if (tree != NULL) {
> + if (h != NULL) {
> + smb2_util_close(tree, *h);
> + }
> +
> + smb2_util_unlink(tree, fname);
> +
> + talloc_free(tree);
> + }
> +
> + talloc_free(mem_ctx);
> +
> + return ret;
> +}
> +
> +/**
> * basic test for doing a durable open
> * tcp disconnect, reconnect, do a durable reopen (succeeds)
> */
> @@ -1832,6 +2014,7 @@ struct torture_suite *torture_smb2_durable_v2_open_init(void)
> torture_suite_add_1smb2_test(suite, "open-lease", test_durable_v2_open_lease);
> torture_suite_add_1smb2_test(suite, "reopen1", test_durable_v2_open_reopen1);
> torture_suite_add_1smb2_test(suite, "reopen1a", test_durable_v2_open_reopen1a);
> + torture_suite_add_1smb2_test(suite, "reopen1a-lease", test_durable_v2_open_reopen1a_lease);
> torture_suite_add_1smb2_test(suite, "reopen2", test_durable_v2_open_reopen2);
> torture_suite_add_1smb2_test(suite, "reopen2b", test_durable_v2_open_reopen2b);
> torture_suite_add_1smb2_test(suite, "reopen2c", test_durable_v2_open_reopen2c);
> --
> 2.5.0
>
More information about the samba-technical
mailing list