Move channel creation code into separate functions
authorSachin Prabhu <sprabhu@redhat.com>
Tue, 13 Feb 2018 15:56:10 +0000 (21:26 +0530)
committerMichael Adam <obnox@samba.org>
Tue, 18 Sep 2018 10:34:36 +0000 (12:34 +0200)
Avoid code duplication.

Signed-off-by: Sachin Prabhu <sprabhu@redhat.com>
source4/torture/smb2/multichannel.c

index 679716d0b7f5e2013c352f73186ea9a354a43cce..816c93dc781f46ef215194c217ba396147699248 100644 (file)
@@ -252,6 +252,152 @@ static bool test_multichannel_interface_info(struct torture_context *tctx,
        return test_ioctl_network_interface_info(tctx, tree, &info);
 }
 
+static struct smb2_tree *test_multichannel_create_channel(
+                               struct torture_context *tctx,
+                               const char *host,
+                               const char *share,
+                               struct cli_credentials *credentials,
+                               struct smbcli_options *transport2_options,
+                               struct smb2_tree *parent_tree
+                               )
+{
+       NTSTATUS status;
+       struct smb2_transport *transport;
+       struct smb2_session *session;
+       bool ret = true;
+       struct smb2_tree *tree;
+
+       status = smb2_connect(tctx,
+                       host,
+                       lpcfg_smb_ports(tctx->lp_ctx),
+                       share,
+                       lpcfg_resolve_context(tctx->lp_ctx),
+                       credentials,
+                       &tree,
+                       tctx->ev,
+                       transport2_options,
+                       lpcfg_socket_options(tctx->lp_ctx),
+                       lpcfg_gensec_settings(tctx, tctx->lp_ctx)
+                       );
+       torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
+                       "smb2_connect failed");
+       transport = tree->session->transport;
+       transport->oplock.handler = torture_oplock_ack_handler;
+       transport->oplock.private_data = tree;
+       transport->lease.handler = torture_lease_handler;
+       transport->lease.private_data = tree;
+       torture_comment(tctx, "established transport [%p]\n", transport);
+
+       /*
+        * If parent tree is set, bind the session to the parent transport
+        */
+       if (parent_tree) {
+               session = smb2_session_channel(transport,
+                               lpcfg_gensec_settings(tctx, tctx->lp_ctx),
+                               parent_tree, parent_tree->session);
+               torture_assert_goto(tctx, session != NULL, ret, done,
+                               "smb2_session_channel failed");
+
+               tree->smbXcli = parent_tree->smbXcli;
+               tree->session = session;
+               status = smb2_session_setup_spnego(session,
+                                               credentials,
+                                               0 /* previous_session_id */);
+               CHECK_STATUS(status, NT_STATUS_OK);
+               torture_comment(tctx, "bound new session to parent\n");
+       }
+       /*
+        * We absolutely need to make sure to send something over this
+        * connection to register the oplock break handler with the smb client
+        * connection. If we do not send something (at least a keepalive), we
+        * will *NEVER* receive anything over this transport.
+        */
+       smb2_keepalive(transport);
+
+       return tree;
+done:
+       /* Check below placed to avoid compilation warnings */
+       if (!ret)
+               ret = true;
+
+       return NULL;
+}
+
+static int test_multichannel_create_channels2(
+                               struct torture_context *tctx,
+                               const char *host,
+                               const char *share,
+                               struct cli_credentials *credentials,
+                               struct smbcli_options *transport2_options,
+                               struct smb2_tree **tree2A,
+                               struct smb2_tree **tree2B,
+                               struct smb2_tree **tree2C
+                               )
+{
+       struct smb2_tree *tree;
+       struct smb2_transport *transport2A;
+       struct smb2_transport *transport2B;
+       struct smb2_transport *transport2C;
+       uint16_t local_port = 0;
+
+       transport2_options->client_guid = GUID_random();
+
+       /* Session 2A */
+       torture_comment(tctx, "Setting up connection 2A\n");
+       tree = test_multichannel_create_channel(tctx, host, share,
+                               credentials, transport2_options, NULL);
+       if (!tree) {
+               goto done;
+       }
+       *tree2A = tree;
+       transport2A = tree->session->transport;
+       local_port = torture_get_local_port_from_transport(transport2A);
+       torture_comment(tctx, "transport2A uses tcp port: %d\n", local_port);
+
+       /* Session 2B */
+       if (tree2B) {
+               torture_comment(tctx, "Setting up connection 2B\n");
+               tree = test_multichannel_create_channel(tctx, host, share,
+                               credentials, transport2_options, *tree2A);
+               if (!tree) {
+                       goto done;
+               }
+               *tree2B = tree;
+               transport2B = tree->session->transport;
+               local_port = torture_get_local_port_from_transport(transport2B);
+               torture_comment(tctx, "transport2B uses tcp port: %d\n",
+                                                               local_port);
+       }
+
+       /* Session 2C */
+       if (tree2C) {
+               torture_comment(tctx, "Setting up connection 2C\n");
+               tree = test_multichannel_create_channel(tctx, host, share,
+                               credentials, transport2_options, *tree2A);
+               if (!tree) {
+                       goto done;
+               }
+               *tree2C = tree;
+               transport2C = tree->session->transport;
+               local_port = torture_get_local_port_from_transport(transport2C);
+               torture_comment(tctx, "transport2C uses tcp port: %d\n",
+                                                               local_port);
+       }
+
+       return 0;
+done:
+       return -1;
+}
+
+static void test_multichannel_free_channels2(struct smb2_tree *tree2A,
+                                            struct smb2_tree *tree2B,
+                                            struct smb2_tree *tree2C)
+{
+       TALLOC_FREE(tree2A);
+       TALLOC_FREE(tree2B);
+       TALLOC_FREE(tree2C);
+}
+
 /**
  * Test Oplock Break with Multi Channel
  */
