The branch, v4-7-test has been updated
       via  af47cdb s3:smbd: Do not crash if we fail to init the session table
       via  1efaec6 libsmb: Use smb2 tcon if conn_protocol >= SMB2_02
       via  e8a69b9 torture: Add test for channel sequence number handling
       via  164b38c smbXcli: Add "force_channel_sequence"
       via  f2d311e smbd: Fix channel sequence number checks for long-running 
requests
       via  d5c0ad6 smbd: Remove a "!" from an if-condition for easier 
readability
       via  caca68c torture4: Fix typos
       via  09200da smbd: Fix a typo
      from  b276495 build: fix libceph-common detection

https://git.samba.org/?p=samba.git;a=shortlog;h=v4-7-test


- Log -----------------------------------------------------------------
commit af47cdb3e1310ba0a365fa2c5b0161b6554fbead
Author: Andreas Schneider <a...@samba.org>
Date:   Mon Feb 19 18:07:50 2018 +0100

    s3:smbd: Do not crash if we fail to init the session table
    
    This should the following segfault with SMB1:
    
      #6  sig_fault (sig=<optimized out>) at ../lib/util/fault.c:94
      #7  <signal handler called>
      #8  smbXsrv_session_create (conn=conn@entry=0x5654d3512af0, 
now=now@entry=131594481900356690, _session=_session@entry=0x7ffc93a778e8)
          at ../source3/smbd/smbXsrv_session.c:1212
      #9  0x00007f7618aa21ef in reply_sesssetup_and_X 
(req=req@entry=0x5654d35174b0) at ../source3/smbd/sesssetup.c:961
      #10 0x00007f7618ae17b0 in switch_message (type=<optimized out>, 
req=req@entry=0x5654d35174b0) at ../source3/smbd/process.c:1726
      #11 0x00007f7618ae3550 in construct_reply (deferred_pcd=0x0, 
encrypted=false, seqnum=0, unread_bytes=0, size=140, inbuf=0x0, 
xconn=0x5654d35146d0)
          at ../source3/smbd/process.c:1762
      #12 process_smb (xconn=xconn@entry=0x5654d3512af0, inbuf=<optimized out>, 
nread=140, unread_bytes=0, seqnum=0, encrypted=<optimized out>,
          deferred_pcd=deferred_pcd@entry=0x0) at ../source3/smbd/process.c:2008
      #13 0x00007f7618ae4c41 in smbd_server_connection_read_handler 
(xconn=0x5654d3512af0, fd=40) at ../source3/smbd/process.c:2608
      #14 0x00007f761587eedb in epoll_event_loop_once () from 
/lib64/libtevent.so.0
    
    Inspection the core shows that:
      conn->client-session_table is NULL
      conn->protocol is PROTOCOL_NONE
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13315
    
    Signed-off-by: Andreas Schneider <a...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>
    (cherry picked from commit a89a7146563f2d9eb8bc02f1c090158ee499c878)
    
    Autobuild-User(v4-7-test): Stefan Metzmacher <me...@samba.org>
    Autobuild-Date(v4-7-test): Thu Mar  8 17:53:27 CET 2018 on sn-devel-144

commit 1efaec6bc9f51e3595ed254e38b6569962d36ee4
Author: Dan Robertson <drobert...@tripwire.com>
Date:   Thu Feb 22 20:47:11 2018 +0000

    libsmb: Use smb2 tcon if conn_protocol >= SMB2_02
    
    When the connection protocol is SMB2 the tid from the smb1 member is
    used instead of smb2 in cli_state_set_tid which often results in a null
    deref.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13310
    
    Signed-off-by: Dan Robertson <drobert...@tripwire.com>
    Reviewed-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Andreas Schneider <a...@samba.org>
    (cherry picked from commit b67ffaf518c971817b167b41bf6226cddfdcfd2f)

