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 "libcli/raw/libcliraw.h"
22 #include "libcli/raw/raw_proto.h"
23 #include "libcli/libcli.h"
24 #include "torture/util.h"
25 #include "lib/events/events.h"
26 #include "param/param.h"
27 #include "lib/cmdline/popt_common.h"
28 #include "libcli/resolve/resolve.h"
29 #include "torture/raw/proto.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_warning(tctx, "(%s): wrong value for %s got " \
41 "%d - should be between %d and %d\n", \
42 __location__, #v, (int)v, (int)min, (int)max); \
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_data)
78 struct smbcli_tree *tree = (struct smbcli_tree *)private_data;
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_data)
109 struct smbcli_tree *tree = (struct smbcli_tree *)private_data;
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_data)
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_data)
151 struct smbcli_tree *tree = (struct smbcli_tree *)private_data;
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_data = NULL;
173 static bool open_connection_no_level2_oplocks(struct torture_context *tctx,
174 struct smbcli_state **c)
177 struct smbcli_options options;
178 struct smbcli_session_options session_options;
180 lpcfg_smbcli_options(tctx->lp_ctx, &options);
181 lpcfg_smbcli_session_options(tctx->lp_ctx, &session_options);
183 options.use_level2_oplocks = false;
185 status = smbcli_full_connection(tctx, c,
186 torture_setting_string(tctx, "host", NULL),
187 lpcfg_smb_ports(tctx->lp_ctx),
188 torture_setting_string(tctx, "share", NULL),
189 NULL, lpcfg_socket_options(tctx->lp_ctx), cmdline_credentials,
190 lpcfg_resolve_context(tctx->lp_ctx),
191 tctx->ev, &options, &session_options,
192 lpcfg_gensec_settings(tctx, tctx->lp_ctx));
193 if (!NT_STATUS_IS_OK(status)) {
194 torture_comment(tctx, "Failed to open connection - %s\n",
203 Timer handler function notifies the registering function that time is up
205 static void timeout_cb(struct tevent_context *ev,
206 struct tevent_timer *te,
207 struct timeval current_time,
210 bool *timesup = (bool *)private_data;
216 Wait a short period of time to receive a single oplock break request
218 static void torture_wait_for_oplock_break(struct torture_context *tctx)
220 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
221 struct tevent_timer *te = NULL;
223 bool timesup = false;
224 int old_count = break_info.count;
226 /* Wait .1 seconds for an oplock break */
227 ne = tevent_timeval_current_ofs(0, 100000);
229 if ((te = tevent_add_timer(tctx->ev, tmp_ctx, ne, timeout_cb, ×up))
232 torture_comment(tctx, "Failed to wait for an oplock break. "
233 "test results may not be accurate.");
237 while (!timesup && break_info.count < old_count + 1) {
238 if (tevent_loop_once(tctx->ev) != 0) {
239 torture_comment(tctx, "Failed to wait for an oplock "
240 "break. test results may not be "
247 /* We don't know if the timed event fired and was freed, we received
248 * our oplock break, or some other event triggered the loop. Thus,
249 * we create a tmp_ctx to be able to safely free/remove the timed
250 * event in all 3 cases. */
251 talloc_free(tmp_ctx);
256 static uint8_t get_break_level1_to_none_count(struct torture_context *tctx)
258 return torture_setting_bool(tctx, "2_step_break_to_none", false) ?
262 static uint8_t get_setinfo_break_count(struct torture_context *tctx)
264 if (TARGET_IS_W2K12(tctx)) {
267 if (TARGET_IS_SAMBA3(tctx)) {
273 static bool test_raw_oplock_exclusive1(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
275 const char *fname = BASEDIR "\\test_exclusive1.dat";
279 union smb_unlink unl;
282 if (!torture_setup_dir(cli1, BASEDIR)) {
287 smbcli_unlink(cli1->tree, fname);
289 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
294 io.generic.level = RAW_OPEN_NTCREATEX;
295 io.ntcreatex.in.root_fid.fnum = 0;
296 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
297 io.ntcreatex.in.alloc_size = 0;
298 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
299 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
300 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
301 io.ntcreatex.in.create_options = 0;
302 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
303 io.ntcreatex.in.security_flags = 0;
304 io.ntcreatex.in.fname = fname;
306 torture_comment(tctx, "EXCLUSIVE1: open a file with an exclusive oplock (share mode: none)\n");
307 ZERO_STRUCT(break_info);
308 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
310 status = smb_raw_open(cli1->tree, tctx, &io);
311 CHECK_STATUS(tctx, status, NT_STATUS_OK);
312 fnum = io.ntcreatex.out.file.fnum;
313 CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
315 torture_comment(tctx, "a 2nd open should not cause a break\n");
316 status = smb_raw_open(cli2->tree, tctx, &io);
317 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
318 torture_wait_for_oplock_break(tctx);
319 CHECK_VAL(break_info.count, 0);
320 CHECK_VAL(break_info.failures, 0);
322 torture_comment(tctx, "unlink it - should also be no break\n");
323 unl.unlink.in.pattern = fname;
324 unl.unlink.in.attrib = 0;
325 status = smb_raw_unlink(cli2->tree, &unl);
326 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
327 torture_wait_for_oplock_break(tctx);
328 CHECK_VAL(break_info.count, 0);
329 CHECK_VAL(break_info.failures, 0);
331 smbcli_close(cli1->tree, fnum);
334 smb_raw_exit(cli1->session);
335 smb_raw_exit(cli2->session);
336 smbcli_deltree(cli1->tree, BASEDIR);
340 static bool test_raw_oplock_exclusive2(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
342 const char *fname = BASEDIR "\\test_exclusive2.dat";
346 union smb_unlink unl;
347 uint16_t fnum=0, fnum2=0;
349 if (!torture_setup_dir(cli1, BASEDIR)) {
354 smbcli_unlink(cli1->tree, fname);
356 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
361 io.generic.level = RAW_OPEN_NTCREATEX;
362 io.ntcreatex.in.root_fid.fnum = 0;
363 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
364 io.ntcreatex.in.alloc_size = 0;
365 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
366 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
367 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
368 io.ntcreatex.in.create_options = 0;
369 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
370 io.ntcreatex.in.security_flags = 0;
371 io.ntcreatex.in.fname = fname;
373 torture_comment(tctx, "EXCLUSIVE2: open a file with an exclusive oplock (share mode: all)\n");
374 ZERO_STRUCT(break_info);
375 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
376 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
377 NTCREATEX_SHARE_ACCESS_WRITE|
378 NTCREATEX_SHARE_ACCESS_DELETE;
380 status = smb_raw_open(cli1->tree, tctx, &io);
381 CHECK_STATUS(tctx, status, NT_STATUS_OK);
382 fnum = io.ntcreatex.out.file.fnum;
383 CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
385 torture_comment(tctx, "a 2nd open should cause a break to level 2\n");
386 status = smb_raw_open(cli2->tree, tctx, &io);
387 CHECK_STATUS(tctx, status, NT_STATUS_OK);
388 fnum2 = io.ntcreatex.out.file.fnum;
389 torture_wait_for_oplock_break(tctx);
390 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
391 CHECK_VAL(break_info.count, 1);
392 CHECK_VAL(break_info.fnum, fnum);
393 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
394 CHECK_VAL(break_info.failures, 0);
395 ZERO_STRUCT(break_info);
397 /* now we have 2 level II oplocks... */
398 torture_comment(tctx, "try to unlink it - should not cause a break, but a sharing violation\n");
399 unl.unlink.in.pattern = fname;
400 unl.unlink.in.attrib = 0;
401 status = smb_raw_unlink(cli2->tree, &unl);
402 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
403 torture_wait_for_oplock_break(tctx);
404 CHECK_VAL(break_info.count, 0);
405 CHECK_VAL(break_info.failures, 0);
407 torture_comment(tctx, "close 1st handle\n");
408 smbcli_close(cli1->tree, fnum);
410 torture_comment(tctx, "try to unlink it - should not cause a break, but a sharing violation\n");
411 unl.unlink.in.pattern = fname;
412 unl.unlink.in.attrib = 0;
413 status = smb_raw_unlink(cli2->tree, &unl);
414 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
415 torture_wait_for_oplock_break(tctx);
416 CHECK_VAL(break_info.count, 0);
417 CHECK_VAL(break_info.failures, 0);
419 torture_comment(tctx, "close 2nd handle\n");
420 smbcli_close(cli2->tree, fnum2);
422 torture_comment(tctx, "unlink it\n");
423 unl.unlink.in.pattern = fname;
424 unl.unlink.in.attrib = 0;
425 status = smb_raw_unlink(cli2->tree, &unl);
426 CHECK_STATUS(tctx, status, NT_STATUS_OK);
427 torture_wait_for_oplock_break(tctx);
428 CHECK_VAL(break_info.count, 0);
429 CHECK_VAL(break_info.failures, 0);
432 smb_raw_exit(cli1->session);
433 smb_raw_exit(cli2->session);
434 smbcli_deltree(cli1->tree, BASEDIR);
438 static bool test_raw_oplock_exclusive3(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
440 const char *fname = BASEDIR "\\test_exclusive3.dat";
444 union smb_setfileinfo sfi;
447 if (!torture_setup_dir(cli1, BASEDIR)) {
452 smbcli_unlink(cli1->tree, fname);
454 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
459 io.generic.level = RAW_OPEN_NTCREATEX;
460 io.ntcreatex.in.root_fid.fnum = 0;
461 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
462 io.ntcreatex.in.alloc_size = 0;
463 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
464 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_WRITE;
465 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
466 io.ntcreatex.in.create_options = 0;
467 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
468 io.ntcreatex.in.security_flags = 0;
469 io.ntcreatex.in.fname = fname;
471 torture_comment(tctx, "EXCLUSIVE3: open a file with an exclusive oplock (share mode: none)\n");
473 ZERO_STRUCT(break_info);
474 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
476 status = smb_raw_open(cli1->tree, tctx, &io);
477 CHECK_STATUS(tctx, status, NT_STATUS_OK);
478 fnum = io.ntcreatex.out.file.fnum;
479 CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
481 torture_comment(tctx, "setpathinfo EOF should trigger a break to none\n");
483 sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
484 sfi.generic.in.file.path = fname;
485 sfi.end_of_file_info.in.size = 100;
487 status = smb_raw_setpathinfo(cli2->tree, &sfi);
489 CHECK_STATUS(tctx, status, NT_STATUS_OK);
490 torture_wait_for_oplock_break(tctx);
491 CHECK_VAL(break_info.count, get_setinfo_break_count(tctx));
492 CHECK_VAL(break_info.failures, 0);
493 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_NONE);
495 smbcli_close(cli1->tree, fnum);
498 smb_raw_exit(cli1->session);
499 smb_raw_exit(cli2->session);
500 smbcli_deltree(cli1->tree, BASEDIR);
504 static bool test_raw_oplock_exclusive4(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
506 const char *fname = BASEDIR "\\test_exclusive4.dat";
510 uint16_t fnum=0, fnum2=0;
512 if (!torture_setup_dir(cli1, BASEDIR)) {
517 smbcli_unlink(cli1->tree, fname);
519 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
524 io.generic.level = RAW_OPEN_NTCREATEX;
525 io.ntcreatex.in.root_fid.fnum = 0;
526 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
527 io.ntcreatex.in.alloc_size = 0;
528 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
529 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
530 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
531 io.ntcreatex.in.create_options = 0;
532 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
533 io.ntcreatex.in.security_flags = 0;
534 io.ntcreatex.in.fname = fname;
536 torture_comment(tctx, "EXCLUSIVE4: open with exclusive oplock\n");
537 ZERO_STRUCT(break_info);
538 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
540 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
541 status = smb_raw_open(cli1->tree, tctx, &io);
542 CHECK_STATUS(tctx, status, NT_STATUS_OK);
543 fnum = io.ntcreatex.out.file.fnum;
544 CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
546 ZERO_STRUCT(break_info);
547 torture_comment(tctx, "second open with attributes only shouldn't cause oplock break\n");
549 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
550 io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
551 status = smb_raw_open(cli2->tree, tctx, &io);
552 CHECK_STATUS(tctx, status, NT_STATUS_OK);
553 fnum2 = io.ntcreatex.out.file.fnum;
554 CHECK_VAL(io.ntcreatex.out.oplock_level, NO_OPLOCK_RETURN);
555 torture_wait_for_oplock_break(tctx);
556 CHECK_VAL(break_info.count, 0);
557 CHECK_VAL(break_info.failures, 0);
559 smbcli_close(cli1->tree, fnum);
560 smbcli_close(cli2->tree, fnum2);
563 smb_raw_exit(cli1->session);
564 smb_raw_exit(cli2->session);
565 smbcli_deltree(cli1->tree, BASEDIR);
569 static bool test_raw_oplock_exclusive5(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
571 const char *fname = BASEDIR "\\test_exclusive5.dat";
575 uint16_t fnum=0, fnum2=0;
577 if (!torture_setup_dir(cli1, BASEDIR)) {
582 smbcli_unlink(cli1->tree, fname);
584 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
585 smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli1->tree);
590 io.generic.level = RAW_OPEN_NTCREATEX;
591 io.ntcreatex.in.root_fid.fnum = 0;
592 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
593 io.ntcreatex.in.alloc_size = 0;
594 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
595 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
596 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
597 io.ntcreatex.in.create_options = 0;
598 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
599 io.ntcreatex.in.security_flags = 0;
600 io.ntcreatex.in.fname = fname;
602 torture_comment(tctx, "EXCLUSIVE5: open with exclusive oplock\n");
603 ZERO_STRUCT(break_info);
604 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
607 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
608 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
609 NTCREATEX_SHARE_ACCESS_WRITE|
610 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 ZERO_STRUCT(break_info);
618 torture_comment(tctx, "second open with attributes only and NTCREATEX_DISP_OVERWRITE_IF dispostion causes oplock break\n");
620 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
621 io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
622 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE_IF;
623 status = smb_raw_open(cli2->tree, tctx, &io);
624 CHECK_STATUS(tctx, status, NT_STATUS_OK);
625 fnum2 = io.ntcreatex.out.file.fnum;
626 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
627 torture_wait_for_oplock_break(tctx);
628 CHECK_VAL(break_info.count, get_break_level1_to_none_count(tctx));
629 CHECK_VAL(break_info.failures, 0);
631 smbcli_close(cli1->tree, fnum);
632 smbcli_close(cli2->tree, fnum2);
635 smb_raw_exit(cli1->session);
636 smb_raw_exit(cli2->session);
637 smbcli_deltree(cli1->tree, BASEDIR);
641 static bool test_raw_oplock_exclusive6(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
643 const char *fname1 = BASEDIR "\\test_exclusive6_1.dat";
644 const char *fname2 = BASEDIR "\\test_exclusive6_2.dat";
651 if (!torture_setup_dir(cli1, BASEDIR)) {
656 smbcli_unlink(cli1->tree, fname1);
657 smbcli_unlink(cli1->tree, fname2);
659 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
664 io.generic.level = RAW_OPEN_NTCREATEX;
665 io.ntcreatex.in.root_fid.fnum = 0;
666 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
667 io.ntcreatex.in.alloc_size = 0;
668 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
669 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
670 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
671 io.ntcreatex.in.create_options = 0;
672 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
673 io.ntcreatex.in.security_flags = 0;
674 io.ntcreatex.in.fname = fname1;
676 torture_comment(tctx, "EXCLUSIVE6: open a file with an exclusive "
677 "oplock (share mode: none)\n");
678 ZERO_STRUCT(break_info);
679 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_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, EXCLUSIVE_OPLOCK_RETURN);
686 torture_comment(tctx, "rename should not generate a break but get a "
687 "sharing violation\n");
689 rn.generic.level = RAW_RENAME_RENAME;
690 rn.rename.in.pattern1 = fname1;
691 rn.rename.in.pattern2 = fname2;
692 rn.rename.in.attrib = 0;
694 torture_comment(tctx, "trying rename while first file open\n");
695 status = smb_raw_rename(cli2->tree, &rn);
697 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
698 torture_wait_for_oplock_break(tctx);
699 CHECK_VAL(break_info.count, 0);
700 CHECK_VAL(break_info.failures, 0);
702 smbcli_close(cli1->tree, fnum);
705 smb_raw_exit(cli1->session);
706 smb_raw_exit(cli2->session);
707 smbcli_deltree(cli1->tree, BASEDIR);
712 * Exclusive version of batch19
714 static bool test_raw_oplock_exclusive7(struct torture_context *tctx,
715 struct smbcli_state *cli1, struct smbcli_state *cli2)
717 const char *fname1 = BASEDIR "\\test_exclusiv6_1.dat";
718 const char *fname2 = BASEDIR "\\test_exclusiv6_2.dat";
719 const char *fname3 = BASEDIR "\\test_exclusiv6_3.dat";
723 union smb_fileinfo qfi;
724 union smb_setfileinfo sfi;
728 if (!torture_setup_dir(cli1, BASEDIR)) {
733 smbcli_unlink(cli1->tree, fname1);
734 smbcli_unlink(cli1->tree, fname2);
735 smbcli_unlink(cli1->tree, fname3);
737 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given,
743 io.generic.level = RAW_OPEN_NTCREATEX;
744 io.ntcreatex.in.root_fid.fnum = 0;
745 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
746 io.ntcreatex.in.alloc_size = 0;
747 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
748 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
749 NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_DELETE;
750 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
751 io.ntcreatex.in.create_options = 0;
752 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
753 io.ntcreatex.in.security_flags = 0;
754 io.ntcreatex.in.fname = fname1;
756 torture_comment(tctx, "open a file with an exclusive oplock (share "
758 ZERO_STRUCT(break_info);
759 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
760 NTCREATEX_FLAGS_REQUEST_OPLOCK;
761 status = smb_raw_open(cli1->tree, tctx, &io);
762 CHECK_STATUS(tctx, status, NT_STATUS_OK);
763 fnum = io.ntcreatex.out.file.fnum;
764 CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
766 torture_comment(tctx, "setpathinfo rename info should trigger a break "
769 sfi.generic.level = RAW_SFILEINFO_RENAME_INFORMATION;
770 sfi.generic.in.file.path = fname1;
771 sfi.rename_information.in.overwrite = 0;
772 sfi.rename_information.in.root_fid = 0;
773 sfi.rename_information.in.new_name = fname2+strlen(BASEDIR)+1;
775 status = smb_raw_setpathinfo(cli2->tree, &sfi);
776 CHECK_STATUS(tctx, status, NT_STATUS_OK);
778 torture_wait_for_oplock_break(tctx);
779 CHECK_VAL(break_info.failures, 0);
781 if (TARGET_IS_WINXP(tctx) || TARGET_IS_W2K12(tctx)) {
782 /* XP incorrectly breaks to level2. */
783 CHECK_VAL(break_info.count, 1);
784 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
786 /* Exclusive oplocks should not be broken on rename. */
787 CHECK_VAL(break_info.failures, 0);
788 CHECK_VAL(break_info.count, 0);
792 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
793 qfi.generic.in.file.fnum = fnum;
795 status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
796 CHECK_STATUS(tctx, status, NT_STATUS_OK);
797 CHECK_STRMATCH(qfi.all_info.out.fname.s, fname2);
799 /* Try breaking to level2 and then see if rename breaks the level2.*/
800 ZERO_STRUCT(break_info);
801 io.ntcreatex.in.fname = fname2;
802 status = smb_raw_open(cli2->tree, tctx, &io);
803 CHECK_STATUS(tctx, status, NT_STATUS_OK);
804 fnum2 = io.ntcreatex.out.file.fnum;
805 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
807 torture_wait_for_oplock_break(tctx);
808 CHECK_VAL(break_info.failures, 0);
810 if (TARGET_IS_WINXP(tctx)) {
811 /* XP already broke to level2. */
812 CHECK_VAL(break_info.failures, 0);
813 CHECK_VAL(break_info.count, 0);
814 } else if (TARGET_IS_W2K12(tctx)) {
816 CHECK_VAL(break_info.count, 0);
817 CHECK_VAL(break_info.level, 0);
819 /* Break to level 2 expected. */
820 CHECK_VAL(break_info.count, 1);
821 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
824 ZERO_STRUCT(break_info);
825 sfi.generic.in.file.path = fname2;
826 sfi.rename_information.in.overwrite = 0;
827 sfi.rename_information.in.root_fid = 0;
828 sfi.rename_information.in.new_name = fname1+strlen(BASEDIR)+1;
830 status = smb_raw_setpathinfo(cli2->tree, &sfi);
831 CHECK_STATUS(tctx, status, NT_STATUS_OK);
833 /* Level2 oplocks are not broken on rename. */
834 torture_wait_for_oplock_break(tctx);
835 CHECK_VAL(break_info.failures, 0);
836 CHECK_VAL(break_info.count, 0);
838 /* Close and re-open file with oplock. */
839 smbcli_close(cli1->tree, fnum);
840 status = smb_raw_open(cli1->tree, tctx, &io);
841 CHECK_STATUS(tctx, status, NT_STATUS_OK);
842 fnum = io.ntcreatex.out.file.fnum;
843 CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
845 torture_comment(tctx, "setfileinfo rename info on a client's own fid "
846 "should not trigger a break nor a violation\n");
847 ZERO_STRUCT(break_info);
849 sfi.generic.level = RAW_SFILEINFO_RENAME_INFORMATION;
850 sfi.generic.in.file.fnum = fnum;
851 sfi.rename_information.in.overwrite = 0;
852 sfi.rename_information.in.root_fid = 0;
853 sfi.rename_information.in.new_name = fname3+strlen(BASEDIR)+1;
855 status = smb_raw_setfileinfo(cli1->tree, &sfi);
856 CHECK_STATUS(tctx, status, NT_STATUS_OK);
858 torture_wait_for_oplock_break(tctx);
859 if (TARGET_IS_WINXP(tctx)) {
860 /* XP incorrectly breaks to level2. */
861 CHECK_VAL(break_info.count, 1);
862 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
864 CHECK_VAL(break_info.count, 0);
868 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
869 qfi.generic.in.file.fnum = fnum;
871 status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
872 CHECK_STATUS(tctx, status, NT_STATUS_OK);
873 CHECK_STRMATCH(qfi.all_info.out.fname.s, fname3);
876 smbcli_close(cli1->tree, fnum);
877 smbcli_close(cli2->tree, fnum2);
879 smb_raw_exit(cli1->session);
880 smb_raw_exit(cli2->session);
881 smbcli_deltree(cli1->tree, BASEDIR);
885 static bool test_raw_oplock_exclusive8(struct torture_context *tctx,
886 struct smbcli_state *cli1,
887 struct smbcli_state *cli2)
889 const char *fname = BASEDIR "\\test_exclusive8.dat";
897 if (!torture_setup_dir(cli1, BASEDIR)) {
902 smbcli_unlink(cli1->tree, fname);
904 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given,
910 io.generic.level = RAW_OPEN_NTCREATEX;
911 io.ntcreatex.in.root_fid.fnum = 0;
912 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
913 io.ntcreatex.in.alloc_size = 0;
914 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
915 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
916 NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_DELETE;
917 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
918 io.ntcreatex.in.create_options = 0;
919 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
920 io.ntcreatex.in.security_flags = 0;
921 io.ntcreatex.in.fname = fname;
923 torture_comment(tctx, "open a file with an exclusive oplock (share "
925 ZERO_STRUCT(break_info);
926 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
927 NTCREATEX_FLAGS_REQUEST_OPLOCK;
928 status = smb_raw_open(cli1->tree, tctx, &io);
929 CHECK_STATUS(tctx, status, NT_STATUS_OK);
930 fnum1 = io.ntcreatex.out.file.fnum;
931 CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
933 torture_comment(tctx, "second open with delete should trigger a "
936 io.ntcreatex.in.access_mask = SEC_STD_DELETE;
937 io.ntcreatex.in.flags = 0;
938 status = smb_raw_open(cli2->tree, tctx, &io);
939 CHECK_STATUS(tctx, status, NT_STATUS_OK);
940 fnum2 = io.ntcreatex.out.file.fnum;
941 CHECK_VAL(break_info.count, get_break_level1_to_none_count(tctx));
942 CHECK_VAL(break_info.failures, 0);
943 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
945 /* Trigger a little panic in "old" samba code.. */
946 status = smb_raw_open(cli2->tree, tctx, &io);
947 CHECK_STATUS(tctx, status, NT_STATUS_OK);
948 fnum3 = io.ntcreatex.out.file.fnum;
950 smbcli_close(cli2->tree, fnum3);
951 smbcli_close(cli2->tree, fnum2);
952 smbcli_close(cli1->tree, fnum1);
955 smbcli_deltree(cli1->tree, BASEDIR);
956 smb_raw_exit(cli1->session);
957 smb_raw_exit(cli2->session);
961 static bool test_raw_oplock_batch1(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
963 const char *fname = BASEDIR "\\test_batch1.dat";
967 union smb_unlink unl;
971 if (!torture_setup_dir(cli1, BASEDIR)) {
976 smbcli_unlink(cli1->tree, fname);
978 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
983 io.generic.level = RAW_OPEN_NTCREATEX;
984 io.ntcreatex.in.root_fid.fnum = 0;
985 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
986 io.ntcreatex.in.alloc_size = 0;
987 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
988 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
989 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
990 io.ntcreatex.in.create_options = 0;
991 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
992 io.ntcreatex.in.security_flags = 0;
993 io.ntcreatex.in.fname = fname;
996 with a batch oplock we get a break
998 torture_comment(tctx, "BATCH1: open with batch oplock\n");
999 ZERO_STRUCT(break_info);
1000 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1001 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1002 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1003 status = smb_raw_open(cli1->tree, tctx, &io);
1004 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1005 fnum = io.ntcreatex.out.file.fnum;
1006 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1008 torture_comment(tctx, "unlink should generate a break\n");
1009 unl.unlink.in.pattern = fname;
1010 unl.unlink.in.attrib = 0;
1011 status = smb_raw_unlink(cli2->tree, &unl);
1012 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
1014 torture_wait_for_oplock_break(tctx);
1015 CHECK_VAL(break_info.count, 1);
1016 CHECK_VAL(break_info.fnum, fnum);
1017 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
1018 CHECK_VAL(break_info.failures, 0);
1020 torture_comment(tctx, "2nd unlink should not generate a break\n");
1021 ZERO_STRUCT(break_info);
1022 status = smb_raw_unlink(cli2->tree, &unl);
1023 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
1025 torture_wait_for_oplock_break(tctx);
1026 CHECK_VAL(break_info.count, 0);
1028 torture_comment(tctx, "writing should generate a self break to none\n");
1029 smbcli_write(cli1->tree, fnum, 0, &c, 0, 1);
1031 torture_wait_for_oplock_break(tctx);
1032 torture_wait_for_oplock_break(tctx);
1033 CHECK_VAL(break_info.count, 1);
1034 CHECK_VAL(break_info.fnum, fnum);
1035 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_NONE);
1036 CHECK_VAL(break_info.failures, 0);
1038 smbcli_close(cli1->tree, fnum);
1041 smb_raw_exit(cli1->session);
1042 smb_raw_exit(cli2->session);
1043 smbcli_deltree(cli1->tree, BASEDIR);
1047 static bool test_raw_oplock_batch2(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1049 const char *fname = BASEDIR "\\test_batch2.dat";
1053 union smb_unlink unl;
1057 if (!torture_setup_dir(cli1, BASEDIR)) {
1062 smbcli_unlink(cli1->tree, fname);
1064 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1067 base ntcreatex parms
1069 io.generic.level = RAW_OPEN_NTCREATEX;
1070 io.ntcreatex.in.root_fid.fnum = 0;
1071 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1072 io.ntcreatex.in.alloc_size = 0;
1073 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1074 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1075 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1076 io.ntcreatex.in.create_options = 0;
1077 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1078 io.ntcreatex.in.security_flags = 0;
1079 io.ntcreatex.in.fname = fname;
1081 torture_comment(tctx, "BATCH2: open with batch oplock\n");
1082 ZERO_STRUCT(break_info);
1083 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1084 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1085 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1086 status = smb_raw_open(cli1->tree, tctx, &io);
1087 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1088 fnum = io.ntcreatex.out.file.fnum;
1089 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1091 torture_comment(tctx, "unlink should generate a break, which we ack as break to none\n");
1092 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_none, cli1->tree);
1093 unl.unlink.in.pattern = fname;
1094 unl.unlink.in.attrib = 0;
1095 status = smb_raw_unlink(cli2->tree, &unl);
1096 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
1098 torture_wait_for_oplock_break(tctx);
1099 CHECK_VAL(break_info.count, 1);
1100 CHECK_VAL(break_info.fnum, fnum);
1101 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
1102 CHECK_VAL(break_info.failures, 0);
1104 torture_comment(tctx, "2nd unlink should not generate a break\n");
1105 ZERO_STRUCT(break_info);
1106 status = smb_raw_unlink(cli2->tree, &unl);
1107 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
1109 torture_wait_for_oplock_break(tctx);
1110 CHECK_VAL(break_info.count, 0);
1112 torture_comment(tctx, "writing should not generate a break\n");
1113 smbcli_write(cli1->tree, fnum, 0, &c, 0, 1);
1115 torture_wait_for_oplock_break(tctx);
1116 CHECK_VAL(break_info.count, 0);
1118 smbcli_close(cli1->tree, fnum);
1121 smb_raw_exit(cli1->session);
1122 smb_raw_exit(cli2->session);
1123 smbcli_deltree(cli1->tree, BASEDIR);
1127 static bool test_raw_oplock_batch3(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1129 const char *fname = BASEDIR "\\test_batch3.dat";
1133 union smb_unlink unl;
1136 if (!torture_setup_dir(cli1, BASEDIR)) {
1141 smbcli_unlink(cli1->tree, fname);
1143 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1146 base ntcreatex parms
1148 io.generic.level = RAW_OPEN_NTCREATEX;
1149 io.ntcreatex.in.root_fid.fnum = 0;
1150 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1151 io.ntcreatex.in.alloc_size = 0;
1152 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1153 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1154 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1155 io.ntcreatex.in.create_options = 0;
1156 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1157 io.ntcreatex.in.security_flags = 0;
1158 io.ntcreatex.in.fname = fname;
1160 torture_comment(tctx, "BATCH3: if we close on break then the unlink can succeed\n");
1161 ZERO_STRUCT(break_info);
1162 smbcli_oplock_handler(cli1->transport, oplock_handler_close, cli1->tree);
1163 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1164 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1165 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1166 status = smb_raw_open(cli1->tree, tctx, &io);
1167 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1168 fnum = io.ntcreatex.out.file.fnum;
1169 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1171 unl.unlink.in.pattern = fname;
1172 unl.unlink.in.attrib = 0;
1173 ZERO_STRUCT(break_info);
1174 status = smb_raw_unlink(cli2->tree, &unl);
1175 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1177 torture_wait_for_oplock_break(tctx);
1178 CHECK_VAL(break_info.count, 1);
1179 CHECK_VAL(break_info.fnum, fnum);
1180 CHECK_VAL(break_info.level, 1);
1181 CHECK_VAL(break_info.failures, 0);
1183 smbcli_close(cli1->tree, fnum);
1186 smb_raw_exit(cli1->session);
1187 smb_raw_exit(cli2->session);
1188 smbcli_deltree(cli1->tree, BASEDIR);
1192 static bool test_raw_oplock_batch4(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1194 const char *fname = BASEDIR "\\test_batch4.dat";
1201 if (!torture_setup_dir(cli1, BASEDIR)) {
1206 smbcli_unlink(cli1->tree, fname);
1208 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1211 base ntcreatex parms
1213 io.generic.level = RAW_OPEN_NTCREATEX;
1214 io.ntcreatex.in.root_fid.fnum = 0;
1215 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1216 io.ntcreatex.in.alloc_size = 0;
1217 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1218 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1219 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1220 io.ntcreatex.in.create_options = 0;
1221 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1222 io.ntcreatex.in.security_flags = 0;
1223 io.ntcreatex.in.fname = fname;
1225 torture_comment(tctx, "BATCH4: a self read should not cause a break\n");
1226 ZERO_STRUCT(break_info);
1227 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1229 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1230 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1231 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1232 status = smb_raw_open(cli1->tree, tctx, &io);
1233 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1234 fnum = io.ntcreatex.out.file.fnum;
1235 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1237 rd.readx.level = RAW_READ_READX;
1238 rd.readx.in.file.fnum = fnum;
1239 rd.readx.in.mincnt = 1;
1240 rd.readx.in.maxcnt = 1;
1241 rd.readx.in.offset = 0;
1242 rd.readx.in.remaining = 0;
1243 rd.readx.in.read_for_execute = false;
1244 status = smb_raw_read(cli1->tree, &rd);
1245 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1246 torture_wait_for_oplock_break(tctx);
1247 CHECK_VAL(break_info.count, 0);
1248 CHECK_VAL(break_info.failures, 0);
1250 smbcli_close(cli1->tree, fnum);
1253 smb_raw_exit(cli1->session);
1254 smb_raw_exit(cli2->session);
1255 smbcli_deltree(cli1->tree, BASEDIR);
1259 static bool test_raw_oplock_batch5(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1261 const char *fname = BASEDIR "\\test_batch5.dat";
1267 if (!torture_setup_dir(cli1, BASEDIR)) {
1272 smbcli_unlink(cli1->tree, fname);
1274 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1277 base ntcreatex parms
1279 io.generic.level = RAW_OPEN_NTCREATEX;
1280 io.ntcreatex.in.root_fid.fnum = 0;
1281 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1282 io.ntcreatex.in.alloc_size = 0;
1283 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1284 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1285 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1286 io.ntcreatex.in.create_options = 0;
1287 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1288 io.ntcreatex.in.security_flags = 0;
1289 io.ntcreatex.in.fname = fname;
1291 torture_comment(tctx, "BATCH5: a 2nd open should give a break\n");
1292 ZERO_STRUCT(break_info);
1293 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1295 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1296 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1297 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1298 status = smb_raw_open(cli1->tree, tctx, &io);
1299 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1300 fnum = io.ntcreatex.out.file.fnum;
1301 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1303 ZERO_STRUCT(break_info);
1305 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
1306 status = smb_raw_open(cli2->tree, tctx, &io);
1307 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
1309 torture_wait_for_oplock_break(tctx);
1310 CHECK_VAL(break_info.count, 1);
1311 CHECK_VAL(break_info.fnum, fnum);
1312 CHECK_VAL(break_info.level, 1);
1313 CHECK_VAL(break_info.failures, 0);
1315 smbcli_close(cli1->tree, fnum);
1318 smb_raw_exit(cli1->session);
1319 smb_raw_exit(cli2->session);
1320 smbcli_deltree(cli1->tree, BASEDIR);
1324 static bool test_raw_oplock_batch6(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1326 const char *fname = BASEDIR "\\test_batch6.dat";
1330 uint16_t fnum=0, fnum2=0;
1333 if (!torture_setup_dir(cli1, BASEDIR)) {
1338 smbcli_unlink(cli1->tree, fname);
1340 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1341 smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli2->tree);
1344 base ntcreatex parms
1346 io.generic.level = RAW_OPEN_NTCREATEX;
1347 io.ntcreatex.in.root_fid.fnum = 0;
1348 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1349 io.ntcreatex.in.alloc_size = 0;
1350 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1351 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1352 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1353 io.ntcreatex.in.create_options = 0;
1354 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1355 io.ntcreatex.in.security_flags = 0;
1356 io.ntcreatex.in.fname = fname;
1358 torture_comment(tctx, "BATCH6: a 2nd open should give a break to level II if the first open allowed shared read\n");
1359 ZERO_STRUCT(break_info);
1361 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_READ | SEC_RIGHTS_FILE_WRITE;
1362 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
1363 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1364 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1365 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1366 status = smb_raw_open(cli1->tree, tctx, &io);
1367 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1368 fnum = io.ntcreatex.out.file.fnum;
1369 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1371 ZERO_STRUCT(break_info);
1373 status = smb_raw_open(cli2->tree, tctx, &io);
1374 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1375 fnum2 = io.ntcreatex.out.file.fnum;
1376 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1378 //torture_wait_for_oplock_break(tctx);
1379 CHECK_VAL(break_info.count, 1);
1380 CHECK_VAL(break_info.fnum, fnum);
1381 CHECK_VAL(break_info.level, 1);
1382 CHECK_VAL(break_info.failures, 0);
1383 ZERO_STRUCT(break_info);
1385 torture_comment(tctx, "write should trigger a break to none on both\n");
1386 smbcli_write(cli1->tree, fnum, 0, &c, 0, 1);
1388 /* We expect two breaks */
1389 torture_wait_for_oplock_break(tctx);
1390 torture_wait_for_oplock_break(tctx);
1392 CHECK_VAL(break_info.count, 2);
1393 CHECK_VAL(break_info.level, 0);
1394 CHECK_VAL(break_info.failures, 0);
1396 smbcli_close(cli1->tree, fnum);
1397 smbcli_close(cli2->tree, fnum2);
1400 smb_raw_exit(cli1->session);
1401 smb_raw_exit(cli2->session);
1402 smbcli_deltree(cli1->tree, BASEDIR);
1406 static bool test_raw_oplock_batch7(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1408 const char *fname = BASEDIR "\\test_batch7.dat";
1412 uint16_t fnum=0, fnum2=0;
1414 if (!torture_setup_dir(cli1, BASEDIR)) {
1419 smbcli_unlink(cli1->tree, fname);
1421 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1424 base ntcreatex parms
1426 io.generic.level = RAW_OPEN_NTCREATEX;
1427 io.ntcreatex.in.root_fid.fnum = 0;
1428 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1429 io.ntcreatex.in.alloc_size = 0;
1430 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1431 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1432 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1433 io.ntcreatex.in.create_options = 0;
1434 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1435 io.ntcreatex.in.security_flags = 0;
1436 io.ntcreatex.in.fname = fname;
1438 torture_comment(tctx, "BATCH7: a 2nd open should get an oplock when we close instead of ack\n");
1439 ZERO_STRUCT(break_info);
1440 smbcli_oplock_handler(cli1->transport, oplock_handler_close, cli1->tree);
1442 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1443 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1444 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1445 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1446 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1447 status = smb_raw_open(cli1->tree, tctx, &io);
1448 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1449 fnum2 = io.ntcreatex.out.file.fnum;
1450 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1452 ZERO_STRUCT(break_info);
1454 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1455 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1456 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1457 status = smb_raw_open(cli2->tree, tctx, &io);
1458 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1459 fnum = io.ntcreatex.out.file.fnum;
1460 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1462 torture_wait_for_oplock_break(tctx);
1463 CHECK_VAL(break_info.count, 1);
1464 CHECK_VAL(break_info.fnum, fnum2);
1465 CHECK_VAL(break_info.level, 1);
1466 CHECK_VAL(break_info.failures, 0);
1468 smbcli_close(cli2->tree, fnum);
1471 smb_raw_exit(cli1->session);
1472 smb_raw_exit(cli2->session);
1473 smbcli_deltree(cli1->tree, BASEDIR);
1477 static bool test_raw_oplock_batch8(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1479 const char *fname = BASEDIR "\\test_batch8.dat";
1483 uint16_t fnum=0, fnum2=0;
1485 if (!torture_setup_dir(cli1, BASEDIR)) {
1490 smbcli_unlink(cli1->tree, fname);
1492 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1495 base ntcreatex parms
1497 io.generic.level = RAW_OPEN_NTCREATEX;
1498 io.ntcreatex.in.root_fid.fnum = 0;
1499 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1500 io.ntcreatex.in.alloc_size = 0;
1501 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1502 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1503 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1504 io.ntcreatex.in.create_options = 0;
1505 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1506 io.ntcreatex.in.security_flags = 0;
1507 io.ntcreatex.in.fname = fname;
1509 torture_comment(tctx, "BATCH8: open with batch oplock\n");
1510 ZERO_STRUCT(break_info);
1511 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1513 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1514 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1515 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1516 status = smb_raw_open(cli1->tree, tctx, &io);
1517 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1518 fnum = io.ntcreatex.out.file.fnum;
1519 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1521 ZERO_STRUCT(break_info);
1522 torture_comment(tctx, "second open with attributes only shouldn't cause oplock break\n");
1524 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1525 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1526 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1527 io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
1528 status = smb_raw_open(cli2->tree, tctx, &io);
1529 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1530 fnum2 = io.ntcreatex.out.file.fnum;
1531 CHECK_VAL(io.ntcreatex.out.oplock_level, NO_OPLOCK_RETURN);
1532 torture_wait_for_oplock_break(tctx);
1533 CHECK_VAL(break_info.count, 0);
1534 CHECK_VAL(break_info.failures, 0);
1536 smbcli_close(cli1->tree, fnum);
1537 smbcli_close(cli2->tree, fnum2);
1540 smb_raw_exit(cli1->session);
1541 smb_raw_exit(cli2->session);
1542 smbcli_deltree(cli1->tree, BASEDIR);
1546 static bool test_raw_oplock_batch9(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1548 const char *fname = BASEDIR "\\test_batch9.dat";
1552 uint16_t fnum=0, fnum2=0;
1555 if (!torture_setup_dir(cli1, BASEDIR)) {
1560 smbcli_unlink(cli1->tree, fname);
1562 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1565 base ntcreatex parms
1567 io.generic.level = RAW_OPEN_NTCREATEX;
1568 io.ntcreatex.in.root_fid.fnum = 0;
1569 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1570 io.ntcreatex.in.alloc_size = 0;
1571 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1572 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1573 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1574 io.ntcreatex.in.create_options = 0;
1575 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1576 io.ntcreatex.in.security_flags = 0;
1577 io.ntcreatex.in.fname = fname;
1579 torture_comment(tctx, "BATCH9: open with attributes only can create file\n");
1581 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1582 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1583 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1584 io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
1585 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1586 status = smb_raw_open(cli1->tree, tctx, &io);
1587 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1588 fnum = io.ntcreatex.out.file.fnum;
1589 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1591 torture_comment(tctx, "Subsequent normal open should break oplock on attribute only open to level II\n");
1593 ZERO_STRUCT(break_info);
1594 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1596 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1597 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1598 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1599 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1600 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1601 status = smb_raw_open(cli2->tree, tctx, &io);
1602 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1603 fnum2 = io.ntcreatex.out.file.fnum;
1604 torture_wait_for_oplock_break(tctx);
1605 CHECK_VAL(break_info.count, 1);
1606 CHECK_VAL(break_info.fnum, fnum);
1607 CHECK_VAL(break_info.failures, 0);
1608 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
1609 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1610 smbcli_close(cli2->tree, fnum2);
1612 torture_comment(tctx, "third oplocked open should grant level2 without break\n");
1613 ZERO_STRUCT(break_info);
1614 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1615 smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli2->tree);
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_RIGHTS_FILE_ALL;
1620 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1621 status = smb_raw_open(cli2->tree, tctx, &io);
1622 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1623 fnum2 = io.ntcreatex.out.file.fnum;
1624 torture_wait_for_oplock_break(tctx);
1625 CHECK_VAL(break_info.count, 0);
1626 CHECK_VAL(break_info.failures, 0);
1627 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1629 ZERO_STRUCT(break_info);
1631 torture_comment(tctx, "write should trigger a break to none on both\n");
1632 smbcli_write(cli2->tree, fnum2, 0, &c, 0, 1);
1634 /* We expect two breaks */
1635 torture_wait_for_oplock_break(tctx);
1636 torture_wait_for_oplock_break(tctx);
1638 CHECK_VAL(break_info.count, 2);
1639 CHECK_VAL(break_info.level, 0);
1640 CHECK_VAL(break_info.failures, 0);
1642 smbcli_close(cli1->tree, fnum);
1643 smbcli_close(cli2->tree, fnum2);
1646 smb_raw_exit(cli1->session);
1647 smb_raw_exit(cli2->session);
1648 smbcli_deltree(cli1->tree, BASEDIR);
1652 static bool test_raw_oplock_batch10(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1654 const char *fname = BASEDIR "\\test_batch10.dat";
1658 uint16_t fnum=0, fnum2=0;
1660 if (!torture_setup_dir(cli1, BASEDIR)) {
1665 smbcli_unlink(cli1->tree, fname);
1667 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1670 base ntcreatex parms
1672 io.generic.level = RAW_OPEN_NTCREATEX;
1673 io.ntcreatex.in.root_fid.fnum = 0;
1674 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1675 io.ntcreatex.in.alloc_size = 0;
1676 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1677 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1678 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1679 io.ntcreatex.in.create_options = 0;
1680 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1681 io.ntcreatex.in.security_flags = 0;
1682 io.ntcreatex.in.fname = fname;
1684 torture_comment(tctx, "BATCH10: Open with oplock after a non-oplock open should grant level2\n");
1685 ZERO_STRUCT(break_info);
1686 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
1687 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1688 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1689 NTCREATEX_SHARE_ACCESS_WRITE|
1690 NTCREATEX_SHARE_ACCESS_DELETE;
1691 status = smb_raw_open(cli1->tree, tctx, &io);
1692 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1693 fnum = io.ntcreatex.out.file.fnum;
1694 torture_wait_for_oplock_break(tctx);
1695 CHECK_VAL(break_info.count, 0);
1696 CHECK_VAL(break_info.failures, 0);
1697 CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
1699 smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli2->tree);
1701 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1702 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1703 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1704 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1705 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1706 NTCREATEX_SHARE_ACCESS_WRITE|
1707 NTCREATEX_SHARE_ACCESS_DELETE;
1708 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1709 status = smb_raw_open(cli2->tree, tctx, &io);
1710 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1711 fnum2 = io.ntcreatex.out.file.fnum;
1712 torture_wait_for_oplock_break(tctx);
1713 CHECK_VAL(break_info.count, 0);
1714 CHECK_VAL(break_info.failures, 0);
1715 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1717 torture_comment(tctx, "write should trigger a break to none\n");
1720 wr.write.level = RAW_WRITE_WRITE;
1721 wr.write.in.file.fnum = fnum;
1722 wr.write.in.count = 1;
1723 wr.write.in.offset = 0;
1724 wr.write.in.remaining = 0;
1725 wr.write.in.data = (const uint8_t *)"x";
1726 status = smb_raw_write(cli1->tree, &wr);
1727 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1730 torture_wait_for_oplock_break(tctx);
1732 CHECK_VAL(break_info.count, 1);
1733 CHECK_VAL(break_info.fnum, fnum2);
1734 CHECK_VAL(break_info.level, 0);
1735 CHECK_VAL(break_info.failures, 0);
1737 smbcli_close(cli1->tree, fnum);
1738 smbcli_close(cli2->tree, fnum2);
1741 smb_raw_exit(cli1->session);
1742 smb_raw_exit(cli2->session);
1743 smbcli_deltree(cli1->tree, BASEDIR);
1747 static bool test_raw_oplock_batch11(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1749 const char *fname = BASEDIR "\\test_batch11.dat";
1753 union smb_setfileinfo sfi;
1756 if (!torture_setup_dir(cli1, BASEDIR)) {
1761 smbcli_unlink(cli1->tree, fname);
1763 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1766 base ntcreatex parms
1768 io.generic.level = RAW_OPEN_NTCREATEX;
1769 io.ntcreatex.in.root_fid.fnum = 0;
1770 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1771 io.ntcreatex.in.alloc_size = 0;
1772 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1773 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_WRITE;
1774 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1775 io.ntcreatex.in.create_options = 0;
1776 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1777 io.ntcreatex.in.security_flags = 0;
1778 io.ntcreatex.in.fname = fname;
1780 /* Test if a set-eof on pathname breaks an exclusive oplock. */
1781 torture_comment(tctx, "BATCH11: Test if setpathinfo set EOF breaks oplocks.\n");
1783 ZERO_STRUCT(break_info);
1785 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1786 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1787 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1788 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1789 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1790 NTCREATEX_SHARE_ACCESS_WRITE|
1791 NTCREATEX_SHARE_ACCESS_DELETE;
1792 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1793 status = smb_raw_open(cli1->tree, tctx, &io);
1794 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1795 fnum = io.ntcreatex.out.file.fnum;
1796 torture_wait_for_oplock_break(tctx);
1797 CHECK_VAL(break_info.count, 0);
1798 CHECK_VAL(break_info.failures, 0);
1799 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1802 sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
1803 sfi.generic.in.file.path = fname;
1804 sfi.end_of_file_info.in.size = 100;
1806 status = smb_raw_setpathinfo(cli2->tree, &sfi);
1807 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1809 torture_wait_for_oplock_break(tctx);
1810 CHECK_VAL(break_info.count, get_setinfo_break_count(tctx));
1811 CHECK_VAL(break_info.failures, 0);
1812 CHECK_VAL(break_info.level, 0);
1814 smbcli_close(cli1->tree, fnum);
1817 smb_raw_exit(cli1->session);
1818 smb_raw_exit(cli2->session);
1819 smbcli_deltree(cli1->tree, BASEDIR);
1823 static bool test_raw_oplock_batch12(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1825 const char *fname = BASEDIR "\\test_batch12.dat";
1829 union smb_setfileinfo sfi;
1832 if (!torture_setup_dir(cli1, BASEDIR)) {
1837 smbcli_unlink(cli1->tree, fname);
1839 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1842 base ntcreatex parms
1844 io.generic.level = RAW_OPEN_NTCREATEX;
1845 io.ntcreatex.in.root_fid.fnum = 0;
1846 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1847 io.ntcreatex.in.alloc_size = 0;
1848 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1849 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1850 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1851 io.ntcreatex.in.create_options = 0;
1852 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1853 io.ntcreatex.in.security_flags = 0;
1854 io.ntcreatex.in.fname = fname;
1856 /* Test if a set-allocation size on pathname breaks an exclusive oplock. */
1857 torture_comment(tctx, "BATCH12: Test if setpathinfo allocation size breaks oplocks.\n");
1859 ZERO_STRUCT(break_info);
1860 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1862 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1863 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1864 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1865 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1866 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1867 NTCREATEX_SHARE_ACCESS_WRITE|
1868 NTCREATEX_SHARE_ACCESS_DELETE;
1869 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1870 status = smb_raw_open(cli1->tree, tctx, &io);
1871 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1872 fnum = io.ntcreatex.out.file.fnum;
1873 torture_wait_for_oplock_break(tctx);
1874 CHECK_VAL(break_info.count, 0);
1875 CHECK_VAL(break_info.failures, 0);
1876 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1879 sfi.generic.level = SMB_SFILEINFO_ALLOCATION_INFORMATION;
1880 sfi.generic.in.file.path = fname;
1881 sfi.allocation_info.in.alloc_size = 65536 * 8;
1883 status = smb_raw_setpathinfo(cli2->tree, &sfi);
1884 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1886 torture_wait_for_oplock_break(tctx);
1887 CHECK_VAL(break_info.count, get_setinfo_break_count(tctx));
1888 CHECK_VAL(break_info.failures, 0);
1889 CHECK_VAL(break_info.level, 0);
1891 smbcli_close(cli1->tree, fnum);
1894 smb_raw_exit(cli1->session);
1895 smb_raw_exit(cli2->session);
1896 smbcli_deltree(cli1->tree, BASEDIR);
1900 static bool test_raw_oplock_batch13(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1902 const char *fname = BASEDIR "\\test_batch13.dat";
1906 uint16_t fnum=0, fnum2=0;
1908 if (!torture_setup_dir(cli1, BASEDIR)) {
1913 smbcli_unlink(cli1->tree, fname);
1915 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1916 smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli1->tree);
1919 base ntcreatex parms
1921 io.generic.level = RAW_OPEN_NTCREATEX;
1922 io.ntcreatex.in.root_fid.fnum = 0;
1923 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1924 io.ntcreatex.in.alloc_size = 0;
1925 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1926 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1927 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1928 io.ntcreatex.in.create_options = 0;
1929 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1930 io.ntcreatex.in.security_flags = 0;
1931 io.ntcreatex.in.fname = fname;
1933 torture_comment(tctx, "BATCH13: open with batch oplock\n");
1934 ZERO_STRUCT(break_info);
1936 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1937 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1938 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1939 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1940 NTCREATEX_SHARE_ACCESS_WRITE|
1941 NTCREATEX_SHARE_ACCESS_DELETE;
1942 status = smb_raw_open(cli1->tree, tctx, &io);
1943 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1944 fnum = io.ntcreatex.out.file.fnum;
1945 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1947 ZERO_STRUCT(break_info);
1949 torture_comment(tctx, "second open with attributes only and NTCREATEX_DISP_OVERWRITE dispostion causes oplock break\n");
1951 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1952 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1953 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1954 io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
1955 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1956 NTCREATEX_SHARE_ACCESS_WRITE|
1957 NTCREATEX_SHARE_ACCESS_DELETE;
1958 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE;
1959 status = smb_raw_open(cli2->tree, tctx, &io);
1960 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1961 fnum2 = io.ntcreatex.out.file.fnum;
1962 torture_wait_for_oplock_break(tctx);
1963 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1964 CHECK_VAL(break_info.count, get_break_level1_to_none_count(tctx));
1965 CHECK_VAL(break_info.failures, 0);
1967 smbcli_close(cli1->tree, fnum);
1968 smbcli_close(cli2->tree, fnum2);
1971 smb_raw_exit(cli1->session);
1972 smb_raw_exit(cli2->session);
1973 smbcli_deltree(cli1->tree, BASEDIR);
1977 static bool test_raw_oplock_batch14(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1979 const char *fname = BASEDIR "\\test_batch14.dat";
1983 uint16_t fnum=0, fnum2=0;
1985 if (!torture_setup_dir(cli1, BASEDIR)) {
1990 smbcli_unlink(cli1->tree, fname);
1992 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1995 base ntcreatex parms
1997 io.generic.level = RAW_OPEN_NTCREATEX;
1998 io.ntcreatex.in.root_fid.fnum = 0;
1999 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2000 io.ntcreatex.in.alloc_size = 0;
2001 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2002 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2003 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2004 io.ntcreatex.in.create_options = 0;
2005 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2006 io.ntcreatex.in.security_flags = 0;
2007 io.ntcreatex.in.fname = fname;
2009 torture_comment(tctx, "BATCH14: open with batch oplock\n");
2010 ZERO_STRUCT(break_info);
2012 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2013 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2014 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2015 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
2016 NTCREATEX_SHARE_ACCESS_WRITE|
2017 NTCREATEX_SHARE_ACCESS_DELETE;
2018 status = smb_raw_open(cli1->tree, tctx, &io);
2019 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2020 fnum = io.ntcreatex.out.file.fnum;
2021 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
2023 ZERO_STRUCT(break_info);
2025 torture_comment(tctx, "second open with attributes only and NTCREATEX_DISP_SUPERSEDE dispostion causes oplock break\n");
2027 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2028 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2029 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2030 io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
2031 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
2032 NTCREATEX_SHARE_ACCESS_WRITE|
2033 NTCREATEX_SHARE_ACCESS_DELETE;
2034 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE;
2035 status = smb_raw_open(cli2->tree, tctx, &io);
2036 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2037 fnum2 = io.ntcreatex.out.file.fnum;
2038 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
2040 torture_wait_for_oplock_break(tctx);
2041 CHECK_VAL(break_info.count, get_break_level1_to_none_count(tctx));
2042 CHECK_VAL(break_info.failures, 0);
2044 smbcli_close(cli1->tree, fnum);
2045 smbcli_close(cli2->tree, fnum2);
2047 smb_raw_exit(cli1->session);
2048 smb_raw_exit(cli2->session);
2049 smbcli_deltree(cli1->tree, BASEDIR);
2053 static bool test_raw_oplock_batch15(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
2055 const char *fname = BASEDIR "\\test_batch15.dat";
2059 union smb_fileinfo qfi;
2062 if (!torture_setup_dir(cli1, BASEDIR)) {
2067 smbcli_unlink(cli1->tree, fname);
2069 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2072 base ntcreatex parms
2074 io.generic.level = RAW_OPEN_NTCREATEX;
2075 io.ntcreatex.in.root_fid.fnum = 0;
2076 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2077 io.ntcreatex.in.alloc_size = 0;
2078 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2079 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2080 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2081 io.ntcreatex.in.create_options = 0;
2082 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2083 io.ntcreatex.in.security_flags = 0;
2084 io.ntcreatex.in.fname = fname;
2086 /* Test if a qpathinfo all info on pathname breaks a batch oplock. */
2087 torture_comment(tctx, "BATCH15: Test if qpathinfo all info breaks a batch oplock (should not).\n");
2089 ZERO_STRUCT(break_info);
2091 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2092 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2093 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2094 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2095 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
2096 NTCREATEX_SHARE_ACCESS_WRITE|
2097 NTCREATEX_SHARE_ACCESS_DELETE;
2098 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2099 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
2100 status = smb_raw_open(cli1->tree, tctx, &io);
2101 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2102 fnum = io.ntcreatex.out.file.fnum;
2104 torture_wait_for_oplock_break(tctx);
2105 CHECK_VAL(break_info.count, 0);
2106 CHECK_VAL(break_info.failures, 0);
2107 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
2110 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2111 qfi.generic.in.file.path = fname;
2113 status = smb_raw_pathinfo(cli2->tree, tctx, &qfi);
2114 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2116 torture_wait_for_oplock_break(tctx);
2117 CHECK_VAL(break_info.count, 0);
2119 smbcli_close(cli1->tree, fnum);
2122 smb_raw_exit(cli1->session);
2123 smb_raw_exit(cli2->session);
2124 smbcli_deltree(cli1->tree, BASEDIR);
2128 static bool test_raw_oplock_batch16(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
2130 const char *fname = BASEDIR "\\test_batch16.dat";
2134 uint16_t fnum=0, fnum2=0;
2136 if (!torture_setup_dir(cli1, BASEDIR)) {
2141 smbcli_unlink(cli1->tree, fname);
2143 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2144 smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli1->tree);
2147 base ntcreatex parms
2149 io.generic.level = RAW_OPEN_NTCREATEX;
2150 io.ntcreatex.in.root_fid.fnum = 0;
2151 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2152 io.ntcreatex.in.alloc_size = 0;
2153 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2154 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2155 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2156 io.ntcreatex.in.create_options = 0;
2157 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2158 io.ntcreatex.in.security_flags = 0;
2159 io.ntcreatex.in.fname = fname;
2161 torture_comment(tctx, "BATCH16: open with batch oplock\n");
2162 ZERO_STRUCT(break_info);
2164 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2165 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2166 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2167 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
2168 NTCREATEX_SHARE_ACCESS_WRITE|
2169 NTCREATEX_SHARE_ACCESS_DELETE;
2170 status = smb_raw_open(cli1->tree, tctx, &io);
2171 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2172 fnum = io.ntcreatex.out.file.fnum;
2173 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
2175 ZERO_STRUCT(break_info);
2177 torture_comment(tctx, "second open with attributes only and NTCREATEX_DISP_OVERWRITE_IF dispostion causes oplock break\n");
2179 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2180 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2181 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2182 io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
2183 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
2184 NTCREATEX_SHARE_ACCESS_WRITE|
2185 NTCREATEX_SHARE_ACCESS_DELETE;
2186 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE_IF;
2187 status = smb_raw_open(cli2->tree, tctx, &io);
2188 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2189 fnum2 = io.ntcreatex.out.file.fnum;
2190 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
2192 torture_wait_for_oplock_break(tctx);
2193 CHECK_VAL(break_info.count, get_break_level1_to_none_count(tctx));
2194 CHECK_VAL(break_info.failures, 0);
2196 smbcli_close(cli1->tree, fnum);
2197 smbcli_close(cli2->tree, fnum2);
2200 smb_raw_exit(cli1->session);
2201 smb_raw_exit(cli2->session);
2202 smbcli_deltree(cli1->tree, BASEDIR);
2206 static bool test_raw_oplock_batch17(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
2208 const char *fname1 = BASEDIR "\\test_batch17_1.dat";
2209 const char *fname2 = BASEDIR "\\test_batch17_2.dat";
2213 union smb_rename rn;
2216 if (!torture_setup_dir(cli1, BASEDIR)) {
2221 smbcli_unlink(cli1->tree, fname1);
2222 smbcli_unlink(cli1->tree, fname2);
2224 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2227 base ntcreatex parms
2229 io.generic.level = RAW_OPEN_NTCREATEX;
2230 io.ntcreatex.in.root_fid.fnum = 0;
2231 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2232 io.ntcreatex.in.alloc_size = 0;
2233 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2234 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2235 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2236 io.ntcreatex.in.create_options = 0;
2237 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2238 io.ntcreatex.in.security_flags = 0;
2239 io.ntcreatex.in.fname = fname1;
2241 torture_comment(tctx, "BATCH17: open a file with an batch oplock (share mode: none)\n");
2243 ZERO_STRUCT(break_info);
2244 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2245 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2246 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2248 status = smb_raw_open(cli1->tree, tctx, &io);
2249 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2250 fnum = io.ntcreatex.out.file.fnum;
2251 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
2253 torture_comment(tctx, "rename should trigger a break\n");
2255 rn.generic.level = RAW_RENAME_RENAME;
2256 rn.rename.in.pattern1 = fname1;
2257 rn.rename.in.pattern2 = fname2;
2258 rn.rename.in.attrib = 0;
2260 torture_comment(tctx, "trying rename while first file open\n");
2261 status = smb_raw_rename(cli2->tree, &rn);
2262 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
2264 torture_wait_for_oplock_break(tctx);
2265 CHECK_VAL(break_info.count, 1);
2266 CHECK_VAL(break_info.failures, 0);
2267 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
2269 smbcli_close(cli1->tree, fnum);
2272 smb_raw_exit(cli1->session);
2273 smb_raw_exit(cli2->session);
2274 smbcli_deltree(cli1->tree, BASEDIR);
2278 static bool test_raw_oplock_batch18(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
2280 const char *fname1 = BASEDIR "\\test_batch18_1.dat";
2281 const char *fname2 = BASEDIR "\\test_batch18_2.dat";
2285 union smb_rename rn;
2288 if (!torture_setup_dir(cli1, BASEDIR)) {
2293 smbcli_unlink(cli1->tree, fname1);
2294 smbcli_unlink(cli1->tree, fname2);
2296 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2299 base ntcreatex parms
2301 io.generic.level = RAW_OPEN_NTCREATEX;
2302 io.ntcreatex.in.root_fid.fnum = 0;
2303 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2304 io.ntcreatex.in.alloc_size = 0;
2305 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2306 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2307 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2308 io.ntcreatex.in.create_options = 0;
2309 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2310 io.ntcreatex.in.security_flags = 0;
2311 io.ntcreatex.in.fname = fname1;
2313 torture_comment(tctx, "BATCH18: open a file with an batch oplock (share mode: none)\n");
2315 ZERO_STRUCT(break_info);
2316 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2317 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2318 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2320 status = smb_raw_open(cli1->tree, tctx, &io);
2321 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2322 fnum = io.ntcreatex.out.file.fnum;
2323 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
2325 torture_comment(tctx, "ntrename should trigger a break\n");
2327 rn.generic.level = RAW_RENAME_NTRENAME;
2328 rn.ntrename.in.attrib = 0;
2329 rn.ntrename.in.flags = RENAME_FLAG_RENAME;
2330 rn.ntrename.in.old_name = fname1;
2331 rn.ntrename.in.new_name = fname2;
2332 torture_comment(tctx, "trying rename while first file open\n");
2333 status = smb_raw_rename(cli2->tree, &rn);
2334 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
2336 torture_wait_for_oplock_break(tctx);
2337 CHECK_VAL(break_info.count, 1);
2338 CHECK_VAL(break_info.failures, 0);
2339 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
2341 smbcli_close(cli1->tree, fnum);
2344 smb_raw_exit(cli1->session);
2345 smb_raw_exit(cli2->session);
2346 smbcli_deltree(cli1->tree, BASEDIR);
2350 static bool test_raw_oplock_batch19(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
2352 const char *fname1 = BASEDIR "\\test_batch19_1.dat";
2353 const char *fname2 = BASEDIR "\\test_batch19_2.dat";
2354 const char *fname3 = BASEDIR "\\test_batch19_3.dat";
2358 union smb_fileinfo qfi;
2359 union smb_setfileinfo sfi;
2362 if (!torture_setup_dir(cli1, BASEDIR)) {
2367 smbcli_unlink(cli1->tree, fname1);
2368 smbcli_unlink(cli1->tree, fname2);
2369 smbcli_unlink(cli1->tree, fname3);
2371 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2374 base ntcreatex parms
2376 io.generic.level = RAW_OPEN_NTCREATEX;
2377 io.ntcreatex.in.root_fid.fnum = 0;
2378 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2379 io.ntcreatex.in.alloc_size = 0;
2380 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2381 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
2382 NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_DELETE;
2383 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2384 io.ntcreatex.in.create_options = 0;
2385 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2386 io.ntcreatex.in.security_flags = 0;
2387 io.ntcreatex.in.fname = fname1;
2389 torture_comment(tctx, "BATCH19: open a file with an batch oplock (share mode: none)\n");
2390 ZERO_STRUCT(break_info);
2391 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2392 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2393 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2394 status = smb_raw_open(cli1->tree, tctx, &io);
2395 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2396 fnum = io.ntcreatex.out.file.fnum;
2397 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
2399 torture_comment(tctx, "setpathinfo rename info should trigger a break "
2402 sfi.generic.level = RAW_SFILEINFO_RENAME_INFORMATION;
2403 sfi.generic.in.file.path = fname1;
2404 sfi.rename_information.in.overwrite = 0;
2405 sfi.rename_information.in.root_fid = 0;
2406 sfi.rename_information.in.new_name = fname2+strlen(BASEDIR)+1;
2408 status = smb_raw_setpathinfo(cli2->tree, &sfi);
2409 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2411 torture_wait_for_oplock_break(tctx);
2413 CHECK_VAL(break_info.failures, 0);
2415 if (TARGET_IS_WINXP(tctx) || TARGET_IS_W2K12(tctx)) {
2416 /* Win XP breaks to level2. */
2417 CHECK_VAL(break_info.count, 1);
2418 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
2419 } else if (TARGET_IS_W2K3(tctx) || TARGET_IS_W2K8(tctx) ||
2420 TARGET_IS_SAMBA3(tctx) || TARGET_IS_SAMBA4(tctx)) {
2421 /* Win2K3/2k8 incorrectly doesn't break at all. */
2422 CHECK_VAL(break_info.count, 0);
2424 /* win7/2k8r2 break to none. */
2425 CHECK_VAL(break_info.count, 1);
2426 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_NONE);
2430 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2431 qfi.generic.in.file.fnum = fnum;
2433 status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
2434 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2435 CHECK_STRMATCH(qfi.all_info.out.fname.s, fname2);
2437 /* Close and re-open file with oplock. */
2438 smbcli_close(cli1->tree, fnum);
2439 status = smb_raw_open(cli1->tree, tctx, &io);
2440 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2441 fnum = io.ntcreatex.out.file.fnum;
2442 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
2444 torture_comment(tctx, "setfileinfo rename info on a client's own fid "
2445 "should not trigger a break nor a violation\n");
2446 ZERO_STRUCT(break_info);
2448 sfi.generic.level = RAW_SFILEINFO_RENAME_INFORMATION;
2449 sfi.generic.in.file.fnum = fnum;
2450 sfi.rename_information.in.overwrite = 0;
2451 sfi.rename_information.in.root_fid = 0;
2452 sfi.rename_information.in.new_name = fname3+strlen(BASEDIR)+1;
2454 status = smb_raw_setfileinfo(cli1->tree, &sfi);
2455 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2457 torture_wait_for_oplock_break(tctx);
2458 if (TARGET_IS_WINXP(tctx)) {
2459 /* XP incorrectly breaks to level2. */
2460 CHECK_VAL(break_info.count, 1);
2461 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
2463 CHECK_VAL(break_info.count, 0);
2467 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2468 qfi.generic.in.file.fnum = fnum;
2470 status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
2471 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2472 CHECK_STRMATCH(qfi.all_info.out.fname.s, fname3);
2475 smbcli_close(cli1->tree, fnum);
2476 smb_raw_exit(cli1->session);
2477 smb_raw_exit(cli2->session);
2478 smbcli_deltree(cli1->tree, BASEDIR);
2482 /****************************************************
2483 Called from raw-rename - we need oplock handling for
2484 this test so this is why it's in oplock.c, not rename.c
2485 ****************************************************/
2487 bool test_trans2rename(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
2489 const char *fname1 = BASEDIR "\\test_trans2rename_1.dat";
2490 const char *fname2 = BASEDIR "\\test_trans2rename_2.dat";
2491 const char *fname3 = BASEDIR "\\test_trans2rename_3.dat";
2495 union smb_fileinfo qfi;
2496 union smb_setfileinfo sfi;
2499 if (!torture_setup_dir(cli1, BASEDIR)) {
2504 smbcli_unlink(cli1->tree, fname1);
2505 smbcli_unlink(cli1->tree, fname2);
2506 smbcli_unlink(cli1->tree, fname3);
2508 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2511 base ntcreatex parms
2513 io.generic.level = RAW_OPEN_NTCREATEX;
2514 io.ntcreatex.in.root_fid.fnum = 0;
2515 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2516 io.ntcreatex.in.alloc_size = 0;
2517 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2518 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
2519 NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_DELETE;
2520 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2521 io.ntcreatex.in.create_options = 0;
2522 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2523 io.ntcreatex.in.security_flags = 0;
2524 io.ntcreatex.in.fname = fname1;
2526 torture_comment(tctx, "open a file with an exclusive oplock (share mode: none)\n");
2527 ZERO_STRUCT(break_info);
2528 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2529 NTCREATEX_FLAGS_REQUEST_OPLOCK;
2530 status = smb_raw_open(cli1->tree, tctx, &io);
2531 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2532 fnum = io.ntcreatex.out.file.fnum;
2533 CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
2535 torture_comment(tctx, "setpathinfo rename info should not trigger a break nor a violation\n");
2537 sfi.generic.level = RAW_SFILEINFO_RENAME_INFORMATION;
2538 sfi.generic.in.file.path = fname1;
2539 sfi.rename_information.in.overwrite = 0;
2540 sfi.rename_information.in.root_fid = 0;
2541 sfi.rename_information.in.new_name = fname2+strlen(BASEDIR)+1;
2543 status = smb_raw_setpathinfo(cli2->tree, &sfi);
2545 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2547 torture_wait_for_oplock_break(tctx);
2548 CHECK_VAL(break_info.count, 0);
2551 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2552 qfi.generic.in.file.fnum = fnum;
2554 status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
2555 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2556 CHECK_STRMATCH(qfi.all_info.out.fname.s, fname2);
2558 torture_comment(tctx, "setfileinfo rename info should not trigger a break nor a violation\n");
2560 sfi.generic.level = RAW_SFILEINFO_RENAME_INFORMATION;
2561 sfi.generic.in.file.fnum = fnum;
2562 sfi.rename_information.in.overwrite = 0;
2563 sfi.rename_information.in.root_fid = 0;
2564 sfi.rename_information.in.new_name = fname3+strlen(BASEDIR)+1;
2566 status = smb_raw_setfileinfo(cli1->tree, &sfi);
2567 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2569 torture_wait_for_oplock_break(tctx);
2570 CHECK_VAL(break_info.count, 0);
2573 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2574 qfi.generic.in.file.fnum = fnum;
2576 status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
2577 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2578 CHECK_STRMATCH(qfi.all_info.out.fname.s, fname3);
2581 smbcli_close(cli1->tree, fnum);
2582 smb_raw_exit(cli1->session);
2583 smb_raw_exit(cli2->session);
2584 smbcli_deltree(cli1->tree, BASEDIR);
2588 /****************************************************
2589 Called from raw-rename - we need oplock handling for
2590 this test so this is why it's in oplock.c, not rename.c
2591 ****************************************************/
2593 bool test_nttransrename(struct torture_context *tctx, struct smbcli_state *cli1)
2595 const char *fname1 = BASEDIR "\\test_nttransrename_1.dat";
2596 const char *fname2 = BASEDIR "\\test_nttransrename_2.dat";
2600 union smb_fileinfo qfi, qpi;
2601 union smb_rename rn;
2604 if (!torture_setup_dir(cli1, BASEDIR)) {
2609 smbcli_unlink(cli1->tree, fname1);
2610 smbcli_unlink(cli1->tree, fname2);
2612 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2615 base ntcreatex parms
2617 io.generic.level = RAW_OPEN_NTCREATEX;
2618 io.ntcreatex.in.root_fid.fnum = 0;
2619 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2620 io.ntcreatex.in.alloc_size = 0;
2621 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2622 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2623 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2624 io.ntcreatex.in.create_options = 0;
2625 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2626 io.ntcreatex.in.security_flags = 0;
2627 io.ntcreatex.in.fname = fname1;
2629 torture_comment(tctx, "nttrans_rename: open a file with an exclusive oplock (share mode: none)\n");
2630 ZERO_STRUCT(break_info);
2631 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2632 NTCREATEX_FLAGS_REQUEST_OPLOCK;
2633 status = smb_raw_open(cli1->tree, tctx, &io);
2634 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2635 fnum = io.ntcreatex.out.file.fnum;
2636 CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
2638 torture_comment(tctx, "nttrans_rename: should not trigger a break nor a share mode violation\n");
2640 rn.generic.level = RAW_RENAME_NTTRANS;
2641 rn.nttrans.in.file.fnum = fnum;
2642 rn.nttrans.in.flags = 0;
2643 rn.nttrans.in.new_name = fname2+strlen(BASEDIR)+1;
2645 status = smb_raw_rename(cli1->tree, &rn);
2646 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2648 torture_wait_for_oplock_break(tctx);
2649 CHECK_VAL(break_info.count, 0);
2651 /* w2k3 does nothing, it doesn't rename the file */
2652 torture_comment(tctx, "nttrans_rename: the server should have done nothing\n");
2654 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2655 qfi.generic.in.file.fnum = fnum;
2657 status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
2658 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2659 CHECK_STRMATCH(qfi.all_info.out.fname.s, fname1);
2662 qpi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2663 qpi.generic.in.file.path = fname1;
2665 status = smb_raw_pathinfo(cli1->tree, tctx, &qpi);
2666 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2667 CHECK_STRMATCH(qpi.all_info.out.fname.s, fname1);
2670 qpi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2671 qpi.generic.in.file.path = fname2;
2673 status = smb_raw_pathinfo(cli1->tree, tctx, &qpi);
2674 CHECK_STATUS(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
2676 torture_comment(tctx, "nttrans_rename: after closing the file the file is still not renamed\n");
2677 status = smbcli_close(cli1->tree, fnum);
2678 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2681 qpi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2682 qpi.generic.in.file.path = fname1;
2684 status = smb_raw_pathinfo(cli1->tree, tctx, &qpi);
2685 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2686 CHECK_STRMATCH(qpi.all_info.out.fname.s, fname1);
2689 qpi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2690 qpi.generic.in.file.path = fname2;
2692 status = smb_raw_pathinfo(cli1->tree, tctx, &qpi);
2693 CHECK_STATUS(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
2695 torture_comment(tctx, "nttrans_rename: rename with an invalid handle gives NT_STATUS_INVALID_HANDLE\n");
2697 rn.generic.level = RAW_RENAME_NTTRANS;
2698 rn.nttrans.in.file.fnum = fnum+1;
2699 rn.nttrans.in.flags = 0;
2700 rn.nttrans.in.new_name = fname2+strlen(BASEDIR)+1;
2702 status = smb_raw_rename(cli1->tree, &rn);
2704 CHECK_STATUS(tctx, status, NT_STATUS_INVALID_HANDLE);
2707 smb_raw_exit(cli1->session);
2708 smbcli_deltree(cli1->tree, BASEDIR);
2713 static bool test_raw_oplock_batch20(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
2715 const char *fname1 = BASEDIR "\\test_batch20_1.dat";
2716 const char *fname2 = BASEDIR "\\test_batch20_2.dat";
2717 const char *fname3 = BASEDIR "\\test_batch20_3.dat";
2721 union smb_fileinfo qfi;
2722 union smb_setfileinfo sfi;
2723 uint16_t fnum=0,fnum2=0;
2725 if (!torture_setup_dir(cli1, BASEDIR)) {
2730 smbcli_unlink(cli1->tree, fname1);
2731 smbcli_unlink(cli1->tree, fname2);
2732 smbcli_unlink(cli1->tree, fname3);
2734 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2737 base ntcreatex parms
2739 io.generic.level = RAW_OPEN_NTCREATEX;
2740 io.ntcreatex.in.root_fid.fnum = 0;
2741 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2742 io.ntcreatex.in.alloc_size = 0;
2743 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2744 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2745 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2746 io.ntcreatex.in.create_options = 0;
2747 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2748 io.ntcreatex.in.security_flags = 0;
2749 io.ntcreatex.in.fname = fname1;
2751 torture_comment(tctx, "BATCH20: open a file with an batch oplock (share mode: all)\n");
2752 ZERO_STRUCT(break_info);
2753 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2754 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2755 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2756 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
2757 NTCREATEX_SHARE_ACCESS_WRITE|
2758 NTCREATEX_SHARE_ACCESS_DELETE;
2759 status = smb_raw_open(cli1->tree, tctx, &io);
2760 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2761 fnum = io.ntcreatex.out.file.fnum;
2762 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
2765 sfi.generic.level = RAW_SFILEINFO_RENAME_INFORMATION;
2766 sfi.generic.in.file.path = fname1;
2767 sfi.rename_information.in.overwrite = 0;
2768 sfi.rename_information.in.root_fid = 0;
2769 sfi.rename_information.in.new_name = fname2+strlen(BASEDIR)+1;
2771 status = smb_raw_setpathinfo(cli2->tree, &sfi);
2772 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2774 torture_wait_for_oplock_break(tctx);
2775 CHECK_VAL(break_info.failures, 0);
2777 if (TARGET_IS_WINXP(tctx) || TARGET_IS_W2K12(tctx)) {
2778 /* Win XP breaks to level2. */
2779 CHECK_VAL(break_info.count, 1);
2780 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
2781 } else if (TARGET_IS_W2K3(tctx) || TARGET_IS_W2K8(tctx) ||
2782 TARGET_IS_SAMBA3(tctx) || TARGET_IS_SAMBA4(tctx)) {
2783 /* Win2K3/2k8 incorrectly doesn't break at all. */
2784 CHECK_VAL(break_info.count, 0);
2786 /* win7/2k8r2 break to none. */
2787 CHECK_VAL(break_info.count, 1);
2788 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_NONE);
2792 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2793 qfi.generic.in.file.fnum = fnum;
2795 status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
2796 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2797 CHECK_STRMATCH(qfi.all_info.out.fname.s, fname2);
2799 torture_comment(tctx, "open a file with the new name an batch oplock (share mode: all)\n");
2800 ZERO_STRUCT(break_info);
2801 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2802 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2803 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2804 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
2805 NTCREATEX_SHARE_ACCESS_WRITE|
2806 NTCREATEX_SHARE_ACCESS_DELETE;
2807 io.ntcreatex.in.fname = fname2;
2808 status = smb_raw_open(cli2->tree, tctx, &io);
2809 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2810 fnum2 = io.ntcreatex.out.file.fnum;
2811 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
2813 torture_wait_for_oplock_break(tctx);
2815 if (TARGET_IS_WINXP(tctx)) {
2816 /* XP broke to level2, and doesn't break again. */
2817 CHECK_VAL(break_info.count, 0);
2818 } else if (TARGET_IS_W2K3(tctx) || TARGET_IS_W2K8(tctx) ||
2819 TARGET_IS_SAMBA3(tctx) || TARGET_IS_SAMBA4(tctx)) {
2820 /* Win2K3 incorrectly didn't break before so break now. */
2821 CHECK_VAL(break_info.count, 1);
2822 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
2824 /* win7/2k8r2 broke to none, and doesn't break again. */
2825 CHECK_VAL(break_info.count, 0);
2828 ZERO_STRUCT(break_info);
2831 sfi.generic.level = RAW_SFILEINFO_RENAME_INFORMATION;
2832 sfi.generic.in.file.fnum = fnum;
2833 sfi.rename_information.in.overwrite = 0;
2834 sfi.rename_information.in.root_fid = 0;
2835 sfi.rename_information.in.new_name = fname3+strlen(BASEDIR)+1;
2837 status = smb_raw_setfileinfo(cli1->tree, &sfi);
2838 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2840 torture_wait_for_oplock_break(tctx);
2841 CHECK_VAL(break_info.count, 0);
2844 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2845 qfi.generic.in.file.fnum = fnum;
2847 status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
2848 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2849 CHECK_STRMATCH(qfi.all_info.out.fname.s, fname3);
2852 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2853 qfi.generic.in.file.fnum = fnum2;
2855 status = smb_raw_fileinfo(cli2->tree, tctx, &qfi);
2856 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2857 CHECK_STRMATCH(qfi.all_info.out.fname.s, fname3);
2861 smbcli_close(cli1->tree, fnum);
2862 smbcli_close(cli2->tree, fnum2);
2863 smb_raw_exit(cli1->session);
2864 smb_raw_exit(cli2->session);
2865 smbcli_deltree(cli1->tree, BASEDIR);
2869 static bool test_raw_oplock_batch21(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
2871 const char *fname = BASEDIR "\\test_batch21.dat";
2880 if (!torture_setup_dir(cli1, BASEDIR)) {
2885 smbcli_unlink(cli1->tree, fname);
2887 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2890 base ntcreatex parms
2892 io.generic.level = RAW_OPEN_NTCREATEX;
2893 io.ntcreatex.in.root_fid.fnum = 0;
2894 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2895 io.ntcreatex.in.alloc_size = 0;
2896 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2897 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2898 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2899 io.ntcreatex.in.create_options = 0;
2900 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2901 io.ntcreatex.in.security_flags = 0;
2902 io.ntcreatex.in.fname = fname;
2905 with a batch oplock we get a break
2907 torture_comment(tctx, "BATCH21: open with batch oplock\n");
2908 ZERO_STRUCT(break_info);
2909 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2910 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2911 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2912 status = smb_raw_open(cli1->tree, tctx, &io);
2913 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2914 fnum = io.ntcreatex.out.file.fnum;
2915 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
2917 torture_comment(tctx, "writing should not generate a break\n");
2918 wr = smbcli_write(cli1->tree, fnum, 0, &c, 0, 1);
2920 CHECK_STATUS(tctx, smbcli_nt_error(cli1->tree), NT_STATUS_OK);
2923 e.in.repeat_count = 1;
2924 status = smb_raw_echo(cli1->transport, &e);
2925 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2927 torture_wait_for_oplock_break(tctx);
2928 CHECK_VAL(break_info.count, 0);
2930 smbcli_close(cli1->tree, fnum);
2933 smb_raw_exit(cli1->session);
2934 smb_raw_exit(cli2->session);
2935 smbcli_deltree(cli1->tree, BASEDIR);
2939 static bool test_raw_oplock_batch22(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
2941 const char *fname = BASEDIR "\\test_batch22.dat";
2945 uint16_t fnum = 0, fnum2 = 0, fnum3 = 0;
2947 int timeout = torture_setting_int(tctx, "oplocktimeout", 30);
2950 if (!torture_setup_dir(cli1, BASEDIR)) {
2955 smbcli_unlink(cli1->tree, fname);
2957 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2959 base ntcreatex parms
2961 io.generic.level = RAW_OPEN_NTCREATEX;
2962 io.ntcreatex.in.root_fid.fnum = 0;
2963 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2964 io.ntcreatex.in.alloc_size = 0;
2965 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2966 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2967 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2968 io.ntcreatex.in.create_options = 0;
2969 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2970 io.ntcreatex.in.security_flags = 0;
2971 io.ntcreatex.in.fname = fname;
2974 with a batch oplock we get a break
2976 torture_comment(tctx, "BATCH22: open with batch oplock\n");
2977 ZERO_STRUCT(break_info);
2978 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2979 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2980 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2981 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
2982 NTCREATEX_SHARE_ACCESS_WRITE|
2983 NTCREATEX_SHARE_ACCESS_DELETE;
2984 status = smb_raw_open(cli1->tree, tctx, &io);
2985 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2986 fnum = io.ntcreatex.out.file.fnum;
2987 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
2989 torture_comment(tctx, "a 2nd open should not succeed after the oplock "
2991 tv = timeval_current();
2992 smbcli_oplock_handler(cli1->transport, oplock_handler_timeout, cli1->tree);
2993 status = smb_raw_open(cli1->tree, tctx, &io);
2995 if (TARGET_IS_W2K3(tctx)) {
2996 /* 2k3 has an issue here. xp/win7 are ok. */
2997 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
2999 CHECK_STATUS(tctx, status, NT_STATUS_OK);
3002 fnum2 = io.ntcreatex.out.file.fnum;
3004 torture_wait_for_oplock_break(tctx);
3005 te = (int)timeval_elapsed(&tv);
3008 * Some servers detect clients that let oplocks timeout, so this check
3009 * only shows a warning message instead failing the test to eliminate
3010 * failures from repeated runs of the test. This isn't ideal, but
3011 * it's better than not running the test at all.
3013 CHECK_RANGE(te, timeout - 1, timeout + 15);
3015 CHECK_VAL(break_info.count, 1);
3016 CHECK_VAL(break_info.fnum, fnum);
3017 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
3018 CHECK_VAL(break_info.failures, 0);
3019 ZERO_STRUCT(break_info);
3021 torture_comment(tctx, "a 2nd open should succeed after the oplock "
3022 "release without break\n");
3023 tv = timeval_current();
3024 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
3025 status = smb_raw_open(cli1->tree, tctx, &io);
3026 CHECK_STATUS(tctx, status, NT_STATUS_OK);
3028 /* Samba 3.6.0 and above behave as Windows. */
3029 if (TARGET_IS_SAMBA3(tctx)) {
3030 /* samba3 doesn't grant additional oplocks to bad clients. */
3031 CHECK_VAL(io.ntcreatex.out.oplock_level, NO_OPLOCK_RETURN);
3033 CHECK_VAL(io.ntcreatex.out.oplock_level,
3034 LEVEL_II_OPLOCK_RETURN);
3037 CHECK_VAL(io.ntcreatex.out.oplock_level,
3038 LEVEL_II_OPLOCK_RETURN);
3040 torture_wait_for_oplock_break(tctx);
3041 te = (int)timeval_elapsed(&tv);
3042 /* it should come in without delay */
3043 CHECK_RANGE(te+1, 0, timeout);
3044 fnum3 = io.ntcreatex.out.file.fnum;
3046 CHECK_VAL(break_info.count, 0);
3048 smbcli_close(cli1->tree, fnum);
3049 smbcli_close(cli1->tree, fnum2);
3050 smbcli_close(cli1->tree, fnum3);
3053 smb_raw_exit(cli1->session);
3054 smb_raw_exit(cli2->session);
3055 smbcli_deltree(cli1->tree, BASEDIR);
3059 static bool test_raw_oplock_batch23(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
3061 const char *fname = BASEDIR "\\test_batch23.dat";
3065 uint16_t fnum=0, fnum2=0,fnum3=0;
3066 struct smbcli_state *cli3 = NULL;
3068 if (!torture_setup_dir(cli1, BASEDIR)) {
3073 smbcli_unlink(cli1->tree, fname);
3075 ret = open_connection_no_level2_oplocks(tctx, &cli3);
3076 CHECK_VAL(ret, true);
3078 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
3079 smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli2->tree);
3080 smbcli_oplock_handler(cli3->transport, oplock_handler_ack_to_given, cli3->tree);
3083 base ntcreatex parms
3085 io.generic.level = RAW_OPEN_NTCREATEX;
3086 io.ntcreatex.in.root_fid.fnum = 0;
3087 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
3088 io.ntcreatex.in.alloc_size = 0;
3089 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
3090 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
3091 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
3092 io.ntcreatex.in.create_options = 0;
3093 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
3094 io.ntcreatex.in.security_flags = 0;
3095 io.ntcreatex.in.fname = fname;
3097 torture_comment(tctx, "BATCH23: a open and ask for a batch oplock\n");
3098 ZERO_STRUCT(break_info);
3100 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_READ | SEC_RIGHTS_FILE_WRITE;
3101 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
3102 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
3103 NTCREATEX_FLAGS_REQUEST_OPLOCK |
3104 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
3105 status = smb_raw_open(cli1->tree, tctx, &io);
3106 CHECK_STATUS(tctx, status, NT_STATUS_OK);
3107 fnum = io.ntcreatex.out.file.fnum;
3108 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
3110 ZERO_STRUCT(break_info);
3112 torture_comment(tctx, "a 2nd open without level2 oplock support should generate a break to level2\n");
3113 status = smb_raw_open(cli3->tree, tctx, &io);
3114 CHECK_STATUS(tctx, status, NT_STATUS_OK);
3115 fnum3 = io.ntcreatex.out.file.fnum;
3116 CHECK_VAL(io.ntcreatex.out.oplock_level, NO_OPLOCK_RETURN);
3118 torture_wait_for_oplock_break(tctx);
3119 CHECK_VAL(break_info.count, 1);
3120 CHECK_VAL(break_info.fnum, fnum);
3121 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
3122 CHECK_VAL(break_info.failures, 0);
3124 ZERO_STRUCT(break_info);
3126 torture_comment(tctx, "a 3rd open with level2 oplock support should not generate a break\n");
3127 status = smb_raw_open(cli2->tree, tctx, &io);
3128 CHECK_STATUS(tctx, status, NT_STATUS_OK);
3129 fnum2 = io.ntcreatex.out.file.fnum;
3130 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
3132 torture_wait_for_oplock_break(tctx);
3133 CHECK_VAL(break_info.count, 0);
3135 smbcli_close(cli1->tree, fnum);
3136 smbcli_close(cli2->tree, fnum2);
3137 smbcli_close(cli3->tree, fnum3);
3140 smb_raw_exit(cli1->session);
3141 smb_raw_exit(cli2->session);
3142 smb_raw_exit(cli3->session);
3143 smbcli_deltree(cli1->tree, BASEDIR);
3147 static bool test_raw_oplock_batch24(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
3149 const char *fname = BASEDIR "\\test_batch24.dat";
3153 uint16_t fnum2=0,fnum3=0;
3154 struct smbcli_state *cli3 = NULL;
3156 if (!torture_setup_dir(cli1, BASEDIR)) {
3161 smbcli_unlink(cli1->tree, fname);
3163 ret = open_connection_no_level2_oplocks(tctx, &cli3);
3164 CHECK_VAL(ret, true);
3166 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
3167 smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli2->tree);
3168 smbcli_oplock_handler(cli3->transport, oplock_handler_ack_to_given, cli3->tree);
3171 base ntcreatex parms
3173 io.generic.level = RAW_OPEN_NTCREATEX;
3174 io.ntcreatex.in.root_fid.fnum = 0;
3175 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
3176 io.ntcreatex.in.alloc_size = 0;
3177 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
3178 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
3179 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
3180 io.ntcreatex.in.create_options = 0;
3181 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
3182 io.ntcreatex.in.security_flags = 0;
3183 io.ntcreatex.in.fname = fname;
3185 torture_comment(tctx, "BATCH24: a open without level support and ask for a batch oplock\n");
3186 ZERO_STRUCT(break_info);
3188 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_READ | SEC_RIGHTS_FILE_WRITE;
3189 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
3190 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
3191 NTCREATEX_FLAGS_REQUEST_OPLOCK |
3192 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
3193 status = smb_raw_open(cli3->tree, tctx, &io);
3194 CHECK_STATUS(tctx, status, NT_STATUS_OK);
3195 fnum3 = io.ntcreatex.out.file.fnum;
3196 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
3198 ZERO_STRUCT(break_info);
3200 torture_comment(tctx, "a 2nd open with level2 oplock support should generate a break to none\n");
3201 status = smb_raw_open(cli2->tree, tctx, &io);
3202 CHECK_STATUS(tctx, status, NT_STATUS_OK);
3203 fnum2 = io.ntcreatex.out.file.fnum;
3204 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
3206 torture_wait_for_oplock_break(tctx);
3207 CHECK_VAL(break_info.count, 1);
3208 CHECK_VAL(break_info.fnum, fnum3);
3209 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_NONE);
3210 CHECK_VAL(break_info.failures, 0);
3212 smbcli_close(cli3->tree, fnum3);
3213 smbcli_close(cli2->tree, fnum2);
3216 smb_raw_exit(cli1->session);
3217 smb_raw_exit(cli2->session);
3218 smb_raw_exit(cli3->session);
3219 smbcli_deltree(cli1->tree, BASEDIR);
3223 static bool test_raw_oplock_batch25(struct torture_context *tctx,
3224 struct smbcli_state *cli1,
3225 struct smbcli_state *cli2)
3227 const char *fname = BASEDIR "\\test_batch25.dat";
3231 union smb_setfileinfo sfi;
3234 if (!torture_setup_dir(cli1, BASEDIR)) {
3239 smbcli_unlink(cli1->tree, fname);
3241 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
3244 base ntcreatex parms
3246 io.generic.level = RAW_OPEN_NTCREATEX;
3247 io.ntcreatex.in.root_fid.fnum = 0;
3248 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
3249 io.ntcreatex.in.alloc_size = 0;
3250 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
3251 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
3252 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
3253 io.ntcreatex.in.create_options = 0;
3254 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
3255 io.ntcreatex.in.security_flags = 0;
3256 io.ntcreatex.in.fname = fname;
3258 torture_comment(tctx, "BATCH25: open a file with an batch oplock "
3259 "(share mode: none)\n");
3261 ZERO_STRUCT(break_info);
3262 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
3263 NTCREATEX_FLAGS_REQUEST_OPLOCK |
3264 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
3265 status = smb_raw_open(cli1->tree, tctx, &io);
3266 CHECK_STATUS(tctx, status, NT_STATUS_OK);
3267 fnum = io.ntcreatex.out.file.fnum;
3268 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
3270 torture_comment(tctx, "setpathinfo attribute info should not trigger "
3271 "a break nor a violation\n");
3273 sfi.generic.level = RAW_SFILEINFO_SETATTR;
3274 sfi.generic.in.file.path = fname;
3275 sfi.setattr.in.attrib = FILE_ATTRIBUTE_HIDDEN;
3276 sfi.setattr.in.write_time = 0;
3278 status = smb_raw_setpathinfo(cli2->tree, &sfi);
3279 CHECK_STATUS(tctx, status, NT_STATUS_OK);
3281 torture_wait_for_oplock_break(tctx);
3282 CHECK_VAL(break_info.count, 0);
3284 smbcli_close(cli1->tree, fnum);
3287 smb_raw_exit(cli1->session);
3288 smb_raw_exit(cli2->session);
3289 smbcli_deltree(cli1->tree, BASEDIR);
3294 * Similar to batch17/18, but test with open share mode rather than
3297 static bool test_raw_oplock_batch26(struct torture_context *tctx,
3298 struct smbcli_state *cli1, struct smbcli_state *cli2)
3300 const char *fname1 = BASEDIR "\\test_batch26_1.dat";
3301 const char *fname2 = BASEDIR "\\test_batch26_2.dat";
3305 union smb_rename rn;
3308 if (!torture_setup_dir(cli1, BASEDIR)) {
3313 smbcli_unlink(cli1->tree, fname1);
3314 smbcli_unlink(cli1->tree, fname2);
3316 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given,
3320 base ntcreatex parms
3322 io.generic.level = RAW_OPEN_NTCREATEX;
3323 io.ntcreatex.in.root_fid.fnum = 0;
3324 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
3325 io.ntcreatex.in.alloc_size = 0;
3326 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
3327 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
3328 NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_DELETE;
3329 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
3330 io.ntcreatex.in.create_options = 0;
3331 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
3332 io.ntcreatex.in.security_flags = 0;
3333 io.ntcreatex.in.fname = fname1;
3335 torture_comment(tctx, "BATCH26: open a file with an batch oplock "
3336 "(share mode: none)\n");
3338 ZERO_STRUCT(break_info);
3339 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
3340 NTCREATEX_FLAGS_REQUEST_OPLOCK |
3341 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
3344 status = smb_raw_open(cli1->tree, tctx, &io);
3345 CHECK_STATUS(tctx, status, NT_STATUS_OK);
3346 fnum = io.ntcreatex.out.file.fnum;
3347 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
3349 torture_comment(tctx, "rename should trigger a break\n");
3351 rn.generic.level = RAW_RENAME_RENAME;
3352 rn.rename.in.pattern1 = fname1;
3353 rn.rename.in.pattern2 = fname2;
3354 rn.rename.in.attrib = 0;
3356 torture_comment(tctx, "trying rename while first file open\n");
3357 status = smb_raw_rename(cli2->tree, &rn);
3358 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
3360 torture_wait_for_oplock_break(tctx);
3361 CHECK_VAL(break_info.count, 1);
3362 CHECK_VAL(break_info.failures, 0);
3363 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
3365 /* Close and reopen with batch again. */
3366 smbcli_close(cli1->tree, fnum);
3367 ZERO_STRUCT(break_info);
3369 status = smb_raw_open(cli1->tree, tctx, &io);
3370 CHECK_STATUS(tctx, status, NT_STATUS_OK);
3371 fnum = io.ntcreatex.out.file.fnum;
3372 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
3374 /* Now try ntrename. */
3375 torture_comment(tctx, "ntrename should trigger a break\n");
3377 rn.generic.level = RAW_RENAME_NTRENAME;
3378 rn.ntrename.in.attrib = 0;
3379 rn.ntrename.in.flags = RENAME_FLAG_RENAME;
3380 rn.ntrename.in.old_name = fname1;
3381 rn.ntrename.in.new_name = fname2;
3382 torture_comment(tctx, "trying rename while first file open\n");
3383 status = smb_raw_rename(cli2->tree, &rn);
3384 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
3386 torture_wait_for_oplock_break(tctx);
3387 CHECK_VAL(break_info.count, 1);
3388 CHECK_VAL(break_info.failures, 0);
3389 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
3391 smbcli_close(cli1->tree, fnum);
3394 smb_raw_exit(cli1->session);
3395 smb_raw_exit(cli2->session);
3396 smbcli_deltree(cli1->tree, BASEDIR);
3400 /* Test how oplocks work on streams. */
3401 static bool test_raw_oplock_stream1(struct torture_context *tctx,
3402 struct smbcli_state *cli1,
3403 struct smbcli_state *cli2)
3407 const char *fname_base = BASEDIR "\\test_stream1.txt";
3408 const char *stream = "Stream One:$DATA";
3409 const char *fname_stream, *fname_default_stream;
3410 const char *default_stream = "::$DATA";
3414 int stream_fnum = -1;
3415 uint32_t batch_req = NTCREATEX_FLAGS_REQUEST_OPLOCK |
3416 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK | NTCREATEX_FLAGS_EXTENDED;
3417 uint32_t exclusive_req = NTCREATEX_FLAGS_REQUEST_OPLOCK |
3418 NTCREATEX_FLAGS_EXTENDED;
3420 #define NSTREAM_OPLOCK_RESULTS 8
3423 bool open_base_file;
3424 uint32_t oplock_req;
3425 uint32_t oplock_granted;
3426 } stream_oplock_results[NSTREAM_OPLOCK_RESULTS] = {
3427 /* Request oplock on stream without the base file open. */
3428 {&fname_stream, false, batch_req, NO_OPLOCK_RETURN},
3429 {&fname_default_stream, false, batch_req, NO_OPLOCK_RETURN},
3430 {&fname_stream, false, exclusive_req, EXCLUSIVE_OPLOCK_RETURN},
3431 {&fname_default_stream, false, exclusive_req, EXCLUSIVE_OPLOCK_RETURN},
3433 /* Request oplock on stream with the base file open. */
3434 {&fname_stream, true, batch_req, NO_OPLOCK_RETURN},
3435 {&fname_default_stream, true, batch_req, NO_OPLOCK_RETURN},
3436 {&fname_stream, true, exclusive_req, EXCLUSIVE_OPLOCK_RETURN},
3437 {&fname_default_stream, true, exclusive_req, LEVEL_II_OPLOCK_RETURN},
3442 /* Only passes against windows at the moment. */
3443 if (torture_setting_bool(tctx, "samba3", false) ||
3444 torture_setting_bool(tctx, "samba4", false)) {
3445 torture_skip(tctx, "STREAM1 disabled against samba3+4\n");
3448 fname_stream = talloc_asprintf(tctx, "%s:%s", fname_base, stream);
3449 fname_default_stream = talloc_asprintf(tctx, "%s%s", fname_base,
3452 if (!torture_setup_dir(cli1, BASEDIR)) {
3455 smbcli_unlink(cli1->tree, fname_base);
3457 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
3458 smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli2->tree);
3460 /* Setup generic open parameters. */
3461 io.generic.level = RAW_OPEN_NTCREATEX;
3462 io.ntcreatex.in.root_fid.fnum = 0;
3463 io.ntcreatex.in.access_mask = (SEC_FILE_READ_DATA|SEC_FILE_WRITE_DATA|
3464 SEC_FILE_APPEND_DATA|SEC_STD_READ_CONTROL);
3465 io.ntcreatex.in.create_options = 0;
3466 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
3467 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
3468 NTCREATEX_SHARE_ACCESS_WRITE;
3469 io.ntcreatex.in.alloc_size = 0;
3470 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
3471 io.ntcreatex.in.security_flags = 0;
3473 /* Create the file with a stream */
3474 io.ntcreatex.in.fname = fname_stream;
3475 io.ntcreatex.in.flags = 0;
3476 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
3477 status = smb_raw_open(cli1->tree, tctx, &io);
3478 CHECK_STATUS(tctx, status, NT_STATUS_OK);
3479 smbcli_close(cli1->tree, io.ntcreatex.out.file.fnum);
3481 /* Change the disposition to open now that the file has been created. */
3482 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
3484 /* Try some permutations of taking oplocks on streams. */
3485 for (i = 0; i < NSTREAM_OPLOCK_RESULTS; i++) {
3486 const char *fname = *stream_oplock_results[i].fname;
3487 bool open_base_file = stream_oplock_results[i].open_base_file;
3488 uint32_t oplock_req = stream_oplock_results[i].oplock_req;
3489 uint32_t oplock_granted =
3490 stream_oplock_results[i].oplock_granted;
3493 if (open_base_file) {
3494 torture_comment(tctx, "Opening base file: %s with "
3495 "%d\n", fname_base, batch_req);
3496 io.ntcreatex.in.fname = fname_base;
3497 io.ntcreatex.in.flags = batch_req;
3498 status = smb_raw_open(cli2->tree, tctx, &io);
3499 CHECK_STATUS(tctx, status, NT_STATUS_OK);
3500 CHECK_VAL(io.ntcreatex.out.oplock_level,
3501 BATCH_OPLOCK_RETURN);
3502 base_fnum = io.ntcreatex.out.file.fnum;
3505 torture_comment(tctx, "%d: Opening stream: %s with %d\n", i,
3507 io.ntcreatex.in.fname = fname;
3508 io.ntcreatex.in.flags = oplock_req;
3510 /* Do the open with the desired oplock on the stream. */
3511 status = smb_raw_open(cli1->tree, tctx, &io);
3512 CHECK_STATUS(tctx, status, NT_STATUS_OK);
3513 CHECK_VAL(io.ntcreatex.out.oplock_level, oplock_granted);
3514 smbcli_close(cli1->tree, io.ntcreatex.out.file.fnum);
3516 /* Cleanup the base file if it was opened. */
3517 if (base_fnum != -1) {
3518 smbcli_close(cli2->tree, base_fnum);
3522 /* Open the stream with an exclusive oplock. */
3523 torture_comment(tctx, "Opening stream: %s with %d\n",
3524 fname_stream, exclusive_req);
3525 io.ntcreatex.in.fname = fname_stream;
3526 io.ntcreatex.in.flags = exclusive_req;
3527 status = smb_raw_open(cli1->tree, tctx, &io);
3528 CHECK_STATUS(tctx, status, NT_STATUS_OK);
3529 CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
3530 stream_fnum = io.ntcreatex.out.file.fnum;
3532 /* Open the base file and see if it contends. */
3533 ZERO_STRUCT(break_info);
3534 torture_comment(tctx, "Opening base file: %s with "
3535 "%d\n", fname_base, batch_req);
3536 io.ntcreatex.in.fname = fname_base;
3537 io.ntcreatex.in.flags = batch_req;
3538 status = smb_raw_open(cli2->tree, tctx, &io);
3539 CHECK_STATUS(tctx, status, NT_STATUS_OK);
3540 CHECK_VAL(io.ntcreatex.out.oplock_level,
3541 BATCH_OPLOCK_RETURN);
3542 smbcli_close(cli2->tree, io.ntcreatex.out.file.fnum);
3544 torture_wait_for_oplock_break(tctx);
3545 CHECK_VAL(break_info.count, 0);
3546 CHECK_VAL(break_info.failures, 0);
3548 /* Open the stream again to see if it contends. */
3549 ZERO_STRUCT(break_info);
3550 torture_comment(tctx, "Opening stream again: %s with "
3551 "%d\n", fname_base, batch_req);
3552 io.ntcreatex.in.fname = fname_stream;
3553 io.ntcreatex.in.flags = exclusive_req;
3554 status = smb_raw_open(cli2->tree, tctx, &io);
3555 CHECK_STATUS(tctx, status, NT_STATUS_OK);
3556 CHECK_VAL(io.ntcreatex.out.oplock_level,
3557 LEVEL_II_OPLOCK_RETURN);
3558 smbcli_close(cli2->tree, io.ntcreatex.out.file.fnum);
3560 torture_wait_for_oplock_break(tctx);
3561 CHECK_VAL(break_info.count, 1);
3562 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
3563 CHECK_VAL(break_info.failures, 0);
3565 /* Close the stream. */
3566 if (stream_fnum != -1) {
3567 smbcli_close(cli1->tree, stream_fnum);
3571 smbcli_close(cli1->tree, fnum);
3572 smb_raw_exit(cli1->session);
3573 smb_raw_exit(cli2->session);
3574 smbcli_deltree(cli1->tree, BASEDIR);
3578 static bool test_raw_oplock_doc(struct torture_context *tctx,
3579 struct smbcli_state *cli,
3580 struct smbcli_state *cli2)
3582 const char *fname = BASEDIR "\\test_oplock_doc.dat";
3588 torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
3591 smbcli_unlink(cli->tree, fname);
3593 smbcli_oplock_handler(cli->transport, oplock_handler_ack_to_given,
3597 base ntcreatex parms
3599 io.generic.level = RAW_OPEN_NTCREATEX;
3600 io.ntcreatex.in.root_fid.fnum = 0;
3601 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
3602 io.ntcreatex.in.alloc_size = 0;
3603 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
3604 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
3605 NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE;
3606 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
3607 io.ntcreatex.in.create_options = 0;
3608 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
3609 io.ntcreatex.in.security_flags = 0;
3610 io.ntcreatex.in.fname = fname;
3612 torture_comment(tctx, "open a file with a batch oplock\n");
3613 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
3614 NTCREATEX_FLAGS_REQUEST_OPLOCK |
3615 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
3617 status = smb_raw_open(cli->tree, tctx, &io);
3618 CHECK_STATUS(tctx, status, NT_STATUS_OK);
3619 fnum = io.ntcreatex.out.file.fnum;
3620 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
3622 torture_comment(tctx, "Set delete-on-close\n");
3623 status = smbcli_nt_delete_on_close(cli->tree, fnum, true);
3624 CHECK_STATUS(tctx, status, NT_STATUS_OK);
3626 torture_comment(tctx, "2nd open should not break and get "
3627 "DELETE_PENDING\n");
3628 ZERO_STRUCT(break_info);
3629 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
3630 io.ntcreatex.in.create_options = 0;
3631 io.ntcreatex.in.access_mask = SEC_FILE_READ_DATA;
3632 status = smb_raw_open(cli2->tree, tctx, &io);
3633 CHECK_STATUS(tctx, status, NT_STATUS_DELETE_PENDING);
3634 CHECK_VAL(break_info.count, 0);
3636 smbcli_close(cli->tree, fnum);
3639 smb_raw_exit(cli->session);
3640 smbcli_deltree(cli->tree, BASEDIR);
3644 /* Open a file with a batch oplock, then open it again from a second client
3645 * requesting no oplock. Having two open file handles should break our own
3646 * oplock during BRL acquisition.
3648 static bool test_raw_oplock_brl1(struct torture_context *tctx,
3649 struct smbcli_state *cli1,
3650 struct smbcli_state *cli2)
3652 const char *fname = BASEDIR "\\test_batch_brl.dat";
3661 if (!torture_setup_dir(cli1, BASEDIR)) {
3666 smbcli_unlink(cli1->tree, fname);
3668 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given,
3672 base ntcreatex parms
3674 io.generic.level = RAW_OPEN_NTCREATEX;
3675 io.ntcreatex.in.root_fid.fnum = 0;
3676 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_READ |
3677 SEC_RIGHTS_FILE_WRITE;
3678 io.ntcreatex.in.alloc_size = 0;
3679 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
3680 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
3681 NTCREATEX_SHARE_ACCESS_WRITE;
3682 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
3683 io.ntcreatex.in.create_options = 0;
3684 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
3685 io.ntcreatex.in.security_flags = 0;
3686 io.ntcreatex.in.fname = fname;
3689 with a batch oplock we get a break
3691 torture_comment(tctx, "open with batch oplock\n");
3692 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
3693 NTCREATEX_FLAGS_REQUEST_OPLOCK |
3694 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
3696 status = smb_raw_open(cli1->tree, tctx, &io);
3697 CHECK_STATUS(tctx, status, NT_STATUS_OK);
3698 fnum = io.ntcreatex.out.file.fnum;
3699 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
3700 /* create a file with bogus data */
3701 memset(buf, 0, sizeof(buf));
3703 if (smbcli_write(cli1->tree, fnum, 0, buf, 0, sizeof(buf)) !=
3706 torture_comment(tctx, "Failed to create file\n");
3710 torture_comment(tctx, "a 2nd open should give a break\n");
3711 ZERO_STRUCT(break_info);
3713 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
3714 status = smb_raw_open(cli2->tree, tctx, &io);
3715 fnum2 = io.ntcreatex.out.file.fnum;
3716 CHECK_STATUS(tctx, status, NT_STATUS_OK);
3717 CHECK_VAL(break_info.count, 1);
3718 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
3719 CHECK_VAL(break_info.failures, 0);
3720 CHECK_VAL(break_info.fnum, fnum);
3722 ZERO_STRUCT(break_info);
3724 torture_comment(tctx, "a self BRL acquisition should break to none\n");
3726 status = smbcli_lock(cli1->tree, fnum, 0, 4, 0, WRITE_LOCK);
3727 CHECK_STATUS(tctx, status, NT_STATUS_OK);
3729 torture_wait_for_oplock_break(tctx);
3730 CHECK_VAL(break_info.count, 1);
3731 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_NONE);
3732 CHECK_VAL(break_info.fnum, fnum);
3733 CHECK_VAL(break_info.failures, 0);
3735 /* expect no oplock break */
3736 ZERO_STRUCT(break_info);
3737 status = smbcli_lock(cli1->tree, fnum, 2, 4, 0, WRITE_LOCK);
3738 CHECK_STATUS(tctx, status, NT_STATUS_LOCK_NOT_GRANTED);
3740 torture_wait_for_oplock_break(tctx);
3741 CHECK_VAL(break_info.count, 0);
3742 CHECK_VAL(break_info.level, 0);
3743 CHECK_VAL(break_info.fnum, 0);
3744 CHECK_VAL(break_info.failures, 0);
3746 smbcli_close(cli1->tree, fnum);
3747 smbcli_close(cli2->tree, fnum2);
3750 smb_raw_exit(cli1->session);
3751 smb_raw_exit(cli2->session);
3752 smbcli_deltree(cli1->tree, BASEDIR);
3757 /* Open a file with a batch oplock on one client and then acquire a brl.
3758 * We should not contend our own oplock.
3760 static bool test_raw_oplock_brl2(struct torture_context *tctx, struct smbcli_state *cli1)
3762 const char *fname = BASEDIR "\\test_batch_brl.dat";
3770 if (!torture_setup_dir(cli1, BASEDIR)) {
3775 smbcli_unlink(cli1->tree, fname);
3777 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given,
3781 base ntcreatex parms
3783 io.generic.level = RAW_OPEN_NTCREATEX;
3784 io.ntcreatex.in.root_fid.fnum = 0;
3785 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_READ |
3786 SEC_RIGHTS_FILE_WRITE;
3787 io.ntcreatex.in.alloc_size = 0;
3788 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
3789 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
3790 NTCREATEX_SHARE_ACCESS_WRITE;
3791 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
3792 io.ntcreatex.in.create_options = 0;
3793 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
3794 io.ntcreatex.in.security_flags = 0;
3795 io.ntcreatex.in.fname = fname;
3798 with a batch oplock we get a break
3800 torture_comment(tctx, "open with batch oplock\n");
3801 ZERO_STRUCT(break_info);
3802 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
3803 NTCREATEX_FLAGS_REQUEST_OPLOCK |
3804 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
3806 status = smb_raw_open(cli1->tree, tctx, &io);
3807 CHECK_STATUS(tctx, status, NT_STATUS_OK);
3808 fnum = io.ntcreatex.out.file.fnum;
3809 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
3811 /* create a file with bogus data */
3812 memset(buf, 0, sizeof(buf));
3814 if (smbcli_write(cli1->tree, fnum, 0, buf, 0, sizeof(buf)) !=
3817 torture_comment(tctx, "Failed to create file\n");
3821 torture_comment(tctx, "a self BRL acquisition should not break to "
3824 status = smbcli_lock(cli1->tree, fnum, 0, 4, 0, WRITE_LOCK);
3825 CHECK_STATUS(tctx, status, NT_STATUS_OK);
3827 status = smbcli_lock(cli1->tree, fnum, 2, 4, 0, WRITE_LOCK);
3828 CHECK_STATUS(tctx, status, NT_STATUS_LOCK_NOT_GRANTED);
3830 /* With one file handle open a BRL should not contend our oplock.
3831 * Thus, no oplock break will be received and the entire break_info
3832 * struct will be 0 */
3833 torture_wait_for_oplock_break(tctx);
3834 CHECK_VAL(break_info.fnum, 0);
3835 CHECK_VAL(break_info.count, 0);
3836 CHECK_VAL(break_info.level, 0);
3837 CHECK_VAL(break_info.failures, 0);
3839 smbcli_close(cli1->tree, fnum);
3842 smb_raw_exit(cli1->session);
3843 smbcli_deltree(cli1->tree, BASEDIR);
3847 /* Open a file with a batch oplock twice from one client and then acquire a
3848 * brl. BRL acquisition should break our own oplock.
3850 static bool test_raw_oplock_brl3(struct torture_context *tctx,
3851 struct smbcli_state *cli1)
3853 const char *fname = BASEDIR "\\test_batch_brl.dat";
3861 if (!torture_setup_dir(cli1, BASEDIR)) {
3866 smbcli_unlink(cli1->tree, fname);
3868 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given,
3872 base ntcreatex parms
3874 io.generic.level = RAW_OPEN_NTCREATEX;
3875 io.ntcreatex.in.root_fid.fnum = 0;
3876 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_READ |
3877 SEC_RIGHTS_FILE_WRITE;
3878 io.ntcreatex.in.alloc_size = 0;
3879 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
3880 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
3881 NTCREATEX_SHARE_ACCESS_WRITE;
3882 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
3883 io.ntcreatex.in.create_options = 0;
3884 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
3885 io.ntcreatex.in.security_flags = 0;
3886 io.ntcreatex.in.fname = fname;
3889 with a batch oplock we get a break
3891 torture_comment(tctx, "open with batch oplock\n");
3892 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
3893 NTCREATEX_FLAGS_REQUEST_OPLOCK |
3894 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
3896 status = smb_raw_open(cli1->tree, tctx, &io);
3897 CHECK_STATUS(tctx, status, NT_STATUS_OK);
3898 fnum = io.ntcreatex.out.file.fnum;
3899 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
3901 /* create a file with bogus data */
3902 memset(buf, 0, sizeof(buf));
3904 if (smbcli_write(cli1->tree, fnum, 0, buf, 0, sizeof(buf)) !=
3907 torture_comment(tctx, "Failed to create file\n");
3912 torture_comment(tctx, "a 2nd open should give a break\n");
3913 ZERO_STRUCT(break_info);
3915 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
3916 status = smb_raw_open(cli1->tree, tctx, &io);
3917 fnum2 = io.ntcreatex.out.file.fnum;
3918 CHECK_STATUS(tctx, status, NT_STATUS_OK);
3919 CHECK_VAL(break_info.count, 1);
3920 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
3921 CHECK_VAL(break_info.failures, 0);
3922 CHECK_VAL(break_info.fnum, fnum);
3924 ZERO_STRUCT(break_info);
3926 torture_comment(tctx, "a self BRL acquisition should break to none\n");
3928 status = smbcli_lock(cli1->tree, fnum, 0, 4, 0, WRITE_LOCK);
3929 CHECK_STATUS(tctx, status, NT_STATUS_OK);
3931 torture_wait_for_oplock_break(tctx);
3932 CHECK_VAL(break_info.count, 1);
3933 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_NONE);
3934 CHECK_VAL(break_info.fnum, fnum);
3935 CHECK_VAL(break_info.failures, 0);
3937 /* expect no oplock break */
3938 ZERO_STRUCT(break_info);
3939 status = smbcli_lock(cli1->tree, fnum, 2, 4, 0, WRITE_LOCK);
3940 CHECK_STATUS(tctx, status, NT_STATUS_LOCK_NOT_GRANTED);
3942 torture_wait_for_oplock_break(tctx);
3943 CHECK_VAL(break_info.count, 0);
3944 CHECK_VAL(break_info.level, 0);
3945 CHECK_VAL(break_info.fnum, 0);
3946 CHECK_VAL(break_info.failures, 0);
3948 smbcli_close(cli1->tree, fnum);
3949 smbcli_close(cli1->tree, fnum2);
3952 smb_raw_exit(cli1->session);
3953 smbcli_deltree(cli1->tree, BASEDIR);
3958 * Open a file with an exclusive oplock from the 1st client and acquire a
3959 * brl. Then open the same file from the 2nd client that should give oplock
3960 * break with level2 to the 1st and return no oplock to the 2nd.
3962 static bool test_raw_oplock_brl4(struct torture_context *tctx,
3963 struct smbcli_state *cli1,
3964 struct smbcli_state *cli2)
3966 const char *fname = BASEDIR "\\test_batch_brl.dat";
3974 if (!torture_setup_dir(cli1, BASEDIR)) {
3979 smbcli_unlink(cli1->tree, fname);
3981 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given,
3985 base ntcreatex parms
3987 io.generic.level = RAW_OPEN_NTCREATEX;
3988 io.ntcreatex.in.root_fid.fnum = 0;
3989 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_READ |
3990 SEC_RIGHTS_FILE_WRITE;
3991 io.ntcreatex.in.alloc_size = 0;
3992 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
3993 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
3994 NTCREATEX_SHARE_ACCESS_WRITE;
3995 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
3996 io.ntcreatex.in.create_options = 0;
3997 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
3998 io.ntcreatex.in.security_flags = 0;
3999 io.ntcreatex.in.fname = fname;
4001 torture_comment(tctx, "open with exclusive oplock\n");
4002 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
4003 NTCREATEX_FLAGS_REQUEST_OPLOCK;
4005 status = smb_raw_open(cli1->tree, tctx, &io);
4007 CHECK_STATUS(tctx, status, NT_STATUS_OK);
4008 fnum = io.ntcreatex.out.file.fnum;
4009 CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
4011 /* create a file with bogus data */
4012 memset(buf, 0, sizeof(buf));
4014 if (smbcli_write(cli1->tree, fnum, 0, buf, 0, sizeof(buf)) !=
4017 torture_comment(tctx, "Failed to create file\n");
4021 status = smbcli_lock(cli1->tree, fnum, 0, 1, 0, WRITE_LOCK);
4022 CHECK_STATUS(tctx, status, NT_STATUS_OK);
4024 torture_comment(tctx, "a 2nd open should give a break to the 1st\n");
4025 ZERO_STRUCT(break_info);
4027 status = smb_raw_open(cli2->tree, tctx, &io);
4029 CHECK_STATUS(tctx, status, NT_STATUS_OK);
4030 CHECK_VAL(break_info.count, 1);
4031 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
4032 CHECK_VAL(break_info.failures, 0);
4033 CHECK_VAL(break_info.fnum, fnum);
4035 torture_comment(tctx, "and return no oplock to the 2nd\n");
4036 fnum2 = io.ntcreatex.out.file.fnum;
4037 CHECK_VAL(io.ntcreatex.out.oplock_level, NO_OPLOCK_RETURN);
4039 smbcli_close(cli1->tree, fnum);
4040 smbcli_close(cli2->tree, fnum2);
4043 smb_raw_exit(cli1->session);
4044 smb_raw_exit(cli2->session);
4045 smbcli_deltree(cli1->tree, BASEDIR);
4050 basic testing of oplocks
4052 struct torture_suite *torture_raw_oplock(TALLOC_CTX *mem_ctx)
4054 struct torture_suite *suite = torture_suite_create(mem_ctx, "oplock");
4056 torture_suite_add_2smb_test(suite, "exclusive1", test_raw_oplock_exclusive1);
4057 torture_suite_add_2smb_test(suite, "exclusive2", test_raw_oplock_exclusive2);
4058 torture_suite_add_2smb_test(suite, "exclusive3", test_raw_oplock_exclusive3);
4059 torture_suite_add_2smb_test(suite, "exclusive4", test_raw_oplock_exclusive4);
4060 torture_suite_add_2smb_test(suite, "exclusive5", test_raw_oplock_exclusive5);
4061 torture_suite_add_2smb_test(suite, "exclusive6", test_raw_oplock_exclusive6);
4062 torture_suite_add_2smb_test(suite, "exclusive7", test_raw_oplock_exclusive7);
4063 torture_suite_add_2smb_test(suite, "exclusive8",
4064 test_raw_oplock_exclusive8);
4065 torture_suite_add_2smb_test(suite, "batch1", test_raw_oplock_batch1);
4066 torture_suite_add_2smb_test(suite, "batch2", test_raw_oplock_batch2);
4067 torture_suite_add_2smb_test(suite, "batch3", test_raw_oplock_batch3);
4068 torture_suite_add_2smb_test(suite, "batch4", test_raw_oplock_batch4);
4069 torture_suite_add_2smb_test(suite, "batch5", test_raw_oplock_batch5);
4070 torture_suite_add_2smb_test(suite, "batch6", test_raw_oplock_batch6);
4071 torture_suite_add_2smb_test(suite, "batch7", test_raw_oplock_batch7);
4072 torture_suite_add_2smb_test(suite, "batch8", test_raw_oplock_batch8);
4073 torture_suite_add_2smb_test(suite, "batch9", test_raw_oplock_batch9);
4074 torture_suite_add_2smb_test(suite, "batch10", test_raw_oplock_batch10);
4075 torture_suite_add_2smb_test(suite, "batch11", test_raw_oplock_batch11);
4076 torture_suite_add_2smb_test(suite, "batch12", test_raw_oplock_batch12);
4077 torture_suite_add_2smb_test(suite, "batch13", test_raw_oplock_batch13);
4078 torture_suite_add_2smb_test(suite, "batch14", test_raw_oplock_batch14);
4079 torture_suite_add_2smb_test(suite, "batch15", test_raw_oplock_batch15);
4080 torture_suite_add_2smb_test(suite, "batch16", test_raw_oplock_batch16);
4081 torture_suite_add_2smb_test(suite, "batch17", test_raw_oplock_batch17);
4082 torture_suite_add_2smb_test(suite, "batch18", test_raw_oplock_batch18);
4083 torture_suite_add_2smb_test(suite, "batch19", test_raw_oplock_batch19);
4084 torture_suite_add_2smb_test(suite, "batch20", test_raw_oplock_batch20);
4085 torture_suite_add_2smb_test(suite, "batch21", test_raw_oplock_batch21);
4086 torture_suite_add_2smb_test(suite, "batch22", test_raw_oplock_batch22);
4087 torture_suite_add_2smb_test(suite, "batch23", test_raw_oplock_batch23);
4088 torture_suite_add_2smb_test(suite, "batch24", test_raw_oplock_batch24);
4089 torture_suite_add_2smb_test(suite, "batch25", test_raw_oplock_batch25);
4090 torture_suite_add_2smb_test(suite, "batch26", test_raw_oplock_batch26);
4091 torture_suite_add_2smb_test(suite, "stream1", test_raw_oplock_stream1);
4092 torture_suite_add_2smb_test(suite, "doc1", test_raw_oplock_doc);
4093 torture_suite_add_2smb_test(suite, "brl1", test_raw_oplock_brl1);
4094 torture_suite_add_1smb_test(suite, "brl2", test_raw_oplock_brl2);
4095 torture_suite_add_1smb_test(suite, "brl3", test_raw_oplock_brl3);
4096 torture_suite_add_2smb_test(suite, "brl4", test_raw_oplock_brl4);
4102 stress testing of oplocks
4104 bool torture_bench_oplock(struct torture_context *torture)
4106 struct smbcli_state **cli;
4108 TALLOC_CTX *mem_ctx = talloc_new(torture);
4109 int torture_nprocs = torture_setting_int(torture, "nprocs", 4);
4111 int timelimit = torture_setting_int(torture, "timelimit", 10);
4115 cli = talloc_array(mem_ctx, struct smbcli_state *, torture_nprocs);
4117 torture_comment(torture, "Opening %d connections\n", torture_nprocs);
4118 for (i=0;i<torture_nprocs;i++) {
4119 if (!torture_open_connection_ev(&cli[i], i, torture, torture->ev)) {
4122 talloc_steal(mem_ctx, cli[i]);
4123 smbcli_oplock_handler(cli[i]->transport, oplock_handler_close,
4127 if (!torture_setup_dir(cli[0], BASEDIR)) {
4132 io.ntcreatex.level = RAW_OPEN_NTCREATEX;
4133 io.ntcreatex.in.root_fid.fnum = 0;
4134 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
4135 io.ntcreatex.in.alloc_size = 0;
4136 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
4137 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
4138 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
4139 io.ntcreatex.in.create_options = 0;
4140 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
4141 io.ntcreatex.in.security_flags = 0;
4142 io.ntcreatex.in.fname = BASEDIR "\\test.dat";
4143 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
4144 NTCREATEX_FLAGS_REQUEST_OPLOCK |
4145 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
4147 tv = timeval_current();
4150 we open the same file with SHARE_ACCESS_NONE from all the
4151 connections in a round robin fashion. Each open causes an
4152 oplock break on the previous connection, which is answered
4153 by the oplock_handler_close() to close the file.
4155 This measures how fast we can pass on oplocks, and stresses
4156 the oplock handling code
4158 torture_comment(torture, "Running for %d seconds\n", timelimit);
4159 while (timeval_elapsed(&tv) < timelimit) {
4160 for (i=0;i<torture_nprocs;i++) {
4163 status = smb_raw_open(cli[i]->tree, mem_ctx, &io);
4164 CHECK_STATUS(torture, status, NT_STATUS_OK);
4168 if (torture_setting_bool(torture, "progress", true)) {
4169 torture_comment(torture, "%.2f ops/second\r", count/timeval_elapsed(&tv));
4173 torture_comment(torture, "%.2f ops/second\n", count/timeval_elapsed(&tv));
4175 smb_raw_exit(cli[torture_nprocs-1]->session);
4178 smb_raw_exit(cli[0]->session);
4179 smbcli_deltree(cli[0]->tree, BASEDIR);
4180 talloc_free(mem_ctx);
4185 static struct hold_oplock_info {
4187 bool close_on_break;
4188 uint32_t share_access;
4191 { BASEDIR "\\notshared_close", true,
4192 NTCREATEX_SHARE_ACCESS_NONE, },
4193 { BASEDIR "\\notshared_noclose", false,
4194 NTCREATEX_SHARE_ACCESS_NONE, },
4195 { BASEDIR "\\shared_close", true,
4196 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE, },
4197 { BASEDIR "\\shared_noclose", false,
4198 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE, },
4201 static bool oplock_handler_hold(struct smbcli_transport *transport,
4202 uint16_t tid, uint16_t fnum, uint8_t level,
4205 struct smbcli_tree *tree = (struct smbcli_tree *)private_data;
4206 struct hold_oplock_info *info;
4209 for (i=0;i<ARRAY_SIZE(hold_info);i++) {
4210 if (hold_info[i].fnum == fnum) break;
4213 if (i == ARRAY_SIZE(hold_info)) {
4214 printf("oplock break for unknown fnum %u\n", fnum);
4218 info = &hold_info[i];
4220 if (info->close_on_break) {
4221 printf("oplock break on %s - closing\n",
4223 oplock_handler_close(transport, tid, fnum, level, private_data);
4227 printf("oplock break on %s - acking break\n", info->fname);
4229 return smbcli_oplock_ack(tree, fnum, OPLOCK_BREAK_TO_NONE);
4234 used for manual testing of oplocks - especially interaction with
4235 other filesystems (such as NFS and local access)
4237 bool torture_hold_oplock(struct torture_context *torture,
4238 struct smbcli_state *cli)
4240 struct tevent_context *ev = torture->ev;
4243 printf("Setting up open files with oplocks in %s\n", BASEDIR);
4245 torture_assert(torture, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
4247 smbcli_oplock_handler(cli->transport, oplock_handler_hold, cli->tree);
4249 /* setup the files */
4250 for (i=0;i<ARRAY_SIZE(hold_info);i++) {
4255 io.generic.level = RAW_OPEN_NTCREATEX;
4256 io.ntcreatex.in.root_fid.fnum = 0;
4257 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
4258 io.ntcreatex.in.alloc_size = 0;
4259 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
4260 io.ntcreatex.in.share_access = hold_info[i].share_access;
4261 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
4262 io.ntcreatex.in.create_options = 0;
4263 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
4264 io.ntcreatex.in.security_flags = 0;
4265 io.ntcreatex.in.fname = hold_info[i].fname;
4266 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
4267 NTCREATEX_FLAGS_REQUEST_OPLOCK |
4268 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
4269 printf("opening %s\n", hold_info[i].fname);
4271 status = smb_raw_open(cli->tree, cli, &io);
4272 if (!NT_STATUS_IS_OK(status)) {
4273 printf("Failed to open %s - %s\n",
4274 hold_info[i].fname, nt_errstr(status));
4278 if (io.ntcreatex.out.oplock_level != BATCH_OPLOCK_RETURN) {
4279 printf("Oplock not granted for %s - expected %d but got %d\n",
4280 hold_info[i].fname, BATCH_OPLOCK_RETURN,
4281 io.ntcreatex.out.oplock_level);
4284 hold_info[i].fnum = io.ntcreatex.out.file.fnum;
4286 /* make the file non-zero size */
4287 if (smbcli_write(cli->tree, hold_info[i].fnum, 0, &c, 0, 1) != 1) {
4288 printf("Failed to write to file\n");
4293 printf("Waiting for oplock events\n");
4294 tevent_loop_wait(ev);