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