The branch, master has been updated
       via  d23e2678e93 s3:smbd: stop accepting multichannel connections early 
in exit_server_common()
       via  e5a8b16a11f s3:smbd: move exit_firsttime checking to the start of 
exit_server_common()
       via  8fbb7ad275d s4:torture/smb2: make smb2.durable-v2-delay tests more 
robust
       via  3fa9c3d5bb8 s4:torture/smb2: split replay_smb3_specification into 
durable handle and multichannel
      from  aa4d135710e s3: lib: Fix missing TALLOC_FREE in error code path.

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit d23e2678e93362b03df21b6fc26835ad8efdcc9f
Author: Stefan Metzmacher <[email protected]>
Date:   Mon Jul 6 16:51:05 2020 +0200

    s3:smbd: stop accepting multichannel connections early in 
exit_server_common()
    
    This is just a step in the correct direction, but there's still a
    possible race...
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14433
    
    Signed-off-by: Stefan Metzmacher <[email protected]>
    Reviewed-by: Guenther Deschner <[email protected]>
    
    Autobuild-User(master): Günther Deschner <[email protected]>
    Autobuild-Date(master): Tue Jul 14 14:59:19 UTC 2020 on sn-devel-184

commit e5a8b16a11f7286b88e3ea2057c26aa558b9f74a
Author: Stefan Metzmacher <[email protected]>
Date:   Mon Jul 6 16:42:46 2020 +0200

    s3:smbd: move exit_firsttime checking to the start of exit_server_common()
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14433
    
    Signed-off-by: Stefan Metzmacher <[email protected]>
    Reviewed-by: Guenther Deschner <[email protected]>

commit 8fbb7ad275dea54b1d331ec9c591ec4e50778922
Author: Stefan Metzmacher <[email protected]>
Date:   Sat Jul 4 11:50:14 2020 +0200

    s4:torture/smb2: make smb2.durable-v2-delay tests more robust
    
    We should not crash when the test fails, so we use a 2nd independent
    connection to unlink the file at the end.
    
    Signed-off-by: Stefan Metzmacher <[email protected]>
    Reviewed-by: Guenther Deschner <[email protected]>

commit 3fa9c3d5bb835d3f512a0a93bf971d8ae54600a0
Author: Stefan Metzmacher <[email protected]>
Date:   Fri Jul 3 10:09:16 2020 +0200

    s4:torture/smb2: split replay_smb3_specification into durable handle and 
multichannel
    
    It's better to have durable handles and multichannel tested separate:
    1. we test both cases in the server
    2. it makes it easier to deal with knownfail entries if only one
       of these features is active on the server.
    
    Signed-off-by: Stefan Metzmacher <[email protected]>
    Reviewed-by: Guenther Deschner <[email protected]>

-----------------------------------------------------------------------

Summary of changes:
 selftest/knownfail                     |  3 +-
 source3/librpc/idl/smbXsrv.idl         |  1 +
 source3/smbd/server_exit.c             | 25 ++++++++++++---
 source3/smbd/smbXsrv_client.c          |  6 ++++
 source4/torture/smb2/durable_v2_open.c | 52 ++++++++++++++++---------------
 source4/torture/smb2/lock.c            | 57 +++++++++++++++++++++++++++++-----
 6 files changed, 106 insertions(+), 38 deletions(-)


Changeset truncated at 500 lines:

diff --git a/selftest/knownfail b/selftest/knownfail
index 4fe503f4cc1..6c005d1f4de 100644
--- a/selftest/knownfail
+++ b/selftest/knownfail
@@ -215,7 +215,8 @@
 ^samba3.smb2.compound.aio.interim2 # wrong return code (STATUS_CANCELLED)
 ^samba3.smb2.replay.replay3 # This requires multi-chanel
 ^samba3.smb2.replay.replay4 # This requires multi-chanel
-^samba3.smb2.lock.replay_smb3_specification # This requires multi-chanel or 
durable handles
+^samba3.smb2.lock.replay_smb3_specification_multi # This requires multi-chanel
+^samba3.smb2.lock.replay_smb3_specification_durable\(nt4_dc\) # Requires 
durable handles
 ^samba3.smb2.lock.*replay_broken_windows # This tests the windows behaviour
 ^samba3.smb2.lease.statopen3
 ^samba3.smb2.lease.unlink # we currently do not downgrade RH lease to R after 
unlink
diff --git a/source3/librpc/idl/smbXsrv.idl b/source3/librpc/idl/smbXsrv.idl
index a74ac42b312..78fc3644d2f 100644
--- a/source3/librpc/idl/smbXsrv.idl
+++ b/source3/librpc/idl/smbXsrv.idl
@@ -142,6 +142,7 @@ interface smbXsrv
                [ignore] struct smbXsrv_connection      *connections;
                boolean8                server_multi_channel_enabled;
                hyper                   next_channel_id;
