mirror of
https://github.com/samba-team/samba.git
synced 2025-03-08 04:58:40 +03:00
s4:torture/smb2: add smb2.lease.timeout-disconnect test
This reproduces a problem that is triggered when smbd_server_connection_terminate() is called recursively. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14533 Signed-off-by: Stefan Metzmacher <metze@samba.org> Reviewed-by: Jeremy Allison <jra@samba.org>
This commit is contained in:
parent
638c4435a0
commit
2a0626c32a
1
selftest/knownfail.d/smb2.lease.timeout-disconnect
Normal file
1
selftest/knownfail.d/smb2.lease.timeout-disconnect
Normal file
@ -0,0 +1 @@
|
||||
^samba3.smb2.lease.timeout-disconnect
|
@ -4149,6 +4149,151 @@ done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool test_lease_timeout_disconnect(struct torture_context *tctx,
|
||||
struct smb2_tree *tree1)
|
||||
{
|
||||
TALLOC_CTX *mem_ctx = talloc_new(tctx);
|
||||
NTSTATUS status;
|
||||
bool ret = true;
|
||||
struct smbcli_options transport2_options;
|
||||
struct smbcli_options transport3_options;
|
||||
struct smb2_tree *tree2 = NULL;
|
||||
struct smb2_tree *tree3 = NULL;
|
||||
struct smb2_transport *transport1 = tree1->session->transport;
|
||||
struct smb2_transport *transport2;
|
||||
struct smb2_transport *transport3;
|
||||
const char *fname = "lease_timeout_logoff.dat" ;
|
||||
uint32_t caps;
|
||||
struct smb2_create io1;
|
||||
struct smb2_create io2;
|
||||
struct smb2_request *req2 = NULL;
|
||||
struct smb2_lease ls1;
|
||||
|
||||
caps = smb2cli_conn_server_capabilities(
|
||||
tree1->session->transport->conn);
|
||||
if (!(caps & SMB2_CAP_LEASING)) {
|
||||
torture_skip(tctx, "leases are not supported");
|
||||
}
|
||||
|
||||
smb2_util_unlink(tree1, fname);
|
||||
|
||||
/* Connect 2nd connection */
|
||||
torture_comment(tctx, "connect tree2 with the same client_guid\n");
|
||||
transport2_options = transport1->options;
|
||||
if (!torture_smb2_connection_ext(tctx, 0, &transport2_options, &tree2)) {
|
||||
torture_warning(tctx, "couldn't reconnect, bailing\n");
|
||||
return false;
|
||||
}
|
||||
transport2 = tree2->session->transport;
|
||||
|
||||
/* Connect 3rd connection */
|
||||
torture_comment(tctx, "connect tree3 with the same client_guid\n");
|
||||
transport3_options = transport1->options;
|
||||
if (!torture_smb2_connection_ext(tctx, 0, &transport3_options, &tree3)) {
|
||||
torture_warning(tctx, "couldn't reconnect, bailing\n");
|
||||
return false;
|
||||
}
|
||||
transport3 = tree3->session->transport;
|
||||
|
||||
/* Set lease handlers */
|
||||
transport1->lease.handler = torture_lease_handler;
|
||||
transport1->lease.private_data = tree1;
|
||||
transport2->lease.handler = torture_lease_handler;
|
||||
transport2->lease.private_data = tree2;
|
||||
transport3->lease.handler = torture_lease_handler;
|
||||
transport3->lease.private_data = tree3;
|
||||
|
||||
smb2_lease_create_share(&io1, &ls1, false, fname,
|
||||
smb2_util_share_access(""),
|
||||
LEASE1,
|
||||
smb2_util_lease_state("RH"));
|
||||
io1.in.durable_open = true;
|
||||
smb2_generic_create(&io2, NULL, false, fname,
|
||||
NTCREATEX_DISP_OPEN_IF,
|
||||
SMB2_OPLOCK_LEVEL_NONE, 0, 0);
|
||||
|
||||
torture_comment(tctx, "tree1: create file[%s] with durable RH lease (SHARE NONE)\n", fname);
|
||||
torture_reset_lease_break_info(tctx, &lease_break_info);
|
||||
lease_break_info.lease_skip_ack = true;
|
||||
status = smb2_create(tree1, mem_ctx, &io1);
|
||||
CHECK_STATUS(status, NT_STATUS_OK);
|
||||
CHECK_CREATED(&io1, CREATED, FILE_ATTRIBUTE_ARCHIVE);
|
||||
CHECK_LEASE(&io1, "RH", true, LEASE1, 0);
|
||||
CHECK_VAL(lease_break_info.count, 0);
|
||||
|
||||
torture_comment(tctx, "tree1: skip lease acks\n");
|
||||
torture_reset_lease_break_info(tctx, &lease_break_info);
|
||||
lease_break_info.lease_skip_ack = true;
|
||||
torture_comment(tctx, "tree2: open file[%s] without lease (SHARE RWD)\n", fname);
|
||||
req2 = smb2_create_send(tree2, &io2);
|
||||
torture_assert(tctx, req2 != NULL, "req2 started");
|
||||
|
||||
torture_comment(tctx, "tree1: wait for lease break\n");
|
||||
torture_wait_for_lease_break(tctx);
|
||||
CHECK_VAL(lease_break_info.count, 1);
|
||||
CHECK_BREAK_INFO("RH", "R", LEASE1);
|
||||
|
||||
torture_comment(tctx, "tree1: reset lease handler\n");
|
||||
torture_reset_lease_break_info(tctx, &lease_break_info);
|
||||
lease_break_info.lease_skip_ack = true;
|
||||
CHECK_VAL(lease_break_info.count, 0);
|
||||
|
||||
torture_comment(tctx, "tree2: check for SMB2_REQUEST_RECV\n");
|
||||
torture_assert_int_equal(tctx, req2->state,
|
||||
SMB2_REQUEST_RECV,
|
||||
"SMB2_REQUEST_RECV");
|
||||
|
||||
torture_comment(tctx, "sleep 1\n");
|
||||
smb_msleep(1000);
|
||||
|
||||
torture_comment(tctx, "transport1: keepalive\n");
|
||||
status = smb2_keepalive(transport1);
|
||||
CHECK_STATUS(status, NT_STATUS_OK);
|
||||
|
||||
torture_comment(tctx, "transport2: keepalive\n");
|
||||
status = smb2_keepalive(transport2);
|
||||
CHECK_STATUS(status, NT_STATUS_OK);
|
||||
|
||||
torture_comment(tctx, "transport3: keepalive\n");
|
||||
status = smb2_keepalive(transport3);
|
||||
CHECK_STATUS(status, NT_STATUS_OK);
|
||||
|
||||
torture_comment(tctx, "tree2: check for SMB2_REQUEST_RECV\n");
|
||||
torture_assert_int_equal(tctx, req2->state,
|
||||
SMB2_REQUEST_RECV,
|
||||
"SMB2_REQUEST_RECV");
|
||||
torture_comment(tctx, "tree2: check for STATUS_PENDING\n");
|
||||
torture_assert(tctx, req2->cancel.can_cancel, "STATUS_PENDING");
|
||||
|
||||
torture_comment(tctx, "sleep 1\n");
|
||||
smb_msleep(1000);
|
||||
torture_comment(tctx, "transport1: keepalive\n");
|
||||
status = smb2_keepalive(transport1);
|
||||
CHECK_STATUS(status, NT_STATUS_OK);
|
||||
torture_comment(tctx, "transport2: disconnect\n");
|
||||
TALLOC_FREE(tree2);
|
||||
|
||||
torture_comment(tctx, "sleep 1\n");
|
||||
smb_msleep(1000);
|
||||
torture_comment(tctx, "transport1: keepalive\n");
|
||||
status = smb2_keepalive(transport1);
|
||||
CHECK_STATUS(status, NT_STATUS_OK);
|
||||
torture_comment(tctx, "transport1: disconnect\n");
|
||||
TALLOC_FREE(tree1);
|
||||
|
||||
torture_comment(tctx, "sleep 1\n");
|
||||
smb_msleep(1000);
|
||||
torture_comment(tctx, "transport3: keepalive\n");
|
||||
status = smb2_keepalive(transport3);
|
||||
CHECK_STATUS(status, NT_STATUS_OK);
|
||||
torture_comment(tctx, "transport3: disconnect\n");
|
||||
TALLOC_FREE(tree3);
|
||||
|
||||
done:
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct torture_suite *torture_smb2_lease_init(TALLOC_CTX *ctx)
|
||||
{
|
||||
struct torture_suite *suite =
|
||||
@ -4190,6 +4335,7 @@ struct torture_suite *torture_smb2_lease_init(TALLOC_CTX *ctx)
|
||||
torture_suite_add_1smb2_test(suite, "dynamic_share", test_lease_dynamic_share);
|
||||
torture_suite_add_1smb2_test(suite, "timeout", test_lease_timeout);
|
||||
torture_suite_add_1smb2_test(suite, "unlink", test_lease_unlink);
|
||||
torture_suite_add_1smb2_test(suite, "timeout-disconnect", test_lease_timeout_disconnect);
|
||||
|
||||
suite->description = talloc_strdup(suite, "SMB2-LEASE tests");
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user