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_STRMATCH(v, correct) do { \
36 if (!v || strstr((v),(correct)) == NULL) { \
37 torture_result(tctx, TORTURE_FAIL, "(%s): wrong value for %s got '%s' - should be '%s'\n", \
38 __location__, #v, v?v:"NULL", correct); \
43 #define CHECK_STATUS(tctx, status, correct) do { \
44 if (!NT_STATUS_EQUAL(status, correct)) { \
45 torture_result(tctx, TORTURE_FAIL, __location__": Incorrect status %s - should be %s", \
46 nt_errstr(status), nt_errstr(correct)); \
59 #define BASEDIR "\\test_oplock"
62 a handler function for oplock break requests. Ack it as a break to level II if possible
64 static bool oplock_handler_ack_to_levelII(struct smbcli_transport *transport,
65 uint16_t tid, uint16_t fnum,
66 uint8_t level, void *private)
68 struct smbcli_tree *tree = (struct smbcli_tree *)private;
69 break_info.fnum = fnum;
70 break_info.level = level;
73 printf("Acking to level II in oplock handler\n");
75 return smbcli_oplock_ack(tree, fnum, level);
79 a handler function for oplock break requests. Ack it as a break to none
81 static bool oplock_handler_ack_to_none(struct smbcli_transport *transport,
82 uint16_t tid, uint16_t fnum,
83 uint8_t level, void *private)
85 struct smbcli_tree *tree = (struct smbcli_tree *)private;
86 break_info.fnum = fnum;
87 break_info.level = level;
90 printf("Acking to none in oplock handler\n");
92 return smbcli_oplock_ack(tree, fnum, OPLOCK_BREAK_TO_NONE);
95 static void oplock_handler_close_recv(struct smbcli_request *req)
98 status = smbcli_request_simple_recv(req);
99 if (!NT_STATUS_IS_OK(status)) {
100 printf("close failed in oplock_handler_close\n");
101 break_info.failures++;
106 a handler function for oplock break requests - close the file
108 static bool oplock_handler_close(struct smbcli_transport *transport, uint16_t tid,
109 uint16_t fnum, uint8_t level, void *private)
112 struct smbcli_tree *tree = (struct smbcli_tree *)private;
113 struct smbcli_request *req;
115 break_info.fnum = fnum;
116 break_info.level = level;
119 io.close.level = RAW_CLOSE_CLOSE;
120 io.close.in.file.fnum = fnum;
121 io.close.in.write_time = 0;
122 req = smb_raw_close_send(tree, &io);
124 printf("failed to send close in oplock_handler_close\n");
128 req->async.fn = oplock_handler_close_recv;
129 req->async.private = NULL;
134 static bool test_raw_oplock_exclusive1(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
136 const char *fname = BASEDIR "\\test_exclusive1.dat";
140 union smb_unlink unl;
143 if (!torture_setup_dir(cli1, BASEDIR)) {
148 smbcli_unlink(cli1->tree, fname);
150 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
155 io.generic.level = RAW_OPEN_NTCREATEX;
156 io.ntcreatex.in.root_fid = 0;
157 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
158 io.ntcreatex.in.alloc_size = 0;
159 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
160 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
161 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
162 io.ntcreatex.in.create_options = 0;
163 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
164 io.ntcreatex.in.security_flags = 0;
165 io.ntcreatex.in.fname = fname;
167 torture_comment(tctx, "open a file with an exclusive oplock (share mode: none)\n");
168 ZERO_STRUCT(break_info);
169 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
171 status = smb_raw_open(cli1->tree, tctx, &io);
172 CHECK_STATUS(tctx, status, NT_STATUS_OK);
173 fnum = io.ntcreatex.out.file.fnum;
174 CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
176 torture_comment(tctx, "a 2nd open should not cause a break\n");
177 status = smb_raw_open(cli2->tree, tctx, &io);
178 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
179 CHECK_VAL(break_info.count, 0);
180 CHECK_VAL(break_info.failures, 0);
182 torture_comment(tctx, "unlink it - should also be no break\n");
183 unl.unlink.in.pattern = fname;
184 unl.unlink.in.attrib = 0;
185 status = smb_raw_unlink(cli2->tree, &unl);
186 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
187 CHECK_VAL(break_info.count, 0);
188 CHECK_VAL(break_info.failures, 0);
190 smbcli_close(cli1->tree, fnum);
193 smb_raw_exit(cli1->session);
194 smb_raw_exit(cli2->session);
195 smbcli_deltree(cli1->tree, BASEDIR);
199 static bool test_raw_oplock_exclusive2(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
201 const char *fname = BASEDIR "\\test_exclusive2.dat";
205 union smb_unlink unl;
206 uint16_t fnum=0, fnum2=0;
208 if (!torture_setup_dir(cli1, BASEDIR)) {
213 smbcli_unlink(cli1->tree, fname);
215 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
220 io.generic.level = RAW_OPEN_NTCREATEX;
221 io.ntcreatex.in.root_fid = 0;
222 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
223 io.ntcreatex.in.alloc_size = 0;
224 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
225 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
226 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
227 io.ntcreatex.in.create_options = 0;
228 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
229 io.ntcreatex.in.security_flags = 0;
230 io.ntcreatex.in.fname = fname;
232 torture_comment(tctx, "open a file with an exclusive oplock (share mode: all)\n");
233 ZERO_STRUCT(break_info);
234 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
235 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
236 NTCREATEX_SHARE_ACCESS_WRITE|
237 NTCREATEX_SHARE_ACCESS_DELETE;
239 status = smb_raw_open(cli1->tree, tctx, &io);
240 CHECK_STATUS(tctx, status, NT_STATUS_OK);
241 fnum = io.ntcreatex.out.file.fnum;
242 CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
244 torture_comment(tctx, "a 2nd open should cause a break to level 2\n");
245 status = smb_raw_open(cli2->tree, tctx, &io);
246 CHECK_STATUS(tctx, status, NT_STATUS_OK);
247 fnum2 = io.ntcreatex.out.file.fnum;
248 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
249 CHECK_VAL(break_info.count, 1);
250 CHECK_VAL(break_info.fnum, fnum);
251 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
252 CHECK_VAL(break_info.failures, 0);
253 ZERO_STRUCT(break_info);
255 /* now we have 2 level II oplocks... */
256 torture_comment(tctx, "try to unlink it - should not cause a break, but a sharing violation\n");
257 unl.unlink.in.pattern = fname;
258 unl.unlink.in.attrib = 0;
259 status = smb_raw_unlink(cli2->tree, &unl);
260 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
261 CHECK_VAL(break_info.count, 0);
262 CHECK_VAL(break_info.failures, 0);
264 torture_comment(tctx, "close 1st handle\n");
265 smbcli_close(cli1->tree, fnum);
267 torture_comment(tctx, "try to unlink it - should not cause a break, but a sharing violation\n");
268 unl.unlink.in.pattern = fname;
269 unl.unlink.in.attrib = 0;
270 status = smb_raw_unlink(cli2->tree, &unl);
271 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
272 CHECK_VAL(break_info.count, 0);
273 CHECK_VAL(break_info.failures, 0);
275 torture_comment(tctx, "close 1st handle\n");
276 smbcli_close(cli2->tree, fnum2);
278 torture_comment(tctx, "unlink it\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_OK);
283 CHECK_VAL(break_info.count, 0);
284 CHECK_VAL(break_info.failures, 0);
287 smb_raw_exit(cli1->session);
288 smb_raw_exit(cli2->session);
289 smbcli_deltree(cli1->tree, BASEDIR);
293 static bool test_raw_oplock_exclusive3(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
295 const char *fname = BASEDIR "\\test_exclusive3.dat";
299 union smb_setfileinfo sfi;
301 bool s3 = torture_setting_bool(tctx, "samba3", false);
303 if (!torture_setup_dir(cli1, BASEDIR)) {
308 smbcli_unlink(cli1->tree, fname);
310 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
315 io.generic.level = RAW_OPEN_NTCREATEX;
316 io.ntcreatex.in.root_fid = 0;
317 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
318 io.ntcreatex.in.alloc_size = 0;
319 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
320 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
321 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
322 io.ntcreatex.in.create_options = 0;
323 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
324 io.ntcreatex.in.security_flags = 0;
325 io.ntcreatex.in.fname = fname;
327 torture_comment(tctx, "open a file with an exclusive oplock (share mode: %s)\n",
329 ZERO_STRUCT(break_info);
330 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
332 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
333 NTCREATEX_SHARE_ACCESS_WRITE|
334 NTCREATEX_SHARE_ACCESS_DELETE;
337 status = smb_raw_open(cli1->tree, tctx, &io);
338 CHECK_STATUS(tctx, status, NT_STATUS_OK);
339 fnum = io.ntcreatex.out.file.fnum;
340 CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
342 torture_comment(tctx, "setpathinfo EOF should trigger a break to none\n");
344 sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
345 sfi.generic.in.file.path = fname;
346 sfi.end_of_file_info.in.size = 100;
348 status = smb_raw_setpathinfo(cli2->tree, &sfi);
350 CHECK_STATUS(tctx, status, NT_STATUS_OK);
351 CHECK_VAL(break_info.count, 1);
352 CHECK_VAL(break_info.failures, 0);
353 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_NONE);
355 smbcli_close(cli1->tree, fnum);
358 smb_raw_exit(cli1->session);
359 smb_raw_exit(cli2->session);
360 smbcli_deltree(cli1->tree, BASEDIR);
364 static bool test_raw_oplock_exclusive4(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
366 const char *fname = BASEDIR "\\test_exclusive4.dat";
370 uint16_t fnum=0, fnum2=0;
372 if (!torture_setup_dir(cli1, BASEDIR)) {
377 smbcli_unlink(cli1->tree, fname);
379 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
384 io.generic.level = RAW_OPEN_NTCREATEX;
385 io.ntcreatex.in.root_fid = 0;
386 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
387 io.ntcreatex.in.alloc_size = 0;
388 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
389 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
390 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
391 io.ntcreatex.in.create_options = 0;
392 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
393 io.ntcreatex.in.security_flags = 0;
394 io.ntcreatex.in.fname = fname;
396 torture_comment(tctx, "open with exclusive oplock\n");
397 ZERO_STRUCT(break_info);
398 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
400 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
401 status = smb_raw_open(cli1->tree, tctx, &io);
402 CHECK_STATUS(tctx, status, NT_STATUS_OK);
403 fnum = io.ntcreatex.out.file.fnum;
404 CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
406 ZERO_STRUCT(break_info);
407 torture_comment(tctx, "second open with attributes only shouldn't cause oplock break\n");
409 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
410 io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
411 status = smb_raw_open(cli2->tree, tctx, &io);
412 CHECK_STATUS(tctx, status, NT_STATUS_OK);
413 fnum2 = io.ntcreatex.out.file.fnum;
414 CHECK_VAL(io.ntcreatex.out.oplock_level, NO_OPLOCK_RETURN);
415 CHECK_VAL(break_info.count, 0);
416 CHECK_VAL(break_info.failures, 0);
418 smbcli_close(cli1->tree, fnum);
419 smbcli_close(cli2->tree, fnum2);
422 smb_raw_exit(cli1->session);
423 smb_raw_exit(cli2->session);
424 smbcli_deltree(cli1->tree, BASEDIR);
428 static bool test_raw_oplock_exclusive5(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
430 const char *fname = BASEDIR "\\test_exclusive5.dat";
434 uint16_t fnum=0, fnum2=0;
436 if (!torture_setup_dir(cli1, BASEDIR)) {
441 smbcli_unlink(cli1->tree, fname);
443 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
444 smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_levelII, cli1->tree);
449 io.generic.level = RAW_OPEN_NTCREATEX;
450 io.ntcreatex.in.root_fid = 0;
451 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
452 io.ntcreatex.in.alloc_size = 0;
453 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
454 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
455 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
456 io.ntcreatex.in.create_options = 0;
457 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
458 io.ntcreatex.in.security_flags = 0;
459 io.ntcreatex.in.fname = fname;
461 torture_comment(tctx, "open with exclusive oplock\n");
462 ZERO_STRUCT(break_info);
463 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
466 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
467 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
468 NTCREATEX_SHARE_ACCESS_WRITE|
469 NTCREATEX_SHARE_ACCESS_DELETE;
470 status = smb_raw_open(cli1->tree, tctx, &io);
471 CHECK_STATUS(tctx, status, NT_STATUS_OK);
472 fnum = io.ntcreatex.out.file.fnum;
473 CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
475 ZERO_STRUCT(break_info);
477 torture_comment(tctx, "second open with attributes only and NTCREATEX_DISP_OVERWRITE_IF dispostion causes oplock break\n");
479 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
480 io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
481 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE_IF;
482 status = smb_raw_open(cli2->tree, tctx, &io);
483 CHECK_STATUS(tctx, status, NT_STATUS_OK);
484 fnum2 = io.ntcreatex.out.file.fnum;
485 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
486 CHECK_VAL(break_info.count, 1);
487 CHECK_VAL(break_info.failures, 0);
489 smbcli_close(cli1->tree, fnum);
490 smbcli_close(cli2->tree, fnum2);
493 smb_raw_exit(cli1->session);
494 smb_raw_exit(cli2->session);
495 smbcli_deltree(cli1->tree, BASEDIR);
499 static bool test_raw_oplock_exclusive6(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
501 const char *fname1 = BASEDIR "\\test_exclusive6_1.dat";
502 const char *fname2 = BASEDIR "\\test_exclusive6_2.dat";
508 bool s3 = torture_setting_bool(tctx, "samba3", false);
510 if (!torture_setup_dir(cli1, BASEDIR)) {
515 smbcli_unlink(cli1->tree, fname1);
516 smbcli_unlink(cli1->tree, fname2);
518 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
523 io.generic.level = RAW_OPEN_NTCREATEX;
524 io.ntcreatex.in.root_fid = 0;
525 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
526 io.ntcreatex.in.alloc_size = 0;
527 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
528 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
529 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
530 io.ntcreatex.in.create_options = 0;
531 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
532 io.ntcreatex.in.security_flags = 0;
533 io.ntcreatex.in.fname = fname1;
535 /* we should use no share mode, when samba3 passes this */
536 torture_comment(tctx, "open a file with an exclusive oplock (share mode: %s)\n",
538 ZERO_STRUCT(break_info);
539 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
541 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
542 NTCREATEX_SHARE_ACCESS_WRITE|
543 NTCREATEX_SHARE_ACCESS_DELETE;
546 status = smb_raw_open(cli1->tree, tctx, &io);
547 CHECK_STATUS(tctx, status, NT_STATUS_OK);
548 fnum = io.ntcreatex.out.file.fnum;
549 CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
551 torture_comment(tctx, "rename should not generate a break but get a sharing violation\n");
553 rn.generic.level = RAW_RENAME_RENAME;
554 rn.rename.in.pattern1 = fname1;
555 rn.rename.in.pattern2 = fname2;
556 rn.rename.in.attrib = 0;
558 printf("trying rename while first file open\n");
559 status = smb_raw_rename(cli2->tree, &rn);
561 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
562 CHECK_VAL(break_info.count, 0);
563 CHECK_VAL(break_info.failures, 0);
565 smbcli_close(cli1->tree, fnum);
568 smb_raw_exit(cli1->session);
569 smb_raw_exit(cli2->session);
570 smbcli_deltree(cli1->tree, BASEDIR);
574 static bool test_raw_oplock_batch1(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
576 const char *fname = BASEDIR "\\test_batch1.dat";
580 union smb_unlink unl;
584 if (!torture_setup_dir(cli1, BASEDIR)) {
589 smbcli_unlink(cli1->tree, fname);
591 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
596 io.generic.level = RAW_OPEN_NTCREATEX;
597 io.ntcreatex.in.root_fid = 0;
598 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
599 io.ntcreatex.in.alloc_size = 0;
600 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
601 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
602 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
603 io.ntcreatex.in.create_options = 0;
604 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
605 io.ntcreatex.in.security_flags = 0;
606 io.ntcreatex.in.fname = fname;
609 with a batch oplock we get a break
611 torture_comment(tctx, "open with batch oplock\n");
612 ZERO_STRUCT(break_info);
613 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
614 NTCREATEX_FLAGS_REQUEST_OPLOCK |
615 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
616 status = smb_raw_open(cli1->tree, tctx, &io);
617 CHECK_STATUS(tctx, status, NT_STATUS_OK);
618 fnum = io.ntcreatex.out.file.fnum;
619 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
621 torture_comment(tctx, "unlink should generate a break\n");
622 unl.unlink.in.pattern = fname;
623 unl.unlink.in.attrib = 0;
624 status = smb_raw_unlink(cli2->tree, &unl);
625 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
627 CHECK_VAL(break_info.count, 1);
628 CHECK_VAL(break_info.fnum, fnum);
629 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
630 CHECK_VAL(break_info.failures, 0);
632 torture_comment(tctx, "2nd unlink should not generate a break\n");
633 ZERO_STRUCT(break_info);
634 status = smb_raw_unlink(cli2->tree, &unl);
635 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
637 CHECK_VAL(break_info.count, 0);
639 torture_comment(tctx, "writing should generate a self break to none\n");
640 smbcli_write(cli1->tree, fnum, 0, &c, 0, 1);
642 smbcli_write(cli1->tree, fnum, 0, &c, 1, 1);
644 CHECK_VAL(break_info.count, 1);
645 CHECK_VAL(break_info.fnum, fnum);
646 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_NONE);
647 CHECK_VAL(break_info.failures, 0);
649 smbcli_close(cli1->tree, fnum);
652 smb_raw_exit(cli1->session);
653 smb_raw_exit(cli2->session);
654 smbcli_deltree(cli1->tree, BASEDIR);
658 static bool test_raw_oplock_batch2(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
660 const char *fname = BASEDIR "\\test_batch2.dat";
664 union smb_unlink unl;
668 if (!torture_setup_dir(cli1, BASEDIR)) {
673 smbcli_unlink(cli1->tree, fname);
675 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
680 io.generic.level = RAW_OPEN_NTCREATEX;
681 io.ntcreatex.in.root_fid = 0;
682 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
683 io.ntcreatex.in.alloc_size = 0;
684 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
685 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
686 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
687 io.ntcreatex.in.create_options = 0;
688 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
689 io.ntcreatex.in.security_flags = 0;
690 io.ntcreatex.in.fname = fname;
692 torture_comment(tctx, "open with batch oplock\n");
693 ZERO_STRUCT(break_info);
694 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
695 NTCREATEX_FLAGS_REQUEST_OPLOCK |
696 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
697 status = smb_raw_open(cli1->tree, tctx, &io);
698 CHECK_STATUS(tctx, status, NT_STATUS_OK);
699 fnum = io.ntcreatex.out.file.fnum;
700 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
702 torture_comment(tctx, "unlink should generate a break, which we ack as break to none\n");
703 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_none, cli1->tree);
704 unl.unlink.in.pattern = fname;
705 unl.unlink.in.attrib = 0;
706 status = smb_raw_unlink(cli2->tree, &unl);
707 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
709 CHECK_VAL(break_info.count, 1);
710 CHECK_VAL(break_info.fnum, fnum);
711 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
712 CHECK_VAL(break_info.failures, 0);
714 torture_comment(tctx, "2nd unlink should not generate a break\n");
715 ZERO_STRUCT(break_info);
716 status = smb_raw_unlink(cli2->tree, &unl);
717 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
719 CHECK_VAL(break_info.count, 0);
721 torture_comment(tctx, "writing should not generate a break\n");
722 smbcli_write(cli1->tree, fnum, 0, &c, 0, 1);
724 smbcli_write(cli1->tree, fnum, 0, &c, 1, 1);
726 CHECK_VAL(break_info.count, 0);
728 smbcli_close(cli1->tree, fnum);
731 smb_raw_exit(cli1->session);
732 smb_raw_exit(cli2->session);
733 smbcli_deltree(cli1->tree, BASEDIR);
737 static bool test_raw_oplock_batch3(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
739 const char *fname = BASEDIR "\\test_batch3.dat";
743 union smb_unlink unl;
746 if (!torture_setup_dir(cli1, BASEDIR)) {
751 smbcli_unlink(cli1->tree, fname);
753 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
758 io.generic.level = RAW_OPEN_NTCREATEX;
759 io.ntcreatex.in.root_fid = 0;
760 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
761 io.ntcreatex.in.alloc_size = 0;
762 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
763 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
764 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
765 io.ntcreatex.in.create_options = 0;
766 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
767 io.ntcreatex.in.security_flags = 0;
768 io.ntcreatex.in.fname = fname;
770 torture_comment(tctx, "if we close on break then the unlink can succeed\n");
771 ZERO_STRUCT(break_info);
772 smbcli_oplock_handler(cli1->transport, oplock_handler_close, cli1->tree);
773 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
774 NTCREATEX_FLAGS_REQUEST_OPLOCK |
775 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
776 status = smb_raw_open(cli1->tree, tctx, &io);
777 CHECK_STATUS(tctx, status, NT_STATUS_OK);
778 fnum = io.ntcreatex.out.file.fnum;
779 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
781 unl.unlink.in.pattern = fname;
782 unl.unlink.in.attrib = 0;
783 ZERO_STRUCT(break_info);
784 status = smb_raw_unlink(cli2->tree, &unl);
785 CHECK_STATUS(tctx, status, NT_STATUS_OK);
787 CHECK_VAL(break_info.count, 1);
788 CHECK_VAL(break_info.fnum, fnum);
789 CHECK_VAL(break_info.level, 1);
790 CHECK_VAL(break_info.failures, 0);
792 smbcli_close(cli1->tree, fnum);
795 smb_raw_exit(cli1->session);
796 smb_raw_exit(cli2->session);
797 smbcli_deltree(cli1->tree, BASEDIR);
801 static bool test_raw_oplock_batch4(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
803 const char *fname = BASEDIR "\\test_batch4.dat";
810 if (!torture_setup_dir(cli1, BASEDIR)) {
815 smbcli_unlink(cli1->tree, fname);
817 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
822 io.generic.level = RAW_OPEN_NTCREATEX;
823 io.ntcreatex.in.root_fid = 0;
824 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
825 io.ntcreatex.in.alloc_size = 0;
826 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
827 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
828 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
829 io.ntcreatex.in.create_options = 0;
830 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
831 io.ntcreatex.in.security_flags = 0;
832 io.ntcreatex.in.fname = fname;
834 torture_comment(tctx, "a self read should not cause a break\n");
835 ZERO_STRUCT(break_info);
836 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
838 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
839 NTCREATEX_FLAGS_REQUEST_OPLOCK |
840 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
841 status = smb_raw_open(cli1->tree, tctx, &io);
842 CHECK_STATUS(tctx, status, NT_STATUS_OK);
843 fnum = io.ntcreatex.out.file.fnum;
844 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
846 rd.read.level = RAW_READ_READ;
847 rd.read.in.file.fnum = fnum;
848 rd.read.in.count = 1;
849 rd.read.in.offset = 0;
850 rd.read.in.remaining = 0;
851 status = smb_raw_read(cli1->tree, &rd);
852 CHECK_STATUS(tctx, status, NT_STATUS_OK);
853 CHECK_VAL(break_info.count, 0);
854 CHECK_VAL(break_info.failures, 0);
856 smbcli_close(cli1->tree, fnum);
859 smb_raw_exit(cli1->session);
860 smb_raw_exit(cli2->session);
861 smbcli_deltree(cli1->tree, BASEDIR);
865 static bool test_raw_oplock_batch5(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
867 const char *fname = BASEDIR "\\test_batch5.dat";
873 if (!torture_setup_dir(cli1, BASEDIR)) {
878 smbcli_unlink(cli1->tree, fname);
880 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
885 io.generic.level = RAW_OPEN_NTCREATEX;
886 io.ntcreatex.in.root_fid = 0;
887 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
888 io.ntcreatex.in.alloc_size = 0;
889 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
890 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
891 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
892 io.ntcreatex.in.create_options = 0;
893 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
894 io.ntcreatex.in.security_flags = 0;
895 io.ntcreatex.in.fname = fname;
897 torture_comment(tctx, "a 2nd open should give a break\n");
898 ZERO_STRUCT(break_info);
899 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
901 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
902 NTCREATEX_FLAGS_REQUEST_OPLOCK |
903 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
904 status = smb_raw_open(cli1->tree, tctx, &io);
905 CHECK_STATUS(tctx, status, NT_STATUS_OK);
906 fnum = io.ntcreatex.out.file.fnum;
907 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
909 ZERO_STRUCT(break_info);
911 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
912 status = smb_raw_open(cli2->tree, tctx, &io);
913 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
915 CHECK_VAL(break_info.count, 1);
916 CHECK_VAL(break_info.fnum, fnum);
917 CHECK_VAL(break_info.level, 1);
918 CHECK_VAL(break_info.failures, 0);
920 smbcli_close(cli1->tree, fnum);
923 smb_raw_exit(cli1->session);
924 smb_raw_exit(cli2->session);
925 smbcli_deltree(cli1->tree, BASEDIR);
929 static bool test_raw_oplock_batch6(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
931 const char *fname = BASEDIR "\\test_batch6.dat";
935 uint16_t fnum=0, fnum2=0;
938 if (!torture_setup_dir(cli1, BASEDIR)) {
943 smbcli_unlink(cli1->tree, fname);
945 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
950 io.generic.level = RAW_OPEN_NTCREATEX;
951 io.ntcreatex.in.root_fid = 0;
952 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
953 io.ntcreatex.in.alloc_size = 0;
954 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
955 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
956 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
957 io.ntcreatex.in.create_options = 0;
958 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
959 io.ntcreatex.in.security_flags = 0;
960 io.ntcreatex.in.fname = fname;
962 torture_comment(tctx, "a 2nd open should give a break to level II if the first open allowed shared read\n");
963 ZERO_STRUCT(break_info);
964 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
965 smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_levelII, cli2->tree);
967 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_READ | SEC_RIGHTS_FILE_WRITE;
968 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
969 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
970 NTCREATEX_FLAGS_REQUEST_OPLOCK |
971 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
972 status = smb_raw_open(cli1->tree, tctx, &io);
973 CHECK_STATUS(tctx, status, NT_STATUS_OK);
974 fnum = io.ntcreatex.out.file.fnum;
975 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
977 ZERO_STRUCT(break_info);
979 status = smb_raw_open(cli2->tree, tctx, &io);
980 CHECK_STATUS(tctx, status, NT_STATUS_OK);
981 fnum2 = io.ntcreatex.out.file.fnum;
982 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
984 CHECK_VAL(break_info.count, 1);
985 CHECK_VAL(break_info.fnum, fnum);
986 CHECK_VAL(break_info.level, 1);
987 CHECK_VAL(break_info.failures, 0);
988 ZERO_STRUCT(break_info);
990 torture_comment(tctx, "write should trigger a break to none on both\n");
991 smbcli_write(cli1->tree, fnum, 0, &c, 0, 1);
993 smbcli_write(cli1->tree, fnum, 0, &c, 1, 1);
995 CHECK_VAL(break_info.count, 2);
996 CHECK_VAL(break_info.level, 0);
997 CHECK_VAL(break_info.failures, 0);
999 smbcli_close(cli1->tree, fnum);
1000 smbcli_close(cli2->tree, fnum2);
1004 smb_raw_exit(cli1->session);
1005 smb_raw_exit(cli2->session);
1006 smbcli_deltree(cli1->tree, BASEDIR);
1010 static bool test_raw_oplock_batch7(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1012 const char *fname = BASEDIR "\\test_batch7.dat";
1016 uint16_t fnum=0, fnum2=0;
1018 if (!torture_setup_dir(cli1, BASEDIR)) {
1023 smbcli_unlink(cli1->tree, fname);
1025 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1028 base ntcreatex parms
1030 io.generic.level = RAW_OPEN_NTCREATEX;
1031 io.ntcreatex.in.root_fid = 0;
1032 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1033 io.ntcreatex.in.alloc_size = 0;
1034 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1035 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1036 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1037 io.ntcreatex.in.create_options = 0;
1038 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1039 io.ntcreatex.in.security_flags = 0;
1040 io.ntcreatex.in.fname = fname;
1042 torture_comment(tctx, "a 2nd open should get an oplock when we close instead of ack\n");
1043 ZERO_STRUCT(break_info);
1044 smbcli_oplock_handler(cli1->transport, oplock_handler_close, cli1->tree);
1046 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1047 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1048 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1049 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1050 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1051 status = smb_raw_open(cli1->tree, tctx, &io);
1052 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1053 fnum2 = io.ntcreatex.out.file.fnum;
1054 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1056 ZERO_STRUCT(break_info);
1058 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1059 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1060 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1061 status = smb_raw_open(cli2->tree, tctx, &io);
1062 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1063 fnum = io.ntcreatex.out.file.fnum;
1064 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1066 CHECK_VAL(break_info.count, 1);
1067 CHECK_VAL(break_info.fnum, fnum2);
1068 CHECK_VAL(break_info.level, 1);
1069 CHECK_VAL(break_info.failures, 0);
1071 smbcli_close(cli2->tree, fnum);
1074 smb_raw_exit(cli1->session);
1075 smb_raw_exit(cli2->session);
1076 smbcli_deltree(cli1->tree, BASEDIR);
1080 static bool test_raw_oplock_batch8(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1082 const char *fname = BASEDIR "\\test_batch8.dat";
1086 uint16_t fnum=0, fnum2=0;
1088 if (!torture_setup_dir(cli1, BASEDIR)) {
1093 smbcli_unlink(cli1->tree, fname);
1095 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1098 base ntcreatex parms
1100 io.generic.level = RAW_OPEN_NTCREATEX;
1101 io.ntcreatex.in.root_fid = 0;
1102 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1103 io.ntcreatex.in.alloc_size = 0;
1104 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1105 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1106 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1107 io.ntcreatex.in.create_options = 0;
1108 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1109 io.ntcreatex.in.security_flags = 0;
1110 io.ntcreatex.in.fname = fname;
1112 torture_comment(tctx, "open with batch oplock\n");
1113 ZERO_STRUCT(break_info);
1114 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1116 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1117 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1118 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1119 status = smb_raw_open(cli1->tree, tctx, &io);
1120 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1121 fnum = io.ntcreatex.out.file.fnum;
1122 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1124 ZERO_STRUCT(break_info);
1125 torture_comment(tctx, "second open with attributes only shouldn't cause oplock break\n");
1127 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1128 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1129 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1130 io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
1131 status = smb_raw_open(cli2->tree, tctx, &io);
1132 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1133 fnum2 = io.ntcreatex.out.file.fnum;
1134 CHECK_VAL(io.ntcreatex.out.oplock_level, NO_OPLOCK_RETURN);
1135 CHECK_VAL(break_info.count, 0);
1136 CHECK_VAL(break_info.failures, 0);
1138 smbcli_close(cli1->tree, fnum);
1139 smbcli_close(cli2->tree, fnum2);
1142 smb_raw_exit(cli1->session);
1143 smb_raw_exit(cli2->session);
1144 smbcli_deltree(cli1->tree, BASEDIR);
1148 static bool test_raw_oplock_batch9(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1150 const char *fname = BASEDIR "\\test_batch9.dat";
1154 uint16_t fnum=0, fnum2=0;
1157 if (!torture_setup_dir(cli1, BASEDIR)) {
1162 smbcli_unlink(cli1->tree, fname);
1164 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1167 base ntcreatex parms
1169 io.generic.level = RAW_OPEN_NTCREATEX;
1170 io.ntcreatex.in.root_fid = 0;
1171 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1172 io.ntcreatex.in.alloc_size = 0;
1173 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1174 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1175 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1176 io.ntcreatex.in.create_options = 0;
1177 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1178 io.ntcreatex.in.security_flags = 0;
1179 io.ntcreatex.in.fname = fname;
1181 torture_comment(tctx, "open with attributes only can create file\n");
1183 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1184 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1185 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1186 io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
1187 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1188 status = smb_raw_open(cli1->tree, tctx, &io);
1189 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1190 fnum = io.ntcreatex.out.file.fnum;
1191 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1193 torture_comment(tctx, "Subsequent normal open should break oplock on attribute only open to level II\n");
1195 ZERO_STRUCT(break_info);
1196 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1198 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1199 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1200 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1201 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1202 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1203 status = smb_raw_open(cli2->tree, tctx, &io);
1204 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1205 fnum2 = io.ntcreatex.out.file.fnum;
1206 CHECK_VAL(break_info.count, 1);
1207 CHECK_VAL(break_info.fnum, fnum);
1208 CHECK_VAL(break_info.failures, 0);
1209 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
1210 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1211 smbcli_close(cli2->tree, fnum2);
1213 torture_comment(tctx, "third oplocked open should grant level2 without break\n");
1214 ZERO_STRUCT(break_info);
1215 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1216 smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_levelII, cli2->tree);
1217 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1218 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1219 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1220 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1221 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1222 status = smb_raw_open(cli2->tree, tctx, &io);
1223 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1224 fnum2 = io.ntcreatex.out.file.fnum;
1225 CHECK_VAL(break_info.count, 0);
1226 CHECK_VAL(break_info.failures, 0);
1227 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1229 ZERO_STRUCT(break_info);
1231 torture_comment(tctx, "write should trigger a break to none on both\n");
1232 smbcli_write(cli2->tree, fnum2, 0, &c, 0, 1);
1234 /* Now the oplock break request comes in. But right now we can't
1235 * answer it. Do another write */
1238 smbcli_write(cli2->tree, fnum2, 0, &c, 1, 1);
1240 CHECK_VAL(break_info.count, 2);
1241 CHECK_VAL(break_info.level, 0);
1242 CHECK_VAL(break_info.failures, 0);
1244 smbcli_close(cli1->tree, fnum);
1245 smbcli_close(cli2->tree, fnum2);
1248 smb_raw_exit(cli1->session);
1249 smb_raw_exit(cli2->session);
1250 smbcli_deltree(cli1->tree, BASEDIR);
1254 static bool test_raw_oplock_batch10(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1256 const char *fname = BASEDIR "\\test_batch10.dat";
1260 uint16_t fnum=0, fnum2=0;
1262 if (!torture_setup_dir(cli1, BASEDIR)) {
1267 smbcli_unlink(cli1->tree, fname);
1269 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1272 base ntcreatex parms
1274 io.generic.level = RAW_OPEN_NTCREATEX;
1275 io.ntcreatex.in.root_fid = 0;
1276 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1277 io.ntcreatex.in.alloc_size = 0;
1278 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1279 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1280 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1281 io.ntcreatex.in.create_options = 0;
1282 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1283 io.ntcreatex.in.security_flags = 0;
1284 io.ntcreatex.in.fname = fname;
1286 torture_comment(tctx, "Open with oplock after a non-oplock open should grant level2\n");
1287 ZERO_STRUCT(break_info);
1288 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
1289 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1290 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1291 NTCREATEX_SHARE_ACCESS_WRITE|
1292 NTCREATEX_SHARE_ACCESS_DELETE;
1293 status = smb_raw_open(cli1->tree, tctx, &io);
1294 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1295 fnum = io.ntcreatex.out.file.fnum;
1296 CHECK_VAL(break_info.count, 0);
1297 CHECK_VAL(break_info.failures, 0);
1298 CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
1300 smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_levelII, cli2->tree);
1302 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1303 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1304 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1305 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1306 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1307 NTCREATEX_SHARE_ACCESS_WRITE|
1308 NTCREATEX_SHARE_ACCESS_DELETE;
1309 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1310 status = smb_raw_open(cli2->tree, tctx, &io);
1311 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1312 fnum2 = io.ntcreatex.out.file.fnum;
1313 CHECK_VAL(break_info.count, 0);
1314 CHECK_VAL(break_info.failures, 0);
1315 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1317 torture_comment(tctx, "write should trigger a break to none\n");
1320 wr.write.level = RAW_WRITE_WRITE;
1321 wr.write.in.file.fnum = fnum;
1322 wr.write.in.count = 1;
1323 wr.write.in.offset = 0;
1324 wr.write.in.remaining = 0;
1325 wr.write.in.data = (const uint8_t *)"x";
1326 status = smb_raw_write(cli1->tree, &wr);
1327 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1330 /* Now the oplock break request comes in. But right now we can't
1331 * answer it. Do another write */
1337 wr.write.level = RAW_WRITE_WRITE;
1338 wr.write.in.file.fnum = fnum;
1339 wr.write.in.count = 1;
1340 wr.write.in.offset = 0;
1341 wr.write.in.remaining = 0;
1342 wr.write.in.data = (const uint8_t *)"x";
1343 status = smb_raw_write(cli1->tree, &wr);
1344 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1347 CHECK_VAL(break_info.count, 1);
1348 CHECK_VAL(break_info.fnum, fnum2);
1349 CHECK_VAL(break_info.level, 0);
1350 CHECK_VAL(break_info.failures, 0);
1352 smbcli_close(cli1->tree, fnum);
1353 smbcli_close(cli2->tree, fnum2);
1356 smb_raw_exit(cli1->session);
1357 smb_raw_exit(cli2->session);
1358 smbcli_deltree(cli1->tree, BASEDIR);
1362 static bool test_raw_oplock_batch11(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1364 const char *fname = BASEDIR "\\test_batch11.dat";
1368 union smb_setfileinfo sfi;
1371 if (!torture_setup_dir(cli1, BASEDIR)) {
1376 smbcli_unlink(cli1->tree, fname);
1378 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1381 base ntcreatex parms
1383 io.generic.level = RAW_OPEN_NTCREATEX;
1384 io.ntcreatex.in.root_fid = 0;
1385 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1386 io.ntcreatex.in.alloc_size = 0;
1387 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1388 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1389 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1390 io.ntcreatex.in.create_options = 0;
1391 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1392 io.ntcreatex.in.security_flags = 0;
1393 io.ntcreatex.in.fname = fname;
1395 /* Test if a set-eof on pathname breaks an exclusive oplock. */
1396 torture_comment(tctx, "Test if setpathinfo set EOF breaks oplocks.\n");
1398 ZERO_STRUCT(break_info);
1399 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1401 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1402 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1403 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1404 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1405 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1406 NTCREATEX_SHARE_ACCESS_WRITE|
1407 NTCREATEX_SHARE_ACCESS_DELETE;
1408 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1409 status = smb_raw_open(cli1->tree, tctx, &io);
1410 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1411 fnum = io.ntcreatex.out.file.fnum;
1412 CHECK_VAL(break_info.count, 0);
1413 CHECK_VAL(break_info.failures, 0);
1414 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1417 sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
1418 sfi.generic.in.file.path = fname;
1419 sfi.end_of_file_info.in.size = 100;
1421 status = smb_raw_setpathinfo(cli2->tree, &sfi);
1423 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1424 CHECK_VAL(break_info.count, 1);
1425 CHECK_VAL(break_info.failures, 0);
1426 CHECK_VAL(break_info.level, 0);
1428 smbcli_close(cli1->tree, fnum);
1431 smb_raw_exit(cli1->session);
1432 smb_raw_exit(cli2->session);
1433 smbcli_deltree(cli1->tree, BASEDIR);
1437 static bool test_raw_oplock_batch12(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1439 const char *fname = BASEDIR "\\test_batch12.dat";
1443 union smb_setfileinfo sfi;
1446 if (!torture_setup_dir(cli1, BASEDIR)) {
1451 smbcli_unlink(cli1->tree, fname);
1453 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1456 base ntcreatex parms
1458 io.generic.level = RAW_OPEN_NTCREATEX;
1459 io.ntcreatex.in.root_fid = 0;
1460 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1461 io.ntcreatex.in.alloc_size = 0;
1462 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1463 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1464 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1465 io.ntcreatex.in.create_options = 0;
1466 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1467 io.ntcreatex.in.security_flags = 0;
1468 io.ntcreatex.in.fname = fname;
1470 /* Test if a set-allocation size on pathname breaks an exclusive oplock. */
1471 torture_comment(tctx, "Test if setpathinfo allocation size breaks oplocks.\n");
1473 ZERO_STRUCT(break_info);
1474 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1476 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1477 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1478 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1479 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1480 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1481 NTCREATEX_SHARE_ACCESS_WRITE|
1482 NTCREATEX_SHARE_ACCESS_DELETE;
1483 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1484 status = smb_raw_open(cli1->tree, tctx, &io);
1485 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1486 fnum = io.ntcreatex.out.file.fnum;
1487 CHECK_VAL(break_info.count, 0);
1488 CHECK_VAL(break_info.failures, 0);
1489 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1492 sfi.generic.level = SMB_SFILEINFO_ALLOCATION_INFORMATION;
1493 sfi.generic.in.file.path = fname;
1494 sfi.allocation_info.in.alloc_size = 65536 * 8;
1496 status = smb_raw_setpathinfo(cli2->tree, &sfi);
1498 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1499 CHECK_VAL(break_info.count, 1);
1500 CHECK_VAL(break_info.failures, 0);
1501 CHECK_VAL(break_info.level, 0);
1503 smbcli_close(cli1->tree, fnum);
1506 smb_raw_exit(cli1->session);
1507 smb_raw_exit(cli2->session);
1508 smbcli_deltree(cli1->tree, BASEDIR);
1512 static bool test_raw_oplock_batch13(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1514 const char *fname = BASEDIR "\\test_batch13.dat";
1518 uint16_t fnum=0, fnum2=0;
1520 if (!torture_setup_dir(cli1, BASEDIR)) {
1525 smbcli_unlink(cli1->tree, fname);
1527 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1528 smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_levelII, cli1->tree);
1531 base ntcreatex parms
1533 io.generic.level = RAW_OPEN_NTCREATEX;
1534 io.ntcreatex.in.root_fid = 0;
1535 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1536 io.ntcreatex.in.alloc_size = 0;
1537 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1538 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1539 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1540 io.ntcreatex.in.create_options = 0;
1541 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1542 io.ntcreatex.in.security_flags = 0;
1543 io.ntcreatex.in.fname = fname;
1545 torture_comment(tctx, "open with batch oplock\n");
1546 ZERO_STRUCT(break_info);
1547 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1550 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1551 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1552 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1553 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1554 NTCREATEX_SHARE_ACCESS_WRITE|
1555 NTCREATEX_SHARE_ACCESS_DELETE;
1556 status = smb_raw_open(cli1->tree, tctx, &io);
1557 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1558 fnum = io.ntcreatex.out.file.fnum;
1559 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1561 ZERO_STRUCT(break_info);
1563 torture_comment(tctx, "second open with attributes only and NTCREATEX_DISP_OVERWRITE dispostion causes oplock break\n");
1565 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1566 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1567 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1568 io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
1569 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1570 NTCREATEX_SHARE_ACCESS_WRITE|
1571 NTCREATEX_SHARE_ACCESS_DELETE;
1572 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE;
1573 status = smb_raw_open(cli2->tree, tctx, &io);
1574 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1575 fnum2 = io.ntcreatex.out.file.fnum;
1576 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1577 CHECK_VAL(break_info.count, 1);
1578 CHECK_VAL(break_info.failures, 0);
1580 smbcli_close(cli1->tree, fnum);
1581 smbcli_close(cli2->tree, fnum2);
1584 smb_raw_exit(cli1->session);
1585 smb_raw_exit(cli2->session);
1586 smbcli_deltree(cli1->tree, BASEDIR);
1590 static bool test_raw_oplock_batch14(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1592 const char *fname = BASEDIR "\\test_batch14.dat";
1596 uint16_t fnum=0, fnum2=0;
1598 if (!torture_setup_dir(cli1, BASEDIR)) {
1603 smbcli_unlink(cli1->tree, fname);
1605 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1608 base ntcreatex parms
1610 io.generic.level = RAW_OPEN_NTCREATEX;
1611 io.ntcreatex.in.root_fid = 0;
1612 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1613 io.ntcreatex.in.alloc_size = 0;
1614 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1615 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1616 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1617 io.ntcreatex.in.create_options = 0;
1618 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1619 io.ntcreatex.in.security_flags = 0;
1620 io.ntcreatex.in.fname = fname;
1622 torture_comment(tctx, "open with batch oplock\n");
1623 ZERO_STRUCT(break_info);
1624 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1626 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1627 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1628 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1629 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1630 NTCREATEX_SHARE_ACCESS_WRITE|
1631 NTCREATEX_SHARE_ACCESS_DELETE;
1632 status = smb_raw_open(cli1->tree, tctx, &io);
1633 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1634 fnum = io.ntcreatex.out.file.fnum;
1635 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1637 ZERO_STRUCT(break_info);
1639 torture_comment(tctx, "second open with attributes only and NTCREATEX_DISP_SUPERSEDE dispostion causes oplock break\n");
1641 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1642 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1643 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1644 io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
1645 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1646 NTCREATEX_SHARE_ACCESS_WRITE|
1647 NTCREATEX_SHARE_ACCESS_DELETE;
1648 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE;
1649 status = smb_raw_open(cli2->tree, tctx, &io);
1650 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1651 fnum2 = io.ntcreatex.out.file.fnum;
1652 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1653 CHECK_VAL(break_info.count, 1);
1654 CHECK_VAL(break_info.failures, 0);
1656 smbcli_close(cli1->tree, fnum);
1657 smbcli_close(cli2->tree, fnum2);
1659 smb_raw_exit(cli1->session);
1660 smb_raw_exit(cli2->session);
1661 smbcli_deltree(cli1->tree, BASEDIR);
1665 static bool test_raw_oplock_batch15(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1667 const char *fname = BASEDIR "\\test_batch15.dat";
1671 union smb_fileinfo qfi;
1674 if (!torture_setup_dir(cli1, BASEDIR)) {
1679 smbcli_unlink(cli1->tree, fname);
1681 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1684 base ntcreatex parms
1686 io.generic.level = RAW_OPEN_NTCREATEX;
1687 io.ntcreatex.in.root_fid = 0;
1688 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1689 io.ntcreatex.in.alloc_size = 0;
1690 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1691 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1692 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1693 io.ntcreatex.in.create_options = 0;
1694 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1695 io.ntcreatex.in.security_flags = 0;
1696 io.ntcreatex.in.fname = fname;
1698 /* Test if a qpathinfo all info on pathname breaks a batch oplock. */
1699 torture_comment(tctx, "Test if qpathinfo all info breaks a batch oplock (should not).\n");
1701 ZERO_STRUCT(break_info);
1702 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1704 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1705 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1706 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1707 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1708 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1709 NTCREATEX_SHARE_ACCESS_WRITE|
1710 NTCREATEX_SHARE_ACCESS_DELETE;
1711 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1712 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1713 status = smb_raw_open(cli1->tree, tctx, &io);
1714 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1715 fnum = io.ntcreatex.out.file.fnum;
1716 CHECK_VAL(break_info.count, 0);
1717 CHECK_VAL(break_info.failures, 0);
1718 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1721 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
1722 qfi.generic.in.file.path = fname;
1724 status = smb_raw_pathinfo(cli2->tree, tctx, &qfi);
1726 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1727 CHECK_VAL(break_info.count, 0);
1729 smbcli_close(cli1->tree, fnum);
1732 smb_raw_exit(cli1->session);
1733 smb_raw_exit(cli2->session);
1734 smbcli_deltree(cli1->tree, BASEDIR);
1738 static bool test_raw_oplock_batch16(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1740 const char *fname = BASEDIR "\\test_batch16.dat";
1744 uint16_t fnum=0, fnum2=0;
1746 if (!torture_setup_dir(cli1, BASEDIR)) {
1751 smbcli_unlink(cli1->tree, fname);
1753 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1754 smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_levelII, cli1->tree);
1757 base ntcreatex parms
1759 io.generic.level = RAW_OPEN_NTCREATEX;
1760 io.ntcreatex.in.root_fid = 0;
1761 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1762 io.ntcreatex.in.alloc_size = 0;
1763 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1764 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1765 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1766 io.ntcreatex.in.create_options = 0;
1767 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1768 io.ntcreatex.in.security_flags = 0;
1769 io.ntcreatex.in.fname = fname;
1771 torture_comment(tctx, "open with batch oplock\n");
1772 ZERO_STRUCT(break_info);
1773 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1776 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1777 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1778 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1779 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1780 NTCREATEX_SHARE_ACCESS_WRITE|
1781 NTCREATEX_SHARE_ACCESS_DELETE;
1782 status = smb_raw_open(cli1->tree, tctx, &io);
1783 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1784 fnum = io.ntcreatex.out.file.fnum;
1785 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1787 ZERO_STRUCT(break_info);
1789 torture_comment(tctx, "second open with attributes only and NTCREATEX_DISP_OVERWRITE_IF dispostion causes oplock break\n");
1791 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1792 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1793 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1794 io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
1795 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1796 NTCREATEX_SHARE_ACCESS_WRITE|
1797 NTCREATEX_SHARE_ACCESS_DELETE;
1798 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE_IF;
1799 status = smb_raw_open(cli2->tree, tctx, &io);
1800 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1801 fnum2 = io.ntcreatex.out.file.fnum;
1802 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1803 CHECK_VAL(break_info.count, 1);
1804 CHECK_VAL(break_info.failures, 0);
1806 smbcli_close(cli1->tree, fnum);
1807 smbcli_close(cli2->tree, fnum2);
1810 smb_raw_exit(cli1->session);
1811 smb_raw_exit(cli2->session);
1812 smbcli_deltree(cli1->tree, BASEDIR);
1816 static bool test_raw_oplock_batch17(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1818 const char *fname1 = BASEDIR "\\test_batch17_1.dat";
1819 const char *fname2 = BASEDIR "\\test_batch17_2.dat";
1823 union smb_rename rn;
1825 bool s3 = torture_setting_bool(tctx, "samba3", false);
1827 if (!torture_setup_dir(cli1, BASEDIR)) {
1832 smbcli_unlink(cli1->tree, fname1);
1833 smbcli_unlink(cli1->tree, fname2);
1835 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1838 base ntcreatex parms
1840 io.generic.level = RAW_OPEN_NTCREATEX;
1841 io.ntcreatex.in.root_fid = 0;
1842 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1843 io.ntcreatex.in.alloc_size = 0;
1844 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1845 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1846 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1847 io.ntcreatex.in.create_options = 0;
1848 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1849 io.ntcreatex.in.security_flags = 0;
1850 io.ntcreatex.in.fname = fname1;
1852 /* we should use no share mode, when samba3 passes this */
1853 torture_comment(tctx, "open a file with an batch oplock (share mode: %s)\n",
1855 ZERO_STRUCT(break_info);
1856 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1857 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1858 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1860 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1861 NTCREATEX_SHARE_ACCESS_WRITE|
1862 NTCREATEX_SHARE_ACCESS_DELETE;
1865 status = smb_raw_open(cli1->tree, tctx, &io);
1866 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1867 fnum = io.ntcreatex.out.file.fnum;
1868 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1870 torture_comment(tctx, "rename should trigger a break\n");
1872 rn.generic.level = RAW_RENAME_RENAME;
1873 rn.rename.in.pattern1 = fname1;
1874 rn.rename.in.pattern2 = fname2;
1875 rn.rename.in.attrib = 0;
1877 printf("trying rename while first file open\n");
1878 status = smb_raw_rename(cli2->tree, &rn);
1880 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
1881 CHECK_VAL(break_info.count, 1);
1882 CHECK_VAL(break_info.failures, 0);
1883 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
1885 smbcli_close(cli1->tree, fnum);
1888 smb_raw_exit(cli1->session);
1889 smb_raw_exit(cli2->session);
1890 smbcli_deltree(cli1->tree, BASEDIR);
1894 static bool test_raw_oplock_batch18(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1896 const char *fname1 = BASEDIR "\\test_batch18_1.dat";
1897 const char *fname2 = BASEDIR "\\test_batch18_2.dat";
1901 union smb_rename rn;
1903 bool s3 = torture_setting_bool(tctx, "samba3", false);
1905 if (!torture_setup_dir(cli1, BASEDIR)) {
1910 smbcli_unlink(cli1->tree, fname1);
1911 smbcli_unlink(cli1->tree, fname2);
1913 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1916 base ntcreatex parms
1918 io.generic.level = RAW_OPEN_NTCREATEX;
1919 io.ntcreatex.in.root_fid = 0;
1920 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1921 io.ntcreatex.in.alloc_size = 0;
1922 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1923 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1924 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1925 io.ntcreatex.in.create_options = 0;
1926 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1927 io.ntcreatex.in.security_flags = 0;
1928 io.ntcreatex.in.fname = fname1;
1930 /* we should use no share mode, when samba3 passes this */
1931 torture_comment(tctx, "open a file with an batch oplock (share mode: %s)\n",
1933 ZERO_STRUCT(break_info);
1934 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1935 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1936 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1938 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1939 NTCREATEX_SHARE_ACCESS_WRITE|
1940 NTCREATEX_SHARE_ACCESS_DELETE;
1943 status = smb_raw_open(cli1->tree, tctx, &io);
1944 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1945 fnum = io.ntcreatex.out.file.fnum;
1946 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1948 torture_comment(tctx, "ntrename should trigger a break\n");
1950 rn.generic.level = RAW_RENAME_NTRENAME;
1951 rn.ntrename.in.attrib = 0;
1952 rn.ntrename.in.flags = RENAME_FLAG_RENAME;
1953 rn.ntrename.in.old_name = fname1;
1954 rn.ntrename.in.new_name = fname2;
1955 printf("trying rename while first file open\n");
1956 status = smb_raw_rename(cli2->tree, &rn);
1958 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
1959 CHECK_VAL(break_info.count, 1);
1960 CHECK_VAL(break_info.failures, 0);
1961 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
1963 smbcli_close(cli1->tree, fnum);
1966 smb_raw_exit(cli1->session);
1967 smb_raw_exit(cli2->session);
1968 smbcli_deltree(cli1->tree, BASEDIR);
1972 static bool test_raw_oplock_batch19(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1974 const char *fname1 = BASEDIR "\\test_batch19_1.dat";
1975 const char *fname2 = BASEDIR "\\test_batch19_2.dat";
1976 const char *fname3 = BASEDIR "\\test_batch19_3.dat";
1980 union smb_fileinfo qfi;
1981 union smb_setfileinfo sfi;
1984 if (torture_setting_bool(tctx, "samba3", false)) {
1985 torture_skip(tctx, "BACHT19 disabled against samba3\n");
1988 if (!torture_setup_dir(cli1, BASEDIR)) {
1993 smbcli_unlink(cli1->tree, fname1);
1994 smbcli_unlink(cli1->tree, fname2);
1995 smbcli_unlink(cli1->tree, fname3);
1997 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
2000 base ntcreatex parms
2002 io.generic.level = RAW_OPEN_NTCREATEX;
2003 io.ntcreatex.in.root_fid = 0;
2004 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2005 io.ntcreatex.in.alloc_size = 0;
2006 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2007 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2008 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2009 io.ntcreatex.in.create_options = 0;
2010 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2011 io.ntcreatex.in.security_flags = 0;
2012 io.ntcreatex.in.fname = fname1;
2014 torture_comment(tctx, "open a file with an batch oplock (share mode: none)\n");
2015 ZERO_STRUCT(break_info);
2016 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2017 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2018 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2019 status = smb_raw_open(cli1->tree, tctx, &io);
2020 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2021 fnum = io.ntcreatex.out.file.fnum;
2022 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
2024 torture_comment(tctx, "setpathinfo rename info should not trigger a break nor a violation\n");
2026 sfi.generic.level = RAW_SFILEINFO_RENAME_INFORMATION;
2027 sfi.generic.in.file.path = fname1;
2028 sfi.rename_information.in.overwrite = 0;
2029 sfi.rename_information.in.root_fid = 0;
2030 sfi.rename_information.in.new_name = fname2+strlen(BASEDIR)+1;
2032 status = smb_raw_setpathinfo(cli2->tree, &sfi);
2034 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2035 CHECK_VAL(break_info.count, 0);
2038 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2039 qfi.generic.in.file.fnum = fnum;
2041 status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
2042 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2043 CHECK_STRMATCH(qfi.all_info.out.fname.s, fname2);
2045 torture_comment(tctx, "setfileinfo rename info should not trigger a break nor a violation\n");
2047 sfi.generic.level = RAW_SFILEINFO_RENAME_INFORMATION;
2048 sfi.generic.in.file.fnum = fnum;
2049 sfi.rename_information.in.overwrite = 0;
2050 sfi.rename_information.in.root_fid = 0;
2051 sfi.rename_information.in.new_name = fname3+strlen(BASEDIR)+1;
2053 status = smb_raw_setfileinfo(cli1->tree, &sfi);
2054 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2055 CHECK_VAL(break_info.count, 0);
2058 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2059 qfi.generic.in.file.fnum = fnum;
2061 status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
2062 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2063 CHECK_STRMATCH(qfi.all_info.out.fname.s, fname3);
2065 smbcli_close(cli1->tree, fnum);
2068 smb_raw_exit(cli1->session);
2069 smb_raw_exit(cli2->session);
2070 smbcli_deltree(cli1->tree, BASEDIR);
2074 static bool test_raw_oplock_batch20(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
2076 const char *fname1 = BASEDIR "\\test_batch20_1.dat";
2077 const char *fname2 = BASEDIR "\\test_batch20_2.dat";
2078 const char *fname3 = BASEDIR "\\test_batch20_3.dat";
2082 union smb_fileinfo qfi;
2083 union smb_setfileinfo sfi;
2084 uint16_t fnum=0,fnum2=0;
2086 if (torture_setting_bool(tctx, "samba3", false)) {
2087 torture_skip(tctx, "BACHT20 disabled against samba3\n");
2090 if (!torture_setup_dir(cli1, BASEDIR)) {
2095 smbcli_unlink(cli1->tree, fname1);
2096 smbcli_unlink(cli1->tree, fname2);
2097 smbcli_unlink(cli1->tree, fname3);
2099 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
2102 base ntcreatex parms
2104 io.generic.level = RAW_OPEN_NTCREATEX;
2105 io.ntcreatex.in.root_fid = 0;
2106 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2107 io.ntcreatex.in.alloc_size = 0;
2108 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2109 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2110 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2111 io.ntcreatex.in.create_options = 0;
2112 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2113 io.ntcreatex.in.security_flags = 0;
2114 io.ntcreatex.in.fname = fname1;
2116 torture_comment(tctx, "open a file with an batch oplock (share mode: all)\n");
2117 ZERO_STRUCT(break_info);
2118 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2119 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2120 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2121 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
2122 NTCREATEX_SHARE_ACCESS_WRITE|
2123 NTCREATEX_SHARE_ACCESS_DELETE;
2124 status = smb_raw_open(cli1->tree, tctx, &io);
2125 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2126 fnum = io.ntcreatex.out.file.fnum;
2127 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
2129 torture_comment(tctx, "setpathinfo rename info should not trigger a break nor a violation\n");
2131 sfi.generic.level = RAW_SFILEINFO_RENAME_INFORMATION;
2132 sfi.generic.in.file.path = fname1;
2133 sfi.rename_information.in.overwrite = 0;
2134 sfi.rename_information.in.root_fid = 0;
2135 sfi.rename_information.in.new_name = fname2+strlen(BASEDIR)+1;
2137 status = smb_raw_setpathinfo(cli2->tree, &sfi);
2139 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2140 CHECK_VAL(break_info.count, 0);
2143 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2144 qfi.generic.in.file.fnum = fnum;
2146 status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
2147 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2148 CHECK_STRMATCH(qfi.all_info.out.fname.s, fname2);
2150 /* we should use no share mode, when samba3 passes this */
2151 torture_comment(tctx, "open a file with the new name an batch oplock (share mode: all)\n");
2152 ZERO_STRUCT(break_info);
2153 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2154 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2155 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2156 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
2157 NTCREATEX_SHARE_ACCESS_WRITE|
2158 NTCREATEX_SHARE_ACCESS_DELETE;
2159 io.ntcreatex.in.fname = fname2;
2160 status = smb_raw_open(cli2->tree, tctx, &io);
2161 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2162 fnum2 = io.ntcreatex.out.file.fnum;
2163 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
2164 CHECK_VAL(break_info.count, 1);
2165 CHECK_VAL(break_info.failures, 0);
2166 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
2168 torture_comment(tctx, "setfileinfo rename info should not trigger a break nor a violation\n");
2170 sfi.generic.level = RAW_SFILEINFO_RENAME_INFORMATION;
2171 sfi.generic.in.file.fnum = fnum;
2172 sfi.rename_information.in.overwrite = 0;
2173 sfi.rename_information.in.root_fid = 0;
2174 sfi.rename_information.in.new_name = fname3+strlen(BASEDIR)+1;
2176 status = smb_raw_setfileinfo(cli1->tree, &sfi);
2177 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2178 CHECK_VAL(break_info.count, 1);
2179 CHECK_VAL(break_info.failures, 0);
2180 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
2183 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2184 qfi.generic.in.file.fnum = fnum;
2186 status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
2187 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2188 CHECK_STRMATCH(qfi.all_info.out.fname.s, fname3);
2191 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2192 qfi.generic.in.file.fnum = fnum2;
2194 status = smb_raw_fileinfo(cli2->tree, tctx, &qfi);
2195 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2196 CHECK_STRMATCH(qfi.all_info.out.fname.s, fname3);
2198 smbcli_close(cli1->tree, fnum);
2201 smb_raw_exit(cli1->session);
2202 smb_raw_exit(cli2->session);
2203 smbcli_deltree(cli1->tree, BASEDIR);
2208 basic testing of oplocks
2210 struct torture_suite *torture_raw_oplock(TALLOC_CTX *mem_ctx)
2212 struct torture_suite *suite = torture_suite_create(mem_ctx, "OPLOCK");
2214 torture_suite_add_2smb_test(suite, "EXCLUSIVE1", test_raw_oplock_exclusive1);
2215 torture_suite_add_2smb_test(suite, "EXCLUSIVE2", test_raw_oplock_exclusive2);
2216 torture_suite_add_2smb_test(suite, "EXCLUSIVE3", test_raw_oplock_exclusive3);
2217 torture_suite_add_2smb_test(suite, "EXCLUSIVE4", test_raw_oplock_exclusive4);
2218 torture_suite_add_2smb_test(suite, "EXCLUSIVE5", test_raw_oplock_exclusive5);
2219 torture_suite_add_2smb_test(suite, "EXCLUSIVE6", test_raw_oplock_exclusive6);
2220 torture_suite_add_2smb_test(suite, "BATCH1", test_raw_oplock_batch1);
2221 torture_suite_add_2smb_test(suite, "BATCH2", test_raw_oplock_batch2);
2222 torture_suite_add_2smb_test(suite, "BATCH3", test_raw_oplock_batch3);
2223 torture_suite_add_2smb_test(suite, "BATCH4", test_raw_oplock_batch4);
2224 torture_suite_add_2smb_test(suite, "BATCH5", test_raw_oplock_batch5);
2225 torture_suite_add_2smb_test(suite, "BATCH6", test_raw_oplock_batch6);
2226 torture_suite_add_2smb_test(suite, "BATCH7", test_raw_oplock_batch7);
2227 torture_suite_add_2smb_test(suite, "BATCH8", test_raw_oplock_batch8);
2228 torture_suite_add_2smb_test(suite, "BATCH9", test_raw_oplock_batch9);
2229 torture_suite_add_2smb_test(suite, "BATCH10", test_raw_oplock_batch10);
2230 torture_suite_add_2smb_test(suite, "BATCH11", test_raw_oplock_batch11);
2231 torture_suite_add_2smb_test(suite, "BATCH12", test_raw_oplock_batch12);
2232 torture_suite_add_2smb_test(suite, "BATCH13", test_raw_oplock_batch13);
2233 torture_suite_add_2smb_test(suite, "BATCH14", test_raw_oplock_batch14);
2234 torture_suite_add_2smb_test(suite, "BATCH15", test_raw_oplock_batch15);
2235 torture_suite_add_2smb_test(suite, "BATCH16", test_raw_oplock_batch16);
2236 torture_suite_add_2smb_test(suite, "BATCH17", test_raw_oplock_batch17);
2237 torture_suite_add_2smb_test(suite, "BATCH18", test_raw_oplock_batch18);
2238 torture_suite_add_2smb_test(suite, "BATCH19", test_raw_oplock_batch19);
2239 torture_suite_add_2smb_test(suite, "BATCH20", test_raw_oplock_batch20);
2245 stress testing of oplocks
2247 bool torture_bench_oplock(struct torture_context *torture)
2249 struct smbcli_state **cli;
2251 TALLOC_CTX *mem_ctx = talloc_new(torture);
2252 int torture_nprocs = torture_setting_int(torture, "nprocs", 4);
2254 int timelimit = torture_setting_int(torture, "timelimit", 10);
2257 struct event_context *ev = event_context_find(mem_ctx);
2259 cli = talloc_array(mem_ctx, struct smbcli_state *, torture_nprocs);
2261 torture_comment(torture, "Opening %d connections\n", torture_nprocs);
2262 for (i=0;i<torture_nprocs;i++) {
2263 if (!torture_open_connection_ev(&cli[i], i, torture, ev)) {
2266 talloc_steal(mem_ctx, cli[i]);
2267 smbcli_oplock_handler(cli[i]->transport, oplock_handler_close,
2271 if (!torture_setup_dir(cli[0], BASEDIR)) {
2276 io.ntcreatex.level = RAW_OPEN_NTCREATEX;
2277 io.ntcreatex.in.root_fid = 0;
2278 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2279 io.ntcreatex.in.alloc_size = 0;
2280 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2281 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2282 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2283 io.ntcreatex.in.create_options = 0;
2284 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2285 io.ntcreatex.in.security_flags = 0;
2286 io.ntcreatex.in.fname = BASEDIR "\\test.dat";
2287 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2288 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2289 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2291 tv = timeval_current();
2294 we open the same file with SHARE_ACCESS_NONE from all the
2295 connections in a round robin fashion. Each open causes an
2296 oplock break on the previous connection, which is answered
2297 by the oplock_handler_close() to close the file.
2299 This measures how fast we can pass on oplocks, and stresses
2300 the oplock handling code
2302 torture_comment(torture, "Running for %d seconds\n", timelimit);
2303 while (timeval_elapsed(&tv) < timelimit) {
2304 for (i=0;i<torture_nprocs;i++) {
2307 status = smb_raw_open(cli[i]->tree, mem_ctx, &io);
2308 CHECK_STATUS(torture, status, NT_STATUS_OK);
2312 if (torture_setting_bool(torture, "progress", true)) {
2313 torture_comment(torture, "%.2f ops/second\r", count/timeval_elapsed(&tv));
2317 torture_comment(torture, "%.2f ops/second\n", count/timeval_elapsed(&tv));
2319 smb_raw_exit(cli[torture_nprocs-1]->session);
2322 smb_raw_exit(cli[0]->session);
2323 smbcli_deltree(cli[0]->tree, BASEDIR);
2324 talloc_free(mem_ctx);
2329 static struct hold_oplock_info {
2331 bool close_on_break;
2332 uint32_t share_access;
2335 { BASEDIR "\\notshared_close", true,
2336 NTCREATEX_SHARE_ACCESS_NONE, },
2337 { BASEDIR "\\notshared_noclose", false,
2338 NTCREATEX_SHARE_ACCESS_NONE, },
2339 { BASEDIR "\\shared_close", true,
2340 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE, },
2341 { BASEDIR "\\shared_noclose", false,
2342 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE, },
2345 static bool oplock_handler_hold(struct smbcli_transport *transport,
2346 uint16_t tid, uint16_t fnum, uint8_t level,
2349 struct smbcli_tree *tree = (struct smbcli_tree *)private;
2350 struct hold_oplock_info *info;
2353 for (i=0;i<ARRAY_SIZE(hold_info);i++) {
2354 if (hold_info[i].fnum == fnum) break;
2357 if (i == ARRAY_SIZE(hold_info)) {
2358 printf("oplock break for unknown fnum %u\n", fnum);
2362 info = &hold_info[i];
2364 if (info->close_on_break) {
2365 printf("oplock break on %s - closing\n",
2367 oplock_handler_close(transport, tid, fnum, level, private);
2371 printf("oplock break on %s - acking break\n", info->fname);
2373 return smbcli_oplock_ack(tree, fnum, OPLOCK_BREAK_TO_NONE);
2378 used for manual testing of oplocks - especially interaction with
2379 other filesystems (such as NFS and local access)
2381 bool torture_hold_oplock(struct torture_context *torture,
2382 struct smbcli_state *cli)
2384 struct event_context *ev =
2385 (struct event_context *)cli->transport->socket->event.ctx;
2388 printf("Setting up open files with oplocks in %s\n", BASEDIR);
2390 if (!torture_setup_dir(cli, BASEDIR)) {
2394 smbcli_oplock_handler(cli->transport, oplock_handler_hold, cli->tree);
2396 /* setup the files */
2397 for (i=0;i<ARRAY_SIZE(hold_info);i++) {
2402 io.generic.level = RAW_OPEN_NTCREATEX;
2403 io.ntcreatex.in.root_fid = 0;
2404 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2405 io.ntcreatex.in.alloc_size = 0;
2406 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2407 io.ntcreatex.in.share_access = hold_info[i].share_access;
2408 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2409 io.ntcreatex.in.create_options = 0;
2410 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2411 io.ntcreatex.in.security_flags = 0;
2412 io.ntcreatex.in.fname = hold_info[i].fname;
2413 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2414 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2415 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2416 printf("opening %s\n", hold_info[i].fname);
2418 status = smb_raw_open(cli->tree, cli, &io);
2419 if (!NT_STATUS_IS_OK(status)) {
2420 printf("Failed to open %s - %s\n",
2421 hold_info[i].fname, nt_errstr(status));
2425 if (io.ntcreatex.out.oplock_level != BATCH_OPLOCK_RETURN) {
2426 printf("Oplock not granted for %s - expected %d but got %d\n",
2427 hold_info[i].fname, BATCH_OPLOCK_RETURN,
2428 io.ntcreatex.out.oplock_level);
2431 hold_info[i].fnum = io.ntcreatex.out.file.fnum;
2433 /* make the file non-zero size */
2434 if (smbcli_write(cli->tree, hold_info[i].fnum, 0, &c, 0, 1) != 1) {
2435 printf("Failed to write to file\n");
2440 printf("Waiting for oplock events\n");
2441 event_loop_wait(ev);