+               [ignore] struct tevent_req              *connection_pass_subreq;
 
                /*
                 * A List of pending breaks.
diff --git a/source3/smbd/server_exit.c b/source3/smbd/server_exit.c
index e3efa993159..397ea810633 100644
--- a/source3/smbd/server_exit.c
+++ b/source3/smbd/server_exit.c
@@ -83,6 +83,11 @@ static void exit_server_common(enum server_exit_reason how,
        struct messaging_context *msg_ctx = global_messaging_context();
        NTSTATUS disconnect_status;
 
+       if (!exit_firsttime) {
+               exit(0);
+       }
+       exit_firsttime = false;
+
        switch (how) {
        case SERVER_EXIT_NORMAL:
                disconnect_status = NT_STATUS_LOCAL_DISCONNECT;
@@ -94,13 +99,25 @@ static void exit_server_common(enum server_exit_reason how,
        }
 
        if (client != NULL) {
+               NTSTATUS status;
+
                sconn = client->sconn;
                xconn = client->connections;
-       }
 
-       if (!exit_firsttime)
-               exit(0);
-       exit_firsttime = false;
+               /*
+                * Make sure we stop handling new multichannel
+                * connections early!
+                *
+                * From here, we're not able to handle them.
+                */
+               status = smbXsrv_client_remove(client);
+               if (!NT_STATUS_IS_OK(status)) {
+                       D_ERR("Server exit (%s)\n",
+                             (reason ? reason : "normal exit"));
+                       DBG_ERR("smbXsrv_client_remove() failed (%s)\n",
+                               nt_errstr(status));
+               }
+       }
 
        change_to_root_user();
 
diff --git a/source3/smbd/smbXsrv_client.c b/source3/smbd/smbXsrv_client.c
index e0658d87969..fcfa225048a 100644
--- a/source3/smbd/smbXsrv_client.c
+++ b/source3/smbd/smbXsrv_client.c
@@ -568,6 +568,7 @@ NTSTATUS smbXsrv_client_create(TALLOC_CTX *mem_ctx,
                return NT_STATUS_NO_MEMORY;
        }
        tevent_req_set_callback(subreq, smbXsrv_client_connection_pass_loop, 
client);
+       client->connection_pass_subreq = subreq;
 
        *_client = client;
        return NT_STATUS_OK;
@@ -607,6 +608,8 @@ static void smbXsrv_client_connection_pass_loop(struct 
tevent_req *subreq)
        int sock_fd = -1;
        uint64_t seq_low;
 
+       client->connection_pass_subreq = NULL;
+
        ret = messaging_filtered_read_recv(subreq, talloc_tos(), &rec);
        TALLOC_FREE(subreq);
        if (ret != 0) {
@@ -731,6 +734,7 @@ next:
                return;
        }
        tevent_req_set_callback(subreq, smbXsrv_client_connection_pass_loop, 
client);
+       client->connection_pass_subreq = subreq;
 }
 
 NTSTATUS smbXsrv_client_update(struct smbXsrv_client *client)
@@ -797,6 +801,8 @@ NTSTATUS smbXsrv_client_remove(struct smbXsrv_client 
*client)
                return NT_STATUS_OK;
        }
 
