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 torture_assert(tctx
, torture_setup_dir(cli
, BASEDIR
), "Failed to setup up test directory: " BASEDIR
);
51 printf("Trying non-existent file\n");
52 io
.unlink
.in
.pattern
= fname
;
53 io
.unlink
.in
.attrib
= 0;
54 status
= smb_raw_unlink(cli
->tree
, &io
);
55 CHECK_STATUS(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
);
57 smbcli_close(cli
->tree
, smbcli_open(cli
->tree
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
));
59 io
.unlink
.in
.pattern
= fname
;
60 io
.unlink
.in
.attrib
= 0;
61 status
= smb_raw_unlink(cli
->tree
, &io
);
62 CHECK_STATUS(status
, NT_STATUS_OK
);
64 printf("Trying a hidden file\n");
65 smbcli_close(cli
->tree
, smbcli_open(cli
->tree
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
));
66 torture_set_file_attribute(cli
->tree
, fname
, FILE_ATTRIBUTE_HIDDEN
);
68 io
.unlink
.in
.pattern
= fname
;
69 io
.unlink
.in
.attrib
= 0;
70 status
= smb_raw_unlink(cli
->tree
, &io
);
71 CHECK_STATUS(status
, NT_STATUS_NO_SUCH_FILE
);
73 io
.unlink
.in
.pattern
= fname
;
74 io
.unlink
.in
.attrib
= FILE_ATTRIBUTE_HIDDEN
;
75 status
= smb_raw_unlink(cli
->tree
, &io
);
76 CHECK_STATUS(status
, NT_STATUS_OK
);
78 io
.unlink
.in
.pattern
= fname
;
79 io
.unlink
.in
.attrib
= FILE_ATTRIBUTE_HIDDEN
;
80 status
= smb_raw_unlink(cli
->tree
, &io
);
81 CHECK_STATUS(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
);
83 printf("Trying a directory\n");
84 io
.unlink
.in
.pattern
= BASEDIR
;
85 io
.unlink
.in
.attrib
= 0;
86 status
= smb_raw_unlink(cli
->tree
, &io
);
87 CHECK_STATUS(status
, NT_STATUS_FILE_IS_A_DIRECTORY
);
89 io
.unlink
.in
.pattern
= BASEDIR
;
90 io
.unlink
.in
.attrib
= FILE_ATTRIBUTE_DIRECTORY
;
91 status
= smb_raw_unlink(cli
->tree
, &io
);
92 CHECK_STATUS(status
, NT_STATUS_FILE_IS_A_DIRECTORY
);
94 printf("Trying a bad path\n");
95 io
.unlink
.in
.pattern
= "..";
96 io
.unlink
.in
.attrib
= 0;
97 status
= smb_raw_unlink(cli
->tree
, &io
);
98 CHECK_STATUS(status
, NT_STATUS_OBJECT_PATH_SYNTAX_BAD
);
100 io
.unlink
.in
.pattern
= "\\..";
101 io
.unlink
.in
.attrib
= 0;
102 status
= smb_raw_unlink(cli
->tree
, &io
);
103 CHECK_STATUS(status
, NT_STATUS_OBJECT_PATH_SYNTAX_BAD
);
105 io
.unlink
.in
.pattern
= BASEDIR
"\\..\\..";
106 io
.unlink
.in
.attrib
= 0;
107 status
= smb_raw_unlink(cli
->tree
, &io
);
108 CHECK_STATUS(status
, NT_STATUS_OBJECT_PATH_SYNTAX_BAD
);
110 io
.unlink
.in
.pattern
= BASEDIR
"\\..";
111 io
.unlink
.in
.attrib
= 0;
112 status
= smb_raw_unlink(cli
->tree
, &io
);
113 CHECK_STATUS(status
, NT_STATUS_FILE_IS_A_DIRECTORY
);
115 printf("Trying wildcards\n");
116 smbcli_close(cli
->tree
, smbcli_open(cli
->tree
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
));
117 io
.unlink
.in
.pattern
= BASEDIR
"\\t*.t";
118 io
.unlink
.in
.attrib
= 0;
119 status
= smb_raw_unlink(cli
->tree
, &io
);
120 CHECK_STATUS(status
, NT_STATUS_NO_SUCH_FILE
);
122 io
.unlink
.in
.pattern
= BASEDIR
"\\z*";
123 io
.unlink
.in
.attrib
= 0;
124 status
= smb_raw_unlink(cli
->tree
, &io
);
125 CHECK_STATUS(status
, NT_STATUS_NO_SUCH_FILE
);
127 io
.unlink
.in
.pattern
= BASEDIR
"\\z*";
128 io
.unlink
.in
.attrib
= FILE_ATTRIBUTE_DIRECTORY
;
129 status
= smb_raw_unlink(cli
->tree
, &io
);
131 if (torture_setting_bool(tctx
, "samba3", false)) {
133 * In Samba3 we gave up upon getting the error codes in
134 * wildcard unlink correct. Trying gentest showed that this is
135 * irregular beyond our capabilities. So for
136 * FILE_ATTRIBUTE_DIRECTORY we always return NAME_INVALID.
137 * Tried by jra and vl. If others feel like solving this
138 * puzzle, please tell us :-)
140 CHECK_STATUS(status
, NT_STATUS_OBJECT_NAME_INVALID
);
143 CHECK_STATUS(status
, NT_STATUS_NO_SUCH_FILE
);
146 io
.unlink
.in
.pattern
= BASEDIR
"\\*";
147 io
.unlink
.in
.attrib
= FILE_ATTRIBUTE_DIRECTORY
;
148 status
= smb_raw_unlink(cli
->tree
, &io
);
149 CHECK_STATUS(status
, NT_STATUS_OBJECT_NAME_INVALID
);
151 io
.unlink
.in
.pattern
= BASEDIR
"\\?";
152 io
.unlink
.in
.attrib
= FILE_ATTRIBUTE_DIRECTORY
;
153 status
= smb_raw_unlink(cli
->tree
, &io
);
154 CHECK_STATUS(status
, NT_STATUS_OBJECT_NAME_INVALID
);
156 io
.unlink
.in
.pattern
= BASEDIR
"\\t*";
157 io
.unlink
.in
.attrib
= FILE_ATTRIBUTE_DIRECTORY
;
158 status
= smb_raw_unlink(cli
->tree
, &io
);
159 if (torture_setting_bool(tctx
, "samba3", false)) {
160 CHECK_STATUS(status
, NT_STATUS_OBJECT_NAME_INVALID
);
163 CHECK_STATUS(status
, NT_STATUS_OK
);
166 smbcli_close(cli
->tree
, smbcli_open(cli
->tree
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
));
168 io
.unlink
.in
.pattern
= BASEDIR
"\\*.dat";
169 io
.unlink
.in
.attrib
= FILE_ATTRIBUTE_DIRECTORY
;
170 status
= smb_raw_unlink(cli
->tree
, &io
);
171 if (torture_setting_bool(tctx
, "samba3", false)) {
172 CHECK_STATUS(status
, NT_STATUS_OBJECT_NAME_INVALID
);
175 CHECK_STATUS(status
, NT_STATUS_NO_SUCH_FILE
);
178 io
.unlink
.in
.pattern
= BASEDIR
"\\*.tx?";
179 io
.unlink
.in
.attrib
= 0;
180 status
= smb_raw_unlink(cli
->tree
, &io
);
181 if (torture_setting_bool(tctx
, "samba3", false)) {
182 CHECK_STATUS(status
, NT_STATUS_NO_SUCH_FILE
);
185 CHECK_STATUS(status
, NT_STATUS_OK
);
188 status
= smb_raw_unlink(cli
->tree
, &io
);
189 CHECK_STATUS(status
, NT_STATUS_NO_SUCH_FILE
);
193 smb_raw_exit(cli
->session
);
194 smbcli_deltree(cli
->tree
, BASEDIR
);
202 static bool test_delete_on_close(struct torture_context
*tctx
,
203 struct smbcli_state
*cli
)
207 struct smb_rmdir dio
;
211 const char *fname
= BASEDIR
"\\test.txt";
212 const char *dname
= BASEDIR
"\\test.dir";
213 const char *inside
= BASEDIR
"\\test.dir\\test.txt";
214 union smb_setfileinfo sfinfo
;
216 torture_assert(tctx
, torture_setup_dir(cli
, BASEDIR
), "Failed to setup up test directory: " BASEDIR
);
220 io
.unlink
.in
.pattern
= fname
;
221 io
.unlink
.in
.attrib
= 0;
222 status
= smb_raw_unlink(cli
->tree
, &io
);
223 CHECK_STATUS(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
);
225 printf("Testing with delete_on_close 0\n");
226 fnum
= create_complex_file(cli
, tctx
, fname
);
228 sfinfo
.disposition_info
.level
= RAW_SFILEINFO_DISPOSITION_INFO
;
229 sfinfo
.disposition_info
.in
.file
.fnum
= fnum
;
230 sfinfo
.disposition_info
.in
.delete_on_close
= 0;
231 status
= smb_raw_setfileinfo(cli
->tree
, &sfinfo
);
232 CHECK_STATUS(status
, NT_STATUS_OK
);
234 smbcli_close(cli
->tree
, fnum
);
236 status
= smb_raw_unlink(cli
->tree
, &io
);
237 CHECK_STATUS(status
, NT_STATUS_OK
);
239 printf("Testing with delete_on_close 1\n");
240 fnum
= create_complex_file(cli
, tctx
, fname
);
241 sfinfo
.disposition_info
.in
.file
.fnum
= fnum
;
242 sfinfo
.disposition_info
.in
.delete_on_close
= 1;
243 status
= smb_raw_setfileinfo(cli
->tree
, &sfinfo
);
244 CHECK_STATUS(status
, NT_STATUS_OK
);
246 smbcli_close(cli
->tree
, fnum
);
248 status
= smb_raw_unlink(cli
->tree
, &io
);
249 CHECK_STATUS(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
);
252 printf("Testing with directory and delete_on_close 0\n");
253 status
= create_directory_handle(cli
->tree
, dname
, &fnum
);
254 CHECK_STATUS(status
, NT_STATUS_OK
);
256 sfinfo
.disposition_info
.level
= RAW_SFILEINFO_DISPOSITION_INFO
;
257 sfinfo
.disposition_info
.in
.file
.fnum
= fnum
;
258 sfinfo
.disposition_info
.in
.delete_on_close
= 0;
259 status
= smb_raw_setfileinfo(cli
->tree
, &sfinfo
);
260 CHECK_STATUS(status
, NT_STATUS_OK
);
262 smbcli_close(cli
->tree
, fnum
);
264 status
= smb_raw_rmdir(cli
->tree
, &dio
);
265 CHECK_STATUS(status
, NT_STATUS_OK
);
267 printf("Testing with directory delete_on_close 1\n");
268 status
= create_directory_handle(cli
->tree
, dname
, &fnum
);
269 CHECK_STATUS(status
, NT_STATUS_OK
);
271 sfinfo
.disposition_info
.in
.file
.fnum
= fnum
;
272 sfinfo
.disposition_info
.in
.delete_on_close
= 1;
273 status
= smb_raw_setfileinfo(cli
->tree
, &sfinfo
);
274 CHECK_STATUS(status
, NT_STATUS_OK
);
276 smbcli_close(cli
->tree
, fnum
);
278 status
= smb_raw_rmdir(cli
->tree
, &dio
);
279 CHECK_STATUS(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
);
282 if (!torture_setting_bool(tctx
, "samba3", false)) {
285 * Known deficiency, also skipped in base-delete.
288 printf("Testing with non-empty directory delete_on_close\n");
289 status
= create_directory_handle(cli
->tree
, dname
, &fnum
);
290 CHECK_STATUS(status
, NT_STATUS_OK
);
292 fnum2
= create_complex_file(cli
, tctx
, inside
);
294 sfinfo
.disposition_info
.in
.file
.fnum
= fnum
;
295 sfinfo
.disposition_info
.in
.delete_on_close
= 1;
296 status
= smb_raw_setfileinfo(cli
->tree
, &sfinfo
);
297 CHECK_STATUS(status
, NT_STATUS_DIRECTORY_NOT_EMPTY
);
299 sfinfo
.disposition_info
.in
.file
.fnum
= fnum2
;
300 status
= smb_raw_setfileinfo(cli
->tree
, &sfinfo
);
301 CHECK_STATUS(status
, NT_STATUS_OK
);
303 sfinfo
.disposition_info
.in
.file
.fnum
= fnum
;
304 status
= smb_raw_setfileinfo(cli
->tree
, &sfinfo
);
305 CHECK_STATUS(status
, NT_STATUS_DIRECTORY_NOT_EMPTY
);
307 smbcli_close(cli
->tree
, fnum2
);
309 status
= smb_raw_setfileinfo(cli
->tree
, &sfinfo
);
310 CHECK_STATUS(status
, NT_STATUS_OK
);
312 smbcli_close(cli
->tree
, fnum
);
314 status
= smb_raw_rmdir(cli
->tree
, &dio
);
315 CHECK_STATUS(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
);
318 printf("Testing open dir with delete_on_close\n");
319 status
= create_directory_handle(cli
->tree
, dname
, &fnum
);
320 CHECK_STATUS(status
, NT_STATUS_OK
);
322 smbcli_close(cli
->tree
, fnum
);
323 fnum2
= create_complex_file(cli
, tctx
, inside
);
324 smbcli_close(cli
->tree
, fnum2
);
326 op
.generic
.level
= RAW_OPEN_NTCREATEX
;
327 op
.ntcreatex
.in
.root_fid
.fnum
= 0;
328 op
.ntcreatex
.in
.flags
= 0;
329 op
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
330 op
.ntcreatex
.in
.create_options
= NTCREATEX_OPTIONS_DIRECTORY
|NTCREATEX_OPTIONS_DELETE_ON_CLOSE
;
331 op
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
332 op
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
| NTCREATEX_SHARE_ACCESS_WRITE
;
333 op
.ntcreatex
.in
.alloc_size
= 0;
334 op
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN
;
335 op
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
336 op
.ntcreatex
.in
.security_flags
= 0;
337 op
.ntcreatex
.in
.fname
= dname
;
339 status
= smb_raw_open(cli
->tree
, tctx
, &op
);
340 CHECK_STATUS(status
, NT_STATUS_OK
);
341 fnum
= op
.ntcreatex
.out
.file
.fnum
;
343 smbcli_close(cli
->tree
, fnum
);
345 status
= smb_raw_rmdir(cli
->tree
, &dio
);
346 CHECK_STATUS(status
, NT_STATUS_DIRECTORY_NOT_EMPTY
);
348 smbcli_deltree(cli
->tree
, dname
);
350 printf("Testing double open dir with second delete_on_close\n");
351 status
= create_directory_handle(cli
->tree
, dname
, &fnum
);
352 CHECK_STATUS(status
, NT_STATUS_OK
);
353 smbcli_close(cli
->tree
, fnum
);
355 fnum2
= create_complex_file(cli
, tctx
, inside
);
356 smbcli_close(cli
->tree
, fnum2
);
358 op
.generic
.level
= RAW_OPEN_NTCREATEX
;
359 op
.ntcreatex
.in
.root_fid
.fnum
= 0;
360 op
.ntcreatex
.in
.flags
= 0;
361 op
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
362 op
.ntcreatex
.in
.create_options
= NTCREATEX_OPTIONS_DIRECTORY
|NTCREATEX_OPTIONS_DELETE_ON_CLOSE
;
363 op
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
364 op
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
| NTCREATEX_SHARE_ACCESS_WRITE
;
365 op
.ntcreatex
.in
.alloc_size
= 0;
366 op
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN
;
367 op
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
368 op
.ntcreatex
.in
.security_flags
= 0;
369 op
.ntcreatex
.in
.fname
= dname
;
371 status
= smb_raw_open(cli
->tree
, tctx
, &op
);
372 CHECK_STATUS(status
, NT_STATUS_OK
);
373 fnum2
= op
.ntcreatex
.out
.file
.fnum
;
375 smbcli_close(cli
->tree
, fnum2
);
377 status
= smb_raw_rmdir(cli
->tree
, &dio
);
378 CHECK_STATUS(status
, NT_STATUS_DIRECTORY_NOT_EMPTY
);
380 smbcli_deltree(cli
->tree
, dname
);
382 printf("Testing pre-existing open dir with second delete_on_close\n");
383 status
= create_directory_handle(cli
->tree
, dname
, &fnum
);
384 CHECK_STATUS(status
, NT_STATUS_OK
);
386 smbcli_close(cli
->tree
, fnum
);
388 fnum
= create_complex_file(cli
, tctx
, inside
);
389 smbcli_close(cli
->tree
, fnum
);
391 /* we have a dir with a file in it, no handles open */
393 op
.generic
.level
= RAW_OPEN_NTCREATEX
;
394 op
.ntcreatex
.in
.root_fid
.fnum
= 0;
395 op
.ntcreatex
.in
.flags
= 0;
396 op
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
397 op
.ntcreatex
.in
.create_options
= NTCREATEX_OPTIONS_DIRECTORY
|NTCREATEX_OPTIONS_DELETE_ON_CLOSE
;
398 op
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
399 op
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
| NTCREATEX_SHARE_ACCESS_WRITE
| NTCREATEX_SHARE_ACCESS_DELETE
;
400 op
.ntcreatex
.in
.alloc_size
= 0;
401 op
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN
;
402 op
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
403 op
.ntcreatex
.in
.security_flags
= 0;
404 op
.ntcreatex
.in
.fname
= dname
;
406 status
= smb_raw_open(cli
->tree
, tctx
, &op
);
407 CHECK_STATUS(status
, NT_STATUS_OK
);
408 fnum
= op
.ntcreatex
.out
.file
.fnum
;
410 /* open without delete on close */
411 op
.ntcreatex
.in
.create_options
= NTCREATEX_OPTIONS_DIRECTORY
;
412 status
= smb_raw_open(cli
->tree
, tctx
, &op
);
413 CHECK_STATUS(status
, NT_STATUS_OK
);
414 fnum2
= op
.ntcreatex
.out
.file
.fnum
;
416 /* close 2nd file handle */
417 smbcli_close(cli
->tree
, fnum2
);
419 status
= smb_raw_rmdir(cli
->tree
, &dio
);
420 CHECK_STATUS(status
, NT_STATUS_DIRECTORY_NOT_EMPTY
);
423 smbcli_close(cli
->tree
, fnum
);
425 status
= smb_raw_rmdir(cli
->tree
, &dio
);
426 CHECK_STATUS(status
, NT_STATUS_DIRECTORY_NOT_EMPTY
);
429 smb_raw_exit(cli
->session
);
430 smbcli_deltree(cli
->tree
, BASEDIR
);
435 struct unlink_defer_cli_state
{
436 struct torture_context
*tctx
;
437 struct smbcli_state
*cli1
;
441 * A handler function for oplock break requests. Ack it as a break to none
443 static bool oplock_handler_ack_to_none(struct smbcli_transport
*transport
,
444 uint16_t tid
, uint16_t fnum
,
445 uint8_t level
, void *private_data
)
447 struct unlink_defer_cli_state
*ud_cli_state
=
448 (struct unlink_defer_cli_state
*)private_data
;
449 union smb_setfileinfo sfinfo
;
451 struct smbcli_request
*req
= NULL
;
453 torture_comment(ud_cli_state
->tctx
, "delete the file before sending "
456 /* cli1: set delete on close */
457 sfinfo
.disposition_info
.level
= RAW_SFILEINFO_DISPOSITION_INFO
;
458 sfinfo
.disposition_info
.in
.file
.fnum
= fnum
;
459 sfinfo
.disposition_info
.in
.delete_on_close
= 1;
460 req
= smb_raw_setfileinfo_send(ud_cli_state
->cli1
->tree
, &sfinfo
);
462 torture_comment(ud_cli_state
->tctx
, "smb_raw_setfileinfo_send "
466 smbcli_close(ud_cli_state
->cli1
->tree
, fnum
);
468 torture_comment(ud_cli_state
->tctx
, "Acking the oplock to NONE\n");
470 ret
= smbcli_oplock_ack(ud_cli_state
->cli1
->tree
, fnum
,
471 OPLOCK_BREAK_TO_NONE
);
476 static bool test_unlink_defer(struct torture_context
*tctx
,
477 struct smbcli_state
*cli1
,
478 struct smbcli_state
*cli2
)
480 const char *fname
= BASEDIR
"\\test_unlink_defer.dat";
484 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
);
522 /* cli2: Try to unlink it, but block on the oplock */
523 torture_comment(tctx
, "Try an unlink (should defer the open\n");
524 unl
.unlink
.in
.pattern
= fname
;
525 unl
.unlink
.in
.attrib
= 0;
526 status
= smb_raw_unlink(cli2
->tree
, &unl
);
529 smb_raw_exit(cli1
->session
);
530 smb_raw_exit(cli2
->session
);
531 smbcli_deltree(cli1
->tree
, BASEDIR
);
536 basic testing of unlink calls
538 struct torture_suite
*torture_raw_unlink(TALLOC_CTX
*mem_ctx
)
540 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "unlink");
542 torture_suite_add_1smb_test(suite
, "unlink", test_unlink
);
543 torture_suite_add_1smb_test(suite
, "delete_on_close", test_delete_on_close
);
544 torture_suite_add_2smb_test(suite
, "unlink-defer", test_unlink_defer
);