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 "libcli/raw/libcliraw.h"
22 #include "libcli/raw/raw_proto.h"
23 #include "libcli/libcli.h"
24 #include "torture/util.h"
25 #include "lib/events/events.h"
26 #include "param/param.h"
27 #include "lib/cmdline/popt_common.h"
28 #include "libcli/resolve/resolve.h"
29 #include "torture/raw/proto.h"
31 #define CHECK_VAL(v, correct) do { \
32 if ((v) != (correct)) { \
33 torture_result(tctx, TORTURE_FAIL, "(%s): wrong value for %s got 0x%x - should be 0x%x\n", \
34 __location__, #v, (int)v, (int)correct); \
38 #define CHECK_RANGE(v, min, max) do { \
39 if ((v) < (min) || (v) > (max)) { \
40 torture_warning(tctx, "(%s): wrong value for %s got " \
41 "%d - should be between %d and %d\n", \
42 __location__, #v, (int)v, (int)min, (int)max); \
45 #define CHECK_STRMATCH(v, correct) do { \
46 if (!v || strstr((v),(correct)) == NULL) { \
47 torture_result(tctx, TORTURE_FAIL, "(%s): wrong value for %s got '%s' - should be '%s'\n", \
48 __location__, #v, v?v:"NULL", correct); \
53 #define CHECK_STATUS(tctx, status, correct) do { \
54 if (!NT_STATUS_EQUAL(status, correct)) { \
55 torture_result(tctx, TORTURE_FAIL, __location__": Incorrect status %s - should be %s", \
56 nt_errstr(status), nt_errstr(correct)); \
69 #define BASEDIR "\\test_oplock"
72 a handler function for oplock break requests. Ack it as a break to level II if possible
74 static bool oplock_handler_ack_to_given(struct smbcli_transport
*transport
,
75 uint16_t tid
, uint16_t fnum
,
76 uint8_t level
, void *private_data
)
78 struct smbcli_tree
*tree
= (struct smbcli_tree
*)private_data
;
81 break_info
.fnum
= fnum
;
82 break_info
.level
= level
;
86 case OPLOCK_BREAK_TO_LEVEL_II
:
89 case OPLOCK_BREAK_TO_NONE
:
94 break_info
.failures
++;
96 printf("Acking to %s [0x%02X] in oplock handler\n",
99 return smbcli_oplock_ack(tree
, fnum
, level
);
103 a handler function for oplock break requests. Ack it as a break to none
105 static bool oplock_handler_ack_to_none(struct smbcli_transport
*transport
,
106 uint16_t tid
, uint16_t fnum
,
107 uint8_t level
, void *private_data
)
109 struct smbcli_tree
*tree
= (struct smbcli_tree
*)private_data
;
110 break_info
.fnum
= fnum
;
111 break_info
.level
= level
;
114 printf("Acking to none in oplock handler\n");
116 return smbcli_oplock_ack(tree
, fnum
, OPLOCK_BREAK_TO_NONE
);
120 a handler function for oplock break requests. Let it timeout
122 static bool oplock_handler_timeout(struct smbcli_transport
*transport
,
123 uint16_t tid
, uint16_t fnum
,
124 uint8_t level
, void *private_data
)
126 break_info
.fnum
= fnum
;
127 break_info
.level
= level
;
130 printf("Let oplock break timeout\n");
134 static void oplock_handler_close_recv(struct smbcli_request
*req
)
137 status
= smbcli_request_simple_recv(req
);
138 if (!NT_STATUS_IS_OK(status
)) {
139 printf("close failed in oplock_handler_close\n");
140 break_info
.failures
++;
145 a handler function for oplock break requests - close the file
147 static bool oplock_handler_close(struct smbcli_transport
*transport
, uint16_t tid
,
148 uint16_t fnum
, uint8_t level
, void *private_data
)
151 struct smbcli_tree
*tree
= (struct smbcli_tree
*)private_data
;
152 struct smbcli_request
*req
;
154 break_info
.fnum
= fnum
;
155 break_info
.level
= level
;
158 io
.close
.level
= RAW_CLOSE_CLOSE
;
159 io
.close
.in
.file
.fnum
= fnum
;
160 io
.close
.in
.write_time
= 0;
161 req
= smb_raw_close_send(tree
, &io
);
163 printf("failed to send close in oplock_handler_close\n");
167 req
->async
.fn
= oplock_handler_close_recv
;
168 req
->async
.private_data
= NULL
;
173 static bool open_connection_no_level2_oplocks(struct torture_context
*tctx
,
174 struct smbcli_state
**c
)
177 struct smbcli_options options
;
178 struct smbcli_session_options session_options
;
180 lpcfg_smbcli_options(tctx
->lp_ctx
, &options
);
181 lpcfg_smbcli_session_options(tctx
->lp_ctx
, &session_options
);
183 options
.use_level2_oplocks
= false;
185 status
= smbcli_full_connection(tctx
, c
,
186 torture_setting_string(tctx
, "host", NULL
),
187 lpcfg_smb_ports(tctx
->lp_ctx
),
188 torture_setting_string(tctx
, "share", NULL
),
189 NULL
, lpcfg_socket_options(tctx
->lp_ctx
), cmdline_credentials
,
190 lpcfg_resolve_context(tctx
->lp_ctx
),
191 tctx
->ev
, &options
, &session_options
,
192 lpcfg_gensec_settings(tctx
, tctx
->lp_ctx
));
193 if (!NT_STATUS_IS_OK(status
)) {
194 torture_comment(tctx
, "Failed to open connection - %s\n",
203 Timer handler function notifies the registering function that time is up
205 static void timeout_cb(struct tevent_context
*ev
,
206 struct tevent_timer
*te
,
207 struct timeval current_time
,
210 bool *timesup
= (bool *)private_data
;
216 Wait a short period of time to receive a single oplock break request
218 static void torture_wait_for_oplock_break(struct torture_context
*tctx
)
220 TALLOC_CTX
*tmp_ctx
= talloc_new(NULL
);
221 struct tevent_timer
*te
= NULL
;
223 bool timesup
= false;
224 int old_count
= break_info
.count
;
226 /* Wait .1 seconds for an oplock break */
227 ne
= tevent_timeval_current_ofs(0, 100000);
229 if ((te
= tevent_add_timer(tctx
->ev
, tmp_ctx
, ne
, timeout_cb
, ×up
))
232 torture_comment(tctx
, "Failed to wait for an oplock break. "
233 "test results may not be accurate.");
237 while (!timesup
&& break_info
.count
< old_count
+ 1) {
238 if (tevent_loop_once(tctx
->ev
) != 0) {
239 torture_comment(tctx
, "Failed to wait for an oplock "
240 "break. test results may not be "
247 /* We don't know if the timed event fired and was freed, we received
248 * our oplock break, or some other event triggered the loop. Thus,
249 * we create a tmp_ctx to be able to safely free/remove the timed
250 * event in all 3 cases. */
251 talloc_free(tmp_ctx
);
256 static uint8_t get_break_level1_to_none_count(struct torture_context
*tctx
)
258 return torture_setting_bool(tctx
, "2_step_break_to_none", false) ?
262 static uint8_t get_setinfo_break_count(struct torture_context
*tctx
)
264 if (TARGET_IS_W2K12(tctx
)) {
267 if (TARGET_IS_SAMBA3(tctx
)) {
273 static bool test_raw_oplock_exclusive1(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
275 const char *fname
= BASEDIR
"\\test_exclusive1.dat";
279 union smb_unlink unl
;
282 if (!torture_setup_dir(cli1
, BASEDIR
)) {
287 smbcli_unlink(cli1
->tree
, fname
);
289 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
294 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
295 io
.ntcreatex
.in
.root_fid
.fnum
= 0;
296 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
297 io
.ntcreatex
.in
.alloc_size
= 0;
298 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
299 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
300 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
301 io
.ntcreatex
.in
.create_options
= 0;
302 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
303 io
.ntcreatex
.in
.security_flags
= 0;
304 io
.ntcreatex
.in
.fname
= fname
;
306 torture_comment(tctx
, "EXCLUSIVE1: open a file with an exclusive oplock (share mode: none)\n");
307 ZERO_STRUCT(break_info
);
308 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
| NTCREATEX_FLAGS_REQUEST_OPLOCK
;
310 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
311 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
312 fnum
= io
.ntcreatex
.out
.file
.fnum
;
313 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, EXCLUSIVE_OPLOCK_RETURN
);
315 torture_comment(tctx
, "a 2nd open should not cause a break\n");
316 status
= smb_raw_open(cli2
->tree
, tctx
, &io
);
317 CHECK_STATUS(tctx
, status
, NT_STATUS_SHARING_VIOLATION
);
318 torture_wait_for_oplock_break(tctx
);
319 CHECK_VAL(break_info
.count
, 0);
320 CHECK_VAL(break_info
.failures
, 0);
322 torture_comment(tctx
, "unlink it - should also be no break\n");
323 unl
.unlink
.in
.pattern
= fname
;
324 unl
.unlink
.in
.attrib
= 0;
325 status
= smb_raw_unlink(cli2
->tree
, &unl
);
326 CHECK_STATUS(tctx
, status
, NT_STATUS_SHARING_VIOLATION
);
327 torture_wait_for_oplock_break(tctx
);
328 CHECK_VAL(break_info
.count
, 0);
329 CHECK_VAL(break_info
.failures
, 0);
331 smbcli_close(cli1
->tree
, fnum
);
334 smb_raw_exit(cli1
->session
);
335 smb_raw_exit(cli2
->session
);
336 smbcli_deltree(cli1
->tree
, BASEDIR
);
340 static bool test_raw_oplock_exclusive2(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
342 const char *fname
= BASEDIR
"\\test_exclusive2.dat";
346 union smb_unlink unl
;
347 uint16_t fnum
=0, fnum2
=0;
349 if (!torture_setup_dir(cli1
, BASEDIR
)) {
354 smbcli_unlink(cli1
->tree
, fname
);
356 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
361 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
362 io
.ntcreatex
.in
.root_fid
.fnum
= 0;
363 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
364 io
.ntcreatex
.in
.alloc_size
= 0;
365 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
366 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
367 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
368 io
.ntcreatex
.in
.create_options
= 0;
369 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
370 io
.ntcreatex
.in
.security_flags
= 0;
371 io
.ntcreatex
.in
.fname
= fname
;
373 torture_comment(tctx
, "EXCLUSIVE2: open a file with an exclusive oplock (share mode: all)\n");
374 ZERO_STRUCT(break_info
);
375 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
| NTCREATEX_FLAGS_REQUEST_OPLOCK
;
376 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
|
377 NTCREATEX_SHARE_ACCESS_WRITE
|
378 NTCREATEX_SHARE_ACCESS_DELETE
;
380 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
381 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
382 fnum
= io
.ntcreatex
.out
.file
.fnum
;
383 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, EXCLUSIVE_OPLOCK_RETURN
);
385 torture_comment(tctx
, "a 2nd open should cause a break to level 2\n");
386 status
= smb_raw_open(cli2
->tree
, tctx
, &io
);
387 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
388 fnum2
= io
.ntcreatex
.out
.file
.fnum
;
389 torture_wait_for_oplock_break(tctx
);
390 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, LEVEL_II_OPLOCK_RETURN
);
391 CHECK_VAL(break_info
.count
, 1);
392 CHECK_VAL(break_info
.fnum
, fnum
);
393 CHECK_VAL(break_info
.level
, OPLOCK_BREAK_TO_LEVEL_II
);
394 CHECK_VAL(break_info
.failures
, 0);
395 ZERO_STRUCT(break_info
);
397 /* now we have 2 level II oplocks... */
398 torture_comment(tctx
, "try to unlink it - should not cause a break, but a sharing violation\n");
399 unl
.unlink
.in
.pattern
= fname
;
400 unl
.unlink
.in
.attrib
= 0;
401 status
= smb_raw_unlink(cli2
->tree
, &unl
);
402 CHECK_STATUS(tctx
, status
, NT_STATUS_SHARING_VIOLATION
);
403 torture_wait_for_oplock_break(tctx
);
404 CHECK_VAL(break_info
.count
, 0);
405 CHECK_VAL(break_info
.failures
, 0);
407 torture_comment(tctx
, "close 1st handle\n");
408 smbcli_close(cli1
->tree
, fnum
);
410 torture_comment(tctx
, "try to unlink it - should not cause a break, but a sharing violation\n");
411 unl
.unlink
.in
.pattern
= fname
;
412 unl
.unlink
.in
.attrib
= 0;
413 status
= smb_raw_unlink(cli2
->tree
, &unl
);
414 CHECK_STATUS(tctx
, status
, NT_STATUS_SHARING_VIOLATION
);
415 torture_wait_for_oplock_break(tctx
);
416 CHECK_VAL(break_info
.count
, 0);
417 CHECK_VAL(break_info
.failures
, 0);
419 torture_comment(tctx
, "close 2nd handle\n");
420 smbcli_close(cli2
->tree
, fnum2
);
422 torture_comment(tctx
, "unlink it\n");
423 unl
.unlink
.in
.pattern
= fname
;
424 unl
.unlink
.in
.attrib
= 0;
425 status
= smb_raw_unlink(cli2
->tree
, &unl
);
426 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
427 torture_wait_for_oplock_break(tctx
);
428 CHECK_VAL(break_info
.count
, 0);
429 CHECK_VAL(break_info
.failures
, 0);
432 smb_raw_exit(cli1
->session
);
433 smb_raw_exit(cli2
->session
);
434 smbcli_deltree(cli1
->tree
, BASEDIR
);
438 static bool test_raw_oplock_exclusive3(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
440 const char *fname
= BASEDIR
"\\test_exclusive3.dat";
444 union smb_setfileinfo sfi
;
447 if (!torture_setup_dir(cli1
, BASEDIR
)) {
452 smbcli_unlink(cli1
->tree
, fname
);
454 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
459 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
460 io
.ntcreatex
.in
.root_fid
.fnum
= 0;
461 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
462 io
.ntcreatex
.in
.alloc_size
= 0;
463 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
464 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_WRITE
;
465 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
466 io
.ntcreatex
.in
.create_options
= 0;
467 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
468 io
.ntcreatex
.in
.security_flags
= 0;
469 io
.ntcreatex
.in
.fname
= fname
;
471 torture_comment(tctx
, "EXCLUSIVE3: open a file with an exclusive oplock (share mode: none)\n");
473 ZERO_STRUCT(break_info
);
474 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
| NTCREATEX_FLAGS_REQUEST_OPLOCK
;
476 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
477 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
478 fnum
= io
.ntcreatex
.out
.file
.fnum
;
479 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, EXCLUSIVE_OPLOCK_RETURN
);
481 torture_comment(tctx
, "setpathinfo EOF should trigger a break to none\n");
483 sfi
.generic
.level
= RAW_SFILEINFO_END_OF_FILE_INFORMATION
;
484 sfi
.generic
.in
.file
.path
= fname
;
485 sfi
.end_of_file_info
.in
.size
= 100;
487 status
= smb_raw_setpathinfo(cli2
->tree
, &sfi
);
489 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
490 torture_wait_for_oplock_break(tctx
);
491 CHECK_VAL(break_info
.count
, get_setinfo_break_count(tctx
));
492 CHECK_VAL(break_info
.failures
, 0);
493 CHECK_VAL(break_info
.level
, OPLOCK_BREAK_TO_NONE
);
495 smbcli_close(cli1
->tree
, fnum
);
498 smb_raw_exit(cli1
->session
);
499 smb_raw_exit(cli2
->session
);
500 smbcli_deltree(cli1
->tree
, BASEDIR
);
504 static bool test_raw_oplock_exclusive4(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
506 const char *fname
= BASEDIR
"\\test_exclusive4.dat";
510 uint16_t fnum
=0, fnum2
=0;
512 if (!torture_setup_dir(cli1
, BASEDIR
)) {
517 smbcli_unlink(cli1
->tree
, fname
);
519 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
524 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
525 io
.ntcreatex
.in
.root_fid
.fnum
= 0;
526 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
527 io
.ntcreatex
.in
.alloc_size
= 0;
528 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
529 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
530 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
531 io
.ntcreatex
.in
.create_options
= 0;
532 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
533 io
.ntcreatex
.in
.security_flags
= 0;
534 io
.ntcreatex
.in
.fname
= fname
;
536 torture_comment(tctx
, "EXCLUSIVE4: open with exclusive oplock\n");
537 ZERO_STRUCT(break_info
);
538 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
540 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
| NTCREATEX_FLAGS_REQUEST_OPLOCK
;
541 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
542 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
543 fnum
= io
.ntcreatex
.out
.file
.fnum
;
544 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, EXCLUSIVE_OPLOCK_RETURN
);
546 ZERO_STRUCT(break_info
);
547 torture_comment(tctx
, "second open with attributes only shouldn't cause oplock break\n");
549 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
| NTCREATEX_FLAGS_REQUEST_OPLOCK
;
550 io
.ntcreatex
.in
.access_mask
= SEC_FILE_READ_ATTRIBUTE
|SEC_FILE_WRITE_ATTRIBUTE
|SEC_STD_SYNCHRONIZE
;
551 status
= smb_raw_open(cli2
->tree
, tctx
, &io
);
552 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
553 fnum2
= io
.ntcreatex
.out
.file
.fnum
;
554 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, NO_OPLOCK_RETURN
);
555 torture_wait_for_oplock_break(tctx
);
556 CHECK_VAL(break_info
.count
, 0);
557 CHECK_VAL(break_info
.failures
, 0);
560 * Open another non-stat open. This reproduces bug 10216. Make sure it
561 * won't happen again...
563 io
.ntcreatex
.in
.flags
= 0;
564 io
.ntcreatex
.in
.access_mask
= SEC_FILE_READ_DATA
;
565 status
= smb_raw_open(cli2
->tree
, tctx
, &io
);
566 CHECK_STATUS(tctx
, status
, NT_STATUS_SHARING_VIOLATION
);
567 torture_wait_for_oplock_break(tctx
);
568 CHECK_VAL(break_info
.count
, 0);
569 CHECK_VAL(break_info
.failures
, 0);
571 smbcli_close(cli1
->tree
, fnum
);
572 smbcli_close(cli2
->tree
, fnum2
);
575 smb_raw_exit(cli1
->session
);
576 smb_raw_exit(cli2
->session
);
577 smbcli_deltree(cli1
->tree
, BASEDIR
);
581 static bool test_raw_oplock_exclusive5(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
583 const char *fname
= BASEDIR
"\\test_exclusive5.dat";
587 uint16_t fnum
=0, fnum2
=0;
589 if (!torture_setup_dir(cli1
, BASEDIR
)) {
594 smbcli_unlink(cli1
->tree
, fname
);
596 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
597 smbcli_oplock_handler(cli2
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
602 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
603 io
.ntcreatex
.in
.root_fid
.fnum
= 0;
604 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
605 io
.ntcreatex
.in
.alloc_size
= 0;
606 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
607 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
608 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
609 io
.ntcreatex
.in
.create_options
= 0;
610 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
611 io
.ntcreatex
.in
.security_flags
= 0;
612 io
.ntcreatex
.in
.fname
= fname
;
614 torture_comment(tctx
, "EXCLUSIVE5: open with exclusive oplock\n");
615 ZERO_STRUCT(break_info
);
616 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
619 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
| NTCREATEX_FLAGS_REQUEST_OPLOCK
;
620 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
|
621 NTCREATEX_SHARE_ACCESS_WRITE
|
622 NTCREATEX_SHARE_ACCESS_DELETE
;
623 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
624 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
625 fnum
= io
.ntcreatex
.out
.file
.fnum
;
626 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, EXCLUSIVE_OPLOCK_RETURN
);
628 ZERO_STRUCT(break_info
);
630 torture_comment(tctx
, "second open with attributes only and NTCREATEX_DISP_OVERWRITE_IF dispostion causes oplock break\n");
632 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
| NTCREATEX_FLAGS_REQUEST_OPLOCK
;
633 io
.ntcreatex
.in
.access_mask
= SEC_FILE_READ_ATTRIBUTE
|SEC_FILE_WRITE_ATTRIBUTE
|SEC_STD_SYNCHRONIZE
;
634 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OVERWRITE_IF
;
635 status
= smb_raw_open(cli2
->tree
, tctx
, &io
);
636 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
637 fnum2
= io
.ntcreatex
.out
.file
.fnum
;
638 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, LEVEL_II_OPLOCK_RETURN
);
639 torture_wait_for_oplock_break(tctx
);
640 CHECK_VAL(break_info
.count
, get_break_level1_to_none_count(tctx
));
641 CHECK_VAL(break_info
.level
, OPLOCK_BREAK_TO_NONE
);
642 CHECK_VAL(break_info
.failures
, 0);
644 smbcli_close(cli1
->tree
, fnum
);
645 smbcli_close(cli2
->tree
, fnum2
);
648 smb_raw_exit(cli1
->session
);
649 smb_raw_exit(cli2
->session
);
650 smbcli_deltree(cli1
->tree
, BASEDIR
);
654 static bool test_raw_oplock_exclusive6(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
656 const char *fname1
= BASEDIR
"\\test_exclusive6_1.dat";
657 const char *fname2
= BASEDIR
"\\test_exclusive6_2.dat";
664 if (!torture_setup_dir(cli1
, BASEDIR
)) {
669 smbcli_unlink(cli1
->tree
, fname1
);
670 smbcli_unlink(cli1
->tree
, fname2
);
672 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
677 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
678 io
.ntcreatex
.in
.root_fid
.fnum
= 0;
679 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
680 io
.ntcreatex
.in
.alloc_size
= 0;
681 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
682 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
683 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
684 io
.ntcreatex
.in
.create_options
= 0;
685 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
686 io
.ntcreatex
.in
.security_flags
= 0;
687 io
.ntcreatex
.in
.fname
= fname1
;
689 torture_comment(tctx
, "EXCLUSIVE6: open a file with an exclusive "
690 "oplock (share mode: none)\n");
691 ZERO_STRUCT(break_info
);
692 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
| NTCREATEX_FLAGS_REQUEST_OPLOCK
;
694 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
695 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
696 fnum
= io
.ntcreatex
.out
.file
.fnum
;
697 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, EXCLUSIVE_OPLOCK_RETURN
);
699 torture_comment(tctx
, "rename should not generate a break but get a "
700 "sharing violation\n");
702 rn
.generic
.level
= RAW_RENAME_RENAME
;
703 rn
.rename
.in
.pattern1
= fname1
;
704 rn
.rename
.in
.pattern2
= fname2
;
705 rn
.rename
.in
.attrib
= 0;
707 torture_comment(tctx
, "trying rename while first file open\n");
708 status
= smb_raw_rename(cli2
->tree
, &rn
);
710 CHECK_STATUS(tctx
, status
, NT_STATUS_SHARING_VIOLATION
);
711 torture_wait_for_oplock_break(tctx
);
712 CHECK_VAL(break_info
.count
, 0);
713 CHECK_VAL(break_info
.failures
, 0);
715 smbcli_close(cli1
->tree
, fnum
);
718 smb_raw_exit(cli1
->session
);
719 smb_raw_exit(cli2
->session
);
720 smbcli_deltree(cli1
->tree
, BASEDIR
);
725 * Exclusive version of batch19
727 static bool test_raw_oplock_exclusive7(struct torture_context
*tctx
,
728 struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
730 const char *fname1
= BASEDIR
"\\test_exclusiv6_1.dat";
731 const char *fname2
= BASEDIR
"\\test_exclusiv6_2.dat";
732 const char *fname3
= BASEDIR
"\\test_exclusiv6_3.dat";
736 union smb_fileinfo qfi
;
737 union smb_setfileinfo sfi
;
741 if (!torture_setup_dir(cli1
, BASEDIR
)) {
746 smbcli_unlink(cli1
->tree
, fname1
);
747 smbcli_unlink(cli1
->tree
, fname2
);
748 smbcli_unlink(cli1
->tree
, fname3
);
750 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
,
756 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
757 io
.ntcreatex
.in
.root_fid
.fnum
= 0;
758 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
759 io
.ntcreatex
.in
.alloc_size
= 0;
760 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
761 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
|
762 NTCREATEX_SHARE_ACCESS_WRITE
| NTCREATEX_SHARE_ACCESS_DELETE
;
763 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
764 io
.ntcreatex
.in
.create_options
= 0;
765 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
766 io
.ntcreatex
.in
.security_flags
= 0;
767 io
.ntcreatex
.in
.fname
= fname1
;
769 torture_comment(tctx
, "open a file with an exclusive oplock (share "
771 ZERO_STRUCT(break_info
);
772 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
773 NTCREATEX_FLAGS_REQUEST_OPLOCK
;
774 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
775 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
776 fnum
= io
.ntcreatex
.out
.file
.fnum
;
777 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, EXCLUSIVE_OPLOCK_RETURN
);
779 torture_comment(tctx
, "setpathinfo rename info should trigger a break "
782 sfi
.generic
.level
= RAW_SFILEINFO_RENAME_INFORMATION
;
783 sfi
.generic
.in
.file
.path
= fname1
;
784 sfi
.rename_information
.in
.overwrite
= 0;
785 sfi
.rename_information
.in
.root_fid
= 0;
786 sfi
.rename_information
.in
.new_name
= fname2
+strlen(BASEDIR
)+1;
788 status
= smb_raw_setpathinfo(cli2
->tree
, &sfi
);
789 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
791 torture_wait_for_oplock_break(tctx
);
792 CHECK_VAL(break_info
.failures
, 0);
794 if (TARGET_IS_WINXP(tctx
) || TARGET_IS_W2K12(tctx
)) {
795 /* XP incorrectly breaks to level2. */
796 CHECK_VAL(break_info
.count
, 1);
797 CHECK_VAL(break_info
.level
, OPLOCK_BREAK_TO_LEVEL_II
);
799 /* Exclusive oplocks should not be broken on rename. */
800 CHECK_VAL(break_info
.failures
, 0);
801 CHECK_VAL(break_info
.count
, 0);
805 qfi
.generic
.level
= RAW_FILEINFO_ALL_INFORMATION
;
806 qfi
.generic
.in
.file
.fnum
= fnum
;
808 status
= smb_raw_fileinfo(cli1
->tree
, tctx
, &qfi
);
809 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
810 CHECK_STRMATCH(qfi
.all_info
.out
.fname
.s
, fname2
);
812 /* Try breaking to level2 and then see if rename breaks the level2.*/
813 ZERO_STRUCT(break_info
);
814 io
.ntcreatex
.in
.fname
= fname2
;
815 status
= smb_raw_open(cli2
->tree
, tctx
, &io
);
816 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
817 fnum2
= io
.ntcreatex
.out
.file
.fnum
;
818 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, LEVEL_II_OPLOCK_RETURN
);
820 torture_wait_for_oplock_break(tctx
);
821 CHECK_VAL(break_info
.failures
, 0);
823 if (TARGET_IS_WINXP(tctx
)) {
824 /* XP already broke to level2. */
825 CHECK_VAL(break_info
.failures
, 0);
826 CHECK_VAL(break_info
.count
, 0);
827 } else if (TARGET_IS_W2K12(tctx
)) {
829 CHECK_VAL(break_info
.count
, 0);
830 CHECK_VAL(break_info
.level
, 0);
832 /* Break to level 2 expected. */
833 CHECK_VAL(break_info
.count
, 1);
834 CHECK_VAL(break_info
.level
, OPLOCK_BREAK_TO_LEVEL_II
);
837 ZERO_STRUCT(break_info
);
838 sfi
.generic
.in
.file
.path
= fname2
;
839 sfi
.rename_information
.in
.overwrite
= 0;
840 sfi
.rename_information
.in
.root_fid
= 0;
841 sfi
.rename_information
.in
.new_name
= fname1
+strlen(BASEDIR
)+1;
843 status
= smb_raw_setpathinfo(cli2
->tree
, &sfi
);
844 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
846 /* Level2 oplocks are not broken on rename. */
847 torture_wait_for_oplock_break(tctx
);
848 CHECK_VAL(break_info
.failures
, 0);
849 CHECK_VAL(break_info
.count
, 0);
851 /* Close and re-open file with oplock. */
852 smbcli_close(cli1
->tree
, fnum
);
853 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
854 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
855 fnum
= io
.ntcreatex
.out
.file
.fnum
;
856 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, EXCLUSIVE_OPLOCK_RETURN
);
858 torture_comment(tctx
, "setfileinfo rename info on a client's own fid "
859 "should not trigger a break nor a violation\n");
860 ZERO_STRUCT(break_info
);
862 sfi
.generic
.level
= RAW_SFILEINFO_RENAME_INFORMATION
;
863 sfi
.generic
.in
.file
.fnum
= fnum
;
864 sfi
.rename_information
.in
.overwrite
= 0;
865 sfi
.rename_information
.in
.root_fid
= 0;
866 sfi
.rename_information
.in
.new_name
= fname3
+strlen(BASEDIR
)+1;
868 status
= smb_raw_setfileinfo(cli1
->tree
, &sfi
);
869 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
871 torture_wait_for_oplock_break(tctx
);
872 if (TARGET_IS_WINXP(tctx
)) {
873 /* XP incorrectly breaks to level2. */
874 CHECK_VAL(break_info
.count
, 1);
875 CHECK_VAL(break_info
.level
, OPLOCK_BREAK_TO_LEVEL_II
);
877 CHECK_VAL(break_info
.count
, 0);
881 qfi
.generic
.level
= RAW_FILEINFO_ALL_INFORMATION
;
882 qfi
.generic
.in
.file
.fnum
= fnum
;
884 status
= smb_raw_fileinfo(cli1
->tree
, tctx
, &qfi
);
885 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
886 CHECK_STRMATCH(qfi
.all_info
.out
.fname
.s
, fname3
);
889 smbcli_close(cli1
->tree
, fnum
);
890 smbcli_close(cli2
->tree
, fnum2
);
892 smb_raw_exit(cli1
->session
);
893 smb_raw_exit(cli2
->session
);
894 smbcli_deltree(cli1
->tree
, BASEDIR
);
898 static bool test_raw_oplock_exclusive8(struct torture_context
*tctx
,
899 struct smbcli_state
*cli1
,
900 struct smbcli_state
*cli2
)
902 const char *fname
= BASEDIR
"\\test_exclusive8.dat";
910 if (!torture_setup_dir(cli1
, BASEDIR
)) {
915 smbcli_unlink(cli1
->tree
, fname
);
917 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
,
923 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
924 io
.ntcreatex
.in
.root_fid
.fnum
= 0;
925 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
926 io
.ntcreatex
.in
.alloc_size
= 0;
927 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
928 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
|
929 NTCREATEX_SHARE_ACCESS_WRITE
| NTCREATEX_SHARE_ACCESS_DELETE
;
930 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
931 io
.ntcreatex
.in
.create_options
= 0;
932 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
933 io
.ntcreatex
.in
.security_flags
= 0;
934 io
.ntcreatex
.in
.fname
= fname
;
936 torture_comment(tctx
, "open a file with an exclusive oplock (share "
938 ZERO_STRUCT(break_info
);
939 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
940 NTCREATEX_FLAGS_REQUEST_OPLOCK
;
941 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
942 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
943 fnum1
= io
.ntcreatex
.out
.file
.fnum
;
944 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, EXCLUSIVE_OPLOCK_RETURN
);
946 torture_comment(tctx
, "second open with delete should trigger a "
949 io
.ntcreatex
.in
.access_mask
= SEC_STD_DELETE
;
950 io
.ntcreatex
.in
.flags
= 0;
951 status
= smb_raw_open(cli2
->tree
, tctx
, &io
);
952 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
953 fnum2
= io
.ntcreatex
.out
.file
.fnum
;
954 CHECK_VAL(break_info
.count
, get_break_level1_to_none_count(tctx
));
955 CHECK_VAL(break_info
.failures
, 0);
956 CHECK_VAL(break_info
.level
, OPLOCK_BREAK_TO_LEVEL_II
);
958 /* Trigger a little panic in "old" samba code.. */
959 status
= smb_raw_open(cli2
->tree
, tctx
, &io
);
960 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
961 fnum3
= io
.ntcreatex
.out
.file
.fnum
;
963 smbcli_close(cli2
->tree
, fnum3
);
964 smbcli_close(cli2
->tree
, fnum2
);
965 smbcli_close(cli1
->tree
, fnum1
);
968 smbcli_deltree(cli1
->tree
, BASEDIR
);
969 smb_raw_exit(cli1
->session
);
970 smb_raw_exit(cli2
->session
);
974 static bool test_raw_oplock_exclusive9(struct torture_context
*tctx
,
975 struct smbcli_state
*cli1
,
976 struct smbcli_state
*cli2
)
978 const char *fname
= BASEDIR
"\\test_exclusive9.dat";
982 uint16_t fnum
=0, fnum2
=0;
986 uint32_t create_disposition
;
987 uint32_t break_level
;
989 { NTCREATEX_DISP_SUPERSEDE
, OPLOCK_BREAK_TO_NONE
},
990 { NTCREATEX_DISP_OPEN
, OPLOCK_BREAK_TO_LEVEL_II
},
991 { NTCREATEX_DISP_OVERWRITE_IF
, OPLOCK_BREAK_TO_NONE
},
992 { NTCREATEX_DISP_OPEN_IF
, OPLOCK_BREAK_TO_LEVEL_II
},
995 if (!torture_setup_dir(cli1
, BASEDIR
)) {
1000 smbcli_unlink(cli1
->tree
, fname
);
1002 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
,
1004 smbcli_oplock_handler(cli2
->transport
, oplock_handler_ack_to_given
,
1008 base ntcreatex parms
1010 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
1011 io
.ntcreatex
.in
.root_fid
.fnum
= 0;
1012 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
1013 io
.ntcreatex
.in
.alloc_size
= 0;
1014 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
1015 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
1016 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
1017 io
.ntcreatex
.in
.create_options
= 0;
1018 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
1019 io
.ntcreatex
.in
.security_flags
= 0;
1020 io
.ntcreatex
.in
.fname
= fname
;
1022 ZERO_STRUCT(break_info
);
1023 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
,
1026 for (i
=0; i
<ARRAY_SIZE(levels
); i
++) {
1028 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
1029 NTCREATEX_FLAGS_REQUEST_OPLOCK
;
1030 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
|
1031 NTCREATEX_SHARE_ACCESS_WRITE
|
1032 NTCREATEX_SHARE_ACCESS_DELETE
;
1033 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
1034 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
1035 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
1036 fnum
= io
.ntcreatex
.out
.file
.fnum
;
1037 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
,
1038 EXCLUSIVE_OPLOCK_RETURN
);
1040 ZERO_STRUCT(break_info
);
1042 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
1043 NTCREATEX_FLAGS_REQUEST_OPLOCK
;
1044 io
.ntcreatex
.in
.access_mask
= SEC_FILE_READ_DATA
;
1045 io
.ntcreatex
.in
.open_disposition
=
1046 levels
[i
].create_disposition
;
1047 status
= smb_raw_open(cli2
->tree
, tctx
, &io
);
1048 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
1049 fnum2
= io
.ntcreatex
.out
.file
.fnum
;
1050 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
,
1051 LEVEL_II_OPLOCK_RETURN
);
1052 torture_wait_for_oplock_break(tctx
);
1053 CHECK_VAL(break_info
.count
, 1);
1054 CHECK_VAL(break_info
.level
, levels
[i
].break_level
);
1055 CHECK_VAL(break_info
.failures
, 0);
1057 smbcli_close(cli1
->tree
, fnum
);
1058 smbcli_close(cli2
->tree
, fnum2
);
1062 smb_raw_exit(cli1
->session
);
1063 smb_raw_exit(cli2
->session
);
1064 smbcli_deltree(cli1
->tree
, BASEDIR
);
1068 static bool test_raw_oplock_level_ii_1(struct torture_context
*tctx
,
1069 struct smbcli_state
*cli1
,
1070 struct smbcli_state
*cli2
)
1072 const char *fname
= BASEDIR
"\\test_level_ii_1.dat";
1076 uint16_t fnum
=0, fnum2
=0;
1080 if (!torture_setup_dir(cli1
, BASEDIR
)) {
1085 smbcli_unlink(cli1
->tree
, fname
);
1087 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
,
1089 smbcli_oplock_handler(cli2
->transport
, oplock_handler_ack_to_given
,
1093 base ntcreatex parms
1095 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
1096 io
.ntcreatex
.in
.root_fid
.fnum
= 0;
1097 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
1098 io
.ntcreatex
.in
.alloc_size
= 0;
1099 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
1100 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
1101 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
1102 io
.ntcreatex
.in
.create_options
= 0;
1103 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
1104 io
.ntcreatex
.in
.security_flags
= 0;
1105 io
.ntcreatex
.in
.fname
= fname
;
1107 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
1108 NTCREATEX_FLAGS_REQUEST_OPLOCK
;
1109 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
|
1110 NTCREATEX_SHARE_ACCESS_WRITE
|
1111 NTCREATEX_SHARE_ACCESS_DELETE
;
1112 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
1113 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
1114 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
1115 fnum
= io
.ntcreatex
.out
.file
.fnum
;
1116 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, EXCLUSIVE_OPLOCK_RETURN
);
1118 ZERO_STRUCT(break_info
);
1120 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
1121 NTCREATEX_FLAGS_REQUEST_OPLOCK
;
1122 io
.ntcreatex
.in
.access_mask
= SEC_FILE_READ_DATA
|SEC_FILE_WRITE_DATA
;
1123 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
1124 status
= smb_raw_open(cli2
->tree
, tctx
, &io
);
1125 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
1126 fnum2
= io
.ntcreatex
.out
.file
.fnum
;
1127 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, LEVEL_II_OPLOCK_RETURN
);
1128 torture_wait_for_oplock_break(tctx
);
1129 CHECK_VAL(break_info
.count
, 1);
1130 CHECK_VAL(break_info
.level
, OPLOCK_BREAK_TO_LEVEL_II
);
1131 CHECK_VAL(break_info
.failures
, 0);
1133 status
= smbcli_close(cli2
->tree
, fnum2
);
1134 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
1137 * fnum1 has a level2 oplock now
1140 ZERO_STRUCT(break_info
);
1143 * Don't answer the break to none that will come in
1146 smbcli_oplock_handler(cli1
->transport
, oplock_handler_timeout
,
1149 io
.ntcreatex
.in
.flags
= 0;
1150 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OVERWRITE_IF
;
1152 status
= smb_raw_open(cli2
->tree
, tctx
, &io
);
1153 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
1154 fnum2
= io
.ntcreatex
.out
.file
.fnum
;
1155 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, NO_OPLOCK_RETURN
);
1156 torture_wait_for_oplock_break(tctx
);
1157 CHECK_VAL(break_info
.count
, 1);
1158 CHECK_VAL(break_info
.level
, OPLOCK_BREAK_TO_NONE
);
1159 CHECK_VAL(break_info
.failures
, 0);
1162 * Check that a write does not cause another break. This used to be a
1166 ZERO_STRUCT(break_info
);
1167 written
= smbcli_write(cli2
->tree
, fnum2
, 0, &c
, 0, 1);
1168 CHECK_VAL(written
, 1);
1169 torture_wait_for_oplock_break(tctx
);
1170 CHECK_VAL(break_info
.count
, 0);
1171 CHECK_VAL(break_info
.failures
, 0);
1173 status
= smbcli_close(cli2
->tree
, fnum2
);
1174 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
1175 status
= smbcli_close(cli1
->tree
, fnum
);
1176 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
1179 smb_raw_exit(cli1
->session
);
1180 smb_raw_exit(cli2
->session
);
1181 smbcli_deltree(cli1
->tree
, BASEDIR
);
1185 static bool test_raw_oplock_batch1(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
1187 const char *fname
= BASEDIR
"\\test_batch1.dat";
1191 union smb_unlink unl
;
1195 if (!torture_setup_dir(cli1
, BASEDIR
)) {
1200 smbcli_unlink(cli1
->tree
, fname
);
1202 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
1205 base ntcreatex parms
1207 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
1208 io
.ntcreatex
.in
.root_fid
.fnum
= 0;
1209 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
1210 io
.ntcreatex
.in
.alloc_size
= 0;
1211 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
1212 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
1213 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
1214 io
.ntcreatex
.in
.create_options
= 0;
1215 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
1216 io
.ntcreatex
.in
.security_flags
= 0;
1217 io
.ntcreatex
.in
.fname
= fname
;
1220 with a batch oplock we get a break
1222 torture_comment(tctx
, "BATCH1: open with batch oplock\n");
1223 ZERO_STRUCT(break_info
);
1224 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
1225 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
1226 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
1227 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
1228 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
1229 fnum
= io
.ntcreatex
.out
.file
.fnum
;
1230 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, BATCH_OPLOCK_RETURN
);
1232 torture_comment(tctx
, "unlink should generate a break\n");
1233 unl
.unlink
.in
.pattern
= fname
;
1234 unl
.unlink
.in
.attrib
= 0;
1235 status
= smb_raw_unlink(cli2
->tree
, &unl
);
1236 CHECK_STATUS(tctx
, status
, NT_STATUS_SHARING_VIOLATION
);
1238 torture_wait_for_oplock_break(tctx
);
1239 CHECK_VAL(break_info
.count
, 1);
1240 CHECK_VAL(break_info
.fnum
, fnum
);
1241 CHECK_VAL(break_info
.level
, OPLOCK_BREAK_TO_LEVEL_II
);
1242 CHECK_VAL(break_info
.failures
, 0);
1244 torture_comment(tctx
, "2nd unlink should not generate a break\n");
1245 ZERO_STRUCT(break_info
);
1246 status
= smb_raw_unlink(cli2
->tree
, &unl
);
1247 CHECK_STATUS(tctx
, status
, NT_STATUS_SHARING_VIOLATION
);
1249 torture_wait_for_oplock_break(tctx
);
1250 CHECK_VAL(break_info
.count
, 0);
1252 torture_comment(tctx
, "writing should generate a self break to none\n");
1253 smbcli_write(cli1
->tree
, fnum
, 0, &c
, 0, 1);
1255 torture_wait_for_oplock_break(tctx
);
1256 torture_wait_for_oplock_break(tctx
);
1257 CHECK_VAL(break_info
.count
, 1);
1258 CHECK_VAL(break_info
.fnum
, fnum
);
1259 CHECK_VAL(break_info
.level
, OPLOCK_BREAK_TO_NONE
);
1260 CHECK_VAL(break_info
.failures
, 0);
1262 smbcli_close(cli1
->tree
, fnum
);
1265 smb_raw_exit(cli1
->session
);
1266 smb_raw_exit(cli2
->session
);
1267 smbcli_deltree(cli1
->tree
, BASEDIR
);
1271 static bool test_raw_oplock_batch2(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
1273 const char *fname
= BASEDIR
"\\test_batch2.dat";
1277 union smb_unlink unl
;
1281 if (!torture_setup_dir(cli1
, BASEDIR
)) {
1286 smbcli_unlink(cli1
->tree
, fname
);
1288 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
1291 base ntcreatex parms
1293 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
1294 io
.ntcreatex
.in
.root_fid
.fnum
= 0;
1295 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
1296 io
.ntcreatex
.in
.alloc_size
= 0;
1297 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
1298 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
1299 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
1300 io
.ntcreatex
.in
.create_options
= 0;
1301 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
1302 io
.ntcreatex
.in
.security_flags
= 0;
1303 io
.ntcreatex
.in
.fname
= fname
;
1305 torture_comment(tctx
, "BATCH2: open with batch oplock\n");
1306 ZERO_STRUCT(break_info
);
1307 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
1308 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
1309 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
1310 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
1311 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
1312 fnum
= io
.ntcreatex
.out
.file
.fnum
;
1313 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, BATCH_OPLOCK_RETURN
);
1315 torture_comment(tctx
, "unlink should generate a break, which we ack as break to none\n");
1316 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_none
, cli1
->tree
);
1317 unl
.unlink
.in
.pattern
= fname
;
1318 unl
.unlink
.in
.attrib
= 0;
1319 status
= smb_raw_unlink(cli2
->tree
, &unl
);
1320 CHECK_STATUS(tctx
, status
, NT_STATUS_SHARING_VIOLATION
);
1322 torture_wait_for_oplock_break(tctx
);
1323 CHECK_VAL(break_info
.count
, 1);
1324 CHECK_VAL(break_info
.fnum
, fnum
);
1325 CHECK_VAL(break_info
.level
, OPLOCK_BREAK_TO_LEVEL_II
);
1326 CHECK_VAL(break_info
.failures
, 0);
1328 torture_comment(tctx
, "2nd unlink should not generate a break\n");
1329 ZERO_STRUCT(break_info
);
1330 status
= smb_raw_unlink(cli2
->tree
, &unl
);
1331 CHECK_STATUS(tctx
, status
, NT_STATUS_SHARING_VIOLATION
);
1333 torture_wait_for_oplock_break(tctx
);
1334 CHECK_VAL(break_info
.count
, 0);
1336 torture_comment(tctx
, "writing should not generate a break\n");
1337 smbcli_write(cli1
->tree
, fnum
, 0, &c
, 0, 1);
1339 torture_wait_for_oplock_break(tctx
);
1340 CHECK_VAL(break_info
.count
, 0);
1342 smbcli_close(cli1
->tree
, fnum
);
1345 smb_raw_exit(cli1
->session
);
1346 smb_raw_exit(cli2
->session
);
1347 smbcli_deltree(cli1
->tree
, BASEDIR
);
1351 static bool test_raw_oplock_batch3(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
1353 const char *fname
= BASEDIR
"\\test_batch3.dat";
1357 union smb_unlink unl
;
1360 if (!torture_setup_dir(cli1
, BASEDIR
)) {
1365 smbcli_unlink(cli1
->tree
, fname
);
1367 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
1370 base ntcreatex parms
1372 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
1373 io
.ntcreatex
.in
.root_fid
.fnum
= 0;
1374 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
1375 io
.ntcreatex
.in
.alloc_size
= 0;
1376 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
1377 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
1378 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
1379 io
.ntcreatex
.in
.create_options
= 0;
1380 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
1381 io
.ntcreatex
.in
.security_flags
= 0;
1382 io
.ntcreatex
.in
.fname
= fname
;
1384 torture_comment(tctx
, "BATCH3: if we close on break then the unlink can succeed\n");
1385 ZERO_STRUCT(break_info
);
1386 smbcli_oplock_handler(cli1
->transport
, oplock_handler_close
, cli1
->tree
);
1387 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
1388 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
1389 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
1390 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
1391 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
1392 fnum
= io
.ntcreatex
.out
.file
.fnum
;
1393 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, BATCH_OPLOCK_RETURN
);
1395 unl
.unlink
.in
.pattern
= fname
;
1396 unl
.unlink
.in
.attrib
= 0;
1397 ZERO_STRUCT(break_info
);
1398 status
= smb_raw_unlink(cli2
->tree
, &unl
);
1399 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
1401 torture_wait_for_oplock_break(tctx
);
1402 CHECK_VAL(break_info
.count
, 1);
1403 CHECK_VAL(break_info
.fnum
, fnum
);
1404 CHECK_VAL(break_info
.level
, 1);
1405 CHECK_VAL(break_info
.failures
, 0);
1407 smbcli_close(cli1
->tree
, fnum
);
1410 smb_raw_exit(cli1
->session
);
1411 smb_raw_exit(cli2
->session
);
1412 smbcli_deltree(cli1
->tree
, BASEDIR
);
1416 static bool test_raw_oplock_batch4(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
1418 const char *fname
= BASEDIR
"\\test_batch4.dat";
1425 if (!torture_setup_dir(cli1
, BASEDIR
)) {
1430 smbcli_unlink(cli1
->tree
, fname
);
1432 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
1435 base ntcreatex parms
1437 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
1438 io
.ntcreatex
.in
.root_fid
.fnum
= 0;
1439 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
1440 io
.ntcreatex
.in
.alloc_size
= 0;
1441 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
1442 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
1443 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
1444 io
.ntcreatex
.in
.create_options
= 0;
1445 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
1446 io
.ntcreatex
.in
.security_flags
= 0;
1447 io
.ntcreatex
.in
.fname
= fname
;
1449 torture_comment(tctx
, "BATCH4: a self read should not cause a break\n");
1450 ZERO_STRUCT(break_info
);
1451 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
1453 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
1454 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
1455 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
1456 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
1457 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
1458 fnum
= io
.ntcreatex
.out
.file
.fnum
;
1459 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, BATCH_OPLOCK_RETURN
);
1461 rd
.readx
.level
= RAW_READ_READX
;
1462 rd
.readx
.in
.file
.fnum
= fnum
;
1463 rd
.readx
.in
.mincnt
= 1;
1464 rd
.readx
.in
.maxcnt
= 1;
1465 rd
.readx
.in
.offset
= 0;
1466 rd
.readx
.in
.remaining
= 0;
1467 rd
.readx
.in
.read_for_execute
= false;
1468 status
= smb_raw_read(cli1
->tree
, &rd
);
1469 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
1470 torture_wait_for_oplock_break(tctx
);
1471 CHECK_VAL(break_info
.count
, 0);
1472 CHECK_VAL(break_info
.failures
, 0);
1474 smbcli_close(cli1
->tree
, fnum
);
1477 smb_raw_exit(cli1
->session
);
1478 smb_raw_exit(cli2
->session
);
1479 smbcli_deltree(cli1
->tree
, BASEDIR
);
1483 static bool test_raw_oplock_batch5(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
1485 const char *fname
= BASEDIR
"\\test_batch5.dat";
1491 if (!torture_setup_dir(cli1
, BASEDIR
)) {
1496 smbcli_unlink(cli1
->tree
, fname
);
1498 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
1501 base ntcreatex parms
1503 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
1504 io
.ntcreatex
.in
.root_fid
.fnum
= 0;
1505 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
1506 io
.ntcreatex
.in
.alloc_size
= 0;
1507 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
1508 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
1509 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
1510 io
.ntcreatex
.in
.create_options
= 0;
1511 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
1512 io
.ntcreatex
.in
.security_flags
= 0;
1513 io
.ntcreatex
.in
.fname
= fname
;
1515 torture_comment(tctx
, "BATCH5: a 2nd open should give a break\n");
1516 ZERO_STRUCT(break_info
);
1517 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
1519 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
1520 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
1521 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
1522 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
1523 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
1524 fnum
= io
.ntcreatex
.out
.file
.fnum
;
1525 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, BATCH_OPLOCK_RETURN
);
1527 ZERO_STRUCT(break_info
);
1529 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
;
1530 status
= smb_raw_open(cli2
->tree
, tctx
, &io
);
1531 CHECK_STATUS(tctx
, status
, NT_STATUS_SHARING_VIOLATION
);
1533 torture_wait_for_oplock_break(tctx
);
1534 CHECK_VAL(break_info
.count
, 1);
1535 CHECK_VAL(break_info
.fnum
, fnum
);
1536 CHECK_VAL(break_info
.level
, 1);
1537 CHECK_VAL(break_info
.failures
, 0);
1539 smbcli_close(cli1
->tree
, fnum
);
1542 smb_raw_exit(cli1
->session
);
1543 smb_raw_exit(cli2
->session
);
1544 smbcli_deltree(cli1
->tree
, BASEDIR
);
1548 static bool test_raw_oplock_batch6(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
1550 const char *fname
= BASEDIR
"\\test_batch6.dat";
1554 uint16_t fnum
=0, fnum2
=0;
1557 if (!torture_setup_dir(cli1
, BASEDIR
)) {
1562 smbcli_unlink(cli1
->tree
, fname
);
1564 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
1565 smbcli_oplock_handler(cli2
->transport
, oplock_handler_ack_to_given
, cli2
->tree
);
1568 base ntcreatex parms
1570 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
1571 io
.ntcreatex
.in
.root_fid
.fnum
= 0;
1572 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
1573 io
.ntcreatex
.in
.alloc_size
= 0;
1574 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
1575 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
1576 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
1577 io
.ntcreatex
.in
.create_options
= 0;
1578 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
1579 io
.ntcreatex
.in
.security_flags
= 0;
1580 io
.ntcreatex
.in
.fname
= fname
;
1582 torture_comment(tctx
, "BATCH6: a 2nd open should give a break to level II if the first open allowed shared read\n");
1583 ZERO_STRUCT(break_info
);
1585 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_READ
| SEC_RIGHTS_FILE_WRITE
;
1586 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
| NTCREATEX_SHARE_ACCESS_WRITE
;
1587 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
1588 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
1589 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
1590 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
1591 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
1592 fnum
= io
.ntcreatex
.out
.file
.fnum
;
1593 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, BATCH_OPLOCK_RETURN
);
1595 ZERO_STRUCT(break_info
);
1597 status
= smb_raw_open(cli2
->tree
, tctx
, &io
);
1598 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
1599 fnum2
= io
.ntcreatex
.out
.file
.fnum
;
1600 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, LEVEL_II_OPLOCK_RETURN
);
1602 //torture_wait_for_oplock_break(tctx);
1603 CHECK_VAL(break_info
.count
, 1);
1604 CHECK_VAL(break_info
.fnum
, fnum
);
1605 CHECK_VAL(break_info
.level
, 1);
1606 CHECK_VAL(break_info
.failures
, 0);
1607 ZERO_STRUCT(break_info
);
1609 torture_comment(tctx
, "write should trigger a break to none on both\n");
1610 smbcli_write(cli1
->tree
, fnum
, 0, &c
, 0, 1);
1612 /* We expect two breaks */
1613 torture_wait_for_oplock_break(tctx
);
1614 torture_wait_for_oplock_break(tctx
);
1616 CHECK_VAL(break_info
.count
, 2);
1617 CHECK_VAL(break_info
.level
, 0);
1618 CHECK_VAL(break_info
.failures
, 0);
1620 smbcli_close(cli1
->tree
, fnum
);
1621 smbcli_close(cli2
->tree
, fnum2
);
1624 smb_raw_exit(cli1
->session
);
1625 smb_raw_exit(cli2
->session
);
1626 smbcli_deltree(cli1
->tree
, BASEDIR
);
1630 static bool test_raw_oplock_batch7(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
1632 const char *fname
= BASEDIR
"\\test_batch7.dat";
1636 uint16_t fnum
=0, fnum2
=0;
1638 if (!torture_setup_dir(cli1
, BASEDIR
)) {
1643 smbcli_unlink(cli1
->tree
, fname
);
1645 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
1648 base ntcreatex parms
1650 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
1651 io
.ntcreatex
.in
.root_fid
.fnum
= 0;
1652 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
1653 io
.ntcreatex
.in
.alloc_size
= 0;
1654 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
1655 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
1656 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
1657 io
.ntcreatex
.in
.create_options
= 0;
1658 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
1659 io
.ntcreatex
.in
.security_flags
= 0;
1660 io
.ntcreatex
.in
.fname
= fname
;
1662 torture_comment(tctx
, "BATCH7: a 2nd open should get an oplock when we close instead of ack\n");
1663 ZERO_STRUCT(break_info
);
1664 smbcli_oplock_handler(cli1
->transport
, oplock_handler_close
, cli1
->tree
);
1666 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
1667 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
1668 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
1669 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
1670 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
1671 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
1672 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
1673 fnum2
= io
.ntcreatex
.out
.file
.fnum
;
1674 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, BATCH_OPLOCK_RETURN
);
1676 ZERO_STRUCT(break_info
);
1678 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
1679 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
1680 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
1681 status
= smb_raw_open(cli2
->tree
, tctx
, &io
);
1682 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
1683 fnum
= io
.ntcreatex
.out
.file
.fnum
;
1684 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, BATCH_OPLOCK_RETURN
);
1686 torture_wait_for_oplock_break(tctx
);
1687 CHECK_VAL(break_info
.count
, 1);
1688 CHECK_VAL(break_info
.fnum
, fnum2
);
1689 CHECK_VAL(break_info
.level
, 1);
1690 CHECK_VAL(break_info
.failures
, 0);
1692 smbcli_close(cli2
->tree
, fnum
);
1695 smb_raw_exit(cli1
->session
);
1696 smb_raw_exit(cli2
->session
);
1697 smbcli_deltree(cli1
->tree
, BASEDIR
);
1701 static bool test_raw_oplock_batch8(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
1703 const char *fname
= BASEDIR
"\\test_batch8.dat";
1707 uint16_t fnum
=0, fnum2
=0;
1709 if (!torture_setup_dir(cli1
, BASEDIR
)) {
1714 smbcli_unlink(cli1
->tree
, fname
);
1716 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
1719 base ntcreatex parms
1721 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
1722 io
.ntcreatex
.in
.root_fid
.fnum
= 0;
1723 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
1724 io
.ntcreatex
.in
.alloc_size
= 0;
1725 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
1726 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
1727 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
1728 io
.ntcreatex
.in
.create_options
= 0;
1729 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
1730 io
.ntcreatex
.in
.security_flags
= 0;
1731 io
.ntcreatex
.in
.fname
= fname
;
1733 torture_comment(tctx
, "BATCH8: open with batch oplock\n");
1734 ZERO_STRUCT(break_info
);
1735 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
1737 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
1738 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
1739 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
1740 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
1741 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
1742 fnum
= io
.ntcreatex
.out
.file
.fnum
;
1743 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, BATCH_OPLOCK_RETURN
);
1745 ZERO_STRUCT(break_info
);
1746 torture_comment(tctx
, "second open with attributes only shouldn't cause oplock break\n");
1748 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
1749 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
1750 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
1751 io
.ntcreatex
.in
.access_mask
= SEC_FILE_READ_ATTRIBUTE
|SEC_FILE_WRITE_ATTRIBUTE
|SEC_STD_SYNCHRONIZE
;
1752 status
= smb_raw_open(cli2
->tree
, tctx
, &io
);
1753 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
1754 fnum2
= io
.ntcreatex
.out
.file
.fnum
;
1755 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, NO_OPLOCK_RETURN
);
1756 torture_wait_for_oplock_break(tctx
);
1757 CHECK_VAL(break_info
.count
, 0);
1758 CHECK_VAL(break_info
.failures
, 0);
1760 smbcli_close(cli1
->tree
, fnum
);
1761 smbcli_close(cli2
->tree
, fnum2
);
1764 smb_raw_exit(cli1
->session
);
1765 smb_raw_exit(cli2
->session
);
1766 smbcli_deltree(cli1
->tree
, BASEDIR
);
1770 static bool test_raw_oplock_batch9(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
1772 const char *fname
= BASEDIR
"\\test_batch9.dat";
1776 uint16_t fnum
=0, fnum2
=0;
1779 if (!torture_setup_dir(cli1
, BASEDIR
)) {
1784 smbcli_unlink(cli1
->tree
, fname
);
1786 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
1789 base ntcreatex parms
1791 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
1792 io
.ntcreatex
.in
.root_fid
.fnum
= 0;
1793 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
1794 io
.ntcreatex
.in
.alloc_size
= 0;
1795 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
1796 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
1797 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
1798 io
.ntcreatex
.in
.create_options
= 0;
1799 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
1800 io
.ntcreatex
.in
.security_flags
= 0;
1801 io
.ntcreatex
.in
.fname
= fname
;
1803 torture_comment(tctx
, "BATCH9: open with attributes only can create file\n");
1805 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
1806 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
1807 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
1808 io
.ntcreatex
.in
.access_mask
= SEC_FILE_READ_ATTRIBUTE
|SEC_FILE_WRITE_ATTRIBUTE
|SEC_STD_SYNCHRONIZE
;
1809 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_CREATE
;
1810 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
1811 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
1812 fnum
= io
.ntcreatex
.out
.file
.fnum
;
1813 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, BATCH_OPLOCK_RETURN
);
1815 torture_comment(tctx
, "Subsequent normal open should break oplock on attribute only open to level II\n");
1817 ZERO_STRUCT(break_info
);
1818 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
1820 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
1821 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
1822 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
1823 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
1824 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN
;
1825 status
= smb_raw_open(cli2
->tree
, tctx
, &io
);
1826 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
1827 fnum2
= io
.ntcreatex
.out
.file
.fnum
;
1828 torture_wait_for_oplock_break(tctx
);
1829 CHECK_VAL(break_info
.count
, 1);
1830 CHECK_VAL(break_info
.fnum
, fnum
);
1831 CHECK_VAL(break_info
.failures
, 0);
1832 CHECK_VAL(break_info
.level
, OPLOCK_BREAK_TO_LEVEL_II
);
1833 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, LEVEL_II_OPLOCK_RETURN
);
1834 smbcli_close(cli2
->tree
, fnum2
);
1836 torture_comment(tctx
, "third oplocked open should grant level2 without break\n");
1837 ZERO_STRUCT(break_info
);
1838 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
1839 smbcli_oplock_handler(cli2
->transport
, oplock_handler_ack_to_given
, cli2
->tree
);
1840 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
1841 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
1842 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
1843 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
1844 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN
;
1845 status
= smb_raw_open(cli2
->tree
, tctx
, &io
);
1846 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
1847 fnum2
= io
.ntcreatex
.out
.file
.fnum
;
1848 torture_wait_for_oplock_break(tctx
);
1849 CHECK_VAL(break_info
.count
, 0);
1850 CHECK_VAL(break_info
.failures
, 0);
1851 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, LEVEL_II_OPLOCK_RETURN
);
1853 ZERO_STRUCT(break_info
);
1855 torture_comment(tctx
, "write should trigger a break to none on both\n");
1856 smbcli_write(cli2
->tree
, fnum2
, 0, &c
, 0, 1);
1858 /* We expect two breaks */
1859 torture_wait_for_oplock_break(tctx
);
1860 torture_wait_for_oplock_break(tctx
);
1862 CHECK_VAL(break_info
.count
, 2);
1863 CHECK_VAL(break_info
.level
, 0);
1864 CHECK_VAL(break_info
.failures
, 0);
1866 smbcli_close(cli1
->tree
, fnum
);
1867 smbcli_close(cli2
->tree
, fnum2
);
1870 smb_raw_exit(cli1
->session
);
1871 smb_raw_exit(cli2
->session
);
1872 smbcli_deltree(cli1
->tree
, BASEDIR
);
1876 static bool test_raw_oplock_batch10(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
1878 const char *fname
= BASEDIR
"\\test_batch10.dat";
1882 uint16_t fnum
=0, fnum2
=0;
1884 if (!torture_setup_dir(cli1
, BASEDIR
)) {
1889 smbcli_unlink(cli1
->tree
, fname
);
1891 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
1894 base ntcreatex parms
1896 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
1897 io
.ntcreatex
.in
.root_fid
.fnum
= 0;
1898 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
1899 io
.ntcreatex
.in
.alloc_size
= 0;
1900 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
1901 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
1902 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
1903 io
.ntcreatex
.in
.create_options
= 0;
1904 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
1905 io
.ntcreatex
.in
.security_flags
= 0;
1906 io
.ntcreatex
.in
.fname
= fname
;
1908 torture_comment(tctx
, "BATCH10: Open with oplock after a non-oplock open should grant level2\n");
1909 ZERO_STRUCT(break_info
);
1910 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
;
1911 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
1912 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
|
1913 NTCREATEX_SHARE_ACCESS_WRITE
|
1914 NTCREATEX_SHARE_ACCESS_DELETE
;
1915 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
1916 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
1917 fnum
= io
.ntcreatex
.out
.file
.fnum
;
1918 torture_wait_for_oplock_break(tctx
);
1919 CHECK_VAL(break_info
.count
, 0);
1920 CHECK_VAL(break_info
.failures
, 0);
1921 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, 0);
1925 wr
.write
.level
= RAW_WRITE_WRITE
;
1926 wr
.write
.in
.file
.fnum
= fnum
;
1927 wr
.write
.in
.count
= 1;
1928 wr
.write
.in
.offset
= 0;
1929 wr
.write
.in
.remaining
= 0;
1930 wr
.write
.in
.data
= (const uint8_t *)"x";
1931 status
= smb_raw_write(cli1
->tree
, &wr
);
1932 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
1935 smbcli_oplock_handler(cli2
->transport
, oplock_handler_ack_to_given
, cli2
->tree
);
1937 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
1938 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
1939 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
1940 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
1941 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
|
1942 NTCREATEX_SHARE_ACCESS_WRITE
|
1943 NTCREATEX_SHARE_ACCESS_DELETE
;
1944 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN
;
1945 status
= smb_raw_open(cli2
->tree
, tctx
, &io
);
1946 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
1947 fnum2
= io
.ntcreatex
.out
.file
.fnum
;
1948 torture_wait_for_oplock_break(tctx
);
1949 CHECK_VAL(break_info
.count
, 0);
1950 CHECK_VAL(break_info
.failures
, 0);
1951 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, LEVEL_II_OPLOCK_RETURN
);
1953 torture_comment(tctx
, "write should trigger a break to none\n");
1956 wr
.write
.level
= RAW_WRITE_WRITE
;
1957 wr
.write
.in
.file
.fnum
= fnum
;
1958 wr
.write
.in
.count
= 1;
1959 wr
.write
.in
.offset
= 0;
1960 wr
.write
.in
.remaining
= 0;
1961 wr
.write
.in
.data
= (const uint8_t *)"x";
1962 status
= smb_raw_write(cli1
->tree
, &wr
);
1963 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
1966 torture_wait_for_oplock_break(tctx
);
1968 CHECK_VAL(break_info
.count
, 1);
1969 CHECK_VAL(break_info
.fnum
, fnum2
);
1970 CHECK_VAL(break_info
.level
, 0);
1971 CHECK_VAL(break_info
.failures
, 0);
1973 smbcli_close(cli1
->tree
, fnum
);
1974 smbcli_close(cli2
->tree
, fnum2
);
1977 smb_raw_exit(cli1
->session
);
1978 smb_raw_exit(cli2
->session
);
1979 smbcli_deltree(cli1
->tree
, BASEDIR
);
1983 static bool test_raw_oplock_batch11(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
1985 const char *fname
= BASEDIR
"\\test_batch11.dat";
1989 union smb_setfileinfo sfi
;
1992 if (!torture_setup_dir(cli1
, BASEDIR
)) {
1997 smbcli_unlink(cli1
->tree
, fname
);
1999 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
2002 base ntcreatex parms
2004 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
2005 io
.ntcreatex
.in
.root_fid
.fnum
= 0;
2006 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
2007 io
.ntcreatex
.in
.alloc_size
= 0;
2008 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
2009 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_WRITE
;
2010 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
2011 io
.ntcreatex
.in
.create_options
= 0;
2012 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
2013 io
.ntcreatex
.in
.security_flags
= 0;
2014 io
.ntcreatex
.in
.fname
= fname
;
2016 /* Test if a set-eof on pathname breaks an exclusive oplock. */
2017 torture_comment(tctx
, "BATCH11: Test if setpathinfo set EOF breaks oplocks.\n");
2019 ZERO_STRUCT(break_info
);
2021 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
2022 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
2023 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
2024 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
2025 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
|
2026 NTCREATEX_SHARE_ACCESS_WRITE
|
2027 NTCREATEX_SHARE_ACCESS_DELETE
;
2028 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_CREATE
;
2029 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
2030 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
2031 fnum
= io
.ntcreatex
.out
.file
.fnum
;
2032 torture_wait_for_oplock_break(tctx
);
2033 CHECK_VAL(break_info
.count
, 0);
2034 CHECK_VAL(break_info
.failures
, 0);
2035 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, BATCH_OPLOCK_RETURN
);
2038 sfi
.generic
.level
= RAW_SFILEINFO_END_OF_FILE_INFORMATION
;
2039 sfi
.generic
.in
.file
.path
= fname
;
2040 sfi
.end_of_file_info
.in
.size
= 100;
2042 status
= smb_raw_setpathinfo(cli2
->tree
, &sfi
);
2043 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
2045 torture_wait_for_oplock_break(tctx
);
2046 CHECK_VAL(break_info
.count
, get_setinfo_break_count(tctx
));
2047 CHECK_VAL(break_info
.failures
, 0);
2048 CHECK_VAL(break_info
.level
, 0);
2050 smbcli_close(cli1
->tree
, fnum
);
2053 smb_raw_exit(cli1
->session
);
2054 smb_raw_exit(cli2
->session
);
2055 smbcli_deltree(cli1
->tree
, BASEDIR
);
2059 static bool test_raw_oplock_batch12(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
2061 const char *fname
= BASEDIR
"\\test_batch12.dat";
2065 union smb_setfileinfo sfi
;
2068 if (!torture_setup_dir(cli1
, BASEDIR
)) {
2073 smbcli_unlink(cli1
->tree
, fname
);
2075 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
2078 base ntcreatex parms
2080 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
2081 io
.ntcreatex
.in
.root_fid
.fnum
= 0;
2082 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
2083 io
.ntcreatex
.in
.alloc_size
= 0;
2084 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
2085 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
2086 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
2087 io
.ntcreatex
.in
.create_options
= 0;
2088 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
2089 io
.ntcreatex
.in
.security_flags
= 0;
2090 io
.ntcreatex
.in
.fname
= fname
;
2092 /* Test if a set-allocation size on pathname breaks an exclusive oplock. */
2093 torture_comment(tctx
, "BATCH12: Test if setpathinfo allocation size breaks oplocks.\n");
2095 ZERO_STRUCT(break_info
);
2096 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
2098 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
2099 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
2100 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
2101 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
2102 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
|
2103 NTCREATEX_SHARE_ACCESS_WRITE
|
2104 NTCREATEX_SHARE_ACCESS_DELETE
;
2105 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_CREATE
;
2106 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
2107 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
2108 fnum
= io
.ntcreatex
.out
.file
.fnum
;
2109 torture_wait_for_oplock_break(tctx
);
2110 CHECK_VAL(break_info
.count
, 0);
2111 CHECK_VAL(break_info
.failures
, 0);
2112 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, BATCH_OPLOCK_RETURN
);
2115 sfi
.generic
.level
= SMB_SFILEINFO_ALLOCATION_INFORMATION
;
2116 sfi
.generic
.in
.file
.path
= fname
;
2117 sfi
.allocation_info
.in
.alloc_size
= 65536 * 8;
2119 status
= smb_raw_setpathinfo(cli2
->tree
, &sfi
);
2120 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
2122 torture_wait_for_oplock_break(tctx
);
2123 CHECK_VAL(break_info
.count
, get_setinfo_break_count(tctx
));
2124 CHECK_VAL(break_info
.failures
, 0);
2125 CHECK_VAL(break_info
.level
, 0);
2127 smbcli_close(cli1
->tree
, fnum
);
2130 smb_raw_exit(cli1
->session
);
2131 smb_raw_exit(cli2
->session
);
2132 smbcli_deltree(cli1
->tree
, BASEDIR
);
2136 static bool test_raw_oplock_batch13(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
2138 const char *fname
= BASEDIR
"\\test_batch13.dat";
2142 uint16_t fnum
=0, fnum2
=0;
2144 if (!torture_setup_dir(cli1
, BASEDIR
)) {
2149 smbcli_unlink(cli1
->tree
, fname
);
2151 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
2152 smbcli_oplock_handler(cli2
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
2155 base ntcreatex parms
2157 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
2158 io
.ntcreatex
.in
.root_fid
.fnum
= 0;
2159 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
2160 io
.ntcreatex
.in
.alloc_size
= 0;
2161 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
2162 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
2163 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
2164 io
.ntcreatex
.in
.create_options
= 0;
2165 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
2166 io
.ntcreatex
.in
.security_flags
= 0;
2167 io
.ntcreatex
.in
.fname
= fname
;
2169 torture_comment(tctx
, "BATCH13: open with batch oplock\n");
2170 ZERO_STRUCT(break_info
);
2172 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
2173 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
2174 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
2175 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
|
2176 NTCREATEX_SHARE_ACCESS_WRITE
|
2177 NTCREATEX_SHARE_ACCESS_DELETE
;
2178 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
2179 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
2180 fnum
= io
.ntcreatex
.out
.file
.fnum
;
2181 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, BATCH_OPLOCK_RETURN
);
2183 ZERO_STRUCT(break_info
);
2185 torture_comment(tctx
, "second open with attributes only and NTCREATEX_DISP_OVERWRITE dispostion causes oplock break\n");
2187 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
2188 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
2189 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
2190 io
.ntcreatex
.in
.access_mask
= SEC_FILE_READ_ATTRIBUTE
|SEC_FILE_WRITE_ATTRIBUTE
|SEC_STD_SYNCHRONIZE
;
2191 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
|
2192 NTCREATEX_SHARE_ACCESS_WRITE
|
2193 NTCREATEX_SHARE_ACCESS_DELETE
;
2194 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OVERWRITE
;
2195 status
= smb_raw_open(cli2
->tree
, tctx
, &io
);
2196 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
2197 fnum2
= io
.ntcreatex
.out
.file
.fnum
;
2198 torture_wait_for_oplock_break(tctx
);
2199 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, LEVEL_II_OPLOCK_RETURN
);
2200 CHECK_VAL(break_info
.count
, get_break_level1_to_none_count(tctx
));
2201 CHECK_VAL(break_info
.failures
, 0);
2203 smbcli_close(cli1
->tree
, fnum
);
2204 smbcli_close(cli2
->tree
, fnum2
);
2207 smb_raw_exit(cli1
->session
);
2208 smb_raw_exit(cli2
->session
);
2209 smbcli_deltree(cli1
->tree
, BASEDIR
);
2213 static bool test_raw_oplock_batch14(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
2215 const char *fname
= BASEDIR
"\\test_batch14.dat";
2219 uint16_t fnum
=0, fnum2
=0;
2221 if (!torture_setup_dir(cli1
, BASEDIR
)) {
2226 smbcli_unlink(cli1
->tree
, fname
);
2228 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
2231 base ntcreatex parms
2233 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
2234 io
.ntcreatex
.in
.root_fid
.fnum
= 0;
2235 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
2236 io
.ntcreatex
.in
.alloc_size
= 0;
2237 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
2238 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
2239 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
2240 io
.ntcreatex
.in
.create_options
= 0;
2241 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
2242 io
.ntcreatex
.in
.security_flags
= 0;
2243 io
.ntcreatex
.in
.fname
= fname
;
2245 torture_comment(tctx
, "BATCH14: open with batch oplock\n");
2246 ZERO_STRUCT(break_info
);
2248 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
2249 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
2250 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
2251 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
|
2252 NTCREATEX_SHARE_ACCESS_WRITE
|
2253 NTCREATEX_SHARE_ACCESS_DELETE
;
2254 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
2255 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
2256 fnum
= io
.ntcreatex
.out
.file
.fnum
;
2257 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, BATCH_OPLOCK_RETURN
);
2259 ZERO_STRUCT(break_info
);
2261 torture_comment(tctx
, "second open with attributes only and NTCREATEX_DISP_SUPERSEDE dispostion causes oplock break\n");
2263 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
2264 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
2265 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
2266 io
.ntcreatex
.in
.access_mask
= SEC_FILE_READ_ATTRIBUTE
|SEC_FILE_WRITE_ATTRIBUTE
|SEC_STD_SYNCHRONIZE
;
2267 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
|
2268 NTCREATEX_SHARE_ACCESS_WRITE
|
2269 NTCREATEX_SHARE_ACCESS_DELETE
;
2270 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OVERWRITE
;
2271 status
= smb_raw_open(cli2
->tree
, tctx
, &io
);
2272 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
2273 fnum2
= io
.ntcreatex
.out
.file
.fnum
;
2274 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, LEVEL_II_OPLOCK_RETURN
);
2276 torture_wait_for_oplock_break(tctx
);
2277 CHECK_VAL(break_info
.count
, get_break_level1_to_none_count(tctx
));
2278 CHECK_VAL(break_info
.failures
, 0);
2280 smbcli_close(cli1
->tree
, fnum
);
2281 smbcli_close(cli2
->tree
, fnum2
);
2283 smb_raw_exit(cli1
->session
);
2284 smb_raw_exit(cli2
->session
);
2285 smbcli_deltree(cli1
->tree
, BASEDIR
);
2289 static bool test_raw_oplock_batch15(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
2291 const char *fname
= BASEDIR
"\\test_batch15.dat";
2295 union smb_fileinfo qfi
;
2298 if (!torture_setup_dir(cli1
, BASEDIR
)) {
2303 smbcli_unlink(cli1
->tree
, fname
);
2305 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
2308 base ntcreatex parms
2310 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
2311 io
.ntcreatex
.in
.root_fid
.fnum
= 0;
2312 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
2313 io
.ntcreatex
.in
.alloc_size
= 0;
2314 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
2315 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
2316 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
2317 io
.ntcreatex
.in
.create_options
= 0;
2318 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
2319 io
.ntcreatex
.in
.security_flags
= 0;
2320 io
.ntcreatex
.in
.fname
= fname
;
2322 /* Test if a qpathinfo all info on pathname breaks a batch oplock. */
2323 torture_comment(tctx
, "BATCH15: Test if qpathinfo all info breaks a batch oplock (should not).\n");
2325 ZERO_STRUCT(break_info
);
2327 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
2328 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
2329 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
2330 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
2331 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
|
2332 NTCREATEX_SHARE_ACCESS_WRITE
|
2333 NTCREATEX_SHARE_ACCESS_DELETE
;
2334 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
2335 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_CREATE
;
2336 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
2337 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
2338 fnum
= io
.ntcreatex
.out
.file
.fnum
;
2340 torture_wait_for_oplock_break(tctx
);
2341 CHECK_VAL(break_info
.count
, 0);
2342 CHECK_VAL(break_info
.failures
, 0);
2343 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, BATCH_OPLOCK_RETURN
);
2346 qfi
.generic
.level
= RAW_FILEINFO_ALL_INFORMATION
;
2347 qfi
.generic
.in
.file
.path
= fname
;
2349 status
= smb_raw_pathinfo(cli2
->tree
, tctx
, &qfi
);
2350 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
2352 torture_wait_for_oplock_break(tctx
);
2353 CHECK_VAL(break_info
.count
, 0);
2355 smbcli_close(cli1
->tree
, fnum
);
2358 smb_raw_exit(cli1
->session
);
2359 smb_raw_exit(cli2
->session
);
2360 smbcli_deltree(cli1
->tree
, BASEDIR
);
2364 static bool test_raw_oplock_batch16(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
2366 const char *fname
= BASEDIR
"\\test_batch16.dat";
2370 uint16_t fnum
=0, fnum2
=0;
2372 if (!torture_setup_dir(cli1
, BASEDIR
)) {
2377 smbcli_unlink(cli1
->tree
, fname
);
2379 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
2380 smbcli_oplock_handler(cli2
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
2383 base ntcreatex parms
2385 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
2386 io
.ntcreatex
.in
.root_fid
.fnum
= 0;
2387 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
2388 io
.ntcreatex
.in
.alloc_size
= 0;
2389 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
2390 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
2391 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
2392 io
.ntcreatex
.in
.create_options
= 0;
2393 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
2394 io
.ntcreatex
.in
.security_flags
= 0;
2395 io
.ntcreatex
.in
.fname
= fname
;
2397 torture_comment(tctx
, "BATCH16: open with batch oplock\n");
2398 ZERO_STRUCT(break_info
);
2400 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
2401 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
2402 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
2403 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
|
2404 NTCREATEX_SHARE_ACCESS_WRITE
|
2405 NTCREATEX_SHARE_ACCESS_DELETE
;
2406 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
2407 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
2408 fnum
= io
.ntcreatex
.out
.file
.fnum
;
2409 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, BATCH_OPLOCK_RETURN
);
2411 ZERO_STRUCT(break_info
);
2413 torture_comment(tctx
, "second open with attributes only and NTCREATEX_DISP_OVERWRITE_IF dispostion causes oplock break\n");
2415 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
2416 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
2417 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
2418 io
.ntcreatex
.in
.access_mask
= SEC_FILE_READ_ATTRIBUTE
|SEC_FILE_WRITE_ATTRIBUTE
|SEC_STD_SYNCHRONIZE
;
2419 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
|
2420 NTCREATEX_SHARE_ACCESS_WRITE
|
2421 NTCREATEX_SHARE_ACCESS_DELETE
;
2422 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OVERWRITE_IF
;
2423 status
= smb_raw_open(cli2
->tree
, tctx
, &io
);
2424 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
2425 fnum2
= io
.ntcreatex
.out
.file
.fnum
;
2426 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, LEVEL_II_OPLOCK_RETURN
);
2428 torture_wait_for_oplock_break(tctx
);
2429 CHECK_VAL(break_info
.count
, get_break_level1_to_none_count(tctx
));
2430 CHECK_VAL(break_info
.failures
, 0);
2432 smbcli_close(cli1
->tree
, fnum
);
2433 smbcli_close(cli2
->tree
, fnum2
);
2436 smb_raw_exit(cli1
->session
);
2437 smb_raw_exit(cli2
->session
);
2438 smbcli_deltree(cli1
->tree
, BASEDIR
);
2442 static bool test_raw_oplock_batch17(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
2444 const char *fname1
= BASEDIR
"\\test_batch17_1.dat";
2445 const char *fname2
= BASEDIR
"\\test_batch17_2.dat";
2449 union smb_rename rn
;
2452 if (!torture_setup_dir(cli1
, BASEDIR
)) {
2457 smbcli_unlink(cli1
->tree
, fname1
);
2458 smbcli_unlink(cli1
->tree
, fname2
);
2460 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
2463 base ntcreatex parms
2465 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
2466 io
.ntcreatex
.in
.root_fid
.fnum
= 0;
2467 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
2468 io
.ntcreatex
.in
.alloc_size
= 0;
2469 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
2470 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
2471 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
2472 io
.ntcreatex
.in
.create_options
= 0;
2473 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
2474 io
.ntcreatex
.in
.security_flags
= 0;
2475 io
.ntcreatex
.in
.fname
= fname1
;
2477 torture_comment(tctx
, "BATCH17: open a file with an batch oplock (share mode: none)\n");
2479 ZERO_STRUCT(break_info
);
2480 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
2481 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
2482 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
2484 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
2485 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
2486 fnum
= io
.ntcreatex
.out
.file
.fnum
;
2487 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, BATCH_OPLOCK_RETURN
);
2489 torture_comment(tctx
, "rename should trigger a break\n");
2491 rn
.generic
.level
= RAW_RENAME_RENAME
;
2492 rn
.rename
.in
.pattern1
= fname1
;
2493 rn
.rename
.in
.pattern2
= fname2
;
2494 rn
.rename
.in
.attrib
= 0;
2496 torture_comment(tctx
, "trying rename while first file open\n");
2497 status
= smb_raw_rename(cli2
->tree
, &rn
);
2498 CHECK_STATUS(tctx
, status
, NT_STATUS_SHARING_VIOLATION
);
2500 torture_wait_for_oplock_break(tctx
);
2501 CHECK_VAL(break_info
.count
, 1);
2502 CHECK_VAL(break_info
.failures
, 0);
2503 CHECK_VAL(break_info
.level
, OPLOCK_BREAK_TO_LEVEL_II
);
2505 smbcli_close(cli1
->tree
, fnum
);
2508 smb_raw_exit(cli1
->session
);
2509 smb_raw_exit(cli2
->session
);
2510 smbcli_deltree(cli1
->tree
, BASEDIR
);
2514 static bool test_raw_oplock_batch18(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
2516 const char *fname1
= BASEDIR
"\\test_batch18_1.dat";
2517 const char *fname2
= BASEDIR
"\\test_batch18_2.dat";
2521 union smb_rename rn
;
2524 if (!torture_setup_dir(cli1
, BASEDIR
)) {
2529 smbcli_unlink(cli1
->tree
, fname1
);
2530 smbcli_unlink(cli1
->tree
, fname2
);
2532 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
2535 base ntcreatex parms
2537 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
2538 io
.ntcreatex
.in
.root_fid
.fnum
= 0;
2539 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
2540 io
.ntcreatex
.in
.alloc_size
= 0;
2541 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
2542 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
2543 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
2544 io
.ntcreatex
.in
.create_options
= 0;
2545 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
2546 io
.ntcreatex
.in
.security_flags
= 0;
2547 io
.ntcreatex
.in
.fname
= fname1
;
2549 torture_comment(tctx
, "BATCH18: open a file with an batch oplock (share mode: none)\n");
2551 ZERO_STRUCT(break_info
);
2552 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
2553 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
2554 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
2556 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
2557 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
2558 fnum
= io
.ntcreatex
.out
.file
.fnum
;
2559 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, BATCH_OPLOCK_RETURN
);
2561 torture_comment(tctx
, "ntrename should trigger a break\n");
2563 rn
.generic
.level
= RAW_RENAME_NTRENAME
;
2564 rn
.ntrename
.in
.attrib
= 0;
2565 rn
.ntrename
.in
.flags
= RENAME_FLAG_RENAME
;
2566 rn
.ntrename
.in
.old_name
= fname1
;
2567 rn
.ntrename
.in
.new_name
= fname2
;
2568 torture_comment(tctx
, "trying rename while first file open\n");
2569 status
= smb_raw_rename(cli2
->tree
, &rn
);
2570 CHECK_STATUS(tctx
, status
, NT_STATUS_SHARING_VIOLATION
);
2572 torture_wait_for_oplock_break(tctx
);
2573 CHECK_VAL(break_info
.count
, 1);
2574 CHECK_VAL(break_info
.failures
, 0);
2575 CHECK_VAL(break_info
.level
, OPLOCK_BREAK_TO_LEVEL_II
);
2577 smbcli_close(cli1
->tree
, fnum
);
2580 smb_raw_exit(cli1
->session
);
2581 smb_raw_exit(cli2
->session
);
2582 smbcli_deltree(cli1
->tree
, BASEDIR
);
2586 static bool test_raw_oplock_batch19(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
2588 const char *fname1
= BASEDIR
"\\test_batch19_1.dat";
2589 const char *fname2
= BASEDIR
"\\test_batch19_2.dat";
2590 const char *fname3
= BASEDIR
"\\test_batch19_3.dat";
2594 union smb_fileinfo qfi
;
2595 union smb_setfileinfo sfi
;
2598 if (!torture_setup_dir(cli1
, BASEDIR
)) {
2603 smbcli_unlink(cli1
->tree
, fname1
);
2604 smbcli_unlink(cli1
->tree
, fname2
);
2605 smbcli_unlink(cli1
->tree
, fname3
);
2607 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
2610 base ntcreatex parms
2612 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
2613 io
.ntcreatex
.in
.root_fid
.fnum
= 0;
2614 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
2615 io
.ntcreatex
.in
.alloc_size
= 0;
2616 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
2617 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
|
2618 NTCREATEX_SHARE_ACCESS_WRITE
| NTCREATEX_SHARE_ACCESS_DELETE
;
2619 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
2620 io
.ntcreatex
.in
.create_options
= 0;
2621 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
2622 io
.ntcreatex
.in
.security_flags
= 0;
2623 io
.ntcreatex
.in
.fname
= fname1
;
2625 torture_comment(tctx
, "BATCH19: open a file with an batch oplock (share mode: none)\n");
2626 ZERO_STRUCT(break_info
);
2627 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
2628 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
2629 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
2630 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
2631 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
2632 fnum
= io
.ntcreatex
.out
.file
.fnum
;
2633 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, BATCH_OPLOCK_RETURN
);
2635 torture_comment(tctx
, "setpathinfo rename info should trigger a break "
2638 sfi
.generic
.level
= RAW_SFILEINFO_RENAME_INFORMATION
;
2639 sfi
.generic
.in
.file
.path
= fname1
;
2640 sfi
.rename_information
.in
.overwrite
= 0;
2641 sfi
.rename_information
.in
.root_fid
= 0;
2642 sfi
.rename_information
.in
.new_name
= fname2
+strlen(BASEDIR
)+1;
2644 status
= smb_raw_setpathinfo(cli2
->tree
, &sfi
);
2645 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
2647 torture_wait_for_oplock_break(tctx
);
2649 CHECK_VAL(break_info
.failures
, 0);
2651 if (TARGET_IS_WINXP(tctx
) || TARGET_IS_W2K12(tctx
)) {
2652 /* Win XP breaks to level2. */
2653 CHECK_VAL(break_info
.count
, 1);
2654 CHECK_VAL(break_info
.level
, OPLOCK_BREAK_TO_LEVEL_II
);
2655 } else if (TARGET_IS_W2K3(tctx
) || TARGET_IS_W2K8(tctx
) ||
2656 TARGET_IS_SAMBA3(tctx
) || TARGET_IS_SAMBA4(tctx
)) {
2657 /* Win2K3/2k8 incorrectly doesn't break at all. */
2658 CHECK_VAL(break_info
.count
, 0);
2660 /* win7/2k8r2 break to none. */
2661 CHECK_VAL(break_info
.count
, 1);
2662 CHECK_VAL(break_info
.level
, OPLOCK_BREAK_TO_NONE
);
2666 qfi
.generic
.level
= RAW_FILEINFO_ALL_INFORMATION
;
2667 qfi
.generic
.in
.file
.fnum
= fnum
;
2669 status
= smb_raw_fileinfo(cli1
->tree
, tctx
, &qfi
);
2670 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
2671 CHECK_STRMATCH(qfi
.all_info
.out
.fname
.s
, fname2
);
2673 /* Close and re-open file with oplock. */
2674 smbcli_close(cli1
->tree
, fnum
);
2675 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
2676 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
2677 fnum
= io
.ntcreatex
.out
.file
.fnum
;
2678 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, BATCH_OPLOCK_RETURN
);
2680 torture_comment(tctx
, "setfileinfo rename info on a client's own fid "
2681 "should not trigger a break nor a violation\n");
2682 ZERO_STRUCT(break_info
);
2684 sfi
.generic
.level
= RAW_SFILEINFO_RENAME_INFORMATION
;
2685 sfi
.generic
.in
.file
.fnum
= fnum
;
2686 sfi
.rename_information
.in
.overwrite
= 0;
2687 sfi
.rename_information
.in
.root_fid
= 0;
2688 sfi
.rename_information
.in
.new_name
= fname3
+strlen(BASEDIR
)+1;
2690 status
= smb_raw_setfileinfo(cli1
->tree
, &sfi
);
2691 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
2693 torture_wait_for_oplock_break(tctx
);
2694 if (TARGET_IS_WINXP(tctx
)) {
2695 /* XP incorrectly breaks to level2. */
2696 CHECK_VAL(break_info
.count
, 1);
2697 CHECK_VAL(break_info
.level
, OPLOCK_BREAK_TO_LEVEL_II
);
2699 CHECK_VAL(break_info
.count
, 0);
2703 qfi
.generic
.level
= RAW_FILEINFO_ALL_INFORMATION
;
2704 qfi
.generic
.in
.file
.fnum
= fnum
;
2706 status
= smb_raw_fileinfo(cli1
->tree
, tctx
, &qfi
);
2707 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
2708 CHECK_STRMATCH(qfi
.all_info
.out
.fname
.s
, fname3
);
2711 smbcli_close(cli1
->tree
, fnum
);
2712 smb_raw_exit(cli1
->session
);
2713 smb_raw_exit(cli2
->session
);
2714 smbcli_deltree(cli1
->tree
, BASEDIR
);
2718 /****************************************************
2719 Called from raw-rename - we need oplock handling for
2720 this test so this is why it's in oplock.c, not rename.c
2721 ****************************************************/
2723 bool test_trans2rename(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
2725 const char *fname1
= BASEDIR
"\\test_trans2rename_1.dat";
2726 const char *fname2
= BASEDIR
"\\test_trans2rename_2.dat";
2727 const char *fname3
= BASEDIR
"\\test_trans2rename_3.dat";
2731 union smb_fileinfo qfi
;
2732 union smb_setfileinfo sfi
;
2735 if (!torture_setup_dir(cli1
, BASEDIR
)) {
2740 smbcli_unlink(cli1
->tree
, fname1
);
2741 smbcli_unlink(cli1
->tree
, fname2
);
2742 smbcli_unlink(cli1
->tree
, fname3
);
2744 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
2747 base ntcreatex parms
2749 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
2750 io
.ntcreatex
.in
.root_fid
.fnum
= 0;
2751 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
2752 io
.ntcreatex
.in
.alloc_size
= 0;
2753 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
2754 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
|
2755 NTCREATEX_SHARE_ACCESS_WRITE
| NTCREATEX_SHARE_ACCESS_DELETE
;
2756 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
2757 io
.ntcreatex
.in
.create_options
= 0;
2758 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
2759 io
.ntcreatex
.in
.security_flags
= 0;
2760 io
.ntcreatex
.in
.fname
= fname1
;
2762 torture_comment(tctx
, "open a file with an exclusive oplock (share mode: none)\n");
2763 ZERO_STRUCT(break_info
);
2764 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
2765 NTCREATEX_FLAGS_REQUEST_OPLOCK
;
2766 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
2767 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
2768 fnum
= io
.ntcreatex
.out
.file
.fnum
;
2769 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, EXCLUSIVE_OPLOCK_RETURN
);
2771 torture_comment(tctx
, "setpathinfo rename info should not trigger a break nor a violation\n");
2773 sfi
.generic
.level
= RAW_SFILEINFO_RENAME_INFORMATION
;
2774 sfi
.generic
.in
.file
.path
= fname1
;
2775 sfi
.rename_information
.in
.overwrite
= 0;
2776 sfi
.rename_information
.in
.root_fid
= 0;
2777 sfi
.rename_information
.in
.new_name
= fname2
+strlen(BASEDIR
)+1;
2779 status
= smb_raw_setpathinfo(cli2
->tree
, &sfi
);
2781 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
2783 torture_wait_for_oplock_break(tctx
);
2784 CHECK_VAL(break_info
.count
, 0);
2787 qfi
.generic
.level
= RAW_FILEINFO_ALL_INFORMATION
;
2788 qfi
.generic
.in
.file
.fnum
= fnum
;
2790 status
= smb_raw_fileinfo(cli1
->tree
, tctx
, &qfi
);
2791 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
2792 CHECK_STRMATCH(qfi
.all_info
.out
.fname
.s
, fname2
);
2794 torture_comment(tctx
, "setfileinfo rename info should not trigger a break nor a violation\n");
2796 sfi
.generic
.level
= RAW_SFILEINFO_RENAME_INFORMATION
;
2797 sfi
.generic
.in
.file
.fnum
= fnum
;
2798 sfi
.rename_information
.in
.overwrite
= 0;
2799 sfi
.rename_information
.in
.root_fid
= 0;
2800 sfi
.rename_information
.in
.new_name
= fname3
+strlen(BASEDIR
)+1;
2802 status
= smb_raw_setfileinfo(cli1
->tree
, &sfi
);
2803 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
2805 torture_wait_for_oplock_break(tctx
);
2806 CHECK_VAL(break_info
.count
, 0);
2809 qfi
.generic
.level
= RAW_FILEINFO_ALL_INFORMATION
;
2810 qfi
.generic
.in
.file
.fnum
= fnum
;
2812 status
= smb_raw_fileinfo(cli1
->tree
, tctx
, &qfi
);
2813 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
2814 CHECK_STRMATCH(qfi
.all_info
.out
.fname
.s
, fname3
);
2817 smbcli_close(cli1
->tree
, fnum
);
2818 smb_raw_exit(cli1
->session
);
2819 smb_raw_exit(cli2
->session
);
2820 smbcli_deltree(cli1
->tree
, BASEDIR
);
2824 /****************************************************
2825 Called from raw-rename - we need oplock handling for
2826 this test so this is why it's in oplock.c, not rename.c
2827 ****************************************************/
2829 bool test_nttransrename(struct torture_context
*tctx
, struct smbcli_state
*cli1
)
2831 const char *fname1
= BASEDIR
"\\test_nttransrename_1.dat";
2832 const char *fname2
= BASEDIR
"\\test_nttransrename_2.dat";
2836 union smb_fileinfo qfi
, qpi
;
2837 union smb_rename rn
;
2840 if (!torture_setup_dir(cli1
, BASEDIR
)) {
2845 smbcli_unlink(cli1
->tree
, fname1
);
2846 smbcli_unlink(cli1
->tree
, fname2
);
2848 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
2851 base ntcreatex parms
2853 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
2854 io
.ntcreatex
.in
.root_fid
.fnum
= 0;
2855 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
2856 io
.ntcreatex
.in
.alloc_size
= 0;
2857 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
2858 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
2859 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
2860 io
.ntcreatex
.in
.create_options
= 0;
2861 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
2862 io
.ntcreatex
.in
.security_flags
= 0;
2863 io
.ntcreatex
.in
.fname
= fname1
;
2865 torture_comment(tctx
, "nttrans_rename: open a file with an exclusive oplock (share mode: none)\n");
2866 ZERO_STRUCT(break_info
);
2867 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
2868 NTCREATEX_FLAGS_REQUEST_OPLOCK
;
2869 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
2870 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
2871 fnum
= io
.ntcreatex
.out
.file
.fnum
;
2872 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, EXCLUSIVE_OPLOCK_RETURN
);
2874 torture_comment(tctx
, "nttrans_rename: should not trigger a break nor a share mode violation\n");
2876 rn
.generic
.level
= RAW_RENAME_NTTRANS
;
2877 rn
.nttrans
.in
.file
.fnum
= fnum
;
2878 rn
.nttrans
.in
.flags
= 0;
2879 rn
.nttrans
.in
.new_name
= fname2
+strlen(BASEDIR
)+1;
2881 status
= smb_raw_rename(cli1
->tree
, &rn
);
2882 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
2884 torture_wait_for_oplock_break(tctx
);
2885 CHECK_VAL(break_info
.count
, 0);
2887 /* w2k3 does nothing, it doesn't rename the file */
2888 torture_comment(tctx
, "nttrans_rename: the server should have done nothing\n");
2890 qfi
.generic
.level
= RAW_FILEINFO_ALL_INFORMATION
;
2891 qfi
.generic
.in
.file
.fnum
= fnum
;
2893 status
= smb_raw_fileinfo(cli1
->tree
, tctx
, &qfi
);
2894 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
2895 CHECK_STRMATCH(qfi
.all_info
.out
.fname
.s
, fname1
);
2898 qpi
.generic
.level
= RAW_FILEINFO_ALL_INFORMATION
;
2899 qpi
.generic
.in
.file
.path
= fname1
;
2901 status
= smb_raw_pathinfo(cli1
->tree
, tctx
, &qpi
);
2902 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
2903 CHECK_STRMATCH(qpi
.all_info
.out
.fname
.s
, fname1
);
2906 qpi
.generic
.level
= RAW_FILEINFO_ALL_INFORMATION
;
2907 qpi
.generic
.in
.file
.path
= fname2
;
2909 status
= smb_raw_pathinfo(cli1
->tree
, tctx
, &qpi
);
2910 CHECK_STATUS(tctx
, status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
);
2912 torture_comment(tctx
, "nttrans_rename: after closing the file the file is still not renamed\n");
2913 status
= smbcli_close(cli1
->tree
, fnum
);
2914 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
2917 qpi
.generic
.level
= RAW_FILEINFO_ALL_INFORMATION
;
2918 qpi
.generic
.in
.file
.path
= fname1
;
2920 status
= smb_raw_pathinfo(cli1
->tree
, tctx
, &qpi
);
2921 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
2922 CHECK_STRMATCH(qpi
.all_info
.out
.fname
.s
, fname1
);
2925 qpi
.generic
.level
= RAW_FILEINFO_ALL_INFORMATION
;
2926 qpi
.generic
.in
.file
.path
= fname2
;
2928 status
= smb_raw_pathinfo(cli1
->tree
, tctx
, &qpi
);
2929 CHECK_STATUS(tctx
, status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
);
2931 torture_comment(tctx
, "nttrans_rename: rename with an invalid handle gives NT_STATUS_INVALID_HANDLE\n");
2933 rn
.generic
.level
= RAW_RENAME_NTTRANS
;
2934 rn
.nttrans
.in
.file
.fnum
= fnum
+1;
2935 rn
.nttrans
.in
.flags
= 0;
2936 rn
.nttrans
.in
.new_name
= fname2
+strlen(BASEDIR
)+1;
2938 status
= smb_raw_rename(cli1
->tree
, &rn
);
2940 CHECK_STATUS(tctx
, status
, NT_STATUS_INVALID_HANDLE
);
2943 smb_raw_exit(cli1
->session
);
2944 smbcli_deltree(cli1
->tree
, BASEDIR
);
2949 static bool test_raw_oplock_batch20(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
2951 const char *fname1
= BASEDIR
"\\test_batch20_1.dat";
2952 const char *fname2
= BASEDIR
"\\test_batch20_2.dat";
2953 const char *fname3
= BASEDIR
"\\test_batch20_3.dat";
2957 union smb_fileinfo qfi
;
2958 union smb_setfileinfo sfi
;
2959 uint16_t fnum
=0,fnum2
=0;
2961 if (!torture_setup_dir(cli1
, BASEDIR
)) {
2966 smbcli_unlink(cli1
->tree
, fname1
);
2967 smbcli_unlink(cli1
->tree
, fname2
);
2968 smbcli_unlink(cli1
->tree
, fname3
);
2970 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
2973 base ntcreatex parms
2975 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
2976 io
.ntcreatex
.in
.root_fid
.fnum
= 0;
2977 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
2978 io
.ntcreatex
.in
.alloc_size
= 0;
2979 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
2980 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
2981 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
2982 io
.ntcreatex
.in
.create_options
= 0;
2983 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
2984 io
.ntcreatex
.in
.security_flags
= 0;
2985 io
.ntcreatex
.in
.fname
= fname1
;
2987 torture_comment(tctx
, "BATCH20: open a file with an batch oplock (share mode: all)\n");
2988 ZERO_STRUCT(break_info
);
2989 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
2990 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
2991 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
2992 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
|
2993 NTCREATEX_SHARE_ACCESS_WRITE
|
2994 NTCREATEX_SHARE_ACCESS_DELETE
;
2995 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
2996 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
2997 fnum
= io
.ntcreatex
.out
.file
.fnum
;
2998 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, BATCH_OPLOCK_RETURN
);
3001 sfi
.generic
.level
= RAW_SFILEINFO_RENAME_INFORMATION
;
3002 sfi
.generic
.in
.file
.path
= fname1
;
3003 sfi
.rename_information
.in
.overwrite
= 0;
3004 sfi
.rename_information
.in
.root_fid
= 0;
3005 sfi
.rename_information
.in
.new_name
= fname2
+strlen(BASEDIR
)+1;
3007 status
= smb_raw_setpathinfo(cli2
->tree
, &sfi
);
3008 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
3010 torture_wait_for_oplock_break(tctx
);
3011 CHECK_VAL(break_info
.failures
, 0);
3013 if (TARGET_IS_WINXP(tctx
) || TARGET_IS_W2K12(tctx
)) {
3014 /* Win XP breaks to level2. */
3015 CHECK_VAL(break_info
.count
, 1);
3016 CHECK_VAL(break_info
.level
, OPLOCK_BREAK_TO_LEVEL_II
);
3017 } else if (TARGET_IS_W2K3(tctx
) || TARGET_IS_W2K8(tctx
) ||
3018 TARGET_IS_SAMBA3(tctx
) || TARGET_IS_SAMBA4(tctx
)) {
3019 /* Win2K3/2k8 incorrectly doesn't break at all. */
3020 CHECK_VAL(break_info
.count
, 0);
3022 /* win7/2k8r2 break to none. */
3023 CHECK_VAL(break_info
.count
, 1);
3024 CHECK_VAL(break_info
.level
, OPLOCK_BREAK_TO_NONE
);
3028 qfi
.generic
.level
= RAW_FILEINFO_ALL_INFORMATION
;
3029 qfi
.generic
.in
.file
.fnum
= fnum
;
3031 status
= smb_raw_fileinfo(cli1
->tree
, tctx
, &qfi
);
3032 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
3033 CHECK_STRMATCH(qfi
.all_info
.out
.fname
.s
, fname2
);
3035 torture_comment(tctx
, "open a file with the new name an batch oplock (share mode: all)\n");
3036 ZERO_STRUCT(break_info
);
3037 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
3038 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
3039 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
3040 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
|
3041 NTCREATEX_SHARE_ACCESS_WRITE
|
3042 NTCREATEX_SHARE_ACCESS_DELETE
;
3043 io
.ntcreatex
.in
.fname
= fname2
;
3044 status
= smb_raw_open(cli2
->tree
, tctx
, &io
);
3045 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
3046 fnum2
= io
.ntcreatex
.out
.file
.fnum
;
3047 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, LEVEL_II_OPLOCK_RETURN
);
3049 torture_wait_for_oplock_break(tctx
);
3051 if (TARGET_IS_WINXP(tctx
)) {
3052 /* XP broke to level2, and doesn't break again. */
3053 CHECK_VAL(break_info
.count
, 0);
3054 } else if (TARGET_IS_W2K3(tctx
) || TARGET_IS_W2K8(tctx
) ||
3055 TARGET_IS_SAMBA3(tctx
) || TARGET_IS_SAMBA4(tctx
)) {
3056 /* Win2K3 incorrectly didn't break before so break now. */
3057 CHECK_VAL(break_info
.count
, 1);
3058 CHECK_VAL(break_info
.level
, OPLOCK_BREAK_TO_LEVEL_II
);
3060 /* win7/2k8r2 broke to none, and doesn't break again. */
3061 CHECK_VAL(break_info
.count
, 0);
3064 ZERO_STRUCT(break_info
);
3067 sfi
.generic
.level
= RAW_SFILEINFO_RENAME_INFORMATION
;
3068 sfi
.generic
.in
.file
.fnum
= fnum
;
3069 sfi
.rename_information
.in
.overwrite
= 0;
3070 sfi
.rename_information
.in
.root_fid
= 0;
3071 sfi
.rename_information
.in
.new_name
= fname3
+strlen(BASEDIR
)+1;
3073 status
= smb_raw_setfileinfo(cli1
->tree
, &sfi
);
3074 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
3076 torture_wait_for_oplock_break(tctx
);
3077 CHECK_VAL(break_info
.count
, 0);
3080 qfi
.generic
.level
= RAW_FILEINFO_ALL_INFORMATION
;
3081 qfi
.generic
.in
.file
.fnum
= fnum
;
3083 status
= smb_raw_fileinfo(cli1
->tree
, tctx
, &qfi
);
3084 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
3085 CHECK_STRMATCH(qfi
.all_info
.out
.fname
.s
, fname3
);
3088 qfi
.generic
.level
= RAW_FILEINFO_ALL_INFORMATION
;
3089 qfi
.generic
.in
.file
.fnum
= fnum2
;
3091 status
= smb_raw_fileinfo(cli2
->tree
, tctx
, &qfi
);
3092 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
3093 CHECK_STRMATCH(qfi
.all_info
.out
.fname
.s
, fname3
);
3097 smbcli_close(cli1
->tree
, fnum
);
3098 smbcli_close(cli2
->tree
, fnum2
);
3099 smb_raw_exit(cli1
->session
);
3100 smb_raw_exit(cli2
->session
);
3101 smbcli_deltree(cli1
->tree
, BASEDIR
);
3105 static bool test_raw_oplock_batch21(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
3107 const char *fname
= BASEDIR
"\\test_batch21.dat";
3116 if (!torture_setup_dir(cli1
, BASEDIR
)) {
3121 smbcli_unlink(cli1
->tree
, fname
);
3123 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
3126 base ntcreatex parms
3128 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
3129 io
.ntcreatex
.in
.root_fid
.fnum
= 0;
3130 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
3131 io
.ntcreatex
.in
.alloc_size
= 0;
3132 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
3133 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
3134 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
3135 io
.ntcreatex
.in
.create_options
= 0;
3136 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
3137 io
.ntcreatex
.in
.security_flags
= 0;
3138 io
.ntcreatex
.in
.fname
= fname
;
3141 with a batch oplock we get a break
3143 torture_comment(tctx
, "BATCH21: open with batch oplock\n");
3144 ZERO_STRUCT(break_info
);
3145 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
3146 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
3147 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
3148 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
3149 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
3150 fnum
= io
.ntcreatex
.out
.file
.fnum
;
3151 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, BATCH_OPLOCK_RETURN
);
3153 torture_comment(tctx
, "writing should not generate a break\n");
3154 wr
= smbcli_write(cli1
->tree
, fnum
, 0, &c
, 0, 1);
3156 CHECK_STATUS(tctx
, smbcli_nt_error(cli1
->tree
), NT_STATUS_OK
);
3159 e
.in
.repeat_count
= 1;
3160 status
= smb_raw_echo(cli1
->transport
, &e
);
3161 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
3163 torture_wait_for_oplock_break(tctx
);
3164 CHECK_VAL(break_info
.count
, 0);
3166 smbcli_close(cli1
->tree
, fnum
);
3169 smb_raw_exit(cli1
->session
);
3170 smb_raw_exit(cli2
->session
);
3171 smbcli_deltree(cli1
->tree
, BASEDIR
);
3175 static bool test_raw_oplock_batch22(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
3177 const char *fname
= BASEDIR
"\\test_batch22.dat";
3181 uint16_t fnum
= 0, fnum2
= 0, fnum3
= 0;
3183 int timeout
= torture_setting_int(tctx
, "oplocktimeout", 30);
3186 if (!torture_setup_dir(cli1
, BASEDIR
)) {
3191 smbcli_unlink(cli1
->tree
, fname
);
3193 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
3195 base ntcreatex parms
3197 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
3198 io
.ntcreatex
.in
.root_fid
.fnum
= 0;
3199 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
3200 io
.ntcreatex
.in
.alloc_size
= 0;
3201 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
3202 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
3203 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
3204 io
.ntcreatex
.in
.create_options
= 0;
3205 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
3206 io
.ntcreatex
.in
.security_flags
= 0;
3207 io
.ntcreatex
.in
.fname
= fname
;
3210 with a batch oplock we get a break
3212 torture_comment(tctx
, "BATCH22: open with batch oplock\n");
3213 ZERO_STRUCT(break_info
);
3214 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
3215 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
3216 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
3217 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
|
3218 NTCREATEX_SHARE_ACCESS_WRITE
|
3219 NTCREATEX_SHARE_ACCESS_DELETE
;
3220 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
3221 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
3222 fnum
= io
.ntcreatex
.out
.file
.fnum
;
3223 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, BATCH_OPLOCK_RETURN
);
3225 torture_comment(tctx
, "a 2nd open should not succeed after the oplock "
3227 tv
= timeval_current();
3228 smbcli_oplock_handler(cli1
->transport
, oplock_handler_timeout
, cli1
->tree
);
3229 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
3231 if (TARGET_IS_W2K3(tctx
)) {
3232 /* 2k3 has an issue here. xp/win7 are ok. */
3233 CHECK_STATUS(tctx
, status
, NT_STATUS_SHARING_VIOLATION
);
3235 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
3238 fnum2
= io
.ntcreatex
.out
.file
.fnum
;
3240 torture_wait_for_oplock_break(tctx
);
3241 te
= (int)timeval_elapsed(&tv
);
3244 * Some servers detect clients that let oplocks timeout, so this check
3245 * only shows a warning message instead failing the test to eliminate
3246 * failures from repeated runs of the test. This isn't ideal, but
3247 * it's better than not running the test at all.
3249 CHECK_RANGE(te
, timeout
- 1, timeout
+ 15);
3251 CHECK_VAL(break_info
.count
, 1);
3252 CHECK_VAL(break_info
.fnum
, fnum
);
3253 CHECK_VAL(break_info
.level
, OPLOCK_BREAK_TO_LEVEL_II
);
3254 CHECK_VAL(break_info
.failures
, 0);
3255 ZERO_STRUCT(break_info
);
3257 torture_comment(tctx
, "a 2nd open should succeed after the oplock "
3258 "release without break\n");
3259 tv
= timeval_current();
3260 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
3261 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
3262 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
3264 /* Samba 3.6.0 and above behave as Windows. */
3265 if (TARGET_IS_SAMBA3(tctx
)) {
3266 /* samba3 doesn't grant additional oplocks to bad clients. */
3267 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, NO_OPLOCK_RETURN
);
3269 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
,
3270 LEVEL_II_OPLOCK_RETURN
);
3273 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
,
3274 LEVEL_II_OPLOCK_RETURN
);
3276 torture_wait_for_oplock_break(tctx
);
3277 te
= (int)timeval_elapsed(&tv
);
3278 /* it should come in without delay */
3279 CHECK_RANGE(te
+1, 0, timeout
);
3280 fnum3
= io
.ntcreatex
.out
.file
.fnum
;
3282 CHECK_VAL(break_info
.count
, 0);
3284 smbcli_close(cli1
->tree
, fnum
);
3285 smbcli_close(cli1
->tree
, fnum2
);
3286 smbcli_close(cli1
->tree
, fnum3
);
3289 smb_raw_exit(cli1
->session
);
3290 smb_raw_exit(cli2
->session
);
3291 smbcli_deltree(cli1
->tree
, BASEDIR
);
3295 static bool test_raw_oplock_batch23(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
3297 const char *fname
= BASEDIR
"\\test_batch23.dat";
3301 uint16_t fnum
=0, fnum2
=0,fnum3
=0;
3302 struct smbcli_state
*cli3
= NULL
;
3304 if (!torture_setup_dir(cli1
, BASEDIR
)) {
3309 smbcli_unlink(cli1
->tree
, fname
);
3311 ret
= open_connection_no_level2_oplocks(tctx
, &cli3
);
3312 CHECK_VAL(ret
, true);
3314 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
3315 smbcli_oplock_handler(cli2
->transport
, oplock_handler_ack_to_given
, cli2
->tree
);
3316 smbcli_oplock_handler(cli3
->transport
, oplock_handler_ack_to_given
, cli3
->tree
);
3319 base ntcreatex parms
3321 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
3322 io
.ntcreatex
.in
.root_fid
.fnum
= 0;
3323 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
3324 io
.ntcreatex
.in
.alloc_size
= 0;
3325 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
3326 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
3327 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
3328 io
.ntcreatex
.in
.create_options
= 0;
3329 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
3330 io
.ntcreatex
.in
.security_flags
= 0;
3331 io
.ntcreatex
.in
.fname
= fname
;
3333 torture_comment(tctx
, "BATCH23: a open and ask for a batch oplock\n");
3334 ZERO_STRUCT(break_info
);
3336 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_READ
| SEC_RIGHTS_FILE_WRITE
;
3337 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
| NTCREATEX_SHARE_ACCESS_WRITE
;
3338 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
3339 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
3340 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
3341 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
3342 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
3343 fnum
= io
.ntcreatex
.out
.file
.fnum
;
3344 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, BATCH_OPLOCK_RETURN
);
3346 ZERO_STRUCT(break_info
);
3348 torture_comment(tctx
, "a 2nd open without level2 oplock support should generate a break to level2\n");
3349 status
= smb_raw_open(cli3
->tree
, tctx
, &io
);
3350 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
3351 fnum3
= io
.ntcreatex
.out
.file
.fnum
;
3352 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, NO_OPLOCK_RETURN
);
3354 torture_wait_for_oplock_break(tctx
);
3355 CHECK_VAL(break_info
.count
, 1);
3356 CHECK_VAL(break_info
.fnum
, fnum
);
3357 CHECK_VAL(break_info
.level
, OPLOCK_BREAK_TO_LEVEL_II
);
3358 CHECK_VAL(break_info
.failures
, 0);
3360 ZERO_STRUCT(break_info
);
3362 torture_comment(tctx
, "a 3rd open with level2 oplock support should not generate a break\n");
3363 status
= smb_raw_open(cli2
->tree
, tctx
, &io
);
3364 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
3365 fnum2
= io
.ntcreatex
.out
.file
.fnum
;
3366 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, LEVEL_II_OPLOCK_RETURN
);
3368 torture_wait_for_oplock_break(tctx
);
3369 CHECK_VAL(break_info
.count
, 0);
3371 smbcli_close(cli1
->tree
, fnum
);
3372 smbcli_close(cli2
->tree
, fnum2
);
3373 smbcli_close(cli3
->tree
, fnum3
);
3376 smb_raw_exit(cli1
->session
);
3377 smb_raw_exit(cli2
->session
);
3378 smb_raw_exit(cli3
->session
);
3379 smbcli_deltree(cli1
->tree
, BASEDIR
);
3383 static bool test_raw_oplock_batch24(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
3385 const char *fname
= BASEDIR
"\\test_batch24.dat";
3389 uint16_t fnum2
=0,fnum3
=0;
3390 struct smbcli_state
*cli3
= NULL
;
3392 if (!torture_setup_dir(cli1
, BASEDIR
)) {
3397 smbcli_unlink(cli1
->tree
, fname
);
3399 ret
= open_connection_no_level2_oplocks(tctx
, &cli3
);
3400 CHECK_VAL(ret
, true);
3402 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
3403 smbcli_oplock_handler(cli2
->transport
, oplock_handler_ack_to_given
, cli2
->tree
);
3404 smbcli_oplock_handler(cli3
->transport
, oplock_handler_ack_to_given
, cli3
->tree
);
3407 base ntcreatex parms
3409 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
3410 io
.ntcreatex
.in
.root_fid
.fnum
= 0;
3411 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
3412 io
.ntcreatex
.in
.alloc_size
= 0;
3413 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
3414 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
3415 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
3416 io
.ntcreatex
.in
.create_options
= 0;
3417 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
3418 io
.ntcreatex
.in
.security_flags
= 0;
3419 io
.ntcreatex
.in
.fname
= fname
;
3421 torture_comment(tctx
, "BATCH24: a open without level support and ask for a batch oplock\n");
3422 ZERO_STRUCT(break_info
);
3424 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_READ
| SEC_RIGHTS_FILE_WRITE
;
3425 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
| NTCREATEX_SHARE_ACCESS_WRITE
;
3426 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
3427 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
3428 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
3429 status
= smb_raw_open(cli3
->tree
, tctx
, &io
);
3430 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
3431 fnum3
= io
.ntcreatex
.out
.file
.fnum
;
3432 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, BATCH_OPLOCK_RETURN
);
3434 ZERO_STRUCT(break_info
);
3436 torture_comment(tctx
, "a 2nd open with level2 oplock support should generate a break to none\n");
3437 status
= smb_raw_open(cli2
->tree
, tctx
, &io
);
3438 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
3439 fnum2
= io
.ntcreatex
.out
.file
.fnum
;
3440 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, LEVEL_II_OPLOCK_RETURN
);
3442 torture_wait_for_oplock_break(tctx
);
3443 CHECK_VAL(break_info
.count
, 1);
3444 CHECK_VAL(break_info
.fnum
, fnum3
);
3445 CHECK_VAL(break_info
.level
, OPLOCK_BREAK_TO_NONE
);
3446 CHECK_VAL(break_info
.failures
, 0);
3448 smbcli_close(cli3
->tree
, fnum3
);
3449 smbcli_close(cli2
->tree
, fnum2
);
3452 smb_raw_exit(cli1
->session
);
3453 smb_raw_exit(cli2
->session
);
3454 smb_raw_exit(cli3
->session
);
3455 smbcli_deltree(cli1
->tree
, BASEDIR
);
3459 static bool test_raw_oplock_batch25(struct torture_context
*tctx
,
3460 struct smbcli_state
*cli1
,
3461 struct smbcli_state
*cli2
)
3463 const char *fname
= BASEDIR
"\\test_batch25.dat";
3467 union smb_setfileinfo sfi
;
3470 if (!torture_setup_dir(cli1
, BASEDIR
)) {
3475 smbcli_unlink(cli1
->tree
, fname
);
3477 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
3480 base ntcreatex parms
3482 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
3483 io
.ntcreatex
.in
.root_fid
.fnum
= 0;
3484 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
3485 io
.ntcreatex
.in
.alloc_size
= 0;
3486 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
3487 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
3488 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
3489 io
.ntcreatex
.in
.create_options
= 0;
3490 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
3491 io
.ntcreatex
.in
.security_flags
= 0;
3492 io
.ntcreatex
.in
.fname
= fname
;
3494 torture_comment(tctx
, "BATCH25: open a file with an batch oplock "
3495 "(share mode: none)\n");
3497 ZERO_STRUCT(break_info
);
3498 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
3499 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
3500 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
3501 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
3502 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
3503 fnum
= io
.ntcreatex
.out
.file
.fnum
;
3504 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, BATCH_OPLOCK_RETURN
);
3506 torture_comment(tctx
, "setpathinfo attribute info should not trigger "
3507 "a break nor a violation\n");
3509 sfi
.generic
.level
= RAW_SFILEINFO_SETATTR
;
3510 sfi
.generic
.in
.file
.path
= fname
;
3511 sfi
.setattr
.in
.attrib
= FILE_ATTRIBUTE_HIDDEN
;
3512 sfi
.setattr
.in
.write_time
= 0;
3514 status
= smb_raw_setpathinfo(cli2
->tree
, &sfi
);
3515 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
3517 torture_wait_for_oplock_break(tctx
);
3518 CHECK_VAL(break_info
.count
, 0);
3520 smbcli_close(cli1
->tree
, fnum
);
3523 smb_raw_exit(cli1
->session
);
3524 smb_raw_exit(cli2
->session
);
3525 smbcli_deltree(cli1
->tree
, BASEDIR
);
3530 * Similar to batch17/18, but test with open share mode rather than
3533 static bool test_raw_oplock_batch26(struct torture_context
*tctx
,
3534 struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
3536 const char *fname1
= BASEDIR
"\\test_batch26_1.dat";
3537 const char *fname2
= BASEDIR
"\\test_batch26_2.dat";
3541 union smb_rename rn
;
3544 if (!torture_setup_dir(cli1
, BASEDIR
)) {
3549 smbcli_unlink(cli1
->tree
, fname1
);
3550 smbcli_unlink(cli1
->tree
, fname2
);
3552 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
,
3556 base ntcreatex parms
3558 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
3559 io
.ntcreatex
.in
.root_fid
.fnum
= 0;
3560 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
3561 io
.ntcreatex
.in
.alloc_size
= 0;
3562 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
3563 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
|
3564 NTCREATEX_SHARE_ACCESS_WRITE
| NTCREATEX_SHARE_ACCESS_DELETE
;
3565 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
3566 io
.ntcreatex
.in
.create_options
= 0;
3567 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
3568 io
.ntcreatex
.in
.security_flags
= 0;
3569 io
.ntcreatex
.in
.fname
= fname1
;
3571 torture_comment(tctx
, "BATCH26: open a file with an batch oplock "
3572 "(share mode: none)\n");
3574 ZERO_STRUCT(break_info
);
3575 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
3576 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
3577 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
3580 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
3581 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
3582 fnum
= io
.ntcreatex
.out
.file
.fnum
;
3583 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, BATCH_OPLOCK_RETURN
);
3585 torture_comment(tctx
, "rename should trigger a break\n");
3587 rn
.generic
.level
= RAW_RENAME_RENAME
;
3588 rn
.rename
.in
.pattern1
= fname1
;
3589 rn
.rename
.in
.pattern2
= fname2
;
3590 rn
.rename
.in
.attrib
= 0;
3592 torture_comment(tctx
, "trying rename while first file open\n");
3593 status
= smb_raw_rename(cli2
->tree
, &rn
);
3594 CHECK_STATUS(tctx
, status
, NT_STATUS_SHARING_VIOLATION
);
3596 torture_wait_for_oplock_break(tctx
);
3597 CHECK_VAL(break_info
.count
, 1);
3598 CHECK_VAL(break_info
.failures
, 0);
3599 CHECK_VAL(break_info
.level
, OPLOCK_BREAK_TO_LEVEL_II
);
3601 /* Close and reopen with batch again. */
3602 smbcli_close(cli1
->tree
, fnum
);
3603 ZERO_STRUCT(break_info
);
3605 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
3606 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
3607 fnum
= io
.ntcreatex
.out
.file
.fnum
;
3608 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, BATCH_OPLOCK_RETURN
);
3610 /* Now try ntrename. */
3611 torture_comment(tctx
, "ntrename should trigger a break\n");
3613 rn
.generic
.level
= RAW_RENAME_NTRENAME
;
3614 rn
.ntrename
.in
.attrib
= 0;
3615 rn
.ntrename
.in
.flags
= RENAME_FLAG_RENAME
;
3616 rn
.ntrename
.in
.old_name
= fname1
;
3617 rn
.ntrename
.in
.new_name
= fname2
;
3618 torture_comment(tctx
, "trying rename while first file open\n");
3619 status
= smb_raw_rename(cli2
->tree
, &rn
);
3620 CHECK_STATUS(tctx
, status
, NT_STATUS_SHARING_VIOLATION
);
3622 torture_wait_for_oplock_break(tctx
);
3623 CHECK_VAL(break_info
.count
, 1);
3624 CHECK_VAL(break_info
.failures
, 0);
3625 CHECK_VAL(break_info
.level
, OPLOCK_BREAK_TO_LEVEL_II
);
3627 smbcli_close(cli1
->tree
, fnum
);
3630 smb_raw_exit(cli1
->session
);
3631 smb_raw_exit(cli2
->session
);
3632 smbcli_deltree(cli1
->tree
, BASEDIR
);
3636 /* Test how oplocks work on streams. */
3637 static bool test_raw_oplock_stream1(struct torture_context
*tctx
,
3638 struct smbcli_state
*cli1
,
3639 struct smbcli_state
*cli2
)
3643 const char *fname_base
= BASEDIR
"\\test_stream1.txt";
3644 const char *stream
= "Stream One:$DATA";
3645 const char *fname_stream
, *fname_default_stream
;
3646 const char *default_stream
= "::$DATA";
3650 int stream_fnum
= -1;
3651 uint32_t batch_req
= NTCREATEX_FLAGS_REQUEST_OPLOCK
|
3652 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
| NTCREATEX_FLAGS_EXTENDED
;
3653 uint32_t exclusive_req
= NTCREATEX_FLAGS_REQUEST_OPLOCK
|
3654 NTCREATEX_FLAGS_EXTENDED
;
3656 #define NSTREAM_OPLOCK_RESULTS 8
3659 bool open_base_file
;
3660 uint32_t oplock_req
;
3661 uint32_t oplock_granted
;
3662 } stream_oplock_results
[NSTREAM_OPLOCK_RESULTS
] = {
3663 /* Request oplock on stream without the base file open. */
3664 {&fname_stream
, false, batch_req
, NO_OPLOCK_RETURN
},
3665 {&fname_default_stream
, false, batch_req
, NO_OPLOCK_RETURN
},
3666 {&fname_stream
, false, exclusive_req
, EXCLUSIVE_OPLOCK_RETURN
},
3667 {&fname_default_stream
, false, exclusive_req
, EXCLUSIVE_OPLOCK_RETURN
},
3669 /* Request oplock on stream with the base file open. */
3670 {&fname_stream
, true, batch_req
, NO_OPLOCK_RETURN
},
3671 {&fname_default_stream
, true, batch_req
, NO_OPLOCK_RETURN
},
3672 {&fname_stream
, true, exclusive_req
, EXCLUSIVE_OPLOCK_RETURN
},
3673 {&fname_default_stream
, true, exclusive_req
, LEVEL_II_OPLOCK_RETURN
},
3678 /* Only passes against windows at the moment. */
3679 if (torture_setting_bool(tctx
, "samba3", false) ||
3680 torture_setting_bool(tctx
, "samba4", false)) {
3681 torture_skip(tctx
, "STREAM1 disabled against samba3+4\n");
3684 fname_stream
= talloc_asprintf(tctx
, "%s:%s", fname_base
, stream
);
3685 fname_default_stream
= talloc_asprintf(tctx
, "%s%s", fname_base
,
3688 if (!torture_setup_dir(cli1
, BASEDIR
)) {
3691 smbcli_unlink(cli1
->tree
, fname_base
);
3693 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
, cli1
->tree
);
3694 smbcli_oplock_handler(cli2
->transport
, oplock_handler_ack_to_given
, cli2
->tree
);
3696 /* Setup generic open parameters. */
3697 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
3698 io
.ntcreatex
.in
.root_fid
.fnum
= 0;
3699 io
.ntcreatex
.in
.access_mask
= (SEC_FILE_READ_DATA
|SEC_FILE_WRITE_DATA
|
3700 SEC_FILE_APPEND_DATA
|SEC_STD_READ_CONTROL
);
3701 io
.ntcreatex
.in
.create_options
= 0;
3702 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
3703 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
|
3704 NTCREATEX_SHARE_ACCESS_WRITE
;
3705 io
.ntcreatex
.in
.alloc_size
= 0;
3706 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
3707 io
.ntcreatex
.in
.security_flags
= 0;
3709 /* Create the file with a stream */
3710 io
.ntcreatex
.in
.fname
= fname_stream
;
3711 io
.ntcreatex
.in
.flags
= 0;
3712 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_CREATE
;
3713 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
3714 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
3715 smbcli_close(cli1
->tree
, io
.ntcreatex
.out
.file
.fnum
);
3717 /* Change the disposition to open now that the file has been created. */
3718 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN
;
3720 /* Try some permutations of taking oplocks on streams. */
3721 for (i
= 0; i
< NSTREAM_OPLOCK_RESULTS
; i
++) {
3722 const char *fname
= *stream_oplock_results
[i
].fname
;
3723 bool open_base_file
= stream_oplock_results
[i
].open_base_file
;
3724 uint32_t oplock_req
= stream_oplock_results
[i
].oplock_req
;
3725 uint32_t oplock_granted
=
3726 stream_oplock_results
[i
].oplock_granted
;
3729 if (open_base_file
) {
3730 torture_comment(tctx
, "Opening base file: %s with "
3731 "%d\n", fname_base
, batch_req
);
3732 io
.ntcreatex
.in
.fname
= fname_base
;
3733 io
.ntcreatex
.in
.flags
= batch_req
;
3734 status
= smb_raw_open(cli2
->tree
, tctx
, &io
);
3735 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
3736 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
,
3737 BATCH_OPLOCK_RETURN
);
3738 base_fnum
= io
.ntcreatex
.out
.file
.fnum
;
3741 torture_comment(tctx
, "%d: Opening stream: %s with %d\n", i
,
3743 io
.ntcreatex
.in
.fname
= fname
;
3744 io
.ntcreatex
.in
.flags
= oplock_req
;
3746 /* Do the open with the desired oplock on the stream. */
3747 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
3748 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
3749 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, oplock_granted
);
3750 smbcli_close(cli1
->tree
, io
.ntcreatex
.out
.file
.fnum
);
3752 /* Cleanup the base file if it was opened. */
3753 if (base_fnum
!= -1) {
3754 smbcli_close(cli2
->tree
, base_fnum
);
3758 /* Open the stream with an exclusive oplock. */
3759 torture_comment(tctx
, "Opening stream: %s with %d\n",
3760 fname_stream
, exclusive_req
);
3761 io
.ntcreatex
.in
.fname
= fname_stream
;
3762 io
.ntcreatex
.in
.flags
= exclusive_req
;
3763 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
3764 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
3765 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, EXCLUSIVE_OPLOCK_RETURN
);
3766 stream_fnum
= io
.ntcreatex
.out
.file
.fnum
;
3768 /* Open the base file and see if it contends. */
3769 ZERO_STRUCT(break_info
);
3770 torture_comment(tctx
, "Opening base file: %s with "
3771 "%d\n", fname_base
, batch_req
);
3772 io
.ntcreatex
.in
.fname
= fname_base
;
3773 io
.ntcreatex
.in
.flags
= batch_req
;
3774 status
= smb_raw_open(cli2
->tree
, tctx
, &io
);
3775 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
3776 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
,
3777 BATCH_OPLOCK_RETURN
);
3778 smbcli_close(cli2
->tree
, io
.ntcreatex
.out
.file
.fnum
);
3780 torture_wait_for_oplock_break(tctx
);
3781 CHECK_VAL(break_info
.count
, 0);
3782 CHECK_VAL(break_info
.failures
, 0);
3784 /* Open the stream again to see if it contends. */
3785 ZERO_STRUCT(break_info
);
3786 torture_comment(tctx
, "Opening stream again: %s with "
3787 "%d\n", fname_base
, batch_req
);
3788 io
.ntcreatex
.in
.fname
= fname_stream
;
3789 io
.ntcreatex
.in
.flags
= exclusive_req
;
3790 status
= smb_raw_open(cli2
->tree
, tctx
, &io
);
3791 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
3792 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
,
3793 LEVEL_II_OPLOCK_RETURN
);
3794 smbcli_close(cli2
->tree
, io
.ntcreatex
.out
.file
.fnum
);
3796 torture_wait_for_oplock_break(tctx
);
3797 CHECK_VAL(break_info
.count
, 1);
3798 CHECK_VAL(break_info
.level
, OPLOCK_BREAK_TO_LEVEL_II
);
3799 CHECK_VAL(break_info
.failures
, 0);
3801 /* Close the stream. */
3802 if (stream_fnum
!= -1) {
3803 smbcli_close(cli1
->tree
, stream_fnum
);
3807 smbcli_close(cli1
->tree
, fnum
);
3808 smb_raw_exit(cli1
->session
);
3809 smb_raw_exit(cli2
->session
);
3810 smbcli_deltree(cli1
->tree
, BASEDIR
);
3814 static bool test_raw_oplock_doc(struct torture_context
*tctx
,
3815 struct smbcli_state
*cli
,
3816 struct smbcli_state
*cli2
)
3818 const char *fname
= BASEDIR
"\\test_oplock_doc.dat";
3824 torture_assert(tctx
, torture_setup_dir(cli
, BASEDIR
), "Failed to setup up test directory: " BASEDIR
);
3827 smbcli_unlink(cli
->tree
, fname
);
3829 smbcli_oplock_handler(cli
->transport
, oplock_handler_ack_to_given
,
3833 base ntcreatex parms
3835 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
3836 io
.ntcreatex
.in
.root_fid
.fnum
= 0;
3837 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
3838 io
.ntcreatex
.in
.alloc_size
= 0;
3839 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
3840 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
|
3841 NTCREATEX_SHARE_ACCESS_WRITE
|NTCREATEX_SHARE_ACCESS_DELETE
;
3842 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
3843 io
.ntcreatex
.in
.create_options
= 0;
3844 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
3845 io
.ntcreatex
.in
.security_flags
= 0;
3846 io
.ntcreatex
.in
.fname
= fname
;
3848 torture_comment(tctx
, "open a file with a batch oplock\n");
3849 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
3850 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
3851 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
3853 status
= smb_raw_open(cli
->tree
, tctx
, &io
);
3854 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
3855 fnum
= io
.ntcreatex
.out
.file
.fnum
;
3856 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, BATCH_OPLOCK_RETURN
);
3858 torture_comment(tctx
, "Set delete-on-close\n");
3859 status
= smbcli_nt_delete_on_close(cli
->tree
, fnum
, true);
3860 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
3862 torture_comment(tctx
, "2nd open should not break and get "
3863 "DELETE_PENDING\n");
3864 ZERO_STRUCT(break_info
);
3865 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN
;
3866 io
.ntcreatex
.in
.create_options
= 0;
3867 io
.ntcreatex
.in
.access_mask
= SEC_FILE_READ_DATA
;
3868 status
= smb_raw_open(cli2
->tree
, tctx
, &io
);
3869 CHECK_STATUS(tctx
, status
, NT_STATUS_DELETE_PENDING
);
3870 CHECK_VAL(break_info
.count
, 0);
3872 smbcli_close(cli
->tree
, fnum
);
3875 smb_raw_exit(cli
->session
);
3876 smbcli_deltree(cli
->tree
, BASEDIR
);
3880 /* Open a file with a batch oplock, then open it again from a second client
3881 * requesting no oplock. Having two open file handles should break our own
3882 * oplock during BRL acquisition.
3884 static bool test_raw_oplock_brl1(struct torture_context
*tctx
,
3885 struct smbcli_state
*cli1
,
3886 struct smbcli_state
*cli2
)
3888 const char *fname
= BASEDIR
"\\test_batch_brl.dat";
3897 if (!torture_setup_dir(cli1
, BASEDIR
)) {
3902 smbcli_unlink(cli1
->tree
, fname
);
3904 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
,
3908 base ntcreatex parms
3910 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
3911 io
.ntcreatex
.in
.root_fid
.fnum
= 0;
3912 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_READ
|
3913 SEC_RIGHTS_FILE_WRITE
;
3914 io
.ntcreatex
.in
.alloc_size
= 0;
3915 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
3916 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
|
3917 NTCREATEX_SHARE_ACCESS_WRITE
;
3918 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
3919 io
.ntcreatex
.in
.create_options
= 0;
3920 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
3921 io
.ntcreatex
.in
.security_flags
= 0;
3922 io
.ntcreatex
.in
.fname
= fname
;
3925 with a batch oplock we get a break
3927 torture_comment(tctx
, "open with batch oplock\n");
3928 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
3929 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
3930 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
3932 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
3933 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
3934 fnum
= io
.ntcreatex
.out
.file
.fnum
;
3935 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, BATCH_OPLOCK_RETURN
);
3936 /* create a file with bogus data */
3937 memset(buf
, 0, sizeof(buf
));
3939 if (smbcli_write(cli1
->tree
, fnum
, 0, buf
, 0, sizeof(buf
)) !=
3942 torture_comment(tctx
, "Failed to create file\n");
3946 torture_comment(tctx
, "a 2nd open should give a break\n");
3947 ZERO_STRUCT(break_info
);
3949 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
;
3950 status
= smb_raw_open(cli2
->tree
, tctx
, &io
);
3951 fnum2
= io
.ntcreatex
.out
.file
.fnum
;
3952 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
3953 CHECK_VAL(break_info
.count
, 1);
3954 CHECK_VAL(break_info
.level
, OPLOCK_BREAK_TO_LEVEL_II
);
3955 CHECK_VAL(break_info
.failures
, 0);
3956 CHECK_VAL(break_info
.fnum
, fnum
);
3958 ZERO_STRUCT(break_info
);
3960 torture_comment(tctx
, "a self BRL acquisition should break to none\n");
3962 status
= smbcli_lock(cli1
->tree
, fnum
, 0, 4, 0, WRITE_LOCK
);
3963 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
3965 torture_wait_for_oplock_break(tctx
);
3966 CHECK_VAL(break_info
.count
, 1);
3967 CHECK_VAL(break_info
.level
, OPLOCK_BREAK_TO_NONE
);
3968 CHECK_VAL(break_info
.fnum
, fnum
);
3969 CHECK_VAL(break_info
.failures
, 0);
3971 /* expect no oplock break */
3972 ZERO_STRUCT(break_info
);
3973 status
= smbcli_lock(cli1
->tree
, fnum
, 2, 4, 0, WRITE_LOCK
);
3974 CHECK_STATUS(tctx
, status
, NT_STATUS_LOCK_NOT_GRANTED
);
3976 torture_wait_for_oplock_break(tctx
);
3977 CHECK_VAL(break_info
.count
, 0);
3978 CHECK_VAL(break_info
.level
, 0);
3979 CHECK_VAL(break_info
.fnum
, 0);
3980 CHECK_VAL(break_info
.failures
, 0);
3982 smbcli_close(cli1
->tree
, fnum
);
3983 smbcli_close(cli2
->tree
, fnum2
);
3986 smb_raw_exit(cli1
->session
);
3987 smb_raw_exit(cli2
->session
);
3988 smbcli_deltree(cli1
->tree
, BASEDIR
);
3993 /* Open a file with a batch oplock on one client and then acquire a brl.
3994 * We should not contend our own oplock.
3996 static bool test_raw_oplock_brl2(struct torture_context
*tctx
, struct smbcli_state
*cli1
)
3998 const char *fname
= BASEDIR
"\\test_batch_brl.dat";
4006 if (!torture_setup_dir(cli1
, BASEDIR
)) {
4011 smbcli_unlink(cli1
->tree
, fname
);
4013 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
,
4017 base ntcreatex parms
4019 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
4020 io
.ntcreatex
.in
.root_fid
.fnum
= 0;
4021 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_READ
|
4022 SEC_RIGHTS_FILE_WRITE
;
4023 io
.ntcreatex
.in
.alloc_size
= 0;
4024 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
4025 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
|
4026 NTCREATEX_SHARE_ACCESS_WRITE
;
4027 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
4028 io
.ntcreatex
.in
.create_options
= 0;
4029 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
4030 io
.ntcreatex
.in
.security_flags
= 0;
4031 io
.ntcreatex
.in
.fname
= fname
;
4034 with a batch oplock we get a break
4036 torture_comment(tctx
, "open with batch oplock\n");
4037 ZERO_STRUCT(break_info
);
4038 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
4039 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
4040 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
4042 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
4043 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
4044 fnum
= io
.ntcreatex
.out
.file
.fnum
;
4045 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, BATCH_OPLOCK_RETURN
);
4047 /* create a file with bogus data */
4048 memset(buf
, 0, sizeof(buf
));
4050 if (smbcli_write(cli1
->tree
, fnum
, 0, buf
, 0, sizeof(buf
)) !=
4053 torture_comment(tctx
, "Failed to create file\n");
4057 torture_comment(tctx
, "a self BRL acquisition should not break to "
4060 status
= smbcli_lock(cli1
->tree
, fnum
, 0, 4, 0, WRITE_LOCK
);
4061 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
4063 status
= smbcli_lock(cli1
->tree
, fnum
, 2, 4, 0, WRITE_LOCK
);
4064 CHECK_STATUS(tctx
, status
, NT_STATUS_LOCK_NOT_GRANTED
);
4066 /* With one file handle open a BRL should not contend our oplock.
4067 * Thus, no oplock break will be received and the entire break_info
4068 * struct will be 0 */
4069 torture_wait_for_oplock_break(tctx
);
4070 CHECK_VAL(break_info
.fnum
, 0);
4071 CHECK_VAL(break_info
.count
, 0);
4072 CHECK_VAL(break_info
.level
, 0);
4073 CHECK_VAL(break_info
.failures
, 0);
4075 smbcli_close(cli1
->tree
, fnum
);
4078 smb_raw_exit(cli1
->session
);
4079 smbcli_deltree(cli1
->tree
, BASEDIR
);
4083 /* Open a file with a batch oplock twice from one client and then acquire a
4084 * brl. BRL acquisition should break our own oplock.
4086 static bool test_raw_oplock_brl3(struct torture_context
*tctx
,
4087 struct smbcli_state
*cli1
)
4089 const char *fname
= BASEDIR
"\\test_batch_brl.dat";
4097 if (!torture_setup_dir(cli1
, BASEDIR
)) {
4102 smbcli_unlink(cli1
->tree
, fname
);
4104 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
,
4108 base ntcreatex parms
4110 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
4111 io
.ntcreatex
.in
.root_fid
.fnum
= 0;
4112 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_READ
|
4113 SEC_RIGHTS_FILE_WRITE
;
4114 io
.ntcreatex
.in
.alloc_size
= 0;
4115 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
4116 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
|
4117 NTCREATEX_SHARE_ACCESS_WRITE
;
4118 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
4119 io
.ntcreatex
.in
.create_options
= 0;
4120 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
4121 io
.ntcreatex
.in
.security_flags
= 0;
4122 io
.ntcreatex
.in
.fname
= fname
;
4125 with a batch oplock we get a break
4127 torture_comment(tctx
, "open with batch oplock\n");
4128 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
4129 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
4130 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
4132 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
4133 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
4134 fnum
= io
.ntcreatex
.out
.file
.fnum
;
4135 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, BATCH_OPLOCK_RETURN
);
4137 /* create a file with bogus data */
4138 memset(buf
, 0, sizeof(buf
));
4140 if (smbcli_write(cli1
->tree
, fnum
, 0, buf
, 0, sizeof(buf
)) !=
4143 torture_comment(tctx
, "Failed to create file\n");
4148 torture_comment(tctx
, "a 2nd open should give a break\n");
4149 ZERO_STRUCT(break_info
);
4151 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
;
4152 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
4153 fnum2
= io
.ntcreatex
.out
.file
.fnum
;
4154 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
4155 CHECK_VAL(break_info
.count
, 1);
4156 CHECK_VAL(break_info
.level
, OPLOCK_BREAK_TO_LEVEL_II
);
4157 CHECK_VAL(break_info
.failures
, 0);
4158 CHECK_VAL(break_info
.fnum
, fnum
);
4160 ZERO_STRUCT(break_info
);
4162 torture_comment(tctx
, "a self BRL acquisition should break to none\n");
4164 status
= smbcli_lock(cli1
->tree
, fnum
, 0, 4, 0, WRITE_LOCK
);
4165 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
4167 torture_wait_for_oplock_break(tctx
);
4168 CHECK_VAL(break_info
.count
, 1);
4169 CHECK_VAL(break_info
.level
, OPLOCK_BREAK_TO_NONE
);
4170 CHECK_VAL(break_info
.fnum
, fnum
);
4171 CHECK_VAL(break_info
.failures
, 0);
4173 /* expect no oplock break */
4174 ZERO_STRUCT(break_info
);
4175 status
= smbcli_lock(cli1
->tree
, fnum
, 2, 4, 0, WRITE_LOCK
);
4176 CHECK_STATUS(tctx
, status
, NT_STATUS_LOCK_NOT_GRANTED
);
4178 torture_wait_for_oplock_break(tctx
);
4179 CHECK_VAL(break_info
.count
, 0);
4180 CHECK_VAL(break_info
.level
, 0);
4181 CHECK_VAL(break_info
.fnum
, 0);
4182 CHECK_VAL(break_info
.failures
, 0);
4184 smbcli_close(cli1
->tree
, fnum
);
4185 smbcli_close(cli1
->tree
, fnum2
);
4188 smb_raw_exit(cli1
->session
);
4189 smbcli_deltree(cli1
->tree
, BASEDIR
);
4194 * Open a file with an exclusive oplock from the 1st client and acquire a
4195 * brl. Then open the same file from the 2nd client that should give oplock
4196 * break with level2 to the 1st and return no oplock to the 2nd.
4198 static bool test_raw_oplock_brl4(struct torture_context
*tctx
,
4199 struct smbcli_state
*cli1
,
4200 struct smbcli_state
*cli2
)
4202 const char *fname
= BASEDIR
"\\test_batch_brl.dat";
4210 if (!torture_setup_dir(cli1
, BASEDIR
)) {
4215 smbcli_unlink(cli1
->tree
, fname
);
4217 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_given
,
4221 base ntcreatex parms
4223 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
4224 io
.ntcreatex
.in
.root_fid
.fnum
= 0;
4225 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_READ
|
4226 SEC_RIGHTS_FILE_WRITE
;
4227 io
.ntcreatex
.in
.alloc_size
= 0;
4228 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
4229 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
|
4230 NTCREATEX_SHARE_ACCESS_WRITE
;
4231 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
4232 io
.ntcreatex
.in
.create_options
= 0;
4233 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
4234 io
.ntcreatex
.in
.security_flags
= 0;
4235 io
.ntcreatex
.in
.fname
= fname
;
4237 torture_comment(tctx
, "open with exclusive oplock\n");
4238 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
4239 NTCREATEX_FLAGS_REQUEST_OPLOCK
;
4241 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
4243 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
4244 fnum
= io
.ntcreatex
.out
.file
.fnum
;
4245 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, EXCLUSIVE_OPLOCK_RETURN
);
4247 /* create a file with bogus data */
4248 memset(buf
, 0, sizeof(buf
));
4250 if (smbcli_write(cli1
->tree
, fnum
, 0, buf
, 0, sizeof(buf
)) !=
4253 torture_comment(tctx
, "Failed to create file\n");
4257 status
= smbcli_lock(cli1
->tree
, fnum
, 0, 1, 0, WRITE_LOCK
);
4258 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
4260 torture_comment(tctx
, "a 2nd open should give a break to the 1st\n");
4261 ZERO_STRUCT(break_info
);
4263 status
= smb_raw_open(cli2
->tree
, tctx
, &io
);
4265 CHECK_STATUS(tctx
, status
, NT_STATUS_OK
);
4266 CHECK_VAL(break_info
.count
, 1);
4267 CHECK_VAL(break_info
.level
, OPLOCK_BREAK_TO_LEVEL_II
);
4268 CHECK_VAL(break_info
.failures
, 0);
4269 CHECK_VAL(break_info
.fnum
, fnum
);
4271 torture_comment(tctx
, "and return no oplock to the 2nd\n");
4272 fnum2
= io
.ntcreatex
.out
.file
.fnum
;
4273 CHECK_VAL(io
.ntcreatex
.out
.oplock_level
, NO_OPLOCK_RETURN
);
4275 smbcli_close(cli1
->tree
, fnum
);
4276 smbcli_close(cli2
->tree
, fnum2
);
4279 smb_raw_exit(cli1
->session
);
4280 smb_raw_exit(cli2
->session
);
4281 smbcli_deltree(cli1
->tree
, BASEDIR
);
4286 basic testing of oplocks
4288 struct torture_suite
*torture_raw_oplock(TALLOC_CTX
*mem_ctx
)
4290 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "oplock");
4292 torture_suite_add_2smb_test(suite
, "exclusive1", test_raw_oplock_exclusive1
);
4293 torture_suite_add_2smb_test(suite
, "exclusive2", test_raw_oplock_exclusive2
);
4294 torture_suite_add_2smb_test(suite
, "exclusive3", test_raw_oplock_exclusive3
);
4295 torture_suite_add_2smb_test(suite
, "exclusive4", test_raw_oplock_exclusive4
);
4296 torture_suite_add_2smb_test(suite
, "exclusive5", test_raw_oplock_exclusive5
);
4297 torture_suite_add_2smb_test(suite
, "exclusive6", test_raw_oplock_exclusive6
);
4298 torture_suite_add_2smb_test(suite
, "exclusive7", test_raw_oplock_exclusive7
);
4299 torture_suite_add_2smb_test(suite
, "exclusive8",
4300 test_raw_oplock_exclusive8
);
4301 torture_suite_add_2smb_test(suite
, "exclusive9",
4302 test_raw_oplock_exclusive9
);
4303 torture_suite_add_2smb_test(suite
, "level_ii_1",
4304 test_raw_oplock_level_ii_1
);
4305 torture_suite_add_2smb_test(suite
, "batch1", test_raw_oplock_batch1
);
4306 torture_suite_add_2smb_test(suite
, "batch2", test_raw_oplock_batch2
);
4307 torture_suite_add_2smb_test(suite
, "batch3", test_raw_oplock_batch3
);
4308 torture_suite_add_2smb_test(suite
, "batch4", test_raw_oplock_batch4
);
4309 torture_suite_add_2smb_test(suite
, "batch5", test_raw_oplock_batch5
);
4310 torture_suite_add_2smb_test(suite
, "batch6", test_raw_oplock_batch6
);
4311 torture_suite_add_2smb_test(suite
, "batch7", test_raw_oplock_batch7
);
4312 torture_suite_add_2smb_test(suite
, "batch8", test_raw_oplock_batch8
);
4313 torture_suite_add_2smb_test(suite
, "batch9", test_raw_oplock_batch9
);
4314 torture_suite_add_2smb_test(suite
, "batch10", test_raw_oplock_batch10
);
4315 torture_suite_add_2smb_test(suite
, "batch11", test_raw_oplock_batch11
);
4316 torture_suite_add_2smb_test(suite
, "batch12", test_raw_oplock_batch12
);
4317 torture_suite_add_2smb_test(suite
, "batch13", test_raw_oplock_batch13
);
4318 torture_suite_add_2smb_test(suite
, "batch14", test_raw_oplock_batch14
);
4319 torture_suite_add_2smb_test(suite
, "batch15", test_raw_oplock_batch15
);
4320 torture_suite_add_2smb_test(suite
, "batch16", test_raw_oplock_batch16
);
4321 torture_suite_add_2smb_test(suite
, "batch17", test_raw_oplock_batch17
);
4322 torture_suite_add_2smb_test(suite
, "batch18", test_raw_oplock_batch18
);
4323 torture_suite_add_2smb_test(suite
, "batch19", test_raw_oplock_batch19
);
4324 torture_suite_add_2smb_test(suite
, "batch20", test_raw_oplock_batch20
);
4325 torture_suite_add_2smb_test(suite
, "batch21", test_raw_oplock_batch21
);
4326 torture_suite_add_2smb_test(suite
, "batch22", test_raw_oplock_batch22
);
4327 torture_suite_add_2smb_test(suite
, "batch23", test_raw_oplock_batch23
);
4328 torture_suite_add_2smb_test(suite
, "batch24", test_raw_oplock_batch24
);
4329 torture_suite_add_2smb_test(suite
, "batch25", test_raw_oplock_batch25
);
4330 torture_suite_add_2smb_test(suite
, "batch26", test_raw_oplock_batch26
);
4331 torture_suite_add_2smb_test(suite
, "stream1", test_raw_oplock_stream1
);
4332 torture_suite_add_2smb_test(suite
, "doc1", test_raw_oplock_doc
);
4333 torture_suite_add_2smb_test(suite
, "brl1", test_raw_oplock_brl1
);
4334 torture_suite_add_1smb_test(suite
, "brl2", test_raw_oplock_brl2
);
4335 torture_suite_add_1smb_test(suite
, "brl3", test_raw_oplock_brl3
);
4336 torture_suite_add_2smb_test(suite
, "brl4", test_raw_oplock_brl4
);
4342 stress testing of oplocks
4344 bool torture_bench_oplock(struct torture_context
*torture
)
4346 struct smbcli_state
**cli
;
4348 TALLOC_CTX
*mem_ctx
= talloc_new(torture
);
4349 int torture_nprocs
= torture_setting_int(torture
, "nprocs", 4);
4351 int timelimit
= torture_setting_int(torture
, "timelimit", 10);
4355 cli
= talloc_array(mem_ctx
, struct smbcli_state
*, torture_nprocs
);
4357 torture_comment(torture
, "Opening %d connections\n", torture_nprocs
);
4358 for (i
=0;i
<torture_nprocs
;i
++) {
4359 if (!torture_open_connection_ev(&cli
[i
], i
, torture
, torture
->ev
)) {
4362 talloc_steal(mem_ctx
, cli
[i
]);
4363 smbcli_oplock_handler(cli
[i
]->transport
, oplock_handler_close
,
4367 if (!torture_setup_dir(cli
[0], BASEDIR
)) {
4372 io
.ntcreatex
.level
= RAW_OPEN_NTCREATEX
;
4373 io
.ntcreatex
.in
.root_fid
.fnum
= 0;
4374 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
4375 io
.ntcreatex
.in
.alloc_size
= 0;
4376 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
4377 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
4378 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
4379 io
.ntcreatex
.in
.create_options
= 0;
4380 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
4381 io
.ntcreatex
.in
.security_flags
= 0;
4382 io
.ntcreatex
.in
.fname
= BASEDIR
"\\test.dat";
4383 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
4384 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
4385 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
4387 tv
= timeval_current();
4390 we open the same file with SHARE_ACCESS_NONE from all the
4391 connections in a round robin fashion. Each open causes an
4392 oplock break on the previous connection, which is answered
4393 by the oplock_handler_close() to close the file.
4395 This measures how fast we can pass on oplocks, and stresses
4396 the oplock handling code
4398 torture_comment(torture
, "Running for %d seconds\n", timelimit
);
4399 while (timeval_elapsed(&tv
) < timelimit
) {
4400 for (i
=0;i
<torture_nprocs
;i
++) {
4403 status
= smb_raw_open(cli
[i
]->tree
, mem_ctx
, &io
);
4404 CHECK_STATUS(torture
, status
, NT_STATUS_OK
);
4408 if (torture_setting_bool(torture
, "progress", true)) {
4409 torture_comment(torture
, "%.2f ops/second\r", count
/timeval_elapsed(&tv
));
4413 torture_comment(torture
, "%.2f ops/second\n", count
/timeval_elapsed(&tv
));
4415 smb_raw_exit(cli
[torture_nprocs
-1]->session
);
4418 smb_raw_exit(cli
[0]->session
);
4419 smbcli_deltree(cli
[0]->tree
, BASEDIR
);
4420 talloc_free(mem_ctx
);
4425 static struct hold_oplock_info
{
4427 bool close_on_break
;
4428 uint32_t share_access
;
4431 { BASEDIR
"\\notshared_close", true,
4432 NTCREATEX_SHARE_ACCESS_NONE
, },
4433 { BASEDIR
"\\notshared_noclose", false,
4434 NTCREATEX_SHARE_ACCESS_NONE
, },
4435 { BASEDIR
"\\shared_close", true,
4436 NTCREATEX_SHARE_ACCESS_READ
|NTCREATEX_SHARE_ACCESS_WRITE
|NTCREATEX_SHARE_ACCESS_DELETE
, },
4437 { BASEDIR
"\\shared_noclose", false,
4438 NTCREATEX_SHARE_ACCESS_READ
|NTCREATEX_SHARE_ACCESS_WRITE
|NTCREATEX_SHARE_ACCESS_DELETE
, },
4441 static bool oplock_handler_hold(struct smbcli_transport
*transport
,
4442 uint16_t tid
, uint16_t fnum
, uint8_t level
,
4445 struct smbcli_tree
*tree
= (struct smbcli_tree
*)private_data
;
4446 struct hold_oplock_info
*info
;
4449 for (i
=0;i
<ARRAY_SIZE(hold_info
);i
++) {
4450 if (hold_info
[i
].fnum
== fnum
) break;
4453 if (i
== ARRAY_SIZE(hold_info
)) {
4454 printf("oplock break for unknown fnum %u\n", fnum
);
4458 info
= &hold_info
[i
];
4460 if (info
->close_on_break
) {
4461 printf("oplock break on %s - closing\n",
4463 oplock_handler_close(transport
, tid
, fnum
, level
, private_data
);
4467 printf("oplock break on %s - acking break\n", info
->fname
);
4469 return smbcli_oplock_ack(tree
, fnum
, OPLOCK_BREAK_TO_NONE
);
4474 used for manual testing of oplocks - especially interaction with
4475 other filesystems (such as NFS and local access)
4477 bool torture_hold_oplock(struct torture_context
*torture
,
4478 struct smbcli_state
*cli
)
4480 struct tevent_context
*ev
= torture
->ev
;
4483 printf("Setting up open files with oplocks in %s\n", BASEDIR
);
4485 torture_assert(torture
, torture_setup_dir(cli
, BASEDIR
), "Failed to setup up test directory: " BASEDIR
);
4487 smbcli_oplock_handler(cli
->transport
, oplock_handler_hold
, cli
->tree
);
4489 /* setup the files */
4490 for (i
=0;i
<ARRAY_SIZE(hold_info
);i
++) {
4495 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
4496 io
.ntcreatex
.in
.root_fid
.fnum
= 0;
4497 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
4498 io
.ntcreatex
.in
.alloc_size
= 0;
4499 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
4500 io
.ntcreatex
.in
.share_access
= hold_info
[i
].share_access
;
4501 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
4502 io
.ntcreatex
.in
.create_options
= 0;
4503 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
4504 io
.ntcreatex
.in
.security_flags
= 0;
4505 io
.ntcreatex
.in
.fname
= hold_info
[i
].fname
;
4506 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
4507 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
4508 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
4509 printf("opening %s\n", hold_info
[i
].fname
);
4511 status
= smb_raw_open(cli
->tree
, cli
, &io
);
4512 if (!NT_STATUS_IS_OK(status
)) {
4513 printf("Failed to open %s - %s\n",
4514 hold_info
[i
].fname
, nt_errstr(status
));
4518 if (io
.ntcreatex
.out
.oplock_level
!= BATCH_OPLOCK_RETURN
) {
4519 printf("Oplock not granted for %s - expected %d but got %d\n",
4520 hold_info
[i
].fname
, BATCH_OPLOCK_RETURN
,
4521 io
.ntcreatex
.out
.oplock_level
);
4524 hold_info
[i
].fnum
= io
.ntcreatex
.out
.file
.fnum
;
4526 /* make the file non-zero size */
4527 if (smbcli_write(cli
->tree
, hold_info
[i
].fnum
, 0, &c
, 0, 1) != 1) {
4528 printf("Failed to write to file\n");
4533 printf("Waiting for oplock events\n");
4534 tevent_loop_wait(ev
);