commit e8a69b9a3a58de4d78be1fabe7c5263002528a47
Author: Volker Lendecke <v...@samba.org>
Date:   Thu Jan 11 11:55:39 2018 +0100

    torture: Add test for channel sequence number handling
    
    We run into an assert when the csn wraps
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=13215
    
    Signed-off-by: Volker Lendecke <v...@samba.org>
    Reviewed-by: Stefan Metzmacher <me...@samba.org>
    
    Autobuild-User(master): Stefan Metzmacher <me...@samba.org>
    Autobuild-Date(master): Sun Jan 14 14:47:15 CET 2018 on sn-devel-144
    
    (cherry picked from commit 0abe16a5343de9a69bb5cccbad9809b28b642f45)

commit 164b38ccb778a9128fd6ad29cad72ab96e109f9d
Author: Volker Lendecke <v...@samba.org>
Date:   Thu Jan 11 11:25:49 2018 +0100

    smbXcli: Add "force_channel_sequence"
    
    This enables use of the channel sequence number even for
    non-multi-channel servers. This makes our client invalid, but we need to
    protect against broken clients with tests.
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=13215
    
    Signed-off-by: Volker Lendecke <v...@samba.org>
    Reviewed-by: Stefan Metzmacher <me...@samba.org>
    (cherry picked from commit cd288a08500b1cc38ef26e5cb8ef754b4da658b6)

commit f2d311eee9301717b99ed7ae758f0d05958d86b0
Author: Volker Lendecke <v...@samba.org>
Date:   Thu Jan 11 15:34:45 2018 +0100

    smbd: Fix channel sequence number checks for long-running requests
    
    When the client's supplied csn overflows and hits a pending, long-running
    request's csn, we panic. Fix this by counting the overflows in
    smbXsrv_open_global0->channel_generation
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=13215
    
    Pair-Programmed-With: Stefan Metzmacher <me...@samba.org>
    
    Signed-off-by: Volker Lendecke <v...@samba.org>
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    (cherry picked from commit 0b57434151a8334a6e9b9b7542824ce4915421a2)

commit d5c0ad63c942f4df60ef6dfcee5c48c65ba7dea3
Author: Volker Lendecke <v...@samba.org>
Date:   Wed Jan 10 14:59:08 2018 +0100

    smbd: Remove a "!" from an if-condition for easier readability
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=13215
    
    Signed-off-by: Volker Lendecke <v...@samba.org>
    Reviewed-by: Stefan Metzmacher <me...@samba.org>
    (cherry picked from commit 03f65a7cdc91091a171269cfebc9916f2f678388)

commit caca68c233f63a5ce3968c8bf8444aff9ac62479
Author: Volker Lendecke <v...@samba.org>
Date:   Wed Jan 10 15:51:56 2018 +0100

    torture4: Fix typos
    
    Signed-off-by: Volker Lendecke <v...@samba.org>
    Reviewed-by: Stefan Metzmacher <me...@samba.org>
    (cherry picked from commit 71cee27962cba53da3249bd3f5ece32a1d10071d)

commit 09200da7f28d0764022c4fc8db02d70e4bd37bb0
Author: Volker Lendecke <v...@samba.org>
Date:   Wed Jan 10 14:29:01 2018 +0100

    smbd: Fix a typo
    
    Signed-off-by: Volker Lendecke <v...@samba.org>
    Reviewed-by: Stefan Metzmacher <me...@samba.org>
    (cherry picked from commit e8636e7ab75f89e89ef054b5d4aa6c07fddcbe2a)

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

Summary of changes:
 libcli/smb/smbXcli_base.c      |  15 +++++-
 libcli/smb/smbXcli_base.h      |   4 ++
 source3/librpc/idl/smbXsrv.idl |   3 +-
 source3/libsmb/clientgen.c     |   2 +-
 source3/smbd/globals.h         |   1 +
 source3/smbd/negprot.c         |  23 ++++++--
 source3/smbd/smb2_server.c     |  27 +++++++---
 source4/torture/smb2/replay.c  | 117 +++++++++++++++++++++++++++++++++++++----
 8 files changed, 169 insertions(+), 23 deletions(-)


