summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2020-06-08 16:33:45 +0200
committerStefan Metzmacher <metze@samba.org>2020-07-08 15:54:39 +0000
commit68a351b7620a87fc8191666e49058cbfdee62e67 (patch)
treeee52a0933777348a7e43b3b025aad54c33fa9685
parent8c7bb245ff84b1603935c45969c3bec004dff335 (diff)
downloadsamba-68a351b7620a87fc8191666e49058cbfdee62e67.tar.gz
s4:torture/smb2: make use of FSCTL_SMBTORTURE_FORCE_UNACKED_TIMEOUT
This is a way to test without being able to use iptables. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11897 Signed-off-by: Stefan Metzmacher <metze@samba.org> Reviewed-by: Günther Deschner <gd@samba.org>
-rw-r--r--source4/torture/smb2/multichannel.c155
1 files changed, 131 insertions, 24 deletions
diff --git a/source4/torture/smb2/multichannel.c b/source4/torture/smb2/multichannel.c
index 7cf39dadbe3..3742cb8bac8 100644
--- a/source4/torture/smb2/multichannel.c
+++ b/source4/torture/smb2/multichannel.c
@@ -36,6 +36,7 @@
#include "oplock_break_handler.h"
#include "lease_break_handler.h"
#include "torture/smb2/block.h"
+#include "lib/util/tevent_ntstatus.h"
#define BASEDIR "multichanneltestdir"
@@ -367,28 +368,6 @@ static void test_multichannel_init_smb_create(struct smb2_create *io)
}
/*
- * We simulate blocking incoming oplock break requests by simply ignoring
- * the incoming break requests.
- */
-static bool test_set_ignore_break_handler(struct torture_context *tctx,
- struct smb2_transport *transport)
-{
- transport->oplock.handler = torture_oplock_ignore_handler;
- transport->lease.handler = torture_lease_ignore_handler;
-
- return true;
-}
-
-static bool test_reset_break_handler(struct torture_context *tctx,
- struct smb2_transport *transport)
-{
- transport->oplock.handler = torture_oplock_ack_handler;
- transport->lease.handler = torture_lease_handler;
-
- return true;
-}
-
-/*
* Use iptables to block channels
*/
static bool test_iptables_block_channel(struct torture_context *tctx,
@@ -421,6 +400,134 @@ static bool test_iptables_unblock_channel(struct torture_context *tctx,
return ret;
}
+static bool torture_blocked_lease_handler(struct smb2_transport *transport,
+ const struct smb2_lease_break *lb,
+ void *private_data)
+{
+ struct smb2_transport *transport_copy =
+ talloc_get_type_abort(private_data,
+ struct smb2_transport);
+ bool lease_skip_ack = lease_break_info.lease_skip_ack;
+ bool ok;
+
+ lease_break_info.lease_skip_ack = true;
+ ok = transport_copy->lease.handler(transport,
+ lb,
+ transport_copy->lease.private_data);
+ lease_break_info.lease_skip_ack = lease_skip_ack;
+
+ if (!ok) {
+ return false;
+ }
+
+ if (lease_break_info.lease_skip_ack) {
+ return true;
+ }
+
+ if (lb->break_flags & SMB2_NOTIFY_BREAK_LEASE_FLAG_ACK_REQUIRED) {
+ lease_break_info.failures++;
+ }
+
+ return true;
+}
+
+static bool torture_blocked_oplock_handler(struct smb2_transport *transport,
+ const struct smb2_handle *handle,
+ uint8_t level,
+ void *private_data)
+{
+ struct smb2_transport *transport_copy =
+ talloc_get_type_abort(private_data,
+ struct smb2_transport);
+ bool oplock_skip_ack = break_info.oplock_skip_ack;
+ bool ok;
+
+ break_info.oplock_skip_ack = true;
+ ok = transport_copy->oplock.handler(transport,
+ handle,
+ level,
+ transport_copy->oplock.private_data);
+ break_info.oplock_skip_ack = oplock_skip_ack;
+
+ if (!ok) {
+ return false;
+ }
+
+ if (break_info.oplock_skip_ack) {
+ return true;
+ }
+
+ break_info.failures++;
+ break_info.failure_status = NT_STATUS_CONNECTION_DISCONNECTED;
+
+ return true;
+}
+
+static bool test_block_smb2_transport_fsctl_smbtorture(struct torture_context *tctx,
+ struct smb2_transport *transport,
+ const char *name)
+{
+ struct smb2_transport *transport_copy = NULL;
+ DATA_BLOB in_input_buffer = data_blob_null;
+ DATA_BLOB in_output_buffer = data_blob_null;
+ DATA_BLOB out_input_buffer = data_blob_null;
+ DATA_BLOB out_output_buffer = data_blob_null;
+ struct tevent_req *req = NULL;
+ uint16_t local_port;
+ NTSTATUS status;
+ bool ok;
+
+ transport_copy = talloc_zero(transport, struct smb2_transport);
+ torture_assert(tctx, transport_copy, "talloc transport_copy");
+ transport_copy->lease = transport->lease;
+ transport_copy->oplock = transport->oplock;
+
+ local_port = torture_get_local_port_from_transport(transport);
+ torture_comment(tctx, "transport[%s] uses tcp port: %d\n", name, local_port);
+ req = smb2cli_ioctl_send(tctx,
+ tctx->ev,
+ transport->conn,
+ 1000, /* timeout_msec */
+ NULL, /* session */
+ NULL, /* tcon */
+ UINT64_MAX, /* in_fid_persistent */
+ UINT64_MAX, /* in_fid_volatile */
+ FSCTL_SMBTORTURE_FORCE_UNACKED_TIMEOUT,
+ 0, /* in_max_input_length */
+ &in_input_buffer,
+ 0, /* in_max_output_length */
+ &in_output_buffer,
+ SMB2_IOCTL_FLAG_IS_FSCTL);
+ torture_assert(tctx, req != NULL, "smb2cli_ioctl_send() failed");
+ ok = tevent_req_poll_ntstatus(req, tctx->ev, &status);
+ if (ok) {
+ status = NT_STATUS_OK;
+ }
+ torture_assert_ntstatus_ok(tctx, status, "tevent_req_poll_ntstatus() failed");
+ status = smb2cli_ioctl_recv(req, tctx,
+ &out_input_buffer,
+ &out_output_buffer);
+ torture_assert_ntstatus_ok(tctx, status,
+ "FSCTL_SMBTORTURE_FORCE_UNACKED_TIMEOUT failed\n\n"
+ "On a Samba server 'smbd:FSCTL_SMBTORTURE = yes' is needed!\n\n"
+ "Otherwise you may need to use iptables like this:\n"
+ "--option='torture:use_iptables=yes'\n"
+ "And maybe something like this in addition:\n"
+ "--option='torture:iptables_command=sudo /sbin/iptables'\n\n");
+ TALLOC_FREE(req);
+
+ if (transport->lease.handler != NULL) {
+ transport->lease.handler = torture_blocked_lease_handler;
+ transport->lease.private_data = transport_copy;
+ }
+ if (transport->oplock.handler != NULL) {
+ transport->oplock.handler = torture_blocked_oplock_handler;
+ transport->oplock.private_data = transport_copy;
+ }
+
+ return true;
+}
+
#define test_block_channel(_tctx, _t) _test_block_channel(_tctx, _t, #_t)
static bool _test_block_channel(struct torture_context *tctx,
struct smb2_transport *transport,
@@ -432,7 +539,7 @@ static bool _test_block_channel(struct torture_context *tctx,
if (use_iptables) {
return test_iptables_block_channel(tctx, transport, name);
} else {
- return test_set_ignore_break_handler(tctx, transport);
+ return test_block_smb2_transport_fsctl_smbtorture(tctx, transport, name);
}
}
@@ -447,7 +554,7 @@ static bool _test_unblock_channel(struct torture_context *tctx,
if (use_iptables) {
return test_iptables_unblock_channel(tctx, transport, name);
} else {
- return test_reset_break_handler(tctx, transport);
+ return true;
}
}