2 Unix SMB/CIFS implementation.
3 basic raw test suite for oplocks
4 Copyright (C) Andrew Tridgell 2003
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "torture/torture.h"
22 #include "librpc/gen_ndr/security.h"
23 #include "libcli/raw/libcliraw.h"
24 #include "libcli/libcli.h"
25 #include "torture/util.h"
26 #include "lib/events/events.h"
28 #define CHECK_VAL(v, correct) do { \
29 if ((v) != (correct)) { \
30 torture_result(tctx, TORTURE_FAIL, "(%s): wrong value for %s got 0x%x - should be 0x%x\n", \
31 __location__, #v, (int)v, (int)correct); \
35 #define CHECK_RANGE(v, min, max) do { \
36 if ((v) < (min) || (v) > (max)) { \
37 torture_result(tctx, TORTURE_FAIL, "(%s): wrong value for %s got %d - should be between %d and %d\n", \
38 __location__, #v, (int)v, (int)min, (int)max); \
42 #define CHECK_STRMATCH(v, correct) do { \
43 if (!v || strstr((v),(correct)) == NULL) { \
44 torture_result(tctx, TORTURE_FAIL, "(%s): wrong value for %s got '%s' - should be '%s'\n", \
45 __location__, #v, v?v:"NULL", correct); \
50 #define CHECK_STATUS(tctx, status, correct) do { \
51 if (!NT_STATUS_EQUAL(status, correct)) { \
52 torture_result(tctx, TORTURE_FAIL, __location__": Incorrect status %s - should be %s", \
53 nt_errstr(status), nt_errstr(correct)); \
66 #define BASEDIR "\\test_oplock"
69 a handler function for oplock break requests. Ack it as a break to level II if possible
71 static bool oplock_handler_ack_to_levelII(struct smbcli_transport *transport,
72 uint16_t tid, uint16_t fnum,
73 uint8_t level, void *private)
75 struct smbcli_tree *tree = (struct smbcli_tree *)private;
76 break_info.fnum = fnum;
77 break_info.level = level;
80 printf("Acking to level II in oplock handler\n");
82 return smbcli_oplock_ack(tree, fnum, level);
86 a handler function for oplock break requests. Ack it as a break to none
88 static bool oplock_handler_ack_to_none(struct smbcli_transport *transport,
89 uint16_t tid, uint16_t fnum,
90 uint8_t level, void *private)
92 struct smbcli_tree *tree = (struct smbcli_tree *)private;
93 break_info.fnum = fnum;
94 break_info.level = level;
97 printf("Acking to none in oplock handler\n");
99 return smbcli_oplock_ack(tree, fnum, OPLOCK_BREAK_TO_NONE);
103 a handler function for oplock break requests. Let it timeout
105 static bool oplock_handler_timeout(struct smbcli_transport *transport,
106 uint16_t tid, uint16_t fnum,
107 uint8_t level, void *private)
109 break_info.fnum = fnum;
110 break_info.level = level;
113 printf("Let oplock break timeout\n");
117 static void oplock_handler_close_recv(struct smbcli_request *req)
120 status = smbcli_request_simple_recv(req);
121 if (!NT_STATUS_IS_OK(status)) {
122 printf("close failed in oplock_handler_close\n");
123 break_info.failures++;
128 a handler function for oplock break requests - close the file
130 static bool oplock_handler_close(struct smbcli_transport *transport, uint16_t tid,
131 uint16_t fnum, uint8_t level, void *private)
134 struct smbcli_tree *tree = (struct smbcli_tree *)private;
135 struct smbcli_request *req;
137 break_info.fnum = fnum;
138 break_info.level = level;
141 io.close.level = RAW_CLOSE_CLOSE;
142 io.close.in.file.fnum = fnum;
143 io.close.in.write_time = 0;
144 req = smb_raw_close_send(tree, &io);
146 printf("failed to send close in oplock_handler_close\n");
150 req->async.fn = oplock_handler_close_recv;
151 req->async.private = NULL;
156 static bool test_raw_oplock_exclusive1(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
158 const char *fname = BASEDIR "\\test_exclusive1.dat";
162 union smb_unlink unl;
165 if (!torture_setup_dir(cli1, BASEDIR)) {
170 smbcli_unlink(cli1->tree, fname);
172 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
177 io.generic.level = RAW_OPEN_NTCREATEX;
178 io.ntcreatex.in.root_fid = 0;
179 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
180 io.ntcreatex.in.alloc_size = 0;
181 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
182 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
183 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
184 io.ntcreatex.in.create_options = 0;
185 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
186 io.ntcreatex.in.security_flags = 0;
187 io.ntcreatex.in.fname = fname;
189 torture_comment(tctx, "open a file with an exclusive oplock (share mode: none)\n");
190 ZERO_STRUCT(break_info);
191 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
193 status = smb_raw_open(cli1->tree, tctx, &io);
194 CHECK_STATUS(tctx, status, NT_STATUS_OK);
195 fnum = io.ntcreatex.out.file.fnum;
196 CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
198 torture_comment(tctx, "a 2nd open should not cause a break\n");
199 status = smb_raw_open(cli2->tree, tctx, &io);
200 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
201 CHECK_VAL(break_info.count, 0);
202 CHECK_VAL(break_info.failures, 0);
204 torture_comment(tctx, "unlink it - should also be no break\n");
205 unl.unlink.in.pattern = fname;
206 unl.unlink.in.attrib = 0;
207 status = smb_raw_unlink(cli2->tree, &unl);
208 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
209 CHECK_VAL(break_info.count, 0);
210 CHECK_VAL(break_info.failures, 0);
212 smbcli_close(cli1->tree, fnum);
215 smb_raw_exit(cli1->session);
216 smb_raw_exit(cli2->session);
217 smbcli_deltree(cli1->tree, BASEDIR);
221 static bool test_raw_oplock_exclusive2(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
223 const char *fname = BASEDIR "\\test_exclusive2.dat";
227 union smb_unlink unl;
228 uint16_t fnum=0, fnum2=0;
230 if (!torture_setup_dir(cli1, BASEDIR)) {
235 smbcli_unlink(cli1->tree, fname);
237 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
242 io.generic.level = RAW_OPEN_NTCREATEX;
243 io.ntcreatex.in.root_fid = 0;
244 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
245 io.ntcreatex.in.alloc_size = 0;
246 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
247 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
248 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
249 io.ntcreatex.in.create_options = 0;
250 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
251 io.ntcreatex.in.security_flags = 0;
252 io.ntcreatex.in.fname = fname;
254 torture_comment(tctx, "open a file with an exclusive oplock (share mode: all)\n");
255 ZERO_STRUCT(break_info);
256 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
257 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
258 NTCREATEX_SHARE_ACCESS_WRITE|
259 NTCREATEX_SHARE_ACCESS_DELETE;
261 status = smb_raw_open(cli1->tree, tctx, &io);
262 CHECK_STATUS(tctx, status, NT_STATUS_OK);
263 fnum = io.ntcreatex.out.file.fnum;
264 CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
266 torture_comment(tctx, "a 2nd open should cause a break to level 2\n");
267 status = smb_raw_open(cli2->tree, tctx, &io);
268 CHECK_STATUS(tctx, status, NT_STATUS_OK);
269 fnum2 = io.ntcreatex.out.file.fnum;
270 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
271 CHECK_VAL(break_info.count, 1);
272 CHECK_VAL(break_info.fnum, fnum);
273 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
274 CHECK_VAL(break_info.failures, 0);
275 ZERO_STRUCT(break_info);
277 /* now we have 2 level II oplocks... */
278 torture_comment(tctx, "try to unlink it - should not cause a break, but a sharing violation\n");
279 unl.unlink.in.pattern = fname;
280 unl.unlink.in.attrib = 0;
281 status = smb_raw_unlink(cli2->tree, &unl);
282 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
283 CHECK_VAL(break_info.count, 0);
284 CHECK_VAL(break_info.failures, 0);
286 torture_comment(tctx, "close 1st handle\n");
287 smbcli_close(cli1->tree, fnum);
289 torture_comment(tctx, "try to unlink it - should not cause a break, but a sharing violation\n");
290 unl.unlink.in.pattern = fname;
291 unl.unlink.in.attrib = 0;
292 status = smb_raw_unlink(cli2->tree, &unl);
293 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
294 CHECK_VAL(break_info.count, 0);
295 CHECK_VAL(break_info.failures, 0);
297 torture_comment(tctx, "close 1st handle\n");
298 smbcli_close(cli2->tree, fnum2);
300 torture_comment(tctx, "unlink it\n");
301 unl.unlink.in.pattern = fname;
302 unl.unlink.in.attrib = 0;
303 status = smb_raw_unlink(cli2->tree, &unl);
304 CHECK_STATUS(tctx, status, NT_STATUS_OK);
305 CHECK_VAL(break_info.count, 0);
306 CHECK_VAL(break_info.failures, 0);
309 smb_raw_exit(cli1->session);
310 smb_raw_exit(cli2->session);
311 smbcli_deltree(cli1->tree, BASEDIR);
315 static bool test_raw_oplock_exclusive3(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
317 const char *fname = BASEDIR "\\test_exclusive3.dat";
321 union smb_setfileinfo sfi;
323 bool s3 = torture_setting_bool(tctx, "samba3", false);
325 if (!torture_setup_dir(cli1, BASEDIR)) {
330 smbcli_unlink(cli1->tree, fname);
332 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
337 io.generic.level = RAW_OPEN_NTCREATEX;
338 io.ntcreatex.in.root_fid = 0;
339 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
340 io.ntcreatex.in.alloc_size = 0;
341 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
342 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
343 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
344 io.ntcreatex.in.create_options = 0;
345 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
346 io.ntcreatex.in.security_flags = 0;
347 io.ntcreatex.in.fname = fname;
349 torture_comment(tctx, "open a file with an exclusive oplock (share mode: %s)\n",
351 ZERO_STRUCT(break_info);
352 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
354 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
355 NTCREATEX_SHARE_ACCESS_WRITE|
356 NTCREATEX_SHARE_ACCESS_DELETE;
359 status = smb_raw_open(cli1->tree, tctx, &io);
360 CHECK_STATUS(tctx, status, NT_STATUS_OK);
361 fnum = io.ntcreatex.out.file.fnum;
362 CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
364 torture_comment(tctx, "setpathinfo EOF should trigger a break to none\n");
366 sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
367 sfi.generic.in.file.path = fname;
368 sfi.end_of_file_info.in.size = 100;
370 status = smb_raw_setpathinfo(cli2->tree, &sfi);
372 CHECK_STATUS(tctx, status, NT_STATUS_OK);
373 CHECK_VAL(break_info.count, 1);
374 CHECK_VAL(break_info.failures, 0);
375 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_NONE);
377 smbcli_close(cli1->tree, fnum);
380 smb_raw_exit(cli1->session);
381 smb_raw_exit(cli2->session);
382 smbcli_deltree(cli1->tree, BASEDIR);
386 static bool test_raw_oplock_exclusive4(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
388 const char *fname = BASEDIR "\\test_exclusive4.dat";
392 uint16_t fnum=0, fnum2=0;
394 if (!torture_setup_dir(cli1, BASEDIR)) {
399 smbcli_unlink(cli1->tree, fname);
401 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
406 io.generic.level = RAW_OPEN_NTCREATEX;
407 io.ntcreatex.in.root_fid = 0;
408 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
409 io.ntcreatex.in.alloc_size = 0;
410 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
411 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
412 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
413 io.ntcreatex.in.create_options = 0;
414 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
415 io.ntcreatex.in.security_flags = 0;
416 io.ntcreatex.in.fname = fname;
418 torture_comment(tctx, "open with exclusive oplock\n");
419 ZERO_STRUCT(break_info);
420 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
422 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
423 status = smb_raw_open(cli1->tree, tctx, &io);
424 CHECK_STATUS(tctx, status, NT_STATUS_OK);
425 fnum = io.ntcreatex.out.file.fnum;
426 CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
428 ZERO_STRUCT(break_info);
429 torture_comment(tctx, "second open with attributes only shouldn't cause oplock break\n");
431 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
432 io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
433 status = smb_raw_open(cli2->tree, tctx, &io);
434 CHECK_STATUS(tctx, status, NT_STATUS_OK);
435 fnum2 = io.ntcreatex.out.file.fnum;
436 CHECK_VAL(io.ntcreatex.out.oplock_level, NO_OPLOCK_RETURN);
437 CHECK_VAL(break_info.count, 0);
438 CHECK_VAL(break_info.failures, 0);
440 smbcli_close(cli1->tree, fnum);
441 smbcli_close(cli2->tree, fnum2);
444 smb_raw_exit(cli1->session);
445 smb_raw_exit(cli2->session);
446 smbcli_deltree(cli1->tree, BASEDIR);
450 static bool test_raw_oplock_exclusive5(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
452 const char *fname = BASEDIR "\\test_exclusive5.dat";
456 uint16_t fnum=0, fnum2=0;
458 if (!torture_setup_dir(cli1, BASEDIR)) {
463 smbcli_unlink(cli1->tree, fname);
465 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
466 smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_levelII, cli1->tree);
471 io.generic.level = RAW_OPEN_NTCREATEX;
472 io.ntcreatex.in.root_fid = 0;
473 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
474 io.ntcreatex.in.alloc_size = 0;
475 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
476 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
477 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
478 io.ntcreatex.in.create_options = 0;
479 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
480 io.ntcreatex.in.security_flags = 0;
481 io.ntcreatex.in.fname = fname;
483 torture_comment(tctx, "open with exclusive oplock\n");
484 ZERO_STRUCT(break_info);
485 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
488 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
489 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
490 NTCREATEX_SHARE_ACCESS_WRITE|
491 NTCREATEX_SHARE_ACCESS_DELETE;
492 status = smb_raw_open(cli1->tree, tctx, &io);
493 CHECK_STATUS(tctx, status, NT_STATUS_OK);
494 fnum = io.ntcreatex.out.file.fnum;
495 CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
497 ZERO_STRUCT(break_info);
499 torture_comment(tctx, "second open with attributes only and NTCREATEX_DISP_OVERWRITE_IF dispostion causes oplock break\n");
501 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
502 io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
503 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE_IF;
504 status = smb_raw_open(cli2->tree, tctx, &io);
505 CHECK_STATUS(tctx, status, NT_STATUS_OK);
506 fnum2 = io.ntcreatex.out.file.fnum;
507 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
508 CHECK_VAL(break_info.count, 1);
509 CHECK_VAL(break_info.failures, 0);
511 smbcli_close(cli1->tree, fnum);
512 smbcli_close(cli2->tree, fnum2);
515 smb_raw_exit(cli1->session);
516 smb_raw_exit(cli2->session);
517 smbcli_deltree(cli1->tree, BASEDIR);
521 static bool test_raw_oplock_exclusive6(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
523 const char *fname1 = BASEDIR "\\test_exclusive6_1.dat";
524 const char *fname2 = BASEDIR "\\test_exclusive6_2.dat";
530 bool s3 = torture_setting_bool(tctx, "samba3", false);
532 if (!torture_setup_dir(cli1, BASEDIR)) {
537 smbcli_unlink(cli1->tree, fname1);
538 smbcli_unlink(cli1->tree, fname2);
540 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
545 io.generic.level = RAW_OPEN_NTCREATEX;
546 io.ntcreatex.in.root_fid = 0;
547 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
548 io.ntcreatex.in.alloc_size = 0;
549 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
550 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
551 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
552 io.ntcreatex.in.create_options = 0;
553 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
554 io.ntcreatex.in.security_flags = 0;
555 io.ntcreatex.in.fname = fname1;
557 /* we should use no share mode, when samba3 passes this */
558 torture_comment(tctx, "open a file with an exclusive oplock (share mode: %s)\n",
560 ZERO_STRUCT(break_info);
561 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
563 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
564 NTCREATEX_SHARE_ACCESS_WRITE|
565 NTCREATEX_SHARE_ACCESS_DELETE;
568 status = smb_raw_open(cli1->tree, tctx, &io);
569 CHECK_STATUS(tctx, status, NT_STATUS_OK);
570 fnum = io.ntcreatex.out.file.fnum;
571 CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
573 torture_comment(tctx, "rename should not generate a break but get a sharing violation\n");
575 rn.generic.level = RAW_RENAME_RENAME;
576 rn.rename.in.pattern1 = fname1;
577 rn.rename.in.pattern2 = fname2;
578 rn.rename.in.attrib = 0;
580 printf("trying rename while first file open\n");
581 status = smb_raw_rename(cli2->tree, &rn);
583 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
584 CHECK_VAL(break_info.count, 0);
585 CHECK_VAL(break_info.failures, 0);
587 smbcli_close(cli1->tree, fnum);
590 smb_raw_exit(cli1->session);
591 smb_raw_exit(cli2->session);
592 smbcli_deltree(cli1->tree, BASEDIR);
596 static bool test_raw_oplock_batch1(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
598 const char *fname = BASEDIR "\\test_batch1.dat";
602 union smb_unlink unl;
606 if (!torture_setup_dir(cli1, BASEDIR)) {
611 smbcli_unlink(cli1->tree, fname);
613 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
618 io.generic.level = RAW_OPEN_NTCREATEX;
619 io.ntcreatex.in.root_fid = 0;
620 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
621 io.ntcreatex.in.alloc_size = 0;
622 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
623 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
624 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
625 io.ntcreatex.in.create_options = 0;
626 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
627 io.ntcreatex.in.security_flags = 0;
628 io.ntcreatex.in.fname = fname;
631 with a batch oplock we get a break
633 torture_comment(tctx, "open with batch oplock\n");
634 ZERO_STRUCT(break_info);
635 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
636 NTCREATEX_FLAGS_REQUEST_OPLOCK |
637 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
638 status = smb_raw_open(cli1->tree, tctx, &io);
639 CHECK_STATUS(tctx, status, NT_STATUS_OK);
640 fnum = io.ntcreatex.out.file.fnum;
641 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
643 torture_comment(tctx, "unlink should generate a break\n");
644 unl.unlink.in.pattern = fname;
645 unl.unlink.in.attrib = 0;
646 status = smb_raw_unlink(cli2->tree, &unl);
647 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
649 CHECK_VAL(break_info.count, 1);
650 CHECK_VAL(break_info.fnum, fnum);
651 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
652 CHECK_VAL(break_info.failures, 0);
654 torture_comment(tctx, "2nd unlink should not generate a break\n");
655 ZERO_STRUCT(break_info);
656 status = smb_raw_unlink(cli2->tree, &unl);
657 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
659 CHECK_VAL(break_info.count, 0);
661 torture_comment(tctx, "writing should generate a self break to none\n");
662 smbcli_write(cli1->tree, fnum, 0, &c, 0, 1);
664 smbcli_write(cli1->tree, fnum, 0, &c, 1, 1);
666 CHECK_VAL(break_info.count, 1);
667 CHECK_VAL(break_info.fnum, fnum);
668 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_NONE);
669 CHECK_VAL(break_info.failures, 0);
671 smbcli_close(cli1->tree, fnum);
674 smb_raw_exit(cli1->session);
675 smb_raw_exit(cli2->session);
676 smbcli_deltree(cli1->tree, BASEDIR);
680 static bool test_raw_oplock_batch2(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
682 const char *fname = BASEDIR "\\test_batch2.dat";
686 union smb_unlink unl;
690 if (!torture_setup_dir(cli1, BASEDIR)) {
695 smbcli_unlink(cli1->tree, fname);
697 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
702 io.generic.level = RAW_OPEN_NTCREATEX;
703 io.ntcreatex.in.root_fid = 0;
704 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
705 io.ntcreatex.in.alloc_size = 0;
706 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
707 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
708 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
709 io.ntcreatex.in.create_options = 0;
710 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
711 io.ntcreatex.in.security_flags = 0;
712 io.ntcreatex.in.fname = fname;
714 torture_comment(tctx, "open with batch oplock\n");
715 ZERO_STRUCT(break_info);
716 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
717 NTCREATEX_FLAGS_REQUEST_OPLOCK |
718 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
719 status = smb_raw_open(cli1->tree, tctx, &io);
720 CHECK_STATUS(tctx, status, NT_STATUS_OK);
721 fnum = io.ntcreatex.out.file.fnum;
722 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
724 torture_comment(tctx, "unlink should generate a break, which we ack as break to none\n");
725 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_none, cli1->tree);
726 unl.unlink.in.pattern = fname;
727 unl.unlink.in.attrib = 0;
728 status = smb_raw_unlink(cli2->tree, &unl);
729 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
731 CHECK_VAL(break_info.count, 1);
732 CHECK_VAL(break_info.fnum, fnum);
733 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
734 CHECK_VAL(break_info.failures, 0);
736 torture_comment(tctx, "2nd unlink should not generate a break\n");
737 ZERO_STRUCT(break_info);
738 status = smb_raw_unlink(cli2->tree, &unl);
739 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
741 CHECK_VAL(break_info.count, 0);
743 torture_comment(tctx, "writing should not generate a break\n");
744 smbcli_write(cli1->tree, fnum, 0, &c, 0, 1);
746 smbcli_write(cli1->tree, fnum, 0, &c, 1, 1);
748 CHECK_VAL(break_info.count, 0);
750 smbcli_close(cli1->tree, fnum);
753 smb_raw_exit(cli1->session);
754 smb_raw_exit(cli2->session);
755 smbcli_deltree(cli1->tree, BASEDIR);
759 static bool test_raw_oplock_batch3(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
761 const char *fname = BASEDIR "\\test_batch3.dat";
765 union smb_unlink unl;
768 if (!torture_setup_dir(cli1, BASEDIR)) {
773 smbcli_unlink(cli1->tree, fname);
775 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
780 io.generic.level = RAW_OPEN_NTCREATEX;
781 io.ntcreatex.in.root_fid = 0;
782 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
783 io.ntcreatex.in.alloc_size = 0;
784 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
785 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
786 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
787 io.ntcreatex.in.create_options = 0;
788 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
789 io.ntcreatex.in.security_flags = 0;
790 io.ntcreatex.in.fname = fname;
792 torture_comment(tctx, "if we close on break then the unlink can succeed\n");
793 ZERO_STRUCT(break_info);
794 smbcli_oplock_handler(cli1->transport, oplock_handler_close, cli1->tree);
795 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
796 NTCREATEX_FLAGS_REQUEST_OPLOCK |
797 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
798 status = smb_raw_open(cli1->tree, tctx, &io);
799 CHECK_STATUS(tctx, status, NT_STATUS_OK);
800 fnum = io.ntcreatex.out.file.fnum;
801 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
803 unl.unlink.in.pattern = fname;
804 unl.unlink.in.attrib = 0;
805 ZERO_STRUCT(break_info);
806 status = smb_raw_unlink(cli2->tree, &unl);
807 CHECK_STATUS(tctx, status, NT_STATUS_OK);
809 CHECK_VAL(break_info.count, 1);
810 CHECK_VAL(break_info.fnum, fnum);
811 CHECK_VAL(break_info.level, 1);
812 CHECK_VAL(break_info.failures, 0);
814 smbcli_close(cli1->tree, fnum);
817 smb_raw_exit(cli1->session);
818 smb_raw_exit(cli2->session);
819 smbcli_deltree(cli1->tree, BASEDIR);
823 static bool test_raw_oplock_batch4(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
825 const char *fname = BASEDIR "\\test_batch4.dat";
832 if (!torture_setup_dir(cli1, BASEDIR)) {
837 smbcli_unlink(cli1->tree, fname);
839 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
844 io.generic.level = RAW_OPEN_NTCREATEX;
845 io.ntcreatex.in.root_fid = 0;
846 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
847 io.ntcreatex.in.alloc_size = 0;
848 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
849 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
850 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
851 io.ntcreatex.in.create_options = 0;
852 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
853 io.ntcreatex.in.security_flags = 0;
854 io.ntcreatex.in.fname = fname;
856 torture_comment(tctx, "a self read should not cause a break\n");
857 ZERO_STRUCT(break_info);
858 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
860 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
861 NTCREATEX_FLAGS_REQUEST_OPLOCK |
862 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
863 status = smb_raw_open(cli1->tree, tctx, &io);
864 CHECK_STATUS(tctx, status, NT_STATUS_OK);
865 fnum = io.ntcreatex.out.file.fnum;
866 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
868 rd.read.level = RAW_READ_READ;
869 rd.read.in.file.fnum = fnum;
870 rd.read.in.count = 1;
871 rd.read.in.offset = 0;
872 rd.read.in.remaining = 0;
873 status = smb_raw_read(cli1->tree, &rd);
874 CHECK_STATUS(tctx, status, NT_STATUS_OK);
875 CHECK_VAL(break_info.count, 0);
876 CHECK_VAL(break_info.failures, 0);
878 smbcli_close(cli1->tree, fnum);
881 smb_raw_exit(cli1->session);
882 smb_raw_exit(cli2->session);
883 smbcli_deltree(cli1->tree, BASEDIR);
887 static bool test_raw_oplock_batch5(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
889 const char *fname = BASEDIR "\\test_batch5.dat";
895 if (!torture_setup_dir(cli1, BASEDIR)) {
900 smbcli_unlink(cli1->tree, fname);
902 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
907 io.generic.level = RAW_OPEN_NTCREATEX;
908 io.ntcreatex.in.root_fid = 0;
909 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
910 io.ntcreatex.in.alloc_size = 0;
911 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
912 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
913 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
914 io.ntcreatex.in.create_options = 0;
915 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
916 io.ntcreatex.in.security_flags = 0;
917 io.ntcreatex.in.fname = fname;
919 torture_comment(tctx, "a 2nd open should give a break\n");
920 ZERO_STRUCT(break_info);
921 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
923 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
924 NTCREATEX_FLAGS_REQUEST_OPLOCK |
925 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
926 status = smb_raw_open(cli1->tree, tctx, &io);
927 CHECK_STATUS(tctx, status, NT_STATUS_OK);
928 fnum = io.ntcreatex.out.file.fnum;
929 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
931 ZERO_STRUCT(break_info);
933 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
934 status = smb_raw_open(cli2->tree, tctx, &io);
935 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
937 CHECK_VAL(break_info.count, 1);
938 CHECK_VAL(break_info.fnum, fnum);
939 CHECK_VAL(break_info.level, 1);
940 CHECK_VAL(break_info.failures, 0);
942 smbcli_close(cli1->tree, fnum);
945 smb_raw_exit(cli1->session);
946 smb_raw_exit(cli2->session);
947 smbcli_deltree(cli1->tree, BASEDIR);
951 static bool test_raw_oplock_batch6(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
953 const char *fname = BASEDIR "\\test_batch6.dat";
957 uint16_t fnum=0, fnum2=0;
960 if (!torture_setup_dir(cli1, BASEDIR)) {
965 smbcli_unlink(cli1->tree, fname);
967 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
972 io.generic.level = RAW_OPEN_NTCREATEX;
973 io.ntcreatex.in.root_fid = 0;
974 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
975 io.ntcreatex.in.alloc_size = 0;
976 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
977 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
978 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
979 io.ntcreatex.in.create_options = 0;
980 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
981 io.ntcreatex.in.security_flags = 0;
982 io.ntcreatex.in.fname = fname;
984 torture_comment(tctx, "a 2nd open should give a break to level II if the first open allowed shared read\n");
985 ZERO_STRUCT(break_info);
986 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
987 smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_levelII, cli2->tree);
989 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_READ | SEC_RIGHTS_FILE_WRITE;
990 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
991 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
992 NTCREATEX_FLAGS_REQUEST_OPLOCK |
993 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
994 status = smb_raw_open(cli1->tree, tctx, &io);
995 CHECK_STATUS(tctx, status, NT_STATUS_OK);
996 fnum = io.ntcreatex.out.file.fnum;
997 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
999 ZERO_STRUCT(break_info);
1001 status = smb_raw_open(cli2->tree, tctx, &io);
1002 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1003 fnum2 = io.ntcreatex.out.file.fnum;
1004 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1006 CHECK_VAL(break_info.count, 1);
1007 CHECK_VAL(break_info.fnum, fnum);
1008 CHECK_VAL(break_info.level, 1);
1009 CHECK_VAL(break_info.failures, 0);
1010 ZERO_STRUCT(break_info);
1012 torture_comment(tctx, "write should trigger a break to none on both\n");
1013 smbcli_write(cli1->tree, fnum, 0, &c, 0, 1);
1015 smbcli_write(cli1->tree, fnum, 0, &c, 1, 1);
1017 CHECK_VAL(break_info.count, 2);
1018 CHECK_VAL(break_info.level, 0);
1019 CHECK_VAL(break_info.failures, 0);
1021 smbcli_close(cli1->tree, fnum);
1022 smbcli_close(cli2->tree, fnum2);
1026 smb_raw_exit(cli1->session);
1027 smb_raw_exit(cli2->session);
1028 smbcli_deltree(cli1->tree, BASEDIR);
1032 static bool test_raw_oplock_batch7(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1034 const char *fname = BASEDIR "\\test_batch7.dat";
1038 uint16_t fnum=0, fnum2=0;
1040 if (!torture_setup_dir(cli1, BASEDIR)) {
1045 smbcli_unlink(cli1->tree, fname);
1047 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1050 base ntcreatex parms
1052 io.generic.level = RAW_OPEN_NTCREATEX;
1053 io.ntcreatex.in.root_fid = 0;
1054 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1055 io.ntcreatex.in.alloc_size = 0;
1056 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1057 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1058 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1059 io.ntcreatex.in.create_options = 0;
1060 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1061 io.ntcreatex.in.security_flags = 0;
1062 io.ntcreatex.in.fname = fname;
1064 torture_comment(tctx, "a 2nd open should get an oplock when we close instead of ack\n");
1065 ZERO_STRUCT(break_info);
1066 smbcli_oplock_handler(cli1->transport, oplock_handler_close, cli1->tree);
1068 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1069 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1070 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1071 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1072 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1073 status = smb_raw_open(cli1->tree, tctx, &io);
1074 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1075 fnum2 = io.ntcreatex.out.file.fnum;
1076 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1078 ZERO_STRUCT(break_info);
1080 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1081 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1082 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1083 status = smb_raw_open(cli2->tree, tctx, &io);
1084 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1085 fnum = io.ntcreatex.out.file.fnum;
1086 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1088 CHECK_VAL(break_info.count, 1);
1089 CHECK_VAL(break_info.fnum, fnum2);
1090 CHECK_VAL(break_info.level, 1);
1091 CHECK_VAL(break_info.failures, 0);
1093 smbcli_close(cli2->tree, fnum);
1096 smb_raw_exit(cli1->session);
1097 smb_raw_exit(cli2->session);
1098 smbcli_deltree(cli1->tree, BASEDIR);
1102 static bool test_raw_oplock_batch8(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1104 const char *fname = BASEDIR "\\test_batch8.dat";
1108 uint16_t fnum=0, fnum2=0;
1110 if (!torture_setup_dir(cli1, BASEDIR)) {
1115 smbcli_unlink(cli1->tree, fname);
1117 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1120 base ntcreatex parms
1122 io.generic.level = RAW_OPEN_NTCREATEX;
1123 io.ntcreatex.in.root_fid = 0;
1124 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1125 io.ntcreatex.in.alloc_size = 0;
1126 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1127 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1128 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1129 io.ntcreatex.in.create_options = 0;
1130 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1131 io.ntcreatex.in.security_flags = 0;
1132 io.ntcreatex.in.fname = fname;
1134 torture_comment(tctx, "open with batch oplock\n");
1135 ZERO_STRUCT(break_info);
1136 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1138 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1139 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1140 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1141 status = smb_raw_open(cli1->tree, tctx, &io);
1142 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1143 fnum = io.ntcreatex.out.file.fnum;
1144 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1146 ZERO_STRUCT(break_info);
1147 torture_comment(tctx, "second open with attributes only shouldn't cause oplock break\n");
1149 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1150 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1151 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1152 io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
1153 status = smb_raw_open(cli2->tree, tctx, &io);
1154 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1155 fnum2 = io.ntcreatex.out.file.fnum;
1156 CHECK_VAL(io.ntcreatex.out.oplock_level, NO_OPLOCK_RETURN);
1157 CHECK_VAL(break_info.count, 0);
1158 CHECK_VAL(break_info.failures, 0);
1160 smbcli_close(cli1->tree, fnum);
1161 smbcli_close(cli2->tree, fnum2);
1164 smb_raw_exit(cli1->session);
1165 smb_raw_exit(cli2->session);
1166 smbcli_deltree(cli1->tree, BASEDIR);
1170 static bool test_raw_oplock_batch9(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1172 const char *fname = BASEDIR "\\test_batch9.dat";
1176 uint16_t fnum=0, fnum2=0;
1179 if (!torture_setup_dir(cli1, BASEDIR)) {
1184 smbcli_unlink(cli1->tree, fname);
1186 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1189 base ntcreatex parms
1191 io.generic.level = RAW_OPEN_NTCREATEX;
1192 io.ntcreatex.in.root_fid = 0;
1193 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1194 io.ntcreatex.in.alloc_size = 0;
1195 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1196 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1197 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1198 io.ntcreatex.in.create_options = 0;
1199 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1200 io.ntcreatex.in.security_flags = 0;
1201 io.ntcreatex.in.fname = fname;
1203 torture_comment(tctx, "open with attributes only can create file\n");
1205 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1206 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1207 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1208 io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
1209 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1210 status = smb_raw_open(cli1->tree, tctx, &io);
1211 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1212 fnum = io.ntcreatex.out.file.fnum;
1213 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1215 torture_comment(tctx, "Subsequent normal open should break oplock on attribute only open to level II\n");
1217 ZERO_STRUCT(break_info);
1218 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1220 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1221 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1222 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1223 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1224 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1225 status = smb_raw_open(cli2->tree, tctx, &io);
1226 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1227 fnum2 = io.ntcreatex.out.file.fnum;
1228 CHECK_VAL(break_info.count, 1);
1229 CHECK_VAL(break_info.fnum, fnum);
1230 CHECK_VAL(break_info.failures, 0);
1231 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
1232 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1233 smbcli_close(cli2->tree, fnum2);
1235 torture_comment(tctx, "third oplocked open should grant level2 without break\n");
1236 ZERO_STRUCT(break_info);
1237 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1238 smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_levelII, cli2->tree);
1239 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1240 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1241 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1242 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1243 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1244 status = smb_raw_open(cli2->tree, tctx, &io);
1245 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1246 fnum2 = io.ntcreatex.out.file.fnum;
1247 CHECK_VAL(break_info.count, 0);
1248 CHECK_VAL(break_info.failures, 0);
1249 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1251 ZERO_STRUCT(break_info);
1253 torture_comment(tctx, "write should trigger a break to none on both\n");
1254 smbcli_write(cli2->tree, fnum2, 0, &c, 0, 1);
1256 /* Now the oplock break request comes in. But right now we can't
1257 * answer it. Do another write */
1260 smbcli_write(cli2->tree, fnum2, 0, &c, 1, 1);
1262 CHECK_VAL(break_info.count, 2);
1263 CHECK_VAL(break_info.level, 0);
1264 CHECK_VAL(break_info.failures, 0);
1266 smbcli_close(cli1->tree, fnum);
1267 smbcli_close(cli2->tree, fnum2);
1270 smb_raw_exit(cli1->session);
1271 smb_raw_exit(cli2->session);
1272 smbcli_deltree(cli1->tree, BASEDIR);
1276 static bool test_raw_oplock_batch10(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1278 const char *fname = BASEDIR "\\test_batch10.dat";
1282 uint16_t fnum=0, fnum2=0;
1284 if (!torture_setup_dir(cli1, BASEDIR)) {
1289 smbcli_unlink(cli1->tree, fname);
1291 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1294 base ntcreatex parms
1296 io.generic.level = RAW_OPEN_NTCREATEX;
1297 io.ntcreatex.in.root_fid = 0;
1298 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1299 io.ntcreatex.in.alloc_size = 0;
1300 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1301 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1302 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1303 io.ntcreatex.in.create_options = 0;
1304 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1305 io.ntcreatex.in.security_flags = 0;
1306 io.ntcreatex.in.fname = fname;
1308 torture_comment(tctx, "Open with oplock after a non-oplock open should grant level2\n");
1309 ZERO_STRUCT(break_info);
1310 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
1311 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1312 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1313 NTCREATEX_SHARE_ACCESS_WRITE|
1314 NTCREATEX_SHARE_ACCESS_DELETE;
1315 status = smb_raw_open(cli1->tree, tctx, &io);
1316 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1317 fnum = io.ntcreatex.out.file.fnum;
1318 CHECK_VAL(break_info.count, 0);
1319 CHECK_VAL(break_info.failures, 0);
1320 CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
1322 smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_levelII, cli2->tree);
1324 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1325 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1326 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1327 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1328 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1329 NTCREATEX_SHARE_ACCESS_WRITE|
1330 NTCREATEX_SHARE_ACCESS_DELETE;
1331 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1332 status = smb_raw_open(cli2->tree, tctx, &io);
1333 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1334 fnum2 = io.ntcreatex.out.file.fnum;
1335 CHECK_VAL(break_info.count, 0);
1336 CHECK_VAL(break_info.failures, 0);
1337 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1339 torture_comment(tctx, "write should trigger a break to none\n");
1342 wr.write.level = RAW_WRITE_WRITE;
1343 wr.write.in.file.fnum = fnum;
1344 wr.write.in.count = 1;
1345 wr.write.in.offset = 0;
1346 wr.write.in.remaining = 0;
1347 wr.write.in.data = (const uint8_t *)"x";
1348 status = smb_raw_write(cli1->tree, &wr);
1349 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1352 /* Now the oplock break request comes in. But right now we can't
1353 * answer it. Do another write */
1359 wr.write.level = RAW_WRITE_WRITE;
1360 wr.write.in.file.fnum = fnum;
1361 wr.write.in.count = 1;
1362 wr.write.in.offset = 0;
1363 wr.write.in.remaining = 0;
1364 wr.write.in.data = (const uint8_t *)"x";
1365 status = smb_raw_write(cli1->tree, &wr);
1366 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1369 CHECK_VAL(break_info.count, 1);
1370 CHECK_VAL(break_info.fnum, fnum2);
1371 CHECK_VAL(break_info.level, 0);
1372 CHECK_VAL(break_info.failures, 0);
1374 smbcli_close(cli1->tree, fnum);
1375 smbcli_close(cli2->tree, fnum2);
1378 smb_raw_exit(cli1->session);
1379 smb_raw_exit(cli2->session);
1380 smbcli_deltree(cli1->tree, BASEDIR);
1384 static bool test_raw_oplock_batch11(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1386 const char *fname = BASEDIR "\\test_batch11.dat";
1390 union smb_setfileinfo sfi;
1393 if (!torture_setup_dir(cli1, BASEDIR)) {
1398 smbcli_unlink(cli1->tree, fname);
1400 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1403 base ntcreatex parms
1405 io.generic.level = RAW_OPEN_NTCREATEX;
1406 io.ntcreatex.in.root_fid = 0;
1407 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1408 io.ntcreatex.in.alloc_size = 0;
1409 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1410 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1411 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1412 io.ntcreatex.in.create_options = 0;
1413 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1414 io.ntcreatex.in.security_flags = 0;
1415 io.ntcreatex.in.fname = fname;
1417 /* Test if a set-eof on pathname breaks an exclusive oplock. */
1418 torture_comment(tctx, "Test if setpathinfo set EOF breaks oplocks.\n");
1420 ZERO_STRUCT(break_info);
1421 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1423 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1424 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1425 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1426 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1427 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1428 NTCREATEX_SHARE_ACCESS_WRITE|
1429 NTCREATEX_SHARE_ACCESS_DELETE;
1430 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1431 status = smb_raw_open(cli1->tree, tctx, &io);
1432 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1433 fnum = io.ntcreatex.out.file.fnum;
1434 CHECK_VAL(break_info.count, 0);
1435 CHECK_VAL(break_info.failures, 0);
1436 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1439 sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
1440 sfi.generic.in.file.path = fname;
1441 sfi.end_of_file_info.in.size = 100;
1443 status = smb_raw_setpathinfo(cli2->tree, &sfi);
1445 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1446 CHECK_VAL(break_info.count, 1);
1447 CHECK_VAL(break_info.failures, 0);
1448 CHECK_VAL(break_info.level, 0);
1450 smbcli_close(cli1->tree, fnum);
1453 smb_raw_exit(cli1->session);
1454 smb_raw_exit(cli2->session);
1455 smbcli_deltree(cli1->tree, BASEDIR);
1459 static bool test_raw_oplock_batch12(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1461 const char *fname = BASEDIR "\\test_batch12.dat";
1465 union smb_setfileinfo sfi;
1468 if (!torture_setup_dir(cli1, BASEDIR)) {
1473 smbcli_unlink(cli1->tree, fname);
1475 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1478 base ntcreatex parms
1480 io.generic.level = RAW_OPEN_NTCREATEX;
1481 io.ntcreatex.in.root_fid = 0;
1482 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1483 io.ntcreatex.in.alloc_size = 0;
1484 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1485 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1486 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1487 io.ntcreatex.in.create_options = 0;
1488 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1489 io.ntcreatex.in.security_flags = 0;
1490 io.ntcreatex.in.fname = fname;
1492 /* Test if a set-allocation size on pathname breaks an exclusive oplock. */
1493 torture_comment(tctx, "Test if setpathinfo allocation size breaks oplocks.\n");
1495 ZERO_STRUCT(break_info);
1496 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1498 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1499 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1500 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1501 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1502 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1503 NTCREATEX_SHARE_ACCESS_WRITE|
1504 NTCREATEX_SHARE_ACCESS_DELETE;
1505 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1506 status = smb_raw_open(cli1->tree, tctx, &io);
1507 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1508 fnum = io.ntcreatex.out.file.fnum;
1509 CHECK_VAL(break_info.count, 0);
1510 CHECK_VAL(break_info.failures, 0);
1511 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1514 sfi.generic.level = SMB_SFILEINFO_ALLOCATION_INFORMATION;
1515 sfi.generic.in.file.path = fname;
1516 sfi.allocation_info.in.alloc_size = 65536 * 8;
1518 status = smb_raw_setpathinfo(cli2->tree, &sfi);
1520 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1521 CHECK_VAL(break_info.count, 1);
1522 CHECK_VAL(break_info.failures, 0);
1523 CHECK_VAL(break_info.level, 0);
1525 smbcli_close(cli1->tree, fnum);
1528 smb_raw_exit(cli1->session);
1529 smb_raw_exit(cli2->session);
1530 smbcli_deltree(cli1->tree, BASEDIR);
1534 static bool test_raw_oplock_batch13(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1536 const char *fname = BASEDIR "\\test_batch13.dat";
1540 uint16_t fnum=0, fnum2=0;
1542 if (!torture_setup_dir(cli1, BASEDIR)) {
1547 smbcli_unlink(cli1->tree, fname);
1549 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1550 smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_levelII, cli1->tree);
1553 base ntcreatex parms
1555 io.generic.level = RAW_OPEN_NTCREATEX;
1556 io.ntcreatex.in.root_fid = 0;
1557 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1558 io.ntcreatex.in.alloc_size = 0;
1559 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1560 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1561 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1562 io.ntcreatex.in.create_options = 0;
1563 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1564 io.ntcreatex.in.security_flags = 0;
1565 io.ntcreatex.in.fname = fname;
1567 torture_comment(tctx, "open with batch oplock\n");
1568 ZERO_STRUCT(break_info);
1569 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1572 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1573 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1574 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1575 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1576 NTCREATEX_SHARE_ACCESS_WRITE|
1577 NTCREATEX_SHARE_ACCESS_DELETE;
1578 status = smb_raw_open(cli1->tree, tctx, &io);
1579 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1580 fnum = io.ntcreatex.out.file.fnum;
1581 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1583 ZERO_STRUCT(break_info);
1585 torture_comment(tctx, "second open with attributes only and NTCREATEX_DISP_OVERWRITE dispostion causes oplock break\n");
1587 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1588 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1589 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1590 io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
1591 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1592 NTCREATEX_SHARE_ACCESS_WRITE|
1593 NTCREATEX_SHARE_ACCESS_DELETE;
1594 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE;
1595 status = smb_raw_open(cli2->tree, tctx, &io);
1596 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1597 fnum2 = io.ntcreatex.out.file.fnum;
1598 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1599 CHECK_VAL(break_info.count, 1);
1600 CHECK_VAL(break_info.failures, 0);
1602 smbcli_close(cli1->tree, fnum);
1603 smbcli_close(cli2->tree, fnum2);
1606 smb_raw_exit(cli1->session);
1607 smb_raw_exit(cli2->session);
1608 smbcli_deltree(cli1->tree, BASEDIR);
1612 static bool test_raw_oplock_batch14(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1614 const char *fname = BASEDIR "\\test_batch14.dat";
1618 uint16_t fnum=0, fnum2=0;
1620 if (!torture_setup_dir(cli1, BASEDIR)) {
1625 smbcli_unlink(cli1->tree, fname);
1627 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1630 base ntcreatex parms
1632 io.generic.level = RAW_OPEN_NTCREATEX;
1633 io.ntcreatex.in.root_fid = 0;
1634 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1635 io.ntcreatex.in.alloc_size = 0;
1636 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1637 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1638 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1639 io.ntcreatex.in.create_options = 0;
1640 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1641 io.ntcreatex.in.security_flags = 0;
1642 io.ntcreatex.in.fname = fname;
1644 torture_comment(tctx, "open with batch oplock\n");
1645 ZERO_STRUCT(break_info);
1646 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1648 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1649 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1650 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1651 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1652 NTCREATEX_SHARE_ACCESS_WRITE|
1653 NTCREATEX_SHARE_ACCESS_DELETE;
1654 status = smb_raw_open(cli1->tree, tctx, &io);
1655 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1656 fnum = io.ntcreatex.out.file.fnum;
1657 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1659 ZERO_STRUCT(break_info);
1661 torture_comment(tctx, "second open with attributes only and NTCREATEX_DISP_SUPERSEDE dispostion causes oplock break\n");
1663 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1664 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1665 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1666 io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
1667 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1668 NTCREATEX_SHARE_ACCESS_WRITE|
1669 NTCREATEX_SHARE_ACCESS_DELETE;
1670 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE;
1671 status = smb_raw_open(cli2->tree, tctx, &io);
1672 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1673 fnum2 = io.ntcreatex.out.file.fnum;
1674 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1675 CHECK_VAL(break_info.count, 1);
1676 CHECK_VAL(break_info.failures, 0);
1678 smbcli_close(cli1->tree, fnum);
1679 smbcli_close(cli2->tree, fnum2);
1681 smb_raw_exit(cli1->session);
1682 smb_raw_exit(cli2->session);
1683 smbcli_deltree(cli1->tree, BASEDIR);
1687 static bool test_raw_oplock_batch15(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1689 const char *fname = BASEDIR "\\test_batch15.dat";
1693 union smb_fileinfo qfi;
1696 if (!torture_setup_dir(cli1, BASEDIR)) {
1701 smbcli_unlink(cli1->tree, fname);
1703 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1706 base ntcreatex parms
1708 io.generic.level = RAW_OPEN_NTCREATEX;
1709 io.ntcreatex.in.root_fid = 0;
1710 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1711 io.ntcreatex.in.alloc_size = 0;
1712 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1713 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1714 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1715 io.ntcreatex.in.create_options = 0;
1716 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1717 io.ntcreatex.in.security_flags = 0;
1718 io.ntcreatex.in.fname = fname;
1720 /* Test if a qpathinfo all info on pathname breaks a batch oplock. */
1721 torture_comment(tctx, "Test if qpathinfo all info breaks a batch oplock (should not).\n");
1723 ZERO_STRUCT(break_info);
1724 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1726 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1727 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1728 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1729 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1730 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1731 NTCREATEX_SHARE_ACCESS_WRITE|
1732 NTCREATEX_SHARE_ACCESS_DELETE;
1733 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1734 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1735 status = smb_raw_open(cli1->tree, tctx, &io);
1736 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1737 fnum = io.ntcreatex.out.file.fnum;
1738 CHECK_VAL(break_info.count, 0);
1739 CHECK_VAL(break_info.failures, 0);
1740 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1743 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
1744 qfi.generic.in.file.path = fname;
1746 status = smb_raw_pathinfo(cli2->tree, tctx, &qfi);
1748 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1749 CHECK_VAL(break_info.count, 0);
1751 smbcli_close(cli1->tree, fnum);
1754 smb_raw_exit(cli1->session);
1755 smb_raw_exit(cli2->session);
1756 smbcli_deltree(cli1->tree, BASEDIR);
1760 static bool test_raw_oplock_batch16(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1762 const char *fname = BASEDIR "\\test_batch16.dat";
1766 uint16_t fnum=0, fnum2=0;
1768 if (!torture_setup_dir(cli1, BASEDIR)) {
1773 smbcli_unlink(cli1->tree, fname);
1775 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1776 smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_levelII, cli1->tree);
1779 base ntcreatex parms
1781 io.generic.level = RAW_OPEN_NTCREATEX;
1782 io.ntcreatex.in.root_fid = 0;
1783 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1784 io.ntcreatex.in.alloc_size = 0;
1785 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1786 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1787 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1788 io.ntcreatex.in.create_options = 0;
1789 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1790 io.ntcreatex.in.security_flags = 0;
1791 io.ntcreatex.in.fname = fname;
1793 torture_comment(tctx, "open with batch oplock\n");
1794 ZERO_STRUCT(break_info);
1795 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1798 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1799 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1800 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1801 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1802 NTCREATEX_SHARE_ACCESS_WRITE|
1803 NTCREATEX_SHARE_ACCESS_DELETE;
1804 status = smb_raw_open(cli1->tree, tctx, &io);
1805 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1806 fnum = io.ntcreatex.out.file.fnum;
1807 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1809 ZERO_STRUCT(break_info);
1811 torture_comment(tctx, "second open with attributes only and NTCREATEX_DISP_OVERWRITE_IF dispostion causes oplock break\n");
1813 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1814 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1815 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1816 io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
1817 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1818 NTCREATEX_SHARE_ACCESS_WRITE|
1819 NTCREATEX_SHARE_ACCESS_DELETE;
1820 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE_IF;
1821 status = smb_raw_open(cli2->tree, tctx, &io);
1822 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1823 fnum2 = io.ntcreatex.out.file.fnum;
1824 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1825 CHECK_VAL(break_info.count, 1);
1826 CHECK_VAL(break_info.failures, 0);
1828 smbcli_close(cli1->tree, fnum);
1829 smbcli_close(cli2->tree, fnum2);
1832 smb_raw_exit(cli1->session);
1833 smb_raw_exit(cli2->session);
1834 smbcli_deltree(cli1->tree, BASEDIR);
1838 static bool test_raw_oplock_batch17(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1840 const char *fname1 = BASEDIR "\\test_batch17_1.dat";
1841 const char *fname2 = BASEDIR "\\test_batch17_2.dat";
1845 union smb_rename rn;
1847 bool s3 = torture_setting_bool(tctx, "samba3", false);
1849 if (!torture_setup_dir(cli1, BASEDIR)) {
1854 smbcli_unlink(cli1->tree, fname1);
1855 smbcli_unlink(cli1->tree, fname2);
1857 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1860 base ntcreatex parms
1862 io.generic.level = RAW_OPEN_NTCREATEX;
1863 io.ntcreatex.in.root_fid = 0;
1864 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1865 io.ntcreatex.in.alloc_size = 0;
1866 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1867 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1868 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1869 io.ntcreatex.in.create_options = 0;
1870 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1871 io.ntcreatex.in.security_flags = 0;
1872 io.ntcreatex.in.fname = fname1;
1874 /* we should use no share mode, when samba3 passes this */
1875 torture_comment(tctx, "open a file with an batch oplock (share mode: %s)\n",
1877 ZERO_STRUCT(break_info);
1878 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1879 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1880 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1882 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1883 NTCREATEX_SHARE_ACCESS_WRITE|
1884 NTCREATEX_SHARE_ACCESS_DELETE;
1887 status = smb_raw_open(cli1->tree, tctx, &io);
1888 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1889 fnum = io.ntcreatex.out.file.fnum;
1890 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1892 torture_comment(tctx, "rename should trigger a break\n");
1894 rn.generic.level = RAW_RENAME_RENAME;
1895 rn.rename.in.pattern1 = fname1;
1896 rn.rename.in.pattern2 = fname2;
1897 rn.rename.in.attrib = 0;
1899 printf("trying rename while first file open\n");
1900 status = smb_raw_rename(cli2->tree, &rn);
1902 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
1903 CHECK_VAL(break_info.count, 1);
1904 CHECK_VAL(break_info.failures, 0);
1905 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
1907 smbcli_close(cli1->tree, fnum);
1910 smb_raw_exit(cli1->session);
1911 smb_raw_exit(cli2->session);
1912 smbcli_deltree(cli1->tree, BASEDIR);
1916 static bool test_raw_oplock_batch18(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1918 const char *fname1 = BASEDIR "\\test_batch18_1.dat";
1919 const char *fname2 = BASEDIR "\\test_batch18_2.dat";
1923 union smb_rename rn;
1925 bool s3 = torture_setting_bool(tctx, "samba3", false);
1927 if (!torture_setup_dir(cli1, BASEDIR)) {
1932 smbcli_unlink(cli1->tree, fname1);
1933 smbcli_unlink(cli1->tree, fname2);
1935 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1938 base ntcreatex parms
1940 io.generic.level = RAW_OPEN_NTCREATEX;
1941 io.ntcreatex.in.root_fid = 0;
1942 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1943 io.ntcreatex.in.alloc_size = 0;
1944 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1945 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1946 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1947 io.ntcreatex.in.create_options = 0;
1948 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1949 io.ntcreatex.in.security_flags = 0;
1950 io.ntcreatex.in.fname = fname1;
1952 /* we should use no share mode, when samba3 passes this */
1953 torture_comment(tctx, "open a file with an batch oplock (share mode: %s)\n",
1955 ZERO_STRUCT(break_info);
1956 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1957 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1958 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1960 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1961 NTCREATEX_SHARE_ACCESS_WRITE|
1962 NTCREATEX_SHARE_ACCESS_DELETE;
1965 status = smb_raw_open(cli1->tree, tctx, &io);
1966 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1967 fnum = io.ntcreatex.out.file.fnum;
1968 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1970 torture_comment(tctx, "ntrename should trigger a break\n");
1972 rn.generic.level = RAW_RENAME_NTRENAME;
1973 rn.ntrename.in.attrib = 0;
1974 rn.ntrename.in.flags = RENAME_FLAG_RENAME;
1975 rn.ntrename.in.old_name = fname1;
1976 rn.ntrename.in.new_name = fname2;
1977 printf("trying rename while first file open\n");
1978 status = smb_raw_rename(cli2->tree, &rn);
1980 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
1981 CHECK_VAL(break_info.count, 1);
1982 CHECK_VAL(break_info.failures, 0);
1983 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
1985 smbcli_close(cli1->tree, fnum);
1988 smb_raw_exit(cli1->session);
1989 smb_raw_exit(cli2->session);
1990 smbcli_deltree(cli1->tree, BASEDIR);
1994 static bool test_raw_oplock_batch19(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1996 const char *fname1 = BASEDIR "\\test_batch19_1.dat";
1997 const char *fname2 = BASEDIR "\\test_batch19_2.dat";
1998 const char *fname3 = BASEDIR "\\test_batch19_3.dat";
2002 union smb_fileinfo qfi;
2003 union smb_setfileinfo sfi;
2006 if (torture_setting_bool(tctx, "samba3", false)) {
2007 torture_skip(tctx, "BACHT19 disabled against samba3\n");
2010 if (!torture_setup_dir(cli1, BASEDIR)) {
2015 smbcli_unlink(cli1->tree, fname1);
2016 smbcli_unlink(cli1->tree, fname2);
2017 smbcli_unlink(cli1->tree, fname3);
2019 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
2022 base ntcreatex parms
2024 io.generic.level = RAW_OPEN_NTCREATEX;
2025 io.ntcreatex.in.root_fid = 0;
2026 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2027 io.ntcreatex.in.alloc_size = 0;
2028 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2029 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2030 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2031 io.ntcreatex.in.create_options = 0;
2032 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2033 io.ntcreatex.in.security_flags = 0;
2034 io.ntcreatex.in.fname = fname1;
2036 torture_comment(tctx, "open a file with an batch oplock (share mode: none)\n");
2037 ZERO_STRUCT(break_info);
2038 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2039 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2040 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2041 status = smb_raw_open(cli1->tree, tctx, &io);
2042 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2043 fnum = io.ntcreatex.out.file.fnum;
2044 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
2046 torture_comment(tctx, "setpathinfo rename info should not trigger a break nor a violation\n");
2048 sfi.generic.level = RAW_SFILEINFO_RENAME_INFORMATION;
2049 sfi.generic.in.file.path = fname1;
2050 sfi.rename_information.in.overwrite = 0;
2051 sfi.rename_information.in.root_fid = 0;
2052 sfi.rename_information.in.new_name = fname2+strlen(BASEDIR)+1;
2054 status = smb_raw_setpathinfo(cli2->tree, &sfi);
2056 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2057 CHECK_VAL(break_info.count, 0);
2060 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2061 qfi.generic.in.file.fnum = fnum;
2063 status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
2064 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2065 CHECK_STRMATCH(qfi.all_info.out.fname.s, fname2);
2067 torture_comment(tctx, "setfileinfo rename info should not trigger a break nor a violation\n");
2069 sfi.generic.level = RAW_SFILEINFO_RENAME_INFORMATION;
2070 sfi.generic.in.file.fnum = fnum;
2071 sfi.rename_information.in.overwrite = 0;
2072 sfi.rename_information.in.root_fid = 0;
2073 sfi.rename_information.in.new_name = fname3+strlen(BASEDIR)+1;
2075 status = smb_raw_setfileinfo(cli1->tree, &sfi);
2076 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2077 CHECK_VAL(break_info.count, 0);
2080 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2081 qfi.generic.in.file.fnum = fnum;
2083 status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
2084 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2085 CHECK_STRMATCH(qfi.all_info.out.fname.s, fname3);
2087 smbcli_close(cli1->tree, fnum);
2090 smb_raw_exit(cli1->session);
2091 smb_raw_exit(cli2->session);
2092 smbcli_deltree(cli1->tree, BASEDIR);
2096 static bool test_raw_oplock_batch20(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
2098 const char *fname1 = BASEDIR "\\test_batch20_1.dat";
2099 const char *fname2 = BASEDIR "\\test_batch20_2.dat";
2100 const char *fname3 = BASEDIR "\\test_batch20_3.dat";
2104 union smb_fileinfo qfi;
2105 union smb_setfileinfo sfi;
2106 uint16_t fnum=0,fnum2=0;
2108 if (torture_setting_bool(tctx, "samba3", false)) {
2109 torture_skip(tctx, "BACHT20 disabled against samba3\n");
2112 if (!torture_setup_dir(cli1, BASEDIR)) {
2117 smbcli_unlink(cli1->tree, fname1);
2118 smbcli_unlink(cli1->tree, fname2);
2119 smbcli_unlink(cli1->tree, fname3);
2121 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
2124 base ntcreatex parms
2126 io.generic.level = RAW_OPEN_NTCREATEX;
2127 io.ntcreatex.in.root_fid = 0;
2128 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2129 io.ntcreatex.in.alloc_size = 0;
2130 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2131 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2132 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2133 io.ntcreatex.in.create_options = 0;
2134 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2135 io.ntcreatex.in.security_flags = 0;
2136 io.ntcreatex.in.fname = fname1;
2138 torture_comment(tctx, "open a file with an batch oplock (share mode: all)\n");
2139 ZERO_STRUCT(break_info);
2140 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2141 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2142 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2143 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
2144 NTCREATEX_SHARE_ACCESS_WRITE|
2145 NTCREATEX_SHARE_ACCESS_DELETE;
2146 status = smb_raw_open(cli1->tree, tctx, &io);
2147 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2148 fnum = io.ntcreatex.out.file.fnum;
2149 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
2151 torture_comment(tctx, "setpathinfo rename info should not trigger a break nor a violation\n");
2153 sfi.generic.level = RAW_SFILEINFO_RENAME_INFORMATION;
2154 sfi.generic.in.file.path = fname1;
2155 sfi.rename_information.in.overwrite = 0;
2156 sfi.rename_information.in.root_fid = 0;
2157 sfi.rename_information.in.new_name = fname2+strlen(BASEDIR)+1;
2159 status = smb_raw_setpathinfo(cli2->tree, &sfi);
2161 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2162 CHECK_VAL(break_info.count, 0);
2165 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2166 qfi.generic.in.file.fnum = fnum;
2168 status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
2169 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2170 CHECK_STRMATCH(qfi.all_info.out.fname.s, fname2);
2172 /* we should use no share mode, when samba3 passes this */
2173 torture_comment(tctx, "open a file with the new name an batch oplock (share mode: all)\n");
2174 ZERO_STRUCT(break_info);
2175 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2176 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2177 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2178 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
2179 NTCREATEX_SHARE_ACCESS_WRITE|
2180 NTCREATEX_SHARE_ACCESS_DELETE;
2181 io.ntcreatex.in.fname = fname2;
2182 status = smb_raw_open(cli2->tree, tctx, &io);
2183 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2184 fnum2 = io.ntcreatex.out.file.fnum;
2185 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
2186 CHECK_VAL(break_info.count, 1);
2187 CHECK_VAL(break_info.failures, 0);
2188 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
2190 torture_comment(tctx, "setfileinfo rename info should not trigger a break nor a violation\n");
2192 sfi.generic.level = RAW_SFILEINFO_RENAME_INFORMATION;
2193 sfi.generic.in.file.fnum = fnum;
2194 sfi.rename_information.in.overwrite = 0;
2195 sfi.rename_information.in.root_fid = 0;
2196 sfi.rename_information.in.new_name = fname3+strlen(BASEDIR)+1;
2198 status = smb_raw_setfileinfo(cli1->tree, &sfi);
2199 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2200 CHECK_VAL(break_info.count, 1);
2201 CHECK_VAL(break_info.failures, 0);
2202 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
2205 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2206 qfi.generic.in.file.fnum = fnum;
2208 status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
2209 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2210 CHECK_STRMATCH(qfi.all_info.out.fname.s, fname3);
2213 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2214 qfi.generic.in.file.fnum = fnum2;
2216 status = smb_raw_fileinfo(cli2->tree, tctx, &qfi);
2217 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2218 CHECK_STRMATCH(qfi.all_info.out.fname.s, fname3);
2220 smbcli_close(cli1->tree, fnum);
2223 smb_raw_exit(cli1->session);
2224 smb_raw_exit(cli2->session);
2225 smbcli_deltree(cli1->tree, BASEDIR);
2229 static bool test_raw_oplock_batch21(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
2231 const char *fname = BASEDIR "\\test_batch21.dat";
2240 if (!torture_setup_dir(cli1, BASEDIR)) {
2245 smbcli_unlink(cli1->tree, fname);
2247 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
2250 base ntcreatex parms
2252 io.generic.level = RAW_OPEN_NTCREATEX;
2253 io.ntcreatex.in.root_fid = 0;
2254 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2255 io.ntcreatex.in.alloc_size = 0;
2256 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2257 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2258 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2259 io.ntcreatex.in.create_options = 0;
2260 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2261 io.ntcreatex.in.security_flags = 0;
2262 io.ntcreatex.in.fname = fname;
2265 with a batch oplock we get a break
2267 torture_comment(tctx, "open with batch oplock\n");
2268 ZERO_STRUCT(break_info);
2269 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2270 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2271 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2272 status = smb_raw_open(cli1->tree, tctx, &io);
2273 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2274 fnum = io.ntcreatex.out.file.fnum;
2275 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
2277 torture_comment(tctx, "writing should not generate a break\n");
2278 wr = smbcli_write(cli1->tree, fnum, 0, &c, 0, 1);
2280 CHECK_STATUS(tctx, smbcli_nt_error(cli1->tree), NT_STATUS_OK);
2283 e.in.repeat_count = 1;
2284 status = smb_raw_echo(cli1->transport, &e);
2285 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2287 CHECK_VAL(break_info.count, 0);
2289 smbcli_close(cli1->tree, fnum);
2292 smb_raw_exit(cli1->session);
2293 smb_raw_exit(cli2->session);
2294 smbcli_deltree(cli1->tree, BASEDIR);
2298 static bool test_raw_oplock_batch22(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
2300 const char *fname = BASEDIR "\\test_batch22.dat";
2304 uint16_t fnum=0, fnum2=0;
2306 int timeout = torture_setting_int(tctx, "oplocktimeout", 30);
2309 if (torture_setting_bool(tctx, "samba3", false)) {
2310 torture_skip(tctx, "BACHT22 disabled against samba3\n");
2313 if (!torture_setup_dir(cli1, BASEDIR)) {
2318 smbcli_unlink(cli1->tree, fname);
2320 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
2323 base ntcreatex parms
2325 io.generic.level = RAW_OPEN_NTCREATEX;
2326 io.ntcreatex.in.root_fid = 0;
2327 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2328 io.ntcreatex.in.alloc_size = 0;
2329 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2330 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2331 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2332 io.ntcreatex.in.create_options = 0;
2333 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2334 io.ntcreatex.in.security_flags = 0;
2335 io.ntcreatex.in.fname = fname;
2338 with a batch oplock we get a break
2340 torture_comment(tctx, "open with batch oplock\n");
2341 ZERO_STRUCT(break_info);
2342 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2343 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2344 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2345 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
2346 NTCREATEX_SHARE_ACCESS_WRITE|
2347 NTCREATEX_SHARE_ACCESS_DELETE;
2348 status = smb_raw_open(cli1->tree, tctx, &io);
2349 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2350 fnum = io.ntcreatex.out.file.fnum;
2351 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
2353 torture_comment(tctx, "a 2nd open shoud not succeed after the oplock break timeout\n");
2354 tv = timeval_current();
2355 smbcli_oplock_handler(cli1->transport, oplock_handler_timeout, cli1->tree);
2356 status = smb_raw_open(cli1->tree, tctx, &io);
2357 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
2358 te = (int)timeval_elapsed(&tv);
2359 CHECK_RANGE(te, timeout - 1, timeout + 15);
2361 CHECK_VAL(break_info.count, 1);
2362 CHECK_VAL(break_info.fnum, fnum);
2363 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
2364 CHECK_VAL(break_info.failures, 0);
2365 ZERO_STRUCT(break_info);
2367 torture_comment(tctx, "a 2nd open shoud succeed after the oplock release without break\n");
2368 tv = timeval_current();
2369 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
2370 status = smb_raw_open(cli1->tree, tctx, &io);
2371 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2372 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
2373 te = (int)timeval_elapsed(&tv);
2374 /* it should come in without delay */
2375 CHECK_RANGE(te+1, 0, timeout);
2376 fnum2 = io.ntcreatex.out.file.fnum;
2378 CHECK_VAL(break_info.count, 0);
2380 smbcli_close(cli1->tree, fnum);
2381 smbcli_close(cli1->tree, fnum2);
2384 smb_raw_exit(cli1->session);
2385 smb_raw_exit(cli2->session);
2386 smbcli_deltree(cli1->tree, BASEDIR);
2391 basic testing of oplocks
2393 struct torture_suite *torture_raw_oplock(TALLOC_CTX *mem_ctx)
2395 struct torture_suite *suite = torture_suite_create(mem_ctx, "OPLOCK");
2397 torture_suite_add_2smb_test(suite, "EXCLUSIVE1", test_raw_oplock_exclusive1);
2398 torture_suite_add_2smb_test(suite, "EXCLUSIVE2", test_raw_oplock_exclusive2);
2399 torture_suite_add_2smb_test(suite, "EXCLUSIVE3", test_raw_oplock_exclusive3);
2400 torture_suite_add_2smb_test(suite, "EXCLUSIVE4", test_raw_oplock_exclusive4);
2401 torture_suite_add_2smb_test(suite, "EXCLUSIVE5", test_raw_oplock_exclusive5);
2402 torture_suite_add_2smb_test(suite, "EXCLUSIVE6", test_raw_oplock_exclusive6);
2403 torture_suite_add_2smb_test(suite, "BATCH1", test_raw_oplock_batch1);
2404 torture_suite_add_2smb_test(suite, "BATCH2", test_raw_oplock_batch2);
2405 torture_suite_add_2smb_test(suite, "BATCH3", test_raw_oplock_batch3);
2406 torture_suite_add_2smb_test(suite, "BATCH4", test_raw_oplock_batch4);
2407 torture_suite_add_2smb_test(suite, "BATCH5", test_raw_oplock_batch5);
2408 torture_suite_add_2smb_test(suite, "BATCH6", test_raw_oplock_batch6);
2409 torture_suite_add_2smb_test(suite, "BATCH7", test_raw_oplock_batch7);
2410 torture_suite_add_2smb_test(suite, "BATCH8", test_raw_oplock_batch8);
2411 torture_suite_add_2smb_test(suite, "BATCH9", test_raw_oplock_batch9);
2412 torture_suite_add_2smb_test(suite, "BATCH10", test_raw_oplock_batch10);
2413 torture_suite_add_2smb_test(suite, "BATCH11", test_raw_oplock_batch11);
2414 torture_suite_add_2smb_test(suite, "BATCH12", test_raw_oplock_batch12);
2415 torture_suite_add_2smb_test(suite, "BATCH13", test_raw_oplock_batch13);
2416 torture_suite_add_2smb_test(suite, "BATCH14", test_raw_oplock_batch14);
2417 torture_suite_add_2smb_test(suite, "BATCH15", test_raw_oplock_batch15);
2418 torture_suite_add_2smb_test(suite, "BATCH16", test_raw_oplock_batch16);
2419 torture_suite_add_2smb_test(suite, "BATCH17", test_raw_oplock_batch17);
2420 torture_suite_add_2smb_test(suite, "BATCH18", test_raw_oplock_batch18);
2421 torture_suite_add_2smb_test(suite, "BATCH19", test_raw_oplock_batch19);
2422 torture_suite_add_2smb_test(suite, "BATCH20", test_raw_oplock_batch20);
2423 torture_suite_add_2smb_test(suite, "BATCH21", test_raw_oplock_batch21);
2424 torture_suite_add_2smb_test(suite, "BATCH22", test_raw_oplock_batch22);
2430 stress testing of oplocks
2432 bool torture_bench_oplock(struct torture_context *torture)
2434 struct smbcli_state **cli;
2436 TALLOC_CTX *mem_ctx = talloc_new(torture);
2437 int torture_nprocs = torture_setting_int(torture, "nprocs", 4);
2439 int timelimit = torture_setting_int(torture, "timelimit", 10);
2442 struct event_context *ev = event_context_find(mem_ctx);
2444 cli = talloc_array(mem_ctx, struct smbcli_state *, torture_nprocs);
2446 torture_comment(torture, "Opening %d connections\n", torture_nprocs);
2447 for (i=0;i<torture_nprocs;i++) {
2448 if (!torture_open_connection_ev(&cli[i], i, torture, ev)) {
2451 talloc_steal(mem_ctx, cli[i]);
2452 smbcli_oplock_handler(cli[i]->transport, oplock_handler_close,
2456 if (!torture_setup_dir(cli[0], BASEDIR)) {
2461 io.ntcreatex.level = RAW_OPEN_NTCREATEX;
2462 io.ntcreatex.in.root_fid = 0;
2463 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2464 io.ntcreatex.in.alloc_size = 0;
2465 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2466 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2467 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2468 io.ntcreatex.in.create_options = 0;
2469 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2470 io.ntcreatex.in.security_flags = 0;
2471 io.ntcreatex.in.fname = BASEDIR "\\test.dat";
2472 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2473 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2474 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2476 tv = timeval_current();
2479 we open the same file with SHARE_ACCESS_NONE from all the
2480 connections in a round robin fashion. Each open causes an
2481 oplock break on the previous connection, which is answered
2482 by the oplock_handler_close() to close the file.
2484 This measures how fast we can pass on oplocks, and stresses
2485 the oplock handling code
2487 torture_comment(torture, "Running for %d seconds\n", timelimit);
2488 while (timeval_elapsed(&tv) < timelimit) {
2489 for (i=0;i<torture_nprocs;i++) {
2492 status = smb_raw_open(cli[i]->tree, mem_ctx, &io);
2493 CHECK_STATUS(torture, status, NT_STATUS_OK);
2497 if (torture_setting_bool(torture, "progress", true)) {
2498 torture_comment(torture, "%.2f ops/second\r", count/timeval_elapsed(&tv));
2502 torture_comment(torture, "%.2f ops/second\n", count/timeval_elapsed(&tv));
2504 smb_raw_exit(cli[torture_nprocs-1]->session);
2507 smb_raw_exit(cli[0]->session);
2508 smbcli_deltree(cli[0]->tree, BASEDIR);
2509 talloc_free(mem_ctx);
2514 static struct hold_oplock_info {
2516 bool close_on_break;
2517 uint32_t share_access;
2520 { BASEDIR "\\notshared_close", true,
2521 NTCREATEX_SHARE_ACCESS_NONE, },
2522 { BASEDIR "\\notshared_noclose", false,
2523 NTCREATEX_SHARE_ACCESS_NONE, },
2524 { BASEDIR "\\shared_close", true,
2525 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE, },
2526 { BASEDIR "\\shared_noclose", false,
2527 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE, },
2530 static bool oplock_handler_hold(struct smbcli_transport *transport,
2531 uint16_t tid, uint16_t fnum, uint8_t level,
2534 struct smbcli_tree *tree = (struct smbcli_tree *)private;
2535 struct hold_oplock_info *info;
2538 for (i=0;i<ARRAY_SIZE(hold_info);i++) {
2539 if (hold_info[i].fnum == fnum) break;
2542 if (i == ARRAY_SIZE(hold_info)) {
2543 printf("oplock break for unknown fnum %u\n", fnum);
2547 info = &hold_info[i];
2549 if (info->close_on_break) {
2550 printf("oplock break on %s - closing\n",
2552 oplock_handler_close(transport, tid, fnum, level, private);
2556 printf("oplock break on %s - acking break\n", info->fname);
2558 return smbcli_oplock_ack(tree, fnum, OPLOCK_BREAK_TO_NONE);
2563 used for manual testing of oplocks - especially interaction with
2564 other filesystems (such as NFS and local access)
2566 bool torture_hold_oplock(struct torture_context *torture,
2567 struct smbcli_state *cli)
2569 struct event_context *ev =
2570 (struct event_context *)cli->transport->socket->event.ctx;
2573 printf("Setting up open files with oplocks in %s\n", BASEDIR);
2575 if (!torture_setup_dir(cli, BASEDIR)) {
2579 smbcli_oplock_handler(cli->transport, oplock_handler_hold, cli->tree);
2581 /* setup the files */
2582 for (i=0;i<ARRAY_SIZE(hold_info);i++) {
2587 io.generic.level = RAW_OPEN_NTCREATEX;
2588 io.ntcreatex.in.root_fid = 0;
2589 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2590 io.ntcreatex.in.alloc_size = 0;
2591 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2592 io.ntcreatex.in.share_access = hold_info[i].share_access;
2593 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2594 io.ntcreatex.in.create_options = 0;
2595 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2596 io.ntcreatex.in.security_flags = 0;
2597 io.ntcreatex.in.fname = hold_info[i].fname;
2598 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2599 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2600 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2601 printf("opening %s\n", hold_info[i].fname);
2603 status = smb_raw_open(cli->tree, cli, &io);
2604 if (!NT_STATUS_IS_OK(status)) {
2605 printf("Failed to open %s - %s\n",
2606 hold_info[i].fname, nt_errstr(status));
2610 if (io.ntcreatex.out.oplock_level != BATCH_OPLOCK_RETURN) {
2611 printf("Oplock not granted for %s - expected %d but got %d\n",
2612 hold_info[i].fname, BATCH_OPLOCK_RETURN,
2613 io.ntcreatex.out.oplock_level);
2616 hold_info[i].fnum = io.ntcreatex.out.file.fnum;
2618 /* make the file non-zero size */
2619 if (smbcli_write(cli->tree, hold_info[i].fnum, 0, &c, 0, 1) != 1) {
2620 printf("Failed to write to file\n");
2625 printf("Waiting for oplock events\n");
2626 event_loop_wait(ev);