From f97216eb4ae1052e435d83ce51a7067fa6697ff4 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 5 Jan 2012 17:44:44 +0100 Subject: [PATCH] s3: Add a test for proper brlock cleanup We need to improve the server here. Maybe we should validate the brlock entry whenever we detect a read/write being blocked from locking? This is not our hot code path anyway, and it would gain us significant robustness. The code might become quite a bit simpler as well. --- source3/torture/proto.h | 1 + source3/torture/test_cleanup.c | 87 ++++++++++++++++++++++++++++++++++ source3/torture/torture.c | 1 + 3 files changed, 89 insertions(+) diff --git a/source3/torture/proto.h b/source3/torture/proto.h index 19e7a72a70..8d661aada9 100644 --- a/source3/torture/proto.h +++ b/source3/torture/proto.h @@ -102,5 +102,6 @@ bool run_smb2_session_reauth(int dummy); bool run_local_conv_auth_info(int dummy); bool run_local_sprintf_append(int dummy); bool run_cleanup1(int dummy); +bool run_cleanup2(int dummy); #endif /* __TORTURE_H__ */ diff --git a/source3/torture/test_cleanup.c b/source3/torture/test_cleanup.c index 4e89893bcd..2b4989e48b 100644 --- a/source3/torture/test_cleanup.c +++ b/source3/torture/test_cleanup.c @@ -22,6 +22,7 @@ #include "system/filesys.h" #include "libsmb/libsmb.h" #include "libcli/smb/smbXcli_base.h" +#include "libcli/security/security.h" bool run_cleanup1(int dummy) { @@ -68,3 +69,89 @@ done: torture_close_connection(cli); return NT_STATUS_IS_OK(status); } + +bool run_cleanup2(int dummy) +{ + struct cli_state *cli1, *cli2; + const char *fname = "\\cleanup2"; + uint16_t fnum1, fnum2; + NTSTATUS status; + char buf; + + printf("CLEANUP2: Checking that a conflicting brlock is cleaned up\n"); + + if (!torture_open_connection(&cli1, 0)) { + return false; + } + status = cli_ntcreate( + cli1, fname, 0, FILE_GENERIC_READ|FILE_GENERIC_WRITE, + FILE_ATTRIBUTE_NORMAL, + FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, + FILE_OVERWRITE_IF, 0, 0, &fnum1); + if (!NT_STATUS_IS_OK(status)) { + printf("open of %s failed (%s)\n", fname, nt_errstr(status)); + return false; + } + status = cli_lock32(cli1, fnum1, 0, 1, 0, WRITE_LOCK); + if (!NT_STATUS_IS_OK(status)) { + printf("lock failed (%s)\n", nt_errstr(status)); + return false; + } + + /* + * Check the file is indeed locked + */ + if (!torture_open_connection(&cli2, 0)) { + return false; + } + status = cli_ntcreate( + cli2, fname, 0, FILE_GENERIC_READ|FILE_GENERIC_WRITE, + FILE_ATTRIBUTE_NORMAL, + FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, + FILE_OPEN, 0, 0, &fnum2); + if (!NT_STATUS_IS_OK(status)) { + printf("open of %s failed (%s)\n", fname, nt_errstr(status)); + return false; + } + buf = 'x'; + status = cli_smbwrite(cli2, fnum2, &buf, 0, 1, NULL); + if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) { + printf("write succeeded\n"); + return false; + } + + /* + * Kill the lock holder + */ + status = smbXcli_conn_samba_suicide(cli1->conn, 1); + if (!NT_STATUS_IS_OK(status)) { + printf("smbXcli_conn_samba_suicide failed: %s\n", + nt_errstr(status)); + return false; + } + + /* + * Right now we don't clean up immediately. Re-open the 2nd connection. + */ +#if 1 + cli_shutdown(cli2); + if (!torture_open_connection(&cli2, 0)) { + return false; + } + status = cli_ntcreate( + cli2, fname, 0, FILE_GENERIC_READ|FILE_GENERIC_WRITE, + FILE_ATTRIBUTE_NORMAL, + FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, + FILE_OPEN, 0, 0, &fnum2); + if (!NT_STATUS_IS_OK(status)) { + printf("open of %s failed (%s)\n", fname, nt_errstr(status)); + return false; + } +#endif + status = cli_smbwrite(cli2, fnum2, &buf, 0, 1, NULL); + if (!NT_STATUS_IS_OK(status)) { + printf("write failed: %s\n", nt_errstr(status)); + return false; + } + return true; +} diff --git a/source3/torture/torture.c b/source3/torture/torture.c index 9d18f72271..8535333a28 100644 --- a/source3/torture/torture.c +++ b/source3/torture/torture.c @@ -8880,6 +8880,7 @@ static struct { { "SMB2-MULTI-CHANNEL", run_smb2_multi_channel }, { "SMB2-SESSION-REAUTH", run_smb2_session_reauth }, { "CLEANUP1", run_cleanup1 }, + { "CLEANUP2", run_cleanup2 }, { "LOCAL-SUBSTITUTE", run_local_substitute, 0}, { "LOCAL-GENCACHE", run_local_gencache, 0}, { "LOCAL-TALLOC-DICT", run_local_talloc_dict, 0}, -- 2.34.1