2 Unix SMB/CIFS implementation.
3 basic raw test suite for oplocks
4 Copyright (C) Andrew Tridgell 2003
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "torture/torture.h"
22 #include "librpc/gen_ndr/security.h"
23 #include "libcli/raw/libcliraw.h"
24 #include "libcli/raw/raw_proto.h"
25 #include "libcli/libcli.h"
26 #include "torture/util.h"
27 #include "lib/events/events.h"
28 #include "param/param.h"
29 #include "lib/cmdline/popt_common.h"
30 #include "libcli/resolve/resolve.h"
32 #define CHECK_VAL(v, correct) do { \
33 if ((v) != (correct)) { \
34 torture_result(tctx, TORTURE_FAIL, "(%s): wrong value for %s got 0x%x - should be 0x%x\n", \
35 __location__, #v, (int)v, (int)correct); \
39 #define CHECK_RANGE(v, min, max) do { \
40 if ((v) < (min) || (v) > (max)) { \
41 torture_result(tctx, TORTURE_FAIL, "(%s): wrong value for %s got %d - should be between %d and %d\n", \
42 __location__, #v, (int)v, (int)min, (int)max); \
46 #define CHECK_STRMATCH(v, correct) do { \
47 if (!v || strstr((v),(correct)) == NULL) { \
48 torture_result(tctx, TORTURE_FAIL, "(%s): wrong value for %s got '%s' - should be '%s'\n", \
49 __location__, #v, v?v:"NULL", correct); \
54 #define CHECK_STATUS(tctx, status, correct) do { \
55 if (!NT_STATUS_EQUAL(status, correct)) { \
56 torture_result(tctx, TORTURE_FAIL, __location__": Incorrect status %s - should be %s", \
57 nt_errstr(status), nt_errstr(correct)); \
70 #define BASEDIR "\\test_oplock"
73 a handler function for oplock break requests. Ack it as a break to level II if possible
75 static bool oplock_handler_ack_to_given(struct smbcli_transport *transport,
76 uint16_t tid, uint16_t fnum,
77 uint8_t level, void *private)
79 struct smbcli_tree *tree = (struct smbcli_tree *)private;
82 break_info.fnum = fnum;
83 break_info.level = level;
87 case OPLOCK_BREAK_TO_LEVEL_II:
90 case OPLOCK_BREAK_TO_NONE:
95 break_info.failures++;
97 printf("Acking to %s [0x%02X] in oplock handler\n",
100 return smbcli_oplock_ack(tree, fnum, level);
104 a handler function for oplock break requests. Ack it as a break to none
106 static bool oplock_handler_ack_to_none(struct smbcli_transport *transport,
107 uint16_t tid, uint16_t fnum,
108 uint8_t level, void *private)
110 struct smbcli_tree *tree = (struct smbcli_tree *)private;
111 break_info.fnum = fnum;
112 break_info.level = level;
115 printf("Acking to none in oplock handler\n");
117 return smbcli_oplock_ack(tree, fnum, OPLOCK_BREAK_TO_NONE);
121 a handler function for oplock break requests. Let it timeout
123 static bool oplock_handler_timeout(struct smbcli_transport *transport,
124 uint16_t tid, uint16_t fnum,
125 uint8_t level, void *private)
127 break_info.fnum = fnum;
128 break_info.level = level;
131 printf("Let oplock break timeout\n");
135 static void oplock_handler_close_recv(struct smbcli_request *req)
138 status = smbcli_request_simple_recv(req);
139 if (!NT_STATUS_IS_OK(status)) {
140 printf("close failed in oplock_handler_close\n");
141 break_info.failures++;
146 a handler function for oplock break requests - close the file
148 static bool oplock_handler_close(struct smbcli_transport *transport, uint16_t tid,
149 uint16_t fnum, uint8_t level, void *private)
152 struct smbcli_tree *tree = (struct smbcli_tree *)private;
153 struct smbcli_request *req;
155 break_info.fnum = fnum;
156 break_info.level = level;
159 io.close.level = RAW_CLOSE_CLOSE;
160 io.close.in.file.fnum = fnum;
161 io.close.in.write_time = 0;
162 req = smb_raw_close_send(tree, &io);
164 printf("failed to send close in oplock_handler_close\n");
168 req->async.fn = oplock_handler_close_recv;
169 req->async.private = NULL;
174 static bool open_connection_no_level2_oplocks(struct torture_context *tctx,
175 struct smbcli_state **c)
179 struct smbcli_options options;
181 lp_smbcli_options(tctx->lp_ctx, &options);
183 options.use_level2_oplocks = false;
185 status = smbcli_full_connection(tctx, c,
186 torture_setting_string(tctx, "host", NULL),
187 lp_smb_ports(tctx->lp_ctx),
188 torture_setting_string(tctx, "share", NULL),
189 NULL, cmdline_credentials,
190 lp_resolve_context(tctx->lp_ctx),
192 if (!NT_STATUS_IS_OK(status)) {
193 printf("Failed to open connection - %s\n", nt_errstr(status));
200 static bool test_raw_oplock_exclusive1(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
202 const char *fname = BASEDIR "\\test_exclusive1.dat";
206 union smb_unlink unl;
209 if (!torture_setup_dir(cli1, BASEDIR)) {
214 smbcli_unlink(cli1->tree, fname);
216 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
221 io.generic.level = RAW_OPEN_NTCREATEX;
222 io.ntcreatex.in.root_fid = 0;
223 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
224 io.ntcreatex.in.alloc_size = 0;
225 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
226 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
227 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
228 io.ntcreatex.in.create_options = 0;
229 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
230 io.ntcreatex.in.security_flags = 0;
231 io.ntcreatex.in.fname = fname;
233 torture_comment(tctx, "EXCLUSIVE1: open a file with an exclusive oplock (share mode: none)\n");
234 ZERO_STRUCT(break_info);
235 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
237 status = smb_raw_open(cli1->tree, tctx, &io);
238 CHECK_STATUS(tctx, status, NT_STATUS_OK);
239 fnum = io.ntcreatex.out.file.fnum;
240 CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
242 torture_comment(tctx, "a 2nd open should not cause a break\n");
243 status = smb_raw_open(cli2->tree, tctx, &io);
244 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
245 CHECK_VAL(break_info.count, 0);
246 CHECK_VAL(break_info.failures, 0);
248 torture_comment(tctx, "unlink it - should also be no break\n");
249 unl.unlink.in.pattern = fname;
250 unl.unlink.in.attrib = 0;
251 status = smb_raw_unlink(cli2->tree, &unl);
252 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
253 CHECK_VAL(break_info.count, 0);
254 CHECK_VAL(break_info.failures, 0);
256 smbcli_close(cli1->tree, fnum);
259 smb_raw_exit(cli1->session);
260 smb_raw_exit(cli2->session);
261 smbcli_deltree(cli1->tree, BASEDIR);
265 static bool test_raw_oplock_exclusive2(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
267 const char *fname = BASEDIR "\\test_exclusive2.dat";
271 union smb_unlink unl;
272 uint16_t fnum=0, fnum2=0;
274 if (!torture_setup_dir(cli1, BASEDIR)) {
279 smbcli_unlink(cli1->tree, fname);
281 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
286 io.generic.level = RAW_OPEN_NTCREATEX;
287 io.ntcreatex.in.root_fid = 0;
288 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
289 io.ntcreatex.in.alloc_size = 0;
290 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
291 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
292 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
293 io.ntcreatex.in.create_options = 0;
294 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
295 io.ntcreatex.in.security_flags = 0;
296 io.ntcreatex.in.fname = fname;
298 torture_comment(tctx, "EXCLUSIVE2: open a file with an exclusive oplock (share mode: all)\n");
299 ZERO_STRUCT(break_info);
300 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
301 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
302 NTCREATEX_SHARE_ACCESS_WRITE|
303 NTCREATEX_SHARE_ACCESS_DELETE;
305 status = smb_raw_open(cli1->tree, tctx, &io);
306 CHECK_STATUS(tctx, status, NT_STATUS_OK);
307 fnum = io.ntcreatex.out.file.fnum;
308 CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
310 torture_comment(tctx, "a 2nd open should cause a break to level 2\n");
311 status = smb_raw_open(cli2->tree, tctx, &io);
312 CHECK_STATUS(tctx, status, NT_STATUS_OK);
313 fnum2 = io.ntcreatex.out.file.fnum;
314 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
315 CHECK_VAL(break_info.count, 1);
316 CHECK_VAL(break_info.fnum, fnum);
317 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
318 CHECK_VAL(break_info.failures, 0);
319 ZERO_STRUCT(break_info);
321 /* now we have 2 level II oplocks... */
322 torture_comment(tctx, "try to unlink it - should not cause a break, but a sharing violation\n");
323 unl.unlink.in.pattern = fname;
324 unl.unlink.in.attrib = 0;
325 status = smb_raw_unlink(cli2->tree, &unl);
326 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
327 CHECK_VAL(break_info.count, 0);
328 CHECK_VAL(break_info.failures, 0);
330 torture_comment(tctx, "close 1st handle\n");
331 smbcli_close(cli1->tree, fnum);
333 torture_comment(tctx, "try to unlink it - should not cause a break, but a sharing violation\n");
334 unl.unlink.in.pattern = fname;
335 unl.unlink.in.attrib = 0;
336 status = smb_raw_unlink(cli2->tree, &unl);
337 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
338 CHECK_VAL(break_info.count, 0);
339 CHECK_VAL(break_info.failures, 0);
341 torture_comment(tctx, "close 1st handle\n");
342 smbcli_close(cli2->tree, fnum2);
344 torture_comment(tctx, "unlink it\n");
345 unl.unlink.in.pattern = fname;
346 unl.unlink.in.attrib = 0;
347 status = smb_raw_unlink(cli2->tree, &unl);
348 CHECK_STATUS(tctx, status, NT_STATUS_OK);
349 CHECK_VAL(break_info.count, 0);
350 CHECK_VAL(break_info.failures, 0);
353 smb_raw_exit(cli1->session);
354 smb_raw_exit(cli2->session);
355 smbcli_deltree(cli1->tree, BASEDIR);
359 static bool test_raw_oplock_exclusive3(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
361 const char *fname = BASEDIR "\\test_exclusive3.dat";
365 union smb_setfileinfo sfi;
368 if (!torture_setup_dir(cli1, BASEDIR)) {
373 smbcli_unlink(cli1->tree, fname);
375 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
380 io.generic.level = RAW_OPEN_NTCREATEX;
381 io.ntcreatex.in.root_fid = 0;
382 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
383 io.ntcreatex.in.alloc_size = 0;
384 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
385 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
386 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
387 io.ntcreatex.in.create_options = 0;
388 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
389 io.ntcreatex.in.security_flags = 0;
390 io.ntcreatex.in.fname = fname;
392 torture_comment(tctx, "EXCLUSIVE3: open a file with an exclusive oplock (share mode: none)\n");
394 ZERO_STRUCT(break_info);
395 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
397 status = smb_raw_open(cli1->tree, tctx, &io);
398 CHECK_STATUS(tctx, status, NT_STATUS_OK);
399 fnum = io.ntcreatex.out.file.fnum;
400 CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
402 torture_comment(tctx, "setpathinfo EOF should trigger a break to none\n");
404 sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
405 sfi.generic.in.file.path = fname;
406 sfi.end_of_file_info.in.size = 100;
408 status = smb_raw_setpathinfo(cli2->tree, &sfi);
410 CHECK_STATUS(tctx, status, NT_STATUS_OK);
411 CHECK_VAL(break_info.count, 1);
412 CHECK_VAL(break_info.failures, 0);
413 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_NONE);
415 smbcli_close(cli1->tree, fnum);
418 smb_raw_exit(cli1->session);
419 smb_raw_exit(cli2->session);
420 smbcli_deltree(cli1->tree, BASEDIR);
424 static bool test_raw_oplock_exclusive4(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
426 const char *fname = BASEDIR "\\test_exclusive4.dat";
430 uint16_t fnum=0, fnum2=0;
432 if (!torture_setup_dir(cli1, BASEDIR)) {
437 smbcli_unlink(cli1->tree, fname);
439 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
444 io.generic.level = RAW_OPEN_NTCREATEX;
445 io.ntcreatex.in.root_fid = 0;
446 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
447 io.ntcreatex.in.alloc_size = 0;
448 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
449 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
450 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
451 io.ntcreatex.in.create_options = 0;
452 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
453 io.ntcreatex.in.security_flags = 0;
454 io.ntcreatex.in.fname = fname;
456 torture_comment(tctx, "EXCLUSIVE4: open with exclusive oplock\n");
457 ZERO_STRUCT(break_info);
458 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
460 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
461 status = smb_raw_open(cli1->tree, tctx, &io);
462 CHECK_STATUS(tctx, status, NT_STATUS_OK);
463 fnum = io.ntcreatex.out.file.fnum;
464 CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
466 ZERO_STRUCT(break_info);
467 torture_comment(tctx, "second open with attributes only shouldn't cause oplock break\n");
469 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
470 io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
471 status = smb_raw_open(cli2->tree, tctx, &io);
472 CHECK_STATUS(tctx, status, NT_STATUS_OK);
473 fnum2 = io.ntcreatex.out.file.fnum;
474 CHECK_VAL(io.ntcreatex.out.oplock_level, NO_OPLOCK_RETURN);
475 CHECK_VAL(break_info.count, 0);
476 CHECK_VAL(break_info.failures, 0);
478 smbcli_close(cli1->tree, fnum);
479 smbcli_close(cli2->tree, fnum2);
482 smb_raw_exit(cli1->session);
483 smb_raw_exit(cli2->session);
484 smbcli_deltree(cli1->tree, BASEDIR);
488 static bool test_raw_oplock_exclusive5(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
490 const char *fname = BASEDIR "\\test_exclusive5.dat";
494 uint16_t fnum=0, fnum2=0;
496 if (!torture_setup_dir(cli1, BASEDIR)) {
501 smbcli_unlink(cli1->tree, fname);
503 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
504 smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli1->tree);
509 io.generic.level = RAW_OPEN_NTCREATEX;
510 io.ntcreatex.in.root_fid = 0;
511 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
512 io.ntcreatex.in.alloc_size = 0;
513 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
514 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
515 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
516 io.ntcreatex.in.create_options = 0;
517 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
518 io.ntcreatex.in.security_flags = 0;
519 io.ntcreatex.in.fname = fname;
521 torture_comment(tctx, "EXCLUSIVE5: open with exclusive oplock\n");
522 ZERO_STRUCT(break_info);
523 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
526 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
527 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
528 NTCREATEX_SHARE_ACCESS_WRITE|
529 NTCREATEX_SHARE_ACCESS_DELETE;
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);
537 torture_comment(tctx, "second open with attributes only and NTCREATEX_DISP_OVERWRITE_IF dispostion causes oplock break\n");
539 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
540 io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
541 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE_IF;
542 status = smb_raw_open(cli2->tree, tctx, &io);
543 CHECK_STATUS(tctx, status, NT_STATUS_OK);
544 fnum2 = io.ntcreatex.out.file.fnum;
545 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
546 CHECK_VAL(break_info.count, 1);
547 CHECK_VAL(break_info.failures, 0);
549 smbcli_close(cli1->tree, fnum);
550 smbcli_close(cli2->tree, fnum2);
553 smb_raw_exit(cli1->session);
554 smb_raw_exit(cli2->session);
555 smbcli_deltree(cli1->tree, BASEDIR);
559 static bool test_raw_oplock_exclusive6(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
561 const char *fname1 = BASEDIR "\\test_exclusive6_1.dat";
562 const char *fname2 = BASEDIR "\\test_exclusive6_2.dat";
569 if (!torture_setup_dir(cli1, BASEDIR)) {
574 smbcli_unlink(cli1->tree, fname1);
575 smbcli_unlink(cli1->tree, fname2);
577 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
582 io.generic.level = RAW_OPEN_NTCREATEX;
583 io.ntcreatex.in.root_fid = 0;
584 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
585 io.ntcreatex.in.alloc_size = 0;
586 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
587 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
588 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
589 io.ntcreatex.in.create_options = 0;
590 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
591 io.ntcreatex.in.security_flags = 0;
592 io.ntcreatex.in.fname = fname1;
594 torture_comment(tctx, "EXCLUSIVE6: open a file with an exclusive oplock (share mode: none)\n");
595 ZERO_STRUCT(break_info);
596 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
598 status = smb_raw_open(cli1->tree, tctx, &io);
599 CHECK_STATUS(tctx, status, NT_STATUS_OK);
600 fnum = io.ntcreatex.out.file.fnum;
601 CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
603 torture_comment(tctx, "rename should not generate a break but get a sharing violation\n");
605 rn.generic.level = RAW_RENAME_RENAME;
606 rn.rename.in.pattern1 = fname1;
607 rn.rename.in.pattern2 = fname2;
608 rn.rename.in.attrib = 0;
610 printf("trying rename while first file open\n");
611 status = smb_raw_rename(cli2->tree, &rn);
613 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
614 CHECK_VAL(break_info.count, 0);
615 CHECK_VAL(break_info.failures, 0);
617 smbcli_close(cli1->tree, fnum);
620 smb_raw_exit(cli1->session);
621 smb_raw_exit(cli2->session);
622 smbcli_deltree(cli1->tree, BASEDIR);
626 static bool test_raw_oplock_batch1(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
628 const char *fname = BASEDIR "\\test_batch1.dat";
632 union smb_unlink unl;
636 if (!torture_setup_dir(cli1, BASEDIR)) {
641 smbcli_unlink(cli1->tree, fname);
643 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
648 io.generic.level = RAW_OPEN_NTCREATEX;
649 io.ntcreatex.in.root_fid = 0;
650 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
651 io.ntcreatex.in.alloc_size = 0;
652 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
653 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
654 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
655 io.ntcreatex.in.create_options = 0;
656 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
657 io.ntcreatex.in.security_flags = 0;
658 io.ntcreatex.in.fname = fname;
661 with a batch oplock we get a break
663 torture_comment(tctx, "BATCH1: open with batch oplock\n");
664 ZERO_STRUCT(break_info);
665 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
666 NTCREATEX_FLAGS_REQUEST_OPLOCK |
667 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
668 status = smb_raw_open(cli1->tree, tctx, &io);
669 CHECK_STATUS(tctx, status, NT_STATUS_OK);
670 fnum = io.ntcreatex.out.file.fnum;
671 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
673 torture_comment(tctx, "unlink should generate a break\n");
674 unl.unlink.in.pattern = fname;
675 unl.unlink.in.attrib = 0;
676 status = smb_raw_unlink(cli2->tree, &unl);
677 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
679 CHECK_VAL(break_info.count, 1);
680 CHECK_VAL(break_info.fnum, fnum);
681 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
682 CHECK_VAL(break_info.failures, 0);
684 torture_comment(tctx, "2nd unlink should not generate a break\n");
685 ZERO_STRUCT(break_info);
686 status = smb_raw_unlink(cli2->tree, &unl);
687 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
689 CHECK_VAL(break_info.count, 0);
691 torture_comment(tctx, "writing should generate a self break to none\n");
692 smbcli_write(cli1->tree, fnum, 0, &c, 0, 1);
694 smbcli_write(cli1->tree, fnum, 0, &c, 1, 1);
696 CHECK_VAL(break_info.count, 1);
697 CHECK_VAL(break_info.fnum, fnum);
698 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_NONE);
699 CHECK_VAL(break_info.failures, 0);
701 smbcli_close(cli1->tree, fnum);
704 smb_raw_exit(cli1->session);
705 smb_raw_exit(cli2->session);
706 smbcli_deltree(cli1->tree, BASEDIR);
710 static bool test_raw_oplock_batch2(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
712 const char *fname = BASEDIR "\\test_batch2.dat";
716 union smb_unlink unl;
720 if (!torture_setup_dir(cli1, BASEDIR)) {
725 smbcli_unlink(cli1->tree, fname);
727 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
732 io.generic.level = RAW_OPEN_NTCREATEX;
733 io.ntcreatex.in.root_fid = 0;
734 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
735 io.ntcreatex.in.alloc_size = 0;
736 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
737 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
738 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
739 io.ntcreatex.in.create_options = 0;
740 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
741 io.ntcreatex.in.security_flags = 0;
742 io.ntcreatex.in.fname = fname;
744 torture_comment(tctx, "BATCH2: open with batch oplock\n");
745 ZERO_STRUCT(break_info);
746 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
747 NTCREATEX_FLAGS_REQUEST_OPLOCK |
748 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
749 status = smb_raw_open(cli1->tree, tctx, &io);
750 CHECK_STATUS(tctx, status, NT_STATUS_OK);
751 fnum = io.ntcreatex.out.file.fnum;
752 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
754 torture_comment(tctx, "unlink should generate a break, which we ack as break to none\n");
755 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_none, cli1->tree);
756 unl.unlink.in.pattern = fname;
757 unl.unlink.in.attrib = 0;
758 status = smb_raw_unlink(cli2->tree, &unl);
759 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
761 CHECK_VAL(break_info.count, 1);
762 CHECK_VAL(break_info.fnum, fnum);
763 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
764 CHECK_VAL(break_info.failures, 0);
766 torture_comment(tctx, "2nd unlink should not generate a break\n");
767 ZERO_STRUCT(break_info);
768 status = smb_raw_unlink(cli2->tree, &unl);
769 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
771 CHECK_VAL(break_info.count, 0);
773 torture_comment(tctx, "writing should not generate a break\n");
774 smbcli_write(cli1->tree, fnum, 0, &c, 0, 1);
776 smbcli_write(cli1->tree, fnum, 0, &c, 1, 1);
778 CHECK_VAL(break_info.count, 0);
780 smbcli_close(cli1->tree, fnum);
783 smb_raw_exit(cli1->session);
784 smb_raw_exit(cli2->session);
785 smbcli_deltree(cli1->tree, BASEDIR);
789 static bool test_raw_oplock_batch3(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
791 const char *fname = BASEDIR "\\test_batch3.dat";
795 union smb_unlink unl;
798 if (!torture_setup_dir(cli1, BASEDIR)) {
803 smbcli_unlink(cli1->tree, fname);
805 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
810 io.generic.level = RAW_OPEN_NTCREATEX;
811 io.ntcreatex.in.root_fid = 0;
812 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
813 io.ntcreatex.in.alloc_size = 0;
814 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
815 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
816 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
817 io.ntcreatex.in.create_options = 0;
818 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
819 io.ntcreatex.in.security_flags = 0;
820 io.ntcreatex.in.fname = fname;
822 torture_comment(tctx, "BATCH3: if we close on break then the unlink can succeed\n");
823 ZERO_STRUCT(break_info);
824 smbcli_oplock_handler(cli1->transport, oplock_handler_close, cli1->tree);
825 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
826 NTCREATEX_FLAGS_REQUEST_OPLOCK |
827 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
828 status = smb_raw_open(cli1->tree, tctx, &io);
829 CHECK_STATUS(tctx, status, NT_STATUS_OK);
830 fnum = io.ntcreatex.out.file.fnum;
831 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
833 unl.unlink.in.pattern = fname;
834 unl.unlink.in.attrib = 0;
835 ZERO_STRUCT(break_info);
836 status = smb_raw_unlink(cli2->tree, &unl);
837 CHECK_STATUS(tctx, status, NT_STATUS_OK);
839 CHECK_VAL(break_info.count, 1);
840 CHECK_VAL(break_info.fnum, fnum);
841 CHECK_VAL(break_info.level, 1);
842 CHECK_VAL(break_info.failures, 0);
844 smbcli_close(cli1->tree, fnum);
847 smb_raw_exit(cli1->session);
848 smb_raw_exit(cli2->session);
849 smbcli_deltree(cli1->tree, BASEDIR);
853 static bool test_raw_oplock_batch4(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
855 const char *fname = BASEDIR "\\test_batch4.dat";
862 if (!torture_setup_dir(cli1, BASEDIR)) {
867 smbcli_unlink(cli1->tree, fname);
869 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
874 io.generic.level = RAW_OPEN_NTCREATEX;
875 io.ntcreatex.in.root_fid = 0;
876 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
877 io.ntcreatex.in.alloc_size = 0;
878 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
879 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
880 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
881 io.ntcreatex.in.create_options = 0;
882 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
883 io.ntcreatex.in.security_flags = 0;
884 io.ntcreatex.in.fname = fname;
886 torture_comment(tctx, "BATCH4: a self read should not cause a break\n");
887 ZERO_STRUCT(break_info);
888 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
890 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
891 NTCREATEX_FLAGS_REQUEST_OPLOCK |
892 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
893 status = smb_raw_open(cli1->tree, tctx, &io);
894 CHECK_STATUS(tctx, status, NT_STATUS_OK);
895 fnum = io.ntcreatex.out.file.fnum;
896 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
898 rd.read.level = RAW_READ_READ;
899 rd.read.in.file.fnum = fnum;
900 rd.read.in.count = 1;
901 rd.read.in.offset = 0;
902 rd.read.in.remaining = 0;
903 status = smb_raw_read(cli1->tree, &rd);
904 CHECK_STATUS(tctx, status, NT_STATUS_OK);
905 CHECK_VAL(break_info.count, 0);
906 CHECK_VAL(break_info.failures, 0);
908 smbcli_close(cli1->tree, fnum);
911 smb_raw_exit(cli1->session);
912 smb_raw_exit(cli2->session);
913 smbcli_deltree(cli1->tree, BASEDIR);
917 static bool test_raw_oplock_batch5(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
919 const char *fname = BASEDIR "\\test_batch5.dat";
925 if (!torture_setup_dir(cli1, BASEDIR)) {
930 smbcli_unlink(cli1->tree, fname);
932 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
937 io.generic.level = RAW_OPEN_NTCREATEX;
938 io.ntcreatex.in.root_fid = 0;
939 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
940 io.ntcreatex.in.alloc_size = 0;
941 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
942 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
943 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
944 io.ntcreatex.in.create_options = 0;
945 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
946 io.ntcreatex.in.security_flags = 0;
947 io.ntcreatex.in.fname = fname;
949 torture_comment(tctx, "BATCH5: a 2nd open should give a break\n");
950 ZERO_STRUCT(break_info);
951 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
953 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
954 NTCREATEX_FLAGS_REQUEST_OPLOCK |
955 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
956 status = smb_raw_open(cli1->tree, tctx, &io);
957 CHECK_STATUS(tctx, status, NT_STATUS_OK);
958 fnum = io.ntcreatex.out.file.fnum;
959 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
961 ZERO_STRUCT(break_info);
963 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
964 status = smb_raw_open(cli2->tree, tctx, &io);
965 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
967 CHECK_VAL(break_info.count, 1);
968 CHECK_VAL(break_info.fnum, fnum);
969 CHECK_VAL(break_info.level, 1);
970 CHECK_VAL(break_info.failures, 0);
972 smbcli_close(cli1->tree, fnum);
975 smb_raw_exit(cli1->session);
976 smb_raw_exit(cli2->session);
977 smbcli_deltree(cli1->tree, BASEDIR);
981 static bool test_raw_oplock_batch6(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
983 const char *fname = BASEDIR "\\test_batch6.dat";
987 uint16_t fnum=0, fnum2=0;
990 if (!torture_setup_dir(cli1, BASEDIR)) {
995 smbcli_unlink(cli1->tree, fname);
997 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1000 base ntcreatex parms
1002 io.generic.level = RAW_OPEN_NTCREATEX;
1003 io.ntcreatex.in.root_fid = 0;
1004 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1005 io.ntcreatex.in.alloc_size = 0;
1006 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1007 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1008 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1009 io.ntcreatex.in.create_options = 0;
1010 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1011 io.ntcreatex.in.security_flags = 0;
1012 io.ntcreatex.in.fname = fname;
1014 torture_comment(tctx, "BATCH6: a 2nd open should give a break to level II if the first open allowed shared read\n");
1015 ZERO_STRUCT(break_info);
1016 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1017 smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli2->tree);
1019 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_READ | SEC_RIGHTS_FILE_WRITE;
1020 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
1021 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1022 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1023 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1024 status = smb_raw_open(cli1->tree, tctx, &io);
1025 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1026 fnum = io.ntcreatex.out.file.fnum;
1027 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1029 ZERO_STRUCT(break_info);
1031 status = smb_raw_open(cli2->tree, tctx, &io);
1032 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1033 fnum2 = io.ntcreatex.out.file.fnum;
1034 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1036 CHECK_VAL(break_info.count, 1);
1037 CHECK_VAL(break_info.fnum, fnum);
1038 CHECK_VAL(break_info.level, 1);
1039 CHECK_VAL(break_info.failures, 0);
1040 ZERO_STRUCT(break_info);
1042 torture_comment(tctx, "write should trigger a break to none on both\n");
1043 smbcli_write(cli1->tree, fnum, 0, &c, 0, 1);
1045 smbcli_write(cli1->tree, fnum, 0, &c, 1, 1);
1047 CHECK_VAL(break_info.count, 2);
1048 CHECK_VAL(break_info.level, 0);
1049 CHECK_VAL(break_info.failures, 0);
1051 smbcli_close(cli1->tree, fnum);
1052 smbcli_close(cli2->tree, fnum2);
1056 smb_raw_exit(cli1->session);
1057 smb_raw_exit(cli2->session);
1058 smbcli_deltree(cli1->tree, BASEDIR);
1062 static bool test_raw_oplock_batch7(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1064 const char *fname = BASEDIR "\\test_batch7.dat";
1068 uint16_t fnum=0, fnum2=0;
1070 if (!torture_setup_dir(cli1, BASEDIR)) {
1075 smbcli_unlink(cli1->tree, fname);
1077 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1080 base ntcreatex parms
1082 io.generic.level = RAW_OPEN_NTCREATEX;
1083 io.ntcreatex.in.root_fid = 0;
1084 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1085 io.ntcreatex.in.alloc_size = 0;
1086 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1087 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1088 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1089 io.ntcreatex.in.create_options = 0;
1090 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1091 io.ntcreatex.in.security_flags = 0;
1092 io.ntcreatex.in.fname = fname;
1094 torture_comment(tctx, "BATCH7: a 2nd open should get an oplock when we close instead of ack\n");
1095 ZERO_STRUCT(break_info);
1096 smbcli_oplock_handler(cli1->transport, oplock_handler_close, cli1->tree);
1098 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1099 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1100 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1101 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1102 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1103 status = smb_raw_open(cli1->tree, tctx, &io);
1104 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1105 fnum2 = io.ntcreatex.out.file.fnum;
1106 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1108 ZERO_STRUCT(break_info);
1110 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1111 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1112 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1113 status = smb_raw_open(cli2->tree, tctx, &io);
1114 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1115 fnum = io.ntcreatex.out.file.fnum;
1116 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1118 CHECK_VAL(break_info.count, 1);
1119 CHECK_VAL(break_info.fnum, fnum2);
1120 CHECK_VAL(break_info.level, 1);
1121 CHECK_VAL(break_info.failures, 0);
1123 smbcli_close(cli2->tree, fnum);
1126 smb_raw_exit(cli1->session);
1127 smb_raw_exit(cli2->session);
1128 smbcli_deltree(cli1->tree, BASEDIR);
1132 static bool test_raw_oplock_batch8(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1134 const char *fname = BASEDIR "\\test_batch8.dat";
1138 uint16_t fnum=0, fnum2=0;
1140 if (!torture_setup_dir(cli1, BASEDIR)) {
1145 smbcli_unlink(cli1->tree, fname);
1147 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1150 base ntcreatex parms
1152 io.generic.level = RAW_OPEN_NTCREATEX;
1153 io.ntcreatex.in.root_fid = 0;
1154 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1155 io.ntcreatex.in.alloc_size = 0;
1156 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1157 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1158 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1159 io.ntcreatex.in.create_options = 0;
1160 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1161 io.ntcreatex.in.security_flags = 0;
1162 io.ntcreatex.in.fname = fname;
1164 torture_comment(tctx, "BATCH8: open with batch oplock\n");
1165 ZERO_STRUCT(break_info);
1166 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1168 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1169 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1170 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1171 status = smb_raw_open(cli1->tree, tctx, &io);
1172 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1173 fnum = io.ntcreatex.out.file.fnum;
1174 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1176 ZERO_STRUCT(break_info);
1177 torture_comment(tctx, "second open with attributes only shouldn't cause oplock break\n");
1179 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1180 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1181 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1182 io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
1183 status = smb_raw_open(cli2->tree, tctx, &io);
1184 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1185 fnum2 = io.ntcreatex.out.file.fnum;
1186 CHECK_VAL(io.ntcreatex.out.oplock_level, NO_OPLOCK_RETURN);
1187 CHECK_VAL(break_info.count, 0);
1188 CHECK_VAL(break_info.failures, 0);
1190 smbcli_close(cli1->tree, fnum);
1191 smbcli_close(cli2->tree, fnum2);
1194 smb_raw_exit(cli1->session);
1195 smb_raw_exit(cli2->session);
1196 smbcli_deltree(cli1->tree, BASEDIR);
1200 static bool test_raw_oplock_batch9(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1202 const char *fname = BASEDIR "\\test_batch9.dat";
1206 uint16_t fnum=0, fnum2=0;
1209 if (!torture_setup_dir(cli1, BASEDIR)) {
1214 smbcli_unlink(cli1->tree, fname);
1216 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1219 base ntcreatex parms
1221 io.generic.level = RAW_OPEN_NTCREATEX;
1222 io.ntcreatex.in.root_fid = 0;
1223 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1224 io.ntcreatex.in.alloc_size = 0;
1225 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1226 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1227 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1228 io.ntcreatex.in.create_options = 0;
1229 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1230 io.ntcreatex.in.security_flags = 0;
1231 io.ntcreatex.in.fname = fname;
1233 torture_comment(tctx, "BATCH9: open with attributes only can create file\n");
1235 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1236 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1237 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1238 io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
1239 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1240 status = smb_raw_open(cli1->tree, tctx, &io);
1241 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1242 fnum = io.ntcreatex.out.file.fnum;
1243 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1245 torture_comment(tctx, "Subsequent normal open should break oplock on attribute only open to level II\n");
1247 ZERO_STRUCT(break_info);
1248 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1250 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1251 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1252 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1253 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1254 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1255 status = smb_raw_open(cli2->tree, tctx, &io);
1256 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1257 fnum2 = io.ntcreatex.out.file.fnum;
1258 CHECK_VAL(break_info.count, 1);
1259 CHECK_VAL(break_info.fnum, fnum);
1260 CHECK_VAL(break_info.failures, 0);
1261 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
1262 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1263 smbcli_close(cli2->tree, fnum2);
1265 torture_comment(tctx, "third oplocked open should grant level2 without break\n");
1266 ZERO_STRUCT(break_info);
1267 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1268 smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli2->tree);
1269 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1270 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1271 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1272 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1273 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1274 status = smb_raw_open(cli2->tree, tctx, &io);
1275 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1276 fnum2 = io.ntcreatex.out.file.fnum;
1277 CHECK_VAL(break_info.count, 0);
1278 CHECK_VAL(break_info.failures, 0);
1279 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1281 ZERO_STRUCT(break_info);
1283 torture_comment(tctx, "write should trigger a break to none on both\n");
1284 smbcli_write(cli2->tree, fnum2, 0, &c, 0, 1);
1286 /* Now the oplock break request comes in. But right now we can't
1287 * answer it. Do another write */
1290 smbcli_write(cli2->tree, fnum2, 0, &c, 1, 1);
1292 CHECK_VAL(break_info.count, 2);
1293 CHECK_VAL(break_info.level, 0);
1294 CHECK_VAL(break_info.failures, 0);
1296 smbcli_close(cli1->tree, fnum);
1297 smbcli_close(cli2->tree, fnum2);
1300 smb_raw_exit(cli1->session);
1301 smb_raw_exit(cli2->session);
1302 smbcli_deltree(cli1->tree, BASEDIR);
1306 static bool test_raw_oplock_batch10(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1308 const char *fname = BASEDIR "\\test_batch10.dat";
1312 uint16_t fnum=0, fnum2=0;
1314 if (!torture_setup_dir(cli1, BASEDIR)) {
1319 smbcli_unlink(cli1->tree, fname);
1321 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1324 base ntcreatex parms
1326 io.generic.level = RAW_OPEN_NTCREATEX;
1327 io.ntcreatex.in.root_fid = 0;
1328 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1329 io.ntcreatex.in.alloc_size = 0;
1330 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1331 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1332 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1333 io.ntcreatex.in.create_options = 0;
1334 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1335 io.ntcreatex.in.security_flags = 0;
1336 io.ntcreatex.in.fname = fname;
1338 torture_comment(tctx, "BATCH10: Open with oplock after a non-oplock open should grant level2\n");
1339 ZERO_STRUCT(break_info);
1340 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
1341 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1342 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1343 NTCREATEX_SHARE_ACCESS_WRITE|
1344 NTCREATEX_SHARE_ACCESS_DELETE;
1345 status = smb_raw_open(cli1->tree, tctx, &io);
1346 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1347 fnum = io.ntcreatex.out.file.fnum;
1348 CHECK_VAL(break_info.count, 0);
1349 CHECK_VAL(break_info.failures, 0);
1350 CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
1352 smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli2->tree);
1354 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1355 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1356 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1357 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1358 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1359 NTCREATEX_SHARE_ACCESS_WRITE|
1360 NTCREATEX_SHARE_ACCESS_DELETE;
1361 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1362 status = smb_raw_open(cli2->tree, tctx, &io);
1363 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1364 fnum2 = io.ntcreatex.out.file.fnum;
1365 CHECK_VAL(break_info.count, 0);
1366 CHECK_VAL(break_info.failures, 0);
1367 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1369 torture_comment(tctx, "write should trigger a break to none\n");
1372 wr.write.level = RAW_WRITE_WRITE;
1373 wr.write.in.file.fnum = fnum;
1374 wr.write.in.count = 1;
1375 wr.write.in.offset = 0;
1376 wr.write.in.remaining = 0;
1377 wr.write.in.data = (const uint8_t *)"x";
1378 status = smb_raw_write(cli1->tree, &wr);
1379 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1382 /* Now the oplock break request comes in. But right now we can't
1383 * answer it. Do another write */
1389 wr.write.level = RAW_WRITE_WRITE;
1390 wr.write.in.file.fnum = fnum;
1391 wr.write.in.count = 1;
1392 wr.write.in.offset = 0;
1393 wr.write.in.remaining = 0;
1394 wr.write.in.data = (const uint8_t *)"x";
1395 status = smb_raw_write(cli1->tree, &wr);
1396 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1399 CHECK_VAL(break_info.count, 1);
1400 CHECK_VAL(break_info.fnum, fnum2);
1401 CHECK_VAL(break_info.level, 0);
1402 CHECK_VAL(break_info.failures, 0);
1404 smbcli_close(cli1->tree, fnum);
1405 smbcli_close(cli2->tree, fnum2);
1408 smb_raw_exit(cli1->session);
1409 smb_raw_exit(cli2->session);
1410 smbcli_deltree(cli1->tree, BASEDIR);
1414 static bool test_raw_oplock_batch11(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1416 const char *fname = BASEDIR "\\test_batch11.dat";
1420 union smb_setfileinfo sfi;
1423 if (!torture_setup_dir(cli1, BASEDIR)) {
1428 smbcli_unlink(cli1->tree, fname);
1430 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1433 base ntcreatex parms
1435 io.generic.level = RAW_OPEN_NTCREATEX;
1436 io.ntcreatex.in.root_fid = 0;
1437 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1438 io.ntcreatex.in.alloc_size = 0;
1439 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1440 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1441 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1442 io.ntcreatex.in.create_options = 0;
1443 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1444 io.ntcreatex.in.security_flags = 0;
1445 io.ntcreatex.in.fname = fname;
1447 /* Test if a set-eof on pathname breaks an exclusive oplock. */
1448 torture_comment(tctx, "BATCH11: Test if setpathinfo set EOF breaks oplocks.\n");
1450 ZERO_STRUCT(break_info);
1451 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1453 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1454 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1455 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1456 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1457 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1458 NTCREATEX_SHARE_ACCESS_WRITE|
1459 NTCREATEX_SHARE_ACCESS_DELETE;
1460 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1461 status = smb_raw_open(cli1->tree, tctx, &io);
1462 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1463 fnum = io.ntcreatex.out.file.fnum;
1464 CHECK_VAL(break_info.count, 0);
1465 CHECK_VAL(break_info.failures, 0);
1466 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1469 sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
1470 sfi.generic.in.file.path = fname;
1471 sfi.end_of_file_info.in.size = 100;
1473 status = smb_raw_setpathinfo(cli2->tree, &sfi);
1475 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1476 CHECK_VAL(break_info.count, 1);
1477 CHECK_VAL(break_info.failures, 0);
1478 CHECK_VAL(break_info.level, 0);
1480 smbcli_close(cli1->tree, fnum);
1483 smb_raw_exit(cli1->session);
1484 smb_raw_exit(cli2->session);
1485 smbcli_deltree(cli1->tree, BASEDIR);
1489 static bool test_raw_oplock_batch12(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1491 const char *fname = BASEDIR "\\test_batch12.dat";
1495 union smb_setfileinfo sfi;
1498 if (!torture_setup_dir(cli1, BASEDIR)) {
1503 smbcli_unlink(cli1->tree, fname);
1505 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1508 base ntcreatex parms
1510 io.generic.level = RAW_OPEN_NTCREATEX;
1511 io.ntcreatex.in.root_fid = 0;
1512 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1513 io.ntcreatex.in.alloc_size = 0;
1514 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1515 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1516 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1517 io.ntcreatex.in.create_options = 0;
1518 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1519 io.ntcreatex.in.security_flags = 0;
1520 io.ntcreatex.in.fname = fname;
1522 /* Test if a set-allocation size on pathname breaks an exclusive oplock. */
1523 torture_comment(tctx, "BATCH12: Test if setpathinfo allocation size breaks oplocks.\n");
1525 ZERO_STRUCT(break_info);
1526 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1528 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1529 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1530 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1531 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1532 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1533 NTCREATEX_SHARE_ACCESS_WRITE|
1534 NTCREATEX_SHARE_ACCESS_DELETE;
1535 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1536 status = smb_raw_open(cli1->tree, tctx, &io);
1537 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1538 fnum = io.ntcreatex.out.file.fnum;
1539 CHECK_VAL(break_info.count, 0);
1540 CHECK_VAL(break_info.failures, 0);
1541 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1544 sfi.generic.level = SMB_SFILEINFO_ALLOCATION_INFORMATION;
1545 sfi.generic.in.file.path = fname;
1546 sfi.allocation_info.in.alloc_size = 65536 * 8;
1548 status = smb_raw_setpathinfo(cli2->tree, &sfi);
1550 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1551 CHECK_VAL(break_info.count, 1);
1552 CHECK_VAL(break_info.failures, 0);
1553 CHECK_VAL(break_info.level, 0);
1555 smbcli_close(cli1->tree, fnum);
1558 smb_raw_exit(cli1->session);
1559 smb_raw_exit(cli2->session);
1560 smbcli_deltree(cli1->tree, BASEDIR);
1564 static bool test_raw_oplock_batch13(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1566 const char *fname = BASEDIR "\\test_batch13.dat";
1570 uint16_t fnum=0, fnum2=0;
1572 if (!torture_setup_dir(cli1, BASEDIR)) {
1577 smbcli_unlink(cli1->tree, fname);
1579 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1580 smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli1->tree);
1583 base ntcreatex parms
1585 io.generic.level = RAW_OPEN_NTCREATEX;
1586 io.ntcreatex.in.root_fid = 0;
1587 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1588 io.ntcreatex.in.alloc_size = 0;
1589 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1590 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1591 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1592 io.ntcreatex.in.create_options = 0;
1593 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1594 io.ntcreatex.in.security_flags = 0;
1595 io.ntcreatex.in.fname = fname;
1597 torture_comment(tctx, "BATCH13: open with batch oplock\n");
1598 ZERO_STRUCT(break_info);
1599 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1602 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1603 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1604 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1605 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1606 NTCREATEX_SHARE_ACCESS_WRITE|
1607 NTCREATEX_SHARE_ACCESS_DELETE;
1608 status = smb_raw_open(cli1->tree, tctx, &io);
1609 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1610 fnum = io.ntcreatex.out.file.fnum;
1611 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1613 ZERO_STRUCT(break_info);
1615 torture_comment(tctx, "second open with attributes only and NTCREATEX_DISP_OVERWRITE dispostion causes oplock break\n");
1617 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1618 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1619 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1620 io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
1621 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1622 NTCREATEX_SHARE_ACCESS_WRITE|
1623 NTCREATEX_SHARE_ACCESS_DELETE;
1624 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE;
1625 status = smb_raw_open(cli2->tree, tctx, &io);
1626 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1627 fnum2 = io.ntcreatex.out.file.fnum;
1628 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1629 CHECK_VAL(break_info.count, 1);
1630 CHECK_VAL(break_info.failures, 0);
1632 smbcli_close(cli1->tree, fnum);
1633 smbcli_close(cli2->tree, fnum2);
1636 smb_raw_exit(cli1->session);
1637 smb_raw_exit(cli2->session);
1638 smbcli_deltree(cli1->tree, BASEDIR);
1642 static bool test_raw_oplock_batch14(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1644 const char *fname = BASEDIR "\\test_batch14.dat";
1648 uint16_t fnum=0, fnum2=0;
1650 if (!torture_setup_dir(cli1, BASEDIR)) {
1655 smbcli_unlink(cli1->tree, fname);
1657 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1660 base ntcreatex parms
1662 io.generic.level = RAW_OPEN_NTCREATEX;
1663 io.ntcreatex.in.root_fid = 0;
1664 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1665 io.ntcreatex.in.alloc_size = 0;
1666 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1667 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1668 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1669 io.ntcreatex.in.create_options = 0;
1670 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1671 io.ntcreatex.in.security_flags = 0;
1672 io.ntcreatex.in.fname = fname;
1674 torture_comment(tctx, "BATCH14: open with batch oplock\n");
1675 ZERO_STRUCT(break_info);
1676 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1678 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1679 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1680 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1681 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1682 NTCREATEX_SHARE_ACCESS_WRITE|
1683 NTCREATEX_SHARE_ACCESS_DELETE;
1684 status = smb_raw_open(cli1->tree, tctx, &io);
1685 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1686 fnum = io.ntcreatex.out.file.fnum;
1687 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1689 ZERO_STRUCT(break_info);
1691 torture_comment(tctx, "second open with attributes only and NTCREATEX_DISP_SUPERSEDE dispostion causes oplock break\n");
1693 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1694 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1695 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1696 io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
1697 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1698 NTCREATEX_SHARE_ACCESS_WRITE|
1699 NTCREATEX_SHARE_ACCESS_DELETE;
1700 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE;
1701 status = smb_raw_open(cli2->tree, tctx, &io);
1702 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1703 fnum2 = io.ntcreatex.out.file.fnum;
1704 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1705 CHECK_VAL(break_info.count, 1);
1706 CHECK_VAL(break_info.failures, 0);
1708 smbcli_close(cli1->tree, fnum);
1709 smbcli_close(cli2->tree, fnum2);
1711 smb_raw_exit(cli1->session);
1712 smb_raw_exit(cli2->session);
1713 smbcli_deltree(cli1->tree, BASEDIR);
1717 static bool test_raw_oplock_batch15(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1719 const char *fname = BASEDIR "\\test_batch15.dat";
1723 union smb_fileinfo qfi;
1726 if (!torture_setup_dir(cli1, BASEDIR)) {
1731 smbcli_unlink(cli1->tree, fname);
1733 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1736 base ntcreatex parms
1738 io.generic.level = RAW_OPEN_NTCREATEX;
1739 io.ntcreatex.in.root_fid = 0;
1740 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1741 io.ntcreatex.in.alloc_size = 0;
1742 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1743 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1744 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1745 io.ntcreatex.in.create_options = 0;
1746 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1747 io.ntcreatex.in.security_flags = 0;
1748 io.ntcreatex.in.fname = fname;
1750 /* Test if a qpathinfo all info on pathname breaks a batch oplock. */
1751 torture_comment(tctx, "BATCH15: Test if qpathinfo all info breaks a batch oplock (should not).\n");
1753 ZERO_STRUCT(break_info);
1754 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1756 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1757 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1758 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1759 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1760 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1761 NTCREATEX_SHARE_ACCESS_WRITE|
1762 NTCREATEX_SHARE_ACCESS_DELETE;
1763 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1764 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1765 status = smb_raw_open(cli1->tree, tctx, &io);
1766 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1767 fnum = io.ntcreatex.out.file.fnum;
1768 CHECK_VAL(break_info.count, 0);
1769 CHECK_VAL(break_info.failures, 0);
1770 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1773 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
1774 qfi.generic.in.file.path = fname;
1776 status = smb_raw_pathinfo(cli2->tree, tctx, &qfi);
1778 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1779 CHECK_VAL(break_info.count, 0);
1781 smbcli_close(cli1->tree, fnum);
1784 smb_raw_exit(cli1->session);
1785 smb_raw_exit(cli2->session);
1786 smbcli_deltree(cli1->tree, BASEDIR);
1790 static bool test_raw_oplock_batch16(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1792 const char *fname = BASEDIR "\\test_batch16.dat";
1796 uint16_t fnum=0, fnum2=0;
1798 if (!torture_setup_dir(cli1, BASEDIR)) {
1803 smbcli_unlink(cli1->tree, fname);
1805 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1806 smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli1->tree);
1809 base ntcreatex parms
1811 io.generic.level = RAW_OPEN_NTCREATEX;
1812 io.ntcreatex.in.root_fid = 0;
1813 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1814 io.ntcreatex.in.alloc_size = 0;
1815 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1816 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1817 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1818 io.ntcreatex.in.create_options = 0;
1819 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1820 io.ntcreatex.in.security_flags = 0;
1821 io.ntcreatex.in.fname = fname;
1823 torture_comment(tctx, "BATCH16: open with batch oplock\n");
1824 ZERO_STRUCT(break_info);
1825 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1828 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1829 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1830 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1831 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1832 NTCREATEX_SHARE_ACCESS_WRITE|
1833 NTCREATEX_SHARE_ACCESS_DELETE;
1834 status = smb_raw_open(cli1->tree, tctx, &io);
1835 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1836 fnum = io.ntcreatex.out.file.fnum;
1837 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1839 ZERO_STRUCT(break_info);
1841 torture_comment(tctx, "second open with attributes only and NTCREATEX_DISP_OVERWRITE_IF dispostion causes oplock break\n");
1843 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1844 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1845 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1846 io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
1847 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1848 NTCREATEX_SHARE_ACCESS_WRITE|
1849 NTCREATEX_SHARE_ACCESS_DELETE;
1850 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE_IF;
1851 status = smb_raw_open(cli2->tree, tctx, &io);
1852 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1853 fnum2 = io.ntcreatex.out.file.fnum;
1854 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1855 CHECK_VAL(break_info.count, 1);
1856 CHECK_VAL(break_info.failures, 0);
1858 smbcli_close(cli1->tree, fnum);
1859 smbcli_close(cli2->tree, fnum2);
1862 smb_raw_exit(cli1->session);
1863 smb_raw_exit(cli2->session);
1864 smbcli_deltree(cli1->tree, BASEDIR);
1868 static bool test_raw_oplock_batch17(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1870 const char *fname1 = BASEDIR "\\test_batch17_1.dat";
1871 const char *fname2 = BASEDIR "\\test_batch17_2.dat";
1875 union smb_rename rn;
1878 if (!torture_setup_dir(cli1, BASEDIR)) {
1883 smbcli_unlink(cli1->tree, fname1);
1884 smbcli_unlink(cli1->tree, fname2);
1886 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1889 base ntcreatex parms
1891 io.generic.level = RAW_OPEN_NTCREATEX;
1892 io.ntcreatex.in.root_fid = 0;
1893 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1894 io.ntcreatex.in.alloc_size = 0;
1895 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1896 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1897 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1898 io.ntcreatex.in.create_options = 0;
1899 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1900 io.ntcreatex.in.security_flags = 0;
1901 io.ntcreatex.in.fname = fname1;
1903 torture_comment(tctx, "BATCH17: open a file with an batch oplock (share mode: none)\n");
1905 ZERO_STRUCT(break_info);
1906 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1907 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1908 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1910 status = smb_raw_open(cli1->tree, tctx, &io);
1911 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1912 fnum = io.ntcreatex.out.file.fnum;
1913 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1915 torture_comment(tctx, "rename should trigger a break\n");
1917 rn.generic.level = RAW_RENAME_RENAME;
1918 rn.rename.in.pattern1 = fname1;
1919 rn.rename.in.pattern2 = fname2;
1920 rn.rename.in.attrib = 0;
1922 printf("trying rename while first file open\n");
1923 status = smb_raw_rename(cli2->tree, &rn);
1925 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
1926 CHECK_VAL(break_info.count, 1);
1927 CHECK_VAL(break_info.failures, 0);
1928 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
1930 smbcli_close(cli1->tree, fnum);
1933 smb_raw_exit(cli1->session);
1934 smb_raw_exit(cli2->session);
1935 smbcli_deltree(cli1->tree, BASEDIR);
1939 static bool test_raw_oplock_batch18(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1941 const char *fname1 = BASEDIR "\\test_batch18_1.dat";
1942 const char *fname2 = BASEDIR "\\test_batch18_2.dat";
1946 union smb_rename rn;
1949 if (!torture_setup_dir(cli1, BASEDIR)) {
1954 smbcli_unlink(cli1->tree, fname1);
1955 smbcli_unlink(cli1->tree, fname2);
1957 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1960 base ntcreatex parms
1962 io.generic.level = RAW_OPEN_NTCREATEX;
1963 io.ntcreatex.in.root_fid = 0;
1964 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1965 io.ntcreatex.in.alloc_size = 0;
1966 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1967 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1968 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1969 io.ntcreatex.in.create_options = 0;
1970 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1971 io.ntcreatex.in.security_flags = 0;
1972 io.ntcreatex.in.fname = fname1;
1974 torture_comment(tctx, "BATCH18: open a file with an batch oplock (share mode: none)\n");
1976 ZERO_STRUCT(break_info);
1977 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1978 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1979 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1981 status = smb_raw_open(cli1->tree, tctx, &io);
1982 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1983 fnum = io.ntcreatex.out.file.fnum;
1984 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1986 torture_comment(tctx, "ntrename should trigger a break\n");
1988 rn.generic.level = RAW_RENAME_NTRENAME;
1989 rn.ntrename.in.attrib = 0;
1990 rn.ntrename.in.flags = RENAME_FLAG_RENAME;
1991 rn.ntrename.in.old_name = fname1;
1992 rn.ntrename.in.new_name = fname2;
1993 printf("trying rename while first file open\n");
1994 status = smb_raw_rename(cli2->tree, &rn);
1996 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
1997 CHECK_VAL(break_info.count, 1);
1998 CHECK_VAL(break_info.failures, 0);
1999 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
2001 smbcli_close(cli1->tree, fnum);
2004 smb_raw_exit(cli1->session);
2005 smb_raw_exit(cli2->session);
2006 smbcli_deltree(cli1->tree, BASEDIR);
2010 static bool test_raw_oplock_batch19(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
2012 const char *fname1 = BASEDIR "\\test_batch19_1.dat";
2013 const char *fname2 = BASEDIR "\\test_batch19_2.dat";
2014 const char *fname3 = BASEDIR "\\test_batch19_3.dat";
2018 union smb_fileinfo qfi;
2019 union smb_setfileinfo sfi;
2022 if (!torture_setup_dir(cli1, BASEDIR)) {
2027 smbcli_unlink(cli1->tree, fname1);
2028 smbcli_unlink(cli1->tree, fname2);
2029 smbcli_unlink(cli1->tree, fname3);
2031 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2034 base ntcreatex parms
2036 io.generic.level = RAW_OPEN_NTCREATEX;
2037 io.ntcreatex.in.root_fid = 0;
2038 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2039 io.ntcreatex.in.alloc_size = 0;
2040 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2041 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2042 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2043 io.ntcreatex.in.create_options = 0;
2044 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2045 io.ntcreatex.in.security_flags = 0;
2046 io.ntcreatex.in.fname = fname1;
2048 torture_comment(tctx, "BATCH19: open a file with an batch oplock (share mode: none)\n");
2049 ZERO_STRUCT(break_info);
2050 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2051 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2052 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2053 status = smb_raw_open(cli1->tree, tctx, &io);
2054 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2055 fnum = io.ntcreatex.out.file.fnum;
2056 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
2058 torture_comment(tctx, "setpathinfo rename info should not trigger a break nor a violation\n");
2060 sfi.generic.level = RAW_SFILEINFO_RENAME_INFORMATION;
2061 sfi.generic.in.file.path = fname1;
2062 sfi.rename_information.in.overwrite = 0;
2063 sfi.rename_information.in.root_fid = 0;
2064 sfi.rename_information.in.new_name = fname2+strlen(BASEDIR)+1;
2066 status = smb_raw_setpathinfo(cli2->tree, &sfi);
2068 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2069 CHECK_VAL(break_info.count, 0);
2072 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2073 qfi.generic.in.file.fnum = fnum;
2075 status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
2076 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2077 CHECK_STRMATCH(qfi.all_info.out.fname.s, fname2);
2079 torture_comment(tctx, "setfileinfo rename info should not trigger a break nor a violation\n");
2081 sfi.generic.level = RAW_SFILEINFO_RENAME_INFORMATION;
2082 sfi.generic.in.file.fnum = fnum;
2083 sfi.rename_information.in.overwrite = 0;
2084 sfi.rename_information.in.root_fid = 0;
2085 sfi.rename_information.in.new_name = fname3+strlen(BASEDIR)+1;
2087 status = smb_raw_setfileinfo(cli1->tree, &sfi);
2088 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2089 CHECK_VAL(break_info.count, 0);
2092 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2093 qfi.generic.in.file.fnum = fnum;
2095 status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
2096 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2097 CHECK_STRMATCH(qfi.all_info.out.fname.s, fname3);
2099 smbcli_close(cli1->tree, fnum);
2102 smb_raw_exit(cli1->session);
2103 smb_raw_exit(cli2->session);
2104 smbcli_deltree(cli1->tree, BASEDIR);
2108 /****************************************************
2109 Called from raw-rename - we need oplock handling for
2110 this test so this is why it's in oplock.c, not rename.c
2111 ****************************************************/
2113 bool test_trans2rename(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
2115 const char *fname1 = BASEDIR "\\test_trans2rename_1.dat";
2116 const char *fname2 = BASEDIR "\\test_trans2rename_2.dat";
2117 const char *fname3 = BASEDIR "\\test_trans2rename_3.dat";
2121 union smb_fileinfo qfi;
2122 union smb_setfileinfo sfi;
2125 if (!torture_setup_dir(cli1, BASEDIR)) {
2130 smbcli_unlink(cli1->tree, fname1);
2131 smbcli_unlink(cli1->tree, fname2);
2132 smbcli_unlink(cli1->tree, fname3);
2134 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2137 base ntcreatex parms
2139 io.generic.level = RAW_OPEN_NTCREATEX;
2140 io.ntcreatex.in.root_fid = 0;
2141 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2142 io.ntcreatex.in.alloc_size = 0;
2143 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2144 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2145 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2146 io.ntcreatex.in.create_options = 0;
2147 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2148 io.ntcreatex.in.security_flags = 0;
2149 io.ntcreatex.in.fname = fname1;
2151 torture_comment(tctx, "open a file with an exclusive oplock (share mode: none)\n");
2152 ZERO_STRUCT(break_info);
2153 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2154 NTCREATEX_FLAGS_REQUEST_OPLOCK;
2155 status = smb_raw_open(cli1->tree, tctx, &io);
2156 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2157 fnum = io.ntcreatex.out.file.fnum;
2158 CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
2160 torture_comment(tctx, "setpathinfo rename info should not trigger a break nor a violation\n");
2162 sfi.generic.level = RAW_SFILEINFO_RENAME_INFORMATION;
2163 sfi.generic.in.file.path = fname1;
2164 sfi.rename_information.in.overwrite = 0;
2165 sfi.rename_information.in.root_fid = 0;
2166 sfi.rename_information.in.new_name = fname2+strlen(BASEDIR)+1;
2168 status = smb_raw_setpathinfo(cli2->tree, &sfi);
2170 CHECK_STATUS(tctx, status, NT_STATUS_OK);
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, fname2);
2181 torture_comment(tctx, "setfileinfo rename info should not trigger a break nor a violation\n");
2183 sfi.generic.level = RAW_SFILEINFO_RENAME_INFORMATION;
2184 sfi.generic.in.file.fnum = fnum;
2185 sfi.rename_information.in.overwrite = 0;
2186 sfi.rename_information.in.root_fid = 0;
2187 sfi.rename_information.in.new_name = fname3+strlen(BASEDIR)+1;
2189 status = smb_raw_setfileinfo(cli1->tree, &sfi);
2190 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2191 CHECK_VAL(break_info.count, 0);
2194 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2195 qfi.generic.in.file.fnum = fnum;
2197 status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
2198 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2199 CHECK_STRMATCH(qfi.all_info.out.fname.s, fname3);
2201 smbcli_close(cli1->tree, fnum);
2204 smb_raw_exit(cli1->session);
2205 smb_raw_exit(cli2->session);
2206 smbcli_deltree(cli1->tree, BASEDIR);
2210 /****************************************************
2211 Called from raw-rename - we need oplock handling for
2212 this test so this is why it's in oplock.c, not rename.c
2213 ****************************************************/
2215 bool test_nttransrename(struct torture_context *tctx, struct smbcli_state *cli1)
2217 const char *fname1 = BASEDIR "\\test_nttransrename_1.dat";
2218 const char *fname2 = BASEDIR "\\test_nttransrename_2.dat";
2222 union smb_fileinfo qfi, qpi;
2223 union smb_rename rn;
2226 if (!torture_setup_dir(cli1, BASEDIR)) {
2231 smbcli_unlink(cli1->tree, fname1);
2232 smbcli_unlink(cli1->tree, fname2);
2234 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2237 base ntcreatex parms
2239 io.generic.level = RAW_OPEN_NTCREATEX;
2240 io.ntcreatex.in.root_fid = 0;
2241 io.ntcreatex.in.access_mask = 0;/* ask for no access at all */;
2242 io.ntcreatex.in.alloc_size = 0;
2243 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2244 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2245 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2246 io.ntcreatex.in.create_options = 0;
2247 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2248 io.ntcreatex.in.security_flags = 0;
2249 io.ntcreatex.in.fname = fname1;
2251 torture_comment(tctx, "nttrans_rename: open a file with an exclusive oplock (share mode: none)\n");
2252 ZERO_STRUCT(break_info);
2253 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2254 NTCREATEX_FLAGS_REQUEST_OPLOCK;
2255 status = smb_raw_open(cli1->tree, tctx, &io);
2256 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2257 fnum = io.ntcreatex.out.file.fnum;
2258 CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
2260 torture_comment(tctx, "nttrans_rename: should not trigger a break nor a share mode violation\n");
2262 rn.generic.level = RAW_RENAME_NTTRANS;
2263 rn.nttrans.in.file.fnum = fnum;
2264 rn.nttrans.in.flags = 0;
2265 rn.nttrans.in.new_name = fname2+strlen(BASEDIR)+1;
2267 status = smb_raw_rename(cli1->tree, &rn);
2269 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2270 CHECK_VAL(break_info.count, 0);
2272 /* w2k3 does nothing, it doesn't rename the file */
2273 torture_comment(tctx, "nttrans_rename: the server should have done nothing\n");
2275 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2276 qfi.generic.in.file.fnum = fnum;
2278 status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
2279 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2280 CHECK_STRMATCH(qfi.all_info.out.fname.s, fname1);
2283 qpi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2284 qpi.generic.in.file.path = fname1;
2286 status = smb_raw_pathinfo(cli1->tree, tctx, &qpi);
2287 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2288 CHECK_STRMATCH(qpi.all_info.out.fname.s, fname1);
2291 qpi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2292 qpi.generic.in.file.path = fname2;
2294 status = smb_raw_pathinfo(cli1->tree, tctx, &qpi);
2295 CHECK_STATUS(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
2297 torture_comment(tctx, "nttrans_rename: after closing the file the file is still not renamed\n");
2298 status = smbcli_close(cli1->tree, fnum);
2299 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2302 qpi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2303 qpi.generic.in.file.path = fname1;
2305 status = smb_raw_pathinfo(cli1->tree, tctx, &qpi);
2306 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2307 CHECK_STRMATCH(qpi.all_info.out.fname.s, fname1);
2310 qpi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2311 qpi.generic.in.file.path = fname2;
2313 status = smb_raw_pathinfo(cli1->tree, tctx, &qpi);
2314 CHECK_STATUS(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
2316 torture_comment(tctx, "nttrans_rename: rename with an invalid handle gives NT_STATUS_INVALID_HANDLE\n");
2318 rn.generic.level = RAW_RENAME_NTTRANS;
2319 rn.nttrans.in.file.fnum = fnum+1;
2320 rn.nttrans.in.flags = 0;
2321 rn.nttrans.in.new_name = fname2+strlen(BASEDIR)+1;
2323 status = smb_raw_rename(cli1->tree, &rn);
2325 CHECK_STATUS(tctx, status, NT_STATUS_INVALID_HANDLE);
2328 smb_raw_exit(cli1->session);
2329 smbcli_deltree(cli1->tree, BASEDIR);
2334 static bool test_raw_oplock_batch20(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
2336 const char *fname1 = BASEDIR "\\test_batch20_1.dat";
2337 const char *fname2 = BASEDIR "\\test_batch20_2.dat";
2338 const char *fname3 = BASEDIR "\\test_batch20_3.dat";
2342 union smb_fileinfo qfi;
2343 union smb_setfileinfo sfi;
2344 uint16_t fnum=0,fnum2=0;
2346 if (!torture_setup_dir(cli1, BASEDIR)) {
2351 smbcli_unlink(cli1->tree, fname1);
2352 smbcli_unlink(cli1->tree, fname2);
2353 smbcli_unlink(cli1->tree, fname3);
2355 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2358 base ntcreatex parms
2360 io.generic.level = RAW_OPEN_NTCREATEX;
2361 io.ntcreatex.in.root_fid = 0;
2362 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2363 io.ntcreatex.in.alloc_size = 0;
2364 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2365 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2366 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2367 io.ntcreatex.in.create_options = 0;
2368 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2369 io.ntcreatex.in.security_flags = 0;
2370 io.ntcreatex.in.fname = fname1;
2372 torture_comment(tctx, "BATCH20: open a file with an batch oplock (share mode: all)\n");
2373 ZERO_STRUCT(break_info);
2374 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2375 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2376 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2377 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
2378 NTCREATEX_SHARE_ACCESS_WRITE|
2379 NTCREATEX_SHARE_ACCESS_DELETE;
2380 status = smb_raw_open(cli1->tree, tctx, &io);
2381 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2382 fnum = io.ntcreatex.out.file.fnum;
2383 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
2385 torture_comment(tctx, "setpathinfo rename info should not trigger a break nor a violation\n");
2387 sfi.generic.level = RAW_SFILEINFO_RENAME_INFORMATION;
2388 sfi.generic.in.file.path = fname1;
2389 sfi.rename_information.in.overwrite = 0;
2390 sfi.rename_information.in.root_fid = 0;
2391 sfi.rename_information.in.new_name = fname2+strlen(BASEDIR)+1;
2393 status = smb_raw_setpathinfo(cli2->tree, &sfi);
2395 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2396 CHECK_VAL(break_info.count, 0);
2399 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2400 qfi.generic.in.file.fnum = fnum;
2402 status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
2403 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2404 CHECK_STRMATCH(qfi.all_info.out.fname.s, fname2);
2406 torture_comment(tctx, "open a file with the new name an batch oplock (share mode: all)\n");
2407 ZERO_STRUCT(break_info);
2408 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2409 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2410 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2411 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
2412 NTCREATEX_SHARE_ACCESS_WRITE|
2413 NTCREATEX_SHARE_ACCESS_DELETE;
2414 io.ntcreatex.in.fname = fname2;
2415 status = smb_raw_open(cli2->tree, tctx, &io);
2416 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2417 fnum2 = io.ntcreatex.out.file.fnum;
2418 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
2419 CHECK_VAL(break_info.count, 1);
2420 CHECK_VAL(break_info.failures, 0);
2421 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
2423 torture_comment(tctx, "setfileinfo rename info should not trigger a break nor a violation\n");
2425 sfi.generic.level = RAW_SFILEINFO_RENAME_INFORMATION;
2426 sfi.generic.in.file.fnum = fnum;
2427 sfi.rename_information.in.overwrite = 0;
2428 sfi.rename_information.in.root_fid = 0;
2429 sfi.rename_information.in.new_name = fname3+strlen(BASEDIR)+1;
2431 status = smb_raw_setfileinfo(cli1->tree, &sfi);
2432 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2433 CHECK_VAL(break_info.count, 1);
2434 CHECK_VAL(break_info.failures, 0);
2435 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
2438 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2439 qfi.generic.in.file.fnum = fnum;
2441 status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
2442 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2443 CHECK_STRMATCH(qfi.all_info.out.fname.s, fname3);
2446 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2447 qfi.generic.in.file.fnum = fnum2;
2449 status = smb_raw_fileinfo(cli2->tree, tctx, &qfi);
2450 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2451 CHECK_STRMATCH(qfi.all_info.out.fname.s, fname3);
2453 smbcli_close(cli1->tree, fnum);
2456 smb_raw_exit(cli1->session);
2457 smb_raw_exit(cli2->session);
2458 smbcli_deltree(cli1->tree, BASEDIR);
2462 static bool test_raw_oplock_batch21(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
2464 const char *fname = BASEDIR "\\test_batch21.dat";
2473 if (!torture_setup_dir(cli1, BASEDIR)) {
2478 smbcli_unlink(cli1->tree, fname);
2480 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2483 base ntcreatex parms
2485 io.generic.level = RAW_OPEN_NTCREATEX;
2486 io.ntcreatex.in.root_fid = 0;
2487 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2488 io.ntcreatex.in.alloc_size = 0;
2489 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2490 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2491 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2492 io.ntcreatex.in.create_options = 0;
2493 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2494 io.ntcreatex.in.security_flags = 0;
2495 io.ntcreatex.in.fname = fname;
2498 with a batch oplock we get a break
2500 torture_comment(tctx, "BATCH21: open with batch oplock\n");
2501 ZERO_STRUCT(break_info);
2502 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2503 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2504 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2505 status = smb_raw_open(cli1->tree, tctx, &io);
2506 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2507 fnum = io.ntcreatex.out.file.fnum;
2508 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
2510 torture_comment(tctx, "writing should not generate a break\n");
2511 wr = smbcli_write(cli1->tree, fnum, 0, &c, 0, 1);
2513 CHECK_STATUS(tctx, smbcli_nt_error(cli1->tree), NT_STATUS_OK);
2516 e.in.repeat_count = 1;
2517 status = smb_raw_echo(cli1->transport, &e);
2518 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2520 CHECK_VAL(break_info.count, 0);
2522 smbcli_close(cli1->tree, fnum);
2525 smb_raw_exit(cli1->session);
2526 smb_raw_exit(cli2->session);
2527 smbcli_deltree(cli1->tree, BASEDIR);
2531 static bool test_raw_oplock_batch22(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
2533 const char *fname = BASEDIR "\\test_batch22.dat";
2537 uint16_t fnum=0, fnum2=0;
2539 int timeout = torture_setting_int(tctx, "oplocktimeout", 30);
2542 if (torture_setting_bool(tctx, "samba3", false)) {
2543 torture_skip(tctx, "BATCH22 disabled against samba3\n");
2546 if (!torture_setup_dir(cli1, BASEDIR)) {
2551 smbcli_unlink(cli1->tree, fname);
2553 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2556 base ntcreatex parms
2558 io.generic.level = RAW_OPEN_NTCREATEX;
2559 io.ntcreatex.in.root_fid = 0;
2560 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2561 io.ntcreatex.in.alloc_size = 0;
2562 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2563 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2564 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2565 io.ntcreatex.in.create_options = 0;
2566 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2567 io.ntcreatex.in.security_flags = 0;
2568 io.ntcreatex.in.fname = fname;
2571 with a batch oplock we get a break
2573 torture_comment(tctx, "BATCH22: open with batch oplock\n");
2574 ZERO_STRUCT(break_info);
2575 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2576 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2577 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2578 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
2579 NTCREATEX_SHARE_ACCESS_WRITE|
2580 NTCREATEX_SHARE_ACCESS_DELETE;
2581 status = smb_raw_open(cli1->tree, tctx, &io);
2582 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2583 fnum = io.ntcreatex.out.file.fnum;
2584 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
2586 torture_comment(tctx, "a 2nd open shoud not succeed after the oplock break timeout\n");
2587 tv = timeval_current();
2588 smbcli_oplock_handler(cli1->transport, oplock_handler_timeout, cli1->tree);
2589 status = smb_raw_open(cli1->tree, tctx, &io);
2590 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
2591 te = (int)timeval_elapsed(&tv);
2592 CHECK_RANGE(te, timeout - 1, timeout + 15);
2594 CHECK_VAL(break_info.count, 1);
2595 CHECK_VAL(break_info.fnum, fnum);
2596 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
2597 CHECK_VAL(break_info.failures, 0);
2598 ZERO_STRUCT(break_info);
2600 torture_comment(tctx, "a 2nd open shoud succeed after the oplock release without break\n");
2601 tv = timeval_current();
2602 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2603 status = smb_raw_open(cli1->tree, tctx, &io);
2604 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2605 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
2606 te = (int)timeval_elapsed(&tv);
2607 /* it should come in without delay */
2608 CHECK_RANGE(te+1, 0, timeout);
2609 fnum2 = io.ntcreatex.out.file.fnum;
2611 CHECK_VAL(break_info.count, 0);
2613 smbcli_close(cli1->tree, fnum);
2614 smbcli_close(cli1->tree, fnum2);
2617 smb_raw_exit(cli1->session);
2618 smb_raw_exit(cli2->session);
2619 smbcli_deltree(cli1->tree, BASEDIR);
2623 static bool test_raw_oplock_batch23(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
2625 const char *fname = BASEDIR "\\test_batch23.dat";
2629 uint16_t fnum=0, fnum2=0,fnum3=0;
2630 struct smbcli_state *cli3 = NULL;
2632 if (torture_setting_bool(tctx, "samba3", false)) {
2633 torture_skip(tctx, "BATCH23 disabled against samba3\n");
2636 if (!torture_setup_dir(cli1, BASEDIR)) {
2641 smbcli_unlink(cli1->tree, fname);
2643 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2645 ret = open_connection_no_level2_oplocks(tctx, &cli3);
2646 CHECK_VAL(ret, true);
2649 base ntcreatex parms
2651 io.generic.level = RAW_OPEN_NTCREATEX;
2652 io.ntcreatex.in.root_fid = 0;
2653 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2654 io.ntcreatex.in.alloc_size = 0;
2655 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2656 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2657 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2658 io.ntcreatex.in.create_options = 0;
2659 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2660 io.ntcreatex.in.security_flags = 0;
2661 io.ntcreatex.in.fname = fname;
2663 torture_comment(tctx, "BATCH23: a open and ask for a batch oplock\n");
2664 ZERO_STRUCT(break_info);
2665 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2666 smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli2->tree);
2667 smbcli_oplock_handler(cli3->transport, oplock_handler_ack_to_given, cli3->tree);
2669 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_READ | SEC_RIGHTS_FILE_WRITE;
2670 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
2671 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2672 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2673 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2674 status = smb_raw_open(cli1->tree, tctx, &io);
2675 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2676 fnum = io.ntcreatex.out.file.fnum;
2677 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
2679 ZERO_STRUCT(break_info);
2681 torture_comment(tctx, "a 2nd open without level2 oplock support should generate a break to level2\n");
2682 status = smb_raw_open(cli3->tree, tctx, &io);
2683 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2684 fnum3 = io.ntcreatex.out.file.fnum;
2685 CHECK_VAL(io.ntcreatex.out.oplock_level, NO_OPLOCK_RETURN);
2687 CHECK_VAL(break_info.count, 1);
2688 CHECK_VAL(break_info.fnum, fnum);
2689 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
2690 CHECK_VAL(break_info.failures, 0);
2692 ZERO_STRUCT(break_info);
2694 torture_comment(tctx, "a 3rd open with level2 oplock support should not generate a break\n");
2695 status = smb_raw_open(cli2->tree, tctx, &io);
2696 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2697 fnum2 = io.ntcreatex.out.file.fnum;
2698 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
2700 CHECK_VAL(break_info.count, 0);
2702 smbcli_close(cli1->tree, fnum);
2703 smbcli_close(cli2->tree, fnum2);
2704 smbcli_close(cli3->tree, fnum3);
2707 smb_raw_exit(cli1->session);
2708 smb_raw_exit(cli2->session);
2709 smb_raw_exit(cli3->session);
2710 smbcli_deltree(cli1->tree, BASEDIR);
2714 static bool test_raw_oplock_batch24(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
2716 const char *fname = BASEDIR "\\test_batch24.dat";
2720 uint16_t fnum2=0,fnum3=0;
2721 struct smbcli_state *cli3 = NULL;
2723 if (!torture_setup_dir(cli1, BASEDIR)) {
2728 smbcli_unlink(cli1->tree, fname);
2730 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2732 ret = open_connection_no_level2_oplocks(tctx, &cli3);
2733 CHECK_VAL(ret, true);
2736 base ntcreatex parms
2738 io.generic.level = RAW_OPEN_NTCREATEX;
2739 io.ntcreatex.in.root_fid = 0;
2740 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2741 io.ntcreatex.in.alloc_size = 0;
2742 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2743 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2744 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2745 io.ntcreatex.in.create_options = 0;
2746 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2747 io.ntcreatex.in.security_flags = 0;
2748 io.ntcreatex.in.fname = fname;
2750 torture_comment(tctx, "BATCH24: a open without level support and ask for a batch oplock\n");
2751 ZERO_STRUCT(break_info);
2752 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2753 smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli2->tree);
2754 smbcli_oplock_handler(cli3->transport, oplock_handler_ack_to_given, cli3->tree);
2756 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_READ | SEC_RIGHTS_FILE_WRITE;
2757 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
2758 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2759 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2760 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2761 status = smb_raw_open(cli3->tree, tctx, &io);
2762 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2763 fnum3 = io.ntcreatex.out.file.fnum;
2764 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
2766 ZERO_STRUCT(break_info);
2768 torture_comment(tctx, "a 2nd open with level2 oplock support should generate a break to none\n");
2769 status = smb_raw_open(cli2->tree, tctx, &io);
2770 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2771 fnum2 = io.ntcreatex.out.file.fnum;
2772 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
2774 CHECK_VAL(break_info.count, 1);
2775 CHECK_VAL(break_info.fnum, fnum3);
2776 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_NONE);
2777 CHECK_VAL(break_info.failures, 0);
2779 smbcli_close(cli3->tree, fnum3);
2780 smbcli_close(cli2->tree, fnum2);
2783 smb_raw_exit(cli1->session);
2784 smb_raw_exit(cli2->session);
2785 smb_raw_exit(cli3->session);
2786 smbcli_deltree(cli1->tree, BASEDIR);
2791 basic testing of oplocks
2793 struct torture_suite *torture_raw_oplock(TALLOC_CTX *mem_ctx)
2795 struct torture_suite *suite = torture_suite_create(mem_ctx, "OPLOCK");
2797 torture_suite_add_2smb_test(suite, "EXCLUSIVE1", test_raw_oplock_exclusive1);
2798 torture_suite_add_2smb_test(suite, "EXCLUSIVE2", test_raw_oplock_exclusive2);
2799 torture_suite_add_2smb_test(suite, "EXCLUSIVE3", test_raw_oplock_exclusive3);
2800 torture_suite_add_2smb_test(suite, "EXCLUSIVE4", test_raw_oplock_exclusive4);
2801 torture_suite_add_2smb_test(suite, "EXCLUSIVE5", test_raw_oplock_exclusive5);
2802 torture_suite_add_2smb_test(suite, "EXCLUSIVE6", test_raw_oplock_exclusive6);
2803 torture_suite_add_2smb_test(suite, "BATCH1", test_raw_oplock_batch1);
2804 torture_suite_add_2smb_test(suite, "BATCH2", test_raw_oplock_batch2);
2805 torture_suite_add_2smb_test(suite, "BATCH3", test_raw_oplock_batch3);
2806 torture_suite_add_2smb_test(suite, "BATCH4", test_raw_oplock_batch4);
2807 torture_suite_add_2smb_test(suite, "BATCH5", test_raw_oplock_batch5);
2808 torture_suite_add_2smb_test(suite, "BATCH6", test_raw_oplock_batch6);
2809 torture_suite_add_2smb_test(suite, "BATCH7", test_raw_oplock_batch7);
2810 torture_suite_add_2smb_test(suite, "BATCH8", test_raw_oplock_batch8);
2811 torture_suite_add_2smb_test(suite, "BATCH9", test_raw_oplock_batch9);
2812 torture_suite_add_2smb_test(suite, "BATCH10", test_raw_oplock_batch10);
2813 torture_suite_add_2smb_test(suite, "BATCH11", test_raw_oplock_batch11);
2814 torture_suite_add_2smb_test(suite, "BATCH12", test_raw_oplock_batch12);
2815 torture_suite_add_2smb_test(suite, "BATCH13", test_raw_oplock_batch13);
2816 torture_suite_add_2smb_test(suite, "BATCH14", test_raw_oplock_batch14);
2817 torture_suite_add_2smb_test(suite, "BATCH15", test_raw_oplock_batch15);
2818 torture_suite_add_2smb_test(suite, "BATCH16", test_raw_oplock_batch16);
2819 torture_suite_add_2smb_test(suite, "BATCH17", test_raw_oplock_batch17);
2820 torture_suite_add_2smb_test(suite, "BATCH18", test_raw_oplock_batch18);
2821 torture_suite_add_2smb_test(suite, "BATCH19", test_raw_oplock_batch19);
2822 torture_suite_add_2smb_test(suite, "BATCH20", test_raw_oplock_batch20);
2823 torture_suite_add_2smb_test(suite, "BATCH21", test_raw_oplock_batch21);
2824 torture_suite_add_2smb_test(suite, "BATCH22", test_raw_oplock_batch22);
2825 torture_suite_add_2smb_test(suite, "BATCH23", test_raw_oplock_batch23);
2826 torture_suite_add_2smb_test(suite, "BATCH24", test_raw_oplock_batch24);
2832 stress testing of oplocks
2834 bool torture_bench_oplock(struct torture_context *torture)
2836 struct smbcli_state **cli;
2838 TALLOC_CTX *mem_ctx = talloc_new(torture);
2839 int torture_nprocs = torture_setting_int(torture, "nprocs", 4);
2841 int timelimit = torture_setting_int(torture, "timelimit", 10);
2845 cli = talloc_array(mem_ctx, struct smbcli_state *, torture_nprocs);
2847 torture_comment(torture, "Opening %d connections\n", torture_nprocs);
2848 for (i=0;i<torture_nprocs;i++) {
2849 if (!torture_open_connection_ev(&cli[i], i, torture, torture->ev)) {
2852 talloc_steal(mem_ctx, cli[i]);
2853 smbcli_oplock_handler(cli[i]->transport, oplock_handler_close,
2857 if (!torture_setup_dir(cli[0], BASEDIR)) {
2862 io.ntcreatex.level = RAW_OPEN_NTCREATEX;
2863 io.ntcreatex.in.root_fid = 0;
2864 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2865 io.ntcreatex.in.alloc_size = 0;
2866 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2867 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2868 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2869 io.ntcreatex.in.create_options = 0;
2870 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2871 io.ntcreatex.in.security_flags = 0;
2872 io.ntcreatex.in.fname = BASEDIR "\\test.dat";
2873 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2874 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2875 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2877 tv = timeval_current();
2880 we open the same file with SHARE_ACCESS_NONE from all the
2881 connections in a round robin fashion. Each open causes an
2882 oplock break on the previous connection, which is answered
2883 by the oplock_handler_close() to close the file.
2885 This measures how fast we can pass on oplocks, and stresses
2886 the oplock handling code
2888 torture_comment(torture, "Running for %d seconds\n", timelimit);
2889 while (timeval_elapsed(&tv) < timelimit) {
2890 for (i=0;i<torture_nprocs;i++) {
2893 status = smb_raw_open(cli[i]->tree, mem_ctx, &io);
2894 CHECK_STATUS(torture, status, NT_STATUS_OK);
2898 if (torture_setting_bool(torture, "progress", true)) {
2899 torture_comment(torture, "%.2f ops/second\r", count/timeval_elapsed(&tv));
2903 torture_comment(torture, "%.2f ops/second\n", count/timeval_elapsed(&tv));
2905 smb_raw_exit(cli[torture_nprocs-1]->session);
2908 smb_raw_exit(cli[0]->session);
2909 smbcli_deltree(cli[0]->tree, BASEDIR);
2910 talloc_free(mem_ctx);
2915 static struct hold_oplock_info {
2917 bool close_on_break;
2918 uint32_t share_access;
2921 { BASEDIR "\\notshared_close", true,
2922 NTCREATEX_SHARE_ACCESS_NONE, },
2923 { BASEDIR "\\notshared_noclose", false,
2924 NTCREATEX_SHARE_ACCESS_NONE, },
2925 { BASEDIR "\\shared_close", true,
2926 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE, },
2927 { BASEDIR "\\shared_noclose", false,
2928 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE, },
2931 static bool oplock_handler_hold(struct smbcli_transport *transport,
2932 uint16_t tid, uint16_t fnum, uint8_t level,
2935 struct smbcli_tree *tree = (struct smbcli_tree *)private;
2936 struct hold_oplock_info *info;
2939 for (i=0;i<ARRAY_SIZE(hold_info);i++) {
2940 if (hold_info[i].fnum == fnum) break;
2943 if (i == ARRAY_SIZE(hold_info)) {
2944 printf("oplock break for unknown fnum %u\n", fnum);
2948 info = &hold_info[i];
2950 if (info->close_on_break) {
2951 printf("oplock break on %s - closing\n",
2953 oplock_handler_close(transport, tid, fnum, level, private);
2957 printf("oplock break on %s - acking break\n", info->fname);
2959 return smbcli_oplock_ack(tree, fnum, OPLOCK_BREAK_TO_NONE);
2964 used for manual testing of oplocks - especially interaction with
2965 other filesystems (such as NFS and local access)
2967 bool torture_hold_oplock(struct torture_context *torture,
2968 struct smbcli_state *cli)
2970 struct event_context *ev =
2971 (struct event_context *)cli->transport->socket->event.ctx;
2974 printf("Setting up open files with oplocks in %s\n", BASEDIR);
2976 if (!torture_setup_dir(cli, BASEDIR)) {
2980 smbcli_oplock_handler(cli->transport, oplock_handler_hold, cli->tree);
2982 /* setup the files */
2983 for (i=0;i<ARRAY_SIZE(hold_info);i++) {
2988 io.generic.level = RAW_OPEN_NTCREATEX;
2989 io.ntcreatex.in.root_fid = 0;
2990 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2991 io.ntcreatex.in.alloc_size = 0;
2992 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2993 io.ntcreatex.in.share_access = hold_info[i].share_access;
2994 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2995 io.ntcreatex.in.create_options = 0;
2996 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2997 io.ntcreatex.in.security_flags = 0;
2998 io.ntcreatex.in.fname = hold_info[i].fname;
2999 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
3000 NTCREATEX_FLAGS_REQUEST_OPLOCK |
3001 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
3002 printf("opening %s\n", hold_info[i].fname);
3004 status = smb_raw_open(cli->tree, cli, &io);
3005 if (!NT_STATUS_IS_OK(status)) {
3006 printf("Failed to open %s - %s\n",
3007 hold_info[i].fname, nt_errstr(status));
3011 if (io.ntcreatex.out.oplock_level != BATCH_OPLOCK_RETURN) {
3012 printf("Oplock not granted for %s - expected %d but got %d\n",
3013 hold_info[i].fname, BATCH_OPLOCK_RETURN,
3014 io.ntcreatex.out.oplock_level);
3017 hold_info[i].fnum = io.ntcreatex.out.file.fnum;
3019 /* make the file non-zero size */
3020 if (smbcli_write(cli->tree, hold_info[i].fnum, 0, &c, 0, 1) != 1) {
3021 printf("Failed to write to file\n");
3026 printf("Waiting for oplock events\n");
3027 event_loop_wait(ev);