The branch, master has been updated via cfebce3 s3:smbd: add debugging to close code (regarding disconnect of a durable) via 2954442 s4:torture: fix segfault in test_durable_open_open2_oplock() via 2f8a033 s4:torture:smb2: fix segfault on error condition in the durable-open.delete_on_close2 test via 1d3bd45 s4:torture:smb2: fix segfault on error condition in the durable-open.delete_on_close1 test via 98b0e90 s4:torture:smb2: fix segfault on error condition in the durable-open.reopen4 test via 10fcbc6 s4:torture:smb2: fix segfault on error condition in the durable-open.reopen3 test via cb9b897 s4:torture:smb2: fix segfault on error condition in the durable-open.reopen2a test via 6385f75 s4:torture:smb2: fix segfault on error condition in durable-open.reopen2 test via 6240a7d s4:torture:smb2:durable: make test functions static via 42bf98d s4:torture: add a durable-open-disconnect test (suite) via f0e6a9b s3:smbd: use smbXsrv_open_close() instead of smbXsrv_open_update() from 8adbd1c srv_epmapper.c: Fix typo.
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit cfebce3c56474ac914474b57ed94f93418b0564b Author: Michael Adam <ob...@samba.org> Date: Tue Feb 12 17:44:51 2013 +0100 s3:smbd: add debugging to close code (regarding disconnect of a durable) Signed-off-by: Michael Adam <ob...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> Autobuild-User(master): Stefan Metzmacher <me...@samba.org> Autobuild-Date(master): Mon Feb 18 17:42:45 CET 2013 on sn-devel-104 commit 295444266d33863e3a8b7c8ffa5d193123db6132 Author: Stefan Metzmacher <me...@samba.org> Date: Wed Feb 13 14:11:57 2013 +0100 s4:torture: fix segfault in test_durable_open_open2_oplock() Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Michael Adam <ob...@samba.org> commit 2f8a033bf2563d547e42be5603074223078595f9 Author: Michael Adam <ob...@samba.org> Date: Wed Feb 13 15:05:40 2013 +0100 s4:torture:smb2: fix segfault on error condition in the durable-open.delete_on_close2 test Signed-off-by: Michael Adam <ob...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit 1d3bd45d6177c8af653dbacac934eb2061acf35e Author: Michael Adam <ob...@samba.org> Date: Wed Feb 13 15:04:10 2013 +0100 s4:torture:smb2: fix segfault on error condition in the durable-open.delete_on_close1 test Signed-off-by: Michael Adam <ob...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit 98b0e909b7b65bee694743617476d4d36fe595a3 Author: Michael Adam <ob...@samba.org> Date: Wed Feb 13 15:03:00 2013 +0100 s4:torture:smb2: fix segfault on error condition in the durable-open.reopen4 test Signed-off-by: Michael Adam <ob...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit 10fcbc6869dc2803e1c2dd3183c6781f4233550d Author: Michael Adam <ob...@samba.org> Date: Wed Feb 13 15:01:47 2013 +0100 s4:torture:smb2: fix segfault on error condition in the durable-open.reopen3 test Signed-off-by: Michael Adam <ob...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit cb9b8975e5a9c032f7c4227c3eafb1ed6ada5e19 Author: Michael Adam <ob...@samba.org> Date: Wed Feb 13 15:00:26 2013 +0100 s4:torture:smb2: fix segfault on error condition in the durable-open.reopen2a test Signed-off-by: Michael Adam <ob...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit 6385f750f19a00a6ba16a0aec9bb91ab1cfcb2be Author: Michael Adam <ob...@samba.org> Date: Wed Feb 13 14:58:29 2013 +0100 s4:torture:smb2: fix segfault on error condition in durable-open.reopen2 test Signed-off-by: Michael Adam <ob...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit 6240a7d11e910027b42ac1d31ca13264e90d2266 Author: Michael Adam <ob...@samba.org> Date: Tue Feb 12 21:51:06 2013 +0100 s4:torture:smb2:durable: make test functions static Signed-off-by: Michael Adam <ob...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit 42bf98d54c36abd5f532a4510cdd4066fe82143d Author: Michael Adam <ob...@samba.org> Date: Tue Feb 12 17:45:23 2013 +0100 s4:torture: add a durable-open-disconnect test (suite) this opens a durable, disconnects it and exits Signed-off-by: Michael Adam <ob...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit f0e6a9be00e441e50f0087c543e1b7c9012d126f Author: Stefan Metzmacher <me...@samba.org> Date: Wed Feb 13 08:26:43 2013 -0500 s3:smbd: use smbXsrv_open_close() instead of smbXsrv_open_update() This makes sure we store the correct disconnect_time for disconnected durable handles. Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Michael Adam <ob...@samba.org> ----------------------------------------------------------------------- Summary of changes: selftest/skip | 1 + source3/smbd/close.c | 26 ++++- source4/torture/smb2/durable_open.c | 221 +++++++++++++++++++++++----------- source4/torture/smb2/smb2.c | 1 + 4 files changed, 176 insertions(+), 73 deletions(-) Changeset truncated at 500 lines: diff --git a/selftest/skip b/selftest/skip index 5c49306..6ea9b25 100644 --- a/selftest/skip +++ b/selftest/skip @@ -41,6 +41,7 @@ ^samba3.*raw.qfsinfo ^samba3.*raw.sfileinfo.base ^samba3.smb2.hold-oplock # Not a test, but a way to block other clients for a test +^samba3.smb2.durable-open-disconnect # Not a test, but a way to create a disconnected durable ^samba3.smb2.scan # No tests ^samba4.base.iometer ^samba4.base.casetable diff --git a/source3/smbd/close.c b/source3/smbd/close.c index 9b988e0..df3ae23 100644 --- a/source3/smbd/close.c +++ b/source3/smbd/close.c @@ -769,10 +769,31 @@ static NTSTATUS close_normal_file(struct smb_request *req, files_struct *fsp, fsp->op, &new_cookie); if (NT_STATUS_IS_OK(tmp)) { + struct timeval tv; + NTTIME now; + + if (req != NULL) { + tv = req->request_time; + } else { + tv = timeval_current(); + } + now = timeval_to_nttime(&tv); + data_blob_free(&fsp->op->global->backend_cookie); fsp->op->global->backend_cookie = new_cookie; - tmp = smbXsrv_open_update(fsp->op); + tmp = smbXsrv_open_close(fsp->op, now); + if (!NT_STATUS_IS_OK(tmp)) { + DEBUG(1, ("Failed to update smbXsrv_open " + "record when disconnecting durable " + "handle for file %s: %s - " + "proceeding with normal close\n", + fsp_str_dbg(fsp), nt_errstr(tmp))); + } + } else { + DEBUG(1, ("Failed to disconnect durable handle for " + "file %s: %s - proceeding with normal " + "close\n", fsp_str_dbg(fsp), nt_errstr(tmp))); } if (!NT_STATUS_IS_OK(tmp)) { is_durable = false; @@ -785,6 +806,9 @@ static NTSTATUS close_normal_file(struct smb_request *req, files_struct *fsp, * a durable handle and closed the underlying file. * In all other cases, we proceed with a genuine close. */ + DEBUG(10, ("%s disconnected durable handle for file %s\n", + conn->session_info->unix_info->unix_name, + fsp_str_dbg(fsp))); file_free(req, fsp); return NT_STATUS_OK; } diff --git a/source4/torture/smb2/durable_open.c b/source4/torture/smb2/durable_open.c index 5a61a56..e3d9185 100644 --- a/source4/torture/smb2/durable_open.c +++ b/source4/torture/smb2/durable_open.c @@ -163,8 +163,8 @@ done: return ret; } -bool test_durable_open_open_oplock(struct torture_context *tctx, - struct smb2_tree *tree) +static bool test_durable_open_open_oplock(struct torture_context *tctx, + struct smb2_tree *tree) { TALLOC_CTX *mem_ctx = talloc_new(tctx); char fname[256]; @@ -311,8 +311,8 @@ done: return ret; } -bool test_durable_open_open_lease(struct torture_context *tctx, - struct smb2_tree *tree) +static bool test_durable_open_open_lease(struct torture_context *tctx, + struct smb2_tree *tree) { TALLOC_CTX *mem_ctx = talloc_new(tctx); char fname[256]; @@ -356,8 +356,8 @@ done: * and do a durable reopen on the same connection * while the first open is still active (fails) */ -bool test_durable_open_reopen1(struct torture_context *tctx, - struct smb2_tree *tree) +static bool test_durable_open_reopen1(struct torture_context *tctx, + struct smb2_tree *tree) { NTSTATUS status; TALLOC_CTX *mem_ctx = talloc_new(tctx); @@ -412,8 +412,8 @@ done: * basic test for doing a durable open * tcp disconnect, reconnect, do a durable reopen (succeeds) */ -bool test_durable_open_reopen2(struct torture_context *tctx, - struct smb2_tree *tree) +static bool test_durable_open_reopen2(struct torture_context *tctx, + struct smb2_tree *tree) { NTSTATUS status; TALLOC_CTX *mem_ctx = talloc_new(tctx); @@ -466,13 +466,15 @@ bool test_durable_open_reopen2(struct torture_context *tctx, h = &_h; done: - if (h != NULL) { - smb2_util_close(tree, *h); - } + if (tree != NULL) { + if (h != NULL) { + smb2_util_close(tree, *h); + } - smb2_util_unlink(tree, fname); + smb2_util_unlink(tree, fname); - talloc_free(tree); + talloc_free(tree); + } talloc_free(mem_ctx); @@ -484,8 +486,8 @@ done: * tcp disconnect, reconnect with a session reconnect and * do a durable reopen (succeeds) */ -bool test_durable_open_reopen2a(struct torture_context *tctx, - struct smb2_tree *tree) +static bool test_durable_open_reopen2a(struct torture_context *tctx, + struct smb2_tree *tree) { NTSTATUS status; TALLOC_CTX *mem_ctx = talloc_new(tctx); @@ -539,13 +541,15 @@ bool test_durable_open_reopen2a(struct torture_context *tctx, h = &_h; done: - if (h != NULL) { - smb2_util_close(tree, *h); - } + if (tree != NULL) { + if (h != NULL) { + smb2_util_close(tree, *h); + } - smb2_util_unlink(tree, fname); + smb2_util_unlink(tree, fname); - talloc_free(tree); + talloc_free(tree); + } talloc_free(mem_ctx); @@ -557,8 +561,8 @@ done: * basic test for doing a durable open: * tdis, new tcon, try durable reopen (fails) */ -bool test_durable_open_reopen3(struct torture_context *tctx, - struct smb2_tree *tree) +static bool test_durable_open_reopen3(struct torture_context *tctx, + struct smb2_tree *tree) { NTSTATUS status; TALLOC_CTX *mem_ctx = talloc_new(tctx); @@ -607,13 +611,15 @@ bool test_durable_open_reopen3(struct torture_context *tctx, CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND); done: - if (h != NULL) { - smb2_util_close(tree, *h); - } + if (tree != NULL) { + if (h != NULL) { + smb2_util_close(tree, *h); + } - smb2_util_unlink(tree2, fname); + smb2_util_unlink(tree2, fname); - talloc_free(tree); + talloc_free(tree); + } talloc_free(mem_ctx); @@ -624,8 +630,8 @@ done: * basic test for doing a durable open: * logoff, create a new session, do a durable reopen (succeeds) */ -bool test_durable_open_reopen4(struct torture_context *tctx, - struct smb2_tree *tree) +static bool test_durable_open_reopen4(struct torture_context *tctx, + struct smb2_tree *tree) { NTSTATUS status; TALLOC_CTX *mem_ctx = talloc_new(tctx); @@ -701,21 +707,23 @@ bool test_durable_open_reopen4(struct torture_context *tctx, CHECK_VAL(io2.out.oplock_level, smb2_util_oplock_level("b")); done: - if (h != NULL) { - smb2_util_close(tree2, *h); - } + if (tree != NULL) { + if (h != NULL) { + smb2_util_close(tree2, *h); + } - smb2_util_unlink(tree2, fname); + smb2_util_unlink(tree2, fname); - talloc_free(tree); + talloc_free(tree); + } talloc_free(mem_ctx); return ret; } -bool test_durable_open_delete_on_close1(struct torture_context *tctx, - struct smb2_tree *tree) +static bool test_durable_open_delete_on_close1(struct torture_context *tctx, + struct smb2_tree *tree) { NTSTATUS status; TALLOC_CTX *mem_ctx = talloc_new(tctx); @@ -779,13 +787,15 @@ bool test_durable_open_delete_on_close1(struct torture_context *tctx, CHECK_VAL(io2.out.oplock_level, smb2_util_oplock_level("b")); done: - if (h != NULL) { - smb2_util_close(tree, *h); - } + if (tree != NULL) { + if (h != NULL) { + smb2_util_close(tree, *h); + } - smb2_util_unlink(tree, fname); + smb2_util_unlink(tree, fname); - talloc_free(tree); + talloc_free(tree); + } talloc_free(mem_ctx); @@ -793,8 +803,8 @@ done: } -bool test_durable_open_delete_on_close2(struct torture_context *tctx, - struct smb2_tree *tree) +static bool test_durable_open_delete_on_close2(struct torture_context *tctx, + struct smb2_tree *tree) { NTSTATUS status; TALLOC_CTX *mem_ctx = talloc_new(tctx); @@ -887,13 +897,15 @@ bool test_durable_open_delete_on_close2(struct torture_context *tctx, CHECK_VAL(io.out.oplock_level, smb2_util_oplock_level("b")); done: - if (h != NULL) { - smb2_util_close(tree, *h); - } + if (tree != NULL) { + if (h != NULL) { + smb2_util_close(tree, *h); + } - smb2_util_unlink(tree, fname); + smb2_util_unlink(tree, fname); - talloc_free(tree); + talloc_free(tree); + } talloc_free(mem_ctx); @@ -904,8 +916,8 @@ done: basic testing of SMB2 durable opens regarding the position information on the handle */ -bool test_durable_open_file_position(struct torture_context *tctx, - struct smb2_tree *tree) +static bool test_durable_open_file_position(struct torture_context *tctx, + struct smb2_tree *tree) { TALLOC_CTX *mem_ctx = talloc_new(tctx); struct smb2_handle h; @@ -1019,9 +1031,9 @@ done: /* Open, disconnect, oplock break, reconnect. */ -bool test_durable_open_oplock(struct torture_context *tctx, - struct smb2_tree *tree1, - struct smb2_tree *tree2) +static bool test_durable_open_oplock(struct torture_context *tctx, + struct smb2_tree *tree1, + struct smb2_tree *tree2) { TALLOC_CTX *mem_ctx = talloc_new(tctx); struct smb2_create io1, io2; @@ -1093,9 +1105,9 @@ bool test_durable_open_oplock(struct torture_context *tctx, /* Open, disconnect, lease break, reconnect. */ -bool test_durable_open_lease(struct torture_context *tctx, - struct smb2_tree *tree1, - struct smb2_tree *tree2) +static bool test_durable_open_lease(struct torture_context *tctx, + struct smb2_tree *tree1, + struct smb2_tree *tree2) { TALLOC_CTX *mem_ctx = talloc_new(tctx); struct smb2_create io1, io2; @@ -1194,8 +1206,8 @@ bool test_durable_open_lease(struct torture_context *tctx, return ret; } -bool test_durable_open_lock_oplock(struct torture_context *tctx, - struct smb2_tree *tree) +static bool test_durable_open_lock_oplock(struct torture_context *tctx, + struct smb2_tree *tree) { TALLOC_CTX *mem_ctx = talloc_new(tctx); struct smb2_create io; @@ -1275,8 +1287,8 @@ bool test_durable_open_lock_oplock(struct torture_context *tctx, /* Open, take BRL, disconnect, reconnect. */ -bool test_durable_open_lock_lease(struct torture_context *tctx, - struct smb2_tree *tree) +static bool test_durable_open_lock_lease(struct torture_context *tctx, + struct smb2_tree *tree) { TALLOC_CTX *mem_ctx = talloc_new(tctx); struct smb2_create io; @@ -1376,9 +1388,9 @@ bool test_durable_open_lock_lease(struct torture_context *tctx, * reconnect after an open, the oplock/lease tests above will certainly * demonstrate an error on reconnect. */ -bool test_durable_open_open2_lease(struct torture_context *tctx, - struct smb2_tree *tree1, - struct smb2_tree *tree2) +static bool test_durable_open_open2_lease(struct torture_context *tctx, + struct smb2_tree *tree1, + struct smb2_tree *tree2) { TALLOC_CTX *mem_ctx = talloc_new(tctx); struct smb2_create io1, io2; @@ -1478,9 +1490,9 @@ bool test_durable_open_open2_lease(struct torture_context *tctx, * reconnect after an open, the oplock/lease tests above will certainly * demonstrate an error on reconnect. */ -bool test_durable_open_open2_oplock(struct torture_context *tctx, - struct smb2_tree *tree1, - struct smb2_tree *tree2) +static bool test_durable_open_open2_oplock(struct torture_context *tctx, + struct smb2_tree *tree1, + struct smb2_tree *tree2) { TALLOC_CTX *mem_ctx = talloc_new(tctx); struct smb2_create io1, io2; @@ -1540,8 +1552,10 @@ bool test_durable_open_open2_oplock(struct torture_context *tctx, done: smb2_util_close(tree2, h2); smb2_util_unlink(tree2, fname); - smb2_util_close(tree1, h1); - smb2_util_unlink(tree1, fname); + if (tree1 != NULL) { + smb2_util_close(tree1, h1); + smb2_util_unlink(tree1, fname); + } talloc_free(tree1); talloc_free(tree2); @@ -1552,8 +1566,8 @@ bool test_durable_open_open2_oplock(struct torture_context *tctx, /** * test behaviour with initial allocation size */ -bool test_durable_open_alloc_size(struct torture_context *tctx, - struct smb2_tree *tree) +static bool test_durable_open_alloc_size(struct torture_context *tctx, + struct smb2_tree *tree) { NTSTATUS status; TALLOC_CTX *mem_ctx = talloc_new(tctx); @@ -1693,8 +1707,8 @@ done: /** * test behaviour when a disconnect happens while creating a read-only file */ -bool test_durable_open_read_only(struct torture_context *tctx, - struct smb2_tree *tree) +static bool test_durable_open_read_only(struct torture_context *tctx, + struct smb2_tree *tree) { NTSTATUS status; TALLOC_CTX *mem_ctx = talloc_new(tctx); @@ -1784,6 +1798,54 @@ done: return ret; } +/** + * durable open with oplock, disconnect, exit + */ +static bool test_durable_open_oplock_disconnect(struct torture_context *tctx, + struct smb2_tree *tree) +{ + TALLOC_CTX *mem_ctx = talloc_new(tctx); + struct smb2_create io; + struct smb2_handle _h; + struct smb2_handle *h = NULL; + NTSTATUS status; + char fname[256]; + bool ret = true; + + snprintf(fname, 256, "durable_open_oplock_disconnect_%s.dat", + generate_random_str(tctx, 8)); + + smb2_util_unlink(tree, fname); + + smb2_oplock_create(&io, fname, SMB2_OPLOCK_LEVEL_BATCH); + io.in.durable_open = true; + + status = smb2_create(tree, mem_ctx, &io); + CHECK_STATUS(status, NT_STATUS_OK); + + _h = io.out.file.handle; + h = &_h; + + CHECK_CREATED(&io, CREATED, FILE_ATTRIBUTE_ARCHIVE); + CHECK_VAL(io.out.durable_open, true); + CHECK_VAL(io.out.oplock_level, SMB2_OPLOCK_LEVEL_BATCH); + + /* disconnect */ + talloc_free(tree); + tree = NULL; + +done: + if (tree != NULL) { + if (h != NULL) { + smb2_util_close(tree, *h); + } + smb2_util_unlink(tree, fname); + } + + return ret; +} + + struct torture_suite *torture_smb2_durable_open_init(void) { struct torture_suite *suite = @@ -1819,3 +1881,18 @@ struct torture_suite *torture_smb2_durable_open_init(void) return suite; } + +struct torture_suite *torture_smb2_durable_open_disconnect_init(void) +{ + struct torture_suite *suite = + torture_suite_create(talloc_autofree_context(), + "durable-open-disconnect"); + + torture_suite_add_1smb2_test(suite, "open-oplock-disconnect", + test_durable_open_oplock_disconnect); + + suite->description = talloc_strdup(suite, + "SMB2-DURABLE-OPEN-DISCONNECT tests"); + + return suite; +} diff --git a/source4/torture/smb2/smb2.c b/source4/torture/smb2/smb2.c index a396a2e..65dc924 100644 --- a/source4/torture/smb2/smb2.c +++ b/source4/torture/smb2/smb2.c @@ -156,6 +156,7 @@ NTSTATUS torture_smb2_init(void) torture_suite_add_suite(suite, torture_smb2_acls_init()); torture_suite_add_suite(suite, torture_smb2_notify_init()); torture_suite_add_suite(suite, torture_smb2_durable_open_init()); + torture_suite_add_suite(suite, torture_smb2_durable_open_disconnect_init()); torture_suite_add_suite(suite, torture_smb2_durable_v2_open_init()); torture_suite_add_suite(suite, torture_smb2_dir_init()); torture_suite_add_suite(suite, torture_smb2_lease_init()); -- Samba Shared Repository