Changeset truncated at 500 lines:

diff --git a/libcli/smb/smbXcli_base.c b/libcli/smb/smbXcli_base.c
index 7322380..f1f90d9 100644
--- a/libcli/smb/smbXcli_base.c
+++ b/libcli/smb/smbXcli_base.c
@@ -138,6 +138,8 @@ struct smbXcli_conn {
 
                uint8_t io_priority;
 
+               bool force_channel_sequence;
+
                uint8_t preauth_sha512[64];
        } smb2;
 
@@ -549,6 +551,17 @@ const struct GUID *smbXcli_conn_server_guid(struct 
smbXcli_conn *conn)
        return &conn->smb1.server.guid;
 }
 
+bool smbXcli_conn_get_force_channel_sequence(struct smbXcli_conn *conn)
+{
+       return conn->smb2.force_channel_sequence;
+}
+
+void smbXcli_conn_set_force_channel_sequence(struct smbXcli_conn *conn,
+                                            bool v)
+{
+       conn->smb2.force_channel_sequence = v;
+}
+
 struct smbXcli_conn_samba_suicide_state {
        struct smbXcli_conn *conn;
        struct iovec iov;
@@ -2899,7 +2912,7 @@ struct tevent_req *smb2cli_req_create(TALLOC_CTX *mem_ctx,
        uint32_t flags = 0;
        uint32_t tid = 0;
        uint64_t uid = 0;
-       bool use_channel_sequence = false;
+       bool use_channel_sequence = conn->smb2.force_channel_sequence;
        uint16_t channel_sequence = 0;
        bool use_replay_flag = false;
 
diff --git a/libcli/smb/smbXcli_base.h b/libcli/smb/smbXcli_base.h
index 6d9198a..2532084 100644
--- a/libcli/smb/smbXcli_base.h
+++ b/libcli/smb/smbXcli_base.h
@@ -59,6 +59,10 @@ uint16_t smbXcli_conn_max_requests(struct smbXcli_conn 
*conn);
 NTTIME smbXcli_conn_server_system_time(struct smbXcli_conn *conn);
 const DATA_BLOB *smbXcli_conn_server_gss_blob(struct smbXcli_conn *conn);
 const struct GUID *smbXcli_conn_server_guid(struct smbXcli_conn *conn);
+bool smbXcli_conn_get_force_channel_sequence(struct smbXcli_conn *conn);
+void smbXcli_conn_set_force_channel_sequence(struct smbXcli_conn *conn,
+                                            bool v);
+
 
 struct tevent_req *smbXcli_conn_samba_suicide_send(TALLOC_CTX *mem_ctx,
                                                   struct tevent_context *ev,
diff --git a/source3/librpc/idl/smbXsrv.idl b/source3/librpc/idl/smbXsrv.idl
index 1bfa51e..d3f8d30 100644
--- a/source3/librpc/idl/smbXsrv.idl
+++ b/source3/librpc/idl/smbXsrv.idl
@@ -430,7 +430,8 @@ interface smbXsrv
                uint32                                  durable_timeout_msec;
                boolean8                                durable;
                DATA_BLOB                               backend_cookie;
-               hyper                                   channel_sequence;
+               uint16                                  channel_sequence;
+               hyper                                   channel_generation;
        } smbXsrv_open_global0;
 
        typedef union {
diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c
index 44afee1..2e4dd15 100644
--- a/source3/libsmb/clientgen.c
+++ b/source3/libsmb/clientgen.c
@@ -371,7 +371,7 @@ uint32_t cli_state_set_tid(struct cli_state *cli, uint32_t 
tid)
        uint32_t ret;
        if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
                ret = smb2cli_tcon_current_id(cli->smb2.tcon);
-               smb2cli_tcon_set_id(cli->smb1.tcon, tid);
+               smb2cli_tcon_set_id(cli->smb2.tcon, tid);
        } else {
                ret = smb1cli_tcon_current_id(cli->smb1.tcon);
                smb1cli_tcon_set_id(cli->smb1.tcon, tid);
diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h
index 78f1260..69db07a 100644
--- a/source3/smbd/globals.h
+++ b/source3/smbd/globals.h
@@ -744,6 +744,7 @@ struct smbd_smb2_request {
         * adapted again in reply.
         */
        bool request_counters_updated;
+       uint64_t channel_generation;
 
        /*
         * The sub request for async backend calls.
diff --git a/source3/smbd/negprot.c b/source3/smbd/negprot.c
index d3f4776..70249f7 100644
--- a/source3/smbd/negprot.c
+++ b/source3/smbd/negprot.c
@@ -65,6 +65,8 @@ static void reply_lanman1(struct smb_request *req, uint16_t 
choice)
        time_t t = time(NULL);
        struct smbXsrv_connection *xconn = req->xconn;
        uint16_t raw;
+       NTSTATUS status;
+
        if (lp_async_smb_echo_handler()) {
                raw = 0;
        } else {
@@ -88,7 +90,11 @@ static void reply_lanman1(struct smb_request *req, uint16_t 
choice)
                SSVAL(req->outbuf,smb_vwv11, 8);
        }
 
-       smbXsrv_connection_init_tables(xconn, PROTOCOL_LANMAN1);
+       status = smbXsrv_connection_init_tables(xconn, PROTOCOL_LANMAN1);
+       if (!NT_STATUS_IS_OK(status)) {
+               reply_nterror(req, status);
+               return;
+       }
 
        /* Reply, SMBlockread, SMBwritelock supported. */
        SCVAL(req->outbuf,smb_flg, FLAG_REPLY|FLAG_SUPPORT_LOCKREAD);
@@ -115,6 +121,8 @@ static void reply_lanman2(struct smb_request *req, uint16_t 
choice)
        time_t t = time(NULL);
        struct smbXsrv_connection *xconn = req->xconn;
        uint16_t raw;
+       NTSTATUS status;
+
        if (lp_async_smb_echo_handler()) {
                raw = 0;
        } else {
@@ -140,7 +148,11 @@ static void reply_lanman2(struct smb_request *req, 
uint16_t choice)
                SSVAL(req->outbuf,smb_vwv11, 8);
        }
 
-       smbXsrv_connection_init_tables(xconn, PROTOCOL_LANMAN2);
+       status = smbXsrv_connection_init_tables(xconn, PROTOCOL_LANMAN2);
+       if (!NT_STATUS_IS_OK(status)) {
+               reply_nterror(req, status);
+               return;
+       }
 
        /* Reply, SMBlockread, SMBwritelock supported. */
        SCVAL(req->outbuf,smb_flg,FLAG_REPLY|FLAG_SUPPORT_LOCKREAD);
@@ -260,6 +272,7 @@ static void reply_nt1(struct smb_request *req, uint16_t 
choice)
        struct smbXsrv_connection *xconn = req->xconn;
        bool signing_desired = false;
        bool signing_required = false;
+       NTSTATUS status;
 
        xconn->smb1.negprot.encrypted_passwords = lp_encrypt_passwords();
 
@@ -337,7 +350,11 @@ static void reply_nt1(struct smb_request *req, uint16_t 
choice)
        SSVAL(req->outbuf,smb_vwv0,choice);
        SCVAL(req->outbuf,smb_vwv1,secword);
 
-       smbXsrv_connection_init_tables(xconn, PROTOCOL_NT1);
+       status = smbXsrv_connection_init_tables(xconn, PROTOCOL_NT1);
+       if (!NT_STATUS_IS_OK(status)) {
+               reply_nterror(req, status);
+               return;
+       }
 
        SSVAL(req->outbuf,smb_vwv1+1, lp_max_mux()); /* maxmpx */
        SSVAL(req->outbuf,smb_vwv2+1, 1); /* num vcs */
diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c
index 5290c05..a731880 100644
--- a/source3/smbd/smb2_server.c
+++ b/source3/smbd/smb2_server.c
@@ -2158,6 +2158,7 @@ static NTSTATUS smbd_smb2_request_dispatch_update_counts(
        struct smbXsrv_connection *xconn = req->xconn;
        const uint8_t *inhdr;
        uint16_t channel_sequence;
+       uint8_t generation_wrap = 0;
        uint32_t flags;
        int cmp;
        struct smbXsrv_open *op;
@@ -2184,6 +2185,14 @@ static NTSTATUS smbd_smb2_request_dispatch_update_counts(
        channel_sequence = SVAL(inhdr, SMB2_HDR_CHANNEL_SEQUENCE);
 
        cmp = channel_sequence - op->global->channel_sequence;
+       if (cmp < 0) {
+               /*
+                * csn wrap. We need to watch out for long-running
+                * requests that are still sitting on a previously
+                * used csn. SMB2_OP_NOTIFY can take VERY long.
+                */
+               generation_wrap += 1;
+       }
 
        if (abs(cmp) > INT16_MAX) {
                /*
@@ -2220,7 +2229,7 @@ static NTSTATUS smbd_smb2_request_dispatch_update_counts(
                 * a 16 bit overflow of the client-submitted sequence
                 * number:
                 *
-                * If the stored channel squence number is more than
+                * If the stored channel sequence number is more than
                 * 0x7FFF larger than the one from the request, then
                 * the client-provided sequence number has likely
                 * overflown. We treat this case as valid instead
@@ -2231,33 +2240,36 @@ static NTSTATUS 
smbd_smb2_request_dispatch_update_counts(
                cmp *= -1;
        }
 
-       if (!(flags & SMB2_HDR_FLAG_REPLAY_OPERATION)) {
-               if (cmp == 0) {
+       if (flags & SMB2_HDR_FLAG_REPLAY_OPERATION) {
+               if (cmp == 0 && op->pre_request_count == 0) {
                        op->request_count += 1;
                        req->request_counters_updated = true;
-               } else if (cmp > 0) {
+               } else if (cmp > 0 && op->pre_request_count == 0) {
                        op->pre_request_count += op->request_count;
                        op->request_count = 1;
                        op->global->channel_sequence = channel_sequence;
+                       op->global->channel_generation += generation_wrap;
                        update_open = true;
                        req->request_counters_updated = true;
                } else if (modify_call) {
                        return NT_STATUS_FILE_NOT_AVAILABLE;
                }
        } else {
-               if (cmp == 0 && op->pre_request_count == 0) {
+               if (cmp == 0) {
                        op->request_count += 1;
                        req->request_counters_updated = true;
-               } else if (cmp > 0 && op->pre_request_count == 0) {
+               } else if (cmp > 0) {
                        op->pre_request_count += op->request_count;
                        op->request_count = 1;
                        op->global->channel_sequence = channel_sequence;
+                       op->global->channel_generation += generation_wrap;
                        update_open = true;
                        req->request_counters_updated = true;
                } else if (modify_call) {
                        return NT_STATUS_FILE_NOT_AVAILABLE;
                }
        }
+       req->channel_generation = op->global->channel_generation;
 
        if (update_open) {
                status = smbXsrv_open_update(op);
@@ -2744,7 +2756,8 @@ static void smbd_smb2_request_reply_update_counts(struct 
smbd_smb2_request *req)
        inhdr = SMBD_SMB2_IN_HDR_PTR(req);
        channel_sequence = SVAL(inhdr, SMB2_HDR_CHANNEL_SEQUENCE);
 
-       if (op->global->channel_sequence == channel_sequence) {
+       if ((op->global->channel_sequence == channel_sequence) &&
+           (op->global->channel_generation == req->channel_generation)) {
                SMB_ASSERT(op->request_count > 0);
                op->request_count -= 1;
        } else {
diff --git a/source4/torture/smb2/replay.c b/source4/torture/smb2/replay.c
index a38518a..021346a 100644
--- a/source4/torture/smb2/replay.c
+++ b/source4/torture/smb2/replay.c
@@ -473,7 +473,7 @@ done:
 }
 
 /**
- * Test Durablity V2 Create Replay Detection on Single Channel.
+ * Test Durability V2 Create Replay Detection on Single Channel.
  */
 static bool test_replay_dhv2_oplock1(struct torture_context *tctx,
                                     struct smb2_tree *tree)
@@ -560,7 +560,7 @@ done:
 }
 
 /**
- * Test Durablity V2 Create Replay Detection on Single Channel.
+ * Test Durability V2 Create Replay Detection on Single Channel.
  * Hand in a different oplock level in the replay.
  * Server responds with the handed in oplock level and
  * corresponding durable status, but does not change the
@@ -697,7 +697,7 @@ done:
 }
 
 /**
- * Test Durablity V2 Create Replay Detection on Single Channel.
+ * Test Durability V2 Create Replay Detection on Single Channel.
  * Replay with a different share mode. The share mode of
  * the opened file is not changed by this.
  */
@@ -823,7 +823,7 @@ done:
 }
 
 /**
- * Test Durablity V2 Create Replay Detection on Single Channel.
+ * Test Durability V2 Create Replay Detection on Single Channel.
  * Create with an oplock, and replay with a lease.
  */
 static bool test_replay_dhv2_oplock_lease(struct torture_context *tctx,
@@ -927,7 +927,7 @@ done:
 
 
 /**
- * Test durablity v2 create replay detection on single channel.
+ * Test durability v2 create replay detection on single channel.
  * Variant with leases instead of oplocks:
  * - open a file with a rh lease
  * - upgrade to a rwh lease with a second create
@@ -1065,7 +1065,7 @@ done:
 }
 
 /**
- * Test durablity v2 create replay detection on single channel.
+ * Test durability v2 create replay detection on single channel.
  * Variant with leases instead of oplocks, where the
  * replay does not specify the original lease level but
  * just a "R" lease. This still gives the upgraded lease
@@ -1216,7 +1216,7 @@ done:
 }
 
 /**
- * Test durablity v2 create replay detection on single channel.
+ * Test durability v2 create replay detection on single channel.
  * create with a lease, and replay with a different lease key
  */
 static bool test_replay_dhv2_lease3(struct torture_context *tctx,
@@ -1349,7 +1349,7 @@ done:
 }
 
 /**
- * Test durablity v2 create replay detection on single channel.
+ * Test durability v2 create replay detection on single channel.
  * Do the original create with a lease, and do the replay
  * with an oplock.
  */
@@ -1758,7 +1758,7 @@ done:
 }
 
 /**
- * Test Durablity V2 Create Replay Detection on Multi Channel
+ * Test Durability V2 Create Replay Detection on Multi Channel
  */
 static bool test_replay3(struct torture_context *tctx, struct smb2_tree *tree1)
 {
@@ -2162,7 +2162,7 @@ done:
 }
 
 /**
- * Test Durablity V2 Persistent Create Replay on a Single Channel
+ * Test Durability V2 Persistent Create Replay on a Single Channel
  */
 static bool test_replay5(struct torture_context *tctx, struct smb2_tree *tree)
 {
@@ -2425,6 +2425,102 @@ done:
        return ret;
 }
 
+static bool test_replay7(struct torture_context *tctx, struct smb2_tree *tree)
+{
+       TALLOC_CTX *mem_ctx = talloc_new(tctx);
+       struct smb2_transport *transport = tree->session->transport;
+       NTSTATUS status;
+       struct smb2_handle _dh;
+       struct smb2_handle *dh = NULL;
+       struct smb2_notify notify;
+       struct smb2_request *req;
+       union smb_fileinfo qfinfo;
+       bool ret = false;
+
+       if (smbXcli_conn_protocol(transport->conn) < PROTOCOL_SMB3_00) {
+               torture_skip(tctx, "SMB 3.X Dialect family required for "
+                                  "replay tests\n");
+       }
+
+       torture_comment(tctx, "Notify across increment/decrement of csn\n");
+
+       smbXcli_conn_set_force_channel_sequence(transport->conn, true);
+
+       status = torture_smb2_testdir(tree, BASEDIR, &_dh);
+       CHECK_STATUS(status, NT_STATUS_OK);
+       dh = &_dh;
+
+       notify.in.recursive             = 0x0000;
+       notify.in.buffer_size   = 0xffff;
+       notify.in.file.handle   = _dh;
+       notify.in.completion_filter     = FILE_NOTIFY_CHANGE_FILE_NAME;
+       notify.in.unknown               = 0x00000000;
+
+       /*
+        * This posts a long-running request with csn==0 to "dh". Now
+        * op->request_count==1 in smb2_server.c.
+        */
+       smb2cli_session_reset_channel_sequence(tree->session->smbXcli, 0);
+       req = smb2_notify_send(tree, &notify);
+
+       qfinfo = (union smb_fileinfo) {
+               .generic.level = RAW_FILEINFO_POSITION_INFORMATION,
+               .generic.in.file.handle = _dh
+       };
+
+       /*
+        * This sequence of 2 dummy requests moves
+        * op->request_count==1 to op->pre_request_count. The numbers
+        * used avoid int16 overflow.
+        */
+
+       smb2cli_session_reset_channel_sequence(tree->session->smbXcli, 30000);
+       status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
+       CHECK_STATUS(status, NT_STATUS_OK);
+
+       smb2cli_session_reset_channel_sequence(tree->session->smbXcli, 60000);
+       status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
+       CHECK_STATUS(status, NT_STATUS_OK);
+
+       /*
+        * This final request turns the op->global->channel_sequence
+        * to the same as we had when sending the notify above. The
+        * notify's request count has in the meantime moved to
+        * op->pre_request_count.
+        */
+
+       smb2cli_session_reset_channel_sequence(tree->session->smbXcli, 0);
+       status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
+       CHECK_STATUS(status, NT_STATUS_OK);
+
+       /*
+        * At this point op->request_count==0.
+        *
+        * The next cancel makes us reply to the notify. Because the
+        * csn we currently use is the same as we used when sending
+        * the notify, smbd thinks it must decrement op->request_count
+        * and not op->pre_request_count.
+        */
+
+       status = smb2_cancel(req);
+       CHECK_STATUS(status, NT_STATUS_OK);
+
+       status = smb2_notify_recv(req, mem_ctx, &notify);
+       CHECK_STATUS(status, NT_STATUS_CANCELLED);
+
+       ret = true;
+
+done:
+       if (dh != NULL) {
+               smb2_util_close(tree, _dh);
+       }
+       smb2_deltree(tree, BASEDIR);
+       talloc_free(tree);
+       talloc_free(mem_ctx);
+
+       return ret;
+}
+
 struct torture_suite *torture_smb2_replay_init(TALLOC_CTX *ctx)
 {
        struct torture_suite *suite =
@@ -2445,6 +2541,7 @@ struct torture_suite *torture_smb2_replay_init(TALLOC_CTX 
*ctx)
        torture_suite_add_1smb2_test(suite, "replay4", test_replay4);
        torture_suite_add_1smb2_test(suite, "replay5", test_replay5);
        torture_suite_add_1smb2_test(suite, "replay6", test_replay6);
+       torture_suite_add_1smb2_test(suite, "replay7", test_replay7);
 
        suite->description = talloc_strdup(suite, "SMB2 REPLAY tests");
 


-- 
Samba Shared Repository

Reply via email to