LCOV - code coverage report
Current view: top level - source4/torture/raw - oplock.c (source / functions) Hit Total Coverage
Test: coverage report for v4-17-test 1498b464 Lines: 2566 2855 89.9 %
Date: 2024-06-13 04:01:37 Functions: 56 59 94.9 %

          Line data    Source code
       1             : /* 
       2             :    Unix SMB/CIFS implementation.
       3             :    basic raw test suite for oplocks
       4             :    Copyright (C) Andrew Tridgell 2003
       5             :    
       6             :    This program is free software; you can redistribute it and/or modify
       7             :    it under the terms of the GNU General Public License as published by
       8             :    the Free Software Foundation; either version 3 of the License, or
       9             :    (at your option) any later version.
      10             :    
      11             :    This program is distributed in the hope that it will be useful,
      12             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             :    GNU General Public License for more details.
      15             :    
      16             :    You should have received a copy of the GNU General Public License
      17             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      18             : */
      19             : 
      20             : #include "includes.h"
      21             : #include "libcli/raw/libcliraw.h"
      22             : #include "libcli/raw/raw_proto.h"
      23             : #include "libcli/libcli.h"
      24             : #include "torture/util.h"
      25             : #include "lib/events/events.h"
      26             : #include "param/param.h"
      27             : #include "lib/cmdline/cmdline.h"
      28             : #include "libcli/resolve/resolve.h"
      29             : #include "torture/raw/proto.h"
      30             : 
      31             : #define CHECK_VAL(v, correct) do { \
      32             :         if ((v) != (correct)) { \
      33             :                 torture_result(tctx, TORTURE_FAIL, "(%s): wrong value for %s got 0x%x - should be 0x%x\n", \
      34             :                                 __location__, #v, (int)v, (int)correct); \
      35             :                 ret = false; \
      36             :         }} while (0)
      37             : 
      38             : #define CHECK_RANGE(v, min, max) do {                                   \
      39             :         if ((v) < (min) || (v) > (max)) {                         \
      40             :                 torture_warning(tctx, "(%s): wrong value for %s got " \
      41             :                     "%d - should be between %d and %d\n",             \
      42             :                     __location__, #v, (int)v, (int)min, (int)max);      \
      43             :         }} while (0)
      44             : 
      45             : #define CHECK_STRMATCH(v, correct) do { \
      46             :         if (!v || strstr((v),(correct)) == NULL) { \
      47             :                 torture_result(tctx, TORTURE_FAIL,  "(%s): wrong value for %s got '%s' - should be '%s'\n", \
      48             :                                 __location__, #v, v?v:"NULL", correct); \
      49             :                 ret = false; \
      50             :         } \
      51             : } while (0)
      52             : 
      53             : #define CHECK_STATUS(tctx, status, correct) do { \
      54             :         if (!NT_STATUS_EQUAL(status, correct)) { \
      55             :                 torture_result(tctx, TORTURE_FAIL, __location__": Incorrect status %s - should be %s", \
      56             :                        nt_errstr(status), nt_errstr(correct)); \
      57             :                 ret = false; \
      58             :                 goto done; \
      59             :         }} while (0)
      60             : 
      61             : 
      62             : static struct {
      63             :         int fnum;
      64             :         uint8_t level;
      65             :         int count;
      66             :         int failures;
      67             : } break_info;
      68             : 
      69             : #define BASEDIR "\\test_oplock"
      70             : 
      71             : /*
      72             :   a handler function for oplock break requests. Ack it as a break to level II if possible
      73             : */
      74          41 : static bool oplock_handler_ack_to_given(struct smbcli_transport *transport,
      75             :                                         uint16_t tid, uint16_t fnum,
      76             :                                         uint8_t level, void *private_data)
      77             : {
      78          41 :         struct smbcli_tree *tree = (struct smbcli_tree *)private_data;
      79             :         const char *name;
      80             : 
      81          41 :         break_info.fnum = fnum;
      82          41 :         break_info.level = level;
      83          41 :         break_info.count++;
      84             : 
      85          41 :         switch (level) {
      86          27 :         case OPLOCK_BREAK_TO_LEVEL_II:
      87          27 :                 name = "level II";
      88          27 :                 break;
      89          14 :         case OPLOCK_BREAK_TO_NONE:
      90          14 :                 name = "none";
      91          14 :                 break;
      92           0 :         default:
      93           0 :                 name = "unknown";
      94           0 :                 break_info.failures++;
      95             :         }
      96          41 :         printf("Acking to %s [0x%02X] in oplock handler\n",
      97             :                 name, level);
      98             : 
      99          41 :         return smbcli_oplock_ack(tree, fnum, level);
     100             : }
     101             : 
     102             : /*
     103             :   a handler function for oplock break requests. Ack it as a break to none
     104             : */
     105           1 : static bool oplock_handler_ack_to_none(struct smbcli_transport *transport, 
     106             :                                        uint16_t tid, uint16_t fnum, 
     107             :                                        uint8_t level, void *private_data)
     108             : {
     109           1 :         struct smbcli_tree *tree = (struct smbcli_tree *)private_data;
     110           1 :         break_info.fnum = fnum;
     111           1 :         break_info.level = level;
     112           1 :         break_info.count++;
     113             : 
     114           1 :         printf("Acking to none in oplock handler\n");
     115             : 
     116           1 :         return smbcli_oplock_ack(tree, fnum, OPLOCK_BREAK_TO_NONE);
     117             : }
     118             : 
     119             : /*
     120             :   a handler function for oplock break requests. Let it timeout
     121             : */
     122           2 : static bool oplock_handler_timeout(struct smbcli_transport *transport,
     123             :                                    uint16_t tid, uint16_t fnum,
     124             :                                    uint8_t level, void *private_data)
     125             : {
     126           2 :         break_info.fnum = fnum;
     127           2 :         break_info.level = level;
     128           2 :         break_info.count++;
     129             : 
     130           2 :         printf("Let oplock break timeout\n");
     131           2 :         return true;
     132             : }
     133             : 
     134           2 : static void oplock_handler_close_recv(struct smbcli_request *req)
     135             : {
     136             :         NTSTATUS status;
     137           2 :         status = smbcli_request_simple_recv(req);
     138           2 :         if (!NT_STATUS_IS_OK(status)) {
     139           0 :                 printf("close failed in oplock_handler_close\n");
     140           0 :                 break_info.failures++;
     141             :         }
     142           2 : }
     143             : 
     144             : /*
     145             :   a handler function for oplock break requests - close the file
     146             : */
     147           2 : static bool oplock_handler_close(struct smbcli_transport *transport, uint16_t tid, 
     148             :                                  uint16_t fnum, uint8_t level, void *private_data)
     149             : {
     150             :         union smb_close io;
     151           2 :         struct smbcli_tree *tree = (struct smbcli_tree *)private_data;
     152             :         struct smbcli_request *req;
     153             : 
     154           2 :         break_info.fnum = fnum;
     155           2 :         break_info.level = level;
     156           2 :         break_info.count++;
     157             : 
     158           2 :         io.close.level = RAW_CLOSE_CLOSE;
     159           2 :         io.close.in.file.fnum = fnum;
     160           2 :         io.close.in.write_time = 0;
     161           2 :         req = smb_raw_close_send(tree, &io);
     162           2 :         if (req == NULL) {
     163           0 :                 printf("failed to send close in oplock_handler_close\n");
     164           0 :                 return false;
     165             :         }
     166             : 
     167           2 :         req->async.fn = oplock_handler_close_recv;
     168           2 :         req->async.private_data = NULL;
     169             : 
     170           2 :         return true;
     171             : }
     172             : 
     173           2 : static bool open_connection_no_level2_oplocks(struct torture_context *tctx,
     174             :                                               struct smbcli_state **c)
     175             : {
     176             :         NTSTATUS status;
     177             :         struct smbcli_options options;
     178             :         struct smbcli_session_options session_options;
     179             : 
     180           2 :         lpcfg_smbcli_options(tctx->lp_ctx, &options);
     181           2 :         lpcfg_smbcli_session_options(tctx->lp_ctx, &session_options);
     182             : 
     183           2 :         options.use_level2_oplocks = false;
     184             : 
     185           2 :         status = smbcli_full_connection(tctx, c,
     186             :                                         torture_setting_string(tctx, "host", NULL),
     187             :                                         lpcfg_smb_ports(tctx->lp_ctx),
     188             :                                         torture_setting_string(tctx, "share", NULL),
     189             :                                         NULL, lpcfg_socket_options(tctx->lp_ctx),
     190             :                                         samba_cmdline_get_creds(),
     191             :                                         lpcfg_resolve_context(tctx->lp_ctx),
     192             :                                         tctx->ev, &options, &session_options,
     193             :                                         lpcfg_gensec_settings(tctx, tctx->lp_ctx));
     194           2 :         if (!NT_STATUS_IS_OK(status)) {
     195           0 :                 torture_comment(tctx, "Failed to open connection - %s\n",
     196             :                                 nt_errstr(status));
     197           0 :                 return false;
     198             :         }
     199             : 
     200           2 :         return true;
     201             : }
     202             : 
     203             : /*
     204             :    Timer handler function notifies the registering function that time is up
     205             : */
     206          68 : static void timeout_cb(struct tevent_context *ev,
     207             :                        struct tevent_timer *te,
     208             :                        struct timeval current_time,
     209             :                        void *private_data)
     210             : {
     211          68 :         bool *timesup = (bool *)private_data;
     212          68 :         *timesup = true;
     213          68 :         return;
     214             : }
     215             : 
     216             : /*
     217             :    Wait a short period of time to receive a single oplock break request
     218             : */
     219          79 : static void torture_wait_for_oplock_break(struct torture_context *tctx)
     220             : {
     221          79 :         TALLOC_CTX *tmp_ctx = talloc_new(NULL);
     222          79 :         struct tevent_timer *te = NULL;
     223             :         struct timeval ne;
     224          79 :         bool timesup = false;
     225          79 :         int old_count = break_info.count;
     226             : 
     227             :         /* Wait .1 seconds for an oplock break */
     228          79 :         ne = tevent_timeval_current_ofs(0, 100000);
     229             : 
     230          79 :         if ((te = tevent_add_timer(tctx->ev, tmp_ctx, ne, timeout_cb, &timesup))
     231             :             == NULL)
     232             :         {
     233           0 :                 torture_comment(tctx, "Failed to wait for an oplock break. "
     234             :                                       "test results may not be accurate.");
     235           0 :                 goto done;
     236             :         }
     237             : 
     238         379 :         while (!timesup && break_info.count < old_count + 1) {
     239         105 :                 if (tevent_loop_once(tctx->ev) != 0) {
     240           0 :                         torture_comment(tctx, "Failed to wait for an oplock "
     241             :                                               "break. test results may not be "
     242             :                                               "accurate.");
     243           0 :                         goto done;
     244             :                 }
     245             :         }
     246             : 
     247          79 : done:
     248             :         /* We don't know if the timed event fired and was freed, we received
     249             :          * our oplock break, or some other event triggered the loop.  Thus,
     250             :          * we create a tmp_ctx to be able to safely free/remove the timed
     251             :          * event in all 3 cases. */
     252          79 :         talloc_free(tmp_ctx);
     253             : 
     254          79 :         return;
     255             : }
     256             : 
     257           5 : static uint8_t get_break_level1_to_none_count(struct torture_context *tctx)
     258             : {
     259           5 :         return torture_setting_bool(tctx, "2_step_break_to_none", false) ?
     260           5 :             2 : 1;
     261             : }
     262             : 
     263           3 : static uint8_t get_setinfo_break_count(struct torture_context *tctx)
     264             : {
     265           3 :         if (TARGET_IS_W2K12(tctx)) {
     266           0 :                 return 2;
     267             :         }
     268           3 :         if (TARGET_IS_SAMBA3(tctx)) {
     269           0 :                 return 2;
     270             :         }
     271           3 :         return 1;
     272             : }
     273             : 
     274           1 : static bool test_raw_oplock_exclusive1(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
     275             : {
     276           1 :         const char *fname = BASEDIR "\\test_exclusive1.dat";
     277             :         NTSTATUS status;
     278           1 :         bool ret = true;
     279             :         union smb_open io;
     280             :         union smb_unlink unl;
     281           1 :         uint16_t fnum=0;
     282             : 
     283           1 :         if (!torture_setup_dir(cli1, BASEDIR)) {
     284           0 :                 return false;
     285             :         }
     286             : 
     287             :         /* cleanup */
     288           1 :         smbcli_unlink(cli1->tree, fname);
     289             : 
     290           1 :         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
     291             : 
     292             :         /*
     293             :           base ntcreatex parms
     294             :         */
     295           1 :         io.generic.level = RAW_OPEN_NTCREATEX;
     296           1 :         io.ntcreatex.in.root_fid.fnum = 0;
     297           1 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
     298           1 :         io.ntcreatex.in.alloc_size = 0;
     299           1 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
     300           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
     301           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
     302           1 :         io.ntcreatex.in.create_options = 0;
     303           1 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
     304           1 :         io.ntcreatex.in.security_flags = 0;
     305           1 :         io.ntcreatex.in.fname = fname;
     306             : 
     307           1 :         torture_comment(tctx, "EXCLUSIVE1: open a file with an exclusive oplock (share mode: none)\n");
     308           1 :         ZERO_STRUCT(break_info);
     309           1 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
     310             : 
     311           1 :         status = smb_raw_open(cli1->tree, tctx, &io);
     312           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
     313           1 :         fnum = io.ntcreatex.out.file.fnum;
     314           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
     315             : 
     316           1 :         torture_comment(tctx, "a 2nd open should not cause a break\n");
     317           1 :         status = smb_raw_open(cli2->tree, tctx, &io);
     318           1 :         CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
     319           1 :         torture_wait_for_oplock_break(tctx);
     320           1 :         CHECK_VAL(break_info.count, 0);
     321           1 :         CHECK_VAL(break_info.failures, 0);
     322             : 
     323           1 :         torture_comment(tctx, "unlink it - should also be no break\n");
     324           1 :         unl.unlink.in.pattern = fname;
     325           1 :         unl.unlink.in.attrib = 0;
     326           1 :         status = smb_raw_unlink(cli2->tree, &unl);
     327           1 :         CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
     328           1 :         torture_wait_for_oplock_break(tctx);
     329           1 :         CHECK_VAL(break_info.count, 0);
     330           1 :         CHECK_VAL(break_info.failures, 0);
     331             : 
     332           1 :         smbcli_close(cli1->tree, fnum);
     333             : 
     334           1 : done:
     335           1 :         smb_raw_exit(cli1->session);
     336           1 :         smb_raw_exit(cli2->session);
     337           1 :         smbcli_deltree(cli1->tree, BASEDIR);
     338           1 :         return ret;
     339             : }
     340             : 
     341           1 : static bool test_raw_oplock_exclusive2(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
     342             : {
     343           1 :         const char *fname = BASEDIR "\\test_exclusive2.dat";
     344             :         NTSTATUS status;
     345           1 :         bool ret = true;
     346             :         union smb_open io;
     347             :         union smb_unlink unl;
     348           1 :         uint16_t fnum=0, fnum2=0;
     349             : 
     350           1 :         if (!torture_setup_dir(cli1, BASEDIR)) {
     351           0 :                 return false;
     352             :         }
     353             : 
     354             :         /* cleanup */
     355           1 :         smbcli_unlink(cli1->tree, fname);
     356             : 
     357           1 :         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
     358             : 
     359             :         /*
     360             :           base ntcreatex parms
     361             :         */
     362           1 :         io.generic.level = RAW_OPEN_NTCREATEX;
     363           1 :         io.ntcreatex.in.root_fid.fnum = 0;
     364           1 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
     365           1 :         io.ntcreatex.in.alloc_size = 0;
     366           1 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
     367           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
     368           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
     369           1 :         io.ntcreatex.in.create_options = 0;
     370           1 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
     371           1 :         io.ntcreatex.in.security_flags = 0;
     372           1 :         io.ntcreatex.in.fname = fname;
     373             : 
     374           1 :         torture_comment(tctx, "EXCLUSIVE2: open a file with an exclusive oplock (share mode: all)\n");
     375           1 :         ZERO_STRUCT(break_info);
     376           1 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
     377           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
     378             :                 NTCREATEX_SHARE_ACCESS_WRITE|
     379             :                 NTCREATEX_SHARE_ACCESS_DELETE;
     380             : 
     381           1 :         status = smb_raw_open(cli1->tree, tctx, &io);
     382           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
     383           1 :         fnum = io.ntcreatex.out.file.fnum;
     384           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
     385             : 
     386           1 :         torture_comment(tctx, "a 2nd open should cause a break to level 2\n");
     387           1 :         status = smb_raw_open(cli2->tree, tctx, &io);
     388           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
     389           1 :         fnum2 = io.ntcreatex.out.file.fnum;
     390           1 :         torture_wait_for_oplock_break(tctx);
     391           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
     392           1 :         CHECK_VAL(break_info.count, 1);
     393           1 :         CHECK_VAL(break_info.fnum, fnum);
     394           1 :         CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
     395           1 :         CHECK_VAL(break_info.failures, 0);
     396           1 :         ZERO_STRUCT(break_info);
     397             : 
     398             :         /* now we have 2 level II oplocks... */
     399           1 :         torture_comment(tctx, "try to unlink it - should not cause a break, but a sharing violation\n");
     400           1 :         unl.unlink.in.pattern = fname;
     401           1 :         unl.unlink.in.attrib = 0;
     402           1 :         status = smb_raw_unlink(cli2->tree, &unl);
     403           1 :         CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
     404           1 :         torture_wait_for_oplock_break(tctx);
     405           1 :         CHECK_VAL(break_info.count, 0);
     406           1 :         CHECK_VAL(break_info.failures, 0);
     407             : 
     408           1 :         torture_comment(tctx, "close 1st handle\n");
     409           1 :         smbcli_close(cli1->tree, fnum);
     410             : 
     411           1 :         torture_comment(tctx, "try to unlink it - should not cause a break, but a sharing violation\n");
     412           1 :         unl.unlink.in.pattern = fname;
     413           1 :         unl.unlink.in.attrib = 0;
     414           1 :         status = smb_raw_unlink(cli2->tree, &unl);
     415           1 :         CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
     416           1 :         torture_wait_for_oplock_break(tctx);
     417           1 :         CHECK_VAL(break_info.count, 0);
     418           1 :         CHECK_VAL(break_info.failures, 0);
     419             : 
     420           1 :         torture_comment(tctx, "close 2nd handle\n");
     421           1 :         smbcli_close(cli2->tree, fnum2);
     422             : 
     423           1 :         torture_comment(tctx, "unlink it\n");
     424           1 :         unl.unlink.in.pattern = fname;
     425           1 :         unl.unlink.in.attrib = 0;
     426           1 :         status = smb_raw_unlink(cli2->tree, &unl);
     427           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
     428           1 :         torture_wait_for_oplock_break(tctx);
     429           1 :         CHECK_VAL(break_info.count, 0);
     430           1 :         CHECK_VAL(break_info.failures, 0);
     431             : 
     432           2 : done:
     433           1 :         smb_raw_exit(cli1->session);
     434           1 :         smb_raw_exit(cli2->session);
     435           1 :         smbcli_deltree(cli1->tree, BASEDIR);
     436           1 :         return ret;
     437             : }
     438             : 
     439           1 : static bool test_raw_oplock_exclusive3(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
     440             : {
     441           1 :         const char *fname = BASEDIR "\\test_exclusive3.dat";
     442             :         NTSTATUS status;
     443           1 :         bool ret = true;
     444             :         union smb_open io;
     445             :         union smb_setfileinfo sfi;
     446           1 :         uint16_t fnum=0;
     447             : 
     448           1 :         if (!torture_setup_dir(cli1, BASEDIR)) {
     449           0 :                 return false;
     450             :         }
     451             : 
     452             :         /* cleanup */
     453           1 :         smbcli_unlink(cli1->tree, fname);
     454             : 
     455           1 :         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
     456             : 
     457             :         /*
     458             :           base ntcreatex parms
     459             :         */
     460           1 :         io.generic.level = RAW_OPEN_NTCREATEX;
     461           1 :         io.ntcreatex.in.root_fid.fnum = 0;
     462           1 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
     463           1 :         io.ntcreatex.in.alloc_size = 0;
     464           1 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
     465           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_WRITE;
     466           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
     467           1 :         io.ntcreatex.in.create_options = 0;
     468           1 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
     469           1 :         io.ntcreatex.in.security_flags = 0;
     470           1 :         io.ntcreatex.in.fname = fname;
     471             : 
     472           1 :         torture_comment(tctx, "EXCLUSIVE3: open a file with an exclusive oplock (share mode: none)\n");
     473             : 
     474           1 :         ZERO_STRUCT(break_info);
     475           1 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
     476             : 
     477           1 :         status = smb_raw_open(cli1->tree, tctx, &io);
     478           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
     479           1 :         fnum = io.ntcreatex.out.file.fnum;
     480           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
     481             : 
     482           1 :         torture_comment(tctx, "setpathinfo EOF should trigger a break to none\n");
     483           1 :         ZERO_STRUCT(sfi);
     484           1 :         sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
     485           1 :         sfi.generic.in.file.path = fname;
     486           1 :         sfi.end_of_file_info.in.size = 100;
     487             : 
     488           1 :         status = smb_raw_setpathinfo(cli2->tree, &sfi);
     489             : 
     490           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
     491           1 :         torture_wait_for_oplock_break(tctx);
     492           1 :         CHECK_VAL(break_info.count, get_setinfo_break_count(tctx));
     493           1 :         CHECK_VAL(break_info.failures, 0);
     494           1 :         CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_NONE);
     495             : 
     496           1 :         smbcli_close(cli1->tree, fnum);
     497             : 
     498           1 : done:
     499           1 :         smb_raw_exit(cli1->session);
     500           1 :         smb_raw_exit(cli2->session);
     501           1 :         smbcli_deltree(cli1->tree, BASEDIR);
     502           1 :         return ret;
     503             : }
     504             : 
     505           1 : static bool test_raw_oplock_exclusive4(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
     506             : {
     507           1 :         const char *fname = BASEDIR "\\test_exclusive4.dat";
     508             :         NTSTATUS status;
     509           1 :         bool ret = true;
     510             :         union smb_open io;
     511           1 :         uint16_t fnum=0, fnum2=0;
     512             : 
     513           1 :         if (!torture_setup_dir(cli1, BASEDIR)) {
     514           0 :                 return false;
     515             :         }
     516             : 
     517             :         /* cleanup */
     518           1 :         smbcli_unlink(cli1->tree, fname);
     519             : 
     520           1 :         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
     521             : 
     522             :         /*
     523             :           base ntcreatex parms
     524             :         */
     525           1 :         io.generic.level = RAW_OPEN_NTCREATEX;
     526           1 :         io.ntcreatex.in.root_fid.fnum = 0;
     527           1 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
     528           1 :         io.ntcreatex.in.alloc_size = 0;
     529           1 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
     530           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
     531           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
     532           1 :         io.ntcreatex.in.create_options = 0;
     533           1 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
     534           1 :         io.ntcreatex.in.security_flags = 0;
     535           1 :         io.ntcreatex.in.fname = fname;
     536             : 
     537           1 :         torture_comment(tctx, "EXCLUSIVE4: open with exclusive oplock\n");
     538           1 :         ZERO_STRUCT(break_info);
     539           1 :         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
     540             : 
     541           1 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
     542           1 :         status = smb_raw_open(cli1->tree, tctx, &io);
     543           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
     544           1 :         fnum = io.ntcreatex.out.file.fnum;
     545           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
     546             : 
     547           1 :         ZERO_STRUCT(break_info);
     548           1 :         torture_comment(tctx, "second open with attributes only shouldn't cause oplock break\n");
     549             : 
     550           1 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
     551           1 :         io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
     552           1 :         status = smb_raw_open(cli2->tree, tctx, &io);
     553           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
     554           1 :         fnum2 = io.ntcreatex.out.file.fnum;
     555           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, NO_OPLOCK_RETURN);
     556           1 :         torture_wait_for_oplock_break(tctx);
     557           1 :         CHECK_VAL(break_info.count, 0);
     558           1 :         CHECK_VAL(break_info.failures, 0);
     559             : 
     560             :         /*
     561             :          * Open another non-stat open. This reproduces bug 10216. Make sure it
     562             :          * won't happen again...
     563             :          */
     564           1 :         io.ntcreatex.in.flags = 0;
     565           1 :         io.ntcreatex.in.access_mask = SEC_FILE_READ_DATA;
     566           1 :         status = smb_raw_open(cli2->tree, tctx, &io);
     567           1 :         CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
     568           1 :         torture_wait_for_oplock_break(tctx);
     569           1 :         CHECK_VAL(break_info.count, 0);
     570           1 :         CHECK_VAL(break_info.failures, 0);
     571             : 
     572           1 :         smbcli_close(cli1->tree, fnum);
     573           1 :         smbcli_close(cli2->tree, fnum2);
     574             : 
     575           1 : done:
     576           1 :         smb_raw_exit(cli1->session);
     577           1 :         smb_raw_exit(cli2->session);
     578           1 :         smbcli_deltree(cli1->tree, BASEDIR);
     579           1 :         return ret;
     580             : }
     581             : 
     582           1 : static bool test_raw_oplock_exclusive5(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
     583             : {
     584           1 :         const char *fname = BASEDIR "\\test_exclusive5.dat";
     585             :         NTSTATUS status;
     586           1 :         bool ret = true;
     587             :         union smb_open io;
     588           1 :         uint16_t fnum=0, fnum2=0;
     589             : 
     590           1 :         if (!torture_setup_dir(cli1, BASEDIR)) {
     591           0 :                 return false;
     592             :         }
     593             : 
     594             :         /* cleanup */
     595           1 :         smbcli_unlink(cli1->tree, fname);
     596             : 
     597           1 :         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
     598           1 :         smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli1->tree);
     599             : 
     600             :         /*
     601             :           base ntcreatex parms
     602             :         */
     603           1 :         io.generic.level = RAW_OPEN_NTCREATEX;
     604           1 :         io.ntcreatex.in.root_fid.fnum = 0;
     605           1 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
     606           1 :         io.ntcreatex.in.alloc_size = 0;
     607           1 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
     608           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
     609           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
     610           1 :         io.ntcreatex.in.create_options = 0;
     611           1 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
     612           1 :         io.ntcreatex.in.security_flags = 0;
     613           1 :         io.ntcreatex.in.fname = fname;
     614             : 
     615           1 :         torture_comment(tctx, "EXCLUSIVE5: open with exclusive oplock\n");
     616           1 :         ZERO_STRUCT(break_info);
     617           1 :         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
     618             : 
     619             : 
     620           1 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
     621           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
     622             :                 NTCREATEX_SHARE_ACCESS_WRITE|
     623             :                 NTCREATEX_SHARE_ACCESS_DELETE;
     624           1 :         status = smb_raw_open(cli1->tree, tctx, &io);
     625           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
     626           1 :         fnum = io.ntcreatex.out.file.fnum;
     627           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
     628             : 
     629           1 :         ZERO_STRUCT(break_info);
     630             : 
     631           1 :         torture_comment(tctx, "second open with attributes only and NTCREATEX_DISP_OVERWRITE_IF dispostion causes oplock break\n");
     632             : 
     633           1 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
     634           1 :         io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
     635           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE_IF;
     636           1 :         status = smb_raw_open(cli2->tree, tctx, &io);
     637           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
     638           1 :         fnum2 = io.ntcreatex.out.file.fnum;
     639           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
     640           1 :         torture_wait_for_oplock_break(tctx);
     641           1 :         CHECK_VAL(break_info.count, get_break_level1_to_none_count(tctx));
     642           1 :         CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_NONE);
     643           1 :         CHECK_VAL(break_info.failures, 0);
     644             : 
     645           1 :         smbcli_close(cli1->tree, fnum);
     646           1 :         smbcli_close(cli2->tree, fnum2);
     647             : 
     648           1 : done:
     649           1 :         smb_raw_exit(cli1->session);
     650           1 :         smb_raw_exit(cli2->session);
     651           1 :         smbcli_deltree(cli1->tree, BASEDIR);
     652           1 :         return ret;
     653             : }
     654             : 
     655           1 : static bool test_raw_oplock_exclusive6(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
     656             : {
     657           1 :         const char *fname1 = BASEDIR "\\test_exclusive6_1.dat";
     658           1 :         const char *fname2 = BASEDIR "\\test_exclusive6_2.dat";
     659             :         NTSTATUS status;
     660           1 :         bool ret = true;
     661             :         union smb_open io;
     662             :         union smb_rename rn;
     663           1 :         uint16_t fnum=0;
     664             : 
     665           1 :         if (!torture_setup_dir(cli1, BASEDIR)) {
     666           0 :                 return false;
     667             :         }
     668             : 
     669             :         /* cleanup */
     670           1 :         smbcli_unlink(cli1->tree, fname1);
     671           1 :         smbcli_unlink(cli1->tree, fname2);
     672             : 
     673           1 :         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
     674             : 
     675             :         /*
     676             :           base ntcreatex parms
     677             :         */
     678           1 :         io.generic.level = RAW_OPEN_NTCREATEX;
     679           1 :         io.ntcreatex.in.root_fid.fnum = 0;
     680           1 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
     681           1 :         io.ntcreatex.in.alloc_size = 0;
     682           1 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
     683           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
     684           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
     685           1 :         io.ntcreatex.in.create_options = 0;
     686           1 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
     687           1 :         io.ntcreatex.in.security_flags = 0;
     688           1 :         io.ntcreatex.in.fname = fname1;
     689             : 
     690           1 :         torture_comment(tctx, "EXCLUSIVE6: open a file with an exclusive "
     691             :                         "oplock (share mode: none)\n");
     692           1 :         ZERO_STRUCT(break_info);
     693           1 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
     694             : 
     695           1 :         status = smb_raw_open(cli1->tree, tctx, &io);
     696           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
     697           1 :         fnum = io.ntcreatex.out.file.fnum;
     698           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
     699             : 
     700           1 :         torture_comment(tctx, "rename should not generate a break but get a "
     701             :                         "sharing violation\n");
     702           1 :         ZERO_STRUCT(rn);
     703           1 :         rn.generic.level = RAW_RENAME_RENAME;
     704           1 :         rn.rename.in.pattern1 = fname1;
     705           1 :         rn.rename.in.pattern2 = fname2;
     706           1 :         rn.rename.in.attrib = 0;
     707             : 
     708           1 :         torture_comment(tctx, "trying rename while first file open\n");
     709           1 :         status = smb_raw_rename(cli2->tree, &rn);
     710             : 
     711           1 :         CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
     712           1 :         torture_wait_for_oplock_break(tctx);
     713           1 :         CHECK_VAL(break_info.count, 0);
     714           1 :         CHECK_VAL(break_info.failures, 0);
     715             : 
     716           1 :         smbcli_close(cli1->tree, fnum);
     717             : 
     718           1 : done:
     719           1 :         smb_raw_exit(cli1->session);
     720           1 :         smb_raw_exit(cli2->session);
     721           1 :         smbcli_deltree(cli1->tree, BASEDIR);
     722           1 :         return ret;
     723             : }
     724             : 
     725             : /**
     726             :  * Exclusive version of batch19
     727             :  */
     728           1 : static bool test_raw_oplock_exclusive7(struct torture_context *tctx,
     729             :     struct smbcli_state *cli1, struct smbcli_state *cli2)
     730             : {
     731           1 :         const char *fname1 = BASEDIR "\\test_exclusiv6_1.dat";
     732           1 :         const char *fname2 = BASEDIR "\\test_exclusiv6_2.dat";
     733           1 :         const char *fname3 = BASEDIR "\\test_exclusiv6_3.dat";
     734             :         NTSTATUS status;
     735           1 :         bool ret = true;
     736             :         union smb_open io;
     737             :         union smb_fileinfo qfi;
     738             :         union smb_setfileinfo sfi;
     739           1 :         uint16_t fnum=0;
     740           1 :         uint16_t fnum2 = 0;
     741             : 
     742           1 :         if (!torture_setup_dir(cli1, BASEDIR)) {
     743           0 :                 return false;
     744             :         }
     745             : 
     746             :         /* cleanup */
     747           1 :         smbcli_unlink(cli1->tree, fname1);
     748           1 :         smbcli_unlink(cli1->tree, fname2);
     749           1 :         smbcli_unlink(cli1->tree, fname3);
     750             : 
     751           1 :         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given,
     752           1 :             cli1->tree);
     753             : 
     754             :         /*
     755             :           base ntcreatex parms
     756             :         */
     757           1 :         io.generic.level = RAW_OPEN_NTCREATEX;
     758           1 :         io.ntcreatex.in.root_fid.fnum = 0;
     759           1 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
     760           1 :         io.ntcreatex.in.alloc_size = 0;
     761           1 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
     762           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
     763             :             NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_DELETE;
     764           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
     765           1 :         io.ntcreatex.in.create_options = 0;
     766           1 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
     767           1 :         io.ntcreatex.in.security_flags = 0;
     768           1 :         io.ntcreatex.in.fname = fname1;
     769             : 
     770           1 :         torture_comment(tctx, "open a file with an exclusive oplock (share "
     771             :             "mode: none)\n");
     772           1 :         ZERO_STRUCT(break_info);
     773           1 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
     774             :                 NTCREATEX_FLAGS_REQUEST_OPLOCK;
     775           1 :         status = smb_raw_open(cli1->tree, tctx, &io);
     776           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
     777           1 :         fnum = io.ntcreatex.out.file.fnum;
     778           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
     779             : 
     780           1 :         torture_comment(tctx, "setpathinfo rename info should trigger a break "
     781             :             "to none\n");
     782           1 :         ZERO_STRUCT(sfi);
     783           1 :         sfi.generic.level = RAW_SFILEINFO_RENAME_INFORMATION;
     784           1 :         sfi.generic.in.file.path = fname1;
     785           1 :         sfi.rename_information.in.overwrite     = 0;
     786           1 :         sfi.rename_information.in.root_fid      = 0;
     787           1 :         sfi.rename_information.in.new_name      = fname2+strlen(BASEDIR)+1;
     788             : 
     789           1 :         status = smb_raw_setpathinfo(cli2->tree, &sfi);
     790           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
     791             : 
     792           1 :         torture_wait_for_oplock_break(tctx);
     793           1 :         CHECK_VAL(break_info.failures, 0);
     794             : 
     795           1 :         if (TARGET_IS_WINXP(tctx) || TARGET_IS_W2K12(tctx)) {
     796             :                 /* XP incorrectly breaks to level2. */
     797           0 :                 CHECK_VAL(break_info.count, 1);
     798           0 :                 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
     799             :         } else {
     800             :                 /* Exclusive oplocks should not be broken on rename. */
     801           1 :                 CHECK_VAL(break_info.failures, 0);
     802           1 :                 CHECK_VAL(break_info.count, 0);
     803             :         }
     804             : 
     805           1 :         ZERO_STRUCT(qfi);
     806           1 :         qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
     807           1 :         qfi.generic.in.file.fnum = fnum;
     808             : 
     809           1 :         status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
     810           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
     811           1 :         CHECK_STRMATCH(qfi.all_info.out.fname.s, fname2);
     812             : 
     813             :         /* Try breaking to level2 and then see if rename breaks the level2.*/
     814           1 :         ZERO_STRUCT(break_info);
     815           1 :         io.ntcreatex.in.fname = fname2;
     816           1 :         status = smb_raw_open(cli2->tree, tctx, &io);
     817           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
     818           1 :         fnum2 = io.ntcreatex.out.file.fnum;
     819           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
     820             : 
     821           1 :         torture_wait_for_oplock_break(tctx);
     822           1 :         CHECK_VAL(break_info.failures, 0);
     823             : 
     824           1 :         if (TARGET_IS_WINXP(tctx)) {
     825             :                 /* XP already broke to level2. */
     826           0 :                 CHECK_VAL(break_info.failures, 0);
     827           0 :                 CHECK_VAL(break_info.count, 0);
     828           1 :         } else if (TARGET_IS_W2K12(tctx)) {
     829             :                 /* no break */
     830           0 :                 CHECK_VAL(break_info.count, 0);
     831           0 :                 CHECK_VAL(break_info.level, 0);
     832             :         } else {
     833             :                 /* Break to level 2 expected. */
     834           1 :                 CHECK_VAL(break_info.count, 1);
     835           1 :                 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
     836             :         }
     837             : 
     838           1 :         ZERO_STRUCT(break_info);
     839           1 :         sfi.generic.in.file.path = fname2;
     840           1 :         sfi.rename_information.in.overwrite     = 0;
     841           1 :         sfi.rename_information.in.root_fid      = 0;
     842           1 :         sfi.rename_information.in.new_name      = fname1+strlen(BASEDIR)+1;
     843             : 
     844           1 :         status = smb_raw_setpathinfo(cli2->tree, &sfi);
     845           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
     846             : 
     847             :         /* Level2 oplocks are not broken on rename. */
     848           1 :         torture_wait_for_oplock_break(tctx);
     849           1 :         CHECK_VAL(break_info.failures, 0);
     850           1 :         CHECK_VAL(break_info.count, 0);
     851             : 
     852             :         /* Close and re-open file with oplock. */
     853           1 :         smbcli_close(cli1->tree, fnum);
     854           1 :         status = smb_raw_open(cli1->tree, tctx, &io);
     855           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
     856           1 :         fnum = io.ntcreatex.out.file.fnum;
     857           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
     858             : 
     859           1 :         torture_comment(tctx, "setfileinfo rename info on a client's own fid "
     860             :             "should not trigger a break nor a violation\n");
     861           1 :         ZERO_STRUCT(break_info);
     862           1 :         ZERO_STRUCT(sfi);
     863           1 :         sfi.generic.level = RAW_SFILEINFO_RENAME_INFORMATION;
     864           1 :         sfi.generic.in.file.fnum = fnum;
     865           1 :         sfi.rename_information.in.overwrite     = 0;
     866           1 :         sfi.rename_information.in.root_fid      = 0;
     867           1 :         sfi.rename_information.in.new_name      = fname3+strlen(BASEDIR)+1;
     868             : 
     869           1 :         status = smb_raw_setfileinfo(cli1->tree, &sfi);
     870           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
     871             : 
     872           1 :         torture_wait_for_oplock_break(tctx);
     873           1 :         if (TARGET_IS_WINXP(tctx)) {
     874             :                 /* XP incorrectly breaks to level2. */
     875           0 :                 CHECK_VAL(break_info.count, 1);
     876           0 :                 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
     877             :         } else {
     878           1 :                 CHECK_VAL(break_info.count, 0);
     879             :         }
     880             : 
     881           1 :         ZERO_STRUCT(qfi);
     882           1 :         qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
     883           1 :         qfi.generic.in.file.fnum = fnum;
     884             : 
     885           1 :         status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
     886           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
     887           1 :         CHECK_STRMATCH(qfi.all_info.out.fname.s, fname3);
     888             : 
     889           2 : done:
     890           1 :         smbcli_close(cli1->tree, fnum);
     891           1 :         smbcli_close(cli2->tree, fnum2);
     892             : 
     893           1 :         smb_raw_exit(cli1->session);
     894           1 :         smb_raw_exit(cli2->session);
     895           1 :         smbcli_deltree(cli1->tree, BASEDIR);
     896           1 :         return ret;
     897             : }
     898             : 
     899           1 : static bool test_raw_oplock_exclusive8(struct torture_context *tctx,
     900             :                                        struct smbcli_state *cli1,
     901             :                                        struct smbcli_state *cli2)
     902             : {
     903           1 :         const char *fname = BASEDIR "\\test_exclusive8.dat";
     904             :         NTSTATUS status;
     905           1 :         bool ret = true;
     906             :         union smb_open io;
     907           1 :         uint16_t fnum1 = 0;
     908           1 :         uint16_t fnum2 = 0;
     909           1 :         uint16_t fnum3 = 0;
     910             : 
     911           1 :         if (!torture_setup_dir(cli1, BASEDIR)) {
     912           0 :                 return false;
     913             :         }
     914             : 
     915             :         /* cleanup */
     916           1 :         smbcli_unlink(cli1->tree, fname);
     917             : 
     918           1 :         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given,
     919           1 :                               cli1->tree);
     920             : 
     921             :         /*
     922             :           base ntcreatex parms
     923             :         */
     924           1 :         io.generic.level = RAW_OPEN_NTCREATEX;
     925           1 :         io.ntcreatex.in.root_fid.fnum = 0;
     926           1 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
     927           1 :         io.ntcreatex.in.alloc_size = 0;
     928           1 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
     929           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
     930             :                 NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_DELETE;
     931           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
     932           1 :         io.ntcreatex.in.create_options = 0;
     933           1 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
     934           1 :         io.ntcreatex.in.security_flags = 0;
     935           1 :         io.ntcreatex.in.fname = fname;
     936             : 
     937           1 :         torture_comment(tctx, "open a file with an exclusive oplock (share "
     938             :                         "mode: all)\n");
     939           1 :         ZERO_STRUCT(break_info);
     940           1 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
     941             :                 NTCREATEX_FLAGS_REQUEST_OPLOCK;
     942           1 :         status = smb_raw_open(cli1->tree, tctx, &io);
     943           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
     944           1 :         fnum1 = io.ntcreatex.out.file.fnum;
     945           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
     946             : 
     947           1 :         torture_comment(tctx, "second open with delete should trigger a "
     948             :                         "break\n");
     949             : 
     950           1 :         io.ntcreatex.in.access_mask = SEC_STD_DELETE;
     951           1 :         io.ntcreatex.in.flags = 0;
     952           1 :         status = smb_raw_open(cli2->tree, tctx, &io);
     953           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
     954           1 :         fnum2 = io.ntcreatex.out.file.fnum;
     955           1 :         CHECK_VAL(break_info.count, get_break_level1_to_none_count(tctx));
     956           1 :         CHECK_VAL(break_info.failures, 0);
     957           1 :         CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
     958             : 
     959             :         /* Trigger a little panic in "old" samba code.. */
     960           1 :         status = smb_raw_open(cli2->tree, tctx, &io);
     961           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
     962           1 :         fnum3 = io.ntcreatex.out.file.fnum;
     963             : 
     964           1 :         smbcli_close(cli2->tree, fnum3);
     965           1 :         smbcli_close(cli2->tree, fnum2);
     966           1 :         smbcli_close(cli1->tree, fnum1);
     967             : 
     968           1 : done:
     969           1 :         smbcli_deltree(cli1->tree, BASEDIR);
     970           1 :         smb_raw_exit(cli1->session);
     971           1 :         smb_raw_exit(cli2->session);
     972           1 :         return ret;
     973             : }
     974             : 
     975           1 : static bool test_raw_oplock_exclusive9(struct torture_context *tctx,
     976             :                                        struct smbcli_state *cli1,
     977             :                                        struct smbcli_state *cli2)
     978             : {
     979           1 :         const char *fname = BASEDIR "\\test_exclusive9.dat";
     980             :         NTSTATUS status;
     981           1 :         bool ret = true;
     982             :         union smb_open io;
     983           1 :         uint16_t fnum=0, fnum2=0;
     984             :         int i;
     985             : 
     986             :         struct {
     987             :                 uint32_t create_disposition;
     988             :                 uint32_t break_level;
     989           1 :         } levels[] = {
     990             :                 { NTCREATEX_DISP_SUPERSEDE, OPLOCK_BREAK_TO_NONE },
     991             :                 { NTCREATEX_DISP_OPEN, OPLOCK_BREAK_TO_LEVEL_II },
     992             :                 { NTCREATEX_DISP_OVERWRITE_IF, OPLOCK_BREAK_TO_NONE },
     993             :                 { NTCREATEX_DISP_OPEN_IF, OPLOCK_BREAK_TO_LEVEL_II },
     994             :         };
     995             : 
     996           1 :         if (!torture_setup_dir(cli1, BASEDIR)) {
     997           0 :                 return false;
     998             :         }
     999             : 
    1000             :         /* cleanup */
    1001           1 :         smbcli_unlink(cli1->tree, fname);
    1002             : 
    1003           1 :         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given,
    1004           1 :                               cli1->tree);
    1005           1 :         smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given,
    1006           1 :                               cli1->tree);
    1007             : 
    1008             :         /*
    1009             :           base ntcreatex parms
    1010             :         */
    1011           1 :         io.generic.level = RAW_OPEN_NTCREATEX;
    1012           1 :         io.ntcreatex.in.root_fid.fnum = 0;
    1013           1 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
    1014           1 :         io.ntcreatex.in.alloc_size = 0;
    1015           1 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
    1016           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
    1017           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
    1018           1 :         io.ntcreatex.in.create_options = 0;
    1019           1 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
    1020           1 :         io.ntcreatex.in.security_flags = 0;
    1021           1 :         io.ntcreatex.in.fname = fname;
    1022             : 
    1023           1 :         ZERO_STRUCT(break_info);
    1024           1 :         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given,
    1025           1 :                               cli1->tree);
    1026             : 
    1027           5 :         for (i=0; i<ARRAY_SIZE(levels); i++) {
    1028             : 
    1029           4 :                 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
    1030             :                         NTCREATEX_FLAGS_REQUEST_OPLOCK;
    1031           4 :                 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
    1032             :                         NTCREATEX_SHARE_ACCESS_WRITE|
    1033             :                         NTCREATEX_SHARE_ACCESS_DELETE;
    1034           4 :                 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
    1035           4 :                 status = smb_raw_open(cli1->tree, tctx, &io);
    1036           4 :                 CHECK_STATUS(tctx, status, NT_STATUS_OK);
    1037           4 :                 fnum = io.ntcreatex.out.file.fnum;
    1038           4 :                 CHECK_VAL(io.ntcreatex.out.oplock_level,
    1039             :                           EXCLUSIVE_OPLOCK_RETURN);
    1040             : 
    1041           4 :                 ZERO_STRUCT(break_info);
    1042             : 
    1043           4 :                 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
    1044             :                         NTCREATEX_FLAGS_REQUEST_OPLOCK;
    1045           4 :                 io.ntcreatex.in.access_mask = SEC_FILE_READ_DATA;
    1046           4 :                 io.ntcreatex.in.open_disposition =
    1047           4 :                         levels[i].create_disposition;
    1048           4 :                 status = smb_raw_open(cli2->tree, tctx, &io);
    1049           4 :                 CHECK_STATUS(tctx, status, NT_STATUS_OK);
    1050           4 :                 fnum2 = io.ntcreatex.out.file.fnum;
    1051           4 :                 CHECK_VAL(io.ntcreatex.out.oplock_level,
    1052             :                           LEVEL_II_OPLOCK_RETURN);
    1053           4 :                 torture_wait_for_oplock_break(tctx);
    1054           4 :                 CHECK_VAL(break_info.count, 1);
    1055           4 :                 CHECK_VAL(break_info.level, levels[i].break_level);
    1056           4 :                 CHECK_VAL(break_info.failures, 0);
    1057             : 
    1058           4 :                 smbcli_close(cli1->tree, fnum);
    1059           4 :                 smbcli_close(cli2->tree, fnum2);
    1060             :         }
    1061             : 
    1062           1 : done:
    1063           1 :         smb_raw_exit(cli1->session);
    1064           1 :         smb_raw_exit(cli2->session);
    1065           1 :         smbcli_deltree(cli1->tree, BASEDIR);
    1066           1 :         return ret;
    1067             : }
    1068             : 
    1069           1 : static bool test_raw_oplock_level_ii_1(struct torture_context *tctx,
    1070             :                                        struct smbcli_state *cli1,
    1071             :                                        struct smbcli_state *cli2)
    1072             : {
    1073           1 :         const char *fname = BASEDIR "\\test_level_ii_1.dat";
    1074             :         NTSTATUS status;
    1075           1 :         bool ret = true;
    1076             :         union smb_open io;
    1077           1 :         uint16_t fnum=0, fnum2=0;
    1078           1 :         char c = 0;
    1079             :         ssize_t written;
    1080             : 
    1081           1 :         if (!torture_setup_dir(cli1, BASEDIR)) {
    1082           0 :                 return false;
    1083             :         }
    1084             : 
    1085             :         /* cleanup */
    1086           1 :         smbcli_unlink(cli1->tree, fname);
    1087             : 
    1088           1 :         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given,
    1089           1 :                               cli1->tree);
    1090           1 :         smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given,
    1091           1 :                               cli1->tree);
    1092             : 
    1093             :         /*
    1094             :           base ntcreatex parms
    1095             :         */
    1096           1 :         io.generic.level = RAW_OPEN_NTCREATEX;
    1097           1 :         io.ntcreatex.in.root_fid.fnum = 0;
    1098           1 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
    1099           1 :         io.ntcreatex.in.alloc_size = 0;
    1100           1 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
    1101           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
    1102           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
    1103           1 :         io.ntcreatex.in.create_options = 0;
    1104           1 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
    1105           1 :         io.ntcreatex.in.security_flags = 0;
    1106           1 :         io.ntcreatex.in.fname = fname;
    1107             : 
    1108           1 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
    1109             :                 NTCREATEX_FLAGS_REQUEST_OPLOCK;
    1110           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
    1111             :                 NTCREATEX_SHARE_ACCESS_WRITE|
    1112             :                 NTCREATEX_SHARE_ACCESS_DELETE;
    1113           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
    1114           1 :         status = smb_raw_open(cli1->tree, tctx, &io);
    1115           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    1116           1 :         fnum = io.ntcreatex.out.file.fnum;
    1117           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
    1118             : 
    1119           1 :         ZERO_STRUCT(break_info);
    1120             : 
    1121           1 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
    1122             :                 NTCREATEX_FLAGS_REQUEST_OPLOCK;
    1123           1 :         io.ntcreatex.in.access_mask = SEC_FILE_READ_DATA|SEC_FILE_WRITE_DATA;
    1124           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
    1125           1 :         status = smb_raw_open(cli2->tree, tctx, &io);
    1126           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    1127           1 :         fnum2 = io.ntcreatex.out.file.fnum;
    1128           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
    1129           1 :         torture_wait_for_oplock_break(tctx);
    1130           1 :         CHECK_VAL(break_info.count, 1);
    1131           1 :         CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
    1132           1 :         CHECK_VAL(break_info.failures, 0);
    1133             : 
    1134           1 :         status = smbcli_close(cli2->tree, fnum2);
    1135           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    1136             : 
    1137             :         /*
    1138             :          * fnum1 has a level2 oplock now
    1139             :          */
    1140             : 
    1141           1 :         ZERO_STRUCT(break_info);
    1142             : 
    1143             :         /*
    1144             :          * Don't answer the break to none that will come in
    1145             :          */
    1146             : 
    1147           1 :         smbcli_oplock_handler(cli1->transport, oplock_handler_timeout,
    1148           1 :                               cli1->tree);
    1149             : 
    1150           1 :         io.ntcreatex.in.flags = 0;
    1151           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE_IF;
    1152             : 
    1153           1 :         status = smb_raw_open(cli2->tree, tctx, &io);
    1154           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    1155           1 :         fnum2 = io.ntcreatex.out.file.fnum;
    1156           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, NO_OPLOCK_RETURN);
    1157           1 :         torture_wait_for_oplock_break(tctx);
    1158           1 :         CHECK_VAL(break_info.count, 1);
    1159           1 :         CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_NONE);
    1160           1 :         CHECK_VAL(break_info.failures, 0);
    1161             : 
    1162             :         /*
    1163             :          * Check that a write does not cause another break. This used to be a
    1164             :          * bug in smbd.
    1165             :          */
    1166             : 
    1167           1 :         ZERO_STRUCT(break_info);
    1168           1 :         written = smbcli_write(cli2->tree, fnum2, 0, &c, 0, 1);
    1169           1 :         CHECK_VAL(written, 1);
    1170           1 :         torture_wait_for_oplock_break(tctx);
    1171           1 :         CHECK_VAL(break_info.count, 0);
    1172           1 :         CHECK_VAL(break_info.failures, 0);
    1173             : 
    1174           1 :         status = smbcli_close(cli2->tree, fnum2);
    1175           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    1176           1 :         status = smbcli_close(cli1->tree, fnum);
    1177           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    1178             : 
    1179           2 : done:
    1180           1 :         smb_raw_exit(cli1->session);
    1181           1 :         smb_raw_exit(cli2->session);
    1182           1 :         smbcli_deltree(cli1->tree, BASEDIR);
    1183           1 :         return ret;
    1184             : }
    1185             : 
    1186           1 : static bool test_raw_oplock_batch1(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
    1187             : {
    1188           1 :         const char *fname = BASEDIR "\\test_batch1.dat";
    1189             :         NTSTATUS status;
    1190           1 :         bool ret = true;
    1191             :         union smb_open io;
    1192             :         union smb_unlink unl;
    1193           1 :         uint16_t fnum=0;
    1194           1 :         char c = 0;
    1195             : 
    1196           1 :         if (!torture_setup_dir(cli1, BASEDIR)) {
    1197           0 :                 return false;
    1198             :         }
    1199             : 
    1200             :         /* cleanup */
    1201           1 :         smbcli_unlink(cli1->tree, fname);
    1202             : 
    1203           1 :         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
    1204             : 
    1205             :         /*
    1206             :           base ntcreatex parms
    1207             :         */
    1208           1 :         io.generic.level = RAW_OPEN_NTCREATEX;
    1209           1 :         io.ntcreatex.in.root_fid.fnum = 0;
    1210           1 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
    1211           1 :         io.ntcreatex.in.alloc_size = 0;
    1212           1 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
    1213           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
    1214           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
    1215           1 :         io.ntcreatex.in.create_options = 0;
    1216           1 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
    1217           1 :         io.ntcreatex.in.security_flags = 0;
    1218           1 :         io.ntcreatex.in.fname = fname;
    1219             : 
    1220             :         /*
    1221             :           with a batch oplock we get a break
    1222             :         */
    1223           1 :         torture_comment(tctx, "BATCH1: open with batch oplock\n");
    1224           1 :         ZERO_STRUCT(break_info);
    1225           1 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | 
    1226             :                 NTCREATEX_FLAGS_REQUEST_OPLOCK | 
    1227             :                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
    1228           1 :         status = smb_raw_open(cli1->tree, tctx, &io);
    1229           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    1230           1 :         fnum = io.ntcreatex.out.file.fnum;
    1231           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
    1232             : 
    1233           1 :         torture_comment(tctx, "unlink should generate a break\n");
    1234           1 :         unl.unlink.in.pattern = fname;
    1235           1 :         unl.unlink.in.attrib = 0;
    1236           1 :         status = smb_raw_unlink(cli2->tree, &unl);
    1237           1 :         CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
    1238             : 
    1239           1 :         torture_wait_for_oplock_break(tctx);
    1240           1 :         CHECK_VAL(break_info.count, 1);
    1241           1 :         CHECK_VAL(break_info.fnum, fnum);
    1242           1 :         CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
    1243           1 :         CHECK_VAL(break_info.failures, 0);
    1244             : 
    1245           1 :         torture_comment(tctx, "2nd unlink should not generate a break\n");
    1246           1 :         ZERO_STRUCT(break_info);
    1247           1 :         status = smb_raw_unlink(cli2->tree, &unl);
    1248           1 :         CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
    1249             : 
    1250           1 :         torture_wait_for_oplock_break(tctx);
    1251           1 :         CHECK_VAL(break_info.count, 0);
    1252             : 
    1253           1 :         torture_comment(tctx, "writing should generate a self break to none\n");
    1254           1 :         smbcli_write(cli1->tree, fnum, 0, &c, 0, 1);
    1255             : 
    1256           1 :         torture_wait_for_oplock_break(tctx);
    1257           1 :         torture_wait_for_oplock_break(tctx);
    1258           1 :         CHECK_VAL(break_info.count, 1);
    1259           1 :         CHECK_VAL(break_info.fnum, fnum);
    1260           1 :         CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_NONE);
    1261           1 :         CHECK_VAL(break_info.failures, 0);
    1262             : 
    1263           1 :         smbcli_close(cli1->tree, fnum);
    1264             : 
    1265           1 : done:
    1266           1 :         smb_raw_exit(cli1->session);
    1267           1 :         smb_raw_exit(cli2->session);
    1268           1 :         smbcli_deltree(cli1->tree, BASEDIR);
    1269           1 :         return ret;
    1270             : }
    1271             : 
    1272           1 : static bool test_raw_oplock_batch2(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
    1273             : {
    1274           1 :         const char *fname = BASEDIR "\\test_batch2.dat";
    1275             :         NTSTATUS status;
    1276           1 :         bool ret = true;
    1277             :         union smb_open io;
    1278             :         union smb_unlink unl;
    1279           1 :         uint16_t fnum=0;
    1280           1 :         char c = 0;
    1281             : 
    1282           1 :         if (!torture_setup_dir(cli1, BASEDIR)) {
    1283           0 :                 return false;
    1284             :         }
    1285             : 
    1286             :         /* cleanup */
    1287           1 :         smbcli_unlink(cli1->tree, fname);
    1288             : 
    1289           1 :         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
    1290             : 
    1291             :         /*
    1292             :           base ntcreatex parms
    1293             :         */
    1294           1 :         io.generic.level = RAW_OPEN_NTCREATEX;
    1295           1 :         io.ntcreatex.in.root_fid.fnum = 0;
    1296           1 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
    1297           1 :         io.ntcreatex.in.alloc_size = 0;
    1298           1 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
    1299           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
    1300           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
    1301           1 :         io.ntcreatex.in.create_options = 0;
    1302           1 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
    1303           1 :         io.ntcreatex.in.security_flags = 0;
    1304           1 :         io.ntcreatex.in.fname = fname;
    1305             : 
    1306           1 :         torture_comment(tctx, "BATCH2: open with batch oplock\n");
    1307           1 :         ZERO_STRUCT(break_info);
    1308           1 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | 
    1309             :                 NTCREATEX_FLAGS_REQUEST_OPLOCK | 
    1310             :                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
    1311           1 :         status = smb_raw_open(cli1->tree, tctx, &io);
    1312           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    1313           1 :         fnum = io.ntcreatex.out.file.fnum;
    1314           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
    1315             : 
    1316           1 :         torture_comment(tctx, "unlink should generate a break, which we ack as break to none\n");
    1317           1 :         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_none, cli1->tree);
    1318           1 :         unl.unlink.in.pattern = fname;
    1319           1 :         unl.unlink.in.attrib = 0;
    1320           1 :         status = smb_raw_unlink(cli2->tree, &unl);
    1321           1 :         CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
    1322             : 
    1323           1 :         torture_wait_for_oplock_break(tctx);
    1324           1 :         CHECK_VAL(break_info.count, 1);
    1325           1 :         CHECK_VAL(break_info.fnum, fnum);
    1326           1 :         CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
    1327           1 :         CHECK_VAL(break_info.failures, 0);
    1328             : 
    1329           1 :         torture_comment(tctx, "2nd unlink should not generate a break\n");
    1330           1 :         ZERO_STRUCT(break_info);
    1331           1 :         status = smb_raw_unlink(cli2->tree, &unl);
    1332           1 :         CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
    1333             : 
    1334           1 :         torture_wait_for_oplock_break(tctx);
    1335           1 :         CHECK_VAL(break_info.count, 0);
    1336             : 
    1337           1 :         torture_comment(tctx, "writing should not generate a break\n");
    1338           1 :         smbcli_write(cli1->tree, fnum, 0, &c, 0, 1);
    1339             : 
    1340           1 :         torture_wait_for_oplock_break(tctx);
    1341           1 :         CHECK_VAL(break_info.count, 0);
    1342             : 
    1343           1 :         smbcli_close(cli1->tree, fnum);
    1344             : 
    1345           1 : done:
    1346           1 :         smb_raw_exit(cli1->session);
    1347           1 :         smb_raw_exit(cli2->session);
    1348           1 :         smbcli_deltree(cli1->tree, BASEDIR);
    1349           1 :         return ret;
    1350             : }
    1351             : 
    1352           1 : static bool test_raw_oplock_batch3(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
    1353             : {
    1354           1 :         const char *fname = BASEDIR "\\test_batch3.dat";
    1355             :         NTSTATUS status;
    1356           1 :         bool ret = true;
    1357             :         union smb_open io;
    1358             :         union smb_unlink unl;
    1359           1 :         uint16_t fnum=0;
    1360             : 
    1361           1 :         if (!torture_setup_dir(cli1, BASEDIR)) {
    1362           0 :                 return false;
    1363             :         }
    1364             : 
    1365             :         /* cleanup */
    1366           1 :         smbcli_unlink(cli1->tree, fname);
    1367             : 
    1368           1 :         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
    1369             : 
    1370             :         /*
    1371             :           base ntcreatex parms
    1372             :         */
    1373           1 :         io.generic.level = RAW_OPEN_NTCREATEX;
    1374           1 :         io.ntcreatex.in.root_fid.fnum = 0;
    1375           1 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
    1376           1 :         io.ntcreatex.in.alloc_size = 0;
    1377           1 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
    1378           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
    1379           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
    1380           1 :         io.ntcreatex.in.create_options = 0;
    1381           1 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
    1382           1 :         io.ntcreatex.in.security_flags = 0;
    1383           1 :         io.ntcreatex.in.fname = fname;
    1384             : 
    1385           1 :         torture_comment(tctx, "BATCH3: if we close on break then the unlink can succeed\n");
    1386           1 :         ZERO_STRUCT(break_info);
    1387           1 :         smbcli_oplock_handler(cli1->transport, oplock_handler_close, cli1->tree);
    1388           1 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | 
    1389             :                 NTCREATEX_FLAGS_REQUEST_OPLOCK | 
    1390             :                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
    1391           1 :         status = smb_raw_open(cli1->tree, tctx, &io);
    1392           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    1393           1 :         fnum = io.ntcreatex.out.file.fnum;
    1394           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
    1395             : 
    1396           1 :         unl.unlink.in.pattern = fname;
    1397           1 :         unl.unlink.in.attrib = 0;
    1398           1 :         ZERO_STRUCT(break_info);
    1399           1 :         status = smb_raw_unlink(cli2->tree, &unl);
    1400           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    1401             : 
    1402           1 :         torture_wait_for_oplock_break(tctx);
    1403           1 :         CHECK_VAL(break_info.count, 1);
    1404           1 :         CHECK_VAL(break_info.fnum, fnum);
    1405           1 :         CHECK_VAL(break_info.level, 1);
    1406           1 :         CHECK_VAL(break_info.failures, 0);
    1407             : 
    1408           1 :         smbcli_close(cli1->tree, fnum);
    1409             : 
    1410           1 : done:
    1411           1 :         smb_raw_exit(cli1->session);
    1412           1 :         smb_raw_exit(cli2->session);
    1413           1 :         smbcli_deltree(cli1->tree, BASEDIR);
    1414           1 :         return ret;
    1415             : }
    1416             : 
    1417           1 : static bool test_raw_oplock_batch4(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
    1418             : {
    1419           1 :         const char *fname = BASEDIR "\\test_batch4.dat";
    1420             :         NTSTATUS status;
    1421           1 :         bool ret = true;
    1422             :         union smb_open io;
    1423             :         union smb_read rd;
    1424           1 :         uint16_t fnum=0;
    1425             : 
    1426           1 :         if (!torture_setup_dir(cli1, BASEDIR)) {
    1427           0 :                 return false;
    1428             :         }
    1429             : 
    1430             :         /* cleanup */
    1431           1 :         smbcli_unlink(cli1->tree, fname);
    1432             : 
    1433           1 :         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
    1434             : 
    1435             :         /*
    1436             :           base ntcreatex parms
    1437             :         */
    1438           1 :         io.generic.level = RAW_OPEN_NTCREATEX;
    1439           1 :         io.ntcreatex.in.root_fid.fnum = 0;
    1440           1 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
    1441           1 :         io.ntcreatex.in.alloc_size = 0;
    1442           1 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
    1443           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
    1444           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
    1445           1 :         io.ntcreatex.in.create_options = 0;
    1446           1 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
    1447           1 :         io.ntcreatex.in.security_flags = 0;
    1448           1 :         io.ntcreatex.in.fname = fname;
    1449             : 
    1450           1 :         torture_comment(tctx, "BATCH4: a self read should not cause a break\n");
    1451           1 :         ZERO_STRUCT(break_info);
    1452           1 :         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
    1453             : 
    1454           1 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | 
    1455             :                 NTCREATEX_FLAGS_REQUEST_OPLOCK | 
    1456             :                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
    1457           1 :         status = smb_raw_open(cli1->tree, tctx, &io);
    1458           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    1459           1 :         fnum = io.ntcreatex.out.file.fnum;
    1460           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
    1461             : 
    1462           1 :         rd.readx.level = RAW_READ_READX;
    1463           1 :         rd.readx.in.file.fnum = fnum;
    1464           1 :         rd.readx.in.mincnt = 1;
    1465           1 :         rd.readx.in.maxcnt = 1;
    1466           1 :         rd.readx.in.offset = 0;
    1467           1 :         rd.readx.in.remaining = 0;
    1468           1 :         rd.readx.in.read_for_execute = false;
    1469           1 :         status = smb_raw_read(cli1->tree, &rd);
    1470           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    1471           1 :         torture_wait_for_oplock_break(tctx);
    1472           1 :         CHECK_VAL(break_info.count, 0);
    1473           1 :         CHECK_VAL(break_info.failures, 0);
    1474             : 
    1475           1 :         smbcli_close(cli1->tree, fnum);
    1476             : 
    1477           1 : done:
    1478           1 :         smb_raw_exit(cli1->session);
    1479           1 :         smb_raw_exit(cli2->session);
    1480           1 :         smbcli_deltree(cli1->tree, BASEDIR);
    1481           1 :         return ret;
    1482             : }
    1483             : 
    1484           1 : static bool test_raw_oplock_batch5(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
    1485             : {
    1486           1 :         const char *fname = BASEDIR "\\test_batch5.dat";
    1487             :         NTSTATUS status;
    1488           1 :         bool ret = true;
    1489             :         union smb_open io;
    1490           1 :         uint16_t fnum=0;
    1491             : 
    1492           1 :         if (!torture_setup_dir(cli1, BASEDIR)) {
    1493           0 :                 return false;
    1494             :         }
    1495             : 
    1496             :         /* cleanup */
    1497           1 :         smbcli_unlink(cli1->tree, fname);
    1498             : 
    1499           1 :         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
    1500             : 
    1501             :         /*
    1502             :           base ntcreatex parms
    1503             :         */
    1504           1 :         io.generic.level = RAW_OPEN_NTCREATEX;
    1505           1 :         io.ntcreatex.in.root_fid.fnum = 0;
    1506           1 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
    1507           1 :         io.ntcreatex.in.alloc_size = 0;
    1508           1 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
    1509           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
    1510           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
    1511           1 :         io.ntcreatex.in.create_options = 0;
    1512           1 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
    1513           1 :         io.ntcreatex.in.security_flags = 0;
    1514           1 :         io.ntcreatex.in.fname = fname;
    1515             : 
    1516           1 :         torture_comment(tctx, "BATCH5: a 2nd open should give a break\n");
    1517           1 :         ZERO_STRUCT(break_info);
    1518           1 :         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
    1519             : 
    1520           1 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | 
    1521             :                 NTCREATEX_FLAGS_REQUEST_OPLOCK | 
    1522             :                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
    1523           1 :         status = smb_raw_open(cli1->tree, tctx, &io);
    1524           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    1525           1 :         fnum = io.ntcreatex.out.file.fnum;
    1526           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
    1527             : 
    1528           1 :         ZERO_STRUCT(break_info);
    1529             : 
    1530           1 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
    1531           1 :         status = smb_raw_open(cli2->tree, tctx, &io);
    1532           1 :         CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
    1533             : 
    1534           1 :         torture_wait_for_oplock_break(tctx);
    1535           1 :         CHECK_VAL(break_info.count, 1);
    1536           1 :         CHECK_VAL(break_info.fnum, fnum);
    1537           1 :         CHECK_VAL(break_info.level, 1);
    1538           1 :         CHECK_VAL(break_info.failures, 0);
    1539             : 
    1540           1 :         smbcli_close(cli1->tree, fnum);
    1541             : 
    1542           1 : done:
    1543           1 :         smb_raw_exit(cli1->session);
    1544           1 :         smb_raw_exit(cli2->session);
    1545           1 :         smbcli_deltree(cli1->tree, BASEDIR);
    1546           1 :         return ret;
    1547             : }
    1548             : 
    1549           1 : static bool test_raw_oplock_batch6(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
    1550             : {
    1551           1 :         const char *fname = BASEDIR "\\test_batch6.dat";
    1552             :         NTSTATUS status;
    1553           1 :         bool ret = true;
    1554             :         union smb_open io;
    1555           1 :         uint16_t fnum=0, fnum2=0;
    1556           1 :         char c = 0;
    1557             : 
    1558           1 :         if (!torture_setup_dir(cli1, BASEDIR)) {
    1559           0 :                 return false;
    1560             :         }
    1561             : 
    1562             :         /* cleanup */
    1563           1 :         smbcli_unlink(cli1->tree, fname);
    1564             : 
    1565           1 :         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
    1566           1 :         smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli2->tree);
    1567             : 
    1568             :         /*
    1569             :           base ntcreatex parms
    1570             :         */
    1571           1 :         io.generic.level = RAW_OPEN_NTCREATEX;
    1572           1 :         io.ntcreatex.in.root_fid.fnum = 0;
    1573           1 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
    1574           1 :         io.ntcreatex.in.alloc_size = 0;
    1575           1 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
    1576           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
    1577           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
    1578           1 :         io.ntcreatex.in.create_options = 0;
    1579           1 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
    1580           1 :         io.ntcreatex.in.security_flags = 0;
    1581           1 :         io.ntcreatex.in.fname = fname;
    1582             : 
    1583           1 :         torture_comment(tctx, "BATCH6: a 2nd open should give a break to level II if the first open allowed shared read\n");
    1584           1 :         ZERO_STRUCT(break_info);
    1585             : 
    1586           1 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_READ | SEC_RIGHTS_FILE_WRITE;
    1587           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
    1588           1 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | 
    1589             :                 NTCREATEX_FLAGS_REQUEST_OPLOCK | 
    1590             :                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
    1591           1 :         status = smb_raw_open(cli1->tree, tctx, &io);
    1592           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    1593           1 :         fnum = io.ntcreatex.out.file.fnum;
    1594           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
    1595             : 
    1596           1 :         ZERO_STRUCT(break_info);
    1597             : 
    1598           1 :         status = smb_raw_open(cli2->tree, tctx, &io);
    1599           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    1600           1 :         fnum2 = io.ntcreatex.out.file.fnum;
    1601           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
    1602             : 
    1603             :         //torture_wait_for_oplock_break(tctx);
    1604           1 :         CHECK_VAL(break_info.count, 1);
    1605           1 :         CHECK_VAL(break_info.fnum, fnum);
    1606           1 :         CHECK_VAL(break_info.level, 1);
    1607           1 :         CHECK_VAL(break_info.failures, 0);
    1608           1 :         ZERO_STRUCT(break_info);
    1609             : 
    1610           1 :         torture_comment(tctx, "write should trigger a break to none on both\n");
    1611           1 :         smbcli_write(cli1->tree, fnum, 0, &c, 0, 1);
    1612             : 
    1613             :         /* We expect two breaks */
    1614           1 :         torture_wait_for_oplock_break(tctx);
    1615           1 :         torture_wait_for_oplock_break(tctx);
    1616             : 
    1617           1 :         CHECK_VAL(break_info.count, 2);
    1618           1 :         CHECK_VAL(break_info.level, 0);
    1619           1 :         CHECK_VAL(break_info.failures, 0);
    1620             : 
    1621           1 :         smbcli_close(cli1->tree, fnum);
    1622           1 :         smbcli_close(cli2->tree, fnum2);
    1623             : 
    1624           1 : done:
    1625           1 :         smb_raw_exit(cli1->session);
    1626           1 :         smb_raw_exit(cli2->session);
    1627           1 :         smbcli_deltree(cli1->tree, BASEDIR);
    1628           1 :         return ret;
    1629             : }
    1630             : 
    1631           1 : static bool test_raw_oplock_batch7(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
    1632             : {
    1633           1 :         const char *fname = BASEDIR "\\test_batch7.dat";
    1634             :         NTSTATUS status;
    1635           1 :         bool ret = true;
    1636             :         union smb_open io;
    1637           1 :         uint16_t fnum=0, fnum2=0;
    1638             : 
    1639           1 :         if (!torture_setup_dir(cli1, BASEDIR)) {
    1640           0 :                 return false;
    1641             :         }
    1642             : 
    1643             :         /* cleanup */
    1644           1 :         smbcli_unlink(cli1->tree, fname);
    1645             : 
    1646           1 :         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
    1647             : 
    1648             :         /*
    1649             :           base ntcreatex parms
    1650             :         */
    1651           1 :         io.generic.level = RAW_OPEN_NTCREATEX;
    1652           1 :         io.ntcreatex.in.root_fid.fnum = 0;
    1653           1 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
    1654           1 :         io.ntcreatex.in.alloc_size = 0;
    1655           1 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
    1656           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
    1657           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
    1658           1 :         io.ntcreatex.in.create_options = 0;
    1659           1 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
    1660           1 :         io.ntcreatex.in.security_flags = 0;
    1661           1 :         io.ntcreatex.in.fname = fname;
    1662             : 
    1663           1 :         torture_comment(tctx, "BATCH7: a 2nd open should get an oplock when we close instead of ack\n");
    1664           1 :         ZERO_STRUCT(break_info);
    1665           1 :         smbcli_oplock_handler(cli1->transport, oplock_handler_close, cli1->tree);
    1666             : 
    1667           1 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
    1668           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
    1669           1 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | 
    1670             :                 NTCREATEX_FLAGS_REQUEST_OPLOCK | 
    1671             :                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
    1672           1 :         status = smb_raw_open(cli1->tree, tctx, &io);
    1673           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    1674           1 :         fnum2 = io.ntcreatex.out.file.fnum;
    1675           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
    1676             : 
    1677           1 :         ZERO_STRUCT(break_info);
    1678             : 
    1679           1 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | 
    1680             :                 NTCREATEX_FLAGS_REQUEST_OPLOCK | 
    1681             :                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
    1682           1 :         status = smb_raw_open(cli2->tree, tctx, &io);
    1683           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    1684           1 :         fnum = io.ntcreatex.out.file.fnum;
    1685           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
    1686             : 
    1687           1 :         torture_wait_for_oplock_break(tctx);
    1688           1 :         CHECK_VAL(break_info.count, 1);
    1689           1 :         CHECK_VAL(break_info.fnum, fnum2);
    1690           1 :         CHECK_VAL(break_info.level, 1);
    1691           1 :         CHECK_VAL(break_info.failures, 0);
    1692             : 
    1693           1 :         smbcli_close(cli2->tree, fnum);
    1694             : 
    1695           1 : done:
    1696           1 :         smb_raw_exit(cli1->session);
    1697           1 :         smb_raw_exit(cli2->session);
    1698           1 :         smbcli_deltree(cli1->tree, BASEDIR);
    1699           1 :         return ret;
    1700             : }
    1701             : 
    1702           1 : static bool test_raw_oplock_batch8(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
    1703             : {
    1704           1 :         const char *fname = BASEDIR "\\test_batch8.dat";
    1705             :         NTSTATUS status;
    1706           1 :         bool ret = true;
    1707             :         union smb_open io;
    1708           1 :         uint16_t fnum=0, fnum2=0;
    1709             : 
    1710           1 :         if (!torture_setup_dir(cli1, BASEDIR)) {
    1711           0 :                 return false;
    1712             :         }
    1713             : 
    1714             :         /* cleanup */
    1715           1 :         smbcli_unlink(cli1->tree, fname);
    1716             : 
    1717           1 :         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
    1718             : 
    1719             :         /*
    1720             :           base ntcreatex parms
    1721             :         */
    1722           1 :         io.generic.level = RAW_OPEN_NTCREATEX;
    1723           1 :         io.ntcreatex.in.root_fid.fnum = 0;
    1724           1 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
    1725           1 :         io.ntcreatex.in.alloc_size = 0;
    1726           1 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
    1727           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
    1728           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
    1729           1 :         io.ntcreatex.in.create_options = 0;
    1730           1 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
    1731           1 :         io.ntcreatex.in.security_flags = 0;
    1732           1 :         io.ntcreatex.in.fname = fname;
    1733             : 
    1734           1 :         torture_comment(tctx, "BATCH8: open with batch oplock\n");
    1735           1 :         ZERO_STRUCT(break_info);
    1736           1 :         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
    1737             : 
    1738           1 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | 
    1739             :                 NTCREATEX_FLAGS_REQUEST_OPLOCK | 
    1740             :                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
    1741           1 :         status = smb_raw_open(cli1->tree, tctx, &io);
    1742           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    1743           1 :         fnum = io.ntcreatex.out.file.fnum;
    1744           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
    1745             : 
    1746           1 :         ZERO_STRUCT(break_info);
    1747           1 :         torture_comment(tctx, "second open with attributes only shouldn't cause oplock break\n");
    1748             : 
    1749           1 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | 
    1750             :                 NTCREATEX_FLAGS_REQUEST_OPLOCK | 
    1751             :                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
    1752           1 :         io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
    1753           1 :         status = smb_raw_open(cli2->tree, tctx, &io);
    1754           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    1755           1 :         fnum2 = io.ntcreatex.out.file.fnum;
    1756           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, NO_OPLOCK_RETURN);
    1757           1 :         torture_wait_for_oplock_break(tctx);
    1758           1 :         CHECK_VAL(break_info.count, 0);
    1759           1 :         CHECK_VAL(break_info.failures, 0);
    1760             : 
    1761           1 :         smbcli_close(cli1->tree, fnum);
    1762           1 :         smbcli_close(cli2->tree, fnum2);
    1763             : 
    1764           1 : done:
    1765           1 :         smb_raw_exit(cli1->session);
    1766           1 :         smb_raw_exit(cli2->session);
    1767           1 :         smbcli_deltree(cli1->tree, BASEDIR);
    1768           1 :         return ret;
    1769             : }
    1770             : 
    1771           1 : static bool test_raw_oplock_batch9(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
    1772             : {
    1773           1 :         const char *fname = BASEDIR "\\test_batch9.dat";
    1774             :         NTSTATUS status;
    1775           1 :         bool ret = true;
    1776             :         union smb_open io;
    1777           1 :         uint16_t fnum=0, fnum2=0;
    1778           1 :         char c = 0;
    1779             : 
    1780           1 :         if (!torture_setup_dir(cli1, BASEDIR)) {
    1781           0 :                 return false;
    1782             :         }
    1783             : 
    1784             :         /* cleanup */
    1785           1 :         smbcli_unlink(cli1->tree, fname);
    1786             : 
    1787           1 :         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
    1788             : 
    1789             :         /*
    1790             :           base ntcreatex parms
    1791             :         */
    1792           1 :         io.generic.level = RAW_OPEN_NTCREATEX;
    1793           1 :         io.ntcreatex.in.root_fid.fnum = 0;
    1794           1 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
    1795           1 :         io.ntcreatex.in.alloc_size = 0;
    1796           1 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
    1797           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
    1798           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
    1799           1 :         io.ntcreatex.in.create_options = 0;
    1800           1 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
    1801           1 :         io.ntcreatex.in.security_flags = 0;
    1802           1 :         io.ntcreatex.in.fname = fname;
    1803             : 
    1804           1 :         torture_comment(tctx, "BATCH9: open with attributes only can create file\n");
    1805             : 
    1806           1 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | 
    1807             :                 NTCREATEX_FLAGS_REQUEST_OPLOCK | 
    1808             :                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
    1809           1 :         io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
    1810           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
    1811           1 :         status = smb_raw_open(cli1->tree, tctx, &io);
    1812           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    1813           1 :         fnum = io.ntcreatex.out.file.fnum;
    1814           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
    1815             : 
    1816           1 :         torture_comment(tctx, "Subsequent normal open should break oplock on attribute only open to level II\n");
    1817             : 
    1818           1 :         ZERO_STRUCT(break_info);
    1819           1 :         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
    1820             : 
    1821           1 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | 
    1822             :                 NTCREATEX_FLAGS_REQUEST_OPLOCK | 
    1823             :                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
    1824           1 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
    1825           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
    1826           1 :         status = smb_raw_open(cli2->tree, tctx, &io);
    1827           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    1828           1 :         fnum2 = io.ntcreatex.out.file.fnum;
    1829           1 :         torture_wait_for_oplock_break(tctx);
    1830           1 :         CHECK_VAL(break_info.count, 1);
    1831           1 :         CHECK_VAL(break_info.fnum, fnum);
    1832           1 :         CHECK_VAL(break_info.failures, 0);
    1833           1 :         CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
    1834           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
    1835           1 :         smbcli_close(cli2->tree, fnum2);
    1836             : 
    1837           1 :         torture_comment(tctx, "third oplocked open should grant level2 without break\n");
    1838           1 :         ZERO_STRUCT(break_info);
    1839           1 :         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
    1840           1 :         smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli2->tree);
    1841           1 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | 
    1842             :                 NTCREATEX_FLAGS_REQUEST_OPLOCK | 
    1843             :                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
    1844           1 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
    1845           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
    1846           1 :         status = smb_raw_open(cli2->tree, tctx, &io);
    1847           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    1848           1 :         fnum2 = io.ntcreatex.out.file.fnum;
    1849           1 :         torture_wait_for_oplock_break(tctx);
    1850           1 :         CHECK_VAL(break_info.count, 0);
    1851           1 :         CHECK_VAL(break_info.failures, 0);
    1852           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
    1853             : 
    1854           1 :         ZERO_STRUCT(break_info);
    1855             : 
    1856           1 :         torture_comment(tctx, "write should trigger a break to none on both\n");
    1857           1 :         smbcli_write(cli2->tree, fnum2, 0, &c, 0, 1);
    1858             : 
    1859             :         /* We expect two breaks */
    1860           1 :         torture_wait_for_oplock_break(tctx);
    1861           1 :         torture_wait_for_oplock_break(tctx);
    1862             : 
    1863           1 :         CHECK_VAL(break_info.count, 2);
    1864           1 :         CHECK_VAL(break_info.level, 0);
    1865           1 :         CHECK_VAL(break_info.failures, 0);
    1866             : 
    1867           1 :         smbcli_close(cli1->tree, fnum);
    1868           1 :         smbcli_close(cli2->tree, fnum2);
    1869             : 
    1870           1 : done:
    1871           1 :         smb_raw_exit(cli1->session);
    1872           1 :         smb_raw_exit(cli2->session);
    1873           1 :         smbcli_deltree(cli1->tree, BASEDIR);
    1874           1 :         return ret;
    1875             : }
    1876             : 
    1877           1 : static bool test_raw_oplock_batch9a(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
    1878             : {
    1879           1 :         const char *fname = BASEDIR "\\test_batch9a.dat";
    1880             :         NTSTATUS status;
    1881           1 :         bool ret = true;
    1882             :         union smb_open io;
    1883           1 :         uint16_t fnum=0, fnum2=0;
    1884           1 :         char c = 0;
    1885             : 
    1886           1 :         if (!torture_setup_dir(cli1, BASEDIR)) {
    1887           0 :                 return false;
    1888             :         }
    1889             : 
    1890             :         /* cleanup */
    1891           1 :         smbcli_unlink(cli1->tree, fname);
    1892             : 
    1893           1 :         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
    1894             : 
    1895             :         /*
    1896             :           base ntcreatex parms
    1897             :         */
    1898           1 :         io.generic.level = RAW_OPEN_NTCREATEX;
    1899           1 :         io.ntcreatex.in.root_fid.fnum = 0;
    1900           1 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
    1901           1 :         io.ntcreatex.in.alloc_size = 0;
    1902           1 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
    1903           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
    1904           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
    1905           1 :         io.ntcreatex.in.create_options = 0;
    1906           1 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
    1907           1 :         io.ntcreatex.in.security_flags = 0;
    1908           1 :         io.ntcreatex.in.fname = fname;
    1909             : 
    1910           1 :         torture_comment(tctx, "BATCH9: open with attributes only can create file\n");
    1911             : 
    1912           1 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
    1913             :                 NTCREATEX_FLAGS_REQUEST_OPLOCK |
    1914             :                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
    1915           1 :         io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
    1916           1 :         status = smb_raw_open(cli1->tree, tctx, &io);
    1917           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    1918           1 :         fnum = io.ntcreatex.out.file.fnum;
    1919           1 :         CHECK_VAL(io.ntcreatex.out.create_action, FILE_WAS_CREATED);
    1920           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
    1921             : 
    1922           1 :         torture_comment(tctx, "Subsequent attributes open should not break\n");
    1923             : 
    1924           1 :         ZERO_STRUCT(break_info);
    1925           1 :         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
    1926             : 
    1927           1 :         status = smb_raw_open(cli2->tree, tctx, &io);
    1928           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    1929           1 :         fnum2 = io.ntcreatex.out.file.fnum;
    1930           1 :         torture_wait_for_oplock_break(tctx);
    1931           1 :         CHECK_VAL(break_info.count, 0);
    1932           1 :         CHECK_VAL(io.ntcreatex.out.create_action, FILE_WAS_OPENED);
    1933           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, NO_OPLOCK_RETURN);
    1934           1 :         smbcli_close(cli2->tree, fnum2);
    1935             : 
    1936           1 :         torture_comment(tctx, "Subsequent normal open should break oplock on attribute only open to level II\n");
    1937             : 
    1938           1 :         ZERO_STRUCT(break_info);
    1939           1 :         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
    1940             : 
    1941           1 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
    1942             :                 NTCREATEX_FLAGS_REQUEST_OPLOCK |
    1943             :                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
    1944           1 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
    1945           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
    1946           1 :         status = smb_raw_open(cli2->tree, tctx, &io);
    1947           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    1948           1 :         fnum2 = io.ntcreatex.out.file.fnum;
    1949           1 :         torture_wait_for_oplock_break(tctx);
    1950           1 :         CHECK_VAL(break_info.count, 1);
    1951           1 :         CHECK_VAL(break_info.fnum, fnum);
    1952           1 :         CHECK_VAL(break_info.failures, 0);
    1953           1 :         CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
    1954           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
    1955           1 :         smbcli_close(cli2->tree, fnum2);
    1956             : 
    1957           1 :         torture_comment(tctx, "third oplocked open should grant level2 without break\n");
    1958           1 :         ZERO_STRUCT(break_info);
    1959           1 :         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
    1960           1 :         smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli2->tree);
    1961           1 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
    1962             :                 NTCREATEX_FLAGS_REQUEST_OPLOCK |
    1963             :                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
    1964           1 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
    1965           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
    1966           1 :         status = smb_raw_open(cli2->tree, tctx, &io);
    1967           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    1968           1 :         fnum2 = io.ntcreatex.out.file.fnum;
    1969           1 :         torture_wait_for_oplock_break(tctx);
    1970           1 :         CHECK_VAL(break_info.count, 0);
    1971           1 :         CHECK_VAL(break_info.failures, 0);
    1972           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
    1973             : 
    1974           1 :         ZERO_STRUCT(break_info);
    1975             : 
    1976           1 :         torture_comment(tctx, "write should trigger a break to none on both\n");
    1977           1 :         smbcli_write(cli2->tree, fnum2, 0, &c, 0, 1);
    1978             : 
    1979             :         /* We expect two breaks */
    1980           1 :         torture_wait_for_oplock_break(tctx);
    1981           1 :         torture_wait_for_oplock_break(tctx);
    1982             : 
    1983           1 :         CHECK_VAL(break_info.count, 2);
    1984           1 :         CHECK_VAL(break_info.level, 0);
    1985           1 :         CHECK_VAL(break_info.failures, 0);
    1986             : 
    1987           1 :         smbcli_close(cli1->tree, fnum);
    1988           1 :         smbcli_close(cli2->tree, fnum2);
    1989             : 
    1990           1 : done:
    1991           1 :         smb_raw_exit(cli1->session);
    1992           1 :         smb_raw_exit(cli2->session);
    1993           1 :         smbcli_deltree(cli1->tree, BASEDIR);
    1994           1 :         return ret;
    1995             : }
    1996             : 
    1997           1 : static bool test_raw_oplock_batch10(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
    1998             : {
    1999           1 :         const char *fname = BASEDIR "\\test_batch10.dat";
    2000             :         NTSTATUS status;
    2001           1 :         bool ret = true;
    2002             :         union smb_open io;
    2003           1 :         uint16_t fnum=0, fnum2=0;
    2004             : 
    2005           1 :         if (!torture_setup_dir(cli1, BASEDIR)) {
    2006           0 :                 return false;
    2007             :         }
    2008             : 
    2009             :         /* cleanup */
    2010           1 :         smbcli_unlink(cli1->tree, fname);
    2011             : 
    2012           1 :         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
    2013             : 
    2014             :         /*
    2015             :           base ntcreatex parms
    2016             :         */
    2017           1 :         io.generic.level = RAW_OPEN_NTCREATEX;
    2018           1 :         io.ntcreatex.in.root_fid.fnum = 0;
    2019           1 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
    2020           1 :         io.ntcreatex.in.alloc_size = 0;
    2021           1 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
    2022           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
    2023           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
    2024           1 :         io.ntcreatex.in.create_options = 0;
    2025           1 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
    2026           1 :         io.ntcreatex.in.security_flags = 0;
    2027           1 :         io.ntcreatex.in.fname = fname;
    2028             : 
    2029           1 :         torture_comment(tctx, "BATCH10: Open with oplock after a non-oplock open should grant level2\n");
    2030           1 :         ZERO_STRUCT(break_info);
    2031           1 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
    2032           1 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
    2033           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
    2034             :                 NTCREATEX_SHARE_ACCESS_WRITE|
    2035             :                 NTCREATEX_SHARE_ACCESS_DELETE;
    2036           1 :         status = smb_raw_open(cli1->tree, tctx, &io);
    2037           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    2038           1 :         fnum = io.ntcreatex.out.file.fnum;
    2039           1 :         torture_wait_for_oplock_break(tctx);
    2040           1 :         CHECK_VAL(break_info.count, 0);
    2041           1 :         CHECK_VAL(break_info.failures, 0);
    2042           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
    2043             : 
    2044             :         {
    2045             :                 union smb_write wr;
    2046           1 :                 wr.write.level = RAW_WRITE_WRITE;
    2047           1 :                 wr.write.in.file.fnum = fnum;
    2048           1 :                 wr.write.in.count = 1;
    2049           1 :                 wr.write.in.offset = 0;
    2050           1 :                 wr.write.in.remaining = 0;
    2051           1 :                 wr.write.in.data = (const uint8_t *)"x";
    2052           1 :                 status = smb_raw_write(cli1->tree, &wr);
    2053           1 :                 CHECK_STATUS(tctx, status, NT_STATUS_OK);
    2054             :         }
    2055             : 
    2056           1 :         smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli2->tree);
    2057             : 
    2058           1 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
    2059             :                 NTCREATEX_FLAGS_REQUEST_OPLOCK | 
    2060             :                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
    2061           1 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
    2062           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
    2063             :                 NTCREATEX_SHARE_ACCESS_WRITE|
    2064             :                 NTCREATEX_SHARE_ACCESS_DELETE;
    2065           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
    2066           1 :         status = smb_raw_open(cli2->tree, tctx, &io);
    2067           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    2068           1 :         fnum2 = io.ntcreatex.out.file.fnum;
    2069           1 :         torture_wait_for_oplock_break(tctx);
    2070           1 :         CHECK_VAL(break_info.count, 0);
    2071           1 :         CHECK_VAL(break_info.failures, 0);
    2072           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
    2073             : 
    2074           1 :         torture_comment(tctx, "write should trigger a break to none\n");
    2075             :         {
    2076             :                 union smb_write wr;
    2077           1 :                 wr.write.level = RAW_WRITE_WRITE;
    2078           1 :                 wr.write.in.file.fnum = fnum;
    2079           1 :                 wr.write.in.count = 1;
    2080           1 :                 wr.write.in.offset = 0;
    2081           1 :                 wr.write.in.remaining = 0;
    2082           1 :                 wr.write.in.data = (const uint8_t *)"x";
    2083           1 :                 status = smb_raw_write(cli1->tree, &wr);
    2084           1 :                 CHECK_STATUS(tctx, status, NT_STATUS_OK);
    2085             :         }
    2086             : 
    2087           1 :         torture_wait_for_oplock_break(tctx);
    2088             : 
    2089           1 :         CHECK_VAL(break_info.count, 1);
    2090           1 :         CHECK_VAL(break_info.fnum, fnum2);
    2091           1 :         CHECK_VAL(break_info.level, 0);
    2092           1 :         CHECK_VAL(break_info.failures, 0);
    2093             : 
    2094           1 :         smbcli_close(cli1->tree, fnum);
    2095           1 :         smbcli_close(cli2->tree, fnum2);
    2096             : 
    2097           1 : done:
    2098           1 :         smb_raw_exit(cli1->session);
    2099           1 :         smb_raw_exit(cli2->session);
    2100           1 :         smbcli_deltree(cli1->tree, BASEDIR);
    2101           1 :         return ret;
    2102             : }
    2103             : 
    2104           1 : static bool test_raw_oplock_batch11(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
    2105             : {
    2106           1 :         const char *fname = BASEDIR "\\test_batch11.dat";
    2107             :         NTSTATUS status;
    2108           1 :         bool ret = true;
    2109             :         union smb_open io;
    2110             :         union smb_setfileinfo sfi;
    2111           1 :         uint16_t fnum=0;
    2112             : 
    2113           1 :         if (!torture_setup_dir(cli1, BASEDIR)) {
    2114           0 :                 return false;
    2115             :         }
    2116             : 
    2117             :         /* cleanup */
    2118           1 :         smbcli_unlink(cli1->tree, fname);
    2119             : 
    2120           1 :         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
    2121             : 
    2122             :         /*
    2123             :           base ntcreatex parms
    2124             :         */
    2125           1 :         io.generic.level = RAW_OPEN_NTCREATEX;
    2126           1 :         io.ntcreatex.in.root_fid.fnum = 0;
    2127           1 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
    2128           1 :         io.ntcreatex.in.alloc_size = 0;
    2129           1 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
    2130           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_WRITE;
    2131           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
    2132           1 :         io.ntcreatex.in.create_options = 0;
    2133           1 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
    2134           1 :         io.ntcreatex.in.security_flags = 0;
    2135           1 :         io.ntcreatex.in.fname = fname;
    2136             : 
    2137             :         /* Test if a set-eof on pathname breaks an exclusive oplock. */
    2138           1 :         torture_comment(tctx, "BATCH11: Test if setpathinfo set EOF breaks oplocks.\n");
    2139             : 
    2140           1 :         ZERO_STRUCT(break_info);
    2141             : 
    2142           1 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
    2143             :                 NTCREATEX_FLAGS_REQUEST_OPLOCK |
    2144             :                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
    2145           1 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
    2146           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
    2147             :                 NTCREATEX_SHARE_ACCESS_WRITE|
    2148             :                 NTCREATEX_SHARE_ACCESS_DELETE;
    2149           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
    2150           1 :         status = smb_raw_open(cli1->tree, tctx, &io);
    2151           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    2152           1 :         fnum = io.ntcreatex.out.file.fnum;
    2153           1 :         torture_wait_for_oplock_break(tctx);
    2154           1 :         CHECK_VAL(break_info.count, 0);
    2155           1 :         CHECK_VAL(break_info.failures, 0);
    2156           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
    2157             : 
    2158           1 :         ZERO_STRUCT(sfi);
    2159           1 :         sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
    2160           1 :         sfi.generic.in.file.path = fname;
    2161           1 :         sfi.end_of_file_info.in.size = 100;
    2162             : 
    2163           1 :         status = smb_raw_setpathinfo(cli2->tree, &sfi);
    2164           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    2165             : 
    2166           1 :         torture_wait_for_oplock_break(tctx);
    2167           1 :         CHECK_VAL(break_info.count, get_setinfo_break_count(tctx));
    2168           1 :         CHECK_VAL(break_info.failures, 0);
    2169           1 :         CHECK_VAL(break_info.level, 0);
    2170             : 
    2171           1 :         smbcli_close(cli1->tree, fnum);
    2172             : 
    2173           1 : done:
    2174           1 :         smb_raw_exit(cli1->session);
    2175           1 :         smb_raw_exit(cli2->session);
    2176           1 :         smbcli_deltree(cli1->tree, BASEDIR);
    2177           1 :         return ret;
    2178             : }
    2179             : 
    2180           1 : static bool test_raw_oplock_batch12(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
    2181             : {
    2182           1 :         const char *fname = BASEDIR "\\test_batch12.dat";
    2183             :         NTSTATUS status;
    2184           1 :         bool ret = true;
    2185             :         union smb_open io;
    2186             :         union smb_setfileinfo sfi;
    2187           1 :         uint16_t fnum=0;
    2188             : 
    2189           1 :         if (!torture_setup_dir(cli1, BASEDIR)) {
    2190           0 :                 return false;
    2191             :         }
    2192             : 
    2193             :         /* cleanup */
    2194           1 :         smbcli_unlink(cli1->tree, fname);
    2195             : 
    2196           1 :         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
    2197             : 
    2198             :         /*
    2199             :           base ntcreatex parms
    2200             :         */
    2201           1 :         io.generic.level = RAW_OPEN_NTCREATEX;
    2202           1 :         io.ntcreatex.in.root_fid.fnum = 0;
    2203           1 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
    2204           1 :         io.ntcreatex.in.alloc_size = 0;
    2205           1 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
    2206           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
    2207           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
    2208           1 :         io.ntcreatex.in.create_options = 0;
    2209           1 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
    2210           1 :         io.ntcreatex.in.security_flags = 0;
    2211           1 :         io.ntcreatex.in.fname = fname;
    2212             : 
    2213             :         /* Test if a set-allocation size on pathname breaks an exclusive oplock. */
    2214           1 :         torture_comment(tctx, "BATCH12: Test if setpathinfo allocation size breaks oplocks.\n");
    2215             : 
    2216           1 :         ZERO_STRUCT(break_info);
    2217           1 :         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
    2218             : 
    2219           1 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
    2220             :                 NTCREATEX_FLAGS_REQUEST_OPLOCK |
    2221             :                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
    2222           1 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
    2223           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
    2224             :                 NTCREATEX_SHARE_ACCESS_WRITE|
    2225             :                 NTCREATEX_SHARE_ACCESS_DELETE;
    2226           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
    2227           1 :         status = smb_raw_open(cli1->tree, tctx, &io);
    2228           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    2229           1 :         fnum = io.ntcreatex.out.file.fnum;
    2230           1 :         torture_wait_for_oplock_break(tctx);
    2231           1 :         CHECK_VAL(break_info.count, 0);
    2232           1 :         CHECK_VAL(break_info.failures, 0);
    2233           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
    2234             : 
    2235           1 :         ZERO_STRUCT(sfi);
    2236           1 :         sfi.generic.level = SMB_SFILEINFO_ALLOCATION_INFORMATION;
    2237           1 :         sfi.generic.in.file.path = fname;
    2238           1 :         sfi.allocation_info.in.alloc_size = 65536 * 8;
    2239             : 
    2240           1 :         status = smb_raw_setpathinfo(cli2->tree, &sfi);
    2241           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    2242             : 
    2243           1 :         torture_wait_for_oplock_break(tctx);
    2244           1 :         CHECK_VAL(break_info.count, get_setinfo_break_count(tctx));
    2245           1 :         CHECK_VAL(break_info.failures, 0);
    2246           1 :         CHECK_VAL(break_info.level, 0);
    2247             : 
    2248           1 :         smbcli_close(cli1->tree, fnum);
    2249             : 
    2250           1 : done:
    2251           1 :         smb_raw_exit(cli1->session);
    2252           1 :         smb_raw_exit(cli2->session);
    2253           1 :         smbcli_deltree(cli1->tree, BASEDIR);
    2254           1 :         return ret;
    2255             : }
    2256             : 
    2257           1 : static bool test_raw_oplock_batch13(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
    2258             : {
    2259           1 :         const char *fname = BASEDIR "\\test_batch13.dat";
    2260             :         NTSTATUS status;
    2261           1 :         bool ret = true;
    2262             :         union smb_open io;
    2263           1 :         uint16_t fnum=0, fnum2=0;
    2264             : 
    2265           1 :         if (!torture_setup_dir(cli1, BASEDIR)) {
    2266           0 :                 return false;
    2267             :         }
    2268             : 
    2269             :         /* cleanup */
    2270           1 :         smbcli_unlink(cli1->tree, fname);
    2271             : 
    2272           1 :         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
    2273           1 :         smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli1->tree);
    2274             : 
    2275             :         /*
    2276             :           base ntcreatex parms
    2277             :         */
    2278           1 :         io.generic.level = RAW_OPEN_NTCREATEX;
    2279           1 :         io.ntcreatex.in.root_fid.fnum = 0;
    2280           1 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
    2281           1 :         io.ntcreatex.in.alloc_size = 0;
    2282           1 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
    2283           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
    2284           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
    2285           1 :         io.ntcreatex.in.create_options = 0;
    2286           1 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
    2287           1 :         io.ntcreatex.in.security_flags = 0;
    2288           1 :         io.ntcreatex.in.fname = fname;
    2289             : 
    2290           1 :         torture_comment(tctx, "BATCH13: open with batch oplock\n");
    2291           1 :         ZERO_STRUCT(break_info);
    2292             : 
    2293           1 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | 
    2294             :                 NTCREATEX_FLAGS_REQUEST_OPLOCK | 
    2295             :                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
    2296           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
    2297             :                 NTCREATEX_SHARE_ACCESS_WRITE|
    2298             :                 NTCREATEX_SHARE_ACCESS_DELETE;
    2299           1 :         status = smb_raw_open(cli1->tree, tctx, &io);
    2300           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    2301           1 :         fnum = io.ntcreatex.out.file.fnum;
    2302           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
    2303             : 
    2304           1 :         ZERO_STRUCT(break_info);
    2305             : 
    2306           1 :         torture_comment(tctx, "second open with attributes only and NTCREATEX_DISP_OVERWRITE dispostion causes oplock break\n");
    2307             : 
    2308           1 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | 
    2309             :                 NTCREATEX_FLAGS_REQUEST_OPLOCK | 
    2310             :                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
    2311           1 :         io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
    2312           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
    2313             :                 NTCREATEX_SHARE_ACCESS_WRITE|
    2314             :                 NTCREATEX_SHARE_ACCESS_DELETE;
    2315           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE;
    2316           1 :         status = smb_raw_open(cli2->tree, tctx, &io);
    2317           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    2318           1 :         fnum2 = io.ntcreatex.out.file.fnum;
    2319           1 :         torture_wait_for_oplock_break(tctx);
    2320           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
    2321           1 :         CHECK_VAL(break_info.count, get_break_level1_to_none_count(tctx));
    2322           1 :         CHECK_VAL(break_info.failures, 0);
    2323             : 
    2324           1 :         smbcli_close(cli1->tree, fnum);
    2325           1 :         smbcli_close(cli2->tree, fnum2);
    2326             : 
    2327           1 : done:
    2328           1 :         smb_raw_exit(cli1->session);
    2329           1 :         smb_raw_exit(cli2->session);
    2330           1 :         smbcli_deltree(cli1->tree, BASEDIR);
    2331           1 :         return ret;
    2332             : }
    2333             : 
    2334           1 : static bool test_raw_oplock_batch14(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
    2335             : {
    2336           1 :         const char *fname = BASEDIR "\\test_batch14.dat";
    2337             :         NTSTATUS status;
    2338           1 :         bool ret = true;
    2339             :         union smb_open io;
    2340           1 :         uint16_t fnum=0, fnum2=0;
    2341             : 
    2342           1 :         if (!torture_setup_dir(cli1, BASEDIR)) {
    2343           0 :                 return false;
    2344             :         }
    2345             : 
    2346             :         /* cleanup */
    2347           1 :         smbcli_unlink(cli1->tree, fname);
    2348             : 
    2349           1 :         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
    2350             : 
    2351             :         /*
    2352             :           base ntcreatex parms
    2353             :         */
    2354           1 :         io.generic.level = RAW_OPEN_NTCREATEX;
    2355           1 :         io.ntcreatex.in.root_fid.fnum = 0;
    2356           1 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
    2357           1 :         io.ntcreatex.in.alloc_size = 0;
    2358           1 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
    2359           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
    2360           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
    2361           1 :         io.ntcreatex.in.create_options = 0;
    2362           1 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
    2363           1 :         io.ntcreatex.in.security_flags = 0;
    2364           1 :         io.ntcreatex.in.fname = fname;
    2365             : 
    2366           1 :         torture_comment(tctx, "BATCH14: open with batch oplock\n");
    2367           1 :         ZERO_STRUCT(break_info);
    2368             : 
    2369           1 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | 
    2370             :                 NTCREATEX_FLAGS_REQUEST_OPLOCK | 
    2371             :                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
    2372           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
    2373             :                 NTCREATEX_SHARE_ACCESS_WRITE|
    2374             :                 NTCREATEX_SHARE_ACCESS_DELETE;
    2375           1 :         status = smb_raw_open(cli1->tree, tctx, &io);
    2376           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    2377           1 :         fnum = io.ntcreatex.out.file.fnum;
    2378           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
    2379             : 
    2380           1 :         ZERO_STRUCT(break_info);
    2381             : 
    2382           1 :         torture_comment(tctx, "second open with attributes only and NTCREATEX_DISP_SUPERSEDE dispostion causes oplock break\n");
    2383             : 
    2384           1 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | 
    2385             :                 NTCREATEX_FLAGS_REQUEST_OPLOCK | 
    2386             :                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
    2387           1 :         io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
    2388           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
    2389             :                 NTCREATEX_SHARE_ACCESS_WRITE|
    2390             :                 NTCREATEX_SHARE_ACCESS_DELETE;
    2391           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE;
    2392           1 :         status = smb_raw_open(cli2->tree, tctx, &io);
    2393           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    2394           1 :         fnum2 = io.ntcreatex.out.file.fnum;
    2395           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
    2396             : 
    2397           1 :         torture_wait_for_oplock_break(tctx);
    2398           1 :         CHECK_VAL(break_info.count, get_break_level1_to_none_count(tctx));
    2399           1 :         CHECK_VAL(break_info.failures, 0);
    2400             : 
    2401           1 :         smbcli_close(cli1->tree, fnum);
    2402           1 :         smbcli_close(cli2->tree, fnum2);
    2403           1 : done:
    2404           1 :         smb_raw_exit(cli1->session);
    2405           1 :         smb_raw_exit(cli2->session);
    2406           1 :         smbcli_deltree(cli1->tree, BASEDIR);
    2407           1 :         return ret;
    2408             : }
    2409             : 
    2410           1 : static bool test_raw_oplock_batch15(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
    2411             : {
    2412           1 :         const char *fname = BASEDIR "\\test_batch15.dat";
    2413             :         NTSTATUS status;
    2414           1 :         bool ret = true;
    2415             :         union smb_open io;
    2416             :         union smb_fileinfo qfi;
    2417           1 :         uint16_t fnum=0;
    2418             : 
    2419           1 :         if (!torture_setup_dir(cli1, BASEDIR)) {
    2420           0 :                 return false;
    2421             :         }
    2422             : 
    2423             :         /* cleanup */
    2424           1 :         smbcli_unlink(cli1->tree, fname);
    2425             : 
    2426           1 :         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
    2427             : 
    2428             :         /*
    2429             :           base ntcreatex parms
    2430             :         */
    2431           1 :         io.generic.level = RAW_OPEN_NTCREATEX;
    2432           1 :         io.ntcreatex.in.root_fid.fnum = 0;
    2433           1 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
    2434           1 :         io.ntcreatex.in.alloc_size = 0;
    2435           1 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
    2436           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
    2437           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
    2438           1 :         io.ntcreatex.in.create_options = 0;
    2439           1 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
    2440           1 :         io.ntcreatex.in.security_flags = 0;
    2441           1 :         io.ntcreatex.in.fname = fname;
    2442             : 
    2443             :         /* Test if a qpathinfo all info on pathname breaks a batch oplock. */
    2444           1 :         torture_comment(tctx, "BATCH15: Test if qpathinfo all info breaks a batch oplock (should not).\n");
    2445             : 
    2446           1 :         ZERO_STRUCT(break_info);
    2447             : 
    2448           1 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
    2449             :                 NTCREATEX_FLAGS_REQUEST_OPLOCK |
    2450             :                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
    2451           1 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
    2452           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
    2453             :                 NTCREATEX_SHARE_ACCESS_WRITE|
    2454             :                 NTCREATEX_SHARE_ACCESS_DELETE;
    2455           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
    2456           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
    2457           1 :         status = smb_raw_open(cli1->tree, tctx, &io);
    2458           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    2459           1 :         fnum = io.ntcreatex.out.file.fnum;
    2460             : 
    2461           1 :         torture_wait_for_oplock_break(tctx);
    2462           1 :         CHECK_VAL(break_info.count, 0);
    2463           1 :         CHECK_VAL(break_info.failures, 0);
    2464           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
    2465             : 
    2466           1 :         ZERO_STRUCT(qfi);
    2467           1 :         qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
    2468           1 :         qfi.generic.in.file.path = fname;
    2469             : 
    2470           1 :         status = smb_raw_pathinfo(cli2->tree, tctx, &qfi);
    2471           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    2472             : 
    2473           1 :         torture_wait_for_oplock_break(tctx);
    2474           1 :         CHECK_VAL(break_info.count, 0);
    2475             : 
    2476           1 :         smbcli_close(cli1->tree, fnum);
    2477             : 
    2478           1 : done:
    2479           1 :         smb_raw_exit(cli1->session);
    2480           1 :         smb_raw_exit(cli2->session);
    2481           1 :         smbcli_deltree(cli1->tree, BASEDIR);
    2482           1 :         return ret;
    2483             : }
    2484             : 
    2485           1 : static bool test_raw_oplock_batch16(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
    2486             : {
    2487           1 :         const char *fname = BASEDIR "\\test_batch16.dat";
    2488             :         NTSTATUS status;
    2489           1 :         bool ret = true;
    2490             :         union smb_open io;
    2491           1 :         uint16_t fnum=0, fnum2=0;
    2492             : 
    2493           1 :         if (!torture_setup_dir(cli1, BASEDIR)) {
    2494           0 :                 return false;
    2495             :         }
    2496             : 
    2497             :         /* cleanup */
    2498           1 :         smbcli_unlink(cli1->tree, fname);
    2499             : 
    2500           1 :         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
    2501           1 :         smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli1->tree);
    2502             : 
    2503             :         /*
    2504             :           base ntcreatex parms
    2505             :         */
    2506           1 :         io.generic.level = RAW_OPEN_NTCREATEX;
    2507           1 :         io.ntcreatex.in.root_fid.fnum = 0;
    2508           1 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
    2509           1 :         io.ntcreatex.in.alloc_size = 0;
    2510           1 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
    2511           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
    2512           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
    2513           1 :         io.ntcreatex.in.create_options = 0;
    2514           1 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
    2515           1 :         io.ntcreatex.in.security_flags = 0;
    2516           1 :         io.ntcreatex.in.fname = fname;
    2517             : 
    2518           1 :         torture_comment(tctx, "BATCH16: open with batch oplock\n");
    2519           1 :         ZERO_STRUCT(break_info);
    2520             : 
    2521           1 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
    2522             :                 NTCREATEX_FLAGS_REQUEST_OPLOCK |
    2523             :                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
    2524           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
    2525             :                 NTCREATEX_SHARE_ACCESS_WRITE|
    2526             :                 NTCREATEX_SHARE_ACCESS_DELETE;
    2527           1 :         status = smb_raw_open(cli1->tree, tctx, &io);
    2528           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    2529           1 :         fnum = io.ntcreatex.out.file.fnum;
    2530           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
    2531             : 
    2532           1 :         ZERO_STRUCT(break_info);
    2533             : 
    2534           1 :         torture_comment(tctx, "second open with attributes only and NTCREATEX_DISP_OVERWRITE_IF dispostion causes oplock break\n");
    2535             : 
    2536           1 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
    2537             :                 NTCREATEX_FLAGS_REQUEST_OPLOCK |
    2538             :                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
    2539           1 :         io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
    2540           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
    2541             :                 NTCREATEX_SHARE_ACCESS_WRITE|
    2542             :                 NTCREATEX_SHARE_ACCESS_DELETE;
    2543           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE_IF;
    2544           1 :         status = smb_raw_open(cli2->tree, tctx, &io);
    2545           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    2546           1 :         fnum2 = io.ntcreatex.out.file.fnum;
    2547           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
    2548             : 
    2549           1 :         torture_wait_for_oplock_break(tctx);
    2550           1 :         CHECK_VAL(break_info.count, get_break_level1_to_none_count(tctx));
    2551           1 :         CHECK_VAL(break_info.failures, 0);
    2552             : 
    2553           1 :         smbcli_close(cli1->tree, fnum);
    2554           1 :         smbcli_close(cli2->tree, fnum2);
    2555             : 
    2556           1 : done:
    2557           1 :         smb_raw_exit(cli1->session);
    2558           1 :         smb_raw_exit(cli2->session);
    2559           1 :         smbcli_deltree(cli1->tree, BASEDIR);
    2560           1 :         return ret;
    2561             : }
    2562             : 
    2563           1 : static bool test_raw_oplock_batch17(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
    2564             : {
    2565           1 :         const char *fname1 = BASEDIR "\\test_batch17_1.dat";
    2566           1 :         const char *fname2 = BASEDIR "\\test_batch17_2.dat";
    2567             :         NTSTATUS status;
    2568           1 :         bool ret = true;
    2569             :         union smb_open io;
    2570             :         union smb_rename rn;
    2571           1 :         uint16_t fnum=0;
    2572             : 
    2573           1 :         if (!torture_setup_dir(cli1, BASEDIR)) {
    2574           0 :                 return false;
    2575             :         }
    2576             : 
    2577             :         /* cleanup */
    2578           1 :         smbcli_unlink(cli1->tree, fname1);
    2579           1 :         smbcli_unlink(cli1->tree, fname2);
    2580             : 
    2581           1 :         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
    2582             : 
    2583             :         /*
    2584             :           base ntcreatex parms
    2585             :         */
    2586           1 :         io.generic.level = RAW_OPEN_NTCREATEX;
    2587           1 :         io.ntcreatex.in.root_fid.fnum = 0;
    2588           1 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
    2589           1 :         io.ntcreatex.in.alloc_size = 0;
    2590           1 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
    2591           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
    2592           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
    2593           1 :         io.ntcreatex.in.create_options = 0;
    2594           1 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
    2595           1 :         io.ntcreatex.in.security_flags = 0;
    2596           1 :         io.ntcreatex.in.fname = fname1;
    2597             : 
    2598           1 :         torture_comment(tctx, "BATCH17: open a file with an batch oplock (share mode: none)\n");
    2599             : 
    2600           1 :         ZERO_STRUCT(break_info);
    2601           1 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
    2602             :                 NTCREATEX_FLAGS_REQUEST_OPLOCK |
    2603             :                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
    2604             : 
    2605           1 :         status = smb_raw_open(cli1->tree, tctx, &io);
    2606           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    2607           1 :         fnum = io.ntcreatex.out.file.fnum;
    2608           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
    2609             : 
    2610           1 :         torture_comment(tctx, "rename should trigger a break\n");
    2611           1 :         ZERO_STRUCT(rn);
    2612           1 :         rn.generic.level = RAW_RENAME_RENAME;
    2613           1 :         rn.rename.in.pattern1 = fname1;
    2614           1 :         rn.rename.in.pattern2 = fname2;
    2615           1 :         rn.rename.in.attrib = 0;
    2616             : 
    2617           1 :         torture_comment(tctx, "trying rename while first file open\n");
    2618           1 :         status = smb_raw_rename(cli2->tree, &rn);
    2619           1 :         CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
    2620             : 
    2621           1 :         torture_wait_for_oplock_break(tctx);
    2622           1 :         CHECK_VAL(break_info.count, 1);
    2623           1 :         CHECK_VAL(break_info.failures, 0);
    2624           1 :         CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
    2625             : 
    2626           1 :         smbcli_close(cli1->tree, fnum);
    2627             : 
    2628           1 : done:
    2629           1 :         smb_raw_exit(cli1->session);
    2630           1 :         smb_raw_exit(cli2->session);
    2631           1 :         smbcli_deltree(cli1->tree, BASEDIR);
    2632           1 :         return ret;
    2633             : }
    2634             : 
    2635           1 : static bool test_raw_oplock_batch18(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
    2636             : {
    2637           1 :         const char *fname1 = BASEDIR "\\test_batch18_1.dat";
    2638           1 :         const char *fname2 = BASEDIR "\\test_batch18_2.dat";
    2639             :         NTSTATUS status;
    2640           1 :         bool ret = true;
    2641             :         union smb_open io;
    2642             :         union smb_rename rn;
    2643           1 :         uint16_t fnum=0;
    2644             : 
    2645           1 :         if (!torture_setup_dir(cli1, BASEDIR)) {
    2646           0 :                 return false;
    2647             :         }
    2648             : 
    2649             :         /* cleanup */
    2650           1 :         smbcli_unlink(cli1->tree, fname1);
    2651           1 :         smbcli_unlink(cli1->tree, fname2);
    2652             : 
    2653           1 :         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
    2654             : 
    2655             :         /*
    2656             :           base ntcreatex parms
    2657             :         */
    2658           1 :         io.generic.level = RAW_OPEN_NTCREATEX;
    2659           1 :         io.ntcreatex.in.root_fid.fnum = 0;
    2660           1 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
    2661           1 :         io.ntcreatex.in.alloc_size = 0;
    2662           1 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
    2663           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
    2664           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
    2665           1 :         io.ntcreatex.in.create_options = 0;
    2666           1 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
    2667           1 :         io.ntcreatex.in.security_flags = 0;
    2668           1 :         io.ntcreatex.in.fname = fname1;
    2669             : 
    2670           1 :         torture_comment(tctx, "BATCH18: open a file with an batch oplock (share mode: none)\n");
    2671             : 
    2672           1 :         ZERO_STRUCT(break_info);
    2673           1 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
    2674             :                 NTCREATEX_FLAGS_REQUEST_OPLOCK |
    2675             :                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
    2676             : 
    2677           1 :         status = smb_raw_open(cli1->tree, tctx, &io);
    2678           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    2679           1 :         fnum = io.ntcreatex.out.file.fnum;
    2680           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
    2681             : 
    2682           1 :         torture_comment(tctx, "ntrename should trigger a break\n");
    2683           1 :         ZERO_STRUCT(rn);
    2684           1 :         rn.generic.level = RAW_RENAME_NTRENAME;
    2685           1 :         rn.ntrename.in.attrib   = 0;
    2686           1 :         rn.ntrename.in.flags    = RENAME_FLAG_RENAME;
    2687           1 :         rn.ntrename.in.old_name = fname1;
    2688           1 :         rn.ntrename.in.new_name = fname2;
    2689           1 :         torture_comment(tctx, "trying rename while first file open\n");
    2690           1 :         status = smb_raw_rename(cli2->tree, &rn);
    2691           1 :         CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
    2692             : 
    2693           1 :         torture_wait_for_oplock_break(tctx);
    2694           1 :         CHECK_VAL(break_info.count, 1);
    2695           1 :         CHECK_VAL(break_info.failures, 0);
    2696           1 :         CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
    2697             : 
    2698           1 :         smbcli_close(cli1->tree, fnum);
    2699             : 
    2700           1 : done:
    2701           1 :         smb_raw_exit(cli1->session);
    2702           1 :         smb_raw_exit(cli2->session);
    2703           1 :         smbcli_deltree(cli1->tree, BASEDIR);
    2704           1 :         return ret;
    2705             : }
    2706             : 
    2707           1 : static bool test_raw_oplock_batch19(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
    2708             : {
    2709           1 :         const char *fname1 = BASEDIR "\\test_batch19_1.dat";
    2710           1 :         const char *fname2 = BASEDIR "\\test_batch19_2.dat";
    2711           1 :         const char *fname3 = BASEDIR "\\test_batch19_3.dat";
    2712             :         NTSTATUS status;
    2713           1 :         bool ret = true;
    2714             :         union smb_open io;
    2715             :         union smb_fileinfo qfi;
    2716             :         union smb_setfileinfo sfi;
    2717           1 :         uint16_t fnum=0;
    2718             : 
    2719           1 :         if (!torture_setup_dir(cli1, BASEDIR)) {
    2720           0 :                 return false;
    2721             :         }
    2722             : 
    2723             :         /* cleanup */
    2724           1 :         smbcli_unlink(cli1->tree, fname1);
    2725           1 :         smbcli_unlink(cli1->tree, fname2);
    2726           1 :         smbcli_unlink(cli1->tree, fname3);
    2727             : 
    2728           1 :         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
    2729             : 
    2730             :         /*
    2731             :           base ntcreatex parms
    2732             :         */
    2733           1 :         io.generic.level = RAW_OPEN_NTCREATEX;
    2734           1 :         io.ntcreatex.in.root_fid.fnum = 0;
    2735           1 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
    2736           1 :         io.ntcreatex.in.alloc_size = 0;
    2737           1 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
    2738           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
    2739             :             NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_DELETE;
    2740           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
    2741           1 :         io.ntcreatex.in.create_options = 0;
    2742           1 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
    2743           1 :         io.ntcreatex.in.security_flags = 0;
    2744           1 :         io.ntcreatex.in.fname = fname1;
    2745             : 
    2746           1 :         torture_comment(tctx, "BATCH19: open a file with an batch oplock (share mode: none)\n");
    2747           1 :         ZERO_STRUCT(break_info);
    2748           1 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
    2749             :                 NTCREATEX_FLAGS_REQUEST_OPLOCK |
    2750             :                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
    2751           1 :         status = smb_raw_open(cli1->tree, tctx, &io);
    2752           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    2753           1 :         fnum = io.ntcreatex.out.file.fnum;
    2754           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
    2755             : 
    2756           1 :         torture_comment(tctx, "setpathinfo rename info should trigger a break "
    2757             :             "to none\n");
    2758           1 :         ZERO_STRUCT(sfi);
    2759           1 :         sfi.generic.level = RAW_SFILEINFO_RENAME_INFORMATION;
    2760           1 :         sfi.generic.in.file.path = fname1;
    2761           1 :         sfi.rename_information.in.overwrite     = 0;
    2762           1 :         sfi.rename_information.in.root_fid      = 0;
    2763           1 :         sfi.rename_information.in.new_name      = fname2+strlen(BASEDIR)+1;
    2764             : 
    2765           1 :         status = smb_raw_setpathinfo(cli2->tree, &sfi);
    2766           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    2767             : 
    2768           1 :         torture_wait_for_oplock_break(tctx);
    2769             : 
    2770           1 :         CHECK_VAL(break_info.failures, 0);
    2771             : 
    2772           1 :         if (TARGET_IS_WINXP(tctx) || TARGET_IS_W2K12(tctx)) {
    2773             :                 /* Win XP breaks to level2. */
    2774           0 :                 CHECK_VAL(break_info.count, 1);
    2775           0 :                 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
    2776           2 :         } else if (TARGET_IS_W2K3(tctx) || TARGET_IS_W2K8(tctx) ||
    2777           2 :             TARGET_IS_SAMBA3(tctx) || TARGET_IS_SAMBA4(tctx)) {
    2778             :                 /* Win2K3/2k8 incorrectly doesn't break at all. */
    2779           1 :                 CHECK_VAL(break_info.count, 0);
    2780             :         } else {
    2781             :                 /* win7/2k8r2 break to none. */
    2782           0 :                 CHECK_VAL(break_info.count, 1);
    2783           0 :                 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_NONE);
    2784             :         }
    2785             : 
    2786           1 :         ZERO_STRUCT(qfi);
    2787           1 :         qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
    2788           1 :         qfi.generic.in.file.fnum = fnum;
    2789             : 
    2790           1 :         status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
    2791           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    2792           1 :         CHECK_STRMATCH(qfi.all_info.out.fname.s, fname2);
    2793             : 
    2794             :         /* Close and re-open file with oplock. */
    2795           1 :         smbcli_close(cli1->tree, fnum);
    2796           1 :         status = smb_raw_open(cli1->tree, tctx, &io);
    2797           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    2798           1 :         fnum = io.ntcreatex.out.file.fnum;
    2799           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
    2800             : 
    2801           1 :         torture_comment(tctx, "setfileinfo rename info on a client's own fid "
    2802             :             "should not trigger a break nor a violation\n");
    2803           1 :         ZERO_STRUCT(break_info);
    2804           1 :         ZERO_STRUCT(sfi);
    2805           1 :         sfi.generic.level = RAW_SFILEINFO_RENAME_INFORMATION;
    2806           1 :         sfi.generic.in.file.fnum = fnum;
    2807           1 :         sfi.rename_information.in.overwrite     = 0;
    2808           1 :         sfi.rename_information.in.root_fid      = 0;
    2809           1 :         sfi.rename_information.in.new_name      = fname3+strlen(BASEDIR)+1;
    2810             : 
    2811           1 :         status = smb_raw_setfileinfo(cli1->tree, &sfi);
    2812           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    2813             : 
    2814           1 :         torture_wait_for_oplock_break(tctx);
    2815           1 :         if (TARGET_IS_WINXP(tctx)) {
    2816             :                 /* XP incorrectly breaks to level2. */
    2817           0 :                 CHECK_VAL(break_info.count, 1);
    2818           0 :                 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
    2819             :         } else {
    2820           1 :                 CHECK_VAL(break_info.count, 0);
    2821             :         }
    2822             : 
    2823           1 :         ZERO_STRUCT(qfi);
    2824           1 :         qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
    2825           1 :         qfi.generic.in.file.fnum = fnum;
    2826             : 
    2827           1 :         status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
    2828           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    2829           1 :         CHECK_STRMATCH(qfi.all_info.out.fname.s, fname3);
    2830             : 
    2831           2 : done:
    2832           1 :         smbcli_close(cli1->tree, fnum);
    2833           1 :         smb_raw_exit(cli1->session);
    2834           1 :         smb_raw_exit(cli2->session);
    2835           1 :         smbcli_deltree(cli1->tree, BASEDIR);
    2836           1 :         return ret;
    2837             : }
    2838             : 
    2839             : /****************************************************
    2840             :  Called from raw-rename - we need oplock handling for
    2841             :  this test so this is why it's in oplock.c, not rename.c
    2842             : ****************************************************/
    2843             : 
    2844           1 : bool test_trans2rename(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
    2845             : {
    2846           1 :         const char *fname1 = BASEDIR "\\test_trans2rename_1.dat";
    2847           1 :         const char *fname2 = BASEDIR "\\test_trans2rename_2.dat";
    2848           1 :         const char *fname3 = BASEDIR "\\test_trans2rename_3.dat";
    2849             :         NTSTATUS status;
    2850           1 :         bool ret = true;
    2851             :         union smb_open io;
    2852             :         union smb_fileinfo qfi;
    2853             :         union smb_setfileinfo sfi;
    2854           1 :         uint16_t fnum=0;
    2855             : 
    2856           1 :         if (!torture_setup_dir(cli1, BASEDIR)) {
    2857           0 :                 return false;
    2858             :         }
    2859             : 
    2860             :         /* cleanup */
    2861           1 :         smbcli_unlink(cli1->tree, fname1);
    2862           1 :         smbcli_unlink(cli1->tree, fname2);
    2863           1 :         smbcli_unlink(cli1->tree, fname3);
    2864             : 
    2865           1 :         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
    2866             : 
    2867             :         /*
    2868             :           base ntcreatex parms
    2869             :         */
    2870           1 :         io.generic.level = RAW_OPEN_NTCREATEX;
    2871           1 :         io.ntcreatex.in.root_fid.fnum = 0;
    2872           1 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
    2873           1 :         io.ntcreatex.in.alloc_size = 0;
    2874           1 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
    2875           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
    2876             :             NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_DELETE;
    2877           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
    2878           1 :         io.ntcreatex.in.create_options = 0;
    2879           1 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
    2880           1 :         io.ntcreatex.in.security_flags = 0;
    2881           1 :         io.ntcreatex.in.fname = fname1;
    2882             : 
    2883           1 :         torture_comment(tctx, "open a file with an exclusive oplock (share mode: none)\n");
    2884           1 :         ZERO_STRUCT(break_info);
    2885           1 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
    2886             :                 NTCREATEX_FLAGS_REQUEST_OPLOCK;
    2887           1 :         status = smb_raw_open(cli1->tree, tctx, &io);
    2888           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    2889           1 :         fnum = io.ntcreatex.out.file.fnum;
    2890           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
    2891             : 
    2892           1 :         torture_comment(tctx, "setpathinfo rename info should not trigger a break nor a violation\n");
    2893           1 :         ZERO_STRUCT(sfi);
    2894           1 :         sfi.generic.level = RAW_SFILEINFO_RENAME_INFORMATION;
    2895           1 :         sfi.generic.in.file.path = fname1;
    2896           1 :         sfi.rename_information.in.overwrite     = 0;
    2897           1 :         sfi.rename_information.in.root_fid      = 0;
    2898           1 :         sfi.rename_information.in.new_name      = fname2+strlen(BASEDIR)+1;
    2899             : 
    2900           1 :         status = smb_raw_setpathinfo(cli2->tree, &sfi);
    2901             : 
    2902           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    2903             : 
    2904           1 :         torture_wait_for_oplock_break(tctx);
    2905           1 :         CHECK_VAL(break_info.count, 0);
    2906             : 
    2907           1 :         ZERO_STRUCT(qfi);
    2908           1 :         qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
    2909           1 :         qfi.generic.in.file.fnum = fnum;
    2910             : 
    2911           1 :         status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
    2912           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    2913           1 :         CHECK_STRMATCH(qfi.all_info.out.fname.s, fname2);
    2914             : 
    2915           1 :         torture_comment(tctx, "setfileinfo rename info should not trigger a break nor a violation\n");
    2916           1 :         ZERO_STRUCT(sfi);
    2917           1 :         sfi.generic.level = RAW_SFILEINFO_RENAME_INFORMATION;
    2918           1 :         sfi.generic.in.file.fnum = fnum;
    2919           1 :         sfi.rename_information.in.overwrite     = 0;
    2920           1 :         sfi.rename_information.in.root_fid      = 0;
    2921           1 :         sfi.rename_information.in.new_name      = fname3+strlen(BASEDIR)+1;
    2922             : 
    2923           1 :         status = smb_raw_setfileinfo(cli1->tree, &sfi);
    2924           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    2925             : 
    2926           1 :         torture_wait_for_oplock_break(tctx);
    2927           1 :         CHECK_VAL(break_info.count, 0);
    2928             : 
    2929           1 :         ZERO_STRUCT(qfi);
    2930           1 :         qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
    2931           1 :         qfi.generic.in.file.fnum = fnum;
    2932             : 
    2933           1 :         status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
    2934           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    2935           1 :         CHECK_STRMATCH(qfi.all_info.out.fname.s, fname3);
    2936             : 
    2937           2 : done:
    2938           1 :         smbcli_close(cli1->tree, fnum);
    2939           1 :         smb_raw_exit(cli1->session);
    2940           1 :         smb_raw_exit(cli2->session);
    2941           1 :         smbcli_deltree(cli1->tree, BASEDIR);
    2942           1 :         return ret;
    2943             : }
    2944             : 
    2945             : /****************************************************
    2946             :  Called from raw-rename - we need oplock handling for
    2947             :  this test so this is why it's in oplock.c, not rename.c
    2948             : ****************************************************/
    2949             : 
    2950           1 : bool test_nttransrename(struct torture_context *tctx, struct smbcli_state *cli1)
    2951             : {
    2952           1 :         const char *fname1 = BASEDIR "\\test_nttransrename_1.dat";
    2953           1 :         const char *fname2 = BASEDIR "\\test_nttransrename_2.dat";
    2954             :         NTSTATUS status;
    2955           1 :         bool ret = true;
    2956             :         union smb_open io;
    2957             :         union smb_fileinfo qfi, qpi;
    2958             :         union smb_rename rn;
    2959           1 :         uint16_t fnum=0;
    2960             : 
    2961           1 :         if (!torture_setup_dir(cli1, BASEDIR)) {
    2962           0 :                 return false;
    2963             :         }
    2964             : 
    2965             :         /* cleanup */
    2966           1 :         smbcli_unlink(cli1->tree, fname1);
    2967           1 :         smbcli_unlink(cli1->tree, fname2);
    2968             : 
    2969           1 :         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
    2970             : 
    2971             :         /*
    2972             :           base ntcreatex parms
    2973             :         */
    2974           1 :         io.generic.level = RAW_OPEN_NTCREATEX;
    2975           1 :         io.ntcreatex.in.root_fid.fnum = 0;
    2976           1 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
    2977           1 :         io.ntcreatex.in.alloc_size = 0;
    2978           1 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
    2979           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
    2980           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
    2981           1 :         io.ntcreatex.in.create_options = 0;
    2982           1 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
    2983           1 :         io.ntcreatex.in.security_flags = 0;
    2984           1 :         io.ntcreatex.in.fname = fname1;
    2985             : 
    2986           1 :         torture_comment(tctx, "nttrans_rename: open a file with an exclusive oplock (share mode: none)\n");
    2987           1 :         ZERO_STRUCT(break_info);
    2988           1 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
    2989             :                 NTCREATEX_FLAGS_REQUEST_OPLOCK;
    2990           1 :         status = smb_raw_open(cli1->tree, tctx, &io);
    2991           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    2992           1 :         fnum = io.ntcreatex.out.file.fnum;
    2993           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
    2994             : 
    2995           1 :         torture_comment(tctx, "nttrans_rename: should not trigger a break nor a share mode violation\n");
    2996           1 :         ZERO_STRUCT(rn);
    2997           1 :         rn.generic.level = RAW_RENAME_NTTRANS;
    2998           1 :         rn.nttrans.in.file.fnum = fnum;
    2999           1 :         rn.nttrans.in.flags     = 0;
    3000           1 :         rn.nttrans.in.new_name  = fname2+strlen(BASEDIR)+1;
    3001             : 
    3002           1 :         status = smb_raw_rename(cli1->tree, &rn);
    3003           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    3004             : 
    3005           1 :         torture_wait_for_oplock_break(tctx);
    3006           1 :         CHECK_VAL(break_info.count, 0);
    3007             : 
    3008             :         /* w2k3 does nothing, it doesn't rename the file */
    3009           1 :         torture_comment(tctx, "nttrans_rename: the server should have done nothing\n");
    3010           1 :         ZERO_STRUCT(qfi);
    3011           1 :         qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
    3012           1 :         qfi.generic.in.file.fnum = fnum;
    3013             : 
    3014           1 :         status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
    3015           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    3016           1 :         CHECK_STRMATCH(qfi.all_info.out.fname.s, fname1);
    3017             : 
    3018           1 :         ZERO_STRUCT(qpi);
    3019           1 :         qpi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
    3020           1 :         qpi.generic.in.file.path = fname1;
    3021             : 
    3022           1 :         status = smb_raw_pathinfo(cli1->tree, tctx, &qpi);
    3023           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    3024           1 :         CHECK_STRMATCH(qpi.all_info.out.fname.s, fname1);
    3025             : 
    3026           1 :         ZERO_STRUCT(qpi);
    3027           1 :         qpi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
    3028           1 :         qpi.generic.in.file.path = fname2;
    3029             : 
    3030           1 :         status = smb_raw_pathinfo(cli1->tree, tctx, &qpi);
    3031           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
    3032             : 
    3033           1 :         torture_comment(tctx, "nttrans_rename: after closing the file the file is still not renamed\n");
    3034           1 :         status = smbcli_close(cli1->tree, fnum);
    3035           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    3036             : 
    3037           1 :         ZERO_STRUCT(qpi);
    3038           1 :         qpi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
    3039           1 :         qpi.generic.in.file.path = fname1;
    3040             : 
    3041           1 :         status = smb_raw_pathinfo(cli1->tree, tctx, &qpi);
    3042           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    3043           1 :         CHECK_STRMATCH(qpi.all_info.out.fname.s, fname1);
    3044             : 
    3045           1 :         ZERO_STRUCT(qpi);
    3046           1 :         qpi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
    3047           1 :         qpi.generic.in.file.path = fname2;
    3048             : 
    3049           1 :         status = smb_raw_pathinfo(cli1->tree, tctx, &qpi);
    3050           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
    3051             : 
    3052           1 :         torture_comment(tctx, "nttrans_rename: rename with an invalid handle gives NT_STATUS_INVALID_HANDLE\n");
    3053           1 :         ZERO_STRUCT(rn);
    3054           1 :         rn.generic.level = RAW_RENAME_NTTRANS;
    3055           1 :         rn.nttrans.in.file.fnum = fnum+1;
    3056           1 :         rn.nttrans.in.flags     = 0;
    3057           1 :         rn.nttrans.in.new_name  = fname2+strlen(BASEDIR)+1;
    3058             : 
    3059           1 :         status = smb_raw_rename(cli1->tree, &rn);
    3060             : 
    3061           1 :         CHECK_STATUS(tctx, status, NT_STATUS_INVALID_HANDLE);
    3062             : 
    3063           2 : done:
    3064           1 :         smb_raw_exit(cli1->session);
    3065           1 :         smbcli_deltree(cli1->tree, BASEDIR);
    3066           1 :         return ret;
    3067             : }
    3068             : 
    3069             : 
    3070           1 : static bool test_raw_oplock_batch20(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
    3071             : {
    3072           1 :         const char *fname1 = BASEDIR "\\test_batch20_1.dat";
    3073           1 :         const char *fname2 = BASEDIR "\\test_batch20_2.dat";
    3074           1 :         const char *fname3 = BASEDIR "\\test_batch20_3.dat";
    3075             :         NTSTATUS status;
    3076           1 :         bool ret = true;
    3077             :         union smb_open io;
    3078             :         union smb_fileinfo qfi;
    3079             :         union smb_setfileinfo sfi;
    3080           1 :         uint16_t fnum=0,fnum2=0;
    3081             : 
    3082           1 :         if (!torture_setup_dir(cli1, BASEDIR)) {
    3083           0 :                 return false;
    3084             :         }
    3085             : 
    3086             :         /* cleanup */
    3087           1 :         smbcli_unlink(cli1->tree, fname1);
    3088           1 :         smbcli_unlink(cli1->tree, fname2);
    3089           1 :         smbcli_unlink(cli1->tree, fname3);
    3090             : 
    3091           1 :         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
    3092             : 
    3093             :         /*
    3094             :           base ntcreatex parms
    3095             :         */
    3096           1 :         io.generic.level = RAW_OPEN_NTCREATEX;
    3097           1 :         io.ntcreatex.in.root_fid.fnum = 0;
    3098           1 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
    3099           1 :         io.ntcreatex.in.alloc_size = 0;
    3100           1 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
    3101           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
    3102           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
    3103           1 :         io.ntcreatex.in.create_options = 0;
    3104           1 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
    3105           1 :         io.ntcreatex.in.security_flags = 0;
    3106           1 :         io.ntcreatex.in.fname = fname1;
    3107             : 
    3108           1 :         torture_comment(tctx, "BATCH20: open a file with an batch oplock (share mode: all)\n");
    3109           1 :         ZERO_STRUCT(break_info);
    3110           1 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
    3111             :                 NTCREATEX_FLAGS_REQUEST_OPLOCK |
    3112             :                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
    3113           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
    3114             :                 NTCREATEX_SHARE_ACCESS_WRITE|
    3115             :                 NTCREATEX_SHARE_ACCESS_DELETE;
    3116           1 :         status = smb_raw_open(cli1->tree, tctx, &io);
    3117           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    3118           1 :         fnum = io.ntcreatex.out.file.fnum;
    3119           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
    3120             : 
    3121           1 :         ZERO_STRUCT(sfi);
    3122           1 :         sfi.generic.level = RAW_SFILEINFO_RENAME_INFORMATION;
    3123           1 :         sfi.generic.in.file.path = fname1;
    3124           1 :         sfi.rename_information.in.overwrite     = 0;
    3125           1 :         sfi.rename_information.in.root_fid      = 0;
    3126           1 :         sfi.rename_information.in.new_name      = fname2+strlen(BASEDIR)+1;
    3127             : 
    3128           1 :         status = smb_raw_setpathinfo(cli2->tree, &sfi);
    3129           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    3130             : 
    3131           1 :         torture_wait_for_oplock_break(tctx);
    3132           1 :         CHECK_VAL(break_info.failures, 0);
    3133             : 
    3134           1 :         if (TARGET_IS_WINXP(tctx) || TARGET_IS_W2K12(tctx)) {
    3135             :                 /* Win XP breaks to level2. */
    3136           0 :                 CHECK_VAL(break_info.count, 1);
    3137           0 :                 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
    3138           2 :         } else if (TARGET_IS_W2K3(tctx) || TARGET_IS_W2K8(tctx) ||
    3139           2 :             TARGET_IS_SAMBA3(tctx) || TARGET_IS_SAMBA4(tctx)) {
    3140             :                 /* Win2K3/2k8 incorrectly doesn't break at all. */
    3141           1 :                 CHECK_VAL(break_info.count, 0);
    3142             :         } else {
    3143             :                 /* win7/2k8r2 break to none. */
    3144           0 :                 CHECK_VAL(break_info.count, 1);
    3145           0 :                 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_NONE);
    3146             :         }
    3147             : 
    3148           1 :         ZERO_STRUCT(qfi);
    3149           1 :         qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
    3150           1 :         qfi.generic.in.file.fnum = fnum;
    3151             : 
    3152           1 :         status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
    3153           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    3154           1 :         CHECK_STRMATCH(qfi.all_info.out.fname.s, fname2);
    3155             : 
    3156           1 :         torture_comment(tctx, "open a file with the new name an batch oplock (share mode: all)\n");
    3157           1 :         ZERO_STRUCT(break_info);
    3158           1 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
    3159             :                 NTCREATEX_FLAGS_REQUEST_OPLOCK |
    3160             :                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
    3161           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
    3162             :                 NTCREATEX_SHARE_ACCESS_WRITE|
    3163             :                 NTCREATEX_SHARE_ACCESS_DELETE;
    3164           1 :         io.ntcreatex.in.fname = fname2;
    3165           1 :         status = smb_raw_open(cli2->tree, tctx, &io);
    3166           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    3167           1 :         fnum2 = io.ntcreatex.out.file.fnum;
    3168           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
    3169             : 
    3170           1 :         torture_wait_for_oplock_break(tctx);
    3171             : 
    3172           1 :         if (TARGET_IS_WINXP(tctx)) {
    3173             :                 /* XP broke to level2, and doesn't break again. */
    3174           0 :                 CHECK_VAL(break_info.count, 0);
    3175           2 :         } else if (TARGET_IS_W2K3(tctx) || TARGET_IS_W2K8(tctx) ||
    3176           2 :             TARGET_IS_SAMBA3(tctx) || TARGET_IS_SAMBA4(tctx)) {
    3177             :                 /* Win2K3 incorrectly didn't break before so break now. */
    3178           1 :                 CHECK_VAL(break_info.count, 1);
    3179           1 :                 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
    3180             :         } else {
    3181             :                 /* win7/2k8r2 broke to none, and doesn't break again. */
    3182           0 :                 CHECK_VAL(break_info.count, 0);
    3183             :         }
    3184             : 
    3185           1 :         ZERO_STRUCT(break_info);
    3186             : 
    3187           1 :         ZERO_STRUCT(sfi);
    3188           1 :         sfi.generic.level = RAW_SFILEINFO_RENAME_INFORMATION;
    3189           1 :         sfi.generic.in.file.fnum = fnum;
    3190           1 :         sfi.rename_information.in.overwrite     = 0;
    3191           1 :         sfi.rename_information.in.root_fid      = 0;
    3192           1 :         sfi.rename_information.in.new_name      = fname3+strlen(BASEDIR)+1;
    3193             : 
    3194           1 :         status = smb_raw_setfileinfo(cli1->tree, &sfi);
    3195           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    3196             : 
    3197           1 :         torture_wait_for_oplock_break(tctx);
    3198           1 :         CHECK_VAL(break_info.count, 0);
    3199             : 
    3200           1 :         ZERO_STRUCT(qfi);
    3201           1 :         qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
    3202           1 :         qfi.generic.in.file.fnum = fnum;
    3203             : 
    3204           1 :         status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
    3205           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    3206           1 :         CHECK_STRMATCH(qfi.all_info.out.fname.s, fname3);
    3207             : 
    3208           1 :         ZERO_STRUCT(qfi);
    3209           1 :         qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
    3210           1 :         qfi.generic.in.file.fnum = fnum2;
    3211             : 
    3212           1 :         status = smb_raw_fileinfo(cli2->tree, tctx, &qfi);
    3213           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    3214           1 :         CHECK_STRMATCH(qfi.all_info.out.fname.s, fname3);
    3215             : 
    3216             : 
    3217           2 : done:
    3218           1 :         smbcli_close(cli1->tree, fnum);
    3219           1 :         smbcli_close(cli2->tree, fnum2);
    3220           1 :         smb_raw_exit(cli1->session);
    3221           1 :         smb_raw_exit(cli2->session);
    3222           1 :         smbcli_deltree(cli1->tree, BASEDIR);
    3223           1 :         return ret;
    3224             : }
    3225             : 
    3226           1 : static bool test_raw_oplock_batch21(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
    3227             : {
    3228           1 :         const char *fname = BASEDIR "\\test_batch21.dat";
    3229             :         NTSTATUS status;
    3230           1 :         bool ret = true;
    3231             :         union smb_open io;
    3232             :         struct smb_echo e;
    3233           1 :         uint16_t fnum=0;
    3234           1 :         char c = 0;
    3235             :         ssize_t wr;
    3236             : 
    3237           1 :         if (!torture_setup_dir(cli1, BASEDIR)) {
    3238           0 :                 return false;
    3239             :         }
    3240             : 
    3241             :         /* cleanup */
    3242           1 :         smbcli_unlink(cli1->tree, fname);
    3243             : 
    3244           1 :         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
    3245             : 
    3246             :         /*
    3247             :           base ntcreatex parms
    3248             :         */
    3249           1 :         io.generic.level = RAW_OPEN_NTCREATEX;
    3250           1 :         io.ntcreatex.in.root_fid.fnum = 0;
    3251           1 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
    3252           1 :         io.ntcreatex.in.alloc_size = 0;
    3253           1 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
    3254           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
    3255           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
    3256           1 :         io.ntcreatex.in.create_options = 0;
    3257           1 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
    3258           1 :         io.ntcreatex.in.security_flags = 0;
    3259           1 :         io.ntcreatex.in.fname = fname;
    3260             : 
    3261             :         /*
    3262             :           with a batch oplock we get a break
    3263             :         */
    3264           1 :         torture_comment(tctx, "BATCH21: open with batch oplock\n");
    3265           1 :         ZERO_STRUCT(break_info);
    3266           1 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
    3267             :                 NTCREATEX_FLAGS_REQUEST_OPLOCK |
    3268             :                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
    3269           1 :         status = smb_raw_open(cli1->tree, tctx, &io);
    3270           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    3271           1 :         fnum = io.ntcreatex.out.file.fnum;
    3272           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
    3273             : 
    3274           1 :         torture_comment(tctx, "writing should not generate a break\n");
    3275           1 :         wr = smbcli_write(cli1->tree, fnum, 0, &c, 0, 1);
    3276           1 :         CHECK_VAL(wr, 1);
    3277           1 :         CHECK_STATUS(tctx, smbcli_nt_error(cli1->tree), NT_STATUS_OK);
    3278             : 
    3279           1 :         ZERO_STRUCT(e);
    3280           1 :         e.in.repeat_count = 1;
    3281           1 :         status = smb_raw_echo(cli1->transport, &e);
    3282           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    3283             : 
    3284           1 :         torture_wait_for_oplock_break(tctx);
    3285           1 :         CHECK_VAL(break_info.count, 0);
    3286             : 
    3287           1 :         smbcli_close(cli1->tree, fnum);
    3288             : 
    3289           1 : done:
    3290           1 :         smb_raw_exit(cli1->session);
    3291           1 :         smb_raw_exit(cli2->session);
    3292           1 :         smbcli_deltree(cli1->tree, BASEDIR);
    3293           1 :         return ret;
    3294             : }
    3295             : 
    3296           1 : static bool test_raw_oplock_batch22(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
    3297             : {
    3298           1 :         const char *fname = BASEDIR "\\test_batch22.dat";
    3299             :         NTSTATUS status;
    3300           1 :         bool ret = true;
    3301             :         union smb_open io;
    3302           1 :         uint16_t fnum = 0, fnum2 = 0, fnum3 = 0;
    3303             :         struct timeval tv;
    3304           1 :         int timeout = torture_setting_int(tctx, "oplocktimeout", 30);
    3305             :         int te;
    3306             : 
    3307           1 :         if (!torture_setup_dir(cli1, BASEDIR)) {
    3308           0 :                 return false;
    3309             :         }
    3310             : 
    3311             :         /* cleanup */
    3312           1 :         smbcli_unlink(cli1->tree, fname);
    3313             : 
    3314           1 :         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
    3315             :         /*
    3316             :           base ntcreatex parms
    3317             :         */
    3318           1 :         io.generic.level = RAW_OPEN_NTCREATEX;
    3319           1 :         io.ntcreatex.in.root_fid.fnum = 0;
    3320           1 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
    3321           1 :         io.ntcreatex.in.alloc_size = 0;
    3322           1 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
    3323           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
    3324           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
    3325           1 :         io.ntcreatex.in.create_options = 0;
    3326           1 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
    3327           1 :         io.ntcreatex.in.security_flags = 0;
    3328           1 :         io.ntcreatex.in.fname = fname;
    3329             : 
    3330             :         /*
    3331             :           with a batch oplock we get a break
    3332             :         */
    3333           1 :         torture_comment(tctx, "BATCH22: open with batch oplock\n");
    3334           1 :         ZERO_STRUCT(break_info);
    3335           1 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
    3336             :                 NTCREATEX_FLAGS_REQUEST_OPLOCK |
    3337             :                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
    3338           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
    3339             :                 NTCREATEX_SHARE_ACCESS_WRITE|
    3340             :                 NTCREATEX_SHARE_ACCESS_DELETE;
    3341           1 :         status = smb_raw_open(cli1->tree, tctx, &io);
    3342           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    3343           1 :         fnum = io.ntcreatex.out.file.fnum;
    3344           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
    3345             : 
    3346           1 :         torture_comment(tctx, "a 2nd open should not succeed after the oplock "
    3347             :                         "break timeout\n");
    3348           1 :         tv = timeval_current();
    3349           1 :         smbcli_oplock_handler(cli1->transport, oplock_handler_timeout, cli1->tree);
    3350           1 :         status = smb_raw_open(cli1->tree, tctx, &io);
    3351             : 
    3352           1 :         if (TARGET_IS_W2K3(tctx)) {
    3353             :                 /* 2k3 has an issue here. xp/win7 are ok. */
    3354           0 :                 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
    3355             :         } else {
    3356           1 :                 CHECK_STATUS(tctx, status, NT_STATUS_OK);
    3357             :         }
    3358             : 
    3359           0 :         fnum2 = io.ntcreatex.out.file.fnum;
    3360             : 
    3361           0 :         torture_wait_for_oplock_break(tctx);
    3362           0 :         te = (int)timeval_elapsed(&tv);
    3363             : 
    3364             :         /*
    3365             :          * Some servers detect clients that let oplocks timeout, so this check
    3366             :          * only shows a warning message instead failing the test to eliminate
    3367             :          * failures from repeated runs of the test.  This isn't ideal, but
    3368             :          * it's better than not running the test at all.
    3369             :          */
    3370           0 :         CHECK_RANGE(te, timeout - 1, timeout + 15);
    3371             : 
    3372           0 :         CHECK_VAL(break_info.count, 1);
    3373           0 :         CHECK_VAL(break_info.fnum, fnum);
    3374           0 :         CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
    3375           0 :         CHECK_VAL(break_info.failures, 0);
    3376           0 :         ZERO_STRUCT(break_info);
    3377             : 
    3378           0 :         torture_comment(tctx, "a 2nd open should succeed after the oplock "
    3379             :                         "release without break\n");
    3380           0 :         tv = timeval_current();
    3381           0 :         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
    3382           0 :         status = smb_raw_open(cli1->tree, tctx, &io);
    3383           0 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    3384             : #if 0
    3385             :         /* Samba 3.6.0 and above behave as Windows. */
    3386             :         if (TARGET_IS_SAMBA3(tctx)) {
    3387             :                 /* samba3 doesn't grant additional oplocks to bad clients. */
    3388             :                 CHECK_VAL(io.ntcreatex.out.oplock_level, NO_OPLOCK_RETURN);
    3389             :         } else {
    3390             :                 CHECK_VAL(io.ntcreatex.out.oplock_level,
    3391             :                         LEVEL_II_OPLOCK_RETURN);
    3392             :         }
    3393             : #else
    3394           0 :         CHECK_VAL(io.ntcreatex.out.oplock_level,
    3395             :                   LEVEL_II_OPLOCK_RETURN);
    3396             : #endif
    3397           0 :         torture_wait_for_oplock_break(tctx);
    3398           0 :         te = (int)timeval_elapsed(&tv);
    3399             :         /* it should come in without delay */
    3400           0 :         CHECK_RANGE(te+1, 0, timeout);
    3401           0 :         fnum3 = io.ntcreatex.out.file.fnum;
    3402             : 
    3403           0 :         CHECK_VAL(break_info.count, 0);
    3404             : 
    3405           0 :         smbcli_close(cli1->tree, fnum);
    3406           0 :         smbcli_close(cli1->tree, fnum2);
    3407           0 :         smbcli_close(cli1->tree, fnum3);
    3408             : 
    3409           1 : done:
    3410           1 :         smb_raw_exit(cli1->session);
    3411           1 :         smb_raw_exit(cli2->session);
    3412           1 :         smbcli_deltree(cli1->tree, BASEDIR);
    3413           1 :         return ret;
    3414             : }
    3415             : 
    3416           1 : static bool test_raw_oplock_batch23(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
    3417             : {
    3418           1 :         const char *fname = BASEDIR "\\test_batch23.dat";
    3419             :         NTSTATUS status;
    3420           1 :         bool ret = true;
    3421             :         union smb_open io;
    3422           1 :         uint16_t fnum=0, fnum2=0,fnum3=0;
    3423           1 :         struct smbcli_state *cli3 = NULL;
    3424             : 
    3425           1 :         if (!torture_setup_dir(cli1, BASEDIR)) {
    3426           0 :                 return false;
    3427             :         }
    3428             : 
    3429             :         /* cleanup */
    3430           1 :         smbcli_unlink(cli1->tree, fname);
    3431             : 
    3432           1 :         ret = open_connection_no_level2_oplocks(tctx, &cli3);
    3433           1 :         CHECK_VAL(ret, true);
    3434             : 
    3435           1 :         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
    3436           1 :         smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli2->tree);
    3437           1 :         smbcli_oplock_handler(cli3->transport, oplock_handler_ack_to_given, cli3->tree);
    3438             : 
    3439             :         /*
    3440             :           base ntcreatex parms
    3441             :         */
    3442           1 :         io.generic.level = RAW_OPEN_NTCREATEX;
    3443           1 :         io.ntcreatex.in.root_fid.fnum = 0;
    3444           1 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
    3445           1 :         io.ntcreatex.in.alloc_size = 0;
    3446           1 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
    3447           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
    3448           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
    3449           1 :         io.ntcreatex.in.create_options = 0;
    3450           1 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
    3451           1 :         io.ntcreatex.in.security_flags = 0;
    3452           1 :         io.ntcreatex.in.fname = fname;
    3453             : 
    3454           1 :         torture_comment(tctx, "BATCH23: a open and ask for a batch oplock\n");
    3455           1 :         ZERO_STRUCT(break_info);
    3456             : 
    3457           1 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_READ | SEC_RIGHTS_FILE_WRITE;
    3458           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
    3459           1 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
    3460             :                 NTCREATEX_FLAGS_REQUEST_OPLOCK |
    3461             :                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
    3462           1 :         status = smb_raw_open(cli1->tree, tctx, &io);
    3463           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    3464           1 :         fnum = io.ntcreatex.out.file.fnum;
    3465           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
    3466             : 
    3467           1 :         ZERO_STRUCT(break_info);
    3468             : 
    3469           1 :         torture_comment(tctx, "a 2nd open without level2 oplock support should generate a break to level2\n");
    3470           1 :         status = smb_raw_open(cli3->tree, tctx, &io);
    3471           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    3472           1 :         fnum3 = io.ntcreatex.out.file.fnum;
    3473           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, NO_OPLOCK_RETURN);
    3474             : 
    3475           1 :         torture_wait_for_oplock_break(tctx);
    3476           1 :         CHECK_VAL(break_info.count, 1);
    3477           1 :         CHECK_VAL(break_info.fnum, fnum);
    3478           1 :         CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
    3479           1 :         CHECK_VAL(break_info.failures, 0);
    3480             : 
    3481           1 :         ZERO_STRUCT(break_info);
    3482             : 
    3483           1 :         torture_comment(tctx, "a 3rd open with level2 oplock support should not generate a break\n");
    3484           1 :         status = smb_raw_open(cli2->tree, tctx, &io);
    3485           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    3486           1 :         fnum2 = io.ntcreatex.out.file.fnum;
    3487           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
    3488             : 
    3489           1 :         torture_wait_for_oplock_break(tctx);
    3490           1 :         CHECK_VAL(break_info.count, 0);
    3491             : 
    3492           1 :         smbcli_close(cli1->tree, fnum);
    3493           1 :         smbcli_close(cli2->tree, fnum2);
    3494           1 :         smbcli_close(cli3->tree, fnum3);
    3495             : 
    3496           1 : done:
    3497           1 :         smb_raw_exit(cli1->session);
    3498           1 :         smb_raw_exit(cli2->session);
    3499           1 :         smb_raw_exit(cli3->session);
    3500           1 :         smbcli_deltree(cli1->tree, BASEDIR);
    3501           1 :         return ret;
    3502             : }
    3503             : 
    3504           1 : static bool test_raw_oplock_batch24(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
    3505             : {
    3506           1 :         const char *fname = BASEDIR "\\test_batch24.dat";
    3507             :         NTSTATUS status;
    3508           1 :         bool ret = true;
    3509             :         union smb_open io;
    3510           1 :         uint16_t fnum2=0,fnum3=0;
    3511           1 :         struct smbcli_state *cli3 = NULL;
    3512             : 
    3513           1 :         if (!torture_setup_dir(cli1, BASEDIR)) {
    3514           0 :                 return false;
    3515             :         }
    3516             : 
    3517             :         /* cleanup */
    3518           1 :         smbcli_unlink(cli1->tree, fname);
    3519             : 
    3520           1 :         ret = open_connection_no_level2_oplocks(tctx, &cli3);
    3521           1 :         CHECK_VAL(ret, true);
    3522             : 
    3523           1 :         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
    3524           1 :         smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli2->tree);
    3525           1 :         smbcli_oplock_handler(cli3->transport, oplock_handler_ack_to_given, cli3->tree);
    3526             : 
    3527             :         /*
    3528             :           base ntcreatex parms
    3529             :         */
    3530           1 :         io.generic.level = RAW_OPEN_NTCREATEX;
    3531           1 :         io.ntcreatex.in.root_fid.fnum = 0;
    3532           1 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
    3533           1 :         io.ntcreatex.in.alloc_size = 0;
    3534           1 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
    3535           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
    3536           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
    3537           1 :         io.ntcreatex.in.create_options = 0;
    3538           1 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
    3539           1 :         io.ntcreatex.in.security_flags = 0;
    3540           1 :         io.ntcreatex.in.fname = fname;
    3541             : 
    3542           1 :         torture_comment(tctx, "BATCH24: a open without level support and ask for a batch oplock\n");
    3543           1 :         ZERO_STRUCT(break_info);
    3544             : 
    3545           1 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_READ | SEC_RIGHTS_FILE_WRITE;
    3546           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
    3547           1 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
    3548             :                 NTCREATEX_FLAGS_REQUEST_OPLOCK |
    3549             :                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
    3550           1 :         status = smb_raw_open(cli3->tree, tctx, &io);
    3551           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    3552           1 :         fnum3 = io.ntcreatex.out.file.fnum;
    3553           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
    3554             : 
    3555           1 :         ZERO_STRUCT(break_info);
    3556             : 
    3557           1 :         torture_comment(tctx, "a 2nd open with level2 oplock support should generate a break to none\n");
    3558           1 :         status = smb_raw_open(cli2->tree, tctx, &io);
    3559           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    3560           1 :         fnum2 = io.ntcreatex.out.file.fnum;
    3561           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
    3562             : 
    3563           1 :         torture_wait_for_oplock_break(tctx);
    3564           1 :         CHECK_VAL(break_info.count, 1);
    3565           1 :         CHECK_VAL(break_info.fnum, fnum3);
    3566           1 :         CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_NONE);
    3567           1 :         CHECK_VAL(break_info.failures, 0);
    3568             : 
    3569           1 :         smbcli_close(cli3->tree, fnum3);
    3570           1 :         smbcli_close(cli2->tree, fnum2);
    3571             : 
    3572           1 : done:
    3573           1 :         smb_raw_exit(cli1->session);
    3574           1 :         smb_raw_exit(cli2->session);
    3575           1 :         smb_raw_exit(cli3->session);
    3576           1 :         smbcli_deltree(cli1->tree, BASEDIR);
    3577           1 :         return ret;
    3578             : }
    3579             : 
    3580           1 : static bool test_raw_oplock_batch25(struct torture_context *tctx,
    3581             :                                     struct smbcli_state *cli1,
    3582             :                                     struct smbcli_state *cli2)
    3583             : {
    3584           1 :         const char *fname = BASEDIR "\\test_batch25.dat";
    3585             :         NTSTATUS status;
    3586           1 :         bool ret = true;
    3587             :         union smb_open io;
    3588             :         union smb_setfileinfo sfi;
    3589           1 :         uint16_t fnum=0;
    3590             : 
    3591           1 :         if (!torture_setup_dir(cli1, BASEDIR)) {
    3592           0 :                 return false;
    3593             :         }
    3594             : 
    3595             :         /* cleanup */
    3596           1 :         smbcli_unlink(cli1->tree, fname);
    3597             : 
    3598           1 :         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
    3599             : 
    3600             :         /*
    3601             :           base ntcreatex parms
    3602             :         */
    3603           1 :         io.generic.level = RAW_OPEN_NTCREATEX;
    3604           1 :         io.ntcreatex.in.root_fid.fnum = 0;
    3605           1 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
    3606           1 :         io.ntcreatex.in.alloc_size = 0;
    3607           1 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
    3608           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
    3609           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
    3610           1 :         io.ntcreatex.in.create_options = 0;
    3611           1 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
    3612           1 :         io.ntcreatex.in.security_flags = 0;
    3613           1 :         io.ntcreatex.in.fname = fname;
    3614             : 
    3615           1 :         torture_comment(tctx, "BATCH25: open a file with an batch oplock "
    3616             :                         "(share mode: none)\n");
    3617             : 
    3618           1 :         ZERO_STRUCT(break_info);
    3619           1 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
    3620             :                 NTCREATEX_FLAGS_REQUEST_OPLOCK |
    3621             :                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
    3622           1 :         status = smb_raw_open(cli1->tree, tctx, &io);
    3623           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    3624           1 :         fnum = io.ntcreatex.out.file.fnum;
    3625           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
    3626             : 
    3627           1 :         torture_comment(tctx, "setpathinfo attribute info should not trigger "
    3628             :                         "a break nor a violation\n");
    3629           1 :         ZERO_STRUCT(sfi);
    3630           1 :         sfi.generic.level = RAW_SFILEINFO_SETATTR;
    3631           1 :         sfi.generic.in.file.path        = fname;
    3632           1 :         sfi.setattr.in.attrib           = FILE_ATTRIBUTE_HIDDEN;
    3633           1 :         sfi.setattr.in.write_time       = 0;
    3634             : 
    3635           1 :         status = smb_raw_setpathinfo(cli2->tree, &sfi);
    3636           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    3637             : 
    3638           1 :         torture_wait_for_oplock_break(tctx);
    3639           1 :         CHECK_VAL(break_info.count, 0);
    3640             : 
    3641           1 :         smbcli_close(cli1->tree, fnum);
    3642             : 
    3643           1 : done:
    3644           1 :         smb_raw_exit(cli1->session);
    3645           1 :         smb_raw_exit(cli2->session);
    3646           1 :         smbcli_deltree(cli1->tree, BASEDIR);
    3647           1 :         return ret;
    3648             : }
    3649             : 
    3650             : /**
    3651             :  * Similar to batch17/18, but test with open share mode rather than
    3652             :  * share_none.
    3653             :  */
    3654           1 : static bool test_raw_oplock_batch26(struct torture_context *tctx,
    3655             :     struct smbcli_state *cli1, struct smbcli_state *cli2)
    3656             : {
    3657           1 :         const char *fname1 = BASEDIR "\\test_batch26_1.dat";
    3658           1 :         const char *fname2 = BASEDIR "\\test_batch26_2.dat";
    3659             :         NTSTATUS status;
    3660           1 :         bool ret = true;
    3661             :         union smb_open io;
    3662             :         union smb_rename rn;
    3663           1 :         uint16_t fnum=0;
    3664             : 
    3665           1 :         if (!torture_setup_dir(cli1, BASEDIR)) {
    3666           0 :                 return false;
    3667             :         }
    3668             : 
    3669             :         /* cleanup */
    3670           1 :         smbcli_unlink(cli1->tree, fname1);
    3671           1 :         smbcli_unlink(cli1->tree, fname2);
    3672             : 
    3673           1 :         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given,
    3674           1 :             cli1->tree);
    3675             : 
    3676             :         /*
    3677             :           base ntcreatex parms
    3678             :         */
    3679           1 :         io.generic.level = RAW_OPEN_NTCREATEX;
    3680           1 :         io.ntcreatex.in.root_fid.fnum = 0;
    3681           1 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
    3682           1 :         io.ntcreatex.in.alloc_size = 0;
    3683           1 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
    3684           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
    3685             :             NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_DELETE;
    3686           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
    3687           1 :         io.ntcreatex.in.create_options = 0;
    3688           1 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
    3689           1 :         io.ntcreatex.in.security_flags = 0;
    3690           1 :         io.ntcreatex.in.fname = fname1;
    3691             : 
    3692           1 :         torture_comment(tctx,
    3693             :                         "BATCH26: open a file with an batch oplock "
    3694             :                         "(share mode: all)\n");
    3695             : 
    3696           1 :         ZERO_STRUCT(break_info);
    3697           1 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
    3698             :                 NTCREATEX_FLAGS_REQUEST_OPLOCK |
    3699             :                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
    3700             : 
    3701             : 
    3702           1 :         status = smb_raw_open(cli1->tree, tctx, &io);
    3703           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    3704           1 :         fnum = io.ntcreatex.out.file.fnum;
    3705           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
    3706             : 
    3707           1 :         torture_comment(tctx, "rename should trigger a break\n");
    3708           1 :         ZERO_STRUCT(rn);
    3709           1 :         rn.generic.level = RAW_RENAME_RENAME;
    3710           1 :         rn.rename.in.pattern1 = fname1;
    3711           1 :         rn.rename.in.pattern2 = fname2;
    3712           1 :         rn.rename.in.attrib = 0;
    3713             : 
    3714           1 :         torture_comment(tctx, "trying rename while first file open\n");
    3715           1 :         status = smb_raw_rename(cli2->tree, &rn);
    3716           1 :         CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
    3717             : 
    3718           1 :         torture_wait_for_oplock_break(tctx);
    3719           1 :         CHECK_VAL(break_info.count, 1);
    3720           1 :         CHECK_VAL(break_info.failures, 0);
    3721           1 :         CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
    3722             : 
    3723             :         /* Close and reopen with batch again. */
    3724           1 :         smbcli_close(cli1->tree, fnum);
    3725           1 :         ZERO_STRUCT(break_info);
    3726             : 
    3727           1 :         status = smb_raw_open(cli1->tree, tctx, &io);
    3728           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    3729           1 :         fnum = io.ntcreatex.out.file.fnum;
    3730           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
    3731             : 
    3732             :         /* Now try ntrename. */
    3733           1 :         torture_comment(tctx, "ntrename should trigger a break\n");
    3734           1 :         ZERO_STRUCT(rn);
    3735           1 :         rn.generic.level = RAW_RENAME_NTRENAME;
    3736           1 :         rn.ntrename.in.attrib   = 0;
    3737           1 :         rn.ntrename.in.flags    = RENAME_FLAG_RENAME;
    3738           1 :         rn.ntrename.in.old_name = fname1;
    3739           1 :         rn.ntrename.in.new_name = fname2;
    3740           1 :         torture_comment(tctx, "trying rename while first file open\n");
    3741           1 :         status = smb_raw_rename(cli2->tree, &rn);
    3742           1 :         CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
    3743             : 
    3744           1 :         torture_wait_for_oplock_break(tctx);
    3745           1 :         CHECK_VAL(break_info.count, 1);
    3746           1 :         CHECK_VAL(break_info.failures, 0);
    3747           1 :         CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
    3748             : 
    3749           1 :         smbcli_close(cli1->tree, fnum);
    3750             : 
    3751           1 : done:
    3752           1 :         smb_raw_exit(cli1->session);
    3753           1 :         smb_raw_exit(cli2->session);
    3754           1 :         smbcli_deltree(cli1->tree, BASEDIR);
    3755           1 :         return ret;
    3756             : }
    3757             : 
    3758             : /* Test how oplocks work on streams. */
    3759           1 : static bool test_raw_oplock_stream1(struct torture_context *tctx,
    3760             :                                     struct smbcli_state *cli1,
    3761             :                                     struct smbcli_state *cli2)
    3762             : {
    3763             :         NTSTATUS status;
    3764             :         union smb_open io;
    3765           1 :         const char *fname_base = BASEDIR "\\test_stream1.txt";
    3766           1 :         const char *stream = "Stream One:$DATA";
    3767             :         const char *fname_stream, *fname_default_stream;
    3768           1 :         const char *default_stream = "::$DATA";
    3769           1 :         bool ret = true;
    3770           1 :         int fnum = -1;
    3771             :         int i;
    3772           1 :         int stream_fnum = -1;
    3773           1 :         uint32_t batch_req = NTCREATEX_FLAGS_REQUEST_OPLOCK |
    3774             :             NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK | NTCREATEX_FLAGS_EXTENDED;
    3775           1 :         uint32_t exclusive_req = NTCREATEX_FLAGS_REQUEST_OPLOCK |
    3776             :             NTCREATEX_FLAGS_EXTENDED;
    3777             : 
    3778             : #define NSTREAM_OPLOCK_RESULTS 8
    3779             :         struct {
    3780             :                 const char **fname;
    3781             :                 bool open_base_file;
    3782             :                 uint32_t oplock_req;
    3783             :                 uint32_t oplock_granted;
    3784           1 :         } stream_oplock_results[NSTREAM_OPLOCK_RESULTS] = {
    3785             :                 /* Request oplock on stream without the base file open. */
    3786             :                 {&fname_stream, false, batch_req, NO_OPLOCK_RETURN},
    3787             :                 {&fname_default_stream, false, batch_req, NO_OPLOCK_RETURN},
    3788             :                 {&fname_stream, false, exclusive_req, EXCLUSIVE_OPLOCK_RETURN},
    3789             :                 {&fname_default_stream, false,  exclusive_req, EXCLUSIVE_OPLOCK_RETURN},
    3790             : 
    3791             :                 /* Request oplock on stream with the base file open. */
    3792             :                 {&fname_stream, true, batch_req, NO_OPLOCK_RETURN},
    3793             :                 {&fname_default_stream, true, batch_req, NO_OPLOCK_RETURN},
    3794             :                 {&fname_stream, true, exclusive_req, EXCLUSIVE_OPLOCK_RETURN},
    3795             :                 {&fname_default_stream, true,  exclusive_req, LEVEL_II_OPLOCK_RETURN},
    3796             : 
    3797             :         };
    3798             : 
    3799             : 
    3800             :         /* Only passes against windows at the moment. */
    3801           2 :         if (torture_setting_bool(tctx, "samba3", false) ||
    3802           1 :             torture_setting_bool(tctx, "samba4", false)) {
    3803           1 :                 torture_skip(tctx, "STREAM1 disabled against samba3+4\n");
    3804             :         }
    3805             : 
    3806           0 :         fname_stream = talloc_asprintf(tctx, "%s:%s", fname_base, stream);
    3807           0 :         fname_default_stream = talloc_asprintf(tctx, "%s%s", fname_base,
    3808             :                                                default_stream);
    3809             : 
    3810           0 :         if (!torture_setup_dir(cli1, BASEDIR)) {
    3811           0 :                 return false;
    3812             :         }
    3813           0 :         smbcli_unlink(cli1->tree, fname_base);
    3814             : 
    3815           0 :         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
    3816           0 :         smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli2->tree);
    3817             : 
    3818             :         /* Setup generic open parameters. */
    3819           0 :         io.generic.level = RAW_OPEN_NTCREATEX;
    3820           0 :         io.ntcreatex.in.root_fid.fnum = 0;
    3821           0 :         io.ntcreatex.in.access_mask = (SEC_FILE_READ_DATA|SEC_FILE_WRITE_DATA|
    3822             :             SEC_FILE_APPEND_DATA|SEC_STD_READ_CONTROL);
    3823           0 :         io.ntcreatex.in.create_options = 0;
    3824           0 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
    3825           0 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
    3826             :             NTCREATEX_SHARE_ACCESS_WRITE;
    3827           0 :         io.ntcreatex.in.alloc_size = 0;
    3828           0 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
    3829           0 :         io.ntcreatex.in.security_flags = 0;
    3830             : 
    3831             :         /* Create the file with a stream */
    3832           0 :         io.ntcreatex.in.fname = fname_stream;
    3833           0 :         io.ntcreatex.in.flags = 0;
    3834           0 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
    3835           0 :         status = smb_raw_open(cli1->tree, tctx, &io);
    3836           0 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    3837           0 :         smbcli_close(cli1->tree, io.ntcreatex.out.file.fnum);
    3838             : 
    3839             :         /* Change the disposition to open now that the file has been created. */
    3840           0 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
    3841             : 
    3842             :         /* Try some permutations of taking oplocks on streams. */
    3843           0 :         for (i = 0; i < NSTREAM_OPLOCK_RESULTS; i++) {
    3844           0 :                 const char *fname = *stream_oplock_results[i].fname;
    3845           0 :                 bool open_base_file = stream_oplock_results[i].open_base_file;
    3846           0 :                 uint32_t oplock_req = stream_oplock_results[i].oplock_req;
    3847           0 :                 uint32_t oplock_granted =
    3848             :                     stream_oplock_results[i].oplock_granted;
    3849           0 :                 int base_fnum = -1;
    3850             : 
    3851           0 :                 if (open_base_file) {
    3852           0 :                         torture_comment(tctx, "Opening base file: %s with "
    3853             :                             "%d\n", fname_base, batch_req);
    3854           0 :                         io.ntcreatex.in.fname = fname_base;
    3855           0 :                         io.ntcreatex.in.flags = batch_req;
    3856           0 :                         status = smb_raw_open(cli2->tree, tctx, &io);
    3857           0 :                         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    3858           0 :                         CHECK_VAL(io.ntcreatex.out.oplock_level,
    3859             :                             BATCH_OPLOCK_RETURN);
    3860           0 :                         base_fnum = io.ntcreatex.out.file.fnum;
    3861             :                 }
    3862             : 
    3863           0 :                 torture_comment(tctx, "%d: Opening stream: %s with %d\n", i,
    3864             :                     fname, oplock_req);
    3865           0 :                 io.ntcreatex.in.fname = fname;
    3866           0 :                 io.ntcreatex.in.flags = oplock_req;
    3867             : 
    3868             :                 /* Do the open with the desired oplock on the stream. */
    3869           0 :                 status = smb_raw_open(cli1->tree, tctx, &io);
    3870           0 :                 CHECK_STATUS(tctx, status, NT_STATUS_OK);
    3871           0 :                 CHECK_VAL(io.ntcreatex.out.oplock_level, oplock_granted);
    3872           0 :                 smbcli_close(cli1->tree, io.ntcreatex.out.file.fnum);
    3873             : 
    3874             :                 /* Cleanup the base file if it was opened. */
    3875           0 :                 if (base_fnum != -1) {
    3876           0 :                         smbcli_close(cli2->tree, base_fnum);
    3877             :                 }
    3878             :         }
    3879             : 
    3880             :         /* Open the stream with an exclusive oplock. */
    3881           0 :         torture_comment(tctx, "Opening stream: %s with %d\n",
    3882             :             fname_stream, exclusive_req);
    3883           0 :         io.ntcreatex.in.fname = fname_stream;
    3884           0 :         io.ntcreatex.in.flags = exclusive_req;
    3885           0 :         status = smb_raw_open(cli1->tree, tctx, &io);
    3886           0 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    3887           0 :         CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
    3888           0 :         stream_fnum = io.ntcreatex.out.file.fnum;
    3889             : 
    3890             :         /* Open the base file and see if it contends. */
    3891           0 :         ZERO_STRUCT(break_info);
    3892           0 :         torture_comment(tctx, "Opening base file: %s with "
    3893             :             "%d\n", fname_base, batch_req);
    3894           0 :         io.ntcreatex.in.fname = fname_base;
    3895           0 :         io.ntcreatex.in.flags = batch_req;
    3896           0 :         status = smb_raw_open(cli2->tree, tctx, &io);
    3897           0 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    3898           0 :         CHECK_VAL(io.ntcreatex.out.oplock_level,
    3899             :             BATCH_OPLOCK_RETURN);
    3900           0 :         smbcli_close(cli2->tree, io.ntcreatex.out.file.fnum);
    3901             : 
    3902           0 :         torture_wait_for_oplock_break(tctx);
    3903           0 :         CHECK_VAL(break_info.count, 0);
    3904           0 :         CHECK_VAL(break_info.failures, 0);
    3905             : 
    3906             :         /* Open the stream again to see if it contends. */
    3907           0 :         ZERO_STRUCT(break_info);
    3908           0 :         torture_comment(tctx, "Opening stream again: %s with "
    3909             :             "%d\n", fname_base, batch_req);
    3910           0 :         io.ntcreatex.in.fname = fname_stream;
    3911           0 :         io.ntcreatex.in.flags = exclusive_req;
    3912           0 :         status = smb_raw_open(cli2->tree, tctx, &io);
    3913           0 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    3914           0 :         CHECK_VAL(io.ntcreatex.out.oplock_level,
    3915             :             LEVEL_II_OPLOCK_RETURN);
    3916           0 :         smbcli_close(cli2->tree, io.ntcreatex.out.file.fnum);
    3917             : 
    3918           0 :         torture_wait_for_oplock_break(tctx);
    3919           0 :         CHECK_VAL(break_info.count, 1);
    3920           0 :         CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
    3921           0 :         CHECK_VAL(break_info.failures, 0);
    3922             : 
    3923             :         /* Close the stream. */
    3924           0 :         if (stream_fnum != -1) {
    3925           0 :                 smbcli_close(cli1->tree, stream_fnum);
    3926             :         }
    3927             : 
    3928           0 :  done:
    3929           0 :         smbcli_close(cli1->tree, fnum);
    3930           0 :         smb_raw_exit(cli1->session);
    3931           0 :         smb_raw_exit(cli2->session);
    3932           0 :         smbcli_deltree(cli1->tree, BASEDIR);
    3933           0 :         return ret;
    3934             : }
    3935             : 
    3936           1 : static bool test_raw_oplock_doc(struct torture_context *tctx,
    3937             :                                 struct smbcli_state *cli,
    3938             :                                 struct smbcli_state *cli2)
    3939             : {
    3940           1 :         const char *fname = BASEDIR "\\test_oplock_doc.dat";
    3941             :         NTSTATUS status;
    3942           1 :         bool ret = true;
    3943             :         union smb_open io;
    3944           1 :         uint16_t fnum=0;
    3945             : 
    3946           1 :         torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
    3947             : 
    3948             :         /* cleanup */
    3949           1 :         smbcli_unlink(cli->tree, fname);
    3950             : 
    3951           1 :         smbcli_oplock_handler(cli->transport, oplock_handler_ack_to_given,
    3952           1 :                               cli->tree);
    3953             : 
    3954             :         /*
    3955             :           base ntcreatex parms
    3956             :         */
    3957           1 :         io.generic.level = RAW_OPEN_NTCREATEX;
    3958           1 :         io.ntcreatex.in.root_fid.fnum = 0;
    3959           1 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
    3960           1 :         io.ntcreatex.in.alloc_size = 0;
    3961           1 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
    3962           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
    3963             :                 NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE;
    3964           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
    3965           1 :         io.ntcreatex.in.create_options = 0;
    3966           1 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
    3967           1 :         io.ntcreatex.in.security_flags = 0;
    3968           1 :         io.ntcreatex.in.fname = fname;
    3969             : 
    3970           1 :         torture_comment(tctx, "open a file with a batch oplock\n");
    3971           1 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
    3972             :             NTCREATEX_FLAGS_REQUEST_OPLOCK |
    3973             :             NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
    3974             : 
    3975           1 :         status = smb_raw_open(cli->tree, tctx, &io);
    3976           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    3977           1 :         fnum = io.ntcreatex.out.file.fnum;
    3978           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
    3979             : 
    3980           1 :         torture_comment(tctx, "Set delete-on-close\n");
    3981           1 :         status = smbcli_nt_delete_on_close(cli->tree, fnum, true);
    3982           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    3983             : 
    3984           1 :         torture_comment(tctx, "2nd open should not break and get "
    3985             :                         "DELETE_PENDING\n");
    3986           1 :         ZERO_STRUCT(break_info);
    3987           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
    3988           1 :         io.ntcreatex.in.create_options = 0;
    3989           1 :         io.ntcreatex.in.access_mask = SEC_FILE_READ_DATA;
    3990           1 :         status = smb_raw_open(cli2->tree, tctx, &io);
    3991           1 :         CHECK_STATUS(tctx, status, NT_STATUS_DELETE_PENDING);
    3992           1 :         CHECK_VAL(break_info.count, 0);
    3993             : 
    3994           1 :         smbcli_close(cli->tree, fnum);
    3995             : 
    3996           1 : done:
    3997           1 :         smb_raw_exit(cli->session);
    3998           1 :         smbcli_deltree(cli->tree, BASEDIR);
    3999           1 :         return ret;
    4000             : }
    4001             : 
    4002             : /* Open a file with a batch oplock, then open it again from a second client
    4003             :  * requesting no oplock. Having two open file handles should break our own
    4004             :  * oplock during BRL acquisition.
    4005             :  */
    4006           1 : static bool test_raw_oplock_brl1(struct torture_context *tctx,
    4007             :                                  struct smbcli_state *cli1,
    4008             :                                  struct smbcli_state *cli2)
    4009             : {
    4010           1 :         const char *fname = BASEDIR "\\test_batch_brl.dat";
    4011             :         /*int fname, f;*/
    4012           1 :         bool ret = true;
    4013             :         uint8_t buf[1000];
    4014             :         union smb_open io;
    4015             :         NTSTATUS status;
    4016           1 :         uint16_t fnum=0;
    4017           1 :         uint16_t fnum2=0;
    4018             : 
    4019           1 :         if (!torture_setup_dir(cli1, BASEDIR)) {
    4020           0 :                 return false;
    4021             :         }
    4022             : 
    4023             :         /* cleanup */
    4024           1 :         smbcli_unlink(cli1->tree, fname);
    4025             : 
    4026           1 :         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given,
    4027           1 :                               cli1->tree);
    4028             : 
    4029             :         /*
    4030             :           base ntcreatex parms
    4031             :         */
    4032           1 :         io.generic.level = RAW_OPEN_NTCREATEX;
    4033           1 :         io.ntcreatex.in.root_fid.fnum = 0;
    4034           1 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_READ |
    4035             :                                       SEC_RIGHTS_FILE_WRITE;
    4036           1 :         io.ntcreatex.in.alloc_size = 0;
    4037           1 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
    4038           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
    4039             :                                        NTCREATEX_SHARE_ACCESS_WRITE;
    4040           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
    4041           1 :         io.ntcreatex.in.create_options = 0;
    4042           1 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
    4043           1 :         io.ntcreatex.in.security_flags = 0;
    4044           1 :         io.ntcreatex.in.fname = fname;
    4045             : 
    4046             :         /*
    4047             :           with a batch oplock we get a break
    4048             :         */
    4049           1 :         torture_comment(tctx, "open with batch oplock\n");
    4050           1 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
    4051             :                 NTCREATEX_FLAGS_REQUEST_OPLOCK |
    4052             :                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
    4053             : 
    4054           1 :         status = smb_raw_open(cli1->tree, tctx, &io);
    4055           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    4056           1 :         fnum = io.ntcreatex.out.file.fnum;
    4057           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
    4058             :         /* create a file with bogus data */
    4059           1 :         memset(buf, 0, sizeof(buf));
    4060             : 
    4061           1 :         if (smbcli_write(cli1->tree, fnum, 0, buf, 0, sizeof(buf)) !=
    4062             :                          sizeof(buf))
    4063             :         {
    4064           0 :                 torture_comment(tctx, "Failed to create file\n");
    4065           0 :                 goto done;
    4066             :         }
    4067             : 
    4068           1 :         torture_comment(tctx, "a 2nd open should give a break\n");
    4069           1 :         ZERO_STRUCT(break_info);
    4070             : 
    4071           1 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
    4072           1 :         status = smb_raw_open(cli2->tree, tctx, &io);
    4073           1 :         fnum2 = io.ntcreatex.out.file.fnum;
    4074           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    4075           1 :         CHECK_VAL(break_info.count, 1);
    4076           1 :         CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
    4077           1 :         CHECK_VAL(break_info.failures, 0);
    4078           1 :         CHECK_VAL(break_info.fnum, fnum);
    4079             : 
    4080           1 :         ZERO_STRUCT(break_info);
    4081             : 
    4082           1 :         torture_comment(tctx, "a self BRL acquisition should break to none\n");
    4083             : 
    4084           1 :         status = smbcli_lock(cli1->tree, fnum, 0, 4, 0, WRITE_LOCK);
    4085           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    4086             : 
    4087           1 :         torture_wait_for_oplock_break(tctx);
    4088           1 :         CHECK_VAL(break_info.count, 1);
    4089           1 :         CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_NONE);
    4090           1 :         CHECK_VAL(break_info.fnum, fnum);
    4091           1 :         CHECK_VAL(break_info.failures, 0);
    4092             : 
    4093             :         /* expect no oplock break */
    4094           1 :         ZERO_STRUCT(break_info);
    4095           1 :         status = smbcli_lock(cli1->tree, fnum, 2, 4, 0, WRITE_LOCK);
    4096           1 :         CHECK_STATUS(tctx, status, NT_STATUS_LOCK_NOT_GRANTED);
    4097             : 
    4098           1 :         torture_wait_for_oplock_break(tctx);
    4099           1 :         CHECK_VAL(break_info.count, 0);
    4100           1 :         CHECK_VAL(break_info.level, 0);
    4101           1 :         CHECK_VAL(break_info.fnum, 0);
    4102           1 :         CHECK_VAL(break_info.failures, 0);
    4103             : 
    4104           1 :         smbcli_close(cli1->tree, fnum);
    4105           1 :         smbcli_close(cli2->tree, fnum2);
    4106             : 
    4107           1 : done:
    4108           1 :         smb_raw_exit(cli1->session);
    4109           1 :         smb_raw_exit(cli2->session);
    4110           1 :         smbcli_deltree(cli1->tree, BASEDIR);
    4111           1 :         return ret;
    4112             : 
    4113             : }
    4114             : 
    4115             : /* Open a file with a batch oplock on one client and then acquire a brl.
    4116             :  * We should not contend our own oplock.
    4117             :  */
    4118           1 : static bool test_raw_oplock_brl2(struct torture_context *tctx, struct smbcli_state *cli1)
    4119             : {
    4120           1 :         const char *fname = BASEDIR "\\test_batch_brl.dat";
    4121             :         /*int fname, f;*/
    4122           1 :         bool ret = true;
    4123             :         uint8_t buf[1000];
    4124             :         union smb_open io;
    4125             :         NTSTATUS status;
    4126           1 :         uint16_t fnum=0;
    4127             : 
    4128           1 :         if (!torture_setup_dir(cli1, BASEDIR)) {
    4129           0 :                 return false;
    4130             :         }
    4131             : 
    4132             :         /* cleanup */
    4133           1 :         smbcli_unlink(cli1->tree, fname);
    4134             : 
    4135           1 :         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given,
    4136           1 :                               cli1->tree);
    4137             : 
    4138             :         /*
    4139             :           base ntcreatex parms
    4140             :         */
    4141           1 :         io.generic.level = RAW_OPEN_NTCREATEX;
    4142           1 :         io.ntcreatex.in.root_fid.fnum = 0;
    4143           1 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_READ |
    4144             :                                       SEC_RIGHTS_FILE_WRITE;
    4145           1 :         io.ntcreatex.in.alloc_size = 0;
    4146           1 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
    4147           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
    4148             :                                        NTCREATEX_SHARE_ACCESS_WRITE;
    4149           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
    4150           1 :         io.ntcreatex.in.create_options = 0;
    4151           1 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
    4152           1 :         io.ntcreatex.in.security_flags = 0;
    4153           1 :         io.ntcreatex.in.fname = fname;
    4154             : 
    4155             :         /*
    4156             :           with a batch oplock we get a break
    4157             :         */
    4158           1 :         torture_comment(tctx, "open with batch oplock\n");
    4159           1 :         ZERO_STRUCT(break_info);
    4160           1 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
    4161             :                 NTCREATEX_FLAGS_REQUEST_OPLOCK |
    4162             :                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
    4163             : 
    4164           1 :         status = smb_raw_open(cli1->tree, tctx, &io);
    4165           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    4166           1 :         fnum = io.ntcreatex.out.file.fnum;
    4167           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
    4168             : 
    4169             :         /* create a file with bogus data */
    4170           1 :         memset(buf, 0, sizeof(buf));
    4171             : 
    4172           1 :         if (smbcli_write(cli1->tree, fnum, 0, buf, 0, sizeof(buf)) !=
    4173             :                          sizeof(buf))
    4174             :         {
    4175           0 :                 torture_comment(tctx, "Failed to create file\n");
    4176           0 :                 goto done;
    4177             :         }
    4178             : 
    4179           1 :         torture_comment(tctx, "a self BRL acquisition should not break to "
    4180             :                         "none\n");
    4181             : 
    4182           1 :         status = smbcli_lock(cli1->tree, fnum, 0, 4, 0, WRITE_LOCK);
    4183           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    4184             : 
    4185           1 :         status = smbcli_lock(cli1->tree, fnum, 2, 4, 0, WRITE_LOCK);
    4186           1 :         CHECK_STATUS(tctx, status, NT_STATUS_LOCK_NOT_GRANTED);
    4187             : 
    4188             :         /* With one file handle open a BRL should not contend our oplock.
    4189             :          * Thus, no oplock break will be received and the entire break_info
    4190             :          * struct will be 0 */
    4191           1 :         torture_wait_for_oplock_break(tctx);
    4192           1 :         CHECK_VAL(break_info.fnum, 0);
    4193           1 :         CHECK_VAL(break_info.count, 0);
    4194           1 :         CHECK_VAL(break_info.level, 0);
    4195           1 :         CHECK_VAL(break_info.failures, 0);
    4196             : 
    4197           1 :         smbcli_close(cli1->tree, fnum);
    4198             : 
    4199           1 : done:
    4200           1 :         smb_raw_exit(cli1->session);
    4201           1 :         smbcli_deltree(cli1->tree, BASEDIR);
    4202           1 :         return ret;
    4203             : }
    4204             : 
    4205             : /* Open a file with a batch oplock twice from one client and then acquire a
    4206             :  * brl. BRL acquisition should break our own oplock.
    4207             :  */
    4208           1 : static bool test_raw_oplock_brl3(struct torture_context *tctx,
    4209             :                                  struct smbcli_state *cli1)
    4210             : {
    4211           1 :         const char *fname = BASEDIR "\\test_batch_brl.dat";
    4212           1 :         bool ret = true;
    4213             :         uint8_t buf[1000];
    4214             :         union smb_open io;
    4215             :         NTSTATUS status;
    4216           1 :         uint16_t fnum=0;
    4217           1 :         uint16_t fnum2=0;
    4218             : 
    4219           1 :         if (!torture_setup_dir(cli1, BASEDIR)) {
    4220           0 :                 return false;
    4221             :         }
    4222             : 
    4223             :         /* cleanup */
    4224           1 :         smbcli_unlink(cli1->tree, fname);
    4225             : 
    4226           1 :         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given,
    4227           1 :                               cli1->tree);
    4228             : 
    4229             :         /*
    4230             :           base ntcreatex parms
    4231             :         */
    4232           1 :         io.generic.level = RAW_OPEN_NTCREATEX;
    4233           1 :         io.ntcreatex.in.root_fid.fnum = 0;
    4234           1 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_READ |
    4235             :                                       SEC_RIGHTS_FILE_WRITE;
    4236           1 :         io.ntcreatex.in.alloc_size = 0;
    4237           1 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
    4238           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
    4239             :                                        NTCREATEX_SHARE_ACCESS_WRITE;
    4240           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
    4241           1 :         io.ntcreatex.in.create_options = 0;
    4242           1 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
    4243           1 :         io.ntcreatex.in.security_flags = 0;
    4244           1 :         io.ntcreatex.in.fname = fname;
    4245             : 
    4246             :         /*
    4247             :           with a batch oplock we get a break
    4248             :         */
    4249           1 :         torture_comment(tctx, "open with batch oplock\n");
    4250           1 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
    4251             :                 NTCREATEX_FLAGS_REQUEST_OPLOCK |
    4252             :                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
    4253             : 
    4254           1 :         status = smb_raw_open(cli1->tree, tctx, &io);
    4255           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    4256           1 :         fnum = io.ntcreatex.out.file.fnum;
    4257           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
    4258             : 
    4259             :         /* create a file with bogus data */
    4260           1 :         memset(buf, 0, sizeof(buf));
    4261             : 
    4262           1 :         if (smbcli_write(cli1->tree, fnum, 0, buf, 0, sizeof(buf)) !=
    4263             :                          sizeof(buf))
    4264             :         {
    4265           0 :                 torture_comment(tctx, "Failed to create file\n");
    4266           0 :                 ret = false;
    4267           0 :                 goto done;
    4268             :         }
    4269             : 
    4270           1 :         torture_comment(tctx, "a 2nd open should give a break\n");
    4271           1 :         ZERO_STRUCT(break_info);
    4272             : 
    4273           1 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
    4274           1 :         status = smb_raw_open(cli1->tree, tctx, &io);
    4275           1 :         fnum2 = io.ntcreatex.out.file.fnum;
    4276           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    4277           1 :         CHECK_VAL(break_info.count, 1);
    4278           1 :         CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
    4279           1 :         CHECK_VAL(break_info.failures, 0);
    4280           1 :         CHECK_VAL(break_info.fnum, fnum);
    4281             : 
    4282           1 :         ZERO_STRUCT(break_info);
    4283             : 
    4284           1 :         torture_comment(tctx, "a self BRL acquisition should break to none\n");
    4285             : 
    4286           1 :         status = smbcli_lock(cli1->tree, fnum, 0, 4, 0, WRITE_LOCK);
    4287           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    4288             : 
    4289           1 :         torture_wait_for_oplock_break(tctx);
    4290           1 :         CHECK_VAL(break_info.count, 1);
    4291           1 :         CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_NONE);
    4292           1 :         CHECK_VAL(break_info.fnum, fnum);
    4293           1 :         CHECK_VAL(break_info.failures, 0);
    4294             : 
    4295             :         /* expect no oplock break */
    4296           1 :         ZERO_STRUCT(break_info);
    4297           1 :         status = smbcli_lock(cli1->tree, fnum, 2, 4, 0, WRITE_LOCK);
    4298           1 :         CHECK_STATUS(tctx, status, NT_STATUS_LOCK_NOT_GRANTED);
    4299             : 
    4300           1 :         torture_wait_for_oplock_break(tctx);
    4301           1 :         CHECK_VAL(break_info.count, 0);
    4302           1 :         CHECK_VAL(break_info.level, 0);
    4303           1 :         CHECK_VAL(break_info.fnum, 0);
    4304           1 :         CHECK_VAL(break_info.failures, 0);
    4305             : 
    4306           1 :         smbcli_close(cli1->tree, fnum);
    4307           1 :         smbcli_close(cli1->tree, fnum2);
    4308             : 
    4309           1 : done:
    4310           1 :         smb_raw_exit(cli1->session);
    4311           1 :         smbcli_deltree(cli1->tree, BASEDIR);
    4312           1 :         return ret;
    4313             : }
    4314             : 
    4315             : /*
    4316             :  * Open a file with an exclusive oplock from the 1st client and acquire a
    4317             :  * brl. Then open the same file from the 2nd client that should give oplock
    4318             :  * break with level2 to the 1st and return no oplock to the 2nd.
    4319             :  */
    4320           1 : static bool test_raw_oplock_brl4(struct torture_context *tctx,
    4321             :                                  struct smbcli_state *cli1,
    4322             :                                  struct smbcli_state *cli2)
    4323             : {
    4324           1 :         const char *fname = BASEDIR "\\test_batch_brl.dat";
    4325           1 :         bool ret = true;
    4326             :         uint8_t buf[1000];
    4327             :         union smb_open io;
    4328             :         NTSTATUS status;
    4329           1 :         uint16_t fnum = 0;
    4330           1 :         uint16_t fnum2 = 0;
    4331             : 
    4332           1 :         if (!torture_setup_dir(cli1, BASEDIR)) {
    4333           0 :                 return false;
    4334             :         }
    4335             : 
    4336             :         /* cleanup */
    4337           1 :         smbcli_unlink(cli1->tree, fname);
    4338             : 
    4339           1 :         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given,
    4340           1 :                               cli1->tree);
    4341             : 
    4342             :         /*
    4343             :           base ntcreatex parms
    4344             :         */
    4345           1 :         io.generic.level = RAW_OPEN_NTCREATEX;
    4346           1 :         io.ntcreatex.in.root_fid.fnum = 0;
    4347           1 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_READ |
    4348             :                                       SEC_RIGHTS_FILE_WRITE;
    4349           1 :         io.ntcreatex.in.alloc_size = 0;
    4350           1 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
    4351           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
    4352             :                                        NTCREATEX_SHARE_ACCESS_WRITE;
    4353           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
    4354           1 :         io.ntcreatex.in.create_options = 0;
    4355           1 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
    4356           1 :         io.ntcreatex.in.security_flags = 0;
    4357           1 :         io.ntcreatex.in.fname = fname;
    4358             : 
    4359           1 :         torture_comment(tctx, "open with exclusive oplock\n");
    4360           1 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
    4361             :                 NTCREATEX_FLAGS_REQUEST_OPLOCK;
    4362             : 
    4363           1 :         status = smb_raw_open(cli1->tree, tctx, &io);
    4364             : 
    4365           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    4366           1 :         fnum = io.ntcreatex.out.file.fnum;
    4367           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
    4368             : 
    4369             :         /* create a file with bogus data */
    4370           1 :         memset(buf, 0, sizeof(buf));
    4371             : 
    4372           1 :         if (smbcli_write(cli1->tree, fnum, 0, buf, 0, sizeof(buf)) !=
    4373             :                          sizeof(buf))
    4374             :         {
    4375           0 :                 torture_comment(tctx, "Failed to create file\n");
    4376           0 :                 goto done;
    4377             :         }
    4378             : 
    4379           1 :         status = smbcli_lock(cli1->tree, fnum, 0, 1, 0, WRITE_LOCK);
    4380           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    4381             : 
    4382           1 :         torture_comment(tctx, "a 2nd open should give a break to the 1st\n");
    4383           1 :         ZERO_STRUCT(break_info);
    4384             : 
    4385           1 :         status = smb_raw_open(cli2->tree, tctx, &io);
    4386             : 
    4387           1 :         CHECK_STATUS(tctx, status, NT_STATUS_OK);
    4388           1 :         CHECK_VAL(break_info.count, 1);
    4389           1 :         CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
    4390           1 :         CHECK_VAL(break_info.failures, 0);
    4391           1 :         CHECK_VAL(break_info.fnum, fnum);
    4392             : 
    4393           1 :         torture_comment(tctx, "and return no oplock to the 2nd\n");
    4394           1 :         fnum2 = io.ntcreatex.out.file.fnum;
    4395           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, NO_OPLOCK_RETURN);
    4396             : 
    4397           1 :         smbcli_close(cli1->tree, fnum);
    4398           1 :         smbcli_close(cli2->tree, fnum2);
    4399             : 
    4400           1 : done:
    4401           1 :         smb_raw_exit(cli1->session);
    4402           1 :         smb_raw_exit(cli2->session);
    4403           1 :         smbcli_deltree(cli1->tree, BASEDIR);
    4404           1 :         return ret;
    4405             : }
    4406             : 
    4407             : /*
    4408             :    basic testing of oplocks
    4409             : */
    4410         964 : struct torture_suite *torture_raw_oplock(TALLOC_CTX *mem_ctx)
    4411             : {
    4412         964 :         struct torture_suite *suite = torture_suite_create(mem_ctx, "oplock");
    4413             : 
    4414         964 :         torture_suite_add_2smb_test(suite, "exclusive1", test_raw_oplock_exclusive1);
    4415         964 :         torture_suite_add_2smb_test(suite, "exclusive2", test_raw_oplock_exclusive2);
    4416         964 :         torture_suite_add_2smb_test(suite, "exclusive3", test_raw_oplock_exclusive3);
    4417         964 :         torture_suite_add_2smb_test(suite, "exclusive4", test_raw_oplock_exclusive4);
    4418         964 :         torture_suite_add_2smb_test(suite, "exclusive5", test_raw_oplock_exclusive5);
    4419         964 :         torture_suite_add_2smb_test(suite, "exclusive6", test_raw_oplock_exclusive6);
    4420         964 :         torture_suite_add_2smb_test(suite, "exclusive7", test_raw_oplock_exclusive7);
    4421         964 :         torture_suite_add_2smb_test(suite, "exclusive8",
    4422             :                                     test_raw_oplock_exclusive8);
    4423         964 :         torture_suite_add_2smb_test(suite, "exclusive9",
    4424             :                                     test_raw_oplock_exclusive9);
    4425         964 :         torture_suite_add_2smb_test(suite, "level_ii_1",
    4426             :                                     test_raw_oplock_level_ii_1);
    4427         964 :         torture_suite_add_2smb_test(suite, "batch1", test_raw_oplock_batch1);
    4428         964 :         torture_suite_add_2smb_test(suite, "batch2", test_raw_oplock_batch2);
    4429         964 :         torture_suite_add_2smb_test(suite, "batch3", test_raw_oplock_batch3);
    4430         964 :         torture_suite_add_2smb_test(suite, "batch4", test_raw_oplock_batch4);
    4431         964 :         torture_suite_add_2smb_test(suite, "batch5", test_raw_oplock_batch5);
    4432         964 :         torture_suite_add_2smb_test(suite, "batch6", test_raw_oplock_batch6);
    4433         964 :         torture_suite_add_2smb_test(suite, "batch7", test_raw_oplock_batch7);
    4434         964 :         torture_suite_add_2smb_test(suite, "batch8", test_raw_oplock_batch8);
    4435         964 :         torture_suite_add_2smb_test(suite, "batch9", test_raw_oplock_batch9);
    4436         964 :         torture_suite_add_2smb_test(suite, "batch9a", test_raw_oplock_batch9a);
    4437         964 :         torture_suite_add_2smb_test(suite, "batch10", test_raw_oplock_batch10);
    4438         964 :         torture_suite_add_2smb_test(suite, "batch11", test_raw_oplock_batch11);
    4439         964 :         torture_suite_add_2smb_test(suite, "batch12", test_raw_oplock_batch12);
    4440         964 :         torture_suite_add_2smb_test(suite, "batch13", test_raw_oplock_batch13);
    4441         964 :         torture_suite_add_2smb_test(suite, "batch14", test_raw_oplock_batch14);
    4442         964 :         torture_suite_add_2smb_test(suite, "batch15", test_raw_oplock_batch15);
    4443         964 :         torture_suite_add_2smb_test(suite, "batch16", test_raw_oplock_batch16);
    4444         964 :         torture_suite_add_2smb_test(suite, "batch17", test_raw_oplock_batch17);
    4445         964 :         torture_suite_add_2smb_test(suite, "batch18", test_raw_oplock_batch18);
    4446         964 :         torture_suite_add_2smb_test(suite, "batch19", test_raw_oplock_batch19);
    4447         964 :         torture_suite_add_2smb_test(suite, "batch20", test_raw_oplock_batch20);
    4448         964 :         torture_suite_add_2smb_test(suite, "batch21", test_raw_oplock_batch21);
    4449         964 :         torture_suite_add_2smb_test(suite, "batch22", test_raw_oplock_batch22);
    4450         964 :         torture_suite_add_2smb_test(suite, "batch23", test_raw_oplock_batch23);
    4451         964 :         torture_suite_add_2smb_test(suite, "batch24", test_raw_oplock_batch24);
    4452         964 :         torture_suite_add_2smb_test(suite, "batch25", test_raw_oplock_batch25);
    4453         964 :         torture_suite_add_2smb_test(suite, "batch26", test_raw_oplock_batch26);
    4454         964 :         torture_suite_add_2smb_test(suite, "stream1", test_raw_oplock_stream1);
    4455         964 :         torture_suite_add_2smb_test(suite, "doc1", test_raw_oplock_doc);
    4456         964 :         torture_suite_add_2smb_test(suite, "brl1", test_raw_oplock_brl1);
    4457         964 :         torture_suite_add_1smb_test(suite, "brl2", test_raw_oplock_brl2);
    4458         964 :         torture_suite_add_1smb_test(suite, "brl3", test_raw_oplock_brl3);
    4459         964 :         torture_suite_add_2smb_test(suite, "brl4", test_raw_oplock_brl4);
    4460             : 
    4461         964 :         return suite;
    4462             : }
    4463             : 
    4464             : /*
    4465             :    stress testing of oplocks
    4466             : */
    4467           0 : bool torture_bench_oplock(struct torture_context *torture)
    4468             : {
    4469             :         struct smbcli_state **cli;
    4470           0 :         bool ret = true;
    4471           0 :         TALLOC_CTX *mem_ctx = talloc_new(torture);
    4472           0 :         int torture_nprocs = torture_setting_int(torture, "nprocs", 4);
    4473           0 :         int i, count=0;
    4474           0 :         int timelimit = torture_setting_int(torture, "timelimit", 10);
    4475             :         union smb_open io;
    4476             :         struct timeval tv;
    4477             : 
    4478           0 :         cli = talloc_array(mem_ctx, struct smbcli_state *, torture_nprocs);
    4479             : 
    4480           0 :         torture_comment(torture, "Opening %d connections\n", torture_nprocs);
    4481           0 :         for (i=0;i<torture_nprocs;i++) {
    4482           0 :                 if (!torture_open_connection_ev(&cli[i], i, torture, torture->ev)) {
    4483           0 :                         return false;
    4484             :                 }
    4485           0 :                 talloc_steal(mem_ctx, cli[i]);
    4486           0 :                 smbcli_oplock_handler(cli[i]->transport, oplock_handler_close, 
    4487           0 :                                       cli[i]->tree);
    4488             :         }
    4489             : 
    4490           0 :         if (!torture_setup_dir(cli[0], BASEDIR)) {
    4491           0 :                 ret = false;
    4492           0 :                 goto done;
    4493             :         }
    4494             : 
    4495           0 :         io.ntcreatex.level = RAW_OPEN_NTCREATEX;
    4496           0 :         io.ntcreatex.in.root_fid.fnum = 0;
    4497           0 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
    4498           0 :         io.ntcreatex.in.alloc_size = 0;
    4499           0 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
    4500           0 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
    4501           0 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
    4502           0 :         io.ntcreatex.in.create_options = 0;
    4503           0 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
    4504           0 :         io.ntcreatex.in.security_flags = 0;
    4505           0 :         io.ntcreatex.in.fname = BASEDIR "\\test.dat";
    4506           0 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | 
    4507             :                 NTCREATEX_FLAGS_REQUEST_OPLOCK | 
    4508             :                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
    4509             : 
    4510           0 :         tv = timeval_current(); 
    4511             : 
    4512             :         /*
    4513             :           we open the same file with SHARE_ACCESS_NONE from all the
    4514             :           connections in a round robin fashion. Each open causes an
    4515             :           oplock break on the previous connection, which is answered
    4516             :           by the oplock_handler_close() to close the file.
    4517             : 
    4518             :           This measures how fast we can pass on oplocks, and stresses
    4519             :           the oplock handling code
    4520             :         */
    4521           0 :         torture_comment(torture, "Running for %d seconds\n", timelimit);
    4522           0 :         while (timeval_elapsed(&tv) < timelimit) {
    4523           0 :                 for (i=0;i<torture_nprocs;i++) {
    4524             :                         NTSTATUS status;
    4525             : 
    4526           0 :                         status = smb_raw_open(cli[i]->tree, mem_ctx, &io);
    4527           0 :                         CHECK_STATUS(torture, status, NT_STATUS_OK);
    4528           0 :                         count++;
    4529             :                 }
    4530             : 
    4531           0 :                 if (torture_setting_bool(torture, "progress", true)) {
    4532           0 :                         torture_comment(torture, "%.2f ops/second\r", count/timeval_elapsed(&tv));
    4533             :                 }
    4534             :         }
    4535             : 
    4536           0 :         torture_comment(torture, "%.2f ops/second\n", count/timeval_elapsed(&tv));
    4537             : 
    4538           0 :         smb_raw_exit(cli[torture_nprocs-1]->session);
    4539             :         
    4540           0 : done:
    4541           0 :         smb_raw_exit(cli[0]->session);
    4542           0 :         smbcli_deltree(cli[0]->tree, BASEDIR);
    4543           0 :         talloc_free(mem_ctx);
    4544           0 :         return ret;
    4545             : }
    4546             : 
    4547             : 
    4548             : static struct hold_oplock_info {
    4549             :         const char *fname;
    4550             :         bool close_on_break;
    4551             :         uint32_t share_access;
    4552             :         uint16_t fnum;
    4553             : } hold_info[] = {
    4554             :         {
    4555             :                 .fname          = BASEDIR "\\notshared_close",
    4556             :                 .close_on_break = true,
    4557             :                 .share_access   = NTCREATEX_SHARE_ACCESS_NONE,
    4558             :         },
    4559             :         {
    4560             :                 .fname          = BASEDIR "\\notshared_noclose",
    4561             :                 .close_on_break = false,
    4562             :                 .share_access   = NTCREATEX_SHARE_ACCESS_NONE,
    4563             :         },
    4564             :         {
    4565             :                 .fname          = BASEDIR "\\shared_close",
    4566             :                 .close_on_break = true,
    4567             :                 .share_access   = NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE,
    4568             :         },
    4569             :         {
    4570             :                 .fname          = BASEDIR "\\shared_noclose",
    4571             :                 .close_on_break = false,
    4572             :                 .share_access   = NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE,
    4573             :         },
    4574             : };
    4575             : 
    4576           0 : static bool oplock_handler_hold(struct smbcli_transport *transport, 
    4577             :                                 uint16_t tid, uint16_t fnum, uint8_t level, 
    4578             :                                 void *private_data)
    4579             : {
    4580           0 :         struct smbcli_tree *tree = (struct smbcli_tree *)private_data;
    4581             :         struct hold_oplock_info *info;
    4582             :         int i;
    4583             : 
    4584           0 :         for (i=0;i<ARRAY_SIZE(hold_info);i++) {
    4585           0 :                 if (hold_info[i].fnum == fnum) break;
    4586             :         }
    4587             : 
    4588           0 :         if (i == ARRAY_SIZE(hold_info)) {
    4589           0 :                 printf("oplock break for unknown fnum %u\n", fnum);
    4590           0 :                 return false;
    4591             :         }
    4592             : 
    4593           0 :         info = &hold_info[i];
    4594             : 
    4595           0 :         if (info->close_on_break) {
    4596           0 :                 printf("oplock break on %s - closing\n",
    4597             :                        info->fname);
    4598           0 :                 oplock_handler_close(transport, tid, fnum, level, private_data);
    4599           0 :                 return true;
    4600             :         }
    4601             : 
    4602           0 :         printf("oplock break on %s - acking break\n", info->fname);
    4603             : 
    4604           0 :         return smbcli_oplock_ack(tree, fnum, OPLOCK_BREAK_TO_NONE);
    4605             : }
    4606             : 
    4607             : 
    4608             : /* 
    4609             :    used for manual testing of oplocks - especially interaction with
    4610             :    other filesystems (such as NFS and local access)
    4611             : */
    4612           0 : bool torture_hold_oplock(struct torture_context *torture, 
    4613             :                          struct smbcli_state *cli)
    4614             : {
    4615           0 :         struct tevent_context *ev = torture->ev;
    4616             :         int i;
    4617             : 
    4618           0 :         printf("Setting up open files with oplocks in %s\n", BASEDIR);
    4619             : 
    4620           0 :         torture_assert(torture, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
    4621             : 
    4622           0 :         smbcli_oplock_handler(cli->transport, oplock_handler_hold, cli->tree);
    4623             : 
    4624             :         /* setup the files */
    4625           0 :         for (i=0;i<ARRAY_SIZE(hold_info);i++) {
    4626             :                 union smb_open io;
    4627             :                 NTSTATUS status;
    4628           0 :                 char c = 1;
    4629             : 
    4630           0 :                 io.generic.level = RAW_OPEN_NTCREATEX;
    4631           0 :                 io.ntcreatex.in.root_fid.fnum = 0;
    4632           0 :                 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
    4633           0 :                 io.ntcreatex.in.alloc_size = 0;
    4634           0 :                 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
    4635           0 :                 io.ntcreatex.in.share_access = hold_info[i].share_access;
    4636           0 :                 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
    4637           0 :                 io.ntcreatex.in.create_options = 0;
    4638           0 :                 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
    4639           0 :                 io.ntcreatex.in.security_flags = 0;
    4640           0 :                 io.ntcreatex.in.fname = hold_info[i].fname;
    4641           0 :                 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | 
    4642             :                         NTCREATEX_FLAGS_REQUEST_OPLOCK |
    4643             :                         NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
    4644           0 :                 printf("opening %s\n", hold_info[i].fname);
    4645             : 
    4646           0 :                 status = smb_raw_open(cli->tree, cli, &io);
    4647           0 :                 if (!NT_STATUS_IS_OK(status)) {
    4648           0 :                         printf("Failed to open %s - %s\n", 
    4649             :                                hold_info[i].fname, nt_errstr(status));
    4650           0 :                         return false;
    4651             :                 }
    4652             : 
    4653           0 :                 if (io.ntcreatex.out.oplock_level != BATCH_OPLOCK_RETURN) {
    4654           0 :                         printf("Oplock not granted for %s - expected %d but got %d\n", 
    4655             :                                hold_info[i].fname, BATCH_OPLOCK_RETURN, 
    4656           0 :                                 io.ntcreatex.out.oplock_level);
    4657           0 :                         return false;
    4658             :                 }
    4659           0 :                 hold_info[i].fnum = io.ntcreatex.out.file.fnum;
    4660             : 
    4661             :                 /* make the file non-zero size */
    4662           0 :                 if (smbcli_write(cli->tree, hold_info[i].fnum, 0, &c, 0, 1) != 1) {
    4663           0 :                         printf("Failed to write to file\n");
    4664           0 :                         return false;
    4665             :                 }
    4666             :         }
    4667             : 
    4668           0 :         printf("Waiting for oplock events\n");
    4669           0 :         tevent_loop_wait(ev);
    4670             : 
    4671           0 :         return true;
    4672             : }

Generated by: LCOV version 1.13