2 Unix SMB/CIFS implementation.
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 "system/filesys.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 "torture/raw/proto.h"
29 #define CHECK_STATUS(status, correct) do { \
30 if (!NT_STATUS_EQUAL(status, correct)) { \
31 printf("(%s) Incorrect status %s - should be %s\n", \
32 __location__, nt_errstr(status), nt_errstr(correct)); \
37 #define BASEDIR "\\testunlink"
42 static bool test_unlink(struct torture_context
*tctx
, struct smbcli_state
*cli
)
47 const char *fname
= BASEDIR
"\\test.txt";
49 if (!torture_setup_dir(cli
, BASEDIR
)) {
53 printf("Trying non-existant file\n");
54 io
.unlink
.in
.pattern
= fname
;
55 io
.unlink
.in
.attrib
= 0;
56 status
= smb_raw_unlink(cli
->tree
, &io
);
57 CHECK_STATUS(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
);
59 smbcli_close(cli
->tree
, smbcli_open(cli
->tree
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
));
61 io
.unlink
.in
.pattern
= fname
;
62 io
.unlink
.in
.attrib
= 0;
63 status
= smb_raw_unlink(cli
->tree
, &io
);
64 CHECK_STATUS(status
, NT_STATUS_OK
);
66 printf("Trying a hidden file\n");
67 smbcli_close(cli
->tree
, smbcli_open(cli
->tree
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
));
68 torture_set_file_attribute(cli
->tree
, fname
, FILE_ATTRIBUTE_HIDDEN
);
70 io
.unlink
.in
.pattern
= fname
;
71 io
.unlink
.in
.attrib
= 0;
72 status
= smb_raw_unlink(cli
->tree
, &io
);
73 CHECK_STATUS(status
, NT_STATUS_NO_SUCH_FILE
);
75 io
.unlink
.in
.pattern
= fname
;
76 io
.unlink
.in
.attrib
= FILE_ATTRIBUTE_HIDDEN
;
77 status
= smb_raw_unlink(cli
->tree
, &io
);
78 CHECK_STATUS(status
, NT_STATUS_OK
);
80 io
.unlink
.in
.pattern
= fname
;
81 io
.unlink
.in
.attrib
= FILE_ATTRIBUTE_HIDDEN
;
82 status
= smb_raw_unlink(cli
->tree
, &io
);
83 CHECK_STATUS(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
);
85 printf("Trying a directory\n");
86 io
.unlink
.in
.pattern
= BASEDIR
;
87 io
.unlink
.in
.attrib
= 0;
88 status
= smb_raw_unlink(cli
->tree
, &io
);
89 CHECK_STATUS(status
, NT_STATUS_FILE_IS_A_DIRECTORY
);
91 io
.unlink
.in
.pattern
= BASEDIR
;
92 io
.unlink
.in
.attrib
= FILE_ATTRIBUTE_DIRECTORY
;
93 status
= smb_raw_unlink(cli
->tree
, &io
);
94 CHECK_STATUS(status
, NT_STATUS_FILE_IS_A_DIRECTORY
);
96 printf("Trying a bad path\n");
97 io
.unlink
.in
.pattern
= "..";
98 io
.unlink
.in
.attrib
= 0;
99 status
= smb_raw_unlink(cli
->tree
, &io
);
100 CHECK_STATUS(status
, NT_STATUS_OBJECT_PATH_SYNTAX_BAD
);
102 io
.unlink
.in
.pattern
= "\\..";
103 io
.unlink
.in
.attrib
= 0;
104 status
= smb_raw_unlink(cli
->tree
, &io
);
105 CHECK_STATUS(status
, NT_STATUS_OBJECT_PATH_SYNTAX_BAD
);
107 io
.unlink
.in
.pattern
= BASEDIR
"\\..\\..";
108 io
.unlink
.in
.attrib
= 0;
109 status
= smb_raw_unlink(cli
->tree
, &io
);
110 CHECK_STATUS(status
, NT_STATUS_OBJECT_PATH_SYNTAX_BAD
);
112 io
.unlink
.in
.pattern
= BASEDIR
"\\..";
113 io
.unlink
.in
.attrib
= 0;
114 status
= smb_raw_unlink(cli
->tree
, &io
);
115 CHECK_STATUS(status
, NT_STATUS_FILE_IS_A_DIRECTORY
);
117 printf("Trying wildcards\n");
118 smbcli_close(cli
->tree
, smbcli_open(cli
->tree
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
));
119 io
.unlink
.in
.pattern
= BASEDIR
"\\t*.t";
120 io
.unlink
.in
.attrib
= 0;
121 status
= smb_raw_unlink(cli
->tree
, &io
);
122 CHECK_STATUS(status
, NT_STATUS_NO_SUCH_FILE
);
124 io
.unlink
.in
.pattern
= BASEDIR
"\\z*";
125 io
.unlink
.in
.attrib
= 0;
126 status
= smb_raw_unlink(cli
->tree
, &io
);
127 CHECK_STATUS(status
, NT_STATUS_NO_SUCH_FILE
);
129 io
.unlink
.in
.pattern
= BASEDIR
"\\z*";
130 io
.unlink
.in
.attrib
= FILE_ATTRIBUTE_DIRECTORY
;
131 status
= smb_raw_unlink(cli
->tree
, &io
);
133 if (torture_setting_bool(tctx
, "samba3", false)) {
135 * In Samba3 we gave up upon getting the error codes in
136 * wildcard unlink correct. Trying gentest showed that this is
137 * irregular beyond our capabilities. So for
138 * FILE_ATTRIBUTE_DIRECTORY we always return NAME_INVALID.
139 * Tried by jra and vl. If others feel like solving this
140 * puzzle, please tell us :-)
142 CHECK_STATUS(status
, NT_STATUS_OBJECT_NAME_INVALID
);
145 CHECK_STATUS(status
, NT_STATUS_NO_SUCH_FILE
);
148 io
.unlink
.in
.pattern
= BASEDIR
"\\*";
149 io
.unlink
.in
.attrib
= FILE_ATTRIBUTE_DIRECTORY
;
150 status
= smb_raw_unlink(cli
->tree
, &io
);
151 CHECK_STATUS(status
, NT_STATUS_OBJECT_NAME_INVALID
);
153 io
.unlink
.in
.pattern
= BASEDIR
"\\?";
154 io
.unlink
.in
.attrib
= FILE_ATTRIBUTE_DIRECTORY
;
155 status
= smb_raw_unlink(cli
->tree
, &io
);
156 CHECK_STATUS(status
, NT_STATUS_OBJECT_NAME_INVALID
);
158 io
.unlink
.in
.pattern
= BASEDIR
"\\t*";
159 io
.unlink
.in
.attrib
= FILE_ATTRIBUTE_DIRECTORY
;
160 status
= smb_raw_unlink(cli
->tree
, &io
);
161 if (torture_setting_bool(tctx
, "samba3", false)) {
162 CHECK_STATUS(status
, NT_STATUS_OBJECT_NAME_INVALID
);
165 CHECK_STATUS(status
, NT_STATUS_OK
);
168 smbcli_close(cli
->tree
, smbcli_open(cli
->tree
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
));
170 io
.unlink
.in
.pattern
= BASEDIR
"\\*.dat";
171 io
.unlink
.in
.attrib
= FILE_ATTRIBUTE_DIRECTORY
;
172 status
= smb_raw_unlink(cli
->tree
, &io
);
173 if (torture_setting_bool(tctx
, "samba3", false)) {
174 CHECK_STATUS(status
, NT_STATUS_OBJECT_NAME_INVALID
);
177 CHECK_STATUS(status
, NT_STATUS_NO_SUCH_FILE
);
180 io
.unlink
.in
.pattern
= BASEDIR
"\\*.tx?";
181 io
.unlink
.in
.attrib
= 0;
182 status
= smb_raw_unlink(cli
->tree
, &io
);
183 if (torture_setting_bool(tctx
, "samba3", false)) {
184 CHECK_STATUS(status
, NT_STATUS_NO_SUCH_FILE
);
187 CHECK_STATUS(status
, NT_STATUS_OK
);
190 status
= smb_raw_unlink(cli
->tree
, &io
);
191 CHECK_STATUS(status
, NT_STATUS_NO_SUCH_FILE
);
195 smb_raw_exit(cli
->session
);
196 smbcli_deltree(cli
->tree
, BASEDIR
);
204 static bool test_delete_on_close(struct torture_context
*tctx
,
205 struct smbcli_state
*cli
)
209 struct smb_rmdir dio
;
213 const char *fname
= BASEDIR
"\\test.txt";
214 const char *dname
= BASEDIR
"\\test.dir";
215 const char *inside
= BASEDIR
"\\test.dir\\test.txt";
216 union smb_setfileinfo sfinfo
;
218 if (!torture_setup_dir(cli
, BASEDIR
)) {
224 io
.unlink
.in
.pattern
= fname
;
225 io
.unlink
.in
.attrib
= 0;
226 status
= smb_raw_unlink(cli
->tree
, &io
);
227 CHECK_STATUS(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
);
229 printf("Testing with delete_on_close 0\n");
230 fnum
= create_complex_file(cli
, tctx
, fname
);
232 sfinfo
.disposition_info
.level
= RAW_SFILEINFO_DISPOSITION_INFO
;
233 sfinfo
.disposition_info
.in
.file
.fnum
= fnum
;
234 sfinfo
.disposition_info
.in
.delete_on_close
= 0;
235 status
= smb_raw_setfileinfo(cli
->tree
, &sfinfo
);
236 CHECK_STATUS(status
, NT_STATUS_OK
);
238 smbcli_close(cli
->tree
, fnum
);
240 status
= smb_raw_unlink(cli
->tree
, &io
);
241 CHECK_STATUS(status
, NT_STATUS_OK
);
243 printf("Testing with delete_on_close 1\n");
244 fnum
= create_complex_file(cli
, tctx
, fname
);
245 sfinfo
.disposition_info
.in
.file
.fnum
= fnum
;
246 sfinfo
.disposition_info
.in
.delete_on_close
= 1;
247 status
= smb_raw_setfileinfo(cli
->tree
, &sfinfo
);
248 CHECK_STATUS(status
, NT_STATUS_OK
);
250 smbcli_close(cli
->tree
, fnum
);
252 status
= smb_raw_unlink(cli
->tree
, &io
);
253 CHECK_STATUS(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
);
256 printf("Testing with directory and delete_on_close 0\n");
257 status
= create_directory_handle(cli
->tree
, dname
, &fnum
);
258 CHECK_STATUS(status
, NT_STATUS_OK
);
260 sfinfo
.disposition_info
.level
= RAW_SFILEINFO_DISPOSITION_INFO
;
261 sfinfo
.disposition_info
.in
.file
.fnum
= fnum
;
262 sfinfo
.disposition_info
.in
.delete_on_close
= 0;
263 status
= smb_raw_setfileinfo(cli
->tree
, &sfinfo
);
264 CHECK_STATUS(status
, NT_STATUS_OK
);
266 smbcli_close(cli
->tree
, fnum
);
268 status
= smb_raw_rmdir(cli
->tree
, &dio
);
269 CHECK_STATUS(status
, NT_STATUS_OK
);
271 printf("Testing with directory delete_on_close 1\n");
272 status
= create_directory_handle(cli
->tree
, dname
, &fnum
);
273 CHECK_STATUS(status
, NT_STATUS_OK
);
275 sfinfo
.disposition_info
.in
.file
.fnum
= fnum
;
276 sfinfo
.disposition_info
.in
.delete_on_close
= 1;
277 status
= smb_raw_setfileinfo(cli
->tree
, &sfinfo
);
278 CHECK_STATUS(status
, NT_STATUS_OK
);
280 smbcli_close(cli
->tree
, fnum
);
282 status
= smb_raw_rmdir(cli
->tree
, &dio
);
283 CHECK_STATUS(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
);
286 if (!torture_setting_bool(tctx
, "samba3", false)) {
289 * Known deficiency, also skipped in base-delete.
292 printf("Testing with non-empty directory delete_on_close\n");
293 status
= create_directory_handle(cli
->tree
, dname
, &fnum
);
294 CHECK_STATUS(status
, NT_STATUS_OK
);
296 fnum2
= create_complex_file(cli
, tctx
, inside
);
298 sfinfo
.disposition_info
.in
.file
.fnum
= fnum
;
299 sfinfo
.disposition_info
.in
.delete_on_close
= 1;
300 status
= smb_raw_setfileinfo(cli
->tree
, &sfinfo
);
301 CHECK_STATUS(status
, NT_STATUS_DIRECTORY_NOT_EMPTY
);
303 sfinfo
.disposition_info
.in
.file
.fnum
= fnum2
;
304 status
= smb_raw_setfileinfo(cli
->tree
, &sfinfo
);
305 CHECK_STATUS(status
, NT_STATUS_OK
);
307 sfinfo
.disposition_info
.in
.file
.fnum
= fnum
;
308 status
= smb_raw_setfileinfo(cli
->tree
, &sfinfo
);
309 CHECK_STATUS(status
, NT_STATUS_DIRECTORY_NOT_EMPTY
);
311 smbcli_close(cli
->tree
, fnum2
);
313 status
= smb_raw_setfileinfo(cli
->tree
, &sfinfo
);
314 CHECK_STATUS(status
, NT_STATUS_OK
);
316 smbcli_close(cli
->tree
, fnum
);
318 status
= smb_raw_rmdir(cli
->tree
, &dio
);
319 CHECK_STATUS(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
);
322 printf("Testing open dir with delete_on_close\n");
323 status
= create_directory_handle(cli
->tree
, dname
, &fnum
);
324 CHECK_STATUS(status
, NT_STATUS_OK
);
326 smbcli_close(cli
->tree
, fnum
);
327 fnum2
= create_complex_file(cli
, tctx
, inside
);
328 smbcli_close(cli
->tree
, fnum2
);
330 op
.generic
.level
= RAW_OPEN_NTCREATEX
;
331 op
.ntcreatex
.in
.root_fid
.fnum
= 0;
332 op
.ntcreatex
.in
.flags
= 0;
333 op
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
334 op
.ntcreatex
.in
.create_options
= NTCREATEX_OPTIONS_DIRECTORY
|NTCREATEX_OPTIONS_DELETE_ON_CLOSE
;
335 op
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
336 op
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
| NTCREATEX_SHARE_ACCESS_WRITE
;
337 op
.ntcreatex
.in
.alloc_size
= 0;
338 op
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN
;
339 op
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
340 op
.ntcreatex
.in
.security_flags
= 0;
341 op
.ntcreatex
.in
.fname
= dname
;
343 status
= smb_raw_open(cli
->tree
, tctx
, &op
);
344 CHECK_STATUS(status
, NT_STATUS_OK
);
345 fnum
= op
.ntcreatex
.out
.file
.fnum
;
347 smbcli_close(cli
->tree
, fnum
);
349 status
= smb_raw_rmdir(cli
->tree
, &dio
);
350 CHECK_STATUS(status
, NT_STATUS_DIRECTORY_NOT_EMPTY
);
352 smbcli_deltree(cli
->tree
, dname
);
354 printf("Testing double open dir with second delete_on_close\n");
355 status
= create_directory_handle(cli
->tree
, dname
, &fnum
);
356 CHECK_STATUS(status
, NT_STATUS_OK
);
357 smbcli_close(cli
->tree
, fnum
);
359 fnum2
= create_complex_file(cli
, tctx
, inside
);
360 smbcli_close(cli
->tree
, fnum2
);
362 op
.generic
.level
= RAW_OPEN_NTCREATEX
;
363 op
.ntcreatex
.in
.root_fid
.fnum
= 0;
364 op
.ntcreatex
.in
.flags
= 0;
365 op
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
366 op
.ntcreatex
.in
.create_options
= NTCREATEX_OPTIONS_DIRECTORY
|NTCREATEX_OPTIONS_DELETE_ON_CLOSE
;
367 op
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
368 op
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
| NTCREATEX_SHARE_ACCESS_WRITE
;
369 op
.ntcreatex
.in
.alloc_size
= 0;
370 op
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN
;
371 op
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
372 op
.ntcreatex
.in
.security_flags
= 0;
373 op
.ntcreatex
.in
.fname
= dname
;
375 status
= smb_raw_open(cli
->tree
, tctx
, &op
);
376 CHECK_STATUS(status
, NT_STATUS_OK
);
377 fnum2
= op
.ntcreatex
.out
.file
.fnum
;
379 smbcli_close(cli
->tree
, fnum2
);
381 status
= smb_raw_rmdir(cli
->tree
, &dio
);
382 CHECK_STATUS(status
, NT_STATUS_DIRECTORY_NOT_EMPTY
);
384 smbcli_deltree(cli
->tree
, dname
);
386 printf("Testing pre-existing open dir with second delete_on_close\n");
387 status
= create_directory_handle(cli
->tree
, dname
, &fnum
);
388 CHECK_STATUS(status
, NT_STATUS_OK
);
390 smbcli_close(cli
->tree
, fnum
);
392 fnum
= create_complex_file(cli
, tctx
, inside
);
393 smbcli_close(cli
->tree
, fnum
);
395 /* we have a dir with a file in it, no handles open */
397 op
.generic
.level
= RAW_OPEN_NTCREATEX
;
398 op
.ntcreatex
.in
.root_fid
.fnum
= 0;
399 op
.ntcreatex
.in
.flags
= 0;
400 op
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
401 op
.ntcreatex
.in
.create_options
= NTCREATEX_OPTIONS_DIRECTORY
|NTCREATEX_OPTIONS_DELETE_ON_CLOSE
;
402 op
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
403 op
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
| NTCREATEX_SHARE_ACCESS_WRITE
| NTCREATEX_SHARE_ACCESS_DELETE
;
404 op
.ntcreatex
.in
.alloc_size
= 0;
405 op
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN
;
406 op
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
407 op
.ntcreatex
.in
.security_flags
= 0;
408 op
.ntcreatex
.in
.fname
= dname
;
410 status
= smb_raw_open(cli
->tree
, tctx
, &op
);
411 CHECK_STATUS(status
, NT_STATUS_OK
);
412 fnum
= op
.ntcreatex
.out
.file
.fnum
;
414 /* open without delete on close */
415 op
.ntcreatex
.in
.create_options
= NTCREATEX_OPTIONS_DIRECTORY
;
416 status
= smb_raw_open(cli
->tree
, tctx
, &op
);
417 CHECK_STATUS(status
, NT_STATUS_OK
);
418 fnum2
= op
.ntcreatex
.out
.file
.fnum
;
420 /* close 2nd file handle */
421 smbcli_close(cli
->tree
, fnum2
);
423 status
= smb_raw_rmdir(cli
->tree
, &dio
);
424 CHECK_STATUS(status
, NT_STATUS_DIRECTORY_NOT_EMPTY
);
427 smbcli_close(cli
->tree
, fnum
);
429 status
= smb_raw_rmdir(cli
->tree
, &dio
);
430 CHECK_STATUS(status
, NT_STATUS_DIRECTORY_NOT_EMPTY
);
433 smb_raw_exit(cli
->session
);
434 smbcli_deltree(cli
->tree
, BASEDIR
);
439 struct unlink_defer_cli_state
{
440 struct torture_context
*tctx
;
441 struct smbcli_state
*cli1
;
445 * A handler function for oplock break requests. Ack it as a break to none
447 static bool oplock_handler_ack_to_none(struct smbcli_transport
*transport
,
448 uint16_t tid
, uint16_t fnum
,
449 uint8_t level
, void *private_data
)
451 struct unlink_defer_cli_state
*ud_cli_state
=
452 (struct unlink_defer_cli_state
*)private_data
;
453 union smb_setfileinfo sfinfo
;
455 struct smbcli_request
*req
= NULL
;
457 torture_comment(ud_cli_state
->tctx
, "delete the file before sending "
460 /* cli1: set delete on close */
461 sfinfo
.disposition_info
.level
= RAW_SFILEINFO_DISPOSITION_INFO
;
462 sfinfo
.disposition_info
.in
.file
.fnum
= fnum
;
463 sfinfo
.disposition_info
.in
.delete_on_close
= 1;
464 req
= smb_raw_setfileinfo_send(ud_cli_state
->cli1
->tree
, &sfinfo
);
466 torture_comment(ud_cli_state
->tctx
, "smb_raw_setfileinfo_send "
470 smbcli_close(ud_cli_state
->cli1
->tree
, fnum
);
472 torture_comment(ud_cli_state
->tctx
, "Acking the oplock to NONE\n");
474 ret
= smbcli_oplock_ack(ud_cli_state
->cli1
->tree
, fnum
,
475 OPLOCK_BREAK_TO_NONE
);
480 static bool test_unlink_defer(struct torture_context
*tctx
,
481 struct smbcli_state
*cli1
,
482 struct smbcli_state
*cli2
)
484 const char *fname
= BASEDIR
"\\test_unlink_defer.dat";
488 union smb_unlink unl
;
489 struct unlink_defer_cli_state ud_cli_state
= {};
491 if (!torture_setup_dir(cli1
, BASEDIR
)) {
496 smbcli_unlink(cli1
->tree
, fname
);
498 ud_cli_state
.tctx
= tctx
;
499 ud_cli_state
.cli1
= cli1
;
501 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_none
,
504 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
505 io
.ntcreatex
.in
.root_fid
.fnum
= 0;
506 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
507 io
.ntcreatex
.in
.alloc_size
= 0;
508 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
509 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
|
510 NTCREATEX_SHARE_ACCESS_WRITE
|
511 NTCREATEX_SHARE_ACCESS_DELETE
;
512 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
513 io
.ntcreatex
.in
.create_options
= 0;
514 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
515 io
.ntcreatex
.in
.security_flags
= 0;
516 io
.ntcreatex
.in
.fname
= fname
;
518 /* cli1: open file with a batch oplock. */
519 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
520 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
521 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
523 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
524 CHECK_STATUS(status
, NT_STATUS_OK
);
526 /* cli2: Try to unlink it, but block on the oplock */
527 torture_comment(tctx
, "Try an unlink (should defer the open\n");
528 unl
.unlink
.in
.pattern
= fname
;
529 unl
.unlink
.in
.attrib
= 0;
530 status
= smb_raw_unlink(cli2
->tree
, &unl
);
533 smb_raw_exit(cli1
->session
);
534 smb_raw_exit(cli2
->session
);
535 smbcli_deltree(cli1
->tree
, BASEDIR
);
540 basic testing of unlink calls
542 struct torture_suite
*torture_raw_unlink(TALLOC_CTX
*mem_ctx
)
544 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "unlink");
546 torture_suite_add_1smb_test(suite
, "unlink", test_unlink
);
547 torture_suite_add_1smb_test(suite
, "delete_on_close", test_delete_on_close
);
548 torture_suite_add_2smb_test(suite
, "unlink-defer", test_unlink_defer
);