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"
30 #define CHECK_VAL(v, correct) do { \
31 if ((v) != (correct)) { \
32 torture_result(tctx, TORTURE_FAIL, "(%s): wrong value for %s got 0x%x - should be 0x%x\n", \
33 __location__, #v, (int)v, (int)correct); \
37 #define CHECK_RANGE(v, min, max) do { \
38 if ((v) < (min) || (v) > (max)) { \
39 torture_warning(tctx, "(%s): wrong value for %s got " \
40 "%d - should be between %d and %d\n", \
41 __location__, #v, (int)v, (int)min, (int)max); \
44 #define CHECK_STRMATCH(v, correct) do { \
45 if (!v || strstr((v),(correct)) == NULL) { \
46 torture_result(tctx, TORTURE_FAIL, "(%s): wrong value for %s got '%s' - should be '%s'\n", \
47 __location__, #v, v?v:"NULL", correct); \
52 #define CHECK_STATUS(tctx, status, correct) do { \
53 if (!NT_STATUS_EQUAL(status, correct)) { \
54 torture_result(tctx, TORTURE_FAIL, __location__": Incorrect status %s - should be %s", \
55 nt_errstr(status), nt_errstr(correct)); \
68 #define BASEDIR "\\test_oplock"
71 a handler function for oplock break requests. Ack it as a break to level II if possible
73 static bool oplock_handler_ack_to_given(struct smbcli_transport *transport,
74 uint16_t tid, uint16_t fnum,
75 uint8_t level, void *private_data)
77 struct smbcli_tree *tree = (struct smbcli_tree *)private_data;
80 break_info.fnum = fnum;
81 break_info.level = level;
85 case OPLOCK_BREAK_TO_LEVEL_II:
88 case OPLOCK_BREAK_TO_NONE:
93 break_info.failures++;
95 printf("Acking to %s [0x%02X] in oplock handler\n",
98 return smbcli_oplock_ack(tree, fnum, level);
102 a handler function for oplock break requests. Ack it as a break to none
104 static bool oplock_handler_ack_to_none(struct smbcli_transport *transport,
105 uint16_t tid, uint16_t fnum,
106 uint8_t level, void *private_data)
108 struct smbcli_tree *tree = (struct smbcli_tree *)private_data;
109 break_info.fnum = fnum;
110 break_info.level = level;
113 printf("Acking to none in oplock handler\n");
115 return smbcli_oplock_ack(tree, fnum, OPLOCK_BREAK_TO_NONE);
119 a handler function for oplock break requests. Let it timeout
121 static bool oplock_handler_timeout(struct smbcli_transport *transport,
122 uint16_t tid, uint16_t fnum,
123 uint8_t level, void *private_data)
125 break_info.fnum = fnum;
126 break_info.level = level;
129 printf("Let oplock break timeout\n");
133 static void oplock_handler_close_recv(struct smbcli_request *req)
136 status = smbcli_request_simple_recv(req);
137 if (!NT_STATUS_IS_OK(status)) {
138 printf("close failed in oplock_handler_close\n");
139 break_info.failures++;
144 a handler function for oplock break requests - close the file
146 static bool oplock_handler_close(struct smbcli_transport *transport, uint16_t tid,
147 uint16_t fnum, uint8_t level, void *private_data)
150 struct smbcli_tree *tree = (struct smbcli_tree *)private_data;
151 struct smbcli_request *req;
153 break_info.fnum = fnum;
154 break_info.level = level;
157 io.close.level = RAW_CLOSE_CLOSE;
158 io.close.in.file.fnum = fnum;
159 io.close.in.write_time = 0;
160 req = smb_raw_close_send(tree, &io);
162 printf("failed to send close in oplock_handler_close\n");
166 req->async.fn = oplock_handler_close_recv;
167 req->async.private_data = NULL;
172 static bool open_connection_no_level2_oplocks(struct torture_context *tctx,
173 struct smbcli_state **c)
176 struct smbcli_options options;
177 struct smbcli_session_options session_options;
179 lp_smbcli_options(tctx->lp_ctx, &options);
180 lp_smbcli_session_options(tctx->lp_ctx, &session_options);
182 options.use_level2_oplocks = false;
184 status = smbcli_full_connection(tctx, c,
185 torture_setting_string(tctx, "host", NULL),
186 lp_smb_ports(tctx->lp_ctx),
187 torture_setting_string(tctx, "share", NULL),
188 NULL, lp_socket_options(tctx->lp_ctx), cmdline_credentials,
189 lp_resolve_context(tctx->lp_ctx),
190 tctx->ev, &options, &session_options,
191 lp_iconv_convenience(tctx->lp_ctx),
192 lp_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 = event_add_timed(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 (event_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 bool test_raw_oplock_exclusive1(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
264 const char *fname = BASEDIR "\\test_exclusive1.dat";
268 union smb_unlink unl;
271 if (!torture_setup_dir(cli1, BASEDIR)) {
276 smbcli_unlink(cli1->tree, fname);
278 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
283 io.generic.level = RAW_OPEN_NTCREATEX;
284 io.ntcreatex.in.root_fid.fnum = 0;
285 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
286 io.ntcreatex.in.alloc_size = 0;
287 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
288 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
289 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
290 io.ntcreatex.in.create_options = 0;
291 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
292 io.ntcreatex.in.security_flags = 0;
293 io.ntcreatex.in.fname = fname;
295 torture_comment(tctx, "EXCLUSIVE1: open a file with an exclusive oplock (share mode: none)\n");
296 ZERO_STRUCT(break_info);
297 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
299 status = smb_raw_open(cli1->tree, tctx, &io);
300 CHECK_STATUS(tctx, status, NT_STATUS_OK);
301 fnum = io.ntcreatex.out.file.fnum;
302 CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
304 torture_comment(tctx, "a 2nd open should not cause a break\n");
305 status = smb_raw_open(cli2->tree, tctx, &io);
306 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
307 torture_wait_for_oplock_break(tctx);
308 CHECK_VAL(break_info.count, 0);
309 CHECK_VAL(break_info.failures, 0);
311 torture_comment(tctx, "unlink it - should also be no break\n");
312 unl.unlink.in.pattern = fname;
313 unl.unlink.in.attrib = 0;
314 status = smb_raw_unlink(cli2->tree, &unl);
315 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
316 torture_wait_for_oplock_break(tctx);
317 CHECK_VAL(break_info.count, 0);
318 CHECK_VAL(break_info.failures, 0);
320 smbcli_close(cli1->tree, fnum);
323 smb_raw_exit(cli1->session);
324 smb_raw_exit(cli2->session);
325 smbcli_deltree(cli1->tree, BASEDIR);
329 static bool test_raw_oplock_exclusive2(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
331 const char *fname = BASEDIR "\\test_exclusive2.dat";
335 union smb_unlink unl;
336 uint16_t fnum=0, fnum2=0;
338 if (!torture_setup_dir(cli1, BASEDIR)) {
343 smbcli_unlink(cli1->tree, fname);
345 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
350 io.generic.level = RAW_OPEN_NTCREATEX;
351 io.ntcreatex.in.root_fid.fnum = 0;
352 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
353 io.ntcreatex.in.alloc_size = 0;
354 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
355 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
356 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
357 io.ntcreatex.in.create_options = 0;
358 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
359 io.ntcreatex.in.security_flags = 0;
360 io.ntcreatex.in.fname = fname;
362 torture_comment(tctx, "EXCLUSIVE2: open a file with an exclusive oplock (share mode: all)\n");
363 ZERO_STRUCT(break_info);
364 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
365 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
366 NTCREATEX_SHARE_ACCESS_WRITE|
367 NTCREATEX_SHARE_ACCESS_DELETE;
369 status = smb_raw_open(cli1->tree, tctx, &io);
370 CHECK_STATUS(tctx, status, NT_STATUS_OK);
371 fnum = io.ntcreatex.out.file.fnum;
372 CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
374 torture_comment(tctx, "a 2nd open should cause a break to level 2\n");
375 status = smb_raw_open(cli2->tree, tctx, &io);
376 CHECK_STATUS(tctx, status, NT_STATUS_OK);
377 fnum2 = io.ntcreatex.out.file.fnum;
378 torture_wait_for_oplock_break(tctx);
379 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
380 CHECK_VAL(break_info.count, 1);
381 CHECK_VAL(break_info.fnum, fnum);
382 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
383 CHECK_VAL(break_info.failures, 0);
384 ZERO_STRUCT(break_info);
386 /* now we have 2 level II oplocks... */
387 torture_comment(tctx, "try to unlink it - should not cause a break, but a sharing violation\n");
388 unl.unlink.in.pattern = fname;
389 unl.unlink.in.attrib = 0;
390 status = smb_raw_unlink(cli2->tree, &unl);
391 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
392 torture_wait_for_oplock_break(tctx);
393 CHECK_VAL(break_info.count, 0);
394 CHECK_VAL(break_info.failures, 0);
396 torture_comment(tctx, "close 1st handle\n");
397 smbcli_close(cli1->tree, fnum);
399 torture_comment(tctx, "try to unlink it - should not cause a break, but a sharing violation\n");
400 unl.unlink.in.pattern = fname;
401 unl.unlink.in.attrib = 0;
402 status = smb_raw_unlink(cli2->tree, &unl);
403 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
404 torture_wait_for_oplock_break(tctx);
405 CHECK_VAL(break_info.count, 0);
406 CHECK_VAL(break_info.failures, 0);
408 torture_comment(tctx, "close 2nd handle\n");
409 smbcli_close(cli2->tree, fnum2);
411 torture_comment(tctx, "unlink it\n");
412 unl.unlink.in.pattern = fname;
413 unl.unlink.in.attrib = 0;
414 status = smb_raw_unlink(cli2->tree, &unl);
415 CHECK_STATUS(tctx, status, NT_STATUS_OK);
416 torture_wait_for_oplock_break(tctx);
417 CHECK_VAL(break_info.count, 0);
418 CHECK_VAL(break_info.failures, 0);
421 smb_raw_exit(cli1->session);
422 smb_raw_exit(cli2->session);
423 smbcli_deltree(cli1->tree, BASEDIR);
427 static bool test_raw_oplock_exclusive3(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
429 const char *fname = BASEDIR "\\test_exclusive3.dat";
433 union smb_setfileinfo sfi;
436 if (!torture_setup_dir(cli1, BASEDIR)) {
441 smbcli_unlink(cli1->tree, fname);
443 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
448 io.generic.level = RAW_OPEN_NTCREATEX;
449 io.ntcreatex.in.root_fid.fnum = 0;
450 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
451 io.ntcreatex.in.alloc_size = 0;
452 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
453 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_WRITE;
454 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
455 io.ntcreatex.in.create_options = 0;
456 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
457 io.ntcreatex.in.security_flags = 0;
458 io.ntcreatex.in.fname = fname;
460 torture_comment(tctx, "EXCLUSIVE3: open a file with an exclusive oplock (share mode: none)\n");
462 ZERO_STRUCT(break_info);
463 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
465 status = smb_raw_open(cli1->tree, tctx, &io);
466 CHECK_STATUS(tctx, status, NT_STATUS_OK);
467 fnum = io.ntcreatex.out.file.fnum;
468 CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
470 torture_comment(tctx, "setpathinfo EOF should trigger a break to none\n");
472 sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
473 sfi.generic.in.file.path = fname;
474 sfi.end_of_file_info.in.size = 100;
476 status = smb_raw_setpathinfo(cli2->tree, &sfi);
478 CHECK_STATUS(tctx, status, NT_STATUS_OK);
479 torture_wait_for_oplock_break(tctx);
480 CHECK_VAL(break_info.count, get_break_level1_to_none_count(tctx));
481 CHECK_VAL(break_info.failures, 0);
482 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_NONE);
484 smbcli_close(cli1->tree, fnum);
487 smb_raw_exit(cli1->session);
488 smb_raw_exit(cli2->session);
489 smbcli_deltree(cli1->tree, BASEDIR);
493 static bool test_raw_oplock_exclusive4(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
495 const char *fname = BASEDIR "\\test_exclusive4.dat";
499 uint16_t fnum=0, fnum2=0;
501 if (!torture_setup_dir(cli1, BASEDIR)) {
506 smbcli_unlink(cli1->tree, fname);
508 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
513 io.generic.level = RAW_OPEN_NTCREATEX;
514 io.ntcreatex.in.root_fid.fnum = 0;
515 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
516 io.ntcreatex.in.alloc_size = 0;
517 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
518 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
519 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
520 io.ntcreatex.in.create_options = 0;
521 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
522 io.ntcreatex.in.security_flags = 0;
523 io.ntcreatex.in.fname = fname;
525 torture_comment(tctx, "EXCLUSIVE4: open with exclusive oplock\n");
526 ZERO_STRUCT(break_info);
527 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
529 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
530 status = smb_raw_open(cli1->tree, tctx, &io);
531 CHECK_STATUS(tctx, status, NT_STATUS_OK);
532 fnum = io.ntcreatex.out.file.fnum;
533 CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
535 ZERO_STRUCT(break_info);
536 torture_comment(tctx, "second open with attributes only shouldn't cause oplock break\n");
538 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
539 io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
540 status = smb_raw_open(cli2->tree, tctx, &io);
541 CHECK_STATUS(tctx, status, NT_STATUS_OK);
542 fnum2 = io.ntcreatex.out.file.fnum;
543 CHECK_VAL(io.ntcreatex.out.oplock_level, NO_OPLOCK_RETURN);
544 torture_wait_for_oplock_break(tctx);
545 CHECK_VAL(break_info.count, 0);
546 CHECK_VAL(break_info.failures, 0);
548 smbcli_close(cli1->tree, fnum);
549 smbcli_close(cli2->tree, fnum2);
552 smb_raw_exit(cli1->session);
553 smb_raw_exit(cli2->session);
554 smbcli_deltree(cli1->tree, BASEDIR);
558 static bool test_raw_oplock_exclusive5(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
560 const char *fname = BASEDIR "\\test_exclusive5.dat";
564 uint16_t fnum=0, fnum2=0;
566 if (!torture_setup_dir(cli1, BASEDIR)) {
571 smbcli_unlink(cli1->tree, fname);
573 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
574 smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli1->tree);
579 io.generic.level = RAW_OPEN_NTCREATEX;
580 io.ntcreatex.in.root_fid.fnum = 0;
581 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
582 io.ntcreatex.in.alloc_size = 0;
583 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
584 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
585 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
586 io.ntcreatex.in.create_options = 0;
587 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
588 io.ntcreatex.in.security_flags = 0;
589 io.ntcreatex.in.fname = fname;
591 torture_comment(tctx, "EXCLUSIVE5: open with exclusive oplock\n");
592 ZERO_STRUCT(break_info);
593 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
596 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
597 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
598 NTCREATEX_SHARE_ACCESS_WRITE|
599 NTCREATEX_SHARE_ACCESS_DELETE;
600 status = smb_raw_open(cli1->tree, tctx, &io);
601 CHECK_STATUS(tctx, status, NT_STATUS_OK);
602 fnum = io.ntcreatex.out.file.fnum;
603 CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
605 ZERO_STRUCT(break_info);
607 torture_comment(tctx, "second open with attributes only and NTCREATEX_DISP_OVERWRITE_IF dispostion causes oplock break\n");
609 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
610 io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
611 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE_IF;
612 status = smb_raw_open(cli2->tree, tctx, &io);
613 CHECK_STATUS(tctx, status, NT_STATUS_OK);
614 fnum2 = io.ntcreatex.out.file.fnum;
615 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
616 torture_wait_for_oplock_break(tctx);
617 CHECK_VAL(break_info.count, get_break_level1_to_none_count(tctx));
618 CHECK_VAL(break_info.failures, 0);
620 smbcli_close(cli1->tree, fnum);
621 smbcli_close(cli2->tree, fnum2);
624 smb_raw_exit(cli1->session);
625 smb_raw_exit(cli2->session);
626 smbcli_deltree(cli1->tree, BASEDIR);
630 static bool test_raw_oplock_exclusive6(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
632 const char *fname1 = BASEDIR "\\test_exclusive6_1.dat";
633 const char *fname2 = BASEDIR "\\test_exclusive6_2.dat";
640 if (!torture_setup_dir(cli1, BASEDIR)) {
645 smbcli_unlink(cli1->tree, fname1);
646 smbcli_unlink(cli1->tree, fname2);
648 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
653 io.generic.level = RAW_OPEN_NTCREATEX;
654 io.ntcreatex.in.root_fid.fnum = 0;
655 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
656 io.ntcreatex.in.alloc_size = 0;
657 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
658 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
659 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
660 io.ntcreatex.in.create_options = 0;
661 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
662 io.ntcreatex.in.security_flags = 0;
663 io.ntcreatex.in.fname = fname1;
665 torture_comment(tctx, "EXCLUSIVE6: open a file with an exclusive "
666 "oplock (share mode: none)\n");
667 ZERO_STRUCT(break_info);
668 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
670 status = smb_raw_open(cli1->tree, tctx, &io);
671 CHECK_STATUS(tctx, status, NT_STATUS_OK);
672 fnum = io.ntcreatex.out.file.fnum;
673 CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
675 torture_comment(tctx, "rename should not generate a break but get a "
676 "sharing violation\n");
678 rn.generic.level = RAW_RENAME_RENAME;
679 rn.rename.in.pattern1 = fname1;
680 rn.rename.in.pattern2 = fname2;
681 rn.rename.in.attrib = 0;
683 torture_comment(tctx, "trying rename while first file open\n");
684 status = smb_raw_rename(cli2->tree, &rn);
686 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
687 torture_wait_for_oplock_break(tctx);
688 CHECK_VAL(break_info.count, 0);
689 CHECK_VAL(break_info.failures, 0);
691 smbcli_close(cli1->tree, fnum);
694 smb_raw_exit(cli1->session);
695 smb_raw_exit(cli2->session);
696 smbcli_deltree(cli1->tree, BASEDIR);
700 static bool test_raw_oplock_batch1(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
702 const char *fname = BASEDIR "\\test_batch1.dat";
706 union smb_unlink unl;
710 if (!torture_setup_dir(cli1, BASEDIR)) {
715 smbcli_unlink(cli1->tree, fname);
717 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
722 io.generic.level = RAW_OPEN_NTCREATEX;
723 io.ntcreatex.in.root_fid.fnum = 0;
724 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
725 io.ntcreatex.in.alloc_size = 0;
726 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
727 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
728 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
729 io.ntcreatex.in.create_options = 0;
730 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
731 io.ntcreatex.in.security_flags = 0;
732 io.ntcreatex.in.fname = fname;
735 with a batch oplock we get a break
737 torture_comment(tctx, "BATCH1: open with batch oplock\n");
738 ZERO_STRUCT(break_info);
739 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
740 NTCREATEX_FLAGS_REQUEST_OPLOCK |
741 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
742 status = smb_raw_open(cli1->tree, tctx, &io);
743 CHECK_STATUS(tctx, status, NT_STATUS_OK);
744 fnum = io.ntcreatex.out.file.fnum;
745 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
747 torture_comment(tctx, "unlink should generate a break\n");
748 unl.unlink.in.pattern = fname;
749 unl.unlink.in.attrib = 0;
750 status = smb_raw_unlink(cli2->tree, &unl);
751 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
753 torture_wait_for_oplock_break(tctx);
754 CHECK_VAL(break_info.count, 1);
755 CHECK_VAL(break_info.fnum, fnum);
756 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
757 CHECK_VAL(break_info.failures, 0);
759 torture_comment(tctx, "2nd unlink should not generate a break\n");
760 ZERO_STRUCT(break_info);
761 status = smb_raw_unlink(cli2->tree, &unl);
762 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
764 torture_wait_for_oplock_break(tctx);
765 CHECK_VAL(break_info.count, 0);
767 torture_comment(tctx, "writing should generate a self break to none\n");
768 smbcli_write(cli1->tree, fnum, 0, &c, 0, 1);
770 torture_wait_for_oplock_break(tctx);
771 torture_wait_for_oplock_break(tctx);
772 CHECK_VAL(break_info.count, 1);
773 CHECK_VAL(break_info.fnum, fnum);
774 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_NONE);
775 CHECK_VAL(break_info.failures, 0);
777 smbcli_close(cli1->tree, fnum);
780 smb_raw_exit(cli1->session);
781 smb_raw_exit(cli2->session);
782 smbcli_deltree(cli1->tree, BASEDIR);
786 static bool test_raw_oplock_batch2(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
788 const char *fname = BASEDIR "\\test_batch2.dat";
792 union smb_unlink unl;
796 if (!torture_setup_dir(cli1, BASEDIR)) {
801 smbcli_unlink(cli1->tree, fname);
803 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
808 io.generic.level = RAW_OPEN_NTCREATEX;
809 io.ntcreatex.in.root_fid.fnum = 0;
810 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
811 io.ntcreatex.in.alloc_size = 0;
812 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
813 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
814 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
815 io.ntcreatex.in.create_options = 0;
816 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
817 io.ntcreatex.in.security_flags = 0;
818 io.ntcreatex.in.fname = fname;
820 torture_comment(tctx, "BATCH2: open with batch oplock\n");
821 ZERO_STRUCT(break_info);
822 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
823 NTCREATEX_FLAGS_REQUEST_OPLOCK |
824 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
825 status = smb_raw_open(cli1->tree, tctx, &io);
826 CHECK_STATUS(tctx, status, NT_STATUS_OK);
827 fnum = io.ntcreatex.out.file.fnum;
828 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
830 torture_comment(tctx, "unlink should generate a break, which we ack as break to none\n");
831 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_none, cli1->tree);
832 unl.unlink.in.pattern = fname;
833 unl.unlink.in.attrib = 0;
834 status = smb_raw_unlink(cli2->tree, &unl);
835 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
837 torture_wait_for_oplock_break(tctx);
838 CHECK_VAL(break_info.count, 1);
839 CHECK_VAL(break_info.fnum, fnum);
840 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
841 CHECK_VAL(break_info.failures, 0);
843 torture_comment(tctx, "2nd unlink should not generate a break\n");
844 ZERO_STRUCT(break_info);
845 status = smb_raw_unlink(cli2->tree, &unl);
846 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
848 torture_wait_for_oplock_break(tctx);
849 CHECK_VAL(break_info.count, 0);
851 torture_comment(tctx, "writing should not generate a break\n");
852 smbcli_write(cli1->tree, fnum, 0, &c, 0, 1);
854 torture_wait_for_oplock_break(tctx);
855 CHECK_VAL(break_info.count, 0);
857 smbcli_close(cli1->tree, fnum);
860 smb_raw_exit(cli1->session);
861 smb_raw_exit(cli2->session);
862 smbcli_deltree(cli1->tree, BASEDIR);
866 static bool test_raw_oplock_batch3(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
868 const char *fname = BASEDIR "\\test_batch3.dat";
872 union smb_unlink unl;
875 if (!torture_setup_dir(cli1, BASEDIR)) {
880 smbcli_unlink(cli1->tree, fname);
882 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
887 io.generic.level = RAW_OPEN_NTCREATEX;
888 io.ntcreatex.in.root_fid.fnum = 0;
889 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
890 io.ntcreatex.in.alloc_size = 0;
891 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
892 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
893 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
894 io.ntcreatex.in.create_options = 0;
895 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
896 io.ntcreatex.in.security_flags = 0;
897 io.ntcreatex.in.fname = fname;
899 torture_comment(tctx, "BATCH3: if we close on break then the unlink can succeed\n");
900 ZERO_STRUCT(break_info);
901 smbcli_oplock_handler(cli1->transport, oplock_handler_close, cli1->tree);
902 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
903 NTCREATEX_FLAGS_REQUEST_OPLOCK |
904 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
905 status = smb_raw_open(cli1->tree, tctx, &io);
906 CHECK_STATUS(tctx, status, NT_STATUS_OK);
907 fnum = io.ntcreatex.out.file.fnum;
908 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
910 unl.unlink.in.pattern = fname;
911 unl.unlink.in.attrib = 0;
912 ZERO_STRUCT(break_info);
913 status = smb_raw_unlink(cli2->tree, &unl);
914 CHECK_STATUS(tctx, status, NT_STATUS_OK);
916 torture_wait_for_oplock_break(tctx);
917 CHECK_VAL(break_info.count, 1);
918 CHECK_VAL(break_info.fnum, fnum);
919 CHECK_VAL(break_info.level, 1);
920 CHECK_VAL(break_info.failures, 0);
922 smbcli_close(cli1->tree, fnum);
925 smb_raw_exit(cli1->session);
926 smb_raw_exit(cli2->session);
927 smbcli_deltree(cli1->tree, BASEDIR);
931 static bool test_raw_oplock_batch4(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
933 const char *fname = BASEDIR "\\test_batch4.dat";
940 if (!torture_setup_dir(cli1, BASEDIR)) {
945 smbcli_unlink(cli1->tree, fname);
947 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
952 io.generic.level = RAW_OPEN_NTCREATEX;
953 io.ntcreatex.in.root_fid.fnum = 0;
954 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
955 io.ntcreatex.in.alloc_size = 0;
956 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
957 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
958 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
959 io.ntcreatex.in.create_options = 0;
960 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
961 io.ntcreatex.in.security_flags = 0;
962 io.ntcreatex.in.fname = fname;
964 torture_comment(tctx, "BATCH4: a self read should not cause a break\n");
965 ZERO_STRUCT(break_info);
966 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
968 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
969 NTCREATEX_FLAGS_REQUEST_OPLOCK |
970 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
971 status = smb_raw_open(cli1->tree, tctx, &io);
972 CHECK_STATUS(tctx, status, NT_STATUS_OK);
973 fnum = io.ntcreatex.out.file.fnum;
974 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
976 rd.readx.level = RAW_READ_READX;
977 rd.readx.in.file.fnum = fnum;
978 rd.readx.in.mincnt = 1;
979 rd.readx.in.maxcnt = 1;
980 rd.readx.in.offset = 0;
981 rd.readx.in.remaining = 0;
982 rd.readx.in.read_for_execute = false;
983 status = smb_raw_read(cli1->tree, &rd);
984 CHECK_STATUS(tctx, status, NT_STATUS_OK);
985 torture_wait_for_oplock_break(tctx);
986 CHECK_VAL(break_info.count, 0);
987 CHECK_VAL(break_info.failures, 0);
989 smbcli_close(cli1->tree, fnum);
992 smb_raw_exit(cli1->session);
993 smb_raw_exit(cli2->session);
994 smbcli_deltree(cli1->tree, BASEDIR);
998 static bool test_raw_oplock_batch5(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1000 const char *fname = BASEDIR "\\test_batch5.dat";
1006 if (!torture_setup_dir(cli1, BASEDIR)) {
1011 smbcli_unlink(cli1->tree, fname);
1013 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1016 base ntcreatex parms
1018 io.generic.level = RAW_OPEN_NTCREATEX;
1019 io.ntcreatex.in.root_fid.fnum = 0;
1020 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1021 io.ntcreatex.in.alloc_size = 0;
1022 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1023 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1024 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1025 io.ntcreatex.in.create_options = 0;
1026 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1027 io.ntcreatex.in.security_flags = 0;
1028 io.ntcreatex.in.fname = fname;
1030 torture_comment(tctx, "BATCH5: a 2nd open should give a break\n");
1031 ZERO_STRUCT(break_info);
1032 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1034 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1035 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1036 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1037 status = smb_raw_open(cli1->tree, tctx, &io);
1038 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1039 fnum = io.ntcreatex.out.file.fnum;
1040 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1042 ZERO_STRUCT(break_info);
1044 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
1045 status = smb_raw_open(cli2->tree, tctx, &io);
1046 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
1048 torture_wait_for_oplock_break(tctx);
1049 CHECK_VAL(break_info.count, 1);
1050 CHECK_VAL(break_info.fnum, fnum);
1051 CHECK_VAL(break_info.level, 1);
1052 CHECK_VAL(break_info.failures, 0);
1054 smbcli_close(cli1->tree, fnum);
1057 smb_raw_exit(cli1->session);
1058 smb_raw_exit(cli2->session);
1059 smbcli_deltree(cli1->tree, BASEDIR);
1063 static bool test_raw_oplock_batch6(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1065 const char *fname = BASEDIR "\\test_batch6.dat";
1069 uint16_t fnum=0, fnum2=0;
1072 if (!torture_setup_dir(cli1, BASEDIR)) {
1077 smbcli_unlink(cli1->tree, fname);
1079 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1080 smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli2->tree);
1083 base ntcreatex parms
1085 io.generic.level = RAW_OPEN_NTCREATEX;
1086 io.ntcreatex.in.root_fid.fnum = 0;
1087 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1088 io.ntcreatex.in.alloc_size = 0;
1089 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1090 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1091 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1092 io.ntcreatex.in.create_options = 0;
1093 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1094 io.ntcreatex.in.security_flags = 0;
1095 io.ntcreatex.in.fname = fname;
1097 torture_comment(tctx, "BATCH6: a 2nd open should give a break to level II if the first open allowed shared read\n");
1098 ZERO_STRUCT(break_info);
1100 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_READ | SEC_RIGHTS_FILE_WRITE;
1101 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
1102 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1103 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1104 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1105 status = smb_raw_open(cli1->tree, tctx, &io);
1106 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1107 fnum = io.ntcreatex.out.file.fnum;
1108 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1110 ZERO_STRUCT(break_info);
1112 status = smb_raw_open(cli2->tree, tctx, &io);
1113 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1114 fnum2 = io.ntcreatex.out.file.fnum;
1115 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1117 //torture_wait_for_oplock_break(tctx);
1118 CHECK_VAL(break_info.count, 1);
1119 CHECK_VAL(break_info.fnum, fnum);
1120 CHECK_VAL(break_info.level, 1);
1121 CHECK_VAL(break_info.failures, 0);
1122 ZERO_STRUCT(break_info);
1124 torture_comment(tctx, "write should trigger a break to none on both\n");
1125 smbcli_write(cli1->tree, fnum, 0, &c, 0, 1);
1127 /* We expect two breaks */
1128 torture_wait_for_oplock_break(tctx);
1129 torture_wait_for_oplock_break(tctx);
1131 CHECK_VAL(break_info.count, 2);
1132 CHECK_VAL(break_info.level, 0);
1133 CHECK_VAL(break_info.failures, 0);
1135 smbcli_close(cli1->tree, fnum);
1136 smbcli_close(cli2->tree, fnum2);
1139 smb_raw_exit(cli1->session);
1140 smb_raw_exit(cli2->session);
1141 smbcli_deltree(cli1->tree, BASEDIR);
1145 static bool test_raw_oplock_batch7(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1147 const char *fname = BASEDIR "\\test_batch7.dat";
1151 uint16_t fnum=0, fnum2=0;
1153 if (!torture_setup_dir(cli1, BASEDIR)) {
1158 smbcli_unlink(cli1->tree, fname);
1160 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1163 base ntcreatex parms
1165 io.generic.level = RAW_OPEN_NTCREATEX;
1166 io.ntcreatex.in.root_fid.fnum = 0;
1167 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1168 io.ntcreatex.in.alloc_size = 0;
1169 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1170 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1171 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1172 io.ntcreatex.in.create_options = 0;
1173 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1174 io.ntcreatex.in.security_flags = 0;
1175 io.ntcreatex.in.fname = fname;
1177 torture_comment(tctx, "BATCH7: a 2nd open should get an oplock when we close instead of ack\n");
1178 ZERO_STRUCT(break_info);
1179 smbcli_oplock_handler(cli1->transport, oplock_handler_close, cli1->tree);
1181 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1182 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1183 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1184 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1185 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1186 status = smb_raw_open(cli1->tree, tctx, &io);
1187 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1188 fnum2 = io.ntcreatex.out.file.fnum;
1189 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1191 ZERO_STRUCT(break_info);
1193 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1194 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1195 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1196 status = smb_raw_open(cli2->tree, tctx, &io);
1197 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1198 fnum = io.ntcreatex.out.file.fnum;
1199 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1201 torture_wait_for_oplock_break(tctx);
1202 CHECK_VAL(break_info.count, 1);
1203 CHECK_VAL(break_info.fnum, fnum2);
1204 CHECK_VAL(break_info.level, 1);
1205 CHECK_VAL(break_info.failures, 0);
1207 smbcli_close(cli2->tree, fnum);
1210 smb_raw_exit(cli1->session);
1211 smb_raw_exit(cli2->session);
1212 smbcli_deltree(cli1->tree, BASEDIR);
1216 static bool test_raw_oplock_batch8(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1218 const char *fname = BASEDIR "\\test_batch8.dat";
1222 uint16_t fnum=0, fnum2=0;
1224 if (!torture_setup_dir(cli1, BASEDIR)) {
1229 smbcli_unlink(cli1->tree, fname);
1231 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1234 base ntcreatex parms
1236 io.generic.level = RAW_OPEN_NTCREATEX;
1237 io.ntcreatex.in.root_fid.fnum = 0;
1238 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1239 io.ntcreatex.in.alloc_size = 0;
1240 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1241 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1242 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1243 io.ntcreatex.in.create_options = 0;
1244 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1245 io.ntcreatex.in.security_flags = 0;
1246 io.ntcreatex.in.fname = fname;
1248 torture_comment(tctx, "BATCH8: open with batch oplock\n");
1249 ZERO_STRUCT(break_info);
1250 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1252 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1253 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1254 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1255 status = smb_raw_open(cli1->tree, tctx, &io);
1256 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1257 fnum = io.ntcreatex.out.file.fnum;
1258 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1260 ZERO_STRUCT(break_info);
1261 torture_comment(tctx, "second open with attributes only shouldn't cause oplock break\n");
1263 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1264 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1265 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1266 io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
1267 status = smb_raw_open(cli2->tree, tctx, &io);
1268 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1269 fnum2 = io.ntcreatex.out.file.fnum;
1270 CHECK_VAL(io.ntcreatex.out.oplock_level, NO_OPLOCK_RETURN);
1271 torture_wait_for_oplock_break(tctx);
1272 CHECK_VAL(break_info.count, 0);
1273 CHECK_VAL(break_info.failures, 0);
1275 smbcli_close(cli1->tree, fnum);
1276 smbcli_close(cli2->tree, fnum2);
1279 smb_raw_exit(cli1->session);
1280 smb_raw_exit(cli2->session);
1281 smbcli_deltree(cli1->tree, BASEDIR);
1285 static bool test_raw_oplock_batch9(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1287 const char *fname = BASEDIR "\\test_batch9.dat";
1291 uint16_t fnum=0, fnum2=0;
1294 if (!torture_setup_dir(cli1, BASEDIR)) {
1299 smbcli_unlink(cli1->tree, fname);
1301 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1304 base ntcreatex parms
1306 io.generic.level = RAW_OPEN_NTCREATEX;
1307 io.ntcreatex.in.root_fid.fnum = 0;
1308 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1309 io.ntcreatex.in.alloc_size = 0;
1310 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1311 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1312 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1313 io.ntcreatex.in.create_options = 0;
1314 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1315 io.ntcreatex.in.security_flags = 0;
1316 io.ntcreatex.in.fname = fname;
1318 torture_comment(tctx, "BATCH9: open with attributes only can create file\n");
1320 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1321 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1322 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1323 io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
1324 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1325 status = smb_raw_open(cli1->tree, tctx, &io);
1326 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1327 fnum = io.ntcreatex.out.file.fnum;
1328 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1330 torture_comment(tctx, "Subsequent normal open should break oplock on attribute only open to level II\n");
1332 ZERO_STRUCT(break_info);
1333 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1335 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1336 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1337 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1338 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1339 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1340 status = smb_raw_open(cli2->tree, tctx, &io);
1341 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1342 fnum2 = io.ntcreatex.out.file.fnum;
1343 torture_wait_for_oplock_break(tctx);
1344 CHECK_VAL(break_info.count, 1);
1345 CHECK_VAL(break_info.fnum, fnum);
1346 CHECK_VAL(break_info.failures, 0);
1347 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
1348 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1349 smbcli_close(cli2->tree, fnum2);
1351 torture_comment(tctx, "third oplocked open should grant level2 without break\n");
1352 ZERO_STRUCT(break_info);
1353 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1354 smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli2->tree);
1355 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1356 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1357 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1358 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1359 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1360 status = smb_raw_open(cli2->tree, tctx, &io);
1361 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1362 fnum2 = io.ntcreatex.out.file.fnum;
1363 torture_wait_for_oplock_break(tctx);
1364 CHECK_VAL(break_info.count, 0);
1365 CHECK_VAL(break_info.failures, 0);
1366 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1368 ZERO_STRUCT(break_info);
1370 torture_comment(tctx, "write should trigger a break to none on both\n");
1371 smbcli_write(cli2->tree, fnum2, 0, &c, 0, 1);
1373 /* We expect two breaks */
1374 torture_wait_for_oplock_break(tctx);
1375 torture_wait_for_oplock_break(tctx);
1377 CHECK_VAL(break_info.count, 2);
1378 CHECK_VAL(break_info.level, 0);
1379 CHECK_VAL(break_info.failures, 0);
1381 smbcli_close(cli1->tree, fnum);
1382 smbcli_close(cli2->tree, fnum2);
1385 smb_raw_exit(cli1->session);
1386 smb_raw_exit(cli2->session);
1387 smbcli_deltree(cli1->tree, BASEDIR);
1391 static bool test_raw_oplock_batch10(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1393 const char *fname = BASEDIR "\\test_batch10.dat";
1397 uint16_t fnum=0, fnum2=0;
1399 if (!torture_setup_dir(cli1, BASEDIR)) {
1404 smbcli_unlink(cli1->tree, fname);
1406 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1409 base ntcreatex parms
1411 io.generic.level = RAW_OPEN_NTCREATEX;
1412 io.ntcreatex.in.root_fid.fnum = 0;
1413 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1414 io.ntcreatex.in.alloc_size = 0;
1415 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1416 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1417 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1418 io.ntcreatex.in.create_options = 0;
1419 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1420 io.ntcreatex.in.security_flags = 0;
1421 io.ntcreatex.in.fname = fname;
1423 torture_comment(tctx, "BATCH10: Open with oplock after a non-oplock open should grant level2\n");
1424 ZERO_STRUCT(break_info);
1425 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
1426 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1427 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1428 NTCREATEX_SHARE_ACCESS_WRITE|
1429 NTCREATEX_SHARE_ACCESS_DELETE;
1430 status = smb_raw_open(cli1->tree, tctx, &io);
1431 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1432 fnum = io.ntcreatex.out.file.fnum;
1433 torture_wait_for_oplock_break(tctx);
1434 CHECK_VAL(break_info.count, 0);
1435 CHECK_VAL(break_info.failures, 0);
1436 CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
1438 smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli2->tree);
1440 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1441 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1442 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1443 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1444 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1445 NTCREATEX_SHARE_ACCESS_WRITE|
1446 NTCREATEX_SHARE_ACCESS_DELETE;
1447 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1448 status = smb_raw_open(cli2->tree, tctx, &io);
1449 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1450 fnum2 = io.ntcreatex.out.file.fnum;
1451 torture_wait_for_oplock_break(tctx);
1452 CHECK_VAL(break_info.count, 0);
1453 CHECK_VAL(break_info.failures, 0);
1454 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1456 torture_comment(tctx, "write should trigger a break to none\n");
1459 wr.write.level = RAW_WRITE_WRITE;
1460 wr.write.in.file.fnum = fnum;
1461 wr.write.in.count = 1;
1462 wr.write.in.offset = 0;
1463 wr.write.in.remaining = 0;
1464 wr.write.in.data = (const uint8_t *)"x";
1465 status = smb_raw_write(cli1->tree, &wr);
1466 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1469 torture_wait_for_oplock_break(tctx);
1471 CHECK_VAL(break_info.count, 1);
1472 CHECK_VAL(break_info.fnum, fnum2);
1473 CHECK_VAL(break_info.level, 0);
1474 CHECK_VAL(break_info.failures, 0);
1476 smbcli_close(cli1->tree, fnum);
1477 smbcli_close(cli2->tree, fnum2);
1480 smb_raw_exit(cli1->session);
1481 smb_raw_exit(cli2->session);
1482 smbcli_deltree(cli1->tree, BASEDIR);
1486 static bool test_raw_oplock_batch11(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1488 const char *fname = BASEDIR "\\test_batch11.dat";
1492 union smb_setfileinfo sfi;
1495 if (!torture_setup_dir(cli1, BASEDIR)) {
1500 smbcli_unlink(cli1->tree, fname);
1502 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1505 base ntcreatex parms
1507 io.generic.level = RAW_OPEN_NTCREATEX;
1508 io.ntcreatex.in.root_fid.fnum = 0;
1509 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1510 io.ntcreatex.in.alloc_size = 0;
1511 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1512 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_WRITE;
1513 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1514 io.ntcreatex.in.create_options = 0;
1515 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1516 io.ntcreatex.in.security_flags = 0;
1517 io.ntcreatex.in.fname = fname;
1519 /* Test if a set-eof on pathname breaks an exclusive oplock. */
1520 torture_comment(tctx, "BATCH11: Test if setpathinfo set EOF breaks oplocks.\n");
1522 ZERO_STRUCT(break_info);
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_RIGHTS_FILE_ALL;
1528 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1529 NTCREATEX_SHARE_ACCESS_WRITE|
1530 NTCREATEX_SHARE_ACCESS_DELETE;
1531 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1532 status = smb_raw_open(cli1->tree, tctx, &io);
1533 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1534 fnum = io.ntcreatex.out.file.fnum;
1535 torture_wait_for_oplock_break(tctx);
1536 CHECK_VAL(break_info.count, 0);
1537 CHECK_VAL(break_info.failures, 0);
1538 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1541 sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
1542 sfi.generic.in.file.path = fname;
1543 sfi.end_of_file_info.in.size = 100;
1545 status = smb_raw_setpathinfo(cli2->tree, &sfi);
1546 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1548 torture_wait_for_oplock_break(tctx);
1549 CHECK_VAL(break_info.count, get_break_level1_to_none_count(tctx));
1550 CHECK_VAL(break_info.failures, 0);
1551 CHECK_VAL(break_info.level, 0);
1553 smbcli_close(cli1->tree, fnum);
1556 smb_raw_exit(cli1->session);
1557 smb_raw_exit(cli2->session);
1558 smbcli_deltree(cli1->tree, BASEDIR);
1562 static bool test_raw_oplock_batch12(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1564 const char *fname = BASEDIR "\\test_batch12.dat";
1568 union smb_setfileinfo sfi;
1571 if (!torture_setup_dir(cli1, BASEDIR)) {
1576 smbcli_unlink(cli1->tree, fname);
1578 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1581 base ntcreatex parms
1583 io.generic.level = RAW_OPEN_NTCREATEX;
1584 io.ntcreatex.in.root_fid.fnum = 0;
1585 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1586 io.ntcreatex.in.alloc_size = 0;
1587 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1588 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1589 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1590 io.ntcreatex.in.create_options = 0;
1591 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1592 io.ntcreatex.in.security_flags = 0;
1593 io.ntcreatex.in.fname = fname;
1595 /* Test if a set-allocation size on pathname breaks an exclusive oplock. */
1596 torture_comment(tctx, "BATCH12: Test if setpathinfo allocation size breaks oplocks.\n");
1598 ZERO_STRUCT(break_info);
1599 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1601 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1602 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1603 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1604 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1605 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1606 NTCREATEX_SHARE_ACCESS_WRITE|
1607 NTCREATEX_SHARE_ACCESS_DELETE;
1608 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1609 status = smb_raw_open(cli1->tree, tctx, &io);
1610 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1611 fnum = io.ntcreatex.out.file.fnum;
1612 torture_wait_for_oplock_break(tctx);
1613 CHECK_VAL(break_info.count, 0);
1614 CHECK_VAL(break_info.failures, 0);
1615 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1618 sfi.generic.level = SMB_SFILEINFO_ALLOCATION_INFORMATION;
1619 sfi.generic.in.file.path = fname;
1620 sfi.allocation_info.in.alloc_size = 65536 * 8;
1622 status = smb_raw_setpathinfo(cli2->tree, &sfi);
1623 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1625 torture_wait_for_oplock_break(tctx);
1626 CHECK_VAL(break_info.count, get_break_level1_to_none_count(tctx));
1627 CHECK_VAL(break_info.failures, 0);
1628 CHECK_VAL(break_info.level, 0);
1630 smbcli_close(cli1->tree, fnum);
1633 smb_raw_exit(cli1->session);
1634 smb_raw_exit(cli2->session);
1635 smbcli_deltree(cli1->tree, BASEDIR);
1639 static bool test_raw_oplock_batch13(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1641 const char *fname = BASEDIR "\\test_batch13.dat";
1645 uint16_t fnum=0, fnum2=0;
1647 if (!torture_setup_dir(cli1, BASEDIR)) {
1652 smbcli_unlink(cli1->tree, fname);
1654 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1655 smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli1->tree);
1658 base ntcreatex parms
1660 io.generic.level = RAW_OPEN_NTCREATEX;
1661 io.ntcreatex.in.root_fid.fnum = 0;
1662 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1663 io.ntcreatex.in.alloc_size = 0;
1664 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1665 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1666 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1667 io.ntcreatex.in.create_options = 0;
1668 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1669 io.ntcreatex.in.security_flags = 0;
1670 io.ntcreatex.in.fname = fname;
1672 torture_comment(tctx, "BATCH13: open with batch oplock\n");
1673 ZERO_STRUCT(break_info);
1675 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1676 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1677 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1678 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1679 NTCREATEX_SHARE_ACCESS_WRITE|
1680 NTCREATEX_SHARE_ACCESS_DELETE;
1681 status = smb_raw_open(cli1->tree, tctx, &io);
1682 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1683 fnum = io.ntcreatex.out.file.fnum;
1684 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1686 ZERO_STRUCT(break_info);
1688 torture_comment(tctx, "second open with attributes only and NTCREATEX_DISP_OVERWRITE dispostion causes oplock break\n");
1690 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1691 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1692 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1693 io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
1694 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1695 NTCREATEX_SHARE_ACCESS_WRITE|
1696 NTCREATEX_SHARE_ACCESS_DELETE;
1697 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE;
1698 status = smb_raw_open(cli2->tree, tctx, &io);
1699 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1700 fnum2 = io.ntcreatex.out.file.fnum;
1701 torture_wait_for_oplock_break(tctx);
1702 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1703 CHECK_VAL(break_info.count, get_break_level1_to_none_count(tctx));
1704 CHECK_VAL(break_info.failures, 0);
1706 smbcli_close(cli1->tree, fnum);
1707 smbcli_close(cli2->tree, fnum2);
1710 smb_raw_exit(cli1->session);
1711 smb_raw_exit(cli2->session);
1712 smbcli_deltree(cli1->tree, BASEDIR);
1716 static bool test_raw_oplock_batch14(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1718 const char *fname = BASEDIR "\\test_batch14.dat";
1722 uint16_t fnum=0, fnum2=0;
1724 if (!torture_setup_dir(cli1, BASEDIR)) {
1729 smbcli_unlink(cli1->tree, fname);
1731 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1734 base ntcreatex parms
1736 io.generic.level = RAW_OPEN_NTCREATEX;
1737 io.ntcreatex.in.root_fid.fnum = 0;
1738 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1739 io.ntcreatex.in.alloc_size = 0;
1740 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1741 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1742 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1743 io.ntcreatex.in.create_options = 0;
1744 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1745 io.ntcreatex.in.security_flags = 0;
1746 io.ntcreatex.in.fname = fname;
1748 torture_comment(tctx, "BATCH14: open with batch oplock\n");
1749 ZERO_STRUCT(break_info);
1751 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1752 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1753 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1754 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1755 NTCREATEX_SHARE_ACCESS_WRITE|
1756 NTCREATEX_SHARE_ACCESS_DELETE;
1757 status = smb_raw_open(cli1->tree, tctx, &io);
1758 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1759 fnum = io.ntcreatex.out.file.fnum;
1760 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1762 ZERO_STRUCT(break_info);
1764 torture_comment(tctx, "second open with attributes only and NTCREATEX_DISP_SUPERSEDE dispostion causes oplock break\n");
1766 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1767 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1768 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1769 io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
1770 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1771 NTCREATEX_SHARE_ACCESS_WRITE|
1772 NTCREATEX_SHARE_ACCESS_DELETE;
1773 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE;
1774 status = smb_raw_open(cli2->tree, tctx, &io);
1775 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1776 fnum2 = io.ntcreatex.out.file.fnum;
1777 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1779 torture_wait_for_oplock_break(tctx);
1780 CHECK_VAL(break_info.count, get_break_level1_to_none_count(tctx));
1781 CHECK_VAL(break_info.failures, 0);
1783 smbcli_close(cli1->tree, fnum);
1784 smbcli_close(cli2->tree, fnum2);
1786 smb_raw_exit(cli1->session);
1787 smb_raw_exit(cli2->session);
1788 smbcli_deltree(cli1->tree, BASEDIR);
1792 static bool test_raw_oplock_batch15(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1794 const char *fname = BASEDIR "\\test_batch15.dat";
1798 union smb_fileinfo qfi;
1801 if (!torture_setup_dir(cli1, BASEDIR)) {
1806 smbcli_unlink(cli1->tree, fname);
1808 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1811 base ntcreatex parms
1813 io.generic.level = RAW_OPEN_NTCREATEX;
1814 io.ntcreatex.in.root_fid.fnum = 0;
1815 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1816 io.ntcreatex.in.alloc_size = 0;
1817 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1818 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1819 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1820 io.ntcreatex.in.create_options = 0;
1821 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1822 io.ntcreatex.in.security_flags = 0;
1823 io.ntcreatex.in.fname = fname;
1825 /* Test if a qpathinfo all info on pathname breaks a batch oplock. */
1826 torture_comment(tctx, "BATCH15: Test if qpathinfo all info breaks a batch oplock (should not).\n");
1828 ZERO_STRUCT(break_info);
1830 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1831 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1832 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1833 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1834 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1835 NTCREATEX_SHARE_ACCESS_WRITE|
1836 NTCREATEX_SHARE_ACCESS_DELETE;
1837 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1838 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1839 status = smb_raw_open(cli1->tree, tctx, &io);
1840 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1841 fnum = io.ntcreatex.out.file.fnum;
1843 torture_wait_for_oplock_break(tctx);
1844 CHECK_VAL(break_info.count, 0);
1845 CHECK_VAL(break_info.failures, 0);
1846 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1849 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
1850 qfi.generic.in.file.path = fname;
1852 status = smb_raw_pathinfo(cli2->tree, tctx, &qfi);
1853 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1855 torture_wait_for_oplock_break(tctx);
1856 CHECK_VAL(break_info.count, 0);
1858 smbcli_close(cli1->tree, fnum);
1861 smb_raw_exit(cli1->session);
1862 smb_raw_exit(cli2->session);
1863 smbcli_deltree(cli1->tree, BASEDIR);
1867 static bool test_raw_oplock_batch16(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1869 const char *fname = BASEDIR "\\test_batch16.dat";
1873 uint16_t fnum=0, fnum2=0;
1875 if (!torture_setup_dir(cli1, BASEDIR)) {
1880 smbcli_unlink(cli1->tree, fname);
1882 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1883 smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli1->tree);
1886 base ntcreatex parms
1888 io.generic.level = RAW_OPEN_NTCREATEX;
1889 io.ntcreatex.in.root_fid.fnum = 0;
1890 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1891 io.ntcreatex.in.alloc_size = 0;
1892 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1893 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1894 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1895 io.ntcreatex.in.create_options = 0;
1896 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1897 io.ntcreatex.in.security_flags = 0;
1898 io.ntcreatex.in.fname = fname;
1900 torture_comment(tctx, "BATCH16: open with batch oplock\n");
1901 ZERO_STRUCT(break_info);
1903 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1904 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1905 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1906 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1907 NTCREATEX_SHARE_ACCESS_WRITE|
1908 NTCREATEX_SHARE_ACCESS_DELETE;
1909 status = smb_raw_open(cli1->tree, tctx, &io);
1910 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1911 fnum = io.ntcreatex.out.file.fnum;
1912 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1914 ZERO_STRUCT(break_info);
1916 torture_comment(tctx, "second open with attributes only and NTCREATEX_DISP_OVERWRITE_IF dispostion causes oplock break\n");
1918 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1919 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1920 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1921 io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
1922 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1923 NTCREATEX_SHARE_ACCESS_WRITE|
1924 NTCREATEX_SHARE_ACCESS_DELETE;
1925 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE_IF;
1926 status = smb_raw_open(cli2->tree, tctx, &io);
1927 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1928 fnum2 = io.ntcreatex.out.file.fnum;
1929 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1931 torture_wait_for_oplock_break(tctx);
1932 CHECK_VAL(break_info.count, get_break_level1_to_none_count(tctx));
1933 CHECK_VAL(break_info.failures, 0);
1935 smbcli_close(cli1->tree, fnum);
1936 smbcli_close(cli2->tree, fnum2);
1939 smb_raw_exit(cli1->session);
1940 smb_raw_exit(cli2->session);
1941 smbcli_deltree(cli1->tree, BASEDIR);
1945 static bool test_raw_oplock_batch17(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1947 const char *fname1 = BASEDIR "\\test_batch17_1.dat";
1948 const char *fname2 = BASEDIR "\\test_batch17_2.dat";
1952 union smb_rename rn;
1955 if (!torture_setup_dir(cli1, BASEDIR)) {
1960 smbcli_unlink(cli1->tree, fname1);
1961 smbcli_unlink(cli1->tree, fname2);
1963 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1966 base ntcreatex parms
1968 io.generic.level = RAW_OPEN_NTCREATEX;
1969 io.ntcreatex.in.root_fid.fnum = 0;
1970 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1971 io.ntcreatex.in.alloc_size = 0;
1972 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1973 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1974 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1975 io.ntcreatex.in.create_options = 0;
1976 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1977 io.ntcreatex.in.security_flags = 0;
1978 io.ntcreatex.in.fname = fname1;
1980 torture_comment(tctx, "BATCH17: open a file with an batch oplock (share mode: none)\n");
1982 ZERO_STRUCT(break_info);
1983 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1984 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1985 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1987 status = smb_raw_open(cli1->tree, tctx, &io);
1988 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1989 fnum = io.ntcreatex.out.file.fnum;
1990 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1992 torture_comment(tctx, "rename should trigger a break\n");
1994 rn.generic.level = RAW_RENAME_RENAME;
1995 rn.rename.in.pattern1 = fname1;
1996 rn.rename.in.pattern2 = fname2;
1997 rn.rename.in.attrib = 0;
1999 torture_comment(tctx, "trying rename while first file open\n");
2000 status = smb_raw_rename(cli2->tree, &rn);
2001 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
2003 torture_wait_for_oplock_break(tctx);
2004 CHECK_VAL(break_info.count, 1);
2005 CHECK_VAL(break_info.failures, 0);
2006 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
2008 smbcli_close(cli1->tree, fnum);
2011 smb_raw_exit(cli1->session);
2012 smb_raw_exit(cli2->session);
2013 smbcli_deltree(cli1->tree, BASEDIR);
2017 static bool test_raw_oplock_batch18(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
2019 const char *fname1 = BASEDIR "\\test_batch18_1.dat";
2020 const char *fname2 = BASEDIR "\\test_batch18_2.dat";
2024 union smb_rename rn;
2027 if (!torture_setup_dir(cli1, BASEDIR)) {
2032 smbcli_unlink(cli1->tree, fname1);
2033 smbcli_unlink(cli1->tree, fname2);
2035 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2038 base ntcreatex parms
2040 io.generic.level = RAW_OPEN_NTCREATEX;
2041 io.ntcreatex.in.root_fid.fnum = 0;
2042 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2043 io.ntcreatex.in.alloc_size = 0;
2044 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2045 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2046 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2047 io.ntcreatex.in.create_options = 0;
2048 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2049 io.ntcreatex.in.security_flags = 0;
2050 io.ntcreatex.in.fname = fname1;
2052 torture_comment(tctx, "BATCH18: open a file with an batch oplock (share mode: none)\n");
2054 ZERO_STRUCT(break_info);
2055 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2056 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2057 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2059 status = smb_raw_open(cli1->tree, tctx, &io);
2060 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2061 fnum = io.ntcreatex.out.file.fnum;
2062 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
2064 torture_comment(tctx, "ntrename should trigger a break\n");
2066 rn.generic.level = RAW_RENAME_NTRENAME;
2067 rn.ntrename.in.attrib = 0;
2068 rn.ntrename.in.flags = RENAME_FLAG_RENAME;
2069 rn.ntrename.in.old_name = fname1;
2070 rn.ntrename.in.new_name = fname2;
2071 torture_comment(tctx, "trying rename while first file open\n");
2072 status = smb_raw_rename(cli2->tree, &rn);
2073 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
2075 torture_wait_for_oplock_break(tctx);
2076 CHECK_VAL(break_info.count, 1);
2077 CHECK_VAL(break_info.failures, 0);
2078 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
2080 smbcli_close(cli1->tree, fnum);
2083 smb_raw_exit(cli1->session);
2084 smb_raw_exit(cli2->session);
2085 smbcli_deltree(cli1->tree, BASEDIR);
2089 static bool test_raw_oplock_batch19(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
2091 const char *fname1 = BASEDIR "\\test_batch19_1.dat";
2092 const char *fname2 = BASEDIR "\\test_batch19_2.dat";
2093 const char *fname3 = BASEDIR "\\test_batch19_3.dat";
2097 union smb_fileinfo qfi;
2098 union smb_setfileinfo sfi;
2101 if (!torture_setup_dir(cli1, BASEDIR)) {
2106 smbcli_unlink(cli1->tree, fname1);
2107 smbcli_unlink(cli1->tree, fname2);
2108 smbcli_unlink(cli1->tree, fname3);
2110 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2113 base ntcreatex parms
2115 io.generic.level = RAW_OPEN_NTCREATEX;
2116 io.ntcreatex.in.root_fid.fnum = 0;
2117 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2118 io.ntcreatex.in.alloc_size = 0;
2119 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2120 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2121 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2122 io.ntcreatex.in.create_options = 0;
2123 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2124 io.ntcreatex.in.security_flags = 0;
2125 io.ntcreatex.in.fname = fname1;
2127 torture_comment(tctx, "BATCH19: open a file with an batch oplock (share mode: none)\n");
2128 ZERO_STRUCT(break_info);
2129 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2130 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2131 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2132 status = smb_raw_open(cli1->tree, tctx, &io);
2133 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2134 fnum = io.ntcreatex.out.file.fnum;
2135 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
2137 torture_comment(tctx, "setpathinfo rename info should not trigger a break nor a violation\n");
2139 sfi.generic.level = RAW_SFILEINFO_RENAME_INFORMATION;
2140 sfi.generic.in.file.path = fname1;
2141 sfi.rename_information.in.overwrite = 0;
2142 sfi.rename_information.in.root_fid = 0;
2143 sfi.rename_information.in.new_name = fname2+strlen(BASEDIR)+1;
2145 status = smb_raw_setpathinfo(cli2->tree, &sfi);
2146 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2148 torture_wait_for_oplock_break(tctx);
2149 CHECK_VAL(break_info.count, 0);
2152 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2153 qfi.generic.in.file.fnum = fnum;
2155 status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
2156 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2157 CHECK_STRMATCH(qfi.all_info.out.fname.s, fname2);
2159 torture_comment(tctx, "setfileinfo rename info should not trigger a break nor a violation\n");
2161 sfi.generic.level = RAW_SFILEINFO_RENAME_INFORMATION;
2162 sfi.generic.in.file.fnum = fnum;
2163 sfi.rename_information.in.overwrite = 0;
2164 sfi.rename_information.in.root_fid = 0;
2165 sfi.rename_information.in.new_name = fname3+strlen(BASEDIR)+1;
2167 status = smb_raw_setfileinfo(cli1->tree, &sfi);
2168 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2170 torture_wait_for_oplock_break(tctx);
2171 CHECK_VAL(break_info.count, 0);
2174 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2175 qfi.generic.in.file.fnum = fnum;
2177 status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
2178 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2179 CHECK_STRMATCH(qfi.all_info.out.fname.s, fname3);
2181 smbcli_close(cli1->tree, fnum);
2184 smb_raw_exit(cli1->session);
2185 smb_raw_exit(cli2->session);
2186 smbcli_deltree(cli1->tree, BASEDIR);
2190 /****************************************************
2191 Called from raw-rename - we need oplock handling for
2192 this test so this is why it's in oplock.c, not rename.c
2193 ****************************************************/
2195 bool test_trans2rename(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
2197 const char *fname1 = BASEDIR "\\test_trans2rename_1.dat";
2198 const char *fname2 = BASEDIR "\\test_trans2rename_2.dat";
2199 const char *fname3 = BASEDIR "\\test_trans2rename_3.dat";
2203 union smb_fileinfo qfi;
2204 union smb_setfileinfo sfi;
2207 if (!torture_setup_dir(cli1, BASEDIR)) {
2212 smbcli_unlink(cli1->tree, fname1);
2213 smbcli_unlink(cli1->tree, fname2);
2214 smbcli_unlink(cli1->tree, fname3);
2216 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2219 base ntcreatex parms
2221 io.generic.level = RAW_OPEN_NTCREATEX;
2222 io.ntcreatex.in.root_fid.fnum = 0;
2223 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2224 io.ntcreatex.in.alloc_size = 0;
2225 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2226 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2227 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2228 io.ntcreatex.in.create_options = 0;
2229 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2230 io.ntcreatex.in.security_flags = 0;
2231 io.ntcreatex.in.fname = fname1;
2233 torture_comment(tctx, "open a file with an exclusive oplock (share mode: none)\n");
2234 ZERO_STRUCT(break_info);
2235 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2236 NTCREATEX_FLAGS_REQUEST_OPLOCK;
2237 status = smb_raw_open(cli1->tree, tctx, &io);
2238 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2239 fnum = io.ntcreatex.out.file.fnum;
2240 CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
2242 torture_comment(tctx, "setpathinfo rename info should not trigger a break nor a violation\n");
2244 sfi.generic.level = RAW_SFILEINFO_RENAME_INFORMATION;
2245 sfi.generic.in.file.path = fname1;
2246 sfi.rename_information.in.overwrite = 0;
2247 sfi.rename_information.in.root_fid = 0;
2248 sfi.rename_information.in.new_name = fname2+strlen(BASEDIR)+1;
2250 status = smb_raw_setpathinfo(cli2->tree, &sfi);
2252 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2254 torture_wait_for_oplock_break(tctx);
2255 CHECK_VAL(break_info.count, 0);
2258 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2259 qfi.generic.in.file.fnum = fnum;
2261 status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
2262 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2263 CHECK_STRMATCH(qfi.all_info.out.fname.s, fname2);
2265 torture_comment(tctx, "setfileinfo rename info should not trigger a break nor a violation\n");
2267 sfi.generic.level = RAW_SFILEINFO_RENAME_INFORMATION;
2268 sfi.generic.in.file.fnum = fnum;
2269 sfi.rename_information.in.overwrite = 0;
2270 sfi.rename_information.in.root_fid = 0;
2271 sfi.rename_information.in.new_name = fname3+strlen(BASEDIR)+1;
2273 status = smb_raw_setfileinfo(cli1->tree, &sfi);
2274 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2276 torture_wait_for_oplock_break(tctx);
2277 CHECK_VAL(break_info.count, 0);
2280 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2281 qfi.generic.in.file.fnum = fnum;
2283 status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
2284 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2285 CHECK_STRMATCH(qfi.all_info.out.fname.s, fname3);
2287 smbcli_close(cli1->tree, fnum);
2290 smb_raw_exit(cli1->session);
2291 smb_raw_exit(cli2->session);
2292 smbcli_deltree(cli1->tree, BASEDIR);
2296 /****************************************************
2297 Called from raw-rename - we need oplock handling for
2298 this test so this is why it's in oplock.c, not rename.c
2299 ****************************************************/
2301 bool test_nttransrename(struct torture_context *tctx, struct smbcli_state *cli1)
2303 const char *fname1 = BASEDIR "\\test_nttransrename_1.dat";
2304 const char *fname2 = BASEDIR "\\test_nttransrename_2.dat";
2308 union smb_fileinfo qfi, qpi;
2309 union smb_rename rn;
2312 if (!torture_setup_dir(cli1, BASEDIR)) {
2317 smbcli_unlink(cli1->tree, fname1);
2318 smbcli_unlink(cli1->tree, fname2);
2320 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2323 base ntcreatex parms
2325 io.generic.level = RAW_OPEN_NTCREATEX;
2326 io.ntcreatex.in.root_fid.fnum = 0;
2327 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2328 io.ntcreatex.in.alloc_size = 0;
2329 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2330 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2331 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2332 io.ntcreatex.in.create_options = 0;
2333 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2334 io.ntcreatex.in.security_flags = 0;
2335 io.ntcreatex.in.fname = fname1;
2337 torture_comment(tctx, "nttrans_rename: open a file with an exclusive oplock (share mode: none)\n");
2338 ZERO_STRUCT(break_info);
2339 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2340 NTCREATEX_FLAGS_REQUEST_OPLOCK;
2341 status = smb_raw_open(cli1->tree, tctx, &io);
2342 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2343 fnum = io.ntcreatex.out.file.fnum;
2344 CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
2346 torture_comment(tctx, "nttrans_rename: should not trigger a break nor a share mode violation\n");
2348 rn.generic.level = RAW_RENAME_NTTRANS;
2349 rn.nttrans.in.file.fnum = fnum;
2350 rn.nttrans.in.flags = 0;
2351 rn.nttrans.in.new_name = fname2+strlen(BASEDIR)+1;
2353 status = smb_raw_rename(cli1->tree, &rn);
2354 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2356 torture_wait_for_oplock_break(tctx);
2357 CHECK_VAL(break_info.count, 0);
2359 /* w2k3 does nothing, it doesn't rename the file */
2360 torture_comment(tctx, "nttrans_rename: the server should have done nothing\n");
2362 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2363 qfi.generic.in.file.fnum = fnum;
2365 status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
2366 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2367 CHECK_STRMATCH(qfi.all_info.out.fname.s, fname1);
2370 qpi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2371 qpi.generic.in.file.path = fname1;
2373 status = smb_raw_pathinfo(cli1->tree, tctx, &qpi);
2374 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2375 CHECK_STRMATCH(qpi.all_info.out.fname.s, fname1);
2378 qpi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2379 qpi.generic.in.file.path = fname2;
2381 status = smb_raw_pathinfo(cli1->tree, tctx, &qpi);
2382 CHECK_STATUS(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
2384 torture_comment(tctx, "nttrans_rename: after closing the file the file is still not renamed\n");
2385 status = smbcli_close(cli1->tree, fnum);
2386 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2389 qpi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2390 qpi.generic.in.file.path = fname1;
2392 status = smb_raw_pathinfo(cli1->tree, tctx, &qpi);
2393 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2394 CHECK_STRMATCH(qpi.all_info.out.fname.s, fname1);
2397 qpi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2398 qpi.generic.in.file.path = fname2;
2400 status = smb_raw_pathinfo(cli1->tree, tctx, &qpi);
2401 CHECK_STATUS(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
2403 torture_comment(tctx, "nttrans_rename: rename with an invalid handle gives NT_STATUS_INVALID_HANDLE\n");
2405 rn.generic.level = RAW_RENAME_NTTRANS;
2406 rn.nttrans.in.file.fnum = fnum+1;
2407 rn.nttrans.in.flags = 0;
2408 rn.nttrans.in.new_name = fname2+strlen(BASEDIR)+1;
2410 status = smb_raw_rename(cli1->tree, &rn);
2412 CHECK_STATUS(tctx, status, NT_STATUS_INVALID_HANDLE);
2415 smb_raw_exit(cli1->session);
2416 smbcli_deltree(cli1->tree, BASEDIR);
2421 static bool test_raw_oplock_batch20(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
2423 const char *fname1 = BASEDIR "\\test_batch20_1.dat";
2424 const char *fname2 = BASEDIR "\\test_batch20_2.dat";
2425 const char *fname3 = BASEDIR "\\test_batch20_3.dat";
2429 union smb_fileinfo qfi;
2430 union smb_setfileinfo sfi;
2431 uint16_t fnum=0,fnum2=0;
2433 if (!torture_setup_dir(cli1, BASEDIR)) {
2438 smbcli_unlink(cli1->tree, fname1);
2439 smbcli_unlink(cli1->tree, fname2);
2440 smbcli_unlink(cli1->tree, fname3);
2442 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2445 base ntcreatex parms
2447 io.generic.level = RAW_OPEN_NTCREATEX;
2448 io.ntcreatex.in.root_fid.fnum = 0;
2449 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2450 io.ntcreatex.in.alloc_size = 0;
2451 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2452 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2453 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2454 io.ntcreatex.in.create_options = 0;
2455 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2456 io.ntcreatex.in.security_flags = 0;
2457 io.ntcreatex.in.fname = fname1;
2459 torture_comment(tctx, "BATCH20: open a file with an batch oplock (share mode: all)\n");
2460 ZERO_STRUCT(break_info);
2461 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2462 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2463 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2464 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
2465 NTCREATEX_SHARE_ACCESS_WRITE|
2466 NTCREATEX_SHARE_ACCESS_DELETE;
2467 status = smb_raw_open(cli1->tree, tctx, &io);
2468 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2469 fnum = io.ntcreatex.out.file.fnum;
2470 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
2472 torture_comment(tctx, "setpathinfo rename info should not trigger a break nor a violation\n");
2474 sfi.generic.level = RAW_SFILEINFO_RENAME_INFORMATION;
2475 sfi.generic.in.file.path = fname1;
2476 sfi.rename_information.in.overwrite = 0;
2477 sfi.rename_information.in.root_fid = 0;
2478 sfi.rename_information.in.new_name = fname2+strlen(BASEDIR)+1;
2480 status = smb_raw_setpathinfo(cli2->tree, &sfi);
2481 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2483 torture_wait_for_oplock_break(tctx);
2484 CHECK_VAL(break_info.count, 0);
2487 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2488 qfi.generic.in.file.fnum = fnum;
2490 status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
2491 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2492 CHECK_STRMATCH(qfi.all_info.out.fname.s, fname2);
2494 torture_comment(tctx, "open a file with the new name an batch oplock (share mode: all)\n");
2495 ZERO_STRUCT(break_info);
2496 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2497 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2498 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2499 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
2500 NTCREATEX_SHARE_ACCESS_WRITE|
2501 NTCREATEX_SHARE_ACCESS_DELETE;
2502 io.ntcreatex.in.fname = fname2;
2503 status = smb_raw_open(cli2->tree, tctx, &io);
2504 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2505 fnum2 = io.ntcreatex.out.file.fnum;
2506 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
2508 torture_wait_for_oplock_break(tctx);
2509 CHECK_VAL(break_info.count, 1);
2510 CHECK_VAL(break_info.failures, 0);
2511 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
2513 torture_comment(tctx, "setfileinfo rename info should not trigger a break nor a violation\n");
2515 sfi.generic.level = RAW_SFILEINFO_RENAME_INFORMATION;
2516 sfi.generic.in.file.fnum = fnum;
2517 sfi.rename_information.in.overwrite = 0;
2518 sfi.rename_information.in.root_fid = 0;
2519 sfi.rename_information.in.new_name = fname3+strlen(BASEDIR)+1;
2521 status = smb_raw_setfileinfo(cli1->tree, &sfi);
2522 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2524 torture_wait_for_oplock_break(tctx);
2525 CHECK_VAL(break_info.count, 1);
2526 CHECK_VAL(break_info.failures, 0);
2527 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
2530 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2531 qfi.generic.in.file.fnum = fnum;
2533 status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
2534 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2535 CHECK_STRMATCH(qfi.all_info.out.fname.s, fname3);
2538 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2539 qfi.generic.in.file.fnum = fnum2;
2541 status = smb_raw_fileinfo(cli2->tree, tctx, &qfi);
2542 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2543 CHECK_STRMATCH(qfi.all_info.out.fname.s, fname3);
2545 smbcli_close(cli1->tree, fnum);
2548 smb_raw_exit(cli1->session);
2549 smb_raw_exit(cli2->session);
2550 smbcli_deltree(cli1->tree, BASEDIR);
2554 static bool test_raw_oplock_batch21(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
2556 const char *fname = BASEDIR "\\test_batch21.dat";
2565 if (!torture_setup_dir(cli1, BASEDIR)) {
2570 smbcli_unlink(cli1->tree, fname);
2572 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2575 base ntcreatex parms
2577 io.generic.level = RAW_OPEN_NTCREATEX;
2578 io.ntcreatex.in.root_fid.fnum = 0;
2579 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2580 io.ntcreatex.in.alloc_size = 0;
2581 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2582 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2583 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2584 io.ntcreatex.in.create_options = 0;
2585 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2586 io.ntcreatex.in.security_flags = 0;
2587 io.ntcreatex.in.fname = fname;
2590 with a batch oplock we get a break
2592 torture_comment(tctx, "BATCH21: open with batch oplock\n");
2593 ZERO_STRUCT(break_info);
2594 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2595 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2596 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2597 status = smb_raw_open(cli1->tree, tctx, &io);
2598 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2599 fnum = io.ntcreatex.out.file.fnum;
2600 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
2602 torture_comment(tctx, "writing should not generate a break\n");
2603 wr = smbcli_write(cli1->tree, fnum, 0, &c, 0, 1);
2605 CHECK_STATUS(tctx, smbcli_nt_error(cli1->tree), NT_STATUS_OK);
2608 e.in.repeat_count = 1;
2609 status = smb_raw_echo(cli1->transport, &e);
2610 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2612 torture_wait_for_oplock_break(tctx);
2613 CHECK_VAL(break_info.count, 0);
2615 smbcli_close(cli1->tree, fnum);
2618 smb_raw_exit(cli1->session);
2619 smb_raw_exit(cli2->session);
2620 smbcli_deltree(cli1->tree, BASEDIR);
2624 static bool test_raw_oplock_batch22(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
2626 const char *fname = BASEDIR "\\test_batch22.dat";
2630 uint16_t fnum = 0, fnum2 = 0, fnum3 = 0;
2632 int timeout = torture_setting_int(tctx, "oplocktimeout", 30);
2635 if (!torture_setup_dir(cli1, BASEDIR)) {
2640 smbcli_unlink(cli1->tree, fname);
2642 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2644 base ntcreatex parms
2646 io.generic.level = RAW_OPEN_NTCREATEX;
2647 io.ntcreatex.in.root_fid.fnum = 0;
2648 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2649 io.ntcreatex.in.alloc_size = 0;
2650 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2651 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2652 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2653 io.ntcreatex.in.create_options = 0;
2654 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2655 io.ntcreatex.in.security_flags = 0;
2656 io.ntcreatex.in.fname = fname;
2659 with a batch oplock we get a break
2661 torture_comment(tctx, "BATCH22: open with batch oplock\n");
2662 ZERO_STRUCT(break_info);
2663 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2664 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2665 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2666 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
2667 NTCREATEX_SHARE_ACCESS_WRITE|
2668 NTCREATEX_SHARE_ACCESS_DELETE;
2669 status = smb_raw_open(cli1->tree, tctx, &io);
2670 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2671 fnum = io.ntcreatex.out.file.fnum;
2672 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
2674 torture_comment(tctx, "a 2nd open should not succeed after the oplock "
2676 tv = timeval_current();
2677 smbcli_oplock_handler(cli1->transport, oplock_handler_timeout, cli1->tree);
2678 status = smb_raw_open(cli1->tree, tctx, &io);
2680 if (TARGET_IS_W2K3(tctx)) {
2681 /* 2k3 has an issue here. xp/win7 are ok. */
2682 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
2684 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2687 fnum2 = io.ntcreatex.out.file.fnum;
2689 torture_wait_for_oplock_break(tctx);
2690 te = (int)timeval_elapsed(&tv);
2693 * Some servers detect clients that let oplocks timeout, so this check
2694 * only shows a warning message instead failing the test to eliminate
2695 * failures from repeated runs of the test. This isn't ideal, but
2696 * it's better than not running the test at all.
2698 CHECK_RANGE(te, timeout - 1, timeout + 15);
2700 CHECK_VAL(break_info.count, 1);
2701 CHECK_VAL(break_info.fnum, fnum);
2702 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
2703 CHECK_VAL(break_info.failures, 0);
2704 ZERO_STRUCT(break_info);
2706 torture_comment(tctx, "a 2nd open should succeed after the oplock "
2707 "release without break\n");
2708 tv = timeval_current();
2709 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2710 status = smb_raw_open(cli1->tree, tctx, &io);
2711 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2712 if (TARGET_IS_SAMBA3(tctx)) {
2713 /* samba3 doesn't grant additional oplocks to bad clients. */
2714 CHECK_VAL(io.ntcreatex.out.oplock_level, NO_OPLOCK_RETURN);
2716 CHECK_VAL(io.ntcreatex.out.oplock_level,
2717 LEVEL_II_OPLOCK_RETURN);
2719 torture_wait_for_oplock_break(tctx);
2720 te = (int)timeval_elapsed(&tv);
2721 /* it should come in without delay */
2722 CHECK_RANGE(te+1, 0, timeout);
2723 fnum3 = io.ntcreatex.out.file.fnum;
2725 CHECK_VAL(break_info.count, 0);
2727 smbcli_close(cli1->tree, fnum);
2728 smbcli_close(cli1->tree, fnum2);
2729 smbcli_close(cli1->tree, fnum3);
2732 smb_raw_exit(cli1->session);
2733 smb_raw_exit(cli2->session);
2734 smbcli_deltree(cli1->tree, BASEDIR);
2738 static bool test_raw_oplock_batch23(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
2740 const char *fname = BASEDIR "\\test_batch23.dat";
2744 uint16_t fnum=0, fnum2=0,fnum3=0;
2745 struct smbcli_state *cli3 = NULL;
2747 if (!torture_setup_dir(cli1, BASEDIR)) {
2752 smbcli_unlink(cli1->tree, fname);
2754 ret = open_connection_no_level2_oplocks(tctx, &cli3);
2755 CHECK_VAL(ret, true);
2757 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2758 smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli2->tree);
2759 smbcli_oplock_handler(cli3->transport, oplock_handler_ack_to_given, cli3->tree);
2762 base ntcreatex parms
2764 io.generic.level = RAW_OPEN_NTCREATEX;
2765 io.ntcreatex.in.root_fid.fnum = 0;
2766 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2767 io.ntcreatex.in.alloc_size = 0;
2768 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2769 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2770 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2771 io.ntcreatex.in.create_options = 0;
2772 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2773 io.ntcreatex.in.security_flags = 0;
2774 io.ntcreatex.in.fname = fname;
2776 torture_comment(tctx, "BATCH23: a open and ask for a batch oplock\n");
2777 ZERO_STRUCT(break_info);
2779 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_READ | SEC_RIGHTS_FILE_WRITE;
2780 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
2781 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2782 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2783 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2784 status = smb_raw_open(cli1->tree, tctx, &io);
2785 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2786 fnum = io.ntcreatex.out.file.fnum;
2787 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
2789 ZERO_STRUCT(break_info);
2791 torture_comment(tctx, "a 2nd open without level2 oplock support should generate a break to level2\n");
2792 status = smb_raw_open(cli3->tree, tctx, &io);
2793 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2794 fnum3 = io.ntcreatex.out.file.fnum;
2795 CHECK_VAL(io.ntcreatex.out.oplock_level, NO_OPLOCK_RETURN);
2797 torture_wait_for_oplock_break(tctx);
2798 CHECK_VAL(break_info.count, 1);
2799 CHECK_VAL(break_info.fnum, fnum);
2800 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
2801 CHECK_VAL(break_info.failures, 0);
2803 ZERO_STRUCT(break_info);
2805 torture_comment(tctx, "a 3rd open with level2 oplock support should not generate a break\n");
2806 status = smb_raw_open(cli2->tree, tctx, &io);
2807 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2808 fnum2 = io.ntcreatex.out.file.fnum;
2809 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
2811 torture_wait_for_oplock_break(tctx);
2812 CHECK_VAL(break_info.count, 0);
2814 smbcli_close(cli1->tree, fnum);
2815 smbcli_close(cli2->tree, fnum2);
2816 smbcli_close(cli3->tree, fnum3);
2819 smb_raw_exit(cli1->session);
2820 smb_raw_exit(cli2->session);
2821 smb_raw_exit(cli3->session);
2822 smbcli_deltree(cli1->tree, BASEDIR);
2826 static bool test_raw_oplock_batch24(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
2828 const char *fname = BASEDIR "\\test_batch24.dat";
2832 uint16_t fnum2=0,fnum3=0;
2833 struct smbcli_state *cli3 = NULL;
2835 if (!torture_setup_dir(cli1, BASEDIR)) {
2840 smbcli_unlink(cli1->tree, fname);
2842 ret = open_connection_no_level2_oplocks(tctx, &cli3);
2843 CHECK_VAL(ret, true);
2845 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2846 smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli2->tree);
2847 smbcli_oplock_handler(cli3->transport, oplock_handler_ack_to_given, cli3->tree);
2850 base ntcreatex parms
2852 io.generic.level = RAW_OPEN_NTCREATEX;
2853 io.ntcreatex.in.root_fid.fnum = 0;
2854 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2855 io.ntcreatex.in.alloc_size = 0;
2856 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2857 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2858 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2859 io.ntcreatex.in.create_options = 0;
2860 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2861 io.ntcreatex.in.security_flags = 0;
2862 io.ntcreatex.in.fname = fname;
2864 torture_comment(tctx, "BATCH24: a open without level support and ask for a batch oplock\n");
2865 ZERO_STRUCT(break_info);
2867 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_READ | SEC_RIGHTS_FILE_WRITE;
2868 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
2869 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2870 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2871 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2872 status = smb_raw_open(cli3->tree, tctx, &io);
2873 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2874 fnum3 = io.ntcreatex.out.file.fnum;
2875 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
2877 ZERO_STRUCT(break_info);
2879 torture_comment(tctx, "a 2nd open with level2 oplock support should generate a break to none\n");
2880 status = smb_raw_open(cli2->tree, tctx, &io);
2881 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2882 fnum2 = io.ntcreatex.out.file.fnum;
2883 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
2885 torture_wait_for_oplock_break(tctx);
2886 CHECK_VAL(break_info.count, 1);
2887 CHECK_VAL(break_info.fnum, fnum3);
2888 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_NONE);
2889 CHECK_VAL(break_info.failures, 0);
2891 smbcli_close(cli3->tree, fnum3);
2892 smbcli_close(cli2->tree, fnum2);
2895 smb_raw_exit(cli1->session);
2896 smb_raw_exit(cli2->session);
2897 smb_raw_exit(cli3->session);
2898 smbcli_deltree(cli1->tree, BASEDIR);
2902 static bool test_raw_oplock_batch25(struct torture_context *tctx,
2903 struct smbcli_state *cli1,
2904 struct smbcli_state *cli2)
2906 const char *fname = BASEDIR "\\test_batch25.dat";
2910 union smb_setfileinfo sfi;
2913 if (!torture_setup_dir(cli1, BASEDIR)) {
2918 smbcli_unlink(cli1->tree, fname);
2920 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2923 base ntcreatex parms
2925 io.generic.level = RAW_OPEN_NTCREATEX;
2926 io.ntcreatex.in.root_fid.fnum = 0;
2927 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2928 io.ntcreatex.in.alloc_size = 0;
2929 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2930 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2931 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2932 io.ntcreatex.in.create_options = 0;
2933 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2934 io.ntcreatex.in.security_flags = 0;
2935 io.ntcreatex.in.fname = fname;
2937 torture_comment(tctx, "BATCH25: open a file with an batch oplock "
2938 "(share mode: none)\n");
2940 ZERO_STRUCT(break_info);
2941 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2942 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2943 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2944 status = smb_raw_open(cli1->tree, tctx, &io);
2945 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2946 fnum = io.ntcreatex.out.file.fnum;
2947 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
2949 torture_comment(tctx, "setpathinfo attribute info should not trigger "
2950 "a break nor a violation\n");
2952 sfi.generic.level = RAW_SFILEINFO_SETATTR;
2953 sfi.generic.in.file.path = fname;
2954 sfi.setattr.in.attrib = FILE_ATTRIBUTE_HIDDEN;
2955 sfi.setattr.in.write_time = 0;
2957 status = smb_raw_setpathinfo(cli2->tree, &sfi);
2958 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2960 torture_wait_for_oplock_break(tctx);
2961 CHECK_VAL(break_info.count, 0);
2963 smbcli_close(cli1->tree, fnum);
2966 smb_raw_exit(cli1->session);
2967 smb_raw_exit(cli2->session);
2968 smbcli_deltree(cli1->tree, BASEDIR);
2973 * Similar to batch17/18, but test with open share mode rather than
2976 static bool test_raw_oplock_batch26(struct torture_context *tctx,
2977 struct smbcli_state *cli1, struct smbcli_state *cli2)
2979 const char *fname1 = BASEDIR "\\test_batch26_1.dat";
2980 const char *fname2 = BASEDIR "\\test_batch26_2.dat";
2984 union smb_rename rn;
2987 if (!torture_setup_dir(cli1, BASEDIR)) {
2992 smbcli_unlink(cli1->tree, fname1);
2993 smbcli_unlink(cli1->tree, fname2);
2995 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given,
2999 base ntcreatex parms
3001 io.generic.level = RAW_OPEN_NTCREATEX;
3002 io.ntcreatex.in.root_fid.fnum = 0;
3003 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
3004 io.ntcreatex.in.alloc_size = 0;
3005 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
3006 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
3007 NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_DELETE;
3008 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
3009 io.ntcreatex.in.create_options = 0;
3010 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
3011 io.ntcreatex.in.security_flags = 0;
3012 io.ntcreatex.in.fname = fname1;
3014 torture_comment(tctx, "BATCH26: open a file with an batch oplock "
3015 "(share mode: none)\n");
3017 ZERO_STRUCT(break_info);
3018 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
3019 NTCREATEX_FLAGS_REQUEST_OPLOCK |
3020 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
3023 status = smb_raw_open(cli1->tree, tctx, &io);
3024 CHECK_STATUS(tctx, status, NT_STATUS_OK);
3025 fnum = io.ntcreatex.out.file.fnum;
3026 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
3028 torture_comment(tctx, "rename should trigger a break\n");
3030 rn.generic.level = RAW_RENAME_RENAME;
3031 rn.rename.in.pattern1 = fname1;
3032 rn.rename.in.pattern2 = fname2;
3033 rn.rename.in.attrib = 0;
3035 torture_comment(tctx, "trying rename while first file open\n");
3036 status = smb_raw_rename(cli2->tree, &rn);
3037 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
3039 torture_wait_for_oplock_break(tctx);
3040 CHECK_VAL(break_info.count, 1);
3041 CHECK_VAL(break_info.failures, 0);
3042 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
3044 /* Close and reopen with batch again. */
3045 smbcli_close(cli1->tree, fnum);
3046 ZERO_STRUCT(break_info);
3048 status = smb_raw_open(cli1->tree, tctx, &io);
3049 CHECK_STATUS(tctx, status, NT_STATUS_OK);
3050 fnum = io.ntcreatex.out.file.fnum;
3051 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
3053 /* Now try ntrename. */
3054 torture_comment(tctx, "ntrename should trigger a break\n");
3056 rn.generic.level = RAW_RENAME_NTRENAME;
3057 rn.ntrename.in.attrib = 0;
3058 rn.ntrename.in.flags = RENAME_FLAG_RENAME;
3059 rn.ntrename.in.old_name = fname1;
3060 rn.ntrename.in.new_name = fname2;
3061 torture_comment(tctx, "trying rename while first file open\n");
3062 status = smb_raw_rename(cli2->tree, &rn);
3063 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
3065 torture_wait_for_oplock_break(tctx);
3066 CHECK_VAL(break_info.count, 1);
3067 CHECK_VAL(break_info.failures, 0);
3068 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
3070 smbcli_close(cli1->tree, fnum);
3073 smb_raw_exit(cli1->session);
3074 smb_raw_exit(cli2->session);
3075 smbcli_deltree(cli1->tree, BASEDIR);
3079 /* Test how oplocks work on streams. */
3080 static bool test_raw_oplock_stream1(struct torture_context *tctx,
3081 struct smbcli_state *cli1,
3082 struct smbcli_state *cli2)
3086 const char *fname_base = BASEDIR "\\test_stream1.txt";
3087 const char *stream = "Stream One:$DATA";
3088 const char *fname_stream, *fname_default_stream;
3089 const char *default_stream = "::$DATA";
3093 int stream_fnum = -1;
3094 uint32_t batch_req = NTCREATEX_FLAGS_REQUEST_OPLOCK |
3095 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK | NTCREATEX_FLAGS_EXTENDED;
3096 uint32_t exclusive_req = NTCREATEX_FLAGS_REQUEST_OPLOCK |
3097 NTCREATEX_FLAGS_EXTENDED;
3099 #define NSTREAM_OPLOCK_RESULTS 8
3102 bool open_base_file;
3103 uint32_t oplock_req;
3104 uint32_t oplock_granted;
3105 } stream_oplock_results[NSTREAM_OPLOCK_RESULTS] = {
3106 /* Request oplock on stream without the base file open. */
3107 {&fname_stream, false, batch_req, NO_OPLOCK_RETURN},
3108 {&fname_default_stream, false, batch_req, NO_OPLOCK_RETURN},
3109 {&fname_stream, false, exclusive_req, EXCLUSIVE_OPLOCK_RETURN},
3110 {&fname_default_stream, false, exclusive_req, EXCLUSIVE_OPLOCK_RETURN},
3112 /* Request oplock on stream with the base file open. */
3113 {&fname_stream, true, batch_req, NO_OPLOCK_RETURN},
3114 {&fname_default_stream, true, batch_req, NO_OPLOCK_RETURN},
3115 {&fname_stream, true, exclusive_req, EXCLUSIVE_OPLOCK_RETURN},
3116 {&fname_default_stream, true, exclusive_req, LEVEL_II_OPLOCK_RETURN},
3121 /* Only passes against windows at the moment. */
3122 if (torture_setting_bool(tctx, "samba3", false) ||
3123 torture_setting_bool(tctx, "samba4", false)) {
3124 torture_skip(tctx, "STREAM1 disabled against samba3+4\n");
3127 fname_stream = talloc_asprintf(tctx, "%s:%s", fname_base, stream);
3128 fname_default_stream = talloc_asprintf(tctx, "%s%s", fname_base,
3131 if (!torture_setup_dir(cli1, BASEDIR)) {
3134 smbcli_unlink(cli1->tree, fname_base);
3136 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
3137 smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli2->tree);
3139 /* Setup generic open parameters. */
3140 io.generic.level = RAW_OPEN_NTCREATEX;
3141 io.ntcreatex.in.root_fid.fnum = 0;
3142 io.ntcreatex.in.access_mask = (SEC_FILE_READ_DATA|SEC_FILE_WRITE_DATA|
3143 SEC_FILE_APPEND_DATA|SEC_STD_READ_CONTROL);
3144 io.ntcreatex.in.create_options = 0;
3145 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
3146 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
3147 NTCREATEX_SHARE_ACCESS_WRITE;
3148 io.ntcreatex.in.alloc_size = 0;
3149 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
3150 io.ntcreatex.in.security_flags = 0;
3152 /* Create the file with a stream */
3153 io.ntcreatex.in.fname = fname_stream;
3154 io.ntcreatex.in.flags = 0;
3155 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
3156 status = smb_raw_open(cli1->tree, tctx, &io);
3157 CHECK_STATUS(tctx, status, NT_STATUS_OK);
3158 smbcli_close(cli1->tree, io.ntcreatex.out.file.fnum);
3160 /* Change the disposition to open now that the file has been created. */
3161 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
3163 /* Try some permutations of taking oplocks on streams. */
3164 for (i = 0; i < NSTREAM_OPLOCK_RESULTS; i++) {
3165 const char *fname = *stream_oplock_results[i].fname;
3166 bool open_base_file = stream_oplock_results[i].open_base_file;
3167 uint32_t oplock_req = stream_oplock_results[i].oplock_req;
3168 uint32_t oplock_granted =
3169 stream_oplock_results[i].oplock_granted;
3172 if (open_base_file) {
3173 torture_comment(tctx, "Opening base file: %s with "
3174 "%d\n", fname_base, batch_req);
3175 io.ntcreatex.in.fname = fname_base;
3176 io.ntcreatex.in.flags = batch_req;
3177 status = smb_raw_open(cli2->tree, tctx, &io);
3178 CHECK_STATUS(tctx, status, NT_STATUS_OK);
3179 CHECK_VAL(io.ntcreatex.out.oplock_level,
3180 BATCH_OPLOCK_RETURN);
3181 base_fnum = io.ntcreatex.out.file.fnum;
3184 torture_comment(tctx, "%d: Opening stream: %s with %d\n", i,
3186 io.ntcreatex.in.fname = fname;
3187 io.ntcreatex.in.flags = oplock_req;
3189 /* Do the open with the desired oplock on the stream. */
3190 status = smb_raw_open(cli1->tree, tctx, &io);
3191 CHECK_STATUS(tctx, status, NT_STATUS_OK);
3192 CHECK_VAL(io.ntcreatex.out.oplock_level, oplock_granted);
3193 smbcli_close(cli1->tree, io.ntcreatex.out.file.fnum);
3195 /* Cleanup the base file if it was opened. */
3196 if (base_fnum != -1) {
3197 smbcli_close(cli2->tree, base_fnum);
3201 /* Open the stream with an exclusive oplock. */
3202 torture_comment(tctx, "Opening stream: %s with %d\n",
3203 fname_stream, exclusive_req);
3204 io.ntcreatex.in.fname = fname_stream;
3205 io.ntcreatex.in.flags = exclusive_req;
3206 status = smb_raw_open(cli1->tree, tctx, &io);
3207 CHECK_STATUS(tctx, status, NT_STATUS_OK);
3208 CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
3209 stream_fnum = io.ntcreatex.out.file.fnum;
3211 /* Open the base file and see if it contends. */
3212 ZERO_STRUCT(break_info);
3213 torture_comment(tctx, "Opening base file: %s with "
3214 "%d\n", fname_base, batch_req);
3215 io.ntcreatex.in.fname = fname_base;
3216 io.ntcreatex.in.flags = batch_req;
3217 status = smb_raw_open(cli2->tree, tctx, &io);
3218 CHECK_STATUS(tctx, status, NT_STATUS_OK);
3219 CHECK_VAL(io.ntcreatex.out.oplock_level,
3220 BATCH_OPLOCK_RETURN);
3221 smbcli_close(cli2->tree, io.ntcreatex.out.file.fnum);
3223 torture_wait_for_oplock_break(tctx);
3224 CHECK_VAL(break_info.count, 0);
3225 CHECK_VAL(break_info.failures, 0);
3227 /* Open the stream again to see if it contends. */
3228 ZERO_STRUCT(break_info);
3229 torture_comment(tctx, "Opening stream again: %s with "
3230 "%d\n", fname_base, batch_req);
3231 io.ntcreatex.in.fname = fname_stream;
3232 io.ntcreatex.in.flags = exclusive_req;
3233 status = smb_raw_open(cli2->tree, tctx, &io);
3234 CHECK_STATUS(tctx, status, NT_STATUS_OK);
3235 CHECK_VAL(io.ntcreatex.out.oplock_level,
3236 LEVEL_II_OPLOCK_RETURN);
3237 smbcli_close(cli2->tree, io.ntcreatex.out.file.fnum);
3239 torture_wait_for_oplock_break(tctx);
3240 CHECK_VAL(break_info.count, 1);
3241 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
3242 CHECK_VAL(break_info.failures, 0);
3244 /* Close the stream. */
3245 if (stream_fnum != -1) {
3246 smbcli_close(cli1->tree, stream_fnum);
3250 smbcli_close(cli1->tree, fnum);
3251 smb_raw_exit(cli1->session);
3252 smb_raw_exit(cli2->session);
3253 smbcli_deltree(cli1->tree, BASEDIR);
3257 static bool test_raw_oplock_doc(struct torture_context *tctx,
3258 struct smbcli_state *cli)
3260 const char *fname = BASEDIR "\\test_oplock_doc.dat";
3266 if (!torture_setup_dir(cli, BASEDIR)) {
3271 smbcli_unlink(cli->tree, fname);
3273 smbcli_oplock_handler(cli->transport, oplock_handler_ack_to_given,
3277 base ntcreatex parms
3279 io.generic.level = RAW_OPEN_NTCREATEX;
3280 io.ntcreatex.in.root_fid.fnum = 0;
3281 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
3282 io.ntcreatex.in.alloc_size = 0;
3283 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
3284 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
3285 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
3286 io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DELETE_ON_CLOSE;
3287 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
3288 io.ntcreatex.in.security_flags = 0;
3289 io.ntcreatex.in.fname = fname;
3291 torture_comment(tctx, "open a delete-on-close file with a batch "
3293 ZERO_STRUCT(break_info);
3294 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
3295 NTCREATEX_FLAGS_REQUEST_OPLOCK |
3296 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
3298 status = smb_raw_open(cli->tree, tctx, &io);
3299 CHECK_STATUS(tctx, status, NT_STATUS_OK);
3300 fnum = io.ntcreatex.out.file.fnum;
3301 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
3303 smbcli_close(cli->tree, fnum);
3306 smb_raw_exit(cli->session);
3307 smbcli_deltree(cli->tree, BASEDIR);
3311 /* Open a file with a batch oplock, then open it again from a second client
3312 * requesting no oplock. Having two open file handles should break our own
3313 * oplock during BRL acquisition.
3315 static bool test_raw_oplock_brl1(struct torture_context *tctx,
3316 struct smbcli_state *cli1,
3317 struct smbcli_state *cli2)
3319 const char *fname = BASEDIR "\\test_batch_brl.dat";
3323 bool correct = true;
3329 if (!torture_setup_dir(cli1, BASEDIR)) {
3334 smbcli_unlink(cli1->tree, fname);
3336 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given,
3340 base ntcreatex parms
3342 io.generic.level = RAW_OPEN_NTCREATEX;
3343 io.ntcreatex.in.root_fid.fnum = 0;
3344 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_READ |
3345 SEC_RIGHTS_FILE_WRITE;
3346 io.ntcreatex.in.alloc_size = 0;
3347 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
3348 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
3349 NTCREATEX_SHARE_ACCESS_WRITE;
3350 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
3351 io.ntcreatex.in.create_options = 0;
3352 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
3353 io.ntcreatex.in.security_flags = 0;
3354 io.ntcreatex.in.fname = fname;
3357 with a batch oplock we get a break
3359 torture_comment(tctx, "open with batch oplock\n");
3360 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
3361 NTCREATEX_FLAGS_REQUEST_OPLOCK |
3362 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
3364 status = smb_raw_open(cli1->tree, tctx, &io);
3365 CHECK_STATUS(tctx, status, NT_STATUS_OK);
3366 fnum = io.ntcreatex.out.file.fnum;
3367 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
3368 /* create a file with bogus data */
3369 memset(buf, 0, sizeof(buf));
3371 if (smbcli_write(cli1->tree, fnum, 0, buf, 0, sizeof(buf)) !=
3374 torture_comment(tctx, "Failed to create file\n");
3379 torture_comment(tctx, "a 2nd open should give a break\n");
3380 ZERO_STRUCT(break_info);
3382 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
3383 status = smb_raw_open(cli2->tree, tctx, &io);
3384 fnum2 = io.ntcreatex.out.file.fnum;
3385 CHECK_STATUS(tctx, status, NT_STATUS_OK);
3386 CHECK_VAL(break_info.count, 1);
3387 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
3388 CHECK_VAL(break_info.failures, 0);
3389 CHECK_VAL(break_info.fnum, fnum);
3391 ZERO_STRUCT(break_info);
3393 torture_comment(tctx, "a self BRL acquisition should break to none\n");
3395 status = smbcli_lock(cli1->tree, fnum, 0, 4, 0, WRITE_LOCK);
3396 CHECK_STATUS(tctx, status, NT_STATUS_OK);
3398 torture_wait_for_oplock_break(tctx);
3399 CHECK_VAL(break_info.count, 1);
3400 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_NONE);
3401 CHECK_VAL(break_info.fnum, fnum);
3402 CHECK_VAL(break_info.failures, 0);
3404 /* expect no oplock break */
3405 ZERO_STRUCT(break_info);
3406 status = smbcli_lock(cli1->tree, fnum, 2, 4, 0, WRITE_LOCK);
3407 CHECK_STATUS(tctx, status, NT_STATUS_LOCK_NOT_GRANTED);
3409 torture_wait_for_oplock_break(tctx);
3410 CHECK_VAL(break_info.count, 0);
3411 CHECK_VAL(break_info.level, 0);
3412 CHECK_VAL(break_info.fnum, 0);
3413 CHECK_VAL(break_info.failures, 0);
3415 smbcli_close(cli1->tree, fnum);
3416 smbcli_close(cli2->tree, fnum2);
3419 smb_raw_exit(cli1->session);
3420 smb_raw_exit(cli2->session);
3421 smbcli_deltree(cli1->tree, BASEDIR);
3426 /* Open a file with a batch oplock on one client and then acquire a brl.
3427 * We should not contend our own oplock.
3429 static bool test_raw_oplock_brl2(struct torture_context *tctx, struct smbcli_state *cli1)
3431 const char *fname = BASEDIR "\\test_batch_brl.dat";
3435 bool correct = true;
3440 if (!torture_setup_dir(cli1, BASEDIR)) {
3445 smbcli_unlink(cli1->tree, fname);
3447 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given,
3451 base ntcreatex parms
3453 io.generic.level = RAW_OPEN_NTCREATEX;
3454 io.ntcreatex.in.root_fid.fnum = 0;
3455 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_READ |
3456 SEC_RIGHTS_FILE_WRITE;
3457 io.ntcreatex.in.alloc_size = 0;
3458 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
3459 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
3460 NTCREATEX_SHARE_ACCESS_WRITE;
3461 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
3462 io.ntcreatex.in.create_options = 0;
3463 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
3464 io.ntcreatex.in.security_flags = 0;
3465 io.ntcreatex.in.fname = fname;
3468 with a batch oplock we get a break
3470 torture_comment(tctx, "open with batch oplock\n");
3471 ZERO_STRUCT(break_info);
3472 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
3473 NTCREATEX_FLAGS_REQUEST_OPLOCK |
3474 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
3476 status = smb_raw_open(cli1->tree, tctx, &io);
3477 CHECK_STATUS(tctx, status, NT_STATUS_OK);
3478 fnum = io.ntcreatex.out.file.fnum;
3479 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
3481 /* create a file with bogus data */
3482 memset(buf, 0, sizeof(buf));
3484 if (smbcli_write(cli1->tree, fnum, 0, buf, 0, sizeof(buf)) !=
3487 torture_comment(tctx, "Failed to create file\n");
3492 torture_comment(tctx, "a self BRL acquisition should not break to "
3495 status = smbcli_lock(cli1->tree, fnum, 0, 4, 0, WRITE_LOCK);
3496 CHECK_STATUS(tctx, status, NT_STATUS_OK);
3498 status = smbcli_lock(cli1->tree, fnum, 2, 4, 0, WRITE_LOCK);
3499 CHECK_STATUS(tctx, status, NT_STATUS_LOCK_NOT_GRANTED);
3501 /* With one file handle open a BRL should not contend our oplock.
3502 * Thus, no oplock break will be received and the entire break_info
3503 * struct will be 0 */
3504 torture_wait_for_oplock_break(tctx);
3505 CHECK_VAL(break_info.fnum, 0);
3506 CHECK_VAL(break_info.count, 0);
3507 CHECK_VAL(break_info.level, 0);
3508 CHECK_VAL(break_info.failures, 0);
3510 smbcli_close(cli1->tree, fnum);
3513 smb_raw_exit(cli1->session);
3514 smbcli_deltree(cli1->tree, BASEDIR);
3518 /* Open a file with a batch oplock twice from one client and then acquire a
3519 * brl. BRL acquisition should break our own oplock.
3521 static bool test_raw_oplock_brl3(struct torture_context *tctx,
3522 struct smbcli_state *cli1)
3524 const char *fname = BASEDIR "\\test_batch_brl.dat";
3527 bool correct = true;
3533 if (!torture_setup_dir(cli1, BASEDIR)) {
3538 smbcli_unlink(cli1->tree, fname);
3540 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given,
3544 base ntcreatex parms
3546 io.generic.level = RAW_OPEN_NTCREATEX;
3547 io.ntcreatex.in.root_fid.fnum = 0;
3548 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_READ |
3549 SEC_RIGHTS_FILE_WRITE;
3550 io.ntcreatex.in.alloc_size = 0;
3551 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
3552 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
3553 NTCREATEX_SHARE_ACCESS_WRITE;
3554 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
3555 io.ntcreatex.in.create_options = 0;
3556 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
3557 io.ntcreatex.in.security_flags = 0;
3558 io.ntcreatex.in.fname = fname;
3561 with a batch oplock we get a break
3563 torture_comment(tctx, "open with batch oplock\n");
3564 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
3565 NTCREATEX_FLAGS_REQUEST_OPLOCK |
3566 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
3568 status = smb_raw_open(cli1->tree, tctx, &io);
3569 CHECK_STATUS(tctx, status, NT_STATUS_OK);
3570 fnum = io.ntcreatex.out.file.fnum;
3571 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
3573 /* create a file with bogus data */
3574 memset(buf, 0, sizeof(buf));
3576 if (smbcli_write(cli1->tree, fnum, 0, buf, 0, sizeof(buf)) !=
3579 torture_comment(tctx, "Failed to create file\n");
3584 torture_comment(tctx, "a 2nd open should give a break\n");
3585 ZERO_STRUCT(break_info);
3587 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
3588 status = smb_raw_open(cli1->tree, tctx, &io);
3589 fnum2 = io.ntcreatex.out.file.fnum;
3590 CHECK_STATUS(tctx, status, NT_STATUS_OK);
3591 CHECK_VAL(break_info.count, 1);
3592 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
3593 CHECK_VAL(break_info.failures, 0);
3594 CHECK_VAL(break_info.fnum, fnum);
3596 ZERO_STRUCT(break_info);
3598 torture_comment(tctx, "a self BRL acquisition should break to none\n");
3600 status = smbcli_lock(cli1->tree, fnum, 0, 4, 0, WRITE_LOCK);
3601 CHECK_STATUS(tctx, status, NT_STATUS_OK);
3603 torture_wait_for_oplock_break(tctx);
3604 CHECK_VAL(break_info.count, 1);
3605 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_NONE);
3606 CHECK_VAL(break_info.fnum, fnum);
3607 CHECK_VAL(break_info.failures, 0);
3609 /* expect no oplock break */
3610 ZERO_STRUCT(break_info);
3611 status = smbcli_lock(cli1->tree, fnum, 2, 4, 0, WRITE_LOCK);
3612 CHECK_STATUS(tctx, status, NT_STATUS_LOCK_NOT_GRANTED);
3614 torture_wait_for_oplock_break(tctx);
3615 CHECK_VAL(break_info.count, 0);
3616 CHECK_VAL(break_info.level, 0);
3617 CHECK_VAL(break_info.fnum, 0);
3618 CHECK_VAL(break_info.failures, 0);
3620 smbcli_close(cli1->tree, fnum);
3621 smbcli_close(cli1->tree, fnum2);
3624 smb_raw_exit(cli1->session);
3625 smbcli_deltree(cli1->tree, BASEDIR);
3630 basic testing of oplocks
3632 struct torture_suite *torture_raw_oplock(TALLOC_CTX *mem_ctx)
3634 struct torture_suite *suite = torture_suite_create(mem_ctx, "OPLOCK");
3636 torture_suite_add_2smb_test(suite, "EXCLUSIVE1", test_raw_oplock_exclusive1);
3637 torture_suite_add_2smb_test(suite, "EXCLUSIVE2", test_raw_oplock_exclusive2);
3638 torture_suite_add_2smb_test(suite, "EXCLUSIVE3", test_raw_oplock_exclusive3);
3639 torture_suite_add_2smb_test(suite, "EXCLUSIVE4", test_raw_oplock_exclusive4);
3640 torture_suite_add_2smb_test(suite, "EXCLUSIVE5", test_raw_oplock_exclusive5);
3641 torture_suite_add_2smb_test(suite, "EXCLUSIVE6", test_raw_oplock_exclusive6);
3642 torture_suite_add_2smb_test(suite, "BATCH1", test_raw_oplock_batch1);
3643 torture_suite_add_2smb_test(suite, "BATCH2", test_raw_oplock_batch2);
3644 torture_suite_add_2smb_test(suite, "BATCH3", test_raw_oplock_batch3);
3645 torture_suite_add_2smb_test(suite, "BATCH4", test_raw_oplock_batch4);
3646 torture_suite_add_2smb_test(suite, "BATCH5", test_raw_oplock_batch5);
3647 torture_suite_add_2smb_test(suite, "BATCH6", test_raw_oplock_batch6);
3648 torture_suite_add_2smb_test(suite, "BATCH7", test_raw_oplock_batch7);
3649 torture_suite_add_2smb_test(suite, "BATCH8", test_raw_oplock_batch8);
3650 torture_suite_add_2smb_test(suite, "BATCH9", test_raw_oplock_batch9);
3651 torture_suite_add_2smb_test(suite, "BATCH10", test_raw_oplock_batch10);
3652 torture_suite_add_2smb_test(suite, "BATCH11", test_raw_oplock_batch11);
3653 torture_suite_add_2smb_test(suite, "BATCH12", test_raw_oplock_batch12);
3654 torture_suite_add_2smb_test(suite, "BATCH13", test_raw_oplock_batch13);
3655 torture_suite_add_2smb_test(suite, "BATCH14", test_raw_oplock_batch14);
3656 torture_suite_add_2smb_test(suite, "BATCH15", test_raw_oplock_batch15);
3657 torture_suite_add_2smb_test(suite, "BATCH16", test_raw_oplock_batch16);
3658 torture_suite_add_2smb_test(suite, "BATCH17", test_raw_oplock_batch17);
3659 torture_suite_add_2smb_test(suite, "BATCH18", test_raw_oplock_batch18);
3660 torture_suite_add_2smb_test(suite, "BATCH19", test_raw_oplock_batch19);
3661 torture_suite_add_2smb_test(suite, "BATCH20", test_raw_oplock_batch20);
3662 torture_suite_add_2smb_test(suite, "BATCH21", test_raw_oplock_batch21);
3663 torture_suite_add_2smb_test(suite, "BATCH22", test_raw_oplock_batch22);
3664 torture_suite_add_2smb_test(suite, "BATCH23", test_raw_oplock_batch23);
3665 torture_suite_add_2smb_test(suite, "BATCH24", test_raw_oplock_batch24);
3666 torture_suite_add_2smb_test(suite, "BATCH25", test_raw_oplock_batch25);
3667 torture_suite_add_2smb_test(suite, "BATCH26", test_raw_oplock_batch26);
3668 torture_suite_add_2smb_test(suite, "STREAM1", test_raw_oplock_stream1);
3669 torture_suite_add_1smb_test(suite, "DOC1", test_raw_oplock_doc);
3670 torture_suite_add_2smb_test(suite, "BRL1", test_raw_oplock_brl1);
3671 torture_suite_add_1smb_test(suite, "BRL2", test_raw_oplock_brl2);
3672 torture_suite_add_1smb_test(suite, "BRL3", test_raw_oplock_brl3);
3678 stress testing of oplocks
3680 bool torture_bench_oplock(struct torture_context *torture)
3682 struct smbcli_state **cli;
3684 TALLOC_CTX *mem_ctx = talloc_new(torture);
3685 int torture_nprocs = torture_setting_int(torture, "nprocs", 4);
3687 int timelimit = torture_setting_int(torture, "timelimit", 10);
3691 cli = talloc_array(mem_ctx, struct smbcli_state *, torture_nprocs);
3693 torture_comment(torture, "Opening %d connections\n", torture_nprocs);
3694 for (i=0;i<torture_nprocs;i++) {
3695 if (!torture_open_connection_ev(&cli[i], i, torture, torture->ev)) {
3698 talloc_steal(mem_ctx, cli[i]);
3699 smbcli_oplock_handler(cli[i]->transport, oplock_handler_close,
3703 if (!torture_setup_dir(cli[0], BASEDIR)) {
3708 io.ntcreatex.level = RAW_OPEN_NTCREATEX;
3709 io.ntcreatex.in.root_fid.fnum = 0;
3710 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
3711 io.ntcreatex.in.alloc_size = 0;
3712 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
3713 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
3714 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
3715 io.ntcreatex.in.create_options = 0;
3716 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
3717 io.ntcreatex.in.security_flags = 0;
3718 io.ntcreatex.in.fname = BASEDIR "\\test.dat";
3719 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
3720 NTCREATEX_FLAGS_REQUEST_OPLOCK |
3721 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
3723 tv = timeval_current();
3726 we open the same file with SHARE_ACCESS_NONE from all the
3727 connections in a round robin fashion. Each open causes an
3728 oplock break on the previous connection, which is answered
3729 by the oplock_handler_close() to close the file.
3731 This measures how fast we can pass on oplocks, and stresses
3732 the oplock handling code
3734 torture_comment(torture, "Running for %d seconds\n", timelimit);
3735 while (timeval_elapsed(&tv) < timelimit) {
3736 for (i=0;i<torture_nprocs;i++) {
3739 status = smb_raw_open(cli[i]->tree, mem_ctx, &io);
3740 CHECK_STATUS(torture, status, NT_STATUS_OK);
3744 if (torture_setting_bool(torture, "progress", true)) {
3745 torture_comment(torture, "%.2f ops/second\r", count/timeval_elapsed(&tv));
3749 torture_comment(torture, "%.2f ops/second\n", count/timeval_elapsed(&tv));
3751 smb_raw_exit(cli[torture_nprocs-1]->session);
3754 smb_raw_exit(cli[0]->session);
3755 smbcli_deltree(cli[0]->tree, BASEDIR);
3756 talloc_free(mem_ctx);
3761 static struct hold_oplock_info {
3763 bool close_on_break;
3764 uint32_t share_access;
3767 { BASEDIR "\\notshared_close", true,
3768 NTCREATEX_SHARE_ACCESS_NONE, },
3769 { BASEDIR "\\notshared_noclose", false,
3770 NTCREATEX_SHARE_ACCESS_NONE, },
3771 { BASEDIR "\\shared_close", true,
3772 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE, },
3773 { BASEDIR "\\shared_noclose", false,
3774 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE, },
3777 static bool oplock_handler_hold(struct smbcli_transport *transport,
3778 uint16_t tid, uint16_t fnum, uint8_t level,
3781 struct smbcli_tree *tree = (struct smbcli_tree *)private_data;
3782 struct hold_oplock_info *info;
3785 for (i=0;i<ARRAY_SIZE(hold_info);i++) {
3786 if (hold_info[i].fnum == fnum) break;
3789 if (i == ARRAY_SIZE(hold_info)) {
3790 printf("oplock break for unknown fnum %u\n", fnum);
3794 info = &hold_info[i];
3796 if (info->close_on_break) {
3797 printf("oplock break on %s - closing\n",
3799 oplock_handler_close(transport, tid, fnum, level, private_data);
3803 printf("oplock break on %s - acking break\n", info->fname);
3805 return smbcli_oplock_ack(tree, fnum, OPLOCK_BREAK_TO_NONE);
3810 used for manual testing of oplocks - especially interaction with
3811 other filesystems (such as NFS and local access)
3813 bool torture_hold_oplock(struct torture_context *torture,
3814 struct smbcli_state *cli)
3816 struct tevent_context *ev =
3817 (struct tevent_context *)cli->transport->socket->event.ctx;
3820 printf("Setting up open files with oplocks in %s\n", BASEDIR);
3822 if (!torture_setup_dir(cli, BASEDIR)) {
3826 smbcli_oplock_handler(cli->transport, oplock_handler_hold, cli->tree);
3828 /* setup the files */
3829 for (i=0;i<ARRAY_SIZE(hold_info);i++) {
3834 io.generic.level = RAW_OPEN_NTCREATEX;
3835 io.ntcreatex.in.root_fid.fnum = 0;
3836 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
3837 io.ntcreatex.in.alloc_size = 0;
3838 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
3839 io.ntcreatex.in.share_access = hold_info[i].share_access;
3840 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
3841 io.ntcreatex.in.create_options = 0;
3842 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
3843 io.ntcreatex.in.security_flags = 0;
3844 io.ntcreatex.in.fname = hold_info[i].fname;
3845 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
3846 NTCREATEX_FLAGS_REQUEST_OPLOCK |
3847 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
3848 printf("opening %s\n", hold_info[i].fname);
3850 status = smb_raw_open(cli->tree, cli, &io);
3851 if (!NT_STATUS_IS_OK(status)) {
3852 printf("Failed to open %s - %s\n",
3853 hold_info[i].fname, nt_errstr(status));
3857 if (io.ntcreatex.out.oplock_level != BATCH_OPLOCK_RETURN) {
3858 printf("Oplock not granted for %s - expected %d but got %d\n",
3859 hold_info[i].fname, BATCH_OPLOCK_RETURN,
3860 io.ntcreatex.out.oplock_level);
3863 hold_info[i].fnum = io.ntcreatex.out.file.fnum;
3865 /* make the file non-zero size */
3866 if (smbcli_write(cli->tree, hold_info[i].fnum, 0, &c, 0, 1) != 1) {
3867 printf("Failed to write to file\n");
3872 printf("Waiting for oplock events\n");
3873 event_loop_wait(ev);