2 Unix SMB/CIFS implementation.
3 basic raw test suite for oplocks
4 Copyright (C) Andrew Tridgell 2003
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "torture/torture.h"
22 #include "librpc/gen_ndr/security.h"
23 #include "libcli/raw/libcliraw.h"
24 #include "libcli/raw/raw_proto.h"
25 #include "libcli/libcli.h"
26 #include "torture/util.h"
27 #include "lib/events/events.h"
28 #include "param/param.h"
29 #include "lib/cmdline/popt_common.h"
30 #include "libcli/resolve/resolve.h"
32 #define CHECK_VAL(v, correct) do { \
33 if ((v) != (correct)) { \
34 torture_result(tctx, TORTURE_FAIL, "(%s): wrong value for %s got 0x%x - should be 0x%x\n", \
35 __location__, #v, (int)v, (int)correct); \
39 #define CHECK_RANGE(v, min, max) do { \
40 if ((v) < (min) || (v) > (max)) { \
41 torture_result(tctx, TORTURE_FAIL, "(%s): wrong value for %s got %d - should be between %d and %d\n", \
42 __location__, #v, (int)v, (int)min, (int)max); \
46 #define CHECK_STRMATCH(v, correct) do { \
47 if (!v || strstr((v),(correct)) == NULL) { \
48 torture_result(tctx, TORTURE_FAIL, "(%s): wrong value for %s got '%s' - should be '%s'\n", \
49 __location__, #v, v?v:"NULL", correct); \
54 #define CHECK_STATUS(tctx, status, correct) do { \
55 if (!NT_STATUS_EQUAL(status, correct)) { \
56 torture_result(tctx, TORTURE_FAIL, __location__": Incorrect status %s - should be %s", \
57 nt_errstr(status), nt_errstr(correct)); \
70 #define BASEDIR "\\test_oplock"
73 a handler function for oplock break requests. Ack it as a break to level II if possible
75 static bool oplock_handler_ack_to_given(struct smbcli_transport *transport,
76 uint16_t tid, uint16_t fnum,
77 uint8_t level, void *private)
79 struct smbcli_tree *tree = (struct smbcli_tree *)private;
82 break_info.fnum = fnum;
83 break_info.level = level;
87 case OPLOCK_BREAK_TO_LEVEL_II:
90 case OPLOCK_BREAK_TO_NONE:
95 break_info.failures++;
97 printf("Acking to %s [0x%02X] in oplock handler\n",
100 return smbcli_oplock_ack(tree, fnum, level);
104 a handler function for oplock break requests. Ack it as a break to none
106 static bool oplock_handler_ack_to_none(struct smbcli_transport *transport,
107 uint16_t tid, uint16_t fnum,
108 uint8_t level, void *private)
110 struct smbcli_tree *tree = (struct smbcli_tree *)private;
111 break_info.fnum = fnum;
112 break_info.level = level;
115 printf("Acking to none in oplock handler\n");
117 return smbcli_oplock_ack(tree, fnum, OPLOCK_BREAK_TO_NONE);
121 a handler function for oplock break requests. Let it timeout
123 static bool oplock_handler_timeout(struct smbcli_transport *transport,
124 uint16_t tid, uint16_t fnum,
125 uint8_t level, void *private)
127 break_info.fnum = fnum;
128 break_info.level = level;
131 printf("Let oplock break timeout\n");
135 static void oplock_handler_close_recv(struct smbcli_request *req)
138 status = smbcli_request_simple_recv(req);
139 if (!NT_STATUS_IS_OK(status)) {
140 printf("close failed in oplock_handler_close\n");
141 break_info.failures++;
146 a handler function for oplock break requests - close the file
148 static bool oplock_handler_close(struct smbcli_transport *transport, uint16_t tid,
149 uint16_t fnum, uint8_t level, void *private)
152 struct smbcli_tree *tree = (struct smbcli_tree *)private;
153 struct smbcli_request *req;
155 break_info.fnum = fnum;
156 break_info.level = level;
159 io.close.level = RAW_CLOSE_CLOSE;
160 io.close.in.file.fnum = fnum;
161 io.close.in.write_time = 0;
162 req = smb_raw_close_send(tree, &io);
164 printf("failed to send close in oplock_handler_close\n");
168 req->async.fn = oplock_handler_close_recv;
169 req->async.private = NULL;
174 static bool open_connection_no_level2_oplocks(struct torture_context *tctx,
175 struct smbcli_state **c)
178 struct smbcli_options options;
179 struct smbcli_session_options session_options;
181 lp_smbcli_options(tctx->lp_ctx, &options);
182 lp_smbcli_session_options(tctx->lp_ctx, &session_options);
184 options.use_level2_oplocks = false;
186 status = smbcli_full_connection(tctx, c,
187 torture_setting_string(tctx, "host", NULL),
188 lp_smb_ports(tctx->lp_ctx),
189 torture_setting_string(tctx, "share", NULL),
190 NULL, cmdline_credentials,
191 lp_resolve_context(tctx->lp_ctx),
192 tctx->ev, &options, &session_options);
193 if (!NT_STATUS_IS_OK(status)) {
194 printf("Failed to open connection - %s\n", nt_errstr(status));
201 static bool test_raw_oplock_exclusive1(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
203 const char *fname = BASEDIR "\\test_exclusive1.dat";
207 union smb_unlink unl;
210 if (!torture_setup_dir(cli1, BASEDIR)) {
215 smbcli_unlink(cli1->tree, fname);
217 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
222 io.generic.level = RAW_OPEN_NTCREATEX;
223 io.ntcreatex.in.root_fid = 0;
224 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
225 io.ntcreatex.in.alloc_size = 0;
226 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
227 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
228 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
229 io.ntcreatex.in.create_options = 0;
230 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
231 io.ntcreatex.in.security_flags = 0;
232 io.ntcreatex.in.fname = fname;
234 torture_comment(tctx, "EXCLUSIVE1: open a file with an exclusive oplock (share mode: none)\n");
235 ZERO_STRUCT(break_info);
236 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
238 status = smb_raw_open(cli1->tree, tctx, &io);
239 CHECK_STATUS(tctx, status, NT_STATUS_OK);
240 fnum = io.ntcreatex.out.file.fnum;
241 CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
243 torture_comment(tctx, "a 2nd open should not cause a break\n");
244 status = smb_raw_open(cli2->tree, tctx, &io);
245 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
246 CHECK_VAL(break_info.count, 0);
247 CHECK_VAL(break_info.failures, 0);
249 torture_comment(tctx, "unlink it - should also be no break\n");
250 unl.unlink.in.pattern = fname;
251 unl.unlink.in.attrib = 0;
252 status = smb_raw_unlink(cli2->tree, &unl);
253 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
254 CHECK_VAL(break_info.count, 0);
255 CHECK_VAL(break_info.failures, 0);
257 smbcli_close(cli1->tree, fnum);
260 smb_raw_exit(cli1->session);
261 smb_raw_exit(cli2->session);
262 smbcli_deltree(cli1->tree, BASEDIR);
266 static bool test_raw_oplock_exclusive2(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
268 const char *fname = BASEDIR "\\test_exclusive2.dat";
272 union smb_unlink unl;
273 uint16_t fnum=0, fnum2=0;
275 if (!torture_setup_dir(cli1, BASEDIR)) {
280 smbcli_unlink(cli1->tree, fname);
282 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
287 io.generic.level = RAW_OPEN_NTCREATEX;
288 io.ntcreatex.in.root_fid = 0;
289 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
290 io.ntcreatex.in.alloc_size = 0;
291 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
292 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
293 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
294 io.ntcreatex.in.create_options = 0;
295 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
296 io.ntcreatex.in.security_flags = 0;
297 io.ntcreatex.in.fname = fname;
299 torture_comment(tctx, "EXCLUSIVE2: open a file with an exclusive oplock (share mode: all)\n");
300 ZERO_STRUCT(break_info);
301 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
302 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
303 NTCREATEX_SHARE_ACCESS_WRITE|
304 NTCREATEX_SHARE_ACCESS_DELETE;
306 status = smb_raw_open(cli1->tree, tctx, &io);
307 CHECK_STATUS(tctx, status, NT_STATUS_OK);
308 fnum = io.ntcreatex.out.file.fnum;
309 CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
311 torture_comment(tctx, "a 2nd open should cause a break to level 2\n");
312 status = smb_raw_open(cli2->tree, tctx, &io);
313 CHECK_STATUS(tctx, status, NT_STATUS_OK);
314 fnum2 = io.ntcreatex.out.file.fnum;
315 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
316 CHECK_VAL(break_info.count, 1);
317 CHECK_VAL(break_info.fnum, fnum);
318 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
319 CHECK_VAL(break_info.failures, 0);
320 ZERO_STRUCT(break_info);
322 /* now we have 2 level II oplocks... */
323 torture_comment(tctx, "try to unlink it - should not cause a break, but a sharing violation\n");
324 unl.unlink.in.pattern = fname;
325 unl.unlink.in.attrib = 0;
326 status = smb_raw_unlink(cli2->tree, &unl);
327 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
328 CHECK_VAL(break_info.count, 0);
329 CHECK_VAL(break_info.failures, 0);
331 torture_comment(tctx, "close 1st handle\n");
332 smbcli_close(cli1->tree, fnum);
334 torture_comment(tctx, "try to unlink it - should not cause a break, but a sharing violation\n");
335 unl.unlink.in.pattern = fname;
336 unl.unlink.in.attrib = 0;
337 status = smb_raw_unlink(cli2->tree, &unl);
338 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
339 CHECK_VAL(break_info.count, 0);
340 CHECK_VAL(break_info.failures, 0);
342 torture_comment(tctx, "close 1st handle\n");
343 smbcli_close(cli2->tree, fnum2);
345 torture_comment(tctx, "unlink it\n");
346 unl.unlink.in.pattern = fname;
347 unl.unlink.in.attrib = 0;
348 status = smb_raw_unlink(cli2->tree, &unl);
349 CHECK_STATUS(tctx, status, NT_STATUS_OK);
350 CHECK_VAL(break_info.count, 0);
351 CHECK_VAL(break_info.failures, 0);
354 smb_raw_exit(cli1->session);
355 smb_raw_exit(cli2->session);
356 smbcli_deltree(cli1->tree, BASEDIR);
360 static bool test_raw_oplock_exclusive3(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
362 const char *fname = BASEDIR "\\test_exclusive3.dat";
366 union smb_setfileinfo sfi;
369 if (!torture_setup_dir(cli1, BASEDIR)) {
374 smbcli_unlink(cli1->tree, fname);
376 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
381 io.generic.level = RAW_OPEN_NTCREATEX;
382 io.ntcreatex.in.root_fid = 0;
383 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
384 io.ntcreatex.in.alloc_size = 0;
385 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
386 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
387 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
388 io.ntcreatex.in.create_options = 0;
389 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
390 io.ntcreatex.in.security_flags = 0;
391 io.ntcreatex.in.fname = fname;
393 torture_comment(tctx, "EXCLUSIVE3: open a file with an exclusive oplock (share mode: none)\n");
395 ZERO_STRUCT(break_info);
396 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
398 status = smb_raw_open(cli1->tree, tctx, &io);
399 CHECK_STATUS(tctx, status, NT_STATUS_OK);
400 fnum = io.ntcreatex.out.file.fnum;
401 CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
403 torture_comment(tctx, "setpathinfo EOF should trigger a break to none\n");
405 sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
406 sfi.generic.in.file.path = fname;
407 sfi.end_of_file_info.in.size = 100;
409 status = smb_raw_setpathinfo(cli2->tree, &sfi);
411 CHECK_STATUS(tctx, status, NT_STATUS_OK);
412 CHECK_VAL(break_info.count, 1);
413 CHECK_VAL(break_info.failures, 0);
414 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_NONE);
416 smbcli_close(cli1->tree, fnum);
419 smb_raw_exit(cli1->session);
420 smb_raw_exit(cli2->session);
421 smbcli_deltree(cli1->tree, BASEDIR);
425 static bool test_raw_oplock_exclusive4(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
427 const char *fname = BASEDIR "\\test_exclusive4.dat";
431 uint16_t fnum=0, fnum2=0;
433 if (!torture_setup_dir(cli1, BASEDIR)) {
438 smbcli_unlink(cli1->tree, fname);
440 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
445 io.generic.level = RAW_OPEN_NTCREATEX;
446 io.ntcreatex.in.root_fid = 0;
447 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
448 io.ntcreatex.in.alloc_size = 0;
449 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
450 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
451 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
452 io.ntcreatex.in.create_options = 0;
453 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
454 io.ntcreatex.in.security_flags = 0;
455 io.ntcreatex.in.fname = fname;
457 torture_comment(tctx, "EXCLUSIVE4: open with exclusive oplock\n");
458 ZERO_STRUCT(break_info);
459 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
461 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
462 status = smb_raw_open(cli1->tree, tctx, &io);
463 CHECK_STATUS(tctx, status, NT_STATUS_OK);
464 fnum = io.ntcreatex.out.file.fnum;
465 CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
467 ZERO_STRUCT(break_info);
468 torture_comment(tctx, "second open with attributes only shouldn't cause oplock break\n");
470 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
471 io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
472 status = smb_raw_open(cli2->tree, tctx, &io);
473 CHECK_STATUS(tctx, status, NT_STATUS_OK);
474 fnum2 = io.ntcreatex.out.file.fnum;
475 CHECK_VAL(io.ntcreatex.out.oplock_level, NO_OPLOCK_RETURN);
476 CHECK_VAL(break_info.count, 0);
477 CHECK_VAL(break_info.failures, 0);
479 smbcli_close(cli1->tree, fnum);
480 smbcli_close(cli2->tree, fnum2);
483 smb_raw_exit(cli1->session);
484 smb_raw_exit(cli2->session);
485 smbcli_deltree(cli1->tree, BASEDIR);
489 static bool test_raw_oplock_exclusive5(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
491 const char *fname = BASEDIR "\\test_exclusive5.dat";
495 uint16_t fnum=0, fnum2=0;
497 if (!torture_setup_dir(cli1, BASEDIR)) {
502 smbcli_unlink(cli1->tree, fname);
504 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
505 smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli1->tree);
510 io.generic.level = RAW_OPEN_NTCREATEX;
511 io.ntcreatex.in.root_fid = 0;
512 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
513 io.ntcreatex.in.alloc_size = 0;
514 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
515 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
516 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
517 io.ntcreatex.in.create_options = 0;
518 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
519 io.ntcreatex.in.security_flags = 0;
520 io.ntcreatex.in.fname = fname;
522 torture_comment(tctx, "EXCLUSIVE5: open with exclusive oplock\n");
523 ZERO_STRUCT(break_info);
524 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
527 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
528 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
529 NTCREATEX_SHARE_ACCESS_WRITE|
530 NTCREATEX_SHARE_ACCESS_DELETE;
531 status = smb_raw_open(cli1->tree, tctx, &io);
532 CHECK_STATUS(tctx, status, NT_STATUS_OK);
533 fnum = io.ntcreatex.out.file.fnum;
534 CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
536 ZERO_STRUCT(break_info);
538 torture_comment(tctx, "second open with attributes only and NTCREATEX_DISP_OVERWRITE_IF dispostion causes oplock break\n");
540 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
541 io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
542 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE_IF;
543 status = smb_raw_open(cli2->tree, tctx, &io);
544 CHECK_STATUS(tctx, status, NT_STATUS_OK);
545 fnum2 = io.ntcreatex.out.file.fnum;
546 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
547 CHECK_VAL(break_info.count, 1);
548 CHECK_VAL(break_info.failures, 0);
550 smbcli_close(cli1->tree, fnum);
551 smbcli_close(cli2->tree, fnum2);
554 smb_raw_exit(cli1->session);
555 smb_raw_exit(cli2->session);
556 smbcli_deltree(cli1->tree, BASEDIR);
560 static bool test_raw_oplock_exclusive6(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
562 const char *fname1 = BASEDIR "\\test_exclusive6_1.dat";
563 const char *fname2 = BASEDIR "\\test_exclusive6_2.dat";
570 if (!torture_setup_dir(cli1, BASEDIR)) {
575 smbcli_unlink(cli1->tree, fname1);
576 smbcli_unlink(cli1->tree, fname2);
578 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
583 io.generic.level = RAW_OPEN_NTCREATEX;
584 io.ntcreatex.in.root_fid = 0;
585 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
586 io.ntcreatex.in.alloc_size = 0;
587 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
588 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
589 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
590 io.ntcreatex.in.create_options = 0;
591 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
592 io.ntcreatex.in.security_flags = 0;
593 io.ntcreatex.in.fname = fname1;
595 torture_comment(tctx, "EXCLUSIVE6: open a file with an exclusive oplock (share mode: none)\n");
596 ZERO_STRUCT(break_info);
597 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
599 status = smb_raw_open(cli1->tree, tctx, &io);
600 CHECK_STATUS(tctx, status, NT_STATUS_OK);
601 fnum = io.ntcreatex.out.file.fnum;
602 CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
604 torture_comment(tctx, "rename should not generate a break but get a sharing violation\n");
606 rn.generic.level = RAW_RENAME_RENAME;
607 rn.rename.in.pattern1 = fname1;
608 rn.rename.in.pattern2 = fname2;
609 rn.rename.in.attrib = 0;
611 printf("trying rename while first file open\n");
612 status = smb_raw_rename(cli2->tree, &rn);
614 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
615 CHECK_VAL(break_info.count, 0);
616 CHECK_VAL(break_info.failures, 0);
618 smbcli_close(cli1->tree, fnum);
621 smb_raw_exit(cli1->session);
622 smb_raw_exit(cli2->session);
623 smbcli_deltree(cli1->tree, BASEDIR);
627 static bool test_raw_oplock_batch1(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
629 const char *fname = BASEDIR "\\test_batch1.dat";
633 union smb_unlink unl;
637 if (!torture_setup_dir(cli1, BASEDIR)) {
642 smbcli_unlink(cli1->tree, fname);
644 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
649 io.generic.level = RAW_OPEN_NTCREATEX;
650 io.ntcreatex.in.root_fid = 0;
651 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
652 io.ntcreatex.in.alloc_size = 0;
653 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
654 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
655 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
656 io.ntcreatex.in.create_options = 0;
657 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
658 io.ntcreatex.in.security_flags = 0;
659 io.ntcreatex.in.fname = fname;
662 with a batch oplock we get a break
664 torture_comment(tctx, "BATCH1: open with batch oplock\n");
665 ZERO_STRUCT(break_info);
666 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
667 NTCREATEX_FLAGS_REQUEST_OPLOCK |
668 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
669 status = smb_raw_open(cli1->tree, tctx, &io);
670 CHECK_STATUS(tctx, status, NT_STATUS_OK);
671 fnum = io.ntcreatex.out.file.fnum;
672 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
674 torture_comment(tctx, "unlink should generate a break\n");
675 unl.unlink.in.pattern = fname;
676 unl.unlink.in.attrib = 0;
677 status = smb_raw_unlink(cli2->tree, &unl);
678 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
680 CHECK_VAL(break_info.count, 1);
681 CHECK_VAL(break_info.fnum, fnum);
682 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
683 CHECK_VAL(break_info.failures, 0);
685 torture_comment(tctx, "2nd unlink should not generate a break\n");
686 ZERO_STRUCT(break_info);
687 status = smb_raw_unlink(cli2->tree, &unl);
688 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
690 CHECK_VAL(break_info.count, 0);
692 torture_comment(tctx, "writing should generate a self break to none\n");
693 smbcli_write(cli1->tree, fnum, 0, &c, 0, 1);
695 smbcli_write(cli1->tree, fnum, 0, &c, 1, 1);
697 CHECK_VAL(break_info.count, 1);
698 CHECK_VAL(break_info.fnum, fnum);
699 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_NONE);
700 CHECK_VAL(break_info.failures, 0);
702 smbcli_close(cli1->tree, fnum);
705 smb_raw_exit(cli1->session);
706 smb_raw_exit(cli2->session);
707 smbcli_deltree(cli1->tree, BASEDIR);
711 static bool test_raw_oplock_batch2(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
713 const char *fname = BASEDIR "\\test_batch2.dat";
717 union smb_unlink unl;
721 if (!torture_setup_dir(cli1, BASEDIR)) {
726 smbcli_unlink(cli1->tree, fname);
728 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
733 io.generic.level = RAW_OPEN_NTCREATEX;
734 io.ntcreatex.in.root_fid = 0;
735 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
736 io.ntcreatex.in.alloc_size = 0;
737 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
738 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
739 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
740 io.ntcreatex.in.create_options = 0;
741 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
742 io.ntcreatex.in.security_flags = 0;
743 io.ntcreatex.in.fname = fname;
745 torture_comment(tctx, "BATCH2: open with batch oplock\n");
746 ZERO_STRUCT(break_info);
747 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
748 NTCREATEX_FLAGS_REQUEST_OPLOCK |
749 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
750 status = smb_raw_open(cli1->tree, tctx, &io);
751 CHECK_STATUS(tctx, status, NT_STATUS_OK);
752 fnum = io.ntcreatex.out.file.fnum;
753 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
755 torture_comment(tctx, "unlink should generate a break, which we ack as break to none\n");
756 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_none, cli1->tree);
757 unl.unlink.in.pattern = fname;
758 unl.unlink.in.attrib = 0;
759 status = smb_raw_unlink(cli2->tree, &unl);
760 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
762 CHECK_VAL(break_info.count, 1);
763 CHECK_VAL(break_info.fnum, fnum);
764 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
765 CHECK_VAL(break_info.failures, 0);
767 torture_comment(tctx, "2nd unlink should not generate a break\n");
768 ZERO_STRUCT(break_info);
769 status = smb_raw_unlink(cli2->tree, &unl);
770 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
772 CHECK_VAL(break_info.count, 0);
774 torture_comment(tctx, "writing should not generate a break\n");
775 smbcli_write(cli1->tree, fnum, 0, &c, 0, 1);
777 smbcli_write(cli1->tree, fnum, 0, &c, 1, 1);
779 CHECK_VAL(break_info.count, 0);
781 smbcli_close(cli1->tree, fnum);
784 smb_raw_exit(cli1->session);
785 smb_raw_exit(cli2->session);
786 smbcli_deltree(cli1->tree, BASEDIR);
790 static bool test_raw_oplock_batch3(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
792 const char *fname = BASEDIR "\\test_batch3.dat";
796 union smb_unlink unl;
799 if (!torture_setup_dir(cli1, BASEDIR)) {
804 smbcli_unlink(cli1->tree, fname);
806 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
811 io.generic.level = RAW_OPEN_NTCREATEX;
812 io.ntcreatex.in.root_fid = 0;
813 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
814 io.ntcreatex.in.alloc_size = 0;
815 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
816 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
817 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
818 io.ntcreatex.in.create_options = 0;
819 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
820 io.ntcreatex.in.security_flags = 0;
821 io.ntcreatex.in.fname = fname;
823 torture_comment(tctx, "BATCH3: if we close on break then the unlink can succeed\n");
824 ZERO_STRUCT(break_info);
825 smbcli_oplock_handler(cli1->transport, oplock_handler_close, cli1->tree);
826 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
827 NTCREATEX_FLAGS_REQUEST_OPLOCK |
828 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
829 status = smb_raw_open(cli1->tree, tctx, &io);
830 CHECK_STATUS(tctx, status, NT_STATUS_OK);
831 fnum = io.ntcreatex.out.file.fnum;
832 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
834 unl.unlink.in.pattern = fname;
835 unl.unlink.in.attrib = 0;
836 ZERO_STRUCT(break_info);
837 status = smb_raw_unlink(cli2->tree, &unl);
838 CHECK_STATUS(tctx, status, NT_STATUS_OK);
840 CHECK_VAL(break_info.count, 1);
841 CHECK_VAL(break_info.fnum, fnum);
842 CHECK_VAL(break_info.level, 1);
843 CHECK_VAL(break_info.failures, 0);
845 smbcli_close(cli1->tree, fnum);
848 smb_raw_exit(cli1->session);
849 smb_raw_exit(cli2->session);
850 smbcli_deltree(cli1->tree, BASEDIR);
854 static bool test_raw_oplock_batch4(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
856 const char *fname = BASEDIR "\\test_batch4.dat";
863 if (!torture_setup_dir(cli1, BASEDIR)) {
868 smbcli_unlink(cli1->tree, fname);
870 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
875 io.generic.level = RAW_OPEN_NTCREATEX;
876 io.ntcreatex.in.root_fid = 0;
877 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
878 io.ntcreatex.in.alloc_size = 0;
879 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
880 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
881 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
882 io.ntcreatex.in.create_options = 0;
883 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
884 io.ntcreatex.in.security_flags = 0;
885 io.ntcreatex.in.fname = fname;
887 torture_comment(tctx, "BATCH4: a self read should not cause a break\n");
888 ZERO_STRUCT(break_info);
889 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
891 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
892 NTCREATEX_FLAGS_REQUEST_OPLOCK |
893 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
894 status = smb_raw_open(cli1->tree, tctx, &io);
895 CHECK_STATUS(tctx, status, NT_STATUS_OK);
896 fnum = io.ntcreatex.out.file.fnum;
897 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
899 rd.read.level = RAW_READ_READ;
900 rd.read.in.file.fnum = fnum;
901 rd.read.in.count = 1;
902 rd.read.in.offset = 0;
903 rd.read.in.remaining = 0;
904 status = smb_raw_read(cli1->tree, &rd);
905 CHECK_STATUS(tctx, status, NT_STATUS_OK);
906 CHECK_VAL(break_info.count, 0);
907 CHECK_VAL(break_info.failures, 0);
909 smbcli_close(cli1->tree, fnum);
912 smb_raw_exit(cli1->session);
913 smb_raw_exit(cli2->session);
914 smbcli_deltree(cli1->tree, BASEDIR);
918 static bool test_raw_oplock_batch5(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
920 const char *fname = BASEDIR "\\test_batch5.dat";
926 if (!torture_setup_dir(cli1, BASEDIR)) {
931 smbcli_unlink(cli1->tree, fname);
933 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
938 io.generic.level = RAW_OPEN_NTCREATEX;
939 io.ntcreatex.in.root_fid = 0;
940 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
941 io.ntcreatex.in.alloc_size = 0;
942 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
943 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
944 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
945 io.ntcreatex.in.create_options = 0;
946 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
947 io.ntcreatex.in.security_flags = 0;
948 io.ntcreatex.in.fname = fname;
950 torture_comment(tctx, "BATCH5: a 2nd open should give a break\n");
951 ZERO_STRUCT(break_info);
952 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
954 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
955 NTCREATEX_FLAGS_REQUEST_OPLOCK |
956 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
957 status = smb_raw_open(cli1->tree, tctx, &io);
958 CHECK_STATUS(tctx, status, NT_STATUS_OK);
959 fnum = io.ntcreatex.out.file.fnum;
960 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
962 ZERO_STRUCT(break_info);
964 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
965 status = smb_raw_open(cli2->tree, tctx, &io);
966 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
968 CHECK_VAL(break_info.count, 1);
969 CHECK_VAL(break_info.fnum, fnum);
970 CHECK_VAL(break_info.level, 1);
971 CHECK_VAL(break_info.failures, 0);
973 smbcli_close(cli1->tree, fnum);
976 smb_raw_exit(cli1->session);
977 smb_raw_exit(cli2->session);
978 smbcli_deltree(cli1->tree, BASEDIR);
982 static bool test_raw_oplock_batch6(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
984 const char *fname = BASEDIR "\\test_batch6.dat";
988 uint16_t fnum=0, fnum2=0;
991 if (!torture_setup_dir(cli1, BASEDIR)) {
996 smbcli_unlink(cli1->tree, fname);
998 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1001 base ntcreatex parms
1003 io.generic.level = RAW_OPEN_NTCREATEX;
1004 io.ntcreatex.in.root_fid = 0;
1005 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1006 io.ntcreatex.in.alloc_size = 0;
1007 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1008 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1009 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1010 io.ntcreatex.in.create_options = 0;
1011 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1012 io.ntcreatex.in.security_flags = 0;
1013 io.ntcreatex.in.fname = fname;
1015 torture_comment(tctx, "BATCH6: a 2nd open should give a break to level II if the first open allowed shared read\n");
1016 ZERO_STRUCT(break_info);
1017 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1018 smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli2->tree);
1020 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_READ | SEC_RIGHTS_FILE_WRITE;
1021 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
1022 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1023 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1024 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1025 status = smb_raw_open(cli1->tree, tctx, &io);
1026 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1027 fnum = io.ntcreatex.out.file.fnum;
1028 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1030 ZERO_STRUCT(break_info);
1032 status = smb_raw_open(cli2->tree, tctx, &io);
1033 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1034 fnum2 = io.ntcreatex.out.file.fnum;
1035 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1037 CHECK_VAL(break_info.count, 1);
1038 CHECK_VAL(break_info.fnum, fnum);
1039 CHECK_VAL(break_info.level, 1);
1040 CHECK_VAL(break_info.failures, 0);
1041 ZERO_STRUCT(break_info);
1043 torture_comment(tctx, "write should trigger a break to none on both\n");
1044 smbcli_write(cli1->tree, fnum, 0, &c, 0, 1);
1046 smbcli_write(cli1->tree, fnum, 0, &c, 1, 1);
1048 CHECK_VAL(break_info.count, 2);
1049 CHECK_VAL(break_info.level, 0);
1050 CHECK_VAL(break_info.failures, 0);
1052 smbcli_close(cli1->tree, fnum);
1053 smbcli_close(cli2->tree, fnum2);
1057 smb_raw_exit(cli1->session);
1058 smb_raw_exit(cli2->session);
1059 smbcli_deltree(cli1->tree, BASEDIR);
1063 static bool test_raw_oplock_batch7(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1065 const char *fname = BASEDIR "\\test_batch7.dat";
1069 uint16_t fnum=0, fnum2=0;
1071 if (!torture_setup_dir(cli1, BASEDIR)) {
1076 smbcli_unlink(cli1->tree, fname);
1078 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1081 base ntcreatex parms
1083 io.generic.level = RAW_OPEN_NTCREATEX;
1084 io.ntcreatex.in.root_fid = 0;
1085 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1086 io.ntcreatex.in.alloc_size = 0;
1087 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1088 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1089 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1090 io.ntcreatex.in.create_options = 0;
1091 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1092 io.ntcreatex.in.security_flags = 0;
1093 io.ntcreatex.in.fname = fname;
1095 torture_comment(tctx, "BATCH7: a 2nd open should get an oplock when we close instead of ack\n");
1096 ZERO_STRUCT(break_info);
1097 smbcli_oplock_handler(cli1->transport, oplock_handler_close, cli1->tree);
1099 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1100 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1101 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1102 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1103 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1104 status = smb_raw_open(cli1->tree, tctx, &io);
1105 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1106 fnum2 = io.ntcreatex.out.file.fnum;
1107 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1109 ZERO_STRUCT(break_info);
1111 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1112 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1113 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1114 status = smb_raw_open(cli2->tree, tctx, &io);
1115 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1116 fnum = io.ntcreatex.out.file.fnum;
1117 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1119 CHECK_VAL(break_info.count, 1);
1120 CHECK_VAL(break_info.fnum, fnum2);
1121 CHECK_VAL(break_info.level, 1);
1122 CHECK_VAL(break_info.failures, 0);
1124 smbcli_close(cli2->tree, fnum);
1127 smb_raw_exit(cli1->session);
1128 smb_raw_exit(cli2->session);
1129 smbcli_deltree(cli1->tree, BASEDIR);
1133 static bool test_raw_oplock_batch8(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1135 const char *fname = BASEDIR "\\test_batch8.dat";
1139 uint16_t fnum=0, fnum2=0;
1141 if (!torture_setup_dir(cli1, BASEDIR)) {
1146 smbcli_unlink(cli1->tree, fname);
1148 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1151 base ntcreatex parms
1153 io.generic.level = RAW_OPEN_NTCREATEX;
1154 io.ntcreatex.in.root_fid = 0;
1155 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1156 io.ntcreatex.in.alloc_size = 0;
1157 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1158 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1159 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1160 io.ntcreatex.in.create_options = 0;
1161 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1162 io.ntcreatex.in.security_flags = 0;
1163 io.ntcreatex.in.fname = fname;
1165 torture_comment(tctx, "BATCH8: open with batch oplock\n");
1166 ZERO_STRUCT(break_info);
1167 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1169 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1170 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1171 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1172 status = smb_raw_open(cli1->tree, tctx, &io);
1173 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1174 fnum = io.ntcreatex.out.file.fnum;
1175 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1177 ZERO_STRUCT(break_info);
1178 torture_comment(tctx, "second open with attributes only shouldn't cause oplock break\n");
1180 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1181 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1182 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1183 io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
1184 status = smb_raw_open(cli2->tree, tctx, &io);
1185 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1186 fnum2 = io.ntcreatex.out.file.fnum;
1187 CHECK_VAL(io.ntcreatex.out.oplock_level, NO_OPLOCK_RETURN);
1188 CHECK_VAL(break_info.count, 0);
1189 CHECK_VAL(break_info.failures, 0);
1191 smbcli_close(cli1->tree, fnum);
1192 smbcli_close(cli2->tree, fnum2);
1195 smb_raw_exit(cli1->session);
1196 smb_raw_exit(cli2->session);
1197 smbcli_deltree(cli1->tree, BASEDIR);
1201 static bool test_raw_oplock_batch9(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1203 const char *fname = BASEDIR "\\test_batch9.dat";
1207 uint16_t fnum=0, fnum2=0;
1210 if (!torture_setup_dir(cli1, BASEDIR)) {
1215 smbcli_unlink(cli1->tree, fname);
1217 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1220 base ntcreatex parms
1222 io.generic.level = RAW_OPEN_NTCREATEX;
1223 io.ntcreatex.in.root_fid = 0;
1224 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1225 io.ntcreatex.in.alloc_size = 0;
1226 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1227 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1228 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1229 io.ntcreatex.in.create_options = 0;
1230 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1231 io.ntcreatex.in.security_flags = 0;
1232 io.ntcreatex.in.fname = fname;
1234 torture_comment(tctx, "BATCH9: open with attributes only can create file\n");
1236 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1237 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1238 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1239 io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
1240 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1241 status = smb_raw_open(cli1->tree, tctx, &io);
1242 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1243 fnum = io.ntcreatex.out.file.fnum;
1244 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1246 torture_comment(tctx, "Subsequent normal open should break oplock on attribute only open to level II\n");
1248 ZERO_STRUCT(break_info);
1249 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1251 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1252 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1253 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1254 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1255 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1256 status = smb_raw_open(cli2->tree, tctx, &io);
1257 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1258 fnum2 = io.ntcreatex.out.file.fnum;
1259 CHECK_VAL(break_info.count, 1);
1260 CHECK_VAL(break_info.fnum, fnum);
1261 CHECK_VAL(break_info.failures, 0);
1262 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
1263 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1264 smbcli_close(cli2->tree, fnum2);
1266 torture_comment(tctx, "third oplocked open should grant level2 without break\n");
1267 ZERO_STRUCT(break_info);
1268 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1269 smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli2->tree);
1270 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1271 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1272 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1273 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1274 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1275 status = smb_raw_open(cli2->tree, tctx, &io);
1276 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1277 fnum2 = io.ntcreatex.out.file.fnum;
1278 CHECK_VAL(break_info.count, 0);
1279 CHECK_VAL(break_info.failures, 0);
1280 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1282 ZERO_STRUCT(break_info);
1284 torture_comment(tctx, "write should trigger a break to none on both\n");
1285 smbcli_write(cli2->tree, fnum2, 0, &c, 0, 1);
1287 /* Now the oplock break request comes in. But right now we can't
1288 * answer it. Do another write */
1291 smbcli_write(cli2->tree, fnum2, 0, &c, 1, 1);
1293 CHECK_VAL(break_info.count, 2);
1294 CHECK_VAL(break_info.level, 0);
1295 CHECK_VAL(break_info.failures, 0);
1297 smbcli_close(cli1->tree, fnum);
1298 smbcli_close(cli2->tree, fnum2);
1301 smb_raw_exit(cli1->session);
1302 smb_raw_exit(cli2->session);
1303 smbcli_deltree(cli1->tree, BASEDIR);
1307 static bool test_raw_oplock_batch10(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1309 const char *fname = BASEDIR "\\test_batch10.dat";
1313 uint16_t fnum=0, fnum2=0;
1315 if (!torture_setup_dir(cli1, BASEDIR)) {
1320 smbcli_unlink(cli1->tree, fname);
1322 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1325 base ntcreatex parms
1327 io.generic.level = RAW_OPEN_NTCREATEX;
1328 io.ntcreatex.in.root_fid = 0;
1329 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1330 io.ntcreatex.in.alloc_size = 0;
1331 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1332 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1333 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1334 io.ntcreatex.in.create_options = 0;
1335 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1336 io.ntcreatex.in.security_flags = 0;
1337 io.ntcreatex.in.fname = fname;
1339 torture_comment(tctx, "BATCH10: Open with oplock after a non-oplock open should grant level2\n");
1340 ZERO_STRUCT(break_info);
1341 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
1342 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1343 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1344 NTCREATEX_SHARE_ACCESS_WRITE|
1345 NTCREATEX_SHARE_ACCESS_DELETE;
1346 status = smb_raw_open(cli1->tree, tctx, &io);
1347 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1348 fnum = io.ntcreatex.out.file.fnum;
1349 CHECK_VAL(break_info.count, 0);
1350 CHECK_VAL(break_info.failures, 0);
1351 CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
1353 smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli2->tree);
1355 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1356 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1357 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1358 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1359 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1360 NTCREATEX_SHARE_ACCESS_WRITE|
1361 NTCREATEX_SHARE_ACCESS_DELETE;
1362 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1363 status = smb_raw_open(cli2->tree, tctx, &io);
1364 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1365 fnum2 = io.ntcreatex.out.file.fnum;
1366 CHECK_VAL(break_info.count, 0);
1367 CHECK_VAL(break_info.failures, 0);
1368 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1370 torture_comment(tctx, "write should trigger a break to none\n");
1373 wr.write.level = RAW_WRITE_WRITE;
1374 wr.write.in.file.fnum = fnum;
1375 wr.write.in.count = 1;
1376 wr.write.in.offset = 0;
1377 wr.write.in.remaining = 0;
1378 wr.write.in.data = (const uint8_t *)"x";
1379 status = smb_raw_write(cli1->tree, &wr);
1380 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1383 /* Now the oplock break request comes in. But right now we can't
1384 * answer it. Do another write */
1390 wr.write.level = RAW_WRITE_WRITE;
1391 wr.write.in.file.fnum = fnum;
1392 wr.write.in.count = 1;
1393 wr.write.in.offset = 0;
1394 wr.write.in.remaining = 0;
1395 wr.write.in.data = (const uint8_t *)"x";
1396 status = smb_raw_write(cli1->tree, &wr);
1397 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1400 CHECK_VAL(break_info.count, 1);
1401 CHECK_VAL(break_info.fnum, fnum2);
1402 CHECK_VAL(break_info.level, 0);
1403 CHECK_VAL(break_info.failures, 0);
1405 smbcli_close(cli1->tree, fnum);
1406 smbcli_close(cli2->tree, fnum2);
1409 smb_raw_exit(cli1->session);
1410 smb_raw_exit(cli2->session);
1411 smbcli_deltree(cli1->tree, BASEDIR);
1415 static bool test_raw_oplock_batch11(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1417 const char *fname = BASEDIR "\\test_batch11.dat";
1421 union smb_setfileinfo sfi;
1424 if (!torture_setup_dir(cli1, BASEDIR)) {
1429 smbcli_unlink(cli1->tree, fname);
1431 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1434 base ntcreatex parms
1436 io.generic.level = RAW_OPEN_NTCREATEX;
1437 io.ntcreatex.in.root_fid = 0;
1438 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1439 io.ntcreatex.in.alloc_size = 0;
1440 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1441 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1442 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1443 io.ntcreatex.in.create_options = 0;
1444 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1445 io.ntcreatex.in.security_flags = 0;
1446 io.ntcreatex.in.fname = fname;
1448 /* Test if a set-eof on pathname breaks an exclusive oplock. */
1449 torture_comment(tctx, "BATCH11: Test if setpathinfo set EOF breaks oplocks.\n");
1451 ZERO_STRUCT(break_info);
1452 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1454 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1455 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1456 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1457 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1458 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1459 NTCREATEX_SHARE_ACCESS_WRITE|
1460 NTCREATEX_SHARE_ACCESS_DELETE;
1461 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1462 status = smb_raw_open(cli1->tree, tctx, &io);
1463 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1464 fnum = io.ntcreatex.out.file.fnum;
1465 CHECK_VAL(break_info.count, 0);
1466 CHECK_VAL(break_info.failures, 0);
1467 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1470 sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
1471 sfi.generic.in.file.path = fname;
1472 sfi.end_of_file_info.in.size = 100;
1474 status = smb_raw_setpathinfo(cli2->tree, &sfi);
1476 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1477 CHECK_VAL(break_info.count, 1);
1478 CHECK_VAL(break_info.failures, 0);
1479 CHECK_VAL(break_info.level, 0);
1481 smbcli_close(cli1->tree, fnum);
1484 smb_raw_exit(cli1->session);
1485 smb_raw_exit(cli2->session);
1486 smbcli_deltree(cli1->tree, BASEDIR);
1490 static bool test_raw_oplock_batch12(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1492 const char *fname = BASEDIR "\\test_batch12.dat";
1496 union smb_setfileinfo sfi;
1499 if (!torture_setup_dir(cli1, BASEDIR)) {
1504 smbcli_unlink(cli1->tree, fname);
1506 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1509 base ntcreatex parms
1511 io.generic.level = RAW_OPEN_NTCREATEX;
1512 io.ntcreatex.in.root_fid = 0;
1513 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1514 io.ntcreatex.in.alloc_size = 0;
1515 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1516 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1517 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1518 io.ntcreatex.in.create_options = 0;
1519 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1520 io.ntcreatex.in.security_flags = 0;
1521 io.ntcreatex.in.fname = fname;
1523 /* Test if a set-allocation size on pathname breaks an exclusive oplock. */
1524 torture_comment(tctx, "BATCH12: Test if setpathinfo allocation size breaks oplocks.\n");
1526 ZERO_STRUCT(break_info);
1527 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1529 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1530 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1531 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1532 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1533 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1534 NTCREATEX_SHARE_ACCESS_WRITE|
1535 NTCREATEX_SHARE_ACCESS_DELETE;
1536 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1537 status = smb_raw_open(cli1->tree, tctx, &io);
1538 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1539 fnum = io.ntcreatex.out.file.fnum;
1540 CHECK_VAL(break_info.count, 0);
1541 CHECK_VAL(break_info.failures, 0);
1542 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1545 sfi.generic.level = SMB_SFILEINFO_ALLOCATION_INFORMATION;
1546 sfi.generic.in.file.path = fname;
1547 sfi.allocation_info.in.alloc_size = 65536 * 8;
1549 status = smb_raw_setpathinfo(cli2->tree, &sfi);
1551 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1552 CHECK_VAL(break_info.count, 1);
1553 CHECK_VAL(break_info.failures, 0);
1554 CHECK_VAL(break_info.level, 0);
1556 smbcli_close(cli1->tree, fnum);
1559 smb_raw_exit(cli1->session);
1560 smb_raw_exit(cli2->session);
1561 smbcli_deltree(cli1->tree, BASEDIR);
1565 static bool test_raw_oplock_batch13(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1567 const char *fname = BASEDIR "\\test_batch13.dat";
1571 uint16_t fnum=0, fnum2=0;
1573 if (!torture_setup_dir(cli1, BASEDIR)) {
1578 smbcli_unlink(cli1->tree, fname);
1580 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1581 smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli1->tree);
1584 base ntcreatex parms
1586 io.generic.level = RAW_OPEN_NTCREATEX;
1587 io.ntcreatex.in.root_fid = 0;
1588 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1589 io.ntcreatex.in.alloc_size = 0;
1590 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1591 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1592 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1593 io.ntcreatex.in.create_options = 0;
1594 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1595 io.ntcreatex.in.security_flags = 0;
1596 io.ntcreatex.in.fname = fname;
1598 torture_comment(tctx, "BATCH13: open with batch oplock\n");
1599 ZERO_STRUCT(break_info);
1600 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1603 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1604 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1605 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1606 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1607 NTCREATEX_SHARE_ACCESS_WRITE|
1608 NTCREATEX_SHARE_ACCESS_DELETE;
1609 status = smb_raw_open(cli1->tree, tctx, &io);
1610 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1611 fnum = io.ntcreatex.out.file.fnum;
1612 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1614 ZERO_STRUCT(break_info);
1616 torture_comment(tctx, "second open with attributes only and NTCREATEX_DISP_OVERWRITE dispostion causes oplock break\n");
1618 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1619 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1620 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1621 io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
1622 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1623 NTCREATEX_SHARE_ACCESS_WRITE|
1624 NTCREATEX_SHARE_ACCESS_DELETE;
1625 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE;
1626 status = smb_raw_open(cli2->tree, tctx, &io);
1627 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1628 fnum2 = io.ntcreatex.out.file.fnum;
1629 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1630 CHECK_VAL(break_info.count, 1);
1631 CHECK_VAL(break_info.failures, 0);
1633 smbcli_close(cli1->tree, fnum);
1634 smbcli_close(cli2->tree, fnum2);
1637 smb_raw_exit(cli1->session);
1638 smb_raw_exit(cli2->session);
1639 smbcli_deltree(cli1->tree, BASEDIR);
1643 static bool test_raw_oplock_batch14(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1645 const char *fname = BASEDIR "\\test_batch14.dat";
1649 uint16_t fnum=0, fnum2=0;
1651 if (!torture_setup_dir(cli1, BASEDIR)) {
1656 smbcli_unlink(cli1->tree, fname);
1658 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1661 base ntcreatex parms
1663 io.generic.level = RAW_OPEN_NTCREATEX;
1664 io.ntcreatex.in.root_fid = 0;
1665 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1666 io.ntcreatex.in.alloc_size = 0;
1667 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1668 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1669 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1670 io.ntcreatex.in.create_options = 0;
1671 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1672 io.ntcreatex.in.security_flags = 0;
1673 io.ntcreatex.in.fname = fname;
1675 torture_comment(tctx, "BATCH14: open with batch oplock\n");
1676 ZERO_STRUCT(break_info);
1677 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1679 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1680 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1681 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1682 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1683 NTCREATEX_SHARE_ACCESS_WRITE|
1684 NTCREATEX_SHARE_ACCESS_DELETE;
1685 status = smb_raw_open(cli1->tree, tctx, &io);
1686 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1687 fnum = io.ntcreatex.out.file.fnum;
1688 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1690 ZERO_STRUCT(break_info);
1692 torture_comment(tctx, "second open with attributes only and NTCREATEX_DISP_SUPERSEDE dispostion causes oplock break\n");
1694 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1695 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1696 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1697 io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
1698 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1699 NTCREATEX_SHARE_ACCESS_WRITE|
1700 NTCREATEX_SHARE_ACCESS_DELETE;
1701 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE;
1702 status = smb_raw_open(cli2->tree, tctx, &io);
1703 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1704 fnum2 = io.ntcreatex.out.file.fnum;
1705 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1706 CHECK_VAL(break_info.count, 1);
1707 CHECK_VAL(break_info.failures, 0);
1709 smbcli_close(cli1->tree, fnum);
1710 smbcli_close(cli2->tree, fnum2);
1712 smb_raw_exit(cli1->session);
1713 smb_raw_exit(cli2->session);
1714 smbcli_deltree(cli1->tree, BASEDIR);
1718 static bool test_raw_oplock_batch15(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1720 const char *fname = BASEDIR "\\test_batch15.dat";
1724 union smb_fileinfo qfi;
1727 if (!torture_setup_dir(cli1, BASEDIR)) {
1732 smbcli_unlink(cli1->tree, fname);
1734 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1737 base ntcreatex parms
1739 io.generic.level = RAW_OPEN_NTCREATEX;
1740 io.ntcreatex.in.root_fid = 0;
1741 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1742 io.ntcreatex.in.alloc_size = 0;
1743 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1744 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1745 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1746 io.ntcreatex.in.create_options = 0;
1747 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1748 io.ntcreatex.in.security_flags = 0;
1749 io.ntcreatex.in.fname = fname;
1751 /* Test if a qpathinfo all info on pathname breaks a batch oplock. */
1752 torture_comment(tctx, "BATCH15: Test if qpathinfo all info breaks a batch oplock (should not).\n");
1754 ZERO_STRUCT(break_info);
1755 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1757 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1758 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1759 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1760 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1761 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1762 NTCREATEX_SHARE_ACCESS_WRITE|
1763 NTCREATEX_SHARE_ACCESS_DELETE;
1764 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1765 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1766 status = smb_raw_open(cli1->tree, tctx, &io);
1767 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1768 fnum = io.ntcreatex.out.file.fnum;
1769 CHECK_VAL(break_info.count, 0);
1770 CHECK_VAL(break_info.failures, 0);
1771 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1774 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
1775 qfi.generic.in.file.path = fname;
1777 status = smb_raw_pathinfo(cli2->tree, tctx, &qfi);
1779 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1780 CHECK_VAL(break_info.count, 0);
1782 smbcli_close(cli1->tree, fnum);
1785 smb_raw_exit(cli1->session);
1786 smb_raw_exit(cli2->session);
1787 smbcli_deltree(cli1->tree, BASEDIR);
1791 static bool test_raw_oplock_batch16(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1793 const char *fname = BASEDIR "\\test_batch16.dat";
1797 uint16_t fnum=0, fnum2=0;
1799 if (!torture_setup_dir(cli1, BASEDIR)) {
1804 smbcli_unlink(cli1->tree, fname);
1806 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1807 smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli1->tree);
1810 base ntcreatex parms
1812 io.generic.level = RAW_OPEN_NTCREATEX;
1813 io.ntcreatex.in.root_fid = 0;
1814 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1815 io.ntcreatex.in.alloc_size = 0;
1816 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1817 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1818 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1819 io.ntcreatex.in.create_options = 0;
1820 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1821 io.ntcreatex.in.security_flags = 0;
1822 io.ntcreatex.in.fname = fname;
1824 torture_comment(tctx, "BATCH16: open with batch oplock\n");
1825 ZERO_STRUCT(break_info);
1826 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1829 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1830 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1831 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1832 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1833 NTCREATEX_SHARE_ACCESS_WRITE|
1834 NTCREATEX_SHARE_ACCESS_DELETE;
1835 status = smb_raw_open(cli1->tree, tctx, &io);
1836 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1837 fnum = io.ntcreatex.out.file.fnum;
1838 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1840 ZERO_STRUCT(break_info);
1842 torture_comment(tctx, "second open with attributes only and NTCREATEX_DISP_OVERWRITE_IF dispostion causes oplock break\n");
1844 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1845 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1846 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1847 io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
1848 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1849 NTCREATEX_SHARE_ACCESS_WRITE|
1850 NTCREATEX_SHARE_ACCESS_DELETE;
1851 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE_IF;
1852 status = smb_raw_open(cli2->tree, tctx, &io);
1853 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1854 fnum2 = io.ntcreatex.out.file.fnum;
1855 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1856 CHECK_VAL(break_info.count, 1);
1857 CHECK_VAL(break_info.failures, 0);
1859 smbcli_close(cli1->tree, fnum);
1860 smbcli_close(cli2->tree, fnum2);
1863 smb_raw_exit(cli1->session);
1864 smb_raw_exit(cli2->session);
1865 smbcli_deltree(cli1->tree, BASEDIR);
1869 static bool test_raw_oplock_batch17(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1871 const char *fname1 = BASEDIR "\\test_batch17_1.dat";
1872 const char *fname2 = BASEDIR "\\test_batch17_2.dat";
1876 union smb_rename rn;
1879 if (!torture_setup_dir(cli1, BASEDIR)) {
1884 smbcli_unlink(cli1->tree, fname1);
1885 smbcli_unlink(cli1->tree, fname2);
1887 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1890 base ntcreatex parms
1892 io.generic.level = RAW_OPEN_NTCREATEX;
1893 io.ntcreatex.in.root_fid = 0;
1894 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1895 io.ntcreatex.in.alloc_size = 0;
1896 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1897 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1898 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1899 io.ntcreatex.in.create_options = 0;
1900 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1901 io.ntcreatex.in.security_flags = 0;
1902 io.ntcreatex.in.fname = fname1;
1904 torture_comment(tctx, "BATCH17: open a file with an batch oplock (share mode: none)\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 status = smb_raw_open(cli1->tree, tctx, &io);
1912 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1913 fnum = io.ntcreatex.out.file.fnum;
1914 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1916 torture_comment(tctx, "rename should trigger a break\n");
1918 rn.generic.level = RAW_RENAME_RENAME;
1919 rn.rename.in.pattern1 = fname1;
1920 rn.rename.in.pattern2 = fname2;
1921 rn.rename.in.attrib = 0;
1923 printf("trying rename while first file open\n");
1924 status = smb_raw_rename(cli2->tree, &rn);
1926 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
1927 CHECK_VAL(break_info.count, 1);
1928 CHECK_VAL(break_info.failures, 0);
1929 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
1931 smbcli_close(cli1->tree, fnum);
1934 smb_raw_exit(cli1->session);
1935 smb_raw_exit(cli2->session);
1936 smbcli_deltree(cli1->tree, BASEDIR);
1940 static bool test_raw_oplock_batch18(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1942 const char *fname1 = BASEDIR "\\test_batch18_1.dat";
1943 const char *fname2 = BASEDIR "\\test_batch18_2.dat";
1947 union smb_rename rn;
1950 if (!torture_setup_dir(cli1, BASEDIR)) {
1955 smbcli_unlink(cli1->tree, fname1);
1956 smbcli_unlink(cli1->tree, fname2);
1958 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1961 base ntcreatex parms
1963 io.generic.level = RAW_OPEN_NTCREATEX;
1964 io.ntcreatex.in.root_fid = 0;
1965 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1966 io.ntcreatex.in.alloc_size = 0;
1967 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1968 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1969 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1970 io.ntcreatex.in.create_options = 0;
1971 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1972 io.ntcreatex.in.security_flags = 0;
1973 io.ntcreatex.in.fname = fname1;
1975 torture_comment(tctx, "BATCH18: open a file with an batch oplock (share mode: none)\n");
1977 ZERO_STRUCT(break_info);
1978 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1979 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1980 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1982 status = smb_raw_open(cli1->tree, tctx, &io);
1983 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1984 fnum = io.ntcreatex.out.file.fnum;
1985 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1987 torture_comment(tctx, "ntrename should trigger a break\n");
1989 rn.generic.level = RAW_RENAME_NTRENAME;
1990 rn.ntrename.in.attrib = 0;
1991 rn.ntrename.in.flags = RENAME_FLAG_RENAME;
1992 rn.ntrename.in.old_name = fname1;
1993 rn.ntrename.in.new_name = fname2;
1994 printf("trying rename while first file open\n");
1995 status = smb_raw_rename(cli2->tree, &rn);
1997 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
1998 CHECK_VAL(break_info.count, 1);
1999 CHECK_VAL(break_info.failures, 0);
2000 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
2002 smbcli_close(cli1->tree, fnum);
2005 smb_raw_exit(cli1->session);
2006 smb_raw_exit(cli2->session);
2007 smbcli_deltree(cli1->tree, BASEDIR);
2011 static bool test_raw_oplock_batch19(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
2013 const char *fname1 = BASEDIR "\\test_batch19_1.dat";
2014 const char *fname2 = BASEDIR "\\test_batch19_2.dat";
2015 const char *fname3 = BASEDIR "\\test_batch19_3.dat";
2019 union smb_fileinfo qfi;
2020 union smb_setfileinfo sfi;
2023 if (!torture_setup_dir(cli1, BASEDIR)) {
2028 smbcli_unlink(cli1->tree, fname1);
2029 smbcli_unlink(cli1->tree, fname2);
2030 smbcli_unlink(cli1->tree, fname3);
2032 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2035 base ntcreatex parms
2037 io.generic.level = RAW_OPEN_NTCREATEX;
2038 io.ntcreatex.in.root_fid = 0;
2039 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2040 io.ntcreatex.in.alloc_size = 0;
2041 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2042 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2043 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2044 io.ntcreatex.in.create_options = 0;
2045 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2046 io.ntcreatex.in.security_flags = 0;
2047 io.ntcreatex.in.fname = fname1;
2049 torture_comment(tctx, "BATCH19: open a file with an batch oplock (share mode: none)\n");
2050 ZERO_STRUCT(break_info);
2051 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2052 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2053 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2054 status = smb_raw_open(cli1->tree, tctx, &io);
2055 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2056 fnum = io.ntcreatex.out.file.fnum;
2057 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
2059 torture_comment(tctx, "setpathinfo rename info should not trigger a break nor a violation\n");
2061 sfi.generic.level = RAW_SFILEINFO_RENAME_INFORMATION;
2062 sfi.generic.in.file.path = fname1;
2063 sfi.rename_information.in.overwrite = 0;
2064 sfi.rename_information.in.root_fid = 0;
2065 sfi.rename_information.in.new_name = fname2+strlen(BASEDIR)+1;
2067 status = smb_raw_setpathinfo(cli2->tree, &sfi);
2069 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2070 CHECK_VAL(break_info.count, 0);
2073 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2074 qfi.generic.in.file.fnum = fnum;
2076 status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
2077 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2078 CHECK_STRMATCH(qfi.all_info.out.fname.s, fname2);
2080 torture_comment(tctx, "setfileinfo rename info should not trigger a break nor a violation\n");
2082 sfi.generic.level = RAW_SFILEINFO_RENAME_INFORMATION;
2083 sfi.generic.in.file.fnum = fnum;
2084 sfi.rename_information.in.overwrite = 0;
2085 sfi.rename_information.in.root_fid = 0;
2086 sfi.rename_information.in.new_name = fname3+strlen(BASEDIR)+1;
2088 status = smb_raw_setfileinfo(cli1->tree, &sfi);
2089 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2090 CHECK_VAL(break_info.count, 0);
2093 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2094 qfi.generic.in.file.fnum = fnum;
2096 status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
2097 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2098 CHECK_STRMATCH(qfi.all_info.out.fname.s, fname3);
2100 smbcli_close(cli1->tree, fnum);
2103 smb_raw_exit(cli1->session);
2104 smb_raw_exit(cli2->session);
2105 smbcli_deltree(cli1->tree, BASEDIR);
2109 /****************************************************
2110 Called from raw-rename - we need oplock handling for
2111 this test so this is why it's in oplock.c, not rename.c
2112 ****************************************************/
2114 bool test_trans2rename(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
2116 const char *fname1 = BASEDIR "\\test_trans2rename_1.dat";
2117 const char *fname2 = BASEDIR "\\test_trans2rename_2.dat";
2118 const char *fname3 = BASEDIR "\\test_trans2rename_3.dat";
2122 union smb_fileinfo qfi;
2123 union smb_setfileinfo sfi;
2126 if (!torture_setup_dir(cli1, BASEDIR)) {
2131 smbcli_unlink(cli1->tree, fname1);
2132 smbcli_unlink(cli1->tree, fname2);
2133 smbcli_unlink(cli1->tree, fname3);
2135 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2138 base ntcreatex parms
2140 io.generic.level = RAW_OPEN_NTCREATEX;
2141 io.ntcreatex.in.root_fid = 0;
2142 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2143 io.ntcreatex.in.alloc_size = 0;
2144 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2145 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2146 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2147 io.ntcreatex.in.create_options = 0;
2148 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2149 io.ntcreatex.in.security_flags = 0;
2150 io.ntcreatex.in.fname = fname1;
2152 torture_comment(tctx, "open a file with an exclusive oplock (share mode: none)\n");
2153 ZERO_STRUCT(break_info);
2154 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2155 NTCREATEX_FLAGS_REQUEST_OPLOCK;
2156 status = smb_raw_open(cli1->tree, tctx, &io);
2157 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2158 fnum = io.ntcreatex.out.file.fnum;
2159 CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
2161 torture_comment(tctx, "setpathinfo rename info should not trigger a break nor a violation\n");
2163 sfi.generic.level = RAW_SFILEINFO_RENAME_INFORMATION;
2164 sfi.generic.in.file.path = fname1;
2165 sfi.rename_information.in.overwrite = 0;
2166 sfi.rename_information.in.root_fid = 0;
2167 sfi.rename_information.in.new_name = fname2+strlen(BASEDIR)+1;
2169 status = smb_raw_setpathinfo(cli2->tree, &sfi);
2171 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2172 CHECK_VAL(break_info.count, 0);
2175 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2176 qfi.generic.in.file.fnum = fnum;
2178 status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
2179 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2180 CHECK_STRMATCH(qfi.all_info.out.fname.s, fname2);
2182 torture_comment(tctx, "setfileinfo rename info should not trigger a break nor a violation\n");
2184 sfi.generic.level = RAW_SFILEINFO_RENAME_INFORMATION;
2185 sfi.generic.in.file.fnum = fnum;
2186 sfi.rename_information.in.overwrite = 0;
2187 sfi.rename_information.in.root_fid = 0;
2188 sfi.rename_information.in.new_name = fname3+strlen(BASEDIR)+1;
2190 status = smb_raw_setfileinfo(cli1->tree, &sfi);
2191 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2192 CHECK_VAL(break_info.count, 0);
2195 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2196 qfi.generic.in.file.fnum = fnum;
2198 status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
2199 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2200 CHECK_STRMATCH(qfi.all_info.out.fname.s, fname3);
2202 smbcli_close(cli1->tree, fnum);
2205 smb_raw_exit(cli1->session);
2206 smb_raw_exit(cli2->session);
2207 smbcli_deltree(cli1->tree, BASEDIR);
2211 /****************************************************
2212 Called from raw-rename - we need oplock handling for
2213 this test so this is why it's in oplock.c, not rename.c
2214 ****************************************************/
2216 bool test_nttransrename(struct torture_context *tctx, struct smbcli_state *cli1)
2218 const char *fname1 = BASEDIR "\\test_nttransrename_1.dat";
2219 const char *fname2 = BASEDIR "\\test_nttransrename_2.dat";
2223 union smb_fileinfo qfi, qpi;
2224 union smb_rename rn;
2227 if (!torture_setup_dir(cli1, BASEDIR)) {
2232 smbcli_unlink(cli1->tree, fname1);
2233 smbcli_unlink(cli1->tree, fname2);
2235 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2238 base ntcreatex parms
2240 io.generic.level = RAW_OPEN_NTCREATEX;
2241 io.ntcreatex.in.root_fid = 0;
2242 io.ntcreatex.in.access_mask = 0;/* ask for no access at all */;
2243 io.ntcreatex.in.alloc_size = 0;
2244 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2245 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2246 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2247 io.ntcreatex.in.create_options = 0;
2248 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2249 io.ntcreatex.in.security_flags = 0;
2250 io.ntcreatex.in.fname = fname1;
2252 torture_comment(tctx, "nttrans_rename: open a file with an exclusive oplock (share mode: none)\n");
2253 ZERO_STRUCT(break_info);
2254 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2255 NTCREATEX_FLAGS_REQUEST_OPLOCK;
2256 status = smb_raw_open(cli1->tree, tctx, &io);
2257 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2258 fnum = io.ntcreatex.out.file.fnum;
2259 CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
2261 torture_comment(tctx, "nttrans_rename: should not trigger a break nor a share mode violation\n");
2263 rn.generic.level = RAW_RENAME_NTTRANS;
2264 rn.nttrans.in.file.fnum = fnum;
2265 rn.nttrans.in.flags = 0;
2266 rn.nttrans.in.new_name = fname2+strlen(BASEDIR)+1;
2268 status = smb_raw_rename(cli1->tree, &rn);
2270 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2271 CHECK_VAL(break_info.count, 0);
2273 /* w2k3 does nothing, it doesn't rename the file */
2274 torture_comment(tctx, "nttrans_rename: the server should have done nothing\n");
2276 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2277 qfi.generic.in.file.fnum = fnum;
2279 status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
2280 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2281 CHECK_STRMATCH(qfi.all_info.out.fname.s, fname1);
2284 qpi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2285 qpi.generic.in.file.path = fname1;
2287 status = smb_raw_pathinfo(cli1->tree, tctx, &qpi);
2288 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2289 CHECK_STRMATCH(qpi.all_info.out.fname.s, fname1);
2292 qpi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2293 qpi.generic.in.file.path = fname2;
2295 status = smb_raw_pathinfo(cli1->tree, tctx, &qpi);
2296 CHECK_STATUS(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
2298 torture_comment(tctx, "nttrans_rename: after closing the file the file is still not renamed\n");
2299 status = smbcli_close(cli1->tree, fnum);
2300 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2303 qpi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2304 qpi.generic.in.file.path = fname1;
2306 status = smb_raw_pathinfo(cli1->tree, tctx, &qpi);
2307 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2308 CHECK_STRMATCH(qpi.all_info.out.fname.s, fname1);
2311 qpi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2312 qpi.generic.in.file.path = fname2;
2314 status = smb_raw_pathinfo(cli1->tree, tctx, &qpi);
2315 CHECK_STATUS(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
2317 torture_comment(tctx, "nttrans_rename: rename with an invalid handle gives NT_STATUS_INVALID_HANDLE\n");
2319 rn.generic.level = RAW_RENAME_NTTRANS;
2320 rn.nttrans.in.file.fnum = fnum+1;
2321 rn.nttrans.in.flags = 0;
2322 rn.nttrans.in.new_name = fname2+strlen(BASEDIR)+1;
2324 status = smb_raw_rename(cli1->tree, &rn);
2326 CHECK_STATUS(tctx, status, NT_STATUS_INVALID_HANDLE);
2329 smb_raw_exit(cli1->session);
2330 smbcli_deltree(cli1->tree, BASEDIR);
2335 static bool test_raw_oplock_batch20(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
2337 const char *fname1 = BASEDIR "\\test_batch20_1.dat";
2338 const char *fname2 = BASEDIR "\\test_batch20_2.dat";
2339 const char *fname3 = BASEDIR "\\test_batch20_3.dat";
2343 union smb_fileinfo qfi;
2344 union smb_setfileinfo sfi;
2345 uint16_t fnum=0,fnum2=0;
2347 if (!torture_setup_dir(cli1, BASEDIR)) {
2352 smbcli_unlink(cli1->tree, fname1);
2353 smbcli_unlink(cli1->tree, fname2);
2354 smbcli_unlink(cli1->tree, fname3);
2356 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2359 base ntcreatex parms
2361 io.generic.level = RAW_OPEN_NTCREATEX;
2362 io.ntcreatex.in.root_fid = 0;
2363 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2364 io.ntcreatex.in.alloc_size = 0;
2365 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2366 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2367 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2368 io.ntcreatex.in.create_options = 0;
2369 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2370 io.ntcreatex.in.security_flags = 0;
2371 io.ntcreatex.in.fname = fname1;
2373 torture_comment(tctx, "BATCH20: open a file with an batch oplock (share mode: all)\n");
2374 ZERO_STRUCT(break_info);
2375 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2376 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2377 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2378 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
2379 NTCREATEX_SHARE_ACCESS_WRITE|
2380 NTCREATEX_SHARE_ACCESS_DELETE;
2381 status = smb_raw_open(cli1->tree, tctx, &io);
2382 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2383 fnum = io.ntcreatex.out.file.fnum;
2384 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
2386 torture_comment(tctx, "setpathinfo rename info should not trigger a break nor a violation\n");
2388 sfi.generic.level = RAW_SFILEINFO_RENAME_INFORMATION;
2389 sfi.generic.in.file.path = fname1;
2390 sfi.rename_information.in.overwrite = 0;
2391 sfi.rename_information.in.root_fid = 0;
2392 sfi.rename_information.in.new_name = fname2+strlen(BASEDIR)+1;
2394 status = smb_raw_setpathinfo(cli2->tree, &sfi);
2396 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2397 CHECK_VAL(break_info.count, 0);
2400 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2401 qfi.generic.in.file.fnum = fnum;
2403 status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
2404 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2405 CHECK_STRMATCH(qfi.all_info.out.fname.s, fname2);
2407 torture_comment(tctx, "open a file with the new name an batch oplock (share mode: all)\n");
2408 ZERO_STRUCT(break_info);
2409 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2410 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2411 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2412 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
2413 NTCREATEX_SHARE_ACCESS_WRITE|
2414 NTCREATEX_SHARE_ACCESS_DELETE;
2415 io.ntcreatex.in.fname = fname2;
2416 status = smb_raw_open(cli2->tree, tctx, &io);
2417 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2418 fnum2 = io.ntcreatex.out.file.fnum;
2419 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
2420 CHECK_VAL(break_info.count, 1);
2421 CHECK_VAL(break_info.failures, 0);
2422 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
2424 torture_comment(tctx, "setfileinfo rename info should not trigger a break nor a violation\n");
2426 sfi.generic.level = RAW_SFILEINFO_RENAME_INFORMATION;
2427 sfi.generic.in.file.fnum = fnum;
2428 sfi.rename_information.in.overwrite = 0;
2429 sfi.rename_information.in.root_fid = 0;
2430 sfi.rename_information.in.new_name = fname3+strlen(BASEDIR)+1;
2432 status = smb_raw_setfileinfo(cli1->tree, &sfi);
2433 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2434 CHECK_VAL(break_info.count, 1);
2435 CHECK_VAL(break_info.failures, 0);
2436 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
2439 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2440 qfi.generic.in.file.fnum = fnum;
2442 status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
2443 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2444 CHECK_STRMATCH(qfi.all_info.out.fname.s, fname3);
2447 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2448 qfi.generic.in.file.fnum = fnum2;
2450 status = smb_raw_fileinfo(cli2->tree, tctx, &qfi);
2451 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2452 CHECK_STRMATCH(qfi.all_info.out.fname.s, fname3);
2454 smbcli_close(cli1->tree, fnum);
2457 smb_raw_exit(cli1->session);
2458 smb_raw_exit(cli2->session);
2459 smbcli_deltree(cli1->tree, BASEDIR);
2463 static bool test_raw_oplock_batch21(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
2465 const char *fname = BASEDIR "\\test_batch21.dat";
2474 if (!torture_setup_dir(cli1, BASEDIR)) {
2479 smbcli_unlink(cli1->tree, fname);
2481 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2484 base ntcreatex parms
2486 io.generic.level = RAW_OPEN_NTCREATEX;
2487 io.ntcreatex.in.root_fid = 0;
2488 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2489 io.ntcreatex.in.alloc_size = 0;
2490 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2491 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2492 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2493 io.ntcreatex.in.create_options = 0;
2494 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2495 io.ntcreatex.in.security_flags = 0;
2496 io.ntcreatex.in.fname = fname;
2499 with a batch oplock we get a break
2501 torture_comment(tctx, "BATCH21: open with batch oplock\n");
2502 ZERO_STRUCT(break_info);
2503 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2504 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2505 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2506 status = smb_raw_open(cli1->tree, tctx, &io);
2507 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2508 fnum = io.ntcreatex.out.file.fnum;
2509 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
2511 torture_comment(tctx, "writing should not generate a break\n");
2512 wr = smbcli_write(cli1->tree, fnum, 0, &c, 0, 1);
2514 CHECK_STATUS(tctx, smbcli_nt_error(cli1->tree), NT_STATUS_OK);
2517 e.in.repeat_count = 1;
2518 status = smb_raw_echo(cli1->transport, &e);
2519 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2521 CHECK_VAL(break_info.count, 0);
2523 smbcli_close(cli1->tree, fnum);
2526 smb_raw_exit(cli1->session);
2527 smb_raw_exit(cli2->session);
2528 smbcli_deltree(cli1->tree, BASEDIR);
2532 static bool test_raw_oplock_batch22(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
2534 const char *fname = BASEDIR "\\test_batch22.dat";
2538 uint16_t fnum=0, fnum2=0;
2540 int timeout = torture_setting_int(tctx, "oplocktimeout", 30);
2543 if (torture_setting_bool(tctx, "samba3", false)) {
2544 torture_skip(tctx, "BATCH22 disabled against samba3\n");
2547 if (!torture_setup_dir(cli1, BASEDIR)) {
2552 smbcli_unlink(cli1->tree, fname);
2554 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2557 base ntcreatex parms
2559 io.generic.level = RAW_OPEN_NTCREATEX;
2560 io.ntcreatex.in.root_fid = 0;
2561 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2562 io.ntcreatex.in.alloc_size = 0;
2563 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2564 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2565 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2566 io.ntcreatex.in.create_options = 0;
2567 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2568 io.ntcreatex.in.security_flags = 0;
2569 io.ntcreatex.in.fname = fname;
2572 with a batch oplock we get a break
2574 torture_comment(tctx, "BATCH22: open with batch oplock\n");
2575 ZERO_STRUCT(break_info);
2576 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2577 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2578 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2579 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
2580 NTCREATEX_SHARE_ACCESS_WRITE|
2581 NTCREATEX_SHARE_ACCESS_DELETE;
2582 status = smb_raw_open(cli1->tree, tctx, &io);
2583 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2584 fnum = io.ntcreatex.out.file.fnum;
2585 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
2587 torture_comment(tctx, "a 2nd open shoud not succeed after the oplock break timeout\n");
2588 tv = timeval_current();
2589 smbcli_oplock_handler(cli1->transport, oplock_handler_timeout, cli1->tree);
2590 status = smb_raw_open(cli1->tree, tctx, &io);
2591 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
2592 te = (int)timeval_elapsed(&tv);
2593 CHECK_RANGE(te, timeout - 1, timeout + 15);
2595 CHECK_VAL(break_info.count, 1);
2596 CHECK_VAL(break_info.fnum, fnum);
2597 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
2598 CHECK_VAL(break_info.failures, 0);
2599 ZERO_STRUCT(break_info);
2601 torture_comment(tctx, "a 2nd open shoud succeed after the oplock release without break\n");
2602 tv = timeval_current();
2603 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2604 status = smb_raw_open(cli1->tree, tctx, &io);
2605 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2606 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
2607 te = (int)timeval_elapsed(&tv);
2608 /* it should come in without delay */
2609 CHECK_RANGE(te+1, 0, timeout);
2610 fnum2 = io.ntcreatex.out.file.fnum;
2612 CHECK_VAL(break_info.count, 0);
2614 smbcli_close(cli1->tree, fnum);
2615 smbcli_close(cli1->tree, fnum2);
2618 smb_raw_exit(cli1->session);
2619 smb_raw_exit(cli2->session);
2620 smbcli_deltree(cli1->tree, BASEDIR);
2624 static bool test_raw_oplock_batch23(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
2626 const char *fname = BASEDIR "\\test_batch23.dat";
2630 uint16_t fnum=0, fnum2=0,fnum3=0;
2631 struct smbcli_state *cli3 = NULL;
2633 if (torture_setting_bool(tctx, "samba3", false)) {
2634 torture_skip(tctx, "BATCH23 disabled against samba3\n");
2637 if (!torture_setup_dir(cli1, BASEDIR)) {
2642 smbcli_unlink(cli1->tree, fname);
2644 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2646 ret = open_connection_no_level2_oplocks(tctx, &cli3);
2647 CHECK_VAL(ret, true);
2650 base ntcreatex parms
2652 io.generic.level = RAW_OPEN_NTCREATEX;
2653 io.ntcreatex.in.root_fid = 0;
2654 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2655 io.ntcreatex.in.alloc_size = 0;
2656 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2657 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2658 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2659 io.ntcreatex.in.create_options = 0;
2660 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2661 io.ntcreatex.in.security_flags = 0;
2662 io.ntcreatex.in.fname = fname;
2664 torture_comment(tctx, "BATCH23: a open and ask for a batch oplock\n");
2665 ZERO_STRUCT(break_info);
2666 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2667 smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli2->tree);
2668 smbcli_oplock_handler(cli3->transport, oplock_handler_ack_to_given, cli3->tree);
2670 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_READ | SEC_RIGHTS_FILE_WRITE;
2671 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
2672 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2673 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2674 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2675 status = smb_raw_open(cli1->tree, tctx, &io);
2676 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2677 fnum = io.ntcreatex.out.file.fnum;
2678 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
2680 ZERO_STRUCT(break_info);
2682 torture_comment(tctx, "a 2nd open without level2 oplock support should generate a break to level2\n");
2683 status = smb_raw_open(cli3->tree, tctx, &io);
2684 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2685 fnum3 = io.ntcreatex.out.file.fnum;
2686 CHECK_VAL(io.ntcreatex.out.oplock_level, NO_OPLOCK_RETURN);
2688 CHECK_VAL(break_info.count, 1);
2689 CHECK_VAL(break_info.fnum, fnum);
2690 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
2691 CHECK_VAL(break_info.failures, 0);
2693 ZERO_STRUCT(break_info);
2695 torture_comment(tctx, "a 3rd open with level2 oplock support should not generate a break\n");
2696 status = smb_raw_open(cli2->tree, tctx, &io);
2697 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2698 fnum2 = io.ntcreatex.out.file.fnum;
2699 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
2701 CHECK_VAL(break_info.count, 0);
2703 smbcli_close(cli1->tree, fnum);
2704 smbcli_close(cli2->tree, fnum2);
2705 smbcli_close(cli3->tree, fnum3);
2708 smb_raw_exit(cli1->session);
2709 smb_raw_exit(cli2->session);
2710 smb_raw_exit(cli3->session);
2711 smbcli_deltree(cli1->tree, BASEDIR);
2715 static bool test_raw_oplock_batch24(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
2717 const char *fname = BASEDIR "\\test_batch24.dat";
2721 uint16_t fnum2=0,fnum3=0;
2722 struct smbcli_state *cli3 = NULL;
2724 if (!torture_setup_dir(cli1, BASEDIR)) {
2729 smbcli_unlink(cli1->tree, fname);
2731 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2733 ret = open_connection_no_level2_oplocks(tctx, &cli3);
2734 CHECK_VAL(ret, true);
2737 base ntcreatex parms
2739 io.generic.level = RAW_OPEN_NTCREATEX;
2740 io.ntcreatex.in.root_fid = 0;
2741 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2742 io.ntcreatex.in.alloc_size = 0;
2743 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2744 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2745 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2746 io.ntcreatex.in.create_options = 0;
2747 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2748 io.ntcreatex.in.security_flags = 0;
2749 io.ntcreatex.in.fname = fname;
2751 torture_comment(tctx, "BATCH24: a open without level support and ask for a batch oplock\n");
2752 ZERO_STRUCT(break_info);
2753 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2754 smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli2->tree);
2755 smbcli_oplock_handler(cli3->transport, oplock_handler_ack_to_given, cli3->tree);
2757 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_READ | SEC_RIGHTS_FILE_WRITE;
2758 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
2759 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2760 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2761 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2762 status = smb_raw_open(cli3->tree, tctx, &io);
2763 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2764 fnum3 = io.ntcreatex.out.file.fnum;
2765 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
2767 ZERO_STRUCT(break_info);
2769 torture_comment(tctx, "a 2nd open with level2 oplock support should generate a break to none\n");
2770 status = smb_raw_open(cli2->tree, tctx, &io);
2771 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2772 fnum2 = io.ntcreatex.out.file.fnum;
2773 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
2775 CHECK_VAL(break_info.count, 1);
2776 CHECK_VAL(break_info.fnum, fnum3);
2777 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_NONE);
2778 CHECK_VAL(break_info.failures, 0);
2780 smbcli_close(cli3->tree, fnum3);
2781 smbcli_close(cli2->tree, fnum2);
2784 smb_raw_exit(cli1->session);
2785 smb_raw_exit(cli2->session);
2786 smb_raw_exit(cli3->session);
2787 smbcli_deltree(cli1->tree, BASEDIR);
2792 basic testing of oplocks
2794 struct torture_suite *torture_raw_oplock(TALLOC_CTX *mem_ctx)
2796 struct torture_suite *suite = torture_suite_create(mem_ctx, "OPLOCK");
2798 torture_suite_add_2smb_test(suite, "EXCLUSIVE1", test_raw_oplock_exclusive1);
2799 torture_suite_add_2smb_test(suite, "EXCLUSIVE2", test_raw_oplock_exclusive2);
2800 torture_suite_add_2smb_test(suite, "EXCLUSIVE3", test_raw_oplock_exclusive3);
2801 torture_suite_add_2smb_test(suite, "EXCLUSIVE4", test_raw_oplock_exclusive4);
2802 torture_suite_add_2smb_test(suite, "EXCLUSIVE5", test_raw_oplock_exclusive5);
2803 torture_suite_add_2smb_test(suite, "EXCLUSIVE6", test_raw_oplock_exclusive6);
2804 torture_suite_add_2smb_test(suite, "BATCH1", test_raw_oplock_batch1);
2805 torture_suite_add_2smb_test(suite, "BATCH2", test_raw_oplock_batch2);
2806 torture_suite_add_2smb_test(suite, "BATCH3", test_raw_oplock_batch3);
2807 torture_suite_add_2smb_test(suite, "BATCH4", test_raw_oplock_batch4);
2808 torture_suite_add_2smb_test(suite, "BATCH5", test_raw_oplock_batch5);
2809 torture_suite_add_2smb_test(suite, "BATCH6", test_raw_oplock_batch6);
2810 torture_suite_add_2smb_test(suite, "BATCH7", test_raw_oplock_batch7);
2811 torture_suite_add_2smb_test(suite, "BATCH8", test_raw_oplock_batch8);
2812 torture_suite_add_2smb_test(suite, "BATCH9", test_raw_oplock_batch9);
2813 torture_suite_add_2smb_test(suite, "BATCH10", test_raw_oplock_batch10);
2814 torture_suite_add_2smb_test(suite, "BATCH11", test_raw_oplock_batch11);
2815 torture_suite_add_2smb_test(suite, "BATCH12", test_raw_oplock_batch12);
2816 torture_suite_add_2smb_test(suite, "BATCH13", test_raw_oplock_batch13);
2817 torture_suite_add_2smb_test(suite, "BATCH14", test_raw_oplock_batch14);
2818 torture_suite_add_2smb_test(suite, "BATCH15", test_raw_oplock_batch15);
2819 torture_suite_add_2smb_test(suite, "BATCH16", test_raw_oplock_batch16);
2820 torture_suite_add_2smb_test(suite, "BATCH17", test_raw_oplock_batch17);
2821 torture_suite_add_2smb_test(suite, "BATCH18", test_raw_oplock_batch18);
2822 torture_suite_add_2smb_test(suite, "BATCH19", test_raw_oplock_batch19);
2823 torture_suite_add_2smb_test(suite, "BATCH20", test_raw_oplock_batch20);
2824 torture_suite_add_2smb_test(suite, "BATCH21", test_raw_oplock_batch21);
2825 torture_suite_add_2smb_test(suite, "BATCH22", test_raw_oplock_batch22);
2826 torture_suite_add_2smb_test(suite, "BATCH23", test_raw_oplock_batch23);
2827 torture_suite_add_2smb_test(suite, "BATCH24", test_raw_oplock_batch24);
2833 stress testing of oplocks
2835 bool torture_bench_oplock(struct torture_context *torture)
2837 struct smbcli_state **cli;
2839 TALLOC_CTX *mem_ctx = talloc_new(torture);
2840 int torture_nprocs = torture_setting_int(torture, "nprocs", 4);
2842 int timelimit = torture_setting_int(torture, "timelimit", 10);
2846 cli = talloc_array(mem_ctx, struct smbcli_state *, torture_nprocs);
2848 torture_comment(torture, "Opening %d connections\n", torture_nprocs);
2849 for (i=0;i<torture_nprocs;i++) {
2850 if (!torture_open_connection_ev(&cli[i], i, torture, torture->ev)) {
2853 talloc_steal(mem_ctx, cli[i]);
2854 smbcli_oplock_handler(cli[i]->transport, oplock_handler_close,
2858 if (!torture_setup_dir(cli[0], BASEDIR)) {
2863 io.ntcreatex.level = RAW_OPEN_NTCREATEX;
2864 io.ntcreatex.in.root_fid = 0;
2865 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2866 io.ntcreatex.in.alloc_size = 0;
2867 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2868 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2869 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2870 io.ntcreatex.in.create_options = 0;
2871 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2872 io.ntcreatex.in.security_flags = 0;
2873 io.ntcreatex.in.fname = BASEDIR "\\test.dat";
2874 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2875 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2876 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2878 tv = timeval_current();
2881 we open the same file with SHARE_ACCESS_NONE from all the
2882 connections in a round robin fashion. Each open causes an
2883 oplock break on the previous connection, which is answered
2884 by the oplock_handler_close() to close the file.
2886 This measures how fast we can pass on oplocks, and stresses
2887 the oplock handling code
2889 torture_comment(torture, "Running for %d seconds\n", timelimit);
2890 while (timeval_elapsed(&tv) < timelimit) {
2891 for (i=0;i<torture_nprocs;i++) {
2894 status = smb_raw_open(cli[i]->tree, mem_ctx, &io);
2895 CHECK_STATUS(torture, status, NT_STATUS_OK);
2899 if (torture_setting_bool(torture, "progress", true)) {
2900 torture_comment(torture, "%.2f ops/second\r", count/timeval_elapsed(&tv));
2904 torture_comment(torture, "%.2f ops/second\n", count/timeval_elapsed(&tv));
2906 smb_raw_exit(cli[torture_nprocs-1]->session);
2909 smb_raw_exit(cli[0]->session);
2910 smbcli_deltree(cli[0]->tree, BASEDIR);
2911 talloc_free(mem_ctx);
2916 static struct hold_oplock_info {
2918 bool close_on_break;
2919 uint32_t share_access;
2922 { BASEDIR "\\notshared_close", true,
2923 NTCREATEX_SHARE_ACCESS_NONE, },
2924 { BASEDIR "\\notshared_noclose", false,
2925 NTCREATEX_SHARE_ACCESS_NONE, },
2926 { BASEDIR "\\shared_close", true,
2927 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE, },
2928 { BASEDIR "\\shared_noclose", false,
2929 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE, },
2932 static bool oplock_handler_hold(struct smbcli_transport *transport,
2933 uint16_t tid, uint16_t fnum, uint8_t level,
2936 struct smbcli_tree *tree = (struct smbcli_tree *)private;
2937 struct hold_oplock_info *info;
2940 for (i=0;i<ARRAY_SIZE(hold_info);i++) {
2941 if (hold_info[i].fnum == fnum) break;
2944 if (i == ARRAY_SIZE(hold_info)) {
2945 printf("oplock break for unknown fnum %u\n", fnum);
2949 info = &hold_info[i];
2951 if (info->close_on_break) {
2952 printf("oplock break on %s - closing\n",
2954 oplock_handler_close(transport, tid, fnum, level, private);
2958 printf("oplock break on %s - acking break\n", info->fname);
2960 return smbcli_oplock_ack(tree, fnum, OPLOCK_BREAK_TO_NONE);
2965 used for manual testing of oplocks - especially interaction with
2966 other filesystems (such as NFS and local access)
2968 bool torture_hold_oplock(struct torture_context *torture,
2969 struct smbcli_state *cli)
2971 struct event_context *ev =
2972 (struct event_context *)cli->transport->socket->event.ctx;
2975 printf("Setting up open files with oplocks in %s\n", BASEDIR);
2977 if (!torture_setup_dir(cli, BASEDIR)) {
2981 smbcli_oplock_handler(cli->transport, oplock_handler_hold, cli->tree);
2983 /* setup the files */
2984 for (i=0;i<ARRAY_SIZE(hold_info);i++) {
2989 io.generic.level = RAW_OPEN_NTCREATEX;
2990 io.ntcreatex.in.root_fid = 0;
2991 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2992 io.ntcreatex.in.alloc_size = 0;
2993 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2994 io.ntcreatex.in.share_access = hold_info[i].share_access;
2995 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2996 io.ntcreatex.in.create_options = 0;
2997 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2998 io.ntcreatex.in.security_flags = 0;
2999 io.ntcreatex.in.fname = hold_info[i].fname;
3000 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
3001 NTCREATEX_FLAGS_REQUEST_OPLOCK |
3002 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
3003 printf("opening %s\n", hold_info[i].fname);
3005 status = smb_raw_open(cli->tree, cli, &io);
3006 if (!NT_STATUS_IS_OK(status)) {
3007 printf("Failed to open %s - %s\n",
3008 hold_info[i].fname, nt_errstr(status));
3012 if (io.ntcreatex.out.oplock_level != BATCH_OPLOCK_RETURN) {
3013 printf("Oplock not granted for %s - expected %d but got %d\n",
3014 hold_info[i].fname, BATCH_OPLOCK_RETURN,
3015 io.ntcreatex.out.oplock_level);
3018 hold_info[i].fnum = io.ntcreatex.out.file.fnum;
3020 /* make the file non-zero size */
3021 if (smbcli_write(cli->tree, hold_info[i].fnum, 0, &c, 0, 1) != 1) {
3022 printf("Failed to write to file\n");
3027 printf("Waiting for oplock events\n");
3028 event_loop_wait(ev);