2 Unix SMB/CIFS implementation.
3 basic raw test suite for oplocks
4 Copyright (C) Andrew Tridgell 2003
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "torture/torture.h"
22 #include "torture/smbtorture.h"
23 #include "librpc/gen_ndr/security.h"
24 #include "librpc/gen_ndr/ndr_security.h"
25 #include "libcli/raw/libcliraw.h"
26 #include "libcli/raw/raw_proto.h"
27 #include "libcli/security/security.h"
28 #include "libcli/libcli.h"
29 #include "torture/util.h"
30 #include "lib/events/events.h"
31 #include "param/param.h"
32 #include "lib/cmdline/popt_common.h"
33 #include "libcli/resolve/resolve.h"
35 #define CHECK_VAL(v, correct) do { \
36 if ((v) != (correct)) { \
37 torture_result(tctx, TORTURE_FAIL, "(%s): wrong value for %s got 0x%x - should be 0x%x\n", \
38 __location__, #v, (int)v, (int)correct); \
42 #define CHECK_RANGE(v, min, max) do { \
43 if ((v) < (min) || (v) > (max)) { \
44 torture_result(tctx, TORTURE_FAIL, "(%s): wrong value for %s got %d - should be between %d and %d\n", \
45 __location__, #v, (int)v, (int)min, (int)max); \
49 #define CHECK_STRMATCH(v, correct) do { \
50 if (!v || strstr((v),(correct)) == NULL) { \
51 torture_result(tctx, TORTURE_FAIL, "(%s): wrong value for %s got '%s' - should be '%s'\n", \
52 __location__, #v, v?v:"NULL", correct); \
57 #define CHECK_STATUS(tctx, status, correct) do { \
58 if (!NT_STATUS_EQUAL(status, correct)) { \
59 torture_result(tctx, TORTURE_FAIL, __location__": Incorrect status %s - should be %s", \
60 nt_errstr(status), nt_errstr(correct)); \
73 #define BASEDIR "\\test_oplock"
76 a handler function for oplock break requests. Ack it as a break to level II if possible
78 static bool oplock_handler_ack_to_given(struct smbcli_transport
*transport
,
79 uint16_t tid
, uint16_t fnum
,
80 uint8_t level
, void *private_data
)
82 struct smbcli_tree
*tree
= (struct smbcli_tree
*)private_data
;
85 break_info
.fnum
= fnum
;
86 break_info
.level
= level
;
90 case OPLOCK_BREAK_TO_LEVEL_II
:
93 case OPLOCK_BREAK_TO_NONE
:
98 break_info
.failures
++;
100 printf("Acking to %s [0x%02X] in oplock handler\n",
103 return smbcli_oplock_ack(tree
, fnum
, level
);
107 a handler function for oplock break requests. Ack it as a break to none
109 static bool oplock_handler_ack_to_none(struct smbcli_transport
*transport
,
110 uint16_t tid
, uint16_t fnum
,
111 uint8_t level
, void *private_data
)
113 struct smbcli_tree
*tree
= (struct smbcli_tree
*)private_data
;
114 break_info
.fnum
= fnum
;
115 break_info
.level
= level
;
118 printf("Acking to none in oplock handler\n");
120 return smbcli_oplock_ack(tree
, fnum
, OPLOCK_BREAK_TO_NONE
);
124 a handler function for oplock break requests. Let it timeout
126 static bool oplock_handler_timeout(struct smbcli_transport
*transport
,
127 uint16_t tid
, uint16_t fnum
,
128 uint8_t level
, void *private_data
)
130 break_info
.fnum
= fnum
;
131 break_info
.level
= level
;
134 printf("Let oplock break timeout\n");
138 static void oplock_handler_close_recv(struct smbcli_request
*req
)
141 status
= smbcli_request_simple_recv(req
);
142 if (!NT_STATUS_IS_OK(status
)) {
143 printf("close failed in oplock_handler_close\n");
144 break_info
.failures
++;
149 a handler function for oplock break requests - close the file
151 static bool oplock_handler_close(struct smbcli_transport
*transport
, uint16_t tid
,
152 uint16_t fnum
, uint8_t level
, void *private_data
)
155 struct smbcli_tree
*tree
= (struct smbcli_tree
*)private_data
;
156 struct smbcli_request
*req
;
158 break_info
.fnum
= fnum
;
159 break_info
.level
= level
;
162 io
.close
.level
= RAW_CLOSE_CLOSE
;
163 io
.close
.in
.file
.fnum
= fnum
;
164 io
.close
.in
.write_time
= 0;
165 req
= smb_raw_close_send(tree
, &io
);
167 printf("failed to send close in oplock_handler_close\n");
171 req
->async
.fn
= oplock_handler_close_recv
;
172 req
->async
.private_data
= NULL
;
177 static bool open_connection_no_level2_oplocks(struct torture_context
*tctx
,
178 struct smbcli_state
**c
)
181 struct smbcli_options options
;
182 struct smbcli_session_options session_options
;
184 lp_smbcli_options(tctx
->lp_ctx
, &options
);
185 lp_smbcli_session_options(tctx
->lp_ctx
, &session_options
);
187 options
.use_level2_oplocks
= false;
189 status
= smbcli_full_connection(tctx
, c
,
190 torture_setting_string(tctx
, "host", NULL
),
191 lp_smb_ports(tctx
->lp_ctx
),
192 torture_setting_string(tctx
, "share", NULL
),
193 NULL
, lp_socket_options(tctx
->lp_ctx
), cmdline_credentials
,
194 lp_resolve_context(tctx
->lp_ctx
),
195 tctx
->ev
, &options
, &session_options
,
196 lp_iconv_convenience(tctx
->lp_ctx
),
197 lp_gensec_settings(tctx
, tctx
->lp_ctx
));
198 if (!NT_STATUS_IS_OK(status
)) {
199 torture_comment(tctx
, "Failed to open connection - %s\n",
207 static bool test_raw_oplock_exclusive1(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
209 const char *fname
= BASEDIR
"\\test_exclusive1.dat";
213 union smb_unlink unl
;
216 if (!torture_setup_dir(cli1
, BASEDIR
)) {
221 smbcli_unlink(cli1
->tree
, fname
);
223 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
228 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
229 io
.ntcreatex
.in
.root_fid
= 0;
230 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
231 io
.ntcreatex
.in
.alloc_size
= 0;
232 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
233 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
234 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
235 io
.ntcreatex
.in
.create_options
= 0;
236 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
237 io
.ntcreatex
.in
.security_flags
= 0;
238 io
.ntcreatex
.in
.fname
= fname
;
240 torture_comment(tctx
, "EXCLUSIVE1: open a file with an exclusive oplock (share mode: none)\n");
241 ZERO_STRUCT(break_info
);
242 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
| NTCREATEX_FLAGS_REQUEST_OPLOCK
;
244 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
245 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
246 fnum
= io
.ntcreatex
.out
.file
.fnum
;
247 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, EXCLUSIVE_OPLOCK_RETURN
);
249 torture_comment(tctx
, "a 2nd open should not cause a break\n");
250 status
= smb_raw_open(cli2
->tree
, tctx
, &io
);
251 CHECK_STATUS(tctx
, status
, NT_STATUS_SHARING_VIOLATION
);
252 CHECK_VAL(break_info
.count
, 0);
253 CHECK_VAL(break_info
.failures
, 0);
255 torture_comment(tctx
, "unlink it - should also be no break\n");
256 unl
.unlink
.in
.pattern
= fname
;
257 unl
.unlink
.in
.attrib
= 0;
258 status
= smb_raw_unlink(cli2
->tree
, &unl
);
259 CHECK_STATUS(tctx
, status
, NT_STATUS_SHARING_VIOLATION
);
260 CHECK_VAL(break_info
.count
, 0);
261 CHECK_VAL(break_info
.failures
, 0);
263 smbcli_close(cli1
->tree
, fnum
);
266 smb_raw_exit(cli1
->session
);
267 smb_raw_exit(cli2
->session
);
268 smbcli_deltree(cli1
->tree
, BASEDIR
);
272 static bool test_raw_oplock_exclusive2(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
274 const char *fname
= BASEDIR
"\\test_exclusive2.dat";
278 union smb_unlink unl
;
279 uint16_t fnum
=0, fnum2
=0;
281 if (!torture_setup_dir(cli1
, BASEDIR
)) {
286 smbcli_unlink(cli1
->tree
, fname
);
288 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
293 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
294 io
.ntcreatex
.in
.root_fid
= 0;
295 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
296 io
.ntcreatex
.in
.alloc_size
= 0;
297 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
298 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
299 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
300 io
.ntcreatex
.in
.create_options
= 0;
301 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
302 io
.ntcreatex
.in
.security_flags
= 0;
303 io
.ntcreatex
.in
.fname
= fname
;
305 torture_comment(tctx
, "EXCLUSIVE2: open a file with an exclusive oplock (share mode: all)\n");
306 ZERO_STRUCT(break_info
);
307 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
| NTCREATEX_FLAGS_REQUEST_OPLOCK
;
308 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
|
309 NTCREATEX_SHARE_ACCESS_WRITE
|
310 NTCREATEX_SHARE_ACCESS_DELETE
;
312 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
313 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
314 fnum
= io
.ntcreatex
.out
.file
.fnum
;
315 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, EXCLUSIVE_OPLOCK_RETURN
);
317 torture_comment(tctx
, "a 2nd open should cause a break to level 2\n");
318 status
= smb_raw_open(cli2
->tree
, tctx
, &io
);
319 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
320 fnum2
= io
.ntcreatex
.out
.file
.fnum
;
321 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, LEVEL_II_OPLOCK_RETURN
);
322 CHECK_VAL(break_info
.count
, 1);
323 CHECK_VAL(break_info
.fnum
, fnum
);
324 CHECK_VAL(break_info
.level
, OPLOCK_BREAK_TO_LEVEL_II
);
325 CHECK_VAL(break_info
.failures
, 0);
326 ZERO_STRUCT(break_info
);
328 /* now we have 2 level II oplocks... */
329 torture_comment(tctx
, "try to unlink it - should not cause a break, but a sharing violation\n");
330 unl
.unlink
.in
.pattern
= fname
;
331 unl
.unlink
.in
.attrib
= 0;
332 status
= smb_raw_unlink(cli2
->tree
, &unl
);
333 CHECK_STATUS(tctx
, status
, NT_STATUS_SHARING_VIOLATION
);
334 CHECK_VAL(break_info
.count
, 0);
335 CHECK_VAL(break_info
.failures
, 0);
337 torture_comment(tctx
, "close 1st handle\n");
338 smbcli_close(cli1
->tree
, fnum
);
340 torture_comment(tctx
, "try to unlink it - should not cause a break, but a sharing violation\n");
341 unl
.unlink
.in
.pattern
= fname
;
342 unl
.unlink
.in
.attrib
= 0;
343 status
= smb_raw_unlink(cli2
->tree
, &unl
);
344 CHECK_STATUS(tctx
, status
, NT_STATUS_SHARING_VIOLATION
);
345 CHECK_VAL(break_info
.count
, 0);
346 CHECK_VAL(break_info
.failures
, 0);
348 torture_comment(tctx
, "close 1st handle\n");
349 smbcli_close(cli2
->tree
, fnum2
);
351 torture_comment(tctx
, "unlink it\n");
352 unl
.unlink
.in
.pattern
= fname
;
353 unl
.unlink
.in
.attrib
= 0;
354 status
= smb_raw_unlink(cli2
->tree
, &unl
);
355 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
356 CHECK_VAL(break_info
.count
, 0);
357 CHECK_VAL(break_info
.failures
, 0);
360 smb_raw_exit(cli1
->session
);
361 smb_raw_exit(cli2
->session
);
362 smbcli_deltree(cli1
->tree
, BASEDIR
);
366 static bool test_raw_oplock_exclusive3(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
368 const char *fname
= BASEDIR
"\\test_exclusive3.dat";
372 union smb_setfileinfo sfi
;
375 if (!torture_setup_dir(cli1
, BASEDIR
)) {
380 smbcli_unlink(cli1
->tree
, fname
);
382 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
387 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
388 io
.ntcreatex
.in
.root_fid
= 0;
389 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
390 io
.ntcreatex
.in
.alloc_size
= 0;
391 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
392 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
393 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
394 io
.ntcreatex
.in
.create_options
= 0;
395 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
396 io
.ntcreatex
.in
.security_flags
= 0;
397 io
.ntcreatex
.in
.fname
= fname
;
399 torture_comment(tctx
, "EXCLUSIVE3: open a file with an exclusive oplock (share mode: none)\n");
401 ZERO_STRUCT(break_info
);
402 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
| NTCREATEX_FLAGS_REQUEST_OPLOCK
;
404 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
405 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
406 fnum
= io
.ntcreatex
.out
.file
.fnum
;
407 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, EXCLUSIVE_OPLOCK_RETURN
);
409 torture_comment(tctx
, "setpathinfo EOF should trigger a break to none\n");
411 sfi
.generic
.level
= RAW_SFILEINFO_END_OF_FILE_INFORMATION
;
412 sfi
.generic
.in
.file
.path
= fname
;
413 sfi
.end_of_file_info
.in
.size
= 100;
415 status
= smb_raw_setpathinfo(cli2
->tree
, &sfi
);
417 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
418 CHECK_VAL(break_info
.count
, 1);
419 CHECK_VAL(break_info
.failures
, 0);
420 CHECK_VAL(break_info
.level
, OPLOCK_BREAK_TO_NONE
);
422 smbcli_close(cli1
->tree
, fnum
);
425 smb_raw_exit(cli1
->session
);
426 smb_raw_exit(cli2
->session
);
427 smbcli_deltree(cli1
->tree
, BASEDIR
);
431 static bool test_raw_oplock_exclusive4(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
433 const char *fname
= BASEDIR
"\\test_exclusive4.dat";
437 uint16_t fnum
=0, fnum2
=0;
439 if (!torture_setup_dir(cli1
, BASEDIR
)) {
444 smbcli_unlink(cli1
->tree
, fname
);
446 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
451 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
452 io
.ntcreatex
.in
.root_fid
= 0;
453 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
454 io
.ntcreatex
.in
.alloc_size
= 0;
455 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
456 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
457 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
458 io
.ntcreatex
.in
.create_options
= 0;
459 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
460 io
.ntcreatex
.in
.security_flags
= 0;
461 io
.ntcreatex
.in
.fname
= fname
;
463 torture_comment(tctx
, "EXCLUSIVE4: open with exclusive oplock\n");
464 ZERO_STRUCT(break_info
);
465 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
467 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
| NTCREATEX_FLAGS_REQUEST_OPLOCK
;
468 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
469 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
470 fnum
= io
.ntcreatex
.out
.file
.fnum
;
471 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, EXCLUSIVE_OPLOCK_RETURN
);
473 ZERO_STRUCT(break_info
);
474 torture_comment(tctx
, "second open with attributes only shouldn't cause oplock break\n");
476 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
| NTCREATEX_FLAGS_REQUEST_OPLOCK
;
477 io
.ntcreatex
.in
.access_mask
= SEC_FILE_READ_ATTRIBUTE
|SEC_FILE_WRITE_ATTRIBUTE
|SEC_STD_SYNCHRONIZE
;
478 status
= smb_raw_open(cli2
->tree
, tctx
, &io
);
479 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
480 fnum2
= io
.ntcreatex
.out
.file
.fnum
;
481 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, NO_OPLOCK_RETURN
);
482 CHECK_VAL(break_info
.count
, 0);
483 CHECK_VAL(break_info
.failures
, 0);
485 smbcli_close(cli1
->tree
, fnum
);
486 smbcli_close(cli2
->tree
, fnum2
);
489 smb_raw_exit(cli1
->session
);
490 smb_raw_exit(cli2
->session
);
491 smbcli_deltree(cli1
->tree
, BASEDIR
);
495 static bool test_raw_oplock_exclusive5(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
497 const char *fname
= BASEDIR
"\\test_exclusive5.dat";
501 uint16_t fnum
=0, fnum2
=0;
503 if (!torture_setup_dir(cli1
, BASEDIR
)) {
508 smbcli_unlink(cli1
->tree
, fname
);
510 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
511 smbcli_oplock_handler(cli2
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
516 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
517 io
.ntcreatex
.in
.root_fid
= 0;
518 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
519 io
.ntcreatex
.in
.alloc_size
= 0;
520 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
521 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
522 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
523 io
.ntcreatex
.in
.create_options
= 0;
524 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
525 io
.ntcreatex
.in
.security_flags
= 0;
526 io
.ntcreatex
.in
.fname
= fname
;
528 torture_comment(tctx
, "EXCLUSIVE5: open with exclusive oplock\n");
529 ZERO_STRUCT(break_info
);
530 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
533 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
| NTCREATEX_FLAGS_REQUEST_OPLOCK
;
534 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
|
535 NTCREATEX_SHARE_ACCESS_WRITE
|
536 NTCREATEX_SHARE_ACCESS_DELETE
;
537 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
538 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
539 fnum
= io
.ntcreatex
.out
.file
.fnum
;
540 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, EXCLUSIVE_OPLOCK_RETURN
);
542 ZERO_STRUCT(break_info
);
544 torture_comment(tctx
, "second open with attributes only and NTCREATEX_DISP_OVERWRITE_IF dispostion causes oplock break\n");
546 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
| NTCREATEX_FLAGS_REQUEST_OPLOCK
;
547 io
.ntcreatex
.in
.access_mask
= SEC_FILE_READ_ATTRIBUTE
|SEC_FILE_WRITE_ATTRIBUTE
|SEC_STD_SYNCHRONIZE
;
548 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OVERWRITE_IF
;
549 status
= smb_raw_open(cli2
->tree
, tctx
, &io
);
550 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
551 fnum2
= io
.ntcreatex
.out
.file
.fnum
;
552 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, LEVEL_II_OPLOCK_RETURN
);
553 CHECK_VAL(break_info
.count
, 1);
554 CHECK_VAL(break_info
.failures
, 0);
556 smbcli_close(cli1
->tree
, fnum
);
557 smbcli_close(cli2
->tree
, fnum2
);
560 smb_raw_exit(cli1
->session
);
561 smb_raw_exit(cli2
->session
);
562 smbcli_deltree(cli1
->tree
, BASEDIR
);
566 static bool test_raw_oplock_exclusive6(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
568 const char *fname1
= BASEDIR
"\\test_exclusive6_1.dat";
569 const char *fname2
= BASEDIR
"\\test_exclusive6_2.dat";
576 if (!torture_setup_dir(cli1
, BASEDIR
)) {
581 smbcli_unlink(cli1
->tree
, fname1
);
582 smbcli_unlink(cli1
->tree
, fname2
);
584 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
589 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
590 io
.ntcreatex
.in
.root_fid
= 0;
591 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
592 io
.ntcreatex
.in
.alloc_size
= 0;
593 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
594 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
595 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
596 io
.ntcreatex
.in
.create_options
= 0;
597 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
598 io
.ntcreatex
.in
.security_flags
= 0;
599 io
.ntcreatex
.in
.fname
= fname1
;
601 torture_comment(tctx
, "EXCLUSIVE6: open a file with an exclusive "
602 "oplock (share mode: none)\n");
603 ZERO_STRUCT(break_info
);
604 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
| NTCREATEX_FLAGS_REQUEST_OPLOCK
;
606 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
607 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
608 fnum
= io
.ntcreatex
.out
.file
.fnum
;
609 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, EXCLUSIVE_OPLOCK_RETURN
);
611 torture_comment(tctx
, "rename should not generate a break but get a "
612 "sharing violation\n");
614 rn
.generic
.level
= RAW_RENAME_RENAME
;
615 rn
.rename
.in
.pattern1
= fname1
;
616 rn
.rename
.in
.pattern2
= fname2
;
617 rn
.rename
.in
.attrib
= 0;
619 torture_comment(tctx
, "trying rename while first file open\n");
620 status
= smb_raw_rename(cli2
->tree
, &rn
);
622 CHECK_STATUS(tctx
, status
, NT_STATUS_SHARING_VIOLATION
);
623 CHECK_VAL(break_info
.count
, 0);
624 CHECK_VAL(break_info
.failures
, 0);
626 smbcli_close(cli1
->tree
, fnum
);
629 smb_raw_exit(cli1
->session
);
630 smb_raw_exit(cli2
->session
);
631 smbcli_deltree(cli1
->tree
, BASEDIR
);
635 static bool test_raw_oplock_batch1(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
637 const char *fname
= BASEDIR
"\\test_batch1.dat";
641 union smb_unlink unl
;
645 if (!torture_setup_dir(cli1
, BASEDIR
)) {
650 smbcli_unlink(cli1
->tree
, fname
);
652 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
657 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
658 io
.ntcreatex
.in
.root_fid
= 0;
659 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
660 io
.ntcreatex
.in
.alloc_size
= 0;
661 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
662 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
663 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
664 io
.ntcreatex
.in
.create_options
= 0;
665 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
666 io
.ntcreatex
.in
.security_flags
= 0;
667 io
.ntcreatex
.in
.fname
= fname
;
670 with a batch oplock we get a break
672 torture_comment(tctx
, "BATCH1: open with batch oplock\n");
673 ZERO_STRUCT(break_info
);
674 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
675 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
676 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
677 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
678 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
679 fnum
= io
.ntcreatex
.out
.file
.fnum
;
680 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, BATCH_OPLOCK_RETURN
);
682 torture_comment(tctx
, "unlink should generate a break\n");
683 unl
.unlink
.in
.pattern
= fname
;
684 unl
.unlink
.in
.attrib
= 0;
685 status
= smb_raw_unlink(cli2
->tree
, &unl
);
686 CHECK_STATUS(tctx
, status
, NT_STATUS_SHARING_VIOLATION
);
688 CHECK_VAL(break_info
.count
, 1);
689 CHECK_VAL(break_info
.fnum
, fnum
);
690 CHECK_VAL(break_info
.level
, OPLOCK_BREAK_TO_LEVEL_II
);
691 CHECK_VAL(break_info
.failures
, 0);
693 torture_comment(tctx
, "2nd unlink should not generate a break\n");
694 ZERO_STRUCT(break_info
);
695 status
= smb_raw_unlink(cli2
->tree
, &unl
);
696 CHECK_STATUS(tctx
, status
, NT_STATUS_SHARING_VIOLATION
);
698 CHECK_VAL(break_info
.count
, 0);
700 torture_comment(tctx
, "writing should generate a self break to none\n");
701 smbcli_write(cli1
->tree
, fnum
, 0, &c
, 0, 1);
703 smbcli_write(cli1
->tree
, fnum
, 0, &c
, 1, 1);
705 CHECK_VAL(break_info
.count
, 1);
706 CHECK_VAL(break_info
.fnum
, fnum
);
707 CHECK_VAL(break_info
.level
, OPLOCK_BREAK_TO_NONE
);
708 CHECK_VAL(break_info
.failures
, 0);
710 smbcli_close(cli1
->tree
, fnum
);
713 smb_raw_exit(cli1
->session
);
714 smb_raw_exit(cli2
->session
);
715 smbcli_deltree(cli1
->tree
, BASEDIR
);
719 static bool test_raw_oplock_batch2(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
721 const char *fname
= BASEDIR
"\\test_batch2.dat";
725 union smb_unlink unl
;
729 if (!torture_setup_dir(cli1
, BASEDIR
)) {
734 smbcli_unlink(cli1
->tree
, fname
);
736 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
741 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
742 io
.ntcreatex
.in
.root_fid
= 0;
743 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
744 io
.ntcreatex
.in
.alloc_size
= 0;
745 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
746 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
747 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
748 io
.ntcreatex
.in
.create_options
= 0;
749 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
750 io
.ntcreatex
.in
.security_flags
= 0;
751 io
.ntcreatex
.in
.fname
= fname
;
753 torture_comment(tctx
, "BATCH2: open with batch oplock\n");
754 ZERO_STRUCT(break_info
);
755 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
756 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
757 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
758 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
759 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
760 fnum
= io
.ntcreatex
.out
.file
.fnum
;
761 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, BATCH_OPLOCK_RETURN
);
763 torture_comment(tctx
, "unlink should generate a break, which we ack as break to none\n");
764 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_none
, cli1
->tree
);
765 unl
.unlink
.in
.pattern
= fname
;
766 unl
.unlink
.in
.attrib
= 0;
767 status
= smb_raw_unlink(cli2
->tree
, &unl
);
768 CHECK_STATUS(tctx
, status
, NT_STATUS_SHARING_VIOLATION
);
770 CHECK_VAL(break_info
.count
, 1);
771 CHECK_VAL(break_info
.fnum
, fnum
);
772 CHECK_VAL(break_info
.level
, OPLOCK_BREAK_TO_LEVEL_II
);
773 CHECK_VAL(break_info
.failures
, 0);
775 torture_comment(tctx
, "2nd unlink should not generate a break\n");
776 ZERO_STRUCT(break_info
);
777 status
= smb_raw_unlink(cli2
->tree
, &unl
);
778 CHECK_STATUS(tctx
, status
, NT_STATUS_SHARING_VIOLATION
);
780 CHECK_VAL(break_info
.count
, 0);
782 torture_comment(tctx
, "writing should not generate a break\n");
783 smbcli_write(cli1
->tree
, fnum
, 0, &c
, 0, 1);
785 smbcli_write(cli1
->tree
, fnum
, 0, &c
, 1, 1);
787 CHECK_VAL(break_info
.count
, 0);
789 smbcli_close(cli1
->tree
, fnum
);
792 smb_raw_exit(cli1
->session
);
793 smb_raw_exit(cli2
->session
);
794 smbcli_deltree(cli1
->tree
, BASEDIR
);
798 static bool test_raw_oplock_batch3(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
800 const char *fname
= BASEDIR
"\\test_batch3.dat";
804 union smb_unlink unl
;
807 if (!torture_setup_dir(cli1
, BASEDIR
)) {
812 smbcli_unlink(cli1
->tree
, fname
);
814 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
819 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
820 io
.ntcreatex
.in
.root_fid
= 0;
821 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
822 io
.ntcreatex
.in
.alloc_size
= 0;
823 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
824 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
825 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
826 io
.ntcreatex
.in
.create_options
= 0;
827 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
828 io
.ntcreatex
.in
.security_flags
= 0;
829 io
.ntcreatex
.in
.fname
= fname
;
831 torture_comment(tctx
, "BATCH3: if we close on break then the unlink can succeed\n");
832 ZERO_STRUCT(break_info
);
833 smbcli_oplock_handler(cli1
->transport
, oplock_handler_close
, cli1
->tree
);
834 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
835 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
836 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
837 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
838 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
839 fnum
= io
.ntcreatex
.out
.file
.fnum
;
840 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, BATCH_OPLOCK_RETURN
);
842 unl
.unlink
.in
.pattern
= fname
;
843 unl
.unlink
.in
.attrib
= 0;
844 ZERO_STRUCT(break_info
);
845 status
= smb_raw_unlink(cli2
->tree
, &unl
);
846 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
848 CHECK_VAL(break_info
.count
, 1);
849 CHECK_VAL(break_info
.fnum
, fnum
);
850 CHECK_VAL(break_info
.level
, 1);
851 CHECK_VAL(break_info
.failures
, 0);
853 smbcli_close(cli1
->tree
, fnum
);
856 smb_raw_exit(cli1
->session
);
857 smb_raw_exit(cli2
->session
);
858 smbcli_deltree(cli1
->tree
, BASEDIR
);
862 static bool test_raw_oplock_batch4(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
864 const char *fname
= BASEDIR
"\\test_batch4.dat";
871 if (!torture_setup_dir(cli1
, BASEDIR
)) {
876 smbcli_unlink(cli1
->tree
, fname
);
878 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
883 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
884 io
.ntcreatex
.in
.root_fid
= 0;
885 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
886 io
.ntcreatex
.in
.alloc_size
= 0;
887 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
888 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
889 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
890 io
.ntcreatex
.in
.create_options
= 0;
891 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
892 io
.ntcreatex
.in
.security_flags
= 0;
893 io
.ntcreatex
.in
.fname
= fname
;
895 torture_comment(tctx
, "BATCH4: a self read should not cause a break\n");
896 ZERO_STRUCT(break_info
);
897 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
899 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
900 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
901 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
902 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
903 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
904 fnum
= io
.ntcreatex
.out
.file
.fnum
;
905 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, BATCH_OPLOCK_RETURN
);
907 rd
.read
.level
= RAW_READ_READ
;
908 rd
.read
.in
.file
.fnum
= fnum
;
909 rd
.read
.in
.count
= 1;
910 rd
.read
.in
.offset
= 0;
911 rd
.read
.in
.remaining
= 0;
912 status
= smb_raw_read(cli1
->tree
, &rd
);
913 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
914 CHECK_VAL(break_info
.count
, 0);
915 CHECK_VAL(break_info
.failures
, 0);
917 smbcli_close(cli1
->tree
, fnum
);
920 smb_raw_exit(cli1
->session
);
921 smb_raw_exit(cli2
->session
);
922 smbcli_deltree(cli1
->tree
, BASEDIR
);
926 static bool test_raw_oplock_batch5(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
928 const char *fname
= BASEDIR
"\\test_batch5.dat";
934 if (!torture_setup_dir(cli1
, BASEDIR
)) {
939 smbcli_unlink(cli1
->tree
, fname
);
941 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
946 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
947 io
.ntcreatex
.in
.root_fid
= 0;
948 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
949 io
.ntcreatex
.in
.alloc_size
= 0;
950 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
951 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
952 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
953 io
.ntcreatex
.in
.create_options
= 0;
954 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
955 io
.ntcreatex
.in
.security_flags
= 0;
956 io
.ntcreatex
.in
.fname
= fname
;
958 torture_comment(tctx
, "BATCH5: a 2nd open should give a break\n");
959 ZERO_STRUCT(break_info
);
960 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
962 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
963 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
964 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
965 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
966 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
967 fnum
= io
.ntcreatex
.out
.file
.fnum
;
968 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, BATCH_OPLOCK_RETURN
);
970 ZERO_STRUCT(break_info
);
972 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
;
973 status
= smb_raw_open(cli2
->tree
, tctx
, &io
);
974 CHECK_STATUS(tctx
, status
, NT_STATUS_SHARING_VIOLATION
);
976 CHECK_VAL(break_info
.count
, 1);
977 CHECK_VAL(break_info
.fnum
, fnum
);
978 CHECK_VAL(break_info
.level
, 1);
979 CHECK_VAL(break_info
.failures
, 0);
981 smbcli_close(cli1
->tree
, fnum
);
984 smb_raw_exit(cli1
->session
);
985 smb_raw_exit(cli2
->session
);
986 smbcli_deltree(cli1
->tree
, BASEDIR
);
990 static bool test_raw_oplock_batch6(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
992 const char *fname
= BASEDIR
"\\test_batch6.dat";
996 uint16_t fnum
=0, fnum2
=0;
999 if (!torture_setup_dir(cli1
, BASEDIR
)) {
1004 smbcli_unlink(cli1
->tree
, fname
);
1006 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
1009 base ntcreatex parms
1011 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
1012 io
.ntcreatex
.in
.root_fid
= 0;
1013 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
1014 io
.ntcreatex
.in
.alloc_size
= 0;
1015 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
1016 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
1017 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
1018 io
.ntcreatex
.in
.create_options
= 0;
1019 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
1020 io
.ntcreatex
.in
.security_flags
= 0;
1021 io
.ntcreatex
.in
.fname
= fname
;
1023 torture_comment(tctx
, "BATCH6: a 2nd open should give a break to level II if the first open allowed shared read\n");
1024 ZERO_STRUCT(break_info
);
1025 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
1026 smbcli_oplock_handler(cli2
->transport
, oplock_handler_ack_to_given
, cli2
->tree
);
1028 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_READ
| SEC_RIGHTS_FILE_WRITE
;
1029 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
| NTCREATEX_SHARE_ACCESS_WRITE
;
1030 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
1031 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
1032 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
1033 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
1034 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
1035 fnum
= io
.ntcreatex
.out
.file
.fnum
;
1036 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, BATCH_OPLOCK_RETURN
);
1038 ZERO_STRUCT(break_info
);
1040 status
= smb_raw_open(cli2
->tree
, tctx
, &io
);
1041 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
1042 fnum2
= io
.ntcreatex
.out
.file
.fnum
;
1043 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, LEVEL_II_OPLOCK_RETURN
);
1045 CHECK_VAL(break_info
.count
, 1);
1046 CHECK_VAL(break_info
.fnum
, fnum
);
1047 CHECK_VAL(break_info
.level
, 1);
1048 CHECK_VAL(break_info
.failures
, 0);
1049 ZERO_STRUCT(break_info
);
1051 torture_comment(tctx
, "write should trigger a break to none on both\n");
1052 smbcli_write(cli1
->tree
, fnum
, 0, &c
, 0, 1);
1054 smbcli_write(cli1
->tree
, fnum
, 0, &c
, 1, 1);
1056 CHECK_VAL(break_info
.count
, 2);
1057 CHECK_VAL(break_info
.level
, 0);
1058 CHECK_VAL(break_info
.failures
, 0);
1060 smbcli_close(cli1
->tree
, fnum
);
1061 smbcli_close(cli2
->tree
, fnum2
);
1065 smb_raw_exit(cli1
->session
);
1066 smb_raw_exit(cli2
->session
);
1067 smbcli_deltree(cli1
->tree
, BASEDIR
);
1071 static bool test_raw_oplock_batch7(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
1073 const char *fname
= BASEDIR
"\\test_batch7.dat";
1077 uint16_t fnum
=0, fnum2
=0;
1079 if (!torture_setup_dir(cli1
, BASEDIR
)) {
1084 smbcli_unlink(cli1
->tree
, fname
);
1086 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
1089 base ntcreatex parms
1091 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
1092 io
.ntcreatex
.in
.root_fid
= 0;
1093 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
1094 io
.ntcreatex
.in
.alloc_size
= 0;
1095 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
1096 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
1097 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
1098 io
.ntcreatex
.in
.create_options
= 0;
1099 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
1100 io
.ntcreatex
.in
.security_flags
= 0;
1101 io
.ntcreatex
.in
.fname
= fname
;
1103 torture_comment(tctx
, "BATCH7: a 2nd open should get an oplock when we close instead of ack\n");
1104 ZERO_STRUCT(break_info
);
1105 smbcli_oplock_handler(cli1
->transport
, oplock_handler_close
, cli1
->tree
);
1107 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
1108 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
1109 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
1110 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
1111 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
1112 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
1113 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
1114 fnum2
= io
.ntcreatex
.out
.file
.fnum
;
1115 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, BATCH_OPLOCK_RETURN
);
1117 ZERO_STRUCT(break_info
);
1119 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
1120 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
1121 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
1122 status
= smb_raw_open(cli2
->tree
, tctx
, &io
);
1123 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
1124 fnum
= io
.ntcreatex
.out
.file
.fnum
;
1125 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, BATCH_OPLOCK_RETURN
);
1127 CHECK_VAL(break_info
.count
, 1);
1128 CHECK_VAL(break_info
.fnum
, fnum2
);
1129 CHECK_VAL(break_info
.level
, 1);
1130 CHECK_VAL(break_info
.failures
, 0);
1132 smbcli_close(cli2
->tree
, fnum
);
1135 smb_raw_exit(cli1
->session
);
1136 smb_raw_exit(cli2
->session
);
1137 smbcli_deltree(cli1
->tree
, BASEDIR
);
1141 static bool test_raw_oplock_batch8(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
1143 const char *fname
= BASEDIR
"\\test_batch8.dat";
1147 uint16_t fnum
=0, fnum2
=0;
1149 if (!torture_setup_dir(cli1
, BASEDIR
)) {
1154 smbcli_unlink(cli1
->tree
, fname
);
1156 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
1159 base ntcreatex parms
1161 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
1162 io
.ntcreatex
.in
.root_fid
= 0;
1163 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
1164 io
.ntcreatex
.in
.alloc_size
= 0;
1165 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
1166 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
1167 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
1168 io
.ntcreatex
.in
.create_options
= 0;
1169 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
1170 io
.ntcreatex
.in
.security_flags
= 0;
1171 io
.ntcreatex
.in
.fname
= fname
;
1173 torture_comment(tctx
, "BATCH8: open with batch oplock\n");
1174 ZERO_STRUCT(break_info
);
1175 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
1177 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
1178 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
1179 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
1180 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
1181 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
1182 fnum
= io
.ntcreatex
.out
.file
.fnum
;
1183 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, BATCH_OPLOCK_RETURN
);
1185 ZERO_STRUCT(break_info
);
1186 torture_comment(tctx
, "second open with attributes only shouldn't cause oplock break\n");
1188 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
1189 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
1190 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
1191 io
.ntcreatex
.in
.access_mask
= SEC_FILE_READ_ATTRIBUTE
|SEC_FILE_WRITE_ATTRIBUTE
|SEC_STD_SYNCHRONIZE
;
1192 status
= smb_raw_open(cli2
->tree
, tctx
, &io
);
1193 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
1194 fnum2
= io
.ntcreatex
.out
.file
.fnum
;
1195 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, NO_OPLOCK_RETURN
);
1196 CHECK_VAL(break_info
.count
, 0);
1197 CHECK_VAL(break_info
.failures
, 0);
1199 smbcli_close(cli1
->tree
, fnum
);
1200 smbcli_close(cli2
->tree
, fnum2
);
1203 smb_raw_exit(cli1
->session
);
1204 smb_raw_exit(cli2
->session
);
1205 smbcli_deltree(cli1
->tree
, BASEDIR
);
1209 static bool test_raw_oplock_batch9(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
1211 const char *fname
= BASEDIR
"\\test_batch9.dat";
1215 uint16_t fnum
=0, fnum2
=0;
1218 if (!torture_setup_dir(cli1
, BASEDIR
)) {
1223 smbcli_unlink(cli1
->tree
, fname
);
1225 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
1228 base ntcreatex parms
1230 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
1231 io
.ntcreatex
.in
.root_fid
= 0;
1232 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
1233 io
.ntcreatex
.in
.alloc_size
= 0;
1234 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
1235 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
1236 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
1237 io
.ntcreatex
.in
.create_options
= 0;
1238 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
1239 io
.ntcreatex
.in
.security_flags
= 0;
1240 io
.ntcreatex
.in
.fname
= fname
;
1242 torture_comment(tctx
, "BATCH9: open with attributes only can create file\n");
1244 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
1245 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
1246 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
1247 io
.ntcreatex
.in
.access_mask
= SEC_FILE_READ_ATTRIBUTE
|SEC_FILE_WRITE_ATTRIBUTE
|SEC_STD_SYNCHRONIZE
;
1248 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_CREATE
;
1249 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
1250 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
1251 fnum
= io
.ntcreatex
.out
.file
.fnum
;
1252 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, BATCH_OPLOCK_RETURN
);
1254 torture_comment(tctx
, "Subsequent normal open should break oplock on attribute only open to level II\n");
1256 ZERO_STRUCT(break_info
);
1257 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
1259 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
1260 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
1261 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
1262 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
1263 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN
;
1264 status
= smb_raw_open(cli2
->tree
, tctx
, &io
);
1265 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
1266 fnum2
= io
.ntcreatex
.out
.file
.fnum
;
1267 CHECK_VAL(break_info
.count
, 1);
1268 CHECK_VAL(break_info
.fnum
, fnum
);
1269 CHECK_VAL(break_info
.failures
, 0);
1270 CHECK_VAL(break_info
.level
, OPLOCK_BREAK_TO_LEVEL_II
);
1271 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, LEVEL_II_OPLOCK_RETURN
);
1272 smbcli_close(cli2
->tree
, fnum2
);
1274 torture_comment(tctx
, "third oplocked open should grant level2 without break\n");
1275 ZERO_STRUCT(break_info
);
1276 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
1277 smbcli_oplock_handler(cli2
->transport
, oplock_handler_ack_to_given
, cli2
->tree
);
1278 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
1279 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
1280 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
1281 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
1282 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN
;
1283 status
= smb_raw_open(cli2
->tree
, tctx
, &io
);
1284 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
1285 fnum2
= io
.ntcreatex
.out
.file
.fnum
;
1286 CHECK_VAL(break_info
.count
, 0);
1287 CHECK_VAL(break_info
.failures
, 0);
1288 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, LEVEL_II_OPLOCK_RETURN
);
1290 ZERO_STRUCT(break_info
);
1292 torture_comment(tctx
, "write should trigger a break to none on both\n");
1293 smbcli_write(cli2
->tree
, fnum2
, 0, &c
, 0, 1);
1295 /* Now the oplock break request comes in. But right now we can't
1296 * answer it. Do another write */
1299 smbcli_write(cli2
->tree
, fnum2
, 0, &c
, 1, 1);
1301 CHECK_VAL(break_info
.count
, 2);
1302 CHECK_VAL(break_info
.level
, 0);
1303 CHECK_VAL(break_info
.failures
, 0);
1305 smbcli_close(cli1
->tree
, fnum
);
1306 smbcli_close(cli2
->tree
, fnum2
);
1309 smb_raw_exit(cli1
->session
);
1310 smb_raw_exit(cli2
->session
);
1311 smbcli_deltree(cli1
->tree
, BASEDIR
);
1315 static bool test_raw_oplock_batch10(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
1317 const char *fname
= BASEDIR
"\\test_batch10.dat";
1321 uint16_t fnum
=0, fnum2
=0;
1323 if (!torture_setup_dir(cli1
, BASEDIR
)) {
1328 smbcli_unlink(cli1
->tree
, fname
);
1330 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
1333 base ntcreatex parms
1335 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
1336 io
.ntcreatex
.in
.root_fid
= 0;
1337 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
1338 io
.ntcreatex
.in
.alloc_size
= 0;
1339 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
1340 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
1341 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
1342 io
.ntcreatex
.in
.create_options
= 0;
1343 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
1344 io
.ntcreatex
.in
.security_flags
= 0;
1345 io
.ntcreatex
.in
.fname
= fname
;
1347 torture_comment(tctx
, "BATCH10: Open with oplock after a non-oplock open should grant level2\n");
1348 ZERO_STRUCT(break_info
);
1349 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
;
1350 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
1351 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
|
1352 NTCREATEX_SHARE_ACCESS_WRITE
|
1353 NTCREATEX_SHARE_ACCESS_DELETE
;
1354 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
1355 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
1356 fnum
= io
.ntcreatex
.out
.file
.fnum
;
1357 CHECK_VAL(break_info
.count
, 0);
1358 CHECK_VAL(break_info
.failures
, 0);
1359 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, 0);
1361 smbcli_oplock_handler(cli2
->transport
, oplock_handler_ack_to_given
, cli2
->tree
);
1363 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
1364 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
1365 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
1366 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
1367 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
|
1368 NTCREATEX_SHARE_ACCESS_WRITE
|
1369 NTCREATEX_SHARE_ACCESS_DELETE
;
1370 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN
;
1371 status
= smb_raw_open(cli2
->tree
, tctx
, &io
);
1372 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
1373 fnum2
= io
.ntcreatex
.out
.file
.fnum
;
1374 CHECK_VAL(break_info
.count
, 0);
1375 CHECK_VAL(break_info
.failures
, 0);
1376 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, LEVEL_II_OPLOCK_RETURN
);
1378 torture_comment(tctx
, "write should trigger a break to none\n");
1381 wr
.write
.level
= RAW_WRITE_WRITE
;
1382 wr
.write
.in
.file
.fnum
= fnum
;
1383 wr
.write
.in
.count
= 1;
1384 wr
.write
.in
.offset
= 0;
1385 wr
.write
.in
.remaining
= 0;
1386 wr
.write
.in
.data
= (const uint8_t *)"x";
1387 status
= smb_raw_write(cli1
->tree
, &wr
);
1388 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
1391 /* Now the oplock break request comes in. But right now we can't
1392 * answer it. Do another write */
1398 wr
.write
.level
= RAW_WRITE_WRITE
;
1399 wr
.write
.in
.file
.fnum
= fnum
;
1400 wr
.write
.in
.count
= 1;
1401 wr
.write
.in
.offset
= 0;
1402 wr
.write
.in
.remaining
= 0;
1403 wr
.write
.in
.data
= (const uint8_t *)"x";
1404 status
= smb_raw_write(cli1
->tree
, &wr
);
1405 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
1408 CHECK_VAL(break_info
.count
, 1);
1409 CHECK_VAL(break_info
.fnum
, fnum2
);
1410 CHECK_VAL(break_info
.level
, 0);
1411 CHECK_VAL(break_info
.failures
, 0);
1413 smbcli_close(cli1
->tree
, fnum
);
1414 smbcli_close(cli2
->tree
, fnum2
);
1417 smb_raw_exit(cli1
->session
);
1418 smb_raw_exit(cli2
->session
);
1419 smbcli_deltree(cli1
->tree
, BASEDIR
);
1423 static bool test_raw_oplock_batch11(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
1425 const char *fname
= BASEDIR
"\\test_batch11.dat";
1429 union smb_setfileinfo sfi
;
1432 if (!torture_setup_dir(cli1
, BASEDIR
)) {
1437 smbcli_unlink(cli1
->tree
, fname
);
1439 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
1442 base ntcreatex parms
1444 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
1445 io
.ntcreatex
.in
.root_fid
= 0;
1446 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
1447 io
.ntcreatex
.in
.alloc_size
= 0;
1448 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
1449 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
1450 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
1451 io
.ntcreatex
.in
.create_options
= 0;
1452 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
1453 io
.ntcreatex
.in
.security_flags
= 0;
1454 io
.ntcreatex
.in
.fname
= fname
;
1456 /* Test if a set-eof on pathname breaks an exclusive oplock. */
1457 torture_comment(tctx
, "BATCH11: Test if setpathinfo set EOF breaks oplocks.\n");
1459 ZERO_STRUCT(break_info
);
1460 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
1462 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
1463 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
1464 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
1465 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
1466 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
|
1467 NTCREATEX_SHARE_ACCESS_WRITE
|
1468 NTCREATEX_SHARE_ACCESS_DELETE
;
1469 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_CREATE
;
1470 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
1471 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
1472 fnum
= io
.ntcreatex
.out
.file
.fnum
;
1473 CHECK_VAL(break_info
.count
, 0);
1474 CHECK_VAL(break_info
.failures
, 0);
1475 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, BATCH_OPLOCK_RETURN
);
1478 sfi
.generic
.level
= RAW_SFILEINFO_END_OF_FILE_INFORMATION
;
1479 sfi
.generic
.in
.file
.path
= fname
;
1480 sfi
.end_of_file_info
.in
.size
= 100;
1482 status
= smb_raw_setpathinfo(cli2
->tree
, &sfi
);
1484 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
1485 CHECK_VAL(break_info
.count
, 1);
1486 CHECK_VAL(break_info
.failures
, 0);
1487 CHECK_VAL(break_info
.level
, 0);
1489 smbcli_close(cli1
->tree
, fnum
);
1492 smb_raw_exit(cli1
->session
);
1493 smb_raw_exit(cli2
->session
);
1494 smbcli_deltree(cli1
->tree
, BASEDIR
);
1498 static bool test_raw_oplock_batch12(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
1500 const char *fname
= BASEDIR
"\\test_batch12.dat";
1504 union smb_setfileinfo sfi
;
1507 if (!torture_setup_dir(cli1
, BASEDIR
)) {
1512 smbcli_unlink(cli1
->tree
, fname
);
1514 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
1517 base ntcreatex parms
1519 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
1520 io
.ntcreatex
.in
.root_fid
= 0;
1521 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
1522 io
.ntcreatex
.in
.alloc_size
= 0;
1523 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
1524 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
1525 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
1526 io
.ntcreatex
.in
.create_options
= 0;
1527 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
1528 io
.ntcreatex
.in
.security_flags
= 0;
1529 io
.ntcreatex
.in
.fname
= fname
;
1531 /* Test if a set-allocation size on pathname breaks an exclusive oplock. */
1532 torture_comment(tctx
, "BATCH12: Test if setpathinfo allocation size breaks oplocks.\n");
1534 ZERO_STRUCT(break_info
);
1535 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
1537 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
1538 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
1539 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
1540 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
1541 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
|
1542 NTCREATEX_SHARE_ACCESS_WRITE
|
1543 NTCREATEX_SHARE_ACCESS_DELETE
;
1544 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_CREATE
;
1545 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
1546 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
1547 fnum
= io
.ntcreatex
.out
.file
.fnum
;
1548 CHECK_VAL(break_info
.count
, 0);
1549 CHECK_VAL(break_info
.failures
, 0);
1550 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, BATCH_OPLOCK_RETURN
);
1553 sfi
.generic
.level
= SMB_SFILEINFO_ALLOCATION_INFORMATION
;
1554 sfi
.generic
.in
.file
.path
= fname
;
1555 sfi
.allocation_info
.in
.alloc_size
= 65536 * 8;
1557 status
= smb_raw_setpathinfo(cli2
->tree
, &sfi
);
1559 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
1560 CHECK_VAL(break_info
.count
, 1);
1561 CHECK_VAL(break_info
.failures
, 0);
1562 CHECK_VAL(break_info
.level
, 0);
1564 smbcli_close(cli1
->tree
, fnum
);
1567 smb_raw_exit(cli1
->session
);
1568 smb_raw_exit(cli2
->session
);
1569 smbcli_deltree(cli1
->tree
, BASEDIR
);
1573 static bool test_raw_oplock_batch13(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
1575 const char *fname
= BASEDIR
"\\test_batch13.dat";
1579 uint16_t fnum
=0, fnum2
=0;
1581 if (!torture_setup_dir(cli1
, BASEDIR
)) {
1586 smbcli_unlink(cli1
->tree
, fname
);
1588 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
1589 smbcli_oplock_handler(cli2
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
1592 base ntcreatex parms
1594 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
1595 io
.ntcreatex
.in
.root_fid
= 0;
1596 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
1597 io
.ntcreatex
.in
.alloc_size
= 0;
1598 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
1599 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
1600 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
1601 io
.ntcreatex
.in
.create_options
= 0;
1602 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
1603 io
.ntcreatex
.in
.security_flags
= 0;
1604 io
.ntcreatex
.in
.fname
= fname
;
1606 torture_comment(tctx
, "BATCH13: open with batch oplock\n");
1607 ZERO_STRUCT(break_info
);
1608 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
1611 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
1612 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
1613 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
1614 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
|
1615 NTCREATEX_SHARE_ACCESS_WRITE
|
1616 NTCREATEX_SHARE_ACCESS_DELETE
;
1617 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
1618 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
1619 fnum
= io
.ntcreatex
.out
.file
.fnum
;
1620 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, BATCH_OPLOCK_RETURN
);
1622 ZERO_STRUCT(break_info
);
1624 torture_comment(tctx
, "second open with attributes only and NTCREATEX_DISP_OVERWRITE dispostion causes oplock break\n");
1626 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
1627 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
1628 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
1629 io
.ntcreatex
.in
.access_mask
= SEC_FILE_READ_ATTRIBUTE
|SEC_FILE_WRITE_ATTRIBUTE
|SEC_STD_SYNCHRONIZE
;
1630 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
|
1631 NTCREATEX_SHARE_ACCESS_WRITE
|
1632 NTCREATEX_SHARE_ACCESS_DELETE
;
1633 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OVERWRITE
;
1634 status
= smb_raw_open(cli2
->tree
, tctx
, &io
);
1635 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
1636 fnum2
= io
.ntcreatex
.out
.file
.fnum
;
1637 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, LEVEL_II_OPLOCK_RETURN
);
1638 CHECK_VAL(break_info
.count
, 1);
1639 CHECK_VAL(break_info
.failures
, 0);
1641 smbcli_close(cli1
->tree
, fnum
);
1642 smbcli_close(cli2
->tree
, fnum2
);
1645 smb_raw_exit(cli1
->session
);
1646 smb_raw_exit(cli2
->session
);
1647 smbcli_deltree(cli1
->tree
, BASEDIR
);
1651 static bool test_raw_oplock_batch14(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
1653 const char *fname
= BASEDIR
"\\test_batch14.dat";
1657 uint16_t fnum
=0, fnum2
=0;
1659 if (!torture_setup_dir(cli1
, BASEDIR
)) {
1664 smbcli_unlink(cli1
->tree
, fname
);
1666 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
1669 base ntcreatex parms
1671 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
1672 io
.ntcreatex
.in
.root_fid
= 0;
1673 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
1674 io
.ntcreatex
.in
.alloc_size
= 0;
1675 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
1676 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
1677 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
1678 io
.ntcreatex
.in
.create_options
= 0;
1679 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
1680 io
.ntcreatex
.in
.security_flags
= 0;
1681 io
.ntcreatex
.in
.fname
= fname
;
1683 torture_comment(tctx
, "BATCH14: open with batch oplock\n");
1684 ZERO_STRUCT(break_info
);
1685 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
1687 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
1688 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
1689 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
1690 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
|
1691 NTCREATEX_SHARE_ACCESS_WRITE
|
1692 NTCREATEX_SHARE_ACCESS_DELETE
;
1693 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
1694 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
1695 fnum
= io
.ntcreatex
.out
.file
.fnum
;
1696 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, BATCH_OPLOCK_RETURN
);
1698 ZERO_STRUCT(break_info
);
1700 torture_comment(tctx
, "second open with attributes only and NTCREATEX_DISP_SUPERSEDE dispostion causes oplock break\n");
1702 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
1703 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
1704 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
1705 io
.ntcreatex
.in
.access_mask
= SEC_FILE_READ_ATTRIBUTE
|SEC_FILE_WRITE_ATTRIBUTE
|SEC_STD_SYNCHRONIZE
;
1706 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
|
1707 NTCREATEX_SHARE_ACCESS_WRITE
|
1708 NTCREATEX_SHARE_ACCESS_DELETE
;
1709 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OVERWRITE
;
1710 status
= smb_raw_open(cli2
->tree
, tctx
, &io
);
1711 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
1712 fnum2
= io
.ntcreatex
.out
.file
.fnum
;
1713 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, LEVEL_II_OPLOCK_RETURN
);
1714 CHECK_VAL(break_info
.count
, 1);
1715 CHECK_VAL(break_info
.failures
, 0);
1717 smbcli_close(cli1
->tree
, fnum
);
1718 smbcli_close(cli2
->tree
, fnum2
);
1720 smb_raw_exit(cli1
->session
);
1721 smb_raw_exit(cli2
->session
);
1722 smbcli_deltree(cli1
->tree
, BASEDIR
);
1726 static bool test_raw_oplock_batch15(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
1728 const char *fname
= BASEDIR
"\\test_batch15.dat";
1732 union smb_fileinfo qfi
;
1735 if (!torture_setup_dir(cli1
, BASEDIR
)) {
1740 smbcli_unlink(cli1
->tree
, fname
);
1742 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
1745 base ntcreatex parms
1747 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
1748 io
.ntcreatex
.in
.root_fid
= 0;
1749 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
1750 io
.ntcreatex
.in
.alloc_size
= 0;
1751 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
1752 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
1753 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
1754 io
.ntcreatex
.in
.create_options
= 0;
1755 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
1756 io
.ntcreatex
.in
.security_flags
= 0;
1757 io
.ntcreatex
.in
.fname
= fname
;
1759 /* Test if a qpathinfo all info on pathname breaks a batch oplock. */
1760 torture_comment(tctx
, "BATCH15: Test if qpathinfo all info breaks a batch oplock (should not).\n");
1762 ZERO_STRUCT(break_info
);
1763 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
1765 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
1766 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
1767 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
1768 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
1769 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
|
1770 NTCREATEX_SHARE_ACCESS_WRITE
|
1771 NTCREATEX_SHARE_ACCESS_DELETE
;
1772 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
1773 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_CREATE
;
1774 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
1775 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
1776 fnum
= io
.ntcreatex
.out
.file
.fnum
;
1777 CHECK_VAL(break_info
.count
, 0);
1778 CHECK_VAL(break_info
.failures
, 0);
1779 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, BATCH_OPLOCK_RETURN
);
1782 qfi
.generic
.level
= RAW_FILEINFO_ALL_INFORMATION
;
1783 qfi
.generic
.in
.file
.path
= fname
;
1785 status
= smb_raw_pathinfo(cli2
->tree
, tctx
, &qfi
);
1787 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
1788 CHECK_VAL(break_info
.count
, 0);
1790 smbcli_close(cli1
->tree
, fnum
);
1793 smb_raw_exit(cli1
->session
);
1794 smb_raw_exit(cli2
->session
);
1795 smbcli_deltree(cli1
->tree
, BASEDIR
);
1799 static bool test_raw_oplock_batch16(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
1801 const char *fname
= BASEDIR
"\\test_batch16.dat";
1805 uint16_t fnum
=0, fnum2
=0;
1807 if (!torture_setup_dir(cli1
, BASEDIR
)) {
1812 smbcli_unlink(cli1
->tree
, fname
);
1814 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
1815 smbcli_oplock_handler(cli2
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
1818 base ntcreatex parms
1820 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
1821 io
.ntcreatex
.in
.root_fid
= 0;
1822 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
1823 io
.ntcreatex
.in
.alloc_size
= 0;
1824 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
1825 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
1826 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
1827 io
.ntcreatex
.in
.create_options
= 0;
1828 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
1829 io
.ntcreatex
.in
.security_flags
= 0;
1830 io
.ntcreatex
.in
.fname
= fname
;
1832 torture_comment(tctx
, "BATCH16: open with batch oplock\n");
1833 ZERO_STRUCT(break_info
);
1834 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
1837 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
1838 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
1839 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
1840 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
|
1841 NTCREATEX_SHARE_ACCESS_WRITE
|
1842 NTCREATEX_SHARE_ACCESS_DELETE
;
1843 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
1844 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
1845 fnum
= io
.ntcreatex
.out
.file
.fnum
;
1846 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, BATCH_OPLOCK_RETURN
);
1848 ZERO_STRUCT(break_info
);
1850 torture_comment(tctx
, "second open with attributes only and NTCREATEX_DISP_OVERWRITE_IF dispostion causes oplock break\n");
1852 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
1853 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
1854 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
1855 io
.ntcreatex
.in
.access_mask
= SEC_FILE_READ_ATTRIBUTE
|SEC_FILE_WRITE_ATTRIBUTE
|SEC_STD_SYNCHRONIZE
;
1856 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
|
1857 NTCREATEX_SHARE_ACCESS_WRITE
|
1858 NTCREATEX_SHARE_ACCESS_DELETE
;
1859 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OVERWRITE_IF
;
1860 status
= smb_raw_open(cli2
->tree
, tctx
, &io
);
1861 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
1862 fnum2
= io
.ntcreatex
.out
.file
.fnum
;
1863 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, LEVEL_II_OPLOCK_RETURN
);
1864 CHECK_VAL(break_info
.count
, 1);
1865 CHECK_VAL(break_info
.failures
, 0);
1867 smbcli_close(cli1
->tree
, fnum
);
1868 smbcli_close(cli2
->tree
, fnum2
);
1871 smb_raw_exit(cli1
->session
);
1872 smb_raw_exit(cli2
->session
);
1873 smbcli_deltree(cli1
->tree
, BASEDIR
);
1877 static bool test_raw_oplock_batch17(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
1879 const char *fname1
= BASEDIR
"\\test_batch17_1.dat";
1880 const char *fname2
= BASEDIR
"\\test_batch17_2.dat";
1884 union smb_rename rn
;
1887 if (!torture_setup_dir(cli1
, BASEDIR
)) {
1892 smbcli_unlink(cli1
->tree
, fname1
);
1893 smbcli_unlink(cli1
->tree
, fname2
);
1895 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
1898 base ntcreatex parms
1900 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
1901 io
.ntcreatex
.in
.root_fid
= 0;
1902 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
1903 io
.ntcreatex
.in
.alloc_size
= 0;
1904 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
1905 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
1906 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
1907 io
.ntcreatex
.in
.create_options
= 0;
1908 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
1909 io
.ntcreatex
.in
.security_flags
= 0;
1910 io
.ntcreatex
.in
.fname
= fname1
;
1912 torture_comment(tctx
, "BATCH17: open a file with an batch oplock (share mode: none)\n");
1914 ZERO_STRUCT(break_info
);
1915 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
1916 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
1917 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
1919 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
1920 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
1921 fnum
= io
.ntcreatex
.out
.file
.fnum
;
1922 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, BATCH_OPLOCK_RETURN
);
1924 torture_comment(tctx
, "rename should trigger a break\n");
1926 rn
.generic
.level
= RAW_RENAME_RENAME
;
1927 rn
.rename
.in
.pattern1
= fname1
;
1928 rn
.rename
.in
.pattern2
= fname2
;
1929 rn
.rename
.in
.attrib
= 0;
1931 torture_comment(tctx
, "trying rename while first file open\n");
1932 status
= smb_raw_rename(cli2
->tree
, &rn
);
1934 CHECK_STATUS(tctx
, status
, NT_STATUS_SHARING_VIOLATION
);
1935 CHECK_VAL(break_info
.count
, 1);
1936 CHECK_VAL(break_info
.failures
, 0);
1937 CHECK_VAL(break_info
.level
, OPLOCK_BREAK_TO_LEVEL_II
);
1939 smbcli_close(cli1
->tree
, fnum
);
1942 smb_raw_exit(cli1
->session
);
1943 smb_raw_exit(cli2
->session
);
1944 smbcli_deltree(cli1
->tree
, BASEDIR
);
1948 static bool test_raw_oplock_batch18(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
1950 const char *fname1
= BASEDIR
"\\test_batch18_1.dat";
1951 const char *fname2
= BASEDIR
"\\test_batch18_2.dat";
1955 union smb_rename rn
;
1958 if (!torture_setup_dir(cli1
, BASEDIR
)) {
1963 smbcli_unlink(cli1
->tree
, fname1
);
1964 smbcli_unlink(cli1
->tree
, fname2
);
1966 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
1969 base ntcreatex parms
1971 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
1972 io
.ntcreatex
.in
.root_fid
= 0;
1973 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
1974 io
.ntcreatex
.in
.alloc_size
= 0;
1975 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
1976 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
1977 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
1978 io
.ntcreatex
.in
.create_options
= 0;
1979 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
1980 io
.ntcreatex
.in
.security_flags
= 0;
1981 io
.ntcreatex
.in
.fname
= fname1
;
1983 torture_comment(tctx
, "BATCH18: open a file with an batch oplock (share mode: none)\n");
1985 ZERO_STRUCT(break_info
);
1986 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
1987 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
1988 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
1990 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
1991 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
1992 fnum
= io
.ntcreatex
.out
.file
.fnum
;
1993 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, BATCH_OPLOCK_RETURN
);
1995 torture_comment(tctx
, "ntrename should trigger a break\n");
1997 rn
.generic
.level
= RAW_RENAME_NTRENAME
;
1998 rn
.ntrename
.in
.attrib
= 0;
1999 rn
.ntrename
.in
.flags
= RENAME_FLAG_RENAME
;
2000 rn
.ntrename
.in
.old_name
= fname1
;
2001 rn
.ntrename
.in
.new_name
= fname2
;
2002 torture_comment(tctx
, "trying rename while first file open\n");
2003 status
= smb_raw_rename(cli2
->tree
, &rn
);
2005 CHECK_STATUS(tctx
, status
, NT_STATUS_SHARING_VIOLATION
);
2006 CHECK_VAL(break_info
.count
, 1);
2007 CHECK_VAL(break_info
.failures
, 0);
2008 CHECK_VAL(break_info
.level
, OPLOCK_BREAK_TO_LEVEL_II
);
2010 smbcli_close(cli1
->tree
, fnum
);
2013 smb_raw_exit(cli1
->session
);
2014 smb_raw_exit(cli2
->session
);
2015 smbcli_deltree(cli1
->tree
, BASEDIR
);
2019 static bool test_raw_oplock_batch19(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
2021 const char *fname1
= BASEDIR
"\\test_batch19_1.dat";
2022 const char *fname2
= BASEDIR
"\\test_batch19_2.dat";
2023 const char *fname3
= BASEDIR
"\\test_batch19_3.dat";
2027 union smb_fileinfo qfi
;
2028 union smb_setfileinfo sfi
;
2031 if (!torture_setup_dir(cli1
, BASEDIR
)) {
2036 smbcli_unlink(cli1
->tree
, fname1
);
2037 smbcli_unlink(cli1
->tree
, fname2
);
2038 smbcli_unlink(cli1
->tree
, fname3
);
2040 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
2043 base ntcreatex parms
2045 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
2046 io
.ntcreatex
.in
.root_fid
= 0;
2047 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
2048 io
.ntcreatex
.in
.alloc_size
= 0;
2049 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
2050 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
2051 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
2052 io
.ntcreatex
.in
.create_options
= 0;
2053 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
2054 io
.ntcreatex
.in
.security_flags
= 0;
2055 io
.ntcreatex
.in
.fname
= fname1
;
2057 torture_comment(tctx
, "BATCH19: open a file with an batch oplock (share mode: none)\n");
2058 ZERO_STRUCT(break_info
);
2059 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
2060 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
2061 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
2062 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
2063 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
2064 fnum
= io
.ntcreatex
.out
.file
.fnum
;
2065 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, BATCH_OPLOCK_RETURN
);
2067 torture_comment(tctx
, "setpathinfo rename info should not trigger a break nor a violation\n");
2069 sfi
.generic
.level
= RAW_SFILEINFO_RENAME_INFORMATION
;
2070 sfi
.generic
.in
.file
.path
= fname1
;
2071 sfi
.rename_information
.in
.overwrite
= 0;
2072 sfi
.rename_information
.in
.root_fid
= 0;
2073 sfi
.rename_information
.in
.new_name
= fname2
+strlen(BASEDIR
)+1;
2075 status
= smb_raw_setpathinfo(cli2
->tree
, &sfi
);
2077 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
2078 CHECK_VAL(break_info
.count
, 0);
2081 qfi
.generic
.level
= RAW_FILEINFO_ALL_INFORMATION
;
2082 qfi
.generic
.in
.file
.fnum
= fnum
;
2084 status
= smb_raw_fileinfo(cli1
->tree
, tctx
, &qfi
);
2085 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
2086 CHECK_STRMATCH(qfi
.all_info
.out
.fname
.s
, fname2
);
2088 torture_comment(tctx
, "setfileinfo rename info should not trigger a break nor a violation\n");
2090 sfi
.generic
.level
= RAW_SFILEINFO_RENAME_INFORMATION
;
2091 sfi
.generic
.in
.file
.fnum
= fnum
;
2092 sfi
.rename_information
.in
.overwrite
= 0;
2093 sfi
.rename_information
.in
.root_fid
= 0;
2094 sfi
.rename_information
.in
.new_name
= fname3
+strlen(BASEDIR
)+1;
2096 status
= smb_raw_setfileinfo(cli1
->tree
, &sfi
);
2097 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
2098 CHECK_VAL(break_info
.count
, 0);
2101 qfi
.generic
.level
= RAW_FILEINFO_ALL_INFORMATION
;
2102 qfi
.generic
.in
.file
.fnum
= fnum
;
2104 status
= smb_raw_fileinfo(cli1
->tree
, tctx
, &qfi
);
2105 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
2106 CHECK_STRMATCH(qfi
.all_info
.out
.fname
.s
, fname3
);
2108 smbcli_close(cli1
->tree
, fnum
);
2111 smb_raw_exit(cli1
->session
);
2112 smb_raw_exit(cli2
->session
);
2113 smbcli_deltree(cli1
->tree
, BASEDIR
);
2117 /****************************************************
2118 Called from raw-rename - we need oplock handling for
2119 this test so this is why it's in oplock.c, not rename.c
2120 ****************************************************/
2122 bool test_trans2rename(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
2124 const char *fname1
= BASEDIR
"\\test_trans2rename_1.dat";
2125 const char *fname2
= BASEDIR
"\\test_trans2rename_2.dat";
2126 const char *fname3
= BASEDIR
"\\test_trans2rename_3.dat";
2130 union smb_fileinfo qfi
;
2131 union smb_setfileinfo sfi
;
2134 if (!torture_setup_dir(cli1
, BASEDIR
)) {
2139 smbcli_unlink(cli1
->tree
, fname1
);
2140 smbcli_unlink(cli1
->tree
, fname2
);
2141 smbcli_unlink(cli1
->tree
, fname3
);
2143 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
2146 base ntcreatex parms
2148 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
2149 io
.ntcreatex
.in
.root_fid
= 0;
2150 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
2151 io
.ntcreatex
.in
.alloc_size
= 0;
2152 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
2153 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
2154 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
2155 io
.ntcreatex
.in
.create_options
= 0;
2156 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
2157 io
.ntcreatex
.in
.security_flags
= 0;
2158 io
.ntcreatex
.in
.fname
= fname1
;
2160 torture_comment(tctx
, "open a file with an exclusive oplock (share mode: none)\n");
2161 ZERO_STRUCT(break_info
);
2162 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
2163 NTCREATEX_FLAGS_REQUEST_OPLOCK
;
2164 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
2165 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
2166 fnum
= io
.ntcreatex
.out
.file
.fnum
;
2167 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, EXCLUSIVE_OPLOCK_RETURN
);
2169 torture_comment(tctx
, "setpathinfo rename info should not trigger a break nor a violation\n");
2171 sfi
.generic
.level
= RAW_SFILEINFO_RENAME_INFORMATION
;
2172 sfi
.generic
.in
.file
.path
= fname1
;
2173 sfi
.rename_information
.in
.overwrite
= 0;
2174 sfi
.rename_information
.in
.root_fid
= 0;
2175 sfi
.rename_information
.in
.new_name
= fname2
+strlen(BASEDIR
)+1;
2177 status
= smb_raw_setpathinfo(cli2
->tree
, &sfi
);
2179 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
2180 CHECK_VAL(break_info
.count
, 0);
2183 qfi
.generic
.level
= RAW_FILEINFO_ALL_INFORMATION
;
2184 qfi
.generic
.in
.file
.fnum
= fnum
;
2186 status
= smb_raw_fileinfo(cli1
->tree
, tctx
, &qfi
);
2187 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
2188 CHECK_STRMATCH(qfi
.all_info
.out
.fname
.s
, fname2
);
2190 torture_comment(tctx
, "setfileinfo rename info should not trigger a break nor a violation\n");
2192 sfi
.generic
.level
= RAW_SFILEINFO_RENAME_INFORMATION
;
2193 sfi
.generic
.in
.file
.fnum
= fnum
;
2194 sfi
.rename_information
.in
.overwrite
= 0;
2195 sfi
.rename_information
.in
.root_fid
= 0;
2196 sfi
.rename_information
.in
.new_name
= fname3
+strlen(BASEDIR
)+1;
2198 status
= smb_raw_setfileinfo(cli1
->tree
, &sfi
);
2199 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
2200 CHECK_VAL(break_info
.count
, 0);
2203 qfi
.generic
.level
= RAW_FILEINFO_ALL_INFORMATION
;
2204 qfi
.generic
.in
.file
.fnum
= fnum
;
2206 status
= smb_raw_fileinfo(cli1
->tree
, tctx
, &qfi
);
2207 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
2208 CHECK_STRMATCH(qfi
.all_info
.out
.fname
.s
, fname3
);
2210 smbcli_close(cli1
->tree
, fnum
);
2213 smb_raw_exit(cli1
->session
);
2214 smb_raw_exit(cli2
->session
);
2215 smbcli_deltree(cli1
->tree
, BASEDIR
);
2219 /****************************************************
2220 Called from raw-rename - we need oplock handling for
2221 this test so this is why it's in oplock.c, not rename.c
2222 ****************************************************/
2224 bool test_nttransrename(struct torture_context
*tctx
, struct smbcli_state
*cli1
)
2226 const char *fname1
= BASEDIR
"\\test_nttransrename_1.dat";
2227 const char *fname2
= BASEDIR
"\\test_nttransrename_2.dat";
2231 union smb_fileinfo qfi
, qpi
;
2232 union smb_rename rn
;
2235 if (!torture_setup_dir(cli1
, BASEDIR
)) {
2240 smbcli_unlink(cli1
->tree
, fname1
);
2241 smbcli_unlink(cli1
->tree
, fname2
);
2243 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
2246 base ntcreatex parms
2248 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
2249 io
.ntcreatex
.in
.root_fid
= 0;
2250 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
2251 io
.ntcreatex
.in
.alloc_size
= 0;
2252 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
2253 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
2254 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
2255 io
.ntcreatex
.in
.create_options
= 0;
2256 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
2257 io
.ntcreatex
.in
.security_flags
= 0;
2258 io
.ntcreatex
.in
.fname
= fname1
;
2260 torture_comment(tctx
, "nttrans_rename: open a file with an exclusive oplock (share mode: none)\n");
2261 ZERO_STRUCT(break_info
);
2262 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
2263 NTCREATEX_FLAGS_REQUEST_OPLOCK
;
2264 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
2265 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
2266 fnum
= io
.ntcreatex
.out
.file
.fnum
;
2267 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, EXCLUSIVE_OPLOCK_RETURN
);
2269 torture_comment(tctx
, "nttrans_rename: should not trigger a break nor a share mode violation\n");
2271 rn
.generic
.level
= RAW_RENAME_NTTRANS
;
2272 rn
.nttrans
.in
.file
.fnum
= fnum
;
2273 rn
.nttrans
.in
.flags
= 0;
2274 rn
.nttrans
.in
.new_name
= fname2
+strlen(BASEDIR
)+1;
2276 status
= smb_raw_rename(cli1
->tree
, &rn
);
2278 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
2279 CHECK_VAL(break_info
.count
, 0);
2281 /* w2k3 does nothing, it doesn't rename the file */
2282 torture_comment(tctx
, "nttrans_rename: the server should have done nothing\n");
2284 qfi
.generic
.level
= RAW_FILEINFO_ALL_INFORMATION
;
2285 qfi
.generic
.in
.file
.fnum
= fnum
;
2287 status
= smb_raw_fileinfo(cli1
->tree
, tctx
, &qfi
);
2288 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
2289 CHECK_STRMATCH(qfi
.all_info
.out
.fname
.s
, fname1
);
2292 qpi
.generic
.level
= RAW_FILEINFO_ALL_INFORMATION
;
2293 qpi
.generic
.in
.file
.path
= fname1
;
2295 status
= smb_raw_pathinfo(cli1
->tree
, tctx
, &qpi
);
2296 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
2297 CHECK_STRMATCH(qpi
.all_info
.out
.fname
.s
, fname1
);
2300 qpi
.generic
.level
= RAW_FILEINFO_ALL_INFORMATION
;
2301 qpi
.generic
.in
.file
.path
= fname2
;
2303 status
= smb_raw_pathinfo(cli1
->tree
, tctx
, &qpi
);
2304 CHECK_STATUS(tctx
, status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
);
2306 torture_comment(tctx
, "nttrans_rename: after closing the file the file is still not renamed\n");
2307 status
= smbcli_close(cli1
->tree
, fnum
);
2308 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
2311 qpi
.generic
.level
= RAW_FILEINFO_ALL_INFORMATION
;
2312 qpi
.generic
.in
.file
.path
= fname1
;
2314 status
= smb_raw_pathinfo(cli1
->tree
, tctx
, &qpi
);
2315 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
2316 CHECK_STRMATCH(qpi
.all_info
.out
.fname
.s
, fname1
);
2319 qpi
.generic
.level
= RAW_FILEINFO_ALL_INFORMATION
;
2320 qpi
.generic
.in
.file
.path
= fname2
;
2322 status
= smb_raw_pathinfo(cli1
->tree
, tctx
, &qpi
);
2323 CHECK_STATUS(tctx
, status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
);
2325 torture_comment(tctx
, "nttrans_rename: rename with an invalid handle gives NT_STATUS_INVALID_HANDLE\n");
2327 rn
.generic
.level
= RAW_RENAME_NTTRANS
;
2328 rn
.nttrans
.in
.file
.fnum
= fnum
+1;
2329 rn
.nttrans
.in
.flags
= 0;
2330 rn
.nttrans
.in
.new_name
= fname2
+strlen(BASEDIR
)+1;
2332 status
= smb_raw_rename(cli1
->tree
, &rn
);
2334 CHECK_STATUS(tctx
, status
, NT_STATUS_INVALID_HANDLE
);
2337 smb_raw_exit(cli1
->session
);
2338 smbcli_deltree(cli1
->tree
, BASEDIR
);
2343 static bool test_raw_oplock_batch20(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
2345 const char *fname1
= BASEDIR
"\\test_batch20_1.dat";
2346 const char *fname2
= BASEDIR
"\\test_batch20_2.dat";
2347 const char *fname3
= BASEDIR
"\\test_batch20_3.dat";
2351 union smb_fileinfo qfi
;
2352 union smb_setfileinfo sfi
;
2353 uint16_t fnum
=0,fnum2
=0;
2355 if (!torture_setup_dir(cli1
, BASEDIR
)) {
2360 smbcli_unlink(cli1
->tree
, fname1
);
2361 smbcli_unlink(cli1
->tree
, fname2
);
2362 smbcli_unlink(cli1
->tree
, fname3
);
2364 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
2367 base ntcreatex parms
2369 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
2370 io
.ntcreatex
.in
.root_fid
= 0;
2371 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
2372 io
.ntcreatex
.in
.alloc_size
= 0;
2373 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
2374 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
2375 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
2376 io
.ntcreatex
.in
.create_options
= 0;
2377 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
2378 io
.ntcreatex
.in
.security_flags
= 0;
2379 io
.ntcreatex
.in
.fname
= fname1
;
2381 torture_comment(tctx
, "BATCH20: open a file with an batch oplock (share mode: all)\n");
2382 ZERO_STRUCT(break_info
);
2383 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
2384 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
2385 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
2386 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
|
2387 NTCREATEX_SHARE_ACCESS_WRITE
|
2388 NTCREATEX_SHARE_ACCESS_DELETE
;
2389 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
2390 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
2391 fnum
= io
.ntcreatex
.out
.file
.fnum
;
2392 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, BATCH_OPLOCK_RETURN
);
2394 torture_comment(tctx
, "setpathinfo rename info should not trigger a break nor a violation\n");
2396 sfi
.generic
.level
= RAW_SFILEINFO_RENAME_INFORMATION
;
2397 sfi
.generic
.in
.file
.path
= fname1
;
2398 sfi
.rename_information
.in
.overwrite
= 0;
2399 sfi
.rename_information
.in
.root_fid
= 0;
2400 sfi
.rename_information
.in
.new_name
= fname2
+strlen(BASEDIR
)+1;
2402 status
= smb_raw_setpathinfo(cli2
->tree
, &sfi
);
2404 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
2405 CHECK_VAL(break_info
.count
, 0);
2408 qfi
.generic
.level
= RAW_FILEINFO_ALL_INFORMATION
;
2409 qfi
.generic
.in
.file
.fnum
= fnum
;
2411 status
= smb_raw_fileinfo(cli1
->tree
, tctx
, &qfi
);
2412 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
2413 CHECK_STRMATCH(qfi
.all_info
.out
.fname
.s
, fname2
);
2415 torture_comment(tctx
, "open a file with the new name an batch oplock (share mode: all)\n");
2416 ZERO_STRUCT(break_info
);
2417 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
2418 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
2419 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
2420 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
|
2421 NTCREATEX_SHARE_ACCESS_WRITE
|
2422 NTCREATEX_SHARE_ACCESS_DELETE
;
2423 io
.ntcreatex
.in
.fname
= fname2
;
2424 status
= smb_raw_open(cli2
->tree
, tctx
, &io
);
2425 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
2426 fnum2
= io
.ntcreatex
.out
.file
.fnum
;
2427 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, LEVEL_II_OPLOCK_RETURN
);
2428 CHECK_VAL(break_info
.count
, 1);
2429 CHECK_VAL(break_info
.failures
, 0);
2430 CHECK_VAL(break_info
.level
, OPLOCK_BREAK_TO_LEVEL_II
);
2432 torture_comment(tctx
, "setfileinfo rename info should not trigger a break nor a violation\n");
2434 sfi
.generic
.level
= RAW_SFILEINFO_RENAME_INFORMATION
;
2435 sfi
.generic
.in
.file
.fnum
= fnum
;
2436 sfi
.rename_information
.in
.overwrite
= 0;
2437 sfi
.rename_information
.in
.root_fid
= 0;
2438 sfi
.rename_information
.in
.new_name
= fname3
+strlen(BASEDIR
)+1;
2440 status
= smb_raw_setfileinfo(cli1
->tree
, &sfi
);
2441 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
2442 CHECK_VAL(break_info
.count
, 1);
2443 CHECK_VAL(break_info
.failures
, 0);
2444 CHECK_VAL(break_info
.level
, OPLOCK_BREAK_TO_LEVEL_II
);
2447 qfi
.generic
.level
= RAW_FILEINFO_ALL_INFORMATION
;
2448 qfi
.generic
.in
.file
.fnum
= fnum
;
2450 status
= smb_raw_fileinfo(cli1
->tree
, tctx
, &qfi
);
2451 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
2452 CHECK_STRMATCH(qfi
.all_info
.out
.fname
.s
, fname3
);
2455 qfi
.generic
.level
= RAW_FILEINFO_ALL_INFORMATION
;
2456 qfi
.generic
.in
.file
.fnum
= fnum2
;
2458 status
= smb_raw_fileinfo(cli2
->tree
, tctx
, &qfi
);
2459 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
2460 CHECK_STRMATCH(qfi
.all_info
.out
.fname
.s
, fname3
);
2462 smbcli_close(cli1
->tree
, fnum
);
2465 smb_raw_exit(cli1
->session
);
2466 smb_raw_exit(cli2
->session
);
2467 smbcli_deltree(cli1
->tree
, BASEDIR
);
2471 static bool test_raw_oplock_batch21(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
2473 const char *fname
= BASEDIR
"\\test_batch21.dat";
2482 if (!torture_setup_dir(cli1
, BASEDIR
)) {
2487 smbcli_unlink(cli1
->tree
, fname
);
2489 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
2492 base ntcreatex parms
2494 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
2495 io
.ntcreatex
.in
.root_fid
= 0;
2496 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
2497 io
.ntcreatex
.in
.alloc_size
= 0;
2498 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
2499 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
2500 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
2501 io
.ntcreatex
.in
.create_options
= 0;
2502 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
2503 io
.ntcreatex
.in
.security_flags
= 0;
2504 io
.ntcreatex
.in
.fname
= fname
;
2507 with a batch oplock we get a break
2509 torture_comment(tctx
, "BATCH21: open with batch oplock\n");
2510 ZERO_STRUCT(break_info
);
2511 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
2512 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
2513 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
2514 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
2515 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
2516 fnum
= io
.ntcreatex
.out
.file
.fnum
;
2517 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, BATCH_OPLOCK_RETURN
);
2519 torture_comment(tctx
, "writing should not generate a break\n");
2520 wr
= smbcli_write(cli1
->tree
, fnum
, 0, &c
, 0, 1);
2522 CHECK_STATUS(tctx
, smbcli_nt_error(cli1
->tree
), NT_STATUS_OK
);
2525 e
.in
.repeat_count
= 1;
2526 status
= smb_raw_echo(cli1
->transport
, &e
);
2527 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
2529 CHECK_VAL(break_info
.count
, 0);
2531 smbcli_close(cli1
->tree
, fnum
);
2534 smb_raw_exit(cli1
->session
);
2535 smb_raw_exit(cli2
->session
);
2536 smbcli_deltree(cli1
->tree
, BASEDIR
);
2540 static bool test_raw_oplock_batch22(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
2542 const char *fname
= BASEDIR
"\\test_batch22.dat";
2546 uint16_t fnum
=0, fnum2
=0;
2548 int timeout
= torture_setting_int(tctx
, "oplocktimeout", 30);
2551 if (torture_setting_bool(tctx
, "samba3", false)) {
2552 torture_skip(tctx
, "BATCH22 disabled against samba3\n");
2555 if (!torture_setup_dir(cli1
, BASEDIR
)) {
2560 smbcli_unlink(cli1
->tree
, fname
);
2562 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
2565 base ntcreatex parms
2567 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
2568 io
.ntcreatex
.in
.root_fid
= 0;
2569 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
2570 io
.ntcreatex
.in
.alloc_size
= 0;
2571 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
2572 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
2573 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
2574 io
.ntcreatex
.in
.create_options
= 0;
2575 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
2576 io
.ntcreatex
.in
.security_flags
= 0;
2577 io
.ntcreatex
.in
.fname
= fname
;
2580 with a batch oplock we get a break
2582 torture_comment(tctx
, "BATCH22: open with batch oplock\n");
2583 ZERO_STRUCT(break_info
);
2584 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
2585 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
2586 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
2587 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
|
2588 NTCREATEX_SHARE_ACCESS_WRITE
|
2589 NTCREATEX_SHARE_ACCESS_DELETE
;
2590 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
2591 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
2592 fnum
= io
.ntcreatex
.out
.file
.fnum
;
2593 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, BATCH_OPLOCK_RETURN
);
2595 torture_comment(tctx
, "a 2nd open shoud not succeed after the oplock break timeout\n");
2596 tv
= timeval_current();
2597 smbcli_oplock_handler(cli1
->transport
, oplock_handler_timeout
, cli1
->tree
);
2598 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
2599 CHECK_STATUS(tctx
, status
, NT_STATUS_SHARING_VIOLATION
);
2600 te
= (int)timeval_elapsed(&tv
);
2601 CHECK_RANGE(te
, timeout
- 1, timeout
+ 15);
2603 CHECK_VAL(break_info
.count
, 1);
2604 CHECK_VAL(break_info
.fnum
, fnum
);
2605 CHECK_VAL(break_info
.level
, OPLOCK_BREAK_TO_LEVEL_II
);
2606 CHECK_VAL(break_info
.failures
, 0);
2607 ZERO_STRUCT(break_info
);
2609 torture_comment(tctx
, "a 2nd open shoud succeed after the oplock release without break\n");
2610 tv
= timeval_current();
2611 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
2612 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
2613 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
2614 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, LEVEL_II_OPLOCK_RETURN
);
2615 te
= (int)timeval_elapsed(&tv
);
2616 /* it should come in without delay */
2617 CHECK_RANGE(te
+1, 0, timeout
);
2618 fnum2
= io
.ntcreatex
.out
.file
.fnum
;
2620 CHECK_VAL(break_info
.count
, 0);
2622 smbcli_close(cli1
->tree
, fnum
);
2623 smbcli_close(cli1
->tree
, fnum2
);
2626 smb_raw_exit(cli1
->session
);
2627 smb_raw_exit(cli2
->session
);
2628 smbcli_deltree(cli1
->tree
, BASEDIR
);
2632 static bool test_raw_oplock_batch23(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
2634 const char *fname
= BASEDIR
"\\test_batch23.dat";
2638 uint16_t fnum
=0, fnum2
=0,fnum3
=0;
2639 struct smbcli_state
*cli3
= NULL
;
2641 if (!torture_setup_dir(cli1
, BASEDIR
)) {
2646 smbcli_unlink(cli1
->tree
, fname
);
2648 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
2650 ret
= open_connection_no_level2_oplocks(tctx
, &cli3
);
2651 CHECK_VAL(ret
, true);
2654 base ntcreatex parms
2656 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
2657 io
.ntcreatex
.in
.root_fid
= 0;
2658 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
2659 io
.ntcreatex
.in
.alloc_size
= 0;
2660 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
2661 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
2662 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
2663 io
.ntcreatex
.in
.create_options
= 0;
2664 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
2665 io
.ntcreatex
.in
.security_flags
= 0;
2666 io
.ntcreatex
.in
.fname
= fname
;
2668 torture_comment(tctx
, "BATCH23: a open and ask for a batch oplock\n");
2669 ZERO_STRUCT(break_info
);
2670 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
2671 smbcli_oplock_handler(cli2
->transport
, oplock_handler_ack_to_given
, cli2
->tree
);
2672 smbcli_oplock_handler(cli3
->transport
, oplock_handler_ack_to_given
, cli3
->tree
);
2674 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_READ
| SEC_RIGHTS_FILE_WRITE
;
2675 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
| NTCREATEX_SHARE_ACCESS_WRITE
;
2676 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
2677 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
2678 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
2679 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
2680 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
2681 fnum
= io
.ntcreatex
.out
.file
.fnum
;
2682 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, BATCH_OPLOCK_RETURN
);
2684 ZERO_STRUCT(break_info
);
2686 torture_comment(tctx
, "a 2nd open without level2 oplock support should generate a break to level2\n");
2687 status
= smb_raw_open(cli3
->tree
, tctx
, &io
);
2688 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
2689 fnum3
= io
.ntcreatex
.out
.file
.fnum
;
2690 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, NO_OPLOCK_RETURN
);
2692 CHECK_VAL(break_info
.count
, 1);
2693 CHECK_VAL(break_info
.fnum
, fnum
);
2694 CHECK_VAL(break_info
.level
, OPLOCK_BREAK_TO_LEVEL_II
);
2695 CHECK_VAL(break_info
.failures
, 0);
2697 ZERO_STRUCT(break_info
);
2699 torture_comment(tctx
, "a 3rd open with level2 oplock support should not generate a break\n");
2700 status
= smb_raw_open(cli2
->tree
, tctx
, &io
);
2701 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
2702 fnum2
= io
.ntcreatex
.out
.file
.fnum
;
2703 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, LEVEL_II_OPLOCK_RETURN
);
2705 CHECK_VAL(break_info
.count
, 0);
2707 smbcli_close(cli1
->tree
, fnum
);
2708 smbcli_close(cli2
->tree
, fnum2
);
2709 smbcli_close(cli3
->tree
, fnum3
);
2712 smb_raw_exit(cli1
->session
);
2713 smb_raw_exit(cli2
->session
);
2714 smb_raw_exit(cli3
->session
);
2715 smbcli_deltree(cli1
->tree
, BASEDIR
);
2719 static bool test_raw_oplock_batch24(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
2721 const char *fname
= BASEDIR
"\\test_batch24.dat";
2725 uint16_t fnum2
=0,fnum3
=0;
2726 struct smbcli_state
*cli3
= NULL
;
2728 if (!torture_setup_dir(cli1
, BASEDIR
)) {
2733 smbcli_unlink(cli1
->tree
, fname
);
2735 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
2737 ret
= open_connection_no_level2_oplocks(tctx
, &cli3
);
2738 CHECK_VAL(ret
, true);
2741 base ntcreatex parms
2743 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
2744 io
.ntcreatex
.in
.root_fid
= 0;
2745 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
2746 io
.ntcreatex
.in
.alloc_size
= 0;
2747 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
2748 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
2749 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
2750 io
.ntcreatex
.in
.create_options
= 0;
2751 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
2752 io
.ntcreatex
.in
.security_flags
= 0;
2753 io
.ntcreatex
.in
.fname
= fname
;
2755 torture_comment(tctx
, "BATCH24: a open without level support and ask for a batch oplock\n");
2756 ZERO_STRUCT(break_info
);
2757 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
2758 smbcli_oplock_handler(cli2
->transport
, oplock_handler_ack_to_given
, cli2
->tree
);
2759 smbcli_oplock_handler(cli3
->transport
, oplock_handler_ack_to_given
, cli3
->tree
);
2761 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_READ
| SEC_RIGHTS_FILE_WRITE
;
2762 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
| NTCREATEX_SHARE_ACCESS_WRITE
;
2763 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
2764 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
2765 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
2766 status
= smb_raw_open(cli3
->tree
, tctx
, &io
);
2767 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
2768 fnum3
= io
.ntcreatex
.out
.file
.fnum
;
2769 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, BATCH_OPLOCK_RETURN
);
2771 ZERO_STRUCT(break_info
);
2773 torture_comment(tctx
, "a 2nd open with level2 oplock support should generate a break to none\n");
2774 status
= smb_raw_open(cli2
->tree
, tctx
, &io
);
2775 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
2776 fnum2
= io
.ntcreatex
.out
.file
.fnum
;
2777 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, LEVEL_II_OPLOCK_RETURN
);
2779 CHECK_VAL(break_info
.count
, 1);
2780 CHECK_VAL(break_info
.fnum
, fnum3
);
2781 CHECK_VAL(break_info
.level
, OPLOCK_BREAK_TO_NONE
);
2782 CHECK_VAL(break_info
.failures
, 0);
2784 smbcli_close(cli3
->tree
, fnum3
);
2785 smbcli_close(cli2
->tree
, fnum2
);
2788 smb_raw_exit(cli1
->session
);
2789 smb_raw_exit(cli2
->session
);
2790 smb_raw_exit(cli3
->session
);
2791 smbcli_deltree(cli1
->tree
, BASEDIR
);
2795 static bool test_raw_oplock_batch25(struct torture_context
*tctx
,
2796 struct smbcli_state
*cli1
,
2797 struct smbcli_state
*cli2
)
2799 const char *fname
= BASEDIR
"\\test_batch25.dat";
2803 union smb_setfileinfo sfi
;
2806 if (!torture_setup_dir(cli1
, BASEDIR
)) {
2811 smbcli_unlink(cli1
->tree
, fname
);
2813 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
2816 base ntcreatex parms
2818 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
2819 io
.ntcreatex
.in
.root_fid
= 0;
2820 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
2821 io
.ntcreatex
.in
.alloc_size
= 0;
2822 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
2823 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
2824 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
2825 io
.ntcreatex
.in
.create_options
= 0;
2826 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
2827 io
.ntcreatex
.in
.security_flags
= 0;
2828 io
.ntcreatex
.in
.fname
= fname
;
2830 torture_comment(tctx
, "BATCH25: open a file with an batch oplock "
2831 "(share mode: none)\n");
2833 ZERO_STRUCT(break_info
);
2834 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
2835 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
2836 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
2837 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
2838 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
2839 fnum
= io
.ntcreatex
.out
.file
.fnum
;
2840 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, BATCH_OPLOCK_RETURN
);
2842 torture_comment(tctx
, "setpathinfo attribute info should not trigger "
2843 "a break nor a violation\n");
2845 sfi
.generic
.level
= RAW_SFILEINFO_SETATTR
;
2846 sfi
.generic
.in
.file
.path
= fname
;
2847 sfi
.setattr
.in
.attrib
= FILE_ATTRIBUTE_HIDDEN
;
2848 sfi
.setattr
.in
.write_time
= 0;
2850 status
= smb_raw_setpathinfo(cli2
->tree
, &sfi
);
2852 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
2853 CHECK_VAL(break_info
.count
, 0);
2855 smbcli_close(cli1
->tree
, fnum
);
2858 smb_raw_exit(cli1
->session
);
2859 smb_raw_exit(cli2
->session
);
2860 smbcli_deltree(cli1
->tree
, BASEDIR
);
2864 /* Test how oplocks work on streams. */
2865 static bool test_raw_oplock_stream1(struct torture_context
*tctx
,
2866 struct smbcli_state
*cli1
,
2867 struct smbcli_state
*cli2
)
2871 const char *fname_base
= BASEDIR
"\\test_stream1.txt";
2872 const char *stream
= "Stream One:$DATA";
2873 const char *fname_stream
, *fname_default_stream
;
2874 const char *default_stream
= "::$DATA";
2878 int stream_fnum
= -1;
2879 uint32_t batch_req
= NTCREATEX_FLAGS_REQUEST_OPLOCK
|
2880 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
| NTCREATEX_FLAGS_EXTENDED
;
2881 uint32_t exclusive_req
= NTCREATEX_FLAGS_REQUEST_OPLOCK
|
2882 NTCREATEX_FLAGS_EXTENDED
;
2883 /* Try some permutations of taking oplocks on streams. */
2884 #define NSTREAM_OPLOCK_RESULTS 8
2887 bool open_base_file
;
2888 uint32_t oplock_req
;
2889 uint32_t oplock_granted
;
2890 } stream_oplock_results
[NSTREAM_OPLOCK_RESULTS
] = {
2891 /* Request oplock on stream without the base file open. */
2892 {fname_stream
, false, batch_req
, NO_OPLOCK_RETURN
},
2893 {fname_default_stream
, false, batch_req
, NO_OPLOCK_RETURN
},
2894 {fname_stream
, false, exclusive_req
, EXCLUSIVE_OPLOCK_RETURN
},
2895 {fname_default_stream
, false, exclusive_req
, EXCLUSIVE_OPLOCK_RETURN
},
2897 /* Request oplock on stream with the base file open. */
2898 {fname_stream
, true, batch_req
, NO_OPLOCK_RETURN
},
2899 {fname_default_stream
, true, batch_req
, NO_OPLOCK_RETURN
},
2900 {fname_stream
, true, exclusive_req
, EXCLUSIVE_OPLOCK_RETURN
},
2901 {fname_default_stream
, true, exclusive_req
, LEVEL_II_OPLOCK_RETURN
},
2906 /* Only passes against windows at the moment. */
2907 if (torture_setting_bool(tctx
, "samba3", false) ||
2908 torture_setting_bool(tctx
, "samba4", false)) {
2909 torture_skip(tctx
, "STREAM1 disabled against samba3+4\n");
2912 fname_stream
= talloc_asprintf(tctx
, "%s:%s", fname_base
, stream
);
2913 fname_default_stream
= talloc_asprintf(tctx
, "%s%s", fname_base
,
2916 if (!torture_setup_dir(cli1
, BASEDIR
)) {
2919 smbcli_unlink(cli1
->tree
, fname_base
);
2921 smbcli_oplock_handler(cli2
->transport
, oplock_handler_ack_to_given
, cli2
->tree
);
2922 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
2924 /* Setup generic open parameters. */
2925 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
2926 io
.ntcreatex
.in
.root_fid
= 0;
2927 io
.ntcreatex
.in
.access_mask
= (SEC_FILE_READ_DATA
|SEC_FILE_WRITE_DATA
|
2928 SEC_FILE_APPEND_DATA
|SEC_STD_READ_CONTROL
);
2929 io
.ntcreatex
.in
.create_options
= 0;
2930 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
2931 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
|
2932 NTCREATEX_SHARE_ACCESS_WRITE
;
2933 io
.ntcreatex
.in
.alloc_size
= 0;
2934 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
2935 io
.ntcreatex
.in
.security_flags
= 0;
2937 /* Create the file with a stream */
2938 io
.ntcreatex
.in
.fname
= fname_stream
;
2939 io
.ntcreatex
.in
.flags
= 0;
2940 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_CREATE
;
2941 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
2942 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
2943 smbcli_close(cli1
->tree
, io
.ntcreatex
.out
.file
.fnum
);
2945 /* Change the disposition to open now that the file has been created. */
2946 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN
;
2948 for (i
= 0; i
< NSTREAM_OPLOCK_RESULTS
; i
++) {
2949 const char *fname
= stream_oplock_results
[i
].fname
;
2950 bool open_base_file
= stream_oplock_results
[i
].open_base_file
;
2951 uint32_t oplock_req
= stream_oplock_results
[i
].oplock_req
;
2952 uint32_t oplock_granted
=
2953 stream_oplock_results
[i
].oplock_granted
;
2956 if (open_base_file
) {
2957 torture_comment(tctx
, "Opening base file: %s with "
2958 "%d\n", fname_base
, oplock_req
);
2959 io
.ntcreatex
.in
.fname
= fname_base
;
2960 io
.ntcreatex
.in
.flags
= batch_req
;
2961 status
= smb_raw_open(cli2
->tree
, tctx
, &io
);
2962 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
2963 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
,
2964 BATCH_OPLOCK_RETURN
);
2965 base_fnum
= io
.ntcreatex
.out
.file
.fnum
;
2968 torture_comment(tctx
, "%d: Opening stream: %s with %d\n", i
,
2970 io
.ntcreatex
.in
.fname
= fname
;
2971 io
.ntcreatex
.in
.flags
= oplock_req
;
2973 /* Do the open with the desired oplock on the stream. */
2974 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
2975 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
2976 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, oplock_granted
);
2977 smbcli_close(cli1
->tree
, io
.ntcreatex
.out
.file
.fnum
);
2979 /* Cleanup the base file if it was opened. */
2980 if (base_fnum
!= -1) {
2981 smbcli_close(cli2
->tree
, base_fnum
);
2985 /* Open the stream with an exclusive oplock. */
2986 torture_comment(tctx
, "Opening stream: %s with %d\n",
2987 fname_stream
, exclusive_req
);
2988 io
.ntcreatex
.in
.fname
= fname_stream
;
2989 io
.ntcreatex
.in
.flags
= exclusive_req
;
2990 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
2991 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
2992 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, EXCLUSIVE_OPLOCK_RETURN
);
2993 stream_fnum
= io
.ntcreatex
.out
.file
.fnum
;
2995 /* Open the base file and see if it contends. */
2996 ZERO_STRUCT(break_info
);
2997 torture_comment(tctx
, "Opening base file: %s with "
2998 "%d\n", fname_base
, batch_req
);
2999 io
.ntcreatex
.in
.fname
= fname_base
;
3000 io
.ntcreatex
.in
.flags
= batch_req
;
3001 status
= smb_raw_open(cli2
->tree
, tctx
, &io
);
3002 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
3003 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
,
3004 BATCH_OPLOCK_RETURN
);
3005 smbcli_close(cli2
->tree
, io
.ntcreatex
.out
.file
.fnum
);
3007 CHECK_VAL(break_info
.count
, 0);
3008 CHECK_VAL(break_info
.failures
, 0);
3010 /* Open the stream again to see if it contends. */
3011 ZERO_STRUCT(break_info
);
3012 torture_comment(tctx
, "Opening stream again: %s with "
3013 "%d\n", fname_base
, batch_req
);
3014 io
.ntcreatex
.in
.fname
= fname_stream
;
3015 io
.ntcreatex
.in
.flags
= exclusive_req
;
3016 status
= smb_raw_open(cli2
->tree
, tctx
, &io
);
3017 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
3018 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
,
3019 LEVEL_II_OPLOCK_RETURN
);
3020 smbcli_close(cli2
->tree
, io
.ntcreatex
.out
.file
.fnum
);
3022 CHECK_VAL(break_info
.count
, 1);
3023 CHECK_VAL(break_info
.level
, OPLOCK_BREAK_TO_LEVEL_II
);
3024 CHECK_VAL(break_info
.failures
, 0);
3026 /* Close the stream. */
3027 if (stream_fnum
!= -1) {
3028 smbcli_close(cli1
->tree
, stream_fnum
);
3032 smbcli_close(cli1
->tree
, fnum
);
3033 smb_raw_exit(cli1
->session
);
3034 smb_raw_exit(cli2
->session
);
3035 smbcli_deltree(cli1
->tree
, BASEDIR
);
3039 static bool test_raw_oplock_doc(struct torture_context
*tctx
,
3040 struct smbcli_state
*cli
)
3042 const char *fname
= BASEDIR
"\\test_oplock_doc.dat";
3048 if (!torture_setup_dir(cli
, BASEDIR
)) {
3053 smbcli_unlink(cli
->tree
, fname
);
3055 smbcli_oplock_handler(cli
->transport
, oplock_handler_ack_to_given
,
3059 base ntcreatex parms
3061 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
3062 io
.ntcreatex
.in
.root_fid
= 0;
3063 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
3064 io
.ntcreatex
.in
.alloc_size
= 0;
3065 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
3066 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
3067 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
3068 io
.ntcreatex
.in
.create_options
= NTCREATEX_OPTIONS_DELETE_ON_CLOSE
;
3069 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
3070 io
.ntcreatex
.in
.security_flags
= 0;
3071 io
.ntcreatex
.in
.fname
= fname
;
3073 torture_comment(tctx
, "open a delete-on-close file with a batch "
3075 ZERO_STRUCT(break_info
);
3076 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
3077 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
3078 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
3080 status
= smb_raw_open(cli
->tree
, tctx
, &io
);
3081 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
3082 fnum
= io
.ntcreatex
.out
.file
.fnum
;
3083 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, BATCH_OPLOCK_RETURN
);
3085 smbcli_close(cli
->tree
, fnum
);
3088 smb_raw_exit(cli
->session
);
3089 smbcli_deltree(cli
->tree
, BASEDIR
);
3093 /* Open a file with a batch oplock, then open it again from a second client
3094 * requesting no oplock. Having two open file handles should break our own
3095 * oplock during BRL acquisition.
3097 static bool test_raw_oplock_brl1(struct torture_context
*tctx
,
3098 struct smbcli_state
*cli1
,
3099 struct smbcli_state
*cli2
)
3101 const char *fname
= BASEDIR
"\\test_batch_brl.dat";
3105 bool correct
= true;
3111 if (!torture_setup_dir(cli1
, BASEDIR
)) {
3116 smbcli_unlink(cli1
->tree
, fname
);
3118 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
,
3122 base ntcreatex parms
3124 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
3125 io
.ntcreatex
.in
.root_fid
= 0;
3126 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_READ
|
3127 SEC_RIGHTS_FILE_WRITE
;
3128 io
.ntcreatex
.in
.alloc_size
= 0;
3129 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
3130 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
|
3131 NTCREATEX_SHARE_ACCESS_WRITE
;
3132 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
3133 io
.ntcreatex
.in
.create_options
= 0;
3134 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
3135 io
.ntcreatex
.in
.security_flags
= 0;
3136 io
.ntcreatex
.in
.fname
= fname
;
3139 with a batch oplock we get a break
3141 torture_comment(tctx
, "open with batch oplock\n");
3142 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
3143 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
3144 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
3146 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
3147 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
3148 fnum
= io
.ntcreatex
.out
.file
.fnum
;
3149 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, BATCH_OPLOCK_RETURN
);
3150 /* create a file with bogus data */
3151 memset(buf
, 0, sizeof(buf
));
3153 if (smbcli_write(cli1
->tree
, fnum
, 0, buf
, 0, sizeof(buf
)) !=
3156 torture_comment(tctx
, "Failed to create file\n");
3161 torture_comment(tctx
, "a 2nd open should give a break\n");
3162 ZERO_STRUCT(break_info
);
3163 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
,
3166 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
;
3167 status
= smb_raw_open(cli2
->tree
, tctx
, &io
);
3168 fnum2
= io
.ntcreatex
.out
.file
.fnum
;
3169 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
3170 CHECK_VAL(break_info
.count
, 1);
3171 CHECK_VAL(break_info
.level
, OPLOCK_BREAK_TO_LEVEL_II
);
3172 CHECK_VAL(break_info
.failures
, 0);
3173 CHECK_VAL(break_info
.fnum
, fnum
);
3175 ZERO_STRUCT(break_info
);
3176 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
,
3179 torture_comment(tctx
, "attempt BRL test\n");
3181 status
= smbcli_lock(cli1
->tree
, fnum
, 0, 4, 0, WRITE_LOCK
);
3182 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
3185 * Even though level 2 oplock breaks are asynchronous, with self
3186 * contention we'll always break the oplock before the contending
3187 * operation's response is sent.
3189 CHECK_VAL(break_info
.count
, 1);
3190 CHECK_VAL(break_info
.level
, OPLOCK_BREAK_TO_NONE
);
3191 CHECK_VAL(break_info
.fnum
, fnum
);
3192 CHECK_VAL(break_info
.failures
, 0);
3194 /* expect no oplock break */
3195 ZERO_STRUCT(break_info
);
3196 status
= smbcli_lock(cli1
->tree
, fnum
, 2, 4, 0, WRITE_LOCK
);
3197 CHECK_STATUS(tctx
, status
, NT_STATUS_LOCK_NOT_GRANTED
);
3199 CHECK_VAL(break_info
.count
, 0);
3200 CHECK_VAL(break_info
.level
, 0);
3201 CHECK_VAL(break_info
.fnum
, 0);
3202 CHECK_VAL(break_info
.failures
, 0);
3204 smbcli_close(cli1
->tree
, fnum
);
3205 smbcli_close(cli2
->tree
, fnum2
);
3208 smb_raw_exit(cli1
->session
);
3209 smb_raw_exit(cli2
->session
);
3210 smbcli_deltree(cli1
->tree
, BASEDIR
);
3215 /* Open a file with a batch oplock on one client and then acquire a brl.
3216 * We should not contend our own oplock.
3218 static bool test_raw_oplock_brl2(struct torture_context
*tctx
, struct smbcli_state
*cli1
)
3220 const char *fname
= BASEDIR
"\\test_batch_brl.dat";
3224 bool correct
= true;
3229 if (!torture_setup_dir(cli1
, BASEDIR
)) {
3234 smbcli_unlink(cli1
->tree
, fname
);
3236 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
,
3240 base ntcreatex parms
3242 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
3243 io
.ntcreatex
.in
.root_fid
= 0;
3244 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_READ
|
3245 SEC_RIGHTS_FILE_WRITE
;
3246 io
.ntcreatex
.in
.alloc_size
= 0;
3247 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
3248 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
|
3249 NTCREATEX_SHARE_ACCESS_WRITE
;
3250 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
3251 io
.ntcreatex
.in
.create_options
= 0;
3252 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
3253 io
.ntcreatex
.in
.security_flags
= 0;
3254 io
.ntcreatex
.in
.fname
= fname
;
3257 with a batch oplock we get a break
3259 torture_comment(tctx
, "open with batch oplock\n");
3260 ZERO_STRUCT(break_info
);
3261 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
3262 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
3263 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
3265 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
3266 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
3267 fnum
= io
.ntcreatex
.out
.file
.fnum
;
3268 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, BATCH_OPLOCK_RETURN
);
3270 /* create a file with bogus data */
3271 memset(buf
, 0, sizeof(buf
));
3273 if (smbcli_write(cli1
->tree
, fnum
, 0, buf
, 0, sizeof(buf
)) !=
3276 torture_comment(tctx
, "Failed to create file\n");
3281 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
,
3284 torture_comment(tctx
, "attempt BRL test\n");
3286 status
= smbcli_lock(cli1
->tree
, fnum
, 0, 4, 0, WRITE_LOCK
);
3287 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
3289 status
= smbcli_lock(cli1
->tree
, fnum
, 2, 4, 0, WRITE_LOCK
);
3290 CHECK_STATUS(tctx
, status
, NT_STATUS_LOCK_NOT_GRANTED
);
3292 /* With one file handle open a BRL should not contend our oplock.
3293 * Thus, no oplock break will be received and the entire break_info
3294 * struct will be 0 */
3295 CHECK_VAL(break_info
.fnum
, 0);
3296 CHECK_VAL(break_info
.count
, 0);
3297 CHECK_VAL(break_info
.level
, 0);
3298 CHECK_VAL(break_info
.failures
, 0);
3300 smbcli_close(cli1
->tree
, fnum
);
3303 smb_raw_exit(cli1
->session
);
3304 smbcli_deltree(cli1
->tree
, BASEDIR
);
3308 /* Open a file with a batch oplock twice from one client and then acquire a
3309 * brl. BRL acquisition should break our own oplock.
3311 static bool test_raw_oplock_brl3(struct torture_context
*tctx
,
3312 struct smbcli_state
*cli1
)
3314 const char *fname
= BASEDIR
"\\test_batch_brl.dat";
3317 bool correct
= true;
3323 if (!torture_setup_dir(cli1
, BASEDIR
)) {
3328 smbcli_unlink(cli1
->tree
, fname
);
3330 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
,
3334 base ntcreatex parms
3336 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
3337 io
.ntcreatex
.in
.root_fid
= 0;
3338 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_READ
|
3339 SEC_RIGHTS_FILE_WRITE
;
3340 io
.ntcreatex
.in
.alloc_size
= 0;
3341 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
3342 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
|
3343 NTCREATEX_SHARE_ACCESS_WRITE
;
3344 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
3345 io
.ntcreatex
.in
.create_options
= 0;
3346 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
3347 io
.ntcreatex
.in
.security_flags
= 0;
3348 io
.ntcreatex
.in
.fname
= fname
;
3351 with a batch oplock we get a break
3353 torture_comment(tctx
, "open with batch oplock\n");
3354 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
3355 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
3356 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
3358 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
3359 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
3360 fnum
= io
.ntcreatex
.out
.file
.fnum
;
3361 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, BATCH_OPLOCK_RETURN
);
3363 /* create a file with bogus data */
3364 memset(buf
, 0, sizeof(buf
));
3366 if (smbcli_write(cli1
->tree
, fnum
, 0, buf
, 0, sizeof(buf
)) !=
3369 torture_comment(tctx
, "Failed to create file\n");
3374 torture_comment(tctx
, "a 2nd open should give a break\n");
3375 ZERO_STRUCT(break_info
);
3376 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
,
3379 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
;
3380 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
3381 fnum2
= io
.ntcreatex
.out
.file
.fnum
;
3382 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
3383 CHECK_VAL(break_info
.count
, 1);
3384 CHECK_VAL(break_info
.level
, OPLOCK_BREAK_TO_LEVEL_II
);
3385 CHECK_VAL(break_info
.failures
, 0);
3386 CHECK_VAL(break_info
.fnum
, fnum
);
3388 ZERO_STRUCT(break_info
);
3389 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
,
3392 torture_comment(tctx
, "attempt BRL test\n");
3394 status
= smbcli_lock(cli1
->tree
, fnum
, 0, 4, 0, WRITE_LOCK
);
3395 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
3398 * Even though level 2 oplock breaks are asynchrounous, with self
3399 * contention we'll always break the oplock before the contending
3400 * operation's response is sent.
3402 CHECK_VAL(break_info
.count
, 1);
3403 CHECK_VAL(break_info
.level
, OPLOCK_BREAK_TO_NONE
);
3404 CHECK_VAL(break_info
.fnum
, fnum
);
3405 CHECK_VAL(break_info
.failures
, 0);
3407 /* expect no oplock break */
3408 ZERO_STRUCT(break_info
);
3409 status
= smbcli_lock(cli1
->tree
, fnum
, 2, 4, 0, WRITE_LOCK
);
3410 CHECK_STATUS(tctx
, status
, NT_STATUS_LOCK_NOT_GRANTED
);
3412 CHECK_VAL(break_info
.count
, 0);
3413 CHECK_VAL(break_info
.level
, 0);
3414 CHECK_VAL(break_info
.fnum
, 0);
3415 CHECK_VAL(break_info
.failures
, 0);
3417 smbcli_close(cli1
->tree
, fnum
);
3418 smbcli_close(cli1
->tree
, fnum2
);
3421 smb_raw_exit(cli1
->session
);
3422 smbcli_deltree(cli1
->tree
, BASEDIR
);
3428 basic testing of oplocks
3430 struct torture_suite
*torture_raw_oplock(TALLOC_CTX
*mem_ctx
)
3432 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "OPLOCK");
3434 torture_suite_add_2smb_test(suite
, "EXCLUSIVE1", test_raw_oplock_exclusive1
);
3435 torture_suite_add_2smb_test(suite
, "EXCLUSIVE2", test_raw_oplock_exclusive2
);
3436 torture_suite_add_2smb_test(suite
, "EXCLUSIVE3", test_raw_oplock_exclusive3
);
3437 torture_suite_add_2smb_test(suite
, "EXCLUSIVE4", test_raw_oplock_exclusive4
);
3438 torture_suite_add_2smb_test(suite
, "EXCLUSIVE5", test_raw_oplock_exclusive5
);
3439 torture_suite_add_2smb_test(suite
, "EXCLUSIVE6", test_raw_oplock_exclusive6
);
3440 torture_suite_add_2smb_test(suite
, "BATCH1", test_raw_oplock_batch1
);
3441 torture_suite_add_2smb_test(suite
, "BATCH2", test_raw_oplock_batch2
);
3442 torture_suite_add_2smb_test(suite
, "BATCH3", test_raw_oplock_batch3
);
3443 torture_suite_add_2smb_test(suite
, "BATCH4", test_raw_oplock_batch4
);
3444 torture_suite_add_2smb_test(suite
, "BATCH5", test_raw_oplock_batch5
);
3445 torture_suite_add_2smb_test(suite
, "BATCH6", test_raw_oplock_batch6
);
3446 torture_suite_add_2smb_test(suite
, "BATCH7", test_raw_oplock_batch7
);
3447 torture_suite_add_2smb_test(suite
, "BATCH8", test_raw_oplock_batch8
);
3448 torture_suite_add_2smb_test(suite
, "BATCH9", test_raw_oplock_batch9
);
3449 torture_suite_add_2smb_test(suite
, "BATCH10", test_raw_oplock_batch10
);
3450 torture_suite_add_2smb_test(suite
, "BATCH11", test_raw_oplock_batch11
);
3451 torture_suite_add_2smb_test(suite
, "BATCH12", test_raw_oplock_batch12
);
3452 torture_suite_add_2smb_test(suite
, "BATCH13", test_raw_oplock_batch13
);
3453 torture_suite_add_2smb_test(suite
, "BATCH14", test_raw_oplock_batch14
);
3454 torture_suite_add_2smb_test(suite
, "BATCH15", test_raw_oplock_batch15
);
3455 torture_suite_add_2smb_test(suite
, "BATCH16", test_raw_oplock_batch16
);
3456 torture_suite_add_2smb_test(suite
, "BATCH17", test_raw_oplock_batch17
);
3457 torture_suite_add_2smb_test(suite
, "BATCH18", test_raw_oplock_batch18
);
3458 torture_suite_add_2smb_test(suite
, "BATCH19", test_raw_oplock_batch19
);
3459 torture_suite_add_2smb_test(suite
, "BATCH20", test_raw_oplock_batch20
);
3460 torture_suite_add_2smb_test(suite
, "BATCH21", test_raw_oplock_batch21
);
3461 torture_suite_add_2smb_test(suite
, "BATCH22", test_raw_oplock_batch22
);
3462 torture_suite_add_2smb_test(suite
, "BATCH23", test_raw_oplock_batch23
);
3463 torture_suite_add_2smb_test(suite
, "BATCH24", test_raw_oplock_batch24
);
3464 torture_suite_add_2smb_test(suite
, "BATCH25", test_raw_oplock_batch25
);
3465 torture_suite_add_2smb_test(suite
, "STREAM1", test_raw_oplock_stream1
);
3466 torture_suite_add_1smb_test(suite
, "DOC1", test_raw_oplock_doc
);
3467 torture_suite_add_2smb_test(suite
, "BRL1", test_raw_oplock_brl1
);
3468 torture_suite_add_1smb_test(suite
, "BRL2", test_raw_oplock_brl2
);
3469 torture_suite_add_1smb_test(suite
, "BRL3", test_raw_oplock_brl3
);
3475 stress testing of oplocks
3477 bool torture_bench_oplock(struct torture_context
*torture
)
3479 struct smbcli_state
**cli
;
3481 TALLOC_CTX
*mem_ctx
= talloc_new(torture
);
3482 int torture_nprocs
= torture_setting_int(torture
, "nprocs", 4);
3484 int timelimit
= torture_setting_int(torture
, "timelimit", 10);
3488 cli
= talloc_array(mem_ctx
, struct smbcli_state
*, torture_nprocs
);
3490 torture_comment(torture
, "Opening %d connections\n", torture_nprocs
);
3491 for (i
=0;i
<torture_nprocs
;i
++) {
3492 if (!torture_open_connection_ev(&cli
[i
], i
, torture
, torture
->ev
)) {
3495 talloc_steal(mem_ctx
, cli
[i
]);
3496 smbcli_oplock_handler(cli
[i
]->transport
, oplock_handler_close
,
3500 if (!torture_setup_dir(cli
[0], BASEDIR
)) {
3505 io
.ntcreatex
.level
= RAW_OPEN_NTCREATEX
;
3506 io
.ntcreatex
.in
.root_fid
= 0;
3507 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
3508 io
.ntcreatex
.in
.alloc_size
= 0;
3509 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
3510 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
3511 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
3512 io
.ntcreatex
.in
.create_options
= 0;
3513 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
3514 io
.ntcreatex
.in
.security_flags
= 0;
3515 io
.ntcreatex
.in
.fname
= BASEDIR
"\\test.dat";
3516 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
3517 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
3518 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
3520 tv
= timeval_current();
3523 we open the same file with SHARE_ACCESS_NONE from all the
3524 connections in a round robin fashion. Each open causes an
3525 oplock break on the previous connection, which is answered
3526 by the oplock_handler_close() to close the file.
3528 This measures how fast we can pass on oplocks, and stresses
3529 the oplock handling code
3531 torture_comment(torture
, "Running for %d seconds\n", timelimit
);
3532 while (timeval_elapsed(&tv
) < timelimit
) {
3533 for (i
=0;i
<torture_nprocs
;i
++) {
3536 status
= smb_raw_open(cli
[i
]->tree
, mem_ctx
, &io
);
3537 CHECK_STATUS(torture
, status
, NT_STATUS_OK
);
3541 if (torture_setting_bool(torture
, "progress", true)) {
3542 torture_comment(torture
, "%.2f ops/second\r", count
/timeval_elapsed(&tv
));
3546 torture_comment(torture
, "%.2f ops/second\n", count
/timeval_elapsed(&tv
));
3548 smb_raw_exit(cli
[torture_nprocs
-1]->session
);
3551 smb_raw_exit(cli
[0]->session
);
3552 smbcli_deltree(cli
[0]->tree
, BASEDIR
);
3553 talloc_free(mem_ctx
);
3558 static struct hold_oplock_info
{
3560 bool close_on_break
;
3561 uint32_t share_access
;
3564 { BASEDIR
"\\notshared_close", true,
3565 NTCREATEX_SHARE_ACCESS_NONE
, },
3566 { BASEDIR
"\\notshared_noclose", false,
3567 NTCREATEX_SHARE_ACCESS_NONE
, },
3568 { BASEDIR
"\\shared_close", true,
3569 NTCREATEX_SHARE_ACCESS_READ
|NTCREATEX_SHARE_ACCESS_WRITE
|NTCREATEX_SHARE_ACCESS_DELETE
, },
3570 { BASEDIR
"\\shared_noclose", false,
3571 NTCREATEX_SHARE_ACCESS_READ
|NTCREATEX_SHARE_ACCESS_WRITE
|NTCREATEX_SHARE_ACCESS_DELETE
, },
3574 static bool oplock_handler_hold(struct smbcli_transport
*transport
,
3575 uint16_t tid
, uint16_t fnum
, uint8_t level
,
3578 struct smbcli_tree
*tree
= (struct smbcli_tree
*)private_data
;
3579 struct hold_oplock_info
*info
;
3582 for (i
=0;i
<ARRAY_SIZE(hold_info
);i
++) {
3583 if (hold_info
[i
].fnum
== fnum
) break;
3586 if (i
== ARRAY_SIZE(hold_info
)) {
3587 printf("oplock break for unknown fnum %u\n", fnum
);
3591 info
= &hold_info
[i
];
3593 if (info
->close_on_break
) {
3594 printf("oplock break on %s - closing\n",
3596 oplock_handler_close(transport
, tid
, fnum
, level
, private_data
);
3600 printf("oplock break on %s - acking break\n", info
->fname
);
3602 return smbcli_oplock_ack(tree
, fnum
, OPLOCK_BREAK_TO_NONE
);
3607 used for manual testing of oplocks - especially interaction with
3608 other filesystems (such as NFS and local access)
3610 bool torture_hold_oplock(struct torture_context
*torture
,
3611 struct smbcli_state
*cli
)
3613 struct tevent_context
*ev
=
3614 (struct tevent_context
*)cli
->transport
->socket
->event
.ctx
;
3617 printf("Setting up open files with oplocks in %s\n", BASEDIR
);
3619 if (!torture_setup_dir(cli
, BASEDIR
)) {
3623 smbcli_oplock_handler(cli
->transport
, oplock_handler_hold
, cli
->tree
);
3625 /* setup the files */
3626 for (i
=0;i
<ARRAY_SIZE(hold_info
);i
++) {
3631 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
3632 io
.ntcreatex
.in
.root_fid
= 0;
3633 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
3634 io
.ntcreatex
.in
.alloc_size
= 0;
3635 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
3636 io
.ntcreatex
.in
.share_access
= hold_info
[i
].share_access
;
3637 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
3638 io
.ntcreatex
.in
.create_options
= 0;
3639 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
3640 io
.ntcreatex
.in
.security_flags
= 0;
3641 io
.ntcreatex
.in
.fname
= hold_info
[i
].fname
;
3642 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
3643 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
3644 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
3645 printf("opening %s\n", hold_info
[i
].fname
);
3647 status
= smb_raw_open(cli
->tree
, cli
, &io
);
3648 if (!NT_STATUS_IS_OK(status
)) {
3649 printf("Failed to open %s - %s\n",
3650 hold_info
[i
].fname
, nt_errstr(status
));
3654 if (io
.ntcreatex
.out
.oplock_level
!= BATCH_OPLOCK_RETURN
) {
3655 printf("Oplock not granted for %s - expected %d but got %d\n",
3656 hold_info
[i
].fname
, BATCH_OPLOCK_RETURN
,
3657 io
.ntcreatex
.out
.oplock_level
);
3660 hold_info
[i
].fnum
= io
.ntcreatex
.out
.file
.fnum
;
3662 /* make the file non-zero size */
3663 if (smbcli_write(cli
->tree
, hold_info
[i
].fnum
, 0, &c
, 0, 1) != 1) {
3664 printf("Failed to write to file\n");
3669 printf("Waiting for oplock events\n");
3670 event_loop_wait(ev
);