diff --git a/source4/torture/smb2/lease.c b/source4/torture/smb2/lease.c index c1b6420..78022c0 100644 --- a/source4/torture/smb2/lease.c +++ b/source4/torture/smb2/lease.c @@ -47,7 +47,6 @@ #define CHECK_CREATED(__io, __created, __attribute) \ do { \ CHECK_VAL((__io)->out.create_action, NTCREATEX_ACTION_ ## __created); \ - CHECK_VAL((__io)->out.alloc_size, 0); \ CHECK_VAL((__io)->out.size, 0); \ CHECK_VAL((__io)->out.file_attr, (__attribute)); \ CHECK_VAL((__io)->out.reserved2, 0); \ @@ -2802,6 +2801,96 @@ done: return ret; } +static bool test_lease_breaking7(struct torture_context *tctx, + struct smb2_tree *tree1, + struct smb2_tree *tree2) +{ + TALLOC_CTX *mem_ctx = talloc_new(tctx); + struct smb2_create io1 = {}; + struct smb2_create io2 = {}; + struct smb2_create io3 = {}; + struct smb2_lease ls1 = {}; + struct smb2_lease ls2 = {}; + struct smb2_lease ls3 = {}; + struct smb2_handle h1 = {}; + struct smb2_handle h3 = {}; + const char *fname = "lease_breaking7.dat"; + bool ret = true; + NTSTATUS status; + uint32_t caps; + + caps = smb2cli_conn_server_capabilities(tree1->session->transport->conn); + if (!(caps & SMB2_CAP_LEASING)) { + torture_skip(tctx, "leases are not supported"); + } + caps = smb2cli_conn_server_capabilities(tree2->session->transport->conn); + if (!(caps & SMB2_CAP_LEASING)) { + torture_skip(tctx, "leases are not supported"); + } + + + smb2_util_unlink(tree1, fname); + + tree1->session->transport->lease.handler = torture_lease_handler; + tree1->session->transport->lease.private_data = tree1; + tree1->session->transport->oplock.handler = torture_oplock_handler; + tree1->session->transport->oplock.private_data = tree1; + + tree2->session->transport->lease.handler = torture_lease_handler; + tree2->session->transport->lease.private_data = tree2; + tree2->session->transport->oplock.handler = torture_oplock_handler; + tree2->session->transport->oplock.private_data = tree2; + + ZERO_STRUCT(break_info); + + smb2_lease_create_share(&io1, &ls1, false, fname, + smb2_util_share_access("RWD"), + LEASE1, + smb2_util_lease_state("RH")); + io2.in.create_disposition = NTCREATEX_DISP_CREATE; + status = smb2_create(tree1, mem_ctx, &io1); + CHECK_STATUS(status, NT_STATUS_OK); + h1 = io1.out.file.handle; + CHECK_CREATED(&io1, CREATED, FILE_ATTRIBUTE_ARCHIVE); + CHECK_LEASE(&io1, "RH", true, LEASE1, 0); + + /* + * a conflicting open just gets SHARING_VIOLATION, no break. + */ + smb2_lease_create_share(&io2, &ls2, false, fname, + smb2_util_share_access("R"), + LEASE1, + smb2_util_lease_state("RH")); + io2.in.create_disposition = NTCREATEX_DISP_OPEN; + status = smb2_create(tree2, mem_ctx, &io2); + CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION); + + CHECK_NO_BREAK(tctx); + + /* + * We now ask the server about the current lease state + * which should still be "RH". + */ + smb2_lease_create_share(&io3, &ls3, false, fname, + smb2_util_share_access("RWD"), + LEASE1, + smb2_util_lease_state("")); + io3.in.create_disposition = NTCREATEX_DISP_OPEN; + status = smb2_create(tree1, mem_ctx, &io3); + CHECK_STATUS(status, NT_STATUS_OK); + h3 = io3.out.file.handle; + CHECK_CREATED(&io3, EXISTED, FILE_ATTRIBUTE_ARCHIVE); + CHECK_LEASE(&io3, "RH", true, LEASE1, 0); + +done: + smb2_util_close(tree1, h1); + smb2_util_close(tree1, h3); + smb2_util_unlink(tree1, fname); + talloc_free(mem_ctx); + return ret; +} + + static bool test_lease_lock1(struct torture_context *tctx, struct smb2_tree *tree1a, struct smb2_tree *tree2) @@ -3827,6 +3916,7 @@ struct torture_suite *torture_smb2_lease_init(void) torture_suite_add_1smb2_test(suite, "breaking4", test_lease_breaking4); torture_suite_add_1smb2_test(suite, "breaking5", test_lease_breaking5); torture_suite_add_1smb2_test(suite, "breaking6", test_lease_breaking6); + torture_suite_add_2smb2_test(suite, "breaking7", test_lease_breaking7); torture_suite_add_2smb2_test(suite, "lock1", test_lease_lock1); torture_suite_add_1smb2_test(suite, "complex1", test_lease_complex1); torture_suite_add_1smb2_test(suite, "v2_request_parent",