From e6c54dc4a853c7b323dd2a53a17f1b1e0dc39872 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 4 Dec 2014 10:13:47 -0800 Subject: [PATCH 1/3] s3: leases: Add leases_db_rename() to cope with renaming a leased file. Signed-off-by: Jeremy Allison --- source3/locking/leases_db.c | 22 ++++++++++++++++++++++ source3/locking/leases_db.h | 6 +++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/source3/locking/leases_db.c b/source3/locking/leases_db.c index 67c93ff..7e000aa 100644 --- a/source3/locking/leases_db.c +++ b/source3/locking/leases_db.c @@ -385,3 +385,25 @@ NTSTATUS leases_db_parse(const struct GUID *client_guid, } return state.status; } + +NTSTATUS leases_db_rename(const struct GUID *client_guid, + const struct smb2_lease_key *lease_key, + const struct file_id *id, + const char *filename_new, + const char *stream_name_new) +{ + NTSTATUS status; + + status = leases_db_del(client_guid, + lease_key, + id); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + return leases_db_add(client_guid, + lease_key, + id, + filename_new, + stream_name_new); +} diff --git a/source3/locking/leases_db.h b/source3/locking/leases_db.h index f570356..906a99b 100644 --- a/source3/locking/leases_db.h +++ b/source3/locking/leases_db.h @@ -42,5 +42,9 @@ NTSTATUS leases_db_parse(const struct GUID *client_guid, const char *stream_name, void *private_data), void *private_data); - +NTSTATUS leases_db_rename(const struct GUID *client_guid, + const struct smb2_lease_key *lease_key, + const struct file_id *id, + const char *filename_new, + const char *stream_name_new); #endif /* _LEASES_DB_H_ */ -- 2.2.0.rc0.207.ga3a616c From 9d5e357aec627e9f0952a5c613fe5fa3af24ef98 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 4 Dec 2014 10:14:23 -0800 Subject: [PATCH 2/3] s3: leases : Cope with renaming leased open files. Signed-off-by: Jeremy Allison --- source3/locking/locking.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/source3/locking/locking.c b/source3/locking/locking.c index d144f5c..4ff23f2 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -471,7 +471,7 @@ bool rename_share_filename(struct messaging_context *msg_ctx, size_t sn_len; size_t msg_len; char *frm = NULL; - int i; + uint32_t i; bool strip_two_chars = false; bool has_stream = smb_fname_dst->stream_name != NULL; struct server_id self_pid = messaging_server_id(msg_ctx); @@ -565,6 +565,29 @@ bool rename_share_filename(struct messaging_context *msg_ctx, (uint8 *)frm, msg_len); } + for (i=0; inum_leases; i++) { + /* Update the filename in leases_db. */ + NTSTATUS status; + struct share_mode_lease *l; + + l = &d->leases[i]; + + status = leases_db_rename(&l->client_guid, + &l->lease_key, + &id, + d->base_name, + d->stream_name); + if (!NT_STATUS_IS_OK(status)) { + /* Any error recovery possible here ? */ + DEBUG(10,("Failed to rename lease key for " + "renamed file %s:%s. %s\n", + d->base_name, + d->stream_name, + nt_errstr(status))); + continue; + } + } + return True; } -- 2.2.0.rc0.207.ga3a616c From 124b079f88874d767b6656cdc8fa1ca6ee1550f3 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 4 Dec 2014 10:14:59 -0800 Subject: [PATCH 3/3] s4: torture: leases. Simple lease_v2 rename test "v2_rename". iWith the previous 2 patches we now pass this (as does Windows 2012 :-). Signed-off-by: Jeremy Allison --- source4/torture/smb2/lease.c | 86 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/source4/torture/smb2/lease.c b/source4/torture/smb2/lease.c index 9d14aeb..375b1a8 100644 --- a/source4/torture/smb2/lease.c +++ b/source4/torture/smb2/lease.c @@ -3483,6 +3483,91 @@ static bool test_lease_timeout(struct torture_context *tctx, return ret; } +static bool test_lease_v2_rename(struct torture_context *tctx, + struct smb2_tree *tree) +{ + TALLOC_CTX *mem_ctx = talloc_new(tctx); + struct smb2_create io; + struct smb2_lease ls; + struct smb2_handle h, h1; + union smb_setfileinfo sinfo; + const char *fname = "lease_v2_rename_src.dat"; + const char *fname_dst = "lease_v2_rename_dst.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); + smb2_util_unlink(tree, fname_dst); + + 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, &ls, false, fname, + smb2_util_share_access("RWD"), + LEASE1, NULL, + smb2_util_lease_state("RHW"), + 0x4711); + status = smb2_create(tree, mem_ctx, &io); + CHECK_STATUS(status, NT_STATUS_OK); + h = io.out.file.handle; + CHECK_CREATED(&io, CREATED, FILE_ATTRIBUTE_ARCHIVE); + ls.lease_epoch += 1; + CHECK_LEASE_V2(&io, "RHW", true, LEASE1, 0, 0, ls.lease_epoch); + + /* Now rename - what happens ? */ + ZERO_STRUCT(sinfo); + sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION; + sinfo.rename_information.in.file.handle = h; + sinfo.rename_information.in.overwrite = true; + sinfo.rename_information.in.new_name = fname_dst; + status = smb2_setinfo_file(tree, &sinfo); + CHECK_STATUS(status, NT_STATUS_OK); + + /* No lease break. */ + CHECK_NO_BREAK(tctx); + + /* Check we can open another handle on the new name. */ + smb2_lease_v2_create_share(&io, &ls, false, fname_dst, + smb2_util_share_access("RWD"), + LEASE1, NULL, + smb2_util_lease_state(""), + ls.lease_epoch); + status = smb2_create(tree, mem_ctx, &io); + CHECK_STATUS(status, NT_STATUS_OK); + h1 = io.out.file.handle; + CHECK_CREATED(&io, EXISTED, FILE_ATTRIBUTE_ARCHIVE); + CHECK_LEASE_V2(&io, "RHW", true, LEASE1, 0, 0, ls.lease_epoch); + smb2_util_close(tree, h1); + +done: + + smb2_util_close(tree, h); + smb2_util_unlink(tree, fname); + smb2_util_unlink(tree, fname_dst); + + smb2_util_unlink(tree, fname); + talloc_free(mem_ctx); + return ret; +} + + static bool test_lease_dynamic_share(struct torture_context *tctx, struct smb2_tree *tree1a) { @@ -3704,6 +3789,7 @@ struct torture_suite *torture_smb2_lease_init(void) torture_suite_add_1smb2_test(suite, "v2_epoch3", test_lease_v2_epoch3); torture_suite_add_1smb2_test(suite, "v2_complex1", test_lease_v2_complex1); torture_suite_add_1smb2_test(suite, "v2_complex2", test_lease_v2_complex2); + torture_suite_add_1smb2_test(suite, "v2_rename", test_lease_v2_rename); torture_suite_add_1smb2_test(suite, "dynamic_share", test_lease_dynamic_share); torture_suite_add_1smb2_test(suite, "timeout", test_lease_timeout); -- 2.2.0.rc0.207.ga3a616c