s4:torture/smb2: add smb2.lease.v2_epoch[2|3] tests
authorStefan Metzmacher <metze@samba.org>
Wed, 12 Nov 2014 08:53:45 +0000 (09:53 +0100)
committerStefan Metzmacher <metze@samba.org>
Thu, 27 Nov 2014 15:45:05 +0000 (16:45 +0100)
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 <metze@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
source4/torture/smb2/lease.c

index ac209464b62900d9fd54bda076a81c0bc12369e2..14ce739f2e9d8d663f0a5e5af050442bcfc95bbb 100644 (file)
@@ -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");