]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
s4:torture/smb2: move smb2_transport blocking to the generic block.[ch]
authorStefan Metzmacher <metze@samba.org>
Mon, 22 Jun 2020 15:30:28 +0000 (17:30 +0200)
committerStefan Metzmacher <metze@samba.org>
Wed, 8 Jul 2020 15:54:39 +0000 (15:54 +0000)
We may want to use this in other places too, not only multichannel.c

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>
source4/torture/smb2/block.c
source4/torture/smb2/block.h
source4/torture/smb2/multichannel.c

index d0cb934adf98e56cb4c3fcfe7dfe8688a8e3c3c8..b9982b0574d675c5b44bbba1690bbf66056e2b04 100644 (file)
@@ -27,6 +27,9 @@
 #include "lib/util/util_net.h"
 #include "torture/smb2/block.h"
 #include "libcli/smb/smbXcli_base.h"
+#include "lib/util/tevent_ntstatus.h"
+#include "oplock_break_handler.h"
+#include "lease_break_handler.h"
 
 /*
  * OUTPUT
@@ -230,3 +233,214 @@ bool torture_unblock_tcp_output_cleanup(struct torture_context *tctx)
 {
        return iptables_setup_chain(tctx, "OUTPUT", "SMBTORTURE_OUTPUT", true);
 }
+
+/*
+ * Use iptables to block channels
+ */
+static bool test_block_smb2_transport_iptables(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[%s] uses tcp port: %d\n", name, local_port);
+       ret = torture_block_tcp_output_port(tctx, name, local_port);
+       torture_assert(tctx, ret, "we could not block tcp transport");
+
+       return ret;
+}
+
+static bool test_unblock_smb2_transport_iptables(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[%s] uses tcp port: %d\n", name, local_port);
+       ret = torture_unblock_tcp_output_port(tctx, name, local_port);
+       torture_assert(tctx, ret, "we could not block tcp transport");
+
+       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;
+}
+
+bool _test_block_smb2_transport(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_block_smb2_transport_iptables(tctx, transport, name);
+       } else {
+               return test_block_smb2_transport_fsctl_smbtorture(tctx, transport, name);
+       }
+}
+
+bool _test_unblock_smb2_transport(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_unblock_smb2_transport_iptables(tctx, transport, name);
+       } else {
+               return true;
+       }
+}
+
+bool test_setup_blocked_transports(struct torture_context *tctx)
+{
+       bool use_iptables = torture_setting_bool(tctx,
+                                       "use_iptables", false);
+
+       if (use_iptables) {
+               return torture_block_tcp_output_setup(tctx);
+       }
+
+       return true;
+}
+
+void test_cleanup_blocked_transports(struct torture_context *tctx)
+{
+       bool use_iptables = torture_setting_bool(tctx,
+                                       "use_iptables", false);
+
+       if (use_iptables) {
+               torture_unblock_tcp_output_cleanup(tctx);
+       }
+}
index 7f36b89a6935d499e0dae960fad3adf822ebd00d..6a6370a1ab580d609b02566d246e82973917df86 100644 (file)
@@ -30,3 +30,14 @@ bool torture_unblock_tcp_output_port(struct torture_context *tctx,
 bool torture_block_tcp_output_setup(struct torture_context *tctx);
 bool torture_unblock_tcp_output_cleanup(struct torture_context *tctx);
 
+bool test_setup_blocked_transports(struct torture_context *tctx);
+void test_cleanup_blocked_transports(struct torture_context *tctx);
+
+#define test_block_smb2_transport(_tctx, _t) _test_block_smb2_transport(_tctx, _t, #_t)
+bool _test_block_smb2_transport(struct torture_context *tctx,
+                               struct smb2_transport *transport,
+                               const char *name);
+#define test_unblock_smb2_transport(_tctx, _t) _test_unblock_smb2_transport(_tctx, _t, #_t)
+bool _test_unblock_smb2_transport(struct torture_context *tctx,
+                                 struct smb2_transport *transport,
+                                 const char *name);
index 3742cb8bac8717412207614879e486ffb172643c..3e29c7d02a9d81396c7ff7737fb8bd6bafaec967 100644 (file)
@@ -36,7 +36,6 @@
 #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,219 +366,6 @@ static void test_multichannel_init_smb_create(struct smb2_create *io)
        /* windows 2016 returns 300000 0x493E0 */
 }
 
