root/source4/torture/raw/oplock.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. oplock_handler_ack_to_given
  2. oplock_handler_ack_to_none
  3. oplock_handler_timeout
  4. oplock_handler_close_recv
  5. oplock_handler_close
  6. open_connection_no_level2_oplocks
  7. test_raw_oplock_exclusive1
  8. test_raw_oplock_exclusive2
  9. test_raw_oplock_exclusive3
  10. test_raw_oplock_exclusive4
  11. test_raw_oplock_exclusive5
  12. test_raw_oplock_exclusive6
  13. test_raw_oplock_batch1
  14. test_raw_oplock_batch2
  15. test_raw_oplock_batch3
  16. test_raw_oplock_batch4
  17. test_raw_oplock_batch5
  18. test_raw_oplock_batch6
  19. test_raw_oplock_batch7
  20. test_raw_oplock_batch8
  21. test_raw_oplock_batch9
  22. test_raw_oplock_batch10
  23. test_raw_oplock_batch11
  24. test_raw_oplock_batch12
  25. test_raw_oplock_batch13
  26. test_raw_oplock_batch14
  27. test_raw_oplock_batch15
  28. test_raw_oplock_batch16
  29. test_raw_oplock_batch17
  30. test_raw_oplock_batch18
  31. test_raw_oplock_batch19
  32. test_trans2rename
  33. test_nttransrename
  34. test_raw_oplock_batch20
  35. test_raw_oplock_batch21
  36. test_raw_oplock_batch22
  37. test_raw_oplock_batch23
  38. test_raw_oplock_batch24
  39. test_raw_oplock_batch25
  40. torture_raw_oplock
  41. torture_bench_oplock
  42. oplock_handler_hold
  43. torture_hold_oplock

   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 "torture/torture.h"
  22 #include "librpc/gen_ndr/security.h"
  23 #include "libcli/raw/libcliraw.h"
  24 #include "libcli/raw/raw_proto.h"
  25 #include "libcli/libcli.h"
  26 #include "torture/util.h"
  27 #include "lib/events/events.h"
  28 #include "param/param.h"
  29 #include "lib/cmdline/popt_common.h"
  30 #include "libcli/resolve/resolve.h"
  31 
  32 #define CHECK_VAL(v, correct) do { \
  33         if ((v) != (correct)) { \
  34                 torture_result(tctx, TORTURE_FAIL, "(%s): wrong value for %s got 0x%x - should be 0x%x\n", \
  35                                 __location__, #v, (int)v, (int)correct); \
  36                 ret = false; \
  37         }} while (0)
  38 
  39 #define CHECK_RANGE(v, min, max) do { \
  40         if ((v) < (min) || (v) > (max)) { \
  41                 torture_result(tctx, TORTURE_FAIL, "(%s): wrong value for %s got %d - should be between %d and %d\n", \
  42                                 __location__, #v, (int)v, (int)min, (int)max); \
  43                 ret = false; \
  44         }} while (0)
  45 
  46 #define CHECK_STRMATCH(v, correct) do { \
  47         if (!v || strstr((v),(correct)) == NULL) { \
  48                 torture_result(tctx, TORTURE_FAIL,  "(%s): wrong value for %s got '%s' - should be '%s'\n", \
  49                                 __location__, #v, v?v:"NULL", correct); \
  50                 ret = false; \
  51         } \
  52 } while (0)
  53 
  54 #define CHECK_STATUS(tctx, status, correct) do { \
  55         if (!NT_STATUS_EQUAL(status, correct)) { \
  56                 torture_result(tctx, TORTURE_FAIL, __location__": Incorrect status %s - should be %s", \
  57                        nt_errstr(status), nt_errstr(correct)); \
  58                 ret = false; \
  59                 goto done; \
  60         }} while (0)
  61 
  62 
  63 static struct {
  64         int fnum;
  65         uint8_t level;
  66         int count;
  67         int failures;
  68 } break_info;
  69 
  70 #define BASEDIR "\\test_oplock"
  71 
  72 /*
  73   a handler function for oplock break requests. Ack it as a break to level II if possible
  74 */
  75 static bool oplock_handler_ack_to_given(struct smbcli_transport *transport,
     /* [<][>][^][v][top][bottom][index][help] */
  76                                         uint16_t tid, uint16_t fnum,
  77                                         uint8_t level, void *private_data)
  78 {
  79         struct smbcli_tree *tree = (struct smbcli_tree *)private_data;
  80         const char *name;
  81 
  82         break_info.fnum = fnum;
  83         break_info.level = level;
  84         break_info.count++;
  85 
  86         switch (level) {
  87         case OPLOCK_BREAK_TO_LEVEL_II:
  88                 name = "level II";
  89                 break;
  90         case OPLOCK_BREAK_TO_NONE:
  91                 name = "none";
  92                 break;
  93         default:
  94                 name = "unknown";
  95                 break_info.failures++;
  96         }
  97         printf("Acking to %s [0x%02X] in oplock handler\n",
  98                 name, level);
  99 
 100         return smbcli_oplock_ack(tree, fnum, level);
 101 }
 102 
 103 /*
 104   a handler function for oplock break requests. Ack it as a break to none
 105 */
 106 static bool oplock_handler_ack_to_none(struct smbcli_transport *transport, 
     /* [<][>][^][v][top][bottom][index][help] */
 107                                        uint16_t tid, uint16_t fnum, 
 108                                        uint8_t level, void *private_data)
 109 {
 110         struct smbcli_tree *tree = (struct smbcli_tree *)private_data;
 111         break_info.fnum = fnum;
 112         break_info.level = level;
 113         break_info.count++;
 114 
 115         printf("Acking to none in oplock handler\n");
 116 
 117         return smbcli_oplock_ack(tree, fnum, OPLOCK_BREAK_TO_NONE);
 118 }
 119 
 120 /*
 121   a handler function for oplock break requests. Let it timeout
 122 */
 123 static bool oplock_handler_timeout(struct smbcli_transport *transport,
     /* [<][>][^][v][top][bottom][index][help] */
 124                                    uint16_t tid, uint16_t fnum,
 125                                    uint8_t level, void *private_data)
 126 {
 127         break_info.fnum = fnum;
 128         break_info.level = level;
 129         break_info.count++;
 130 
 131         printf("Let oplock break timeout\n");
 132         return true;
 133 }
 134 
 135 static void oplock_handler_close_recv(struct smbcli_request *req)
     /* [<][>][^][v][top][bottom][index][help] */
 136 {
 137         NTSTATUS status;
 138         status = smbcli_request_simple_recv(req);
 139         if (!NT_STATUS_IS_OK(status)) {
 140                 printf("close failed in oplock_handler_close\n");
 141                 break_info.failures++;
 142         }
 143 }
 144 
 145 /*
 146   a handler function for oplock break requests - close the file
 147 */
 148 static bool oplock_handler_close(struct smbcli_transport *transport, uint16_t tid, 
     /* [<][>][^][v][top][bottom][index][help] */
 149                                  uint16_t fnum, uint8_t level, void *private_data)
 150 {
 151         union smb_close io;
 152         struct smbcli_tree *tree = (struct smbcli_tree *)private_data;
 153         struct smbcli_request *req;
 154 
 155         break_info.fnum = fnum;
 156         break_info.level = level;
 157         break_info.count++;
 158 
 159         io.close.level = RAW_CLOSE_CLOSE;
 160         io.close.in.file.fnum = fnum;
 161         io.close.in.write_time = 0;
 162         req = smb_raw_close_send(tree, &io);
 163         if (req == NULL) {
 164                 printf("failed to send close in oplock_handler_close\n");
 165                 return false;
 166         }
 167 
 168         req->async.fn = oplock_handler_close_recv;
 169         req->async.private_data = NULL;
 170 
 171         return true;
 172 }
 173 
 174 static bool open_connection_no_level2_oplocks(struct torture_context *tctx,
     /* [<][>][^][v][top][bottom][index][help] */
 175                                               struct smbcli_state **c)
 176 {
 177         NTSTATUS status;
 178         struct smbcli_options options;
 179         struct smbcli_session_options session_options;
 180 
 181         lp_smbcli_options(tctx->lp_ctx, &options);
 182         lp_smbcli_session_options(tctx->lp_ctx, &session_options);
 183 
 184         options.use_level2_oplocks = false;
 185 
 186         status = smbcli_full_connection(tctx, c,
 187                                         torture_setting_string(tctx, "host", NULL),
 188                                         lp_smb_ports(tctx->lp_ctx),
 189                                         torture_setting_string(tctx, "share", NULL),
 190                                         NULL, lp_socket_options(tctx->lp_ctx), cmdline_credentials,
 191                                         lp_resolve_context(tctx->lp_ctx),
 192                                         tctx->ev, &options, &session_options,
 193                                         lp_iconv_convenience(tctx->lp_ctx),
 194                                         lp_gensec_settings(tctx, tctx->lp_ctx));
 195         if (!NT_STATUS_IS_OK(status)) {
 196                 printf("Failed to open connection - %s\n", nt_errstr(status));
 197                 return false;
 198         }
 199 
 200         return true;
 201 }
 202 
 203 static bool test_raw_oplock_exclusive1(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
     /* [<][>][^][v][top][bottom][index][help] */
 204 {
 205         const char *fname = BASEDIR "\\test_exclusive1.dat";
 206         NTSTATUS status;
 207         bool ret = true;
 208         union smb_open io;
 209         union smb_unlink unl;
 210         uint16_t fnum=0;
 211 
 212         if (!torture_setup_dir(cli1, BASEDIR)) {
 213                 return false;
 214         }
 215 
 216         /* cleanup */
 217         smbcli_unlink(cli1->tree, fname);
 218 
 219         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
 220 
 221         /*
 222           base ntcreatex parms
 223         */
 224         io.generic.level = RAW_OPEN_NTCREATEX;
 225         io.ntcreatex.in.root_fid = 0;
 226         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
 227         io.ntcreatex.in.alloc_size = 0;
 228         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
 229         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
 230         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
 231         io.ntcreatex.in.create_options = 0;
 232         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
 233         io.ntcreatex.in.security_flags = 0;
 234         io.ntcreatex.in.fname = fname;
 235 
 236         torture_comment(tctx, "EXCLUSIVE1: open a file with an exclusive oplock (share mode: none)\n");
 237         ZERO_STRUCT(break_info);
 238         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
 239 
 240         status = smb_raw_open(cli1->tree, tctx, &io);
 241         CHECK_STATUS(tctx, status, NT_STATUS_OK);
 242         fnum = io.ntcreatex.out.file.fnum;
 243         CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
 244 
 245         torture_comment(tctx, "a 2nd open should not cause a break\n");
 246         status = smb_raw_open(cli2->tree, tctx, &io);
 247         CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
 248         CHECK_VAL(break_info.count, 0);
 249         CHECK_VAL(break_info.failures, 0);
 250 
 251         torture_comment(tctx, "unlink it - should also be no break\n");
 252         unl.unlink.in.pattern = fname;
 253         unl.unlink.in.attrib = 0;
 254         status = smb_raw_unlink(cli2->tree, &unl);
 255         CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
 256         CHECK_VAL(break_info.count, 0);
 257         CHECK_VAL(break_info.failures, 0);
 258 
 259         smbcli_close(cli1->tree, fnum);
 260 
 261 done:
 262         smb_raw_exit(cli1->session);
 263         smb_raw_exit(cli2->session);
 264         smbcli_deltree(cli1->tree, BASEDIR);
 265         return ret;
 266 }
 267 
 268 static bool test_raw_oplock_exclusive2(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
     /* [<][>][^][v][top][bottom][index][help] */
 269 {
 270         const char *fname = BASEDIR "\\test_exclusive2.dat";
 271         NTSTATUS status;
 272         bool ret = true;
 273         union smb_open io;
 274         union smb_unlink unl;
 275         uint16_t fnum=0, fnum2=0;
 276 
 277         if (!torture_setup_dir(cli1, BASEDIR)) {
 278                 return false;
 279         }
 280 
 281         /* cleanup */
 282         smbcli_unlink(cli1->tree, fname);
 283 
 284         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
 285 
 286         /*
 287           base ntcreatex parms
 288         */
 289         io.generic.level = RAW_OPEN_NTCREATEX;
 290         io.ntcreatex.in.root_fid = 0;
 291         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
 292         io.ntcreatex.in.alloc_size = 0;
 293         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
 294         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
 295         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
 296         io.ntcreatex.in.create_options = 0;
 297         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
 298         io.ntcreatex.in.security_flags = 0;
 299         io.ntcreatex.in.fname = fname;
 300 
 301         torture_comment(tctx, "EXCLUSIVE2: open a file with an exclusive oplock (share mode: all)\n");
 302         ZERO_STRUCT(break_info);
 303         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
 304         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
 305                 NTCREATEX_SHARE_ACCESS_WRITE|
 306                 NTCREATEX_SHARE_ACCESS_DELETE;
 307 
 308         status = smb_raw_open(cli1->tree, tctx, &io);
 309         CHECK_STATUS(tctx, status, NT_STATUS_OK);
 310         fnum = io.ntcreatex.out.file.fnum;
 311         CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
 312 
 313         torture_comment(tctx, "a 2nd open should cause a break to level 2\n");
 314         status = smb_raw_open(cli2->tree, tctx, &io);
 315         CHECK_STATUS(tctx, status, NT_STATUS_OK);
 316         fnum2 = io.ntcreatex.out.file.fnum;
 317         CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
 318         CHECK_VAL(break_info.count, 1);
 319         CHECK_VAL(break_info.fnum, fnum);
 320         CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
 321         CHECK_VAL(break_info.failures, 0);
 322         ZERO_STRUCT(break_info);
 323 
 324         /* now we have 2 level II oplocks... */
 325         torture_comment(tctx, "try to unlink it - should not cause a break, but a sharing violation\n");
 326         unl.unlink.in.pattern = fname;
 327         unl.unlink.in.attrib = 0;
 328         status = smb_raw_unlink(cli2->tree, &unl);
 329         CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
 330         CHECK_VAL(break_info.count, 0);
 331         CHECK_VAL(break_info.failures, 0);
 332 
 333         torture_comment(tctx, "close 1st handle\n");
 334         smbcli_close(cli1->tree, fnum);
 335 
 336         torture_comment(tctx, "try to unlink it - should not cause a break, but a sharing violation\n");
 337         unl.unlink.in.pattern = fname;
 338         unl.unlink.in.attrib = 0;
 339         status = smb_raw_unlink(cli2->tree, &unl);
 340         CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
 341         CHECK_VAL(break_info.count, 0);
 342         CHECK_VAL(break_info.failures, 0);
 343 
 344         torture_comment(tctx, "close 1st handle\n");
 345         smbcli_close(cli2->tree, fnum2);
 346 
 347         torture_comment(tctx, "unlink it\n");
 348         unl.unlink.in.pattern = fname;
 349         unl.unlink.in.attrib = 0;
 350         status = smb_raw_unlink(cli2->tree, &unl);
 351         CHECK_STATUS(tctx, status, NT_STATUS_OK);
 352         CHECK_VAL(break_info.count, 0);
 353         CHECK_VAL(break_info.failures, 0);
 354 
 355 done:
 356         smb_raw_exit(cli1->session);
 357         smb_raw_exit(cli2->session);
 358         smbcli_deltree(cli1->tree, BASEDIR);
 359         return ret;
 360 }
 361 
 362 static bool test_raw_oplock_exclusive3(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
     /* [<][>][^][v][top][bottom][index][help] */
 363 {
 364         const char *fname = BASEDIR "\\test_exclusive3.dat";
 365         NTSTATUS status;
 366         bool ret = true;
 367         union smb_open io;
 368         union smb_setfileinfo sfi;
 369         uint16_t fnum=0;
 370 
 371         if (!torture_setup_dir(cli1, BASEDIR)) {
 372                 return false;
 373         }
 374 
 375         /* cleanup */
 376         smbcli_unlink(cli1->tree, fname);
 377 
 378         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
 379 
 380         /*
 381           base ntcreatex parms
 382         */
 383         io.generic.level = RAW_OPEN_NTCREATEX;
 384         io.ntcreatex.in.root_fid = 0;
 385         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
 386         io.ntcreatex.in.alloc_size = 0;
 387         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
 388         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
 389         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
 390         io.ntcreatex.in.create_options = 0;
 391         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
 392         io.ntcreatex.in.security_flags = 0;
 393         io.ntcreatex.in.fname = fname;
 394 
 395         torture_comment(tctx, "EXCLUSIVE3: open a file with an exclusive oplock (share mode: none)\n");
 396 
 397         ZERO_STRUCT(break_info);
 398         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
 399 
 400         status = smb_raw_open(cli1->tree, tctx, &io);
 401         CHECK_STATUS(tctx, status, NT_STATUS_OK);
 402         fnum = io.ntcreatex.out.file.fnum;
 403         CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
 404 
 405         torture_comment(tctx, "setpathinfo EOF should trigger a break to none\n");
 406         ZERO_STRUCT(sfi);
 407         sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
 408         sfi.generic.in.file.path = fname;
 409         sfi.end_of_file_info.in.size = 100;
 410 
 411         status = smb_raw_setpathinfo(cli2->tree, &sfi);
 412 
 413         CHECK_STATUS(tctx, status, NT_STATUS_OK);
 414         CHECK_VAL(break_info.count, 1);
 415         CHECK_VAL(break_info.failures, 0);
 416         CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_NONE);
 417 
 418         smbcli_close(cli1->tree, fnum);
 419 
 420 done:
 421         smb_raw_exit(cli1->session);
 422         smb_raw_exit(cli2->session);
 423         smbcli_deltree(cli1->tree, BASEDIR);
 424         return ret;
 425 }
 426 
 427 static bool test_raw_oplock_exclusive4(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
     /* [<][>][^][v][top][bottom][index][help] */
 428 {
 429         const char *fname = BASEDIR "\\test_exclusive4.dat";
 430         NTSTATUS status;
 431         bool ret = true;
 432         union smb_open io;
 433         uint16_t fnum=0, fnum2=0;
 434 
 435         if (!torture_setup_dir(cli1, BASEDIR)) {
 436                 return false;
 437         }
 438 
 439         /* cleanup */
 440         smbcli_unlink(cli1->tree, fname);
 441 
 442         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
 443 
 444         /*
 445           base ntcreatex parms
 446         */
 447         io.generic.level = RAW_OPEN_NTCREATEX;
 448         io.ntcreatex.in.root_fid = 0;
 449         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
 450         io.ntcreatex.in.alloc_size = 0;
 451         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
 452         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
 453         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
 454         io.ntcreatex.in.create_options = 0;
 455         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
 456         io.ntcreatex.in.security_flags = 0;
 457         io.ntcreatex.in.fname = fname;
 458 
 459         torture_comment(tctx, "EXCLUSIVE4: open with exclusive oplock\n");
 460         ZERO_STRUCT(break_info);
 461         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
 462 
 463         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
 464         status = smb_raw_open(cli1->tree, tctx, &io);
 465         CHECK_STATUS(tctx, status, NT_STATUS_OK);
 466         fnum = io.ntcreatex.out.file.fnum;
 467         CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
 468 
 469         ZERO_STRUCT(break_info);
 470         torture_comment(tctx, "second open with attributes only shouldn't cause oplock break\n");
 471 
 472         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
 473         io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
 474         status = smb_raw_open(cli2->tree, tctx, &io);
 475         CHECK_STATUS(tctx, status, NT_STATUS_OK);
 476         fnum2 = io.ntcreatex.out.file.fnum;
 477         CHECK_VAL(io.ntcreatex.out.oplock_level, NO_OPLOCK_RETURN);
 478         CHECK_VAL(break_info.count, 0);
 479         CHECK_VAL(break_info.failures, 0);
 480 
 481         smbcli_close(cli1->tree, fnum);
 482         smbcli_close(cli2->tree, fnum2);
 483 
 484 done:
 485         smb_raw_exit(cli1->session);
 486         smb_raw_exit(cli2->session);
 487         smbcli_deltree(cli1->tree, BASEDIR);
 488         return ret;
 489 }
 490 
 491 static bool test_raw_oplock_exclusive5(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
     /* [<][>][^][v][top][bottom][index][help] */
 492 {
 493         const char *fname = BASEDIR "\\test_exclusive5.dat";
 494         NTSTATUS status;
 495         bool ret = true;
 496         union smb_open io;
 497         uint16_t fnum=0, fnum2=0;
 498 
 499         if (!torture_setup_dir(cli1, BASEDIR)) {
 500                 return false;
 501         }
 502 
 503         /* cleanup */
 504         smbcli_unlink(cli1->tree, fname);
 505 
 506         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
 507         smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli1->tree);
 508 
 509         /*
 510           base ntcreatex parms
 511         */
 512         io.generic.level = RAW_OPEN_NTCREATEX;
 513         io.ntcreatex.in.root_fid = 0;
 514         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
 515         io.ntcreatex.in.alloc_size = 0;
 516         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
 517         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
 518         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
 519         io.ntcreatex.in.create_options = 0;
 520         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
 521         io.ntcreatex.in.security_flags = 0;
 522         io.ntcreatex.in.fname = fname;
 523 
 524         torture_comment(tctx, "EXCLUSIVE5: open with exclusive oplock\n");
 525         ZERO_STRUCT(break_info);
 526         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
 527 
 528 
 529         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
 530         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
 531                 NTCREATEX_SHARE_ACCESS_WRITE|
 532                 NTCREATEX_SHARE_ACCESS_DELETE;
 533         status = smb_raw_open(cli1->tree, tctx, &io);
 534         CHECK_STATUS(tctx, status, NT_STATUS_OK);
 535         fnum = io.ntcreatex.out.file.fnum;
 536         CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
 537 
 538         ZERO_STRUCT(break_info);
 539 
 540         torture_comment(tctx, "second open with attributes only and NTCREATEX_DISP_OVERWRITE_IF dispostion causes oplock break\n");
 541 
 542         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
 543         io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
 544         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE_IF;
 545         status = smb_raw_open(cli2->tree, tctx, &io);
 546         CHECK_STATUS(tctx, status, NT_STATUS_OK);
 547         fnum2 = io.ntcreatex.out.file.fnum;
 548         CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
 549         CHECK_VAL(break_info.count, 1);
 550         CHECK_VAL(break_info.failures, 0);
 551 
 552         smbcli_close(cli1->tree, fnum);
 553         smbcli_close(cli2->tree, fnum2);
 554 
 555 done:
 556         smb_raw_exit(cli1->session);
 557         smb_raw_exit(cli2->session);
 558         smbcli_deltree(cli1->tree, BASEDIR);
 559         return ret;
 560 }
 561 
 562 static bool test_raw_oplock_exclusive6(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
     /* [<][>][^][v][top][bottom][index][help] */
 563 {
 564         const char *fname1 = BASEDIR "\\test_exclusive6_1.dat";
 565         const char *fname2 = BASEDIR "\\test_exclusive6_2.dat";
 566         NTSTATUS status;
 567         bool ret = true;
 568         union smb_open io;
 569         union smb_rename rn;
 570         uint16_t fnum=0;
 571 
 572         if (!torture_setup_dir(cli1, BASEDIR)) {
 573                 return false;
 574         }
 575 
 576         /* cleanup */
 577         smbcli_unlink(cli1->tree, fname1);
 578         smbcli_unlink(cli1->tree, fname2);
 579 
 580         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
 581 
 582         /*
 583           base ntcreatex parms
 584         */
 585         io.generic.level = RAW_OPEN_NTCREATEX;
 586         io.ntcreatex.in.root_fid = 0;
 587         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
 588         io.ntcreatex.in.alloc_size = 0;
 589         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
 590         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
 591         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
 592         io.ntcreatex.in.create_options = 0;
 593         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
 594         io.ntcreatex.in.security_flags = 0;
 595         io.ntcreatex.in.fname = fname1;
 596 
 597         torture_comment(tctx, "EXCLUSIVE6: open a file with an exclusive oplock (share mode: none)\n");
 598         ZERO_STRUCT(break_info);
 599         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
 600 
 601         status = smb_raw_open(cli1->tree, tctx, &io);
 602         CHECK_STATUS(tctx, status, NT_STATUS_OK);
 603         fnum = io.ntcreatex.out.file.fnum;
 604         CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
 605 
 606         torture_comment(tctx, "rename should not generate a break but get a sharing violation\n");
 607         ZERO_STRUCT(rn);
 608         rn.generic.level = RAW_RENAME_RENAME;
 609         rn.rename.in.pattern1 = fname1;
 610         rn.rename.in.pattern2 = fname2;
 611         rn.rename.in.attrib = 0;
 612 
 613         printf("trying rename while first file open\n");
 614         status = smb_raw_rename(cli2->tree, &rn);
 615 
 616         CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
 617         CHECK_VAL(break_info.count, 0);
 618         CHECK_VAL(break_info.failures, 0);
 619 
 620         smbcli_close(cli1->tree, fnum);
 621 
 622 done:
 623         smb_raw_exit(cli1->session);
 624         smb_raw_exit(cli2->session);
 625         smbcli_deltree(cli1->tree, BASEDIR);
 626         return ret;
 627 }
 628 
 629 static bool test_raw_oplock_batch1(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
     /* [<][>][^][v][top][bottom][index][help] */
 630 {
 631         const char *fname = BASEDIR "\\test_batch1.dat";
 632         NTSTATUS status;
 633         bool ret = true;
 634         union smb_open io;
 635         union smb_unlink unl;
 636         uint16_t fnum=0;
 637         char c = 0;
 638 
 639         if (!torture_setup_dir(cli1, BASEDIR)) {
 640                 return false;
 641         }
 642 
 643         /* cleanup */
 644         smbcli_unlink(cli1->tree, fname);
 645 
 646         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
 647 
 648         /*
 649           base ntcreatex parms
 650         */
 651         io.generic.level = RAW_OPEN_NTCREATEX;
 652         io.ntcreatex.in.root_fid = 0;
 653         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
 654         io.ntcreatex.in.alloc_size = 0;
 655         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
 656         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
 657         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
 658         io.ntcreatex.in.create_options = 0;
 659         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
 660         io.ntcreatex.in.security_flags = 0;
 661         io.ntcreatex.in.fname = fname;
 662 
 663         /*
 664           with a batch oplock we get a break
 665         */
 666         torture_comment(tctx, "BATCH1: open with batch oplock\n");
 667         ZERO_STRUCT(break_info);
 668         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | 
 669                 NTCREATEX_FLAGS_REQUEST_OPLOCK | 
 670                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
 671         status = smb_raw_open(cli1->tree, tctx, &io);
 672         CHECK_STATUS(tctx, status, NT_STATUS_OK);
 673         fnum = io.ntcreatex.out.file.fnum;
 674         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
 675 
 676         torture_comment(tctx, "unlink should generate a break\n");
 677         unl.unlink.in.pattern = fname;
 678         unl.unlink.in.attrib = 0;
 679         status = smb_raw_unlink(cli2->tree, &unl);
 680         CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
 681 
 682         CHECK_VAL(break_info.count, 1);
 683         CHECK_VAL(break_info.fnum, fnum);
 684         CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
 685         CHECK_VAL(break_info.failures, 0);
 686 
 687         torture_comment(tctx, "2nd unlink should not generate a break\n");
 688         ZERO_STRUCT(break_info);
 689         status = smb_raw_unlink(cli2->tree, &unl);
 690         CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
 691 
 692         CHECK_VAL(break_info.count, 0);
 693 
 694         torture_comment(tctx, "writing should generate a self break to none\n");
 695         smbcli_write(cli1->tree, fnum, 0, &c, 0, 1);
 696         msleep(100);
 697         smbcli_write(cli1->tree, fnum, 0, &c, 1, 1);
 698 
 699         CHECK_VAL(break_info.count, 1);
 700         CHECK_VAL(break_info.fnum, fnum);
 701         CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_NONE);
 702         CHECK_VAL(break_info.failures, 0);
 703 
 704         smbcli_close(cli1->tree, fnum);
 705 
 706 done:
 707         smb_raw_exit(cli1->session);
 708         smb_raw_exit(cli2->session);
 709         smbcli_deltree(cli1->tree, BASEDIR);
 710         return ret;
 711 }
 712 
 713 static bool test_raw_oplock_batch2(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
     /* [<][>][^][v][top][bottom][index][help] */
 714 {
 715         const char *fname = BASEDIR "\\test_batch2.dat";
 716         NTSTATUS status;
 717         bool ret = true;
 718         union smb_open io;
 719         union smb_unlink unl;
 720         uint16_t fnum=0;
 721         char c = 0;
 722 
 723         if (!torture_setup_dir(cli1, BASEDIR)) {
 724                 return false;
 725         }
 726 
 727         /* cleanup */
 728         smbcli_unlink(cli1->tree, fname);
 729 
 730         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
 731 
 732         /*
 733           base ntcreatex parms
 734         */
 735         io.generic.level = RAW_OPEN_NTCREATEX;
 736         io.ntcreatex.in.root_fid = 0;
 737         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
 738         io.ntcreatex.in.alloc_size = 0;
 739         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
 740         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
 741         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
 742         io.ntcreatex.in.create_options = 0;
 743         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
 744         io.ntcreatex.in.security_flags = 0;
 745         io.ntcreatex.in.fname = fname;
 746 
 747         torture_comment(tctx, "BATCH2: open with batch oplock\n");
 748         ZERO_STRUCT(break_info);
 749         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | 
 750                 NTCREATEX_FLAGS_REQUEST_OPLOCK | 
 751                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
 752         status = smb_raw_open(cli1->tree, tctx, &io);
 753         CHECK_STATUS(tctx, status, NT_STATUS_OK);
 754         fnum = io.ntcreatex.out.file.fnum;
 755         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
 756 
 757         torture_comment(tctx, "unlink should generate a break, which we ack as break to none\n");
 758         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_none, cli1->tree);
 759         unl.unlink.in.pattern = fname;
 760         unl.unlink.in.attrib = 0;
 761         status = smb_raw_unlink(cli2->tree, &unl);
 762         CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
 763 
 764         CHECK_VAL(break_info.count, 1);
 765         CHECK_VAL(break_info.fnum, fnum);
 766         CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
 767         CHECK_VAL(break_info.failures, 0);
 768 
 769         torture_comment(tctx, "2nd unlink should not generate a break\n");
 770         ZERO_STRUCT(break_info);
 771         status = smb_raw_unlink(cli2->tree, &unl);
 772         CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
 773 
 774         CHECK_VAL(break_info.count, 0);
 775 
 776         torture_comment(tctx, "writing should not generate a break\n");
 777         smbcli_write(cli1->tree, fnum, 0, &c, 0, 1);
 778         msleep(100);
 779         smbcli_write(cli1->tree, fnum, 0, &c, 1, 1);
 780 
 781         CHECK_VAL(break_info.count, 0);
 782 
 783         smbcli_close(cli1->tree, fnum);
 784 
 785 done:
 786         smb_raw_exit(cli1->session);
 787         smb_raw_exit(cli2->session);
 788         smbcli_deltree(cli1->tree, BASEDIR);
 789         return ret;
 790 }
 791 
 792 static bool test_raw_oplock_batch3(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
     /* [<][>][^][v][top][bottom][index][help] */
 793 {
 794         const char *fname = BASEDIR "\\test_batch3.dat";
 795         NTSTATUS status;
 796         bool ret = true;
 797         union smb_open io;
 798         union smb_unlink unl;
 799         uint16_t fnum=0;
 800 
 801         if (!torture_setup_dir(cli1, BASEDIR)) {
 802                 return false;
 803         }
 804 
 805         /* cleanup */
 806         smbcli_unlink(cli1->tree, fname);
 807 
 808         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
 809 
 810         /*
 811           base ntcreatex parms
 812         */
 813         io.generic.level = RAW_OPEN_NTCREATEX;
 814         io.ntcreatex.in.root_fid = 0;
 815         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
 816         io.ntcreatex.in.alloc_size = 0;
 817         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
 818         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
 819         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
 820         io.ntcreatex.in.create_options = 0;
 821         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
 822         io.ntcreatex.in.security_flags = 0;
 823         io.ntcreatex.in.fname = fname;
 824 
 825         torture_comment(tctx, "BATCH3: if we close on break then the unlink can succeed\n");
 826         ZERO_STRUCT(break_info);
 827         smbcli_oplock_handler(cli1->transport, oplock_handler_close, cli1->tree);
 828         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | 
 829                 NTCREATEX_FLAGS_REQUEST_OPLOCK | 
 830                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
 831         status = smb_raw_open(cli1->tree, tctx, &io);
 832         CHECK_STATUS(tctx, status, NT_STATUS_OK);
 833         fnum = io.ntcreatex.out.file.fnum;
 834         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
 835 
 836         unl.unlink.in.pattern = fname;
 837         unl.unlink.in.attrib = 0;
 838         ZERO_STRUCT(break_info);
 839         status = smb_raw_unlink(cli2->tree, &unl);
 840         CHECK_STATUS(tctx, status, NT_STATUS_OK);
 841 
 842         CHECK_VAL(break_info.count, 1);
 843         CHECK_VAL(break_info.fnum, fnum);
 844         CHECK_VAL(break_info.level, 1);
 845         CHECK_VAL(break_info.failures, 0);
 846 
 847         smbcli_close(cli1->tree, fnum);
 848 
 849 done:
 850         smb_raw_exit(cli1->session);
 851         smb_raw_exit(cli2->session);
 852         smbcli_deltree(cli1->tree, BASEDIR);
 853         return ret;
 854 }
 855 
 856 static bool test_raw_oplock_batch4(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
     /* [<][>][^][v][top][bottom][index][help] */
 857 {
 858         const char *fname = BASEDIR "\\test_batch4.dat";
 859         NTSTATUS status;
 860         bool ret = true;
 861         union smb_open io;
 862         union smb_read rd;
 863         uint16_t fnum=0;
 864 
 865         if (!torture_setup_dir(cli1, BASEDIR)) {
 866                 return false;
 867         }
 868 
 869         /* cleanup */
 870         smbcli_unlink(cli1->tree, fname);
 871 
 872         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
 873 
 874         /*
 875           base ntcreatex parms
 876         */
 877         io.generic.level = RAW_OPEN_NTCREATEX;
 878         io.ntcreatex.in.root_fid = 0;
 879         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
 880         io.ntcreatex.in.alloc_size = 0;
 881         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
 882         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
 883         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
 884         io.ntcreatex.in.create_options = 0;
 885         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
 886         io.ntcreatex.in.security_flags = 0;
 887         io.ntcreatex.in.fname = fname;
 888 
 889         torture_comment(tctx, "BATCH4: a self read should not cause a break\n");
 890         ZERO_STRUCT(break_info);
 891         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
 892 
 893         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | 
 894                 NTCREATEX_FLAGS_REQUEST_OPLOCK | 
 895                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
 896         status = smb_raw_open(cli1->tree, tctx, &io);
 897         CHECK_STATUS(tctx, status, NT_STATUS_OK);
 898         fnum = io.ntcreatex.out.file.fnum;
 899         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
 900 
 901         rd.read.level = RAW_READ_READ;
 902         rd.read.in.file.fnum = fnum;
 903         rd.read.in.count = 1;
 904         rd.read.in.offset = 0;
 905         rd.read.in.remaining = 0;
 906         status = smb_raw_read(cli1->tree, &rd);
 907         CHECK_STATUS(tctx, status, NT_STATUS_OK);
 908         CHECK_VAL(break_info.count, 0);
 909         CHECK_VAL(break_info.failures, 0);
 910 
 911         smbcli_close(cli1->tree, fnum);
 912 
 913 done:
 914         smb_raw_exit(cli1->session);
 915         smb_raw_exit(cli2->session);
 916         smbcli_deltree(cli1->tree, BASEDIR);
 917         return ret;
 918 }
 919 
 920 static bool test_raw_oplock_batch5(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
     /* [<][>][^][v][top][bottom][index][help] */
 921 {
 922         const char *fname = BASEDIR "\\test_batch5.dat";
 923         NTSTATUS status;
 924         bool ret = true;
 925         union smb_open io;
 926         uint16_t fnum=0;
 927 
 928         if (!torture_setup_dir(cli1, BASEDIR)) {
 929                 return false;
 930         }
 931 
 932         /* cleanup */
 933         smbcli_unlink(cli1->tree, fname);
 934 
 935         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
 936 
 937         /*
 938           base ntcreatex parms
 939         */
 940         io.generic.level = RAW_OPEN_NTCREATEX;
 941         io.ntcreatex.in.root_fid = 0;
 942         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
 943         io.ntcreatex.in.alloc_size = 0;
 944         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
 945         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
 946         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
 947         io.ntcreatex.in.create_options = 0;
 948         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
 949         io.ntcreatex.in.security_flags = 0;
 950         io.ntcreatex.in.fname = fname;
 951 
 952         torture_comment(tctx, "BATCH5: a 2nd open should give a break\n");
 953         ZERO_STRUCT(break_info);
 954         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
 955 
 956         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | 
 957                 NTCREATEX_FLAGS_REQUEST_OPLOCK | 
 958                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
 959         status = smb_raw_open(cli1->tree, tctx, &io);
 960         CHECK_STATUS(tctx, status, NT_STATUS_OK);
 961         fnum = io.ntcreatex.out.file.fnum;
 962         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
 963 
 964         ZERO_STRUCT(break_info);
 965 
 966         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
 967         status = smb_raw_open(cli2->tree, tctx, &io);
 968         CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
 969 
 970         CHECK_VAL(break_info.count, 1);
 971         CHECK_VAL(break_info.fnum, fnum);
 972         CHECK_VAL(break_info.level, 1);
 973         CHECK_VAL(break_info.failures, 0);
 974 
 975         smbcli_close(cli1->tree, fnum);
 976 
 977 done:
 978         smb_raw_exit(cli1->session);
 979         smb_raw_exit(cli2->session);
 980         smbcli_deltree(cli1->tree, BASEDIR);
 981         return ret;
 982 }
 983 
 984 static bool test_raw_oplock_batch6(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
     /* [<][>][^][v][top][bottom][index][help] */
 985 {
 986         const char *fname = BASEDIR "\\test_batch6.dat";
 987         NTSTATUS status;
 988         bool ret = true;
 989         union smb_open io;
 990         uint16_t fnum=0, fnum2=0;
 991         char c = 0;
 992 
 993         if (!torture_setup_dir(cli1, BASEDIR)) {
 994                 return false;
 995         }
 996 
 997         /* cleanup */
 998         smbcli_unlink(cli1->tree, fname);
 999 
1000         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1001 
1002         /*
1003           base ntcreatex parms
1004         */
1005         io.generic.level = RAW_OPEN_NTCREATEX;
1006         io.ntcreatex.in.root_fid = 0;
1007         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1008         io.ntcreatex.in.alloc_size = 0;
1009         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1010         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1011         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1012         io.ntcreatex.in.create_options = 0;
1013         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1014         io.ntcreatex.in.security_flags = 0;
1015         io.ntcreatex.in.fname = fname;
1016 
1017         torture_comment(tctx, "BATCH6: a 2nd open should give a break to level II if the first open allowed shared read\n");
1018         ZERO_STRUCT(break_info);
1019         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1020         smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli2->tree);
1021 
1022         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_READ | SEC_RIGHTS_FILE_WRITE;
1023         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
1024         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | 
1025                 NTCREATEX_FLAGS_REQUEST_OPLOCK | 
1026                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1027         status = smb_raw_open(cli1->tree, tctx, &io);
1028         CHECK_STATUS(tctx, status, NT_STATUS_OK);
1029         fnum = io.ntcreatex.out.file.fnum;
1030         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1031 
1032         ZERO_STRUCT(break_info);
1033 
1034         status = smb_raw_open(cli2->tree, tctx, &io);
1035         CHECK_STATUS(tctx, status, NT_STATUS_OK);
1036         fnum2 = io.ntcreatex.out.file.fnum;
1037         CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1038 
1039         CHECK_VAL(break_info.count, 1);
1040         CHECK_VAL(break_info.fnum, fnum);
1041         CHECK_VAL(break_info.level, 1);
1042         CHECK_VAL(break_info.failures, 0);
1043         ZERO_STRUCT(break_info);
1044 
1045         torture_comment(tctx, "write should trigger a break to none on both\n");
1046         smbcli_write(cli1->tree, fnum, 0, &c, 0, 1);
1047         msleep(100);
1048         smbcli_write(cli1->tree, fnum, 0, &c, 1, 1);
1049 
1050         CHECK_VAL(break_info.count, 2);
1051         CHECK_VAL(break_info.level, 0);
1052         CHECK_VAL(break_info.failures, 0);
1053 
1054         smbcli_close(cli1->tree, fnum);
1055         smbcli_close(cli2->tree, fnum2);
1056 
1057 
1058 done:
1059         smb_raw_exit(cli1->session);
1060         smb_raw_exit(cli2->session);
1061         smbcli_deltree(cli1->tree, BASEDIR);
1062         return ret;
1063 }
1064 
1065 static bool test_raw_oplock_batch7(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
     /* [<][>][^][v][top][bottom][index][help] */
1066 {
1067         const char *fname = BASEDIR "\\test_batch7.dat";
1068         NTSTATUS status;
1069         bool ret = true;
1070         union smb_open io;
1071         uint16_t fnum=0, fnum2=0;
1072 
1073         if (!torture_setup_dir(cli1, BASEDIR)) {
1074                 return false;
1075         }
1076 
1077         /* cleanup */
1078         smbcli_unlink(cli1->tree, fname);
1079 
1080         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1081 
1082         /*
1083           base ntcreatex parms
1084         */
1085         io.generic.level = RAW_OPEN_NTCREATEX;
1086         io.ntcreatex.in.root_fid = 0;
1087         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1088         io.ntcreatex.in.alloc_size = 0;
1089         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1090         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1091         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1092         io.ntcreatex.in.create_options = 0;
1093         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1094         io.ntcreatex.in.security_flags = 0;
1095         io.ntcreatex.in.fname = fname;
1096 
1097         torture_comment(tctx, "BATCH7: a 2nd open should get an oplock when we close instead of ack\n");
1098         ZERO_STRUCT(break_info);
1099         smbcli_oplock_handler(cli1->transport, oplock_handler_close, cli1->tree);
1100 
1101         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1102         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1103         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | 
1104                 NTCREATEX_FLAGS_REQUEST_OPLOCK | 
1105                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1106         status = smb_raw_open(cli1->tree, tctx, &io);
1107         CHECK_STATUS(tctx, status, NT_STATUS_OK);
1108         fnum2 = io.ntcreatex.out.file.fnum;
1109         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1110 
1111         ZERO_STRUCT(break_info);
1112 
1113         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | 
1114                 NTCREATEX_FLAGS_REQUEST_OPLOCK | 
1115                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1116         status = smb_raw_open(cli2->tree, tctx, &io);
1117         CHECK_STATUS(tctx, status, NT_STATUS_OK);
1118         fnum = io.ntcreatex.out.file.fnum;
1119         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1120 
1121         CHECK_VAL(break_info.count, 1);
1122         CHECK_VAL(break_info.fnum, fnum2);
1123         CHECK_VAL(break_info.level, 1);
1124         CHECK_VAL(break_info.failures, 0);
1125         
1126         smbcli_close(cli2->tree, fnum);
1127 
1128 done:
1129         smb_raw_exit(cli1->session);
1130         smb_raw_exit(cli2->session);
1131         smbcli_deltree(cli1->tree, BASEDIR);
1132         return ret;
1133 }
1134 
1135 static bool test_raw_oplock_batch8(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
     /* [<][>][^][v][top][bottom][index][help] */
1136 {
1137         const char *fname = BASEDIR "\\test_batch8.dat";
1138         NTSTATUS status;
1139         bool ret = true;
1140         union smb_open io;
1141         uint16_t fnum=0, fnum2=0;
1142 
1143         if (!torture_setup_dir(cli1, BASEDIR)) {
1144                 return false;
1145         }
1146 
1147         /* cleanup */
1148         smbcli_unlink(cli1->tree, fname);
1149 
1150         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1151 
1152         /*
1153           base ntcreatex parms
1154         */
1155         io.generic.level = RAW_OPEN_NTCREATEX;
1156         io.ntcreatex.in.root_fid = 0;
1157         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1158         io.ntcreatex.in.alloc_size = 0;
1159         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1160         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1161         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1162         io.ntcreatex.in.create_options = 0;
1163         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1164         io.ntcreatex.in.security_flags = 0;
1165         io.ntcreatex.in.fname = fname;
1166 
1167         torture_comment(tctx, "BATCH8: open with batch oplock\n");
1168         ZERO_STRUCT(break_info);
1169         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1170 
1171         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | 
1172                 NTCREATEX_FLAGS_REQUEST_OPLOCK | 
1173                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1174         status = smb_raw_open(cli1->tree, tctx, &io);
1175         CHECK_STATUS(tctx, status, NT_STATUS_OK);
1176         fnum = io.ntcreatex.out.file.fnum;
1177         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1178 
1179         ZERO_STRUCT(break_info);
1180         torture_comment(tctx, "second open with attributes only shouldn't cause oplock break\n");
1181 
1182         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | 
1183                 NTCREATEX_FLAGS_REQUEST_OPLOCK | 
1184                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1185         io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
1186         status = smb_raw_open(cli2->tree, tctx, &io);
1187         CHECK_STATUS(tctx, status, NT_STATUS_OK);
1188         fnum2 = io.ntcreatex.out.file.fnum;
1189         CHECK_VAL(io.ntcreatex.out.oplock_level, NO_OPLOCK_RETURN);
1190         CHECK_VAL(break_info.count, 0);
1191         CHECK_VAL(break_info.failures, 0);
1192 
1193         smbcli_close(cli1->tree, fnum);
1194         smbcli_close(cli2->tree, fnum2);
1195 
1196 done:
1197         smb_raw_exit(cli1->session);
1198         smb_raw_exit(cli2->session);
1199         smbcli_deltree(cli1->tree, BASEDIR);
1200         return ret;
1201 }
1202 
1203 static bool test_raw_oplock_batch9(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
     /* [<][>][^][v][top][bottom][index][help] */
1204 {
1205         const char *fname = BASEDIR "\\test_batch9.dat";
1206         NTSTATUS status;
1207         bool ret = true;
1208         union smb_open io;
1209         uint16_t fnum=0, fnum2=0;
1210         char c = 0;
1211 
1212         if (!torture_setup_dir(cli1, BASEDIR)) {
1213                 return false;
1214         }
1215 
1216         /* cleanup */
1217         smbcli_unlink(cli1->tree, fname);
1218 
1219         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1220 
1221         /*
1222           base ntcreatex parms
1223         */
1224         io.generic.level = RAW_OPEN_NTCREATEX;
1225         io.ntcreatex.in.root_fid = 0;
1226         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1227         io.ntcreatex.in.alloc_size = 0;
1228         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1229         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1230         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1231         io.ntcreatex.in.create_options = 0;
1232         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1233         io.ntcreatex.in.security_flags = 0;
1234         io.ntcreatex.in.fname = fname;
1235 
1236         torture_comment(tctx, "BATCH9: open with attributes only can create file\n");
1237 
1238         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | 
1239                 NTCREATEX_FLAGS_REQUEST_OPLOCK | 
1240                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1241         io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
1242         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1243         status = smb_raw_open(cli1->tree, tctx, &io);
1244         CHECK_STATUS(tctx, status, NT_STATUS_OK);
1245         fnum = io.ntcreatex.out.file.fnum;
1246         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1247 
1248         torture_comment(tctx, "Subsequent normal open should break oplock on attribute only open to level II\n");
1249 
1250         ZERO_STRUCT(break_info);
1251         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1252 
1253         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | 
1254                 NTCREATEX_FLAGS_REQUEST_OPLOCK | 
1255                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1256         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1257         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1258         status = smb_raw_open(cli2->tree, tctx, &io);
1259         CHECK_STATUS(tctx, status, NT_STATUS_OK);
1260         fnum2 = io.ntcreatex.out.file.fnum;
1261         CHECK_VAL(break_info.count, 1);
1262         CHECK_VAL(break_info.fnum, fnum);
1263         CHECK_VAL(break_info.failures, 0);
1264         CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
1265         CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1266         smbcli_close(cli2->tree, fnum2);
1267 
1268         torture_comment(tctx, "third oplocked open should grant level2 without break\n");
1269         ZERO_STRUCT(break_info);
1270         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1271         smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli2->tree);
1272         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | 
1273                 NTCREATEX_FLAGS_REQUEST_OPLOCK | 
1274                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1275         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1276         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1277         status = smb_raw_open(cli2->tree, tctx, &io);
1278         CHECK_STATUS(tctx, status, NT_STATUS_OK);
1279         fnum2 = io.ntcreatex.out.file.fnum;
1280         CHECK_VAL(break_info.count, 0);
1281         CHECK_VAL(break_info.failures, 0);
1282         CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1283 
1284         ZERO_STRUCT(break_info);
1285 
1286         torture_comment(tctx, "write should trigger a break to none on both\n");
1287         smbcli_write(cli2->tree, fnum2, 0, &c, 0, 1);
1288 
1289         /* Now the oplock break request comes in. But right now we can't
1290          * answer it. Do another write */
1291 
1292         msleep(100);
1293         smbcli_write(cli2->tree, fnum2, 0, &c, 1, 1);
1294 
1295         CHECK_VAL(break_info.count, 2);
1296         CHECK_VAL(break_info.level, 0);
1297         CHECK_VAL(break_info.failures, 0);
1298 
1299         smbcli_close(cli1->tree, fnum);
1300         smbcli_close(cli2->tree, fnum2);
1301 
1302 done:
1303         smb_raw_exit(cli1->session);
1304         smb_raw_exit(cli2->session);
1305         smbcli_deltree(cli1->tree, BASEDIR);
1306         return ret;
1307 }
1308 
1309 static bool test_raw_oplock_batch10(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
     /* [<][>][^][v][top][bottom][index][help] */
1310 {
1311         const char *fname = BASEDIR "\\test_batch10.dat";
1312         NTSTATUS status;
1313         bool ret = true;
1314         union smb_open io;
1315         uint16_t fnum=0, fnum2=0;
1316 
1317         if (!torture_setup_dir(cli1, BASEDIR)) {
1318                 return false;
1319         }
1320 
1321         /* cleanup */
1322         smbcli_unlink(cli1->tree, fname);
1323 
1324         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1325 
1326         /*
1327           base ntcreatex parms
1328         */
1329         io.generic.level = RAW_OPEN_NTCREATEX;
1330         io.ntcreatex.in.root_fid = 0;
1331         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1332         io.ntcreatex.in.alloc_size = 0;
1333         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1334         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1335         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1336         io.ntcreatex.in.create_options = 0;
1337         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1338         io.ntcreatex.in.security_flags = 0;
1339         io.ntcreatex.in.fname = fname;
1340 
1341         torture_comment(tctx, "BATCH10: Open with oplock after a non-oplock open should grant level2\n");
1342         ZERO_STRUCT(break_info);
1343         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
1344         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1345         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1346                 NTCREATEX_SHARE_ACCESS_WRITE|
1347                 NTCREATEX_SHARE_ACCESS_DELETE;
1348         status = smb_raw_open(cli1->tree, tctx, &io);
1349         CHECK_STATUS(tctx, status, NT_STATUS_OK);
1350         fnum = io.ntcreatex.out.file.fnum;
1351         CHECK_VAL(break_info.count, 0);
1352         CHECK_VAL(break_info.failures, 0);
1353         CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
1354 
1355         smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli2->tree);
1356 
1357         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1358                 NTCREATEX_FLAGS_REQUEST_OPLOCK | 
1359                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1360         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1361         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1362                 NTCREATEX_SHARE_ACCESS_WRITE|
1363                 NTCREATEX_SHARE_ACCESS_DELETE;
1364         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1365         status = smb_raw_open(cli2->tree, tctx, &io);
1366         CHECK_STATUS(tctx, status, NT_STATUS_OK);
1367         fnum2 = io.ntcreatex.out.file.fnum;
1368         CHECK_VAL(break_info.count, 0);
1369         CHECK_VAL(break_info.failures, 0);
1370         CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1371 
1372         torture_comment(tctx, "write should trigger a break to none\n");
1373         {
1374                 union smb_write wr;
1375                 wr.write.level = RAW_WRITE_WRITE;
1376                 wr.write.in.file.fnum = fnum;
1377                 wr.write.in.count = 1;
1378                 wr.write.in.offset = 0;
1379                 wr.write.in.remaining = 0;
1380                 wr.write.in.data = (const uint8_t *)"x";
1381                 status = smb_raw_write(cli1->tree, &wr);
1382                 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1383         }
1384 
1385         /* Now the oplock break request comes in. But right now we can't
1386          * answer it. Do another write */
1387 
1388         msleep(100);
1389         
1390         {
1391                 union smb_write wr;
1392                 wr.write.level = RAW_WRITE_WRITE;
1393                 wr.write.in.file.fnum = fnum;
1394                 wr.write.in.count = 1;
1395                 wr.write.in.offset = 0;
1396                 wr.write.in.remaining = 0;
1397                 wr.write.in.data = (const uint8_t *)"x";
1398                 status = smb_raw_write(cli1->tree, &wr);
1399                 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1400         }
1401 
1402         CHECK_VAL(break_info.count, 1);
1403         CHECK_VAL(break_info.fnum, fnum2);
1404         CHECK_VAL(break_info.level, 0);
1405         CHECK_VAL(break_info.failures, 0);
1406 
1407         smbcli_close(cli1->tree, fnum);
1408         smbcli_close(cli2->tree, fnum2);
1409 
1410 done:
1411         smb_raw_exit(cli1->session);
1412         smb_raw_exit(cli2->session);
1413         smbcli_deltree(cli1->tree, BASEDIR);
1414         return ret;
1415 }
1416 
1417 static bool test_raw_oplock_batch11(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
     /* [<][>][^][v][top][bottom][index][help] */
1418 {
1419         const char *fname = BASEDIR "\\test_batch11.dat";
1420         NTSTATUS status;
1421         bool ret = true;
1422         union smb_open io;
1423         union smb_setfileinfo sfi;
1424         uint16_t fnum=0;
1425 
1426         if (!torture_setup_dir(cli1, BASEDIR)) {
1427                 return false;
1428         }
1429 
1430         /* cleanup */
1431         smbcli_unlink(cli1->tree, fname);
1432 
1433         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1434 
1435         /*
1436           base ntcreatex parms
1437         */
1438         io.generic.level = RAW_OPEN_NTCREATEX;
1439         io.ntcreatex.in.root_fid = 0;
1440         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1441         io.ntcreatex.in.alloc_size = 0;
1442         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1443         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1444         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1445         io.ntcreatex.in.create_options = 0;
1446         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1447         io.ntcreatex.in.security_flags = 0;
1448         io.ntcreatex.in.fname = fname;
1449 
1450         /* Test if a set-eof on pathname breaks an exclusive oplock. */
1451         torture_comment(tctx, "BATCH11: Test if setpathinfo set EOF breaks oplocks.\n");
1452 
1453         ZERO_STRUCT(break_info);
1454         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1455 
1456         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1457                 NTCREATEX_FLAGS_REQUEST_OPLOCK | 
1458                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1459         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1460         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1461                 NTCREATEX_SHARE_ACCESS_WRITE|
1462                 NTCREATEX_SHARE_ACCESS_DELETE;
1463         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1464         status = smb_raw_open(cli1->tree, tctx, &io);
1465         CHECK_STATUS(tctx, status, NT_STATUS_OK);
1466         fnum = io.ntcreatex.out.file.fnum;
1467         CHECK_VAL(break_info.count, 0);
1468         CHECK_VAL(break_info.failures, 0);
1469         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1470         
1471         ZERO_STRUCT(sfi);
1472         sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
1473         sfi.generic.in.file.path = fname;
1474         sfi.end_of_file_info.in.size = 100;
1475 
1476         status = smb_raw_setpathinfo(cli2->tree, &sfi);
1477 
1478         CHECK_STATUS(tctx, status, NT_STATUS_OK);
1479         CHECK_VAL(break_info.count, 1);
1480         CHECK_VAL(break_info.failures, 0);
1481         CHECK_VAL(break_info.level, 0);
1482 
1483         smbcli_close(cli1->tree, fnum);
1484 
1485 done:
1486         smb_raw_exit(cli1->session);
1487         smb_raw_exit(cli2->session);
1488         smbcli_deltree(cli1->tree, BASEDIR);
1489         return ret;
1490 }
1491 
1492 static bool test_raw_oplock_batch12(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
     /* [<][>][^][v][top][bottom][index][help] */
1493 {
1494         const char *fname = BASEDIR "\\test_batch12.dat";
1495         NTSTATUS status;
1496         bool ret = true;
1497         union smb_open io;
1498         union smb_setfileinfo sfi;
1499         uint16_t fnum=0;
1500 
1501         if (!torture_setup_dir(cli1, BASEDIR)) {
1502                 return false;
1503         }
1504 
1505         /* cleanup */
1506         smbcli_unlink(cli1->tree, fname);
1507 
1508         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1509 
1510         /*
1511           base ntcreatex parms
1512         */
1513         io.generic.level = RAW_OPEN_NTCREATEX;
1514         io.ntcreatex.in.root_fid = 0;
1515         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1516         io.ntcreatex.in.alloc_size = 0;
1517         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1518         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1519         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1520         io.ntcreatex.in.create_options = 0;
1521         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1522         io.ntcreatex.in.security_flags = 0;
1523         io.ntcreatex.in.fname = fname;
1524 
1525         /* Test if a set-allocation size on pathname breaks an exclusive oplock. */
1526         torture_comment(tctx, "BATCH12: Test if setpathinfo allocation size breaks oplocks.\n");
1527 
1528         ZERO_STRUCT(break_info);
1529         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1530 
1531         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1532                 NTCREATEX_FLAGS_REQUEST_OPLOCK | 
1533                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1534         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1535         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1536                 NTCREATEX_SHARE_ACCESS_WRITE|
1537                 NTCREATEX_SHARE_ACCESS_DELETE;
1538         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1539         status = smb_raw_open(cli1->tree, tctx, &io);
1540         CHECK_STATUS(tctx, status, NT_STATUS_OK);
1541         fnum = io.ntcreatex.out.file.fnum;
1542         CHECK_VAL(break_info.count, 0);
1543         CHECK_VAL(break_info.failures, 0);
1544         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1545         
1546         ZERO_STRUCT(sfi);
1547         sfi.generic.level = SMB_SFILEINFO_ALLOCATION_INFORMATION;
1548         sfi.generic.in.file.path = fname;
1549         sfi.allocation_info.in.alloc_size = 65536 * 8;
1550 
1551         status = smb_raw_setpathinfo(cli2->tree, &sfi);
1552 
1553         CHECK_STATUS(tctx, status, NT_STATUS_OK);
1554         CHECK_VAL(break_info.count, 1);
1555         CHECK_VAL(break_info.failures, 0);
1556         CHECK_VAL(break_info.level, 0);
1557 
1558         smbcli_close(cli1->tree, fnum);
1559 
1560 done:
1561         smb_raw_exit(cli1->session);
1562         smb_raw_exit(cli2->session);
1563         smbcli_deltree(cli1->tree, BASEDIR);
1564         return ret;
1565 }
1566 
1567 static bool test_raw_oplock_batch13(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
     /* [<][>][^][v][top][bottom][index][help] */
1568 {
1569         const char *fname = BASEDIR "\\test_batch13.dat";
1570         NTSTATUS status;
1571         bool ret = true;
1572         union smb_open io;
1573         uint16_t fnum=0, fnum2=0;
1574 
1575         if (!torture_setup_dir(cli1, BASEDIR)) {
1576                 return false;
1577         }
1578 
1579         /* cleanup */
1580         smbcli_unlink(cli1->tree, fname);
1581 
1582         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1583         smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli1->tree);
1584 
1585         /*
1586           base ntcreatex parms
1587         */
1588         io.generic.level = RAW_OPEN_NTCREATEX;
1589         io.ntcreatex.in.root_fid = 0;
1590         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1591         io.ntcreatex.in.alloc_size = 0;
1592         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1593         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1594         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1595         io.ntcreatex.in.create_options = 0;
1596         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1597         io.ntcreatex.in.security_flags = 0;
1598         io.ntcreatex.in.fname = fname;
1599 
1600         torture_comment(tctx, "BATCH13: open with batch oplock\n");
1601         ZERO_STRUCT(break_info);
1602         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1603 
1604 
1605         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | 
1606                 NTCREATEX_FLAGS_REQUEST_OPLOCK | 
1607                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1608         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1609                 NTCREATEX_SHARE_ACCESS_WRITE|
1610                 NTCREATEX_SHARE_ACCESS_DELETE;
1611         status = smb_raw_open(cli1->tree, tctx, &io);
1612         CHECK_STATUS(tctx, status, NT_STATUS_OK);
1613         fnum = io.ntcreatex.out.file.fnum;
1614         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1615 
1616         ZERO_STRUCT(break_info);
1617 
1618         torture_comment(tctx, "second open with attributes only and NTCREATEX_DISP_OVERWRITE dispostion causes oplock break\n");
1619 
1620         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | 
1621                 NTCREATEX_FLAGS_REQUEST_OPLOCK | 
1622                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1623         io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
1624         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1625                 NTCREATEX_SHARE_ACCESS_WRITE|
1626                 NTCREATEX_SHARE_ACCESS_DELETE;
1627         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE;
1628         status = smb_raw_open(cli2->tree, tctx, &io);
1629         CHECK_STATUS(tctx, status, NT_STATUS_OK);
1630         fnum2 = io.ntcreatex.out.file.fnum;
1631         CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1632         CHECK_VAL(break_info.count, 1);
1633         CHECK_VAL(break_info.failures, 0);
1634 
1635         smbcli_close(cli1->tree, fnum);
1636         smbcli_close(cli2->tree, fnum2);
1637 
1638 done:
1639         smb_raw_exit(cli1->session);
1640         smb_raw_exit(cli2->session);
1641         smbcli_deltree(cli1->tree, BASEDIR);
1642         return ret;
1643 }
1644 
1645 static bool test_raw_oplock_batch14(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
     /* [<][>][^][v][top][bottom][index][help] */
1646 {
1647         const char *fname = BASEDIR "\\test_batch14.dat";
1648         NTSTATUS status;
1649         bool ret = true;
1650         union smb_open io;
1651         uint16_t fnum=0, fnum2=0;
1652 
1653         if (!torture_setup_dir(cli1, BASEDIR)) {
1654                 return false;
1655         }
1656 
1657         /* cleanup */
1658         smbcli_unlink(cli1->tree, fname);
1659 
1660         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1661 
1662         /*
1663           base ntcreatex parms
1664         */
1665         io.generic.level = RAW_OPEN_NTCREATEX;
1666         io.ntcreatex.in.root_fid = 0;
1667         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1668         io.ntcreatex.in.alloc_size = 0;
1669         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1670         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1671         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1672         io.ntcreatex.in.create_options = 0;
1673         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1674         io.ntcreatex.in.security_flags = 0;
1675         io.ntcreatex.in.fname = fname;
1676 
1677         torture_comment(tctx, "BATCH14: open with batch oplock\n");
1678         ZERO_STRUCT(break_info);
1679         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1680 
1681         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | 
1682                 NTCREATEX_FLAGS_REQUEST_OPLOCK | 
1683                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1684         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1685                 NTCREATEX_SHARE_ACCESS_WRITE|
1686                 NTCREATEX_SHARE_ACCESS_DELETE;
1687         status = smb_raw_open(cli1->tree, tctx, &io);
1688         CHECK_STATUS(tctx, status, NT_STATUS_OK);
1689         fnum = io.ntcreatex.out.file.fnum;
1690         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1691 
1692         ZERO_STRUCT(break_info);
1693 
1694         torture_comment(tctx, "second open with attributes only and NTCREATEX_DISP_SUPERSEDE dispostion causes oplock break\n");
1695 
1696         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | 
1697                 NTCREATEX_FLAGS_REQUEST_OPLOCK | 
1698                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1699         io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
1700         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1701                 NTCREATEX_SHARE_ACCESS_WRITE|
1702                 NTCREATEX_SHARE_ACCESS_DELETE;
1703         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE;
1704         status = smb_raw_open(cli2->tree, tctx, &io);
1705         CHECK_STATUS(tctx, status, NT_STATUS_OK);
1706         fnum2 = io.ntcreatex.out.file.fnum;
1707         CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1708         CHECK_VAL(break_info.count, 1);
1709         CHECK_VAL(break_info.failures, 0);
1710 
1711         smbcli_close(cli1->tree, fnum);
1712         smbcli_close(cli2->tree, fnum2);
1713 done:
1714         smb_raw_exit(cli1->session);
1715         smb_raw_exit(cli2->session);
1716         smbcli_deltree(cli1->tree, BASEDIR);
1717         return ret;
1718 }
1719 
1720 static bool test_raw_oplock_batch15(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
     /* [<][>][^][v][top][bottom][index][help] */
1721 {
1722         const char *fname = BASEDIR "\\test_batch15.dat";
1723         NTSTATUS status;
1724         bool ret = true;
1725         union smb_open io;
1726         union smb_fileinfo qfi;
1727         uint16_t fnum=0;
1728 
1729         if (!torture_setup_dir(cli1, BASEDIR)) {
1730                 return false;
1731         }
1732 
1733         /* cleanup */
1734         smbcli_unlink(cli1->tree, fname);
1735 
1736         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1737 
1738         /*
1739           base ntcreatex parms
1740         */
1741         io.generic.level = RAW_OPEN_NTCREATEX;
1742         io.ntcreatex.in.root_fid = 0;
1743         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1744         io.ntcreatex.in.alloc_size = 0;
1745         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1746         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1747         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1748         io.ntcreatex.in.create_options = 0;
1749         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1750         io.ntcreatex.in.security_flags = 0;
1751         io.ntcreatex.in.fname = fname;
1752 
1753         /* Test if a qpathinfo all info on pathname breaks a batch oplock. */
1754         torture_comment(tctx, "BATCH15: Test if qpathinfo all info breaks a batch oplock (should not).\n");
1755 
1756         ZERO_STRUCT(break_info);
1757         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1758 
1759         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1760                 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1761                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1762         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1763         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1764                 NTCREATEX_SHARE_ACCESS_WRITE|
1765                 NTCREATEX_SHARE_ACCESS_DELETE;
1766         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1767         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1768         status = smb_raw_open(cli1->tree, tctx, &io);
1769         CHECK_STATUS(tctx, status, NT_STATUS_OK);
1770         fnum = io.ntcreatex.out.file.fnum;
1771         CHECK_VAL(break_info.count, 0);
1772         CHECK_VAL(break_info.failures, 0);
1773         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1774 
1775         ZERO_STRUCT(qfi);
1776         qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
1777         qfi.generic.in.file.path = fname;
1778 
1779         status = smb_raw_pathinfo(cli2->tree, tctx, &qfi);
1780 
1781         CHECK_STATUS(tctx, status, NT_STATUS_OK);
1782         CHECK_VAL(break_info.count, 0);
1783 
1784         smbcli_close(cli1->tree, fnum);
1785 
1786 done:
1787         smb_raw_exit(cli1->session);
1788         smb_raw_exit(cli2->session);
1789         smbcli_deltree(cli1->tree, BASEDIR);
1790         return ret;
1791 }
1792 
1793 static bool test_raw_oplock_batch16(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
     /* [<][>][^][v][top][bottom][index][help] */
1794 {
1795         const char *fname = BASEDIR "\\test_batch16.dat";
1796         NTSTATUS status;
1797         bool ret = true;
1798         union smb_open io;
1799         uint16_t fnum=0, fnum2=0;
1800 
1801         if (!torture_setup_dir(cli1, BASEDIR)) {
1802                 return false;
1803         }
1804 
1805         /* cleanup */
1806         smbcli_unlink(cli1->tree, fname);
1807 
1808         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1809         smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli1->tree);
1810 
1811         /*
1812           base ntcreatex parms
1813         */
1814         io.generic.level = RAW_OPEN_NTCREATEX;
1815         io.ntcreatex.in.root_fid = 0;
1816         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1817         io.ntcreatex.in.alloc_size = 0;
1818         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1819         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1820         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1821         io.ntcreatex.in.create_options = 0;
1822         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1823         io.ntcreatex.in.security_flags = 0;
1824         io.ntcreatex.in.fname = fname;
1825 
1826         torture_comment(tctx, "BATCH16: open with batch oplock\n");
1827         ZERO_STRUCT(break_info);
1828         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1829 
1830 
1831         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1832                 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1833                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1834         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1835                 NTCREATEX_SHARE_ACCESS_WRITE|
1836                 NTCREATEX_SHARE_ACCESS_DELETE;
1837         status = smb_raw_open(cli1->tree, tctx, &io);
1838         CHECK_STATUS(tctx, status, NT_STATUS_OK);
1839         fnum = io.ntcreatex.out.file.fnum;
1840         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1841 
1842         ZERO_STRUCT(break_info);
1843 
1844         torture_comment(tctx, "second open with attributes only and NTCREATEX_DISP_OVERWRITE_IF dispostion causes oplock break\n");
1845 
1846         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1847                 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1848                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1849         io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
1850         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1851                 NTCREATEX_SHARE_ACCESS_WRITE|
1852                 NTCREATEX_SHARE_ACCESS_DELETE;
1853         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE_IF;
1854         status = smb_raw_open(cli2->tree, tctx, &io);
1855         CHECK_STATUS(tctx, status, NT_STATUS_OK);
1856         fnum2 = io.ntcreatex.out.file.fnum;
1857         CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1858         CHECK_VAL(break_info.count, 1);
1859         CHECK_VAL(break_info.failures, 0);
1860 
1861         smbcli_close(cli1->tree, fnum);
1862         smbcli_close(cli2->tree, fnum2);
1863 
1864 done:
1865         smb_raw_exit(cli1->session);
1866         smb_raw_exit(cli2->session);
1867         smbcli_deltree(cli1->tree, BASEDIR);
1868         return ret;
1869 }
1870 
1871 static bool test_raw_oplock_batch17(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
     /* [<][>][^][v][top][bottom][index][help] */
1872 {
1873         const char *fname1 = BASEDIR "\\test_batch17_1.dat";
1874         const char *fname2 = BASEDIR "\\test_batch17_2.dat";
1875         NTSTATUS status;
1876         bool ret = true;
1877         union smb_open io;
1878         union smb_rename rn;
1879         uint16_t fnum=0;
1880 
1881         if (!torture_setup_dir(cli1, BASEDIR)) {
1882                 return false;
1883         }
1884 
1885         /* cleanup */
1886         smbcli_unlink(cli1->tree, fname1);
1887         smbcli_unlink(cli1->tree, fname2);
1888 
1889         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1890 
1891         /*
1892           base ntcreatex parms
1893         */
1894         io.generic.level = RAW_OPEN_NTCREATEX;
1895         io.ntcreatex.in.root_fid = 0;
1896         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1897         io.ntcreatex.in.alloc_size = 0;
1898         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1899         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1900         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1901         io.ntcreatex.in.create_options = 0;
1902         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1903         io.ntcreatex.in.security_flags = 0;
1904         io.ntcreatex.in.fname = fname1;
1905 
1906         torture_comment(tctx, "BATCH17: open a file with an batch oplock (share mode: none)\n");
1907 
1908         ZERO_STRUCT(break_info);
1909         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1910                 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1911                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1912 
1913         status = smb_raw_open(cli1->tree, tctx, &io);
1914         CHECK_STATUS(tctx, status, NT_STATUS_OK);
1915         fnum = io.ntcreatex.out.file.fnum;
1916         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1917 
1918         torture_comment(tctx, "rename should trigger a break\n");
1919         ZERO_STRUCT(rn);
1920         rn.generic.level = RAW_RENAME_RENAME;
1921         rn.rename.in.pattern1 = fname1;
1922         rn.rename.in.pattern2 = fname2;
1923         rn.rename.in.attrib = 0;
1924 
1925         printf("trying rename while first file open\n");
1926         status = smb_raw_rename(cli2->tree, &rn);
1927 
1928         CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
1929         CHECK_VAL(break_info.count, 1);
1930         CHECK_VAL(break_info.failures, 0);
1931         CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
1932 
1933         smbcli_close(cli1->tree, fnum);
1934 
1935 done:
1936         smb_raw_exit(cli1->session);
1937         smb_raw_exit(cli2->session);
1938         smbcli_deltree(cli1->tree, BASEDIR);
1939         return ret;
1940 }
1941 
1942 static bool test_raw_oplock_batch18(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
     /* [<][>][^][v][top][bottom][index][help] */
1943 {
1944         const char *fname1 = BASEDIR "\\test_batch18_1.dat";
1945         const char *fname2 = BASEDIR "\\test_batch18_2.dat";
1946         NTSTATUS status;
1947         bool ret = true;
1948         union smb_open io;
1949         union smb_rename rn;
1950         uint16_t fnum=0;
1951 
1952         if (!torture_setup_dir(cli1, BASEDIR)) {
1953                 return false;
1954         }
1955 
1956         /* cleanup */
1957         smbcli_unlink(cli1->tree, fname1);
1958         smbcli_unlink(cli1->tree, fname2);
1959 
1960         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1961 
1962         /*
1963           base ntcreatex parms
1964         */
1965         io.generic.level = RAW_OPEN_NTCREATEX;
1966         io.ntcreatex.in.root_fid = 0;
1967         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1968         io.ntcreatex.in.alloc_size = 0;
1969         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1970         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1971         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1972         io.ntcreatex.in.create_options = 0;
1973         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1974         io.ntcreatex.in.security_flags = 0;
1975         io.ntcreatex.in.fname = fname1;
1976 
1977         torture_comment(tctx, "BATCH18: open a file with an batch oplock (share mode: none)\n");
1978 
1979         ZERO_STRUCT(break_info);
1980         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1981                 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1982                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1983 
1984         status = smb_raw_open(cli1->tree, tctx, &io);
1985         CHECK_STATUS(tctx, status, NT_STATUS_OK);
1986         fnum = io.ntcreatex.out.file.fnum;
1987         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1988 
1989         torture_comment(tctx, "ntrename should trigger a break\n");
1990         ZERO_STRUCT(rn);
1991         rn.generic.level = RAW_RENAME_NTRENAME;
1992         rn.ntrename.in.attrib   = 0;
1993         rn.ntrename.in.flags    = RENAME_FLAG_RENAME;
1994         rn.ntrename.in.old_name = fname1;
1995         rn.ntrename.in.new_name = fname2;
1996         printf("trying rename while first file open\n");
1997         status = smb_raw_rename(cli2->tree, &rn);
1998 
1999         CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
2000         CHECK_VAL(break_info.count, 1);
2001         CHECK_VAL(break_info.failures, 0);
2002         CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
2003 
2004         smbcli_close(cli1->tree, fnum);
2005 
2006 done:
2007         smb_raw_exit(cli1->session);
2008         smb_raw_exit(cli2->session);
2009         smbcli_deltree(cli1->tree, BASEDIR);
2010         return ret;
2011 }
2012 
2013 static bool test_raw_oplock_batch19(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
     /* [<][>][^][v][top][bottom][index][help] */
2014 {
2015         const char *fname1 = BASEDIR "\\test_batch19_1.dat";
2016         const char *fname2 = BASEDIR "\\test_batch19_2.dat";
2017         const char *fname3 = BASEDIR "\\test_batch19_3.dat";
2018         NTSTATUS status;
2019         bool ret = true;
2020         union smb_open io;
2021         union smb_fileinfo qfi;
2022         union smb_setfileinfo sfi;
2023         uint16_t fnum=0;
2024 
2025         if (!torture_setup_dir(cli1, BASEDIR)) {
2026                 return false;
2027         }
2028 
2029         /* cleanup */
2030         smbcli_unlink(cli1->tree, fname1);
2031         smbcli_unlink(cli1->tree, fname2);
2032         smbcli_unlink(cli1->tree, fname3);
2033 
2034         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2035 
2036         /*
2037           base ntcreatex parms
2038         */
2039         io.generic.level = RAW_OPEN_NTCREATEX;
2040         io.ntcreatex.in.root_fid = 0;
2041         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2042         io.ntcreatex.in.alloc_size = 0;
2043         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2044         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2045         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2046         io.ntcreatex.in.create_options = 0;
2047         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2048         io.ntcreatex.in.security_flags = 0;
2049         io.ntcreatex.in.fname = fname1;
2050 
2051         torture_comment(tctx, "BATCH19: open a file with an batch oplock (share mode: none)\n");
2052         ZERO_STRUCT(break_info);
2053         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2054                 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2055                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2056         status = smb_raw_open(cli1->tree, tctx, &io);
2057         CHECK_STATUS(tctx, status, NT_STATUS_OK);
2058         fnum = io.ntcreatex.out.file.fnum;
2059         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
2060 
2061         torture_comment(tctx, "setpathinfo rename info should not trigger a break nor a violation\n");
2062         ZERO_STRUCT(sfi);
2063         sfi.generic.level = RAW_SFILEINFO_RENAME_INFORMATION;
2064         sfi.generic.in.file.path = fname1;
2065         sfi.rename_information.in.overwrite     = 0;
2066         sfi.rename_information.in.root_fid      = 0;
2067         sfi.rename_information.in.new_name      = fname2+strlen(BASEDIR)+1;
2068 
2069         status = smb_raw_setpathinfo(cli2->tree, &sfi);
2070 
2071         CHECK_STATUS(tctx, status, NT_STATUS_OK);
2072         CHECK_VAL(break_info.count, 0);
2073 
2074         ZERO_STRUCT(qfi);
2075         qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2076         qfi.generic.in.file.fnum = fnum;
2077 
2078         status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
2079         CHECK_STATUS(tctx, status, NT_STATUS_OK);
2080         CHECK_STRMATCH(qfi.all_info.out.fname.s, fname2);
2081 
2082         torture_comment(tctx, "setfileinfo rename info should not trigger a break nor a violation\n");
2083         ZERO_STRUCT(sfi);
2084         sfi.generic.level = RAW_SFILEINFO_RENAME_INFORMATION;
2085         sfi.generic.in.file.fnum = fnum;
2086         sfi.rename_information.in.overwrite     = 0;
2087         sfi.rename_information.in.root_fid      = 0;
2088         sfi.rename_information.in.new_name      = fname3+strlen(BASEDIR)+1;
2089 
2090         status = smb_raw_setfileinfo(cli1->tree, &sfi);
2091         CHECK_STATUS(tctx, status, NT_STATUS_OK);
2092         CHECK_VAL(break_info.count, 0);
2093 
2094         ZERO_STRUCT(qfi);
2095         qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2096         qfi.generic.in.file.fnum = fnum;
2097 
2098         status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
2099         CHECK_STATUS(tctx, status, NT_STATUS_OK);
2100         CHECK_STRMATCH(qfi.all_info.out.fname.s, fname3);
2101 
2102         smbcli_close(cli1->tree, fnum);
2103 
2104 done:
2105         smb_raw_exit(cli1->session);
2106         smb_raw_exit(cli2->session);
2107         smbcli_deltree(cli1->tree, BASEDIR);
2108         return ret;
2109 }
2110 
2111 /****************************************************
2112  Called from raw-rename - we need oplock handling for
2113  this test so this is why it's in oplock.c, not rename.c
2114 ****************************************************/
2115 
2116 bool test_trans2rename(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
     /* [<][>][^][v][top][bottom][index][help] */
2117 {
2118         const char *fname1 = BASEDIR "\\test_trans2rename_1.dat";
2119         const char *fname2 = BASEDIR "\\test_trans2rename_2.dat";
2120         const char *fname3 = BASEDIR "\\test_trans2rename_3.dat";
2121         NTSTATUS status;
2122         bool ret = true;
2123         union smb_open io;
2124         union smb_fileinfo qfi;
2125         union smb_setfileinfo sfi;
2126         uint16_t fnum=0;
2127 
2128         if (!torture_setup_dir(cli1, BASEDIR)) {
2129                 return false;
2130         }
2131 
2132         /* cleanup */
2133         smbcli_unlink(cli1->tree, fname1);
2134         smbcli_unlink(cli1->tree, fname2);
2135         smbcli_unlink(cli1->tree, fname3);
2136 
2137         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2138 
2139         /*
2140           base ntcreatex parms
2141         */
2142         io.generic.level = RAW_OPEN_NTCREATEX;
2143         io.ntcreatex.in.root_fid = 0;
2144         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2145         io.ntcreatex.in.alloc_size = 0;
2146         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2147         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2148         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2149         io.ntcreatex.in.create_options = 0;
2150         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2151         io.ntcreatex.in.security_flags = 0;
2152         io.ntcreatex.in.fname = fname1;
2153 
2154         torture_comment(tctx, "open a file with an exclusive oplock (share mode: none)\n");
2155         ZERO_STRUCT(break_info);
2156         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2157                 NTCREATEX_FLAGS_REQUEST_OPLOCK;
2158         status = smb_raw_open(cli1->tree, tctx, &io);
2159         CHECK_STATUS(tctx, status, NT_STATUS_OK);
2160         fnum = io.ntcreatex.out.file.fnum;
2161         CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
2162 
2163         torture_comment(tctx, "setpathinfo rename info should not trigger a break nor a violation\n");
2164         ZERO_STRUCT(sfi);
2165         sfi.generic.level = RAW_SFILEINFO_RENAME_INFORMATION;
2166         sfi.generic.in.file.path = fname1;
2167         sfi.rename_information.in.overwrite     = 0;
2168         sfi.rename_information.in.root_fid      = 0;
2169         sfi.rename_information.in.new_name      = fname2+strlen(BASEDIR)+1;
2170 
2171         status = smb_raw_setpathinfo(cli2->tree, &sfi);
2172 
2173         CHECK_STATUS(tctx, status, NT_STATUS_OK);
2174         CHECK_VAL(break_info.count, 0);
2175 
2176         ZERO_STRUCT(qfi);
2177         qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2178         qfi.generic.in.file.fnum = fnum;
2179 
2180         status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
2181         CHECK_STATUS(tctx, status, NT_STATUS_OK);
2182         CHECK_STRMATCH(qfi.all_info.out.fname.s, fname2);
2183 
2184         torture_comment(tctx, "setfileinfo rename info should not trigger a break nor a violation\n");
2185         ZERO_STRUCT(sfi);
2186         sfi.generic.level = RAW_SFILEINFO_RENAME_INFORMATION;
2187         sfi.generic.in.file.fnum = fnum;
2188         sfi.rename_information.in.overwrite     = 0;
2189         sfi.rename_information.in.root_fid      = 0;
2190         sfi.rename_information.in.new_name      = fname3+strlen(BASEDIR)+1;
2191 
2192         status = smb_raw_setfileinfo(cli1->tree, &sfi);
2193         CHECK_STATUS(tctx, status, NT_STATUS_OK);
2194         CHECK_VAL(break_info.count, 0);
2195 
2196         ZERO_STRUCT(qfi);
2197         qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2198         qfi.generic.in.file.fnum = fnum;
2199 
2200         status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
2201         CHECK_STATUS(tctx, status, NT_STATUS_OK);
2202         CHECK_STRMATCH(qfi.all_info.out.fname.s, fname3);
2203 
2204         smbcli_close(cli1->tree, fnum);
2205 
2206 done:
2207         smb_raw_exit(cli1->session);
2208         smb_raw_exit(cli2->session);
2209         smbcli_deltree(cli1->tree, BASEDIR);
2210         return ret;
2211 }
2212 
2213 /****************************************************
2214  Called from raw-rename - we need oplock handling for
2215  this test so this is why it's in oplock.c, not rename.c
2216 ****************************************************/
2217 
2218 bool test_nttransrename(struct torture_context *tctx, struct smbcli_state *cli1)
     /* [<][>][^][v][top][bottom][index][help] */
2219 {
2220         const char *fname1 = BASEDIR "\\test_nttransrename_1.dat";
2221         const char *fname2 = BASEDIR "\\test_nttransrename_2.dat";
2222         NTSTATUS status;
2223         bool ret = true;
2224         union smb_open io;
2225         union smb_fileinfo qfi, qpi;
2226         union smb_rename rn;
2227         uint16_t fnum=0;
2228 
2229         if (!torture_setup_dir(cli1, BASEDIR)) {
2230                 return false;
2231         }
2232 
2233         /* cleanup */
2234         smbcli_unlink(cli1->tree, fname1);
2235         smbcli_unlink(cli1->tree, fname2);
2236 
2237         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2238 
2239         /*
2240           base ntcreatex parms
2241         */
2242         io.generic.level = RAW_OPEN_NTCREATEX;
2243         io.ntcreatex.in.root_fid = 0;
2244         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2245         io.ntcreatex.in.alloc_size = 0;
2246         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2247         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2248         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2249         io.ntcreatex.in.create_options = 0;
2250         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2251         io.ntcreatex.in.security_flags = 0;
2252         io.ntcreatex.in.fname = fname1;
2253 
2254         torture_comment(tctx, "nttrans_rename: open a file with an exclusive oplock (share mode: none)\n");
2255         ZERO_STRUCT(break_info);
2256         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2257                 NTCREATEX_FLAGS_REQUEST_OPLOCK;
2258         status = smb_raw_open(cli1->tree, tctx, &io);
2259         CHECK_STATUS(tctx, status, NT_STATUS_OK);
2260         fnum = io.ntcreatex.out.file.fnum;
2261         CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
2262 
2263         torture_comment(tctx, "nttrans_rename: should not trigger a break nor a share mode violation\n");
2264         ZERO_STRUCT(rn);
2265         rn.generic.level = RAW_RENAME_NTTRANS;
2266         rn.nttrans.in.file.fnum = fnum;
2267         rn.nttrans.in.flags     = 0;
2268         rn.nttrans.in.new_name  = fname2+strlen(BASEDIR)+1;
2269 
2270         status = smb_raw_rename(cli1->tree, &rn);
2271 
2272         CHECK_STATUS(tctx, status, NT_STATUS_OK);
2273         CHECK_VAL(break_info.count, 0);
2274 
2275         /* w2k3 does nothing, it doesn't rename the file */
2276         torture_comment(tctx, "nttrans_rename: the server should have done nothing\n");
2277         ZERO_STRUCT(qfi);
2278         qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2279         qfi.generic.in.file.fnum = fnum;
2280 
2281         status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
2282         CHECK_STATUS(tctx, status, NT_STATUS_OK);
2283         CHECK_STRMATCH(qfi.all_info.out.fname.s, fname1);
2284 
2285         ZERO_STRUCT(qpi);
2286         qpi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2287         qpi.generic.in.file.path = fname1;
2288 
2289         status = smb_raw_pathinfo(cli1->tree, tctx, &qpi);
2290         CHECK_STATUS(tctx, status, NT_STATUS_OK);
2291         CHECK_STRMATCH(qpi.all_info.out.fname.s, fname1);
2292 
2293         ZERO_STRUCT(qpi);
2294         qpi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2295         qpi.generic.in.file.path = fname2;
2296 
2297         status = smb_raw_pathinfo(cli1->tree, tctx, &qpi);
2298         CHECK_STATUS(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
2299 
2300         torture_comment(tctx, "nttrans_rename: after closing the file the file is still not renamed\n");
2301         status = smbcli_close(cli1->tree, fnum);
2302         CHECK_STATUS(tctx, status, NT_STATUS_OK);
2303 
2304         ZERO_STRUCT(qpi);
2305         qpi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2306         qpi.generic.in.file.path = fname1;
2307 
2308         status = smb_raw_pathinfo(cli1->tree, tctx, &qpi);
2309         CHECK_STATUS(tctx, status, NT_STATUS_OK);
2310         CHECK_STRMATCH(qpi.all_info.out.fname.s, fname1);
2311 
2312         ZERO_STRUCT(qpi);
2313         qpi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2314         qpi.generic.in.file.path = fname2;
2315 
2316         status = smb_raw_pathinfo(cli1->tree, tctx, &qpi);
2317         CHECK_STATUS(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
2318 
2319         torture_comment(tctx, "nttrans_rename: rename with an invalid handle gives NT_STATUS_INVALID_HANDLE\n");
2320         ZERO_STRUCT(rn);
2321         rn.generic.level = RAW_RENAME_NTTRANS;
2322         rn.nttrans.in.file.fnum = fnum+1;
2323         rn.nttrans.in.flags     = 0;
2324         rn.nttrans.in.new_name  = fname2+strlen(BASEDIR)+1;
2325 
2326         status = smb_raw_rename(cli1->tree, &rn);
2327 
2328         CHECK_STATUS(tctx, status, NT_STATUS_INVALID_HANDLE);
2329 
2330 done:
2331         smb_raw_exit(cli1->session);
2332         smbcli_deltree(cli1->tree, BASEDIR);
2333         return ret;
2334 }
2335 
2336 
2337 static bool test_raw_oplock_batch20(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
     /* [<][>][^][v][top][bottom][index][help] */
2338 {
2339         const char *fname1 = BASEDIR "\\test_batch20_1.dat";
2340         const char *fname2 = BASEDIR "\\test_batch20_2.dat";
2341         const char *fname3 = BASEDIR "\\test_batch20_3.dat";
2342         NTSTATUS status;
2343         bool ret = true;
2344         union smb_open io;
2345         union smb_fileinfo qfi;
2346         union smb_setfileinfo sfi;
2347         uint16_t fnum=0,fnum2=0;
2348 
2349         if (!torture_setup_dir(cli1, BASEDIR)) {
2350                 return false;
2351         }
2352 
2353         /* cleanup */
2354         smbcli_unlink(cli1->tree, fname1);
2355         smbcli_unlink(cli1->tree, fname2);
2356         smbcli_unlink(cli1->tree, fname3);
2357 
2358         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2359 
2360         /*
2361           base ntcreatex parms
2362         */
2363         io.generic.level = RAW_OPEN_NTCREATEX;
2364         io.ntcreatex.in.root_fid = 0;
2365         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2366         io.ntcreatex.in.alloc_size = 0;
2367         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2368         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2369         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2370         io.ntcreatex.in.create_options = 0;
2371         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2372         io.ntcreatex.in.security_flags = 0;
2373         io.ntcreatex.in.fname = fname1;
2374 
2375         torture_comment(tctx, "BATCH20: open a file with an batch oplock (share mode: all)\n");
2376         ZERO_STRUCT(break_info);
2377         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2378                 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2379                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2380         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
2381                 NTCREATEX_SHARE_ACCESS_WRITE|
2382                 NTCREATEX_SHARE_ACCESS_DELETE;
2383         status = smb_raw_open(cli1->tree, tctx, &io);
2384         CHECK_STATUS(tctx, status, NT_STATUS_OK);
2385         fnum = io.ntcreatex.out.file.fnum;
2386         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
2387 
2388         torture_comment(tctx, "setpathinfo rename info should not trigger a break nor a violation\n");
2389         ZERO_STRUCT(sfi);
2390         sfi.generic.level = RAW_SFILEINFO_RENAME_INFORMATION;
2391         sfi.generic.in.file.path = fname1;
2392         sfi.rename_information.in.overwrite     = 0;
2393         sfi.rename_information.in.root_fid      = 0;
2394         sfi.rename_information.in.new_name      = fname2+strlen(BASEDIR)+1;
2395 
2396         status = smb_raw_setpathinfo(cli2->tree, &sfi);
2397 
2398         CHECK_STATUS(tctx, status, NT_STATUS_OK);
2399         CHECK_VAL(break_info.count, 0);
2400 
2401         ZERO_STRUCT(qfi);
2402         qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2403         qfi.generic.in.file.fnum = fnum;
2404 
2405         status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
2406         CHECK_STATUS(tctx, status, NT_STATUS_OK);
2407         CHECK_STRMATCH(qfi.all_info.out.fname.s, fname2);
2408 
2409         torture_comment(tctx, "open a file with the new name an batch oplock (share mode: all)\n");
2410         ZERO_STRUCT(break_info);
2411         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2412                 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2413                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2414         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
2415                 NTCREATEX_SHARE_ACCESS_WRITE|
2416                 NTCREATEX_SHARE_ACCESS_DELETE;
2417         io.ntcreatex.in.fname = fname2;
2418         status = smb_raw_open(cli2->tree, tctx, &io);
2419         CHECK_STATUS(tctx, status, NT_STATUS_OK);
2420         fnum2 = io.ntcreatex.out.file.fnum;
2421         CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
2422         CHECK_VAL(break_info.count, 1);
2423         CHECK_VAL(break_info.failures, 0);
2424         CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
2425 
2426         torture_comment(tctx, "setfileinfo rename info should not trigger a break nor a violation\n");
2427         ZERO_STRUCT(sfi);
2428         sfi.generic.level = RAW_SFILEINFO_RENAME_INFORMATION;
2429         sfi.generic.in.file.fnum = fnum;
2430         sfi.rename_information.in.overwrite     = 0;
2431         sfi.rename_information.in.root_fid      = 0;
2432         sfi.rename_information.in.new_name      = fname3+strlen(BASEDIR)+1;
2433 
2434         status = smb_raw_setfileinfo(cli1->tree, &sfi);
2435         CHECK_STATUS(tctx, status, NT_STATUS_OK);
2436         CHECK_VAL(break_info.count, 1);
2437         CHECK_VAL(break_info.failures, 0);
2438         CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
2439 
2440         ZERO_STRUCT(qfi);
2441         qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2442         qfi.generic.in.file.fnum = fnum;
2443 
2444         status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
2445         CHECK_STATUS(tctx, status, NT_STATUS_OK);
2446         CHECK_STRMATCH(qfi.all_info.out.fname.s, fname3);
2447 
2448         ZERO_STRUCT(qfi);
2449         qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2450         qfi.generic.in.file.fnum = fnum2;
2451 
2452         status = smb_raw_fileinfo(cli2->tree, tctx, &qfi);
2453         CHECK_STATUS(tctx, status, NT_STATUS_OK);
2454         CHECK_STRMATCH(qfi.all_info.out.fname.s, fname3);
2455 
2456         smbcli_close(cli1->tree, fnum);
2457 
2458 done:
2459         smb_raw_exit(cli1->session);
2460         smb_raw_exit(cli2->session);
2461         smbcli_deltree(cli1->tree, BASEDIR);
2462         return ret;
2463 }
2464 
2465 static bool test_raw_oplock_batch21(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
     /* [<][>][^][v][top][bottom][index][help] */
2466 {
2467         const char *fname = BASEDIR "\\test_batch21.dat";
2468         NTSTATUS status;
2469         bool ret = true;
2470         union smb_open io;
2471         struct smb_echo e;
2472         uint16_t fnum=0;
2473         char c = 0;
2474         ssize_t wr;
2475 
2476         if (!torture_setup_dir(cli1, BASEDIR)) {
2477                 return false;
2478         }
2479 
2480         /* cleanup */
2481         smbcli_unlink(cli1->tree, fname);
2482 
2483         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2484 
2485         /*
2486           base ntcreatex parms
2487         */
2488         io.generic.level = RAW_OPEN_NTCREATEX;
2489         io.ntcreatex.in.root_fid = 0;
2490         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2491         io.ntcreatex.in.alloc_size = 0;
2492         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2493         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2494         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2495         io.ntcreatex.in.create_options = 0;
2496         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2497         io.ntcreatex.in.security_flags = 0;
2498         io.ntcreatex.in.fname = fname;
2499 
2500         /*
2501           with a batch oplock we get a break
2502         */
2503         torture_comment(tctx, "BATCH21: open with batch oplock\n");
2504         ZERO_STRUCT(break_info);
2505         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2506                 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2507                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2508         status = smb_raw_open(cli1->tree, tctx, &io);
2509         CHECK_STATUS(tctx, status, NT_STATUS_OK);
2510         fnum = io.ntcreatex.out.file.fnum;
2511         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
2512 
2513         torture_comment(tctx, "writing should not generate a break\n");
2514         wr = smbcli_write(cli1->tree, fnum, 0, &c, 0, 1);
2515         CHECK_VAL(wr, 1);
2516         CHECK_STATUS(tctx, smbcli_nt_error(cli1->tree), NT_STATUS_OK);
2517 
2518         ZERO_STRUCT(e);
2519         e.in.repeat_count = 1;
2520         status = smb_raw_echo(cli1->transport, &e);
2521         CHECK_STATUS(tctx, status, NT_STATUS_OK);
2522 
2523         CHECK_VAL(break_info.count, 0);
2524 
2525         smbcli_close(cli1->tree, fnum);
2526 
2527 done:
2528         smb_raw_exit(cli1->session);
2529         smb_raw_exit(cli2->session);
2530         smbcli_deltree(cli1->tree, BASEDIR);
2531         return ret;
2532 }
2533 
2534 static bool test_raw_oplock_batch22(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
     /* [<][>][^][v][top][bottom][index][help] */
2535 {
2536         const char *fname = BASEDIR "\\test_batch22.dat";
2537         NTSTATUS status;
2538         bool ret = true;
2539         union smb_open io;
2540         uint16_t fnum=0, fnum2=0;
2541         struct timeval tv;
2542         int timeout = torture_setting_int(tctx, "oplocktimeout", 30);
2543         int te;
2544 
2545         if (torture_setting_bool(tctx, "samba3", false)) {
2546                 torture_skip(tctx, "BATCH22 disabled against samba3\n");
2547         }
2548 
2549         if (!torture_setup_dir(cli1, BASEDIR)) {
2550                 return false;
2551         }
2552 
2553         /* cleanup */
2554         smbcli_unlink(cli1->tree, fname);
2555 
2556         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2557 
2558         /*
2559           base ntcreatex parms
2560         */
2561         io.generic.level = RAW_OPEN_NTCREATEX;
2562         io.ntcreatex.in.root_fid = 0;
2563         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2564         io.ntcreatex.in.alloc_size = 0;
2565         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2566         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2567         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2568         io.ntcreatex.in.create_options = 0;
2569         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2570         io.ntcreatex.in.security_flags = 0;
2571         io.ntcreatex.in.fname = fname;
2572 
2573         /*
2574           with a batch oplock we get a break
2575         */
2576         torture_comment(tctx, "BATCH22: open with batch oplock\n");
2577         ZERO_STRUCT(break_info);
2578         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2579                 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2580                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2581         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
2582                 NTCREATEX_SHARE_ACCESS_WRITE|
2583                 NTCREATEX_SHARE_ACCESS_DELETE;
2584         status = smb_raw_open(cli1->tree, tctx, &io);
2585         CHECK_STATUS(tctx, status, NT_STATUS_OK);
2586         fnum = io.ntcreatex.out.file.fnum;
2587         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
2588 
2589         torture_comment(tctx, "a 2nd open shoud not succeed after the oplock break timeout\n");
2590         tv = timeval_current();
2591         smbcli_oplock_handler(cli1->transport, oplock_handler_timeout, cli1->tree);
2592         status = smb_raw_open(cli1->tree, tctx, &io);
2593         CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
2594         te = (int)timeval_elapsed(&tv);
2595         CHECK_RANGE(te, timeout - 1, timeout + 15);
2596 
2597         CHECK_VAL(break_info.count, 1);
2598         CHECK_VAL(break_info.fnum, fnum);
2599         CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
2600         CHECK_VAL(break_info.failures, 0);
2601         ZERO_STRUCT(break_info);
2602 
2603         torture_comment(tctx, "a 2nd open shoud succeed after the oplock release without break\n");
2604         tv = timeval_current();
2605         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2606         status = smb_raw_open(cli1->tree, tctx, &io);
2607         CHECK_STATUS(tctx, status, NT_STATUS_OK);
2608         CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
2609         te = (int)timeval_elapsed(&tv);
2610         /* it should come in without delay */
2611         CHECK_RANGE(te+1, 0, timeout);
2612         fnum2 = io.ntcreatex.out.file.fnum;
2613 
2614         CHECK_VAL(break_info.count, 0);
2615 
2616         smbcli_close(cli1->tree, fnum);
2617         smbcli_close(cli1->tree, fnum2);
2618 
2619 done:
2620         smb_raw_exit(cli1->session);
2621         smb_raw_exit(cli2->session);
2622         smbcli_deltree(cli1->tree, BASEDIR);
2623         return ret;
2624 }
2625 
2626 static bool test_raw_oplock_batch23(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
     /* [<][>][^][v][top][bottom][index][help] */
2627 {
2628         const char *fname = BASEDIR "\\test_batch23.dat";
2629         NTSTATUS status;
2630         bool ret = true;
2631         union smb_open io;
2632         uint16_t fnum=0, fnum2=0,fnum3=0;
2633         struct smbcli_state *cli3 = NULL;
2634 
2635         if (!torture_setup_dir(cli1, BASEDIR)) {
2636                 return false;
2637         }
2638 
2639         /* cleanup */
2640         smbcli_unlink(cli1->tree, fname);
2641 
2642         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2643 
2644         ret = open_connection_no_level2_oplocks(tctx, &cli3);
2645         CHECK_VAL(ret, true);
2646 
2647         /*
2648           base ntcreatex parms
2649         */
2650         io.generic.level = RAW_OPEN_NTCREATEX;
2651         io.ntcreatex.in.root_fid = 0;
2652         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2653         io.ntcreatex.in.alloc_size = 0;
2654         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2655         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2656         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2657         io.ntcreatex.in.create_options = 0;
2658         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2659         io.ntcreatex.in.security_flags = 0;
2660         io.ntcreatex.in.fname = fname;
2661 
2662         torture_comment(tctx, "BATCH23: a open and ask for a batch oplock\n");
2663         ZERO_STRUCT(break_info);
2664         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2665         smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli2->tree);
2666         smbcli_oplock_handler(cli3->transport, oplock_handler_ack_to_given, cli3->tree);
2667 
2668         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_READ | SEC_RIGHTS_FILE_WRITE;
2669         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
2670         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2671                 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2672                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2673         status = smb_raw_open(cli1->tree, tctx, &io);
2674         CHECK_STATUS(tctx, status, NT_STATUS_OK);
2675         fnum = io.ntcreatex.out.file.fnum;
2676         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
2677 
2678         ZERO_STRUCT(break_info);
2679 
2680         torture_comment(tctx, "a 2nd open without level2 oplock support should generate a break to level2\n");
2681         status = smb_raw_open(cli3->tree, tctx, &io);
2682         CHECK_STATUS(tctx, status, NT_STATUS_OK);
2683         fnum3 = io.ntcreatex.out.file.fnum;
2684         CHECK_VAL(io.ntcreatex.out.oplock_level, NO_OPLOCK_RETURN);
2685 
2686         CHECK_VAL(break_info.count, 1);
2687         CHECK_VAL(break_info.fnum, fnum);
2688         CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
2689         CHECK_VAL(break_info.failures, 0);
2690 
2691         ZERO_STRUCT(break_info);
2692 
2693         torture_comment(tctx, "a 3rd open with level2 oplock support should not generate a break\n");
2694         status = smb_raw_open(cli2->tree, tctx, &io);
2695         CHECK_STATUS(tctx, status, NT_STATUS_OK);
2696         fnum2 = io.ntcreatex.out.file.fnum;
2697         CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
2698 
2699         CHECK_VAL(break_info.count, 0);
2700 
2701         smbcli_close(cli1->tree, fnum);
2702         smbcli_close(cli2->tree, fnum2);
2703         smbcli_close(cli3->tree, fnum3);
2704 
2705 done:
2706         smb_raw_exit(cli1->session);
2707         smb_raw_exit(cli2->session);
2708         smb_raw_exit(cli3->session);
2709         smbcli_deltree(cli1->tree, BASEDIR);
2710         return ret;
2711 }
2712 
2713 static bool test_raw_oplock_batch24(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
     /* [<][>][^][v][top][bottom][index][help] */
2714 {
2715         const char *fname = BASEDIR "\\test_batch24.dat";
2716         NTSTATUS status;
2717         bool ret = true;
2718         union smb_open io;
2719         uint16_t fnum2=0,fnum3=0;
2720         struct smbcli_state *cli3 = NULL;
2721 
2722         if (!torture_setup_dir(cli1, BASEDIR)) {
2723                 return false;
2724         }
2725 
2726         /* cleanup */
2727         smbcli_unlink(cli1->tree, fname);
2728 
2729         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2730 
2731         ret = open_connection_no_level2_oplocks(tctx, &cli3);
2732         CHECK_VAL(ret, true);
2733 
2734         /*
2735           base ntcreatex parms
2736         */
2737         io.generic.level = RAW_OPEN_NTCREATEX;
2738         io.ntcreatex.in.root_fid = 0;
2739         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2740         io.ntcreatex.in.alloc_size = 0;
2741         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2742         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2743         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2744         io.ntcreatex.in.create_options = 0;
2745         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2746         io.ntcreatex.in.security_flags = 0;
2747         io.ntcreatex.in.fname = fname;
2748 
2749         torture_comment(tctx, "BATCH24: a open without level support and ask for a batch oplock\n");
2750         ZERO_STRUCT(break_info);
2751         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2752         smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli2->tree);
2753         smbcli_oplock_handler(cli3->transport, oplock_handler_ack_to_given, cli3->tree);
2754 
2755         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_READ | SEC_RIGHTS_FILE_WRITE;
2756         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
2757         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2758                 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2759                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2760         status = smb_raw_open(cli3->tree, tctx, &io);
2761         CHECK_STATUS(tctx, status, NT_STATUS_OK);
2762         fnum3 = io.ntcreatex.out.file.fnum;
2763         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
2764 
2765         ZERO_STRUCT(break_info);
2766 
2767         torture_comment(tctx, "a 2nd open with level2 oplock support should generate a break to none\n");
2768         status = smb_raw_open(cli2->tree, tctx, &io);
2769         CHECK_STATUS(tctx, status, NT_STATUS_OK);
2770         fnum2 = io.ntcreatex.out.file.fnum;
2771         CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
2772 
2773         CHECK_VAL(break_info.count, 1);
2774         CHECK_VAL(break_info.fnum, fnum3);
2775         CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_NONE);
2776         CHECK_VAL(break_info.failures, 0);
2777 
2778         smbcli_close(cli3->tree, fnum3);
2779         smbcli_close(cli2->tree, fnum2);
2780 
2781 done:
2782         smb_raw_exit(cli1->session);
2783         smb_raw_exit(cli2->session);
2784         smb_raw_exit(cli3->session);
2785         smbcli_deltree(cli1->tree, BASEDIR);
2786         return ret;
2787 }
2788 
2789 static bool test_raw_oplock_batch25(struct torture_context *tctx,
     /* [<][>][^][v][top][bottom][index][help] */
2790                                     struct smbcli_state *cli1,
2791                                     struct smbcli_state *cli2)
2792 {
2793         const char *fname = BASEDIR "\\test_batch25.dat";
2794         NTSTATUS status;
2795         bool ret = true;
2796         union smb_open io;
2797         union smb_setfileinfo sfi;
2798         uint16_t fnum=0;
2799 
2800         if (!torture_setup_dir(cli1, BASEDIR)) {
2801                 return false;
2802         }
2803 
2804         /* cleanup */
2805         smbcli_unlink(cli1->tree, fname);
2806 
2807         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2808 
2809         /*
2810           base ntcreatex parms
2811         */
2812         io.generic.level = RAW_OPEN_NTCREATEX;
2813         io.ntcreatex.in.root_fid = 0;
2814         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2815         io.ntcreatex.in.alloc_size = 0;
2816         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2817         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2818         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2819         io.ntcreatex.in.create_options = 0;
2820         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2821         io.ntcreatex.in.security_flags = 0;
2822         io.ntcreatex.in.fname = fname;
2823 
2824         torture_comment(tctx, "BATCH25: open a file with an batch oplock "
2825                         "(share mode: none)\n");
2826 
2827         ZERO_STRUCT(break_info);
2828         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2829                 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2830                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2831         status = smb_raw_open(cli1->tree, tctx, &io);
2832         CHECK_STATUS(tctx, status, NT_STATUS_OK);
2833         fnum = io.ntcreatex.out.file.fnum;
2834         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
2835 
2836         torture_comment(tctx, "setpathinfo attribute info should not trigger "
2837                         "a break nor a violation\n");
2838         ZERO_STRUCT(sfi);
2839         sfi.generic.level = RAW_SFILEINFO_SETATTR;
2840         sfi.generic.in.file.path        = fname;
2841         sfi.setattr.in.attrib           = FILE_ATTRIBUTE_HIDDEN;
2842         sfi.setattr.in.write_time       = 0;
2843 
2844         status = smb_raw_setpathinfo(cli2->tree, &sfi);
2845 
2846         CHECK_STATUS(tctx, status, NT_STATUS_OK);
2847         CHECK_VAL(break_info.count, 0);
2848 
2849         smbcli_close(cli1->tree, fnum);
2850 
2851 done:
2852         smb_raw_exit(cli1->session);
2853         smb_raw_exit(cli2->session);
2854         smbcli_deltree(cli1->tree, BASEDIR);
2855         return ret;
2856 }
2857 
2858 /* 
2859    basic testing of oplocks
2860 */
2861 struct torture_suite *torture_raw_oplock(TALLOC_CTX *mem_ctx)
     /* [<][>][^][v][top][bottom][index][help] */
2862 {
2863         struct torture_suite *suite = torture_suite_create(mem_ctx, "OPLOCK");
2864 
2865         torture_suite_add_2smb_test(suite, "EXCLUSIVE1", test_raw_oplock_exclusive1);
2866         torture_suite_add_2smb_test(suite, "EXCLUSIVE2", test_raw_oplock_exclusive2);
2867         torture_suite_add_2smb_test(suite, "EXCLUSIVE3", test_raw_oplock_exclusive3);
2868         torture_suite_add_2smb_test(suite, "EXCLUSIVE4", test_raw_oplock_exclusive4);
2869         torture_suite_add_2smb_test(suite, "EXCLUSIVE5", test_raw_oplock_exclusive5);
2870         torture_suite_add_2smb_test(suite, "EXCLUSIVE6", test_raw_oplock_exclusive6);
2871         torture_suite_add_2smb_test(suite, "BATCH1", test_raw_oplock_batch1);
2872         torture_suite_add_2smb_test(suite, "BATCH2", test_raw_oplock_batch2);
2873         torture_suite_add_2smb_test(suite, "BATCH3", test_raw_oplock_batch3);
2874         torture_suite_add_2smb_test(suite, "BATCH4", test_raw_oplock_batch4);
2875         torture_suite_add_2smb_test(suite, "BATCH5", test_raw_oplock_batch5);
2876         torture_suite_add_2smb_test(suite, "BATCH6", test_raw_oplock_batch6);
2877         torture_suite_add_2smb_test(suite, "BATCH7", test_raw_oplock_batch7);
2878         torture_suite_add_2smb_test(suite, "BATCH8", test_raw_oplock_batch8);
2879         torture_suite_add_2smb_test(suite, "BATCH9", test_raw_oplock_batch9);
2880         torture_suite_add_2smb_test(suite, "BATCH10", test_raw_oplock_batch10);
2881         torture_suite_add_2smb_test(suite, "BATCH11", test_raw_oplock_batch11);
2882         torture_suite_add_2smb_test(suite, "BATCH12", test_raw_oplock_batch12);
2883         torture_suite_add_2smb_test(suite, "BATCH13", test_raw_oplock_batch13);
2884         torture_suite_add_2smb_test(suite, "BATCH14", test_raw_oplock_batch14);
2885         torture_suite_add_2smb_test(suite, "BATCH15", test_raw_oplock_batch15);
2886         torture_suite_add_2smb_test(suite, "BATCH16", test_raw_oplock_batch16);
2887         torture_suite_add_2smb_test(suite, "BATCH17", test_raw_oplock_batch17);
2888         torture_suite_add_2smb_test(suite, "BATCH18", test_raw_oplock_batch18);
2889         torture_suite_add_2smb_test(suite, "BATCH19", test_raw_oplock_batch19);
2890         torture_suite_add_2smb_test(suite, "BATCH20", test_raw_oplock_batch20);
2891         torture_suite_add_2smb_test(suite, "BATCH21", test_raw_oplock_batch21);
2892         torture_suite_add_2smb_test(suite, "BATCH22", test_raw_oplock_batch22);
2893         torture_suite_add_2smb_test(suite, "BATCH23", test_raw_oplock_batch23);
2894         torture_suite_add_2smb_test(suite, "BATCH24", test_raw_oplock_batch24);
2895         torture_suite_add_2smb_test(suite, "BATCH25", test_raw_oplock_batch25);
2896 
2897         return suite;
2898 }
2899 
2900 /* 
2901    stress testing of oplocks
2902 */
2903 bool torture_bench_oplock(struct torture_context *torture)
     /* [<][>][^][v][top][bottom][index][help] */
2904 {
2905         struct smbcli_state **cli;
2906         bool ret = true;
2907         TALLOC_CTX *mem_ctx = talloc_new(torture);
2908         int torture_nprocs = torture_setting_int(torture, "nprocs", 4);
2909         int i, count=0;
2910         int timelimit = torture_setting_int(torture, "timelimit", 10);
2911         union smb_open io;
2912         struct timeval tv;
2913 
2914         cli = talloc_array(mem_ctx, struct smbcli_state *, torture_nprocs);
2915 
2916         torture_comment(torture, "Opening %d connections\n", torture_nprocs);
2917         for (i=0;i<torture_nprocs;i++) {
2918                 if (!torture_open_connection_ev(&cli[i], i, torture, torture->ev)) {
2919                         return false;
2920                 }
2921                 talloc_steal(mem_ctx, cli[i]);
2922                 smbcli_oplock_handler(cli[i]->transport, oplock_handler_close, 
2923                                       cli[i]->tree);
2924         }
2925 
2926         if (!torture_setup_dir(cli[0], BASEDIR)) {
2927                 ret = false;
2928                 goto done;
2929         }
2930 
2931         io.ntcreatex.level = RAW_OPEN_NTCREATEX;
2932         io.ntcreatex.in.root_fid = 0;
2933         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2934         io.ntcreatex.in.alloc_size = 0;
2935         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2936         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2937         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2938         io.ntcreatex.in.create_options = 0;
2939         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2940         io.ntcreatex.in.security_flags = 0;
2941         io.ntcreatex.in.fname = BASEDIR "\\test.dat";
2942         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | 
2943                 NTCREATEX_FLAGS_REQUEST_OPLOCK | 
2944                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2945 
2946         tv = timeval_current(); 
2947 
2948         /*
2949           we open the same file with SHARE_ACCESS_NONE from all the
2950           connections in a round robin fashion. Each open causes an
2951           oplock break on the previous connection, which is answered
2952           by the oplock_handler_close() to close the file.
2953 
2954           This measures how fast we can pass on oplocks, and stresses
2955           the oplock handling code
2956         */
2957         torture_comment(torture, "Running for %d seconds\n", timelimit);
2958         while (timeval_elapsed(&tv) < timelimit) {
2959                 for (i=0;i<torture_nprocs;i++) {
2960                         NTSTATUS status;
2961 
2962                         status = smb_raw_open(cli[i]->tree, mem_ctx, &io);
2963                         CHECK_STATUS(torture, status, NT_STATUS_OK);
2964                         count++;
2965                 }
2966 
2967                 if (torture_setting_bool(torture, "progress", true)) {
2968                         torture_comment(torture, "%.2f ops/second\r", count/timeval_elapsed(&tv));
2969                 }
2970         }
2971 
2972         torture_comment(torture, "%.2f ops/second\n", count/timeval_elapsed(&tv));
2973 
2974         smb_raw_exit(cli[torture_nprocs-1]->session);
2975         
2976 done:
2977         smb_raw_exit(cli[0]->session);
2978         smbcli_deltree(cli[0]->tree, BASEDIR);
2979         talloc_free(mem_ctx);
2980         return ret;
2981 }
2982 
2983 
2984 static struct hold_oplock_info {
2985         const char *fname;
2986         bool close_on_break;
2987         uint32_t share_access;
2988         uint16_t fnum;
2989 } hold_info[] = {
2990         { BASEDIR "\\notshared_close", true,  
2991           NTCREATEX_SHARE_ACCESS_NONE, },
2992         { BASEDIR "\\notshared_noclose", false, 
2993           NTCREATEX_SHARE_ACCESS_NONE, },
2994         { BASEDIR "\\shared_close", true,  
2995           NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE, },
2996         { BASEDIR "\\shared_noclose", false,  
2997           NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE, },
2998 };
2999 
3000 static bool oplock_handler_hold(struct smbcli_transport *transport, 
     /* [<][>][^][v][top][bottom][index][help] */
3001                                 uint16_t tid, uint16_t fnum, uint8_t level, 
3002                                 void *private_data)
3003 {
3004         struct smbcli_tree *tree = (struct smbcli_tree *)private_data;
3005         struct hold_oplock_info *info;
3006         int i;
3007 
3008         for (i=0;i<ARRAY_SIZE(hold_info);i++) {
3009                 if (hold_info[i].fnum == fnum) break;
3010         }
3011 
3012         if (i == ARRAY_SIZE(hold_info)) {
3013                 printf("oplock break for unknown fnum %u\n", fnum);
3014                 return false;
3015         }
3016 
3017         info = &hold_info[i];
3018 
3019         if (info->close_on_break) {
3020                 printf("oplock break on %s - closing\n",
3021                        info->fname);
3022                 oplock_handler_close(transport, tid, fnum, level, private_data);
3023                 return true;
3024         }
3025 
3026         printf("oplock break on %s - acking break\n", info->fname);
3027 
3028         return smbcli_oplock_ack(tree, fnum, OPLOCK_BREAK_TO_NONE);
3029 }
3030 
3031 
3032 /* 
3033    used for manual testing of oplocks - especially interaction with
3034    other filesystems (such as NFS and local access)
3035 */
3036 bool torture_hold_oplock(struct torture_context *torture, 
     /* [<][>][^][v][top][bottom][index][help] */
3037                          struct smbcli_state *cli)
3038 {
3039         struct tevent_context *ev = 
3040                 (struct tevent_context *)cli->transport->socket->event.ctx;
3041         int i;
3042 
3043         printf("Setting up open files with oplocks in %s\n", BASEDIR);
3044 
3045         if (!torture_setup_dir(cli, BASEDIR)) {
3046                 return false;
3047         }
3048 
3049         smbcli_oplock_handler(cli->transport, oplock_handler_hold, cli->tree);
3050 
3051         /* setup the files */
3052         for (i=0;i<ARRAY_SIZE(hold_info);i++) {
3053                 union smb_open io;
3054                 NTSTATUS status;
3055                 char c = 1;
3056 
3057                 io.generic.level = RAW_OPEN_NTCREATEX;
3058                 io.ntcreatex.in.root_fid = 0;
3059                 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
3060                 io.ntcreatex.in.alloc_size = 0;
3061                 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
3062                 io.ntcreatex.in.share_access = hold_info[i].share_access;
3063                 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
3064                 io.ntcreatex.in.create_options = 0;
3065                 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
3066                 io.ntcreatex.in.security_flags = 0;
3067                 io.ntcreatex.in.fname = hold_info[i].fname;
3068                 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | 
3069                         NTCREATEX_FLAGS_REQUEST_OPLOCK |
3070                         NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
3071                 printf("opening %s\n", hold_info[i].fname);
3072 
3073                 status = smb_raw_open(cli->tree, cli, &io);
3074                 if (!NT_STATUS_IS_OK(status)) {
3075                         printf("Failed to open %s - %s\n", 
3076                                hold_info[i].fname, nt_errstr(status));
3077                         return false;
3078                 }
3079 
3080                 if (io.ntcreatex.out.oplock_level != BATCH_OPLOCK_RETURN) {
3081                         printf("Oplock not granted for %s - expected %d but got %d\n", 
3082                                hold_info[i].fname, BATCH_OPLOCK_RETURN, 
3083                                 io.ntcreatex.out.oplock_level);
3084                         return false;
3085                 }
3086                 hold_info[i].fnum = io.ntcreatex.out.file.fnum;
3087 
3088                 /* make the file non-zero size */
3089                 if (smbcli_write(cli->tree, hold_info[i].fnum, 0, &c, 0, 1) != 1) {
3090                         printf("Failed to write to file\n");
3091                         return false;
3092                 }
3093         }
3094 
3095         printf("Waiting for oplock events\n");
3096         event_loop_wait(ev);
3097 
3098         return true;
3099 }

/* [<][>][^][v][top][bottom][index][help] */