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