From c18c84ca6ca04815e8ffedb3d6f8abadad06500b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 12 Nov 2014 09:53:45 +0100 Subject: [PATCH] s4:torture/smb2: add smb2.lease.v2_epoch[2|3] tests They demonstrate that the lease version (v1 or v2) is selected by the first open. All following opens using the other version still get the lease version of the first open. This implies that the server has to remember the lease version more globaly. Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source4/torture/smb2/lease.c | 210 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 210 insertions(+) diff --git a/source4/torture/smb2/lease.c b/source4/torture/smb2/lease.c index ac209464b62..14ce739f2e9 100644 --- a/source4/torture/smb2/lease.c +++ b/source4/torture/smb2/lease.c @@ -1563,6 +1563,214 @@ done: return ret; } +static bool test_lease_v2_epoch2(struct torture_context *tctx, + struct smb2_tree *tree) +{ + TALLOC_CTX *mem_ctx = talloc_new(tctx); + struct smb2_create io; + struct smb2_lease ls1v2, ls1v2t, ls1v1; + struct smb2_handle hv2 = {}, hv1 = {}; + const char *fname = "lease_v2_epoch2.dat"; + bool ret = true; + NTSTATUS status; + uint32_t caps; + enum protocol_types protocol; + + caps = smb2cli_conn_server_capabilities(tree->session->transport->conn); + if (!(caps & SMB2_CAP_LEASING)) { + torture_skip(tctx, "leases are not supported"); + } + + protocol = smbXcli_conn_protocol(tree->session->transport->conn); + if (protocol < PROTOCOL_SMB3_00) { + torture_skip(tctx, "v2 leases are not supported"); + } + + smb2_util_unlink(tree, fname); + + tree->session->transport->lease.handler = torture_lease_handler; + tree->session->transport->lease.private_data = tree; + tree->session->transport->oplock.handler = torture_oplock_handler; + tree->session->transport->oplock.private_data = tree; + + ZERO_STRUCT(break_info); + + ZERO_STRUCT(io); + smb2_lease_v2_create_share(&io, &ls1v2, false, fname, + smb2_util_share_access("RWD"), + LEASE1, NULL, + smb2_util_lease_state("R"), + 0x4711); + status = smb2_create(tree, mem_ctx, &io); + CHECK_STATUS(status, NT_STATUS_OK); + hv2 = io.out.file.handle; + CHECK_CREATED(&io, CREATED, FILE_ATTRIBUTE_ARCHIVE); + CHECK_LEASE_V2(&io, "R", true, LEASE1, 0, 0, ls1v2.lease_epoch + 1); + + ZERO_STRUCT(io); + smb2_lease_create_share(&io, &ls1v1, false, fname, + smb2_util_share_access("RWD"), + LEASE1, + smb2_util_lease_state("RH")); + status = smb2_create(tree, mem_ctx, &io); + CHECK_STATUS(status, NT_STATUS_OK); + hv1 = io.out.file.handle; + CHECK_CREATED(&io, EXISTED, FILE_ATTRIBUTE_ARCHIVE); + CHECK_LEASE_V2(&io, "RH", true, LEASE1, 0, 0, ls1v2.lease_epoch + 2); + + smb2_util_close(tree, hv2); + + ZERO_STRUCT(io); + smb2_lease_v2_create_share(&io, &ls1v2t, false, fname, + smb2_util_share_access("RWD"), + LEASE1, NULL, + smb2_util_lease_state("RHW"), + 0x11); + status = smb2_create(tree, mem_ctx, &io); + CHECK_STATUS(status, NT_STATUS_OK); + hv2 = io.out.file.handle; + CHECK_CREATED(&io, EXISTED, FILE_ATTRIBUTE_ARCHIVE); + CHECK_LEASE_V2(&io, "RHW", true, LEASE1, 0, 0, ls1v2.lease_epoch + 3); + + smb2_util_close(tree, hv2); + + smb2_oplock_create(&io, fname, SMB2_OPLOCK_LEVEL_NONE); + status = smb2_create(tree, mem_ctx, &io); + CHECK_STATUS(status, NT_STATUS_OK); + hv2 = io.out.file.handle; + CHECK_CREATED(&io, EXISTED, FILE_ATTRIBUTE_ARCHIVE); + CHECK_VAL(io.out.oplock_level, SMB2_OPLOCK_LEVEL_NONE); + + CHECK_BREAK_INFO_V2(tree->session->transport, + "RWH", "RH", LEASE1, ls1v2.lease_epoch + 4); + + smb2_util_close(tree, hv2); + smb2_util_close(tree, hv1); + + ZERO_STRUCT(io); + smb2_lease_create_share(&io, &ls1v1, false, fname, + smb2_util_share_access("RWD"), + LEASE1, + smb2_util_lease_state("RHW")); + status = smb2_create(tree, mem_ctx, &io); + CHECK_STATUS(status, NT_STATUS_OK); + hv1 = io.out.file.handle; + CHECK_CREATED(&io, EXISTED, FILE_ATTRIBUTE_ARCHIVE); + CHECK_LEASE(&io, "RHW", true, LEASE1, 0); + + smb2_util_close(tree, hv1); + +done: + smb2_util_close(tree, hv2); + smb2_util_close(tree, hv1); + smb2_util_unlink(tree, fname); + talloc_free(mem_ctx); + return ret; +} + +static bool test_lease_v2_epoch3(struct torture_context *tctx, + struct smb2_tree *tree) +{ + TALLOC_CTX *mem_ctx = talloc_new(tctx); + struct smb2_create io; + struct smb2_lease ls1v1 = {}, ls1v1t = {},ls1v2 = {}; + struct smb2_handle hv1 = {}, hv2 = {}; + const char *fname = "lease_v2_epoch3.dat"; + bool ret = true; + NTSTATUS status; + uint32_t caps; + enum protocol_types protocol; + + caps = smb2cli_conn_server_capabilities(tree->session->transport->conn); + if (!(caps & SMB2_CAP_LEASING)) { + torture_skip(tctx, "leases are not supported"); + } + + protocol = smbXcli_conn_protocol(tree->session->transport->conn); + if (protocol < PROTOCOL_SMB3_00) { + torture_skip(tctx, "v2 leases are not supported"); + } + + smb2_util_unlink(tree, fname); + + tree->session->transport->lease.handler = torture_lease_handler; + tree->session->transport->lease.private_data = tree; + tree->session->transport->oplock.handler = torture_oplock_handler; + tree->session->transport->oplock.private_data = tree; + + ZERO_STRUCT(break_info); + + ZERO_STRUCT(io); + smb2_lease_create_share(&io, &ls1v1, false, fname, + smb2_util_share_access("RWD"), + LEASE1, + smb2_util_lease_state("R")); + status = smb2_create(tree, mem_ctx, &io); + CHECK_STATUS(status, NT_STATUS_OK); + hv1 = io.out.file.handle; + CHECK_CREATED(&io, CREATED, FILE_ATTRIBUTE_ARCHIVE); + CHECK_LEASE(&io, "R", true, LEASE1, 0); + + ZERO_STRUCT(io); + smb2_lease_v2_create_share(&io, &ls1v2, false, fname, + smb2_util_share_access("RWD"), + LEASE1, NULL, + smb2_util_lease_state("RW"), + 0x4711); + status = smb2_create(tree, mem_ctx, &io); + CHECK_STATUS(status, NT_STATUS_OK); + hv2 = io.out.file.handle; + CHECK_CREATED(&io, EXISTED, FILE_ATTRIBUTE_ARCHIVE); + CHECK_LEASE(&io, "RW", true, LEASE1, 0); + + smb2_util_close(tree, hv1); + + ZERO_STRUCT(io); + smb2_lease_create_share(&io, &ls1v1t, false, fname, + smb2_util_share_access("RWD"), + LEASE1, + smb2_util_lease_state("RWH")); + status = smb2_create(tree, mem_ctx, &io); + CHECK_STATUS(status, NT_STATUS_OK); + hv1 = io.out.file.handle; + CHECK_CREATED(&io, EXISTED, FILE_ATTRIBUTE_ARCHIVE); + CHECK_LEASE(&io, "RWH", true, LEASE1, 0); + + smb2_util_close(tree, hv1); + + smb2_oplock_create(&io, fname, SMB2_OPLOCK_LEVEL_NONE); + status = smb2_create(tree, mem_ctx, &io); + CHECK_STATUS(status, NT_STATUS_OK); + hv1 = io.out.file.handle; + CHECK_CREATED(&io, EXISTED, FILE_ATTRIBUTE_ARCHIVE); + CHECK_VAL(io.out.oplock_level, SMB2_OPLOCK_LEVEL_NONE); + + CHECK_BREAK_INFO("RWH", "RH", LEASE1); + + smb2_util_close(tree, hv1); + smb2_util_close(tree, hv2); + + ZERO_STRUCT(io); + smb2_lease_v2_create_share(&io, &ls1v2, false, fname, + smb2_util_share_access("RWD"), + LEASE1, NULL, + smb2_util_lease_state("RWH"), + 0x4711); + status = smb2_create(tree, mem_ctx, &io); + CHECK_STATUS(status, NT_STATUS_OK); + hv2 = io.out.file.handle; + CHECK_CREATED(&io, EXISTED, FILE_ATTRIBUTE_ARCHIVE); + CHECK_LEASE_V2(&io, "RHW", true, LEASE1, 0, 0, ls1v2.lease_epoch + 1); + smb2_util_close(tree, hv2); + +done: + smb2_util_close(tree, hv2); + smb2_util_close(tree, hv1); + smb2_util_unlink(tree, fname); + talloc_free(mem_ctx); + return ret; +} + static bool test_lease_complex1(struct torture_context *tctx, struct smb2_tree *tree1a) { @@ -1855,6 +2063,8 @@ struct torture_suite *torture_smb2_lease_init(void) test_lease_v2_request_parent); torture_suite_add_1smb2_test(suite, "v2_request", test_lease_v2_request); torture_suite_add_1smb2_test(suite, "v2_epoch1", test_lease_v2_epoch1); + torture_suite_add_1smb2_test(suite, "v2_epoch2", test_lease_v2_epoch2); + torture_suite_add_1smb2_test(suite, "v2_epoch3", test_lease_v2_epoch3); torture_suite_add_1smb2_test(suite, "v2_complex1", test_lease_v2_complex1); suite->description = talloc_strdup(suite, "SMB2-LEASE tests"); -- 2.11.4.GIT