2 Unix SMB/CIFS implementation.
3 basic raw test suite for oplocks
4 Copyright (C) Andrew Tridgell 2003
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.
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.
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/>.
21 #include "torture/torture.h"
22 #include "librpc/gen_ndr/security.h"
23 #include "libcli/raw/libcliraw.h"
24 #include "libcli/libcli.h"
25 #include "torture/util.h"
26 #include "lib/events/events.h"
27 #include "param/param.h"
28 #include "lib/cmdline/popt_common.h"
29 #include "libcli/resolve/resolve.h"
31 #define CHECK_VAL(v, correct) do { \
32 if ((v) != (correct)) { \
33 torture_result(tctx, TORTURE_FAIL, "(%s): wrong value for %s got 0x%x - should be 0x%x\n", \
34 __location__, #v, (int)v, (int)correct); \
38 #define CHECK_RANGE(v, min, max) do { \
39 if ((v) < (min) || (v) > (max)) { \
40 torture_result(tctx, TORTURE_FAIL, "(%s): wrong value for %s got %d - should be between %d and %d\n", \
41 __location__, #v, (int)v, (int)min, (int)max); \
45 #define CHECK_STRMATCH(v, correct) do { \
46 if (!v || strstr((v),(correct)) == NULL) { \
47 torture_result(tctx, TORTURE_FAIL, "(%s): wrong value for %s got '%s' - should be '%s'\n", \
48 __location__, #v, v?v:"NULL", correct); \
53 #define CHECK_STATUS(tctx, status, correct) do { \
54 if (!NT_STATUS_EQUAL(status, correct)) { \
55 torture_result(tctx, TORTURE_FAIL, __location__": Incorrect status %s - should be %s", \
56 nt_errstr(status), nt_errstr(correct)); \
69 #define BASEDIR "\\test_oplock"
72 a handler function for oplock break requests. Ack it as a break to level II if possible
74 static bool oplock_handler_ack_to_given(struct smbcli_transport *transport,
75 uint16_t tid, uint16_t fnum,
76 uint8_t level, void *private)
78 struct smbcli_tree *tree = (struct smbcli_tree *)private;
81 break_info.fnum = fnum;
82 break_info.level = level;
86 case OPLOCK_BREAK_TO_LEVEL_II:
89 case OPLOCK_BREAK_TO_NONE:
94 break_info.failures++;
96 printf("Acking to %s [0x%02X] in oplock handler\n",
99 return smbcli_oplock_ack(tree, fnum, level);
103 a handler function for oplock break requests. Ack it as a break to none
105 static bool oplock_handler_ack_to_none(struct smbcli_transport *transport,
106 uint16_t tid, uint16_t fnum,
107 uint8_t level, void *private)
109 struct smbcli_tree *tree = (struct smbcli_tree *)private;
110 break_info.fnum = fnum;
111 break_info.level = level;
114 printf("Acking to none in oplock handler\n");
116 return smbcli_oplock_ack(tree, fnum, OPLOCK_BREAK_TO_NONE);
120 a handler function for oplock break requests. Let it timeout
122 static bool oplock_handler_timeout(struct smbcli_transport *transport,
123 uint16_t tid, uint16_t fnum,
124 uint8_t level, void *private)
126 break_info.fnum = fnum;
127 break_info.level = level;
130 printf("Let oplock break timeout\n");
134 static void oplock_handler_close_recv(struct smbcli_request *req)
137 status = smbcli_request_simple_recv(req);
138 if (!NT_STATUS_IS_OK(status)) {
139 printf("close failed in oplock_handler_close\n");
140 break_info.failures++;
145 a handler function for oplock break requests - close the file
147 static bool oplock_handler_close(struct smbcli_transport *transport, uint16_t tid,
148 uint16_t fnum, uint8_t level, void *private)
151 struct smbcli_tree *tree = (struct smbcli_tree *)private;
152 struct smbcli_request *req;
154 break_info.fnum = fnum;
155 break_info.level = level;
158 io.close.level = RAW_CLOSE_CLOSE;
159 io.close.in.file.fnum = fnum;
160 io.close.in.write_time = 0;
161 req = smb_raw_close_send(tree, &io);
163 printf("failed to send close in oplock_handler_close\n");
167 req->async.fn = oplock_handler_close_recv;
168 req->async.private = NULL;
173 static bool open_connection_no_level2_oplocks(struct torture_context *tctx,
174 struct smbcli_state **c)
178 struct smbcli_options options;
180 lp_smbcli_options(tctx->lp_ctx, &options);
182 options.use_level2_oplocks = false;
184 status = smbcli_full_connection(tctx, c,
185 torture_setting_string(tctx, "host", NULL),
186 lp_smb_ports(tctx->lp_ctx),
187 torture_setting_string(tctx, "share", NULL),
188 NULL, cmdline_credentials,
189 lp_resolve_context(tctx->lp_ctx),
191 if (!NT_STATUS_IS_OK(status)) {
192 printf("Failed to open connection - %s\n", nt_errstr(status));
199 static bool test_raw_oplock_exclusive1(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
201 const char *fname = BASEDIR "\\test_exclusive1.dat";
205 union smb_unlink unl;
208 if (!torture_setup_dir(cli1, BASEDIR)) {
213 smbcli_unlink(cli1->tree, fname);
215 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
220 io.generic.level = RAW_OPEN_NTCREATEX;
221 io.ntcreatex.in.root_fid = 0;
222 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
223 io.ntcreatex.in.alloc_size = 0;
224 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
225 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
226 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
227 io.ntcreatex.in.create_options = 0;
228 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
229 io.ntcreatex.in.security_flags = 0;
230 io.ntcreatex.in.fname = fname;
232 torture_comment(tctx, "EXCLUSIVE1: open a file with an exclusive oplock (share mode: none)\n");
233 ZERO_STRUCT(break_info);
234 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
236 status = smb_raw_open(cli1->tree, tctx, &io);
237 CHECK_STATUS(tctx, status, NT_STATUS_OK);
238 fnum = io.ntcreatex.out.file.fnum;
239 CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
241 torture_comment(tctx, "a 2nd open should not cause a break\n");
242 status = smb_raw_open(cli2->tree, tctx, &io);
243 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
244 CHECK_VAL(break_info.count, 0);
245 CHECK_VAL(break_info.failures, 0);
247 torture_comment(tctx, "unlink it - should also be no break\n");
248 unl.unlink.in.pattern = fname;
249 unl.unlink.in.attrib = 0;
250 status = smb_raw_unlink(cli2->tree, &unl);
251 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
252 CHECK_VAL(break_info.count, 0);
253 CHECK_VAL(break_info.failures, 0);
255 smbcli_close(cli1->tree, fnum);
258 smb_raw_exit(cli1->session);
259 smb_raw_exit(cli2->session);
260 smbcli_deltree(cli1->tree, BASEDIR);
264 static bool test_raw_oplock_exclusive2(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
266 const char *fname = BASEDIR "\\test_exclusive2.dat";
270 union smb_unlink unl;
271 uint16_t fnum=0, fnum2=0;
273 if (!torture_setup_dir(cli1, BASEDIR)) {
278 smbcli_unlink(cli1->tree, fname);
280 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
285 io.generic.level = RAW_OPEN_NTCREATEX;
286 io.ntcreatex.in.root_fid = 0;
287 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
288 io.ntcreatex.in.alloc_size = 0;
289 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
290 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
291 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
292 io.ntcreatex.in.create_options = 0;
293 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
294 io.ntcreatex.in.security_flags = 0;
295 io.ntcreatex.in.fname = fname;
297 torture_comment(tctx, "EXCLUSIVE2: open a file with an exclusive oplock (share mode: all)\n");
298 ZERO_STRUCT(break_info);
299 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
300 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
301 NTCREATEX_SHARE_ACCESS_WRITE|
302 NTCREATEX_SHARE_ACCESS_DELETE;
304 status = smb_raw_open(cli1->tree, tctx, &io);
305 CHECK_STATUS(tctx, status, NT_STATUS_OK);
306 fnum = io.ntcreatex.out.file.fnum;
307 CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
309 torture_comment(tctx, "a 2nd open should cause a break to level 2\n");
310 status = smb_raw_open(cli2->tree, tctx, &io);
311 CHECK_STATUS(tctx, status, NT_STATUS_OK);
312 fnum2 = io.ntcreatex.out.file.fnum;
313 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
314 CHECK_VAL(break_info.count, 1);
315 CHECK_VAL(break_info.fnum, fnum);
316 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
317 CHECK_VAL(break_info.failures, 0);
318 ZERO_STRUCT(break_info);
320 /* now we have 2 level II oplocks... */
321 torture_comment(tctx, "try to unlink it - should not cause a break, but a sharing violation\n");
322 unl.unlink.in.pattern = fname;
323 unl.unlink.in.attrib = 0;
324 status = smb_raw_unlink(cli2->tree, &unl);
325 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
326 CHECK_VAL(break_info.count, 0);
327 CHECK_VAL(break_info.failures, 0);
329 torture_comment(tctx, "close 1st handle\n");
330 smbcli_close(cli1->tree, fnum);
332 torture_comment(tctx, "try to unlink it - should not cause a break, but a sharing violation\n");
333 unl.unlink.in.pattern = fname;
334 unl.unlink.in.attrib = 0;
335 status = smb_raw_unlink(cli2->tree, &unl);
336 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
337 CHECK_VAL(break_info.count, 0);
338 CHECK_VAL(break_info.failures, 0);
340 torture_comment(tctx, "close 1st handle\n");
341 smbcli_close(cli2->tree, fnum2);
343 torture_comment(tctx, "unlink it\n");
344 unl.unlink.in.pattern = fname;
345 unl.unlink.in.attrib = 0;
346 status = smb_raw_unlink(cli2->tree, &unl);
347 CHECK_STATUS(tctx, status, NT_STATUS_OK);
348 CHECK_VAL(break_info.count, 0);
349 CHECK_VAL(break_info.failures, 0);
352 smb_raw_exit(cli1->session);
353 smb_raw_exit(cli2->session);
354 smbcli_deltree(cli1->tree, BASEDIR);
358 static bool test_raw_oplock_exclusive3(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
360 const char *fname = BASEDIR "\\test_exclusive3.dat";
364 union smb_setfileinfo sfi;
367 if (!torture_setup_dir(cli1, BASEDIR)) {
372 smbcli_unlink(cli1->tree, fname);
374 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
379 io.generic.level = RAW_OPEN_NTCREATEX;
380 io.ntcreatex.in.root_fid = 0;
381 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
382 io.ntcreatex.in.alloc_size = 0;
383 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
384 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
385 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
386 io.ntcreatex.in.create_options = 0;
387 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
388 io.ntcreatex.in.security_flags = 0;
389 io.ntcreatex.in.fname = fname;
391 torture_comment(tctx, "EXCLUSIVE3: open a file with an exclusive oplock (share mode: none)\n");
393 ZERO_STRUCT(break_info);
394 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
396 status = smb_raw_open(cli1->tree, tctx, &io);
397 CHECK_STATUS(tctx, status, NT_STATUS_OK);
398 fnum = io.ntcreatex.out.file.fnum;
399 CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
401 torture_comment(tctx, "setpathinfo EOF should trigger a break to none\n");
403 sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
404 sfi.generic.in.file.path = fname;
405 sfi.end_of_file_info.in.size = 100;
407 status = smb_raw_setpathinfo(cli2->tree, &sfi);
409 CHECK_STATUS(tctx, status, NT_STATUS_OK);
410 CHECK_VAL(break_info.count, 1);
411 CHECK_VAL(break_info.failures, 0);
412 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_NONE);
414 smbcli_close(cli1->tree, fnum);
417 smb_raw_exit(cli1->session);
418 smb_raw_exit(cli2->session);
419 smbcli_deltree(cli1->tree, BASEDIR);
423 static bool test_raw_oplock_exclusive4(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
425 const char *fname = BASEDIR "\\test_exclusive4.dat";
429 uint16_t fnum=0, fnum2=0;
431 if (!torture_setup_dir(cli1, BASEDIR)) {
436 smbcli_unlink(cli1->tree, fname);
438 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
443 io.generic.level = RAW_OPEN_NTCREATEX;
444 io.ntcreatex.in.root_fid = 0;
445 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
446 io.ntcreatex.in.alloc_size = 0;
447 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
448 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
449 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
450 io.ntcreatex.in.create_options = 0;
451 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
452 io.ntcreatex.in.security_flags = 0;
453 io.ntcreatex.in.fname = fname;
455 torture_comment(tctx, "EXCLUSIVE4: open with exclusive oplock\n");
456 ZERO_STRUCT(break_info);
457 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
459 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
460 status = smb_raw_open(cli1->tree, tctx, &io);
461 CHECK_STATUS(tctx, status, NT_STATUS_OK);
462 fnum = io.ntcreatex.out.file.fnum;
463 CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
465 ZERO_STRUCT(break_info);
466 torture_comment(tctx, "second open with attributes only shouldn't cause oplock break\n");
468 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
469 io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
470 status = smb_raw_open(cli2->tree, tctx, &io);
471 CHECK_STATUS(tctx, status, NT_STATUS_OK);
472 fnum2 = io.ntcreatex.out.file.fnum;
473 CHECK_VAL(io.ntcreatex.out.oplock_level, NO_OPLOCK_RETURN);
474 CHECK_VAL(break_info.count, 0);
475 CHECK_VAL(break_info.failures, 0);
477 smbcli_close(cli1->tree, fnum);
478 smbcli_close(cli2->tree, fnum2);
481 smb_raw_exit(cli1->session);
482 smb_raw_exit(cli2->session);
483 smbcli_deltree(cli1->tree, BASEDIR);
487 static bool test_raw_oplock_exclusive5(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
489 const char *fname = BASEDIR "\\test_exclusive5.dat";
493 uint16_t fnum=0, fnum2=0;
495 if (!torture_setup_dir(cli1, BASEDIR)) {
500 smbcli_unlink(cli1->tree, fname);
502 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
503 smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli1->tree);
508 io.generic.level = RAW_OPEN_NTCREATEX;
509 io.ntcreatex.in.root_fid = 0;
510 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
511 io.ntcreatex.in.alloc_size = 0;
512 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
513 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
514 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
515 io.ntcreatex.in.create_options = 0;
516 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
517 io.ntcreatex.in.security_flags = 0;
518 io.ntcreatex.in.fname = fname;
520 torture_comment(tctx, "EXCLUSIVE5: open with exclusive oplock\n");
521 ZERO_STRUCT(break_info);
522 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
525 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
526 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
527 NTCREATEX_SHARE_ACCESS_WRITE|
528 NTCREATEX_SHARE_ACCESS_DELETE;
529 status = smb_raw_open(cli1->tree, tctx, &io);
530 CHECK_STATUS(tctx, status, NT_STATUS_OK);
531 fnum = io.ntcreatex.out.file.fnum;
532 CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
534 ZERO_STRUCT(break_info);
536 torture_comment(tctx, "second open with attributes only and NTCREATEX_DISP_OVERWRITE_IF dispostion causes oplock break\n");
538 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
539 io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
540 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE_IF;
541 status = smb_raw_open(cli2->tree, tctx, &io);
542 CHECK_STATUS(tctx, status, NT_STATUS_OK);
543 fnum2 = io.ntcreatex.out.file.fnum;
544 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
545 CHECK_VAL(break_info.count, 1);
546 CHECK_VAL(break_info.failures, 0);
548 smbcli_close(cli1->tree, fnum);
549 smbcli_close(cli2->tree, fnum2);
552 smb_raw_exit(cli1->session);
553 smb_raw_exit(cli2->session);
554 smbcli_deltree(cli1->tree, BASEDIR);
558 static bool test_raw_oplock_exclusive6(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
560 const char *fname1 = BASEDIR "\\test_exclusive6_1.dat";
561 const char *fname2 = BASEDIR "\\test_exclusive6_2.dat";
568 if (!torture_setup_dir(cli1, BASEDIR)) {
573 smbcli_unlink(cli1->tree, fname1);
574 smbcli_unlink(cli1->tree, fname2);
576 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
581 io.generic.level = RAW_OPEN_NTCREATEX;
582 io.ntcreatex.in.root_fid = 0;
583 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
584 io.ntcreatex.in.alloc_size = 0;
585 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
586 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
587 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
588 io.ntcreatex.in.create_options = 0;
589 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
590 io.ntcreatex.in.security_flags = 0;
591 io.ntcreatex.in.fname = fname1;
593 torture_comment(tctx, "EXCLUSIVE6: open a file with an exclusive oplock (share mode: none)\n");
594 ZERO_STRUCT(break_info);
595 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
597 status = smb_raw_open(cli1->tree, tctx, &io);
598 CHECK_STATUS(tctx, status, NT_STATUS_OK);
599 fnum = io.ntcreatex.out.file.fnum;
600 CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
602 torture_comment(tctx, "rename should not generate a break but get a sharing violation\n");
604 rn.generic.level = RAW_RENAME_RENAME;
605 rn.rename.in.pattern1 = fname1;
606 rn.rename.in.pattern2 = fname2;
607 rn.rename.in.attrib = 0;
609 printf("trying rename while first file open\n");
610 status = smb_raw_rename(cli2->tree, &rn);
612 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
613 CHECK_VAL(break_info.count, 0);
614 CHECK_VAL(break_info.failures, 0);
616 smbcli_close(cli1->tree, fnum);
619 smb_raw_exit(cli1->session);
620 smb_raw_exit(cli2->session);
621 smbcli_deltree(cli1->tree, BASEDIR);
625 static bool test_raw_oplock_batch1(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
627 const char *fname = BASEDIR "\\test_batch1.dat";
631 union smb_unlink unl;
635 if (!torture_setup_dir(cli1, BASEDIR)) {
640 smbcli_unlink(cli1->tree, fname);
642 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
647 io.generic.level = RAW_OPEN_NTCREATEX;
648 io.ntcreatex.in.root_fid = 0;
649 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
650 io.ntcreatex.in.alloc_size = 0;
651 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
652 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
653 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
654 io.ntcreatex.in.create_options = 0;
655 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
656 io.ntcreatex.in.security_flags = 0;
657 io.ntcreatex.in.fname = fname;
660 with a batch oplock we get a break
662 torture_comment(tctx, "BATCH1: open with batch oplock\n");
663 ZERO_STRUCT(break_info);
664 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
665 NTCREATEX_FLAGS_REQUEST_OPLOCK |
666 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
667 status = smb_raw_open(cli1->tree, tctx, &io);
668 CHECK_STATUS(tctx, status, NT_STATUS_OK);
669 fnum = io.ntcreatex.out.file.fnum;
670 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
672 torture_comment(tctx, "unlink should generate a break\n");
673 unl.unlink.in.pattern = fname;
674 unl.unlink.in.attrib = 0;
675 status = smb_raw_unlink(cli2->tree, &unl);
676 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
678 CHECK_VAL(break_info.count, 1);
679 CHECK_VAL(break_info.fnum, fnum);
680 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
681 CHECK_VAL(break_info.failures, 0);
683 torture_comment(tctx, "2nd unlink should not generate a break\n");
684 ZERO_STRUCT(break_info);
685 status = smb_raw_unlink(cli2->tree, &unl);
686 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
688 CHECK_VAL(break_info.count, 0);
690 torture_comment(tctx, "writing should generate a self break to none\n");
691 smbcli_write(cli1->tree, fnum, 0, &c, 0, 1);
693 smbcli_write(cli1->tree, fnum, 0, &c, 1, 1);
695 CHECK_VAL(break_info.count, 1);
696 CHECK_VAL(break_info.fnum, fnum);
697 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_NONE);
698 CHECK_VAL(break_info.failures, 0);
700 smbcli_close(cli1->tree, fnum);
703 smb_raw_exit(cli1->session);
704 smb_raw_exit(cli2->session);
705 smbcli_deltree(cli1->tree, BASEDIR);
709 static bool test_raw_oplock_batch2(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
711 const char *fname = BASEDIR "\\test_batch2.dat";
715 union smb_unlink unl;
719 if (!torture_setup_dir(cli1, BASEDIR)) {
724 smbcli_unlink(cli1->tree, fname);
726 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
731 io.generic.level = RAW_OPEN_NTCREATEX;
732 io.ntcreatex.in.root_fid = 0;
733 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
734 io.ntcreatex.in.alloc_size = 0;
735 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
736 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
737 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
738 io.ntcreatex.in.create_options = 0;
739 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
740 io.ntcreatex.in.security_flags = 0;
741 io.ntcreatex.in.fname = fname;
743 torture_comment(tctx, "BATCH2: open with batch oplock\n");
744 ZERO_STRUCT(break_info);
745 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
746 NTCREATEX_FLAGS_REQUEST_OPLOCK |
747 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
748 status = smb_raw_open(cli1->tree, tctx, &io);
749 CHECK_STATUS(tctx, status, NT_STATUS_OK);
750 fnum = io.ntcreatex.out.file.fnum;
751 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
753 torture_comment(tctx, "unlink should generate a break, which we ack as break to none\n");
754 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_none, cli1->tree);
755 unl.unlink.in.pattern = fname;
756 unl.unlink.in.attrib = 0;
757 status = smb_raw_unlink(cli2->tree, &unl);
758 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
760 CHECK_VAL(break_info.count, 1);
761 CHECK_VAL(break_info.fnum, fnum);
762 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
763 CHECK_VAL(break_info.failures, 0);
765 torture_comment(tctx, "2nd unlink should not generate a break\n");
766 ZERO_STRUCT(break_info);
767 status = smb_raw_unlink(cli2->tree, &unl);
768 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
770 CHECK_VAL(break_info.count, 0);
772 torture_comment(tctx, "writing should not generate a break\n");
773 smbcli_write(cli1->tree, fnum, 0, &c, 0, 1);
775 smbcli_write(cli1->tree, fnum, 0, &c, 1, 1);
777 CHECK_VAL(break_info.count, 0);
779 smbcli_close(cli1->tree, fnum);
782 smb_raw_exit(cli1->session);
783 smb_raw_exit(cli2->session);
784 smbcli_deltree(cli1->tree, BASEDIR);
788 static bool test_raw_oplock_batch3(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
790 const char *fname = BASEDIR "\\test_batch3.dat";
794 union smb_unlink unl;
797 if (!torture_setup_dir(cli1, BASEDIR)) {
802 smbcli_unlink(cli1->tree, fname);
804 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
809 io.generic.level = RAW_OPEN_NTCREATEX;
810 io.ntcreatex.in.root_fid = 0;
811 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
812 io.ntcreatex.in.alloc_size = 0;
813 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
814 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
815 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
816 io.ntcreatex.in.create_options = 0;
817 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
818 io.ntcreatex.in.security_flags = 0;
819 io.ntcreatex.in.fname = fname;
821 torture_comment(tctx, "BATCH3: if we close on break then the unlink can succeed\n");
822 ZERO_STRUCT(break_info);
823 smbcli_oplock_handler(cli1->transport, oplock_handler_close, cli1->tree);
824 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
825 NTCREATEX_FLAGS_REQUEST_OPLOCK |
826 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
827 status = smb_raw_open(cli1->tree, tctx, &io);
828 CHECK_STATUS(tctx, status, NT_STATUS_OK);
829 fnum = io.ntcreatex.out.file.fnum;
830 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
832 unl.unlink.in.pattern = fname;
833 unl.unlink.in.attrib = 0;
834 ZERO_STRUCT(break_info);
835 status = smb_raw_unlink(cli2->tree, &unl);
836 CHECK_STATUS(tctx, status, NT_STATUS_OK);
838 CHECK_VAL(break_info.count, 1);
839 CHECK_VAL(break_info.fnum, fnum);
840 CHECK_VAL(break_info.level, 1);
841 CHECK_VAL(break_info.failures, 0);
843 smbcli_close(cli1->tree, fnum);
846 smb_raw_exit(cli1->session);
847 smb_raw_exit(cli2->session);
848 smbcli_deltree(cli1->tree, BASEDIR);
852 static bool test_raw_oplock_batch4(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
854 const char *fname = BASEDIR "\\test_batch4.dat";
861 if (!torture_setup_dir(cli1, BASEDIR)) {
866 smbcli_unlink(cli1->tree, fname);
868 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
873 io.generic.level = RAW_OPEN_NTCREATEX;
874 io.ntcreatex.in.root_fid = 0;
875 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
876 io.ntcreatex.in.alloc_size = 0;
877 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
878 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
879 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
880 io.ntcreatex.in.create_options = 0;
881 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
882 io.ntcreatex.in.security_flags = 0;
883 io.ntcreatex.in.fname = fname;
885 torture_comment(tctx, "BATCH4: a self read should not cause a break\n");
886 ZERO_STRUCT(break_info);
887 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
889 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
890 NTCREATEX_FLAGS_REQUEST_OPLOCK |
891 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
892 status = smb_raw_open(cli1->tree, tctx, &io);
893 CHECK_STATUS(tctx, status, NT_STATUS_OK);
894 fnum = io.ntcreatex.out.file.fnum;
895 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
897 rd.read.level = RAW_READ_READ;
898 rd.read.in.file.fnum = fnum;
899 rd.read.in.count = 1;
900 rd.read.in.offset = 0;
901 rd.read.in.remaining = 0;
902 status = smb_raw_read(cli1->tree, &rd);
903 CHECK_STATUS(tctx, status, NT_STATUS_OK);
904 CHECK_VAL(break_info.count, 0);
905 CHECK_VAL(break_info.failures, 0);
907 smbcli_close(cli1->tree, fnum);
910 smb_raw_exit(cli1->session);
911 smb_raw_exit(cli2->session);
912 smbcli_deltree(cli1->tree, BASEDIR);
916 static bool test_raw_oplock_batch5(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
918 const char *fname = BASEDIR "\\test_batch5.dat";
924 if (!torture_setup_dir(cli1, BASEDIR)) {
929 smbcli_unlink(cli1->tree, fname);
931 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
936 io.generic.level = RAW_OPEN_NTCREATEX;
937 io.ntcreatex.in.root_fid = 0;
938 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
939 io.ntcreatex.in.alloc_size = 0;
940 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
941 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
942 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
943 io.ntcreatex.in.create_options = 0;
944 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
945 io.ntcreatex.in.security_flags = 0;
946 io.ntcreatex.in.fname = fname;
948 torture_comment(tctx, "BATCH5: a 2nd open should give a break\n");
949 ZERO_STRUCT(break_info);
950 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
952 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
953 NTCREATEX_FLAGS_REQUEST_OPLOCK |
954 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
955 status = smb_raw_open(cli1->tree, tctx, &io);
956 CHECK_STATUS(tctx, status, NT_STATUS_OK);
957 fnum = io.ntcreatex.out.file.fnum;
958 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
960 ZERO_STRUCT(break_info);
962 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
963 status = smb_raw_open(cli2->tree, tctx, &io);
964 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
966 CHECK_VAL(break_info.count, 1);
967 CHECK_VAL(break_info.fnum, fnum);
968 CHECK_VAL(break_info.level, 1);
969 CHECK_VAL(break_info.failures, 0);
971 smbcli_close(cli1->tree, fnum);
974 smb_raw_exit(cli1->session);
975 smb_raw_exit(cli2->session);
976 smbcli_deltree(cli1->tree, BASEDIR);
980 static bool test_raw_oplock_batch6(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
982 const char *fname = BASEDIR "\\test_batch6.dat";
986 uint16_t fnum=0, fnum2=0;
989 if (!torture_setup_dir(cli1, BASEDIR)) {
994 smbcli_unlink(cli1->tree, fname);
996 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1001 io.generic.level = RAW_OPEN_NTCREATEX;
1002 io.ntcreatex.in.root_fid = 0;
1003 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1004 io.ntcreatex.in.alloc_size = 0;
1005 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1006 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1007 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1008 io.ntcreatex.in.create_options = 0;
1009 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1010 io.ntcreatex.in.security_flags = 0;
1011 io.ntcreatex.in.fname = fname;
1013 torture_comment(tctx, "BATCH6: a 2nd open should give a break to level II if the first open allowed shared read\n");
1014 ZERO_STRUCT(break_info);
1015 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1016 smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli2->tree);
1018 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_READ | SEC_RIGHTS_FILE_WRITE;
1019 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
1020 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1021 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1022 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1023 status = smb_raw_open(cli1->tree, tctx, &io);
1024 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1025 fnum = io.ntcreatex.out.file.fnum;
1026 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1028 ZERO_STRUCT(break_info);
1030 status = smb_raw_open(cli2->tree, tctx, &io);
1031 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1032 fnum2 = io.ntcreatex.out.file.fnum;
1033 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1035 CHECK_VAL(break_info.count, 1);
1036 CHECK_VAL(break_info.fnum, fnum);
1037 CHECK_VAL(break_info.level, 1);
1038 CHECK_VAL(break_info.failures, 0);
1039 ZERO_STRUCT(break_info);
1041 torture_comment(tctx, "write should trigger a break to none on both\n");
1042 smbcli_write(cli1->tree, fnum, 0, &c, 0, 1);
1044 smbcli_write(cli1->tree, fnum, 0, &c, 1, 1);
1046 CHECK_VAL(break_info.count, 2);
1047 CHECK_VAL(break_info.level, 0);
1048 CHECK_VAL(break_info.failures, 0);
1050 smbcli_close(cli1->tree, fnum);
1051 smbcli_close(cli2->tree, fnum2);
1055 smb_raw_exit(cli1->session);
1056 smb_raw_exit(cli2->session);
1057 smbcli_deltree(cli1->tree, BASEDIR);
1061 static bool test_raw_oplock_batch7(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1063 const char *fname = BASEDIR "\\test_batch7.dat";
1067 uint16_t fnum=0, fnum2=0;
1069 if (!torture_setup_dir(cli1, BASEDIR)) {
1074 smbcli_unlink(cli1->tree, fname);
1076 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1079 base ntcreatex parms
1081 io.generic.level = RAW_OPEN_NTCREATEX;
1082 io.ntcreatex.in.root_fid = 0;
1083 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1084 io.ntcreatex.in.alloc_size = 0;
1085 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1086 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1087 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1088 io.ntcreatex.in.create_options = 0;
1089 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1090 io.ntcreatex.in.security_flags = 0;
1091 io.ntcreatex.in.fname = fname;
1093 torture_comment(tctx, "BATCH7: a 2nd open should get an oplock when we close instead of ack\n");
1094 ZERO_STRUCT(break_info);
1095 smbcli_oplock_handler(cli1->transport, oplock_handler_close, cli1->tree);
1097 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1098 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1099 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1100 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1101 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1102 status = smb_raw_open(cli1->tree, tctx, &io);
1103 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1104 fnum2 = io.ntcreatex.out.file.fnum;
1105 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1107 ZERO_STRUCT(break_info);
1109 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1110 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1111 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1112 status = smb_raw_open(cli2->tree, tctx, &io);
1113 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1114 fnum = io.ntcreatex.out.file.fnum;
1115 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1117 CHECK_VAL(break_info.count, 1);
1118 CHECK_VAL(break_info.fnum, fnum2);
1119 CHECK_VAL(break_info.level, 1);
1120 CHECK_VAL(break_info.failures, 0);
1122 smbcli_close(cli2->tree, fnum);
1125 smb_raw_exit(cli1->session);
1126 smb_raw_exit(cli2->session);
1127 smbcli_deltree(cli1->tree, BASEDIR);
1131 static bool test_raw_oplock_batch8(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1133 const char *fname = BASEDIR "\\test_batch8.dat";
1137 uint16_t fnum=0, fnum2=0;
1139 if (!torture_setup_dir(cli1, BASEDIR)) {
1144 smbcli_unlink(cli1->tree, fname);
1146 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1149 base ntcreatex parms
1151 io.generic.level = RAW_OPEN_NTCREATEX;
1152 io.ntcreatex.in.root_fid = 0;
1153 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1154 io.ntcreatex.in.alloc_size = 0;
1155 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1156 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1157 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1158 io.ntcreatex.in.create_options = 0;
1159 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1160 io.ntcreatex.in.security_flags = 0;
1161 io.ntcreatex.in.fname = fname;
1163 torture_comment(tctx, "BATCH8: open with batch oplock\n");
1164 ZERO_STRUCT(break_info);
1165 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1167 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1168 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1169 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1170 status = smb_raw_open(cli1->tree, tctx, &io);
1171 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1172 fnum = io.ntcreatex.out.file.fnum;
1173 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1175 ZERO_STRUCT(break_info);
1176 torture_comment(tctx, "second open with attributes only shouldn't cause oplock break\n");
1178 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1179 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1180 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1181 io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
1182 status = smb_raw_open(cli2->tree, tctx, &io);
1183 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1184 fnum2 = io.ntcreatex.out.file.fnum;
1185 CHECK_VAL(io.ntcreatex.out.oplock_level, NO_OPLOCK_RETURN);
1186 CHECK_VAL(break_info.count, 0);
1187 CHECK_VAL(break_info.failures, 0);
1189 smbcli_close(cli1->tree, fnum);
1190 smbcli_close(cli2->tree, fnum2);
1193 smb_raw_exit(cli1->session);
1194 smb_raw_exit(cli2->session);
1195 smbcli_deltree(cli1->tree, BASEDIR);
1199 static bool test_raw_oplock_batch9(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1201 const char *fname = BASEDIR "\\test_batch9.dat";
1205 uint16_t fnum=0, fnum2=0;
1208 if (!torture_setup_dir(cli1, BASEDIR)) {
1213 smbcli_unlink(cli1->tree, fname);
1215 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1218 base ntcreatex parms
1220 io.generic.level = RAW_OPEN_NTCREATEX;
1221 io.ntcreatex.in.root_fid = 0;
1222 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1223 io.ntcreatex.in.alloc_size = 0;
1224 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1225 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1226 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1227 io.ntcreatex.in.create_options = 0;
1228 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1229 io.ntcreatex.in.security_flags = 0;
1230 io.ntcreatex.in.fname = fname;
1232 torture_comment(tctx, "BATCH9: open with attributes only can create file\n");
1234 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1235 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1236 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1237 io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
1238 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1239 status = smb_raw_open(cli1->tree, tctx, &io);
1240 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1241 fnum = io.ntcreatex.out.file.fnum;
1242 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1244 torture_comment(tctx, "Subsequent normal open should break oplock on attribute only open to level II\n");
1246 ZERO_STRUCT(break_info);
1247 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1249 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1250 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1251 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1252 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1253 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1254 status = smb_raw_open(cli2->tree, tctx, &io);
1255 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1256 fnum2 = io.ntcreatex.out.file.fnum;
1257 CHECK_VAL(break_info.count, 1);
1258 CHECK_VAL(break_info.fnum, fnum);
1259 CHECK_VAL(break_info.failures, 0);
1260 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
1261 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1262 smbcli_close(cli2->tree, fnum2);
1264 torture_comment(tctx, "third oplocked open should grant level2 without break\n");
1265 ZERO_STRUCT(break_info);
1266 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1267 smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli2->tree);
1268 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1269 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1270 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1271 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1272 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1273 status = smb_raw_open(cli2->tree, tctx, &io);
1274 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1275 fnum2 = io.ntcreatex.out.file.fnum;
1276 CHECK_VAL(break_info.count, 0);
1277 CHECK_VAL(break_info.failures, 0);
1278 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1280 ZERO_STRUCT(break_info);
1282 torture_comment(tctx, "write should trigger a break to none on both\n");
1283 smbcli_write(cli2->tree, fnum2, 0, &c, 0, 1);
1285 /* Now the oplock break request comes in. But right now we can't
1286 * answer it. Do another write */
1289 smbcli_write(cli2->tree, fnum2, 0, &c, 1, 1);
1291 CHECK_VAL(break_info.count, 2);
1292 CHECK_VAL(break_info.level, 0);
1293 CHECK_VAL(break_info.failures, 0);
1295 smbcli_close(cli1->tree, fnum);
1296 smbcli_close(cli2->tree, fnum2);
1299 smb_raw_exit(cli1->session);
1300 smb_raw_exit(cli2->session);
1301 smbcli_deltree(cli1->tree, BASEDIR);
1305 static bool test_raw_oplock_batch10(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1307 const char *fname = BASEDIR "\\test_batch10.dat";
1311 uint16_t fnum=0, fnum2=0;
1313 if (!torture_setup_dir(cli1, BASEDIR)) {
1318 smbcli_unlink(cli1->tree, fname);
1320 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1323 base ntcreatex parms
1325 io.generic.level = RAW_OPEN_NTCREATEX;
1326 io.ntcreatex.in.root_fid = 0;
1327 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1328 io.ntcreatex.in.alloc_size = 0;
1329 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1330 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1331 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1332 io.ntcreatex.in.create_options = 0;
1333 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1334 io.ntcreatex.in.security_flags = 0;
1335 io.ntcreatex.in.fname = fname;
1337 torture_comment(tctx, "BATCH10: Open with oplock after a non-oplock open should grant level2\n");
1338 ZERO_STRUCT(break_info);
1339 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
1340 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1341 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1342 NTCREATEX_SHARE_ACCESS_WRITE|
1343 NTCREATEX_SHARE_ACCESS_DELETE;
1344 status = smb_raw_open(cli1->tree, tctx, &io);
1345 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1346 fnum = io.ntcreatex.out.file.fnum;
1347 CHECK_VAL(break_info.count, 0);
1348 CHECK_VAL(break_info.failures, 0);
1349 CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
1351 smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli2->tree);
1353 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1354 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1355 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1356 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1357 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1358 NTCREATEX_SHARE_ACCESS_WRITE|
1359 NTCREATEX_SHARE_ACCESS_DELETE;
1360 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1361 status = smb_raw_open(cli2->tree, tctx, &io);
1362 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1363 fnum2 = io.ntcreatex.out.file.fnum;
1364 CHECK_VAL(break_info.count, 0);
1365 CHECK_VAL(break_info.failures, 0);
1366 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1368 torture_comment(tctx, "write should trigger a break to none\n");
1371 wr.write.level = RAW_WRITE_WRITE;
1372 wr.write.in.file.fnum = fnum;
1373 wr.write.in.count = 1;
1374 wr.write.in.offset = 0;
1375 wr.write.in.remaining = 0;
1376 wr.write.in.data = (const uint8_t *)"x";
1377 status = smb_raw_write(cli1->tree, &wr);
1378 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1381 /* Now the oplock break request comes in. But right now we can't
1382 * answer it. Do another write */
1388 wr.write.level = RAW_WRITE_WRITE;
1389 wr.write.in.file.fnum = fnum;
1390 wr.write.in.count = 1;
1391 wr.write.in.offset = 0;
1392 wr.write.in.remaining = 0;
1393 wr.write.in.data = (const uint8_t *)"x";
1394 status = smb_raw_write(cli1->tree, &wr);
1395 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1398 CHECK_VAL(break_info.count, 1);
1399 CHECK_VAL(break_info.fnum, fnum2);
1400 CHECK_VAL(break_info.level, 0);
1401 CHECK_VAL(break_info.failures, 0);
1403 smbcli_close(cli1->tree, fnum);
1404 smbcli_close(cli2->tree, fnum2);
1407 smb_raw_exit(cli1->session);
1408 smb_raw_exit(cli2->session);
1409 smbcli_deltree(cli1->tree, BASEDIR);
1413 static bool test_raw_oplock_batch11(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1415 const char *fname = BASEDIR "\\test_batch11.dat";
1419 union smb_setfileinfo sfi;
1422 if (!torture_setup_dir(cli1, BASEDIR)) {
1427 smbcli_unlink(cli1->tree, fname);
1429 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1432 base ntcreatex parms
1434 io.generic.level = RAW_OPEN_NTCREATEX;
1435 io.ntcreatex.in.root_fid = 0;
1436 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1437 io.ntcreatex.in.alloc_size = 0;
1438 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1439 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1440 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1441 io.ntcreatex.in.create_options = 0;
1442 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1443 io.ntcreatex.in.security_flags = 0;
1444 io.ntcreatex.in.fname = fname;
1446 /* Test if a set-eof on pathname breaks an exclusive oplock. */
1447 torture_comment(tctx, "BATCH11: Test if setpathinfo set EOF breaks oplocks.\n");
1449 ZERO_STRUCT(break_info);
1450 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1452 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1453 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1454 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1455 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1456 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1457 NTCREATEX_SHARE_ACCESS_WRITE|
1458 NTCREATEX_SHARE_ACCESS_DELETE;
1459 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1460 status = smb_raw_open(cli1->tree, tctx, &io);
1461 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1462 fnum = io.ntcreatex.out.file.fnum;
1463 CHECK_VAL(break_info.count, 0);
1464 CHECK_VAL(break_info.failures, 0);
1465 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1468 sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
1469 sfi.generic.in.file.path = fname;
1470 sfi.end_of_file_info.in.size = 100;
1472 status = smb_raw_setpathinfo(cli2->tree, &sfi);
1474 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1475 CHECK_VAL(break_info.count, 1);
1476 CHECK_VAL(break_info.failures, 0);
1477 CHECK_VAL(break_info.level, 0);
1479 smbcli_close(cli1->tree, fnum);
1482 smb_raw_exit(cli1->session);
1483 smb_raw_exit(cli2->session);
1484 smbcli_deltree(cli1->tree, BASEDIR);
1488 static bool test_raw_oplock_batch12(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1490 const char *fname = BASEDIR "\\test_batch12.dat";
1494 union smb_setfileinfo sfi;
1497 if (!torture_setup_dir(cli1, BASEDIR)) {
1502 smbcli_unlink(cli1->tree, fname);
1504 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1507 base ntcreatex parms
1509 io.generic.level = RAW_OPEN_NTCREATEX;
1510 io.ntcreatex.in.root_fid = 0;
1511 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1512 io.ntcreatex.in.alloc_size = 0;
1513 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1514 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1515 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1516 io.ntcreatex.in.create_options = 0;
1517 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1518 io.ntcreatex.in.security_flags = 0;
1519 io.ntcreatex.in.fname = fname;
1521 /* Test if a set-allocation size on pathname breaks an exclusive oplock. */
1522 torture_comment(tctx, "BATCH12: Test if setpathinfo allocation size breaks oplocks.\n");
1524 ZERO_STRUCT(break_info);
1525 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1527 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1528 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1529 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1530 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1531 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1532 NTCREATEX_SHARE_ACCESS_WRITE|
1533 NTCREATEX_SHARE_ACCESS_DELETE;
1534 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1535 status = smb_raw_open(cli1->tree, tctx, &io);
1536 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1537 fnum = io.ntcreatex.out.file.fnum;
1538 CHECK_VAL(break_info.count, 0);
1539 CHECK_VAL(break_info.failures, 0);
1540 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1543 sfi.generic.level = SMB_SFILEINFO_ALLOCATION_INFORMATION;
1544 sfi.generic.in.file.path = fname;
1545 sfi.allocation_info.in.alloc_size = 65536 * 8;
1547 status = smb_raw_setpathinfo(cli2->tree, &sfi);
1549 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1550 CHECK_VAL(break_info.count, 1);
1551 CHECK_VAL(break_info.failures, 0);
1552 CHECK_VAL(break_info.level, 0);
1554 smbcli_close(cli1->tree, fnum);
1557 smb_raw_exit(cli1->session);
1558 smb_raw_exit(cli2->session);
1559 smbcli_deltree(cli1->tree, BASEDIR);
1563 static bool test_raw_oplock_batch13(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1565 const char *fname = BASEDIR "\\test_batch13.dat";
1569 uint16_t fnum=0, fnum2=0;
1571 if (!torture_setup_dir(cli1, BASEDIR)) {
1576 smbcli_unlink(cli1->tree, fname);
1578 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1579 smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli1->tree);
1582 base ntcreatex parms
1584 io.generic.level = RAW_OPEN_NTCREATEX;
1585 io.ntcreatex.in.root_fid = 0;
1586 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1587 io.ntcreatex.in.alloc_size = 0;
1588 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1589 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1590 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1591 io.ntcreatex.in.create_options = 0;
1592 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1593 io.ntcreatex.in.security_flags = 0;
1594 io.ntcreatex.in.fname = fname;
1596 torture_comment(tctx, "BATCH13: open with batch oplock\n");
1597 ZERO_STRUCT(break_info);
1598 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1601 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1602 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1603 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1604 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1605 NTCREATEX_SHARE_ACCESS_WRITE|
1606 NTCREATEX_SHARE_ACCESS_DELETE;
1607 status = smb_raw_open(cli1->tree, tctx, &io);
1608 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1609 fnum = io.ntcreatex.out.file.fnum;
1610 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1612 ZERO_STRUCT(break_info);
1614 torture_comment(tctx, "second open with attributes only and NTCREATEX_DISP_OVERWRITE dispostion causes oplock break\n");
1616 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1617 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1618 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1619 io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
1620 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1621 NTCREATEX_SHARE_ACCESS_WRITE|
1622 NTCREATEX_SHARE_ACCESS_DELETE;
1623 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE;
1624 status = smb_raw_open(cli2->tree, tctx, &io);
1625 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1626 fnum2 = io.ntcreatex.out.file.fnum;
1627 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1628 CHECK_VAL(break_info.count, 1);
1629 CHECK_VAL(break_info.failures, 0);
1631 smbcli_close(cli1->tree, fnum);
1632 smbcli_close(cli2->tree, fnum2);
1635 smb_raw_exit(cli1->session);
1636 smb_raw_exit(cli2->session);
1637 smbcli_deltree(cli1->tree, BASEDIR);
1641 static bool test_raw_oplock_batch14(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1643 const char *fname = BASEDIR "\\test_batch14.dat";
1647 uint16_t fnum=0, fnum2=0;
1649 if (!torture_setup_dir(cli1, BASEDIR)) {
1654 smbcli_unlink(cli1->tree, fname);
1656 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1659 base ntcreatex parms
1661 io.generic.level = RAW_OPEN_NTCREATEX;
1662 io.ntcreatex.in.root_fid = 0;
1663 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1664 io.ntcreatex.in.alloc_size = 0;
1665 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1666 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1667 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1668 io.ntcreatex.in.create_options = 0;
1669 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1670 io.ntcreatex.in.security_flags = 0;
1671 io.ntcreatex.in.fname = fname;
1673 torture_comment(tctx, "BATCH14: open with batch oplock\n");
1674 ZERO_STRUCT(break_info);
1675 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1677 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1678 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1679 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1680 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1681 NTCREATEX_SHARE_ACCESS_WRITE|
1682 NTCREATEX_SHARE_ACCESS_DELETE;
1683 status = smb_raw_open(cli1->tree, tctx, &io);
1684 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1685 fnum = io.ntcreatex.out.file.fnum;
1686 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1688 ZERO_STRUCT(break_info);
1690 torture_comment(tctx, "second open with attributes only and NTCREATEX_DISP_SUPERSEDE dispostion causes oplock break\n");
1692 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1693 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1694 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1695 io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
1696 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1697 NTCREATEX_SHARE_ACCESS_WRITE|
1698 NTCREATEX_SHARE_ACCESS_DELETE;
1699 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE;
1700 status = smb_raw_open(cli2->tree, tctx, &io);
1701 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1702 fnum2 = io.ntcreatex.out.file.fnum;
1703 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1704 CHECK_VAL(break_info.count, 1);
1705 CHECK_VAL(break_info.failures, 0);
1707 smbcli_close(cli1->tree, fnum);
1708 smbcli_close(cli2->tree, fnum2);
1710 smb_raw_exit(cli1->session);
1711 smb_raw_exit(cli2->session);
1712 smbcli_deltree(cli1->tree, BASEDIR);
1716 static bool test_raw_oplock_batch15(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1718 const char *fname = BASEDIR "\\test_batch15.dat";
1722 union smb_fileinfo qfi;
1725 if (!torture_setup_dir(cli1, BASEDIR)) {
1730 smbcli_unlink(cli1->tree, fname);
1732 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1735 base ntcreatex parms
1737 io.generic.level = RAW_OPEN_NTCREATEX;
1738 io.ntcreatex.in.root_fid = 0;
1739 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1740 io.ntcreatex.in.alloc_size = 0;
1741 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1742 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1743 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1744 io.ntcreatex.in.create_options = 0;
1745 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1746 io.ntcreatex.in.security_flags = 0;
1747 io.ntcreatex.in.fname = fname;
1749 /* Test if a qpathinfo all info on pathname breaks a batch oplock. */
1750 torture_comment(tctx, "BATCH15: Test if qpathinfo all info breaks a batch oplock (should not).\n");
1752 ZERO_STRUCT(break_info);
1753 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1755 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1756 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1757 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1758 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1759 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1760 NTCREATEX_SHARE_ACCESS_WRITE|
1761 NTCREATEX_SHARE_ACCESS_DELETE;
1762 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1763 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1764 status = smb_raw_open(cli1->tree, tctx, &io);
1765 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1766 fnum = io.ntcreatex.out.file.fnum;
1767 CHECK_VAL(break_info.count, 0);
1768 CHECK_VAL(break_info.failures, 0);
1769 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1772 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
1773 qfi.generic.in.file.path = fname;
1775 status = smb_raw_pathinfo(cli2->tree, tctx, &qfi);
1777 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1778 CHECK_VAL(break_info.count, 0);
1780 smbcli_close(cli1->tree, fnum);
1783 smb_raw_exit(cli1->session);
1784 smb_raw_exit(cli2->session);
1785 smbcli_deltree(cli1->tree, BASEDIR);
1789 static bool test_raw_oplock_batch16(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1791 const char *fname = BASEDIR "\\test_batch16.dat";
1795 uint16_t fnum=0, fnum2=0;
1797 if (!torture_setup_dir(cli1, BASEDIR)) {
1802 smbcli_unlink(cli1->tree, fname);
1804 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1805 smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli1->tree);
1808 base ntcreatex parms
1810 io.generic.level = RAW_OPEN_NTCREATEX;
1811 io.ntcreatex.in.root_fid = 0;
1812 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1813 io.ntcreatex.in.alloc_size = 0;
1814 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1815 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1816 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1817 io.ntcreatex.in.create_options = 0;
1818 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1819 io.ntcreatex.in.security_flags = 0;
1820 io.ntcreatex.in.fname = fname;
1822 torture_comment(tctx, "BATCH16: open with batch oplock\n");
1823 ZERO_STRUCT(break_info);
1824 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1827 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1828 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1829 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1830 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1831 NTCREATEX_SHARE_ACCESS_WRITE|
1832 NTCREATEX_SHARE_ACCESS_DELETE;
1833 status = smb_raw_open(cli1->tree, tctx, &io);
1834 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1835 fnum = io.ntcreatex.out.file.fnum;
1836 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1838 ZERO_STRUCT(break_info);
1840 torture_comment(tctx, "second open with attributes only and NTCREATEX_DISP_OVERWRITE_IF dispostion causes oplock break\n");
1842 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1843 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1844 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1845 io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
1846 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1847 NTCREATEX_SHARE_ACCESS_WRITE|
1848 NTCREATEX_SHARE_ACCESS_DELETE;
1849 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE_IF;
1850 status = smb_raw_open(cli2->tree, tctx, &io);
1851 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1852 fnum2 = io.ntcreatex.out.file.fnum;
1853 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1854 CHECK_VAL(break_info.count, 1);
1855 CHECK_VAL(break_info.failures, 0);
1857 smbcli_close(cli1->tree, fnum);
1858 smbcli_close(cli2->tree, fnum2);
1861 smb_raw_exit(cli1->session);
1862 smb_raw_exit(cli2->session);
1863 smbcli_deltree(cli1->tree, BASEDIR);
1867 static bool test_raw_oplock_batch17(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1869 const char *fname1 = BASEDIR "\\test_batch17_1.dat";
1870 const char *fname2 = BASEDIR "\\test_batch17_2.dat";
1874 union smb_rename rn;
1877 if (!torture_setup_dir(cli1, BASEDIR)) {
1882 smbcli_unlink(cli1->tree, fname1);
1883 smbcli_unlink(cli1->tree, fname2);
1885 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1888 base ntcreatex parms
1890 io.generic.level = RAW_OPEN_NTCREATEX;
1891 io.ntcreatex.in.root_fid = 0;
1892 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1893 io.ntcreatex.in.alloc_size = 0;
1894 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1895 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1896 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1897 io.ntcreatex.in.create_options = 0;
1898 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1899 io.ntcreatex.in.security_flags = 0;
1900 io.ntcreatex.in.fname = fname1;
1902 torture_comment(tctx, "BATCH17: open a file with an batch oplock (share mode: none)\n");
1904 ZERO_STRUCT(break_info);
1905 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1906 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1907 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1909 status = smb_raw_open(cli1->tree, tctx, &io);
1910 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1911 fnum = io.ntcreatex.out.file.fnum;
1912 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1914 torture_comment(tctx, "rename should trigger a break\n");
1916 rn.generic.level = RAW_RENAME_RENAME;
1917 rn.rename.in.pattern1 = fname1;
1918 rn.rename.in.pattern2 = fname2;
1919 rn.rename.in.attrib = 0;
1921 printf("trying rename while first file open\n");
1922 status = smb_raw_rename(cli2->tree, &rn);
1924 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
1925 CHECK_VAL(break_info.count, 1);
1926 CHECK_VAL(break_info.failures, 0);
1927 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
1929 smbcli_close(cli1->tree, fnum);
1932 smb_raw_exit(cli1->session);
1933 smb_raw_exit(cli2->session);
1934 smbcli_deltree(cli1->tree, BASEDIR);
1938 static bool test_raw_oplock_batch18(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1940 const char *fname1 = BASEDIR "\\test_batch18_1.dat";
1941 const char *fname2 = BASEDIR "\\test_batch18_2.dat";
1945 union smb_rename rn;
1948 if (!torture_setup_dir(cli1, BASEDIR)) {
1953 smbcli_unlink(cli1->tree, fname1);
1954 smbcli_unlink(cli1->tree, fname2);
1956 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1959 base ntcreatex parms
1961 io.generic.level = RAW_OPEN_NTCREATEX;
1962 io.ntcreatex.in.root_fid = 0;
1963 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1964 io.ntcreatex.in.alloc_size = 0;
1965 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1966 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1967 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1968 io.ntcreatex.in.create_options = 0;
1969 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1970 io.ntcreatex.in.security_flags = 0;
1971 io.ntcreatex.in.fname = fname1;
1973 torture_comment(tctx, "BATCH18: open a file with an batch oplock (share mode: none)\n");
1975 ZERO_STRUCT(break_info);
1976 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1977 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1978 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1980 status = smb_raw_open(cli1->tree, tctx, &io);
1981 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1982 fnum = io.ntcreatex.out.file.fnum;
1983 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1985 torture_comment(tctx, "ntrename should trigger a break\n");
1987 rn.generic.level = RAW_RENAME_NTRENAME;
1988 rn.ntrename.in.attrib = 0;
1989 rn.ntrename.in.flags = RENAME_FLAG_RENAME;
1990 rn.ntrename.in.old_name = fname1;
1991 rn.ntrename.in.new_name = fname2;
1992 printf("trying rename while first file open\n");
1993 status = smb_raw_rename(cli2->tree, &rn);
1995 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
1996 CHECK_VAL(break_info.count, 1);
1997 CHECK_VAL(break_info.failures, 0);
1998 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
2000 smbcli_close(cli1->tree, fnum);
2003 smb_raw_exit(cli1->session);
2004 smb_raw_exit(cli2->session);
2005 smbcli_deltree(cli1->tree, BASEDIR);
2009 static bool test_raw_oplock_batch19(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
2011 const char *fname1 = BASEDIR "\\test_batch19_1.dat";
2012 const char *fname2 = BASEDIR "\\test_batch19_2.dat";
2013 const char *fname3 = BASEDIR "\\test_batch19_3.dat";
2017 union smb_fileinfo qfi;
2018 union smb_setfileinfo sfi;
2021 if (!torture_setup_dir(cli1, BASEDIR)) {
2026 smbcli_unlink(cli1->tree, fname1);
2027 smbcli_unlink(cli1->tree, fname2);
2028 smbcli_unlink(cli1->tree, fname3);
2030 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2033 base ntcreatex parms
2035 io.generic.level = RAW_OPEN_NTCREATEX;
2036 io.ntcreatex.in.root_fid = 0;
2037 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2038 io.ntcreatex.in.alloc_size = 0;
2039 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2040 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2041 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2042 io.ntcreatex.in.create_options = 0;
2043 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2044 io.ntcreatex.in.security_flags = 0;
2045 io.ntcreatex.in.fname = fname1;
2047 torture_comment(tctx, "BATCH19: open a file with an batch oplock (share mode: none)\n");
2048 ZERO_STRUCT(break_info);
2049 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2050 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2051 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2052 status = smb_raw_open(cli1->tree, tctx, &io);
2053 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2054 fnum = io.ntcreatex.out.file.fnum;
2055 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
2057 torture_comment(tctx, "setpathinfo rename info should not trigger a break nor a violation\n");
2059 sfi.generic.level = RAW_SFILEINFO_RENAME_INFORMATION;
2060 sfi.generic.in.file.path = fname1;
2061 sfi.rename_information.in.overwrite = 0;
2062 sfi.rename_information.in.root_fid = 0;
2063 sfi.rename_information.in.new_name = fname2+strlen(BASEDIR)+1;
2065 status = smb_raw_setpathinfo(cli2->tree, &sfi);
2067 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2068 CHECK_VAL(break_info.count, 0);
2071 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2072 qfi.generic.in.file.fnum = fnum;
2074 status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
2075 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2076 CHECK_STRMATCH(qfi.all_info.out.fname.s, fname2);
2078 torture_comment(tctx, "setfileinfo rename info should not trigger a break nor a violation\n");
2080 sfi.generic.level = RAW_SFILEINFO_RENAME_INFORMATION;
2081 sfi.generic.in.file.fnum = fnum;
2082 sfi.rename_information.in.overwrite = 0;
2083 sfi.rename_information.in.root_fid = 0;
2084 sfi.rename_information.in.new_name = fname3+strlen(BASEDIR)+1;
2086 status = smb_raw_setfileinfo(cli1->tree, &sfi);
2087 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2088 CHECK_VAL(break_info.count, 0);
2091 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2092 qfi.generic.in.file.fnum = fnum;
2094 status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
2095 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2096 CHECK_STRMATCH(qfi.all_info.out.fname.s, fname3);
2098 smbcli_close(cli1->tree, fnum);
2101 smb_raw_exit(cli1->session);
2102 smb_raw_exit(cli2->session);
2103 smbcli_deltree(cli1->tree, BASEDIR);
2107 /****************************************************
2108 Called from raw-rename - we need oplock handling for
2109 this test so this is why it's in oplock.c, not rename.c
2110 ****************************************************/
2112 bool test_trans2rename(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
2114 const char *fname1 = BASEDIR "\\test_trans2rename_1.dat";
2115 const char *fname2 = BASEDIR "\\test_trans2rename_2.dat";
2116 const char *fname3 = BASEDIR "\\test_trans2rename_3.dat";
2120 union smb_fileinfo qfi;
2121 union smb_setfileinfo sfi;
2124 if (!torture_setup_dir(cli1, BASEDIR)) {
2129 smbcli_unlink(cli1->tree, fname1);
2130 smbcli_unlink(cli1->tree, fname2);
2131 smbcli_unlink(cli1->tree, fname3);
2133 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2136 base ntcreatex parms
2138 io.generic.level = RAW_OPEN_NTCREATEX;
2139 io.ntcreatex.in.root_fid = 0;
2140 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2141 io.ntcreatex.in.alloc_size = 0;
2142 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2143 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2144 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2145 io.ntcreatex.in.create_options = 0;
2146 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2147 io.ntcreatex.in.security_flags = 0;
2148 io.ntcreatex.in.fname = fname1;
2150 torture_comment(tctx, "open a file with an exclusive oplock (share mode: none)\n");
2151 ZERO_STRUCT(break_info);
2152 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2153 NTCREATEX_FLAGS_REQUEST_OPLOCK;
2154 status = smb_raw_open(cli1->tree, tctx, &io);
2155 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2156 fnum = io.ntcreatex.out.file.fnum;
2157 CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
2159 torture_comment(tctx, "setpathinfo rename info should not trigger a break nor a violation\n");
2161 sfi.generic.level = RAW_SFILEINFO_RENAME_INFORMATION;
2162 sfi.generic.in.file.path = fname1;
2163 sfi.rename_information.in.overwrite = 0;
2164 sfi.rename_information.in.root_fid = 0;
2165 sfi.rename_information.in.new_name = fname2+strlen(BASEDIR)+1;
2167 status = smb_raw_setpathinfo(cli2->tree, &sfi);
2169 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2170 CHECK_VAL(break_info.count, 0);
2173 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2174 qfi.generic.in.file.fnum = fnum;
2176 status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
2177 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2178 CHECK_STRMATCH(qfi.all_info.out.fname.s, fname2);
2180 torture_comment(tctx, "setfileinfo rename info should not trigger a break nor a violation\n");
2182 sfi.generic.level = RAW_SFILEINFO_RENAME_INFORMATION;
2183 sfi.generic.in.file.fnum = fnum;
2184 sfi.rename_information.in.overwrite = 0;
2185 sfi.rename_information.in.root_fid = 0;
2186 sfi.rename_information.in.new_name = fname3+strlen(BASEDIR)+1;
2188 status = smb_raw_setfileinfo(cli1->tree, &sfi);
2189 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2190 CHECK_VAL(break_info.count, 0);
2193 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2194 qfi.generic.in.file.fnum = fnum;
2196 status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
2197 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2198 CHECK_STRMATCH(qfi.all_info.out.fname.s, fname3);
2200 smbcli_close(cli1->tree, fnum);
2203 smb_raw_exit(cli1->session);
2204 smb_raw_exit(cli2->session);
2205 smbcli_deltree(cli1->tree, BASEDIR);
2209 /****************************************************
2210 Called from raw-rename - we need oplock handling for
2211 this test so this is why it's in oplock.c, not rename.c
2212 ****************************************************/
2214 bool test_nttransrename(struct torture_context *tctx, struct smbcli_state *cli1)
2216 const char *fname1 = BASEDIR "\\test_nttransrename_1.dat";
2217 const char *fname2 = BASEDIR "\\test_nttransrename_2.dat";
2221 union smb_fileinfo qfi, qpi;
2222 union smb_rename rn;
2225 if (!torture_setup_dir(cli1, BASEDIR)) {
2230 smbcli_unlink(cli1->tree, fname1);
2231 smbcli_unlink(cli1->tree, fname2);
2233 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2236 base ntcreatex parms
2238 io.generic.level = RAW_OPEN_NTCREATEX;
2239 io.ntcreatex.in.root_fid = 0;
2240 io.ntcreatex.in.access_mask = 0;/* ask for no access at all */;
2241 io.ntcreatex.in.alloc_size = 0;
2242 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2243 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2244 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2245 io.ntcreatex.in.create_options = 0;
2246 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2247 io.ntcreatex.in.security_flags = 0;
2248 io.ntcreatex.in.fname = fname1;
2250 torture_comment(tctx, "nttrans_rename: open a file with an exclusive oplock (share mode: none)\n");
2251 ZERO_STRUCT(break_info);
2252 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2253 NTCREATEX_FLAGS_REQUEST_OPLOCK;
2254 status = smb_raw_open(cli1->tree, tctx, &io);
2255 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2256 fnum = io.ntcreatex.out.file.fnum;
2257 CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
2259 torture_comment(tctx, "nttrans_rename: should not trigger a break nor a share mode violation\n");
2261 rn.generic.level = RAW_RENAME_NTTRANS;
2262 rn.nttrans.in.file.fnum = fnum;
2263 rn.nttrans.in.flags = 0;
2264 rn.nttrans.in.new_name = fname2+strlen(BASEDIR)+1;
2266 status = smb_raw_rename(cli1->tree, &rn);
2268 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2269 CHECK_VAL(break_info.count, 0);
2271 /* w2k3 does nothing, it doesn't rename the file */
2272 torture_comment(tctx, "nttrans_rename: the server should have done nothing\n");
2274 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2275 qfi.generic.in.file.fnum = fnum;
2277 status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
2278 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2279 CHECK_STRMATCH(qfi.all_info.out.fname.s, fname1);
2282 qpi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2283 qpi.generic.in.file.path = fname1;
2285 status = smb_raw_pathinfo(cli1->tree, tctx, &qpi);
2286 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2287 CHECK_STRMATCH(qpi.all_info.out.fname.s, fname1);
2290 qpi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2291 qpi.generic.in.file.path = fname2;
2293 status = smb_raw_pathinfo(cli1->tree, tctx, &qpi);
2294 CHECK_STATUS(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
2296 torture_comment(tctx, "nttrans_rename: after closing the file the file is still not renamed\n");
2297 status = smbcli_close(cli1->tree, fnum);
2298 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2301 qpi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2302 qpi.generic.in.file.path = fname1;
2304 status = smb_raw_pathinfo(cli1->tree, tctx, &qpi);
2305 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2306 CHECK_STRMATCH(qpi.all_info.out.fname.s, fname1);
2309 qpi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2310 qpi.generic.in.file.path = fname2;
2312 status = smb_raw_pathinfo(cli1->tree, tctx, &qpi);
2313 CHECK_STATUS(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
2315 torture_comment(tctx, "nttrans_rename: rename with an invalid handle gives NT_STATUS_INVALID_HANDLE\n");
2317 rn.generic.level = RAW_RENAME_NTTRANS;
2318 rn.nttrans.in.file.fnum = fnum+1;
2319 rn.nttrans.in.flags = 0;
2320 rn.nttrans.in.new_name = fname2+strlen(BASEDIR)+1;
2322 status = smb_raw_rename(cli1->tree, &rn);
2324 CHECK_STATUS(tctx, status, NT_STATUS_INVALID_HANDLE);
2327 smb_raw_exit(cli1->session);
2328 smbcli_deltree(cli1->tree, BASEDIR);
2333 static bool test_raw_oplock_batch20(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
2335 const char *fname1 = BASEDIR "\\test_batch20_1.dat";
2336 const char *fname2 = BASEDIR "\\test_batch20_2.dat";
2337 const char *fname3 = BASEDIR "\\test_batch20_3.dat";
2341 union smb_fileinfo qfi;
2342 union smb_setfileinfo sfi;
2343 uint16_t fnum=0,fnum2=0;
2345 if (!torture_setup_dir(cli1, BASEDIR)) {
2350 smbcli_unlink(cli1->tree, fname1);
2351 smbcli_unlink(cli1->tree, fname2);
2352 smbcli_unlink(cli1->tree, fname3);
2354 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2357 base ntcreatex parms
2359 io.generic.level = RAW_OPEN_NTCREATEX;
2360 io.ntcreatex.in.root_fid = 0;
2361 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2362 io.ntcreatex.in.alloc_size = 0;
2363 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2364 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2365 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2366 io.ntcreatex.in.create_options = 0;
2367 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2368 io.ntcreatex.in.security_flags = 0;
2369 io.ntcreatex.in.fname = fname1;
2371 torture_comment(tctx, "BATCH20: open a file with an batch oplock (share mode: all)\n");
2372 ZERO_STRUCT(break_info);
2373 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2374 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2375 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2376 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
2377 NTCREATEX_SHARE_ACCESS_WRITE|
2378 NTCREATEX_SHARE_ACCESS_DELETE;
2379 status = smb_raw_open(cli1->tree, tctx, &io);
2380 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2381 fnum = io.ntcreatex.out.file.fnum;
2382 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
2384 torture_comment(tctx, "setpathinfo rename info should not trigger a break nor a violation\n");
2386 sfi.generic.level = RAW_SFILEINFO_RENAME_INFORMATION;
2387 sfi.generic.in.file.path = fname1;
2388 sfi.rename_information.in.overwrite = 0;
2389 sfi.rename_information.in.root_fid = 0;
2390 sfi.rename_information.in.new_name = fname2+strlen(BASEDIR)+1;
2392 status = smb_raw_setpathinfo(cli2->tree, &sfi);
2394 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2395 CHECK_VAL(break_info.count, 0);
2398 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2399 qfi.generic.in.file.fnum = fnum;
2401 status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
2402 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2403 CHECK_STRMATCH(qfi.all_info.out.fname.s, fname2);
2405 torture_comment(tctx, "open a file with the new name an batch oplock (share mode: all)\n");
2406 ZERO_STRUCT(break_info);
2407 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2408 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2409 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2410 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
2411 NTCREATEX_SHARE_ACCESS_WRITE|
2412 NTCREATEX_SHARE_ACCESS_DELETE;
2413 io.ntcreatex.in.fname = fname2;
2414 status = smb_raw_open(cli2->tree, tctx, &io);
2415 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2416 fnum2 = io.ntcreatex.out.file.fnum;
2417 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
2418 CHECK_VAL(break_info.count, 1);
2419 CHECK_VAL(break_info.failures, 0);
2420 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
2422 torture_comment(tctx, "setfileinfo rename info should not trigger a break nor a violation\n");
2424 sfi.generic.level = RAW_SFILEINFO_RENAME_INFORMATION;
2425 sfi.generic.in.file.fnum = fnum;
2426 sfi.rename_information.in.overwrite = 0;
2427 sfi.rename_information.in.root_fid = 0;
2428 sfi.rename_information.in.new_name = fname3+strlen(BASEDIR)+1;
2430 status = smb_raw_setfileinfo(cli1->tree, &sfi);
2431 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2432 CHECK_VAL(break_info.count, 1);
2433 CHECK_VAL(break_info.failures, 0);
2434 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
2437 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2438 qfi.generic.in.file.fnum = fnum;
2440 status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
2441 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2442 CHECK_STRMATCH(qfi.all_info.out.fname.s, fname3);
2445 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2446 qfi.generic.in.file.fnum = fnum2;
2448 status = smb_raw_fileinfo(cli2->tree, tctx, &qfi);
2449 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2450 CHECK_STRMATCH(qfi.all_info.out.fname.s, fname3);
2452 smbcli_close(cli1->tree, fnum);
2455 smb_raw_exit(cli1->session);
2456 smb_raw_exit(cli2->session);
2457 smbcli_deltree(cli1->tree, BASEDIR);
2461 static bool test_raw_oplock_batch21(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
2463 const char *fname = BASEDIR "\\test_batch21.dat";
2472 if (!torture_setup_dir(cli1, BASEDIR)) {
2477 smbcli_unlink(cli1->tree, fname);
2479 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2482 base ntcreatex parms
2484 io.generic.level = RAW_OPEN_NTCREATEX;
2485 io.ntcreatex.in.root_fid = 0;
2486 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2487 io.ntcreatex.in.alloc_size = 0;
2488 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2489 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2490 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2491 io.ntcreatex.in.create_options = 0;
2492 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2493 io.ntcreatex.in.security_flags = 0;
2494 io.ntcreatex.in.fname = fname;
2497 with a batch oplock we get a break
2499 torture_comment(tctx, "BATCH21: open with batch oplock\n");
2500 ZERO_STRUCT(break_info);
2501 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2502 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2503 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2504 status = smb_raw_open(cli1->tree, tctx, &io);
2505 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2506 fnum = io.ntcreatex.out.file.fnum;
2507 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
2509 torture_comment(tctx, "writing should not generate a break\n");
2510 wr = smbcli_write(cli1->tree, fnum, 0, &c, 0, 1);
2512 CHECK_STATUS(tctx, smbcli_nt_error(cli1->tree), NT_STATUS_OK);
2515 e.in.repeat_count = 1;
2516 status = smb_raw_echo(cli1->transport, &e);
2517 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2519 CHECK_VAL(break_info.count, 0);
2521 smbcli_close(cli1->tree, fnum);
2524 smb_raw_exit(cli1->session);
2525 smb_raw_exit(cli2->session);
2526 smbcli_deltree(cli1->tree, BASEDIR);
2530 static bool test_raw_oplock_batch22(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
2532 const char *fname = BASEDIR "\\test_batch22.dat";
2536 uint16_t fnum=0, fnum2=0;
2538 int timeout = torture_setting_int(tctx, "oplocktimeout", 30);
2541 if (torture_setting_bool(tctx, "samba3", false)) {
2542 torture_skip(tctx, "BACHT22 disabled against samba3\n");
2545 if (!torture_setup_dir(cli1, BASEDIR)) {
2550 smbcli_unlink(cli1->tree, fname);
2552 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2555 base ntcreatex parms
2557 io.generic.level = RAW_OPEN_NTCREATEX;
2558 io.ntcreatex.in.root_fid = 0;
2559 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2560 io.ntcreatex.in.alloc_size = 0;
2561 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2562 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2563 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2564 io.ntcreatex.in.create_options = 0;
2565 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2566 io.ntcreatex.in.security_flags = 0;
2567 io.ntcreatex.in.fname = fname;
2570 with a batch oplock we get a break
2572 torture_comment(tctx, "BATCH22: open with batch oplock\n");
2573 ZERO_STRUCT(break_info);
2574 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2575 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2576 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2577 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
2578 NTCREATEX_SHARE_ACCESS_WRITE|
2579 NTCREATEX_SHARE_ACCESS_DELETE;
2580 status = smb_raw_open(cli1->tree, tctx, &io);
2581 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2582 fnum = io.ntcreatex.out.file.fnum;
2583 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
2585 torture_comment(tctx, "a 2nd open shoud not succeed after the oplock break timeout\n");
2586 tv = timeval_current();
2587 smbcli_oplock_handler(cli1->transport, oplock_handler_timeout, cli1->tree);
2588 status = smb_raw_open(cli1->tree, tctx, &io);
2589 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
2590 te = (int)timeval_elapsed(&tv);
2591 CHECK_RANGE(te, timeout - 1, timeout + 15);
2593 CHECK_VAL(break_info.count, 1);
2594 CHECK_VAL(break_info.fnum, fnum);
2595 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
2596 CHECK_VAL(break_info.failures, 0);
2597 ZERO_STRUCT(break_info);
2599 torture_comment(tctx, "a 2nd open shoud succeed after the oplock release without break\n");
2600 tv = timeval_current();
2601 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2602 status = smb_raw_open(cli1->tree, tctx, &io);
2603 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2604 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
2605 te = (int)timeval_elapsed(&tv);
2606 /* it should come in without delay */
2607 CHECK_RANGE(te+1, 0, timeout);
2608 fnum2 = io.ntcreatex.out.file.fnum;
2610 CHECK_VAL(break_info.count, 0);
2612 smbcli_close(cli1->tree, fnum);
2613 smbcli_close(cli1->tree, fnum2);
2616 smb_raw_exit(cli1->session);
2617 smb_raw_exit(cli2->session);
2618 smbcli_deltree(cli1->tree, BASEDIR);
2622 static bool test_raw_oplock_batch23(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
2624 const char *fname = BASEDIR "\\test_batch23.dat";
2628 uint16_t fnum=0, fnum2=0,fnum3=0;
2629 struct smbcli_state *cli3 = NULL;
2631 if (torture_setting_bool(tctx, "samba3", false)) {
2632 torture_skip(tctx, "BACHT23 disabled against samba3\n");
2635 if (!torture_setup_dir(cli1, BASEDIR)) {
2640 smbcli_unlink(cli1->tree, fname);
2642 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2644 ret = open_connection_no_level2_oplocks(tctx, &cli3);
2645 CHECK_VAL(ret, true);
2648 base ntcreatex parms
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;
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);
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);
2678 ZERO_STRUCT(break_info);
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);
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);
2691 ZERO_STRUCT(break_info);
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);
2699 CHECK_VAL(break_info.count, 0);
2701 smbcli_close(cli1->tree, fnum);
2702 smbcli_close(cli2->tree, fnum2);
2703 smbcli_close(cli3->tree, fnum3);
2706 smb_raw_exit(cli1->session);
2707 smb_raw_exit(cli2->session);
2708 smb_raw_exit(cli3->session);
2709 smbcli_deltree(cli1->tree, BASEDIR);
2713 static bool test_raw_oplock_batch24(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
2715 const char *fname = BASEDIR "\\test_batch24.dat";
2719 uint16_t fnum2=0,fnum3=0;
2720 struct smbcli_state *cli3 = NULL;
2722 if (!torture_setup_dir(cli1, BASEDIR)) {
2727 smbcli_unlink(cli1->tree, fname);
2729 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2731 ret = open_connection_no_level2_oplocks(tctx, &cli3);
2732 CHECK_VAL(ret, true);
2735 base ntcreatex parms
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;
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);
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);
2765 ZERO_STRUCT(break_info);
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);
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);
2778 smbcli_close(cli3->tree, fnum3);
2779 smbcli_close(cli2->tree, fnum2);
2782 smb_raw_exit(cli1->session);
2783 smb_raw_exit(cli2->session);
2784 smb_raw_exit(cli3->session);
2785 smbcli_deltree(cli1->tree, BASEDIR);
2790 basic testing of oplocks
2792 struct torture_suite *torture_raw_oplock(TALLOC_CTX *mem_ctx)
2794 struct torture_suite *suite = torture_suite_create(mem_ctx, "OPLOCK");
2796 torture_suite_add_2smb_test(suite, "EXCLUSIVE1", test_raw_oplock_exclusive1);
2797 torture_suite_add_2smb_test(suite, "EXCLUSIVE2", test_raw_oplock_exclusive2);
2798 torture_suite_add_2smb_test(suite, "EXCLUSIVE3", test_raw_oplock_exclusive3);
2799 torture_suite_add_2smb_test(suite, "EXCLUSIVE4", test_raw_oplock_exclusive4);
2800 torture_suite_add_2smb_test(suite, "EXCLUSIVE5", test_raw_oplock_exclusive5);
2801 torture_suite_add_2smb_test(suite, "EXCLUSIVE6", test_raw_oplock_exclusive6);
2802 torture_suite_add_2smb_test(suite, "BATCH1", test_raw_oplock_batch1);
2803 torture_suite_add_2smb_test(suite, "BATCH2", test_raw_oplock_batch2);
2804 torture_suite_add_2smb_test(suite, "BATCH3", test_raw_oplock_batch3);
2805 torture_suite_add_2smb_test(suite, "BATCH4", test_raw_oplock_batch4);
2806 torture_suite_add_2smb_test(suite, "BATCH5", test_raw_oplock_batch5);
2807 torture_suite_add_2smb_test(suite, "BATCH6", test_raw_oplock_batch6);
2808 torture_suite_add_2smb_test(suite, "BATCH7", test_raw_oplock_batch7);
2809 torture_suite_add_2smb_test(suite, "BATCH8", test_raw_oplock_batch8);
2810 torture_suite_add_2smb_test(suite, "BATCH9", test_raw_oplock_batch9);
2811 torture_suite_add_2smb_test(suite, "BATCH10", test_raw_oplock_batch10);
2812 torture_suite_add_2smb_test(suite, "BATCH11", test_raw_oplock_batch11);
2813 torture_suite_add_2smb_test(suite, "BATCH12", test_raw_oplock_batch12);
2814 torture_suite_add_2smb_test(suite, "BATCH13", test_raw_oplock_batch13);
2815 torture_suite_add_2smb_test(suite, "BATCH14", test_raw_oplock_batch14);
2816 torture_suite_add_2smb_test(suite, "BATCH15", test_raw_oplock_batch15);
2817 torture_suite_add_2smb_test(suite, "BATCH16", test_raw_oplock_batch16);
2818 torture_suite_add_2smb_test(suite, "BATCH17", test_raw_oplock_batch17);
2819 torture_suite_add_2smb_test(suite, "BATCH18", test_raw_oplock_batch18);
2820 torture_suite_add_2smb_test(suite, "BATCH19", test_raw_oplock_batch19);
2821 torture_suite_add_2smb_test(suite, "BATCH20", test_raw_oplock_batch20);
2822 torture_suite_add_2smb_test(suite, "BATCH21", test_raw_oplock_batch21);
2823 torture_suite_add_2smb_test(suite, "BATCH22", test_raw_oplock_batch22);
2824 torture_suite_add_2smb_test(suite, "BATCH23", test_raw_oplock_batch23);
2825 torture_suite_add_2smb_test(suite, "BATCH24", test_raw_oplock_batch24);
2831 stress testing of oplocks
2833 bool torture_bench_oplock(struct torture_context *torture)
2835 struct smbcli_state **cli;
2837 TALLOC_CTX *mem_ctx = talloc_new(torture);
2838 int torture_nprocs = torture_setting_int(torture, "nprocs", 4);
2840 int timelimit = torture_setting_int(torture, "timelimit", 10);
2843 struct event_context *ev = event_context_find(mem_ctx);
2845 cli = talloc_array(mem_ctx, struct smbcli_state *, torture_nprocs);
2847 torture_comment(torture, "Opening %d connections\n", torture_nprocs);
2848 for (i=0;i<torture_nprocs;i++) {
2849 if (!torture_open_connection_ev(&cli[i], i, torture, ev)) {
2852 talloc_steal(mem_ctx, cli[i]);
2853 smbcli_oplock_handler(cli[i]->transport, oplock_handler_close,
2857 if (!torture_setup_dir(cli[0], BASEDIR)) {
2862 io.ntcreatex.level = RAW_OPEN_NTCREATEX;
2863 io.ntcreatex.in.root_fid = 0;
2864 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2865 io.ntcreatex.in.alloc_size = 0;
2866 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2867 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2868 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2869 io.ntcreatex.in.create_options = 0;
2870 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2871 io.ntcreatex.in.security_flags = 0;
2872 io.ntcreatex.in.fname = BASEDIR "\\test.dat";
2873 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2874 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2875 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2877 tv = timeval_current();
2880 we open the same file with SHARE_ACCESS_NONE from all the
2881 connections in a round robin fashion. Each open causes an
2882 oplock break on the previous connection, which is answered
2883 by the oplock_handler_close() to close the file.
2885 This measures how fast we can pass on oplocks, and stresses
2886 the oplock handling code
2888 torture_comment(torture, "Running for %d seconds\n", timelimit);
2889 while (timeval_elapsed(&tv) < timelimit) {
2890 for (i=0;i<torture_nprocs;i++) {
2893 status = smb_raw_open(cli[i]->tree, mem_ctx, &io);
2894 CHECK_STATUS(torture, status, NT_STATUS_OK);
2898 if (torture_setting_bool(torture, "progress", true)) {
2899 torture_comment(torture, "%.2f ops/second\r", count/timeval_elapsed(&tv));
2903 torture_comment(torture, "%.2f ops/second\n", count/timeval_elapsed(&tv));
2905 smb_raw_exit(cli[torture_nprocs-1]->session);
2908 smb_raw_exit(cli[0]->session);
2909 smbcli_deltree(cli[0]->tree, BASEDIR);
2910 talloc_free(mem_ctx);
2915 static struct hold_oplock_info {
2917 bool close_on_break;
2918 uint32_t share_access;
2921 { BASEDIR "\\notshared_close", true,
2922 NTCREATEX_SHARE_ACCESS_NONE, },
2923 { BASEDIR "\\notshared_noclose", false,
2924 NTCREATEX_SHARE_ACCESS_NONE, },
2925 { BASEDIR "\\shared_close", true,
2926 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE, },
2927 { BASEDIR "\\shared_noclose", false,
2928 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE, },
2931 static bool oplock_handler_hold(struct smbcli_transport *transport,
2932 uint16_t tid, uint16_t fnum, uint8_t level,
2935 struct smbcli_tree *tree = (struct smbcli_tree *)private;
2936 struct hold_oplock_info *info;
2939 for (i=0;i<ARRAY_SIZE(hold_info);i++) {
2940 if (hold_info[i].fnum == fnum) break;
2943 if (i == ARRAY_SIZE(hold_info)) {
2944 printf("oplock break for unknown fnum %u\n", fnum);
2948 info = &hold_info[i];
2950 if (info->close_on_break) {
2951 printf("oplock break on %s - closing\n",
2953 oplock_handler_close(transport, tid, fnum, level, private);
2957 printf("oplock break on %s - acking break\n", info->fname);
2959 return smbcli_oplock_ack(tree, fnum, OPLOCK_BREAK_TO_NONE);
2964 used for manual testing of oplocks - especially interaction with
2965 other filesystems (such as NFS and local access)
2967 bool torture_hold_oplock(struct torture_context *torture,
2968 struct smbcli_state *cli)
2970 struct event_context *ev =
2971 (struct event_context *)cli->transport->socket->event.ctx;
2974 printf("Setting up open files with oplocks in %s\n", BASEDIR);
2976 if (!torture_setup_dir(cli, BASEDIR)) {
2980 smbcli_oplock_handler(cli->transport, oplock_handler_hold, cli->tree);
2982 /* setup the files */
2983 for (i=0;i<ARRAY_SIZE(hold_info);i++) {
2988 io.generic.level = RAW_OPEN_NTCREATEX;
2989 io.ntcreatex.in.root_fid = 0;
2990 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2991 io.ntcreatex.in.alloc_size = 0;
2992 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2993 io.ntcreatex.in.share_access = hold_info[i].share_access;
2994 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2995 io.ntcreatex.in.create_options = 0;
2996 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2997 io.ntcreatex.in.security_flags = 0;
2998 io.ntcreatex.in.fname = hold_info[i].fname;
2999 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
3000 NTCREATEX_FLAGS_REQUEST_OPLOCK |
3001 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
3002 printf("opening %s\n", hold_info[i].fname);
3004 status = smb_raw_open(cli->tree, cli, &io);
3005 if (!NT_STATUS_IS_OK(status)) {
3006 printf("Failed to open %s - %s\n",
3007 hold_info[i].fname, nt_errstr(status));
3011 if (io.ntcreatex.out.oplock_level != BATCH_OPLOCK_RETURN) {
3012 printf("Oplock not granted for %s - expected %d but got %d\n",
3013 hold_info[i].fname, BATCH_OPLOCK_RETURN,
3014 io.ntcreatex.out.oplock_level);
3017 hold_info[i].fnum = io.ntcreatex.out.file.fnum;
3019 /* make the file non-zero size */
3020 if (smbcli_write(cli->tree, hold_info[i].fnum, 0, &c, 0, 1) != 1) {
3021 printf("Failed to write to file\n");
3026 printf("Waiting for oplock events\n");
3027 event_loop_wait(ev);