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"
28 #define CHECK_STATUS(status, correct) do { \
29 if (!NT_STATUS_EQUAL(status, correct)) { \
30 printf("(%s) Incorrect status %s - should be %s\n", \
31 __location__, nt_errstr(status), nt_errstr(correct)); \
36 #define BASEDIR "\\testunlink"
41 static bool test_unlink(struct torture_context
*tctx
, struct smbcli_state
*cli
)
46 const char *fname
= BASEDIR
"\\test.txt";
48 if (!torture_setup_dir(cli
, BASEDIR
)) {
52 printf("Trying non-existant file\n");
53 io
.unlink
.in
.pattern
= fname
;
54 io
.unlink
.in
.attrib
= 0;
55 status
= smb_raw_unlink(cli
->tree
, &io
);
56 CHECK_STATUS(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
);
58 smbcli_close(cli
->tree
, smbcli_open(cli
->tree
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
));
60 io
.unlink
.in
.pattern
= fname
;
61 io
.unlink
.in
.attrib
= 0;
62 status
= smb_raw_unlink(cli
->tree
, &io
);
63 CHECK_STATUS(status
, NT_STATUS_OK
);
65 printf("Trying a hidden file\n");
66 smbcli_close(cli
->tree
, smbcli_open(cli
->tree
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
));
67 torture_set_file_attribute(cli
->tree
, fname
, FILE_ATTRIBUTE_HIDDEN
);
69 io
.unlink
.in
.pattern
= fname
;
70 io
.unlink
.in
.attrib
= 0;
71 status
= smb_raw_unlink(cli
->tree
, &io
);
72 CHECK_STATUS(status
, NT_STATUS_NO_SUCH_FILE
);
74 io
.unlink
.in
.pattern
= fname
;
75 io
.unlink
.in
.attrib
= FILE_ATTRIBUTE_HIDDEN
;
76 status
= smb_raw_unlink(cli
->tree
, &io
);
77 CHECK_STATUS(status
, NT_STATUS_OK
);
79 io
.unlink
.in
.pattern
= fname
;
80 io
.unlink
.in
.attrib
= FILE_ATTRIBUTE_HIDDEN
;
81 status
= smb_raw_unlink(cli
->tree
, &io
);
82 CHECK_STATUS(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
);
84 printf("Trying a directory\n");
85 io
.unlink
.in
.pattern
= BASEDIR
;
86 io
.unlink
.in
.attrib
= 0;
87 status
= smb_raw_unlink(cli
->tree
, &io
);
88 CHECK_STATUS(status
, NT_STATUS_FILE_IS_A_DIRECTORY
);
90 io
.unlink
.in
.pattern
= BASEDIR
;
91 io
.unlink
.in
.attrib
= FILE_ATTRIBUTE_DIRECTORY
;
92 status
= smb_raw_unlink(cli
->tree
, &io
);
93 CHECK_STATUS(status
, NT_STATUS_FILE_IS_A_DIRECTORY
);
95 printf("Trying a bad path\n");
96 io
.unlink
.in
.pattern
= "..";
97 io
.unlink
.in
.attrib
= 0;
98 status
= smb_raw_unlink(cli
->tree
, &io
);
99 CHECK_STATUS(status
, NT_STATUS_OBJECT_PATH_SYNTAX_BAD
);
101 io
.unlink
.in
.pattern
= "\\..";
102 io
.unlink
.in
.attrib
= 0;
103 status
= smb_raw_unlink(cli
->tree
, &io
);
104 CHECK_STATUS(status
, NT_STATUS_OBJECT_PATH_SYNTAX_BAD
);
106 io
.unlink
.in
.pattern
= BASEDIR
"\\..\\..";
107 io
.unlink
.in
.attrib
= 0;
108 status
= smb_raw_unlink(cli
->tree
, &io
);
109 CHECK_STATUS(status
, NT_STATUS_OBJECT_PATH_SYNTAX_BAD
);
111 io
.unlink
.in
.pattern
= BASEDIR
"\\..";
112 io
.unlink
.in
.attrib
= 0;
113 status
= smb_raw_unlink(cli
->tree
, &io
);
114 CHECK_STATUS(status
, NT_STATUS_FILE_IS_A_DIRECTORY
);
116 printf("Trying wildcards\n");
117 smbcli_close(cli
->tree
, smbcli_open(cli
->tree
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
));
118 io
.unlink
.in
.pattern
= BASEDIR
"\\t*.t";
119 io
.unlink
.in
.attrib
= 0;
120 status
= smb_raw_unlink(cli
->tree
, &io
);
121 CHECK_STATUS(status
, NT_STATUS_NO_SUCH_FILE
);
123 io
.unlink
.in
.pattern
= BASEDIR
"\\z*";
124 io
.unlink
.in
.attrib
= 0;
125 status
= smb_raw_unlink(cli
->tree
, &io
);
126 CHECK_STATUS(status
, NT_STATUS_NO_SUCH_FILE
);
128 io
.unlink
.in
.pattern
= BASEDIR
"\\z*";
129 io
.unlink
.in
.attrib
= FILE_ATTRIBUTE_DIRECTORY
;
130 status
= smb_raw_unlink(cli
->tree
, &io
);
132 if (torture_setting_bool(tctx
, "samba3", false)) {
134 * In Samba3 we gave up upon getting the error codes in
135 * wildcard unlink correct. Trying gentest showed that this is
136 * irregular beyond our capabilities. So for
137 * FILE_ATTRIBUTE_DIRECTORY we always return NAME_INVALID.
138 * Tried by jra and vl. If others feel like solving this
139 * puzzle, please tell us :-)
141 CHECK_STATUS(status
, NT_STATUS_OBJECT_NAME_INVALID
);
144 CHECK_STATUS(status
, NT_STATUS_NO_SUCH_FILE
);
147 io
.unlink
.in
.pattern
= BASEDIR
"\\*";
148 io
.unlink
.in
.attrib
= FILE_ATTRIBUTE_DIRECTORY
;
149 status
= smb_raw_unlink(cli
->tree
, &io
);
150 CHECK_STATUS(status
, NT_STATUS_OBJECT_NAME_INVALID
);
152 io
.unlink
.in
.pattern
= BASEDIR
"\\?";
153 io
.unlink
.in
.attrib
= FILE_ATTRIBUTE_DIRECTORY
;
154 status
= smb_raw_unlink(cli
->tree
, &io
);
155 CHECK_STATUS(status
, NT_STATUS_OBJECT_NAME_INVALID
);
157 io
.unlink
.in
.pattern
= BASEDIR
"\\t*";
158 io
.unlink
.in
.attrib
= FILE_ATTRIBUTE_DIRECTORY
;
159 status
= smb_raw_unlink(cli
->tree
, &io
);
160 if (torture_setting_bool(tctx
, "samba3", false)) {
161 CHECK_STATUS(status
, NT_STATUS_OBJECT_NAME_INVALID
);
164 CHECK_STATUS(status
, NT_STATUS_OK
);
167 smbcli_close(cli
->tree
, smbcli_open(cli
->tree
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
));
169 io
.unlink
.in
.pattern
= BASEDIR
"\\*.dat";
170 io
.unlink
.in
.attrib
= FILE_ATTRIBUTE_DIRECTORY
;
171 status
= smb_raw_unlink(cli
->tree
, &io
);
172 if (torture_setting_bool(tctx
, "samba3", false)) {
173 CHECK_STATUS(status
, NT_STATUS_OBJECT_NAME_INVALID
);
176 CHECK_STATUS(status
, NT_STATUS_NO_SUCH_FILE
);
179 io
.unlink
.in
.pattern
= BASEDIR
"\\*.tx?";
180 io
.unlink
.in
.attrib
= 0;
181 status
= smb_raw_unlink(cli
->tree
, &io
);
182 if (torture_setting_bool(tctx
, "samba3", false)) {
183 CHECK_STATUS(status
, NT_STATUS_NO_SUCH_FILE
);
186 CHECK_STATUS(status
, NT_STATUS_OK
);
189 status
= smb_raw_unlink(cli
->tree
, &io
);
190 CHECK_STATUS(status
, NT_STATUS_NO_SUCH_FILE
);
194 smb_raw_exit(cli
->session
);
195 smbcli_deltree(cli
->tree
, BASEDIR
);
203 static bool test_delete_on_close(struct torture_context
*tctx
,
204 struct smbcli_state
*cli
)
208 struct smb_rmdir dio
;
212 const char *fname
= BASEDIR
"\\test.txt";
213 const char *dname
= BASEDIR
"\\test.dir";
214 const char *inside
= BASEDIR
"\\test.dir\\test.txt";
215 union smb_setfileinfo sfinfo
;
217 if (!torture_setup_dir(cli
, BASEDIR
)) {
223 io
.unlink
.in
.pattern
= fname
;
224 io
.unlink
.in
.attrib
= 0;
225 status
= smb_raw_unlink(cli
->tree
, &io
);
226 CHECK_STATUS(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
);
228 printf("Testing with delete_on_close 0\n");
229 fnum
= create_complex_file(cli
, tctx
, fname
);
231 sfinfo
.disposition_info
.level
= RAW_SFILEINFO_DISPOSITION_INFO
;
232 sfinfo
.disposition_info
.in
.file
.fnum
= fnum
;
233 sfinfo
.disposition_info
.in
.delete_on_close
= 0;
234 status
= smb_raw_setfileinfo(cli
->tree
, &sfinfo
);
235 CHECK_STATUS(status
, NT_STATUS_OK
);
237 smbcli_close(cli
->tree
, fnum
);
239 status
= smb_raw_unlink(cli
->tree
, &io
);
240 CHECK_STATUS(status
, NT_STATUS_OK
);
242 printf("Testing with delete_on_close 1\n");
243 fnum
= create_complex_file(cli
, tctx
, fname
);
244 sfinfo
.disposition_info
.in
.file
.fnum
= fnum
;
245 sfinfo
.disposition_info
.in
.delete_on_close
= 1;
246 status
= smb_raw_setfileinfo(cli
->tree
, &sfinfo
);
247 CHECK_STATUS(status
, NT_STATUS_OK
);
249 smbcli_close(cli
->tree
, fnum
);
251 status
= smb_raw_unlink(cli
->tree
, &io
);
252 CHECK_STATUS(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
);
255 printf("Testing with directory and delete_on_close 0\n");
256 status
= create_directory_handle(cli
->tree
, dname
, &fnum
);
257 CHECK_STATUS(status
, NT_STATUS_OK
);
259 sfinfo
.disposition_info
.level
= RAW_SFILEINFO_DISPOSITION_INFO
;
260 sfinfo
.disposition_info
.in
.file
.fnum
= fnum
;
261 sfinfo
.disposition_info
.in
.delete_on_close
= 0;
262 status
= smb_raw_setfileinfo(cli
->tree
, &sfinfo
);
263 CHECK_STATUS(status
, NT_STATUS_OK
);
265 smbcli_close(cli
->tree
, fnum
);
267 status
= smb_raw_rmdir(cli
->tree
, &dio
);
268 CHECK_STATUS(status
, NT_STATUS_OK
);
270 printf("Testing with directory delete_on_close 1\n");
271 status
= create_directory_handle(cli
->tree
, dname
, &fnum
);
272 CHECK_STATUS(status
, NT_STATUS_OK
);
274 sfinfo
.disposition_info
.in
.file
.fnum
= fnum
;
275 sfinfo
.disposition_info
.in
.delete_on_close
= 1;
276 status
= smb_raw_setfileinfo(cli
->tree
, &sfinfo
);
277 CHECK_STATUS(status
, NT_STATUS_OK
);
279 smbcli_close(cli
->tree
, fnum
);
281 status
= smb_raw_rmdir(cli
->tree
, &dio
);
282 CHECK_STATUS(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
);
285 if (!torture_setting_bool(tctx
, "samba3", false)) {
288 * Known deficiency, also skipped in base-delete.
291 printf("Testing with non-empty directory delete_on_close\n");
292 status
= create_directory_handle(cli
->tree
, dname
, &fnum
);
293 CHECK_STATUS(status
, NT_STATUS_OK
);
295 fnum2
= create_complex_file(cli
, tctx
, inside
);
297 sfinfo
.disposition_info
.in
.file
.fnum
= fnum
;
298 sfinfo
.disposition_info
.in
.delete_on_close
= 1;
299 status
= smb_raw_setfileinfo(cli
->tree
, &sfinfo
);
300 CHECK_STATUS(status
, NT_STATUS_DIRECTORY_NOT_EMPTY
);
302 sfinfo
.disposition_info
.in
.file
.fnum
= fnum2
;
303 status
= smb_raw_setfileinfo(cli
->tree
, &sfinfo
);
304 CHECK_STATUS(status
, NT_STATUS_OK
);
306 sfinfo
.disposition_info
.in
.file
.fnum
= fnum
;
307 status
= smb_raw_setfileinfo(cli
->tree
, &sfinfo
);
308 CHECK_STATUS(status
, NT_STATUS_DIRECTORY_NOT_EMPTY
);
310 smbcli_close(cli
->tree
, fnum2
);
312 status
= smb_raw_setfileinfo(cli
->tree
, &sfinfo
);
313 CHECK_STATUS(status
, NT_STATUS_OK
);
315 smbcli_close(cli
->tree
, fnum
);
317 status
= smb_raw_rmdir(cli
->tree
, &dio
);
318 CHECK_STATUS(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
);
321 printf("Testing open dir with delete_on_close\n");
322 status
= create_directory_handle(cli
->tree
, dname
, &fnum
);
323 CHECK_STATUS(status
, NT_STATUS_OK
);
325 smbcli_close(cli
->tree
, fnum
);
326 fnum2
= create_complex_file(cli
, tctx
, inside
);
327 smbcli_close(cli
->tree
, fnum2
);
329 op
.generic
.level
= RAW_OPEN_NTCREATEX
;
330 op
.ntcreatex
.in
.root_fid
.fnum
= 0;
331 op
.ntcreatex
.in
.flags
= 0;
332 op
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
333 op
.ntcreatex
.in
.create_options
= NTCREATEX_OPTIONS_DIRECTORY
|NTCREATEX_OPTIONS_DELETE_ON_CLOSE
;
334 op
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
335 op
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
| NTCREATEX_SHARE_ACCESS_WRITE
;
336 op
.ntcreatex
.in
.alloc_size
= 0;
337 op
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN
;
338 op
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
339 op
.ntcreatex
.in
.security_flags
= 0;
340 op
.ntcreatex
.in
.fname
= dname
;
342 status
= smb_raw_open(cli
->tree
, tctx
, &op
);
343 CHECK_STATUS(status
, NT_STATUS_OK
);
344 fnum
= op
.ntcreatex
.out
.file
.fnum
;
346 smbcli_close(cli
->tree
, fnum
);
348 status
= smb_raw_rmdir(cli
->tree
, &dio
);
349 CHECK_STATUS(status
, NT_STATUS_DIRECTORY_NOT_EMPTY
);
351 smbcli_deltree(cli
->tree
, dname
);
353 printf("Testing double open dir with second delete_on_close\n");
354 status
= create_directory_handle(cli
->tree
, dname
, &fnum
);
355 CHECK_STATUS(status
, NT_STATUS_OK
);
356 smbcli_close(cli
->tree
, fnum
);
358 fnum2
= create_complex_file(cli
, tctx
, inside
);
359 smbcli_close(cli
->tree
, fnum2
);
361 op
.generic
.level
= RAW_OPEN_NTCREATEX
;
362 op
.ntcreatex
.in
.root_fid
.fnum
= 0;
363 op
.ntcreatex
.in
.flags
= 0;
364 op
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
365 op
.ntcreatex
.in
.create_options
= NTCREATEX_OPTIONS_DIRECTORY
|NTCREATEX_OPTIONS_DELETE_ON_CLOSE
;
366 op
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
367 op
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
| NTCREATEX_SHARE_ACCESS_WRITE
;
368 op
.ntcreatex
.in
.alloc_size
= 0;
369 op
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN
;
370 op
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
371 op
.ntcreatex
.in
.security_flags
= 0;
372 op
.ntcreatex
.in
.fname
= dname
;
374 status
= smb_raw_open(cli
->tree
, tctx
, &op
);
375 CHECK_STATUS(status
, NT_STATUS_OK
);
376 fnum2
= op
.ntcreatex
.out
.file
.fnum
;
378 smbcli_close(cli
->tree
, fnum2
);
380 status
= smb_raw_rmdir(cli
->tree
, &dio
);
381 CHECK_STATUS(status
, NT_STATUS_DIRECTORY_NOT_EMPTY
);
383 smbcli_deltree(cli
->tree
, dname
);
385 printf("Testing pre-existing open dir with second delete_on_close\n");
386 status
= create_directory_handle(cli
->tree
, dname
, &fnum
);
387 CHECK_STATUS(status
, NT_STATUS_OK
);
389 smbcli_close(cli
->tree
, fnum
);
391 fnum
= create_complex_file(cli
, tctx
, inside
);
392 smbcli_close(cli
->tree
, fnum
);
394 /* we have a dir with a file in it, no handles open */
396 op
.generic
.level
= RAW_OPEN_NTCREATEX
;
397 op
.ntcreatex
.in
.root_fid
.fnum
= 0;
398 op
.ntcreatex
.in
.flags
= 0;
399 op
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
400 op
.ntcreatex
.in
.create_options
= NTCREATEX_OPTIONS_DIRECTORY
|NTCREATEX_OPTIONS_DELETE_ON_CLOSE
;
401 op
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
402 op
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
| NTCREATEX_SHARE_ACCESS_WRITE
| NTCREATEX_SHARE_ACCESS_DELETE
;
403 op
.ntcreatex
.in
.alloc_size
= 0;
404 op
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN
;
405 op
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
406 op
.ntcreatex
.in
.security_flags
= 0;
407 op
.ntcreatex
.in
.fname
= dname
;
409 status
= smb_raw_open(cli
->tree
, tctx
, &op
);
410 CHECK_STATUS(status
, NT_STATUS_OK
);
411 fnum
= op
.ntcreatex
.out
.file
.fnum
;
413 /* open without delete on close */
414 op
.ntcreatex
.in
.create_options
= NTCREATEX_OPTIONS_DIRECTORY
;
415 status
= smb_raw_open(cli
->tree
, tctx
, &op
);
416 CHECK_STATUS(status
, NT_STATUS_OK
);
417 fnum2
= op
.ntcreatex
.out
.file
.fnum
;
419 /* close 2nd file handle */
420 smbcli_close(cli
->tree
, fnum2
);
422 status
= smb_raw_rmdir(cli
->tree
, &dio
);
423 CHECK_STATUS(status
, NT_STATUS_DIRECTORY_NOT_EMPTY
);
426 smbcli_close(cli
->tree
, fnum
);
428 status
= smb_raw_rmdir(cli
->tree
, &dio
);
429 CHECK_STATUS(status
, NT_STATUS_DIRECTORY_NOT_EMPTY
);
432 smb_raw_exit(cli
->session
);
433 smbcli_deltree(cli
->tree
, BASEDIR
);
438 struct unlink_defer_cli_state
{
439 struct torture_context
*tctx
;
440 struct smbcli_state
*cli1
;
444 * A handler function for oplock break requests. Ack it as a break to none
446 static bool oplock_handler_ack_to_none(struct smbcli_transport
*transport
,
447 uint16_t tid
, uint16_t fnum
,
448 uint8_t level
, void *private_data
)
450 struct unlink_defer_cli_state
*ud_cli_state
=
451 (struct unlink_defer_cli_state
*)private_data
;
452 union smb_setfileinfo sfinfo
;
454 struct smbcli_request
*req
= NULL
;
456 torture_comment(ud_cli_state
->tctx
, "delete the file before sending "
459 /* cli1: set delete on close */
460 sfinfo
.disposition_info
.level
= RAW_SFILEINFO_DISPOSITION_INFO
;
461 sfinfo
.disposition_info
.in
.file
.fnum
= fnum
;
462 sfinfo
.disposition_info
.in
.delete_on_close
= 1;
463 req
= smb_raw_setfileinfo_send(ud_cli_state
->cli1
->tree
, &sfinfo
);
465 smbcli_close(ud_cli_state
->cli1
->tree
, fnum
);
467 torture_comment(ud_cli_state
->tctx
, "Acking the oplock to NONE\n");
469 ret
= smbcli_oplock_ack(ud_cli_state
->cli1
->tree
, fnum
,
470 OPLOCK_BREAK_TO_NONE
);
475 static bool test_unlink_defer(struct torture_context
*tctx
,
476 struct smbcli_state
*cli1
,
477 struct smbcli_state
*cli2
)
479 const char *fname
= BASEDIR
"\\test_unlink_defer.dat";
483 union smb_unlink unl
;
485 struct unlink_defer_cli_state ud_cli_state
= {};
487 if (!torture_setup_dir(cli1
, BASEDIR
)) {
492 smbcli_unlink(cli1
->tree
, fname
);
494 ud_cli_state
.tctx
= tctx
;
495 ud_cli_state
.cli1
= cli1
;
497 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_none
,
500 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
501 io
.ntcreatex
.in
.root_fid
.fnum
= 0;
502 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
503 io
.ntcreatex
.in
.alloc_size
= 0;
504 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
505 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
|
506 NTCREATEX_SHARE_ACCESS_WRITE
|
507 NTCREATEX_SHARE_ACCESS_DELETE
;
508 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
509 io
.ntcreatex
.in
.create_options
= 0;
510 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
511 io
.ntcreatex
.in
.security_flags
= 0;
512 io
.ntcreatex
.in
.fname
= fname
;
514 /* cli1: open file with a batch oplock. */
515 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
516 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
517 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
519 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
520 CHECK_STATUS(status
, NT_STATUS_OK
);
521 fnum
= io
.ntcreatex
.out
.file
.fnum
;
523 /* cli2: Try to unlink it, but block on the oplock */
524 torture_comment(tctx
, "Try an unlink (should defer the open\n");
525 unl
.unlink
.in
.pattern
= fname
;
526 unl
.unlink
.in
.attrib
= 0;
527 status
= smb_raw_unlink(cli2
->tree
, &unl
);
530 smb_raw_exit(cli1
->session
);
531 smb_raw_exit(cli2
->session
);
532 smbcli_deltree(cli1
->tree
, BASEDIR
);
537 basic testing of unlink calls
539 struct torture_suite
*torture_raw_unlink(TALLOC_CTX
*mem_ctx
)
541 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "unlink");
543 torture_suite_add_1smb_test(suite
, "unlink", test_unlink
);
544 torture_suite_add_1smb_test(suite
, "delete_on_close", test_delete_on_close
);
545 torture_suite_add_2smb_test(suite
, "unlink-defer", test_unlink_defer
);