Fix async reading winbindd_response
[Samba/gebeck_regimport.git] / source4 / torture / raw / oplock.c
blob0aeded8664afc32f994331f0d2f880ebad640340
1 /*
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/>.
20 #include "includes.h"
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); \
36 ret = false; \
37 }} while (0)
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); \
43 ret = false; \
44 }} while (0)
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); \
50 ret = false; \
51 } \
52 } while (0)
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)); \
58 ret = false; \
59 goto done; \
60 }} while (0)
63 static struct {
64 int fnum;
65 uint8_t level;
66 int count;
67 int failures;
68 } break_info;
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_data)
79 struct smbcli_tree *tree = (struct smbcli_tree *)private_data;
80 const char *name;
82 break_info.fnum = fnum;
83 break_info.level = level;
84 break_info.count++;
86 switch (level) {
87 case OPLOCK_BREAK_TO_LEVEL_II:
88 name = "level II";
89 break;
90 case OPLOCK_BREAK_TO_NONE:
91 name = "none";
92 break;
93 default:
94 name = "unknown";
95 break_info.failures++;
97 printf("Acking to %s [0x%02X] in oplock handler\n",
98 name, level);
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_data)
110 struct smbcli_tree *tree = (struct smbcli_tree *)private_data;
111 break_info.fnum = fnum;
112 break_info.level = level;
113 break_info.count++;
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_data)
127 break_info.fnum = fnum;
128 break_info.level = level;
129 break_info.count++;
131 printf("Let oplock break timeout\n");
132 return true;
135 static void oplock_handler_close_recv(struct smbcli_request *req)
137 NTSTATUS status;
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_data)
151 union smb_close io;
152 struct smbcli_tree *tree = (struct smbcli_tree *)private_data;
153 struct smbcli_request *req;
155 break_info.fnum = fnum;
156 break_info.level = level;
157 break_info.count++;
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);
163 if (req == NULL) {
164 printf("failed to send close in oplock_handler_close\n");
165 return false;
168 req->async.fn = oplock_handler_close_recv;
169 req->async.private_data = NULL;
171 return true;
174 static bool open_connection_no_level2_oplocks(struct torture_context *tctx,
175 struct smbcli_state **c)
177 NTSTATUS status;
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, lp_socket_options(tctx->lp_ctx), cmdline_credentials,
191 lp_resolve_context(tctx->lp_ctx),
192 tctx->ev, &options, &session_options,
193 lp_iconv_convenience(tctx->lp_ctx),
194 lp_gensec_settings(tctx, tctx->lp_ctx));
195 if (!NT_STATUS_IS_OK(status)) {
196 printf("Failed to open connection - %s\n", nt_errstr(status));
197 return false;
200 return true;
203 static bool test_raw_oplock_exclusive1(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
205 const char *fname = BASEDIR "\\test_exclusive1.dat";
206 NTSTATUS status;
207 bool ret = true;
208 union smb_open io;
209 union smb_unlink unl;
210 uint16_t fnum=0;
212 if (!torture_setup_dir(cli1, BASEDIR)) {
213 return false;
216 /* cleanup */
217 smbcli_unlink(cli1->tree, fname);
219 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
222 base ntcreatex parms
224 io.generic.level = RAW_OPEN_NTCREATEX;
225 io.ntcreatex.in.root_fid = 0;
226 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
227 io.ntcreatex.in.alloc_size = 0;
228 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
229 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
230 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
231 io.ntcreatex.in.create_options = 0;
232 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
233 io.ntcreatex.in.security_flags = 0;
234 io.ntcreatex.in.fname = fname;
236 torture_comment(tctx, "EXCLUSIVE1: open a file with an exclusive oplock (share mode: none)\n");
237 ZERO_STRUCT(break_info);
238 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
240 status = smb_raw_open(cli1->tree, tctx, &io);
241 CHECK_STATUS(tctx, status, NT_STATUS_OK);
242 fnum = io.ntcreatex.out.file.fnum;
243 CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
245 torture_comment(tctx, "a 2nd open should not cause a break\n");
246 status = smb_raw_open(cli2->tree, tctx, &io);
247 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
248 CHECK_VAL(break_info.count, 0);
249 CHECK_VAL(break_info.failures, 0);
251 torture_comment(tctx, "unlink it - should also be no break\n");
252 unl.unlink.in.pattern = fname;
253 unl.unlink.in.attrib = 0;
254 status = smb_raw_unlink(cli2->tree, &unl);
255 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
256 CHECK_VAL(break_info.count, 0);
257 CHECK_VAL(break_info.failures, 0);
259 smbcli_close(cli1->tree, fnum);
261 done:
262 smb_raw_exit(cli1->session);
263 smb_raw_exit(cli2->session);
264 smbcli_deltree(cli1->tree, BASEDIR);
265 return ret;
268 static bool test_raw_oplock_exclusive2(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
270 const char *fname = BASEDIR "\\test_exclusive2.dat";
271 NTSTATUS status;
272 bool ret = true;
273 union smb_open io;
274 union smb_unlink unl;
275 uint16_t fnum=0, fnum2=0;
277 if (!torture_setup_dir(cli1, BASEDIR)) {
278 return false;
281 /* cleanup */
282 smbcli_unlink(cli1->tree, fname);
284 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
287 base ntcreatex parms
289 io.generic.level = RAW_OPEN_NTCREATEX;
290 io.ntcreatex.in.root_fid = 0;
291 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
292 io.ntcreatex.in.alloc_size = 0;
293 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
294 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
295 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
296 io.ntcreatex.in.create_options = 0;
297 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
298 io.ntcreatex.in.security_flags = 0;
299 io.ntcreatex.in.fname = fname;
301 torture_comment(tctx, "EXCLUSIVE2: open a file with an exclusive oplock (share mode: all)\n");
302 ZERO_STRUCT(break_info);
303 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
304 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
305 NTCREATEX_SHARE_ACCESS_WRITE|
306 NTCREATEX_SHARE_ACCESS_DELETE;
308 status = smb_raw_open(cli1->tree, tctx, &io);
309 CHECK_STATUS(tctx, status, NT_STATUS_OK);
310 fnum = io.ntcreatex.out.file.fnum;
311 CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
313 torture_comment(tctx, "a 2nd open should cause a break to level 2\n");
314 status = smb_raw_open(cli2->tree, tctx, &io);
315 CHECK_STATUS(tctx, status, NT_STATUS_OK);
316 fnum2 = io.ntcreatex.out.file.fnum;
317 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
318 CHECK_VAL(break_info.count, 1);
319 CHECK_VAL(break_info.fnum, fnum);
320 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
321 CHECK_VAL(break_info.failures, 0);
322 ZERO_STRUCT(break_info);
324 /* now we have 2 level II oplocks... */
325 torture_comment(tctx, "try to unlink it - should not cause a break, but a sharing violation\n");
326 unl.unlink.in.pattern = fname;
327 unl.unlink.in.attrib = 0;
328 status = smb_raw_unlink(cli2->tree, &unl);
329 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
330 CHECK_VAL(break_info.count, 0);
331 CHECK_VAL(break_info.failures, 0);
333 torture_comment(tctx, "close 1st handle\n");
334 smbcli_close(cli1->tree, fnum);
336 torture_comment(tctx, "try to unlink it - should not cause a break, but a sharing violation\n");
337 unl.unlink.in.pattern = fname;
338 unl.unlink.in.attrib = 0;
339 status = smb_raw_unlink(cli2->tree, &unl);
340 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
341 CHECK_VAL(break_info.count, 0);
342 CHECK_VAL(break_info.failures, 0);
344 torture_comment(tctx, "close 1st handle\n");
345 smbcli_close(cli2->tree, fnum2);
347 torture_comment(tctx, "unlink it\n");
348 unl.unlink.in.pattern = fname;
349 unl.unlink.in.attrib = 0;
350 status = smb_raw_unlink(cli2->tree, &unl);
351 CHECK_STATUS(tctx, status, NT_STATUS_OK);
352 CHECK_VAL(break_info.count, 0);
353 CHECK_VAL(break_info.failures, 0);
355 done:
356 smb_raw_exit(cli1->session);
357 smb_raw_exit(cli2->session);
358 smbcli_deltree(cli1->tree, BASEDIR);
359 return ret;
362 static bool test_raw_oplock_exclusive3(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
364 const char *fname = BASEDIR "\\test_exclusive3.dat";
365 NTSTATUS status;
366 bool ret = true;
367 union smb_open io;
368 union smb_setfileinfo sfi;
369 uint16_t fnum=0;
371 if (!torture_setup_dir(cli1, BASEDIR)) {
372 return false;
375 /* cleanup */
376 smbcli_unlink(cli1->tree, fname);
378 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
381 base ntcreatex parms
383 io.generic.level = RAW_OPEN_NTCREATEX;
384 io.ntcreatex.in.root_fid = 0;
385 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
386 io.ntcreatex.in.alloc_size = 0;
387 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
388 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
389 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
390 io.ntcreatex.in.create_options = 0;
391 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
392 io.ntcreatex.in.security_flags = 0;
393 io.ntcreatex.in.fname = fname;
395 torture_comment(tctx, "EXCLUSIVE3: open a file with an exclusive oplock (share mode: none)\n");
397 ZERO_STRUCT(break_info);
398 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
400 status = smb_raw_open(cli1->tree, tctx, &io);
401 CHECK_STATUS(tctx, status, NT_STATUS_OK);
402 fnum = io.ntcreatex.out.file.fnum;
403 CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
405 torture_comment(tctx, "setpathinfo EOF should trigger a break to none\n");
406 ZERO_STRUCT(sfi);
407 sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
408 sfi.generic.in.file.path = fname;
409 sfi.end_of_file_info.in.size = 100;
411 status = smb_raw_setpathinfo(cli2->tree, &sfi);
413 CHECK_STATUS(tctx, status, NT_STATUS_OK);
414 CHECK_VAL(break_info.count, 1);
415 CHECK_VAL(break_info.failures, 0);
416 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_NONE);
418 smbcli_close(cli1->tree, fnum);
420 done:
421 smb_raw_exit(cli1->session);
422 smb_raw_exit(cli2->session);
423 smbcli_deltree(cli1->tree, BASEDIR);
424 return ret;
427 static bool test_raw_oplock_exclusive4(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
429 const char *fname = BASEDIR "\\test_exclusive4.dat";
430 NTSTATUS status;
431 bool ret = true;
432 union smb_open io;
433 uint16_t fnum=0, fnum2=0;
435 if (!torture_setup_dir(cli1, BASEDIR)) {
436 return false;
439 /* cleanup */
440 smbcli_unlink(cli1->tree, fname);
442 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
445 base ntcreatex parms
447 io.generic.level = RAW_OPEN_NTCREATEX;
448 io.ntcreatex.in.root_fid = 0;
449 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
450 io.ntcreatex.in.alloc_size = 0;
451 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
452 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
453 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
454 io.ntcreatex.in.create_options = 0;
455 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
456 io.ntcreatex.in.security_flags = 0;
457 io.ntcreatex.in.fname = fname;
459 torture_comment(tctx, "EXCLUSIVE4: open with exclusive oplock\n");
460 ZERO_STRUCT(break_info);
461 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
463 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
464 status = smb_raw_open(cli1->tree, tctx, &io);
465 CHECK_STATUS(tctx, status, NT_STATUS_OK);
466 fnum = io.ntcreatex.out.file.fnum;
467 CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
469 ZERO_STRUCT(break_info);
470 torture_comment(tctx, "second open with attributes only shouldn't cause oplock break\n");
472 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
473 io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
474 status = smb_raw_open(cli2->tree, tctx, &io);
475 CHECK_STATUS(tctx, status, NT_STATUS_OK);
476 fnum2 = io.ntcreatex.out.file.fnum;
477 CHECK_VAL(io.ntcreatex.out.oplock_level, NO_OPLOCK_RETURN);
478 CHECK_VAL(break_info.count, 0);
479 CHECK_VAL(break_info.failures, 0);
481 smbcli_close(cli1->tree, fnum);
482 smbcli_close(cli2->tree, fnum2);
484 done:
485 smb_raw_exit(cli1->session);
486 smb_raw_exit(cli2->session);
487 smbcli_deltree(cli1->tree, BASEDIR);
488 return ret;
491 static bool test_raw_oplock_exclusive5(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
493 const char *fname = BASEDIR "\\test_exclusive5.dat";
494 NTSTATUS status;
495 bool ret = true;
496 union smb_open io;
497 uint16_t fnum=0, fnum2=0;
499 if (!torture_setup_dir(cli1, BASEDIR)) {
500 return false;
503 /* cleanup */
504 smbcli_unlink(cli1->tree, fname);
506 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
507 smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli1->tree);
510 base ntcreatex parms
512 io.generic.level = RAW_OPEN_NTCREATEX;
513 io.ntcreatex.in.root_fid = 0;
514 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
515 io.ntcreatex.in.alloc_size = 0;
516 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
517 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
518 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
519 io.ntcreatex.in.create_options = 0;
520 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
521 io.ntcreatex.in.security_flags = 0;
522 io.ntcreatex.in.fname = fname;
524 torture_comment(tctx, "EXCLUSIVE5: open with exclusive oplock\n");
525 ZERO_STRUCT(break_info);
526 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
529 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
530 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
531 NTCREATEX_SHARE_ACCESS_WRITE|
532 NTCREATEX_SHARE_ACCESS_DELETE;
533 status = smb_raw_open(cli1->tree, tctx, &io);
534 CHECK_STATUS(tctx, status, NT_STATUS_OK);
535 fnum = io.ntcreatex.out.file.fnum;
536 CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
538 ZERO_STRUCT(break_info);
540 torture_comment(tctx, "second open with attributes only and NTCREATEX_DISP_OVERWRITE_IF dispostion causes oplock break\n");
542 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
543 io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
544 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE_IF;
545 status = smb_raw_open(cli2->tree, tctx, &io);
546 CHECK_STATUS(tctx, status, NT_STATUS_OK);
547 fnum2 = io.ntcreatex.out.file.fnum;
548 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
549 CHECK_VAL(break_info.count, 1);
550 CHECK_VAL(break_info.failures, 0);
552 smbcli_close(cli1->tree, fnum);
553 smbcli_close(cli2->tree, fnum2);
555 done:
556 smb_raw_exit(cli1->session);
557 smb_raw_exit(cli2->session);
558 smbcli_deltree(cli1->tree, BASEDIR);
559 return ret;
562 static bool test_raw_oplock_exclusive6(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
564 const char *fname1 = BASEDIR "\\test_exclusive6_1.dat";
565 const char *fname2 = BASEDIR "\\test_exclusive6_2.dat";
566 NTSTATUS status;
567 bool ret = true;
568 union smb_open io;
569 union smb_rename rn;
570 uint16_t fnum=0;
572 if (!torture_setup_dir(cli1, BASEDIR)) {
573 return false;
576 /* cleanup */
577 smbcli_unlink(cli1->tree, fname1);
578 smbcli_unlink(cli1->tree, fname2);
580 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
583 base ntcreatex parms
585 io.generic.level = RAW_OPEN_NTCREATEX;
586 io.ntcreatex.in.root_fid = 0;
587 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
588 io.ntcreatex.in.alloc_size = 0;
589 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
590 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
591 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
592 io.ntcreatex.in.create_options = 0;
593 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
594 io.ntcreatex.in.security_flags = 0;
595 io.ntcreatex.in.fname = fname1;
597 torture_comment(tctx, "EXCLUSIVE6: open a file with an exclusive oplock (share mode: none)\n");
598 ZERO_STRUCT(break_info);
599 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
601 status = smb_raw_open(cli1->tree, tctx, &io);
602 CHECK_STATUS(tctx, status, NT_STATUS_OK);
603 fnum = io.ntcreatex.out.file.fnum;
604 CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
606 torture_comment(tctx, "rename should not generate a break but get a sharing violation\n");
607 ZERO_STRUCT(rn);
608 rn.generic.level = RAW_RENAME_RENAME;
609 rn.rename.in.pattern1 = fname1;
610 rn.rename.in.pattern2 = fname2;
611 rn.rename.in.attrib = 0;
613 printf("trying rename while first file open\n");
614 status = smb_raw_rename(cli2->tree, &rn);
616 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
617 CHECK_VAL(break_info.count, 0);
618 CHECK_VAL(break_info.failures, 0);
620 smbcli_close(cli1->tree, fnum);
622 done:
623 smb_raw_exit(cli1->session);
624 smb_raw_exit(cli2->session);
625 smbcli_deltree(cli1->tree, BASEDIR);
626 return ret;
629 static bool test_raw_oplock_batch1(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
631 const char *fname = BASEDIR "\\test_batch1.dat";
632 NTSTATUS status;
633 bool ret = true;
634 union smb_open io;
635 union smb_unlink unl;
636 uint16_t fnum=0;
637 char c = 0;
639 if (!torture_setup_dir(cli1, BASEDIR)) {
640 return false;
643 /* cleanup */
644 smbcli_unlink(cli1->tree, fname);
646 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
649 base ntcreatex parms
651 io.generic.level = RAW_OPEN_NTCREATEX;
652 io.ntcreatex.in.root_fid = 0;
653 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
654 io.ntcreatex.in.alloc_size = 0;
655 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
656 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
657 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
658 io.ntcreatex.in.create_options = 0;
659 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
660 io.ntcreatex.in.security_flags = 0;
661 io.ntcreatex.in.fname = fname;
664 with a batch oplock we get a break
666 torture_comment(tctx, "BATCH1: open with batch oplock\n");
667 ZERO_STRUCT(break_info);
668 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
669 NTCREATEX_FLAGS_REQUEST_OPLOCK |
670 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
671 status = smb_raw_open(cli1->tree, tctx, &io);
672 CHECK_STATUS(tctx, status, NT_STATUS_OK);
673 fnum = io.ntcreatex.out.file.fnum;
674 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
676 torture_comment(tctx, "unlink should generate a break\n");
677 unl.unlink.in.pattern = fname;
678 unl.unlink.in.attrib = 0;
679 status = smb_raw_unlink(cli2->tree, &unl);
680 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
682 CHECK_VAL(break_info.count, 1);
683 CHECK_VAL(break_info.fnum, fnum);
684 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
685 CHECK_VAL(break_info.failures, 0);
687 torture_comment(tctx, "2nd unlink should not generate a break\n");
688 ZERO_STRUCT(break_info);
689 status = smb_raw_unlink(cli2->tree, &unl);
690 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
692 CHECK_VAL(break_info.count, 0);
694 torture_comment(tctx, "writing should generate a self break to none\n");
695 smbcli_write(cli1->tree, fnum, 0, &c, 0, 1);
696 msleep(100);
697 smbcli_write(cli1->tree, fnum, 0, &c, 1, 1);
699 CHECK_VAL(break_info.count, 1);
700 CHECK_VAL(break_info.fnum, fnum);
701 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_NONE);
702 CHECK_VAL(break_info.failures, 0);
704 smbcli_close(cli1->tree, fnum);
706 done:
707 smb_raw_exit(cli1->session);
708 smb_raw_exit(cli2->session);
709 smbcli_deltree(cli1->tree, BASEDIR);
710 return ret;
713 static bool test_raw_oplock_batch2(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
715 const char *fname = BASEDIR "\\test_batch2.dat";
716 NTSTATUS status;
717 bool ret = true;
718 union smb_open io;
719 union smb_unlink unl;
720 uint16_t fnum=0;
721 char c = 0;
723 if (!torture_setup_dir(cli1, BASEDIR)) {
724 return false;
727 /* cleanup */
728 smbcli_unlink(cli1->tree, fname);
730 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
733 base ntcreatex parms
735 io.generic.level = RAW_OPEN_NTCREATEX;
736 io.ntcreatex.in.root_fid = 0;
737 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
738 io.ntcreatex.in.alloc_size = 0;
739 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
740 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
741 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
742 io.ntcreatex.in.create_options = 0;
743 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
744 io.ntcreatex.in.security_flags = 0;
745 io.ntcreatex.in.fname = fname;
747 torture_comment(tctx, "BATCH2: open with batch oplock\n");
748 ZERO_STRUCT(break_info);
749 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
750 NTCREATEX_FLAGS_REQUEST_OPLOCK |
751 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
752 status = smb_raw_open(cli1->tree, tctx, &io);
753 CHECK_STATUS(tctx, status, NT_STATUS_OK);
754 fnum = io.ntcreatex.out.file.fnum;
755 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
757 torture_comment(tctx, "unlink should generate a break, which we ack as break to none\n");
758 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_none, cli1->tree);
759 unl.unlink.in.pattern = fname;
760 unl.unlink.in.attrib = 0;
761 status = smb_raw_unlink(cli2->tree, &unl);
762 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
764 CHECK_VAL(break_info.count, 1);
765 CHECK_VAL(break_info.fnum, fnum);
766 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
767 CHECK_VAL(break_info.failures, 0);
769 torture_comment(tctx, "2nd unlink should not generate a break\n");
770 ZERO_STRUCT(break_info);
771 status = smb_raw_unlink(cli2->tree, &unl);
772 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
774 CHECK_VAL(break_info.count, 0);
776 torture_comment(tctx, "writing should not generate a break\n");
777 smbcli_write(cli1->tree, fnum, 0, &c, 0, 1);
778 msleep(100);
779 smbcli_write(cli1->tree, fnum, 0, &c, 1, 1);
781 CHECK_VAL(break_info.count, 0);
783 smbcli_close(cli1->tree, fnum);
785 done:
786 smb_raw_exit(cli1->session);
787 smb_raw_exit(cli2->session);
788 smbcli_deltree(cli1->tree, BASEDIR);
789 return ret;
792 static bool test_raw_oplock_batch3(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
794 const char *fname = BASEDIR "\\test_batch3.dat";
795 NTSTATUS status;
796 bool ret = true;
797 union smb_open io;
798 union smb_unlink unl;
799 uint16_t fnum=0;
801 if (!torture_setup_dir(cli1, BASEDIR)) {
802 return false;
805 /* cleanup */
806 smbcli_unlink(cli1->tree, fname);
808 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
811 base ntcreatex parms
813 io.generic.level = RAW_OPEN_NTCREATEX;
814 io.ntcreatex.in.root_fid = 0;
815 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
816 io.ntcreatex.in.alloc_size = 0;
817 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
818 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
819 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
820 io.ntcreatex.in.create_options = 0;
821 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
822 io.ntcreatex.in.security_flags = 0;
823 io.ntcreatex.in.fname = fname;
825 torture_comment(tctx, "BATCH3: if we close on break then the unlink can succeed\n");
826 ZERO_STRUCT(break_info);
827 smbcli_oplock_handler(cli1->transport, oplock_handler_close, cli1->tree);
828 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
829 NTCREATEX_FLAGS_REQUEST_OPLOCK |
830 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
831 status = smb_raw_open(cli1->tree, tctx, &io);
832 CHECK_STATUS(tctx, status, NT_STATUS_OK);
833 fnum = io.ntcreatex.out.file.fnum;
834 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
836 unl.unlink.in.pattern = fname;
837 unl.unlink.in.attrib = 0;
838 ZERO_STRUCT(break_info);
839 status = smb_raw_unlink(cli2->tree, &unl);
840 CHECK_STATUS(tctx, status, NT_STATUS_OK);
842 CHECK_VAL(break_info.count, 1);
843 CHECK_VAL(break_info.fnum, fnum);
844 CHECK_VAL(break_info.level, 1);
845 CHECK_VAL(break_info.failures, 0);
847 smbcli_close(cli1->tree, fnum);
849 done:
850 smb_raw_exit(cli1->session);
851 smb_raw_exit(cli2->session);
852 smbcli_deltree(cli1->tree, BASEDIR);
853 return ret;
856 static bool test_raw_oplock_batch4(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
858 const char *fname = BASEDIR "\\test_batch4.dat";
859 NTSTATUS status;
860 bool ret = true;
861 union smb_open io;
862 union smb_read rd;
863 uint16_t fnum=0;
865 if (!torture_setup_dir(cli1, BASEDIR)) {
866 return false;
869 /* cleanup */
870 smbcli_unlink(cli1->tree, fname);
872 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
875 base ntcreatex parms
877 io.generic.level = RAW_OPEN_NTCREATEX;
878 io.ntcreatex.in.root_fid = 0;
879 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
880 io.ntcreatex.in.alloc_size = 0;
881 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
882 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
883 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
884 io.ntcreatex.in.create_options = 0;
885 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
886 io.ntcreatex.in.security_flags = 0;
887 io.ntcreatex.in.fname = fname;
889 torture_comment(tctx, "BATCH4: a self read should not cause a break\n");
890 ZERO_STRUCT(break_info);
891 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
893 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
894 NTCREATEX_FLAGS_REQUEST_OPLOCK |
895 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
896 status = smb_raw_open(cli1->tree, tctx, &io);
897 CHECK_STATUS(tctx, status, NT_STATUS_OK);
898 fnum = io.ntcreatex.out.file.fnum;
899 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
901 rd.read.level = RAW_READ_READ;
902 rd.read.in.file.fnum = fnum;
903 rd.read.in.count = 1;
904 rd.read.in.offset = 0;
905 rd.read.in.remaining = 0;
906 status = smb_raw_read(cli1->tree, &rd);
907 CHECK_STATUS(tctx, status, NT_STATUS_OK);
908 CHECK_VAL(break_info.count, 0);
909 CHECK_VAL(break_info.failures, 0);
911 smbcli_close(cli1->tree, fnum);
913 done:
914 smb_raw_exit(cli1->session);
915 smb_raw_exit(cli2->session);
916 smbcli_deltree(cli1->tree, BASEDIR);
917 return ret;
920 static bool test_raw_oplock_batch5(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
922 const char *fname = BASEDIR "\\test_batch5.dat";
923 NTSTATUS status;
924 bool ret = true;
925 union smb_open io;
926 uint16_t fnum=0;
928 if (!torture_setup_dir(cli1, BASEDIR)) {
929 return false;
932 /* cleanup */
933 smbcli_unlink(cli1->tree, fname);
935 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
938 base ntcreatex parms
940 io.generic.level = RAW_OPEN_NTCREATEX;
941 io.ntcreatex.in.root_fid = 0;
942 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
943 io.ntcreatex.in.alloc_size = 0;
944 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
945 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
946 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
947 io.ntcreatex.in.create_options = 0;
948 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
949 io.ntcreatex.in.security_flags = 0;
950 io.ntcreatex.in.fname = fname;
952 torture_comment(tctx, "BATCH5: a 2nd open should give a break\n");
953 ZERO_STRUCT(break_info);
954 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
956 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
957 NTCREATEX_FLAGS_REQUEST_OPLOCK |
958 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
959 status = smb_raw_open(cli1->tree, tctx, &io);
960 CHECK_STATUS(tctx, status, NT_STATUS_OK);
961 fnum = io.ntcreatex.out.file.fnum;
962 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
964 ZERO_STRUCT(break_info);
966 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
967 status = smb_raw_open(cli2->tree, tctx, &io);
968 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
970 CHECK_VAL(break_info.count, 1);
971 CHECK_VAL(break_info.fnum, fnum);
972 CHECK_VAL(break_info.level, 1);
973 CHECK_VAL(break_info.failures, 0);
975 smbcli_close(cli1->tree, fnum);
977 done:
978 smb_raw_exit(cli1->session);
979 smb_raw_exit(cli2->session);
980 smbcli_deltree(cli1->tree, BASEDIR);
981 return ret;
984 static bool test_raw_oplock_batch6(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
986 const char *fname = BASEDIR "\\test_batch6.dat";
987 NTSTATUS status;
988 bool ret = true;
989 union smb_open io;
990 uint16_t fnum=0, fnum2=0;
991 char c = 0;
993 if (!torture_setup_dir(cli1, BASEDIR)) {
994 return false;
997 /* cleanup */
998 smbcli_unlink(cli1->tree, fname);
1000 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1003 base ntcreatex parms
1005 io.generic.level = RAW_OPEN_NTCREATEX;
1006 io.ntcreatex.in.root_fid = 0;
1007 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1008 io.ntcreatex.in.alloc_size = 0;
1009 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1010 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1011 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1012 io.ntcreatex.in.create_options = 0;
1013 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1014 io.ntcreatex.in.security_flags = 0;
1015 io.ntcreatex.in.fname = fname;
1017 torture_comment(tctx, "BATCH6: a 2nd open should give a break to level II if the first open allowed shared read\n");
1018 ZERO_STRUCT(break_info);
1019 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1020 smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli2->tree);
1022 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_READ | SEC_RIGHTS_FILE_WRITE;
1023 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
1024 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1025 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1026 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1027 status = smb_raw_open(cli1->tree, tctx, &io);
1028 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1029 fnum = io.ntcreatex.out.file.fnum;
1030 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1032 ZERO_STRUCT(break_info);
1034 status = smb_raw_open(cli2->tree, tctx, &io);
1035 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1036 fnum2 = io.ntcreatex.out.file.fnum;
1037 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1039 CHECK_VAL(break_info.count, 1);
1040 CHECK_VAL(break_info.fnum, fnum);
1041 CHECK_VAL(break_info.level, 1);
1042 CHECK_VAL(break_info.failures, 0);
1043 ZERO_STRUCT(break_info);
1045 torture_comment(tctx, "write should trigger a break to none on both\n");
1046 smbcli_write(cli1->tree, fnum, 0, &c, 0, 1);
1047 msleep(100);
1048 smbcli_write(cli1->tree, fnum, 0, &c, 1, 1);
1050 CHECK_VAL(break_info.count, 2);
1051 CHECK_VAL(break_info.level, 0);
1052 CHECK_VAL(break_info.failures, 0);
1054 smbcli_close(cli1->tree, fnum);
1055 smbcli_close(cli2->tree, fnum2);
1058 done:
1059 smb_raw_exit(cli1->session);
1060 smb_raw_exit(cli2->session);
1061 smbcli_deltree(cli1->tree, BASEDIR);
1062 return ret;
1065 static bool test_raw_oplock_batch7(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1067 const char *fname = BASEDIR "\\test_batch7.dat";
1068 NTSTATUS status;
1069 bool ret = true;
1070 union smb_open io;
1071 uint16_t fnum=0, fnum2=0;
1073 if (!torture_setup_dir(cli1, BASEDIR)) {
1074 return false;
1077 /* cleanup */
1078 smbcli_unlink(cli1->tree, fname);
1080 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1083 base ntcreatex parms
1085 io.generic.level = RAW_OPEN_NTCREATEX;
1086 io.ntcreatex.in.root_fid = 0;
1087 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1088 io.ntcreatex.in.alloc_size = 0;
1089 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1090 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1091 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1092 io.ntcreatex.in.create_options = 0;
1093 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1094 io.ntcreatex.in.security_flags = 0;
1095 io.ntcreatex.in.fname = fname;
1097 torture_comment(tctx, "BATCH7: a 2nd open should get an oplock when we close instead of ack\n");
1098 ZERO_STRUCT(break_info);
1099 smbcli_oplock_handler(cli1->transport, oplock_handler_close, cli1->tree);
1101 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1102 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1103 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1104 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1105 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1106 status = smb_raw_open(cli1->tree, tctx, &io);
1107 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1108 fnum2 = io.ntcreatex.out.file.fnum;
1109 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1111 ZERO_STRUCT(break_info);
1113 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1114 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1115 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1116 status = smb_raw_open(cli2->tree, tctx, &io);
1117 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1118 fnum = io.ntcreatex.out.file.fnum;
1119 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1121 CHECK_VAL(break_info.count, 1);
1122 CHECK_VAL(break_info.fnum, fnum2);
1123 CHECK_VAL(break_info.level, 1);
1124 CHECK_VAL(break_info.failures, 0);
1126 smbcli_close(cli2->tree, fnum);
1128 done:
1129 smb_raw_exit(cli1->session);
1130 smb_raw_exit(cli2->session);
1131 smbcli_deltree(cli1->tree, BASEDIR);
1132 return ret;
1135 static bool test_raw_oplock_batch8(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1137 const char *fname = BASEDIR "\\test_batch8.dat";
1138 NTSTATUS status;
1139 bool ret = true;
1140 union smb_open io;
1141 uint16_t fnum=0, fnum2=0;
1143 if (!torture_setup_dir(cli1, BASEDIR)) {
1144 return false;
1147 /* cleanup */
1148 smbcli_unlink(cli1->tree, fname);
1150 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1153 base ntcreatex parms
1155 io.generic.level = RAW_OPEN_NTCREATEX;
1156 io.ntcreatex.in.root_fid = 0;
1157 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1158 io.ntcreatex.in.alloc_size = 0;
1159 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1160 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1161 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1162 io.ntcreatex.in.create_options = 0;
1163 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1164 io.ntcreatex.in.security_flags = 0;
1165 io.ntcreatex.in.fname = fname;
1167 torture_comment(tctx, "BATCH8: open with batch oplock\n");
1168 ZERO_STRUCT(break_info);
1169 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1171 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1172 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1173 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1174 status = smb_raw_open(cli1->tree, tctx, &io);
1175 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1176 fnum = io.ntcreatex.out.file.fnum;
1177 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1179 ZERO_STRUCT(break_info);
1180 torture_comment(tctx, "second open with attributes only shouldn't cause oplock break\n");
1182 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1183 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1184 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1185 io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
1186 status = smb_raw_open(cli2->tree, tctx, &io);
1187 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1188 fnum2 = io.ntcreatex.out.file.fnum;
1189 CHECK_VAL(io.ntcreatex.out.oplock_level, NO_OPLOCK_RETURN);
1190 CHECK_VAL(break_info.count, 0);
1191 CHECK_VAL(break_info.failures, 0);
1193 smbcli_close(cli1->tree, fnum);
1194 smbcli_close(cli2->tree, fnum2);
1196 done:
1197 smb_raw_exit(cli1->session);
1198 smb_raw_exit(cli2->session);
1199 smbcli_deltree(cli1->tree, BASEDIR);
1200 return ret;
1203 static bool test_raw_oplock_batch9(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1205 const char *fname = BASEDIR "\\test_batch9.dat";
1206 NTSTATUS status;
1207 bool ret = true;
1208 union smb_open io;
1209 uint16_t fnum=0, fnum2=0;
1210 char c = 0;
1212 if (!torture_setup_dir(cli1, BASEDIR)) {
1213 return false;
1216 /* cleanup */
1217 smbcli_unlink(cli1->tree, fname);
1219 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1222 base ntcreatex parms
1224 io.generic.level = RAW_OPEN_NTCREATEX;
1225 io.ntcreatex.in.root_fid = 0;
1226 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1227 io.ntcreatex.in.alloc_size = 0;
1228 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1229 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1230 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1231 io.ntcreatex.in.create_options = 0;
1232 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1233 io.ntcreatex.in.security_flags = 0;
1234 io.ntcreatex.in.fname = fname;
1236 torture_comment(tctx, "BATCH9: open with attributes only can create file\n");
1238 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1239 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1240 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1241 io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
1242 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1243 status = smb_raw_open(cli1->tree, tctx, &io);
1244 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1245 fnum = io.ntcreatex.out.file.fnum;
1246 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1248 torture_comment(tctx, "Subsequent normal open should break oplock on attribute only open to level II\n");
1250 ZERO_STRUCT(break_info);
1251 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1253 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1254 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1255 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1256 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1257 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1258 status = smb_raw_open(cli2->tree, tctx, &io);
1259 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1260 fnum2 = io.ntcreatex.out.file.fnum;
1261 CHECK_VAL(break_info.count, 1);
1262 CHECK_VAL(break_info.fnum, fnum);
1263 CHECK_VAL(break_info.failures, 0);
1264 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
1265 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1266 smbcli_close(cli2->tree, fnum2);
1268 torture_comment(tctx, "third oplocked open should grant level2 without break\n");
1269 ZERO_STRUCT(break_info);
1270 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1271 smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli2->tree);
1272 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1273 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1274 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1275 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1276 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1277 status = smb_raw_open(cli2->tree, tctx, &io);
1278 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1279 fnum2 = io.ntcreatex.out.file.fnum;
1280 CHECK_VAL(break_info.count, 0);
1281 CHECK_VAL(break_info.failures, 0);
1282 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1284 ZERO_STRUCT(break_info);
1286 torture_comment(tctx, "write should trigger a break to none on both\n");
1287 smbcli_write(cli2->tree, fnum2, 0, &c, 0, 1);
1289 /* Now the oplock break request comes in. But right now we can't
1290 * answer it. Do another write */
1292 msleep(100);
1293 smbcli_write(cli2->tree, fnum2, 0, &c, 1, 1);
1295 CHECK_VAL(break_info.count, 2);
1296 CHECK_VAL(break_info.level, 0);
1297 CHECK_VAL(break_info.failures, 0);
1299 smbcli_close(cli1->tree, fnum);
1300 smbcli_close(cli2->tree, fnum2);
1302 done:
1303 smb_raw_exit(cli1->session);
1304 smb_raw_exit(cli2->session);
1305 smbcli_deltree(cli1->tree, BASEDIR);
1306 return ret;
1309 static bool test_raw_oplock_batch10(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1311 const char *fname = BASEDIR "\\test_batch10.dat";
1312 NTSTATUS status;
1313 bool ret = true;
1314 union smb_open io;
1315 uint16_t fnum=0, fnum2=0;
1317 if (!torture_setup_dir(cli1, BASEDIR)) {
1318 return false;
1321 /* cleanup */
1322 smbcli_unlink(cli1->tree, fname);
1324 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1327 base ntcreatex parms
1329 io.generic.level = RAW_OPEN_NTCREATEX;
1330 io.ntcreatex.in.root_fid = 0;
1331 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1332 io.ntcreatex.in.alloc_size = 0;
1333 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1334 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1335 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1336 io.ntcreatex.in.create_options = 0;
1337 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1338 io.ntcreatex.in.security_flags = 0;
1339 io.ntcreatex.in.fname = fname;
1341 torture_comment(tctx, "BATCH10: Open with oplock after a non-oplock open should grant level2\n");
1342 ZERO_STRUCT(break_info);
1343 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
1344 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1345 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1346 NTCREATEX_SHARE_ACCESS_WRITE|
1347 NTCREATEX_SHARE_ACCESS_DELETE;
1348 status = smb_raw_open(cli1->tree, tctx, &io);
1349 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1350 fnum = io.ntcreatex.out.file.fnum;
1351 CHECK_VAL(break_info.count, 0);
1352 CHECK_VAL(break_info.failures, 0);
1353 CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
1355 smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli2->tree);
1357 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1358 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1359 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1360 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1361 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1362 NTCREATEX_SHARE_ACCESS_WRITE|
1363 NTCREATEX_SHARE_ACCESS_DELETE;
1364 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1365 status = smb_raw_open(cli2->tree, tctx, &io);
1366 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1367 fnum2 = io.ntcreatex.out.file.fnum;
1368 CHECK_VAL(break_info.count, 0);
1369 CHECK_VAL(break_info.failures, 0);
1370 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1372 torture_comment(tctx, "write should trigger a break to none\n");
1374 union smb_write wr;
1375 wr.write.level = RAW_WRITE_WRITE;
1376 wr.write.in.file.fnum = fnum;
1377 wr.write.in.count = 1;
1378 wr.write.in.offset = 0;
1379 wr.write.in.remaining = 0;
1380 wr.write.in.data = (const uint8_t *)"x";
1381 status = smb_raw_write(cli1->tree, &wr);
1382 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1385 /* Now the oplock break request comes in. But right now we can't
1386 * answer it. Do another write */
1388 msleep(100);
1391 union smb_write wr;
1392 wr.write.level = RAW_WRITE_WRITE;
1393 wr.write.in.file.fnum = fnum;
1394 wr.write.in.count = 1;
1395 wr.write.in.offset = 0;
1396 wr.write.in.remaining = 0;
1397 wr.write.in.data = (const uint8_t *)"x";
1398 status = smb_raw_write(cli1->tree, &wr);
1399 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1402 CHECK_VAL(break_info.count, 1);
1403 CHECK_VAL(break_info.fnum, fnum2);
1404 CHECK_VAL(break_info.level, 0);
1405 CHECK_VAL(break_info.failures, 0);
1407 smbcli_close(cli1->tree, fnum);
1408 smbcli_close(cli2->tree, fnum2);
1410 done:
1411 smb_raw_exit(cli1->session);
1412 smb_raw_exit(cli2->session);
1413 smbcli_deltree(cli1->tree, BASEDIR);
1414 return ret;
1417 static bool test_raw_oplock_batch11(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1419 const char *fname = BASEDIR "\\test_batch11.dat";
1420 NTSTATUS status;
1421 bool ret = true;
1422 union smb_open io;
1423 union smb_setfileinfo sfi;
1424 uint16_t fnum=0;
1426 if (!torture_setup_dir(cli1, BASEDIR)) {
1427 return false;
1430 /* cleanup */
1431 smbcli_unlink(cli1->tree, fname);
1433 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1436 base ntcreatex parms
1438 io.generic.level = RAW_OPEN_NTCREATEX;
1439 io.ntcreatex.in.root_fid = 0;
1440 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1441 io.ntcreatex.in.alloc_size = 0;
1442 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1443 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1444 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1445 io.ntcreatex.in.create_options = 0;
1446 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1447 io.ntcreatex.in.security_flags = 0;
1448 io.ntcreatex.in.fname = fname;
1450 /* Test if a set-eof on pathname breaks an exclusive oplock. */
1451 torture_comment(tctx, "BATCH11: Test if setpathinfo set EOF breaks oplocks.\n");
1453 ZERO_STRUCT(break_info);
1454 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1456 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1457 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1458 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1459 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1460 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1461 NTCREATEX_SHARE_ACCESS_WRITE|
1462 NTCREATEX_SHARE_ACCESS_DELETE;
1463 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1464 status = smb_raw_open(cli1->tree, tctx, &io);
1465 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1466 fnum = io.ntcreatex.out.file.fnum;
1467 CHECK_VAL(break_info.count, 0);
1468 CHECK_VAL(break_info.failures, 0);
1469 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1471 ZERO_STRUCT(sfi);
1472 sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
1473 sfi.generic.in.file.path = fname;
1474 sfi.end_of_file_info.in.size = 100;
1476 status = smb_raw_setpathinfo(cli2->tree, &sfi);
1478 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1479 CHECK_VAL(break_info.count, 1);
1480 CHECK_VAL(break_info.failures, 0);
1481 CHECK_VAL(break_info.level, 0);
1483 smbcli_close(cli1->tree, fnum);
1485 done:
1486 smb_raw_exit(cli1->session);
1487 smb_raw_exit(cli2->session);
1488 smbcli_deltree(cli1->tree, BASEDIR);
1489 return ret;
1492 static bool test_raw_oplock_batch12(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1494 const char *fname = BASEDIR "\\test_batch12.dat";
1495 NTSTATUS status;
1496 bool ret = true;
1497 union smb_open io;
1498 union smb_setfileinfo sfi;
1499 uint16_t fnum=0;
1501 if (!torture_setup_dir(cli1, BASEDIR)) {
1502 return false;
1505 /* cleanup */
1506 smbcli_unlink(cli1->tree, fname);
1508 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1511 base ntcreatex parms
1513 io.generic.level = RAW_OPEN_NTCREATEX;
1514 io.ntcreatex.in.root_fid = 0;
1515 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1516 io.ntcreatex.in.alloc_size = 0;
1517 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1518 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1519 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1520 io.ntcreatex.in.create_options = 0;
1521 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1522 io.ntcreatex.in.security_flags = 0;
1523 io.ntcreatex.in.fname = fname;
1525 /* Test if a set-allocation size on pathname breaks an exclusive oplock. */
1526 torture_comment(tctx, "BATCH12: Test if setpathinfo allocation size breaks oplocks.\n");
1528 ZERO_STRUCT(break_info);
1529 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1531 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1532 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1533 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1534 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1535 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1536 NTCREATEX_SHARE_ACCESS_WRITE|
1537 NTCREATEX_SHARE_ACCESS_DELETE;
1538 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1539 status = smb_raw_open(cli1->tree, tctx, &io);
1540 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1541 fnum = io.ntcreatex.out.file.fnum;
1542 CHECK_VAL(break_info.count, 0);
1543 CHECK_VAL(break_info.failures, 0);
1544 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1546 ZERO_STRUCT(sfi);
1547 sfi.generic.level = SMB_SFILEINFO_ALLOCATION_INFORMATION;
1548 sfi.generic.in.file.path = fname;
1549 sfi.allocation_info.in.alloc_size = 65536 * 8;
1551 status = smb_raw_setpathinfo(cli2->tree, &sfi);
1553 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1554 CHECK_VAL(break_info.count, 1);
1555 CHECK_VAL(break_info.failures, 0);
1556 CHECK_VAL(break_info.level, 0);
1558 smbcli_close(cli1->tree, fnum);
1560 done:
1561 smb_raw_exit(cli1->session);
1562 smb_raw_exit(cli2->session);
1563 smbcli_deltree(cli1->tree, BASEDIR);
1564 return ret;
1567 static bool test_raw_oplock_batch13(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1569 const char *fname = BASEDIR "\\test_batch13.dat";
1570 NTSTATUS status;
1571 bool ret = true;
1572 union smb_open io;
1573 uint16_t fnum=0, fnum2=0;
1575 if (!torture_setup_dir(cli1, BASEDIR)) {
1576 return false;
1579 /* cleanup */
1580 smbcli_unlink(cli1->tree, fname);
1582 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1583 smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli1->tree);
1586 base ntcreatex parms
1588 io.generic.level = RAW_OPEN_NTCREATEX;
1589 io.ntcreatex.in.root_fid = 0;
1590 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1591 io.ntcreatex.in.alloc_size = 0;
1592 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1593 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1594 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1595 io.ntcreatex.in.create_options = 0;
1596 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1597 io.ntcreatex.in.security_flags = 0;
1598 io.ntcreatex.in.fname = fname;
1600 torture_comment(tctx, "BATCH13: open with batch oplock\n");
1601 ZERO_STRUCT(break_info);
1602 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1605 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1606 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1607 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1608 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1609 NTCREATEX_SHARE_ACCESS_WRITE|
1610 NTCREATEX_SHARE_ACCESS_DELETE;
1611 status = smb_raw_open(cli1->tree, tctx, &io);
1612 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1613 fnum = io.ntcreatex.out.file.fnum;
1614 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1616 ZERO_STRUCT(break_info);
1618 torture_comment(tctx, "second open with attributes only and NTCREATEX_DISP_OVERWRITE dispostion causes oplock break\n");
1620 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1621 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1622 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1623 io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
1624 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1625 NTCREATEX_SHARE_ACCESS_WRITE|
1626 NTCREATEX_SHARE_ACCESS_DELETE;
1627 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE;
1628 status = smb_raw_open(cli2->tree, tctx, &io);
1629 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1630 fnum2 = io.ntcreatex.out.file.fnum;
1631 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1632 CHECK_VAL(break_info.count, 1);
1633 CHECK_VAL(break_info.failures, 0);
1635 smbcli_close(cli1->tree, fnum);
1636 smbcli_close(cli2->tree, fnum2);
1638 done:
1639 smb_raw_exit(cli1->session);
1640 smb_raw_exit(cli2->session);
1641 smbcli_deltree(cli1->tree, BASEDIR);
1642 return ret;
1645 static bool test_raw_oplock_batch14(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1647 const char *fname = BASEDIR "\\test_batch14.dat";
1648 NTSTATUS status;
1649 bool ret = true;
1650 union smb_open io;
1651 uint16_t fnum=0, fnum2=0;
1653 if (!torture_setup_dir(cli1, BASEDIR)) {
1654 return false;
1657 /* cleanup */
1658 smbcli_unlink(cli1->tree, fname);
1660 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1663 base ntcreatex parms
1665 io.generic.level = RAW_OPEN_NTCREATEX;
1666 io.ntcreatex.in.root_fid = 0;
1667 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1668 io.ntcreatex.in.alloc_size = 0;
1669 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1670 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1671 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1672 io.ntcreatex.in.create_options = 0;
1673 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1674 io.ntcreatex.in.security_flags = 0;
1675 io.ntcreatex.in.fname = fname;
1677 torture_comment(tctx, "BATCH14: open with batch oplock\n");
1678 ZERO_STRUCT(break_info);
1679 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1681 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1682 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1683 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1684 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1685 NTCREATEX_SHARE_ACCESS_WRITE|
1686 NTCREATEX_SHARE_ACCESS_DELETE;
1687 status = smb_raw_open(cli1->tree, tctx, &io);
1688 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1689 fnum = io.ntcreatex.out.file.fnum;
1690 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1692 ZERO_STRUCT(break_info);
1694 torture_comment(tctx, "second open with attributes only and NTCREATEX_DISP_SUPERSEDE dispostion causes oplock break\n");
1696 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1697 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1698 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1699 io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
1700 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1701 NTCREATEX_SHARE_ACCESS_WRITE|
1702 NTCREATEX_SHARE_ACCESS_DELETE;
1703 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE;
1704 status = smb_raw_open(cli2->tree, tctx, &io);
1705 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1706 fnum2 = io.ntcreatex.out.file.fnum;
1707 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1708 CHECK_VAL(break_info.count, 1);
1709 CHECK_VAL(break_info.failures, 0);
1711 smbcli_close(cli1->tree, fnum);
1712 smbcli_close(cli2->tree, fnum2);
1713 done:
1714 smb_raw_exit(cli1->session);
1715 smb_raw_exit(cli2->session);
1716 smbcli_deltree(cli1->tree, BASEDIR);
1717 return ret;
1720 static bool test_raw_oplock_batch15(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1722 const char *fname = BASEDIR "\\test_batch15.dat";
1723 NTSTATUS status;
1724 bool ret = true;
1725 union smb_open io;
1726 union smb_fileinfo qfi;
1727 uint16_t fnum=0;
1729 if (!torture_setup_dir(cli1, BASEDIR)) {
1730 return false;
1733 /* cleanup */
1734 smbcli_unlink(cli1->tree, fname);
1736 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1739 base ntcreatex parms
1741 io.generic.level = RAW_OPEN_NTCREATEX;
1742 io.ntcreatex.in.root_fid = 0;
1743 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1744 io.ntcreatex.in.alloc_size = 0;
1745 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1746 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1747 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1748 io.ntcreatex.in.create_options = 0;
1749 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1750 io.ntcreatex.in.security_flags = 0;
1751 io.ntcreatex.in.fname = fname;
1753 /* Test if a qpathinfo all info on pathname breaks a batch oplock. */
1754 torture_comment(tctx, "BATCH15: Test if qpathinfo all info breaks a batch oplock (should not).\n");
1756 ZERO_STRUCT(break_info);
1757 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1759 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1760 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1761 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1762 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1763 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1764 NTCREATEX_SHARE_ACCESS_WRITE|
1765 NTCREATEX_SHARE_ACCESS_DELETE;
1766 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1767 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1768 status = smb_raw_open(cli1->tree, tctx, &io);
1769 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1770 fnum = io.ntcreatex.out.file.fnum;
1771 CHECK_VAL(break_info.count, 0);
1772 CHECK_VAL(break_info.failures, 0);
1773 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1775 ZERO_STRUCT(qfi);
1776 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
1777 qfi.generic.in.file.path = fname;
1779 status = smb_raw_pathinfo(cli2->tree, tctx, &qfi);
1781 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1782 CHECK_VAL(break_info.count, 0);
1784 smbcli_close(cli1->tree, fnum);
1786 done:
1787 smb_raw_exit(cli1->session);
1788 smb_raw_exit(cli2->session);
1789 smbcli_deltree(cli1->tree, BASEDIR);
1790 return ret;
1793 static bool test_raw_oplock_batch16(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1795 const char *fname = BASEDIR "\\test_batch16.dat";
1796 NTSTATUS status;
1797 bool ret = true;
1798 union smb_open io;
1799 uint16_t fnum=0, fnum2=0;
1801 if (!torture_setup_dir(cli1, BASEDIR)) {
1802 return false;
1805 /* cleanup */
1806 smbcli_unlink(cli1->tree, fname);
1808 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1809 smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli1->tree);
1812 base ntcreatex parms
1814 io.generic.level = RAW_OPEN_NTCREATEX;
1815 io.ntcreatex.in.root_fid = 0;
1816 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1817 io.ntcreatex.in.alloc_size = 0;
1818 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1819 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1820 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1821 io.ntcreatex.in.create_options = 0;
1822 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1823 io.ntcreatex.in.security_flags = 0;
1824 io.ntcreatex.in.fname = fname;
1826 torture_comment(tctx, "BATCH16: open with batch oplock\n");
1827 ZERO_STRUCT(break_info);
1828 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1831 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1832 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1833 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1834 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1835 NTCREATEX_SHARE_ACCESS_WRITE|
1836 NTCREATEX_SHARE_ACCESS_DELETE;
1837 status = smb_raw_open(cli1->tree, tctx, &io);
1838 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1839 fnum = io.ntcreatex.out.file.fnum;
1840 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1842 ZERO_STRUCT(break_info);
1844 torture_comment(tctx, "second open with attributes only and NTCREATEX_DISP_OVERWRITE_IF dispostion causes oplock break\n");
1846 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1847 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1848 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1849 io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
1850 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1851 NTCREATEX_SHARE_ACCESS_WRITE|
1852 NTCREATEX_SHARE_ACCESS_DELETE;
1853 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE_IF;
1854 status = smb_raw_open(cli2->tree, tctx, &io);
1855 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1856 fnum2 = io.ntcreatex.out.file.fnum;
1857 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1858 CHECK_VAL(break_info.count, 1);
1859 CHECK_VAL(break_info.failures, 0);
1861 smbcli_close(cli1->tree, fnum);
1862 smbcli_close(cli2->tree, fnum2);
1864 done:
1865 smb_raw_exit(cli1->session);
1866 smb_raw_exit(cli2->session);
1867 smbcli_deltree(cli1->tree, BASEDIR);
1868 return ret;
1871 static bool test_raw_oplock_batch17(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1873 const char *fname1 = BASEDIR "\\test_batch17_1.dat";
1874 const char *fname2 = BASEDIR "\\test_batch17_2.dat";
1875 NTSTATUS status;
1876 bool ret = true;
1877 union smb_open io;
1878 union smb_rename rn;
1879 uint16_t fnum=0;
1881 if (!torture_setup_dir(cli1, BASEDIR)) {
1882 return false;
1885 /* cleanup */
1886 smbcli_unlink(cli1->tree, fname1);
1887 smbcli_unlink(cli1->tree, fname2);
1889 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1892 base ntcreatex parms
1894 io.generic.level = RAW_OPEN_NTCREATEX;
1895 io.ntcreatex.in.root_fid = 0;
1896 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1897 io.ntcreatex.in.alloc_size = 0;
1898 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1899 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1900 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1901 io.ntcreatex.in.create_options = 0;
1902 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1903 io.ntcreatex.in.security_flags = 0;
1904 io.ntcreatex.in.fname = fname1;
1906 torture_comment(tctx, "BATCH17: open a file with an batch oplock (share mode: none)\n");
1908 ZERO_STRUCT(break_info);
1909 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1910 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1911 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1913 status = smb_raw_open(cli1->tree, tctx, &io);
1914 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1915 fnum = io.ntcreatex.out.file.fnum;
1916 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1918 torture_comment(tctx, "rename should trigger a break\n");
1919 ZERO_STRUCT(rn);
1920 rn.generic.level = RAW_RENAME_RENAME;
1921 rn.rename.in.pattern1 = fname1;
1922 rn.rename.in.pattern2 = fname2;
1923 rn.rename.in.attrib = 0;
1925 printf("trying rename while first file open\n");
1926 status = smb_raw_rename(cli2->tree, &rn);
1928 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
1929 CHECK_VAL(break_info.count, 1);
1930 CHECK_VAL(break_info.failures, 0);
1931 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
1933 smbcli_close(cli1->tree, fnum);
1935 done:
1936 smb_raw_exit(cli1->session);
1937 smb_raw_exit(cli2->session);
1938 smbcli_deltree(cli1->tree, BASEDIR);
1939 return ret;
1942 static bool test_raw_oplock_batch18(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1944 const char *fname1 = BASEDIR "\\test_batch18_1.dat";
1945 const char *fname2 = BASEDIR "\\test_batch18_2.dat";
1946 NTSTATUS status;
1947 bool ret = true;
1948 union smb_open io;
1949 union smb_rename rn;
1950 uint16_t fnum=0;
1952 if (!torture_setup_dir(cli1, BASEDIR)) {
1953 return false;
1956 /* cleanup */
1957 smbcli_unlink(cli1->tree, fname1);
1958 smbcli_unlink(cli1->tree, fname2);
1960 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
1963 base ntcreatex parms
1965 io.generic.level = RAW_OPEN_NTCREATEX;
1966 io.ntcreatex.in.root_fid = 0;
1967 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1968 io.ntcreatex.in.alloc_size = 0;
1969 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1970 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1971 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1972 io.ntcreatex.in.create_options = 0;
1973 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1974 io.ntcreatex.in.security_flags = 0;
1975 io.ntcreatex.in.fname = fname1;
1977 torture_comment(tctx, "BATCH18: open a file with an batch oplock (share mode: none)\n");
1979 ZERO_STRUCT(break_info);
1980 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1981 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1982 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1984 status = smb_raw_open(cli1->tree, tctx, &io);
1985 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1986 fnum = io.ntcreatex.out.file.fnum;
1987 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1989 torture_comment(tctx, "ntrename should trigger a break\n");
1990 ZERO_STRUCT(rn);
1991 rn.generic.level = RAW_RENAME_NTRENAME;
1992 rn.ntrename.in.attrib = 0;
1993 rn.ntrename.in.flags = RENAME_FLAG_RENAME;
1994 rn.ntrename.in.old_name = fname1;
1995 rn.ntrename.in.new_name = fname2;
1996 printf("trying rename while first file open\n");
1997 status = smb_raw_rename(cli2->tree, &rn);
1999 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
2000 CHECK_VAL(break_info.count, 1);
2001 CHECK_VAL(break_info.failures, 0);
2002 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
2004 smbcli_close(cli1->tree, fnum);
2006 done:
2007 smb_raw_exit(cli1->session);
2008 smb_raw_exit(cli2->session);
2009 smbcli_deltree(cli1->tree, BASEDIR);
2010 return ret;
2013 static bool test_raw_oplock_batch19(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
2015 const char *fname1 = BASEDIR "\\test_batch19_1.dat";
2016 const char *fname2 = BASEDIR "\\test_batch19_2.dat";
2017 const char *fname3 = BASEDIR "\\test_batch19_3.dat";
2018 NTSTATUS status;
2019 bool ret = true;
2020 union smb_open io;
2021 union smb_fileinfo qfi;
2022 union smb_setfileinfo sfi;
2023 uint16_t fnum=0;
2025 if (!torture_setup_dir(cli1, BASEDIR)) {
2026 return false;
2029 /* cleanup */
2030 smbcli_unlink(cli1->tree, fname1);
2031 smbcli_unlink(cli1->tree, fname2);
2032 smbcli_unlink(cli1->tree, fname3);
2034 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2037 base ntcreatex parms
2039 io.generic.level = RAW_OPEN_NTCREATEX;
2040 io.ntcreatex.in.root_fid = 0;
2041 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2042 io.ntcreatex.in.alloc_size = 0;
2043 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2044 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2045 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2046 io.ntcreatex.in.create_options = 0;
2047 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2048 io.ntcreatex.in.security_flags = 0;
2049 io.ntcreatex.in.fname = fname1;
2051 torture_comment(tctx, "BATCH19: open a file with an batch oplock (share mode: none)\n");
2052 ZERO_STRUCT(break_info);
2053 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2054 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2055 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2056 status = smb_raw_open(cli1->tree, tctx, &io);
2057 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2058 fnum = io.ntcreatex.out.file.fnum;
2059 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
2061 torture_comment(tctx, "setpathinfo rename info should not trigger a break nor a violation\n");
2062 ZERO_STRUCT(sfi);
2063 sfi.generic.level = RAW_SFILEINFO_RENAME_INFORMATION;
2064 sfi.generic.in.file.path = fname1;
2065 sfi.rename_information.in.overwrite = 0;
2066 sfi.rename_information.in.root_fid = 0;
2067 sfi.rename_information.in.new_name = fname2+strlen(BASEDIR)+1;
2069 status = smb_raw_setpathinfo(cli2->tree, &sfi);
2071 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2072 CHECK_VAL(break_info.count, 0);
2074 ZERO_STRUCT(qfi);
2075 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2076 qfi.generic.in.file.fnum = fnum;
2078 status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
2079 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2080 CHECK_STRMATCH(qfi.all_info.out.fname.s, fname2);
2082 torture_comment(tctx, "setfileinfo rename info should not trigger a break nor a violation\n");
2083 ZERO_STRUCT(sfi);
2084 sfi.generic.level = RAW_SFILEINFO_RENAME_INFORMATION;
2085 sfi.generic.in.file.fnum = fnum;
2086 sfi.rename_information.in.overwrite = 0;
2087 sfi.rename_information.in.root_fid = 0;
2088 sfi.rename_information.in.new_name = fname3+strlen(BASEDIR)+1;
2090 status = smb_raw_setfileinfo(cli1->tree, &sfi);
2091 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2092 CHECK_VAL(break_info.count, 0);
2094 ZERO_STRUCT(qfi);
2095 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2096 qfi.generic.in.file.fnum = fnum;
2098 status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
2099 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2100 CHECK_STRMATCH(qfi.all_info.out.fname.s, fname3);
2102 smbcli_close(cli1->tree, fnum);
2104 done:
2105 smb_raw_exit(cli1->session);
2106 smb_raw_exit(cli2->session);
2107 smbcli_deltree(cli1->tree, BASEDIR);
2108 return ret;
2111 /****************************************************
2112 Called from raw-rename - we need oplock handling for
2113 this test so this is why it's in oplock.c, not rename.c
2114 ****************************************************/
2116 bool test_trans2rename(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
2118 const char *fname1 = BASEDIR "\\test_trans2rename_1.dat";
2119 const char *fname2 = BASEDIR "\\test_trans2rename_2.dat";
2120 const char *fname3 = BASEDIR "\\test_trans2rename_3.dat";
2121 NTSTATUS status;
2122 bool ret = true;
2123 union smb_open io;
2124 union smb_fileinfo qfi;
2125 union smb_setfileinfo sfi;
2126 uint16_t fnum=0;
2128 if (!torture_setup_dir(cli1, BASEDIR)) {
2129 return false;
2132 /* cleanup */
2133 smbcli_unlink(cli1->tree, fname1);
2134 smbcli_unlink(cli1->tree, fname2);
2135 smbcli_unlink(cli1->tree, fname3);
2137 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2140 base ntcreatex parms
2142 io.generic.level = RAW_OPEN_NTCREATEX;
2143 io.ntcreatex.in.root_fid = 0;
2144 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2145 io.ntcreatex.in.alloc_size = 0;
2146 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2147 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2148 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2149 io.ntcreatex.in.create_options = 0;
2150 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2151 io.ntcreatex.in.security_flags = 0;
2152 io.ntcreatex.in.fname = fname1;
2154 torture_comment(tctx, "open a file with an exclusive oplock (share mode: none)\n");
2155 ZERO_STRUCT(break_info);
2156 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2157 NTCREATEX_FLAGS_REQUEST_OPLOCK;
2158 status = smb_raw_open(cli1->tree, tctx, &io);
2159 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2160 fnum = io.ntcreatex.out.file.fnum;
2161 CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
2163 torture_comment(tctx, "setpathinfo rename info should not trigger a break nor a violation\n");
2164 ZERO_STRUCT(sfi);
2165 sfi.generic.level = RAW_SFILEINFO_RENAME_INFORMATION;
2166 sfi.generic.in.file.path = fname1;
2167 sfi.rename_information.in.overwrite = 0;
2168 sfi.rename_information.in.root_fid = 0;
2169 sfi.rename_information.in.new_name = fname2+strlen(BASEDIR)+1;
2171 status = smb_raw_setpathinfo(cli2->tree, &sfi);
2173 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2174 CHECK_VAL(break_info.count, 0);
2176 ZERO_STRUCT(qfi);
2177 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2178 qfi.generic.in.file.fnum = fnum;
2180 status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
2181 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2182 CHECK_STRMATCH(qfi.all_info.out.fname.s, fname2);
2184 torture_comment(tctx, "setfileinfo rename info should not trigger a break nor a violation\n");
2185 ZERO_STRUCT(sfi);
2186 sfi.generic.level = RAW_SFILEINFO_RENAME_INFORMATION;
2187 sfi.generic.in.file.fnum = fnum;
2188 sfi.rename_information.in.overwrite = 0;
2189 sfi.rename_information.in.root_fid = 0;
2190 sfi.rename_information.in.new_name = fname3+strlen(BASEDIR)+1;
2192 status = smb_raw_setfileinfo(cli1->tree, &sfi);
2193 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2194 CHECK_VAL(break_info.count, 0);
2196 ZERO_STRUCT(qfi);
2197 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2198 qfi.generic.in.file.fnum = fnum;
2200 status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
2201 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2202 CHECK_STRMATCH(qfi.all_info.out.fname.s, fname3);
2204 smbcli_close(cli1->tree, fnum);
2206 done:
2207 smb_raw_exit(cli1->session);
2208 smb_raw_exit(cli2->session);
2209 smbcli_deltree(cli1->tree, BASEDIR);
2210 return ret;
2213 /****************************************************
2214 Called from raw-rename - we need oplock handling for
2215 this test so this is why it's in oplock.c, not rename.c
2216 ****************************************************/
2218 bool test_nttransrename(struct torture_context *tctx, struct smbcli_state *cli1)
2220 const char *fname1 = BASEDIR "\\test_nttransrename_1.dat";
2221 const char *fname2 = BASEDIR "\\test_nttransrename_2.dat";
2222 NTSTATUS status;
2223 bool ret = true;
2224 union smb_open io;
2225 union smb_fileinfo qfi, qpi;
2226 union smb_rename rn;
2227 uint16_t fnum=0;
2229 if (!torture_setup_dir(cli1, BASEDIR)) {
2230 return false;
2233 /* cleanup */
2234 smbcli_unlink(cli1->tree, fname1);
2235 smbcli_unlink(cli1->tree, fname2);
2237 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2240 base ntcreatex parms
2242 io.generic.level = RAW_OPEN_NTCREATEX;
2243 io.ntcreatex.in.root_fid = 0;
2244 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2245 io.ntcreatex.in.alloc_size = 0;
2246 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2247 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2248 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2249 io.ntcreatex.in.create_options = 0;
2250 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2251 io.ntcreatex.in.security_flags = 0;
2252 io.ntcreatex.in.fname = fname1;
2254 torture_comment(tctx, "nttrans_rename: open a file with an exclusive oplock (share mode: none)\n");
2255 ZERO_STRUCT(break_info);
2256 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2257 NTCREATEX_FLAGS_REQUEST_OPLOCK;
2258 status = smb_raw_open(cli1->tree, tctx, &io);
2259 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2260 fnum = io.ntcreatex.out.file.fnum;
2261 CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
2263 torture_comment(tctx, "nttrans_rename: should not trigger a break nor a share mode violation\n");
2264 ZERO_STRUCT(rn);
2265 rn.generic.level = RAW_RENAME_NTTRANS;
2266 rn.nttrans.in.file.fnum = fnum;
2267 rn.nttrans.in.flags = 0;
2268 rn.nttrans.in.new_name = fname2+strlen(BASEDIR)+1;
2270 status = smb_raw_rename(cli1->tree, &rn);
2272 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2273 CHECK_VAL(break_info.count, 0);
2275 /* w2k3 does nothing, it doesn't rename the file */
2276 torture_comment(tctx, "nttrans_rename: the server should have done nothing\n");
2277 ZERO_STRUCT(qfi);
2278 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2279 qfi.generic.in.file.fnum = fnum;
2281 status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
2282 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2283 CHECK_STRMATCH(qfi.all_info.out.fname.s, fname1);
2285 ZERO_STRUCT(qpi);
2286 qpi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2287 qpi.generic.in.file.path = fname1;
2289 status = smb_raw_pathinfo(cli1->tree, tctx, &qpi);
2290 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2291 CHECK_STRMATCH(qpi.all_info.out.fname.s, fname1);
2293 ZERO_STRUCT(qpi);
2294 qpi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2295 qpi.generic.in.file.path = fname2;
2297 status = smb_raw_pathinfo(cli1->tree, tctx, &qpi);
2298 CHECK_STATUS(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
2300 torture_comment(tctx, "nttrans_rename: after closing the file the file is still not renamed\n");
2301 status = smbcli_close(cli1->tree, fnum);
2302 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2304 ZERO_STRUCT(qpi);
2305 qpi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2306 qpi.generic.in.file.path = fname1;
2308 status = smb_raw_pathinfo(cli1->tree, tctx, &qpi);
2309 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2310 CHECK_STRMATCH(qpi.all_info.out.fname.s, fname1);
2312 ZERO_STRUCT(qpi);
2313 qpi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2314 qpi.generic.in.file.path = fname2;
2316 status = smb_raw_pathinfo(cli1->tree, tctx, &qpi);
2317 CHECK_STATUS(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
2319 torture_comment(tctx, "nttrans_rename: rename with an invalid handle gives NT_STATUS_INVALID_HANDLE\n");
2320 ZERO_STRUCT(rn);
2321 rn.generic.level = RAW_RENAME_NTTRANS;
2322 rn.nttrans.in.file.fnum = fnum+1;
2323 rn.nttrans.in.flags = 0;
2324 rn.nttrans.in.new_name = fname2+strlen(BASEDIR)+1;
2326 status = smb_raw_rename(cli1->tree, &rn);
2328 CHECK_STATUS(tctx, status, NT_STATUS_INVALID_HANDLE);
2330 done:
2331 smb_raw_exit(cli1->session);
2332 smbcli_deltree(cli1->tree, BASEDIR);
2333 return ret;
2337 static bool test_raw_oplock_batch20(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
2339 const char *fname1 = BASEDIR "\\test_batch20_1.dat";
2340 const char *fname2 = BASEDIR "\\test_batch20_2.dat";
2341 const char *fname3 = BASEDIR "\\test_batch20_3.dat";
2342 NTSTATUS status;
2343 bool ret = true;
2344 union smb_open io;
2345 union smb_fileinfo qfi;
2346 union smb_setfileinfo sfi;
2347 uint16_t fnum=0,fnum2=0;
2349 if (!torture_setup_dir(cli1, BASEDIR)) {
2350 return false;
2353 /* cleanup */
2354 smbcli_unlink(cli1->tree, fname1);
2355 smbcli_unlink(cli1->tree, fname2);
2356 smbcli_unlink(cli1->tree, fname3);
2358 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2361 base ntcreatex parms
2363 io.generic.level = RAW_OPEN_NTCREATEX;
2364 io.ntcreatex.in.root_fid = 0;
2365 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2366 io.ntcreatex.in.alloc_size = 0;
2367 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2368 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2369 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2370 io.ntcreatex.in.create_options = 0;
2371 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2372 io.ntcreatex.in.security_flags = 0;
2373 io.ntcreatex.in.fname = fname1;
2375 torture_comment(tctx, "BATCH20: open a file with an batch oplock (share mode: all)\n");
2376 ZERO_STRUCT(break_info);
2377 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2378 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2379 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2380 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
2381 NTCREATEX_SHARE_ACCESS_WRITE|
2382 NTCREATEX_SHARE_ACCESS_DELETE;
2383 status = smb_raw_open(cli1->tree, tctx, &io);
2384 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2385 fnum = io.ntcreatex.out.file.fnum;
2386 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
2388 torture_comment(tctx, "setpathinfo rename info should not trigger a break nor a violation\n");
2389 ZERO_STRUCT(sfi);
2390 sfi.generic.level = RAW_SFILEINFO_RENAME_INFORMATION;
2391 sfi.generic.in.file.path = fname1;
2392 sfi.rename_information.in.overwrite = 0;
2393 sfi.rename_information.in.root_fid = 0;
2394 sfi.rename_information.in.new_name = fname2+strlen(BASEDIR)+1;
2396 status = smb_raw_setpathinfo(cli2->tree, &sfi);
2398 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2399 CHECK_VAL(break_info.count, 0);
2401 ZERO_STRUCT(qfi);
2402 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2403 qfi.generic.in.file.fnum = fnum;
2405 status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
2406 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2407 CHECK_STRMATCH(qfi.all_info.out.fname.s, fname2);
2409 torture_comment(tctx, "open a file with the new name an batch oplock (share mode: all)\n");
2410 ZERO_STRUCT(break_info);
2411 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2412 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2413 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2414 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
2415 NTCREATEX_SHARE_ACCESS_WRITE|
2416 NTCREATEX_SHARE_ACCESS_DELETE;
2417 io.ntcreatex.in.fname = fname2;
2418 status = smb_raw_open(cli2->tree, tctx, &io);
2419 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2420 fnum2 = io.ntcreatex.out.file.fnum;
2421 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
2422 CHECK_VAL(break_info.count, 1);
2423 CHECK_VAL(break_info.failures, 0);
2424 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
2426 torture_comment(tctx, "setfileinfo rename info should not trigger a break nor a violation\n");
2427 ZERO_STRUCT(sfi);
2428 sfi.generic.level = RAW_SFILEINFO_RENAME_INFORMATION;
2429 sfi.generic.in.file.fnum = fnum;
2430 sfi.rename_information.in.overwrite = 0;
2431 sfi.rename_information.in.root_fid = 0;
2432 sfi.rename_information.in.new_name = fname3+strlen(BASEDIR)+1;
2434 status = smb_raw_setfileinfo(cli1->tree, &sfi);
2435 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2436 CHECK_VAL(break_info.count, 1);
2437 CHECK_VAL(break_info.failures, 0);
2438 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
2440 ZERO_STRUCT(qfi);
2441 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2442 qfi.generic.in.file.fnum = fnum;
2444 status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
2445 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2446 CHECK_STRMATCH(qfi.all_info.out.fname.s, fname3);
2448 ZERO_STRUCT(qfi);
2449 qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2450 qfi.generic.in.file.fnum = fnum2;
2452 status = smb_raw_fileinfo(cli2->tree, tctx, &qfi);
2453 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2454 CHECK_STRMATCH(qfi.all_info.out.fname.s, fname3);
2456 smbcli_close(cli1->tree, fnum);
2458 done:
2459 smb_raw_exit(cli1->session);
2460 smb_raw_exit(cli2->session);
2461 smbcli_deltree(cli1->tree, BASEDIR);
2462 return ret;
2465 static bool test_raw_oplock_batch21(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
2467 const char *fname = BASEDIR "\\test_batch21.dat";
2468 NTSTATUS status;
2469 bool ret = true;
2470 union smb_open io;
2471 struct smb_echo e;
2472 uint16_t fnum=0;
2473 char c = 0;
2474 ssize_t wr;
2476 if (!torture_setup_dir(cli1, BASEDIR)) {
2477 return false;
2480 /* cleanup */
2481 smbcli_unlink(cli1->tree, fname);
2483 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2486 base ntcreatex parms
2488 io.generic.level = RAW_OPEN_NTCREATEX;
2489 io.ntcreatex.in.root_fid = 0;
2490 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2491 io.ntcreatex.in.alloc_size = 0;
2492 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2493 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2494 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2495 io.ntcreatex.in.create_options = 0;
2496 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2497 io.ntcreatex.in.security_flags = 0;
2498 io.ntcreatex.in.fname = fname;
2501 with a batch oplock we get a break
2503 torture_comment(tctx, "BATCH21: open with batch oplock\n");
2504 ZERO_STRUCT(break_info);
2505 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2506 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2507 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2508 status = smb_raw_open(cli1->tree, tctx, &io);
2509 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2510 fnum = io.ntcreatex.out.file.fnum;
2511 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
2513 torture_comment(tctx, "writing should not generate a break\n");
2514 wr = smbcli_write(cli1->tree, fnum, 0, &c, 0, 1);
2515 CHECK_VAL(wr, 1);
2516 CHECK_STATUS(tctx, smbcli_nt_error(cli1->tree), NT_STATUS_OK);
2518 ZERO_STRUCT(e);
2519 e.in.repeat_count = 1;
2520 status = smb_raw_echo(cli1->transport, &e);
2521 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2523 CHECK_VAL(break_info.count, 0);
2525 smbcli_close(cli1->tree, fnum);
2527 done:
2528 smb_raw_exit(cli1->session);
2529 smb_raw_exit(cli2->session);
2530 smbcli_deltree(cli1->tree, BASEDIR);
2531 return ret;
2534 static bool test_raw_oplock_batch22(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
2536 const char *fname = BASEDIR "\\test_batch22.dat";
2537 NTSTATUS status;
2538 bool ret = true;
2539 union smb_open io;
2540 uint16_t fnum=0, fnum2=0;
2541 struct timeval tv;
2542 int timeout = torture_setting_int(tctx, "oplocktimeout", 30);
2543 int te;
2545 if (torture_setting_bool(tctx, "samba3", false)) {
2546 torture_skip(tctx, "BATCH22 disabled against samba3\n");
2549 if (!torture_setup_dir(cli1, BASEDIR)) {
2550 return false;
2553 /* cleanup */
2554 smbcli_unlink(cli1->tree, fname);
2556 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2559 base ntcreatex parms
2561 io.generic.level = RAW_OPEN_NTCREATEX;
2562 io.ntcreatex.in.root_fid = 0;
2563 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2564 io.ntcreatex.in.alloc_size = 0;
2565 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2566 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2567 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2568 io.ntcreatex.in.create_options = 0;
2569 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2570 io.ntcreatex.in.security_flags = 0;
2571 io.ntcreatex.in.fname = fname;
2574 with a batch oplock we get a break
2576 torture_comment(tctx, "BATCH22: open with batch oplock\n");
2577 ZERO_STRUCT(break_info);
2578 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2579 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2580 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2581 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
2582 NTCREATEX_SHARE_ACCESS_WRITE|
2583 NTCREATEX_SHARE_ACCESS_DELETE;
2584 status = smb_raw_open(cli1->tree, tctx, &io);
2585 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2586 fnum = io.ntcreatex.out.file.fnum;
2587 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
2589 torture_comment(tctx, "a 2nd open shoud not succeed after the oplock break timeout\n");
2590 tv = timeval_current();
2591 smbcli_oplock_handler(cli1->transport, oplock_handler_timeout, cli1->tree);
2592 status = smb_raw_open(cli1->tree, tctx, &io);
2593 CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
2594 te = (int)timeval_elapsed(&tv);
2595 CHECK_RANGE(te, timeout - 1, timeout + 15);
2597 CHECK_VAL(break_info.count, 1);
2598 CHECK_VAL(break_info.fnum, fnum);
2599 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
2600 CHECK_VAL(break_info.failures, 0);
2601 ZERO_STRUCT(break_info);
2603 torture_comment(tctx, "a 2nd open shoud succeed after the oplock release without break\n");
2604 tv = timeval_current();
2605 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2606 status = smb_raw_open(cli1->tree, tctx, &io);
2607 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2608 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
2609 te = (int)timeval_elapsed(&tv);
2610 /* it should come in without delay */
2611 CHECK_RANGE(te+1, 0, timeout);
2612 fnum2 = io.ntcreatex.out.file.fnum;
2614 CHECK_VAL(break_info.count, 0);
2616 smbcli_close(cli1->tree, fnum);
2617 smbcli_close(cli1->tree, fnum2);
2619 done:
2620 smb_raw_exit(cli1->session);
2621 smb_raw_exit(cli2->session);
2622 smbcli_deltree(cli1->tree, BASEDIR);
2623 return ret;
2626 static bool test_raw_oplock_batch23(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
2628 const char *fname = BASEDIR "\\test_batch23.dat";
2629 NTSTATUS status;
2630 bool ret = true;
2631 union smb_open io;
2632 uint16_t fnum=0, fnum2=0,fnum3=0;
2633 struct smbcli_state *cli3 = NULL;
2635 if (!torture_setup_dir(cli1, BASEDIR)) {
2636 return false;
2639 /* cleanup */
2640 smbcli_unlink(cli1->tree, fname);
2642 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2644 ret = open_connection_no_level2_oplocks(tctx, &cli3);
2645 CHECK_VAL(ret, true);
2648 base ntcreatex parms
2650 io.generic.level = RAW_OPEN_NTCREATEX;
2651 io.ntcreatex.in.root_fid = 0;
2652 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2653 io.ntcreatex.in.alloc_size = 0;
2654 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2655 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2656 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2657 io.ntcreatex.in.create_options = 0;
2658 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2659 io.ntcreatex.in.security_flags = 0;
2660 io.ntcreatex.in.fname = fname;
2662 torture_comment(tctx, "BATCH23: a open and ask for a batch oplock\n");
2663 ZERO_STRUCT(break_info);
2664 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2665 smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli2->tree);
2666 smbcli_oplock_handler(cli3->transport, oplock_handler_ack_to_given, cli3->tree);
2668 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_READ | SEC_RIGHTS_FILE_WRITE;
2669 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
2670 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2671 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2672 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2673 status = smb_raw_open(cli1->tree, tctx, &io);
2674 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2675 fnum = io.ntcreatex.out.file.fnum;
2676 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
2678 ZERO_STRUCT(break_info);
2680 torture_comment(tctx, "a 2nd open without level2 oplock support should generate a break to level2\n");
2681 status = smb_raw_open(cli3->tree, tctx, &io);
2682 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2683 fnum3 = io.ntcreatex.out.file.fnum;
2684 CHECK_VAL(io.ntcreatex.out.oplock_level, NO_OPLOCK_RETURN);
2686 CHECK_VAL(break_info.count, 1);
2687 CHECK_VAL(break_info.fnum, fnum);
2688 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
2689 CHECK_VAL(break_info.failures, 0);
2691 ZERO_STRUCT(break_info);
2693 torture_comment(tctx, "a 3rd open with level2 oplock support should not generate a break\n");
2694 status = smb_raw_open(cli2->tree, tctx, &io);
2695 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2696 fnum2 = io.ntcreatex.out.file.fnum;
2697 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
2699 CHECK_VAL(break_info.count, 0);
2701 smbcli_close(cli1->tree, fnum);
2702 smbcli_close(cli2->tree, fnum2);
2703 smbcli_close(cli3->tree, fnum3);
2705 done:
2706 smb_raw_exit(cli1->session);
2707 smb_raw_exit(cli2->session);
2708 smb_raw_exit(cli3->session);
2709 smbcli_deltree(cli1->tree, BASEDIR);
2710 return ret;
2713 static bool test_raw_oplock_batch24(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
2715 const char *fname = BASEDIR "\\test_batch24.dat";
2716 NTSTATUS status;
2717 bool ret = true;
2718 union smb_open io;
2719 uint16_t fnum2=0,fnum3=0;
2720 struct smbcli_state *cli3 = NULL;
2722 if (!torture_setup_dir(cli1, BASEDIR)) {
2723 return false;
2726 /* cleanup */
2727 smbcli_unlink(cli1->tree, fname);
2729 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2731 ret = open_connection_no_level2_oplocks(tctx, &cli3);
2732 CHECK_VAL(ret, true);
2735 base ntcreatex parms
2737 io.generic.level = RAW_OPEN_NTCREATEX;
2738 io.ntcreatex.in.root_fid = 0;
2739 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2740 io.ntcreatex.in.alloc_size = 0;
2741 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2742 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2743 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2744 io.ntcreatex.in.create_options = 0;
2745 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2746 io.ntcreatex.in.security_flags = 0;
2747 io.ntcreatex.in.fname = fname;
2749 torture_comment(tctx, "BATCH24: a open without level support and ask for a batch oplock\n");
2750 ZERO_STRUCT(break_info);
2751 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2752 smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli2->tree);
2753 smbcli_oplock_handler(cli3->transport, oplock_handler_ack_to_given, cli3->tree);
2755 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_READ | SEC_RIGHTS_FILE_WRITE;
2756 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
2757 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2758 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2759 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2760 status = smb_raw_open(cli3->tree, tctx, &io);
2761 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2762 fnum3 = io.ntcreatex.out.file.fnum;
2763 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
2765 ZERO_STRUCT(break_info);
2767 torture_comment(tctx, "a 2nd open with level2 oplock support should generate a break to none\n");
2768 status = smb_raw_open(cli2->tree, tctx, &io);
2769 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2770 fnum2 = io.ntcreatex.out.file.fnum;
2771 CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
2773 CHECK_VAL(break_info.count, 1);
2774 CHECK_VAL(break_info.fnum, fnum3);
2775 CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_NONE);
2776 CHECK_VAL(break_info.failures, 0);
2778 smbcli_close(cli3->tree, fnum3);
2779 smbcli_close(cli2->tree, fnum2);
2781 done:
2782 smb_raw_exit(cli1->session);
2783 smb_raw_exit(cli2->session);
2784 smb_raw_exit(cli3->session);
2785 smbcli_deltree(cli1->tree, BASEDIR);
2786 return ret;
2789 static bool test_raw_oplock_batch25(struct torture_context *tctx,
2790 struct smbcli_state *cli1,
2791 struct smbcli_state *cli2)
2793 const char *fname = BASEDIR "\\test_batch25.dat";
2794 NTSTATUS status;
2795 bool ret = true;
2796 union smb_open io;
2797 union smb_setfileinfo sfi;
2798 uint16_t fnum=0;
2800 if (!torture_setup_dir(cli1, BASEDIR)) {
2801 return false;
2804 /* cleanup */
2805 smbcli_unlink(cli1->tree, fname);
2807 smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
2810 base ntcreatex parms
2812 io.generic.level = RAW_OPEN_NTCREATEX;
2813 io.ntcreatex.in.root_fid = 0;
2814 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2815 io.ntcreatex.in.alloc_size = 0;
2816 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2817 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2818 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2819 io.ntcreatex.in.create_options = 0;
2820 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2821 io.ntcreatex.in.security_flags = 0;
2822 io.ntcreatex.in.fname = fname;
2824 torture_comment(tctx, "BATCH25: open a file with an batch oplock "
2825 "(share mode: none)\n");
2827 ZERO_STRUCT(break_info);
2828 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2829 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2830 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2831 status = smb_raw_open(cli1->tree, tctx, &io);
2832 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2833 fnum = io.ntcreatex.out.file.fnum;
2834 CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
2836 torture_comment(tctx, "setpathinfo attribute info should not trigger "
2837 "a break nor a violation\n");
2838 ZERO_STRUCT(sfi);
2839 sfi.generic.level = RAW_SFILEINFO_SETATTR;
2840 sfi.generic.in.file.path = fname;
2841 sfi.setattr.in.attrib = FILE_ATTRIBUTE_HIDDEN;
2842 sfi.setattr.in.write_time = 0;
2844 status = smb_raw_setpathinfo(cli2->tree, &sfi);
2846 CHECK_STATUS(tctx, status, NT_STATUS_OK);
2847 CHECK_VAL(break_info.count, 0);
2849 smbcli_close(cli1->tree, fnum);
2851 done:
2852 smb_raw_exit(cli1->session);
2853 smb_raw_exit(cli2->session);
2854 smbcli_deltree(cli1->tree, BASEDIR);
2855 return ret;
2859 basic testing of oplocks
2861 struct torture_suite *torture_raw_oplock(TALLOC_CTX *mem_ctx)
2863 struct torture_suite *suite = torture_suite_create(mem_ctx, "OPLOCK");
2865 torture_suite_add_2smb_test(suite, "EXCLUSIVE1", test_raw_oplock_exclusive1);
2866 torture_suite_add_2smb_test(suite, "EXCLUSIVE2", test_raw_oplock_exclusive2);
2867 torture_suite_add_2smb_test(suite, "EXCLUSIVE3", test_raw_oplock_exclusive3);
2868 torture_suite_add_2smb_test(suite, "EXCLUSIVE4", test_raw_oplock_exclusive4);
2869 torture_suite_add_2smb_test(suite, "EXCLUSIVE5", test_raw_oplock_exclusive5);
2870 torture_suite_add_2smb_test(suite, "EXCLUSIVE6", test_raw_oplock_exclusive6);
2871 torture_suite_add_2smb_test(suite, "BATCH1", test_raw_oplock_batch1);
2872 torture_suite_add_2smb_test(suite, "BATCH2", test_raw_oplock_batch2);
2873 torture_suite_add_2smb_test(suite, "BATCH3", test_raw_oplock_batch3);
2874 torture_suite_add_2smb_test(suite, "BATCH4", test_raw_oplock_batch4);
2875 torture_suite_add_2smb_test(suite, "BATCH5", test_raw_oplock_batch5);
2876 torture_suite_add_2smb_test(suite, "BATCH6", test_raw_oplock_batch6);
2877 torture_suite_add_2smb_test(suite, "BATCH7", test_raw_oplock_batch7);
2878 torture_suite_add_2smb_test(suite, "BATCH8", test_raw_oplock_batch8);
2879 torture_suite_add_2smb_test(suite, "BATCH9", test_raw_oplock_batch9);
2880 torture_suite_add_2smb_test(suite, "BATCH10", test_raw_oplock_batch10);
2881 torture_suite_add_2smb_test(suite, "BATCH11", test_raw_oplock_batch11);
2882 torture_suite_add_2smb_test(suite, "BATCH12", test_raw_oplock_batch12);
2883 torture_suite_add_2smb_test(suite, "BATCH13", test_raw_oplock_batch13);
2884 torture_suite_add_2smb_test(suite, "BATCH14", test_raw_oplock_batch14);
2885 torture_suite_add_2smb_test(suite, "BATCH15", test_raw_oplock_batch15);
2886 torture_suite_add_2smb_test(suite, "BATCH16", test_raw_oplock_batch16);
2887 torture_suite_add_2smb_test(suite, "BATCH17", test_raw_oplock_batch17);
2888 torture_suite_add_2smb_test(suite, "BATCH18", test_raw_oplock_batch18);
2889 torture_suite_add_2smb_test(suite, "BATCH19", test_raw_oplock_batch19);
2890 torture_suite_add_2smb_test(suite, "BATCH20", test_raw_oplock_batch20);
2891 torture_suite_add_2smb_test(suite, "BATCH21", test_raw_oplock_batch21);
2892 torture_suite_add_2smb_test(suite, "BATCH22", test_raw_oplock_batch22);
2893 torture_suite_add_2smb_test(suite, "BATCH23", test_raw_oplock_batch23);
2894 torture_suite_add_2smb_test(suite, "BATCH24", test_raw_oplock_batch24);
2895 torture_suite_add_2smb_test(suite, "BATCH25", test_raw_oplock_batch25);
2897 return suite;
2901 stress testing of oplocks
2903 bool torture_bench_oplock(struct torture_context *torture)
2905 struct smbcli_state **cli;
2906 bool ret = true;
2907 TALLOC_CTX *mem_ctx = talloc_new(torture);
2908 int torture_nprocs = torture_setting_int(torture, "nprocs", 4);
2909 int i, count=0;
2910 int timelimit = torture_setting_int(torture, "timelimit", 10);
2911 union smb_open io;
2912 struct timeval tv;
2914 cli = talloc_array(mem_ctx, struct smbcli_state *, torture_nprocs);
2916 torture_comment(torture, "Opening %d connections\n", torture_nprocs);
2917 for (i=0;i<torture_nprocs;i++) {
2918 if (!torture_open_connection_ev(&cli[i], i, torture, torture->ev)) {
2919 return false;
2921 talloc_steal(mem_ctx, cli[i]);
2922 smbcli_oplock_handler(cli[i]->transport, oplock_handler_close,
2923 cli[i]->tree);
2926 if (!torture_setup_dir(cli[0], BASEDIR)) {
2927 ret = false;
2928 goto done;
2931 io.ntcreatex.level = RAW_OPEN_NTCREATEX;
2932 io.ntcreatex.in.root_fid = 0;
2933 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2934 io.ntcreatex.in.alloc_size = 0;
2935 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2936 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2937 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2938 io.ntcreatex.in.create_options = 0;
2939 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2940 io.ntcreatex.in.security_flags = 0;
2941 io.ntcreatex.in.fname = BASEDIR "\\test.dat";
2942 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2943 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2944 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2946 tv = timeval_current();
2949 we open the same file with SHARE_ACCESS_NONE from all the
2950 connections in a round robin fashion. Each open causes an
2951 oplock break on the previous connection, which is answered
2952 by the oplock_handler_close() to close the file.
2954 This measures how fast we can pass on oplocks, and stresses
2955 the oplock handling code
2957 torture_comment(torture, "Running for %d seconds\n", timelimit);
2958 while (timeval_elapsed(&tv) < timelimit) {
2959 for (i=0;i<torture_nprocs;i++) {
2960 NTSTATUS status;
2962 status = smb_raw_open(cli[i]->tree, mem_ctx, &io);
2963 CHECK_STATUS(torture, status, NT_STATUS_OK);
2964 count++;
2967 if (torture_setting_bool(torture, "progress", true)) {
2968 torture_comment(torture, "%.2f ops/second\r", count/timeval_elapsed(&tv));
2972 torture_comment(torture, "%.2f ops/second\n", count/timeval_elapsed(&tv));
2974 smb_raw_exit(cli[torture_nprocs-1]->session);
2976 done:
2977 smb_raw_exit(cli[0]->session);
2978 smbcli_deltree(cli[0]->tree, BASEDIR);
2979 talloc_free(mem_ctx);
2980 return ret;
2984 static struct hold_oplock_info {
2985 const char *fname;
2986 bool close_on_break;
2987 uint32_t share_access;
2988 uint16_t fnum;
2989 } hold_info[] = {
2990 { BASEDIR "\\notshared_close", true,
2991 NTCREATEX_SHARE_ACCESS_NONE, },
2992 { BASEDIR "\\notshared_noclose", false,
2993 NTCREATEX_SHARE_ACCESS_NONE, },
2994 { BASEDIR "\\shared_close", true,
2995 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE, },
2996 { BASEDIR "\\shared_noclose", false,
2997 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE, },
3000 static bool oplock_handler_hold(struct smbcli_transport *transport,
3001 uint16_t tid, uint16_t fnum, uint8_t level,
3002 void *private_data)
3004 struct smbcli_tree *tree = (struct smbcli_tree *)private_data;
3005 struct hold_oplock_info *info;
3006 int i;
3008 for (i=0;i<ARRAY_SIZE(hold_info);i++) {
3009 if (hold_info[i].fnum == fnum) break;
3012 if (i == ARRAY_SIZE(hold_info)) {
3013 printf("oplock break for unknown fnum %u\n", fnum);
3014 return false;
3017 info = &hold_info[i];
3019 if (info->close_on_break) {
3020 printf("oplock break on %s - closing\n",
3021 info->fname);
3022 oplock_handler_close(transport, tid, fnum, level, private_data);
3023 return true;
3026 printf("oplock break on %s - acking break\n", info->fname);
3028 return smbcli_oplock_ack(tree, fnum, OPLOCK_BREAK_TO_NONE);
3033 used for manual testing of oplocks - especially interaction with
3034 other filesystems (such as NFS and local access)
3036 bool torture_hold_oplock(struct torture_context *torture,
3037 struct smbcli_state *cli)
3039 struct tevent_context *ev =
3040 (struct tevent_context *)cli->transport->socket->event.ctx;
3041 int i;
3043 printf("Setting up open files with oplocks in %s\n", BASEDIR);
3045 if (!torture_setup_dir(cli, BASEDIR)) {
3046 return false;
3049 smbcli_oplock_handler(cli->transport, oplock_handler_hold, cli->tree);
3051 /* setup the files */
3052 for (i=0;i<ARRAY_SIZE(hold_info);i++) {
3053 union smb_open io;
3054 NTSTATUS status;
3055 char c = 1;
3057 io.generic.level = RAW_OPEN_NTCREATEX;
3058 io.ntcreatex.in.root_fid = 0;
3059 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
3060 io.ntcreatex.in.alloc_size = 0;
3061 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
3062 io.ntcreatex.in.share_access = hold_info[i].share_access;
3063 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
3064 io.ntcreatex.in.create_options = 0;
3065 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
3066 io.ntcreatex.in.security_flags = 0;
3067 io.ntcreatex.in.fname = hold_info[i].fname;
3068 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
3069 NTCREATEX_FLAGS_REQUEST_OPLOCK |
3070 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
3071 printf("opening %s\n", hold_info[i].fname);
3073 status = smb_raw_open(cli->tree, cli, &io);
3074 if (!NT_STATUS_IS_OK(status)) {
3075 printf("Failed to open %s - %s\n",
3076 hold_info[i].fname, nt_errstr(status));
3077 return false;
3080 if (io.ntcreatex.out.oplock_level != BATCH_OPLOCK_RETURN) {
3081 printf("Oplock not granted for %s - expected %d but got %d\n",
3082 hold_info[i].fname, BATCH_OPLOCK_RETURN,
3083 io.ntcreatex.out.oplock_level);
3084 return false;
3086 hold_info[i].fnum = io.ntcreatex.out.file.fnum;
3088 /* make the file non-zero size */
3089 if (smbcli_write(cli->tree, hold_info[i].fnum, 0, &c, 0, 1) != 1) {
3090 printf("Failed to write to file\n");
3091 return false;
3095 printf("Waiting for oplock events\n");
3096 event_loop_wait(ev);
3098 return true;