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"
27 #include "param/param.h"
28 #include "lib/cmdline/popt_common.h"
29 #include "libcli/resolve/resolve.h"
31 #define CHECK_VAL(v, correct) do { \
32 if ((v) != (correct)) { \
33 torture_result(tctx, TORTURE_FAIL, "(%s): wrong value for %s got 0x%x - should be 0x%x\n", \
34 __location__, #v, (int)v, (int)correct); \
38 #define CHECK_RANGE(v, min, max) do { \
39 if ((v) < (min) || (v) > (max)) { \
40 torture_result(tctx, TORTURE_FAIL, "(%s): wrong value for %s got %d - should be between %d and %d\n", \
41 __location__, #v, (int)v, (int)min, (int)max); \
45 #define CHECK_STRMATCH(v, correct) do { \
46 if (!v || strstr((v),(correct)) == NULL) { \
47 torture_result(tctx, TORTURE_FAIL, "(%s): wrong value for %s got '%s' - should be '%s'\n", \
48 __location__, #v, v?v:"NULL", correct); \
53 #define CHECK_STATUS(tctx, status, correct) do { \
54 if (!NT_STATUS_EQUAL(status, correct)) { \
55 torture_result(tctx, TORTURE_FAIL, __location__": Incorrect status %s - should be %s", \
56 nt_errstr(status), nt_errstr(correct)); \
69 #define BASEDIR "\\test_oplock"
72 a handler function for oplock break requests. Ack it as a break to level II if possible
74 static bool oplock_handler_ack_to_levelII(struct smbcli_transport *transport,
75 uint16_t tid, uint16_t fnum,
76 uint8_t level, void *private)
78 struct smbcli_tree *tree = (struct smbcli_tree *)private;
79 break_info.fnum = fnum;
80 break_info.level = level;
83 printf("Acking to level II in oplock handler\n");
85 return smbcli_oplock_ack(tree, fnum, level);
89 a handler function for oplock break requests. Ack it as a break to none
91 static bool oplock_handler_ack_to_none(struct smbcli_transport *transport,
92 uint16_t tid, uint16_t fnum,
93 uint8_t level, void *private)
95 struct smbcli_tree *tree = (struct smbcli_tree *)private;
96 break_info.fnum = fnum;
97 break_info.level = level;
100 printf("Acking to none in oplock handler\n");
102 return smbcli_oplock_ack(tree, fnum, OPLOCK_BREAK_TO_NONE);
106 a handler function for oplock break requests. Let it timeout
108 static bool oplock_handler_timeout(struct smbcli_transport *transport,
109 uint16_t tid, uint16_t fnum,
110 uint8_t level, void *private)
112 break_info.fnum = fnum;
113 break_info.level = level;
116 printf("Let oplock break timeout\n");
120 static void oplock_handler_close_recv(struct smbcli_request *req)
123 status = smbcli_request_simple_recv(req);
124 if (!NT_STATUS_IS_OK(status)) {
125 printf("close failed in oplock_handler_close\n");
126 break_info.failures++;
131 a handler function for oplock break requests - close the file
133 static bool oplock_handler_close(struct smbcli_transport *transport, uint16_t tid,
134 uint16_t fnum, uint8_t level, void *private)
137 struct smbcli_tree *tree = (struct smbcli_tree *)private;
138 struct smbcli_request *req;
140 break_info.fnum = fnum;
141 break_info.level = level;
144 io.close.level = RAW_CLOSE_CLOSE;
145 io.close.in.file.fnum = fnum;
146 io.close.in.write_time = 0;
147 req = smb_raw_close_send(tree, &io);
149 printf("failed to send close in oplock_handler_close\n");
153 req->async.fn = oplock_handler_close_recv;
154 req->async.private = NULL;
159 static bool open_connection_no_level2_oplocks(struct torture_context *tctx,
160 struct smbcli_state **c)
164 struct smbcli_options options;
166 lp_smbcli_options(tctx->lp_ctx, &options);
168 options.use_level2_oplocks = false;
170 status = smbcli_full_connection(tctx, c,
171 torture_setting_string(tctx, "host", NULL),
172 lp_smb_ports(tctx->lp_ctx),
173 torture_setting_string(tctx, "share", NULL),
174 NULL, cmdline_credentials,
175 lp_resolve_context(tctx->lp_ctx),
177 if (!NT_STATUS_IS_OK(status)) {
178 printf("Failed to open connection - %s\n", nt_errstr(status));
185 static bool test_raw_oplock_exclusive1(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
187 const char *fname = BASEDIR "\\test_exclusive1.dat";
191 union smb_unlink unl;
194 if (!torture_setup_dir(cli1, BASEDIR)) {
199 smbcli_unlink(cli1->tree, fname);
201 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
206 io.generic.level = RAW_OPEN_NTCREATEX;
207 io.ntcreatex.in.root_fid = 0;
208 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
209 io.ntcreatex.in.alloc_size = 0;
210 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
211 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
212 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
213 io.ntcreatex.in.create_options = 0;
214 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
215 io.ntcreatex.in.security_flags = 0;
216 io.ntcreatex.in.fname = fname;
218 torture_comment(tctx, "open a file with an exclusive oplock (share mode: none)\n");
219 ZERO_STRUCT(break_info);
220 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
222 status = smb_raw_open(cli1->tree, tctx, &io);
223 CHECK_STATUS(tctx, status, NT_STATUS_OK);
224 fnum = io.ntcreatex.out.file.fnum;
225 CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
227 torture_comment(tctx, "a 2nd open should not cause a break\n");
228 status = smb_raw_open(cli2->tree, tctx, &io);
229 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
230 CHECK_VAL(break_info.count, 0);
231 CHECK_VAL(break_info.failures, 0);
233 torture_comment(tctx, "unlink it - should also be no break\n");
234 unl.unlink.in.pattern = fname;
235 unl.unlink.in.attrib = 0;
236 status = smb_raw_unlink(cli2->tree, &unl);
237 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
238 CHECK_VAL(break_info.count, 0);
239 CHECK_VAL(break_info.failures, 0);
241 smbcli_close(cli1->tree, fnum);
244 smb_raw_exit(cli1->session);
245 smb_raw_exit(cli2->session);
246 smbcli_deltree(cli1->tree, BASEDIR);
250 static bool test_raw_oplock_exclusive2(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
252 const char *fname = BASEDIR "\\test_exclusive2.dat";
256 union smb_unlink unl;
257 uint16_t fnum=0, fnum2=0;
259 if (!torture_setup_dir(cli1, BASEDIR)) {
264 smbcli_unlink(cli1->tree, fname);
266 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
271 io.generic.level = RAW_OPEN_NTCREATEX;
272 io.ntcreatex.in.root_fid = 0;
273 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
274 io.ntcreatex.in.alloc_size = 0;
275 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
276 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
277 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
278 io.ntcreatex.in.create_options = 0;
279 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
280 io.ntcreatex.in.security_flags = 0;
281 io.ntcreatex.in.fname = fname;
283 torture_comment(tctx, "open a file with an exclusive oplock (share mode: all)\n");
284 ZERO_STRUCT(break_info);
285 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
286 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
287 NTCREATEX_SHARE_ACCESS_WRITE|
288 NTCREATEX_SHARE_ACCESS_DELETE;
290 status = smb_raw_open(cli1->tree, tctx, &io);
291 CHECK_STATUS(tctx, status, NT_STATUS_OK);
292 fnum = io.ntcreatex.out.file.fnum;
293 CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
295 torture_comment(tctx, "a 2nd open should cause a break to level 2\n");
296 status = smb_raw_open(cli2->tree, tctx, &io);
297 CHECK_STATUS(tctx, status, NT_STATUS_OK);
298 fnum2 = io.ntcreatex.out.file.fnum;
299 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
300 CHECK_VAL(break_info.count, 1);
301 CHECK_VAL(break_info.fnum, fnum);
302 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
303 CHECK_VAL(break_info.failures, 0);
304 ZERO_STRUCT(break_info);
306 /* now we have 2 level II oplocks... */
307 torture_comment(tctx, "try to unlink it - should not cause a break, but a sharing violation\n");
308 unl.unlink.in.pattern = fname;
309 unl.unlink.in.attrib = 0;
310 status = smb_raw_unlink(cli2->tree, &unl);
311 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
312 CHECK_VAL(break_info.count, 0);
313 CHECK_VAL(break_info.failures, 0);
315 torture_comment(tctx, "close 1st handle\n");
316 smbcli_close(cli1->tree, fnum);
318 torture_comment(tctx, "try to unlink it - should not cause a break, but a sharing violation\n");
319 unl.unlink.in.pattern = fname;
320 unl.unlink.in.attrib = 0;
321 status = smb_raw_unlink(cli2->tree, &unl);
322 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
323 CHECK_VAL(break_info.count, 0);
324 CHECK_VAL(break_info.failures, 0);
326 torture_comment(tctx, "close 1st handle\n");
327 smbcli_close(cli2->tree, fnum2);
329 torture_comment(tctx, "unlink it\n");
330 unl.unlink.in.pattern = fname;
331 unl.unlink.in.attrib = 0;
332 status = smb_raw_unlink(cli2->tree, &unl);
333 CHECK_STATUS(tctx, status, NT_STATUS_OK);
334 CHECK_VAL(break_info.count, 0);
335 CHECK_VAL(break_info.failures, 0);
338 smb_raw_exit(cli1->session);
339 smb_raw_exit(cli2->session);
340 smbcli_deltree(cli1->tree, BASEDIR);
344 static bool test_raw_oplock_exclusive3(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
346 const char *fname = BASEDIR "\\test_exclusive3.dat";
350 union smb_setfileinfo sfi;
352 bool s3 = torture_setting_bool(tctx, "samba3", false);
354 if (!torture_setup_dir(cli1, BASEDIR)) {
359 smbcli_unlink(cli1->tree, fname);
361 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
366 io.generic.level = RAW_OPEN_NTCREATEX;
367 io.ntcreatex.in.root_fid = 0;
368 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
369 io.ntcreatex.in.alloc_size = 0;
370 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
371 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
372 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
373 io.ntcreatex.in.create_options = 0;
374 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
375 io.ntcreatex.in.security_flags = 0;
376 io.ntcreatex.in.fname = fname;
378 torture_comment(tctx, "open a file with an exclusive oplock (share mode: %s)\n",
380 ZERO_STRUCT(break_info);
381 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
383 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
384 NTCREATEX_SHARE_ACCESS_WRITE|
385 NTCREATEX_SHARE_ACCESS_DELETE;
388 status = smb_raw_open(cli1->tree, tctx, &io);
389 CHECK_STATUS(tctx, status, NT_STATUS_OK);
390 fnum = io.ntcreatex.out.file.fnum;
391 CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
393 torture_comment(tctx, "setpathinfo EOF should trigger a break to none\n");
395 sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
396 sfi.generic.in.file.path = fname;
397 sfi.end_of_file_info.in.size = 100;
399 status = smb_raw_setpathinfo(cli2->tree, &sfi);
401 CHECK_STATUS(tctx, status, NT_STATUS_OK);
402 CHECK_VAL(break_info.count, 1);
403 CHECK_VAL(break_info.failures, 0);
404 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_NONE);
406 smbcli_close(cli1->tree, fnum);
409 smb_raw_exit(cli1->session);
410 smb_raw_exit(cli2->session);
411 smbcli_deltree(cli1->tree, BASEDIR);
415 static bool test_raw_oplock_exclusive4(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
417 const char *fname = BASEDIR "\\test_exclusive4.dat";
421 uint16_t fnum=0, fnum2=0;
423 if (!torture_setup_dir(cli1, BASEDIR)) {
428 smbcli_unlink(cli1->tree, fname);
430 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
435 io.generic.level = RAW_OPEN_NTCREATEX;
436 io.ntcreatex.in.root_fid = 0;
437 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
438 io.ntcreatex.in.alloc_size = 0;
439 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
440 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
441 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
442 io.ntcreatex.in.create_options = 0;
443 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
444 io.ntcreatex.in.security_flags = 0;
445 io.ntcreatex.in.fname = fname;
447 torture_comment(tctx, "open with exclusive oplock\n");
448 ZERO_STRUCT(break_info);
449 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
451 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
452 status = smb_raw_open(cli1->tree, tctx, &io);
453 CHECK_STATUS(tctx, status, NT_STATUS_OK);
454 fnum = io.ntcreatex.out.file.fnum;
455 CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
457 ZERO_STRUCT(break_info);
458 torture_comment(tctx, "second open with attributes only shouldn't cause oplock break\n");
460 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
461 io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
462 status = smb_raw_open(cli2->tree, tctx, &io);
463 CHECK_STATUS(tctx, status, NT_STATUS_OK);
464 fnum2 = io.ntcreatex.out.file.fnum;
465 CHECK_VAL(io.ntcreatex.out.oplock_level, NO_OPLOCK_RETURN);
466 CHECK_VAL(break_info.count, 0);
467 CHECK_VAL(break_info.failures, 0);
469 smbcli_close(cli1->tree, fnum);
470 smbcli_close(cli2->tree, fnum2);
473 smb_raw_exit(cli1->session);
474 smb_raw_exit(cli2->session);
475 smbcli_deltree(cli1->tree, BASEDIR);
479 static bool test_raw_oplock_exclusive5(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
481 const char *fname = BASEDIR "\\test_exclusive5.dat";
485 uint16_t fnum=0, fnum2=0;
487 if (!torture_setup_dir(cli1, BASEDIR)) {
492 smbcli_unlink(cli1->tree, fname);
494 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
495 smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_levelII, cli1->tree);
500 io.generic.level = RAW_OPEN_NTCREATEX;
501 io.ntcreatex.in.root_fid = 0;
502 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
503 io.ntcreatex.in.alloc_size = 0;
504 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
505 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
506 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
507 io.ntcreatex.in.create_options = 0;
508 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
509 io.ntcreatex.in.security_flags = 0;
510 io.ntcreatex.in.fname = fname;
512 torture_comment(tctx, "open with exclusive oplock\n");
513 ZERO_STRUCT(break_info);
514 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
517 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
518 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
519 NTCREATEX_SHARE_ACCESS_WRITE|
520 NTCREATEX_SHARE_ACCESS_DELETE;
521 status = smb_raw_open(cli1->tree, tctx, &io);
522 CHECK_STATUS(tctx, status, NT_STATUS_OK);
523 fnum = io.ntcreatex.out.file.fnum;
524 CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
526 ZERO_STRUCT(break_info);
528 torture_comment(tctx, "second open with attributes only and NTCREATEX_DISP_OVERWRITE_IF dispostion causes oplock break\n");
530 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
531 io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
532 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE_IF;
533 status = smb_raw_open(cli2->tree, tctx, &io);
534 CHECK_STATUS(tctx, status, NT_STATUS_OK);
535 fnum2 = io.ntcreatex.out.file.fnum;
536 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
537 CHECK_VAL(break_info.count, 1);
538 CHECK_VAL(break_info.failures, 0);
540 smbcli_close(cli1->tree, fnum);
541 smbcli_close(cli2->tree, fnum2);
544 smb_raw_exit(cli1->session);
545 smb_raw_exit(cli2->session);
546 smbcli_deltree(cli1->tree, BASEDIR);
550 static bool test_raw_oplock_exclusive6(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
552 const char *fname1 = BASEDIR "\\test_exclusive6_1.dat";
553 const char *fname2 = BASEDIR "\\test_exclusive6_2.dat";
559 bool s3 = torture_setting_bool(tctx, "samba3", false);
561 if (!torture_setup_dir(cli1, BASEDIR)) {
566 smbcli_unlink(cli1->tree, fname1);
567 smbcli_unlink(cli1->tree, fname2);
569 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
574 io.generic.level = RAW_OPEN_NTCREATEX;
575 io.ntcreatex.in.root_fid = 0;
576 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
577 io.ntcreatex.in.alloc_size = 0;
578 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
579 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
580 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
581 io.ntcreatex.in.create_options = 0;
582 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
583 io.ntcreatex.in.security_flags = 0;
584 io.ntcreatex.in.fname = fname1;
586 /* we should use no share mode, when samba3 passes this */
587 torture_comment(tctx, "open a file with an exclusive oplock (share mode: %s)\n",
589 ZERO_STRUCT(break_info);
590 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
592 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
593 NTCREATEX_SHARE_ACCESS_WRITE|
594 NTCREATEX_SHARE_ACCESS_DELETE;
597 status = smb_raw_open(cli1->tree, tctx, &io);
598 CHECK_STATUS(tctx, status, NT_STATUS_OK);
599 fnum = io.ntcreatex.out.file.fnum;
600 CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
602 torture_comment(tctx, "rename should not generate a break but get a sharing violation\n");
604 rn.generic.level = RAW_RENAME_RENAME;
605 rn.rename.in.pattern1 = fname1;
606 rn.rename.in.pattern2 = fname2;
607 rn.rename.in.attrib = 0;
609 printf("trying rename while first file open\n");
610 status = smb_raw_rename(cli2->tree, &rn);
612 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
613 CHECK_VAL(break_info.count, 0);
614 CHECK_VAL(break_info.failures, 0);
616 smbcli_close(cli1->tree, fnum);
619 smb_raw_exit(cli1->session);
620 smb_raw_exit(cli2->session);
621 smbcli_deltree(cli1->tree, BASEDIR);
625 static bool test_raw_oplock_batch1(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
627 const char *fname = BASEDIR "\\test_batch1.dat";
631 union smb_unlink unl;
635 if (!torture_setup_dir(cli1, BASEDIR)) {
640 smbcli_unlink(cli1->tree, fname);
642 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
647 io.generic.level = RAW_OPEN_NTCREATEX;
648 io.ntcreatex.in.root_fid = 0;
649 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
650 io.ntcreatex.in.alloc_size = 0;
651 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
652 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
653 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
654 io.ntcreatex.in.create_options = 0;
655 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
656 io.ntcreatex.in.security_flags = 0;
657 io.ntcreatex.in.fname = fname;
660 with a batch oplock we get a break
662 torture_comment(tctx, "open with batch oplock\n");
663 ZERO_STRUCT(break_info);
664 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
665 NTCREATEX_FLAGS_REQUEST_OPLOCK |
666 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
667 status = smb_raw_open(cli1->tree, tctx, &io);
668 CHECK_STATUS(tctx, status, NT_STATUS_OK);
669 fnum = io.ntcreatex.out.file.fnum;
670 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
672 torture_comment(tctx, "unlink should generate a break\n");
673 unl.unlink.in.pattern = fname;
674 unl.unlink.in.attrib = 0;
675 status = smb_raw_unlink(cli2->tree, &unl);
676 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
678 CHECK_VAL(break_info.count, 1);
679 CHECK_VAL(break_info.fnum, fnum);
680 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
681 CHECK_VAL(break_info.failures, 0);
683 torture_comment(tctx, "2nd unlink should not generate a break\n");
684 ZERO_STRUCT(break_info);
685 status = smb_raw_unlink(cli2->tree, &unl);
686 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
688 CHECK_VAL(break_info.count, 0);
690 torture_comment(tctx, "writing should generate a self break to none\n");
691 smbcli_write(cli1->tree, fnum, 0, &c, 0, 1);
693 smbcli_write(cli1->tree, fnum, 0, &c, 1, 1);
695 CHECK_VAL(break_info.count, 1);
696 CHECK_VAL(break_info.fnum, fnum);
697 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_NONE);
698 CHECK_VAL(break_info.failures, 0);
700 smbcli_close(cli1->tree, fnum);
703 smb_raw_exit(cli1->session);
704 smb_raw_exit(cli2->session);
705 smbcli_deltree(cli1->tree, BASEDIR);
709 static bool test_raw_oplock_batch2(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
711 const char *fname = BASEDIR "\\test_batch2.dat";
715 union smb_unlink unl;
719 if (!torture_setup_dir(cli1, BASEDIR)) {
724 smbcli_unlink(cli1->tree, fname);
726 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
731 io.generic.level = RAW_OPEN_NTCREATEX;
732 io.ntcreatex.in.root_fid = 0;
733 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
734 io.ntcreatex.in.alloc_size = 0;
735 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
736 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
737 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
738 io.ntcreatex.in.create_options = 0;
739 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
740 io.ntcreatex.in.security_flags = 0;
741 io.ntcreatex.in.fname = fname;
743 torture_comment(tctx, "open with batch oplock\n");
744 ZERO_STRUCT(break_info);
745 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
746 NTCREATEX_FLAGS_REQUEST_OPLOCK |
747 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
748 status = smb_raw_open(cli1->tree, tctx, &io);
749 CHECK_STATUS(tctx, status, NT_STATUS_OK);
750 fnum = io.ntcreatex.out.file.fnum;
751 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
753 torture_comment(tctx, "unlink should generate a break, which we ack as break to none\n");
754 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_none, cli1->tree);
755 unl.unlink.in.pattern = fname;
756 unl.unlink.in.attrib = 0;
757 status = smb_raw_unlink(cli2->tree, &unl);
758 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
760 CHECK_VAL(break_info.count, 1);
761 CHECK_VAL(break_info.fnum, fnum);
762 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
763 CHECK_VAL(break_info.failures, 0);
765 torture_comment(tctx, "2nd unlink should not generate a break\n");
766 ZERO_STRUCT(break_info);
767 status = smb_raw_unlink(cli2->tree, &unl);
768 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
770 CHECK_VAL(break_info.count, 0);
772 torture_comment(tctx, "writing should not generate a break\n");
773 smbcli_write(cli1->tree, fnum, 0, &c, 0, 1);
775 smbcli_write(cli1->tree, fnum, 0, &c, 1, 1);
777 CHECK_VAL(break_info.count, 0);
779 smbcli_close(cli1->tree, fnum);
782 smb_raw_exit(cli1->session);
783 smb_raw_exit(cli2->session);
784 smbcli_deltree(cli1->tree, BASEDIR);
788 static bool test_raw_oplock_batch3(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
790 const char *fname = BASEDIR "\\test_batch3.dat";
794 union smb_unlink unl;
797 if (!torture_setup_dir(cli1, BASEDIR)) {
802 smbcli_unlink(cli1->tree, fname);
804 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
809 io.generic.level = RAW_OPEN_NTCREATEX;
810 io.ntcreatex.in.root_fid = 0;
811 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
812 io.ntcreatex.in.alloc_size = 0;
813 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
814 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
815 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
816 io.ntcreatex.in.create_options = 0;
817 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
818 io.ntcreatex.in.security_flags = 0;
819 io.ntcreatex.in.fname = fname;
821 torture_comment(tctx, "if we close on break then the unlink can succeed\n");
822 ZERO_STRUCT(break_info);
823 smbcli_oplock_handler(cli1->transport, oplock_handler_close, cli1->tree);
824 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
825 NTCREATEX_FLAGS_REQUEST_OPLOCK |
826 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
827 status = smb_raw_open(cli1->tree, tctx, &io);
828 CHECK_STATUS(tctx, status, NT_STATUS_OK);
829 fnum = io.ntcreatex.out.file.fnum;
830 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
832 unl.unlink.in.pattern = fname;
833 unl.unlink.in.attrib = 0;
834 ZERO_STRUCT(break_info);
835 status = smb_raw_unlink(cli2->tree, &unl);
836 CHECK_STATUS(tctx, status, NT_STATUS_OK);
838 CHECK_VAL(break_info.count, 1);
839 CHECK_VAL(break_info.fnum, fnum);
840 CHECK_VAL(break_info.level, 1);
841 CHECK_VAL(break_info.failures, 0);
843 smbcli_close(cli1->tree, fnum);
846 smb_raw_exit(cli1->session);
847 smb_raw_exit(cli2->session);
848 smbcli_deltree(cli1->tree, BASEDIR);
852 static bool test_raw_oplock_batch4(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
854 const char *fname = BASEDIR "\\test_batch4.dat";
861 if (!torture_setup_dir(cli1, BASEDIR)) {
866 smbcli_unlink(cli1->tree, fname);
868 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
873 io.generic.level = RAW_OPEN_NTCREATEX;
874 io.ntcreatex.in.root_fid = 0;
875 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
876 io.ntcreatex.in.alloc_size = 0;
877 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
878 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
879 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
880 io.ntcreatex.in.create_options = 0;
881 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
882 io.ntcreatex.in.security_flags = 0;
883 io.ntcreatex.in.fname = fname;
885 torture_comment(tctx, "a self read should not cause a break\n");
886 ZERO_STRUCT(break_info);
887 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
889 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
890 NTCREATEX_FLAGS_REQUEST_OPLOCK |
891 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
892 status = smb_raw_open(cli1->tree, tctx, &io);
893 CHECK_STATUS(tctx, status, NT_STATUS_OK);
894 fnum = io.ntcreatex.out.file.fnum;
895 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
897 rd.read.level = RAW_READ_READ;
898 rd.read.in.file.fnum = fnum;
899 rd.read.in.count = 1;
900 rd.read.in.offset = 0;
901 rd.read.in.remaining = 0;
902 status = smb_raw_read(cli1->tree, &rd);
903 CHECK_STATUS(tctx, status, NT_STATUS_OK);
904 CHECK_VAL(break_info.count, 0);
905 CHECK_VAL(break_info.failures, 0);
907 smbcli_close(cli1->tree, fnum);
910 smb_raw_exit(cli1->session);
911 smb_raw_exit(cli2->session);
912 smbcli_deltree(cli1->tree, BASEDIR);
916 static bool test_raw_oplock_batch5(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
918 const char *fname = BASEDIR "\\test_batch5.dat";
924 if (!torture_setup_dir(cli1, BASEDIR)) {
929 smbcli_unlink(cli1->tree, fname);
931 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
936 io.generic.level = RAW_OPEN_NTCREATEX;
937 io.ntcreatex.in.root_fid = 0;
938 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
939 io.ntcreatex.in.alloc_size = 0;
940 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
941 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
942 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
943 io.ntcreatex.in.create_options = 0;
944 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
945 io.ntcreatex.in.security_flags = 0;
946 io.ntcreatex.in.fname = fname;
948 torture_comment(tctx, "a 2nd open should give a break\n");
949 ZERO_STRUCT(break_info);
950 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
952 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
953 NTCREATEX_FLAGS_REQUEST_OPLOCK |
954 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
955 status = smb_raw_open(cli1->tree, tctx, &io);
956 CHECK_STATUS(tctx, status, NT_STATUS_OK);
957 fnum = io.ntcreatex.out.file.fnum;
958 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
960 ZERO_STRUCT(break_info);
962 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
963 status = smb_raw_open(cli2->tree, tctx, &io);
964 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
966 CHECK_VAL(break_info.count, 1);
967 CHECK_VAL(break_info.fnum, fnum);
968 CHECK_VAL(break_info.level, 1);
969 CHECK_VAL(break_info.failures, 0);
971 smbcli_close(cli1->tree, fnum);
974 smb_raw_exit(cli1->session);
975 smb_raw_exit(cli2->session);
976 smbcli_deltree(cli1->tree, BASEDIR);
980 static bool test_raw_oplock_batch6(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
982 const char *fname = BASEDIR "\\test_batch6.dat";
986 uint16_t fnum=0, fnum2=0;
989 if (!torture_setup_dir(cli1, BASEDIR)) {
994 smbcli_unlink(cli1->tree, fname);
996 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1001 io.generic.level = RAW_OPEN_NTCREATEX;
1002 io.ntcreatex.in.root_fid = 0;
1003 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1004 io.ntcreatex.in.alloc_size = 0;
1005 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1006 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1007 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1008 io.ntcreatex.in.create_options = 0;
1009 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1010 io.ntcreatex.in.security_flags = 0;
1011 io.ntcreatex.in.fname = fname;
1013 torture_comment(tctx, "a 2nd open should give a break to level II if the first open allowed shared read\n");
1014 ZERO_STRUCT(break_info);
1015 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1016 smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_levelII, cli2->tree);
1018 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_READ | SEC_RIGHTS_FILE_WRITE;
1019 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
1020 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1021 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1022 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1023 status = smb_raw_open(cli1->tree, tctx, &io);
1024 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1025 fnum = io.ntcreatex.out.file.fnum;
1026 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1028 ZERO_STRUCT(break_info);
1030 status = smb_raw_open(cli2->tree, tctx, &io);
1031 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1032 fnum2 = io.ntcreatex.out.file.fnum;
1033 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1035 CHECK_VAL(break_info.count, 1);
1036 CHECK_VAL(break_info.fnum, fnum);
1037 CHECK_VAL(break_info.level, 1);
1038 CHECK_VAL(break_info.failures, 0);
1039 ZERO_STRUCT(break_info);
1041 torture_comment(tctx, "write should trigger a break to none on both\n");
1042 smbcli_write(cli1->tree, fnum, 0, &c, 0, 1);
1044 smbcli_write(cli1->tree, fnum, 0, &c, 1, 1);
1046 CHECK_VAL(break_info.count, 2);
1047 CHECK_VAL(break_info.level, 0);
1048 CHECK_VAL(break_info.failures, 0);
1050 smbcli_close(cli1->tree, fnum);
1051 smbcli_close(cli2->tree, fnum2);
1055 smb_raw_exit(cli1->session);
1056 smb_raw_exit(cli2->session);
1057 smbcli_deltree(cli1->tree, BASEDIR);
1061 static bool test_raw_oplock_batch7(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1063 const char *fname = BASEDIR "\\test_batch7.dat";
1067 uint16_t fnum=0, fnum2=0;
1069 if (!torture_setup_dir(cli1, BASEDIR)) {
1074 smbcli_unlink(cli1->tree, fname);
1076 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1079 base ntcreatex parms
1081 io.generic.level = RAW_OPEN_NTCREATEX;
1082 io.ntcreatex.in.root_fid = 0;
1083 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1084 io.ntcreatex.in.alloc_size = 0;
1085 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1086 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1087 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1088 io.ntcreatex.in.create_options = 0;
1089 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1090 io.ntcreatex.in.security_flags = 0;
1091 io.ntcreatex.in.fname = fname;
1093 torture_comment(tctx, "a 2nd open should get an oplock when we close instead of ack\n");
1094 ZERO_STRUCT(break_info);
1095 smbcli_oplock_handler(cli1->transport, oplock_handler_close, cli1->tree);
1097 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1098 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1099 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1100 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1101 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1102 status = smb_raw_open(cli1->tree, tctx, &io);
1103 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1104 fnum2 = io.ntcreatex.out.file.fnum;
1105 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1107 ZERO_STRUCT(break_info);
1109 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1110 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1111 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1112 status = smb_raw_open(cli2->tree, tctx, &io);
1113 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1114 fnum = io.ntcreatex.out.file.fnum;
1115 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1117 CHECK_VAL(break_info.count, 1);
1118 CHECK_VAL(break_info.fnum, fnum2);
1119 CHECK_VAL(break_info.level, 1);
1120 CHECK_VAL(break_info.failures, 0);
1122 smbcli_close(cli2->tree, fnum);
1125 smb_raw_exit(cli1->session);
1126 smb_raw_exit(cli2->session);
1127 smbcli_deltree(cli1->tree, BASEDIR);
1131 static bool test_raw_oplock_batch8(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1133 const char *fname = BASEDIR "\\test_batch8.dat";
1137 uint16_t fnum=0, fnum2=0;
1139 if (!torture_setup_dir(cli1, BASEDIR)) {
1144 smbcli_unlink(cli1->tree, fname);
1146 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1149 base ntcreatex parms
1151 io.generic.level = RAW_OPEN_NTCREATEX;
1152 io.ntcreatex.in.root_fid = 0;
1153 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1154 io.ntcreatex.in.alloc_size = 0;
1155 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1156 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1157 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1158 io.ntcreatex.in.create_options = 0;
1159 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1160 io.ntcreatex.in.security_flags = 0;
1161 io.ntcreatex.in.fname = fname;
1163 torture_comment(tctx, "open with batch oplock\n");
1164 ZERO_STRUCT(break_info);
1165 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1167 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1168 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1169 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1170 status = smb_raw_open(cli1->tree, tctx, &io);
1171 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1172 fnum = io.ntcreatex.out.file.fnum;
1173 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1175 ZERO_STRUCT(break_info);
1176 torture_comment(tctx, "second open with attributes only shouldn't cause oplock break\n");
1178 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1179 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1180 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1181 io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
1182 status = smb_raw_open(cli2->tree, tctx, &io);
1183 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1184 fnum2 = io.ntcreatex.out.file.fnum;
1185 CHECK_VAL(io.ntcreatex.out.oplock_level, NO_OPLOCK_RETURN);
1186 CHECK_VAL(break_info.count, 0);
1187 CHECK_VAL(break_info.failures, 0);
1189 smbcli_close(cli1->tree, fnum);
1190 smbcli_close(cli2->tree, fnum2);
1193 smb_raw_exit(cli1->session);
1194 smb_raw_exit(cli2->session);
1195 smbcli_deltree(cli1->tree, BASEDIR);
1199 static bool test_raw_oplock_batch9(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1201 const char *fname = BASEDIR "\\test_batch9.dat";
1205 uint16_t fnum=0, fnum2=0;
1208 if (!torture_setup_dir(cli1, BASEDIR)) {
1213 smbcli_unlink(cli1->tree, fname);
1215 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1218 base ntcreatex parms
1220 io.generic.level = RAW_OPEN_NTCREATEX;
1221 io.ntcreatex.in.root_fid = 0;
1222 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1223 io.ntcreatex.in.alloc_size = 0;
1224 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1225 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1226 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1227 io.ntcreatex.in.create_options = 0;
1228 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1229 io.ntcreatex.in.security_flags = 0;
1230 io.ntcreatex.in.fname = fname;
1232 torture_comment(tctx, "open with attributes only can create file\n");
1234 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1235 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1236 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1237 io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
1238 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1239 status = smb_raw_open(cli1->tree, tctx, &io);
1240 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1241 fnum = io.ntcreatex.out.file.fnum;
1242 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1244 torture_comment(tctx, "Subsequent normal open should break oplock on attribute only open to level II\n");
1246 ZERO_STRUCT(break_info);
1247 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1249 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1250 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1251 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1252 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1253 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1254 status = smb_raw_open(cli2->tree, tctx, &io);
1255 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1256 fnum2 = io.ntcreatex.out.file.fnum;
1257 CHECK_VAL(break_info.count, 1);
1258 CHECK_VAL(break_info.fnum, fnum);
1259 CHECK_VAL(break_info.failures, 0);
1260 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
1261 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1262 smbcli_close(cli2->tree, fnum2);
1264 torture_comment(tctx, "third oplocked open should grant level2 without break\n");
1265 ZERO_STRUCT(break_info);
1266 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1267 smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_levelII, cli2->tree);
1268 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1269 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1270 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1271 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1272 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1273 status = smb_raw_open(cli2->tree, tctx, &io);
1274 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1275 fnum2 = io.ntcreatex.out.file.fnum;
1276 CHECK_VAL(break_info.count, 0);
1277 CHECK_VAL(break_info.failures, 0);
1278 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1280 ZERO_STRUCT(break_info);
1282 torture_comment(tctx, "write should trigger a break to none on both\n");
1283 smbcli_write(cli2->tree, fnum2, 0, &c, 0, 1);
1285 /* Now the oplock break request comes in. But right now we can't
1286 * answer it. Do another write */
1289 smbcli_write(cli2->tree, fnum2, 0, &c, 1, 1);
1291 CHECK_VAL(break_info.count, 2);
1292 CHECK_VAL(break_info.level, 0);
1293 CHECK_VAL(break_info.failures, 0);
1295 smbcli_close(cli1->tree, fnum);
1296 smbcli_close(cli2->tree, fnum2);
1299 smb_raw_exit(cli1->session);
1300 smb_raw_exit(cli2->session);
1301 smbcli_deltree(cli1->tree, BASEDIR);
1305 static bool test_raw_oplock_batch10(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1307 const char *fname = BASEDIR "\\test_batch10.dat";
1311 uint16_t fnum=0, fnum2=0;
1313 if (!torture_setup_dir(cli1, BASEDIR)) {
1318 smbcli_unlink(cli1->tree, fname);
1320 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1323 base ntcreatex parms
1325 io.generic.level = RAW_OPEN_NTCREATEX;
1326 io.ntcreatex.in.root_fid = 0;
1327 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1328 io.ntcreatex.in.alloc_size = 0;
1329 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1330 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1331 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1332 io.ntcreatex.in.create_options = 0;
1333 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1334 io.ntcreatex.in.security_flags = 0;
1335 io.ntcreatex.in.fname = fname;
1337 torture_comment(tctx, "Open with oplock after a non-oplock open should grant level2\n");
1338 ZERO_STRUCT(break_info);
1339 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
1340 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1341 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1342 NTCREATEX_SHARE_ACCESS_WRITE|
1343 NTCREATEX_SHARE_ACCESS_DELETE;
1344 status = smb_raw_open(cli1->tree, tctx, &io);
1345 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1346 fnum = io.ntcreatex.out.file.fnum;
1347 CHECK_VAL(break_info.count, 0);
1348 CHECK_VAL(break_info.failures, 0);
1349 CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
1351 smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_levelII, cli2->tree);
1353 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1354 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1355 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1356 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1357 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1358 NTCREATEX_SHARE_ACCESS_WRITE|
1359 NTCREATEX_SHARE_ACCESS_DELETE;
1360 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1361 status = smb_raw_open(cli2->tree, tctx, &io);
1362 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1363 fnum2 = io.ntcreatex.out.file.fnum;
1364 CHECK_VAL(break_info.count, 0);
1365 CHECK_VAL(break_info.failures, 0);
1366 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1368 torture_comment(tctx, "write should trigger a break to none\n");
1371 wr.write.level = RAW_WRITE_WRITE;
1372 wr.write.in.file.fnum = fnum;
1373 wr.write.in.count = 1;
1374 wr.write.in.offset = 0;
1375 wr.write.in.remaining = 0;
1376 wr.write.in.data = (const uint8_t *)"x";
1377 status = smb_raw_write(cli1->tree, &wr);
1378 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1381 /* Now the oplock break request comes in. But right now we can't
1382 * answer it. Do another write */
1388 wr.write.level = RAW_WRITE_WRITE;
1389 wr.write.in.file.fnum = fnum;
1390 wr.write.in.count = 1;
1391 wr.write.in.offset = 0;
1392 wr.write.in.remaining = 0;
1393 wr.write.in.data = (const uint8_t *)"x";
1394 status = smb_raw_write(cli1->tree, &wr);
1395 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1398 CHECK_VAL(break_info.count, 1);
1399 CHECK_VAL(break_info.fnum, fnum2);
1400 CHECK_VAL(break_info.level, 0);
1401 CHECK_VAL(break_info.failures, 0);
1403 smbcli_close(cli1->tree, fnum);
1404 smbcli_close(cli2->tree, fnum2);
1407 smb_raw_exit(cli1->session);
1408 smb_raw_exit(cli2->session);
1409 smbcli_deltree(cli1->tree, BASEDIR);
1413 static bool test_raw_oplock_batch11(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1415 const char *fname = BASEDIR "\\test_batch11.dat";
1419 union smb_setfileinfo sfi;
1422 if (!torture_setup_dir(cli1, BASEDIR)) {
1427 smbcli_unlink(cli1->tree, fname);
1429 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1432 base ntcreatex parms
1434 io.generic.level = RAW_OPEN_NTCREATEX;
1435 io.ntcreatex.in.root_fid = 0;
1436 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1437 io.ntcreatex.in.alloc_size = 0;
1438 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1439 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1440 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1441 io.ntcreatex.in.create_options = 0;
1442 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1443 io.ntcreatex.in.security_flags = 0;
1444 io.ntcreatex.in.fname = fname;
1446 /* Test if a set-eof on pathname breaks an exclusive oplock. */
1447 torture_comment(tctx, "Test if setpathinfo set EOF breaks oplocks.\n");
1449 ZERO_STRUCT(break_info);
1450 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1452 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1453 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1454 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1455 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1456 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1457 NTCREATEX_SHARE_ACCESS_WRITE|
1458 NTCREATEX_SHARE_ACCESS_DELETE;
1459 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1460 status = smb_raw_open(cli1->tree, tctx, &io);
1461 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1462 fnum = io.ntcreatex.out.file.fnum;
1463 CHECK_VAL(break_info.count, 0);
1464 CHECK_VAL(break_info.failures, 0);
1465 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1468 sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
1469 sfi.generic.in.file.path = fname;
1470 sfi.end_of_file_info.in.size = 100;
1472 status = smb_raw_setpathinfo(cli2->tree, &sfi);
1474 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1475 CHECK_VAL(break_info.count, 1);
1476 CHECK_VAL(break_info.failures, 0);
1477 CHECK_VAL(break_info.level, 0);
1479 smbcli_close(cli1->tree, fnum);
1482 smb_raw_exit(cli1->session);
1483 smb_raw_exit(cli2->session);
1484 smbcli_deltree(cli1->tree, BASEDIR);
1488 static bool test_raw_oplock_batch12(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1490 const char *fname = BASEDIR "\\test_batch12.dat";
1494 union smb_setfileinfo sfi;
1497 if (!torture_setup_dir(cli1, BASEDIR)) {
1502 smbcli_unlink(cli1->tree, fname);
1504 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1507 base ntcreatex parms
1509 io.generic.level = RAW_OPEN_NTCREATEX;
1510 io.ntcreatex.in.root_fid = 0;
1511 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1512 io.ntcreatex.in.alloc_size = 0;
1513 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1514 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1515 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1516 io.ntcreatex.in.create_options = 0;
1517 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1518 io.ntcreatex.in.security_flags = 0;
1519 io.ntcreatex.in.fname = fname;
1521 /* Test if a set-allocation size on pathname breaks an exclusive oplock. */
1522 torture_comment(tctx, "Test if setpathinfo allocation size breaks oplocks.\n");
1524 ZERO_STRUCT(break_info);
1525 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1527 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1528 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1529 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1530 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1531 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1532 NTCREATEX_SHARE_ACCESS_WRITE|
1533 NTCREATEX_SHARE_ACCESS_DELETE;
1534 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1535 status = smb_raw_open(cli1->tree, tctx, &io);
1536 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1537 fnum = io.ntcreatex.out.file.fnum;
1538 CHECK_VAL(break_info.count, 0);
1539 CHECK_VAL(break_info.failures, 0);
1540 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1543 sfi.generic.level = SMB_SFILEINFO_ALLOCATION_INFORMATION;
1544 sfi.generic.in.file.path = fname;
1545 sfi.allocation_info.in.alloc_size = 65536 * 8;
1547 status = smb_raw_setpathinfo(cli2->tree, &sfi);
1549 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1550 CHECK_VAL(break_info.count, 1);
1551 CHECK_VAL(break_info.failures, 0);
1552 CHECK_VAL(break_info.level, 0);
1554 smbcli_close(cli1->tree, fnum);
1557 smb_raw_exit(cli1->session);
1558 smb_raw_exit(cli2->session);
1559 smbcli_deltree(cli1->tree, BASEDIR);
1563 static bool test_raw_oplock_batch13(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1565 const char *fname = BASEDIR "\\test_batch13.dat";
1569 uint16_t fnum=0, fnum2=0;
1571 if (!torture_setup_dir(cli1, BASEDIR)) {
1576 smbcli_unlink(cli1->tree, fname);
1578 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1579 smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_levelII, cli1->tree);
1582 base ntcreatex parms
1584 io.generic.level = RAW_OPEN_NTCREATEX;
1585 io.ntcreatex.in.root_fid = 0;
1586 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1587 io.ntcreatex.in.alloc_size = 0;
1588 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1589 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1590 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1591 io.ntcreatex.in.create_options = 0;
1592 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1593 io.ntcreatex.in.security_flags = 0;
1594 io.ntcreatex.in.fname = fname;
1596 torture_comment(tctx, "open with batch oplock\n");
1597 ZERO_STRUCT(break_info);
1598 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1601 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1602 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1603 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1604 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1605 NTCREATEX_SHARE_ACCESS_WRITE|
1606 NTCREATEX_SHARE_ACCESS_DELETE;
1607 status = smb_raw_open(cli1->tree, tctx, &io);
1608 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1609 fnum = io.ntcreatex.out.file.fnum;
1610 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1612 ZERO_STRUCT(break_info);
1614 torture_comment(tctx, "second open with attributes only and NTCREATEX_DISP_OVERWRITE dispostion causes oplock break\n");
1616 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1617 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1618 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1619 io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
1620 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1621 NTCREATEX_SHARE_ACCESS_WRITE|
1622 NTCREATEX_SHARE_ACCESS_DELETE;
1623 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE;
1624 status = smb_raw_open(cli2->tree, tctx, &io);
1625 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1626 fnum2 = io.ntcreatex.out.file.fnum;
1627 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1628 CHECK_VAL(break_info.count, 1);
1629 CHECK_VAL(break_info.failures, 0);
1631 smbcli_close(cli1->tree, fnum);
1632 smbcli_close(cli2->tree, fnum2);
1635 smb_raw_exit(cli1->session);
1636 smb_raw_exit(cli2->session);
1637 smbcli_deltree(cli1->tree, BASEDIR);
1641 static bool test_raw_oplock_batch14(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1643 const char *fname = BASEDIR "\\test_batch14.dat";
1647 uint16_t fnum=0, fnum2=0;
1649 if (!torture_setup_dir(cli1, BASEDIR)) {
1654 smbcli_unlink(cli1->tree, fname);
1656 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1659 base ntcreatex parms
1661 io.generic.level = RAW_OPEN_NTCREATEX;
1662 io.ntcreatex.in.root_fid = 0;
1663 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1664 io.ntcreatex.in.alloc_size = 0;
1665 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1666 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1667 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1668 io.ntcreatex.in.create_options = 0;
1669 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1670 io.ntcreatex.in.security_flags = 0;
1671 io.ntcreatex.in.fname = fname;
1673 torture_comment(tctx, "open with batch oplock\n");
1674 ZERO_STRUCT(break_info);
1675 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1677 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1678 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1679 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1680 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1681 NTCREATEX_SHARE_ACCESS_WRITE|
1682 NTCREATEX_SHARE_ACCESS_DELETE;
1683 status = smb_raw_open(cli1->tree, tctx, &io);
1684 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1685 fnum = io.ntcreatex.out.file.fnum;
1686 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1688 ZERO_STRUCT(break_info);
1690 torture_comment(tctx, "second open with attributes only and NTCREATEX_DISP_SUPERSEDE dispostion causes oplock break\n");
1692 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1693 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1694 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1695 io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
1696 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1697 NTCREATEX_SHARE_ACCESS_WRITE|
1698 NTCREATEX_SHARE_ACCESS_DELETE;
1699 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE;
1700 status = smb_raw_open(cli2->tree, tctx, &io);
1701 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1702 fnum2 = io.ntcreatex.out.file.fnum;
1703 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1704 CHECK_VAL(break_info.count, 1);
1705 CHECK_VAL(break_info.failures, 0);
1707 smbcli_close(cli1->tree, fnum);
1708 smbcli_close(cli2->tree, fnum2);
1710 smb_raw_exit(cli1->session);
1711 smb_raw_exit(cli2->session);
1712 smbcli_deltree(cli1->tree, BASEDIR);
1716 static bool test_raw_oplock_batch15(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1718 const char *fname = BASEDIR "\\test_batch15.dat";
1722 union smb_fileinfo qfi;
1725 if (!torture_setup_dir(cli1, BASEDIR)) {
1730 smbcli_unlink(cli1->tree, fname);
1732 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1735 base ntcreatex parms
1737 io.generic.level = RAW_OPEN_NTCREATEX;
1738 io.ntcreatex.in.root_fid = 0;
1739 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1740 io.ntcreatex.in.alloc_size = 0;
1741 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1742 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1743 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1744 io.ntcreatex.in.create_options = 0;
1745 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1746 io.ntcreatex.in.security_flags = 0;
1747 io.ntcreatex.in.fname = fname;
1749 /* Test if a qpathinfo all info on pathname breaks a batch oplock. */
1750 torture_comment(tctx, "Test if qpathinfo all info breaks a batch oplock (should not).\n");
1752 ZERO_STRUCT(break_info);
1753 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1755 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1756 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1757 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1758 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1759 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1760 NTCREATEX_SHARE_ACCESS_WRITE|
1761 NTCREATEX_SHARE_ACCESS_DELETE;
1762 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1763 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1764 status = smb_raw_open(cli1->tree, tctx, &io);
1765 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1766 fnum = io.ntcreatex.out.file.fnum;
1767 CHECK_VAL(break_info.count, 0);
1768 CHECK_VAL(break_info.failures, 0);
1769 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1772 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
1773 qfi.generic.in.file.path = fname;
1775 status = smb_raw_pathinfo(cli2->tree, tctx, &qfi);
1777 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1778 CHECK_VAL(break_info.count, 0);
1780 smbcli_close(cli1->tree, fnum);
1783 smb_raw_exit(cli1->session);
1784 smb_raw_exit(cli2->session);
1785 smbcli_deltree(cli1->tree, BASEDIR);
1789 static bool test_raw_oplock_batch16(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1791 const char *fname = BASEDIR "\\test_batch16.dat";
1795 uint16_t fnum=0, fnum2=0;
1797 if (!torture_setup_dir(cli1, BASEDIR)) {
1802 smbcli_unlink(cli1->tree, fname);
1804 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1805 smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_levelII, cli1->tree);
1808 base ntcreatex parms
1810 io.generic.level = RAW_OPEN_NTCREATEX;
1811 io.ntcreatex.in.root_fid = 0;
1812 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1813 io.ntcreatex.in.alloc_size = 0;
1814 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1815 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1816 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1817 io.ntcreatex.in.create_options = 0;
1818 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1819 io.ntcreatex.in.security_flags = 0;
1820 io.ntcreatex.in.fname = fname;
1822 torture_comment(tctx, "open with batch oplock\n");
1823 ZERO_STRUCT(break_info);
1824 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1827 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1828 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1829 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1830 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1831 NTCREATEX_SHARE_ACCESS_WRITE|
1832 NTCREATEX_SHARE_ACCESS_DELETE;
1833 status = smb_raw_open(cli1->tree, tctx, &io);
1834 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1835 fnum = io.ntcreatex.out.file.fnum;
1836 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1838 ZERO_STRUCT(break_info);
1840 torture_comment(tctx, "second open with attributes only and NTCREATEX_DISP_OVERWRITE_IF dispostion causes oplock break\n");
1842 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1843 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1844 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1845 io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
1846 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1847 NTCREATEX_SHARE_ACCESS_WRITE|
1848 NTCREATEX_SHARE_ACCESS_DELETE;
1849 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE_IF;
1850 status = smb_raw_open(cli2->tree, tctx, &io);
1851 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1852 fnum2 = io.ntcreatex.out.file.fnum;
1853 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1854 CHECK_VAL(break_info.count, 1);
1855 CHECK_VAL(break_info.failures, 0);
1857 smbcli_close(cli1->tree, fnum);
1858 smbcli_close(cli2->tree, fnum2);
1861 smb_raw_exit(cli1->session);
1862 smb_raw_exit(cli2->session);
1863 smbcli_deltree(cli1->tree, BASEDIR);
1867 static bool test_raw_oplock_batch17(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1869 const char *fname1 = BASEDIR "\\test_batch17_1.dat";
1870 const char *fname2 = BASEDIR "\\test_batch17_2.dat";
1874 union smb_rename rn;
1876 bool s3 = torture_setting_bool(tctx, "samba3", false);
1878 if (!torture_setup_dir(cli1, BASEDIR)) {
1883 smbcli_unlink(cli1->tree, fname1);
1884 smbcli_unlink(cli1->tree, fname2);
1886 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1889 base ntcreatex parms
1891 io.generic.level = RAW_OPEN_NTCREATEX;
1892 io.ntcreatex.in.root_fid = 0;
1893 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1894 io.ntcreatex.in.alloc_size = 0;
1895 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1896 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1897 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1898 io.ntcreatex.in.create_options = 0;
1899 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1900 io.ntcreatex.in.security_flags = 0;
1901 io.ntcreatex.in.fname = fname1;
1903 /* we should use no share mode, when samba3 passes this */
1904 torture_comment(tctx, "open a file with an batch oplock (share mode: %s)\n",
1906 ZERO_STRUCT(break_info);
1907 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1908 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1909 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1911 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1912 NTCREATEX_SHARE_ACCESS_WRITE|
1913 NTCREATEX_SHARE_ACCESS_DELETE;
1916 status = smb_raw_open(cli1->tree, tctx, &io);
1917 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1918 fnum = io.ntcreatex.out.file.fnum;
1919 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1921 torture_comment(tctx, "rename should trigger a break\n");
1923 rn.generic.level = RAW_RENAME_RENAME;
1924 rn.rename.in.pattern1 = fname1;
1925 rn.rename.in.pattern2 = fname2;
1926 rn.rename.in.attrib = 0;
1928 printf("trying rename while first file open\n");
1929 status = smb_raw_rename(cli2->tree, &rn);
1931 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
1932 CHECK_VAL(break_info.count, 1);
1933 CHECK_VAL(break_info.failures, 0);
1934 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
1936 smbcli_close(cli1->tree, fnum);
1939 smb_raw_exit(cli1->session);
1940 smb_raw_exit(cli2->session);
1941 smbcli_deltree(cli1->tree, BASEDIR);
1945 static bool test_raw_oplock_batch18(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1947 const char *fname1 = BASEDIR "\\test_batch18_1.dat";
1948 const char *fname2 = BASEDIR "\\test_batch18_2.dat";
1952 union smb_rename rn;
1954 bool s3 = torture_setting_bool(tctx, "samba3", false);
1956 if (!torture_setup_dir(cli1, BASEDIR)) {
1961 smbcli_unlink(cli1->tree, fname1);
1962 smbcli_unlink(cli1->tree, fname2);
1964 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1967 base ntcreatex parms
1969 io.generic.level = RAW_OPEN_NTCREATEX;
1970 io.ntcreatex.in.root_fid = 0;
1971 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1972 io.ntcreatex.in.alloc_size = 0;
1973 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1974 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1975 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1976 io.ntcreatex.in.create_options = 0;
1977 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1978 io.ntcreatex.in.security_flags = 0;
1979 io.ntcreatex.in.fname = fname1;
1981 /* we should use no share mode, when samba3 passes this */
1982 torture_comment(tctx, "open a file with an batch oplock (share mode: %s)\n",
1984 ZERO_STRUCT(break_info);
1985 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1986 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1987 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1989 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1990 NTCREATEX_SHARE_ACCESS_WRITE|
1991 NTCREATEX_SHARE_ACCESS_DELETE;
1994 status = smb_raw_open(cli1->tree, tctx, &io);
1995 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1996 fnum = io.ntcreatex.out.file.fnum;
1997 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1999 torture_comment(tctx, "ntrename should trigger a break\n");
2001 rn.generic.level = RAW_RENAME_NTRENAME;
2002 rn.ntrename.in.attrib = 0;
2003 rn.ntrename.in.flags = RENAME_FLAG_RENAME;
2004 rn.ntrename.in.old_name = fname1;
2005 rn.ntrename.in.new_name = fname2;
2006 printf("trying rename while first file open\n");
2007 status = smb_raw_rename(cli2->tree, &rn);
2009 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
2010 CHECK_VAL(break_info.count, 1);
2011 CHECK_VAL(break_info.failures, 0);
2012 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
2014 smbcli_close(cli1->tree, fnum);
2017 smb_raw_exit(cli1->session);
2018 smb_raw_exit(cli2->session);
2019 smbcli_deltree(cli1->tree, BASEDIR);
2023 static bool test_raw_oplock_batch19(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
2025 const char *fname1 = BASEDIR "\\test_batch19_1.dat";
2026 const char *fname2 = BASEDIR "\\test_batch19_2.dat";
2027 const char *fname3 = BASEDIR "\\test_batch19_3.dat";
2031 union smb_fileinfo qfi;
2032 union smb_setfileinfo sfi;
2035 if (torture_setting_bool(tctx, "samba3", false)) {
2036 torture_skip(tctx, "BACHT19 disabled against samba3\n");
2039 if (!torture_setup_dir(cli1, BASEDIR)) {
2044 smbcli_unlink(cli1->tree, fname1);
2045 smbcli_unlink(cli1->tree, fname2);
2046 smbcli_unlink(cli1->tree, fname3);
2048 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
2051 base ntcreatex parms
2053 io.generic.level = RAW_OPEN_NTCREATEX;
2054 io.ntcreatex.in.root_fid = 0;
2055 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2056 io.ntcreatex.in.alloc_size = 0;
2057 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2058 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2059 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2060 io.ntcreatex.in.create_options = 0;
2061 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2062 io.ntcreatex.in.security_flags = 0;
2063 io.ntcreatex.in.fname = fname1;
2065 torture_comment(tctx, "open a file with an batch oplock (share mode: none)\n");
2066 ZERO_STRUCT(break_info);
2067 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2068 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2069 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2070 status = smb_raw_open(cli1->tree, tctx, &io);
2071 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2072 fnum = io.ntcreatex.out.file.fnum;
2073 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
2075 torture_comment(tctx, "setpathinfo rename info should not trigger a break nor a violation\n");
2077 sfi.generic.level = RAW_SFILEINFO_RENAME_INFORMATION;
2078 sfi.generic.in.file.path = fname1;
2079 sfi.rename_information.in.overwrite = 0;
2080 sfi.rename_information.in.root_fid = 0;
2081 sfi.rename_information.in.new_name = fname2+strlen(BASEDIR)+1;
2083 status = smb_raw_setpathinfo(cli2->tree, &sfi);
2085 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2086 CHECK_VAL(break_info.count, 0);
2089 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2090 qfi.generic.in.file.fnum = fnum;
2092 status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
2093 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2094 CHECK_STRMATCH(qfi.all_info.out.fname.s, fname2);
2096 torture_comment(tctx, "setfileinfo rename info should not trigger a break nor a violation\n");
2098 sfi.generic.level = RAW_SFILEINFO_RENAME_INFORMATION;
2099 sfi.generic.in.file.fnum = fnum;
2100 sfi.rename_information.in.overwrite = 0;
2101 sfi.rename_information.in.root_fid = 0;
2102 sfi.rename_information.in.new_name = fname3+strlen(BASEDIR)+1;
2104 status = smb_raw_setfileinfo(cli1->tree, &sfi);
2105 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2106 CHECK_VAL(break_info.count, 0);
2109 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2110 qfi.generic.in.file.fnum = fnum;
2112 status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
2113 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2114 CHECK_STRMATCH(qfi.all_info.out.fname.s, fname3);
2116 smbcli_close(cli1->tree, fnum);
2119 smb_raw_exit(cli1->session);
2120 smb_raw_exit(cli2->session);
2121 smbcli_deltree(cli1->tree, BASEDIR);
2125 static bool test_raw_oplock_batch20(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
2127 const char *fname1 = BASEDIR "\\test_batch20_1.dat";
2128 const char *fname2 = BASEDIR "\\test_batch20_2.dat";
2129 const char *fname3 = BASEDIR "\\test_batch20_3.dat";
2133 union smb_fileinfo qfi;
2134 union smb_setfileinfo sfi;
2135 uint16_t fnum=0,fnum2=0;
2137 if (torture_setting_bool(tctx, "samba3", false)) {
2138 torture_skip(tctx, "BACHT20 disabled against samba3\n");
2141 if (!torture_setup_dir(cli1, BASEDIR)) {
2146 smbcli_unlink(cli1->tree, fname1);
2147 smbcli_unlink(cli1->tree, fname2);
2148 smbcli_unlink(cli1->tree, fname3);
2150 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
2153 base ntcreatex parms
2155 io.generic.level = RAW_OPEN_NTCREATEX;
2156 io.ntcreatex.in.root_fid = 0;
2157 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2158 io.ntcreatex.in.alloc_size = 0;
2159 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2160 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2161 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2162 io.ntcreatex.in.create_options = 0;
2163 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2164 io.ntcreatex.in.security_flags = 0;
2165 io.ntcreatex.in.fname = fname1;
2167 torture_comment(tctx, "open a file with an batch oplock (share mode: all)\n");
2168 ZERO_STRUCT(break_info);
2169 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2170 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2171 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2172 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
2173 NTCREATEX_SHARE_ACCESS_WRITE|
2174 NTCREATEX_SHARE_ACCESS_DELETE;
2175 status = smb_raw_open(cli1->tree, tctx, &io);
2176 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2177 fnum = io.ntcreatex.out.file.fnum;
2178 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
2180 torture_comment(tctx, "setpathinfo rename info should not trigger a break nor a violation\n");
2182 sfi.generic.level = RAW_SFILEINFO_RENAME_INFORMATION;
2183 sfi.generic.in.file.path = fname1;
2184 sfi.rename_information.in.overwrite = 0;
2185 sfi.rename_information.in.root_fid = 0;
2186 sfi.rename_information.in.new_name = fname2+strlen(BASEDIR)+1;
2188 status = smb_raw_setpathinfo(cli2->tree, &sfi);
2190 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2191 CHECK_VAL(break_info.count, 0);
2194 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2195 qfi.generic.in.file.fnum = fnum;
2197 status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
2198 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2199 CHECK_STRMATCH(qfi.all_info.out.fname.s, fname2);
2201 /* we should use no share mode, when samba3 passes this */
2202 torture_comment(tctx, "open a file with the new name an batch oplock (share mode: all)\n");
2203 ZERO_STRUCT(break_info);
2204 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2205 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2206 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2207 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
2208 NTCREATEX_SHARE_ACCESS_WRITE|
2209 NTCREATEX_SHARE_ACCESS_DELETE;
2210 io.ntcreatex.in.fname = fname2;
2211 status = smb_raw_open(cli2->tree, tctx, &io);
2212 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2213 fnum2 = io.ntcreatex.out.file.fnum;
2214 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
2215 CHECK_VAL(break_info.count, 1);
2216 CHECK_VAL(break_info.failures, 0);
2217 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
2219 torture_comment(tctx, "setfileinfo rename info should not trigger a break nor a violation\n");
2221 sfi.generic.level = RAW_SFILEINFO_RENAME_INFORMATION;
2222 sfi.generic.in.file.fnum = fnum;
2223 sfi.rename_information.in.overwrite = 0;
2224 sfi.rename_information.in.root_fid = 0;
2225 sfi.rename_information.in.new_name = fname3+strlen(BASEDIR)+1;
2227 status = smb_raw_setfileinfo(cli1->tree, &sfi);
2228 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2229 CHECK_VAL(break_info.count, 1);
2230 CHECK_VAL(break_info.failures, 0);
2231 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
2234 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2235 qfi.generic.in.file.fnum = fnum;
2237 status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
2238 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2239 CHECK_STRMATCH(qfi.all_info.out.fname.s, fname3);
2242 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2243 qfi.generic.in.file.fnum = fnum2;
2245 status = smb_raw_fileinfo(cli2->tree, tctx, &qfi);
2246 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2247 CHECK_STRMATCH(qfi.all_info.out.fname.s, fname3);
2249 smbcli_close(cli1->tree, fnum);
2252 smb_raw_exit(cli1->session);
2253 smb_raw_exit(cli2->session);
2254 smbcli_deltree(cli1->tree, BASEDIR);
2258 static bool test_raw_oplock_batch21(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
2260 const char *fname = BASEDIR "\\test_batch21.dat";
2269 if (!torture_setup_dir(cli1, BASEDIR)) {
2274 smbcli_unlink(cli1->tree, fname);
2276 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
2279 base ntcreatex parms
2281 io.generic.level = RAW_OPEN_NTCREATEX;
2282 io.ntcreatex.in.root_fid = 0;
2283 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2284 io.ntcreatex.in.alloc_size = 0;
2285 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2286 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2287 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2288 io.ntcreatex.in.create_options = 0;
2289 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2290 io.ntcreatex.in.security_flags = 0;
2291 io.ntcreatex.in.fname = fname;
2294 with a batch oplock we get a break
2296 torture_comment(tctx, "open with batch oplock\n");
2297 ZERO_STRUCT(break_info);
2298 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2299 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2300 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2301 status = smb_raw_open(cli1->tree, tctx, &io);
2302 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2303 fnum = io.ntcreatex.out.file.fnum;
2304 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
2306 torture_comment(tctx, "writing should not generate a break\n");
2307 wr = smbcli_write(cli1->tree, fnum, 0, &c, 0, 1);
2309 CHECK_STATUS(tctx, smbcli_nt_error(cli1->tree), NT_STATUS_OK);
2312 e.in.repeat_count = 1;
2313 status = smb_raw_echo(cli1->transport, &e);
2314 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2316 CHECK_VAL(break_info.count, 0);
2318 smbcli_close(cli1->tree, fnum);
2321 smb_raw_exit(cli1->session);
2322 smb_raw_exit(cli2->session);
2323 smbcli_deltree(cli1->tree, BASEDIR);
2327 static bool test_raw_oplock_batch22(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
2329 const char *fname = BASEDIR "\\test_batch22.dat";
2333 uint16_t fnum=0, fnum2=0;
2335 int timeout = torture_setting_int(tctx, "oplocktimeout", 30);
2338 if (torture_setting_bool(tctx, "samba3", false)) {
2339 torture_skip(tctx, "BACHT22 disabled against samba3\n");
2342 if (!torture_setup_dir(cli1, BASEDIR)) {
2347 smbcli_unlink(cli1->tree, fname);
2349 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
2352 base ntcreatex parms
2354 io.generic.level = RAW_OPEN_NTCREATEX;
2355 io.ntcreatex.in.root_fid = 0;
2356 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2357 io.ntcreatex.in.alloc_size = 0;
2358 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2359 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2360 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2361 io.ntcreatex.in.create_options = 0;
2362 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2363 io.ntcreatex.in.security_flags = 0;
2364 io.ntcreatex.in.fname = fname;
2367 with a batch oplock we get a break
2369 torture_comment(tctx, "open with batch oplock\n");
2370 ZERO_STRUCT(break_info);
2371 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2372 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2373 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2374 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
2375 NTCREATEX_SHARE_ACCESS_WRITE|
2376 NTCREATEX_SHARE_ACCESS_DELETE;
2377 status = smb_raw_open(cli1->tree, tctx, &io);
2378 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2379 fnum = io.ntcreatex.out.file.fnum;
2380 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
2382 torture_comment(tctx, "a 2nd open shoud not succeed after the oplock break timeout\n");
2383 tv = timeval_current();
2384 smbcli_oplock_handler(cli1->transport, oplock_handler_timeout, cli1->tree);
2385 status = smb_raw_open(cli1->tree, tctx, &io);
2386 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
2387 te = (int)timeval_elapsed(&tv);
2388 CHECK_RANGE(te, timeout - 1, timeout + 15);
2390 CHECK_VAL(break_info.count, 1);
2391 CHECK_VAL(break_info.fnum, fnum);
2392 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
2393 CHECK_VAL(break_info.failures, 0);
2394 ZERO_STRUCT(break_info);
2396 torture_comment(tctx, "a 2nd open shoud succeed after the oplock release without break\n");
2397 tv = timeval_current();
2398 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
2399 status = smb_raw_open(cli1->tree, tctx, &io);
2400 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2401 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
2402 te = (int)timeval_elapsed(&tv);
2403 /* it should come in without delay */
2404 CHECK_RANGE(te+1, 0, timeout);
2405 fnum2 = io.ntcreatex.out.file.fnum;
2407 CHECK_VAL(break_info.count, 0);
2409 smbcli_close(cli1->tree, fnum);
2410 smbcli_close(cli1->tree, fnum2);
2413 smb_raw_exit(cli1->session);
2414 smb_raw_exit(cli2->session);
2415 smbcli_deltree(cli1->tree, BASEDIR);
2419 static bool test_raw_oplock_batch23(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
2421 const char *fname = BASEDIR "\\test_batch23.dat";
2425 uint16_t fnum=0, fnum2=0,fnum3=0;
2426 struct smbcli_state *cli3 = NULL;
2428 if (torture_setting_bool(tctx, "samba3", false)) {
2429 torture_skip(tctx, "BACHT23 disabled against samba3\n");
2432 if (!torture_setup_dir(cli1, BASEDIR)) {
2437 smbcli_unlink(cli1->tree, fname);
2439 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
2441 ret = open_connection_no_level2_oplocks(tctx, &cli3);
2442 CHECK_VAL(ret, true);
2445 base ntcreatex parms
2447 io.generic.level = RAW_OPEN_NTCREATEX;
2448 io.ntcreatex.in.root_fid = 0;
2449 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2450 io.ntcreatex.in.alloc_size = 0;
2451 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2452 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2453 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2454 io.ntcreatex.in.create_options = 0;
2455 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2456 io.ntcreatex.in.security_flags = 0;
2457 io.ntcreatex.in.fname = fname;
2459 torture_comment(tctx, "a open and ask for a batch oplock\n");
2460 ZERO_STRUCT(break_info);
2461 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
2462 smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_levelII, cli2->tree);
2463 smbcli_oplock_handler(cli3->transport, oplock_handler_ack_to_levelII, cli3->tree);
2465 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_READ | SEC_RIGHTS_FILE_WRITE;
2466 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
2467 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2468 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2469 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2470 status = smb_raw_open(cli1->tree, tctx, &io);
2471 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2472 fnum = io.ntcreatex.out.file.fnum;
2473 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
2475 ZERO_STRUCT(break_info);
2477 torture_comment(tctx, "a 2nd open without level2 oplock support should generate a break to level2\n");
2478 status = smb_raw_open(cli3->tree, tctx, &io);
2479 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2480 fnum3 = io.ntcreatex.out.file.fnum;
2481 CHECK_VAL(io.ntcreatex.out.oplock_level, NO_OPLOCK_RETURN);
2483 CHECK_VAL(break_info.count, 1);
2484 CHECK_VAL(break_info.fnum, fnum);
2485 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
2486 CHECK_VAL(break_info.failures, 0);
2488 ZERO_STRUCT(break_info);
2490 torture_comment(tctx, "a 3rd open with level2 oplock support should not generate a break\n");
2491 status = smb_raw_open(cli2->tree, tctx, &io);
2492 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2493 fnum2 = io.ntcreatex.out.file.fnum;
2494 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
2496 CHECK_VAL(break_info.count, 0);
2498 smbcli_close(cli1->tree, fnum);
2499 smbcli_close(cli2->tree, fnum2);
2500 smbcli_close(cli3->tree, fnum3);
2503 smb_raw_exit(cli1->session);
2504 smb_raw_exit(cli2->session);
2505 smb_raw_exit(cli3->session);
2506 smbcli_deltree(cli1->tree, BASEDIR);
2510 static bool test_raw_oplock_batch24(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
2512 const char *fname = BASEDIR "\\test_batch24.dat";
2516 uint16_t fnum2=0,fnum3=0;
2517 struct smbcli_state *cli3 = NULL;
2519 if (!torture_setup_dir(cli1, BASEDIR)) {
2524 smbcli_unlink(cli1->tree, fname);
2526 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
2528 ret = open_connection_no_level2_oplocks(tctx, &cli3);
2529 CHECK_VAL(ret, true);
2532 base ntcreatex parms
2534 io.generic.level = RAW_OPEN_NTCREATEX;
2535 io.ntcreatex.in.root_fid = 0;
2536 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2537 io.ntcreatex.in.alloc_size = 0;
2538 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2539 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2540 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2541 io.ntcreatex.in.create_options = 0;
2542 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2543 io.ntcreatex.in.security_flags = 0;
2544 io.ntcreatex.in.fname = fname;
2546 torture_comment(tctx, "a open without level support and ask for a batch oplock\n");
2547 ZERO_STRUCT(break_info);
2548 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
2549 smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_levelII, cli2->tree);
2550 smbcli_oplock_handler(cli3->transport, oplock_handler_ack_to_levelII, cli3->tree);
2552 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_READ | SEC_RIGHTS_FILE_WRITE;
2553 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
2554 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2555 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2556 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2557 status = smb_raw_open(cli3->tree, tctx, &io);
2558 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2559 fnum3 = io.ntcreatex.out.file.fnum;
2560 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
2562 ZERO_STRUCT(break_info);
2564 torture_comment(tctx, "a 2nd open with level2 oplock support should generate a break to none\n");
2565 status = smb_raw_open(cli2->tree, tctx, &io);
2566 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2567 fnum2 = io.ntcreatex.out.file.fnum;
2568 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
2570 CHECK_VAL(break_info.count, 1);
2571 CHECK_VAL(break_info.fnum, fnum3);
2572 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_NONE);
2573 CHECK_VAL(break_info.failures, 0);
2575 smbcli_close(cli3->tree, fnum3);
2576 smbcli_close(cli2->tree, fnum2);
2579 smb_raw_exit(cli1->session);
2580 smb_raw_exit(cli2->session);
2581 smb_raw_exit(cli3->session);
2582 smbcli_deltree(cli1->tree, BASEDIR);
2587 basic testing of oplocks
2589 struct torture_suite *torture_raw_oplock(TALLOC_CTX *mem_ctx)
2591 struct torture_suite *suite = torture_suite_create(mem_ctx, "OPLOCK");
2593 torture_suite_add_2smb_test(suite, "EXCLUSIVE1", test_raw_oplock_exclusive1);
2594 torture_suite_add_2smb_test(suite, "EXCLUSIVE2", test_raw_oplock_exclusive2);
2595 torture_suite_add_2smb_test(suite, "EXCLUSIVE3", test_raw_oplock_exclusive3);
2596 torture_suite_add_2smb_test(suite, "EXCLUSIVE4", test_raw_oplock_exclusive4);
2597 torture_suite_add_2smb_test(suite, "EXCLUSIVE5", test_raw_oplock_exclusive5);
2598 torture_suite_add_2smb_test(suite, "EXCLUSIVE6", test_raw_oplock_exclusive6);
2599 torture_suite_add_2smb_test(suite, "BATCH1", test_raw_oplock_batch1);
2600 torture_suite_add_2smb_test(suite, "BATCH2", test_raw_oplock_batch2);
2601 torture_suite_add_2smb_test(suite, "BATCH3", test_raw_oplock_batch3);
2602 torture_suite_add_2smb_test(suite, "BATCH4", test_raw_oplock_batch4);
2603 torture_suite_add_2smb_test(suite, "BATCH5", test_raw_oplock_batch5);
2604 torture_suite_add_2smb_test(suite, "BATCH6", test_raw_oplock_batch6);
2605 torture_suite_add_2smb_test(suite, "BATCH7", test_raw_oplock_batch7);
2606 torture_suite_add_2smb_test(suite, "BATCH8", test_raw_oplock_batch8);
2607 torture_suite_add_2smb_test(suite, "BATCH9", test_raw_oplock_batch9);
2608 torture_suite_add_2smb_test(suite, "BATCH10", test_raw_oplock_batch10);
2609 torture_suite_add_2smb_test(suite, "BATCH11", test_raw_oplock_batch11);
2610 torture_suite_add_2smb_test(suite, "BATCH12", test_raw_oplock_batch12);
2611 torture_suite_add_2smb_test(suite, "BATCH13", test_raw_oplock_batch13);
2612 torture_suite_add_2smb_test(suite, "BATCH14", test_raw_oplock_batch14);
2613 torture_suite_add_2smb_test(suite, "BATCH15", test_raw_oplock_batch15);
2614 torture_suite_add_2smb_test(suite, "BATCH16", test_raw_oplock_batch16);
2615 torture_suite_add_2smb_test(suite, "BATCH17", test_raw_oplock_batch17);
2616 torture_suite_add_2smb_test(suite, "BATCH18", test_raw_oplock_batch18);
2617 torture_suite_add_2smb_test(suite, "BATCH19", test_raw_oplock_batch19);
2618 torture_suite_add_2smb_test(suite, "BATCH20", test_raw_oplock_batch20);
2619 torture_suite_add_2smb_test(suite, "BATCH21", test_raw_oplock_batch21);
2620 torture_suite_add_2smb_test(suite, "BATCH22", test_raw_oplock_batch22);
2621 torture_suite_add_2smb_test(suite, "BATCH23", test_raw_oplock_batch23);
2622 torture_suite_add_2smb_test(suite, "BATCH24", test_raw_oplock_batch24);
2628 stress testing of oplocks
2630 bool torture_bench_oplock(struct torture_context *torture)
2632 struct smbcli_state **cli;
2634 TALLOC_CTX *mem_ctx = talloc_new(torture);
2635 int torture_nprocs = torture_setting_int(torture, "nprocs", 4);
2637 int timelimit = torture_setting_int(torture, "timelimit", 10);
2640 struct event_context *ev = event_context_find(mem_ctx);
2642 cli = talloc_array(mem_ctx, struct smbcli_state *, torture_nprocs);
2644 torture_comment(torture, "Opening %d connections\n", torture_nprocs);
2645 for (i=0;i<torture_nprocs;i++) {
2646 if (!torture_open_connection_ev(&cli[i], i, torture, ev)) {
2649 talloc_steal(mem_ctx, cli[i]);
2650 smbcli_oplock_handler(cli[i]->transport, oplock_handler_close,
2654 if (!torture_setup_dir(cli[0], BASEDIR)) {
2659 io.ntcreatex.level = RAW_OPEN_NTCREATEX;
2660 io.ntcreatex.in.root_fid = 0;
2661 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2662 io.ntcreatex.in.alloc_size = 0;
2663 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2664 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2665 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2666 io.ntcreatex.in.create_options = 0;
2667 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2668 io.ntcreatex.in.security_flags = 0;
2669 io.ntcreatex.in.fname = BASEDIR "\\test.dat";
2670 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2671 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2672 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2674 tv = timeval_current();
2677 we open the same file with SHARE_ACCESS_NONE from all the
2678 connections in a round robin fashion. Each open causes an
2679 oplock break on the previous connection, which is answered
2680 by the oplock_handler_close() to close the file.
2682 This measures how fast we can pass on oplocks, and stresses
2683 the oplock handling code
2685 torture_comment(torture, "Running for %d seconds\n", timelimit);
2686 while (timeval_elapsed(&tv) < timelimit) {
2687 for (i=0;i<torture_nprocs;i++) {
2690 status = smb_raw_open(cli[i]->tree, mem_ctx, &io);
2691 CHECK_STATUS(torture, status, NT_STATUS_OK);
2695 if (torture_setting_bool(torture, "progress", true)) {
2696 torture_comment(torture, "%.2f ops/second\r", count/timeval_elapsed(&tv));
2700 torture_comment(torture, "%.2f ops/second\n", count/timeval_elapsed(&tv));
2702 smb_raw_exit(cli[torture_nprocs-1]->session);
2705 smb_raw_exit(cli[0]->session);
2706 smbcli_deltree(cli[0]->tree, BASEDIR);
2707 talloc_free(mem_ctx);
2712 static struct hold_oplock_info {
2714 bool close_on_break;
2715 uint32_t share_access;
2718 { BASEDIR "\\notshared_close", true,
2719 NTCREATEX_SHARE_ACCESS_NONE, },
2720 { BASEDIR "\\notshared_noclose", false,
2721 NTCREATEX_SHARE_ACCESS_NONE, },
2722 { BASEDIR "\\shared_close", true,
2723 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE, },
2724 { BASEDIR "\\shared_noclose", false,
2725 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE, },
2728 static bool oplock_handler_hold(struct smbcli_transport *transport,
2729 uint16_t tid, uint16_t fnum, uint8_t level,
2732 struct smbcli_tree *tree = (struct smbcli_tree *)private;
2733 struct hold_oplock_info *info;
2736 for (i=0;i<ARRAY_SIZE(hold_info);i++) {
2737 if (hold_info[i].fnum == fnum) break;
2740 if (i == ARRAY_SIZE(hold_info)) {
2741 printf("oplock break for unknown fnum %u\n", fnum);
2745 info = &hold_info[i];
2747 if (info->close_on_break) {
2748 printf("oplock break on %s - closing\n",
2750 oplock_handler_close(transport, tid, fnum, level, private);
2754 printf("oplock break on %s - acking break\n", info->fname);
2756 return smbcli_oplock_ack(tree, fnum, OPLOCK_BREAK_TO_NONE);
2761 used for manual testing of oplocks - especially interaction with
2762 other filesystems (such as NFS and local access)
2764 bool torture_hold_oplock(struct torture_context *torture,
2765 struct smbcli_state *cli)
2767 struct event_context *ev =
2768 (struct event_context *)cli->transport->socket->event.ctx;
2771 printf("Setting up open files with oplocks in %s\n", BASEDIR);
2773 if (!torture_setup_dir(cli, BASEDIR)) {
2777 smbcli_oplock_handler(cli->transport, oplock_handler_hold, cli->tree);
2779 /* setup the files */
2780 for (i=0;i<ARRAY_SIZE(hold_info);i++) {
2785 io.generic.level = RAW_OPEN_NTCREATEX;
2786 io.ntcreatex.in.root_fid = 0;
2787 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2788 io.ntcreatex.in.alloc_size = 0;
2789 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2790 io.ntcreatex.in.share_access = hold_info[i].share_access;
2791 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2792 io.ntcreatex.in.create_options = 0;
2793 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2794 io.ntcreatex.in.security_flags = 0;
2795 io.ntcreatex.in.fname = hold_info[i].fname;
2796 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2797 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2798 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2799 printf("opening %s\n", hold_info[i].fname);
2801 status = smb_raw_open(cli->tree, cli, &io);
2802 if (!NT_STATUS_IS_OK(status)) {
2803 printf("Failed to open %s - %s\n",
2804 hold_info[i].fname, nt_errstr(status));
2808 if (io.ntcreatex.out.oplock_level != BATCH_OPLOCK_RETURN) {
2809 printf("Oplock not granted for %s - expected %d but got %d\n",
2810 hold_info[i].fname, BATCH_OPLOCK_RETURN,
2811 io.ntcreatex.out.oplock_level);
2814 hold_info[i].fnum = io.ntcreatex.out.file.fnum;
2816 /* make the file non-zero size */
2817 if (smbcli_write(cli->tree, hold_info[i].fnum, 0, &c, 0, 1) != 1) {
2818 printf("Failed to write to file\n");
2823 printf("Waiting for oplock events\n");
2824 event_loop_wait(ev);