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, "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, "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;
366 bool s3 = torture_setting_bool(tctx, "samba3", false);
368 if (!torture_setup_dir(cli1, BASEDIR)) {
373 smbcli_unlink(cli1->tree, fname);
375 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
380 io.generic.level = RAW_OPEN_NTCREATEX;
381 io.ntcreatex.in.root_fid = 0;
382 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
383 io.ntcreatex.in.alloc_size = 0;
384 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
385 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
386 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
387 io.ntcreatex.in.create_options = 0;
388 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
389 io.ntcreatex.in.security_flags = 0;
390 io.ntcreatex.in.fname = fname;
392 torture_comment(tctx, "open a file with an exclusive oplock (share mode: %s)\n",
394 ZERO_STRUCT(break_info);
395 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
397 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
398 NTCREATEX_SHARE_ACCESS_WRITE|
399 NTCREATEX_SHARE_ACCESS_DELETE;
402 status = smb_raw_open(cli1->tree, tctx, &io);
403 CHECK_STATUS(tctx, status, NT_STATUS_OK);
404 fnum = io.ntcreatex.out.file.fnum;
405 CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
407 torture_comment(tctx, "setpathinfo EOF should trigger a break to none\n");
409 sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
410 sfi.generic.in.file.path = fname;
411 sfi.end_of_file_info.in.size = 100;
413 status = smb_raw_setpathinfo(cli2->tree, &sfi);
415 CHECK_STATUS(tctx, status, NT_STATUS_OK);
416 CHECK_VAL(break_info.count, 1);
417 CHECK_VAL(break_info.failures, 0);
418 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_NONE);
420 smbcli_close(cli1->tree, fnum);
423 smb_raw_exit(cli1->session);
424 smb_raw_exit(cli2->session);
425 smbcli_deltree(cli1->tree, BASEDIR);
429 static bool test_raw_oplock_exclusive4(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
431 const char *fname = BASEDIR "\\test_exclusive4.dat";
435 uint16_t fnum=0, fnum2=0;
437 if (!torture_setup_dir(cli1, BASEDIR)) {
442 smbcli_unlink(cli1->tree, fname);
444 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
449 io.generic.level = RAW_OPEN_NTCREATEX;
450 io.ntcreatex.in.root_fid = 0;
451 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
452 io.ntcreatex.in.alloc_size = 0;
453 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
454 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
455 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
456 io.ntcreatex.in.create_options = 0;
457 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
458 io.ntcreatex.in.security_flags = 0;
459 io.ntcreatex.in.fname = fname;
461 torture_comment(tctx, "open with exclusive oplock\n");
462 ZERO_STRUCT(break_info);
463 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
465 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
466 status = smb_raw_open(cli1->tree, tctx, &io);
467 CHECK_STATUS(tctx, status, NT_STATUS_OK);
468 fnum = io.ntcreatex.out.file.fnum;
469 CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
471 ZERO_STRUCT(break_info);
472 torture_comment(tctx, "second open with attributes only shouldn't cause oplock break\n");
474 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
475 io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
476 status = smb_raw_open(cli2->tree, tctx, &io);
477 CHECK_STATUS(tctx, status, NT_STATUS_OK);
478 fnum2 = io.ntcreatex.out.file.fnum;
479 CHECK_VAL(io.ntcreatex.out.oplock_level, NO_OPLOCK_RETURN);
480 CHECK_VAL(break_info.count, 0);
481 CHECK_VAL(break_info.failures, 0);
483 smbcli_close(cli1->tree, fnum);
484 smbcli_close(cli2->tree, fnum2);
487 smb_raw_exit(cli1->session);
488 smb_raw_exit(cli2->session);
489 smbcli_deltree(cli1->tree, BASEDIR);
493 static bool test_raw_oplock_exclusive5(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
495 const char *fname = BASEDIR "\\test_exclusive5.dat";
499 uint16_t fnum=0, fnum2=0;
501 if (!torture_setup_dir(cli1, BASEDIR)) {
506 smbcli_unlink(cli1->tree, fname);
508 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
509 smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli1->tree);
514 io.generic.level = RAW_OPEN_NTCREATEX;
515 io.ntcreatex.in.root_fid = 0;
516 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
517 io.ntcreatex.in.alloc_size = 0;
518 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
519 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
520 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
521 io.ntcreatex.in.create_options = 0;
522 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
523 io.ntcreatex.in.security_flags = 0;
524 io.ntcreatex.in.fname = fname;
526 torture_comment(tctx, "open with exclusive oplock\n");
527 ZERO_STRUCT(break_info);
528 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
531 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
532 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
533 NTCREATEX_SHARE_ACCESS_WRITE|
534 NTCREATEX_SHARE_ACCESS_DELETE;
535 status = smb_raw_open(cli1->tree, tctx, &io);
536 CHECK_STATUS(tctx, status, NT_STATUS_OK);
537 fnum = io.ntcreatex.out.file.fnum;
538 CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
540 ZERO_STRUCT(break_info);
542 torture_comment(tctx, "second open with attributes only and NTCREATEX_DISP_OVERWRITE_IF dispostion causes oplock break\n");
544 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
545 io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
546 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE_IF;
547 status = smb_raw_open(cli2->tree, tctx, &io);
548 CHECK_STATUS(tctx, status, NT_STATUS_OK);
549 fnum2 = io.ntcreatex.out.file.fnum;
550 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
551 CHECK_VAL(break_info.count, 1);
552 CHECK_VAL(break_info.failures, 0);
554 smbcli_close(cli1->tree, fnum);
555 smbcli_close(cli2->tree, fnum2);
558 smb_raw_exit(cli1->session);
559 smb_raw_exit(cli2->session);
560 smbcli_deltree(cli1->tree, BASEDIR);
564 static bool test_raw_oplock_exclusive6(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
566 const char *fname1 = BASEDIR "\\test_exclusive6_1.dat";
567 const char *fname2 = BASEDIR "\\test_exclusive6_2.dat";
573 bool s3 = torture_setting_bool(tctx, "samba3", false);
575 if (!torture_setup_dir(cli1, BASEDIR)) {
580 smbcli_unlink(cli1->tree, fname1);
581 smbcli_unlink(cli1->tree, fname2);
583 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
588 io.generic.level = RAW_OPEN_NTCREATEX;
589 io.ntcreatex.in.root_fid = 0;
590 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
591 io.ntcreatex.in.alloc_size = 0;
592 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
593 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
594 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
595 io.ntcreatex.in.create_options = 0;
596 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
597 io.ntcreatex.in.security_flags = 0;
598 io.ntcreatex.in.fname = fname1;
600 /* we should use no share mode, when samba3 passes this */
601 torture_comment(tctx, "open a file with an exclusive oplock (share mode: %s)\n",
603 ZERO_STRUCT(break_info);
604 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
606 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
607 NTCREATEX_SHARE_ACCESS_WRITE|
608 NTCREATEX_SHARE_ACCESS_DELETE;
611 status = smb_raw_open(cli1->tree, tctx, &io);
612 CHECK_STATUS(tctx, status, NT_STATUS_OK);
613 fnum = io.ntcreatex.out.file.fnum;
614 CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
616 torture_comment(tctx, "rename should not generate a break but get a sharing violation\n");
618 rn.generic.level = RAW_RENAME_RENAME;
619 rn.rename.in.pattern1 = fname1;
620 rn.rename.in.pattern2 = fname2;
621 rn.rename.in.attrib = 0;
623 printf("trying rename while first file open\n");
624 status = smb_raw_rename(cli2->tree, &rn);
626 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
627 CHECK_VAL(break_info.count, 0);
628 CHECK_VAL(break_info.failures, 0);
630 smbcli_close(cli1->tree, fnum);
633 smb_raw_exit(cli1->session);
634 smb_raw_exit(cli2->session);
635 smbcli_deltree(cli1->tree, BASEDIR);
639 static bool test_raw_oplock_batch1(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
641 const char *fname = BASEDIR "\\test_batch1.dat";
645 union smb_unlink unl;
649 if (!torture_setup_dir(cli1, BASEDIR)) {
654 smbcli_unlink(cli1->tree, fname);
656 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
661 io.generic.level = RAW_OPEN_NTCREATEX;
662 io.ntcreatex.in.root_fid = 0;
663 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
664 io.ntcreatex.in.alloc_size = 0;
665 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
666 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
667 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
668 io.ntcreatex.in.create_options = 0;
669 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
670 io.ntcreatex.in.security_flags = 0;
671 io.ntcreatex.in.fname = fname;
674 with a batch oplock we get a break
676 torture_comment(tctx, "open with batch oplock\n");
677 ZERO_STRUCT(break_info);
678 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
679 NTCREATEX_FLAGS_REQUEST_OPLOCK |
680 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
681 status = smb_raw_open(cli1->tree, tctx, &io);
682 CHECK_STATUS(tctx, status, NT_STATUS_OK);
683 fnum = io.ntcreatex.out.file.fnum;
684 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
686 torture_comment(tctx, "unlink should generate a break\n");
687 unl.unlink.in.pattern = fname;
688 unl.unlink.in.attrib = 0;
689 status = smb_raw_unlink(cli2->tree, &unl);
690 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
692 CHECK_VAL(break_info.count, 1);
693 CHECK_VAL(break_info.fnum, fnum);
694 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
695 CHECK_VAL(break_info.failures, 0);
697 torture_comment(tctx, "2nd unlink should not generate a break\n");
698 ZERO_STRUCT(break_info);
699 status = smb_raw_unlink(cli2->tree, &unl);
700 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
702 CHECK_VAL(break_info.count, 0);
704 torture_comment(tctx, "writing should generate a self break to none\n");
705 smbcli_write(cli1->tree, fnum, 0, &c, 0, 1);
707 smbcli_write(cli1->tree, fnum, 0, &c, 1, 1);
709 CHECK_VAL(break_info.count, 1);
710 CHECK_VAL(break_info.fnum, fnum);
711 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_NONE);
712 CHECK_VAL(break_info.failures, 0);
714 smbcli_close(cli1->tree, fnum);
717 smb_raw_exit(cli1->session);
718 smb_raw_exit(cli2->session);
719 smbcli_deltree(cli1->tree, BASEDIR);
723 static bool test_raw_oplock_batch2(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
725 const char *fname = BASEDIR "\\test_batch2.dat";
729 union smb_unlink unl;
733 if (!torture_setup_dir(cli1, BASEDIR)) {
738 smbcli_unlink(cli1->tree, fname);
740 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
745 io.generic.level = RAW_OPEN_NTCREATEX;
746 io.ntcreatex.in.root_fid = 0;
747 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
748 io.ntcreatex.in.alloc_size = 0;
749 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
750 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
751 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
752 io.ntcreatex.in.create_options = 0;
753 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
754 io.ntcreatex.in.security_flags = 0;
755 io.ntcreatex.in.fname = fname;
757 torture_comment(tctx, "open with batch oplock\n");
758 ZERO_STRUCT(break_info);
759 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
760 NTCREATEX_FLAGS_REQUEST_OPLOCK |
761 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
762 status = smb_raw_open(cli1->tree, tctx, &io);
763 CHECK_STATUS(tctx, status, NT_STATUS_OK);
764 fnum = io.ntcreatex.out.file.fnum;
765 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
767 torture_comment(tctx, "unlink should generate a break, which we ack as break to none\n");
768 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_none, cli1->tree);
769 unl.unlink.in.pattern = fname;
770 unl.unlink.in.attrib = 0;
771 status = smb_raw_unlink(cli2->tree, &unl);
772 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
774 CHECK_VAL(break_info.count, 1);
775 CHECK_VAL(break_info.fnum, fnum);
776 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
777 CHECK_VAL(break_info.failures, 0);
779 torture_comment(tctx, "2nd unlink should not generate a break\n");
780 ZERO_STRUCT(break_info);
781 status = smb_raw_unlink(cli2->tree, &unl);
782 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
784 CHECK_VAL(break_info.count, 0);
786 torture_comment(tctx, "writing should not generate a break\n");
787 smbcli_write(cli1->tree, fnum, 0, &c, 0, 1);
789 smbcli_write(cli1->tree, fnum, 0, &c, 1, 1);
791 CHECK_VAL(break_info.count, 0);
793 smbcli_close(cli1->tree, fnum);
796 smb_raw_exit(cli1->session);
797 smb_raw_exit(cli2->session);
798 smbcli_deltree(cli1->tree, BASEDIR);
802 static bool test_raw_oplock_batch3(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
804 const char *fname = BASEDIR "\\test_batch3.dat";
808 union smb_unlink unl;
811 if (!torture_setup_dir(cli1, BASEDIR)) {
816 smbcli_unlink(cli1->tree, fname);
818 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
823 io.generic.level = RAW_OPEN_NTCREATEX;
824 io.ntcreatex.in.root_fid = 0;
825 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
826 io.ntcreatex.in.alloc_size = 0;
827 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
828 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
829 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
830 io.ntcreatex.in.create_options = 0;
831 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
832 io.ntcreatex.in.security_flags = 0;
833 io.ntcreatex.in.fname = fname;
835 torture_comment(tctx, "if we close on break then the unlink can succeed\n");
836 ZERO_STRUCT(break_info);
837 smbcli_oplock_handler(cli1->transport, oplock_handler_close, cli1->tree);
838 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
839 NTCREATEX_FLAGS_REQUEST_OPLOCK |
840 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
841 status = smb_raw_open(cli1->tree, tctx, &io);
842 CHECK_STATUS(tctx, status, NT_STATUS_OK);
843 fnum = io.ntcreatex.out.file.fnum;
844 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
846 unl.unlink.in.pattern = fname;
847 unl.unlink.in.attrib = 0;
848 ZERO_STRUCT(break_info);
849 status = smb_raw_unlink(cli2->tree, &unl);
850 CHECK_STATUS(tctx, status, NT_STATUS_OK);
852 CHECK_VAL(break_info.count, 1);
853 CHECK_VAL(break_info.fnum, fnum);
854 CHECK_VAL(break_info.level, 1);
855 CHECK_VAL(break_info.failures, 0);
857 smbcli_close(cli1->tree, fnum);
860 smb_raw_exit(cli1->session);
861 smb_raw_exit(cli2->session);
862 smbcli_deltree(cli1->tree, BASEDIR);
866 static bool test_raw_oplock_batch4(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
868 const char *fname = BASEDIR "\\test_batch4.dat";
875 if (!torture_setup_dir(cli1, BASEDIR)) {
880 smbcli_unlink(cli1->tree, fname);
882 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
887 io.generic.level = RAW_OPEN_NTCREATEX;
888 io.ntcreatex.in.root_fid = 0;
889 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
890 io.ntcreatex.in.alloc_size = 0;
891 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
892 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
893 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
894 io.ntcreatex.in.create_options = 0;
895 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
896 io.ntcreatex.in.security_flags = 0;
897 io.ntcreatex.in.fname = fname;
899 torture_comment(tctx, "a self read should not cause a break\n");
900 ZERO_STRUCT(break_info);
901 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
903 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
904 NTCREATEX_FLAGS_REQUEST_OPLOCK |
905 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
906 status = smb_raw_open(cli1->tree, tctx, &io);
907 CHECK_STATUS(tctx, status, NT_STATUS_OK);
908 fnum = io.ntcreatex.out.file.fnum;
909 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
911 rd.read.level = RAW_READ_READ;
912 rd.read.in.file.fnum = fnum;
913 rd.read.in.count = 1;
914 rd.read.in.offset = 0;
915 rd.read.in.remaining = 0;
916 status = smb_raw_read(cli1->tree, &rd);
917 CHECK_STATUS(tctx, status, NT_STATUS_OK);
918 CHECK_VAL(break_info.count, 0);
919 CHECK_VAL(break_info.failures, 0);
921 smbcli_close(cli1->tree, fnum);
924 smb_raw_exit(cli1->session);
925 smb_raw_exit(cli2->session);
926 smbcli_deltree(cli1->tree, BASEDIR);
930 static bool test_raw_oplock_batch5(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
932 const char *fname = BASEDIR "\\test_batch5.dat";
938 if (!torture_setup_dir(cli1, BASEDIR)) {
943 smbcli_unlink(cli1->tree, fname);
945 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
950 io.generic.level = RAW_OPEN_NTCREATEX;
951 io.ntcreatex.in.root_fid = 0;
952 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
953 io.ntcreatex.in.alloc_size = 0;
954 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
955 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
956 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
957 io.ntcreatex.in.create_options = 0;
958 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
959 io.ntcreatex.in.security_flags = 0;
960 io.ntcreatex.in.fname = fname;
962 torture_comment(tctx, "a 2nd open should give a break\n");
963 ZERO_STRUCT(break_info);
964 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
966 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
967 NTCREATEX_FLAGS_REQUEST_OPLOCK |
968 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
969 status = smb_raw_open(cli1->tree, tctx, &io);
970 CHECK_STATUS(tctx, status, NT_STATUS_OK);
971 fnum = io.ntcreatex.out.file.fnum;
972 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
974 ZERO_STRUCT(break_info);
976 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
977 status = smb_raw_open(cli2->tree, tctx, &io);
978 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
980 CHECK_VAL(break_info.count, 1);
981 CHECK_VAL(break_info.fnum, fnum);
982 CHECK_VAL(break_info.level, 1);
983 CHECK_VAL(break_info.failures, 0);
985 smbcli_close(cli1->tree, fnum);
988 smb_raw_exit(cli1->session);
989 smb_raw_exit(cli2->session);
990 smbcli_deltree(cli1->tree, BASEDIR);
994 static bool test_raw_oplock_batch6(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
996 const char *fname = BASEDIR "\\test_batch6.dat";
1000 uint16_t fnum=0, fnum2=0;
1003 if (!torture_setup_dir(cli1, BASEDIR)) {
1008 smbcli_unlink(cli1->tree, fname);
1010 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1013 base ntcreatex parms
1015 io.generic.level = RAW_OPEN_NTCREATEX;
1016 io.ntcreatex.in.root_fid = 0;
1017 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1018 io.ntcreatex.in.alloc_size = 0;
1019 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1020 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1021 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1022 io.ntcreatex.in.create_options = 0;
1023 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1024 io.ntcreatex.in.security_flags = 0;
1025 io.ntcreatex.in.fname = fname;
1027 torture_comment(tctx, "a 2nd open should give a break to level II if the first open allowed shared read\n");
1028 ZERO_STRUCT(break_info);
1029 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1030 smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli2->tree);
1032 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_READ | SEC_RIGHTS_FILE_WRITE;
1033 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
1034 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1035 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1036 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1037 status = smb_raw_open(cli1->tree, tctx, &io);
1038 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1039 fnum = io.ntcreatex.out.file.fnum;
1040 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1042 ZERO_STRUCT(break_info);
1044 status = smb_raw_open(cli2->tree, tctx, &io);
1045 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1046 fnum2 = io.ntcreatex.out.file.fnum;
1047 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1049 CHECK_VAL(break_info.count, 1);
1050 CHECK_VAL(break_info.fnum, fnum);
1051 CHECK_VAL(break_info.level, 1);
1052 CHECK_VAL(break_info.failures, 0);
1053 ZERO_STRUCT(break_info);
1055 torture_comment(tctx, "write should trigger a break to none on both\n");
1056 smbcli_write(cli1->tree, fnum, 0, &c, 0, 1);
1058 smbcli_write(cli1->tree, fnum, 0, &c, 1, 1);
1060 CHECK_VAL(break_info.count, 2);
1061 CHECK_VAL(break_info.level, 0);
1062 CHECK_VAL(break_info.failures, 0);
1064 smbcli_close(cli1->tree, fnum);
1065 smbcli_close(cli2->tree, fnum2);
1069 smb_raw_exit(cli1->session);
1070 smb_raw_exit(cli2->session);
1071 smbcli_deltree(cli1->tree, BASEDIR);
1075 static bool test_raw_oplock_batch7(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1077 const char *fname = BASEDIR "\\test_batch7.dat";
1081 uint16_t fnum=0, fnum2=0;
1083 if (!torture_setup_dir(cli1, BASEDIR)) {
1088 smbcli_unlink(cli1->tree, fname);
1090 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1093 base ntcreatex parms
1095 io.generic.level = RAW_OPEN_NTCREATEX;
1096 io.ntcreatex.in.root_fid = 0;
1097 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1098 io.ntcreatex.in.alloc_size = 0;
1099 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1100 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1101 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1102 io.ntcreatex.in.create_options = 0;
1103 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1104 io.ntcreatex.in.security_flags = 0;
1105 io.ntcreatex.in.fname = fname;
1107 torture_comment(tctx, "a 2nd open should get an oplock when we close instead of ack\n");
1108 ZERO_STRUCT(break_info);
1109 smbcli_oplock_handler(cli1->transport, oplock_handler_close, cli1->tree);
1111 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1112 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1113 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1114 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1115 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1116 status = smb_raw_open(cli1->tree, tctx, &io);
1117 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1118 fnum2 = io.ntcreatex.out.file.fnum;
1119 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1121 ZERO_STRUCT(break_info);
1123 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1124 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1125 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1126 status = smb_raw_open(cli2->tree, tctx, &io);
1127 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1128 fnum = io.ntcreatex.out.file.fnum;
1129 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1131 CHECK_VAL(break_info.count, 1);
1132 CHECK_VAL(break_info.fnum, fnum2);
1133 CHECK_VAL(break_info.level, 1);
1134 CHECK_VAL(break_info.failures, 0);
1136 smbcli_close(cli2->tree, fnum);
1139 smb_raw_exit(cli1->session);
1140 smb_raw_exit(cli2->session);
1141 smbcli_deltree(cli1->tree, BASEDIR);
1145 static bool test_raw_oplock_batch8(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1147 const char *fname = BASEDIR "\\test_batch8.dat";
1151 uint16_t fnum=0, fnum2=0;
1153 if (!torture_setup_dir(cli1, BASEDIR)) {
1158 smbcli_unlink(cli1->tree, fname);
1160 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1163 base ntcreatex parms
1165 io.generic.level = RAW_OPEN_NTCREATEX;
1166 io.ntcreatex.in.root_fid = 0;
1167 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1168 io.ntcreatex.in.alloc_size = 0;
1169 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1170 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1171 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1172 io.ntcreatex.in.create_options = 0;
1173 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1174 io.ntcreatex.in.security_flags = 0;
1175 io.ntcreatex.in.fname = fname;
1177 torture_comment(tctx, "open with batch oplock\n");
1178 ZERO_STRUCT(break_info);
1179 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1181 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1182 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1183 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1184 status = smb_raw_open(cli1->tree, tctx, &io);
1185 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1186 fnum = io.ntcreatex.out.file.fnum;
1187 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1189 ZERO_STRUCT(break_info);
1190 torture_comment(tctx, "second open with attributes only shouldn't cause oplock break\n");
1192 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1193 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1194 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1195 io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
1196 status = smb_raw_open(cli2->tree, tctx, &io);
1197 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1198 fnum2 = io.ntcreatex.out.file.fnum;
1199 CHECK_VAL(io.ntcreatex.out.oplock_level, NO_OPLOCK_RETURN);
1200 CHECK_VAL(break_info.count, 0);
1201 CHECK_VAL(break_info.failures, 0);
1203 smbcli_close(cli1->tree, fnum);
1204 smbcli_close(cli2->tree, fnum2);
1207 smb_raw_exit(cli1->session);
1208 smb_raw_exit(cli2->session);
1209 smbcli_deltree(cli1->tree, BASEDIR);
1213 static bool test_raw_oplock_batch9(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1215 const char *fname = BASEDIR "\\test_batch9.dat";
1219 uint16_t fnum=0, fnum2=0;
1222 if (!torture_setup_dir(cli1, BASEDIR)) {
1227 smbcli_unlink(cli1->tree, fname);
1229 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1232 base ntcreatex parms
1234 io.generic.level = RAW_OPEN_NTCREATEX;
1235 io.ntcreatex.in.root_fid = 0;
1236 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1237 io.ntcreatex.in.alloc_size = 0;
1238 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1239 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1240 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1241 io.ntcreatex.in.create_options = 0;
1242 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1243 io.ntcreatex.in.security_flags = 0;
1244 io.ntcreatex.in.fname = fname;
1246 torture_comment(tctx, "open with attributes only can create file\n");
1248 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1249 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1250 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1251 io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
1252 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1253 status = smb_raw_open(cli1->tree, tctx, &io);
1254 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1255 fnum = io.ntcreatex.out.file.fnum;
1256 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1258 torture_comment(tctx, "Subsequent normal open should break oplock on attribute only open to level II\n");
1260 ZERO_STRUCT(break_info);
1261 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1263 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1264 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1265 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1266 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1267 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1268 status = smb_raw_open(cli2->tree, tctx, &io);
1269 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1270 fnum2 = io.ntcreatex.out.file.fnum;
1271 CHECK_VAL(break_info.count, 1);
1272 CHECK_VAL(break_info.fnum, fnum);
1273 CHECK_VAL(break_info.failures, 0);
1274 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
1275 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1276 smbcli_close(cli2->tree, fnum2);
1278 torture_comment(tctx, "third oplocked open should grant level2 without break\n");
1279 ZERO_STRUCT(break_info);
1280 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1281 smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli2->tree);
1282 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1283 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1284 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1285 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1286 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1287 status = smb_raw_open(cli2->tree, tctx, &io);
1288 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1289 fnum2 = io.ntcreatex.out.file.fnum;
1290 CHECK_VAL(break_info.count, 0);
1291 CHECK_VAL(break_info.failures, 0);
1292 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1294 ZERO_STRUCT(break_info);
1296 torture_comment(tctx, "write should trigger a break to none on both\n");
1297 smbcli_write(cli2->tree, fnum2, 0, &c, 0, 1);
1299 /* Now the oplock break request comes in. But right now we can't
1300 * answer it. Do another write */
1303 smbcli_write(cli2->tree, fnum2, 0, &c, 1, 1);
1305 CHECK_VAL(break_info.count, 2);
1306 CHECK_VAL(break_info.level, 0);
1307 CHECK_VAL(break_info.failures, 0);
1309 smbcli_close(cli1->tree, fnum);
1310 smbcli_close(cli2->tree, fnum2);
1313 smb_raw_exit(cli1->session);
1314 smb_raw_exit(cli2->session);
1315 smbcli_deltree(cli1->tree, BASEDIR);
1319 static bool test_raw_oplock_batch10(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1321 const char *fname = BASEDIR "\\test_batch10.dat";
1325 uint16_t fnum=0, fnum2=0;
1327 if (!torture_setup_dir(cli1, BASEDIR)) {
1332 smbcli_unlink(cli1->tree, fname);
1334 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1337 base ntcreatex parms
1339 io.generic.level = RAW_OPEN_NTCREATEX;
1340 io.ntcreatex.in.root_fid = 0;
1341 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1342 io.ntcreatex.in.alloc_size = 0;
1343 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1344 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1345 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1346 io.ntcreatex.in.create_options = 0;
1347 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1348 io.ntcreatex.in.security_flags = 0;
1349 io.ntcreatex.in.fname = fname;
1351 torture_comment(tctx, "Open with oplock after a non-oplock open should grant level2\n");
1352 ZERO_STRUCT(break_info);
1353 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
1354 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1355 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1356 NTCREATEX_SHARE_ACCESS_WRITE|
1357 NTCREATEX_SHARE_ACCESS_DELETE;
1358 status = smb_raw_open(cli1->tree, tctx, &io);
1359 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1360 fnum = io.ntcreatex.out.file.fnum;
1361 CHECK_VAL(break_info.count, 0);
1362 CHECK_VAL(break_info.failures, 0);
1363 CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
1365 smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli2->tree);
1367 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1368 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1369 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1370 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1371 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1372 NTCREATEX_SHARE_ACCESS_WRITE|
1373 NTCREATEX_SHARE_ACCESS_DELETE;
1374 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1375 status = smb_raw_open(cli2->tree, tctx, &io);
1376 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1377 fnum2 = io.ntcreatex.out.file.fnum;
1378 CHECK_VAL(break_info.count, 0);
1379 CHECK_VAL(break_info.failures, 0);
1380 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1382 torture_comment(tctx, "write should trigger a break to none\n");
1385 wr.write.level = RAW_WRITE_WRITE;
1386 wr.write.in.file.fnum = fnum;
1387 wr.write.in.count = 1;
1388 wr.write.in.offset = 0;
1389 wr.write.in.remaining = 0;
1390 wr.write.in.data = (const uint8_t *)"x";
1391 status = smb_raw_write(cli1->tree, &wr);
1392 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1395 /* Now the oplock break request comes in. But right now we can't
1396 * answer it. Do another write */
1402 wr.write.level = RAW_WRITE_WRITE;
1403 wr.write.in.file.fnum = fnum;
1404 wr.write.in.count = 1;
1405 wr.write.in.offset = 0;
1406 wr.write.in.remaining = 0;
1407 wr.write.in.data = (const uint8_t *)"x";
1408 status = smb_raw_write(cli1->tree, &wr);
1409 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1412 CHECK_VAL(break_info.count, 1);
1413 CHECK_VAL(break_info.fnum, fnum2);
1414 CHECK_VAL(break_info.level, 0);
1415 CHECK_VAL(break_info.failures, 0);
1417 smbcli_close(cli1->tree, fnum);
1418 smbcli_close(cli2->tree, fnum2);
1421 smb_raw_exit(cli1->session);
1422 smb_raw_exit(cli2->session);
1423 smbcli_deltree(cli1->tree, BASEDIR);
1427 static bool test_raw_oplock_batch11(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1429 const char *fname = BASEDIR "\\test_batch11.dat";
1433 union smb_setfileinfo sfi;
1436 if (!torture_setup_dir(cli1, BASEDIR)) {
1441 smbcli_unlink(cli1->tree, fname);
1443 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1446 base ntcreatex parms
1448 io.generic.level = RAW_OPEN_NTCREATEX;
1449 io.ntcreatex.in.root_fid = 0;
1450 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1451 io.ntcreatex.in.alloc_size = 0;
1452 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1453 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1454 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1455 io.ntcreatex.in.create_options = 0;
1456 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1457 io.ntcreatex.in.security_flags = 0;
1458 io.ntcreatex.in.fname = fname;
1460 /* Test if a set-eof on pathname breaks an exclusive oplock. */
1461 torture_comment(tctx, "Test if setpathinfo set EOF breaks oplocks.\n");
1463 ZERO_STRUCT(break_info);
1464 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1466 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1467 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1468 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1469 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1470 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1471 NTCREATEX_SHARE_ACCESS_WRITE|
1472 NTCREATEX_SHARE_ACCESS_DELETE;
1473 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1474 status = smb_raw_open(cli1->tree, tctx, &io);
1475 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1476 fnum = io.ntcreatex.out.file.fnum;
1477 CHECK_VAL(break_info.count, 0);
1478 CHECK_VAL(break_info.failures, 0);
1479 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1482 sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
1483 sfi.generic.in.file.path = fname;
1484 sfi.end_of_file_info.in.size = 100;
1486 status = smb_raw_setpathinfo(cli2->tree, &sfi);
1488 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1489 CHECK_VAL(break_info.count, 1);
1490 CHECK_VAL(break_info.failures, 0);
1491 CHECK_VAL(break_info.level, 0);
1493 smbcli_close(cli1->tree, fnum);
1496 smb_raw_exit(cli1->session);
1497 smb_raw_exit(cli2->session);
1498 smbcli_deltree(cli1->tree, BASEDIR);
1502 static bool test_raw_oplock_batch12(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1504 const char *fname = BASEDIR "\\test_batch12.dat";
1508 union smb_setfileinfo sfi;
1511 if (!torture_setup_dir(cli1, BASEDIR)) {
1516 smbcli_unlink(cli1->tree, fname);
1518 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1521 base ntcreatex parms
1523 io.generic.level = RAW_OPEN_NTCREATEX;
1524 io.ntcreatex.in.root_fid = 0;
1525 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1526 io.ntcreatex.in.alloc_size = 0;
1527 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1528 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1529 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1530 io.ntcreatex.in.create_options = 0;
1531 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1532 io.ntcreatex.in.security_flags = 0;
1533 io.ntcreatex.in.fname = fname;
1535 /* Test if a set-allocation size on pathname breaks an exclusive oplock. */
1536 torture_comment(tctx, "Test if setpathinfo allocation size breaks oplocks.\n");
1538 ZERO_STRUCT(break_info);
1539 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1541 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1542 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1543 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1544 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1545 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1546 NTCREATEX_SHARE_ACCESS_WRITE|
1547 NTCREATEX_SHARE_ACCESS_DELETE;
1548 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1549 status = smb_raw_open(cli1->tree, tctx, &io);
1550 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1551 fnum = io.ntcreatex.out.file.fnum;
1552 CHECK_VAL(break_info.count, 0);
1553 CHECK_VAL(break_info.failures, 0);
1554 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1557 sfi.generic.level = SMB_SFILEINFO_ALLOCATION_INFORMATION;
1558 sfi.generic.in.file.path = fname;
1559 sfi.allocation_info.in.alloc_size = 65536 * 8;
1561 status = smb_raw_setpathinfo(cli2->tree, &sfi);
1563 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1564 CHECK_VAL(break_info.count, 1);
1565 CHECK_VAL(break_info.failures, 0);
1566 CHECK_VAL(break_info.level, 0);
1568 smbcli_close(cli1->tree, fnum);
1571 smb_raw_exit(cli1->session);
1572 smb_raw_exit(cli2->session);
1573 smbcli_deltree(cli1->tree, BASEDIR);
1577 static bool test_raw_oplock_batch13(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1579 const char *fname = BASEDIR "\\test_batch13.dat";
1583 uint16_t fnum=0, fnum2=0;
1585 if (!torture_setup_dir(cli1, BASEDIR)) {
1590 smbcli_unlink(cli1->tree, fname);
1592 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1593 smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli1->tree);
1596 base ntcreatex parms
1598 io.generic.level = RAW_OPEN_NTCREATEX;
1599 io.ntcreatex.in.root_fid = 0;
1600 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1601 io.ntcreatex.in.alloc_size = 0;
1602 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1603 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1604 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1605 io.ntcreatex.in.create_options = 0;
1606 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1607 io.ntcreatex.in.security_flags = 0;
1608 io.ntcreatex.in.fname = fname;
1610 torture_comment(tctx, "open with batch oplock\n");
1611 ZERO_STRUCT(break_info);
1612 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1615 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1616 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1617 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1618 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1619 NTCREATEX_SHARE_ACCESS_WRITE|
1620 NTCREATEX_SHARE_ACCESS_DELETE;
1621 status = smb_raw_open(cli1->tree, tctx, &io);
1622 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1623 fnum = io.ntcreatex.out.file.fnum;
1624 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1626 ZERO_STRUCT(break_info);
1628 torture_comment(tctx, "second open with attributes only and NTCREATEX_DISP_OVERWRITE dispostion causes oplock break\n");
1630 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1631 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1632 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1633 io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
1634 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1635 NTCREATEX_SHARE_ACCESS_WRITE|
1636 NTCREATEX_SHARE_ACCESS_DELETE;
1637 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE;
1638 status = smb_raw_open(cli2->tree, tctx, &io);
1639 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1640 fnum2 = io.ntcreatex.out.file.fnum;
1641 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1642 CHECK_VAL(break_info.count, 1);
1643 CHECK_VAL(break_info.failures, 0);
1645 smbcli_close(cli1->tree, fnum);
1646 smbcli_close(cli2->tree, fnum2);
1649 smb_raw_exit(cli1->session);
1650 smb_raw_exit(cli2->session);
1651 smbcli_deltree(cli1->tree, BASEDIR);
1655 static bool test_raw_oplock_batch14(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1657 const char *fname = BASEDIR "\\test_batch14.dat";
1661 uint16_t fnum=0, fnum2=0;
1663 if (!torture_setup_dir(cli1, BASEDIR)) {
1668 smbcli_unlink(cli1->tree, fname);
1670 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1673 base ntcreatex parms
1675 io.generic.level = RAW_OPEN_NTCREATEX;
1676 io.ntcreatex.in.root_fid = 0;
1677 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1678 io.ntcreatex.in.alloc_size = 0;
1679 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1680 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1681 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1682 io.ntcreatex.in.create_options = 0;
1683 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1684 io.ntcreatex.in.security_flags = 0;
1685 io.ntcreatex.in.fname = fname;
1687 torture_comment(tctx, "open with batch oplock\n");
1688 ZERO_STRUCT(break_info);
1689 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1691 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1692 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1693 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1694 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1695 NTCREATEX_SHARE_ACCESS_WRITE|
1696 NTCREATEX_SHARE_ACCESS_DELETE;
1697 status = smb_raw_open(cli1->tree, tctx, &io);
1698 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1699 fnum = io.ntcreatex.out.file.fnum;
1700 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1702 ZERO_STRUCT(break_info);
1704 torture_comment(tctx, "second open with attributes only and NTCREATEX_DISP_SUPERSEDE dispostion causes oplock break\n");
1706 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1707 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1708 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1709 io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
1710 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1711 NTCREATEX_SHARE_ACCESS_WRITE|
1712 NTCREATEX_SHARE_ACCESS_DELETE;
1713 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE;
1714 status = smb_raw_open(cli2->tree, tctx, &io);
1715 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1716 fnum2 = io.ntcreatex.out.file.fnum;
1717 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1718 CHECK_VAL(break_info.count, 1);
1719 CHECK_VAL(break_info.failures, 0);
1721 smbcli_close(cli1->tree, fnum);
1722 smbcli_close(cli2->tree, fnum2);
1724 smb_raw_exit(cli1->session);
1725 smb_raw_exit(cli2->session);
1726 smbcli_deltree(cli1->tree, BASEDIR);
1730 static bool test_raw_oplock_batch15(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1732 const char *fname = BASEDIR "\\test_batch15.dat";
1736 union smb_fileinfo qfi;
1739 if (!torture_setup_dir(cli1, BASEDIR)) {
1744 smbcli_unlink(cli1->tree, fname);
1746 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1749 base ntcreatex parms
1751 io.generic.level = RAW_OPEN_NTCREATEX;
1752 io.ntcreatex.in.root_fid = 0;
1753 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1754 io.ntcreatex.in.alloc_size = 0;
1755 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1756 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1757 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1758 io.ntcreatex.in.create_options = 0;
1759 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1760 io.ntcreatex.in.security_flags = 0;
1761 io.ntcreatex.in.fname = fname;
1763 /* Test if a qpathinfo all info on pathname breaks a batch oplock. */
1764 torture_comment(tctx, "Test if qpathinfo all info breaks a batch oplock (should not).\n");
1766 ZERO_STRUCT(break_info);
1767 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1769 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1770 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1771 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1772 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1773 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1774 NTCREATEX_SHARE_ACCESS_WRITE|
1775 NTCREATEX_SHARE_ACCESS_DELETE;
1776 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1777 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1778 status = smb_raw_open(cli1->tree, tctx, &io);
1779 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1780 fnum = io.ntcreatex.out.file.fnum;
1781 CHECK_VAL(break_info.count, 0);
1782 CHECK_VAL(break_info.failures, 0);
1783 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1786 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
1787 qfi.generic.in.file.path = fname;
1789 status = smb_raw_pathinfo(cli2->tree, tctx, &qfi);
1791 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1792 CHECK_VAL(break_info.count, 0);
1794 smbcli_close(cli1->tree, fnum);
1797 smb_raw_exit(cli1->session);
1798 smb_raw_exit(cli2->session);
1799 smbcli_deltree(cli1->tree, BASEDIR);
1803 static bool test_raw_oplock_batch16(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1805 const char *fname = BASEDIR "\\test_batch16.dat";
1809 uint16_t fnum=0, fnum2=0;
1811 if (!torture_setup_dir(cli1, BASEDIR)) {
1816 smbcli_unlink(cli1->tree, fname);
1818 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1819 smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli1->tree);
1822 base ntcreatex parms
1824 io.generic.level = RAW_OPEN_NTCREATEX;
1825 io.ntcreatex.in.root_fid = 0;
1826 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1827 io.ntcreatex.in.alloc_size = 0;
1828 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1829 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1830 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1831 io.ntcreatex.in.create_options = 0;
1832 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1833 io.ntcreatex.in.security_flags = 0;
1834 io.ntcreatex.in.fname = fname;
1836 torture_comment(tctx, "open with batch oplock\n");
1837 ZERO_STRUCT(break_info);
1838 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1841 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1842 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1843 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1844 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1845 NTCREATEX_SHARE_ACCESS_WRITE|
1846 NTCREATEX_SHARE_ACCESS_DELETE;
1847 status = smb_raw_open(cli1->tree, tctx, &io);
1848 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1849 fnum = io.ntcreatex.out.file.fnum;
1850 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1852 ZERO_STRUCT(break_info);
1854 torture_comment(tctx, "second open with attributes only and NTCREATEX_DISP_OVERWRITE_IF dispostion causes oplock break\n");
1856 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1857 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1858 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1859 io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
1860 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1861 NTCREATEX_SHARE_ACCESS_WRITE|
1862 NTCREATEX_SHARE_ACCESS_DELETE;
1863 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE_IF;
1864 status = smb_raw_open(cli2->tree, tctx, &io);
1865 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1866 fnum2 = io.ntcreatex.out.file.fnum;
1867 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1868 CHECK_VAL(break_info.count, 1);
1869 CHECK_VAL(break_info.failures, 0);
1871 smbcli_close(cli1->tree, fnum);
1872 smbcli_close(cli2->tree, fnum2);
1875 smb_raw_exit(cli1->session);
1876 smb_raw_exit(cli2->session);
1877 smbcli_deltree(cli1->tree, BASEDIR);
1881 static bool test_raw_oplock_batch17(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1883 const char *fname1 = BASEDIR "\\test_batch17_1.dat";
1884 const char *fname2 = BASEDIR "\\test_batch17_2.dat";
1888 union smb_rename rn;
1890 bool s3 = torture_setting_bool(tctx, "samba3", false);
1892 if (!torture_setup_dir(cli1, BASEDIR)) {
1897 smbcli_unlink(cli1->tree, fname1);
1898 smbcli_unlink(cli1->tree, fname2);
1900 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1903 base ntcreatex parms
1905 io.generic.level = RAW_OPEN_NTCREATEX;
1906 io.ntcreatex.in.root_fid = 0;
1907 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1908 io.ntcreatex.in.alloc_size = 0;
1909 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1910 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1911 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1912 io.ntcreatex.in.create_options = 0;
1913 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1914 io.ntcreatex.in.security_flags = 0;
1915 io.ntcreatex.in.fname = fname1;
1917 /* we should use no share mode, when samba3 passes this */
1918 torture_comment(tctx, "open a file with an batch oplock (share mode: %s)\n",
1920 ZERO_STRUCT(break_info);
1921 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1922 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1923 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1925 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1926 NTCREATEX_SHARE_ACCESS_WRITE|
1927 NTCREATEX_SHARE_ACCESS_DELETE;
1930 status = smb_raw_open(cli1->tree, tctx, &io);
1931 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1932 fnum = io.ntcreatex.out.file.fnum;
1933 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1935 torture_comment(tctx, "rename should trigger a break\n");
1937 rn.generic.level = RAW_RENAME_RENAME;
1938 rn.rename.in.pattern1 = fname1;
1939 rn.rename.in.pattern2 = fname2;
1940 rn.rename.in.attrib = 0;
1942 printf("trying rename while first file open\n");
1943 status = smb_raw_rename(cli2->tree, &rn);
1945 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
1946 CHECK_VAL(break_info.count, 1);
1947 CHECK_VAL(break_info.failures, 0);
1948 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
1950 smbcli_close(cli1->tree, fnum);
1953 smb_raw_exit(cli1->session);
1954 smb_raw_exit(cli2->session);
1955 smbcli_deltree(cli1->tree, BASEDIR);
1959 static bool test_raw_oplock_batch18(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1961 const char *fname1 = BASEDIR "\\test_batch18_1.dat";
1962 const char *fname2 = BASEDIR "\\test_batch18_2.dat";
1966 union smb_rename rn;
1968 bool s3 = torture_setting_bool(tctx, "samba3", false);
1970 if (!torture_setup_dir(cli1, BASEDIR)) {
1975 smbcli_unlink(cli1->tree, fname1);
1976 smbcli_unlink(cli1->tree, fname2);
1978 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1981 base ntcreatex parms
1983 io.generic.level = RAW_OPEN_NTCREATEX;
1984 io.ntcreatex.in.root_fid = 0;
1985 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1986 io.ntcreatex.in.alloc_size = 0;
1987 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1988 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1989 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1990 io.ntcreatex.in.create_options = 0;
1991 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1992 io.ntcreatex.in.security_flags = 0;
1993 io.ntcreatex.in.fname = fname1;
1995 /* we should use no share mode, when samba3 passes this */
1996 torture_comment(tctx, "open a file with an batch oplock (share mode: %s)\n",
1998 ZERO_STRUCT(break_info);
1999 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2000 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2001 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2003 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
2004 NTCREATEX_SHARE_ACCESS_WRITE|
2005 NTCREATEX_SHARE_ACCESS_DELETE;
2008 status = smb_raw_open(cli1->tree, tctx, &io);
2009 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2010 fnum = io.ntcreatex.out.file.fnum;
2011 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
2013 torture_comment(tctx, "ntrename should trigger a break\n");
2015 rn.generic.level = RAW_RENAME_NTRENAME;
2016 rn.ntrename.in.attrib = 0;
2017 rn.ntrename.in.flags = RENAME_FLAG_RENAME;
2018 rn.ntrename.in.old_name = fname1;
2019 rn.ntrename.in.new_name = fname2;
2020 printf("trying rename while first file open\n");
2021 status = smb_raw_rename(cli2->tree, &rn);
2023 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
2024 CHECK_VAL(break_info.count, 1);
2025 CHECK_VAL(break_info.failures, 0);
2026 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
2028 smbcli_close(cli1->tree, fnum);
2031 smb_raw_exit(cli1->session);
2032 smb_raw_exit(cli2->session);
2033 smbcli_deltree(cli1->tree, BASEDIR);
2037 static bool test_raw_oplock_batch19(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
2039 const char *fname1 = BASEDIR "\\test_batch19_1.dat";
2040 const char *fname2 = BASEDIR "\\test_batch19_2.dat";
2041 const char *fname3 = BASEDIR "\\test_batch19_3.dat";
2045 union smb_fileinfo qfi;
2046 union smb_setfileinfo sfi;
2049 if (torture_setting_bool(tctx, "samba3", false)) {
2050 torture_skip(tctx, "BACHT19 disabled against samba3\n");
2053 if (!torture_setup_dir(cli1, BASEDIR)) {
2058 smbcli_unlink(cli1->tree, fname1);
2059 smbcli_unlink(cli1->tree, fname2);
2060 smbcli_unlink(cli1->tree, fname3);
2062 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2065 base ntcreatex parms
2067 io.generic.level = RAW_OPEN_NTCREATEX;
2068 io.ntcreatex.in.root_fid = 0;
2069 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2070 io.ntcreatex.in.alloc_size = 0;
2071 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2072 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2073 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2074 io.ntcreatex.in.create_options = 0;
2075 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2076 io.ntcreatex.in.security_flags = 0;
2077 io.ntcreatex.in.fname = fname1;
2079 torture_comment(tctx, "open a file with an batch oplock (share mode: none)\n");
2080 ZERO_STRUCT(break_info);
2081 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2082 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2083 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2084 status = smb_raw_open(cli1->tree, tctx, &io);
2085 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2086 fnum = io.ntcreatex.out.file.fnum;
2087 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
2089 torture_comment(tctx, "setpathinfo rename info should not trigger a break nor a violation\n");
2091 sfi.generic.level = RAW_SFILEINFO_RENAME_INFORMATION;
2092 sfi.generic.in.file.path = fname1;
2093 sfi.rename_information.in.overwrite = 0;
2094 sfi.rename_information.in.root_fid = 0;
2095 sfi.rename_information.in.new_name = fname2+strlen(BASEDIR)+1;
2097 status = smb_raw_setpathinfo(cli2->tree, &sfi);
2099 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2100 CHECK_VAL(break_info.count, 0);
2103 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2104 qfi.generic.in.file.fnum = fnum;
2106 status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
2107 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2108 CHECK_STRMATCH(qfi.all_info.out.fname.s, fname2);
2110 torture_comment(tctx, "setfileinfo rename info should not trigger a break nor a violation\n");
2112 sfi.generic.level = RAW_SFILEINFO_RENAME_INFORMATION;
2113 sfi.generic.in.file.fnum = fnum;
2114 sfi.rename_information.in.overwrite = 0;
2115 sfi.rename_information.in.root_fid = 0;
2116 sfi.rename_information.in.new_name = fname3+strlen(BASEDIR)+1;
2118 status = smb_raw_setfileinfo(cli1->tree, &sfi);
2119 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2120 CHECK_VAL(break_info.count, 0);
2123 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2124 qfi.generic.in.file.fnum = fnum;
2126 status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
2127 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2128 CHECK_STRMATCH(qfi.all_info.out.fname.s, fname3);
2130 smbcli_close(cli1->tree, fnum);
2133 smb_raw_exit(cli1->session);
2134 smb_raw_exit(cli2->session);
2135 smbcli_deltree(cli1->tree, BASEDIR);
2139 static bool test_raw_oplock_batch20(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
2141 const char *fname1 = BASEDIR "\\test_batch20_1.dat";
2142 const char *fname2 = BASEDIR "\\test_batch20_2.dat";
2143 const char *fname3 = BASEDIR "\\test_batch20_3.dat";
2147 union smb_fileinfo qfi;
2148 union smb_setfileinfo sfi;
2149 uint16_t fnum=0,fnum2=0;
2151 if (torture_setting_bool(tctx, "samba3", false)) {
2152 torture_skip(tctx, "BACHT20 disabled against samba3\n");
2155 if (!torture_setup_dir(cli1, BASEDIR)) {
2160 smbcli_unlink(cli1->tree, fname1);
2161 smbcli_unlink(cli1->tree, fname2);
2162 smbcli_unlink(cli1->tree, fname3);
2164 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2167 base ntcreatex parms
2169 io.generic.level = RAW_OPEN_NTCREATEX;
2170 io.ntcreatex.in.root_fid = 0;
2171 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2172 io.ntcreatex.in.alloc_size = 0;
2173 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2174 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2175 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2176 io.ntcreatex.in.create_options = 0;
2177 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2178 io.ntcreatex.in.security_flags = 0;
2179 io.ntcreatex.in.fname = fname1;
2181 torture_comment(tctx, "open a file with an batch oplock (share mode: all)\n");
2182 ZERO_STRUCT(break_info);
2183 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2184 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2185 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2186 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
2187 NTCREATEX_SHARE_ACCESS_WRITE|
2188 NTCREATEX_SHARE_ACCESS_DELETE;
2189 status = smb_raw_open(cli1->tree, tctx, &io);
2190 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2191 fnum = io.ntcreatex.out.file.fnum;
2192 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
2194 torture_comment(tctx, "setpathinfo rename info should not trigger a break nor a violation\n");
2196 sfi.generic.level = RAW_SFILEINFO_RENAME_INFORMATION;
2197 sfi.generic.in.file.path = fname1;
2198 sfi.rename_information.in.overwrite = 0;
2199 sfi.rename_information.in.root_fid = 0;
2200 sfi.rename_information.in.new_name = fname2+strlen(BASEDIR)+1;
2202 status = smb_raw_setpathinfo(cli2->tree, &sfi);
2204 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2205 CHECK_VAL(break_info.count, 0);
2208 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2209 qfi.generic.in.file.fnum = fnum;
2211 status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
2212 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2213 CHECK_STRMATCH(qfi.all_info.out.fname.s, fname2);
2215 /* we should use no share mode, when samba3 passes this */
2216 torture_comment(tctx, "open a file with the new name an batch oplock (share mode: all)\n");
2217 ZERO_STRUCT(break_info);
2218 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2219 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2220 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2221 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
2222 NTCREATEX_SHARE_ACCESS_WRITE|
2223 NTCREATEX_SHARE_ACCESS_DELETE;
2224 io.ntcreatex.in.fname = fname2;
2225 status = smb_raw_open(cli2->tree, tctx, &io);
2226 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2227 fnum2 = io.ntcreatex.out.file.fnum;
2228 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
2229 CHECK_VAL(break_info.count, 1);
2230 CHECK_VAL(break_info.failures, 0);
2231 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
2233 torture_comment(tctx, "setfileinfo rename info should not trigger a break nor a violation\n");
2235 sfi.generic.level = RAW_SFILEINFO_RENAME_INFORMATION;
2236 sfi.generic.in.file.fnum = fnum;
2237 sfi.rename_information.in.overwrite = 0;
2238 sfi.rename_information.in.root_fid = 0;
2239 sfi.rename_information.in.new_name = fname3+strlen(BASEDIR)+1;
2241 status = smb_raw_setfileinfo(cli1->tree, &sfi);
2242 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2243 CHECK_VAL(break_info.count, 1);
2244 CHECK_VAL(break_info.failures, 0);
2245 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
2248 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2249 qfi.generic.in.file.fnum = fnum;
2251 status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
2252 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2253 CHECK_STRMATCH(qfi.all_info.out.fname.s, fname3);
2256 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2257 qfi.generic.in.file.fnum = fnum2;
2259 status = smb_raw_fileinfo(cli2->tree, tctx, &qfi);
2260 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2261 CHECK_STRMATCH(qfi.all_info.out.fname.s, fname3);
2263 smbcli_close(cli1->tree, fnum);
2266 smb_raw_exit(cli1->session);
2267 smb_raw_exit(cli2->session);
2268 smbcli_deltree(cli1->tree, BASEDIR);
2272 static bool test_raw_oplock_batch21(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
2274 const char *fname = BASEDIR "\\test_batch21.dat";
2283 if (!torture_setup_dir(cli1, BASEDIR)) {
2288 smbcli_unlink(cli1->tree, fname);
2290 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2293 base ntcreatex parms
2295 io.generic.level = RAW_OPEN_NTCREATEX;
2296 io.ntcreatex.in.root_fid = 0;
2297 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2298 io.ntcreatex.in.alloc_size = 0;
2299 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2300 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2301 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2302 io.ntcreatex.in.create_options = 0;
2303 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2304 io.ntcreatex.in.security_flags = 0;
2305 io.ntcreatex.in.fname = fname;
2308 with a batch oplock we get a break
2310 torture_comment(tctx, "open with batch oplock\n");
2311 ZERO_STRUCT(break_info);
2312 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2313 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2314 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2315 status = smb_raw_open(cli1->tree, tctx, &io);
2316 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2317 fnum = io.ntcreatex.out.file.fnum;
2318 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
2320 torture_comment(tctx, "writing should not generate a break\n");
2321 wr = smbcli_write(cli1->tree, fnum, 0, &c, 0, 1);
2323 CHECK_STATUS(tctx, smbcli_nt_error(cli1->tree), NT_STATUS_OK);
2326 e.in.repeat_count = 1;
2327 status = smb_raw_echo(cli1->transport, &e);
2328 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2330 CHECK_VAL(break_info.count, 0);
2332 smbcli_close(cli1->tree, fnum);
2335 smb_raw_exit(cli1->session);
2336 smb_raw_exit(cli2->session);
2337 smbcli_deltree(cli1->tree, BASEDIR);
2341 static bool test_raw_oplock_batch22(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
2343 const char *fname = BASEDIR "\\test_batch22.dat";
2347 uint16_t fnum=0, fnum2=0;
2349 int timeout = torture_setting_int(tctx, "oplocktimeout", 30);
2352 if (torture_setting_bool(tctx, "samba3", false)) {
2353 torture_skip(tctx, "BACHT22 disabled against samba3\n");
2356 if (!torture_setup_dir(cli1, BASEDIR)) {
2361 smbcli_unlink(cli1->tree, fname);
2363 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2366 base ntcreatex parms
2368 io.generic.level = RAW_OPEN_NTCREATEX;
2369 io.ntcreatex.in.root_fid = 0;
2370 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2371 io.ntcreatex.in.alloc_size = 0;
2372 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2373 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2374 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2375 io.ntcreatex.in.create_options = 0;
2376 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2377 io.ntcreatex.in.security_flags = 0;
2378 io.ntcreatex.in.fname = fname;
2381 with a batch oplock we get a break
2383 torture_comment(tctx, "open with batch oplock\n");
2384 ZERO_STRUCT(break_info);
2385 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2386 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2387 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2388 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
2389 NTCREATEX_SHARE_ACCESS_WRITE|
2390 NTCREATEX_SHARE_ACCESS_DELETE;
2391 status = smb_raw_open(cli1->tree, tctx, &io);
2392 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2393 fnum = io.ntcreatex.out.file.fnum;
2394 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
2396 torture_comment(tctx, "a 2nd open shoud not succeed after the oplock break timeout\n");
2397 tv = timeval_current();
2398 smbcli_oplock_handler(cli1->transport, oplock_handler_timeout, cli1->tree);
2399 status = smb_raw_open(cli1->tree, tctx, &io);
2400 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
2401 te = (int)timeval_elapsed(&tv);
2402 CHECK_RANGE(te, timeout - 1, timeout + 15);
2404 CHECK_VAL(break_info.count, 1);
2405 CHECK_VAL(break_info.fnum, fnum);
2406 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
2407 CHECK_VAL(break_info.failures, 0);
2408 ZERO_STRUCT(break_info);
2410 torture_comment(tctx, "a 2nd open shoud succeed after the oplock release without break\n");
2411 tv = timeval_current();
2412 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2413 status = smb_raw_open(cli1->tree, tctx, &io);
2414 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2415 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
2416 te = (int)timeval_elapsed(&tv);
2417 /* it should come in without delay */
2418 CHECK_RANGE(te+1, 0, timeout);
2419 fnum2 = io.ntcreatex.out.file.fnum;
2421 CHECK_VAL(break_info.count, 0);
2423 smbcli_close(cli1->tree, fnum);
2424 smbcli_close(cli1->tree, fnum2);
2427 smb_raw_exit(cli1->session);
2428 smb_raw_exit(cli2->session);
2429 smbcli_deltree(cli1->tree, BASEDIR);
2433 static bool test_raw_oplock_batch23(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
2435 const char *fname = BASEDIR "\\test_batch23.dat";
2439 uint16_t fnum=0, fnum2=0,fnum3=0;
2440 struct smbcli_state *cli3 = NULL;
2442 if (torture_setting_bool(tctx, "samba3", false)) {
2443 torture_skip(tctx, "BACHT23 disabled against samba3\n");
2446 if (!torture_setup_dir(cli1, BASEDIR)) {
2451 smbcli_unlink(cli1->tree, fname);
2453 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2455 ret = open_connection_no_level2_oplocks(tctx, &cli3);
2456 CHECK_VAL(ret, true);
2459 base ntcreatex parms
2461 io.generic.level = RAW_OPEN_NTCREATEX;
2462 io.ntcreatex.in.root_fid = 0;
2463 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2464 io.ntcreatex.in.alloc_size = 0;
2465 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2466 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2467 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2468 io.ntcreatex.in.create_options = 0;
2469 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2470 io.ntcreatex.in.security_flags = 0;
2471 io.ntcreatex.in.fname = fname;
2473 torture_comment(tctx, "a open and ask for a batch oplock\n");
2474 ZERO_STRUCT(break_info);
2475 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2476 smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli2->tree);
2477 smbcli_oplock_handler(cli3->transport, oplock_handler_ack_to_given, cli3->tree);
2479 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_READ | SEC_RIGHTS_FILE_WRITE;
2480 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
2481 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2482 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2483 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2484 status = smb_raw_open(cli1->tree, tctx, &io);
2485 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2486 fnum = io.ntcreatex.out.file.fnum;
2487 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
2489 ZERO_STRUCT(break_info);
2491 torture_comment(tctx, "a 2nd open without level2 oplock support should generate a break to level2\n");
2492 status = smb_raw_open(cli3->tree, tctx, &io);
2493 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2494 fnum3 = io.ntcreatex.out.file.fnum;
2495 CHECK_VAL(io.ntcreatex.out.oplock_level, NO_OPLOCK_RETURN);
2497 CHECK_VAL(break_info.count, 1);
2498 CHECK_VAL(break_info.fnum, fnum);
2499 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
2500 CHECK_VAL(break_info.failures, 0);
2502 ZERO_STRUCT(break_info);
2504 torture_comment(tctx, "a 3rd open with level2 oplock support should not generate a break\n");
2505 status = smb_raw_open(cli2->tree, tctx, &io);
2506 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2507 fnum2 = io.ntcreatex.out.file.fnum;
2508 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
2510 CHECK_VAL(break_info.count, 0);
2512 smbcli_close(cli1->tree, fnum);
2513 smbcli_close(cli2->tree, fnum2);
2514 smbcli_close(cli3->tree, fnum3);
2517 smb_raw_exit(cli1->session);
2518 smb_raw_exit(cli2->session);
2519 smb_raw_exit(cli3->session);
2520 smbcli_deltree(cli1->tree, BASEDIR);
2524 static bool test_raw_oplock_batch24(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
2526 const char *fname = BASEDIR "\\test_batch24.dat";
2530 uint16_t fnum2=0,fnum3=0;
2531 struct smbcli_state *cli3 = NULL;
2533 if (!torture_setup_dir(cli1, BASEDIR)) {
2538 smbcli_unlink(cli1->tree, fname);
2540 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2542 ret = open_connection_no_level2_oplocks(tctx, &cli3);
2543 CHECK_VAL(ret, true);
2546 base ntcreatex parms
2548 io.generic.level = RAW_OPEN_NTCREATEX;
2549 io.ntcreatex.in.root_fid = 0;
2550 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2551 io.ntcreatex.in.alloc_size = 0;
2552 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2553 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2554 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2555 io.ntcreatex.in.create_options = 0;
2556 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2557 io.ntcreatex.in.security_flags = 0;
2558 io.ntcreatex.in.fname = fname;
2560 torture_comment(tctx, "a open without level support and ask for a batch oplock\n");
2561 ZERO_STRUCT(break_info);
2562 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2563 smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli2->tree);
2564 smbcli_oplock_handler(cli3->transport, oplock_handler_ack_to_given, cli3->tree);
2566 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_READ | SEC_RIGHTS_FILE_WRITE;
2567 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
2568 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2569 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2570 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2571 status = smb_raw_open(cli3->tree, tctx, &io);
2572 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2573 fnum3 = io.ntcreatex.out.file.fnum;
2574 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
2576 ZERO_STRUCT(break_info);
2578 torture_comment(tctx, "a 2nd open with level2 oplock support should generate a break to none\n");
2579 status = smb_raw_open(cli2->tree, tctx, &io);
2580 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2581 fnum2 = io.ntcreatex.out.file.fnum;
2582 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
2584 CHECK_VAL(break_info.count, 1);
2585 CHECK_VAL(break_info.fnum, fnum3);
2586 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_NONE);
2587 CHECK_VAL(break_info.failures, 0);
2589 smbcli_close(cli3->tree, fnum3);
2590 smbcli_close(cli2->tree, fnum2);
2593 smb_raw_exit(cli1->session);
2594 smb_raw_exit(cli2->session);
2595 smb_raw_exit(cli3->session);
2596 smbcli_deltree(cli1->tree, BASEDIR);
2601 basic testing of oplocks
2603 struct torture_suite *torture_raw_oplock(TALLOC_CTX *mem_ctx)
2605 struct torture_suite *suite = torture_suite_create(mem_ctx, "OPLOCK");
2607 torture_suite_add_2smb_test(suite, "EXCLUSIVE1", test_raw_oplock_exclusive1);
2608 torture_suite_add_2smb_test(suite, "EXCLUSIVE2", test_raw_oplock_exclusive2);
2609 torture_suite_add_2smb_test(suite, "EXCLUSIVE3", test_raw_oplock_exclusive3);
2610 torture_suite_add_2smb_test(suite, "EXCLUSIVE4", test_raw_oplock_exclusive4);
2611 torture_suite_add_2smb_test(suite, "EXCLUSIVE5", test_raw_oplock_exclusive5);
2612 torture_suite_add_2smb_test(suite, "EXCLUSIVE6", test_raw_oplock_exclusive6);
2613 torture_suite_add_2smb_test(suite, "BATCH1", test_raw_oplock_batch1);
2614 torture_suite_add_2smb_test(suite, "BATCH2", test_raw_oplock_batch2);
2615 torture_suite_add_2smb_test(suite, "BATCH3", test_raw_oplock_batch3);
2616 torture_suite_add_2smb_test(suite, "BATCH4", test_raw_oplock_batch4);
2617 torture_suite_add_2smb_test(suite, "BATCH5", test_raw_oplock_batch5);
2618 torture_suite_add_2smb_test(suite, "BATCH6", test_raw_oplock_batch6);
2619 torture_suite_add_2smb_test(suite, "BATCH7", test_raw_oplock_batch7);
2620 torture_suite_add_2smb_test(suite, "BATCH8", test_raw_oplock_batch8);
2621 torture_suite_add_2smb_test(suite, "BATCH9", test_raw_oplock_batch9);
2622 torture_suite_add_2smb_test(suite, "BATCH10", test_raw_oplock_batch10);
2623 torture_suite_add_2smb_test(suite, "BATCH11", test_raw_oplock_batch11);
2624 torture_suite_add_2smb_test(suite, "BATCH12", test_raw_oplock_batch12);
2625 torture_suite_add_2smb_test(suite, "BATCH13", test_raw_oplock_batch13);
2626 torture_suite_add_2smb_test(suite, "BATCH14", test_raw_oplock_batch14);
2627 torture_suite_add_2smb_test(suite, "BATCH15", test_raw_oplock_batch15);
2628 torture_suite_add_2smb_test(suite, "BATCH16", test_raw_oplock_batch16);
2629 torture_suite_add_2smb_test(suite, "BATCH17", test_raw_oplock_batch17);
2630 torture_suite_add_2smb_test(suite, "BATCH18", test_raw_oplock_batch18);
2631 torture_suite_add_2smb_test(suite, "BATCH19", test_raw_oplock_batch19);
2632 torture_suite_add_2smb_test(suite, "BATCH20", test_raw_oplock_batch20);
2633 torture_suite_add_2smb_test(suite, "BATCH21", test_raw_oplock_batch21);
2634 torture_suite_add_2smb_test(suite, "BATCH22", test_raw_oplock_batch22);
2635 torture_suite_add_2smb_test(suite, "BATCH23", test_raw_oplock_batch23);
2636 torture_suite_add_2smb_test(suite, "BATCH24", test_raw_oplock_batch24);
2642 stress testing of oplocks
2644 bool torture_bench_oplock(struct torture_context *torture)
2646 struct smbcli_state **cli;
2648 TALLOC_CTX *mem_ctx = talloc_new(torture);
2649 int torture_nprocs = torture_setting_int(torture, "nprocs", 4);
2651 int timelimit = torture_setting_int(torture, "timelimit", 10);
2654 struct event_context *ev = event_context_find(mem_ctx);
2656 cli = talloc_array(mem_ctx, struct smbcli_state *, torture_nprocs);
2658 torture_comment(torture, "Opening %d connections\n", torture_nprocs);
2659 for (i=0;i<torture_nprocs;i++) {
2660 if (!torture_open_connection_ev(&cli[i], i, torture, ev)) {
2663 talloc_steal(mem_ctx, cli[i]);
2664 smbcli_oplock_handler(cli[i]->transport, oplock_handler_close,
2668 if (!torture_setup_dir(cli[0], BASEDIR)) {
2673 io.ntcreatex.level = RAW_OPEN_NTCREATEX;
2674 io.ntcreatex.in.root_fid = 0;
2675 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2676 io.ntcreatex.in.alloc_size = 0;
2677 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2678 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2679 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2680 io.ntcreatex.in.create_options = 0;
2681 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2682 io.ntcreatex.in.security_flags = 0;
2683 io.ntcreatex.in.fname = BASEDIR "\\test.dat";
2684 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2685 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2686 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2688 tv = timeval_current();
2691 we open the same file with SHARE_ACCESS_NONE from all the
2692 connections in a round robin fashion. Each open causes an
2693 oplock break on the previous connection, which is answered
2694 by the oplock_handler_close() to close the file.
2696 This measures how fast we can pass on oplocks, and stresses
2697 the oplock handling code
2699 torture_comment(torture, "Running for %d seconds\n", timelimit);
2700 while (timeval_elapsed(&tv) < timelimit) {
2701 for (i=0;i<torture_nprocs;i++) {
2704 status = smb_raw_open(cli[i]->tree, mem_ctx, &io);
2705 CHECK_STATUS(torture, status, NT_STATUS_OK);
2709 if (torture_setting_bool(torture, "progress", true)) {
2710 torture_comment(torture, "%.2f ops/second\r", count/timeval_elapsed(&tv));
2714 torture_comment(torture, "%.2f ops/second\n", count/timeval_elapsed(&tv));
2716 smb_raw_exit(cli[torture_nprocs-1]->session);
2719 smb_raw_exit(cli[0]->session);
2720 smbcli_deltree(cli[0]->tree, BASEDIR);
2721 talloc_free(mem_ctx);
2726 static struct hold_oplock_info {
2728 bool close_on_break;
2729 uint32_t share_access;
2732 { BASEDIR "\\notshared_close", true,
2733 NTCREATEX_SHARE_ACCESS_NONE, },
2734 { BASEDIR "\\notshared_noclose", false,
2735 NTCREATEX_SHARE_ACCESS_NONE, },
2736 { BASEDIR "\\shared_close", true,
2737 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE, },
2738 { BASEDIR "\\shared_noclose", false,
2739 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE, },
2742 static bool oplock_handler_hold(struct smbcli_transport *transport,
2743 uint16_t tid, uint16_t fnum, uint8_t level,
2746 struct smbcli_tree *tree = (struct smbcli_tree *)private;
2747 struct hold_oplock_info *info;
2750 for (i=0;i<ARRAY_SIZE(hold_info);i++) {
2751 if (hold_info[i].fnum == fnum) break;
2754 if (i == ARRAY_SIZE(hold_info)) {
2755 printf("oplock break for unknown fnum %u\n", fnum);
2759 info = &hold_info[i];
2761 if (info->close_on_break) {
2762 printf("oplock break on %s - closing\n",
2764 oplock_handler_close(transport, tid, fnum, level, private);
2768 printf("oplock break on %s - acking break\n", info->fname);
2770 return smbcli_oplock_ack(tree, fnum, OPLOCK_BREAK_TO_NONE);
2775 used for manual testing of oplocks - especially interaction with
2776 other filesystems (such as NFS and local access)
2778 bool torture_hold_oplock(struct torture_context *torture,
2779 struct smbcli_state *cli)
2781 struct event_context *ev =
2782 (struct event_context *)cli->transport->socket->event.ctx;
2785 printf("Setting up open files with oplocks in %s\n", BASEDIR);
2787 if (!torture_setup_dir(cli, BASEDIR)) {
2791 smbcli_oplock_handler(cli->transport, oplock_handler_hold, cli->tree);
2793 /* setup the files */
2794 for (i=0;i<ARRAY_SIZE(hold_info);i++) {
2799 io.generic.level = RAW_OPEN_NTCREATEX;
2800 io.ntcreatex.in.root_fid = 0;
2801 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2802 io.ntcreatex.in.alloc_size = 0;
2803 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2804 io.ntcreatex.in.share_access = hold_info[i].share_access;
2805 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2806 io.ntcreatex.in.create_options = 0;
2807 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2808 io.ntcreatex.in.security_flags = 0;
2809 io.ntcreatex.in.fname = hold_info[i].fname;
2810 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2811 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2812 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2813 printf("opening %s\n", hold_info[i].fname);
2815 status = smb_raw_open(cli->tree, cli, &io);
2816 if (!NT_STATUS_IS_OK(status)) {
2817 printf("Failed to open %s - %s\n",
2818 hold_info[i].fname, nt_errstr(status));
2822 if (io.ntcreatex.out.oplock_level != BATCH_OPLOCK_RETURN) {
2823 printf("Oplock not granted for %s - expected %d but got %d\n",
2824 hold_info[i].fname, BATCH_OPLOCK_RETURN,
2825 io.ntcreatex.out.oplock_level);
2828 hold_info[i].fnum = io.ntcreatex.out.file.fnum;
2830 /* make the file non-zero size */
2831 if (smbcli_write(cli->tree, hold_info[i].fnum, 0, &c, 0, 1) != 1) {
2832 printf("Failed to write to file\n");
2837 printf("Waiting for oplock events\n");
2838 event_loop_wait(ev);