+       TALLOC_FREE(client->connection_pass_subreq);
+
        client->global->db_rec = smbXsrv_client_global_fetch_locked(
                                        table->global.db_ctx,
                                        &client->global->client_guid,
diff --git a/source4/torture/smb2/durable_v2_open.c 
b/source4/torture/smb2/durable_v2_open.c
index 014ff192ad1..8efa2622444 100644
--- a/source4/torture/smb2/durable_v2_open.c
+++ b/source4/torture/smb2/durable_v2_open.c
@@ -2040,7 +2040,8 @@ struct torture_suite 
*torture_smb2_durable_v2_open_init(TALLOC_CTX *ctx)
  * tcp disconnect, reconnect, do a durable reopen (succeeds)
  */
 static bool test_durable_v2_reconnect_delay(struct torture_context *tctx,
-                                           struct smb2_tree *tree)
+                                           struct smb2_tree *tree,
+                                           struct smb2_tree *tree2)
 {
        NTSTATUS status;
        TALLOC_CTX *mem_ctx = talloc_new(tctx);
@@ -2053,6 +2054,7 @@ static bool test_durable_v2_reconnect_delay(struct 
torture_context *tctx,
        uint64_t previous_session_id;
        uint8_t b = 0;
        bool ret = true;
+       bool ok;
 
        options = tree->session->transport->options;
        previous_session_id = 
smb2cli_session_current_id(tree->session->smbXcli);
@@ -2087,20 +2089,17 @@ static bool test_durable_v2_reconnect_delay(struct 
torture_context *tctx,
 
        /* disconnect, leaving the durable open */
        TALLOC_FREE(tree);
+       h = NULL;
 
-       if (!torture_smb2_connection_ext(tctx, previous_session_id,
-                                        &options, &tree)) {
-               torture_warning(tctx, "couldn't reconnect, bailing\n");
-               ret = false;
-               goto done;
-       }
+       ok = torture_smb2_connection_ext(tctx, previous_session_id,
+                                        &options, &tree);
+       torture_assert_goto(tctx, ok, ret, done, "couldn't reconnect, 
bailing\n");
 
        ZERO_STRUCT(io);
        io.in.fname = fname;
        io.in.durable_open_v2 = false;
-       io.in.durable_handle_v2 = h;
+       io.in.durable_handle_v2 = &_h;
        io.in.create_guid = create_guid;
-       h = NULL;
 
        status = smb2_create(tree, mem_ctx, &io);
        CHECK_STATUS(status, NT_STATUS_OK);
@@ -2112,10 +2111,11 @@ done:
        if (h != NULL) {
                smb2_util_close(tree, *h);
        }
+       TALLOC_FREE(tree);
 
-       smb2_util_unlink(tree, fname);
+       smb2_util_unlink(tree2, fname);
 
-       talloc_free(tree);
+       TALLOC_FREE(tree2);
 
        talloc_free(mem_ctx);
 
@@ -2126,8 +2126,9 @@ done:
  * basic test for doing a durable open with 1msec cleanup time
  * tcp disconnect, wait a bit, reconnect, do a durable reopen (fails)
  */
-static bool test_durable_v2_reconnect_delay_msec(
-       struct torture_context *tctx, struct smb2_tree *tree)
+static bool test_durable_v2_reconnect_delay_msec(struct torture_context *tctx,
+                                                struct smb2_tree *tree,
+                                                struct smb2_tree *tree2)
 {
        NTSTATUS status;
        TALLOC_CTX *mem_ctx = talloc_new(tctx);
@@ -2141,6 +2142,7 @@ static bool test_durable_v2_reconnect_delay_msec(
        uint64_t previous_session_id;
        uint8_t b = 0;
        bool ret = true;
+       bool ok;
 
        options = tree->session->transport->options;
        previous_session_id = 
smb2cli_session_current_id(tree->session->smbXcli);
@@ -2179,22 +2181,19 @@ static bool test_durable_v2_reconnect_delay_msec(
 
        /* disconnect, leaving the durable open */
        TALLOC_FREE(tree);
+       h = NULL;
 
-       if (!torture_smb2_connection_ext(tctx, previous_session_id,
-                                        &options, &tree)) {
-               torture_warning(tctx, "couldn't reconnect, bailing\n");
-               ret = false;
-               goto done;
-       }
+       ok = torture_smb2_connection_ext(tctx, previous_session_id,
+                                        &options, &tree);
+       torture_assert_goto(tctx, ok, ret, done, "couldn't reconnect, 
bailing\n");
 
        sleep(10);
 
        ZERO_STRUCT(io);
        io.in.fname = fname;
        io.in.durable_open_v2 = false;
-       io.in.durable_handle_v2 = h;
+       io.in.durable_handle_v2 = &_h;
        io.in.create_guid = create_guid;
-       h = NULL;
 
        status = smb2_create(tree, mem_ctx, &io);
        CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
@@ -2205,10 +2204,11 @@ done:
        if (h != NULL) {
                smb2_util_close(tree, *h);
        }
+       TALLOC_FREE(tree);
 
-       smb2_util_unlink(tree, fname);
+       smb2_util_unlink(tree2, fname);
 
-       talloc_free(tree);
+       TALLOC_FREE(tree2);
 
        talloc_free(mem_ctx);
 
@@ -2220,8 +2220,10 @@ struct torture_suite 
*torture_smb2_durable_v2_delay_init(TALLOC_CTX *ctx)
        struct torture_suite *suite =
            torture_suite_create(ctx, "durable-v2-delay");
 
-       torture_suite_add_1smb2_test(suite, "durable_v2_reconnect_delay", 
test_durable_v2_reconnect_delay);
-       torture_suite_add_1smb2_test(suite,
+       torture_suite_add_2smb2_test(suite,
+                                    "durable_v2_reconnect_delay",
+                                    test_durable_v2_reconnect_delay);
+       torture_suite_add_2smb2_test(suite,
                                     "durable_v2_reconnect_delay_msec",
                                     test_durable_v2_reconnect_delay_msec);
 
diff --git a/source4/torture/smb2/lock.c b/source4/torture/smb2/lock.c
index 1c515c865e5..eac0d557fc3 100644
--- a/source4/torture/smb2/lock.c
+++ b/source4/torture/smb2/lock.c
@@ -3167,8 +3167,10 @@ done:
  * Hopefully this will be fixed in future Windows versions and they
  * will avoid Note <314>.
  */
-static bool test_replay_smb3_specification(struct torture_context *torture,
-                                          struct smb2_tree *tree)
+static bool _test_replay_smb3_specification(struct torture_context *torture,
+                                           struct smb2_tree *tree,
+                                           const char *testname,
+                                           bool use_durable)
 {
        NTSTATUS status;
        bool ret = true;
@@ -3176,7 +3178,7 @@ static bool test_replay_smb3_specification(struct 
torture_context *torture,
        struct smb2_handle h;
        struct smb2_lock lck;
        struct smb2_lock_element el;
-       const char *fname = BASEDIR "\\replay_smb3_specification.txt";
+       char fname[256];
        struct smb2_transport *transport = tree->session->transport;
 
        if (smbXcli_conn_protocol(transport->conn) < PROTOCOL_SMB3_00) {
@@ -3184,22 +3186,24 @@ static bool test_replay_smb3_specification(struct 
torture_context *torture,
                                required for Lock Replay tests\n");
        }
 
+       snprintf(fname, sizeof(fname), "%s\\%s.dat", BASEDIR, testname);
+
        status = torture_smb2_testdir(tree, BASEDIR, &h);
        CHECK_STATUS(status, NT_STATUS_OK);
        smb2_util_close(tree, h);
 
-       torture_comment(torture, "Testing Open File:\n");
+       torture_comment(torture, "%s: Testing Open File:\n", testname);
 
        smb2_oplock_create_share(&io, fname,
                                 smb2_util_share_access(""),
                                 smb2_util_oplock_level("b"));
-       io.in.durable_open = true;
+       io.in.durable_open = use_durable;
 
        status = smb2_create(tree, torture, &io);
        CHECK_STATUS(status, NT_STATUS_OK);
        h = io.out.file.handle;
        CHECK_VALUE(io.out.oplock_level, smb2_util_oplock_level("b"));
-       CHECK_VALUE(io.out.durable_open, true);
+       CHECK_VALUE(io.out.durable_open, use_durable);
        CHECK_VALUE(io.out.durable_open_v2, false);
        CHECK_VALUE(io.out.persistent_open, false);
 
@@ -3363,6 +3367,41 @@ done:
        return ret;
 }
 
+static bool test_replay_smb3_specification_durable(struct torture_context 
*torture,
+                                                  struct smb2_tree *tree)
+{
+       const char *testname = "replay_smb3_specification_durable";
+       struct smb2_transport *transport = tree->session->transport;
+
+       if (smbXcli_conn_protocol(transport->conn) < PROTOCOL_SMB2_10) {
+               torture_skip(torture, "SMB 2.1.0 Dialect family or above \
+                               required for Lock Replay tests on durable 
handles\n");
+       }
+
+       return _test_replay_smb3_specification(torture, tree, testname, true);
+}
+
+static bool test_replay_smb3_specification_multi(struct torture_context 
*torture,
+                                                struct smb2_tree *tree)
+{
+       const char *testname = "replay_smb3_specification_multi";
+       struct smb2_transport *transport = tree->session->transport;
+       uint32_t server_capabilities;
+
+       if (smbXcli_conn_protocol(transport->conn) < PROTOCOL_SMB3_00) {
+               torture_skip(torture, "SMB 3.0.0 Dialect family or above \
+                       required for Lock Replay tests on without durable 
handles\n");
+       }
+
+       server_capabilities = smb2cli_conn_server_capabilities(transport->conn);
+       if (!(server_capabilities & SMB2_CAP_MULTI_CHANNEL)) {
+               torture_skip(torture, "MULTI_CHANNEL is \
+                       required for Lock Replay tests on without durable 
handles\n");
+       }
+
+       return _test_replay_smb3_specification(torture, tree, testname, false);
+}
+
 /**
  * Test lock interaction between smbd and ctdb with tombstone records.
  *
@@ -3462,8 +3501,10 @@ struct torture_suite *torture_smb2_lock_init(TALLOC_CTX 
*ctx)
        torture_suite_add_1smb2_test(suite, "truncate", test_truncate);
        torture_suite_add_1smb2_test(suite, "replay_broken_windows",
                                     test_replay_broken_windows);
-       torture_suite_add_1smb2_test(suite, "replay_smb3_specification",
-                                    test_replay_smb3_specification);
+       torture_suite_add_1smb2_test(suite, "replay_smb3_specification_durable",
+                                    test_replay_smb3_specification_durable);
+       torture_suite_add_1smb2_test(suite, "replay_smb3_specification_multi",
+                                    test_replay_smb3_specification_multi);
        torture_suite_add_1smb2_test(suite, "ctdb-delrec-deadlock", 
test_deadlock);
 
        suite->description = talloc_strdup(suite, "SMB2-LOCK tests");


-- 
Samba Shared Repository

Reply via email to