From 3dc532cbe0fd2b3314b832f5d73d09a86e241fe7 Mon Sep 17 00:00:00 2001 From: Sachin Prabhu Date: Thu, 28 Feb 2019 12:51:02 +0000 Subject: [PATCH] s4-torture: Add handlers to block channels for testing We use two methods to block channels 1) Simply ignore incoming oplock break requests and do not respond to them. This method doesn't work against Microsoft Windows based servers which rely on the tcp stack for confirmation that the oplock break command was sent to the client machine. This is meant to be used with samba servers and is the default method. 2) Use iptables to block the channel. The method requires the use of a privileged account and can only be used on Linux systems with iptables installed. To use this blocking method, pass the option --option=torture:use_iptables=true Signed-off-by: Guenther Deschner Signed-off-by: Sachin Prabhu Reviewed-by: Jeremy Allison --- source4/torture/smb2/multichannel.c | 97 +++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) diff --git a/source4/torture/smb2/multichannel.c b/source4/torture/smb2/multichannel.c index 5207fa453da..4a490f04c97 100644 --- a/source4/torture/smb2/multichannel.c +++ b/source4/torture/smb2/multichannel.c @@ -30,6 +30,8 @@ #include "../libcli/smb/smbXcli_base.h" #include "libcli/resolve/resolve.h" #include "lib/param/param.h" +#include "oplock_break_handler.h" +#include "torture/smb2/block.h" #define BASEDIR "multichanneltestdir" @@ -302,6 +304,101 @@ static void test_multichannel_free_channels(struct smb2_tree *tree2A, TALLOC_FREE(tree2C); } +/* + * 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, + struct smb2_transport *transport, + const char *name) +{ + uint16_t local_port; + bool ret; + + local_port = torture_get_local_port_from_transport(transport); + torture_comment(tctx, "transport uses tcp port: %d\n", local_port); + ret = torture_block_tcp_transport_name(tctx, transport, name); + torture_assert(tctx, ret, "we could not block tcp transport"); + + return ret; +} + +static bool test_iptables_unblock_channel(struct torture_context *tctx, + struct smb2_transport *transport, + const char *name) +{ + uint16_t local_port; + bool ret; + + local_port = torture_get_local_port_from_transport(transport); + torture_comment(tctx, "transport uses tcp port: %d\n", local_port); + ret = torture_unblock_tcp_transport_name(tctx, transport, name); + torture_assert(tctx, ret, "we could not block tcp transport"); + + return ret; +} + +#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, + const char *name) +{ + bool use_iptables = torture_setting_bool(tctx, + "use_iptables", false); + + if (use_iptables) { + return test_iptables_block_channel(tctx, transport, name); + } else { + return test_set_ignore_break_handler(tctx, transport); + } +} + +#define test_unblock_channel(_tctx, _t) _test_unblock_channel(_tctx, _t, #_t) +static bool _test_unblock_channel(struct torture_context *tctx, + struct smb2_transport *transport, + const char *name) +{ + bool use_iptables = torture_setting_bool(tctx, + "use_iptables", false); + + if (use_iptables) { + return test_iptables_unblock_channel(tctx, transport, name); + } else { + return test_reset_break_handler(tctx, transport); + } +} + +static void test_cleanup_blocked_channels(struct torture_context *tctx) +{ + bool use_iptables = torture_setting_bool(tctx, + "use_iptables", false); + + if (use_iptables) { + torture_unblock_cleanup(tctx); + } +} + struct torture_suite *torture_smb2_multichannel_init(TALLOC_CTX *ctx) { struct torture_suite *suite = torture_suite_create(ctx, "multichannel"); -- 2.34.1