-/*
- * 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[%s] uses tcp port: %d\n", name, local_port);
-       ret = torture_block_tcp_output_port(tctx, name, local_port);
-       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[%s] uses tcp port: %d\n", name, local_port);
-       ret = torture_unblock_tcp_output_port(tctx, name, local_port);
-       torture_assert(tctx, ret, "we could not block tcp transport");
-
-       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,
-                                         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_block_smb2_transport_fsctl_smbtorture(tctx, transport, name);
-       }
-}
-
-#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 true;
-       }
-}
-
-static bool test_setup_blocked_channels(struct torture_context *tctx)
-{
-       bool use_iptables = torture_setting_bool(tctx,
-                                       "use_iptables", false);
-
-       if (use_iptables) {
-               return torture_block_tcp_output_setup(tctx);
-       }
-
-       return true;
-}
-
-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_tcp_output_cleanup(tctx);
-       }
-}
-
 /* Timer handler function notifies the registering function that time is up */
 static void timeout_cb(struct tevent_context *ev,
                       struct tevent_timer *te,
@@ -899,11 +685,11 @@ static bool test_multichannel_oplock_break_test2(struct torture_context *tctx,
        transport2 = break_info.received_transport;
        torture_reset_break_info(tctx, &break_info);
 
-       block_setup = test_setup_blocked_channels(tctx);
-       torture_assert(tctx, block_setup, "test_setup_blocked_channels");
+       block_setup = test_setup_blocked_transports(tctx);
+       torture_assert(tctx, block_setup, "test_setup_blocked_transports");
 
        /* block channel */
-       block_ok = test_block_channel(tctx, transport2);
+       block_ok = test_block_smb2_transport(tctx, transport2);
 
        torture_comment(tctx, "client1 opens fname2 via session 1\n");
        io2.in.oplock_level = smb2_util_oplock_level("b");
@@ -987,9 +773,9 @@ static bool test_multichannel_oplock_break_test2(struct torture_context *tctx,
 
 done:
        if (block_ok && !unblock_ok) {
-               test_unblock_channel(tctx, transport2);
+               test_unblock_smb2_transport(tctx, transport2);
        }
-       test_cleanup_blocked_channels(tctx);
+       test_cleanup_blocked_transports(tctx);
 
        tree1->session = session1;
 
@@ -1355,12 +1141,12 @@ static bool test_multichannel_lease_break_test2(struct torture_context *tctx,
        CHECK_VAL(io2.out.durable_open, false);
        CHECK_VAL(lease_break_info.count, 0);
 
-       block_setup = test_setup_blocked_channels(tctx);
-       torture_assert(tctx, block_setup, "test_setup_blocked_channels");
+       block_setup = test_setup_blocked_transports(tctx);
+       torture_assert(tctx, block_setup, "test_setup_blocked_transports");
 
        torture_comment(tctx, "Blocking 2A\n");
        /* Block 2A */
-       block_ok = test_block_channel(tctx, transport2A);
+       block_ok = test_block_smb2_transport(tctx, transport2A);
        torture_assert(tctx, block_ok, "we could not block tcp transport");
 
        /* 1 opens file2 */
@@ -1414,7 +1200,7 @@ static bool test_multichannel_lease_break_test2(struct torture_context *tctx,
 
        /* Unblock 2A */
        torture_comment(tctx, "Unblocking 2A\n");
-       unblock_ok = test_unblock_channel(tctx, transport2A);
+       unblock_ok = test_unblock_smb2_transport(tctx, transport2A);
        torture_assert(tctx, unblock_ok, "we could not unblock tcp transport");
 
        /* 1 opens file1 */
@@ -1508,10 +1294,10 @@ static bool test_multichannel_lease_break_test2(struct torture_context *tctx,
 
 done:
        if (block_ok && !unblock_ok) {
-               test_unblock_channel(tctx, transport2A);
+               test_unblock_smb2_transport(tctx, transport2A);
        }
        if (block_setup) {
-               test_cleanup_blocked_channels(tctx);
+               test_cleanup_blocked_transports(tctx);
        }
 
        tree1->session = session1;