static const uint64_t LEASE1F1 = 0xBADC0FFEE0DDF00Dull;
static const uint64_t LEASE1F2 = 0xBADC0FFEE0DDD00Dull;
+static const uint64_t LEASE1F3 = 0xDADC0FFEE0DDD00Dull;
static const uint64_t LEASE2F1 = 0xDEADBEEFFEEDBEADull;
static const uint64_t LEASE2F2 = 0xDAD0FFEDD00DF00Dull;
static const uint64_t LEASE2F3 = 0xBAD0FFEDD00DF00Dull;
transport1->lease.private_data = tree1;
torture_comment(tctx, "transport1 [%p]\n", transport1);
+ local_port = torture_get_local_port_from_transport(transport1);
+ torture_comment(tctx, "transport1 uses tcp port: %d\n", local_port);
+
status = torture_smb2_testdir(tree1, BASEDIR, &_h);
CHECK_STATUS(status, NT_STATUS_OK);
smb2_util_close(tree1, _h);
smb2_util_unlink(tree1, fname3);
CHECK_VAL(lease_break_info.count, 0);
+ /*
+ * Test 1:
+ * open file1 in session 2A
+ * open file2 in session 2B
+ * open file3 in session 2B
+ * open file1 in session 1
+ * lease break sent to 2A
+ * open file2 in session 2
+ * lease break sent to 2B
+ */
+ torture_comment(tctx, "Test 1 start \n");
+
smb2_lease_create(&io1, &ls1, false, fname1, LEASE2F1,
smb2_util_lease_state("RHW"));
io1.in.durable_open = false;
transport2A = tree2A->session->transport;
session2A = tree2A->session;
+
transport2A->lease.handler = torture_lease_handler;
transport2A->lease.private_data = tree2A;
torture_comment(tctx, "transport2A [%p]\n", transport2A);
torture_comment(tctx, "established transport 2A\n");
+ local_port = torture_get_local_port_from_transport(transport2A);
+ torture_comment(tctx, "transport2A uses tcp port: %d\n", local_port);
+
status = smb2_connect(tctx,
host,
lpcfg_smb_ports(tctx->lp_ctx),
torture_comment(tctx, "established transport 2B\n");
+ local_port = torture_get_local_port_from_transport(transport2B);
+ torture_comment(tctx, "transport2B uses tcp port: %d\n", local_port);
+
status = smb2_session_setup_spnego(session2B,
popt_get_cmdline_credentials(),
0 /* previous_session_id */);
CHECK_VAL(io2.out.durable_open, false);
CHECK_VAL(lease_break_info.count, 0);
+ torture_comment(tctx, "client2 opens fname3 via session 2B\n");
+ /* 2b opens file3 */
+ smb2_lease_create(&io3, &ls3, false, fname3, LEASE2F3,
+ smb2_util_lease_state("RHW"));
+ status = smb2_create(tree2B, mem_ctx, &io3);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ h_client2_file3 = io3.out.file.handle;
+ CHECK_CREATED(&io3, CREATED, FILE_ATTRIBUTE_ARCHIVE);
+ CHECK_LEASE(&io3, "RHW", true, LEASE2F3, 0);
+ CHECK_VAL(io3.out.durable_open_v2, false);
+ CHECK_VAL(io3.out.timeout, io3.in.timeout);
+ CHECK_VAL(io3.out.durable_open, false);
+ CHECK_VAL(lease_break_info.count, 0);
/*
* 1 opens file1
smb2_util_unlink(tree1, fname3);
CHECK_VAL(lease_break_info.count, 0);
+ /*
+ * Test 2:
+ * open file1 in session 2A
+ * open file2 in session 2B
+ * open file3 in session 2C
+ * open file1 in session 1
+ * lease break sent to 2A
+ * open file2 in session 2
+ * lease break sent to 2B
+ */
+ torture_comment(tctx, "Test 2 start \n");
+
/* now add a third channel and repeat the test */
status = smb2_connect(tctx,
host,
smb2_keepalive(transport2C);
local_port = torture_get_local_port_from_transport(transport2C);
-
torture_comment(tctx, "transport2C uses tcp port: %d\n", local_port);
torture_comment(tctx, "client2 opens fname1 via session 2A\n");
h_client2_file1 = io1.out.file.handle;
CHECK_CREATED(&io1, CREATED, FILE_ATTRIBUTE_ARCHIVE);
CHECK_LEASE(&io1, "RHW", true, LEASE2F1, 0);
- CHECK_VAL(io1.out.durable_open_v2, false); //true);
+ CHECK_VAL(io1.out.durable_open_v2, false);
CHECK_VAL(io1.out.timeout, io1.in.timeout);
CHECK_VAL(io1.out.durable_open, false);
CHECK_VAL(lease_break_info.count, 0);
h_client2_file2 = io2.out.file.handle;
CHECK_CREATED(&io2, CREATED, FILE_ATTRIBUTE_ARCHIVE);
CHECK_LEASE(&io2, "RHW", true, LEASE2F2, 0);
- CHECK_VAL(io2.out.durable_open_v2, false); //true);
+ CHECK_VAL(io2.out.durable_open_v2, false);
CHECK_VAL(io2.out.timeout, io2.in.timeout);
CHECK_VAL(io2.out.durable_open, false);
CHECK_VAL(lease_break_info.count, 0);
+ torture_comment(tctx, "client2 opens fname3 via session 2C\n");
- block_ok = torture_block_tcp_transport(tctx, transport2A);
- block_ok = torture_block_tcp_transport(tctx, transport2B);
- block_ok = torture_block_tcp_transport(tctx, transport2C);
- smb2_lease_create(&io1, &ls1, false, fname1, LEASE1F1,
+ /* 2c opens file3 */
+ smb2_lease_create(&io3, &ls3, false, fname3, LEASE2F3,
smb2_util_lease_state("RHW"));
- {
- struct smb2_request *req;
- // uint32_t pkts2A = 0;
- // uint32_t pkts2B = 0;
- // uint32_t pkts2C = 0;
- uint32_t pkts2Ainit = 0;
- uint32_t pkts2Binit = 0;
- uint32_t pkts2Cinit = 0;
- req = smb2_create_send(tree1, &io1);
-
- while (req->cancel.can_cancel == false) {
- tevent_loop_once(tctx->ev);
- }
-
- smb_msleep(1000);
- torture_list_tcp_transport(tctx, transport2A, &pkts2Ainit);
- torture_list_tcp_transport(tctx, transport2B, &pkts2Binit);
- torture_list_tcp_transport(tctx, transport2C, &pkts2Cinit);
-#if 0
- for (int i = 0; i < 10; i++) {
-
- smb_msleep(1000);
- torture_list_tcp_transport(tctx, transport2A, &pkts2A);
- torture_list_tcp_transport(tctx, transport2B, &pkts2B);
- torture_list_tcp_transport(tctx, transport2C, &pkts2C);
- }
-#endif
- if (pkts2Ainit == 0) {
- unblock_ok = torture_unblock_tcp_transport(tctx, transport2A);
- }
-
- if (pkts2Binit == 0) {
- unblock_ok = torture_unblock_tcp_transport(tctx, transport2B);
- }
-
- if (pkts2Cinit == 0) {
- unblock_ok = torture_unblock_tcp_transport(tctx, transport2C);
- }
-
- smb_msleep(40000);
- }
- unblock_ok = torture_unblock_tcp_transport(tctx, transport2C);
- unblock_ok = torture_unblock_tcp_transport(tctx, transport2A);
- unblock_ok = torture_unblock_tcp_transport(tctx, transport2B);
- torture_unblock_cleanup(tctx);
- exit(0);
+ status = smb2_create(tree2C, mem_ctx, &io3);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ h_client2_file3 = io3.out.file.handle;
+ CHECK_CREATED(&io3, CREATED, FILE_ATTRIBUTE_ARCHIVE);
+ CHECK_LEASE(&io3, "RHW", true, LEASE2F3, 0);
+ CHECK_VAL(io3.out.durable_open_v2, false);
+ CHECK_VAL(io3.out.timeout, io2.in.timeout);
+ CHECK_VAL(io3.out.durable_open, false);
+ CHECK_VAL(lease_break_info.count, 0);
/*
* 1 opens file1
- * batchoplock break?
+ * lease break?
*/
torture_comment(tctx, "client1 opens fname1 via session 1\n");
torture_reset_lease_break_info(tctx, &lease_break_info);
-
- for (int i = 0; i < 25; i++) {
- torture_list_tcp_transport(tctx, transport2A, NULL);
- torture_list_tcp_transport(tctx, transport2B, NULL);
- torture_list_tcp_transport(tctx, transport2C, NULL);
- smb_msleep(1000);
- }
- torture_assert(tctx, block_ok, "we could not block tcp transport");
-
/*
* 1 opens file2
* lease break?
CHECK_STATUS(status, NT_STATUS_OK);
h_client1_file2 = io2.out.file.handle;
CHECK_CREATED(&io2, EXISTED, FILE_ATTRIBUTE_ARCHIVE);
- CHECK_LEASE(&io2, "RHW", true, LEASE1F2, 0);
-// CHECK_BREAK_INFO("RHW", "RH", LEASE2F2);
+ CHECK_LEASE(&io2, "RH", true, LEASE1F2, 0);
+ CHECK_BREAK_INFO("RHW", "RH", LEASE2F2);
CHECK_VAL(io2.out.durable_open_v2, false);
CHECK_VAL(io2.out.timeout, 0);
CHECK_VAL(io2.out.durable_open, false);
+ CHECK_VAL(lease_break_info.count, 1);
+ CHECK_PTR(lease_break_info.lease_transport, transport2A);
+
+ /* cleanup everything */
+ torture_reset_lease_break_info(tctx, &lease_break_info);
+
+ smb2_util_close(tree1, h_client1_file1);
+ smb2_util_close(tree1, h_client1_file2);
+ smb2_util_close(tree1, h_client1_file3);
+ smb2_util_close(tree2A, h_client2_file1);
+ smb2_util_close(tree2A, h_client2_file2);
+ smb2_util_close(tree2A, h_client2_file3);
+
+ smb2_util_unlink(tree1, fname1);
+ smb2_util_unlink(tree1, fname2);
+ smb2_util_unlink(tree1, fname3);
+ CHECK_VAL(lease_break_info.count, 0);
/*
- * FIXME LEASES! Important: when filtered, Windows will really let the open succeed
- * and *NOT* send a new oplock break over the remaining channels, thus
- * the break info count stays at one.
+ * Test 3:
+ * open file1 in session 2A
+ * open file2 in session 2B
+ * open file3 in session 2C
+ * block 2B 2C
+ * open file2 in session 1
+ * lease break reaches through session 2A
+ * server allows session 1 to open file1
+ * unblock 2B 2C, send keep alive
+ * open file1 in session 1
+ * lease break sent to 2A
*/
+ torture_comment(tctx, "Test 3 start \n");
- CHECK_VAL(lease_break_info.count, 1);
+ /* 2a opens file1 */
- torture_reset_lease_break_info(tctx, &lease_break_info);
+ torture_comment(tctx, "client2 opens fname1 via session 2A\n");
- blob = data_blob_string_const("Here I am");
+ smb2_lease_create(&io1, &ls1, false, fname1, LEASE2F1,
+ smb2_util_lease_state("RHW"));
+ status = smb2_create(tree2A, mem_ctx, &io1);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ h_client2_file1 = io1.out.file.handle;
+ CHECK_CREATED(&io1, CREATED, FILE_ATTRIBUTE_ARCHIVE);
+ CHECK_LEASE(&io1, "RHW", true, LEASE2F1, 0);
+ CHECK_VAL(io1.out.durable_open_v2, false); //true);
+ CHECK_VAL(io1.out.timeout, io1.in.timeout);
+ CHECK_VAL(io1.out.durable_open, false);
+ CHECK_VAL(lease_break_info.count, 0);
- torture_comment(tctx, "Trying write to file2 on tree2B\n");
- status = smb2_util_write(tree2B,
- h_client2_file2,
- blob.data,
- 0,
- blob.length);
- torture_assert_ntstatus_ok(tctx, status,
- "failed to write file2 via channel 2B");
+ torture_comment(tctx, "client2 opens fname2 via session 2B\n");
- smb2_util_close(tree1, h_client1_file2);
+ /* 2b opens file2 */
+ smb2_lease_create(&io2, &ls2, false, fname2, LEASE2F2,
+ smb2_util_lease_state("RHW"));
+ status = smb2_create(tree2B, mem_ctx, &io2);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ h_client2_file2 = io2.out.file.handle;
+ CHECK_CREATED(&io2, CREATED, FILE_ATTRIBUTE_ARCHIVE);
+ CHECK_LEASE(&io2, "RHW", true, LEASE2F2, 0);
+ CHECK_VAL(io2.out.durable_open_v2, false); //true);
+ CHECK_VAL(io2.out.timeout, io2.in.timeout);
+ CHECK_VAL(io2.out.durable_open, false);
+ CHECK_VAL(lease_break_info.count, 0);
+
+
+ torture_comment(tctx, "Blocking 2B and 2C\n");
+ /* Block 2A, 2B and 2C */
+ //block_ok = torture_block_tcp_transport(tctx, transport2A);
+ block_ok = torture_block_tcp_transport(tctx, transport2B);
+ block_ok |= torture_block_tcp_transport(tctx, transport2C);
+ torture_assert(tctx, block_ok, "we could not block tcp transport");
+ /*
+ * 1 opens file2
+ * batchoplock break?
+ */
+
+ torture_comment(tctx, "Client opens fname2 with session 1 with 2B and 2C blocked\n");
smb2_lease_create(&io2, &ls2, false, fname2, LEASE1F2,
smb2_util_lease_state("RHW"));
status = smb2_create(tree1, mem_ctx, &io2);
CHECK_STATUS(status, NT_STATUS_OK);
h_client1_file2 = io2.out.file.handle;
- io2.out.alloc_size = 0;
- io2.out.size = 0;
CHECK_CREATED(&io2, EXISTED, FILE_ATTRIBUTE_ARCHIVE);
CHECK_LEASE(&io2, "RH", true, LEASE1F2, 0);
CHECK_BREAK_INFO("RHW", "RH", LEASE2F2);
CHECK_VAL(io2.out.durable_open_v2, false);
CHECK_VAL(io2.out.timeout, 0);
CHECK_VAL(io2.out.durable_open, false);
+
CHECK_VAL(lease_break_info.count, 1);
- CHECK_PTR(lease_break_info.lease_transport, transport1);
+ torture_reset_lease_break_info(tctx, &lease_break_info);
- unblock_ok = torture_unblock_tcp_transport(tctx, transport2C);
- unblock_ok = torture_unblock_tcp_transport(tctx, transport2A);
+ /* Unblock 2B and 2C */
+ torture_comment(tctx, "Unblocking 2B and 2C\n");
unblock_ok = torture_unblock_tcp_transport(tctx, transport2B);
+ unblock_ok |= torture_unblock_tcp_transport(tctx, transport2C);
torture_assert(tctx, unblock_ok, "we could not unblock tcp transport");
+ torture_unblock_cleanup(tctx);
- /* next test: disconnect 2C and trigger break */
+ /* Will this trigger pending break? */
+ smb2_keepalive(transport2B);
+ smb2_keepalive(transport2C);
+ CHECK_VAL(lease_break_info.count, 0);
- torture_reset_lease_break_info(tctx, &lease_break_info);
/*
- * now add a third channel and repeat the test, we need to reestablish
- * transport2C because the remote end has invalidated our connection
+ * 1 opens file2
+ * lease break?
*/
+ torture_comment(tctx, "client opens fname1 via session 1\n");
+
+ smb2_lease_create(&io1, &ls1, false, fname1, LEASE1F1,
+ smb2_util_lease_state("RHW"));
+ status = smb2_create(tree1, mem_ctx, &io1);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ h_client1_file1 = io1.out.file.handle;
+ CHECK_CREATED(&io1, EXISTED, FILE_ATTRIBUTE_ARCHIVE);
+ CHECK_LEASE(&io1, "RH", true, LEASE1F1, 0);
+ CHECK_BREAK_INFO("RHW", "RH", LEASE2F1);
+ CHECK_VAL(io1.out.durable_open_v2, false);
+ CHECK_VAL(io1.out.timeout, 0);
+ CHECK_VAL(io1.out.durable_open, false);
+ CHECK_VAL(lease_break_info.count, 1);
+
+
+ torture_comment(tctx, "Reconnecting session 2B\n");
+ talloc_free(transport2B);
+ talloc_free(session2B);
+ talloc_free(tree2B);
status = smb2_connect(tctx,
host,
lpcfg_smb_ports(tctx->lp_ctx),
share,
lpcfg_resolve_context(tctx->lp_ctx),
credentials,
- &tree2C,
+ &tree2B,
tctx->ev,
&transport2_options,
lpcfg_socket_options(tctx->lp_ctx),
);
torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
"smb2_connect failed");
- transport2C = tree2C->session->transport;
+ transport2B = tree2B->session->transport;
- torture_comment(tctx, "transport2C [%p]\n", transport2C);
- /*
- * Now bind the session2 to the transport2C
- */
- session2C = smb2_session_channel(transport2C,
+ session2B = smb2_session_channel(transport2B,
lpcfg_gensec_settings(tctx, tctx->lp_ctx),
tree2A, session2A);
- tree2C->smbXcli = tree2A->smbXcli;
- tree2C->session = session2C;
+ tree2B->smbXcli = tree2A->smbXcli;
+ tree2B->session = session2B;
- torture_assert(tctx, session2C != NULL, "smb2_session_channel failed");
+ torture_assert(tctx, session2B != NULL, "smb2_session_channel failed");
- transport2C->lease.handler = torture_lease_handler;
- transport2C->lease.private_data = tree2C;
- torture_comment(tctx, "transport2C [%p]\n", transport2C);
+ transport2B->lease.handler = torture_lease_handler;
+ transport2B->lease.private_data = tree2B;
+ torture_comment(tctx, "transport2B [%p]\n", transport2B);
- torture_comment(tctx, "established transport 2C\n");
+ torture_comment(tctx, "established transport 2B\n");
- status = smb2_session_setup_spnego(session2C,
+ local_port = torture_get_local_port_from_transport(transport2B);
+ torture_comment(tctx, "transport2B uses tcp port: %d\n", local_port);
+
+ status = smb2_session_setup_spnego(session2B,
popt_get_cmdline_credentials(),
0 /* previous_session_id */);
CHECK_STATUS(status, NT_STATUS_OK);
- torture_comment(tctx, "bound session2C to session2A\n");
+ torture_comment(tctx, "bound session2B to session2A\n");
- torture_comment(tctx, "client 2 opening fname3 over newly established transport2C\n");
+ torture_comment(tctx, "client closes fname1 via session 2A\n");
+ status = smb2_util_close(tree2A, h_client2_file1);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ torture_reset_lease_break_info(tctx, &lease_break_info);
+ smb2_util_close(tree1, h_client1_file1);
+ smb2_util_close(tree1, h_client1_file2);
+ smb2_util_close(tree1, h_client1_file3);
+ smb2_util_close(tree2A, h_client2_file1);
+ smb2_util_close(tree2A, h_client2_file2);
+ smb2_util_close(tree2A, h_client2_file3);
+
+ smb2_util_unlink(tree1, fname1);
+ smb2_util_unlink(tree1, fname2);
+ smb2_util_unlink(tree1, fname3);
+ CHECK_VAL(lease_break_info.count, 0);
+
+ /*
+ * Test 4:
+ * open file1 in session 2A
+ * open file2 in session 2B
+ * open file3 in session 2C
+ * Disconnect 2C
+ * open file3 in session 1
+ * lease break?
+ * server allows session 1 to open file1
+ * Block 2B
+ * open file2 in session 1
+ * no oplock break because 2B blocked.
+ * session 1 allowed to open file2
+ * 2A writes "Here I am to file 2"
+ * Recieve break on 1 drop oplock.
+ */
+ torture_comment(tctx, "Test 4 start \n");
+
+ /* 2a opens file1 */
+ torture_comment(tctx, "client2 opens fname1 via session 2A\n");
+ smb2_lease_create(&io1, &ls1, false, fname1, LEASE2F1,
+ smb2_util_lease_state("RHW"));
+ status = smb2_create(tree2A, mem_ctx, &io1);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ h_client2_file1 = io1.out.file.handle;
+ CHECK_CREATED(&io1, CREATED, FILE_ATTRIBUTE_ARCHIVE);
+ CHECK_LEASE(&io1, "RHW", true, LEASE2F1, 0);
+ CHECK_VAL(io1.out.durable_open_v2, false); //true);
+ CHECK_VAL(io1.out.timeout, io1.in.timeout);
+ CHECK_VAL(io1.out.durable_open, false);
+ CHECK_VAL(lease_break_info.count, 0);
+
+ /* 2b opens file2 */
+ torture_comment(tctx, "client2 opens fname2 via session 2B\n");
+ smb2_lease_create(&io2, &ls2, false, fname2, LEASE2F2,
+ smb2_util_lease_state("RHW"));
+ status = smb2_create(tree2B, mem_ctx, &io2);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ h_client2_file2 = io2.out.file.handle;
+ CHECK_CREATED(&io2, CREATED, FILE_ATTRIBUTE_ARCHIVE);
+ CHECK_LEASE(&io2, "RHW", true, LEASE2F2, 0);
+ CHECK_VAL(io2.out.durable_open_v2, false); //true);
+ CHECK_VAL(io2.out.timeout, io2.in.timeout);
+ CHECK_VAL(io2.out.durable_open, false);
+ CHECK_VAL(lease_break_info.count, 0);
+
+ /* 2c opens file3 */
+ torture_comment(tctx, "client2 opens fname3 via session 2C\n");
+ smb2_lease_create(&io3, &ls3, false, fname3, LEASE2F3,
+ smb2_util_lease_state("RHW"));
status = smb2_create(tree2C, mem_ctx, &io3);
CHECK_STATUS(status, NT_STATUS_OK);
h_client2_file3 = io3.out.file.handle;
CHECK_CREATED(&io3, CREATED, FILE_ATTRIBUTE_ARCHIVE);
- CHECK_VAL(io3.out.oplock_level, smb2_util_oplock_level("b"));
- CHECK_VAL(io3.out.durable_open_v2, true);
- CHECK_VAL(io3.out.timeout, io3.in.timeout);
+ CHECK_LEASE(&io3, "RHW", true, LEASE2F3, 0);
+ CHECK_VAL(io3.out.durable_open_v2, false);
+ CHECK_VAL(io3.out.timeout, io2.in.timeout);
CHECK_VAL(io3.out.durable_open, false);
- CHECK_VAL(break_info.count, 0);
+ CHECK_VAL(lease_break_info.count, 0);
+ /* Disconnect 2C */
+ torture_comment(tctx, "Disconnect 2C\n");
torture_comment(tctx, "explicit disconnect of transport2C\n");
smbXcli_conn_disconnect(transport2C->conn, NT_STATUS_FOOBAR);
- torture_comment(tctx, "client1 opens fname3 via session 1\n");
-
+ /*
+ * 1 opens file3
+ * batchoplock break?
+ */
+ torture_comment(tctx, "Client opens fname3 with session 1\n");
+ smb2_lease_create(&io3, &ls3, false, fname3, LEASE1F3,
+ smb2_util_lease_state("RHW"));
status = smb2_create(tree1, mem_ctx, &io3);
CHECK_STATUS(status, NT_STATUS_OK);
h_client1_file3 = io3.out.file.handle;
CHECK_CREATED(&io3, EXISTED, FILE_ATTRIBUTE_ARCHIVE);
- CHECK_VAL(io3.out.oplock_level, smb2_util_oplock_level("s"));
- CHECK_VAL(io3.out.durable_open_v2, false);
- CHECK_VAL(io3.out.timeout, 0);
- CHECK_VAL(io3.out.durable_open, false);
+ CHECK_LEASE(&io3, "RH", true, LEASE1F3, 0);
+ CHECK_BREAK_INFO("RHW", "RH", LEASE2F3);
+ CHECK_VAL(io1.out.durable_open_v2, false);
+ CHECK_VAL(io1.out.timeout, 0);
+ CHECK_VAL(io1.out.durable_open, false);
CHECK_VAL(lease_break_info.count, 1);
- CHECK_PTR(lease_break_info.lease_transport, transport2B);
- if (h != NULL) {
- smb2_util_close(tree1, *h);
- h = NULL;
- }
+ torture_reset_lease_break_info(tctx, &lease_break_info);
+
+ /* Block 2B */
+ block_ok = torture_block_tcp_transport(tctx, transport2B);
+ torture_assert(tctx, block_ok, "we could not block tcp transport");
+
+ /*
+ * 1 opens file2
+ * batchoplock break?
+ */
+ torture_comment(tctx, "client opens fname2 via session 1\n");
+ smb2_lease_create(&io2, &ls2, false, fname2, LEASE1F2,
+ smb2_util_lease_state("RHW"));
+ status = smb2_create(tree1, mem_ctx, &io2);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ h_client1_file2 = io2.out.file.handle;
+ CHECK_CREATED(&io2, EXISTED, FILE_ATTRIBUTE_ARCHIVE);
+ CHECK_LEASE(&io2, "RH", true, LEASE1F2, 0);
+ CHECK_BREAK_INFO("RHW", "RH", LEASE2F2);
+ CHECK_VAL(io2.out.durable_open_v2, false);
+ CHECK_VAL(io2.out.timeout, 0);
+ CHECK_VAL(io2.out.durable_open, false);
+ CHECK_VAL(lease_break_info.count, 1);
+
+ /* 2A writes "Here I am to file 2" */
+
+ torture_comment(tctx, "Trying write to file2 on tree2A\n");
+ blob = data_blob_string_const("Here I am");
+ status = smb2_util_write(tree2A,
+ h_client2_file2,
+ blob.data,
+ 0,
+ blob.length);
+ torture_assert_ntstatus_ok(tctx, status,
+ "failed to write file2 via channel 2A");
+
+ /* Unblock 2B */
+ unblock_ok = torture_unblock_tcp_transport(tctx, transport2B);
+ torture_assert(tctx, unblock_ok, "we could not unblock tcp transport");
+
+ torture_reset_lease_break_info(tctx, &lease_break_info);
+ smb2_util_close(tree1, h_client1_file1);
+ smb2_util_close(tree1, h_client1_file2);
+ smb2_util_close(tree1, h_client1_file3);
+ smb2_util_close(tree2A, h_client2_file1);
+ smb2_util_close(tree2A, h_client2_file2);
+ smb2_util_close(tree2A, h_client2_file3);
+
+ smb2_util_unlink(tree1, fname1);
+ smb2_util_unlink(tree1, fname2);
+ smb2_util_unlink(tree1, fname3);
+ CHECK_VAL(lease_break_info.count, 0);
done:
if (block_ok && !unblock_ok) {