LCOV - code coverage report
Current view: top level - source4/torture/smb2 - replay.c (source / functions) Hit Total Coverage
Test: coverage report for v4-17-test 1498b464 Lines: 476 2524 18.9 %
Date: 2024-06-13 04:01:37 Functions: 61 62 98.4 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             : 
       4             :    test suite for SMB2 replay
       5             : 
       6             :    Copyright (C) Anubhav Rakshit 2014
       7             :    Copyright (C) Stefan Metzmacher 2014
       8             : 
       9             :    This program is free software; you can redistribute it and/or modify
      10             :    it under the terms of the GNU General Public License as published by
      11             :    the Free Software Foundation; either version 3 of the License, or
      12             :    (at your option) any later version.
      13             : 
      14             :    This program is distributed in the hope that it will be useful,
      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17             :    GNU General Public License for more details.
      18             : 
      19             :    You should have received a copy of the GNU General Public License
      20             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      21             : */
      22             : 
      23             : #include "includes.h"
      24             : #include "libcli/smb2/smb2.h"
      25             : #include "libcli/smb2/smb2_calls.h"
      26             : #include "torture/torture.h"
      27             : #include "torture/smb2/proto.h"
      28             : #include "../libcli/smb/smbXcli_base.h"
      29             : #include "lib/cmdline/cmdline.h"
      30             : #include "auth/credentials/credentials.h"
      31             : #include "libcli/security/security.h"
      32             : #include "libcli/resolve/resolve.h"
      33             : #include "lib/param/param.h"
      34             : #include "lib/events/events.h"
      35             : #include "oplock_break_handler.h"
      36             : #include "lease_break_handler.h"
      37             : 
      38             : #define CHECK_VAL(v, correct) do { \
      39             :         if ((v) != (correct)) { \
      40             :                 torture_result(tctx, TORTURE_FAIL, "(%s): wrong value for %s got 0x%x - should be 0x%x\n", \
      41             :                                 __location__, #v, (int)v, (int)correct); \
      42             :                 ret = false; \
      43             :                 goto done; \
      44             :         }} while (0)
      45             : 
      46             : #define CHECK_STATUS(status, correct) do { \
      47             :         if (!NT_STATUS_EQUAL(status, correct)) { \
      48             :                 torture_result(tctx, TORTURE_FAIL, __location__": Incorrect status %s - should be %s", \
      49             :                        nt_errstr(status), nt_errstr(correct)); \
      50             :                 ret = false; \
      51             :                 goto done; \
      52             :         }} while (0)
      53             : 
      54             : #define CHECK_CREATED(__io, __created, __attribute)                     \
      55             :         do {                                                            \
      56             :                 CHECK_VAL((__io)->out.create_action, NTCREATEX_ACTION_ ## __created); \
      57             :                 CHECK_VAL((__io)->out.size, 0);                              \
      58             :                 CHECK_VAL((__io)->out.file_attr, (__attribute));     \
      59             :                 CHECK_VAL((__io)->out.reserved2, 0);                 \
      60             :         } while(0)
      61             : 
      62             : #define CHECK_HANDLE(__h1, __h2)                                        \
      63             :         do {                                                            \
      64             :                 CHECK_VAL((__h1)->data[0], (__h2)->data[0]);              \
      65             :                 CHECK_VAL((__h1)->data[1], (__h2)->data[1]);              \
      66             :         } while(0)
      67             : 
      68             : #define __IO_OUT_VAL(__io1, __io2, __m) \
      69             :         CHECK_VAL((__io1)->out.__m, (__io2)->out.__m)
      70             : 
      71             : #define CHECK_CREATE_OUT(__io1, __io2)                          \
      72             :         do {                                                    \
      73             :                 CHECK_HANDLE(&(__io1)->out.file.handle,          \
      74             :                              &(__io2)->out.file.handle); \
      75             :                 __IO_OUT_VAL(__io1, __io2, oplock_level);       \
      76             :                 __IO_OUT_VAL(__io1, __io2, create_action);      \
      77             :                 __IO_OUT_VAL(__io1, __io2, create_time);        \
      78             :                 __IO_OUT_VAL(__io1, __io2, access_time);        \
      79             :                 __IO_OUT_VAL(__io1, __io2, write_time);         \
      80             :                 __IO_OUT_VAL(__io1, __io2, change_time);        \
      81             :                 __IO_OUT_VAL(__io1, __io2, alloc_size);         \
      82             :                 __IO_OUT_VAL(__io1, __io2, size);               \
      83             :                 __IO_OUT_VAL(__io1, __io2, file_attr);          \
      84             :                 __IO_OUT_VAL(__io1, __io2, durable_open);       \
      85             :                 __IO_OUT_VAL(__io1, __io2, durable_open_v2);    \
      86             :                 __IO_OUT_VAL(__io1, __io2, persistent_open);    \
      87             :                 __IO_OUT_VAL(__io1, __io2, timeout);            \
      88             :                 __IO_OUT_VAL(__io1, __io2, blobs.num_blobs);    \
      89             :                 if ((__io1)->out.oplock_level == SMB2_OPLOCK_LEVEL_LEASE) { \
      90             :                         __IO_OUT_VAL(__io1, __io2, lease_response.lease_state);\
      91             :                         __IO_OUT_VAL(__io1, __io2, lease_response.lease_key.data[0]);\
      92             :                         __IO_OUT_VAL(__io1, __io2, lease_response.lease_key.data[1]);\
      93             :                 } \
      94             :         } while(0)
      95             : 
      96             : #define WAIT_FOR_ASYNC_RESPONSE(__tctx, __req) do { \
      97             :         torture_comment((__tctx), "Waiting for async response: %s\n", #__req); \
      98             :         while (!(__req)->cancel.can_cancel && (__req)->state <= SMB2_REQUEST_RECV) { \
      99             :                 if (tevent_loop_once((__tctx)->ev) != 0) { \
     100             :                         break; \
     101             :                 } \
     102             :         } \
     103             : } while(0)
     104             : 
     105             : #define BASEDIR "replaytestdir"
     106             : 
     107             : /**
     108             :  * Test what happens when SMB2_FLAGS_REPLAY_OPERATION is enabled for various
     109             :  * commands. We want to verify if the server returns an error code or not.
     110             :  */
     111           1 : static bool test_replay_commands(struct torture_context *tctx, struct smb2_tree *tree)
     112             : {
     113           1 :         bool ret = true;
     114             :         NTSTATUS status;
     115             :         struct smb2_handle h;
     116             :         uint8_t buf[200];
     117             :         struct smb2_read rd;
     118             :         union smb_setfileinfo sfinfo;
     119             :         union smb_fileinfo qfinfo;
     120             :         union smb_ioctl ioctl;
     121             :         struct smb2_lock lck;
     122             :         struct smb2_lock_element el[2];
     123             :         struct smb2_flush f;
     124           1 :         TALLOC_CTX *tmp_ctx = talloc_new(tree);
     125           1 :         const char *fname = BASEDIR "\\replay_commands.dat";
     126           1 :         struct smb2_transport *transport = tree->session->transport;
     127             : 
     128           1 :         if (smbXcli_conn_protocol(transport->conn) < PROTOCOL_SMB3_00) {
     129           1 :                 torture_skip(tctx, "SMB 3.X Dialect family required for "
     130             :                                    "Replay tests\n");
     131             :         }
     132             : 
     133           0 :         torture_reset_break_info(tctx, &break_info);
     134           0 :         tree->session->transport->oplock.handler = torture_oplock_ack_handler;
     135           0 :         tree->session->transport->oplock.private_data = tree;
     136             : 
     137           0 :         status = torture_smb2_testdir(tree, BASEDIR, &h);
     138           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     139           0 :         smb2_util_close(tree, h);
     140             : 
     141           0 :         smb2cli_session_start_replay(tree->session->smbXcli);
     142             : 
     143           0 :         torture_comment(tctx, "Try Commands with Replay Flags Enabled\n");
     144             : 
     145           0 :         torture_comment(tctx, "Trying create\n");
     146           0 :         status = torture_smb2_testfile(tree, fname, &h);
     147           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     148           0 :         CHECK_VAL(break_info.count, 0);
     149             :         /*
     150             :          * Wireshark shows that the response has SMB2_FLAGS_REPLAY_OPERATION
     151             :          * flags set. The server should ignore this flag.
     152             :          */
     153             : 
     154           0 :         torture_comment(tctx, "Trying write\n");
     155           0 :         status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
     156           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     157             : 
     158           0 :         f = (struct smb2_flush) {
     159             :                 .in.file.handle = h
     160             :         };
     161           0 :         torture_comment(tctx, "Trying flush\n");
     162           0 :         status = smb2_flush(tree, &f);
     163           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     164             : 
     165           0 :         rd = (struct smb2_read) {
     166             :                 .in.file.handle = h,
     167             :                 .in.length = 10,
     168             :                 .in.offset = 0,
     169             :                 .in.min_count = 1
     170             :         };
     171           0 :         torture_comment(tctx, "Trying read\n");
     172           0 :         status = smb2_read(tree, tmp_ctx, &rd);
     173           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     174           0 :         CHECK_VAL(rd.out.data.length, 10);
     175             : 
     176           0 :         sfinfo.generic.level = RAW_SFILEINFO_POSITION_INFORMATION;
     177           0 :         sfinfo.position_information.in.file.handle = h;
     178           0 :         sfinfo.position_information.in.position = 0x1000;
     179           0 :         torture_comment(tctx, "Trying setinfo\n");
     180           0 :         status = smb2_setinfo_file(tree, &sfinfo);
     181           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     182             : 
     183           0 :         qfinfo = (union smb_fileinfo) {
     184             :                 .generic.level = RAW_FILEINFO_POSITION_INFORMATION,
     185             :                 .generic.in.file.handle = h
     186             :         };
     187           0 :         torture_comment(tctx, "Trying getinfo\n");
     188           0 :         status = smb2_getinfo_file(tree, tmp_ctx, &qfinfo);
     189           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     190           0 :         CHECK_VAL(qfinfo.position_information.out.position, 0x1000);
     191             : 
     192           0 :         ioctl = (union smb_ioctl) {
     193             :                 .smb2.level = RAW_IOCTL_SMB2,
     194             :                 .smb2.in.file.handle = h,
     195             :                 .smb2.in.function = FSCTL_CREATE_OR_GET_OBJECT_ID,
     196             :                 .smb2.in.max_output_response = 64,
     197             :                 .smb2.in.flags = SMB2_IOCTL_FLAG_IS_FSCTL
     198             :         };
     199           0 :         torture_comment(tctx, "Trying ioctl\n");
     200           0 :         status = smb2_ioctl(tree, tmp_ctx, &ioctl.smb2);
     201           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     202             : 
     203           0 :         lck = (struct smb2_lock) {
     204             :                 .in.locks = el,
     205             :                 .in.lock_count = 0x0001,
     206             :                 .in.lock_sequence = 0x00000000,
     207             :                 .in.file.handle = h
     208             :         };
     209           0 :         el[0].reserved          = 0x00000000;
     210           0 :         el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
     211             :                 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
     212             : 
     213           0 :         torture_comment(tctx, "Trying lock\n");
     214           0 :         el[0].offset            = 0x0000000000000000;
     215           0 :         el[0].length            = 0x0000000000000100;
     216           0 :         status = smb2_lock(tree, &lck);
     217           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     218             : 
     219           0 :         lck.in.file.handle      = h;
     220           0 :         el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
     221           0 :         status = smb2_lock(tree, &lck);
     222           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     223             : 
     224           0 :         CHECK_VAL(break_info.count, 0);
     225           0 : done:
     226           0 :         smb2cli_session_stop_replay(tree->session->smbXcli);
     227           0 :         smb2_util_close(tree, h);
     228           0 :         smb2_deltree(tree, BASEDIR);
     229             : 
     230           0 :         talloc_free(tmp_ctx);
     231             : 
     232           0 :         return ret;
     233             : }
     234             : 
     235             : /**
     236             :  * Test replay detection without create GUID on single channel.
     237             :  * Regular creates can not be replayed.
     238             :  * The return code is unaffected of the REPLAY_OPERATION flag.
     239             :  */
     240           1 : static bool test_replay_regular(struct torture_context *tctx,
     241             :                                 struct smb2_tree *tree)
     242             : {
     243             :         NTSTATUS status;
     244           1 :         TALLOC_CTX *mem_ctx = talloc_new(tctx);
     245             :         struct smb2_handle _h;
     246           1 :         struct smb2_handle *h = NULL;
     247             :         struct smb2_create io;
     248           1 :         uint32_t perms = 0;
     249           1 :         bool ret = true;
     250           1 :         const char *fname = BASEDIR "\\replay_regular.dat";
     251           1 :         struct smb2_transport *transport = tree->session->transport;
     252             : 
     253           1 :         if (smbXcli_conn_protocol(transport->conn) < PROTOCOL_SMB3_00) {
     254           1 :                 torture_skip(tctx, "SMB 3.X Dialect family required for "
     255             :                                    "replay tests\n");
     256             :         }
     257             : 
     258           0 :         torture_reset_break_info(tctx, &break_info);
     259           0 :         tree->session->transport->oplock.handler = torture_oplock_ack_handler;
     260           0 :         tree->session->transport->oplock.private_data = tree;
     261             : 
     262           0 :         smb2_util_unlink(tree, fname);
     263           0 :         status = torture_smb2_testdir(tree, BASEDIR, &_h);
     264           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     265           0 :         smb2_util_close(tree, _h);
     266           0 :         CHECK_VAL(break_info.count, 0);
     267             : 
     268           0 :         torture_comment(tctx, "No replay detection for regular create\n");
     269             : 
     270           0 :         perms = SEC_STD_SYNCHRONIZE | SEC_STD_READ_CONTROL | SEC_STD_DELETE |
     271             :                 SEC_DIR_WRITE_ATTRIBUTE | SEC_DIR_READ_ATTRIBUTE |
     272             :                 SEC_DIR_WRITE_EA | SEC_FILE_APPEND_DATA |
     273             :                 SEC_FILE_WRITE_DATA;
     274             : 
     275           0 :         io = (struct smb2_create) {
     276             :                 .in.desired_access  = perms,
     277             :                 .in.file_attributes = 0,
     278             :                 .in.create_disposition = NTCREATEX_DISP_CREATE,
     279             :                 .in.share_access    = NTCREATEX_SHARE_ACCESS_DELETE,
     280             :                 .in.create_options  = 0x0,
     281             :                 .in.fname   = fname
     282             :         };
     283             : 
     284           0 :         status = smb2_create(tree, tctx, &io);
     285           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     286           0 :         CHECK_VAL(break_info.count, 0);
     287           0 :         _h = io.out.file.handle;
     288           0 :         h = &_h;
     289           0 :         CHECK_CREATED(&io, CREATED, FILE_ATTRIBUTE_ARCHIVE);
     290             : 
     291           0 :         smb2cli_session_start_replay(tree->session->smbXcli);
     292           0 :         status = smb2_create(tree, tctx, &io);
     293           0 :         smb2cli_session_stop_replay(tree->session->smbXcli);
     294           0 :         CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_COLLISION);
     295           0 :         CHECK_VAL(break_info.count, 0);
     296             : 
     297           0 :         smb2_util_close(tree, *h);
     298           0 :         h = NULL;
     299           0 :         smb2_util_unlink(tree, fname);
     300             : 
     301             :         /*
     302             :          * Same experiment with different create disposition.
     303             :          */
     304           0 :         io.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
     305           0 :         status = smb2_create(tree, tctx, &io);
     306           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     307           0 :         CHECK_VAL(break_info.count, 0);
     308           0 :         _h = io.out.file.handle;
     309           0 :         h = &_h;
     310           0 :         CHECK_CREATED(&io, CREATED, FILE_ATTRIBUTE_ARCHIVE);
     311             : 
     312           0 :         smb2cli_session_start_replay(tree->session->smbXcli);
     313           0 :         status = smb2_create(tree, tctx, &io);
     314           0 :         smb2cli_session_stop_replay(tree->session->smbXcli);
     315           0 :         CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);
     316           0 :         CHECK_VAL(break_info.count, 0);
     317             : 
     318           0 :         smb2_util_close(tree, *h);
     319           0 :         h = NULL;
     320           0 :         smb2_util_unlink(tree, fname);
     321             : 
     322             :         /*
     323             :          * Now with more generous share mode.
     324             :          */
     325           0 :         io.in.share_access = smb2_util_share_access("RWD");
     326           0 :         status = smb2_create(tree, tctx, &io);
     327           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     328           0 :         CHECK_VAL(break_info.count, 0);
     329           0 :         _h = io.out.file.handle;
     330           0 :         h = &_h;
     331           0 :         CHECK_CREATED(&io, CREATED, FILE_ATTRIBUTE_ARCHIVE);
     332             : 
     333           0 :         smb2cli_session_start_replay(tree->session->smbXcli);
     334           0 :         status = smb2_create(tree, tctx, &io);
     335           0 :         smb2cli_session_stop_replay(tree->session->smbXcli);
     336           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     337           0 :         CHECK_VAL(break_info.count, 0);
     338             : 
     339           0 : done:
     340           0 :         if (h != NULL) {
     341           0 :                 smb2_util_close(tree, *h);
     342             :         }
     343           0 :         smb2_deltree(tree, BASEDIR);
     344             : 
     345           0 :         talloc_free(tree);
     346           0 :         talloc_free(mem_ctx);
     347             : 
     348           0 :         return ret;
     349             : }
     350             : 
     351             : /**
     352             :  * Test Durability V2 Create Replay Detection on Single Channel.
     353             :  */
     354           1 : static bool test_replay_dhv2_oplock1(struct torture_context *tctx,
     355             :                                      struct smb2_tree *tree)
     356             : {
     357             :         NTSTATUS status;
     358           1 :         TALLOC_CTX *mem_ctx = talloc_new(tctx);
     359             :         struct smb2_handle _h;
     360           1 :         struct smb2_handle *h = NULL;
     361             :         struct smb2_create io, ref1;
     362           1 :         struct GUID create_guid = GUID_random();
     363           1 :         bool ret = true;
     364           1 :         const char *fname = BASEDIR "\\replay_dhv2_oplock1.dat";
     365           1 :         struct smb2_transport *transport = tree->session->transport;
     366             :         uint32_t share_capabilities;
     367             :         bool share_is_so;
     368             : 
     369           1 :         if (smbXcli_conn_protocol(transport->conn) < PROTOCOL_SMB3_00) {
     370           1 :                 torture_skip(tctx, "SMB 3.X Dialect family required for "
     371             :                                    "replay tests\n");
     372             :         }
     373             : 
     374           0 :         share_capabilities = smb2cli_tcon_capabilities(tree->smbXcli);
     375           0 :         share_is_so = share_capabilities & SMB2_SHARE_CAP_SCALEOUT;
     376             : 
     377           0 :         torture_reset_break_info(tctx, &break_info);
     378           0 :         tree->session->transport->oplock.handler = torture_oplock_ack_handler;
     379           0 :         tree->session->transport->oplock.private_data = tree;
     380             : 
     381           0 :         torture_comment(tctx, "Replay of DurableHandleReqV2 on Single "
     382             :                               "Channel\n");
     383           0 :         smb2_util_unlink(tree, fname);
     384           0 :         status = torture_smb2_testdir(tree, BASEDIR, &_h);
     385           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     386           0 :         smb2_util_close(tree, _h);
     387           0 :         CHECK_VAL(break_info.count, 0);
     388             : 
     389           0 :         smb2_oplock_create_share(&io, fname,
     390             :                         smb2_util_share_access(""),
     391           0 :                         smb2_util_oplock_level("b"));
     392           0 :         io.in.durable_open = false;
     393           0 :         io.in.durable_open_v2 = true;
     394           0 :         io.in.persistent_open = false;
     395           0 :         io.in.create_guid = create_guid;
     396           0 :         io.in.timeout = UINT32_MAX;
     397             : 
     398           0 :         status = smb2_create(tree, mem_ctx, &io);
     399           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     400           0 :         ref1 = io;
     401           0 :         _h = io.out.file.handle;
     402           0 :         h = &_h;
     403           0 :         CHECK_CREATED(&io, CREATED, FILE_ATTRIBUTE_ARCHIVE);
     404           0 :         CHECK_VAL(io.out.durable_open, false);
     405           0 :         if (share_is_so) {
     406           0 :                 CHECK_VAL(io.out.oplock_level, smb2_util_oplock_level("s"));
     407           0 :                 CHECK_VAL(io.out.durable_open_v2, false);
     408           0 :                 CHECK_VAL(io.out.timeout, 0);
     409             :         } else {
     410           0 :                 CHECK_VAL(io.out.oplock_level, smb2_util_oplock_level("b"));
     411           0 :                 CHECK_VAL(io.out.durable_open_v2, true);
     412           0 :                 CHECK_VAL(io.out.timeout, 300*1000);
     413             :         }
     414             : 
     415             :         /*
     416             :          * Replay Durable V2 Create on single channel
     417             :          */
     418           0 :         smb2cli_session_start_replay(tree->session->smbXcli);
     419           0 :         status = smb2_create(tree, mem_ctx, &io);
     420           0 :         smb2cli_session_stop_replay(tree->session->smbXcli);
     421           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     422           0 :         CHECK_CREATE_OUT(&io, &ref1);
     423           0 :         CHECK_VAL(break_info.count, 0);
     424             : 
     425           0 : done:
     426           0 :         if (h != NULL) {
     427           0 :                 smb2_util_close(tree, *h);
     428             :         }
     429           0 :         smb2_deltree(tree, BASEDIR);
     430             : 
     431           0 :         talloc_free(tree);
     432           0 :         talloc_free(mem_ctx);
     433             : 
     434           0 :         return ret;
     435             : }
     436             : 
     437             : /**
     438             :  * Test Durability V2 Create Replay Detection on Single Channel.
     439             :  * Hand in a different oplock level in the replay.
     440             :  * Server responds with the handed in oplock level and
     441             :  * corresponding durable status, but does not change the
     442             :  * oplock level or durable status of the opened file.
     443             :  */
     444           1 : static bool test_replay_dhv2_oplock2(struct torture_context *tctx,
     445             :                                       struct smb2_tree *tree)
     446             : {
     447             :         NTSTATUS status;
     448           1 :         TALLOC_CTX *mem_ctx = talloc_new(tctx);
     449             :         struct smb2_handle _h;
     450           1 :         struct smb2_handle *h = NULL;
     451             :         struct smb2_create io, ref1, ref2;
     452           1 :         struct GUID create_guid = GUID_random();
     453           1 :         bool ret = true;
     454           1 :         const char *fname = BASEDIR "\\replay_dhv2_oplock2.dat";
     455           1 :         struct smb2_transport *transport = tree->session->transport;
     456             :         uint32_t share_capabilities;
     457             :         bool share_is_so;
     458             : 
     459           1 :         if (smbXcli_conn_protocol(transport->conn) < PROTOCOL_SMB3_00) {
     460           1 :                 torture_skip(tctx, "SMB 3.X Dialect family required for "
     461             :                                    "replay tests\n");
     462             :         }
     463             : 
     464           0 :         share_capabilities = smb2cli_tcon_capabilities(tree->smbXcli);
     465           0 :         share_is_so = share_capabilities & SMB2_SHARE_CAP_SCALEOUT;
     466             : 
     467           0 :         torture_reset_break_info(tctx, &break_info);
     468           0 :         tree->session->transport->oplock.handler = torture_oplock_ack_handler;
     469           0 :         tree->session->transport->oplock.private_data = tree;
     470             : 
     471           0 :         torture_comment(tctx, "Replay of DurableHandleReqV2 on Single "
     472             :                               "Channel\n");
     473           0 :         smb2_util_unlink(tree, fname);
     474           0 :         status = torture_smb2_testdir(tree, BASEDIR, &_h);
     475           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     476           0 :         smb2_util_close(tree, _h);
     477           0 :         CHECK_VAL(break_info.count, 0);
     478             : 
     479           0 :         smb2_oplock_create_share(&io, fname,
     480             :                         smb2_util_share_access(""),
     481           0 :                         smb2_util_oplock_level("b"));
     482           0 :         io.in.durable_open = false;
     483           0 :         io.in.durable_open_v2 = true;
     484           0 :         io.in.persistent_open = false;
     485           0 :         io.in.create_guid = create_guid;
     486           0 :         io.in.timeout = UINT32_MAX;
     487             : 
     488           0 :         status = smb2_create(tree, mem_ctx, &io);
     489           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     490           0 :         ref1 = io;
     491           0 :         _h = io.out.file.handle;
     492           0 :         h = &_h;
     493           0 :         CHECK_CREATED(&io, CREATED, FILE_ATTRIBUTE_ARCHIVE);
     494           0 :         CHECK_VAL(io.out.durable_open, false);
     495           0 :         if (share_is_so) {
     496           0 :                 CHECK_VAL(io.out.oplock_level, smb2_util_oplock_level("s"));
     497           0 :                 CHECK_VAL(io.out.durable_open_v2, false);
     498           0 :                 CHECK_VAL(io.out.timeout, 0);
     499             :         } else {
     500           0 :                 CHECK_VAL(io.out.oplock_level, smb2_util_oplock_level("b"));
     501           0 :                 CHECK_VAL(io.out.durable_open_v2, true);
     502           0 :                 CHECK_VAL(io.out.timeout, 300*1000);
     503             :         }
     504             : 
     505             :         /*
     506             :          * Replay durable v2 create on single channel:
     507             :          *
     508             :          * Replay the create with a different oplock (none).
     509             :          * The server replies with the requested oplock level
     510             :          * and also only replies with durable handle based
     511             :          * on whether it could have been granted based on
     512             :          * the requested oplock type.
     513             :          */
     514           0 :         smb2_oplock_create_share(&io, fname,
     515             :                         smb2_util_share_access(""),
     516           0 :                         smb2_util_oplock_level(""));
     517           0 :         io.in.durable_open = false;
     518           0 :         io.in.durable_open_v2 = true;
     519           0 :         io.in.persistent_open = false;
     520           0 :         io.in.create_guid = create_guid;
     521           0 :         io.in.timeout = UINT32_MAX;
     522             : 
     523             :         /*
     524             :          * Adapt the response to the exepected values
     525             :          */
     526           0 :         ref2 = ref1;
     527           0 :         ref2.out.oplock_level = smb2_util_oplock_level("");
     528           0 :         ref2.out.durable_open_v2 = false;
     529           0 :         ref2.out.timeout = 0;
     530           0 :         ref2.out.blobs.num_blobs = 0;
     531             : 
     532           0 :         smb2cli_session_start_replay(tree->session->smbXcli);
     533           0 :         status = smb2_create(tree, mem_ctx, &io);
     534           0 :         smb2cli_session_stop_replay(tree->session->smbXcli);
     535           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     536           0 :         CHECK_CREATE_OUT(&io, &ref2);
     537           0 :         CHECK_VAL(break_info.count, 0);
     538             : 
     539             :         /*
     540             :          * Prove that the open file still has a batch oplock
     541             :          * by breaking it with another open.
     542             :          */
     543           0 :         smb2_oplock_create_share(&io, fname,
     544             :                         smb2_util_share_access(""),
     545           0 :                         smb2_util_oplock_level("b"));
     546           0 :         io.in.durable_open = false;
     547           0 :         io.in.durable_open_v2 = true;
     548           0 :         io.in.persistent_open = false;
     549           0 :         io.in.create_guid = GUID_random();
     550           0 :         io.in.timeout = UINT32_MAX;
     551           0 :         status = smb2_create(tree, mem_ctx, &io);
     552           0 :         CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);
     553             : 
     554           0 :         if (!share_is_so) {
     555           0 :                 CHECK_VAL(break_info.count, 1);
     556           0 :                 CHECK_HANDLE(&break_info.handle, &ref1.out.file.handle);
     557           0 :                 CHECK_VAL(break_info.level, smb2_util_oplock_level("s"));
     558           0 :                 torture_reset_break_info(tctx, &break_info);
     559             :         }
     560             : 
     561           0 : done:
     562           0 :         if (h != NULL) {
     563           0 :                 smb2_util_close(tree, *h);
     564             :         }
     565           0 :         smb2_deltree(tree, BASEDIR);
     566             : 
     567           0 :         talloc_free(tree);
     568           0 :         talloc_free(mem_ctx);
     569             : 
     570           0 :         return ret;
     571             : }
     572             : 
     573             : /**
     574             :  * Test Durability V2 Create Replay Detection on Single Channel.
     575             :  * Replay with a different share mode. The share mode of
     576             :  * the opened file is not changed by this.
     577             :  */
     578           1 : static bool test_replay_dhv2_oplock3(struct torture_context *tctx,
     579             :                                      struct smb2_tree *tree)
     580             : {
     581             :         NTSTATUS status;
     582           1 :         TALLOC_CTX *mem_ctx = talloc_new(tctx);
     583             :         struct smb2_handle _h;
     584           1 :         struct smb2_handle *h = NULL;
     585             :         struct smb2_create io, ref1;
     586           1 :         struct GUID create_guid = GUID_random();
     587           1 :         bool ret = true;
     588           1 :         const char *fname = BASEDIR "\\replay_dhv2_oplock3.dat";
     589           1 :         struct smb2_transport *transport = tree->session->transport;
     590             :         uint32_t share_capabilities;
     591             :         bool share_is_so;
     592             : 
     593           1 :         if (smbXcli_conn_protocol(transport->conn) < PROTOCOL_SMB3_00) {
     594           1 :                 torture_skip(tctx, "SMB 3.X Dialect family required for "
     595             :                                    "replay tests\n");
     596             :         }
     597             : 
     598           0 :         share_capabilities = smb2cli_tcon_capabilities(tree->smbXcli);
     599           0 :         share_is_so = share_capabilities & SMB2_SHARE_CAP_SCALEOUT;
     600             : 
     601           0 :         torture_reset_break_info(tctx, &break_info);
     602           0 :         tree->session->transport->oplock.handler = torture_oplock_ack_handler;
     603           0 :         tree->session->transport->oplock.private_data = tree;
     604             : 
     605           0 :         torture_comment(tctx, "Replay of DurableHandleReqV2 on Single "
     606             :                               "Channel\n");
     607           0 :         smb2_util_unlink(tree, fname);
     608           0 :         status = torture_smb2_testdir(tree, BASEDIR, &_h);
     609           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     610           0 :         smb2_util_close(tree, _h);
     611           0 :         CHECK_VAL(break_info.count, 0);
     612             : 
     613           0 :         smb2_oplock_create_share(&io, fname,
     614             :                         smb2_util_share_access(""),
     615           0 :                         smb2_util_oplock_level("b"));
     616           0 :         io.in.durable_open = false;
     617           0 :         io.in.durable_open_v2 = true;
     618           0 :         io.in.persistent_open = false;
     619           0 :         io.in.create_guid = create_guid;
     620           0 :         io.in.timeout = UINT32_MAX;
     621             : 
     622           0 :         status = smb2_create(tree, mem_ctx, &io);
     623           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     624           0 :         ref1 = io;
     625           0 :         _h = io.out.file.handle;
     626           0 :         h = &_h;
     627           0 :         CHECK_CREATED(&io, CREATED, FILE_ATTRIBUTE_ARCHIVE);
     628           0 :         CHECK_VAL(io.out.durable_open, false);
     629           0 :         if (share_is_so) {
     630           0 :                 CHECK_VAL(io.out.oplock_level, smb2_util_oplock_level("s"));
     631           0 :                 CHECK_VAL(io.out.durable_open_v2, false);
     632           0 :                 CHECK_VAL(io.out.timeout, 0);
     633             :         } else {
     634           0 :                 CHECK_VAL(io.out.oplock_level, smb2_util_oplock_level("b"));
     635           0 :                 CHECK_VAL(io.out.durable_open_v2, true);
     636           0 :                 CHECK_VAL(io.out.timeout, 300*1000);
     637             :         }
     638             : 
     639             :         /*
     640             :          * Replay durable v2 create on single channel:
     641             :          *
     642             :          * Replay the create with a different share mode.
     643             :          * The server replies with the requested share
     644             :          * mode instead of that which is associated to
     645             :          * the handle.
     646             :          */
     647           0 :         smb2_oplock_create_share(&io, fname,
     648             :                         smb2_util_share_access("RWD"),
     649           0 :                         smb2_util_oplock_level("b"));
     650           0 :         io.in.durable_open = false;
     651           0 :         io.in.durable_open_v2 = true;
     652           0 :         io.in.persistent_open = false;
     653           0 :         io.in.create_guid = create_guid;
     654           0 :         io.in.timeout = UINT32_MAX;
     655             : 
     656           0 :         smb2cli_session_start_replay(tree->session->smbXcli);
     657           0 :         status = smb2_create(tree, mem_ctx, &io);
     658           0 :         smb2cli_session_stop_replay(tree->session->smbXcli);
     659           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     660           0 :         CHECK_CREATE_OUT(&io, &ref1);
     661           0 :         CHECK_VAL(break_info.count, 0);
     662             : 
     663             :         /*
     664             :          * In order to prove that the different share mode in the
     665             :          * replayed create had no effect on the open file handle,
     666             :          * show that a new create yields NT_STATUS_SHARING_VIOLATION.
     667             :          */
     668           0 :         smb2_oplock_create_share(&io, fname,
     669             :                         smb2_util_share_access(""),
     670           0 :                         smb2_util_oplock_level("b"));
     671           0 :         io.in.durable_open = false;
     672           0 :         io.in.durable_open_v2 = true;
     673           0 :         io.in.persistent_open = false;
     674           0 :         io.in.create_guid = GUID_random();
     675           0 :         io.in.timeout = UINT32_MAX;
     676           0 :         status = smb2_create(tree, mem_ctx, &io);
     677           0 :         CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);
     678             : 
     679           0 :         if (!share_is_so) {
     680           0 :                 CHECK_VAL(break_info.count, 1);
     681           0 :                 CHECK_HANDLE(&break_info.handle, &ref1.out.file.handle);
     682           0 :                 CHECK_VAL(break_info.level, smb2_util_oplock_level("s"));
     683           0 :                 torture_reset_break_info(tctx, &break_info);
     684             :         }
     685             : 
     686           0 : done:
     687           0 :         if (h != NULL) {
     688           0 :                 smb2_util_close(tree, *h);
     689             :         }
     690           0 :         smb2_deltree(tree, BASEDIR);
     691             : 
     692           0 :         talloc_free(tree);
     693           0 :         talloc_free(mem_ctx);
     694             : 
     695           0 :         return ret;
     696             : }
     697             : 
     698             : /**
     699             :  * Test Durability V2 Create Replay Detection on Single Channel.
     700             :  * Create with an oplock, and replay with a lease.
     701             :  */
     702           1 : static bool test_replay_dhv2_oplock_lease(struct torture_context *tctx,
     703             :                                           struct smb2_tree *tree)
     704             : {
     705             :         NTSTATUS status;
     706           1 :         TALLOC_CTX *mem_ctx = talloc_new(tctx);
     707             :         struct smb2_handle _h;
     708           1 :         struct smb2_handle *h = NULL;
     709             :         struct smb2_create io;
     710           1 :         struct GUID create_guid = GUID_random();
     711           1 :         bool ret = true;
     712           1 :         const char *fname = BASEDIR "\\replay_dhv2_oplock1.dat";
     713           1 :         struct smb2_transport *transport = tree->session->transport;
     714             :         uint32_t share_capabilities;
     715             :         bool share_is_so;
     716             :         uint32_t server_capabilities;
     717             :         struct smb2_lease ls;
     718             :         uint64_t lease_key;
     719             : 
     720           1 :         if (smbXcli_conn_protocol(transport->conn) < PROTOCOL_SMB3_00) {
     721           1 :                 torture_skip(tctx, "SMB 3.X Dialect family required for "
     722             :                                    "replay tests\n");
     723             :         }
     724             : 
     725           0 :         server_capabilities = smb2cli_conn_server_capabilities(transport->conn);
     726           0 :         if (!(server_capabilities & SMB2_CAP_LEASING)) {
     727           0 :                 torture_skip(tctx, "leases are not supported");
     728             :         }
     729             : 
     730           0 :         share_capabilities = smb2cli_tcon_capabilities(tree->smbXcli);
     731           0 :         share_is_so = share_capabilities & SMB2_SHARE_CAP_SCALEOUT;
     732             : 
     733           0 :         torture_reset_break_info(tctx, &break_info);
     734           0 :         tree->session->transport->oplock.handler = torture_oplock_ack_handler;
     735           0 :         tree->session->transport->oplock.private_data = tree;
     736             : 
     737           0 :         torture_comment(tctx, "Replay of DurableHandleReqV2 on Single "
     738             :                               "Channel\n");
     739           0 :         smb2_util_unlink(tree, fname);
     740           0 :         status = torture_smb2_testdir(tree, BASEDIR, &_h);
     741           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     742           0 :         smb2_util_close(tree, _h);
     743           0 :         CHECK_VAL(break_info.count, 0);
     744             : 
     745           0 :         smb2_oplock_create_share(&io, fname,
     746             :                         smb2_util_share_access(""),
     747           0 :                         smb2_util_oplock_level("b"));
     748           0 :         io.in.durable_open = false;
     749           0 :         io.in.durable_open_v2 = true;
     750           0 :         io.in.persistent_open = false;
     751           0 :         io.in.create_guid = create_guid;
     752           0 :         io.in.timeout = UINT32_MAX;
     753             : 
     754           0 :         status = smb2_create(tree, mem_ctx, &io);
     755           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     756           0 :         _h = io.out.file.handle;
     757           0 :         h = &_h;
     758           0 :         CHECK_CREATED(&io, CREATED, FILE_ATTRIBUTE_ARCHIVE);
     759           0 :         CHECK_VAL(io.out.durable_open, false);
     760           0 :         if (share_is_so) {
     761           0 :                 CHECK_VAL(io.out.oplock_level, smb2_util_oplock_level("s"));
     762           0 :                 CHECK_VAL(io.out.durable_open_v2, false);
     763           0 :                 CHECK_VAL(io.out.timeout, 0);
     764             :         } else {
     765           0 :                 CHECK_VAL(io.out.oplock_level, smb2_util_oplock_level("b"));
     766           0 :                 CHECK_VAL(io.out.durable_open_v2, true);
     767           0 :                 CHECK_VAL(io.out.timeout, 300*1000);
     768             :         }
     769             : 
     770             :         /*
     771             :          * Replay Durable V2 Create on single channel
     772             :          * but replay it with a lease instead of an oplock.
     773             :          */
     774           0 :         lease_key = random();
     775           0 :         smb2_lease_create(&io, &ls, false /* dir */, fname,
     776             :                         lease_key, smb2_util_lease_state("RH"));
     777           0 :         io.in.durable_open = false;
     778           0 :         io.in.durable_open_v2 = true;
     779           0 :         io.in.persistent_open = false;
     780           0 :         io.in.create_guid = create_guid;
     781           0 :         io.in.timeout = UINT32_MAX;
     782             : 
     783           0 :         smb2cli_session_start_replay(tree->session->smbXcli);
     784           0 :         status = smb2_create(tree, mem_ctx, &io);
     785           0 :         smb2cli_session_stop_replay(tree->session->smbXcli);
     786           0 :         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
     787             : 
     788           0 : done:
     789           0 :         if (h != NULL) {
     790           0 :                 smb2_util_close(tree, *h);
     791             :         }
     792           0 :         smb2_deltree(tree, BASEDIR);
     793             : 
     794           0 :         talloc_free(tree);
     795           0 :         talloc_free(mem_ctx);
     796             : 
     797           0 :         return ret;
     798             : }
     799             : 
     800             : 
     801             : /**
     802             :  * Test durability v2 create replay detection on single channel.
     803             :  * Variant with leases instead of oplocks:
     804             :  * - open a file with a rh lease
     805             :  * - upgrade to a rwh lease with a second create
     806             :  * - replay the first create.
     807             :  *   ==> it gets back the upgraded lease level
     808             :  */
     809           1 : static bool test_replay_dhv2_lease1(struct torture_context *tctx,
     810             :                                     struct smb2_tree *tree)
     811             : {
     812             :         NTSTATUS status;
     813           1 :         TALLOC_CTX *mem_ctx = talloc_new(tctx);
     814             :         struct smb2_handle _h1;
     815           1 :         struct smb2_handle *h1 = NULL;
     816             :         struct smb2_handle _h2;
     817           1 :         struct smb2_handle *h2 = NULL;
     818             :         struct smb2_create io1, io2, ref1;
     819           1 :         struct GUID create_guid = GUID_random();
     820           1 :         bool ret = true;
     821           1 :         const char *fname = BASEDIR "\\replay2_lease1.dat";
     822           1 :         struct smb2_transport *transport = tree->session->transport;
     823             :         uint32_t share_capabilities;
     824             :         bool share_is_so;
     825             :         uint32_t server_capabilities;
     826             :         struct smb2_lease ls1, ls2;
     827             :         uint64_t lease_key;
     828             : 
     829           1 :         if (smbXcli_conn_protocol(transport->conn) < PROTOCOL_SMB3_00) {
     830           1 :                 torture_skip(tctx, "SMB 3.X Dialect family required for "
     831             :                                    "replay tests\n");
     832             :         }
     833             : 
     834           0 :         server_capabilities = smb2cli_conn_server_capabilities(transport->conn);
     835           0 :         if (!(server_capabilities & SMB2_CAP_LEASING)) {
     836           0 :                 torture_skip(tctx, "leases are not supported");
     837             :         }
     838             : 
     839           0 :         share_capabilities = smb2cli_tcon_capabilities(tree->smbXcli);
     840           0 :         share_is_so = share_capabilities & SMB2_SHARE_CAP_SCALEOUT;
     841             : 
     842           0 :         torture_reset_break_info(tctx, &break_info);
     843           0 :         tree->session->transport->oplock.handler = torture_oplock_ack_handler;
     844           0 :         tree->session->transport->oplock.private_data = tree;
     845             : 
     846           0 :         torture_comment(tctx, "Replay of DurableHandleReqV2 with Lease "
     847             :                               "on Single Channel\n");
     848           0 :         smb2_util_unlink(tree, fname);
     849           0 :         status = torture_smb2_testdir(tree, BASEDIR, &_h1);
     850           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     851           0 :         smb2_util_close(tree, _h1);
     852           0 :         CHECK_VAL(break_info.count, 0);
     853             : 
     854           0 :         lease_key = random();
     855             : 
     856           0 :         smb2_lease_create(&io1, &ls1, false /* dir */, fname,
     857             :                         lease_key, smb2_util_lease_state("RH"));
     858           0 :         io1.in.durable_open = false;
     859           0 :         io1.in.durable_open_v2 = true;
     860           0 :         io1.in.persistent_open = false;
     861           0 :         io1.in.create_guid = create_guid;
     862           0 :         io1.in.timeout = UINT32_MAX;
     863             : 
     864           0 :         status = smb2_create(tree, mem_ctx, &io1);
     865           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     866           0 :         ref1 = io1;
     867           0 :         _h1 = io1.out.file.handle;
     868           0 :         h1 = &_h1;
     869           0 :         CHECK_CREATED(&io1, CREATED, FILE_ATTRIBUTE_ARCHIVE);
     870           0 :         CHECK_VAL(io1.out.durable_open, false);
     871           0 :         CHECK_VAL(io1.out.oplock_level, SMB2_OPLOCK_LEVEL_LEASE);
     872           0 :         CHECK_VAL(io1.out.lease_response.lease_key.data[0], lease_key);
     873           0 :         CHECK_VAL(io1.out.lease_response.lease_key.data[1], ~lease_key);
     874           0 :         if (share_is_so) {
     875           0 :                 CHECK_VAL(io1.out.lease_response.lease_state,
     876             :                           smb2_util_lease_state("R"));
     877           0 :                 CHECK_VAL(io1.out.durable_open_v2, false);
     878           0 :                 CHECK_VAL(io1.out.timeout, 0);
     879             :         } else {
     880           0 :                 CHECK_VAL(io1.out.lease_response.lease_state,
     881             :                           smb2_util_lease_state("RH"));
     882           0 :                 CHECK_VAL(io1.out.durable_open_v2, true);
     883           0 :                 CHECK_VAL(io1.out.timeout, 300*1000);
     884             :         }
     885             : 
     886             :         /*
     887             :          * Upgrade the lease to RWH
     888             :          */
     889           0 :         smb2_lease_create(&io2, &ls2, false /* dir */, fname,
     890             :                         lease_key, smb2_util_lease_state("RHW"));
     891           0 :         io2.in.durable_open = false;
     892           0 :         io2.in.durable_open_v2 = true;
     893           0 :         io2.in.persistent_open = false;
     894           0 :         io2.in.create_guid = GUID_random(); /* new guid... */
     895           0 :         io2.in.timeout = UINT32_MAX;
     896             : 
     897           0 :         status = smb2_create(tree, mem_ctx, &io2);
     898           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     899           0 :         _h2 = io2.out.file.handle;
     900           0 :         h2 = &_h2;
     901             : 
     902             :         /*
     903             :          * Replay Durable V2 Create on single channel.
     904             :          * We get the io from open #1 but with the
     905             :          * upgraded lease.
     906             :          */
     907             : 
     908             :         /* adapt expected lease in response */
     909           0 :         if (!share_is_so) {
     910           0 :                 ref1.out.lease_response.lease_state =
     911           0 :                         smb2_util_lease_state("RHW");
     912             :         }
     913             : 
     914           0 :         smb2cli_session_start_replay(tree->session->smbXcli);
     915           0 :         status = smb2_create(tree, mem_ctx, &io1);
     916           0 :         smb2cli_session_stop_replay(tree->session->smbXcli);
     917           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     918           0 :         CHECK_CREATE_OUT(&io1, &ref1);
     919           0 :         CHECK_VAL(break_info.count, 0);
     920             : 
     921           0 : done:
     922           0 :         smb2cli_session_stop_replay(tree->session->smbXcli);
     923             : 
     924           0 :         if (h1 != NULL) {
     925           0 :                 smb2_util_close(tree, *h1);
     926             :         }
     927           0 :         if (h2 != NULL) {
     928           0 :                 smb2_util_close(tree, *h2);
     929             :         }
     930           0 :         smb2_deltree(tree, BASEDIR);
     931             : 
     932           0 :         talloc_free(tree);
     933           0 :         talloc_free(mem_ctx);
     934             : 
     935           0 :         return ret;
     936             : }
     937             : 
     938             : /**
     939             :  * Test durability v2 create replay detection on single channel.
     940             :  * Variant with leases instead of oplocks, where the
     941             :  * replay does not specify the original lease level but
     942             :  * just a "R" lease. This still gives the upgraded lease
     943             :  * level in the reply.
     944             :  * - open a file with a rh lease
     945             :  * - upgrade to a rwh lease with a second create
     946             :  * - replay the first create.
     947             :  *   ==> it gets back the upgraded lease level
     948             :  */
     949           1 : static bool test_replay_dhv2_lease2(struct torture_context *tctx,
     950             :                                     struct smb2_tree *tree)
     951             : {
     952             :         NTSTATUS status;
     953           1 :         TALLOC_CTX *mem_ctx = talloc_new(tctx);
     954             :         struct smb2_handle _h1;
     955           1 :         struct smb2_handle *h1 = NULL;
     956             :         struct smb2_handle _h2;
     957           1 :         struct smb2_handle *h2 = NULL;
     958             :         struct smb2_create io1, io2, ref1;
     959           1 :         struct GUID create_guid = GUID_random();
     960           1 :         bool ret = true;
     961           1 :         const char *fname = BASEDIR "\\replay2_lease2.dat";
     962           1 :         struct smb2_transport *transport = tree->session->transport;
     963             :         uint32_t share_capabilities;
     964             :         bool share_is_so;
     965             :         uint32_t server_capabilities;
     966             :         struct smb2_lease ls1, ls2;
     967             :         uint64_t lease_key;
     968             : 
     969           1 :         if (smbXcli_conn_protocol(transport->conn) < PROTOCOL_SMB3_00) {
     970           1 :                 torture_skip(tctx, "SMB 3.X Dialect family required for "
     971             :                                    "replay tests\n");
     972             :         }
     973             : 
     974           0 :         server_capabilities = smb2cli_conn_server_capabilities(transport->conn);
     975           0 :         if (!(server_capabilities & SMB2_CAP_LEASING)) {
     976           0 :                 torture_skip(tctx, "leases are not supported");
     977             :         }
     978             : 
     979           0 :         share_capabilities = smb2cli_tcon_capabilities(tree->smbXcli);
     980           0 :         share_is_so = share_capabilities & SMB2_SHARE_CAP_SCALEOUT;
     981             : 
     982           0 :         torture_reset_break_info(tctx, &break_info);
     983           0 :         tree->session->transport->oplock.handler = torture_oplock_ack_handler;
     984           0 :         tree->session->transport->oplock.private_data = tree;
     985             : 
     986           0 :         torture_comment(tctx, "Replay of DurableHandleReqV2 with Lease "
     987             :                               "on Single Channel\n");
     988           0 :         smb2_util_unlink(tree, fname);
     989           0 :         status = torture_smb2_testdir(tree, BASEDIR, &_h1);
     990           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     991           0 :         smb2_util_close(tree, _h1);
     992           0 :         CHECK_VAL(break_info.count, 0);
     993             : 
     994           0 :         lease_key = random();
     995             : 
     996           0 :         smb2_lease_create(&io1, &ls1, false /* dir */, fname,
     997             :                         lease_key, smb2_util_lease_state("RH"));
     998           0 :         io1.in.durable_open = false;
     999           0 :         io1.in.durable_open_v2 = true;
    1000           0 :         io1.in.persistent_open = false;
    1001           0 :         io1.in.create_guid = create_guid;
    1002           0 :         io1.in.timeout = UINT32_MAX;
    1003             : 
    1004           0 :         status = smb2_create(tree, mem_ctx, &io1);
    1005           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    1006           0 :         CHECK_CREATED(&io1, CREATED, FILE_ATTRIBUTE_ARCHIVE);
    1007           0 :         CHECK_VAL(io1.out.durable_open, false);
    1008           0 :         CHECK_VAL(io1.out.oplock_level, SMB2_OPLOCK_LEVEL_LEASE);
    1009           0 :         CHECK_VAL(io1.out.lease_response.lease_key.data[0], lease_key);
    1010           0 :         CHECK_VAL(io1.out.lease_response.lease_key.data[1], ~lease_key);
    1011           0 :         if (share_is_so) {
    1012           0 :                 CHECK_VAL(io1.out.lease_response.lease_state,
    1013             :                           smb2_util_lease_state("R"));
    1014           0 :                 CHECK_VAL(io1.out.durable_open_v2, false);
    1015           0 :                 CHECK_VAL(io1.out.timeout, 0);
    1016             :         } else {
    1017           0 :                 CHECK_VAL(io1.out.lease_response.lease_state,
    1018             :                           smb2_util_lease_state("RH"));
    1019           0 :                 CHECK_VAL(io1.out.durable_open_v2, true);
    1020           0 :                 CHECK_VAL(io1.out.timeout, 300*1000);
    1021             :         }
    1022           0 :         ref1 = io1;
    1023           0 :         _h1 = io1.out.file.handle;
    1024           0 :         h1 = &_h1;
    1025             : 
    1026             :         /*
    1027             :          * Upgrade the lease to RWH
    1028             :          */
    1029           0 :         smb2_lease_create(&io2, &ls2, false /* dir */, fname,
    1030             :                         lease_key, smb2_util_lease_state("RHW"));
    1031           0 :         io2.in.durable_open = false;
    1032           0 :         io2.in.durable_open_v2 = true;
    1033           0 :         io2.in.persistent_open = false;
    1034           0 :         io2.in.create_guid = GUID_random(); /* new guid... */
    1035           0 :         io2.in.timeout = UINT32_MAX;
    1036             : 
    1037           0 :         status = smb2_create(tree, mem_ctx, &io2);
    1038           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    1039           0 :         _h2 = io2.out.file.handle;
    1040           0 :         h2 = &_h2;
    1041             : 
    1042             :         /*
    1043             :          * Replay Durable V2 Create on single channel.
    1044             :          * Changing the requested lease level to "R"
    1045             :          * does not change the response:
    1046             :          * We get the reply from open #1 but with the
    1047             :          * upgraded lease.
    1048             :          */
    1049             : 
    1050             :         /* adapt the expected response */
    1051           0 :         if (!share_is_so) {
    1052           0 :                 ref1.out.lease_response.lease_state =
    1053           0 :                                         smb2_util_lease_state("RHW");
    1054             :         }
    1055             : 
    1056           0 :         smb2_lease_create(&io1, &ls1, false /* dir */, fname,
    1057             :                         lease_key, smb2_util_lease_state("R"));
    1058           0 :         io1.in.durable_open = false;
    1059           0 :         io1.in.durable_open_v2 = true;
    1060           0 :         io1.in.persistent_open = false;
    1061           0 :         io1.in.create_guid = create_guid;
    1062           0 :         io1.in.timeout = UINT32_MAX;
    1063             : 
    1064           0 :         smb2cli_session_start_replay(tree->session->smbXcli);
    1065           0 :         status = smb2_create(tree, mem_ctx, &io1);
    1066           0 :         smb2cli_session_stop_replay(tree->session->smbXcli);
    1067           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    1068           0 :         CHECK_CREATE_OUT(&io1, &ref1);
    1069           0 :         CHECK_VAL(break_info.count, 0);
    1070             : 
    1071           0 : done:
    1072           0 :         smb2cli_session_stop_replay(tree->session->smbXcli);
    1073             : 
    1074           0 :         if (h1 != NULL) {
    1075           0 :                 smb2_util_close(tree, *h1);
    1076             :         }
    1077           0 :         if (h2 != NULL) {
    1078           0 :                 smb2_util_close(tree, *h2);
    1079             :         }
    1080           0 :         smb2_deltree(tree, BASEDIR);
    1081             : 
    1082           0 :         talloc_free(tree);
    1083           0 :         talloc_free(mem_ctx);
    1084             : 
    1085           0 :         return ret;
    1086             : }
    1087             : 
    1088             : /**
    1089             :  * Test durability v2 create replay detection on single channel.
    1090             :  * create with a lease, and replay with a different lease key
    1091             :  */
    1092           1 : static bool test_replay_dhv2_lease3(struct torture_context *tctx,
    1093             :                                     struct smb2_tree *tree)
    1094             : {
    1095             :         NTSTATUS status;
    1096           1 :         TALLOC_CTX *mem_ctx = talloc_new(tctx);
    1097             :         struct smb2_handle _h1;
    1098           1 :         struct smb2_handle *h1 = NULL;
    1099             :         struct smb2_handle _h2;
    1100           1 :         struct smb2_handle *h2 = NULL;
    1101             :         struct smb2_create io1, io2;
    1102           1 :         struct GUID create_guid = GUID_random();
    1103           1 :         bool ret = true;
    1104           1 :         const char *fname = BASEDIR "\\replay2_lease2.dat";
    1105           1 :         struct smb2_transport *transport = tree->session->transport;
    1106             :         uint32_t share_capabilities;
    1107             :         bool share_is_so;
    1108             :         uint32_t server_capabilities;
    1109             :         struct smb2_lease ls1, ls2;
    1110             :         uint64_t lease_key;
    1111             : 
    1112           1 :         if (smbXcli_conn_protocol(transport->conn) < PROTOCOL_SMB3_00) {
    1113           1 :                 torture_skip(tctx, "SMB 3.X Dialect family required for "
    1114             :                                    "replay tests\n");
    1115             :         }
    1116             : 
    1117           0 :         server_capabilities = smb2cli_conn_server_capabilities(transport->conn);
    1118           0 :         if (!(server_capabilities & SMB2_CAP_LEASING)) {
    1119           0 :                 torture_skip(tctx, "leases are not supported");
    1120             :         }
    1121             : 
    1122           0 :         share_capabilities = smb2cli_tcon_capabilities(tree->smbXcli);
    1123           0 :         share_is_so = share_capabilities & SMB2_SHARE_CAP_SCALEOUT;
    1124             : 
    1125           0 :         torture_reset_break_info(tctx, &break_info);
    1126           0 :         tree->session->transport->oplock.handler = torture_oplock_ack_handler;
    1127           0 :         tree->session->transport->oplock.private_data = tree;
    1128             : 
    1129           0 :         torture_comment(tctx, "Replay of DurableHandleReqV2 with Lease "
    1130             :                               "on Single Channel\n");
    1131           0 :         smb2_util_unlink(tree, fname);
    1132           0 :         status = torture_smb2_testdir(tree, BASEDIR, &_h1);
    1133           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    1134           0 :         smb2_util_close(tree, _h1);
    1135           0 :         CHECK_VAL(break_info.count, 0);
    1136             : 
    1137           0 :         lease_key = random();
    1138             : 
    1139           0 :         smb2_lease_create(&io1, &ls1, false /* dir */, fname,
    1140             :                         lease_key, smb2_util_lease_state("RH"));
    1141           0 :         io1.in.durable_open = false;
    1142           0 :         io1.in.durable_open_v2 = true;
    1143           0 :         io1.in.persistent_open = false;
    1144           0 :         io1.in.create_guid = create_guid;
    1145           0 :         io1.in.timeout = UINT32_MAX;
    1146             : 
    1147           0 :         status = smb2_create(tree, mem_ctx, &io1);
    1148           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    1149           0 :         CHECK_CREATED(&io1, CREATED, FILE_ATTRIBUTE_ARCHIVE);
    1150           0 :         CHECK_VAL(io1.out.durable_open, false);
    1151           0 :         CHECK_VAL(io1.out.oplock_level, SMB2_OPLOCK_LEVEL_LEASE);
    1152           0 :         CHECK_VAL(io1.out.lease_response.lease_key.data[0], lease_key);
    1153           0 :         CHECK_VAL(io1.out.lease_response.lease_key.data[1], ~lease_key);
    1154           0 :         if (share_is_so) {
    1155           0 :                 CHECK_VAL(io1.out.lease_response.lease_state,
    1156             :                           smb2_util_lease_state("R"));
    1157           0 :                 CHECK_VAL(io1.out.durable_open_v2, false);
    1158           0 :                 CHECK_VAL(io1.out.timeout, 0);
    1159             :         } else {
    1160           0 :                 CHECK_VAL(io1.out.lease_response.lease_state,
    1161             :                           smb2_util_lease_state("RH"));
    1162           0 :                 CHECK_VAL(io1.out.durable_open_v2, true);
    1163           0 :                 CHECK_VAL(io1.out.timeout, 300*1000);
    1164             :         }
    1165           0 :         _h1 = io1.out.file.handle;
    1166           0 :         h1 = &_h1;
    1167             : 
    1168             :         /*
    1169             :          * Upgrade the lease to RWH
    1170             :          */
    1171           0 :         smb2_lease_create(&io2, &ls2, false /* dir */, fname,
    1172             :                         lease_key, smb2_util_lease_state("RHW"));
    1173           0 :         io2.in.durable_open = false;
    1174           0 :         io2.in.durable_open_v2 = true;
    1175           0 :         io2.in.persistent_open = false;
    1176           0 :         io2.in.create_guid = GUID_random(); /* new guid... */
    1177           0 :         io2.in.timeout = UINT32_MAX;
    1178             : 
    1179           0 :         status = smb2_create(tree, mem_ctx, &io2);
    1180           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    1181           0 :         _h2 = io2.out.file.handle;
    1182           0 :         h2 = &_h2;
    1183             : 
    1184             :         /*
    1185             :          * Replay Durable V2 Create on single channel.
    1186             :          * use a different lease key.
    1187             :          */
    1188             : 
    1189           0 :         smb2_lease_create(&io1, &ls1, false /* dir */, fname,
    1190           0 :                         random() /* lease key */,
    1191             :                         smb2_util_lease_state("RH"));
    1192           0 :         io1.in.durable_open = false;
    1193           0 :         io1.in.durable_open_v2 = true;
    1194           0 :         io1.in.persistent_open = false;
    1195           0 :         io1.in.create_guid = create_guid;
    1196           0 :         io1.in.timeout = UINT32_MAX;
    1197             : 
    1198           0 :         smb2cli_session_start_replay(tree->session->smbXcli);
    1199           0 :         status = smb2_create(tree, mem_ctx, &io1);
    1200           0 :         smb2cli_session_stop_replay(tree->session->smbXcli);
    1201           0 :         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
    1202             : 
    1203           0 : done:
    1204           0 :         smb2cli_session_stop_replay(tree->session->smbXcli);
    1205             : 
    1206           0 :         if (h1 != NULL) {
    1207           0 :                 smb2_util_close(tree, *h1);
    1208             :         }
    1209           0 :         if (h2 != NULL) {
    1210           0 :                 smb2_util_close(tree, *h2);
    1211             :         }
    1212           0 :         smb2_deltree(tree, BASEDIR);
    1213             : 
    1214           0 :         talloc_free(tree);
    1215           0 :         talloc_free(mem_ctx);
    1216             : 
    1217           0 :         return ret;
    1218             : }
    1219             : 
    1220             : /**
    1221             :  * Test durability v2 create replay detection on single channel.
    1222             :  * Do the original create with a lease, and do the replay
    1223             :  * with an oplock.
    1224             :  */
    1225           1 : static bool test_replay_dhv2_lease_oplock(struct torture_context *tctx,
    1226             :                                           struct smb2_tree *tree)
    1227             : {
    1228             :         NTSTATUS status;
    1229           1 :         TALLOC_CTX *mem_ctx = talloc_new(tctx);
    1230             :         struct smb2_handle _h1;
    1231           1 :         struct smb2_handle *h1 = NULL;
    1232             :         struct smb2_handle _h2;
    1233           1 :         struct smb2_handle *h2 = NULL;
    1234             :         struct smb2_create io1, io2, ref1;
    1235           1 :         struct GUID create_guid = GUID_random();
    1236           1 :         bool ret = true;
    1237           1 :         const char *fname = BASEDIR "\\replay2_lease1.dat";
    1238           1 :         struct smb2_transport *transport = tree->session->transport;
    1239             :         uint32_t share_capabilities;
    1240             :         bool share_is_so;
    1241             :         uint32_t server_capabilities;
    1242             :         struct smb2_lease ls1, ls2;
    1243             :         uint64_t lease_key;
    1244             : 
    1245           1 :         if (smbXcli_conn_protocol(transport->conn) < PROTOCOL_SMB3_00) {
    1246           1 :                 torture_skip(tctx, "SMB 3.X Dialect family required for "
    1247             :                                    "replay tests\n");
    1248             :         }
    1249             : 
    1250           0 :         server_capabilities = smb2cli_conn_server_capabilities(transport->conn);
    1251           0 :         if (!(server_capabilities & SMB2_CAP_LEASING)) {
    1252           0 :                 torture_skip(tctx, "leases are not supported");
    1253             :         }
    1254             : 
    1255           0 :         share_capabilities = smb2cli_tcon_capabilities(tree->smbXcli);
    1256           0 :         share_is_so = share_capabilities & SMB2_SHARE_CAP_SCALEOUT;
    1257             : 
    1258           0 :         torture_reset_break_info(tctx, &break_info);
    1259           0 :         tree->session->transport->oplock.handler = torture_oplock_ack_handler;
    1260           0 :         tree->session->transport->oplock.private_data = tree;
    1261             : 
    1262           0 :         torture_comment(tctx, "Replay of DurableHandleReqV2 with Lease "
    1263             :                               "on Single Channel\n");
    1264           0 :         smb2_util_unlink(tree, fname);
    1265           0 :         status = torture_smb2_testdir(tree, BASEDIR, &_h1);
    1266           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    1267           0 :         smb2_util_close(tree, _h1);
    1268           0 :         CHECK_VAL(break_info.count, 0);
    1269             : 
    1270           0 :         lease_key = random();
    1271             : 
    1272           0 :         smb2_lease_create(&io1, &ls1, false /* dir */, fname,
    1273             :                         lease_key, smb2_util_lease_state("RH"));
    1274           0 :         io1.in.durable_open = false;
    1275           0 :         io1.in.durable_open_v2 = true;
    1276           0 :         io1.in.persistent_open = false;
    1277           0 :         io1.in.create_guid = create_guid;
    1278           0 :         io1.in.timeout = UINT32_MAX;
    1279             : 
    1280           0 :         status = smb2_create(tree, mem_ctx, &io1);
    1281           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    1282           0 :         ref1 = io1;
    1283           0 :         _h1 = io1.out.file.handle;
    1284           0 :         h1 = &_h1;
    1285           0 :         CHECK_CREATED(&io1, CREATED, FILE_ATTRIBUTE_ARCHIVE);
    1286           0 :         CHECK_VAL(io1.out.durable_open, false);
    1287           0 :         CHECK_VAL(io1.out.oplock_level, SMB2_OPLOCK_LEVEL_LEASE);
    1288           0 :         CHECK_VAL(io1.out.lease_response.lease_key.data[0], lease_key);
    1289           0 :         CHECK_VAL(io1.out.lease_response.lease_key.data[1], ~lease_key);
    1290           0 :         if (share_is_so) {
    1291           0 :                 CHECK_VAL(io1.out.lease_response.lease_state,
    1292             :                           smb2_util_lease_state("R"));
    1293           0 :                 CHECK_VAL(io1.out.durable_open_v2, false);
    1294           0 :                 CHECK_VAL(io1.out.timeout, 0);
    1295             :         } else {
    1296           0 :                 CHECK_VAL(io1.out.lease_response.lease_state,
    1297             :                           smb2_util_lease_state("RH"));
    1298           0 :                 CHECK_VAL(io1.out.durable_open_v2, true);
    1299           0 :                 CHECK_VAL(io1.out.timeout, 300*1000);
    1300             :         }
    1301             : 
    1302             :         /*
    1303             :          * Upgrade the lease to RWH
    1304             :          */
    1305           0 :         smb2_lease_create(&io2, &ls2, false /* dir */, fname,
    1306             :                         lease_key, smb2_util_lease_state("RHW"));
    1307           0 :         io2.in.durable_open = false;
    1308           0 :         io2.in.durable_open_v2 = true;
    1309           0 :         io2.in.persistent_open = false;
    1310           0 :         io2.in.create_guid = GUID_random(); /* new guid... */
    1311           0 :         io2.in.timeout = UINT32_MAX;
    1312             : 
    1313           0 :         status = smb2_create(tree, mem_ctx, &io2);
    1314           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    1315           0 :         _h2 = io2.out.file.handle;
    1316           0 :         h2 = &_h2;
    1317             : 
    1318             :         /*
    1319             :          * Replay Durable V2 Create on single channel.
    1320             :          * We get the io from open #1 but with the
    1321             :          * upgraded lease.
    1322             :          */
    1323             : 
    1324           0 :         smb2_oplock_create_share(&io2, fname,
    1325             :                         smb2_util_share_access(""),
    1326           0 :                         smb2_util_oplock_level("b"));
    1327           0 :         io2.in.durable_open = false;
    1328           0 :         io2.in.durable_open_v2 = true;
    1329           0 :         io2.in.persistent_open = false;
    1330           0 :         io2.in.create_guid = create_guid;
    1331           0 :         io2.in.timeout = UINT32_MAX;
    1332             : 
    1333             :         /* adapt expected lease in response */
    1334           0 :         if (!share_is_so) {
    1335           0 :                 ref1.out.lease_response.lease_state =
    1336           0 :                         smb2_util_lease_state("RHW");
    1337             :         }
    1338             : 
    1339           0 :         smb2cli_session_start_replay(tree->session->smbXcli);
    1340           0 :         status = smb2_create(tree, mem_ctx, &io1);
    1341           0 :         smb2cli_session_stop_replay(tree->session->smbXcli);
    1342           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    1343           0 :         CHECK_CREATE_OUT(&io1, &ref1);
    1344           0 :         CHECK_VAL(break_info.count, 0);
    1345             : 
    1346           0 : done:
    1347           0 :         smb2cli_session_stop_replay(tree->session->smbXcli);
    1348             : 
    1349           0 :         if (h1 != NULL) {
    1350           0 :                 smb2_util_close(tree, *h1);
    1351             :         }
    1352           0 :         if (h2 != NULL) {
    1353           0 :                 smb2_util_close(tree, *h2);
    1354             :         }
    1355           0 :         smb2_deltree(tree, BASEDIR);
    1356             : 
    1357           0 :         talloc_free(tree);
    1358           0 :         talloc_free(mem_ctx);
    1359             : 
    1360           0 :         return ret;
    1361             : }
    1362             : 
    1363             : /**
    1364             :  * This tests replay with a pending open on a single
    1365             :  * channel. It tests the case where the client2 open
    1366             :  * is deferred because it conflicts with a HANDLE lease,
    1367             :  * which is broken because the operation should otherwise
    1368             :  * return NT_STATUS_SHARING_VIOLATION.
    1369             :  *
    1370             :  * With a durablev2 request containing a create_guid:
    1371             :  * - client2_level = NONE:
    1372             :  *   but without asking for an oplock nor a lease.
    1373             :  * - client2_level = BATCH:
    1374             :  *   and asking for a batch oplock.
    1375             :  * - client2_level = LEASE
    1376             :  *   and asking for an RWH lease.
    1377             :  *
    1378             :  * While another client holds a batch oplock or
    1379             :  * RWH lease. (client1_level => LEASE or BATCH).
    1380             :  *
    1381             :  * There are two modes of this test one, with releaseing
    1382             :  * the oplock/lease of client1 via close or ack.
    1383             :  * (release_op SMB2_OP_CLOSE/SMB2_OP_BREAK).
    1384             :  *
    1385             :  * Windows doesn't detect replays in this case and
    1386             :  * always result in NT_STATUS_SHARING_VIOLATION.
    1387             :  *
    1388             :  * See https://bugzilla.samba.org/show_bug.cgi?id=14449
    1389             :  */
    1390           4 : static bool _test_dhv2_pending1_vs_violation(struct torture_context *tctx,
    1391             :                                              const char *testname,
    1392             :                                              struct smb2_tree *tree1,
    1393             :                                              uint8_t client1_level,
    1394             :                                              uint8_t release_op,
    1395             :                                              struct smb2_tree *tree2,
    1396             :                                              uint8_t client2_level,
    1397             :                                              NTSTATUS orig21_reject_status,
    1398             :                                              NTSTATUS replay22_reject_status,
    1399             :                                              NTSTATUS replay23_reject_status)
    1400             : {
    1401             :         NTSTATUS status;
    1402           4 :         TALLOC_CTX *mem_ctx = talloc_new(tctx);
    1403             :         struct smb2_handle _h1;
    1404           4 :         struct smb2_handle *h1 = NULL;
    1405           4 :         struct smb2_handle *h2f = NULL;
    1406             :         struct smb2_handle _h21;
    1407           4 :         struct smb2_handle *h21 = NULL;
    1408             :         struct smb2_handle _h23;
    1409           4 :         struct smb2_handle *h23 = NULL;
    1410             :         struct smb2_handle _h24;
    1411           4 :         struct smb2_handle *h24 = NULL;
    1412             :         struct smb2_create io1, io21, io22, io23, io24;
    1413           4 :         struct GUID create_guid1 = GUID_random();
    1414           4 :         struct GUID create_guid2 = GUID_random();
    1415           4 :         struct smb2_request *req21 = NULL;
    1416           4 :         struct smb2_request *req22 = NULL;
    1417           4 :         bool ret = true;
    1418             :         char fname[256];
    1419           4 :         struct smb2_transport *transport1 = tree1->session->transport;
    1420             :         uint32_t server_capabilities;
    1421             :         uint32_t share_capabilities;
    1422             :         struct smb2_lease ls1;
    1423             :         uint64_t lease_key1;
    1424           4 :         uint16_t lease_epoch1 = 0;
    1425             :         struct smb2_break op_ack1;
    1426             :         struct smb2_lease_break_ack lb_ack1;
    1427             :         struct smb2_lease ls2;
    1428             :         uint64_t lease_key2;
    1429           4 :         uint16_t lease_epoch2 = 0;
    1430             :         bool share_is_so;
    1431           4 :         struct smb2_transport *transport2 = tree2->session->transport;
    1432           4 :         int request_timeout2 = transport2->options.request_timeout;
    1433           4 :         struct smb2_session *session2 = tree2->session;
    1434           4 :         const char *hold_name = NULL;
    1435             : 
    1436           4 :         switch (client1_level) {
    1437           4 :         case SMB2_OPLOCK_LEVEL_LEASE:
    1438           4 :                 hold_name = "RWH Lease";
    1439           4 :                 break;
    1440           0 :         case SMB2_OPLOCK_LEVEL_BATCH:
    1441           0 :                 hold_name = "BATCH Oplock";
    1442           0 :                 break;
    1443           0 :         default:
    1444           0 :                 smb_panic(__location__);
    1445             :                 break;
    1446             :         }
    1447             : 
    1448           4 :         if (smbXcli_conn_protocol(transport1->conn) < PROTOCOL_SMB3_00) {
    1449           4 :                 torture_skip(tctx, "SMB 3.X Dialect family required for "
    1450             :                                    "replay tests\n");
    1451             :         }
    1452             : 
    1453           0 :         server_capabilities = smb2cli_conn_server_capabilities(transport1->conn);
    1454           0 :         if (!(server_capabilities & SMB2_CAP_LEASING)) {
    1455           0 :                 if (client1_level == SMB2_OPLOCK_LEVEL_LEASE ||
    1456             :                     client2_level == SMB2_OPLOCK_LEVEL_LEASE) {
    1457           0 :                         torture_skip(tctx, "leases are not supported");
    1458             :                 }
    1459             :         }
    1460             : 
    1461           0 :         share_capabilities = smb2cli_tcon_capabilities(tree1->smbXcli);
    1462           0 :         share_is_so = share_capabilities & SMB2_SHARE_CAP_SCALEOUT;
    1463           0 :         if (share_is_so) {
    1464           0 :                 torture_skip(tctx, talloc_asprintf(tctx,
    1465             :                              "%s not supported on SCALEOUT share",
    1466             :                              hold_name));
    1467             :         }
    1468             : 
    1469             :         /* Add some random component to the file name. */
    1470           0 :         snprintf(fname, sizeof(fname), "%s\\%s_%s.dat",
    1471             :                  BASEDIR, testname, generate_random_str(tctx, 8));
    1472             : 
    1473           0 :         torture_reset_break_info(tctx, &break_info);
    1474           0 :         break_info.oplock_skip_ack = true;
    1475           0 :         ZERO_STRUCT(op_ack1);
    1476           0 :         torture_reset_lease_break_info(tctx, &lease_break_info);
    1477           0 :         lease_break_info.lease_skip_ack = true;
    1478           0 :         ZERO_STRUCT(lb_ack1);
    1479           0 :         transport1->oplock.handler = torture_oplock_ack_handler;
    1480           0 :         transport1->oplock.private_data = tree1;
    1481           0 :         transport1->lease.handler = torture_lease_handler;
    1482           0 :         transport1->lease.private_data = tree1;
    1483           0 :         smb2_keepalive(transport1);
    1484           0 :         transport2->oplock.handler = torture_oplock_ack_handler;
    1485           0 :         transport2->oplock.private_data = tree2;
    1486           0 :         transport2->lease.handler = torture_lease_handler;
    1487           0 :         transport2->lease.private_data = tree2;
    1488           0 :         smb2_keepalive(transport2);
    1489             : 
    1490           0 :         smb2_util_unlink(tree1, fname);
    1491           0 :         status = torture_smb2_testdir(tree1, BASEDIR, &_h1);
    1492           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    1493           0 :         smb2_util_close(tree1, _h1);
    1494           0 :         CHECK_VAL(break_info.count, 0);
    1495             : 
    1496           0 :         lease_key1 = random();
    1497           0 :         if (client1_level == SMB2_OPLOCK_LEVEL_LEASE) {
    1498           0 :                 smb2_lease_v2_create(&io1, &ls1, false /* dir */, fname,
    1499           0 :                         lease_key1, NULL, smb2_util_lease_state("RWH"), lease_epoch1++);
    1500             :         } else {
    1501           0 :                 smb2_oplock_create(&io1, fname, SMB2_OPLOCK_LEVEL_BATCH);
    1502             :         }
    1503           0 :         io1.in.share_access = 0;
    1504           0 :         io1.in.desired_access = SEC_RIGHTS_FILE_ALL;
    1505           0 :         io1.in.durable_open = false;
    1506           0 :         io1.in.durable_open_v2 = true;
    1507           0 :         io1.in.persistent_open = false;
    1508           0 :         io1.in.create_guid = create_guid1;
    1509           0 :         io1.in.timeout = UINT32_MAX;
    1510             : 
    1511           0 :         status = smb2_create(tree1, mem_ctx, &io1);
    1512           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    1513           0 :         _h1 = io1.out.file.handle;
    1514           0 :         h1 = &_h1;
    1515           0 :         CHECK_CREATED(&io1, CREATED, FILE_ATTRIBUTE_ARCHIVE);
    1516           0 :         CHECK_VAL(io1.out.durable_open, false);
    1517           0 :         if (client1_level == SMB2_OPLOCK_LEVEL_LEASE) {
    1518           0 :                 CHECK_VAL(io1.out.oplock_level, SMB2_OPLOCK_LEVEL_LEASE);
    1519           0 :                 CHECK_VAL(io1.out.lease_response_v2.lease_key.data[0], lease_key1);
    1520           0 :                 CHECK_VAL(io1.out.lease_response_v2.lease_key.data[1], ~lease_key1);
    1521           0 :                 CHECK_VAL(io1.out.lease_response_v2.lease_epoch, lease_epoch1);
    1522           0 :                 CHECK_VAL(io1.out.lease_response_v2.lease_state,
    1523             :                           smb2_util_lease_state("RWH"));
    1524             :         } else {
    1525           0 :                 CHECK_VAL(io1.out.oplock_level, SMB2_OPLOCK_LEVEL_BATCH);
    1526             :         }
    1527           0 :         CHECK_VAL(io1.out.durable_open_v2, true);
    1528           0 :         CHECK_VAL(io1.out.timeout, 300*1000);
    1529             : 
    1530           0 :         lease_key2 = random();
    1531           0 :         if (client2_level == SMB2_OPLOCK_LEVEL_LEASE) {
    1532           0 :                 smb2_lease_v2_create(&io21, &ls2, false /* dir */, fname,
    1533           0 :                         lease_key2, NULL, smb2_util_lease_state("RWH"), lease_epoch2++);
    1534             :         } else {
    1535           0 :                 smb2_oplock_create(&io21, fname, client2_level);
    1536             :         }
    1537           0 :         io21.in.share_access = 0;
    1538           0 :         io21.in.desired_access = SEC_RIGHTS_FILE_ALL;
    1539           0 :         io21.in.desired_access = SEC_RIGHTS_FILE_READ;
    1540           0 :         io21.in.durable_open = false;
    1541           0 :         io21.in.durable_open_v2 = true;
    1542           0 :         io21.in.persistent_open = false;
    1543           0 :         io21.in.create_guid = create_guid2;
    1544           0 :         io21.in.timeout = UINT32_MAX;
    1545           0 :         io24 = io23 = io22 = io21;
    1546             : 
    1547           0 :         req21 = smb2_create_send(tree2, &io21);
    1548           0 :         torture_assert(tctx, req21 != NULL, "req21");
    1549             : 
    1550           0 :         if (client1_level == SMB2_OPLOCK_LEVEL_LEASE) {
    1551           0 :                 const struct smb2_lease_break *lb =
    1552             :                         &lease_break_info.lease_break;
    1553           0 :                 const struct smb2_lease *l = &lb->current_lease;
    1554           0 :                 const struct smb2_lease_key *k = &l->lease_key;
    1555             : 
    1556           0 :                 torture_wait_for_lease_break(tctx);
    1557           0 :                 CHECK_VAL(break_info.count, 0);
    1558           0 :                 CHECK_VAL(lease_break_info.count, 1);
    1559             : 
    1560           0 :                 torture_assert(tctx,
    1561             :                         lease_break_info.lease_transport == transport1,
    1562             :                         "expect lease break on transport1\n");
    1563           0 :                 CHECK_VAL(k->data[0], lease_key1);
    1564           0 :                 CHECK_VAL(k->data[1], ~lease_key1);
    1565             :                 /*
    1566             :                  * With share none the handle lease
    1567             :                  * is broken.
    1568             :                  */
    1569           0 :                 CHECK_VAL(lb->new_lease_state,
    1570             :                           smb2_util_lease_state("RW"));
    1571           0 :                 CHECK_VAL(lb->break_flags,
    1572             :                           SMB2_NOTIFY_BREAK_LEASE_FLAG_ACK_REQUIRED);
    1573           0 :                 CHECK_VAL(lb->new_epoch, lease_epoch1+1);
    1574           0 :                 lease_epoch1 += 1;
    1575             : 
    1576           0 :                 lb_ack1.in.lease.lease_key = lb->current_lease.lease_key;
    1577           0 :                 lb_ack1.in.lease.lease_state = lb->new_lease_state;
    1578             :         } else {
    1579           0 :                 torture_wait_for_oplock_break(tctx);
    1580           0 :                 CHECK_VAL(break_info.count, 1);
    1581           0 :                 CHECK_VAL(lease_break_info.count, 0);
    1582             : 
    1583           0 :                 torture_assert(tctx,
    1584             :                         break_info.received_transport == transport1,
    1585             :                         "expect oplock break on transport1\n");
    1586           0 :                 CHECK_VAL(break_info.handle.data[0], _h1.data[0]);
    1587           0 :                 CHECK_VAL(break_info.handle.data[1], _h1.data[1]);
    1588           0 :                 CHECK_VAL(break_info.level, SMB2_OPLOCK_LEVEL_II);
    1589             : 
    1590           0 :                 op_ack1.in = break_info.br.in;
    1591             :         }
    1592             : 
    1593           0 :         torture_reset_break_info(tctx, &break_info);
    1594           0 :         break_info.oplock_skip_ack = true;
    1595           0 :         torture_reset_lease_break_info(tctx, &lease_break_info);
    1596           0 :         lease_break_info.lease_skip_ack = true;
    1597             : 
    1598           0 :         WAIT_FOR_ASYNC_RESPONSE(tctx, req21);
    1599             : 
    1600           0 :         if (client1_level == SMB2_OPLOCK_LEVEL_LEASE) {
    1601           0 :                 torture_wait_for_lease_break(tctx);
    1602             :         } else {
    1603           0 :                 torture_wait_for_oplock_break(tctx);
    1604             :         }
    1605           0 :         CHECK_VAL(break_info.count, 0);
    1606           0 :         CHECK_VAL(lease_break_info.count, 0);
    1607             : 
    1608           0 :         if (NT_STATUS_EQUAL(replay22_reject_status, NT_STATUS_SHARING_VIOLATION)) {
    1609             :                 /*
    1610             :                  * The server is broken and doesn't
    1611             :                  * detect a replay, so we start an async
    1612             :                  * request and send a lease break ack
    1613             :                  * after 5 seconds in order to avoid
    1614             :                  * the 35 second delay.
    1615             :                  */
    1616           0 :                 torture_comment(tctx, "Starting ASYNC Replay req22 expecting %s\n",
    1617             :                                 nt_errstr(replay22_reject_status));
    1618           0 :                 smb2cli_session_start_replay(session2->smbXcli);
    1619           0 :                 transport2->options.request_timeout = 15;
    1620           0 :                 req22 = smb2_create_send(tree2, &io22);
    1621           0 :                 torture_assert(tctx, req22 != NULL, "req22");
    1622           0 :                 transport2->options.request_timeout = request_timeout2;
    1623           0 :                 smb2cli_session_stop_replay(session2->smbXcli);
    1624             : 
    1625           0 :                 WAIT_FOR_ASYNC_RESPONSE(tctx, req22);
    1626             :         } else {
    1627           0 :                 torture_comment(tctx, "SYNC Replay io22 expecting %s\n",
    1628             :                                 nt_errstr(replay22_reject_status));
    1629           0 :                 smb2cli_session_start_replay(session2->smbXcli);
    1630           0 :                 transport2->options.request_timeout = 5;
    1631           0 :                 status = smb2_create(tree2, tctx, &io22);
    1632           0 :                 CHECK_STATUS(status, replay22_reject_status);
    1633           0 :                 transport2->options.request_timeout = request_timeout2;
    1634           0 :                 smb2cli_session_stop_replay(session2->smbXcli);
    1635             :         }
    1636             : 
    1637             :         /*
    1638             :          * We don't expect any action for 35 seconds
    1639             :          *
    1640             :          * But we sleep just 5 seconds before we
    1641             :          * ack the break.
    1642             :          */
    1643           0 :         if (client1_level == SMB2_OPLOCK_LEVEL_LEASE) {
    1644           0 :                 torture_wait_for_lease_break(tctx);
    1645           0 :                 torture_wait_for_lease_break(tctx);
    1646           0 :                 torture_wait_for_lease_break(tctx);
    1647           0 :                 torture_wait_for_lease_break(tctx);
    1648           0 :                 torture_wait_for_lease_break(tctx);
    1649           0 :                 CHECK_VAL(break_info.count, 0);
    1650           0 :                 CHECK_VAL(lease_break_info.count, 0);
    1651             : 
    1652           0 :                 if (release_op == SMB2_OP_CLOSE) {
    1653           0 :                         torture_comment(tctx, "Closing h1\n");
    1654           0 :                         smb2_util_close(tree1, _h1);
    1655           0 :                         h1 = NULL;
    1656             :                 } else {
    1657           0 :                         torture_comment(tctx, "Acking lease_key1\n");
    1658           0 :                         status = smb2_lease_break_ack(tree1, &lb_ack1);
    1659           0 :                         CHECK_STATUS(status, NT_STATUS_OK);
    1660           0 :                         CHECK_VAL(lb_ack1.out.lease.lease_flags, 0);
    1661           0 :                         CHECK_VAL(lb_ack1.out.lease.lease_state, lb_ack1.in.lease.lease_state);
    1662           0 :                         CHECK_VAL(lb_ack1.out.lease.lease_key.data[0], lease_key1);
    1663           0 :                         CHECK_VAL(lb_ack1.out.lease.lease_key.data[1], ~lease_key1);
    1664           0 :                         CHECK_VAL(lb_ack1.out.lease.lease_duration, 0);
    1665             :                 }
    1666             :         } else {
    1667           0 :                 torture_wait_for_oplock_break(tctx);
    1668           0 :                 torture_wait_for_oplock_break(tctx);
    1669           0 :                 torture_wait_for_oplock_break(tctx);
    1670           0 :                 torture_wait_for_oplock_break(tctx);
    1671           0 :                 torture_wait_for_oplock_break(tctx);
    1672           0 :                 CHECK_VAL(break_info.count, 0);
    1673           0 :                 CHECK_VAL(lease_break_info.count, 0);
    1674             : 
    1675           0 :                 if (release_op == SMB2_OP_CLOSE) {
    1676           0 :                         torture_comment(tctx, "Closing h1\n");
    1677           0 :                         smb2_util_close(tree1, _h1);
    1678           0 :                         h1 = NULL;
    1679             :                 } else {
    1680           0 :                         torture_comment(tctx, "Acking break h1\n");
    1681           0 :                         status = smb2_break(tree1, &op_ack1);
    1682           0 :                         CHECK_STATUS(status, NT_STATUS_OK);
    1683           0 :                         CHECK_VAL(op_ack1.out.oplock_level, op_ack1.in.oplock_level);
    1684             :                 }
    1685             :         }
    1686             : 
    1687           0 :         torture_comment(tctx, "Checking req21 expecting %s\n",
    1688             :                         nt_errstr(orig21_reject_status));
    1689           0 :         status = smb2_create_recv(req21, tctx, &io21);
    1690           0 :         CHECK_STATUS(status, orig21_reject_status);
    1691           0 :         if (NT_STATUS_IS_OK(orig21_reject_status)) {
    1692           0 :                 _h21 = io21.out.file.handle;
    1693           0 :                 h21 = &_h21;
    1694           0 :                 if (h2f == NULL) {
    1695           0 :                         h2f = h21;
    1696             :                 }
    1697           0 :                 CHECK_VAL(h21->data[0], h2f->data[0]);
    1698           0 :                 CHECK_VAL(h21->data[1], h2f->data[1]);
    1699           0 :                 CHECK_CREATED(&io21, EXISTED, FILE_ATTRIBUTE_ARCHIVE);
    1700           0 :                 CHECK_VAL(io21.out.oplock_level, client2_level);
    1701           0 :                 CHECK_VAL(io21.out.durable_open, false);
    1702           0 :                 if (client2_level == SMB2_OPLOCK_LEVEL_LEASE) {
    1703           0 :                         CHECK_VAL(io21.out.lease_response_v2.lease_key.data[0], lease_key2);
    1704           0 :                         CHECK_VAL(io21.out.lease_response_v2.lease_key.data[1], ~lease_key2);
    1705           0 :                         CHECK_VAL(io21.out.lease_response_v2.lease_epoch, lease_epoch2);
    1706           0 :                         CHECK_VAL(io21.out.lease_response_v2.lease_state,
    1707             :                                   smb2_util_lease_state("RHW"));
    1708           0 :                         CHECK_VAL(io21.out.durable_open_v2, true);
    1709           0 :                         CHECK_VAL(io21.out.timeout, 300*1000);
    1710           0 :                 } else if (client2_level == SMB2_OPLOCK_LEVEL_BATCH) {
    1711           0 :                         CHECK_VAL(io21.out.durable_open_v2, true);
    1712           0 :                         CHECK_VAL(io21.out.timeout, 300*1000);
    1713             :                 } else {
    1714           0 :                         CHECK_VAL(io21.out.durable_open_v2, false);
    1715             :                 }
    1716             :         }
    1717             : 
    1718           0 :         if (NT_STATUS_EQUAL(replay22_reject_status, NT_STATUS_SHARING_VIOLATION)) {
    1719           0 :                 torture_comment(tctx, "Checking req22 expecting %s\n",
    1720             :                                 nt_errstr(replay22_reject_status));
    1721           0 :                 status = smb2_create_recv(req22, tctx, &io22);
    1722           0 :                 CHECK_STATUS(status, replay22_reject_status);
    1723             :         }
    1724             : 
    1725           0 :         torture_comment(tctx, "SYNC Replay io23 expecting %s\n",
    1726             :                         nt_errstr(replay23_reject_status));
    1727           0 :         smb2cli_session_start_replay(session2->smbXcli);
    1728           0 :         transport2->options.request_timeout = 5;
    1729           0 :         status = smb2_create(tree2, tctx, &io23);
    1730           0 :         transport2->options.request_timeout = request_timeout2;
    1731           0 :         CHECK_STATUS(status, replay23_reject_status);
    1732           0 :         smb2cli_session_stop_replay(session2->smbXcli);
    1733           0 :         if (NT_STATUS_IS_OK(replay23_reject_status)) {
    1734           0 :                 _h23 = io23.out.file.handle;
    1735           0 :                 h23 = &_h23;
    1736           0 :                 if (h2f == NULL) {
    1737           0 :                         h2f = h23;
    1738             :                 }
    1739           0 :                 CHECK_VAL(h23->data[0], h2f->data[0]);
    1740           0 :                 CHECK_VAL(h23->data[1], h2f->data[1]);
    1741           0 :                 CHECK_CREATED(&io23, EXISTED, FILE_ATTRIBUTE_ARCHIVE);
    1742           0 :                 CHECK_VAL(io23.out.oplock_level, client2_level);
    1743           0 :                 CHECK_VAL(io23.out.durable_open, false);
    1744           0 :                 if (client2_level == SMB2_OPLOCK_LEVEL_LEASE) {
    1745           0 :                         CHECK_VAL(io23.out.lease_response_v2.lease_key.data[0], lease_key2);
    1746           0 :                         CHECK_VAL(io23.out.lease_response_v2.lease_key.data[1], ~lease_key2);
    1747           0 :                         CHECK_VAL(io23.out.lease_response_v2.lease_epoch, lease_epoch2);
    1748           0 :                         CHECK_VAL(io23.out.lease_response_v2.lease_state,
    1749             :                                   smb2_util_lease_state("RHW"));
    1750           0 :                         CHECK_VAL(io23.out.durable_open_v2, true);
    1751           0 :                         CHECK_VAL(io23.out.timeout, 300*1000);
    1752           0 :                 } else if (client2_level == SMB2_OPLOCK_LEVEL_BATCH) {
    1753           0 :                         CHECK_VAL(io23.out.durable_open_v2, true);
    1754           0 :                         CHECK_VAL(io23.out.timeout, 300*1000);
    1755             :                 } else {
    1756           0 :                         CHECK_VAL(io23.out.durable_open_v2, false);
    1757             :                 }
    1758             :         }
    1759             : 
    1760           0 :         if (client1_level == SMB2_OPLOCK_LEVEL_LEASE) {
    1761           0 :                 torture_wait_for_lease_break(tctx);
    1762             :         } else {
    1763           0 :                 torture_wait_for_oplock_break(tctx);
    1764             :         }
    1765           0 :         CHECK_VAL(break_info.count, 0);
    1766           0 :         CHECK_VAL(lease_break_info.count, 0);
    1767             : 
    1768           0 :         if (client1_level == SMB2_OPLOCK_LEVEL_LEASE) {
    1769           0 :                 torture_wait_for_lease_break(tctx);
    1770             :         } else {
    1771           0 :                 torture_wait_for_oplock_break(tctx);
    1772             :         }
    1773           0 :         CHECK_VAL(break_info.count, 0);
    1774           0 :         CHECK_VAL(lease_break_info.count, 0);
    1775             : 
    1776           0 :         if (h1 != NULL) {
    1777           0 :                 torture_comment(tctx, "Closing h1\n");
    1778           0 :                 smb2_util_close(tree1, _h1);
    1779           0 :                 h1 = NULL;
    1780             :         }
    1781             : 
    1782           0 :         if (client1_level == SMB2_OPLOCK_LEVEL_LEASE) {
    1783           0 :                 torture_wait_for_lease_break(tctx);
    1784             :         } else {
    1785           0 :                 torture_wait_for_oplock_break(tctx);
    1786             :         }
    1787           0 :         CHECK_VAL(break_info.count, 0);
    1788           0 :         CHECK_VAL(lease_break_info.count, 0);
    1789             : 
    1790           0 :         torture_comment(tctx, "SYNC Replay io24 expecting %s\n",
    1791           0 :                         nt_errstr(NT_STATUS_OK));
    1792           0 :         smb2cli_session_start_replay(session2->smbXcli);
    1793           0 :         transport2->options.request_timeout = 5;
    1794           0 :         status = smb2_create(tree2, tctx, &io24);
    1795           0 :         transport2->options.request_timeout = request_timeout2;
    1796           0 :         smb2cli_session_stop_replay(session2->smbXcli);
    1797           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    1798           0 :         _h24 = io24.out.file.handle;
    1799           0 :         h24 = &_h24;
    1800           0 :         if (h2f == NULL) {
    1801           0 :                 h2f = h24;
    1802             :         }
    1803           0 :         CHECK_VAL(h24->data[0], h2f->data[0]);
    1804           0 :         CHECK_VAL(h24->data[1], h2f->data[1]);
    1805           0 :         CHECK_CREATED(&io24, EXISTED, FILE_ATTRIBUTE_ARCHIVE);
    1806           0 :         CHECK_VAL(io24.out.oplock_level, client2_level);
    1807           0 :         CHECK_VAL(io24.out.durable_open, false);
    1808           0 :         if (client2_level == SMB2_OPLOCK_LEVEL_LEASE) {
    1809           0 :                 CHECK_VAL(io24.out.lease_response_v2.lease_key.data[0], lease_key2);
    1810           0 :                 CHECK_VAL(io24.out.lease_response_v2.lease_key.data[1], ~lease_key2);
    1811           0 :                 CHECK_VAL(io24.out.lease_response_v2.lease_epoch, lease_epoch2);
    1812           0 :                 CHECK_VAL(io24.out.lease_response_v2.lease_state,
    1813             :                           smb2_util_lease_state("RHW"));
    1814           0 :                 CHECK_VAL(io24.out.durable_open_v2, true);
    1815           0 :                 CHECK_VAL(io24.out.timeout, 300*1000);
    1816           0 :         } else if (client2_level == SMB2_OPLOCK_LEVEL_BATCH) {
    1817           0 :                 CHECK_VAL(io24.out.durable_open_v2, true);
    1818           0 :                 CHECK_VAL(io24.out.timeout, 300*1000);
    1819             :         } else {
    1820           0 :                 CHECK_VAL(io24.out.durable_open_v2, false);
    1821             :         }
    1822             : 
    1823           0 :         if (client1_level == SMB2_OPLOCK_LEVEL_LEASE) {
    1824           0 :                 torture_wait_for_lease_break(tctx);
    1825             :         } else {
    1826           0 :                 torture_wait_for_oplock_break(tctx);
    1827             :         }
    1828           0 :         CHECK_VAL(break_info.count, 0);
    1829           0 :         CHECK_VAL(lease_break_info.count, 0);
    1830           0 :         status = smb2_util_close(tree2, *h24);
    1831           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    1832           0 :         h24 = NULL;
    1833             : 
    1834           0 :         if (client1_level == SMB2_OPLOCK_LEVEL_LEASE) {
    1835           0 :                 torture_wait_for_lease_break(tctx);
    1836             :         } else {
    1837           0 :                 torture_wait_for_oplock_break(tctx);
    1838             :         }
    1839           0 :         CHECK_VAL(break_info.count, 0);
    1840           0 :         CHECK_VAL(lease_break_info.count, 0);
    1841             : 
    1842           0 : done:
    1843             : 
    1844           0 :         smbXcli_conn_disconnect(transport2->conn, NT_STATUS_LOCAL_DISCONNECT);
    1845             : 
    1846           0 :         if (h1 != NULL) {
    1847           0 :                 smb2_util_close(tree1, *h1);
    1848             :         }
    1849             : 
    1850           0 :         smb2_deltree(tree1, BASEDIR);
    1851             : 
    1852           0 :         TALLOC_FREE(tree1);
    1853           0 :         talloc_free(mem_ctx);
    1854             : 
    1855           0 :         return ret;
    1856             : }
    1857             : 
    1858             : /*
    1859             :  * This tests replay with a pending open on a single
    1860             :  * channel. It tests the case where the client2 open
    1861             :  * is deferred because it conflicts with a HANDLE lease,
    1862             :  * which is broken because the operation should otherwise
    1863             :  * return NT_STATUS_SHARING_VIOLATION.
    1864             :  *
    1865             :  * With a durablev2 request containing a create_guid,
    1866             :  * but without asking for an oplock nor a lease.
    1867             :  *
    1868             :  * While another client holds an RWH lease,
    1869             :  * which is released by a close.
    1870             :  *
    1871             :  * See https://bugzilla.samba.org/show_bug.cgi?id=14449
    1872             :  *
    1873             :  * This expects the sane reject status of
    1874             :  * NT_STATUS_FILE_NOT_AVAILABLE.
    1875             :  *
    1876             :  * It won't pass against Windows as it returns
    1877             :  * NT_STATUS_SHARING_VIOLATION to the replay (after
    1878             :  * 35 seconds), and this tests reports NT_STATUS_IO_TIMEOUT,
    1879             :  * as it expectes a NT_STATUS_FILE_NOT_AVAILABLE within 5 seconds.
    1880             :  * see test_dhv2_pending1n_vs_violation_lease_close_windows().
    1881             :  */
    1882           1 : static bool test_dhv2_pending1n_vs_violation_lease_close_sane(struct torture_context *tctx,
    1883             :                                                               struct smb2_tree *tree1,
    1884             :                                                               struct smb2_tree *tree2)
    1885             : {
    1886           1 :         return _test_dhv2_pending1_vs_violation(tctx, __func__,
    1887             :                                                 tree1,
    1888             :                                                 SMB2_OPLOCK_LEVEL_LEASE,
    1889             :                                                 SMB2_OP_CLOSE,
    1890             :                                                 tree2,
    1891             :                                                 SMB2_OPLOCK_LEVEL_NONE,
    1892           1 :                                                 NT_STATUS_OK,
    1893           1 :                                                 NT_STATUS_FILE_NOT_AVAILABLE,
    1894           1 :                                                 NT_STATUS_OK);
    1895             : }
    1896             : 
    1897             : /*
    1898             :  * This tests replay with a pending open on a single
    1899             :  * channel. It tests the case where the client2 open
    1900             :  * is deferred because it conflicts with a HANDLE lease,
    1901             :  * which is broken because the operation should otherwise
    1902             :  * return NT_STATUS_SHARING_VIOLATION.
    1903             :  *
    1904             :  * With a durablev2 request containing a create_guid,
    1905             :  * but without asking for an oplock nor a lease.
    1906             :  *
    1907             :  * While another client holds an RWH lease,
    1908             :  * which is released by a close.
    1909             :  *
    1910             :  * See https://bugzilla.samba.org/show_bug.cgi?id=14449
    1911             :  *
    1912             :  * This expects the strange behavior of ignoring the
    1913             :  * replay, which is returned done by Windows Servers.
    1914             :  *
    1915             :  * It won't pass against Samba as it returns
    1916             :  * NT_STATUS_FILE_NOT_AVAILABLE
    1917             :  * see test_dhv2_pending1n_vs_violation_lease_close_sane().
    1918             :  */
    1919           1 : static bool test_dhv2_pending1n_vs_violation_lease_close_windows(struct torture_context *tctx,
    1920             :                                                                  struct smb2_tree *tree1,
    1921             :                                                                  struct smb2_tree *tree2)
    1922             : {
    1923           1 :         return _test_dhv2_pending1_vs_violation(tctx, __func__,
    1924             :                                                 tree1,
    1925             :                                                 SMB2_OPLOCK_LEVEL_LEASE,
    1926             :                                                 SMB2_OP_CLOSE,
    1927             :                                                 tree2,
    1928             :                                                 SMB2_OPLOCK_LEVEL_NONE,
    1929           1 :                                                 NT_STATUS_OK,
    1930           1 :                                                 NT_STATUS_SHARING_VIOLATION,
    1931           1 :                                                 NT_STATUS_OK);
    1932             : }
    1933             : 
    1934             : /*
    1935             :  * This tests replay with a pending open on a single
    1936             :  * channel. It tests the case where the client2 open
    1937             :  * is deferred because it conflicts with a HANDLE lease,
    1938             :  * which is broken because the operation should otherwise
    1939             :  * return NT_STATUS_SHARING_VIOLATION.
    1940             :  *
    1941             :  * With a durablev2 request containing a create_guid,
    1942             :  * but without asking for an oplock nor a lease.
    1943             :  *
    1944             :  * While another client holds an RWH lease,
    1945             :  * which is released by a lease break ack.
    1946             :  *
    1947             :  * See https://bugzilla.samba.org/show_bug.cgi?id=14449
    1948             :  *
    1949             :  * This expects the sane reject status of
    1950             :  * NT_STATUS_FILE_NOT_AVAILABLE.
    1951             :  *
    1952             :  * It won't pass against Windows as it returns
    1953             :  * NT_STATUS_SHARING_VIOLATION to the replay (after
    1954             :  * 35 seconds), and this tests reports NT_STATUS_IO_TIMEOUT,
    1955             :  * as it expectes a NT_STATUS_FILE_NOT_AVAILABLE within 5 seconds.
    1956             :  * see test_dhv2_pending1n_vs_violation_lease_ack_windows().
    1957             :  */
    1958           1 : static bool test_dhv2_pending1n_vs_violation_lease_ack_sane(struct torture_context *tctx,
    1959             :                                                             struct smb2_tree *tree1,
    1960             :                                                             struct smb2_tree *tree2)
    1961             : {
    1962           1 :         return _test_dhv2_pending1_vs_violation(tctx, __func__,
    1963             :                                                 tree1,
    1964             :                                                 SMB2_OPLOCK_LEVEL_LEASE,
    1965             :                                                 SMB2_OP_BREAK,
    1966             :                                                 tree2,
    1967             :                                                 SMB2_OPLOCK_LEVEL_NONE,
    1968           1 :                                                 NT_STATUS_SHARING_VIOLATION,
    1969           1 :                                                 NT_STATUS_FILE_NOT_AVAILABLE,
    1970           1 :                                                 NT_STATUS_SHARING_VIOLATION);
    1971             : }
    1972             : 
    1973             : /*
    1974             :  * This tests replay with a pending open on a single
    1975             :  * channel. It tests the case where the client2 open
    1976             :  * is deferred because it conflicts with a HANDLE lease,
    1977             :  * which is broken because the operation should otherwise
    1978             :  * return NT_STATUS_SHARING_VIOLATION.
    1979             :  *
    1980             :  * With a durablev2 request containing a create_guid,
    1981             :  * but without asking for an oplock nor a lease.
    1982             :  *
    1983             :  * While another client holds an RWH lease,
    1984             :  * which is released by a close.
    1985             :  *
    1986             :  * See https://bugzilla.samba.org/show_bug.cgi?id=14449
    1987             :  *
    1988             :  * This expects the strange behavior of ignoring the
    1989             :  * replay, which is returned done by Windows Servers.
    1990             :  *
    1991             :  * It won't pass against Samba as it returns
    1992             :  * NT_STATUS_FILE_NOT_AVAILABLE
    1993             :  * see test_dhv2_pending1n_vs_violation_lease_ack_sane().
    1994             :  */
    1995           1 : static bool test_dhv2_pending1n_vs_violation_lease_ack_windows(struct torture_context *tctx,
    1996             :                                                                struct smb2_tree *tree1,
    1997             :                                                                struct smb2_tree *tree2)
    1998             : {
    1999           1 :         return _test_dhv2_pending1_vs_violation(tctx, __func__,
    2000             :                                                 tree1,
    2001             :                                                 SMB2_OPLOCK_LEVEL_LEASE,
    2002             :                                                 SMB2_OP_BREAK,
    2003             :                                                 tree2,
    2004             :                                                 SMB2_OPLOCK_LEVEL_NONE,
    2005           1 :                                                 NT_STATUS_SHARING_VIOLATION,
    2006           1 :                                                 NT_STATUS_SHARING_VIOLATION,
    2007           1 :                                                 NT_STATUS_SHARING_VIOLATION);
    2008             : }
    2009             : 
    2010             : /**
    2011             :  * This tests replay with a pending open on a single
    2012             :  * channel.
    2013             :  *
    2014             :  * With a durablev2 request containing a create_guid and
    2015             :  * a share_access of READ/WRITE/DELETE:
    2016             :  * - client2_level = NONE:
    2017             :  *   but without asking for an oplock nor a lease.
    2018             :  * - client2_level = BATCH:
    2019             :  *   and asking for a batch oplock.
    2020             :  * - client2_level = LEASE
    2021             :  *   and asking for an RWH lease.
    2022             :  *
    2023             :  * While another client holds a batch oplock or
    2024             :  * RWH lease. (client1_level => LEASE or BATCH).
    2025             :  * And allows share_access of READ/WRITE/DELETE.
    2026             :  *
    2027             :  * See https://bugzilla.samba.org/show_bug.cgi?id=14449
    2028             :  */
    2029          12 : static bool _test_dhv2_pending1_vs_hold(struct torture_context *tctx,
    2030             :                                         const char *testname,
    2031             :                                         uint8_t client1_level,
    2032             :                                         uint8_t client2_level,
    2033             :                                         NTSTATUS reject_status,
    2034             :                                         struct smb2_tree *tree1,
    2035             :                                         struct smb2_tree *tree2)
    2036             : {
    2037             :         NTSTATUS status;
    2038          12 :         TALLOC_CTX *mem_ctx = talloc_new(tctx);
    2039             :         struct smb2_handle _h1;
    2040          12 :         struct smb2_handle *h1 = NULL;
    2041             :         struct smb2_handle _h21;
    2042          12 :         struct smb2_handle *h21 = NULL;
    2043             :         struct smb2_handle _h24;
    2044          12 :         struct smb2_handle *h24 = NULL;
    2045             :         struct smb2_create io1, io21, io22, io23, io24;
    2046          12 :         struct GUID create_guid1 = GUID_random();
    2047          12 :         struct GUID create_guid2 = GUID_random();
    2048          12 :         struct smb2_request *req21 = NULL;
    2049          12 :         bool ret = true;
    2050             :         char fname[256];
    2051          12 :         struct smb2_transport *transport1 = tree1->session->transport;
    2052             :         uint32_t server_capabilities;
    2053             :         uint32_t share_capabilities;
    2054             :         struct smb2_lease ls1;
    2055             :         uint64_t lease_key1;
    2056          12 :         uint16_t lease_epoch1 = 0;
    2057             :         struct smb2_lease ls2;
    2058             :         uint64_t lease_key2;
    2059          12 :         uint16_t lease_epoch2 = 0;
    2060             :         bool share_is_so;
    2061          12 :         struct smb2_transport *transport2 = tree2->session->transport;
    2062          12 :         int request_timeout2 = transport2->options.request_timeout;
    2063          12 :         struct smb2_session *session2 = tree2->session;
    2064          12 :         const char *hold_name = NULL;
    2065             : 
    2066          12 :         switch (client1_level) {
    2067           6 :         case SMB2_OPLOCK_LEVEL_LEASE:
    2068           6 :                 hold_name = "RWH Lease";
    2069           6 :                 break;
    2070           6 :         case SMB2_OPLOCK_LEVEL_BATCH:
    2071           6 :                 hold_name = "BATCH Oplock";
    2072           6 :                 break;
    2073           0 :         default:
    2074           0 :                 smb_panic(__location__);
    2075             :                 break;
    2076             :         }
    2077             : 
    2078          12 :         if (smbXcli_conn_protocol(transport1->conn) < PROTOCOL_SMB3_00) {
    2079          12 :                 torture_skip(tctx, "SMB 3.X Dialect family required for "
    2080             :                                    "replay tests\n");
    2081             :         }
    2082             : 
    2083           0 :         server_capabilities = smb2cli_conn_server_capabilities(transport1->conn);
    2084           0 :         if (!(server_capabilities & SMB2_CAP_LEASING)) {
    2085           0 :                 if (client1_level == SMB2_OPLOCK_LEVEL_LEASE ||
    2086             :                     client2_level == SMB2_OPLOCK_LEVEL_LEASE) {
    2087           0 :                         torture_skip(tctx, "leases are not supported");
    2088             :                 }
    2089             :         }
    2090             : 
    2091           0 :         share_capabilities = smb2cli_tcon_capabilities(tree1->smbXcli);
    2092           0 :         share_is_so = share_capabilities & SMB2_SHARE_CAP_SCALEOUT;
    2093           0 :         if (share_is_so) {
    2094           0 :                 torture_skip(tctx, talloc_asprintf(tctx,
    2095             :                              "%s not supported on SCALEOUT share",
    2096             :                              hold_name));
    2097             :         }
    2098             : 
    2099             :         /* Add some random component to the file name. */
    2100           0 :         snprintf(fname, sizeof(fname), "%s\\%s_%s.dat",
    2101             :                  BASEDIR, testname, generate_random_str(tctx, 8));
    2102             : 
    2103           0 :         torture_reset_break_info(tctx, &break_info);
    2104           0 :         break_info.oplock_skip_ack = true;
    2105           0 :         torture_reset_lease_break_info(tctx, &lease_break_info);
    2106           0 :         lease_break_info.lease_skip_ack = true;
    2107           0 :         transport1->oplock.handler = torture_oplock_ack_handler;
    2108           0 :         transport1->oplock.private_data = tree1;
    2109           0 :         transport1->lease.handler = torture_lease_handler;
    2110           0 :         transport1->lease.private_data = tree1;
    2111           0 :         smb2_keepalive(transport1);
    2112           0 :         transport2->oplock.handler = torture_oplock_ack_handler;
    2113           0 :         transport2->oplock.private_data = tree2;
    2114           0 :         transport2->lease.handler = torture_lease_handler;
    2115           0 :         transport2->lease.private_data = tree2;
    2116           0 :         smb2_keepalive(transport2);
    2117             : 
    2118           0 :         smb2_util_unlink(tree1, fname);
    2119           0 :         status = torture_smb2_testdir(tree1, BASEDIR, &_h1);
    2120           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    2121           0 :         smb2_util_close(tree1, _h1);
    2122           0 :         CHECK_VAL(break_info.count, 0);
    2123             : 
    2124           0 :         lease_key1 = random();
    2125           0 :         if (client1_level == SMB2_OPLOCK_LEVEL_LEASE) {
    2126           0 :                 smb2_lease_v2_create(&io1, &ls1, false /* dir */, fname,
    2127           0 :                         lease_key1, NULL, smb2_util_lease_state("RWH"), lease_epoch1++);
    2128             :         } else {
    2129           0 :                 smb2_oplock_create(&io1, fname, SMB2_OPLOCK_LEVEL_BATCH);
    2130             :         }
    2131           0 :         io1.in.share_access = smb2_util_share_access("RWD");
    2132           0 :         io1.in.durable_open = false;
    2133           0 :         io1.in.durable_open_v2 = true;
    2134           0 :         io1.in.persistent_open = false;
    2135           0 :         io1.in.create_guid = create_guid1;
    2136           0 :         io1.in.timeout = UINT32_MAX;
    2137             : 
    2138           0 :         status = smb2_create(tree1, mem_ctx, &io1);
    2139           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    2140           0 :         _h1 = io1.out.file.handle;
    2141           0 :         h1 = &_h1;
    2142           0 :         CHECK_CREATED(&io1, CREATED, FILE_ATTRIBUTE_ARCHIVE);
    2143           0 :         CHECK_VAL(io1.out.durable_open, false);
    2144           0 :         if (client1_level == SMB2_OPLOCK_LEVEL_LEASE) {
    2145           0 :                 CHECK_VAL(io1.out.oplock_level, SMB2_OPLOCK_LEVEL_LEASE);
    2146           0 :                 CHECK_VAL(io1.out.lease_response_v2.lease_key.data[0], lease_key1);
    2147           0 :                 CHECK_VAL(io1.out.lease_response_v2.lease_key.data[1], ~lease_key1);
    2148           0 :                 CHECK_VAL(io1.out.lease_response_v2.lease_epoch, lease_epoch1);
    2149           0 :                 CHECK_VAL(io1.out.lease_response_v2.lease_state,
    2150             :                           smb2_util_lease_state("RHW"));
    2151             :         } else {
    2152           0 :                 CHECK_VAL(io1.out.oplock_level, SMB2_OPLOCK_LEVEL_BATCH);
    2153             :         }
    2154           0 :         CHECK_VAL(io1.out.durable_open_v2, true);
    2155           0 :         CHECK_VAL(io1.out.timeout, 300*1000);
    2156             : 
    2157           0 :         lease_key2 = random();
    2158           0 :         if (client2_level == SMB2_OPLOCK_LEVEL_LEASE) {
    2159           0 :                 smb2_lease_v2_create(&io21, &ls2, false /* dir */, fname,
    2160           0 :                         lease_key2, NULL, smb2_util_lease_state("RWH"), lease_epoch2++);
    2161             :         } else {
    2162           0 :                 smb2_oplock_create(&io21, fname, client2_level);
    2163             :         }
    2164           0 :         io21.in.share_access = smb2_util_share_access("RWD");
    2165           0 :         io21.in.durable_open = false;
    2166           0 :         io21.in.durable_open_v2 = true;
    2167           0 :         io21.in.persistent_open = false;
    2168           0 :         io21.in.create_guid = create_guid2;
    2169           0 :         io21.in.timeout = UINT32_MAX;
    2170           0 :         io24 = io23 = io22 = io21;
    2171             : 
    2172           0 :         req21 = smb2_create_send(tree2, &io21);
    2173           0 :         torture_assert(tctx, req21 != NULL, "req21");
    2174             : 
    2175           0 :         if (client1_level == SMB2_OPLOCK_LEVEL_LEASE) {
    2176           0 :                 const struct smb2_lease_break *lb =
    2177             :                         &lease_break_info.lease_break;
    2178           0 :                 const struct smb2_lease *l = &lb->current_lease;
    2179           0 :                 const struct smb2_lease_key *k = &l->lease_key;
    2180             : 
    2181           0 :                 torture_wait_for_lease_break(tctx);
    2182           0 :                 CHECK_VAL(break_info.count, 0);
    2183           0 :                 CHECK_VAL(lease_break_info.count, 1);
    2184             : 
    2185           0 :                 torture_assert(tctx,
    2186             :                         lease_break_info.lease_transport == transport1,
    2187             :                         "expect lease break on transport1\n");
    2188           0 :                 CHECK_VAL(k->data[0], lease_key1);
    2189           0 :                 CHECK_VAL(k->data[1], ~lease_key1);
    2190           0 :                 CHECK_VAL(lb->new_lease_state,
    2191             :                           smb2_util_lease_state("RH"));
    2192           0 :                 CHECK_VAL(lb->break_flags,
    2193             :                           SMB2_NOTIFY_BREAK_LEASE_FLAG_ACK_REQUIRED);
    2194           0 :                 CHECK_VAL(lb->new_epoch, lease_epoch1+1);
    2195           0 :                 lease_epoch1 += 1;
    2196             :         } else {
    2197           0 :                 torture_wait_for_oplock_break(tctx);
    2198           0 :                 CHECK_VAL(break_info.count, 1);
    2199           0 :                 CHECK_VAL(lease_break_info.count, 0);
    2200             : 
    2201           0 :                 torture_assert(tctx,
    2202             :                         break_info.received_transport == transport1,
    2203             :                         "expect oplock break on transport1\n");
    2204           0 :                 CHECK_VAL(break_info.handle.data[0], _h1.data[0]);
    2205           0 :                 CHECK_VAL(break_info.handle.data[1], _h1.data[1]);
    2206           0 :                 CHECK_VAL(break_info.level, SMB2_OPLOCK_LEVEL_II);
    2207             :         }
    2208             : 
    2209           0 :         torture_reset_break_info(tctx, &break_info);
    2210           0 :         break_info.oplock_skip_ack = true;
    2211           0 :         torture_reset_lease_break_info(tctx, &lease_break_info);
    2212           0 :         lease_break_info.lease_skip_ack = true;
    2213             : 
    2214           0 :         WAIT_FOR_ASYNC_RESPONSE(tctx, req21);
    2215             : 
    2216           0 :         if (client1_level == SMB2_OPLOCK_LEVEL_LEASE) {
    2217           0 :                 torture_wait_for_lease_break(tctx);
    2218             :         } else {
    2219           0 :                 torture_wait_for_oplock_break(tctx);
    2220             :         }
    2221           0 :         CHECK_VAL(break_info.count, 0);
    2222           0 :         CHECK_VAL(lease_break_info.count, 0);
    2223             : 
    2224           0 :         smb2cli_session_start_replay(session2->smbXcli);
    2225           0 :         transport2->options.request_timeout = 5;
    2226           0 :         status = smb2_create(tree2, tctx, &io22);
    2227           0 :         transport2->options.request_timeout = request_timeout2;
    2228           0 :         CHECK_STATUS(status, reject_status);
    2229           0 :         smb2cli_session_stop_replay(session2->smbXcli);
    2230             : 
    2231           0 :         if (client1_level == SMB2_OPLOCK_LEVEL_LEASE) {
    2232           0 :                 torture_wait_for_lease_break(tctx);
    2233             :         } else {
    2234           0 :                 torture_wait_for_oplock_break(tctx);
    2235             :         }
    2236           0 :         CHECK_VAL(break_info.count, 0);
    2237           0 :         CHECK_VAL(lease_break_info.count, 0);
    2238             : 
    2239           0 :         smb2cli_session_start_replay(session2->smbXcli);
    2240           0 :         transport2->options.request_timeout = 5;
    2241           0 :         status = smb2_create(tree2, tctx, &io23);
    2242           0 :         transport2->options.request_timeout = request_timeout2;
    2243           0 :         CHECK_STATUS(status, reject_status);
    2244           0 :         smb2cli_session_stop_replay(session2->smbXcli);
    2245             : 
    2246           0 :         if (client1_level == SMB2_OPLOCK_LEVEL_LEASE) {
    2247           0 :                 torture_wait_for_lease_break(tctx);
    2248             :         } else {
    2249           0 :                 torture_wait_for_oplock_break(tctx);
    2250             :         }
    2251           0 :         CHECK_VAL(break_info.count, 0);
    2252           0 :         CHECK_VAL(lease_break_info.count, 0);
    2253             : 
    2254           0 :         smb2_util_close(tree1, _h1);
    2255           0 :         h1 = NULL;
    2256             : 
    2257           0 :         status = smb2_create_recv(req21, tctx, &io21);
    2258           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    2259           0 :         _h21 = io21.out.file.handle;
    2260           0 :         h21 = &_h21;
    2261           0 :         CHECK_CREATED(&io21, EXISTED, FILE_ATTRIBUTE_ARCHIVE);
    2262           0 :         CHECK_VAL(io21.out.oplock_level, client2_level);
    2263           0 :         CHECK_VAL(io21.out.durable_open, false);
    2264           0 :         if (client2_level == SMB2_OPLOCK_LEVEL_LEASE) {
    2265           0 :                 CHECK_VAL(io21.out.lease_response_v2.lease_key.data[0], lease_key2);
    2266           0 :                 CHECK_VAL(io21.out.lease_response_v2.lease_key.data[1], ~lease_key2);
    2267           0 :                 CHECK_VAL(io21.out.lease_response_v2.lease_epoch, lease_epoch2);
    2268           0 :                 CHECK_VAL(io21.out.lease_response_v2.lease_state,
    2269             :                           smb2_util_lease_state("RHW"));
    2270           0 :                 CHECK_VAL(io21.out.durable_open_v2, true);
    2271           0 :                 CHECK_VAL(io21.out.timeout, 300*1000);
    2272           0 :         } else if (client2_level == SMB2_OPLOCK_LEVEL_BATCH) {
    2273           0 :                 CHECK_VAL(io21.out.durable_open_v2, true);
    2274           0 :                 CHECK_VAL(io21.out.timeout, 300*1000);
    2275             :         } else {
    2276           0 :                 CHECK_VAL(io21.out.durable_open_v2, false);
    2277             :         }
    2278             : 
    2279           0 :         if (client1_level == SMB2_OPLOCK_LEVEL_LEASE) {
    2280           0 :                 torture_wait_for_lease_break(tctx);
    2281             :         } else {
    2282           0 :                 torture_wait_for_oplock_break(tctx);
    2283             :         }
    2284           0 :         CHECK_VAL(break_info.count, 0);
    2285           0 :         CHECK_VAL(lease_break_info.count, 0);
    2286             : 
    2287           0 :         smb2cli_session_start_replay(session2->smbXcli);
    2288           0 :         status = smb2_create(tree2, tctx, &io24);
    2289           0 :         smb2cli_session_stop_replay(session2->smbXcli);
    2290           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    2291           0 :         _h24 = io24.out.file.handle;
    2292           0 :         h24 = &_h24;
    2293           0 :         CHECK_CREATED(&io24, EXISTED, FILE_ATTRIBUTE_ARCHIVE);
    2294           0 :         CHECK_VAL(h24->data[0], h21->data[0]);
    2295           0 :         CHECK_VAL(h24->data[1], h21->data[1]);
    2296           0 :         CHECK_VAL(io24.out.oplock_level, client2_level);
    2297           0 :         CHECK_VAL(io24.out.durable_open, false);
    2298           0 :         if (client2_level == SMB2_OPLOCK_LEVEL_LEASE) {
    2299           0 :                 CHECK_VAL(io24.out.lease_response_v2.lease_key.data[0], lease_key2);
    2300           0 :                 CHECK_VAL(io24.out.lease_response_v2.lease_key.data[1], ~lease_key2);
    2301           0 :                 CHECK_VAL(io24.out.lease_response_v2.lease_epoch, lease_epoch2);
    2302           0 :                 CHECK_VAL(io24.out.lease_response_v2.lease_state,
    2303             :                           smb2_util_lease_state("RHW"));
    2304           0 :                 CHECK_VAL(io24.out.durable_open_v2, true);
    2305           0 :                 CHECK_VAL(io24.out.timeout, 300*1000);
    2306           0 :         } else if (client2_level == SMB2_OPLOCK_LEVEL_BATCH) {
    2307           0 :                 CHECK_VAL(io24.out.durable_open_v2, true);
    2308           0 :                 CHECK_VAL(io24.out.timeout, 300*1000);
    2309             :         } else {
    2310           0 :                 CHECK_VAL(io24.out.durable_open_v2, false);
    2311             :         }
    2312             : 
    2313           0 :         if (client1_level == SMB2_OPLOCK_LEVEL_LEASE) {
    2314           0 :                 torture_wait_for_lease_break(tctx);
    2315             :         } else {
    2316           0 :                 torture_wait_for_oplock_break(tctx);
    2317             :         }
    2318           0 :         CHECK_VAL(break_info.count, 0);
    2319           0 :         CHECK_VAL(lease_break_info.count, 0);
    2320           0 :         status = smb2_util_close(tree2, *h24);
    2321           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    2322           0 :         h24 = NULL;
    2323             : 
    2324           0 :         if (client1_level == SMB2_OPLOCK_LEVEL_LEASE) {
    2325           0 :                 torture_wait_for_lease_break(tctx);
    2326             :         } else {
    2327           0 :                 torture_wait_for_oplock_break(tctx);
    2328             :         }
    2329           0 :         CHECK_VAL(break_info.count, 0);
    2330           0 :         CHECK_VAL(lease_break_info.count, 0);
    2331             : 
    2332           0 : done:
    2333             : 
    2334           0 :         smbXcli_conn_disconnect(transport2->conn, NT_STATUS_LOCAL_DISCONNECT);
    2335             : 
    2336           0 :         if (h1 != NULL) {
    2337           0 :                 smb2_util_close(tree1, *h1);
    2338             :         }
    2339             : 
    2340           0 :         smb2_deltree(tree1, BASEDIR);
    2341             : 
    2342           0 :         TALLOC_FREE(tree1);
    2343           0 :         talloc_free(mem_ctx);
    2344             : 
    2345           0 :         return ret;
    2346             : }
    2347             : 
    2348             : /**
    2349             :  * This tests replay with a pending open on a single
    2350             :  * channel.
    2351             :  *
    2352             :  * With a durablev2 request containing a create_guid,
    2353             :  * a share_access of READ/WRITE/DELETE,
    2354             :  * but without asking for an oplock nor a lease.
    2355             :  *
    2356             :  * While another client holds a batch oplock.
    2357             :  * And allows share_access of READ/WRITE/DELETE.
    2358             :  *
    2359             :  * See https://bugzilla.samba.org/show_bug.cgi?id=14449
    2360             :  *
    2361             :  * This expects the sane reject status of
    2362             :  * NT_STATUS_FILE_NOT_AVAILABLE.
    2363             :  *
    2364             :  * It won't pass against Windows as it returns
    2365             :  * NT_STATUS_ACCESS_DENIED see
    2366             :  * test_dhv2_pending1n_vs_oplock_windows().
    2367             :  */
    2368           1 : static bool test_dhv2_pending1n_vs_oplock_sane(struct torture_context *tctx,
    2369             :                                                struct smb2_tree *tree1,
    2370             :                                                struct smb2_tree *tree2)
    2371             : {
    2372           1 :         return _test_dhv2_pending1_vs_hold(tctx, __func__,
    2373             :                                            SMB2_OPLOCK_LEVEL_BATCH,
    2374             :                                            SMB2_OPLOCK_LEVEL_NONE,
    2375           1 :                                            NT_STATUS_FILE_NOT_AVAILABLE,
    2376             :                                            tree1, tree2);
    2377             : }
    2378             : 
    2379             : /**
    2380             :  * This tests replay with a pending open on a single
    2381             :  * channel.
    2382             :  *
    2383             :  * With a durablev2 request containing a create_guid,
    2384             :  * a share_access of READ/WRITE/DELETE,
    2385             :  * but without asking for an oplock nor a lease.
    2386             :  *
    2387             :  * While another client holds a batch oplock.
    2388             :  * And allows share_access of READ/WRITE/DELETE.
    2389             :  *
    2390             :  * See https://bugzilla.samba.org/show_bug.cgi?id=14449
    2391             :  *
    2392             :  * This expects the strange reject status of
    2393             :  * NT_STATUS_ACCESS_DENIED, which is returned
    2394             :  * by Windows Servers.
    2395             :  *
    2396             :  * It won't pass against Samba as it returns
    2397             :  * NT_STATUS_FILE_NOT_AVAILABLE. see
    2398             :  * test_dhv2_pending1n_vs_oplock_sane.
    2399             :  */
    2400           1 : static bool test_dhv2_pending1n_vs_oplock_windows(struct torture_context *tctx,
    2401             :                                                   struct smb2_tree *tree1,
    2402             :                                                   struct smb2_tree *tree2)
    2403             : {
    2404           1 :         return _test_dhv2_pending1_vs_hold(tctx, __func__,
    2405             :                                            SMB2_OPLOCK_LEVEL_BATCH,
    2406             :                                            SMB2_OPLOCK_LEVEL_NONE,
    2407           1 :                                            NT_STATUS_ACCESS_DENIED,
    2408             :                                            tree1, tree2);
    2409             : }
    2410             : 
    2411             : /**
    2412             :  * This tests replay with a pending open on a single
    2413             :  * channel.
    2414             :  *
    2415             :  * With a durablev2 request containing a create_guid,
    2416             :  * a share_access of READ/WRITE/DELETE,
    2417             :  * but without asking for an oplock nor a lease.
    2418             :  *
    2419             :  * While another client holds an RWH lease.
    2420             :  * And allows share_access of READ/WRITE/DELETE.
    2421             :  *
    2422             :  * See https://bugzilla.samba.org/show_bug.cgi?id=14449
    2423             :  *
    2424             :  * This expects the sane reject status of
    2425             :  * NT_STATUS_FILE_NOT_AVAILABLE.
    2426             :  *
    2427             :  * It won't pass against Windows as it returns
    2428             :  * NT_STATUS_ACCESS_DENIED see
    2429             :  * test_dhv2_pending1n_vs_lease_windows().
    2430             :  */
    2431           1 : static bool test_dhv2_pending1n_vs_lease_sane(struct torture_context *tctx,
    2432             :                                               struct smb2_tree *tree1,
    2433             :                                               struct smb2_tree *tree2)
    2434             : {
    2435           1 :         return _test_dhv2_pending1_vs_hold(tctx, __func__,
    2436             :                                            SMB2_OPLOCK_LEVEL_LEASE,
    2437             :                                            SMB2_OPLOCK_LEVEL_NONE,
    2438           1 :                                            NT_STATUS_FILE_NOT_AVAILABLE,
    2439             :                                            tree1, tree2);
    2440             : }
    2441             : 
    2442             : /**
    2443             :  * This tests replay with a pending open on a single
    2444             :  * channel.
    2445             :  *
    2446             :  * With a durablev2 request containing a create_guid,
    2447             :  * a share_access of READ/WRITE/DELETE,
    2448             :  * but without asking for an oplock nor a lease.
    2449             :  *
    2450             :  * While another client holds an RWH lease.
    2451             :  * And allows share_access of READ/WRITE/DELETE.
    2452             :  *
    2453             :  * See https://bugzilla.samba.org/show_bug.cgi?id=14449
    2454             :  *
    2455             :  * This expects the strange reject status of
    2456             :  * NT_STATUS_ACCESS_DENIED, which is returned
    2457             :  * by Windows Servers.
    2458             :  *
    2459             :  * It won't pass against Samba as it returns
    2460             :  * NT_STATUS_FILE_NOT_AVAILABLE. see
    2461             :  * test_dhv2_pending1n_vs_lease_sane.
    2462             :  */
    2463           1 : static bool test_dhv2_pending1n_vs_lease_windows(struct torture_context *tctx,
    2464             :                                                  struct smb2_tree *tree1,
    2465             :                                                  struct smb2_tree *tree2)
    2466             : {
    2467           1 :         return _test_dhv2_pending1_vs_hold(tctx, __func__,
    2468             :                                            SMB2_OPLOCK_LEVEL_LEASE,
    2469             :                                            SMB2_OPLOCK_LEVEL_NONE,
    2470           1 :                                            NT_STATUS_ACCESS_DENIED,
    2471             :                                            tree1, tree2);
    2472             : }
    2473             : 
    2474             : /**
    2475             :  * This tests replay with a pending open on a single
    2476             :  * channel.
    2477             :  *
    2478             :  * With a durablev2 request containing a create_guid,
    2479             :  * a share_access of READ/WRITE/DELETE,
    2480             :  * and asking for a v2 lease.
    2481             :  *
    2482             :  * While another client holds a batch oplock.
    2483             :  * And allows share_access of READ/WRITE/DELETE.
    2484             :  *
    2485             :  * See https://bugzilla.samba.org/show_bug.cgi?id=14449
    2486             :  *
    2487             :  * This expects the sane reject status of
    2488             :  * NT_STATUS_FILE_NOT_AVAILABLE.
    2489             :  *
    2490             :  * It won't pass against Windows as it returns
    2491             :  * NT_STATUS_ACCESS_DENIED see
    2492             :  * test_dhv2_pending1l_vs_oplock_windows().
    2493             :  */
    2494           1 : static bool test_dhv2_pending1l_vs_oplock_sane(struct torture_context *tctx,
    2495             :                                                struct smb2_tree *tree1,
    2496             :                                                struct smb2_tree *tree2)
    2497             : {
    2498           1 :         return _test_dhv2_pending1_vs_hold(tctx, __func__,
    2499             :                                            SMB2_OPLOCK_LEVEL_BATCH,
    2500             :                                            SMB2_OPLOCK_LEVEL_LEASE,
    2501           1 :                                            NT_STATUS_FILE_NOT_AVAILABLE,
    2502             :                                            tree1, tree2);
    2503             : }
    2504             : 
    2505             : /**
    2506             :  * This tests replay with a pending open on a single
    2507             :  * channel.
    2508             :  *
    2509             :  * With a durablev2 request containing a create_guid,
    2510             :  * a share_access of READ/WRITE/DELETE,
    2511             :  * and asking for a v2 lease.
    2512             :  *
    2513             :  * While another client holds a batch oplock.
    2514             :  * And allows share_access of READ/WRITE/DELETE.
    2515             :  *
    2516             :  * See https://bugzilla.samba.org/show_bug.cgi?id=14449
    2517             :  *
    2518             :  * This expects the strange reject status of
    2519             :  * NT_STATUS_ACCESS_DENIED, which is returned
    2520             :  * by Windows Servers.
    2521             :  *
    2522             :  * It won't pass against Samba as it returns
    2523             :  * NT_STATUS_FILE_NOT_AVAILABLE. see
    2524             :  * test_dhv2_pending1l_vs_oplock_sane.
    2525             :  */
    2526           1 : static bool test_dhv2_pending1l_vs_oplock_windows(struct torture_context *tctx,
    2527             :                                                   struct smb2_tree *tree1,
    2528             :                                                   struct smb2_tree *tree2)
    2529             : {
    2530           1 :         return _test_dhv2_pending1_vs_hold(tctx, __func__,
    2531             :                                            SMB2_OPLOCK_LEVEL_BATCH,
    2532             :                                            SMB2_OPLOCK_LEVEL_LEASE,
    2533           1 :                                            NT_STATUS_ACCESS_DENIED,
    2534             :                                            tree1, tree2);
    2535             : }
    2536             : 
    2537             : /**
    2538             :  * This tests replay with a pending open on a single
    2539             :  * channel.
    2540             :  *
    2541             :  * With a durablev2 request containing a create_guid,
    2542             :  * a share_access of READ/WRITE/DELETE,
    2543             :  * and asking for a v2 lease.
    2544             :  *
    2545             :  * While another client holds an RWH lease.
    2546             :  * And allows share_access of READ/WRITE/DELETE.
    2547             :  *
    2548             :  * See https://bugzilla.samba.org/show_bug.cgi?id=14449
    2549             :  *
    2550             :  * This expects the sane reject status of
    2551             :  * NT_STATUS_FILE_NOT_AVAILABLE.
    2552             :  *
    2553             :  * It won't pass against Windows as it returns
    2554             :  * NT_STATUS_ACCESS_DENIED see
    2555             :  * test_dhv2_pending1l_vs_lease_windows().
    2556             :  */
    2557           1 : static bool test_dhv2_pending1l_vs_lease_sane(struct torture_context *tctx,
    2558             :                                               struct smb2_tree *tree1,
    2559             :                                               struct smb2_tree *tree2)
    2560             : {
    2561           1 :         return _test_dhv2_pending1_vs_hold(tctx, __func__,
    2562             :                                            SMB2_OPLOCK_LEVEL_LEASE,
    2563             :                                            SMB2_OPLOCK_LEVEL_LEASE,
    2564           1 :                                            NT_STATUS_FILE_NOT_AVAILABLE,
    2565             :                                            tree1, tree2);
    2566             : }
    2567             : 
    2568             : /**
    2569             :  * This tests replay with a pending open on a single
    2570             :  * channel.
    2571             :  *
    2572             :  * With a durablev2 request containing a create_guid,
    2573             :  * a share_access of READ/WRITE/DELETE,
    2574             :  * and asking for a v2 lease.
    2575             :  *
    2576             :  * While another client holds an RWH lease.
    2577             :  * And allows share_access of READ/WRITE/DELETE.
    2578             :  *
    2579             :  * See https://bugzilla.samba.org/show_bug.cgi?id=14449
    2580             :  *
    2581             :  * This expects the strange reject status of
    2582             :  * NT_STATUS_ACCESS_DENIED, which is returned
    2583             :  * by Windows Servers.
    2584             :  *
    2585             :  * It won't pass against Samba as it returns
    2586             :  * NT_STATUS_FILE_NOT_AVAILABLE. see
    2587             :  * test_dhv2_pending1l_vs_lease_sane.
    2588             :  */
    2589           1 : static bool test_dhv2_pending1l_vs_lease_windows(struct torture_context *tctx,
    2590             :                                                  struct smb2_tree *tree1,
    2591             :                                                  struct smb2_tree *tree2)
    2592             : {
    2593           1 :         return _test_dhv2_pending1_vs_hold(tctx, __func__,
    2594             :                                            SMB2_OPLOCK_LEVEL_LEASE,
    2595             :                                            SMB2_OPLOCK_LEVEL_LEASE,
    2596           1 :                                            NT_STATUS_ACCESS_DENIED,
    2597             :                                            tree1, tree2);
    2598             : }
    2599             : 
    2600             : /**
    2601             :  * This tests replay with a pending open on a single
    2602             :  * channel.
    2603             :  *
    2604             :  * With a durablev2 request containing a create_guid,
    2605             :  * a share_access of READ/WRITE/DELETE,
    2606             :  * and asking for a batch oplock.
    2607             :  *
    2608             :  * While another client holds a batch oplock.
    2609             :  * And allows share_access of READ/WRITE/DELETE.
    2610             :  *
    2611             :  * See https://bugzilla.samba.org/show_bug.cgi?id=14449
    2612             :  *
    2613             :  * This expects the sane reject status of
    2614             :  * NT_STATUS_FILE_NOT_AVAILABLE.
    2615             :  *
    2616             :  * It won't pass against Windows as it returns
    2617             :  * NT_STATUS_ACCESS_DENIED see
    2618             :  * test_dhv2_pending1o_vs_oplock_windows().
    2619             :  */
    2620           1 : static bool test_dhv2_pending1o_vs_oplock_sane(struct torture_context *tctx,
    2621             :                                               struct smb2_tree *tree1,
    2622             :                                               struct smb2_tree *tree2)
    2623             : {
    2624           1 :         return _test_dhv2_pending1_vs_hold(tctx, __func__,
    2625             :                                            SMB2_OPLOCK_LEVEL_BATCH,
    2626             :                                            SMB2_OPLOCK_LEVEL_BATCH,
    2627           1 :                                            NT_STATUS_FILE_NOT_AVAILABLE,
    2628             :                                            tree1, tree2);
    2629             : }
    2630             : 
    2631             : /**
    2632             :  * This tests replay with a pending open on a single
    2633             :  * channel.
    2634             :  *
    2635             :  * With a durablev2 request containing a create_guid,
    2636             :  * a share_access of READ/WRITE/DELETE,
    2637             :  * and asking for a batch oplock.
    2638             :  *
    2639             :  * While another client holds a batch oplock.
    2640             :  * And allows share_access of READ/WRITE/DELETE.
    2641             :  *
    2642             :  * See https://bugzilla.samba.org/show_bug.cgi?id=14449
    2643             :  *
    2644             :  * This expects the strange reject status of
    2645             :  * NT_STATUS_ACCESS_DENIED, which is returned
    2646             :  * by Windows Servers.
    2647             :  *
    2648             :  * It won't pass against Samba as it returns
    2649             :  * NT_STATUS_FILE_NOT_AVAILABLE. see
    2650             :  * test_dhv2_pending1o_vs_oplock_sane.
    2651             :  */
    2652           1 : static bool test_dhv2_pending1o_vs_oplock_windows(struct torture_context *tctx,
    2653             :                                                   struct smb2_tree *tree1,
    2654             :                                                   struct smb2_tree *tree2)
    2655             : {
    2656           1 :         return _test_dhv2_pending1_vs_hold(tctx, __func__,
    2657             :                                            SMB2_OPLOCK_LEVEL_BATCH,
    2658             :                                            SMB2_OPLOCK_LEVEL_BATCH,
    2659           1 :                                            NT_STATUS_ACCESS_DENIED,
    2660             :                                            tree1, tree2);
    2661             : }
    2662             : 
    2663             : /**
    2664             :  * This tests replay with a pending open on a single
    2665             :  * channel.
    2666             :  *
    2667             :  * With a durablev2 request containing a create_guid,
    2668             :  * a share_access of READ/WRITE/DELETE,
    2669             :  * and asking for a batch oplock.
    2670             :  *
    2671             :  * While another client holds an RWH lease.
    2672             :  * And allows share_access of READ/WRITE/DELETE.
    2673             :  *
    2674             :  * See https://bugzilla.samba.org/show_bug.cgi?id=14449
    2675             :  *
    2676             :  * This expects the sane reject status of
    2677             :  * NT_STATUS_FILE_NOT_AVAILABLE.
    2678             :  *
    2679             :  * It won't pass against Windows as it returns
    2680             :  * NT_STATUS_ACCESS_DENIED see
    2681             :  * test_dhv2_pending1o_vs_lease_windows().
    2682             :  */
    2683           1 : static bool test_dhv2_pending1o_vs_lease_sane(struct torture_context *tctx,
    2684             :                                               struct smb2_tree *tree1,
    2685             :                                               struct smb2_tree *tree2_1)
    2686             : {
    2687           1 :         return _test_dhv2_pending1_vs_hold(tctx, __func__,
    2688             :                                            SMB2_OPLOCK_LEVEL_LEASE,
    2689             :                                            SMB2_OPLOCK_LEVEL_BATCH,
    2690           1 :                                            NT_STATUS_FILE_NOT_AVAILABLE,
    2691             :                                            tree1, tree2_1);
    2692             : }
    2693             : 
    2694             : /**
    2695             :  * This tests replay with a pending open on a single
    2696             :  * channel.
    2697             :  *
    2698             :  * With a durablev2 request containing a create_guid,
    2699             :  * a share_access of READ/WRITE/DELETE,
    2700             :  * and asking for a batch oplock.
    2701             :  *
    2702             :  * While another client holds an RWH lease.
    2703             :  * And allows share_access of READ/WRITE/DELETE.
    2704             :  *
    2705             :  * See https://bugzilla.samba.org/show_bug.cgi?id=14449
    2706             :  *
    2707             :  * This expects the strange reject status of
    2708             :  * NT_STATUS_ACCESS_DENIED, which is returned
    2709             :  * by Windows Servers.
    2710             :  *
    2711             :  * It won't pass against Samba as it returns
    2712             :  * NT_STATUS_FILE_NOT_AVAILABLE. see
    2713             :  * test_dhv2_pending1o_vs_lease_sane.
    2714             :  */
    2715           1 : static bool test_dhv2_pending1o_vs_lease_windows(struct torture_context *tctx,
    2716             :                                                  struct smb2_tree *tree1,
    2717             :                                                  struct smb2_tree *tree2)
    2718             : {
    2719           1 :         return _test_dhv2_pending1_vs_hold(tctx, __func__,
    2720             :                                            SMB2_OPLOCK_LEVEL_LEASE,
    2721             :                                            SMB2_OPLOCK_LEVEL_BATCH,
    2722           1 :                                            NT_STATUS_ACCESS_DENIED,
    2723             :                                            tree1, tree2);
    2724             : }
    2725             : 
    2726             : /**
    2727             :  * This tests replay with a pending open with 4 channels
    2728             :  * and closed transports on the client and server side.
    2729             :  *
    2730             :  * With a durablev2 request containing a create_guid and
    2731             :  * a share_access of READ/WRITE/DELETE:
    2732             :  * - client2_level = NONE:
    2733             :  *   but without asking for an oplock nor a lease.
    2734             :  * - client2_level = BATCH:
    2735             :  *   and asking for a batch oplock.
    2736             :  * - client2_level = LEASE
    2737             :  *   and asking for an RWH lease.
    2738             :  *
    2739             :  * While another client holds a batch oplock or
    2740             :  * RWH lease. (client1_level => LEASE or BATCH).
    2741             :  * And allows share_access of READ/WRITE/DELETE.
    2742             :  *
    2743             :  * See https://bugzilla.samba.org/show_bug.cgi?id=14449
    2744             :  */
    2745          12 : static bool _test_dhv2_pending2_vs_hold(struct torture_context *tctx,
    2746             :                                         const char *testname,
    2747             :                                         uint8_t client1_level,
    2748             :                                         uint8_t client2_level,
    2749             :                                         NTSTATUS reject_status,
    2750             :                                         struct smb2_tree *tree1,
    2751             :                                         struct smb2_tree *tree2_1)
    2752             : {
    2753          12 :         const char *host = torture_setting_string(tctx, "host", NULL);
    2754          12 :         const char *share = torture_setting_string(tctx, "share", NULL);
    2755          12 :         struct cli_credentials *credentials = samba_cmdline_get_creds();
    2756             :         NTSTATUS status;
    2757          12 :         TALLOC_CTX *mem_ctx = talloc_new(tctx);
    2758             :         struct smb2_handle _h1;
    2759          12 :         struct smb2_handle *h1 = NULL;
    2760             :         struct smb2_handle _h24;
    2761          12 :         struct smb2_handle *h24 = NULL;
    2762             :         struct smb2_create io1, io21, io22, io23, io24;
    2763          12 :         struct GUID create_guid1 = GUID_random();
    2764          12 :         struct GUID create_guid2 = GUID_random();
    2765          12 :         struct smb2_request *req21 = NULL;
    2766          12 :         bool ret = true;
    2767             :         char fname[256];
    2768          12 :         struct smb2_transport *transport1 = tree1->session->transport;
    2769             :         uint32_t server_capabilities;
    2770             :         uint32_t share_capabilities;
    2771             :         struct smb2_lease ls1;
    2772             :         uint64_t lease_key1;
    2773          12 :         uint16_t lease_epoch1 = 0;
    2774             :         struct smb2_lease ls2;
    2775             :         uint64_t lease_key2;
    2776          12 :         uint16_t lease_epoch2 = 0;
    2777             :         bool share_is_so;
    2778          12 :         struct smb2_transport *transport2_1 = tree2_1->session->transport;
    2779          12 :         int request_timeout2 = transport2_1->options.request_timeout;
    2780             :         struct smbcli_options options2x;
    2781          12 :         struct smb2_tree *tree2_2 = NULL;
    2782          12 :         struct smb2_tree *tree2_3 = NULL;
    2783          12 :         struct smb2_tree *tree2_4 = NULL;
    2784          12 :         struct smb2_transport *transport2_2 = NULL;
    2785          12 :         struct smb2_transport *transport2_3 = NULL;
    2786          12 :         struct smb2_transport *transport2_4 = NULL;
    2787          12 :         struct smb2_session *session2_1 = tree2_1->session;
    2788          12 :         struct smb2_session *session2_2 = NULL;
    2789          12 :         struct smb2_session *session2_3 = NULL;
    2790          12 :         struct smb2_session *session2_4 = NULL;
    2791          12 :         uint16_t csn2 = 1;
    2792          12 :         const char *hold_name = NULL;
    2793             : 
    2794          12 :         switch (client1_level) {
    2795           6 :         case SMB2_OPLOCK_LEVEL_LEASE:
    2796           6 :                 hold_name = "RWH Lease";
    2797           6 :                 break;
    2798           6 :         case SMB2_OPLOCK_LEVEL_BATCH:
    2799           6 :                 hold_name = "BATCH Oplock";
    2800           6 :                 break;
    2801           0 :         default:
    2802           0 :                 smb_panic(__location__);
    2803             :                 break;
    2804             :         }
    2805             : 
    2806          12 :         if (smbXcli_conn_protocol(transport1->conn) < PROTOCOL_SMB3_00) {
    2807          12 :                 torture_skip(tctx, "SMB 3.X Dialect family required for "
    2808             :                                    "replay tests\n");
    2809             :         }
    2810             : 
    2811           0 :         server_capabilities = smb2cli_conn_server_capabilities(transport1->conn);
    2812           0 :         if (!(server_capabilities & SMB2_CAP_MULTI_CHANNEL)) {
    2813           0 :                 torture_skip(tctx, "MULTI_CHANNEL are not supported");
    2814             :         }
    2815           0 :         if (!(server_capabilities & SMB2_CAP_LEASING)) {
    2816           0 :                 if (client1_level == SMB2_OPLOCK_LEVEL_LEASE ||
    2817             :                     client2_level == SMB2_OPLOCK_LEVEL_LEASE) {
    2818           0 :                         torture_skip(tctx, "leases are not supported");
    2819             :                 }
    2820             :         }
    2821             : 
    2822           0 :         share_capabilities = smb2cli_tcon_capabilities(tree1->smbXcli);
    2823           0 :         share_is_so = share_capabilities & SMB2_SHARE_CAP_SCALEOUT;
    2824           0 :         if (share_is_so) {
    2825           0 :                 torture_skip(tctx, talloc_asprintf(tctx,
    2826             :                              "%s not supported on SCALEOUT share",
    2827             :                              hold_name));
    2828             :         }
    2829             : 
    2830             :         /* Add some random component to the file name. */
    2831           0 :         snprintf(fname, sizeof(fname), "%s\\%s_%s.dat",
    2832             :                  BASEDIR, testname, generate_random_str(tctx, 8));
    2833             : 
    2834           0 :         options2x = transport2_1->options;
    2835           0 :         options2x.only_negprot = true;
    2836             : 
    2837           0 :         status = smb2_connect(tctx,
    2838             :                               host,
    2839             :                               lpcfg_smb_ports(tctx->lp_ctx),
    2840             :                               share,
    2841             :                               lpcfg_resolve_context(tctx->lp_ctx),
    2842             :                               credentials,
    2843             :                               &tree2_2,
    2844             :                               tctx->ev,
    2845             :                               &options2x,
    2846             :                               lpcfg_socket_options(tctx->lp_ctx),
    2847             :                               lpcfg_gensec_settings(tctx, tctx->lp_ctx)
    2848             :                               );
    2849           0 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2850             :                                         "smb2_connect failed");
    2851           0 :         transport2_2 = tree2_2->session->transport;
    2852             : 
    2853           0 :         session2_2 = smb2_session_channel(transport2_2,
    2854             :                                           lpcfg_gensec_settings(tctx, tctx->lp_ctx),
    2855             :                                           tctx,
    2856             :                                           session2_1);
    2857           0 :         torture_assert(tctx, session2_2 != NULL, "smb2_session_channel failed");
    2858             : 
    2859           0 :         status = smb2_session_setup_spnego(session2_2,
    2860             :                                            credentials,
    2861             :                                            0 /* previous_session_id */);
    2862           0 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2863             :                                         "smb2_session_setup_spnego failed");
    2864           0 :         tree2_2->smbXcli = tree2_1->smbXcli;
    2865           0 :         tree2_2->session = session2_2;
    2866             : 
    2867           0 :         status = smb2_connect(tctx,
    2868             :                               host,
    2869             :                               lpcfg_smb_ports(tctx->lp_ctx),
    2870             :                               share,
    2871             :                               lpcfg_resolve_context(tctx->lp_ctx),
    2872             :                               credentials,
    2873             :                               &tree2_3,
    2874             :                               tctx->ev,
    2875             :                               &options2x,
    2876             :                               lpcfg_socket_options(tctx->lp_ctx),
    2877             :                               lpcfg_gensec_settings(tctx, tctx->lp_ctx)
    2878             :                               );
    2879           0 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2880             :                                         "smb2_connect failed");
    2881           0 :         transport2_3 = tree2_3->session->transport;
    2882             : 
    2883           0 :         session2_3 = smb2_session_channel(transport2_3,
    2884             :                                           lpcfg_gensec_settings(tctx, tctx->lp_ctx),
    2885             :                                           tctx,
    2886             :                                           session2_1);
    2887           0 :         torture_assert(tctx, session2_3 != NULL, "smb2_session_channel failed");
    2888             : 
    2889           0 :         status = smb2_session_setup_spnego(session2_3,
    2890             :                                            credentials,
    2891             :                                            0 /* previous_session_id */);
    2892           0 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2893             :                                         "smb2_session_setup_spnego failed");
    2894           0 :         tree2_3->smbXcli = tree2_1->smbXcli;
    2895           0 :         tree2_3->session = session2_3;
    2896             : 
    2897           0 :         status = smb2_connect(tctx,
    2898             :                               host,
    2899             :                               lpcfg_smb_ports(tctx->lp_ctx),
    2900             :                               share,
    2901             :                               lpcfg_resolve_context(tctx->lp_ctx),
    2902             :                               credentials,
    2903             :                               &tree2_4,
    2904             :                               tctx->ev,
    2905             :                               &options2x,
    2906             :                               lpcfg_socket_options(tctx->lp_ctx),
    2907             :                               lpcfg_gensec_settings(tctx, tctx->lp_ctx)
    2908             :                               );
    2909           0 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2910             :                                         "smb2_connect failed");
    2911           0 :         transport2_4 = tree2_4->session->transport;
    2912             : 
    2913           0 :         session2_4 = smb2_session_channel(transport2_4,
    2914             :                                           lpcfg_gensec_settings(tctx, tctx->lp_ctx),
    2915             :                                           tctx,
    2916             :                                           session2_1);
    2917           0 :         torture_assert(tctx, session2_4 != NULL, "smb2_session_channel failed");
    2918             : 
    2919           0 :         status = smb2_session_setup_spnego(session2_4,
    2920             :                                            credentials,
    2921             :                                            0 /* previous_session_id */);
    2922           0 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2923             :                                         "smb2_session_setup_spnego failed");
    2924           0 :         tree2_4->smbXcli = tree2_1->smbXcli;
    2925           0 :         tree2_4->session = session2_4;
    2926             : 
    2927           0 :         smb2cli_session_reset_channel_sequence(session2_2->smbXcli, csn2++);
    2928             : 
    2929           0 :         torture_reset_break_info(tctx, &break_info);
    2930           0 :         break_info.oplock_skip_ack = true;
    2931           0 :         torture_reset_lease_break_info(tctx, &lease_break_info);
    2932           0 :         lease_break_info.lease_skip_ack = true;
    2933           0 :         transport1->oplock.handler = torture_oplock_ack_handler;
    2934           0 :         transport1->oplock.private_data = tree1;
    2935           0 :         transport1->lease.handler = torture_lease_handler;
    2936           0 :         transport1->lease.private_data = tree1;
    2937           0 :         smb2_keepalive(transport1);
    2938           0 :         transport2_1->oplock.handler = torture_oplock_ack_handler;
    2939           0 :         transport2_1->oplock.private_data = tree2_1;
    2940           0 :         transport2_1->lease.handler = torture_lease_handler;
    2941           0 :         transport2_1->lease.private_data = tree2_1;
    2942           0 :         smb2_keepalive(transport2_1);
    2943           0 :         transport2_2->oplock.handler = torture_oplock_ack_handler;
    2944           0 :         transport2_2->oplock.private_data = tree2_2;
    2945           0 :         transport2_2->lease.handler = torture_lease_handler;
    2946           0 :         transport2_2->lease.private_data = tree2_2;
    2947           0 :         smb2_keepalive(transport2_2);
    2948           0 :         transport2_3->oplock.handler = torture_oplock_ack_handler;
    2949           0 :         transport2_3->oplock.private_data = tree2_3;
    2950           0 :         transport2_3->lease.handler = torture_lease_handler;
    2951           0 :         transport2_3->lease.private_data = tree2_3;
    2952           0 :         smb2_keepalive(transport2_3);
    2953           0 :         transport2_4->oplock.handler = torture_oplock_ack_handler;
    2954           0 :         transport2_4->oplock.private_data = tree2_4;
    2955           0 :         transport2_4->lease.handler = torture_lease_handler;
    2956           0 :         transport2_4->lease.private_data = tree2_4;
    2957           0 :         smb2_keepalive(transport2_4);
    2958             : 
    2959           0 :         smb2_util_unlink(tree1, fname);
    2960           0 :         status = torture_smb2_testdir(tree1, BASEDIR, &_h1);
    2961           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    2962           0 :         smb2_util_close(tree1, _h1);
    2963           0 :         CHECK_VAL(break_info.count, 0);
    2964             : 
    2965           0 :         lease_key1 = random();
    2966           0 :         if (client1_level == SMB2_OPLOCK_LEVEL_LEASE) {
    2967           0 :                 smb2_lease_v2_create(&io1, &ls1, false /* dir */, fname,
    2968           0 :                         lease_key1, NULL, smb2_util_lease_state("RWH"), lease_epoch1++);
    2969             :         } else {
    2970           0 :                 smb2_oplock_create(&io1, fname, SMB2_OPLOCK_LEVEL_BATCH);
    2971             :         }
    2972           0 :         io1.in.durable_open = false;
    2973           0 :         io1.in.durable_open_v2 = true;
    2974           0 :         io1.in.persistent_open = false;
    2975           0 :         io1.in.create_guid = create_guid1;
    2976           0 :         io1.in.timeout = UINT32_MAX;
    2977             : 
    2978           0 :         status = smb2_create(tree1, mem_ctx, &io1);
    2979           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    2980           0 :         _h1 = io1.out.file.handle;
    2981           0 :         h1 = &_h1;
    2982           0 :         CHECK_CREATED(&io1, CREATED, FILE_ATTRIBUTE_ARCHIVE);
    2983           0 :         CHECK_VAL(io1.out.durable_open, false);
    2984           0 :         if (client1_level == SMB2_OPLOCK_LEVEL_LEASE) {
    2985           0 :                 CHECK_VAL(io1.out.oplock_level, SMB2_OPLOCK_LEVEL_LEASE);
    2986           0 :                 CHECK_VAL(io1.out.lease_response_v2.lease_key.data[0], lease_key1);
    2987           0 :                 CHECK_VAL(io1.out.lease_response_v2.lease_key.data[1], ~lease_key1);
    2988           0 :                 CHECK_VAL(io1.out.lease_response_v2.lease_epoch, lease_epoch1);
    2989           0 :                 CHECK_VAL(io1.out.lease_response_v2.lease_state,
    2990             :                           smb2_util_lease_state("RHW"));
    2991             :         } else {
    2992           0 :                 CHECK_VAL(io1.out.oplock_level, SMB2_OPLOCK_LEVEL_BATCH);
    2993             :         }
    2994           0 :         CHECK_VAL(io1.out.durable_open_v2, true);
    2995           0 :         CHECK_VAL(io1.out.timeout, 300*1000);
    2996             : 
    2997           0 :         lease_key2 = random();
    2998           0 :         if (client2_level == SMB2_OPLOCK_LEVEL_LEASE) {
    2999           0 :                 smb2_lease_v2_create(&io21, &ls2, false /* dir */, fname,
    3000           0 :                         lease_key2, NULL, smb2_util_lease_state("RWH"), lease_epoch2++);
    3001             :         } else {
    3002           0 :                 smb2_oplock_create(&io21, fname, client2_level);
    3003             :         }
    3004           0 :         io21.in.durable_open = false;
    3005           0 :         io21.in.durable_open_v2 = true;
    3006           0 :         io21.in.persistent_open = false;
    3007           0 :         io21.in.create_guid = create_guid2;
    3008           0 :         io21.in.timeout = UINT32_MAX;
    3009           0 :         io24 = io23 = io22 = io21;
    3010             : 
    3011           0 :         req21 = smb2_create_send(tree2_1, &io21);
    3012           0 :         torture_assert(tctx, req21 != NULL, "req21");
    3013             : 
    3014           0 :         if (client1_level == SMB2_OPLOCK_LEVEL_LEASE) {
    3015           0 :                 const struct smb2_lease_break *lb =
    3016             :                         &lease_break_info.lease_break;
    3017           0 :                 const struct smb2_lease *l = &lb->current_lease;
    3018           0 :                 const struct smb2_lease_key *k = &l->lease_key;
    3019             : 
    3020           0 :                 torture_wait_for_lease_break(tctx);
    3021           0 :                 CHECK_VAL(break_info.count, 0);
    3022           0 :                 CHECK_VAL(lease_break_info.count, 1);
    3023             : 
    3024           0 :                 torture_assert(tctx,
    3025             :                         lease_break_info.lease_transport == transport1,
    3026             :                         "expect lease break on transport1\n");
    3027           0 :                 CHECK_VAL(k->data[0], lease_key1);
    3028           0 :                 CHECK_VAL(k->data[1], ~lease_key1);
    3029           0 :                 CHECK_VAL(lb->new_lease_state,
    3030             :                           smb2_util_lease_state("RH"));
    3031           0 :                 CHECK_VAL(lb->break_flags,
    3032             :                           SMB2_NOTIFY_BREAK_LEASE_FLAG_ACK_REQUIRED);
    3033           0 :                 CHECK_VAL(lb->new_epoch, lease_epoch1+1);
    3034           0 :                 lease_epoch1 += 1;
    3035             :         } else {
    3036           0 :                 torture_wait_for_oplock_break(tctx);
    3037           0 :                 CHECK_VAL(break_info.count, 1);
    3038           0 :                 CHECK_VAL(lease_break_info.count, 0);
    3039             : 
    3040           0 :                 torture_assert(tctx,
    3041             :                         break_info.received_transport == transport1,
    3042             :                         "expect oplock break on transport1\n");
    3043           0 :                 CHECK_VAL(break_info.handle.data[0], _h1.data[0]);
    3044           0 :                 CHECK_VAL(break_info.handle.data[1], _h1.data[1]);
    3045           0 :                 CHECK_VAL(break_info.level, SMB2_OPLOCK_LEVEL_II);
    3046             :         }
    3047             : 
    3048           0 :         torture_reset_break_info(tctx, &break_info);
    3049           0 :         break_info.oplock_skip_ack = true;
    3050           0 :         torture_reset_lease_break_info(tctx, &lease_break_info);
    3051           0 :         lease_break_info.lease_skip_ack = true;
    3052             : 
    3053           0 :         WAIT_FOR_ASYNC_RESPONSE(tctx, req21);
    3054             : 
    3055           0 :         if (client1_level == SMB2_OPLOCK_LEVEL_LEASE) {
    3056           0 :                 torture_wait_for_lease_break(tctx);
    3057             :         } else {
    3058           0 :                 torture_wait_for_oplock_break(tctx);
    3059             :         }
    3060           0 :         CHECK_VAL(break_info.count, 0);
    3061           0 :         CHECK_VAL(lease_break_info.count, 0);
    3062             : 
    3063           0 :         smbXcli_conn_disconnect(transport2_1->conn, NT_STATUS_LOCAL_DISCONNECT);
    3064           0 :         smb2cli_session_reset_channel_sequence(session2_1->smbXcli, csn2++);
    3065             : 
    3066           0 :         smb2cli_session_start_replay(session2_2->smbXcli);
    3067           0 :         transport2_2->options.request_timeout = 5;
    3068           0 :         status = smb2_create(tree2_2, tctx, &io22);
    3069           0 :         transport2_2->options.request_timeout = request_timeout2;
    3070           0 :         CHECK_STATUS(status, reject_status);
    3071           0 :         smb2cli_session_stop_replay(session2_2->smbXcli);
    3072             : 
    3073           0 :         if (client1_level == SMB2_OPLOCK_LEVEL_LEASE) {
    3074           0 :                 torture_wait_for_lease_break(tctx);
    3075             :         } else {
    3076           0 :                 torture_wait_for_oplock_break(tctx);
    3077             :         }
    3078           0 :         CHECK_VAL(break_info.count, 0);
    3079           0 :         CHECK_VAL(lease_break_info.count, 0);
    3080             : 
    3081           0 :         smbXcli_conn_disconnect(transport2_2->conn, NT_STATUS_LOCAL_DISCONNECT);
    3082           0 :         smb2cli_session_reset_channel_sequence(session2_2->smbXcli, csn2++);
    3083             : 
    3084           0 :         smb2cli_session_start_replay(session2_3->smbXcli);
    3085           0 :         transport2_3->options.request_timeout = 5;
    3086           0 :         status = smb2_create(tree2_3, tctx, &io23);
    3087           0 :         transport2_3->options.request_timeout = request_timeout2;
    3088           0 :         CHECK_STATUS(status, reject_status);
    3089           0 :         smb2cli_session_stop_replay(session2_3->smbXcli);
    3090             : 
    3091           0 :         if (client1_level == SMB2_OPLOCK_LEVEL_LEASE) {
    3092           0 :                 torture_wait_for_lease_break(tctx);
    3093             :         } else {
    3094           0 :                 torture_wait_for_oplock_break(tctx);
    3095             :         }
    3096           0 :         CHECK_VAL(break_info.count, 0);
    3097           0 :         CHECK_VAL(lease_break_info.count, 0);
    3098             : 
    3099           0 :         smb2_util_close(tree1, _h1);
    3100           0 :         h1 = NULL;
    3101             : 
    3102           0 :         status = smb2_create_recv(req21, tctx, &io21);
    3103           0 :         CHECK_STATUS(status, NT_STATUS_LOCAL_DISCONNECT);
    3104             : 
    3105           0 :         if (client1_level == SMB2_OPLOCK_LEVEL_LEASE) {
    3106           0 :                 torture_wait_for_lease_break(tctx);
    3107             :         } else {
    3108           0 :                 torture_wait_for_oplock_break(tctx);
    3109             :         }
    3110           0 :         CHECK_VAL(break_info.count, 0);
    3111           0 :         CHECK_VAL(lease_break_info.count, 0);
    3112             : 
    3113           0 :         smbXcli_conn_disconnect(transport2_3->conn, NT_STATUS_LOCAL_DISCONNECT);
    3114           0 :         smb2cli_session_reset_channel_sequence(session2_3->smbXcli, csn2++);
    3115             : 
    3116           0 :         smb2cli_session_start_replay(session2_4->smbXcli);
    3117           0 :         status = smb2_create(tree2_4, tctx, &io24);
    3118           0 :         smb2cli_session_stop_replay(session2_4->smbXcli);
    3119           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    3120           0 :         _h24 = io24.out.file.handle;
    3121           0 :         h24 = &_h24;
    3122           0 :         CHECK_CREATED(&io24, EXISTED, FILE_ATTRIBUTE_ARCHIVE);
    3123           0 :         CHECK_VAL(io24.out.oplock_level, client2_level);
    3124           0 :         CHECK_VAL(io24.out.durable_open, false);
    3125           0 :         if (client2_level == SMB2_OPLOCK_LEVEL_LEASE) {
    3126           0 :                 CHECK_VAL(io24.out.lease_response_v2.lease_key.data[0], lease_key2);
    3127           0 :                 CHECK_VAL(io24.out.lease_response_v2.lease_key.data[1], ~lease_key2);
    3128           0 :                 CHECK_VAL(io24.out.lease_response_v2.lease_epoch, lease_epoch2);
    3129           0 :                 CHECK_VAL(io24.out.lease_response_v2.lease_state,
    3130             :                           smb2_util_lease_state("RHW"));
    3131           0 :                 CHECK_VAL(io24.out.durable_open_v2, true);
    3132           0 :                 CHECK_VAL(io24.out.timeout, 300*1000);
    3133           0 :         } else if (client2_level == SMB2_OPLOCK_LEVEL_BATCH) {
    3134           0 :                 CHECK_VAL(io24.out.durable_open_v2, true);
    3135           0 :                 CHECK_VAL(io24.out.timeout, 300*1000);
    3136             :         } else {
    3137           0 :                 CHECK_VAL(io24.out.durable_open_v2, false);
    3138             :         }
    3139             : 
    3140           0 :         if (client1_level == SMB2_OPLOCK_LEVEL_LEASE) {
    3141           0 :                 torture_wait_for_lease_break(tctx);
    3142             :         } else {
    3143           0 :                 torture_wait_for_oplock_break(tctx);
    3144             :         }
    3145           0 :         CHECK_VAL(break_info.count, 0);
    3146           0 :         CHECK_VAL(lease_break_info.count, 0);
    3147           0 :         status = smb2_util_close(tree2_4, *h24);
    3148           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    3149           0 :         h24 = NULL;
    3150             : 
    3151           0 :         if (client1_level == SMB2_OPLOCK_LEVEL_LEASE) {
    3152           0 :                 torture_wait_for_lease_break(tctx);
    3153             :         } else {
    3154           0 :                 torture_wait_for_oplock_break(tctx);
    3155             :         }
    3156           0 :         CHECK_VAL(break_info.count, 0);
    3157           0 :         CHECK_VAL(lease_break_info.count, 0);
    3158             : 
    3159           0 : done:
    3160             : 
    3161           0 :         smbXcli_conn_disconnect(transport2_1->conn, NT_STATUS_LOCAL_DISCONNECT);
    3162           0 :         smbXcli_conn_disconnect(transport2_2->conn, NT_STATUS_LOCAL_DISCONNECT);
    3163           0 :         smbXcli_conn_disconnect(transport2_3->conn, NT_STATUS_LOCAL_DISCONNECT);
    3164           0 :         smbXcli_conn_disconnect(transport2_4->conn, NT_STATUS_LOCAL_DISCONNECT);
    3165             : 
    3166           0 :         if (h1 != NULL) {
    3167           0 :                 smb2_util_close(tree1, *h1);
    3168             :         }
    3169             : 
    3170           0 :         smb2_deltree(tree1, BASEDIR);
    3171             : 
    3172           0 :         TALLOC_FREE(tree1);
    3173           0 :         talloc_free(mem_ctx);
    3174             : 
    3175           0 :         return ret;
    3176             : }
    3177             : 
    3178             : /**
    3179             :  * This tests replay with a pending open with 4 channels
    3180             :  * and closed transports on the client and server side.
    3181             :  *
    3182             :  * With a durablev2 request containing a create_guid,
    3183             :  * a share_access of READ/WRITE/DELETE,
    3184             :  * but without asking for an oplock nor a lease.
    3185             :  *
    3186             :  * While another client holds an RWH lease.
    3187             :  * And allows share_access of READ/WRITE/DELETE.
    3188             :  *
    3189             :  * See https://bugzilla.samba.org/show_bug.cgi?id=14449
    3190             :  *
    3191             :  * This expects the sane reject status of
    3192             :  * NT_STATUS_FILE_NOT_AVAILABLE.
    3193             :  *
    3194             :  * It won't pass against Windows as it returns
    3195             :  * NT_STATUS_ACCESS_DENIED see
    3196             :  * test_dhv2_pending2n_vs_lease_windows().
    3197             :  */
    3198           1 : static bool test_dhv2_pending2n_vs_lease_sane(struct torture_context *tctx,
    3199             :                                               struct smb2_tree *tree1,
    3200             :                                               struct smb2_tree *tree2_1)
    3201             : {
    3202           1 :         return _test_dhv2_pending2_vs_hold(tctx, __func__,
    3203             :                                            SMB2_OPLOCK_LEVEL_LEASE,
    3204             :                                            SMB2_OPLOCK_LEVEL_NONE,
    3205           1 :                                            NT_STATUS_FILE_NOT_AVAILABLE,
    3206             :                                            tree1, tree2_1);
    3207             : }
    3208             : 
    3209             : /**
    3210             :  * This tests replay with a pending open with 4 channels
    3211             :  * and closed transports on the client and server side.
    3212             :  *
    3213             :  * With a durablev2 request containing a create_guid,
    3214             :  * a share_access of READ/WRITE/DELETE,
    3215             :  * but without asking for an oplock nor a lease.
    3216             :  *
    3217             :  * While another client holds an RWH lease.
    3218             :  * And allows share_access of READ/WRITE/DELETE.
    3219             :  *
    3220             :  * See https://bugzilla.samba.org/show_bug.cgi?id=14449
    3221             :  *
    3222             :  * This expects the strange reject status of
    3223             :  * NT_STATUS_ACCESS_DENIED, which is returned
    3224             :  * by Windows Servers.
    3225             :  *
    3226             :  * It won't pass against Samba as it returns
    3227             :  * NT_STATUS_FILE_NOT_AVAILABLE. see
    3228             :  * test_dhv2_pending2n_vs_lease_sane().
    3229             :  */
    3230           1 : static bool test_dhv2_pending2n_vs_lease_windows(struct torture_context *tctx,
    3231             :                                                  struct smb2_tree *tree1,
    3232             :                                                  struct smb2_tree *tree2_1)
    3233             : {
    3234           1 :         return _test_dhv2_pending2_vs_hold(tctx, __func__,
    3235             :                                            SMB2_OPLOCK_LEVEL_LEASE,
    3236             :                                            SMB2_OPLOCK_LEVEL_NONE,
    3237           1 :                                            NT_STATUS_ACCESS_DENIED,
    3238             :                                            tree1, tree2_1);
    3239             : }
    3240             : 
    3241             : /**
    3242             :  * This tests replay with a pending open with 4 channels
    3243             :  * and closed transports on the client and server side.
    3244             :  *
    3245             :  * With a durablev2 request containing a create_guid,
    3246             :  * a share_access of READ/WRITE/DELETE,
    3247             :  * but without asking for an oplock nor a lease.
    3248             :  *
    3249             :  * While another client holds a batch oplock.
    3250             :  * And allows share_access of READ/WRITE/DELETE.
    3251             :  *
    3252             :  * See https://bugzilla.samba.org/show_bug.cgi?id=14449
    3253             :  *
    3254             :  * This expects the sane reject status of
    3255             :  * NT_STATUS_FILE_NOT_AVAILABLE.
    3256             :  *
    3257             :  * It won't pass against Windows as it returns
    3258             :  * NT_STATUS_ACCESS_DENIED see
    3259             :  * test_dhv2_pending2n_vs_oplock_windows().
    3260             :  */
    3261           1 : static bool test_dhv2_pending2n_vs_oplock_sane(struct torture_context *tctx,
    3262             :                                                struct smb2_tree *tree1,
    3263             :                                                struct smb2_tree *tree2_1)
    3264             : {
    3265           1 :         return _test_dhv2_pending2_vs_hold(tctx, __func__,
    3266             :                                            SMB2_OPLOCK_LEVEL_BATCH,
    3267             :                                            SMB2_OPLOCK_LEVEL_NONE,
    3268           1 :                                            NT_STATUS_FILE_NOT_AVAILABLE,
    3269             :                                            tree1, tree2_1);
    3270             : }
    3271             : 
    3272             : /**
    3273             :  * This tests replay with a pending open with 4 channels
    3274             :  * and closed transports on the client and server side.
    3275             :  *
    3276             :  * With a durablev2 request containing a create_guid,
    3277             :  * a share_access of READ/WRITE/DELETE,
    3278             :  * but without asking for an oplock nor a lease.
    3279             :  *
    3280             :  * While another client holds a batch oplock.
    3281             :  * And allows share_access of READ/WRITE/DELETE.
    3282             :  *
    3283             :  * See https://bugzilla.samba.org/show_bug.cgi?id=14449
    3284             :  *
    3285             :  * This expects the strange reject status of
    3286             :  * NT_STATUS_ACCESS_DENIED, which is returned
    3287             :  * by Windows Servers.
    3288             :  *
    3289             :  * It won't pass against Samba as it returns
    3290             :  * NT_STATUS_FILE_NOT_AVAILABLE. see
    3291             :  * test_dhv2_pending2n_vs_oplock_sane().
    3292             :  */
    3293           1 : static bool test_dhv2_pending2n_vs_oplock_windows(struct torture_context *tctx,
    3294             :                                                   struct smb2_tree *tree1,
    3295             :                                                   struct smb2_tree *tree2_1)
    3296             : {
    3297           1 :         return _test_dhv2_pending2_vs_hold(tctx, __func__,
    3298             :                                            SMB2_OPLOCK_LEVEL_BATCH,
    3299             :                                            SMB2_OPLOCK_LEVEL_NONE,
    3300           1 :                                            NT_STATUS_ACCESS_DENIED,
    3301             :                                            tree1, tree2_1);
    3302             : }
    3303             : 
    3304             : /**
    3305             :  * This tests replay with a pending open with 4 channels
    3306             :  * and closed transports on the client and server side.
    3307             :  *
    3308             :  * With a durablev2 request containing a create_guid,
    3309             :  * a share_access of READ/WRITE/DELETE,
    3310             :  * and asking for a v2 lease.
    3311             :  *
    3312             :  * While another client holds a batch oplock.
    3313             :  * And allows share_access of READ/WRITE/DELETE.
    3314             :  *
    3315             :  * See https://bugzilla.samba.org/show_bug.cgi?id=14449
    3316             :  *
    3317             :  * This expects the sane reject status of
    3318             :  * NT_STATUS_FILE_NOT_AVAILABLE.
    3319             :  *
    3320             :  * It won't pass against Windows as it returns
    3321             :  * NT_STATUS_ACCESS_DENIED see
    3322             :  * test_dhv2_pending2l_vs_oplock_windows().
    3323             :  */
    3324           1 : static bool test_dhv2_pending2l_vs_oplock_sane(struct torture_context *tctx,
    3325             :                                                struct smb2_tree *tree1,
    3326             :                                                struct smb2_tree *tree2_1)
    3327             : {
    3328           1 :         return _test_dhv2_pending2_vs_hold(tctx, __func__,
    3329             :                                            SMB2_OPLOCK_LEVEL_BATCH,
    3330             :                                            SMB2_OPLOCK_LEVEL_LEASE,
    3331           1 :                                            NT_STATUS_FILE_NOT_AVAILABLE,
    3332             :                                            tree1, tree2_1);
    3333             : }
    3334             : 
    3335             : /**
    3336             :  * This tests replay with a pending open with 4 channels
    3337             :  * and closed transports on the client and server side.
    3338             :  *
    3339             :  * With a durablev2 request containing a create_guid,
    3340             :  * a share_access of READ/WRITE/DELETE,
    3341             :  * and asking for a v2 lease.
    3342             :  *
    3343             :  * While another client holds a batch oplock.
    3344             :  * And allows share_access of READ/WRITE/DELETE.
    3345             :  *
    3346             :  * See https://bugzilla.samba.org/show_bug.cgi?id=14449
    3347             :  *
    3348             :  * This expects the strange reject status of
    3349             :  * NT_STATUS_ACCESS_DENIED, which is returned
    3350             :  * by Windows Servers.
    3351             :  *
    3352             :  * It won't pass against Samba as it returns
    3353             :  * NT_STATUS_FILE_NOT_AVAILABLE. see
    3354             :  * test_dhv2_pending2l_vs_oplock_sane().
    3355             :  */
    3356           1 : static bool test_dhv2_pending2l_vs_oplock_windows(struct torture_context *tctx,
    3357             :                                                   struct smb2_tree *tree1,
    3358             :                                                   struct smb2_tree *tree2_1)
    3359             : {
    3360           1 :         return _test_dhv2_pending2_vs_hold(tctx, __func__,
    3361             :                                            SMB2_OPLOCK_LEVEL_BATCH,
    3362             :                                            SMB2_OPLOCK_LEVEL_LEASE,
    3363           1 :                                            NT_STATUS_ACCESS_DENIED,
    3364             :                                            tree1, tree2_1);
    3365             : }
    3366             : 
    3367             : /**
    3368             :  * This tests replay with a pending open with 4 channels
    3369             :  * and closed transports on the client and server side.
    3370             :  *
    3371             :  * With a durablev2 request containing a create_guid,
    3372             :  * a share_access of READ/WRITE/DELETE,
    3373             :  * and asking for a v2 lease.
    3374             :  *
    3375             :  * While another client holds an RWH lease.
    3376             :  * And allows share_access of READ/WRITE/DELETE.
    3377             :  *
    3378             :  * See https://bugzilla.samba.org/show_bug.cgi?id=14449
    3379             :  *
    3380             :  * This expects the sane reject status of
    3381             :  * NT_STATUS_FILE_NOT_AVAILABLE.
    3382             :  *
    3383             :  * It won't pass against Windows as it returns
    3384             :  * NT_STATUS_ACCESS_DENIED see
    3385             :  * test_dhv2_pending2l_vs_oplock_windows().
    3386             :  */
    3387           1 : static bool test_dhv2_pending2l_vs_lease_sane(struct torture_context *tctx,
    3388             :                                               struct smb2_tree *tree1,
    3389             :                                               struct smb2_tree *tree2_1)
    3390             : {
    3391           1 :         return _test_dhv2_pending2_vs_hold(tctx, __func__,
    3392             :                                            SMB2_OPLOCK_LEVEL_LEASE,
    3393             :                                            SMB2_OPLOCK_LEVEL_LEASE,
    3394           1 :                                            NT_STATUS_FILE_NOT_AVAILABLE,
    3395             :                                            tree1, tree2_1);
    3396             : }
    3397             : 
    3398             : /**
    3399             :  * This tests replay with a pending open with 4 channels
    3400             :  * and closed transports on the client and server side.
    3401             :  *
    3402             :  * With a durablev2 request containing a create_guid,
    3403             :  * a share_access of READ/WRITE/DELETE,
    3404             :  * and asking for a v2 lease.
    3405             :  *
    3406             :  * While another client holds an RWH lease.
    3407             :  * And allows share_access of READ/WRITE/DELETE.
    3408             :  *
    3409             :  * See https://bugzilla.samba.org/show_bug.cgi?id=14449
    3410             :  *
    3411             :  * This expects the strange reject status of
    3412             :  * NT_STATUS_ACCESS_DENIED, which is returned
    3413             :  * by Windows Servers.
    3414             :  *
    3415             :  * It won't pass against Samba as it returns
    3416             :  * NT_STATUS_FILE_NOT_AVAILABLE. see
    3417             :  * test_dhv2_pending2l_vs_oplock_sane().
    3418             :  */
    3419           1 : static bool test_dhv2_pending2l_vs_lease_windows(struct torture_context *tctx,
    3420             :                                                  struct smb2_tree *tree1,
    3421             :                                                  struct smb2_tree *tree2_1)
    3422             : {
    3423           1 :         return _test_dhv2_pending2_vs_hold(tctx, __func__,
    3424             :                                            SMB2_OPLOCK_LEVEL_LEASE,
    3425             :                                            SMB2_OPLOCK_LEVEL_LEASE,
    3426           1 :                                            NT_STATUS_ACCESS_DENIED,
    3427             :                                            tree1, tree2_1);
    3428             : }
    3429             : 
    3430             : /**
    3431             :  * This tests replay with a pending open with 4 channels
    3432             :  * and closed transports on the client and server side.
    3433             :  *
    3434             :  * With a durablev2 request containing a create_guid,
    3435             :  * a share_access of READ/WRITE/DELETE,
    3436             :  * and asking for a batch oplock
    3437             :  *
    3438             :  * While another client holds a batch oplock.
    3439             :  * And allows share_access of READ/WRITE/DELETE.
    3440             :  *
    3441             :  * See https://bugzilla.samba.org/show_bug.cgi?id=14449
    3442             :  *
    3443             :  * This expects the sane reject status of
    3444             :  * NT_STATUS_FILE_NOT_AVAILABLE.
    3445             :  *
    3446             :  * It won't pass against Windows as it returns
    3447             :  * NT_STATUS_ACCESS_DENIED see
    3448             :  * test_dhv2_pending2o_vs_oplock_windows().
    3449             :  */
    3450           1 : static bool test_dhv2_pending2o_vs_oplock_sane(struct torture_context *tctx,
    3451             :                                                struct smb2_tree *tree1,
    3452             :                                                struct smb2_tree *tree2_1)
    3453             : {
    3454           1 :         return _test_dhv2_pending2_vs_hold(tctx, __func__,
    3455             :                                            SMB2_OPLOCK_LEVEL_BATCH,
    3456             :                                            SMB2_OPLOCK_LEVEL_BATCH,
    3457           1 :                                            NT_STATUS_FILE_NOT_AVAILABLE,
    3458             :                                            tree1, tree2_1);
    3459             : }
    3460             : 
    3461             : /**
    3462             :  * This tests replay with a pending open with 4 channels
    3463             :  * and closed transports on the client and server side.
    3464             :  *
    3465             :  * With a durablev2 request containing a create_guid,
    3466             :  * a share_access of READ/WRITE/DELETE,
    3467             :  * and asking for a batch oplock.
    3468             :  *
    3469             :  * While another client holds a batch oplock.
    3470             :  * And allows share_access of READ/WRITE/DELETE.
    3471             :  *
    3472             :  * See https://bugzilla.samba.org/show_bug.cgi?id=14449
    3473             :  *
    3474             :  * This expects the strange reject status of
    3475             :  * NT_STATUS_ACCESS_DENIED, which is returned
    3476             :  * by Windows Servers.
    3477             :  *
    3478             :  * It won't pass against Samba as it returns
    3479             :  * NT_STATUS_FILE_NOT_AVAILABLE. see
    3480             :  * test_dhv2_pending2o_vs_oplock_sane().
    3481             :  */
    3482           1 : static bool test_dhv2_pending2o_vs_oplock_windows(struct torture_context *tctx,
    3483             :                                                   struct smb2_tree *tree1,
    3484             :                                                   struct smb2_tree *tree2_1)
    3485             : {
    3486           1 :         return _test_dhv2_pending2_vs_hold(tctx, __func__,
    3487             :                                            SMB2_OPLOCK_LEVEL_BATCH,
    3488             :                                            SMB2_OPLOCK_LEVEL_BATCH,
    3489           1 :                                            NT_STATUS_ACCESS_DENIED,
    3490             :                                            tree1, tree2_1);
    3491             : }
    3492             : 
    3493             : /**
    3494             :  * This tests replay with a pending open with 4 channels
    3495             :  * and closed transports on the client and server side.
    3496             :  *
    3497             :  * With a durablev2 request containing a create_guid,
    3498             :  * a share_access of READ/WRITE/DELETE,
    3499             :  * and asking for a batch oplock
    3500             :  *
    3501             :  * While another client holds an RWH lease.
    3502             :  * And allows share_access of READ/WRITE/DELETE.
    3503             :  *
    3504             :  * See https://bugzilla.samba.org/show_bug.cgi?id=14449
    3505             :  *
    3506             :  * This expects the sane reject status of
    3507             :  * NT_STATUS_FILE_NOT_AVAILABLE.
    3508             :  *
    3509             :  * It won't pass against Windows as it returns
    3510             :  * NT_STATUS_ACCESS_DENIED see
    3511             :  * test_dhv2_pending2o_vs_lease_windows().
    3512             :  */
    3513           1 : static bool test_dhv2_pending2o_vs_lease_sane(struct torture_context *tctx,
    3514             :                                               struct smb2_tree *tree1,
    3515             :                                               struct smb2_tree *tree2_1)
    3516             : {
    3517           1 :         return _test_dhv2_pending2_vs_hold(tctx, __func__,
    3518             :                                            SMB2_OPLOCK_LEVEL_LEASE,
    3519             :                                            SMB2_OPLOCK_LEVEL_BATCH,
    3520           1 :                                            NT_STATUS_FILE_NOT_AVAILABLE,
    3521             :                                            tree1, tree2_1);
    3522             : }
    3523             : 
    3524             : /**
    3525             :  * This tests replay with a pending open with 4 channels
    3526             :  * and closed transports on the client and server side.
    3527             :  *
    3528             :  * With a durablev2 request containing a create_guid,
    3529             :  * a share_access of READ/WRITE/DELETE,
    3530             :  * and asking for a batch oplock.
    3531             :  *
    3532             :  * While another client holds an RWH lease.
    3533             :  * And allows share_access of READ/WRITE/DELETE.
    3534             :  *
    3535             :  * See https://bugzilla.samba.org/show_bug.cgi?id=14449
    3536             :  *
    3537             :  * This expects the strange reject status of
    3538             :  * NT_STATUS_ACCESS_DENIED, which is returned
    3539             :  * by Windows Servers.
    3540             :  *
    3541             :  * It won't pass against Samba as it returns
    3542             :  * NT_STATUS_FILE_NOT_AVAILABLE. see
    3543             :  * test_dhv2_pending2o_vs_lease_sane().
    3544             :  */
    3545           1 : static bool test_dhv2_pending2o_vs_lease_windows(struct torture_context *tctx,
    3546             :                                                  struct smb2_tree *tree1,
    3547             :                                                  struct smb2_tree *tree2_1)
    3548             : {
    3549           1 :         return _test_dhv2_pending2_vs_hold(tctx, __func__,
    3550             :                                            SMB2_OPLOCK_LEVEL_LEASE,
    3551             :                                            SMB2_OPLOCK_LEVEL_BATCH,
    3552           1 :                                            NT_STATUS_ACCESS_DENIED,
    3553             :                                            tree1, tree2_1);
    3554             : }
    3555             : 
    3556             : /**
    3557             :  * This tests replay with a pending open with 4 channels
    3558             :  * and blocked transports on the client side.
    3559             :  *
    3560             :  * With a durablev2 request containing a create_guid and
    3561             :  * a share_access of READ/WRITE/DELETE:
    3562             :  * - client2_level = NONE:
    3563             :  *   but without asking for an oplock nor a lease.
    3564             :  * - client2_level = BATCH:
    3565             :  *   and asking for a batch oplock.
    3566             :  * - client2_level = LEASE
    3567             :  *   and asking for an RWH lease.
    3568             :  *
    3569             :  * While another client holds a batch oplock or
    3570             :  * RWH lease. (client1_level => LEASE or BATCH).
    3571             :  * And allows share_access of READ/WRITE/DELETE.
    3572             :  *
    3573             :  * See https://bugzilla.samba.org/show_bug.cgi?id=14449
    3574             :  */
    3575          12 : static bool _test_dhv2_pending3_vs_hold(struct torture_context *tctx,
    3576             :                                         const char *testname,
    3577             :                                         uint8_t client1_level,
    3578             :                                         uint8_t client2_level,
    3579             :                                         NTSTATUS reject_status,
    3580             :                                         struct smb2_tree *tree1,
    3581             :                                         struct smb2_tree *tree2_1)
    3582             : {
    3583          12 :         const char *host = torture_setting_string(tctx, "host", NULL);
    3584          12 :         const char *share = torture_setting_string(tctx, "share", NULL);
    3585          12 :         struct cli_credentials *credentials = samba_cmdline_get_creds();
    3586             :         NTSTATUS status;
    3587          12 :         TALLOC_CTX *mem_ctx = talloc_new(tctx);
    3588             :         struct smb2_handle _h1;
    3589          12 :         struct smb2_handle *h1 = NULL;
    3590             :         struct smb2_handle _h21;
    3591          12 :         struct smb2_handle *h21 = NULL;
    3592             :         struct smb2_handle _h24;
    3593          12 :         struct smb2_handle *h24 = NULL;
    3594             :         struct smb2_create io1, io21, io22, io23, io24;
    3595          12 :         struct GUID create_guid1 = GUID_random();
    3596          12 :         struct GUID create_guid2 = GUID_random();
    3597          12 :         struct smb2_request *req21 = NULL;
    3598          12 :         bool ret = true;
    3599             :         char fname[256];
    3600          12 :         struct smb2_transport *transport1 = tree1->session->transport;
    3601             :         uint32_t server_capabilities;
    3602             :         uint32_t share_capabilities;
    3603             :         struct smb2_lease ls1;
    3604             :         uint64_t lease_key1;
    3605          12 :         uint16_t lease_epoch1 = 0;
    3606             :         struct smb2_lease ls2;
    3607             :         uint64_t lease_key2;
    3608          12 :         uint16_t lease_epoch2 = 0;
    3609             :         bool share_is_so;
    3610          12 :         struct smb2_transport *transport2_1 = tree2_1->session->transport;
    3611          12 :         int request_timeout2 = transport2_1->options.request_timeout;
    3612             :         struct smbcli_options options2x;
    3613          12 :         struct smb2_tree *tree2_2 = NULL;
    3614          12 :         struct smb2_tree *tree2_3 = NULL;
    3615          12 :         struct smb2_tree *tree2_4 = NULL;
    3616          12 :         struct smb2_transport *transport2_2 = NULL;
    3617          12 :         struct smb2_transport *transport2_3 = NULL;
    3618          12 :         struct smb2_transport *transport2_4 = NULL;
    3619          12 :         struct smb2_session *session2_1 = tree2_1->session;
    3620          12 :         struct smb2_session *session2_2 = NULL;
    3621          12 :         struct smb2_session *session2_3 = NULL;
    3622          12 :         struct smb2_session *session2_4 = NULL;
    3623          12 :         bool block_setup = false;
    3624          12 :         bool blocked2_1 = false;
    3625          12 :         bool blocked2_2 = false;
    3626          12 :         bool blocked2_3 = false;
    3627          12 :         uint16_t csn2 = 1;
    3628          12 :         const char *hold_name = NULL;
    3629             : 
    3630          12 :         switch (client1_level) {
    3631           6 :         case SMB2_OPLOCK_LEVEL_LEASE:
    3632           6 :                 hold_name = "RWH Lease";
    3633           6 :                 break;
    3634           6 :         case SMB2_OPLOCK_LEVEL_BATCH:
    3635           6 :                 hold_name = "BATCH Oplock";
    3636           6 :                 break;
    3637           0 :         default:
    3638           0 :                 smb_panic(__location__);
    3639             :                 break;
    3640             :         }
    3641             : 
    3642          12 :         if (smbXcli_conn_protocol(transport1->conn) < PROTOCOL_SMB3_00) {
    3643          12 :                 torture_skip(tctx, "SMB 3.X Dialect family required for "
    3644             :                                    "replay tests\n");
    3645             :         }
    3646             : 
    3647           0 :         server_capabilities = smb2cli_conn_server_capabilities(transport1->conn);
    3648           0 :         if (!(server_capabilities & SMB2_CAP_MULTI_CHANNEL)) {
    3649           0 :                 torture_skip(tctx, "MULTI_CHANNEL are not supported");
    3650             :         }
    3651           0 :         if (!(server_capabilities & SMB2_CAP_LEASING)) {
    3652           0 :                 if (client1_level == SMB2_OPLOCK_LEVEL_LEASE ||
    3653             :                     client2_level == SMB2_OPLOCK_LEVEL_LEASE) {
    3654           0 :                         torture_skip(tctx, "leases are not supported");
    3655             :                 }
    3656             :         }
    3657             : 
    3658           0 :         share_capabilities = smb2cli_tcon_capabilities(tree1->smbXcli);
    3659           0 :         share_is_so = share_capabilities & SMB2_SHARE_CAP_SCALEOUT;
    3660           0 :         if (share_is_so) {
    3661           0 :                 torture_skip(tctx, talloc_asprintf(tctx,
    3662             :                              "%s not supported on SCALEOUT share",
    3663             :                              hold_name));
    3664             :         }
    3665             : 
    3666             :         /* Add some random component to the file name. */
    3667           0 :         snprintf(fname, sizeof(fname), "%s\\%s_%s.dat",
    3668             :                  BASEDIR, testname, generate_random_str(tctx, 8));
    3669             : 
    3670           0 :         options2x = transport2_1->options;
    3671           0 :         options2x.only_negprot = true;
    3672             : 
    3673           0 :         status = smb2_connect(tctx,
    3674             :                               host,
    3675             :                               lpcfg_smb_ports(tctx->lp_ctx),
    3676             :                               share,
    3677             :                               lpcfg_resolve_context(tctx->lp_ctx),
    3678             :                               credentials,
    3679             :                               &tree2_2,
    3680             :                               tctx->ev,
    3681             :                               &options2x,
    3682             :                               lpcfg_socket_options(tctx->lp_ctx),
    3683             :                               lpcfg_gensec_settings(tctx, tctx->lp_ctx)
    3684             :                               );
    3685           0 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    3686             :                                         "smb2_connect failed");
    3687           0 :         transport2_2 = tree2_2->session->transport;
    3688             : 
    3689           0 :         session2_2 = smb2_session_channel(transport2_2,
    3690             :                                           lpcfg_gensec_settings(tctx, tctx->lp_ctx),
    3691             :                                           tctx,
    3692             :                                           session2_1);
    3693           0 :         torture_assert(tctx, session2_2 != NULL, "smb2_session_channel failed");
    3694             : 
    3695           0 :         status = smb2_session_setup_spnego(session2_2,
    3696             :                                            credentials,
    3697             :                                            0 /* previous_session_id */);
    3698           0 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    3699             :                                         "smb2_session_setup_spnego failed");
    3700           0 :         tree2_2->smbXcli = tree2_1->smbXcli;
    3701           0 :         tree2_2->session = session2_2;
    3702             : 
    3703           0 :         status = smb2_connect(tctx,
    3704             :                               host,
    3705             :                               lpcfg_smb_ports(tctx->lp_ctx),
    3706             :                               share,
    3707             :                               lpcfg_resolve_context(tctx->lp_ctx),
    3708             :                               credentials,
    3709             :                               &tree2_3,
    3710             :                               tctx->ev,
    3711             :                               &options2x,
    3712             :                               lpcfg_socket_options(tctx->lp_ctx),
    3713             :                               lpcfg_gensec_settings(tctx, tctx->lp_ctx)
    3714             :                               );
    3715           0 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    3716             :                                         "smb2_connect failed");
    3717           0 :         transport2_3 = tree2_3->session->transport;
    3718             : 
    3719           0 :         session2_3 = smb2_session_channel(transport2_3,
    3720             :                                           lpcfg_gensec_settings(tctx, tctx->lp_ctx),
    3721             :                                           tctx,
    3722             :                                           session2_1);
    3723           0 :         torture_assert(tctx, session2_3 != NULL, "smb2_session_channel failed");
    3724             : 
    3725           0 :         status = smb2_session_setup_spnego(session2_3,
    3726             :                                            credentials,
    3727             :                                            0 /* previous_session_id */);
    3728           0 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    3729             :                                         "smb2_session_setup_spnego failed");
    3730           0 :         tree2_3->smbXcli = tree2_1->smbXcli;
    3731           0 :         tree2_3->session = session2_3;
    3732             : 
    3733           0 :         status = smb2_connect(tctx,
    3734             :                               host,
    3735             :                               lpcfg_smb_ports(tctx->lp_ctx),
    3736             :                               share,
    3737             :                               lpcfg_resolve_context(tctx->lp_ctx),
    3738             :                               credentials,
    3739             :                               &tree2_4,
    3740             :                               tctx->ev,
    3741             :                               &options2x,
    3742             :                               lpcfg_socket_options(tctx->lp_ctx),
    3743             :                               lpcfg_gensec_settings(tctx, tctx->lp_ctx)
    3744             :                               );
    3745           0 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    3746             :                                         "smb2_connect failed");
    3747           0 :         transport2_4 = tree2_4->session->transport;
    3748             : 
    3749           0 :         session2_4 = smb2_session_channel(transport2_4,
    3750             :                                           lpcfg_gensec_settings(tctx, tctx->lp_ctx),
    3751             :                                           tctx,
    3752             :                                           session2_1);
    3753           0 :         torture_assert(tctx, session2_4 != NULL, "smb2_session_channel failed");
    3754             : 
    3755           0 :         status = smb2_session_setup_spnego(session2_4,
    3756             :                                            credentials,
    3757             :                                            0 /* previous_session_id */);
    3758           0 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    3759             :                                         "smb2_session_setup_spnego failed");
    3760           0 :         tree2_4->smbXcli = tree2_1->smbXcli;
    3761           0 :         tree2_4->session = session2_4;
    3762             : 
    3763           0 :         smb2cli_session_reset_channel_sequence(session2_2->smbXcli, csn2++);
    3764             : 
    3765           0 :         torture_reset_break_info(tctx, &break_info);
    3766           0 :         break_info.oplock_skip_ack = true;
    3767           0 :         torture_reset_lease_break_info(tctx, &lease_break_info);
    3768           0 :         lease_break_info.lease_skip_ack = true;
    3769           0 :         transport1->oplock.handler = torture_oplock_ack_handler;
    3770           0 :         transport1->oplock.private_data = tree1;
    3771           0 :         transport1->lease.handler = torture_lease_handler;
    3772           0 :         transport1->lease.private_data = tree1;
    3773           0 :         smb2_keepalive(transport1);
    3774           0 :         transport2_1->oplock.handler = torture_oplock_ack_handler;
    3775           0 :         transport2_1->oplock.private_data = tree2_1;
    3776           0 :         transport2_1->lease.handler = torture_lease_handler;
    3777           0 :         transport2_1->lease.private_data = tree2_1;
    3778           0 :         smb2_keepalive(transport2_1);
    3779           0 :         transport2_2->oplock.handler = torture_oplock_ack_handler;
    3780           0 :         transport2_2->oplock.private_data = tree2_2;
    3781           0 :         transport2_2->lease.handler = torture_lease_handler;
    3782           0 :         transport2_2->lease.private_data = tree2_2;
    3783           0 :         smb2_keepalive(transport2_2);
    3784           0 :         transport2_3->oplock.handler = torture_oplock_ack_handler;
    3785           0 :         transport2_3->oplock.private_data = tree2_3;
    3786           0 :         transport2_3->lease.handler = torture_lease_handler;
    3787           0 :         transport2_3->lease.private_data = tree2_3;
    3788           0 :         smb2_keepalive(transport2_3);
    3789           0 :         transport2_4->oplock.handler = torture_oplock_ack_handler;
    3790           0 :         transport2_4->oplock.private_data = tree2_4;
    3791           0 :         transport2_4->lease.handler = torture_lease_handler;
    3792           0 :         transport2_4->lease.private_data = tree2_4;
    3793           0 :         smb2_keepalive(transport2_4);
    3794             : 
    3795           0 :         smb2_util_unlink(tree1, fname);
    3796           0 :         status = torture_smb2_testdir(tree1, BASEDIR, &_h1);
    3797           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    3798           0 :         smb2_util_close(tree1, _h1);
    3799           0 :         CHECK_VAL(break_info.count, 0);
    3800             : 
    3801           0 :         lease_key1 = random();
    3802           0 :         if (client1_level == SMB2_OPLOCK_LEVEL_LEASE) {
    3803           0 :                 smb2_lease_v2_create(&io1, &ls1, false /* dir */, fname,
    3804           0 :                         lease_key1, NULL, smb2_util_lease_state("RWH"), lease_epoch1++);
    3805             :         } else {
    3806           0 :                 smb2_oplock_create(&io1, fname, SMB2_OPLOCK_LEVEL_BATCH);
    3807             :         }
    3808           0 :         io1.in.durable_open = false;
    3809           0 :         io1.in.durable_open_v2 = true;
    3810           0 :         io1.in.persistent_open = false;
    3811           0 :         io1.in.create_guid = create_guid1;
    3812           0 :         io1.in.timeout = UINT32_MAX;
    3813             : 
    3814           0 :         status = smb2_create(tree1, mem_ctx, &io1);
    3815           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    3816           0 :         _h1 = io1.out.file.handle;
    3817           0 :         h1 = &_h1;
    3818           0 :         CHECK_CREATED(&io1, CREATED, FILE_ATTRIBUTE_ARCHIVE);
    3819           0 :         CHECK_VAL(io1.out.durable_open, false);
    3820           0 :         if (client1_level == SMB2_OPLOCK_LEVEL_LEASE) {
    3821           0 :                 CHECK_VAL(io1.out.oplock_level, SMB2_OPLOCK_LEVEL_LEASE);
    3822           0 :                 CHECK_VAL(io1.out.lease_response_v2.lease_key.data[0], lease_key1);
    3823           0 :                 CHECK_VAL(io1.out.lease_response_v2.lease_key.data[1], ~lease_key1);
    3824           0 :                 CHECK_VAL(io1.out.lease_response_v2.lease_epoch, lease_epoch1);
    3825           0 :                 CHECK_VAL(io1.out.lease_response_v2.lease_state,
    3826             :                           smb2_util_lease_state("RHW"));
    3827             :         } else {
    3828           0 :                 CHECK_VAL(io1.out.oplock_level, SMB2_OPLOCK_LEVEL_BATCH);
    3829             :         }
    3830           0 :         CHECK_VAL(io1.out.durable_open_v2, true);
    3831           0 :         CHECK_VAL(io1.out.timeout, 300*1000);
    3832             : 
    3833           0 :         lease_key2 = random();
    3834           0 :         if (client2_level == SMB2_OPLOCK_LEVEL_LEASE) {
    3835           0 :                 smb2_lease_v2_create(&io21, &ls2, false /* dir */, fname,
    3836           0 :                         lease_key2, NULL, smb2_util_lease_state("RWH"), lease_epoch2++);
    3837             :         } else {
    3838           0 :                 smb2_oplock_create(&io21, fname, client2_level);
    3839             :         }
    3840           0 :         io21.in.durable_open = false;
    3841           0 :         io21.in.durable_open_v2 = true;
    3842           0 :         io21.in.persistent_open = false;
    3843           0 :         io21.in.create_guid = create_guid2;
    3844           0 :         io21.in.timeout = UINT32_MAX;
    3845           0 :         io24 = io23 = io22 = io21;
    3846             : 
    3847           0 :         req21 = smb2_create_send(tree2_1, &io21);
    3848           0 :         torture_assert(tctx, req21 != NULL, "req21");
    3849             : 
    3850           0 :         if (client1_level == SMB2_OPLOCK_LEVEL_LEASE) {
    3851           0 :                 const struct smb2_lease_break *lb =
    3852             :                         &lease_break_info.lease_break;
    3853           0 :                 const struct smb2_lease *l = &lb->current_lease;
    3854           0 :                 const struct smb2_lease_key *k = &l->lease_key;
    3855             : 
    3856           0 :                 torture_wait_for_lease_break(tctx);
    3857           0 :                 CHECK_VAL(break_info.count, 0);
    3858           0 :                 CHECK_VAL(lease_break_info.count, 1);
    3859             : 
    3860           0 :                 torture_assert(tctx,
    3861             :                         lease_break_info.lease_transport == transport1,
    3862             :                         "expect lease break on transport1\n");
    3863           0 :                 CHECK_VAL(k->data[0], lease_key1);
    3864           0 :                 CHECK_VAL(k->data[1], ~lease_key1);
    3865           0 :                 CHECK_VAL(lb->new_lease_state,
    3866             :                           smb2_util_lease_state("RH"));
    3867           0 :                 CHECK_VAL(lb->break_flags,
    3868             :                           SMB2_NOTIFY_BREAK_LEASE_FLAG_ACK_REQUIRED);
    3869           0 :                 CHECK_VAL(lb->new_epoch, lease_epoch1+1);
    3870           0 :                 lease_epoch1 += 1;
    3871             :         } else {
    3872           0 :                 torture_wait_for_oplock_break(tctx);
    3873           0 :                 CHECK_VAL(break_info.count, 1);
    3874           0 :                 CHECK_VAL(lease_break_info.count, 0);
    3875             : 
    3876           0 :                 torture_assert(tctx,
    3877             :                         break_info.received_transport == transport1,
    3878             :                         "expect oplock break on transport1\n");
    3879           0 :                 CHECK_VAL(break_info.handle.data[0], _h1.data[0]);
    3880           0 :                 CHECK_VAL(break_info.handle.data[1], _h1.data[1]);
    3881           0 :                 CHECK_VAL(break_info.level, SMB2_OPLOCK_LEVEL_II);
    3882             :         }
    3883             : 
    3884           0 :         torture_reset_break_info(tctx, &break_info);
    3885           0 :         break_info.oplock_skip_ack = true;
    3886           0 :         torture_reset_lease_break_info(tctx, &lease_break_info);
    3887           0 :         lease_break_info.lease_skip_ack = true;
    3888             : 
    3889           0 :         WAIT_FOR_ASYNC_RESPONSE(tctx, req21);
    3890             : 
    3891           0 :         if (client1_level == SMB2_OPLOCK_LEVEL_LEASE) {
    3892           0 :                 torture_wait_for_lease_break(tctx);
    3893             :         } else {
    3894           0 :                 torture_wait_for_oplock_break(tctx);
    3895             :         }
    3896           0 :         CHECK_VAL(break_info.count, 0);
    3897           0 :         CHECK_VAL(lease_break_info.count, 0);
    3898             : 
    3899           0 :         block_setup = test_setup_blocked_transports(tctx);
    3900           0 :         torture_assert(tctx, block_setup, "test_setup_blocked_transports");
    3901             : 
    3902           0 :         blocked2_1 = _test_block_smb2_transport(tctx, transport2_1, "transport2_1");
    3903           0 :         torture_assert_goto(tctx, blocked2_1, ret, done, "we could not block tcp transport");
    3904           0 :         smb2cli_session_reset_channel_sequence(session2_1->smbXcli, csn2++);
    3905             : 
    3906           0 :         smb2cli_session_start_replay(session2_2->smbXcli);
    3907           0 :         transport2_2->options.request_timeout = 5;
    3908           0 :         status = smb2_create(tree2_2, tctx, &io22);
    3909           0 :         transport2_2->options.request_timeout = request_timeout2;
    3910           0 :         CHECK_STATUS(status, reject_status);
    3911           0 :         smb2cli_session_stop_replay(session2_2->smbXcli);
    3912             : 
    3913           0 :         if (client1_level == SMB2_OPLOCK_LEVEL_LEASE) {
    3914           0 :                 torture_wait_for_lease_break(tctx);
    3915             :         } else {
    3916           0 :                 torture_wait_for_oplock_break(tctx);
    3917             :         }
    3918           0 :         CHECK_VAL(break_info.count, 0);
    3919           0 :         CHECK_VAL(lease_break_info.count, 0);
    3920             : 
    3921           0 :         blocked2_2 = _test_block_smb2_transport(tctx, transport2_2, "transport2_2");
    3922           0 :         torture_assert_goto(tctx, blocked2_2, ret, done, "we could not block tcp transport");
    3923           0 :         smb2cli_session_reset_channel_sequence(session2_2->smbXcli, csn2++);
    3924             : 
    3925           0 :         smb2cli_session_start_replay(session2_3->smbXcli);
    3926           0 :         transport2_3->options.request_timeout = 5;
    3927           0 :         status = smb2_create(tree2_3, tctx, &io23);
    3928           0 :         transport2_3->options.request_timeout = request_timeout2;
    3929           0 :         CHECK_STATUS(status, reject_status);
    3930           0 :         smb2cli_session_stop_replay(session2_3->smbXcli);
    3931             : 
    3932           0 :         if (client1_level == SMB2_OPLOCK_LEVEL_LEASE) {
    3933           0 :                 torture_wait_for_lease_break(tctx);
    3934             :         } else {
    3935           0 :                 torture_wait_for_oplock_break(tctx);
    3936             :         }
    3937           0 :         CHECK_VAL(break_info.count, 0);
    3938           0 :         CHECK_VAL(lease_break_info.count, 0);
    3939             : 
    3940           0 :         smb2_util_close(tree1, _h1);
    3941           0 :         h1 = NULL;
    3942             : 
    3943           0 :         status = smb2_create_recv(req21, tctx, &io21);
    3944           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    3945           0 :         _h21 = io21.out.file.handle;
    3946           0 :         h21 = &_h21;
    3947           0 :         CHECK_CREATED(&io21, EXISTED, FILE_ATTRIBUTE_ARCHIVE);
    3948           0 :         CHECK_VAL(io21.out.oplock_level, client2_level);
    3949           0 :         CHECK_VAL(io21.out.durable_open, false);
    3950           0 :         if (client2_level == SMB2_OPLOCK_LEVEL_LEASE) {
    3951           0 :                 CHECK_VAL(io21.out.lease_response_v2.lease_key.data[0], lease_key2);
    3952           0 :                 CHECK_VAL(io21.out.lease_response_v2.lease_key.data[1], ~lease_key2);
    3953           0 :                 CHECK_VAL(io21.out.lease_response_v2.lease_epoch, lease_epoch2);
    3954           0 :                 CHECK_VAL(io21.out.lease_response_v2.lease_state,
    3955             :                           smb2_util_lease_state("RHW"));
    3956           0 :                 CHECK_VAL(io21.out.durable_open_v2, true);
    3957           0 :                 CHECK_VAL(io21.out.timeout, 300*1000);
    3958           0 :         } else if (client2_level == SMB2_OPLOCK_LEVEL_BATCH) {
    3959           0 :                 CHECK_VAL(io21.out.durable_open_v2, true);
    3960           0 :                 CHECK_VAL(io21.out.timeout, 300*1000);
    3961             :         } else {
    3962           0 :                 CHECK_VAL(io21.out.durable_open_v2, false);
    3963             :         }
    3964             : 
    3965           0 :         if (client1_level == SMB2_OPLOCK_LEVEL_LEASE) {
    3966           0 :                 torture_wait_for_lease_break(tctx);
    3967             :         } else {
    3968           0 :                 torture_wait_for_oplock_break(tctx);
    3969             :         }
    3970           0 :         CHECK_VAL(break_info.count, 0);
    3971           0 :         CHECK_VAL(lease_break_info.count, 0);
    3972             : 
    3973           0 :         blocked2_3 = _test_block_smb2_transport(tctx, transport2_3, "transport2_3");
    3974           0 :         torture_assert_goto(tctx, blocked2_3, ret, done, "we could not block tcp transport");
    3975           0 :         smb2cli_session_reset_channel_sequence(session2_3->smbXcli, csn2++);
    3976             : 
    3977           0 :         smb2cli_session_start_replay(session2_4->smbXcli);
    3978           0 :         status = smb2_create(tree2_4, tctx, &io24);
    3979           0 :         smb2cli_session_stop_replay(session2_4->smbXcli);
    3980           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    3981           0 :         _h24 = io24.out.file.handle;
    3982           0 :         h24 = &_h24;
    3983           0 :         CHECK_CREATED(&io24, EXISTED, FILE_ATTRIBUTE_ARCHIVE);
    3984           0 :         CHECK_VAL(h24->data[0], h21->data[0]);
    3985           0 :         CHECK_VAL(h24->data[1], h21->data[1]);
    3986           0 :         if (client2_level == SMB2_OPLOCK_LEVEL_LEASE) {
    3987           0 :                 CHECK_VAL(io24.out.lease_response_v2.lease_key.data[0], lease_key2);
    3988           0 :                 CHECK_VAL(io24.out.lease_response_v2.lease_key.data[1], ~lease_key2);
    3989           0 :                 CHECK_VAL(io24.out.lease_response_v2.lease_epoch, lease_epoch2);
    3990           0 :                 CHECK_VAL(io24.out.lease_response_v2.lease_state,
    3991             :                           smb2_util_lease_state("RHW"));
    3992           0 :                 CHECK_VAL(io24.out.durable_open_v2, true);
    3993           0 :                 CHECK_VAL(io24.out.timeout, 300*1000);
    3994           0 :         } else if (client2_level == SMB2_OPLOCK_LEVEL_BATCH) {
    3995           0 :                 CHECK_VAL(io24.out.durable_open_v2, true);
    3996           0 :                 CHECK_VAL(io24.out.timeout, 300*1000);
    3997             :         } else {
    3998           0 :                 CHECK_VAL(io24.out.durable_open_v2, false);
    3999             :         }
    4000             : 
    4001           0 :         if (client1_level == SMB2_OPLOCK_LEVEL_LEASE) {
    4002           0 :                 torture_wait_for_lease_break(tctx);
    4003             :         } else {
    4004           0 :                 torture_wait_for_oplock_break(tctx);
    4005             :         }
    4006           0 :         CHECK_VAL(break_info.count, 0);
    4007           0 :         CHECK_VAL(lease_break_info.count, 0);
    4008           0 :         status = smb2_util_close(tree2_4, *h24);
    4009           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    4010           0 :         h24 = NULL;
    4011             : 
    4012           0 :         if (client1_level == SMB2_OPLOCK_LEVEL_LEASE) {
    4013           0 :                 torture_wait_for_lease_break(tctx);
    4014             :         } else {
    4015           0 :                 torture_wait_for_oplock_break(tctx);
    4016             :         }
    4017           0 :         CHECK_VAL(break_info.count, 0);
    4018           0 :         CHECK_VAL(lease_break_info.count, 0);
    4019             : 
    4020           0 : done:
    4021             : 
    4022           0 :         if (blocked2_3) {
    4023           0 :                 _test_unblock_smb2_transport(tctx, transport2_3, "transport2_3");
    4024             :         }
    4025           0 :         if (blocked2_2) {
    4026           0 :                 _test_unblock_smb2_transport(tctx, transport2_2, "transport2_2");
    4027             :         }
    4028           0 :         if (blocked2_1) {
    4029           0 :                 _test_unblock_smb2_transport(tctx, transport2_1, "transport2_1");
    4030             :         }
    4031           0 :         if (block_setup) {
    4032           0 :                 test_cleanup_blocked_transports(tctx);
    4033             :         }
    4034             : 
    4035           0 :         smbXcli_conn_disconnect(transport2_1->conn, NT_STATUS_LOCAL_DISCONNECT);
    4036           0 :         smbXcli_conn_disconnect(transport2_2->conn, NT_STATUS_LOCAL_DISCONNECT);
    4037           0 :         smbXcli_conn_disconnect(transport2_3->conn, NT_STATUS_LOCAL_DISCONNECT);
    4038           0 :         smbXcli_conn_disconnect(transport2_4->conn, NT_STATUS_LOCAL_DISCONNECT);
    4039             : 
    4040           0 :         if (h1 != NULL) {
    4041           0 :                 smb2_util_close(tree1, *h1);
    4042             :         }
    4043             : 
    4044           0 :         smb2_deltree(tree1, BASEDIR);
    4045             : 
    4046           0 :         TALLOC_FREE(tree1);
    4047           0 :         talloc_free(mem_ctx);
    4048             : 
    4049           0 :         return ret;
    4050             : }
    4051             : 
    4052             : /**
    4053             :  * This tests replay with a pending open with 4 channels
    4054             :  * and blocked transports on the client side.
    4055             :  *
    4056             :  * With a durablev2 request containing a create_guid,
    4057             :  * a share_access of READ/WRITE/DELETE,
    4058             :  * but without asking for an oplock nor a lease.
    4059             :  *
    4060             :  * While another client holds an RWH lease.
    4061             :  * And allows share_access of READ/WRITE/DELETE.
    4062             :  *
    4063             :  * See https://bugzilla.samba.org/show_bug.cgi?id=14449
    4064             :  *
    4065             :  * This expects the sane reject status of
    4066             :  * NT_STATUS_FILE_NOT_AVAILABLE.
    4067             :  *
    4068             :  * It won't pass against Windows as it returns
    4069             :  * NT_STATUS_ACCESS_DENIED see
    4070             :  * test_dhv2_pending3n_vs_lease_windows().
    4071             :  */
    4072           1 : static bool test_dhv2_pending3n_vs_lease_sane(struct torture_context *tctx,
    4073             :                                               struct smb2_tree *tree1,
    4074             :                                               struct smb2_tree *tree2_1)
    4075             : {
    4076           1 :         return _test_dhv2_pending3_vs_hold(tctx, __func__,
    4077             :                                            SMB2_OPLOCK_LEVEL_LEASE,
    4078             :                                            SMB2_OPLOCK_LEVEL_NONE,
    4079           1 :                                            NT_STATUS_FILE_NOT_AVAILABLE,
    4080             :                                            tree1, tree2_1);
    4081             : }
    4082             : 
    4083             : /**
    4084             :  * This tests replay with a pending open with 4 channels
    4085             :  * and blocked transports on the client side.
    4086             :  *
    4087             :  * With a durablev2 request containing a create_guid,
    4088             :  * a share_access of READ/WRITE/DELETE,
    4089             :  * but without asking for an oplock nor a lease.
    4090             :  *
    4091             :  * While another client holds an RWH lease.
    4092             :  * And allows share_access of READ/WRITE/DELETE.
    4093             :  *
    4094             :  * See https://bugzilla.samba.org/show_bug.cgi?id=14449
    4095             :  *
    4096             :  * This expects the strange reject status of
    4097             :  * NT_STATUS_ACCESS_DENIED, which is returned
    4098             :  * by Windows Servers.
    4099             :  *
    4100             :  * It won't pass against Samba as it returns
    4101             :  * NT_STATUS_FILE_NOT_AVAILABLE. see
    4102             :  * test_dhv2_pending3n_vs_lease_sane.
    4103             :  */
    4104           1 : static bool test_dhv2_pending3n_vs_lease_windows(struct torture_context *tctx,
    4105             :                                                  struct smb2_tree *tree1,
    4106             :                                                  struct smb2_tree *tree2_1)
    4107             : {
    4108           1 :         return _test_dhv2_pending3_vs_hold(tctx, __func__,
    4109             :                                            SMB2_OPLOCK_LEVEL_LEASE,
    4110             :                                            SMB2_OPLOCK_LEVEL_NONE,
    4111           1 :                                            NT_STATUS_ACCESS_DENIED,
    4112             :                                            tree1, tree2_1);
    4113             : }
    4114             : 
    4115             : /**
    4116             :  * This tests replay with a pending open with 4 channels
    4117             :  * and blocked transports on the client side.
    4118             :  *
    4119             :  * With a durablev2 request containing a create_guid,
    4120             :  * a share_access of READ/WRITE/DELETE,
    4121             :  * but without asking for an oplock nor a lease.
    4122             :  *
    4123             :  * While another client holds a batch oplock.
    4124             :  * And allows share_access of READ/WRITE/DELETE.
    4125             :  *
    4126             :  * See https://bugzilla.samba.org/show_bug.cgi?id=14449
    4127             :  *
    4128             :  * This expects the sane reject status of
    4129             :  * NT_STATUS_FILE_NOT_AVAILABLE.
    4130             :  *
    4131             :  * It won't pass against Windows as it returns
    4132             :  * NT_STATUS_ACCESS_DENIED see
    4133             :  * test_dhv2_pending3n_vs_oplock_windows().
    4134             :  */
    4135           1 : static bool test_dhv2_pending3n_vs_oplock_sane(struct torture_context *tctx,
    4136             :                                                struct smb2_tree *tree1,
    4137             :                                                struct smb2_tree *tree2_1)
    4138             : {
    4139           1 :         return _test_dhv2_pending3_vs_hold(tctx, __func__,
    4140             :                                            SMB2_OPLOCK_LEVEL_BATCH,
    4141             :                                            SMB2_OPLOCK_LEVEL_NONE,
    4142           1 :                                            NT_STATUS_FILE_NOT_AVAILABLE,
    4143             :                                            tree1, tree2_1);
    4144             : }
    4145             : 
    4146             : /**
    4147             :  * This tests replay with a pending open with 4 channels
    4148             :  * and blocked transports on the client side.
    4149             :  *
    4150             :  * With a durablev2 request containing a create_guid,
    4151             :  * a share_access of READ/WRITE/DELETE,
    4152             :  * but without asking for an oplock nor a lease.
    4153             :  *
    4154             :  * While another client holds a batch oplock.
    4155             :  * And allows share_access of READ/WRITE/DELETE.
    4156             :  *
    4157             :  * See https://bugzilla.samba.org/show_bug.cgi?id=14449
    4158             :  *
    4159             :  * This expects the strange reject status of
    4160             :  * NT_STATUS_ACCESS_DENIED, which is returned
    4161             :  * by Windows Servers.
    4162             :  *
    4163             :  * It won't pass against Samba as it returns
    4164             :  * NT_STATUS_FILE_NOT_AVAILABLE. see
    4165             :  * test_dhv2_pending3n_vs_oplock_sane.
    4166             :  */
    4167           1 : static bool test_dhv2_pending3n_vs_oplock_windows(struct torture_context *tctx,
    4168             :                                                   struct smb2_tree *tree1,
    4169             :                                                   struct smb2_tree *tree2_1)
    4170             : {
    4171           1 :         return _test_dhv2_pending3_vs_hold(tctx, __func__,
    4172             :                                            SMB2_OPLOCK_LEVEL_BATCH,
    4173             :                                            SMB2_OPLOCK_LEVEL_NONE,
    4174           1 :                                            NT_STATUS_ACCESS_DENIED,
    4175             :                                            tree1, tree2_1);
    4176             : }
    4177             : 
    4178             : /**
    4179             :  * This tests replay with a pending open with 4 channels
    4180             :  * and blocked transports on the client side.
    4181             :  *
    4182             :  * With a durablev2 request containing a create_guid,
    4183             :  * a share_access of READ/WRITE/DELETE,
    4184             :  * and asking for a v2 lease.
    4185             :  *
    4186             :  * While another client holds a batch oplock.
    4187             :  * And allows share_access of READ/WRITE/DELETE.
    4188             :  *
    4189             :  * See https://bugzilla.samba.org/show_bug.cgi?id=14449
    4190             :  *
    4191             :  * This expects the sane reject status of
    4192             :  * NT_STATUS_FILE_NOT_AVAILABLE.
    4193             :  *
    4194             :  * It won't pass against Windows as it returns
    4195             :  * NT_STATUS_ACCESS_DENIED see
    4196             :  * test_dhv2_pending3l_vs_oplock_windows().
    4197             :  */
    4198           1 : static bool test_dhv2_pending3l_vs_oplock_sane(struct torture_context *tctx,
    4199             :                                                struct smb2_tree *tree1,
    4200             :                                                struct smb2_tree *tree2_1)
    4201             : {
    4202           1 :         return _test_dhv2_pending3_vs_hold(tctx, __func__,
    4203             :                                            SMB2_OPLOCK_LEVEL_BATCH,
    4204             :                                            SMB2_OPLOCK_LEVEL_LEASE,
    4205           1 :                                            NT_STATUS_FILE_NOT_AVAILABLE,
    4206             :                                            tree1, tree2_1);
    4207             : }
    4208             : 
    4209             : /**
    4210             :  * This tests replay with a pending open with 4 channels
    4211             :  * and blocked transports on the client side.
    4212             :  *
    4213             :  * With a durablev2 request containing a create_guid,
    4214             :  * a share_access of READ/WRITE/DELETE,
    4215             :  * and asking for a v2 lease.
    4216             :  *
    4217             :  * While another client holds a batch oplock.
    4218             :  * And allows share_access of READ/WRITE/DELETE.
    4219             :  *
    4220             :  * See https://bugzilla.samba.org/show_bug.cgi?id=14449
    4221             :  *
    4222             :  * This expects the strange reject status of
    4223             :  * NT_STATUS_ACCESS_DENIED, which is returned
    4224             :  * by Windows Servers.
    4225             :  *
    4226             :  * It won't pass against Samba as it returns
    4227             :  * NT_STATUS_FILE_NOT_AVAILABLE. see
    4228             :  * test_dhv2_pending3l_vs_oplock_sane.
    4229             :  */
    4230           1 : static bool test_dhv2_pending3l_vs_oplock_windows(struct torture_context *tctx,
    4231             :                                                   struct smb2_tree *tree1,
    4232             :                                                   struct smb2_tree *tree2_1)
    4233             : {
    4234           1 :         return _test_dhv2_pending3_vs_hold(tctx, __func__,
    4235             :                                            SMB2_OPLOCK_LEVEL_BATCH,
    4236             :                                            SMB2_OPLOCK_LEVEL_LEASE,
    4237           1 :                                            NT_STATUS_ACCESS_DENIED,
    4238             :                                            tree1, tree2_1);
    4239             : }
    4240             : 
    4241             : /**
    4242             :  * This tests replay with a pending open with 4 channels
    4243             :  * and blocked transports on the client side.
    4244             :  *
    4245             :  * With a durablev2 request containing a create_guid,
    4246             :  * a share_access of READ/WRITE/DELETE,
    4247             :  * and asking for a v2 lease.
    4248             :  *
    4249             :  * While another client holds an RWH lease.
    4250             :  * And allows share_access of READ/WRITE/DELETE.
    4251             :  *
    4252             :  * See https://bugzilla.samba.org/show_bug.cgi?id=14449
    4253             :  *
    4254             :  * This expects the sane reject status of
    4255             :  * NT_STATUS_FILE_NOT_AVAILABLE.
    4256             :  *
    4257             :  * It won't pass against Windows as it returns
    4258             :  * NT_STATUS_ACCESS_DENIED see
    4259             :  * test_dhv2_pending3l_vs_lease_windows().
    4260             :  */
    4261           1 : static bool test_dhv2_pending3l_vs_lease_sane(struct torture_context *tctx,
    4262             :                                               struct smb2_tree *tree1,
    4263             :                                               struct smb2_tree *tree2_1)
    4264             : {
    4265           1 :         return _test_dhv2_pending3_vs_hold(tctx, __func__,
    4266             :                                            SMB2_OPLOCK_LEVEL_LEASE,
    4267             :                                            SMB2_OPLOCK_LEVEL_LEASE,
    4268           1 :                                            NT_STATUS_FILE_NOT_AVAILABLE,
    4269             :                                            tree1, tree2_1);
    4270             : }
    4271             : 
    4272             : /**
    4273             :  * This tests replay with a pending open with 4 channels
    4274             :  * and blocked transports on the client side.
    4275             :  *
    4276             :  * With a durablev2 request containing a create_guid,
    4277             :  * a share_access of READ/WRITE/DELETE,
    4278             :  * and asking for a v2 lease.
    4279             :  *
    4280             :  * While another client holds an RWH lease.
    4281             :  * And allows share_access of READ/WRITE/DELETE.
    4282             :  *
    4283             :  * See https://bugzilla.samba.org/show_bug.cgi?id=14449
    4284             :  *
    4285             :  * This expects the strange reject status of
    4286             :  * NT_STATUS_ACCESS_DENIED, which is returned
    4287             :  * by Windows Servers.
    4288             :  *
    4289             :  * It won't pass against Samba as it returns
    4290             :  * NT_STATUS_FILE_NOT_AVAILABLE. see
    4291             :  * test_dhv2_pending3l_vs_lease_sane().
    4292             :  */
    4293           1 : static bool test_dhv2_pending3l_vs_lease_windows(struct torture_context *tctx,
    4294             :                                                  struct smb2_tree *tree1,
    4295             :                                                  struct smb2_tree *tree2_1)
    4296             : {
    4297           1 :         return _test_dhv2_pending3_vs_hold(tctx, __func__,
    4298             :                                            SMB2_OPLOCK_LEVEL_LEASE,
    4299             :                                            SMB2_OPLOCK_LEVEL_LEASE,
    4300           1 :                                            NT_STATUS_ACCESS_DENIED,
    4301             :                                            tree1, tree2_1);
    4302             : }
    4303             : 
    4304             : /**
    4305             :  * This tests replay with a pending open with 4 channels
    4306             :  * and blocked transports on the client side.
    4307             :  *
    4308             :  * With a durablev2 request containing a create_guid,
    4309             :  * a share_access of READ/WRITE/DELETE,
    4310             :  * and asking for a batch oplock.
    4311             :  *
    4312             :  * While another client holds a batch oplock.
    4313             :  * And allows share_access of READ/WRITE/DELETE.
    4314             :  *
    4315             :  * See https://bugzilla.samba.org/show_bug.cgi?id=14449
    4316             :  *
    4317             :  * This expects the sane reject status of
    4318             :  * NT_STATUS_FILE_NOT_AVAILABLE.
    4319             :  *
    4320             :  * It won't pass against Windows as it returns
    4321             :  * NT_STATUS_ACCESS_DENIED see
    4322             :  * test_dhv2_pending3o_vs_oplock_windows().
    4323             :  */
    4324           1 : static bool test_dhv2_pending3o_vs_oplock_sane(struct torture_context *tctx,
    4325             :                                                struct smb2_tree *tree1,
    4326             :                                                struct smb2_tree *tree2_1)
    4327             : {
    4328           1 :         return _test_dhv2_pending3_vs_hold(tctx, __func__,
    4329             :                                            SMB2_OPLOCK_LEVEL_BATCH,
    4330             :                                            SMB2_OPLOCK_LEVEL_BATCH,
    4331           1 :                                            NT_STATUS_FILE_NOT_AVAILABLE,
    4332             :                                            tree1, tree2_1);
    4333             : }
    4334             : 
    4335             : /**
    4336             :  * This tests replay with a pending open with 4 channels
    4337             :  * and blocked transports on the client side.
    4338             :  *
    4339             :  * With a durablev2 request containing a create_guid,
    4340             :  * a share_access of READ/WRITE/DELETE,
    4341             :  * and asking for a batch oplock.
    4342             :  *
    4343             :  * While another client holds a batch oplock.
    4344             :  * And allows share_access of READ/WRITE/DELETE.
    4345             :  *
    4346             :  * See https://bugzilla.samba.org/show_bug.cgi?id=14449
    4347             :  *
    4348             :  * This expects the strange reject status of
    4349             :  * NT_STATUS_ACCESS_DENIED, which is returned
    4350             :  * by Windows Servers.
    4351             :  *
    4352             :  * It won't pass against Samba as it returns
    4353             :  * NT_STATUS_FILE_NOT_AVAILABLE. see
    4354             :  * test_dhv2_pending3o_vs_oplock_sane().
    4355             :  */
    4356           1 : static bool test_dhv2_pending3o_vs_oplock_windows(struct torture_context *tctx,
    4357             :                                                   struct smb2_tree *tree1,
    4358             :                                                   struct smb2_tree *tree2_1)
    4359             : {
    4360           1 :         return _test_dhv2_pending3_vs_hold(tctx, __func__,
    4361             :                                            SMB2_OPLOCK_LEVEL_BATCH,
    4362             :                                            SMB2_OPLOCK_LEVEL_BATCH,
    4363           1 :                                            NT_STATUS_ACCESS_DENIED,
    4364             :                                            tree1, tree2_1);
    4365             : }
    4366             : 
    4367             : /**
    4368             :  * This tests replay with a pending open with 4 channels
    4369             :  * and blocked transports on the client side.
    4370             :  *
    4371             :  * With a durablev2 request containing a create_guid,
    4372             :  * a share_access of READ/WRITE/DELETE,
    4373             :  * and asking for a batch oplock.
    4374             :  *
    4375             :  * While another client holds an RWH lease.
    4376             :  * And allows share_access of READ/WRITE/DELETE.
    4377             :  *
    4378             :  * See https://bugzilla.samba.org/show_bug.cgi?id=14449
    4379             :  *
    4380             :  * This expects the sane reject status of
    4381             :  * NT_STATUS_FILE_NOT_AVAILABLE.
    4382             :  *
    4383             :  * It won't pass against Windows as it returns
    4384             :  * NT_STATUS_ACCESS_DENIED see
    4385             :  * test_dhv2_pending3o_vs_lease_windows().
    4386             :  */
    4387           1 : static bool test_dhv2_pending3o_vs_lease_sane(struct torture_context *tctx,
    4388             :                                               struct smb2_tree *tree1,
    4389             :                                               struct smb2_tree *tree2_1)
    4390             : {
    4391           1 :         return _test_dhv2_pending3_vs_hold(tctx, __func__,
    4392             :                                            SMB2_OPLOCK_LEVEL_LEASE,
    4393             :                                            SMB2_OPLOCK_LEVEL_BATCH,
    4394           1 :                                            NT_STATUS_FILE_NOT_AVAILABLE,
    4395             :                                            tree1, tree2_1);
    4396             : }
    4397             : 
    4398             : /**
    4399             :  * This tests replay with a pending open with 4 channels
    4400             :  * and blocked transports on the client side.
    4401             :  *
    4402             :  * With a durablev2 request containing a create_guid,
    4403             :  * a share_access of READ/WRITE/DELETE,
    4404             :  * and asking for a batch oplock.
    4405             :  *
    4406             :  * While another client holds an RWH lease.
    4407             :  * And allows share_access of READ/WRITE/DELETE.
    4408             :  *
    4409             :  * See https://bugzilla.samba.org/show_bug.cgi?id=14449
    4410             :  *
    4411             :  * This expects the strange reject status of
    4412             :  * NT_STATUS_ACCESS_DENIED, which is returned
    4413             :  * by Windows Servers.
    4414             :  *
    4415             :  * It won't pass against Samba as it returns
    4416             :  * NT_STATUS_FILE_NOT_AVAILABLE. see
    4417             :  * test_dhv2_pending3o_vs_lease_sane().
    4418             :  */
    4419           1 : static bool test_dhv2_pending3o_vs_lease_windows(struct torture_context *tctx,
    4420             :                                                  struct smb2_tree *tree1,
    4421             :                                                  struct smb2_tree *tree2_1)
    4422             : {
    4423           1 :         return _test_dhv2_pending3_vs_hold(tctx, __func__,
    4424             :                                            SMB2_OPLOCK_LEVEL_LEASE,
    4425             :                                            SMB2_OPLOCK_LEVEL_BATCH,
    4426           1 :                                            NT_STATUS_ACCESS_DENIED,
    4427             :                                            tree1, tree2_1);
    4428             : }
    4429             : 
    4430           0 : static bool test_channel_sequence_table(struct torture_context *tctx,
    4431             :                                         struct smb2_tree *tree,
    4432             :                                         bool do_replay,
    4433             :                                         uint16_t opcode)
    4434             : {
    4435           0 :         NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
    4436           0 :         TALLOC_CTX *mem_ctx = talloc_new(tctx);
    4437             :         struct smb2_handle handle;
    4438           0 :         struct smb2_handle *phandle = NULL;
    4439             :         struct smb2_create io;
    4440           0 :         struct GUID create_guid = GUID_random();
    4441           0 :         bool ret = true;
    4442           0 :         const char *fname = BASEDIR "\\channel_sequence.dat";
    4443           0 :         uint16_t csn = 0;
    4444           0 :         uint16_t limit = UINT16_MAX - 0x7fff;
    4445             :         int i;
    4446             :         struct {
    4447             :                 uint16_t csn;
    4448             :                 bool csn_rand_low;
    4449             :                 bool csn_rand_high;
    4450             :                 NTSTATUS expected_status;
    4451           0 :         } tests[] = {
    4452             :                 {
    4453             :                         .csn                    = 0,
    4454             :                         .expected_status        = NT_STATUS_OK,
    4455             :                 },{
    4456             :                         .csn                    = 0x7fff + 1,
    4457             :                         .expected_status        = NT_STATUS_FILE_NOT_AVAILABLE,
    4458             :                 },{
    4459             :                         .csn                    = 0x7fff + 2,
    4460             :                         .expected_status        = NT_STATUS_FILE_NOT_AVAILABLE,
    4461             :                 },{
    4462             :                         .csn                    = -1,
    4463             :                         .csn_rand_high          = true,
    4464             :                         .expected_status        = NT_STATUS_FILE_NOT_AVAILABLE,
    4465             :                 },{
    4466             :                         .csn                    = 0xffff,
    4467             :                         .expected_status        = NT_STATUS_FILE_NOT_AVAILABLE,
    4468             :                 },{
    4469             :                         .csn                    = 0x7fff,
    4470             :                         .expected_status        = NT_STATUS_OK,
    4471             :                 },{
    4472             :                         .csn                    = 0x7ffe,
    4473             :                         .expected_status        = NT_STATUS_FILE_NOT_AVAILABLE,
    4474             :                 },{
    4475             :                         .csn                    = 0,
    4476             :                         .expected_status        = NT_STATUS_FILE_NOT_AVAILABLE,
    4477             :                 },{
    4478             :                         .csn                    = -1,
    4479             :                         .csn_rand_low           = true,
    4480             :                         .expected_status        = NT_STATUS_FILE_NOT_AVAILABLE,
    4481             :                 },{
    4482             :                         .csn                    = 0x7fff + 1,
    4483             :                         .expected_status        = NT_STATUS_OK,
    4484             :                 },{
    4485             :                         .csn                    = 0xffff,
    4486             :                         .expected_status        = NT_STATUS_OK,
    4487             :                 },{
    4488             :                         .csn                    = 0,
    4489             :                         .expected_status        = NT_STATUS_OK,
    4490             :                 },{
    4491             :                         .csn                    = 1,
    4492             :                         .expected_status        = NT_STATUS_OK,
    4493             :                 },{
    4494             :                         .csn                    = 0,
    4495             :                         .expected_status        = NT_STATUS_FILE_NOT_AVAILABLE,
    4496             :                 },{
    4497             :                         .csn                    = 1,
    4498             :                         .expected_status        = NT_STATUS_OK,
    4499             :                 },{
    4500             :                         .csn                    = 0xffff,
    4501             :                         .expected_status        = NT_STATUS_FILE_NOT_AVAILABLE,
    4502             :                 }
    4503             :         };
    4504             : 
    4505           0 :         smb2cli_session_reset_channel_sequence(tree->session->smbXcli, 0);
    4506             : 
    4507           0 :         csn = smb2cli_session_current_channel_sequence(tree->session->smbXcli);
    4508           0 :         torture_comment(tctx, "Testing create with channel sequence number: 0x%04x\n", csn);
    4509             : 
    4510           0 :         smb2_oplock_create_share(&io, fname,
    4511             :                         smb2_util_share_access("RWD"),
    4512           0 :                         smb2_util_oplock_level("b"));
    4513           0 :         io.in.durable_open = false;
    4514           0 :         io.in.durable_open_v2 = true;
    4515           0 :         io.in.create_guid = create_guid;
    4516           0 :         io.in.timeout = UINT32_MAX;
    4517             : 
    4518           0 :         torture_assert_ntstatus_ok_goto(tctx,
    4519             :                 smb2_create(tree, mem_ctx, &io),
    4520             :                 ret, done, "failed to call smb2_create");
    4521             : 
    4522           0 :         handle = io.out.file.handle;
    4523           0 :         phandle = &handle;
    4524             : 
    4525           0 :         for (i=0; i <ARRAY_SIZE(tests); i++) {
    4526             : 
    4527           0 :                 const char *opstr = "";
    4528             :                 union smb_fileinfo qfinfo;
    4529             : 
    4530           0 :                 csn = tests[i].csn;
    4531             : 
    4532           0 :                 if (tests[i].csn_rand_low) {
    4533           0 :                         csn = rand() % limit;
    4534           0 :                 } else if (tests[i].csn_rand_high) {
    4535           0 :                         csn = rand() % limit + 0x7fff;
    4536             :                 }
    4537             : 
    4538           0 :                 switch (opcode) {
    4539           0 :                 case SMB2_OP_WRITE:
    4540           0 :                         opstr = "write";
    4541           0 :                         break;
    4542           0 :                 case SMB2_OP_IOCTL:
    4543           0 :                         opstr = "ioctl";
    4544           0 :                         break;
    4545           0 :                 case SMB2_OP_SETINFO:
    4546           0 :                         opstr = "setinfo";
    4547           0 :                         break;
    4548           0 :                 default:
    4549           0 :                         break;
    4550             :                 }
    4551             : 
    4552           0 :                 smb2cli_session_reset_channel_sequence(tree->session->smbXcli, csn);
    4553           0 :                 csn = smb2cli_session_current_channel_sequence(tree->session->smbXcli);
    4554             : 
    4555           0 :                 torture_comment(tctx, "Testing %s (replay: %s) with CSN 0x%04x, expecting: %s\n",
    4556             :                         opstr, do_replay ? "true" : "false", csn,
    4557             :                         nt_errstr(tests[i].expected_status));
    4558             : 
    4559           0 :                 if (do_replay) {
    4560           0 :                         smb2cli_session_start_replay(tree->session->smbXcli);
    4561             :                 }
    4562             : 
    4563           0 :                 switch (opcode) {
    4564           0 :                 case SMB2_OP_WRITE: {
    4565           0 :                         DATA_BLOB blob = data_blob_talloc(tctx, NULL, 255);
    4566             : 
    4567           0 :                         generate_random_buffer(blob.data, blob.length);
    4568             : 
    4569           0 :                         status = smb2_util_write(tree, handle, blob.data, 0, blob.length);
    4570           0 :                         if (NT_STATUS_IS_OK(status)) {
    4571             :                                 struct smb2_read rd;
    4572             : 
    4573           0 :                                 rd = (struct smb2_read) {
    4574             :                                         .in.file.handle = handle,
    4575           0 :                                         .in.length = blob.length,
    4576             :                                         .in.offset = 0
    4577             :                                 };
    4578             : 
    4579           0 :                                 torture_assert_ntstatus_ok_goto(tctx,
    4580             :                                         smb2_read(tree, tree, &rd),
    4581             :                                         ret, done, "failed to read after write");
    4582             : 
    4583           0 :                                 torture_assert_data_blob_equal(tctx,
    4584             :                                         rd.out.data, blob,
    4585             :                                         "read/write mismatch");
    4586             :                         }
    4587           0 :                         break;
    4588             :                 }
    4589           0 :                 case SMB2_OP_IOCTL: {
    4590             :                         union smb_ioctl ioctl;
    4591           0 :                         ioctl = (union smb_ioctl) {
    4592             :                                 .smb2.level = RAW_IOCTL_SMB2,
    4593             :                                 .smb2.in.file.handle = handle,
    4594             :                                 .smb2.in.function = FSCTL_CREATE_OR_GET_OBJECT_ID,
    4595             :                                 .smb2.in.max_output_response = 64,
    4596             :                                 .smb2.in.flags = SMB2_IOCTL_FLAG_IS_FSCTL
    4597             :                         };
    4598           0 :                         status = smb2_ioctl(tree, mem_ctx, &ioctl.smb2);
    4599           0 :                         break;
    4600             :                 }
    4601           0 :                 case SMB2_OP_SETINFO: {
    4602             :                         union smb_setfileinfo sfinfo;
    4603           0 :                         ZERO_STRUCT(sfinfo);
    4604           0 :                         sfinfo.generic.level = RAW_SFILEINFO_POSITION_INFORMATION;
    4605           0 :                         sfinfo.generic.in.file.handle = handle;
    4606           0 :                         sfinfo.position_information.in.position = 0x1000;
    4607           0 :                         status = smb2_setinfo_file(tree, &sfinfo);
    4608           0 :                         break;
    4609             :                 }
    4610           0 :                 default:
    4611           0 :                         break;
    4612             :                 }
    4613             : 
    4614           0 :                 qfinfo = (union smb_fileinfo) {
    4615             :                         .generic.level = RAW_FILEINFO_POSITION_INFORMATION,
    4616             :                         .generic.in.file.handle = handle
    4617             :                 };
    4618             : 
    4619           0 :                 torture_assert_ntstatus_ok_goto(tctx,
    4620             :                         smb2_getinfo_file(tree, mem_ctx, &qfinfo),
    4621             :                         ret, done, "failed to read after write");
    4622             : 
    4623           0 :                 if (do_replay) {
    4624           0 :                         smb2cli_session_stop_replay(tree->session->smbXcli);
    4625             :                 }
    4626             : 
    4627           0 :                 torture_assert_ntstatus_equal_goto(tctx,
    4628             :                         status, tests[i].expected_status,
    4629             :                         ret, done, "got unexpected failure code");
    4630             : 
    4631             :         }
    4632           0 : done:
    4633           0 :         if (phandle != NULL) {
    4634           0 :                 smb2_util_close(tree, *phandle);
    4635             :         }
    4636             : 
    4637           0 :         smb2_util_unlink(tree, fname);
    4638             : 
    4639           0 :         return ret;
    4640             : }
    4641             : 
    4642           1 : static bool test_channel_sequence(struct torture_context *tctx,
    4643             :                                   struct smb2_tree *tree)
    4644             : {
    4645           1 :         TALLOC_CTX *mem_ctx = talloc_new(tctx);
    4646           1 :         bool ret = true;
    4647           1 :         const char *fname = BASEDIR "\\channel_sequence.dat";
    4648           1 :         struct smb2_transport *transport1 = tree->session->transport;
    4649             :         struct smb2_handle handle;
    4650           1 :         uint16_t opcodes[] = { SMB2_OP_WRITE, SMB2_OP_IOCTL, SMB2_OP_SETINFO };
    4651             :         int i;
    4652             : 
    4653           1 :         if (smbXcli_conn_protocol(transport1->conn) < PROTOCOL_SMB3_00) {
    4654           1 :                 torture_skip(tctx, "SMB 3.X Dialect family required for "
    4655             :                                    "Replay tests\n");
    4656             :         }
    4657             : 
    4658           0 :         torture_comment(tctx, "Testing channel sequence numbers\n");
    4659             : 
    4660           0 :         smbXcli_conn_set_force_channel_sequence(transport1->conn, true);
    4661             : 
    4662           0 :         torture_assert_ntstatus_ok_goto(tctx,
    4663             :                 torture_smb2_testdir(tree, BASEDIR, &handle),
    4664             :                 ret, done, "failed to setup test directory");
    4665             : 
    4666           0 :         smb2_util_close(tree, handle);
    4667           0 :         smb2_util_unlink(tree, fname);
    4668             : 
    4669           0 :         for (i=0; i <ARRAY_SIZE(opcodes); i++) {
    4670           0 :                 torture_assert(tctx,
    4671             :                         test_channel_sequence_table(tctx, tree, false, opcodes[i]),
    4672             :                         "failed to test CSN without replay flag");
    4673           0 :                 torture_assert(tctx,
    4674             :                         test_channel_sequence_table(tctx, tree, true, opcodes[i]),
    4675             :                         "failed to test CSN with replay flag");
    4676             :         }
    4677             : 
    4678           0 : done:
    4679             : 
    4680           0 :         smb2_util_unlink(tree, fname);
    4681           0 :         smb2_deltree(tree, BASEDIR);
    4682             : 
    4683           0 :         talloc_free(tree);
    4684           0 :         talloc_free(mem_ctx);
    4685             : 
    4686           0 :         return ret;
    4687             : }
    4688             : 
    4689             : /**
    4690             :  * Test Durability V2 Create Replay Detection on Multi Channel
    4691             :  */
    4692           1 : static bool test_replay3(struct torture_context *tctx, struct smb2_tree *tree1)
    4693             : {
    4694           1 :         const char *host = torture_setting_string(tctx, "host", NULL);
    4695           1 :         const char *share = torture_setting_string(tctx, "share", NULL);
    4696             :         NTSTATUS status;
    4697           1 :         TALLOC_CTX *mem_ctx = talloc_new(tctx);
    4698             :         struct smb2_handle _h;
    4699           1 :         struct smb2_handle *h = NULL;
    4700             :         struct smb2_create io;
    4701           1 :         struct GUID create_guid = GUID_random();
    4702           1 :         bool ret = true;
    4703           1 :         const char *fname = BASEDIR "\\replay3.dat";
    4704           1 :         struct smb2_tree *tree2 = NULL;
    4705           1 :         struct smb2_transport *transport1 = tree1->session->transport;
    4706           1 :         struct smb2_transport *transport2 = NULL;
    4707           1 :         struct smb2_session *session1_1 = tree1->session;
    4708           1 :         struct smb2_session *session1_2 = NULL;
    4709             :         uint32_t share_capabilities;
    4710             :         bool share_is_so;
    4711             :         uint32_t server_capabilities;
    4712             : 
    4713           1 :         if (smbXcli_conn_protocol(transport1->conn) < PROTOCOL_SMB3_00) {
    4714           1 :                 torture_skip(tctx, "SMB 3.X Dialect family required for "
    4715             :                                    "Replay tests\n");
    4716             :         }
    4717             : 
    4718           0 :         server_capabilities = smb2cli_conn_server_capabilities(
    4719           0 :                                         tree1->session->transport->conn);
    4720           0 :         if (!(server_capabilities & SMB2_CAP_MULTI_CHANNEL)) {
    4721           0 :                 torture_skip(tctx,
    4722             :                              "Server does not support multi-channel.");
    4723             :         }
    4724             : 
    4725           0 :         share_capabilities = smb2cli_tcon_capabilities(tree1->smbXcli);
    4726           0 :         share_is_so = share_capabilities & SMB2_SHARE_CAP_SCALEOUT;
    4727             : 
    4728           0 :         torture_reset_break_info(tctx, &break_info);
    4729           0 :         transport1->oplock.handler = torture_oplock_ack_handler;
    4730           0 :         transport1->oplock.private_data = tree1;
    4731             : 
    4732           0 :         torture_comment(tctx, "Replay of DurableHandleReqV2 on Multi "
    4733             :                               "Channel\n");
    4734           0 :         status = torture_smb2_testdir(tree1, BASEDIR, &_h);
    4735           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    4736           0 :         smb2_util_close(tree1, _h);
    4737           0 :         smb2_util_unlink(tree1, fname);
    4738           0 :         CHECK_VAL(break_info.count, 0);
    4739             : 
    4740             :         /*
    4741             :          * use the 1st channel, 1st session
    4742             :          */
    4743           0 :         smb2_oplock_create_share(&io, fname,
    4744             :                         smb2_util_share_access(""),
    4745           0 :                         smb2_util_oplock_level("b"));
    4746           0 :         io.in.durable_open = false;
    4747           0 :         io.in.durable_open_v2 = true;
    4748           0 :         io.in.persistent_open = false;
    4749           0 :         io.in.create_guid = create_guid;
    4750           0 :         io.in.timeout = UINT32_MAX;
    4751             : 
    4752           0 :         tree1->session = session1_1;
    4753           0 :         status = smb2_create(tree1, mem_ctx, &io);
    4754           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    4755           0 :         _h = io.out.file.handle;
    4756           0 :         h = &_h;
    4757           0 :         CHECK_CREATED(&io, CREATED, FILE_ATTRIBUTE_ARCHIVE);
    4758           0 :         if (share_is_so) {
    4759           0 :                 CHECK_VAL(io.out.oplock_level, smb2_util_oplock_level("s"));
    4760           0 :                 CHECK_VAL(io.out.durable_open_v2, false);
    4761           0 :                 CHECK_VAL(io.out.timeout, 0);
    4762             :         } else {
    4763           0 :                 CHECK_VAL(io.out.oplock_level, smb2_util_oplock_level("b"));
    4764           0 :                 CHECK_VAL(io.out.durable_open_v2, true);
    4765           0 :                 CHECK_VAL(io.out.timeout, 300*1000);
    4766             :         }
    4767           0 :         CHECK_VAL(io.out.durable_open, false);
    4768           0 :         CHECK_VAL(break_info.count, 0);
    4769             : 
    4770           0 :         status = smb2_connect(tctx,
    4771             :                         host,
    4772             :                         lpcfg_smb_ports(tctx->lp_ctx),
    4773             :                         share,
    4774             :                         lpcfg_resolve_context(tctx->lp_ctx),
    4775             :                         samba_cmdline_get_creds(),
    4776             :                         &tree2,
    4777             :                         tctx->ev,
    4778           0 :                         &transport1->options,
    4779             :                         lpcfg_socket_options(tctx->lp_ctx),
    4780             :                         lpcfg_gensec_settings(tctx, tctx->lp_ctx)
    4781             :                         );
    4782           0 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    4783             :                         "smb2_connect failed");
    4784           0 :         transport2 = tree2->session->transport;
    4785             : 
    4786           0 :         transport2->oplock.handler = torture_oplock_ack_handler;
    4787           0 :         transport2->oplock.private_data = tree2;
    4788             : 
    4789             :         /*
    4790             :          * Now bind the 1st session to 2nd transport channel
    4791             :          */
    4792           0 :         session1_2 = smb2_session_channel(transport2,
    4793             :                         lpcfg_gensec_settings(tctx, tctx->lp_ctx),
    4794             :                         tree2, session1_1);
    4795           0 :         torture_assert(tctx, session1_2 != NULL, "smb2_session_channel failed");
    4796             : 
    4797           0 :         status = smb2_session_setup_spnego(session1_2,
    4798             :                         samba_cmdline_get_creds(),
    4799             :                         0 /* previous_session_id */);
    4800           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    4801             : 
    4802             :         /*
    4803             :          * use the 2nd channel, 1st session
    4804             :          */
    4805           0 :         tree1->session = session1_2;
    4806           0 :         smb2cli_session_start_replay(tree1->session->smbXcli);
    4807           0 :         status = smb2_create(tree1, mem_ctx, &io);
    4808           0 :         smb2cli_session_stop_replay(tree1->session->smbXcli);
    4809           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    4810           0 :         _h = io.out.file.handle;
    4811           0 :         h = &_h;
    4812           0 :         CHECK_CREATED(&io, CREATED, FILE_ATTRIBUTE_ARCHIVE);
    4813           0 :         if (share_is_so) {
    4814           0 :                 CHECK_VAL(io.out.oplock_level, smb2_util_oplock_level("s"));
    4815           0 :                 CHECK_VAL(io.out.durable_open_v2, false);
    4816           0 :                 CHECK_VAL(io.out.timeout, 0);
    4817             :         } else {
    4818           0 :                 CHECK_VAL(io.out.oplock_level, smb2_util_oplock_level("b"));
    4819           0 :                 CHECK_VAL(io.out.durable_open_v2, true);
    4820           0 :                 CHECK_VAL(io.out.timeout, 300*1000);
    4821             :         }
    4822           0 :         CHECK_VAL(io.out.durable_open, false);
    4823           0 :         CHECK_VAL(break_info.count, 0);
    4824             : 
    4825           0 :         tree1->session = session1_1;
    4826           0 :         smb2_util_close(tree1, *h);
    4827           0 :         h = NULL;
    4828             : 
    4829           0 : done:
    4830           0 :         talloc_free(tree2);
    4831           0 :         tree1->session = session1_1;
    4832             : 
    4833           0 :         if (h != NULL) {
    4834           0 :                 smb2_util_close(tree1, *h);
    4835             :         }
    4836             : 
    4837           0 :         smb2_util_unlink(tree1, fname);
    4838           0 :         smb2_deltree(tree1, BASEDIR);
    4839             : 
    4840           0 :         talloc_free(tree1);
    4841           0 :         talloc_free(mem_ctx);
    4842             : 
    4843           0 :         return ret;
    4844             : }
    4845             : 
    4846             : /**
    4847             :  * Test Multichannel IO Ordering using ChannelSequence/Channel Epoch number
    4848             :  */
    4849           1 : static bool test_replay4(struct torture_context *tctx, struct smb2_tree *tree1)
    4850             : {
    4851           1 :         const char *host = torture_setting_string(tctx, "host", NULL);
    4852           1 :         const char *share = torture_setting_string(tctx, "share", NULL);
    4853             :         NTSTATUS status;
    4854           1 :         TALLOC_CTX *mem_ctx = talloc_new(tctx);
    4855             :         struct smb2_handle _h1;
    4856           1 :         struct smb2_handle *h1 = NULL;
    4857             :         struct smb2_create io;
    4858           1 :         struct GUID create_guid = GUID_random();
    4859             :         uint8_t buf[64];
    4860             :         struct smb2_read rd;
    4861             :         union smb_setfileinfo sfinfo;
    4862           1 :         bool ret = true;
    4863           1 :         const char *fname = BASEDIR "\\replay4.dat";
    4864           1 :         struct smb2_tree *tree2 = NULL;
    4865           1 :         struct smb2_transport *transport1 = tree1->session->transport;
    4866           1 :         struct smb2_transport *transport2 = NULL;
    4867           1 :         struct smb2_session *session1_1 = tree1->session;
    4868           1 :         struct smb2_session *session1_2 = NULL;
    4869             :         uint16_t curr_cs;
    4870             :         uint32_t share_capabilities;
    4871             :         bool share_is_so;
    4872             :         uint32_t server_capabilities;
    4873             : 
    4874           1 :         if (smbXcli_conn_protocol(transport1->conn) < PROTOCOL_SMB3_00) {
    4875           1 :                 torture_skip(tctx, "SMB 3.X Dialect family required for "
    4876             :                                    "Replay tests\n");
    4877             :         }
    4878             : 
    4879           0 :         server_capabilities = smb2cli_conn_server_capabilities(
    4880           0 :                                         tree1->session->transport->conn);
    4881           0 :         if (!(server_capabilities & SMB2_CAP_MULTI_CHANNEL)) {
    4882           0 :                 torture_skip(tctx,
    4883             :                              "Server does not support multi-channel.");
    4884             :         }
    4885             : 
    4886           0 :         share_capabilities = smb2cli_tcon_capabilities(tree1->smbXcli);
    4887           0 :         share_is_so = share_capabilities & SMB2_SHARE_CAP_SCALEOUT;
    4888             : 
    4889           0 :         torture_reset_break_info(tctx, &break_info);
    4890           0 :         transport1->oplock.handler = torture_oplock_ack_handler;
    4891           0 :         transport1->oplock.private_data = tree1;
    4892             : 
    4893           0 :         torture_comment(tctx, "IO Ordering for Multi Channel\n");
    4894           0 :         status = torture_smb2_testdir(tree1, BASEDIR, &_h1);
    4895           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    4896           0 :         smb2_util_close(tree1, _h1);
    4897           0 :         smb2_util_unlink(tree1, fname);
    4898           0 :         CHECK_VAL(break_info.count, 0);
    4899             : 
    4900             :         /*
    4901             :          * use the 1st channel, 1st session
    4902             :          */
    4903             : 
    4904           0 :         smb2_oplock_create_share(&io, fname,
    4905             :                         smb2_util_share_access(""),
    4906           0 :                         smb2_util_oplock_level("b"));
    4907           0 :         io.in.durable_open = false;
    4908           0 :         io.in.durable_open_v2 = true;
    4909           0 :         io.in.persistent_open = false;
    4910           0 :         io.in.create_guid = create_guid;
    4911           0 :         io.in.timeout = UINT32_MAX;
    4912             : 
    4913           0 :         tree1->session = session1_1;
    4914           0 :         status = smb2_create(tree1, mem_ctx, &io);
    4915           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    4916           0 :         _h1 = io.out.file.handle;
    4917           0 :         h1 = &_h1;
    4918           0 :         CHECK_CREATED(&io, CREATED, FILE_ATTRIBUTE_ARCHIVE);
    4919           0 :         if (share_is_so) {
    4920           0 :                 CHECK_VAL(io.out.oplock_level, smb2_util_oplock_level("s"));
    4921           0 :                 CHECK_VAL(io.out.durable_open_v2, false);
    4922           0 :                 CHECK_VAL(io.out.timeout, 0);
    4923             :         } else {
    4924           0 :                 CHECK_VAL(io.out.oplock_level, smb2_util_oplock_level("b"));
    4925           0 :                 CHECK_VAL(io.out.durable_open_v2, true);
    4926           0 :                 CHECK_VAL(io.out.timeout, 300*1000);
    4927             :         }
    4928           0 :         CHECK_VAL(io.out.durable_open, false);
    4929           0 :         CHECK_VAL(break_info.count, 0);
    4930             : 
    4931           0 :         status = smb2_util_write(tree1, *h1, buf, 0, ARRAY_SIZE(buf));
    4932           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    4933             : 
    4934             :         /*
    4935             :          * Increment ChannelSequence so that server thinks that there's a
    4936             :          * Channel Failure
    4937             :          */
    4938           0 :         smb2cli_session_increment_channel_sequence(tree1->session->smbXcli);
    4939             : 
    4940             :         /*
    4941             :          * Perform a Read with incremented ChannelSequence
    4942             :          */
    4943           0 :         rd = (struct smb2_read) {
    4944           0 :                 .in.file.handle = *h1,
    4945             :                 .in.length = sizeof(buf),
    4946             :                 .in.offset = 0
    4947             :         };
    4948           0 :         status = smb2_read(tree1, tree1, &rd);
    4949           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    4950             : 
    4951             :         /*
    4952             :          * Performing a Write with Stale ChannelSequence is not allowed by
    4953             :          * server
    4954             :          */
    4955           0 :         curr_cs = smb2cli_session_reset_channel_sequence(
    4956           0 :                                                 tree1->session->smbXcli, 0);
    4957           0 :         status = smb2_util_write(tree1, *h1, buf, 0, ARRAY_SIZE(buf));
    4958           0 :         CHECK_STATUS(status, NT_STATUS_FILE_NOT_AVAILABLE);
    4959             : 
    4960             :         /*
    4961             :          * Performing a Write Replay with Stale ChannelSequence is not allowed
    4962             :          * by server
    4963             :          */
    4964           0 :         smb2cli_session_start_replay(tree1->session->smbXcli);
    4965           0 :         smb2cli_session_reset_channel_sequence(tree1->session->smbXcli, 0);
    4966           0 :         status = smb2_util_write(tree1, *h1, buf, 0, ARRAY_SIZE(buf));
    4967           0 :         smb2cli_session_stop_replay(tree1->session->smbXcli);
    4968           0 :         CHECK_STATUS(status, NT_STATUS_FILE_NOT_AVAILABLE);
    4969             : 
    4970             :         /*
    4971             :          * Performing a SetInfo with stale ChannelSequence is not allowed by
    4972             :          * server
    4973             :          */
    4974           0 :         ZERO_STRUCT(sfinfo);
    4975           0 :         sfinfo.generic.level = RAW_SFILEINFO_POSITION_INFORMATION;
    4976           0 :         sfinfo.generic.in.file.handle = *h1;
    4977           0 :         sfinfo.position_information.in.position = 0x1000;
    4978           0 :         status = smb2_setinfo_file(tree1, &sfinfo);
    4979           0 :         CHECK_STATUS(status, NT_STATUS_FILE_NOT_AVAILABLE);
    4980             : 
    4981             :         /*
    4982             :          * Performing a Read with stale ChannelSequence is allowed
    4983             :          */
    4984           0 :         rd = (struct smb2_read) {
    4985           0 :                 .in.file.handle = *h1,
    4986             :                 .in.length = ARRAY_SIZE(buf),
    4987             :                 .in.offset = 0
    4988             :         };
    4989           0 :         status = smb2_read(tree1, tree1, &rd);
    4990           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    4991             : 
    4992           0 :         status = smb2_connect(tctx,
    4993             :                         host,
    4994             :                         lpcfg_smb_ports(tctx->lp_ctx),
    4995             :                         share,
    4996             :                         lpcfg_resolve_context(tctx->lp_ctx),
    4997             :                         samba_cmdline_get_creds(),
    4998             :                         &tree2,
    4999             :                         tctx->ev,
    5000           0 :                         &transport1->options,
    5001             :                         lpcfg_socket_options(tctx->lp_ctx),
    5002             :                         lpcfg_gensec_settings(tctx, tctx->lp_ctx)
    5003             :                         );
    5004           0 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    5005             :                         "smb2_connect failed");
    5006           0 :         transport2 = tree2->session->transport;
    5007             : 
    5008           0 :         transport2->oplock.handler = torture_oplock_ack_handler;
    5009           0 :         transport2->oplock.private_data = tree2;
    5010             : 
    5011             :         /*
    5012             :          * Now bind the 1st session to 2nd transport channel
    5013             :          */
    5014           0 :         session1_2 = smb2_session_channel(transport2,
    5015             :                         lpcfg_gensec_settings(tctx, tctx->lp_ctx),
    5016             :                         tree2, session1_1);
    5017           0 :         torture_assert(tctx, session1_2 != NULL, "smb2_session_channel failed");
    5018             : 
    5019           0 :         status = smb2_session_setup_spnego(session1_2,
    5020             :                         samba_cmdline_get_creds(),
    5021             :                         0 /* previous_session_id */);
    5022           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    5023             : 
    5024             :         /*
    5025             :          * use the 2nd channel, 1st session
    5026             :          */
    5027           0 :         tree1->session = session1_2;
    5028             : 
    5029             :         /*
    5030             :          * Write Replay with Correct ChannelSequence is allowed by the server
    5031             :          */
    5032           0 :         smb2cli_session_start_replay(tree1->session->smbXcli);
    5033           0 :         smb2cli_session_reset_channel_sequence(tree1->session->smbXcli,
    5034             :                                                curr_cs);
    5035           0 :         status = smb2_util_write(tree1, *h1, buf, 0, ARRAY_SIZE(buf));
    5036           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    5037           0 :         smb2cli_session_stop_replay(tree1->session->smbXcli);
    5038             : 
    5039             :         /*
    5040             :          * See what happens if we change the Buffer and perform a Write Replay.
    5041             :          * This is to show that Write Replay does not really care about the data
    5042             :          */
    5043           0 :         memset(buf, 'r', ARRAY_SIZE(buf));
    5044           0 :         smb2cli_session_start_replay(tree1->session->smbXcli);
    5045           0 :         status = smb2_util_write(tree1, *h1, buf, 0, ARRAY_SIZE(buf));
    5046           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    5047           0 :         smb2cli_session_stop_replay(tree1->session->smbXcli);
    5048             : 
    5049             :         /*
    5050             :          * Read back from File to verify what was written
    5051             :          */
    5052           0 :         rd = (struct smb2_read) {
    5053           0 :                 .in.file.handle = *h1,
    5054             :                 .in.length = ARRAY_SIZE(buf),
    5055             :                 .in.offset = 0
    5056             :         };
    5057           0 :         status = smb2_read(tree1, tree1, &rd);
    5058           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    5059             : 
    5060           0 :         if ((rd.out.data.length != ARRAY_SIZE(buf)) ||
    5061           0 :                         memcmp(rd.out.data.data, buf, ARRAY_SIZE(buf))) {
    5062           0 :                 torture_comment(tctx, "Write Replay Data Mismatch\n");
    5063             :         }
    5064             : 
    5065           0 :         tree1->session = session1_1;
    5066           0 :         smb2_util_close(tree1, *h1);
    5067           0 :         h1 = NULL;
    5068             : 
    5069           0 :         if (share_is_so) {
    5070           0 :                 CHECK_VAL(break_info.count, 1);
    5071             :         } else {
    5072           0 :                 CHECK_VAL(break_info.count, 0);
    5073             :         }
    5074           0 : done:
    5075           0 :         talloc_free(tree2);
    5076           0 :         tree1->session = session1_1;
    5077             : 
    5078           0 :         if (h1 != NULL) {
    5079           0 :                 smb2_util_close(tree1, *h1);
    5080             :         }
    5081             : 
    5082           0 :         smb2_util_unlink(tree1, fname);
    5083           0 :         smb2_deltree(tree1, BASEDIR);
    5084             : 
    5085           0 :         talloc_free(tree1);
    5086           0 :         talloc_free(mem_ctx);
    5087             : 
    5088           0 :         return ret;
    5089             : }
    5090             : 
    5091             : /**
    5092             :  * Test Durability V2 Persistent Create Replay on a Single Channel
    5093             :  */
    5094           1 : static bool test_replay5(struct torture_context *tctx, struct smb2_tree *tree)
    5095             : {
    5096             :         NTSTATUS status;
    5097           1 :         TALLOC_CTX *mem_ctx = talloc_new(tctx);
    5098             :         struct smb2_handle _h;
    5099           1 :         struct smb2_handle *h = NULL;
    5100             :         struct smb2_create io;
    5101           1 :         struct GUID create_guid = GUID_random();
    5102           1 :         bool ret = true;
    5103             :         uint32_t share_capabilities;
    5104             :         bool share_is_ca;
    5105             :         bool share_is_so;
    5106             :         uint32_t server_capabilities;
    5107           1 :         const char *fname = BASEDIR "\\replay5.dat";
    5108           1 :         struct smb2_transport *transport = tree->session->transport;
    5109           1 :         struct smbcli_options options = tree->session->transport->options;
    5110           1 :         uint8_t expect_oplock = smb2_util_oplock_level("b");
    5111           1 :         NTSTATUS expect_status = NT_STATUS_DUPLICATE_OBJECTID;
    5112             : 
    5113           1 :         if (smbXcli_conn_protocol(transport->conn) < PROTOCOL_SMB3_00) {
    5114           1 :                 torture_skip(tctx, "SMB 3.X Dialect family required for "
    5115             :                                 "Replay tests\n");
    5116             :         }
    5117             : 
    5118           0 :         server_capabilities = smb2cli_conn_server_capabilities(
    5119           0 :                                         tree->session->transport->conn);
    5120           0 :         if (!(server_capabilities & SMB2_CAP_PERSISTENT_HANDLES)) {
    5121           0 :                 torture_skip(tctx,
    5122             :                              "Server does not support persistent handles.");
    5123             :         }
    5124             : 
    5125           0 :         share_capabilities = smb2cli_tcon_capabilities(tree->smbXcli);
    5126             : 
    5127           0 :         share_is_ca = share_capabilities & SMB2_SHARE_CAP_CONTINUOUS_AVAILABILITY;
    5128           0 :         if (!share_is_ca) {
    5129           0 :                 torture_skip(tctx, "Share is not continuously available.");
    5130             :         }
    5131             : 
    5132           0 :         share_is_so = share_capabilities & SMB2_SHARE_CAP_SCALEOUT;
    5133           0 :         if (share_is_so) {
    5134           0 :                 expect_oplock = smb2_util_oplock_level("s");
    5135           0 :                 expect_status = NT_STATUS_FILE_NOT_AVAILABLE;
    5136             :         }
    5137             : 
    5138           0 :         torture_reset_break_info(tctx, &break_info);
    5139           0 :         transport->oplock.handler = torture_oplock_ack_handler;
    5140           0 :         transport->oplock.private_data = tree;
    5141             : 
    5142           0 :         torture_comment(tctx, "Replay of Persistent DurableHandleReqV2 on Single "
    5143             :                         "Channel\n");
    5144           0 :         status = torture_smb2_testdir(tree, BASEDIR, &_h);
    5145           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    5146           0 :         smb2_util_close(tree, _h);
    5147           0 :         smb2_util_unlink(tree, fname);
    5148           0 :         CHECK_VAL(break_info.count, 0);
    5149             : 
    5150           0 :         smb2_oplock_create_share(&io, fname,
    5151             :                         smb2_util_share_access("RWD"),
    5152           0 :                         smb2_util_oplock_level("b"));
    5153           0 :         io.in.durable_open = false;
    5154           0 :         io.in.durable_open_v2 = true;
    5155           0 :         io.in.persistent_open = true;
    5156           0 :         io.in.create_guid = create_guid;
    5157           0 :         io.in.timeout = UINT32_MAX;
    5158             : 
    5159           0 :         status = smb2_create(tree, mem_ctx, &io);
    5160           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    5161           0 :         _h = io.out.file.handle;
    5162           0 :         h = &_h;
    5163           0 :         CHECK_CREATED(&io, CREATED, FILE_ATTRIBUTE_ARCHIVE);
    5164           0 :         CHECK_VAL(io.out.oplock_level, expect_oplock);
    5165           0 :         CHECK_VAL(io.out.durable_open, false);
    5166           0 :         CHECK_VAL(io.out.durable_open_v2, true);
    5167           0 :         CHECK_VAL(io.out.persistent_open, true);
    5168           0 :         CHECK_VAL(io.out.timeout, 300*1000);
    5169           0 :         CHECK_VAL(break_info.count, 0);
    5170             : 
    5171             :         /* disconnect, leaving the durable open */
    5172           0 :         TALLOC_FREE(tree);
    5173             : 
    5174           0 :         if (!torture_smb2_connection_ext(tctx, 0, &options, &tree)) {
    5175           0 :                 torture_warning(tctx, "couldn't reconnect, bailing\n");
    5176           0 :                 ret = false;
    5177           0 :                 goto done;
    5178             :         }
    5179             : 
    5180             :         /* a re-open of a persistent handle causes an error */
    5181           0 :         status = smb2_create(tree, mem_ctx, &io);
    5182           0 :         CHECK_STATUS(status, expect_status);
    5183             : 
    5184             :         /* SMB2_FLAGS_REPLAY_OPERATION must be set to open the Persistent Handle */
    5185           0 :         smb2cli_session_start_replay(tree->session->smbXcli);
    5186           0 :         smb2cli_session_increment_channel_sequence(tree->session->smbXcli);
    5187           0 :         status = smb2_create(tree, mem_ctx, &io);
    5188           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    5189           0 :         CHECK_CREATED(&io, CREATED, FILE_ATTRIBUTE_ARCHIVE);
    5190           0 :         CHECK_VAL(io.out.durable_open, false);
    5191           0 :         CHECK_VAL(io.out.persistent_open, true);
    5192           0 :         CHECK_VAL(io.out.oplock_level, expect_oplock);
    5193           0 :         _h = io.out.file.handle;
    5194           0 :         h = &_h;
    5195             : 
    5196           0 :         smb2_util_close(tree, *h);
    5197           0 :         h = NULL;
    5198           0 : done:
    5199           0 :         if (h != NULL) {
    5200           0 :                 smb2_util_close(tree, *h);
    5201             :         }
    5202             : 
    5203           0 :         smb2_util_unlink(tree, fname);
    5204           0 :         smb2_deltree(tree, BASEDIR);
    5205             : 
    5206           0 :         talloc_free(tree);
    5207           0 :         talloc_free(mem_ctx);
    5208             : 
    5209           0 :         return ret;
    5210             : }
    5211             : 
    5212             : 
    5213             : /**
    5214             :  * Test Error Codes when a DurableHandleReqV2 with matching CreateGuid is
    5215             :  * re-sent with or without SMB2_FLAGS_REPLAY_OPERATION
    5216             :  */
    5217           1 : static bool test_replay6(struct torture_context *tctx, struct smb2_tree *tree)
    5218             : {
    5219             :         NTSTATUS status;
    5220           1 :         TALLOC_CTX *mem_ctx = talloc_new(tctx);
    5221             :         struct smb2_handle _h;
    5222           1 :         struct smb2_handle *h = NULL;
    5223             :         struct smb2_create io, ref1;
    5224             :         union smb_fileinfo qfinfo;
    5225           1 :         struct GUID create_guid = GUID_random();
    5226           1 :         bool ret = true;
    5227           1 :         const char *fname = BASEDIR "\\replay6.dat";
    5228           1 :         struct smb2_transport *transport = tree->session->transport;
    5229             : 
    5230           1 :         if (smbXcli_conn_protocol(transport->conn) < PROTOCOL_SMB3_00) {
    5231           1 :                 torture_skip(tctx, "SMB 3.X Dialect family required for "
    5232             :                                    "replay tests\n");
    5233             :         }
    5234             : 
    5235           0 :         torture_reset_break_info(tctx, &break_info);
    5236           0 :         tree->session->transport->oplock.handler = torture_oplock_ack_handler;
    5237           0 :         tree->session->transport->oplock.private_data = tree;
    5238             : 
    5239           0 :         torture_comment(tctx, "Error Codes for DurableHandleReqV2 Replay\n");
    5240           0 :         smb2_util_unlink(tree, fname);
    5241           0 :         status = torture_smb2_testdir(tree, BASEDIR, &_h);
    5242           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    5243           0 :         smb2_util_close(tree, _h);
    5244           0 :         torture_wait_for_oplock_break(tctx);
    5245           0 :         CHECK_VAL(break_info.count, 0);
    5246           0 :         torture_reset_break_info(tctx, &break_info);
    5247             : 
    5248           0 :         smb2_oplock_create_share(&io, fname,
    5249             :                         smb2_util_share_access("RWD"),
    5250           0 :                         smb2_util_oplock_level("b"));
    5251           0 :         io.in.durable_open = false;
    5252           0 :         io.in.durable_open_v2 = true;
    5253           0 :         io.in.persistent_open = false;
    5254           0 :         io.in.create_guid = create_guid;
    5255           0 :         io.in.timeout = UINT32_MAX;
    5256             : 
    5257           0 :         status = smb2_create(tree, mem_ctx, &io);
    5258           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    5259           0 :         ref1 = io;
    5260           0 :         _h = io.out.file.handle;
    5261           0 :         h = &_h;
    5262           0 :         CHECK_CREATED(&io, CREATED, FILE_ATTRIBUTE_ARCHIVE);
    5263           0 :         CHECK_VAL(io.out.oplock_level, smb2_util_oplock_level("b"));
    5264           0 :         CHECK_VAL(io.out.durable_open, false);
    5265           0 :         CHECK_VAL(io.out.durable_open_v2, true);
    5266             : 
    5267           0 :         io.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
    5268           0 :         io.in.create_disposition = NTCREATEX_DISP_OPEN;
    5269           0 :         smb2cli_session_start_replay(tree->session->smbXcli);
    5270           0 :         status = smb2_create(tree, mem_ctx, &io);
    5271           0 :         smb2cli_session_stop_replay(tree->session->smbXcli);
    5272           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    5273           0 :         CHECK_CREATE_OUT(&io, &ref1);
    5274           0 :         torture_wait_for_oplock_break(tctx);
    5275           0 :         CHECK_VAL(break_info.count, 0);
    5276           0 :         torture_reset_break_info(tctx, &break_info);
    5277             : 
    5278           0 :         qfinfo = (union smb_fileinfo) {
    5279             :                 .generic.level = RAW_FILEINFO_POSITION_INFORMATION,
    5280           0 :                 .generic.in.file.handle = *h
    5281             :         };
    5282           0 :         torture_comment(tctx, "Trying getinfo\n");
    5283           0 :         status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
    5284           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    5285           0 :         CHECK_VAL(qfinfo.position_information.out.position, 0);
    5286             : 
    5287           0 :         smb2cli_session_start_replay(tree->session->smbXcli);
    5288           0 :         status = smb2_create(tree, mem_ctx, &io);
    5289           0 :         smb2cli_session_stop_replay(tree->session->smbXcli);
    5290           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    5291           0 :         torture_assert_u64_not_equal_goto(tctx,
    5292             :                 io.out.file.handle.data[0],
    5293             :                 ref1.out.file.handle.data[0],
    5294             :                 ret, done, "data 0");
    5295           0 :         torture_assert_u64_not_equal_goto(tctx,
    5296             :                 io.out.file.handle.data[1],
    5297             :                 ref1.out.file.handle.data[1],
    5298             :                 ret, done, "data 1");
    5299           0 :         torture_wait_for_oplock_break(tctx);
    5300           0 :         CHECK_VAL(break_info.count, 1);
    5301           0 :         CHECK_VAL(break_info.level, smb2_util_oplock_level("s"));
    5302           0 :         torture_reset_break_info(tctx, &break_info);
    5303             : 
    5304             :         /*
    5305             :          * Resend the matching Durable V2 Create without
    5306             :          * SMB2_FLAGS_REPLAY_OPERATION. This triggers an oplock break and still
    5307             :          * gets NT_STATUS_DUPLICATE_OBJECTID
    5308             :          */
    5309           0 :         status = smb2_create(tree, mem_ctx, &io);
    5310           0 :         CHECK_STATUS(status, NT_STATUS_DUPLICATE_OBJECTID);
    5311           0 :         torture_wait_for_oplock_break(tctx);
    5312           0 :         CHECK_VAL(break_info.count, 0);
    5313           0 :         torture_reset_break_info(tctx, &break_info);
    5314             : 
    5315             :         /*
    5316             :          * According to MS-SMB2 3.3.5.9.10 if Durable V2 Create is replayed and
    5317             :          * FileAttributes or CreateDisposition do not match the earlier Create
    5318             :          * request the Server fails request with
    5319             :          * NT_STATUS_INVALID_PARAMETER. But through this test we see that server
    5320             :          * does not really care about changed FileAttributes or
    5321             :          * CreateDisposition.
    5322             :          */
    5323           0 :         io.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
    5324           0 :         io.in.create_disposition = NTCREATEX_DISP_OPEN;
    5325           0 :         smb2cli_session_start_replay(tree->session->smbXcli);
    5326           0 :         status = smb2_create(tree, mem_ctx, &io);
    5327           0 :         smb2cli_session_stop_replay(tree->session->smbXcli);
    5328           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    5329           0 :         torture_assert_u64_not_equal_goto(tctx,
    5330             :                 io.out.file.handle.data[0],
    5331             :                 ref1.out.file.handle.data[0],
    5332             :                 ret, done, "data 0");
    5333           0 :         torture_assert_u64_not_equal_goto(tctx,
    5334             :                 io.out.file.handle.data[1],
    5335             :                 ref1.out.file.handle.data[1],
    5336             :                 ret, done, "data 1");
    5337           0 :         torture_wait_for_oplock_break(tctx);
    5338           0 :         CHECK_VAL(break_info.count, 0);
    5339             : 
    5340           0 : done:
    5341           0 :         if (h != NULL) {
    5342           0 :                 smb2_util_close(tree, *h);
    5343             :         }
    5344             : 
    5345           0 :         smb2_util_unlink(tree, fname);
    5346           0 :         smb2_deltree(tree, BASEDIR);
    5347             : 
    5348           0 :         talloc_free(tree);
    5349           0 :         talloc_free(mem_ctx);
    5350             : 
    5351           0 :         return ret;
    5352             : }
    5353             : 
    5354           1 : static bool test_replay7(struct torture_context *tctx, struct smb2_tree *tree)
    5355             : {
    5356           1 :         TALLOC_CTX *mem_ctx = talloc_new(tctx);
    5357           1 :         struct smb2_transport *transport = tree->session->transport;
    5358             :         NTSTATUS status;
    5359             :         struct smb2_handle _dh;
    5360           1 :         struct smb2_handle *dh = NULL;
    5361             :         struct smb2_notify notify;
    5362             :         struct smb2_request *req;
    5363             :         union smb_fileinfo qfinfo;
    5364           1 :         bool ret = false;
    5365             : 
    5366           1 :         if (smbXcli_conn_protocol(transport->conn) < PROTOCOL_SMB3_00) {
    5367           1 :                 torture_skip(tctx, "SMB 3.X Dialect family required for "
    5368             :                                    "replay tests\n");
    5369             :         }
    5370             : 
    5371           0 :         torture_comment(tctx, "Notify across increment/decrement of csn\n");
    5372             : 
    5373           0 :         smbXcli_conn_set_force_channel_sequence(transport->conn, true);
    5374             : 
    5375           0 :         status = torture_smb2_testdir(tree, BASEDIR, &_dh);
    5376           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    5377           0 :         dh = &_dh;
    5378             : 
    5379           0 :         notify.in.recursive             = 0x0000;
    5380           0 :         notify.in.buffer_size   = 0xffff;
    5381           0 :         notify.in.file.handle   = _dh;
    5382           0 :         notify.in.completion_filter     = FILE_NOTIFY_CHANGE_FILE_NAME;
    5383           0 :         notify.in.unknown               = 0x00000000;
    5384             : 
    5385             :         /*
    5386             :          * This posts a long-running request with csn==0 to "dh". Now
    5387             :          * op->request_count==1 in smb2_server.c.
    5388             :          */
    5389           0 :         smb2cli_session_reset_channel_sequence(tree->session->smbXcli, 0);
    5390           0 :         req = smb2_notify_send(tree, &notify);
    5391             : 
    5392           0 :         qfinfo = (union smb_fileinfo) {
    5393             :                 .generic.level = RAW_FILEINFO_POSITION_INFORMATION,
    5394             :                 .generic.in.file.handle = _dh
    5395             :         };
    5396             : 
    5397             :         /*
    5398             :          * This sequence of 2 dummy requests moves
    5399             :          * op->request_count==1 to op->pre_request_count. The numbers
    5400             :          * used avoid int16 overflow.
    5401             :          */
    5402             : 
    5403           0 :         smb2cli_session_reset_channel_sequence(tree->session->smbXcli, 30000);
    5404           0 :         status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
    5405           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    5406             : 
    5407           0 :         smb2cli_session_reset_channel_sequence(tree->session->smbXcli, 60000);
    5408           0 :         status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
    5409           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    5410             : 
    5411             :         /*
    5412             :          * This final request turns the op->global->channel_sequence
    5413             :          * to the same as we had when sending the notify above. The
    5414             :          * notify's request count has in the meantime moved to
    5415             :          * op->pre_request_count.
    5416             :          */
    5417             : 
    5418           0 :         smb2cli_session_reset_channel_sequence(tree->session->smbXcli, 0);
    5419           0 :         status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
    5420           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    5421             : 
    5422             :         /*
    5423             :          * At this point op->request_count==0.
    5424             :          *
    5425             :          * The next cancel makes us reply to the notify. Because the
    5426             :          * csn we currently use is the same as we used when sending
    5427             :          * the notify, smbd thinks it must decrement op->request_count
    5428             :          * and not op->pre_request_count.
    5429             :          */
    5430             : 
    5431           0 :         status = smb2_cancel(req);
    5432           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    5433             : 
    5434           0 :         status = smb2_notify_recv(req, mem_ctx, &notify);
    5435           0 :         CHECK_STATUS(status, NT_STATUS_CANCELLED);
    5436             : 
    5437           0 :         ret = true;
    5438             : 
    5439           0 : done:
    5440           0 :         if (dh != NULL) {
    5441           0 :                 smb2_util_close(tree, _dh);
    5442             :         }
    5443           0 :         smb2_deltree(tree, BASEDIR);
    5444           0 :         talloc_free(tree);
    5445           0 :         talloc_free(mem_ctx);
    5446             : 
    5447           0 :         return ret;
    5448             : }
    5449             : 
    5450         964 : struct torture_suite *torture_smb2_replay_init(TALLOC_CTX *ctx)
    5451             : {
    5452         738 :         struct torture_suite *suite =
    5453         226 :                 torture_suite_create(ctx, "replay");
    5454             : 
    5455         964 :         torture_suite_add_1smb2_test(suite, "replay-commands", test_replay_commands);
    5456         964 :         torture_suite_add_1smb2_test(suite, "replay-regular", test_replay_regular);
    5457         964 :         torture_suite_add_1smb2_test(suite, "replay-dhv2-oplock1", test_replay_dhv2_oplock1);
    5458         964 :         torture_suite_add_1smb2_test(suite, "replay-dhv2-oplock2", test_replay_dhv2_oplock2);
    5459         964 :         torture_suite_add_1smb2_test(suite, "replay-dhv2-oplock3", test_replay_dhv2_oplock3);
    5460         964 :         torture_suite_add_1smb2_test(suite, "replay-dhv2-oplock-lease", test_replay_dhv2_oplock_lease);
    5461         964 :         torture_suite_add_1smb2_test(suite, "replay-dhv2-lease1",  test_replay_dhv2_lease1);
    5462         964 :         torture_suite_add_1smb2_test(suite, "replay-dhv2-lease2",  test_replay_dhv2_lease2);
    5463         964 :         torture_suite_add_1smb2_test(suite, "replay-dhv2-lease3",  test_replay_dhv2_lease3);
    5464         964 :         torture_suite_add_1smb2_test(suite, "replay-dhv2-lease-oplock",  test_replay_dhv2_lease_oplock);
    5465         964 :         torture_suite_add_2smb2_test(suite, "dhv2-pending1n-vs-violation-lease-close-sane", test_dhv2_pending1n_vs_violation_lease_close_sane);
    5466         964 :         torture_suite_add_2smb2_test(suite, "dhv2-pending1n-vs-violation-lease-ack-sane", test_dhv2_pending1n_vs_violation_lease_ack_sane);
    5467         964 :         torture_suite_add_2smb2_test(suite, "dhv2-pending1n-vs-violation-lease-close-windows", test_dhv2_pending1n_vs_violation_lease_close_windows);
    5468         964 :         torture_suite_add_2smb2_test(suite, "dhv2-pending1n-vs-violation-lease-ack-windows", test_dhv2_pending1n_vs_violation_lease_ack_windows);
    5469         964 :         torture_suite_add_2smb2_test(suite, "dhv2-pending1n-vs-oplock-sane", test_dhv2_pending1n_vs_oplock_sane);
    5470         964 :         torture_suite_add_2smb2_test(suite, "dhv2-pending1n-vs-oplock-windows", test_dhv2_pending1n_vs_oplock_windows);
    5471         964 :         torture_suite_add_2smb2_test(suite, "dhv2-pending1n-vs-lease-sane", test_dhv2_pending1n_vs_lease_sane);
    5472         964 :         torture_suite_add_2smb2_test(suite, "dhv2-pending1n-vs-lease-windows",  test_dhv2_pending1n_vs_lease_windows);
    5473         964 :         torture_suite_add_2smb2_test(suite, "dhv2-pending1l-vs-oplock-sane", test_dhv2_pending1l_vs_oplock_sane);
    5474         964 :         torture_suite_add_2smb2_test(suite, "dhv2-pending1l-vs-oplock-windows", test_dhv2_pending1l_vs_oplock_windows);
    5475         964 :         torture_suite_add_2smb2_test(suite, "dhv2-pending1l-vs-lease-sane", test_dhv2_pending1l_vs_lease_sane);
    5476         964 :         torture_suite_add_2smb2_test(suite, "dhv2-pending1l-vs-lease-windows", test_dhv2_pending1l_vs_lease_windows);
    5477         964 :         torture_suite_add_2smb2_test(suite, "dhv2-pending1o-vs-oplock-sane", test_dhv2_pending1o_vs_oplock_sane);
    5478         964 :         torture_suite_add_2smb2_test(suite, "dhv2-pending1o-vs-oplock-windows", test_dhv2_pending1o_vs_oplock_windows);
    5479         964 :         torture_suite_add_2smb2_test(suite, "dhv2-pending1o-vs-lease-sane", test_dhv2_pending1o_vs_lease_sane);
    5480         964 :         torture_suite_add_2smb2_test(suite, "dhv2-pending1o-vs-lease-windows", test_dhv2_pending1o_vs_lease_windows);
    5481         964 :         torture_suite_add_2smb2_test(suite, "dhv2-pending2n-vs-oplock-sane", test_dhv2_pending2n_vs_oplock_sane);
    5482         964 :         torture_suite_add_2smb2_test(suite, "dhv2-pending2n-vs-oplock-windows", test_dhv2_pending2n_vs_oplock_windows);
    5483         964 :         torture_suite_add_2smb2_test(suite, "dhv2-pending2n-vs-lease-sane", test_dhv2_pending2n_vs_lease_sane);
    5484         964 :         torture_suite_add_2smb2_test(suite, "dhv2-pending2n-vs-lease-windows", test_dhv2_pending2n_vs_lease_windows);
    5485         964 :         torture_suite_add_2smb2_test(suite, "dhv2-pending2l-vs-oplock-sane", test_dhv2_pending2l_vs_oplock_sane);
    5486         964 :         torture_suite_add_2smb2_test(suite, "dhv2-pending2l-vs-oplock-windows", test_dhv2_pending2l_vs_oplock_windows);
    5487         964 :         torture_suite_add_2smb2_test(suite, "dhv2-pending2l-vs-lease-sane", test_dhv2_pending2l_vs_lease_sane);
    5488         964 :         torture_suite_add_2smb2_test(suite, "dhv2-pending2l-vs-lease-windows", test_dhv2_pending2l_vs_lease_windows);
    5489         964 :         torture_suite_add_2smb2_test(suite, "dhv2-pending2o-vs-oplock-sane", test_dhv2_pending2o_vs_oplock_sane);
    5490         964 :         torture_suite_add_2smb2_test(suite, "dhv2-pending2o-vs-oplock-windows", test_dhv2_pending2o_vs_oplock_windows);
    5491         964 :         torture_suite_add_2smb2_test(suite, "dhv2-pending2o-vs-lease-sane", test_dhv2_pending2o_vs_lease_sane);
    5492         964 :         torture_suite_add_2smb2_test(suite, "dhv2-pending2o-vs-lease-windows", test_dhv2_pending2o_vs_lease_windows);
    5493         964 :         torture_suite_add_2smb2_test(suite, "dhv2-pending3n-vs-oplock-sane", test_dhv2_pending3n_vs_oplock_sane);
    5494         964 :         torture_suite_add_2smb2_test(suite, "dhv2-pending3n-vs-oplock-windows", test_dhv2_pending3n_vs_oplock_windows);
    5495         964 :         torture_suite_add_2smb2_test(suite, "dhv2-pending3n-vs-lease-sane", test_dhv2_pending3n_vs_lease_sane);
    5496         964 :         torture_suite_add_2smb2_test(suite, "dhv2-pending3n-vs-lease-windows", test_dhv2_pending3n_vs_lease_windows);
    5497         964 :         torture_suite_add_2smb2_test(suite, "dhv2-pending3l-vs-oplock-sane",  test_dhv2_pending3l_vs_oplock_sane);
    5498         964 :         torture_suite_add_2smb2_test(suite, "dhv2-pending3l-vs-oplock-windows",  test_dhv2_pending3l_vs_oplock_windows);
    5499         964 :         torture_suite_add_2smb2_test(suite, "dhv2-pending3l-vs-lease-sane",  test_dhv2_pending3l_vs_lease_sane);
    5500         964 :         torture_suite_add_2smb2_test(suite, "dhv2-pending3l-vs-lease-windows",  test_dhv2_pending3l_vs_lease_windows);
    5501         964 :         torture_suite_add_2smb2_test(suite, "dhv2-pending3o-vs-oplock-sane",  test_dhv2_pending3o_vs_oplock_sane);
    5502         964 :         torture_suite_add_2smb2_test(suite, "dhv2-pending3o-vs-oplock-windows",  test_dhv2_pending3o_vs_oplock_windows);
    5503         964 :         torture_suite_add_2smb2_test(suite, "dhv2-pending3o-vs-lease-sane",  test_dhv2_pending3o_vs_lease_sane);
    5504         964 :         torture_suite_add_2smb2_test(suite, "dhv2-pending3o-vs-lease-windows",  test_dhv2_pending3o_vs_lease_windows);
    5505         964 :         torture_suite_add_1smb2_test(suite, "channel-sequence", test_channel_sequence);
    5506         964 :         torture_suite_add_1smb2_test(suite, "replay3", test_replay3);
    5507         964 :         torture_suite_add_1smb2_test(suite, "replay4", test_replay4);
    5508         964 :         torture_suite_add_1smb2_test(suite, "replay5", test_replay5);
    5509         964 :         torture_suite_add_1smb2_test(suite, "replay6", test_replay6);
    5510         964 :         torture_suite_add_1smb2_test(suite, "replay7", test_replay7);
    5511             : 
    5512         964 :         suite->description = talloc_strdup(suite, "SMB2 REPLAY tests");
    5513             : 
    5514         964 :         return suite;
    5515             : }

Generated by: LCOV version 1.13