@@ -276,6 +422,7 @@ static bool test_multichannel_oplock_break(struct torture_context *tctx,
        struct GUID create_guid2 = GUID_random();
        struct GUID create_guid3 = GUID_random();
        bool ret = true;
+       int rval;
        const char *fname1 = BASEDIR "\\oplock_break_test1.dat";
        const char *fname2 = BASEDIR "\\oplock_break_test2.dat";
        const char *fname3 = BASEDIR "\\oplock_break_test3.dat";
@@ -283,14 +430,10 @@ static bool test_multichannel_oplock_break(struct torture_context *tctx,
        struct smb2_tree *tree2B = NULL;
        struct smb2_tree *tree2C = NULL;
        struct smb2_transport *transport1 = tree1->session->transport;
-       struct smb2_transport *transport2A = NULL;
        struct smb2_transport *transport2B = NULL;
        struct smb2_transport *transport2C = NULL;
        struct smbcli_options transport2_options;
        struct smb2_session *session1 = tree1->session;
-       struct smb2_session *session2A = NULL;
-       struct smb2_session *session2B = NULL;
-       struct smb2_session *session2C = NULL;
        uint32_t server_capabilities;
        struct fsctl_net_iface_info info;
        uint16_t local_port = 0;
@@ -321,6 +464,8 @@ static bool test_multichannel_oplock_break(struct torture_context *tctx,
        transport1->oplock.handler = torture_oplock_ack_handler;
        transport1->oplock.private_data = tree1;
        torture_comment(tctx, "transport1  [%p]\n", transport1);
+       local_port = torture_get_local_port_from_transport(transport1);
+       torture_comment(tctx, "transport1 uses tcp port: %d\n", local_port);
 
        status = torture_smb2_testdir(tree1, BASEDIR, &_h);
        CHECK_STATUS(status, NT_STATUS_OK);
@@ -362,73 +507,13 @@ static bool test_multichannel_oplock_break(struct torture_context *tctx,
        io3.in.timeout = 0x493E0; /* 300000 */
 
        transport2_options = transport1->options;
-       transport2_options.client_guid = GUID_random();
-
-       status = smb2_connect(tctx,
-                       host,
-                       lpcfg_smb_ports(tctx->lp_ctx),
-                       share,
-                       lpcfg_resolve_context(tctx->lp_ctx),
-                       credentials,
-                       &tree2A,
-                       tctx->ev,
-                       &transport2_options,
-                       lpcfg_socket_options(tctx->lp_ctx),
-                       lpcfg_gensec_settings(tctx, tctx->lp_ctx)
-                       );
-       torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
-                       "smb2_connect failed");
-       transport2A = tree2A->session->transport;
-       session2A = tree2A->session;
-
-       transport2A->oplock.handler = torture_oplock_ack_handler;
-       transport2A->oplock.private_data = tree2A;
-       torture_comment(tctx, "transport2A [%p]\n", transport2A);
-
-       torture_comment(tctx, "established transport 2A\n");
-
-       status = smb2_connect(tctx,
-                       host,
-                       lpcfg_smb_ports(tctx->lp_ctx),
-                       share,
-                       lpcfg_resolve_context(tctx->lp_ctx),
-                       credentials,
-                       &tree2B,
-                       tctx->ev,
-                       &transport2_options,
-                       lpcfg_socket_options(tctx->lp_ctx),
-                       lpcfg_gensec_settings(tctx, tctx->lp_ctx)
-                       );
-       torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
-                       "smb2_connect failed");
+       rval = test_multichannel_create_channels2(tctx, host, share,
+                                                 credentials,
+                                                 &transport2_options,
+                                                 &tree2A, &tree2B, NULL);
+       CHECK_VAL(rval, 0);
        transport2B = tree2B->session->transport;
 
-       /*
-        * Now bind the session2 to the transport2B
-        */
-       session2B = smb2_session_channel(transport2B,
-                       lpcfg_gensec_settings(tctx, tctx->lp_ctx),
-                       tree2A, session2A);
-
-       tree2B->smbXcli = tree2A->smbXcli;
-       tree2B->session = session2B;
-
-       torture_assert(tctx, session2B != NULL, "smb2_session_channel failed");
-
-       transport2B->oplock.handler = torture_oplock_ack_handler;
-       transport2B->oplock.private_data = tree2B;
-       torture_comment(tctx, "transport2B [%p]\n", transport2B);
-
-       torture_comment(tctx, "established transport 2B\n");
-
-       status = smb2_session_setup_spnego(session2B,
-                       popt_get_cmdline_credentials(),
-                       0 /* previous_session_id */);
-       CHECK_STATUS(status, NT_STATUS_OK);
-
-       torture_comment(tctx, "bound session2B to session2A\n");
-
-
        /* now the real test starts with opening files */
 
        torture_comment(tctx, "client2 opens fname1 via session 2A\n");
@@ -446,7 +531,6 @@ static bool test_multichannel_oplock_break(struct torture_context *tctx,
        torture_wait_for_oplock_break(tctx);
        CHECK_VAL(break_info.count, 0);
 
-
        torture_comment(tctx, "client2 opens fname2 via session 2B\n");
 
        /* 2b opens file2 */
@@ -518,66 +602,19 @@ static bool test_multichannel_oplock_break(struct torture_context *tctx,
        smb2_util_unlink(tree1, fname2);
        smb2_util_unlink(tree1, fname3);
        CHECK_VAL(break_info.count, 0);
-
-       /* now add a third channel and repeat the test */
-       status = smb2_connect(tctx,
-                       host,
-                       lpcfg_smb_ports(tctx->lp_ctx),
-                       share,
-                       lpcfg_resolve_context(tctx->lp_ctx),
-                       credentials,
-                       &tree2C,
-                       tctx->ev,
-                       &transport2_options,
-                       lpcfg_socket_options(tctx->lp_ctx),
-                       lpcfg_gensec_settings(tctx, tctx->lp_ctx)
-                       );
-       torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
-                       "smb2_connect failed");
+       test_multichannel_free_channels2(tree2A, tree2B, tree2C);
+       tree2A = tree2B = tree2C = NULL;
+
+       /* now repeat the test with the third channel */
+       rval = test_multichannel_create_channels2(tctx, host, share,
+                                                 credentials,
+                                                 &transport2_options,
+                                                 &tree2A, &tree2B, &tree2C);
+       CHECK_VAL(rval, 0);
+       transport2B = tree2B->session->transport;
        transport2C = tree2C->session->transport;
 
-       /*
-        * Now bind the session2 to the transport2C
-        */
-       session2C = smb2_session_channel(transport2C,
-                       lpcfg_gensec_settings(tctx, tctx->lp_ctx),
-                       tree2A, session2A);
-
-       tree2C->smbXcli = tree2A->smbXcli;
-       tree2C->session = session2C;
-
-       torture_assert(tctx, session2C != NULL, "smb2_session_channel failed");
-
-       transport2C->oplock.handler = torture_oplock_ack_handler;
-       transport2C->oplock.private_data = tree2C;
-       torture_comment(tctx, "transport2C [%p]\n", transport2C);
-
-       torture_comment(tctx, "established transport 2C\n");
-
-       status = smb2_session_setup_spnego(session2C,
-                       popt_get_cmdline_credentials(),
-                       0 /* previous_session_id */);
-       CHECK_STATUS(status, NT_STATUS_OK);
-
-       torture_comment(tctx, "bound session2C to session2A\n");
-
-       /*
-        * We absolutely need to make sure to send something over this
-        * connection to register the oplock break handler with the smb client
-        * connection. If we do not send something (at least a keepalive), we
-        * will *NEVER* receive anything over this transport.
-        */
-
-       smb2_keepalive(transport2C);
-
-       local_port = torture_get_local_port_from_transport(transport2C);
-
-       torture_comment(tctx, "transport2C uses tcp port: %d\n", local_port);
-
        torture_comment(tctx, "client2 opens fname1 via session 2A\n");
-
-       /* 2a opens file1 */
-
        io1.in.oplock_level = smb2_util_oplock_level("b");
        status = smb2_create(tree2A, mem_ctx, &io1);
        CHECK_STATUS(status, NT_STATUS_OK);
@@ -703,48 +740,14 @@ static bool test_multichannel_oplock_break(struct torture_context *tctx,
         * now add a third channel and repeat the test, we need to reestablish
         * transport2C because the remote end has invalidated our connection
         */
-
-       status = smb2_connect(tctx,
-                       host,
-                       lpcfg_smb_ports(tctx->lp_ctx),
-                       share,
-                       lpcfg_resolve_context(tctx->lp_ctx),
-                       credentials,
-                       &tree2C,
-                       tctx->ev,
-                       &transport2_options,
-                       lpcfg_socket_options(tctx->lp_ctx),
-                       lpcfg_gensec_settings(tctx, tctx->lp_ctx)
-                       );
-       torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
-                       "smb2_connect failed");
+       torture_comment(tctx, "Reconnecting session 2C\n");
+       talloc_free(tree2C);
+       tree2C = test_multichannel_create_channel(tctx, host, share,
+                               credentials, &transport2_options, tree2A);
+       if (!tree2C)
+               goto done;
        transport2C = tree2C->session->transport;
 
-       /*
-        * Now bind the session2 to the transport2C
-        */
-       session2C = smb2_session_channel(transport2C,
-                       lpcfg_gensec_settings(tctx, tctx->lp_ctx),
-                       tree2A, session2A);
-
-       tree2C->smbXcli = tree2A->smbXcli;
-       tree2C->session = session2C;
-
-       torture_assert(tctx, session2C != NULL, "smb2_session_channel failed");
-
-       transport2C->oplock.handler = torture_oplock_ack_handler;
-       transport2C->oplock.private_data = tree2C;
-       torture_comment(tctx, "transport2C [%p]\n", transport2C);
-
-       torture_comment(tctx, "established transport 2C\n");
-
-       status = smb2_session_setup_spnego(session2C,
-                       popt_get_cmdline_credentials(),
-                       0 /* previous_session_id */);
-       CHECK_STATUS(status, NT_STATUS_OK);
-
-       torture_comment(tctx, "bound session2C to session2A\n");
-
        torture_comment(tctx, "client 2 opening fname3 over newly established transport2C\n");
 
        status = smb2_create(tree2C, mem_ctx, &io3);
@@ -806,7 +809,7 @@ done:
        smb2_util_unlink(tree1, fname3);
        smb2_deltree(tree1, BASEDIR);
 
-       talloc_free(tree2A);
+       test_multichannel_free_channels2(tree2A, tree2B, tree2C);
        talloc_free(tree1);
        talloc_free(mem_ctx);
 
@@ -842,6 +845,7 @@ static bool test_multichannel_lease_break(struct torture_context *tctx,
        struct GUID create_guid2 = GUID_random();
        struct GUID create_guid3 = GUID_random();
        bool ret = true;
+       int rval;
        const char *fname1 = BASEDIR "\\lease_break_test1.dat";
        const char *fname2 = BASEDIR "\\lease_break_test2.dat";
        const char *fname3 = BASEDIR "\\lease_break_test3.dat";
@@ -854,9 +858,6 @@ static bool test_multichannel_lease_break(struct torture_context *tctx,
        struct smb2_transport *transport2C = NULL;
        struct smbcli_options transport2_options;
        struct smb2_session *session1 = tree1->session;
-       struct smb2_session *session2A = NULL;
-       struct smb2_session *session2B = NULL;
-       struct smb2_session *session2C = NULL;
        uint32_t server_capabilities;
        uint16_t local_port = 0;
        bool block_ok = false;
@@ -906,18 +907,6 @@ static bool test_multichannel_lease_break(struct torture_context *tctx,
        smb2_util_unlink(tree1, fname3);
        CHECK_VAL(lease_break_info.count, 0);
 
-       /*
-        * Test 1:
-        *      open file1 in session 2A
-        *      open file2 in session 2B
-        *      open file3 in session 2B
-        *      open file1 in session 1
-        *              lease break sent to 2A
-        *      open file2 in session 2
-        *              lease break sent to 2B
-        */
-       torture_comment(tctx, "Test 1 start \n");
-
        smb2_lease_create(&io1, &ls1, false, fname1, LEASE2F1,
                          smb2_util_lease_state("RHW"));
        io1.in.durable_open = false;
@@ -943,86 +932,31 @@ static bool test_multichannel_lease_break(struct torture_context *tctx,
        io3.in.timeout = 0x493E0;
 
        transport2_options = transport1->options;
-       transport2_options.client_guid = GUID_random();
-
-       status = smb2_connect(tctx,
-                       host,
-                       lpcfg_smb_ports(tctx->lp_ctx),
-                       share,
-                       lpcfg_resolve_context(tctx->lp_ctx),
-                       credentials,
-                       &tree2A,
-                       tctx->ev,
-                       &transport2_options,
-                       lpcfg_socket_options(tctx->lp_ctx),
-                       lpcfg_gensec_settings(tctx, tctx->lp_ctx)
-                       );
-       torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
-                       "smb2_connect failed");
-       transport2A = tree2A->session->transport;
-       session2A = tree2A->session;
-
-
-       transport2A->lease.handler = torture_lease_handler;
-       transport2A->lease.private_data = tree2A;
-       torture_comment(tctx, "transport2A [%p]\n", transport2A);
-
-       torture_comment(tctx, "established transport 2A\n");
-
-       local_port = torture_get_local_port_from_transport(transport2A);
-       torture_comment(tctx, "transport2A uses tcp port: %d\n", local_port);
-
-       status = smb2_connect(tctx,
-                       host,
-                       lpcfg_smb_ports(tctx->lp_ctx),
-                       share,
-                       lpcfg_resolve_context(tctx->lp_ctx),
-                       credentials,
-                       &tree2B,
-                       tctx->ev,
-                       &transport2_options,
-                       lpcfg_socket_options(tctx->lp_ctx),
-                       lpcfg_gensec_settings(tctx, tctx->lp_ctx)
-                       );
-       torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
-                       "smb2_connect failed");
-       transport2B = tree2B->session->transport;
 
        /*
-        * Now bind the session2 to the transport2B
+        * Test 1:
+        *      open file1 in session 2A
+        *      open file2 in session 2B
+        *      open file3 in session 2B
+        *      open file1 in session 1
+        *              lease break sent to 2A
+        *      open file2 in session 2
+        *              lease break sent to 2B
         */
-       session2B = smb2_session_channel(transport2B,
-                       lpcfg_gensec_settings(tctx, tctx->lp_ctx),
-                       tree2A, session2A);
-
-       tree2B->smbXcli = tree2A->smbXcli;
-       tree2B->session = session2B;
-
-       torture_assert(tctx, session2B != NULL, "smb2_session_channel failed");
-
-       transport2B->lease.handler = torture_lease_handler;
-       transport2B->lease.private_data = tree2B;
-       torture_comment(tctx, "transport2B [%p]\n", transport2B);
-
-       torture_comment(tctx, "established transport 2B\n");
-
-       local_port = torture_get_local_port_from_transport(transport2B);
-       torture_comment(tctx, "transport2B uses tcp port: %d\n", local_port);
-
-       status = smb2_session_setup_spnego(session2B,
-                       popt_get_cmdline_credentials(),
-                       0 /* previous_session_id */);
-       CHECK_STATUS(status, NT_STATUS_OK);
-
-       torture_comment(tctx, "bound session2B to session2A\n");
-
-
-       /* now the real test starts with opening files */
+       torture_comment(tctx, "Test 1 start \n");
 
-       torture_comment(tctx, "client2 opens fname1 via session 2A\n");
+       rval = test_multichannel_create_channels2(tctx, host, share,
+                                                 credentials,
+                                                 &transport2_options,
+                                                 &tree2A, &tree2B, &tree2C);
+       CHECK_VAL(rval, 0);
+       transport2A = tree2A->session->transport;
+       transport2B = tree2B->session->transport;
+       transport2C = tree2C->session->transport;
 
        /* 2a opens file1 */
 
+       torture_comment(tctx, "client2 opens fname1 via session 2A\n");
        status = smb2_create(tree2A, mem_ctx, &io1);
        CHECK_STATUS(status, NT_STATUS_OK);
        h_client2_file1 = io1.out.file.handle;
@@ -1033,10 +967,8 @@ static bool test_multichannel_lease_break(struct torture_context *tctx,
        CHECK_VAL(io1.out.durable_open, false);
        CHECK_VAL(lease_break_info.count, 0);
 
-
-       torture_comment(tctx, "client2 opens fname2 via session 2B\n");
-
        /* 2b opens file2 */
+       torture_comment(tctx, "client2 opens fname2 via session 2B\n");
        status = smb2_create(tree2B, mem_ctx, &io2);
        CHECK_STATUS(status, NT_STATUS_OK);
        h_client2_file2 = io2.out.file.handle;
@@ -1047,8 +979,8 @@ static bool test_multichannel_lease_break(struct torture_context *tctx,
        CHECK_VAL(io2.out.durable_open, false);
        CHECK_VAL(lease_break_info.count, 0);
 
-       torture_comment(tctx, "client2 opens fname3 via session 2B\n");
        /* 2b opens file3 */
+       torture_comment(tctx, "client2 opens fname3 via session 2B\n");
        smb2_lease_create(&io3, &ls3, false, fname3, LEASE2F3,
                          smb2_util_lease_state("RHW"));
        status = smb2_create(tree2B, mem_ctx, &io3);
@@ -1067,7 +999,6 @@ static bool test_multichannel_lease_break(struct torture_context *tctx,
         */
 
        torture_comment(tctx, "client1 opens fname1 via session 1\n");
-
        smb2_lease_create(&io1, &ls1, false, fname1, LEASE1F1,
                          smb2_util_lease_state("RHW"));
        status = smb2_create(tree1, mem_ctx, &io1);
@@ -1090,7 +1021,6 @@ static bool test_multichannel_lease_break(struct torture_context *tctx,
         */
 
        torture_comment(tctx, "client1 opens fname2 via session 1\n");
-
        smb2_lease_create(&io2, &ls2, false, fname2, LEASE1F2,
                          smb2_util_lease_state("RHW"));
        status = smb2_create(tree1, mem_ctx, &io2);
@@ -1119,6 +1049,8 @@ static bool test_multichannel_lease_break(struct torture_context *tctx,
        smb2_util_unlink(tree1, fname2);
        smb2_util_unlink(tree1, fname3);
        CHECK_VAL(lease_break_info.count, 0);
+       test_multichannel_free_channels2(tree2A, tree2B, tree2C);
+       tree2A = tree2B = tree2C = NULL;
 
        /*
         * Test 2:
@@ -1132,64 +1064,18 @@ static bool test_multichannel_lease_break(struct torture_context *tctx,
         */
        torture_comment(tctx, "Test 2 start \n");
 
-       /* now add a third channel and repeat the test */
-       status = smb2_connect(tctx,
-                       host,
-                       lpcfg_smb_ports(tctx->lp_ctx),
-                       share,
-                       lpcfg_resolve_context(tctx->lp_ctx),
-                       credentials,
-                       &tree2C,
-                       tctx->ev,
-                       &transport2_options,
-                       lpcfg_socket_options(tctx->lp_ctx),
-                       lpcfg_gensec_settings(tctx, tctx->lp_ctx)
-                       );
-       torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
-                       "smb2_connect failed");
+       transport2_options = transport1->options;
+       rval = test_multichannel_create_channels2(tctx, host, share,
+                                                 credentials,
+                                                 &transport2_options,
+                                                 &tree2A, &tree2B, &tree2C);
+       CHECK_VAL(rval, 0);
+       transport2A = tree2A->session->transport;
+       transport2B = tree2B->session->transport;
        transport2C = tree2C->session->transport;
 
-       /*
-        * Now bind the session2 to the transport2C
-        */
-       session2C = smb2_session_channel(transport2C,
-                       lpcfg_gensec_settings(tctx, tctx->lp_ctx),
-                       tree2A, session2A);
-
-       tree2C->smbXcli = tree2A->smbXcli;
-       tree2C->session = session2C;
-
-       torture_assert(tctx, session2C != NULL, "smb2_session_channel failed");
-
-       transport2C->lease.handler = torture_lease_handler;
-       transport2C->lease.private_data = tree2C;
-       torture_comment(tctx, "transport2C [%p]\n", transport2C);
-
-       torture_comment(tctx, "established transport 2C\n");
-
-       status = smb2_session_setup_spnego(session2C,
-                       popt_get_cmdline_credentials(),
-                       0 /* previous_session_id */);
-       CHECK_STATUS(status, NT_STATUS_OK);
-
-       torture_comment(tctx, "bound session2C to session2A\n");
-
-       /*
-        * We absolutely need to make sure to send something over this
-        * connection to register the oplock break handler with the smb client
-        * connection. If we do not send something (at least a keepalive), we
-        * will *NEVER* receive anything over this transport.
-        */
-
-       smb2_keepalive(transport2C);
-
-       local_port = torture_get_local_port_from_transport(transport2C);
-       torture_comment(tctx, "transport2C uses tcp port: %d\n", local_port);
-
-       torture_comment(tctx, "client2 opens fname1 via session 2A\n");
-
        /* 2a opens file1 */
-
+       torture_comment(tctx, "client2 opens fname1 via session 2A\n");
        smb2_lease_create(&io1, &ls1, false, fname1, LEASE2F1,
                          smb2_util_lease_state("RHW"));
        status = smb2_create(tree2A, mem_ctx, &io1);
@@ -1202,10 +1088,8 @@ static bool test_multichannel_lease_break(struct torture_context *tctx,
        CHECK_VAL(io1.out.durable_open, false);
        CHECK_VAL(lease_break_info.count, 0);
 
-
-       torture_comment(tctx, "client2 opens fname2 via session 2B\n");
-
        /* 2b opens file2 */
+       torture_comment(tctx, "client2 opens fname2 via session 2B\n");
        smb2_lease_create(&io2, &ls2, false, fname2, LEASE2F2,
                          smb2_util_lease_state("RHW"));
        status = smb2_create(tree2B, mem_ctx, &io2);
@@ -1218,9 +1102,8 @@ static bool test_multichannel_lease_break(struct torture_context *tctx,
        CHECK_VAL(io2.out.durable_open, false);
        CHECK_VAL(lease_break_info.count, 0);
 
-       torture_comment(tctx, "client2 opens fname3 via session 2C\n");
-
        /* 2c opens file3 */
+       torture_comment(tctx, "client2 opens fname3 via session 2C\n");
        smb2_lease_create(&io3, &ls3, false, fname3, LEASE2F3,
                          smb2_util_lease_state("RHW"));
        status = smb2_create(tree2C, mem_ctx, &io3);
@@ -1239,7 +1122,6 @@ static bool test_multichannel_lease_break(struct torture_context *tctx,
         */
 
        torture_comment(tctx, "client1 opens fname1 via session 1\n");
-
        smb2_lease_create(&io1, &ls1, false, fname1, LEASE1F1,
                          smb2_util_lease_state("RHW"));
        status = smb2_create(tree1, mem_ctx, &io1);
@@ -1262,7 +1144,6 @@ static bool test_multichannel_lease_break(struct torture_context *tctx,
         */
 
        torture_comment(tctx, "client1 opens fname2 via session 1\n");
-
        smb2_lease_create(&io2, &ls2, false, fname2, LEASE1F2,
                          smb2_util_lease_state("RHW"));
        status = smb2_create(tree1, mem_ctx, &io2);
@@ -1291,6 +1172,8 @@ static bool test_multichannel_lease_break(struct torture_context *tctx,
        smb2_util_unlink(tree1, fname2);
        smb2_util_unlink(tree1, fname3);
        CHECK_VAL(lease_break_info.count, 0);
+       test_multichannel_free_channels2(tree2A, tree2B, tree2C);
+       tree2A = tree2B = tree2C = NULL;
 
        /*
         * Test 3:
@@ -1307,10 +1190,17 @@ static bool test_multichannel_lease_break(struct torture_context *tctx,
         */
        torture_comment(tctx, "Test 3 start \n");
 
-       /* 2a opens file1 */
+       rval = test_multichannel_create_channels2(tctx, host, share,
+                                                 credentials,
+                                                 &transport2_options,
+                                                 &tree2A, &tree2B, &tree2C);
+       CHECK_VAL(rval, 0);
+       transport2A = tree2A->session->transport;
+       transport2B = tree2B->session->transport;
+       transport2C = tree2C->session->transport;
 
+       /* 2a opens file1 */
        torture_comment(tctx, "client2 opens fname1 via session 2A\n");
-
        smb2_lease_create(&io1, &ls1, false, fname1, LEASE2F1,
                          smb2_util_lease_state("RHW"));
        status = smb2_create(tree2A, mem_ctx, &io1);
@@ -1323,10 +1213,8 @@ static bool test_multichannel_lease_break(struct torture_context *tctx,
        CHECK_VAL(io1.out.durable_open, false);
        CHECK_VAL(lease_break_info.count, 0);
 
-
-       torture_comment(tctx, "client2 opens fname2 via session 2B\n");
-
        /* 2b opens file2 */
+       torture_comment(tctx, "client2 opens fname2 via session 2B\n");
        smb2_lease_create(&io2, &ls2, false, fname2, LEASE2F2,
                          smb2_util_lease_state("RHW"));
        status = smb2_create(tree2B, mem_ctx, &io2);
@@ -1341,8 +1229,7 @@ static bool test_multichannel_lease_break(struct torture_context *tctx,
 
 
        torture_comment(tctx, "Blocking 2B and 2C\n");
-       /* Block 2A, 2B and 2C */
-       //block_ok = torture_block_tcp_transport(tctx, transport2A);
+       /* Block 2B and 2C */
        block_ok = torture_block_tcp_transport(tctx, transport2B);
        block_ok |= torture_block_tcp_transport(tctx, transport2C);
        torture_assert(tctx, block_ok, "we could not block tcp transport");
@@ -1401,52 +1288,6 @@ static bool test_multichannel_lease_break(struct torture_context *tctx,
        CHECK_VAL(io1.out.durable_open, false);
        CHECK_VAL(lease_break_info.count, 1);
 
-
-       torture_comment(tctx, "Reconnecting session 2B\n");
-       talloc_free(transport2B);
-       talloc_free(session2B);
-       talloc_free(tree2B);
-       status = smb2_connect(tctx,
-                       host,
-                       lpcfg_smb_ports(tctx->lp_ctx),
-                       share,
-                       lpcfg_resolve_context(tctx->lp_ctx),
-                       credentials,
-                       &tree2B,
-                       tctx->ev,
-                       &transport2_options,
-                       lpcfg_socket_options(tctx->lp_ctx),
-                       lpcfg_gensec_settings(tctx, tctx->lp_ctx)
-                       );
-       torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
-                       "smb2_connect failed");
-       transport2B = tree2B->session->transport;
-
-       session2B = smb2_session_channel(transport2B,
-                       lpcfg_gensec_settings(tctx, tctx->lp_ctx),
-                       tree2A, session2A);
-
-       tree2B->smbXcli = tree2A->smbXcli;
-       tree2B->session = session2B;
-
-       torture_assert(tctx, session2B != NULL, "smb2_session_channel failed");
-
-       transport2B->lease.handler = torture_lease_handler;
-       transport2B->lease.private_data = tree2B;
-       torture_comment(tctx, "transport2B [%p]\n", transport2B);
-
-       torture_comment(tctx, "established transport 2B\n");
-
-       local_port = torture_get_local_port_from_transport(transport2B);
-       torture_comment(tctx, "transport2B uses tcp port: %d\n", local_port);
-
-       status = smb2_session_setup_spnego(session2B,
-                       popt_get_cmdline_credentials(),
-                       0 /* previous_session_id */);
-       CHECK_STATUS(status, NT_STATUS_OK);
-
-       torture_comment(tctx, "bound session2B to session2A\n");
-
        torture_comment(tctx, "client closes fname1 via session 2A\n");
        status = smb2_util_close(tree2A, h_client2_file1);
        CHECK_STATUS(status, NT_STATUS_OK);
@@ -1463,6 +1304,8 @@ static bool test_multichannel_lease_break(struct torture_context *tctx,
        smb2_util_unlink(tree1, fname2);
        smb2_util_unlink(tree1, fname3);
        CHECK_VAL(lease_break_info.count, 0);
+       test_multichannel_free_channels2(tree2A, tree2B, tree2C);
+       tree2A = tree2B = tree2C = NULL;
 
        /*
         * Test 4:
@@ -1482,6 +1325,15 @@ static bool test_multichannel_lease_break(struct torture_context *tctx,
         */
        torture_comment(tctx, "Test 4 start \n");
 
+       rval = test_multichannel_create_channels2(tctx, host, share,
+                                                 credentials,
+                                                 &transport2_options,
+                                                 &tree2A, &tree2B, &tree2C);
+       CHECK_VAL(rval, 0);
+       transport2A = tree2A->session->transport;
+       transport2B = tree2B->session->transport;
+       transport2C = tree2C->session->transport;
+
        /* 2a opens file1 */
        torture_comment(tctx, "client2 opens fname1 via session 2A\n");
        smb2_lease_create(&io1, &ls1, false, fname1, LEASE2F1,
@@ -1599,6 +1451,8 @@ static bool test_multichannel_lease_break(struct torture_context *tctx,
        smb2_util_unlink(tree1, fname2);
        smb2_util_unlink(tree1, fname3);
        CHECK_VAL(lease_break_info.count, 0);
+       test_multichannel_free_channels2(tree2A, tree2B, tree2C);
+       tree2A = tree2B = tree2C = NULL;
 
  done:
        if (block_ok && !unblock_ok) {
@@ -1628,7 +1482,7 @@ static bool test_multichannel_lease_break(struct torture_context *tctx,
        smb2_util_unlink(tree1, fname3);
        smb2_deltree(tree1, BASEDIR);
 
-       talloc_free(tree2A);
+       test_multichannel_free_channels2(tree2A, tree2B, tree2C);
        talloc_free(tree1);
        talloc_free(mem_ctx);