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 CHECK_STATUS(status
, NT_STATUS_OK
);
183 status
= smb_raw_unlink(cli
->tree
, &io
);
184 CHECK_STATUS(status
, NT_STATUS_NO_SUCH_FILE
);
188 smb_raw_exit(cli
->session
);
189 smbcli_deltree(cli
->tree
, BASEDIR
);
197 static bool test_delete_on_close(struct torture_context
*tctx
,
198 struct smbcli_state
*cli
)
202 struct smb_rmdir dio
;
206 const char *fname
= BASEDIR
"\\test.txt";
207 const char *dname
= BASEDIR
"\\test.dir";
208 const char *inside
= BASEDIR
"\\test.dir\\test.txt";
209 union smb_setfileinfo sfinfo
;
211 torture_assert(tctx
, torture_setup_dir(cli
, BASEDIR
), "Failed to setup up test directory: " BASEDIR
);
215 io
.unlink
.in
.pattern
= fname
;
216 io
.unlink
.in
.attrib
= 0;
217 status
= smb_raw_unlink(cli
->tree
, &io
);
218 CHECK_STATUS(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
);
220 printf("Testing with delete_on_close 0\n");
221 fnum
= create_complex_file(cli
, tctx
, fname
);
223 sfinfo
.disposition_info
.level
= RAW_SFILEINFO_DISPOSITION_INFO
;
224 sfinfo
.disposition_info
.in
.file
.fnum
= fnum
;
225 sfinfo
.disposition_info
.in
.delete_on_close
= 0;
226 status
= smb_raw_setfileinfo(cli
->tree
, &sfinfo
);
227 CHECK_STATUS(status
, NT_STATUS_OK
);
229 smbcli_close(cli
->tree
, fnum
);
231 status
= smb_raw_unlink(cli
->tree
, &io
);
232 CHECK_STATUS(status
, NT_STATUS_OK
);
234 printf("Testing with delete_on_close 1\n");
235 fnum
= create_complex_file(cli
, tctx
, fname
);
236 sfinfo
.disposition_info
.in
.file
.fnum
= fnum
;
237 sfinfo
.disposition_info
.in
.delete_on_close
= 1;
238 status
= smb_raw_setfileinfo(cli
->tree
, &sfinfo
);
239 CHECK_STATUS(status
, NT_STATUS_OK
);
241 smbcli_close(cli
->tree
, fnum
);
243 status
= smb_raw_unlink(cli
->tree
, &io
);
244 CHECK_STATUS(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
);
247 printf("Testing with directory and delete_on_close 0\n");
248 status
= create_directory_handle(cli
->tree
, dname
, &fnum
);
249 CHECK_STATUS(status
, NT_STATUS_OK
);
251 sfinfo
.disposition_info
.level
= RAW_SFILEINFO_DISPOSITION_INFO
;
252 sfinfo
.disposition_info
.in
.file
.fnum
= fnum
;
253 sfinfo
.disposition_info
.in
.delete_on_close
= 0;
254 status
= smb_raw_setfileinfo(cli
->tree
, &sfinfo
);
255 CHECK_STATUS(status
, NT_STATUS_OK
);
257 smbcli_close(cli
->tree
, fnum
);
259 status
= smb_raw_rmdir(cli
->tree
, &dio
);
260 CHECK_STATUS(status
, NT_STATUS_OK
);
262 printf("Testing with directory delete_on_close 1\n");
263 status
= create_directory_handle(cli
->tree
, dname
, &fnum
);
264 CHECK_STATUS(status
, NT_STATUS_OK
);
266 sfinfo
.disposition_info
.in
.file
.fnum
= fnum
;
267 sfinfo
.disposition_info
.in
.delete_on_close
= 1;
268 status
= smb_raw_setfileinfo(cli
->tree
, &sfinfo
);
269 CHECK_STATUS(status
, NT_STATUS_OK
);
271 smbcli_close(cli
->tree
, fnum
);
273 status
= smb_raw_rmdir(cli
->tree
, &dio
);
274 CHECK_STATUS(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
);
277 if (!torture_setting_bool(tctx
, "samba3", false)) {
280 * Known deficiency, also skipped in base-delete.
283 printf("Testing with non-empty directory delete_on_close\n");
284 status
= create_directory_handle(cli
->tree
, dname
, &fnum
);
285 CHECK_STATUS(status
, NT_STATUS_OK
);
287 fnum2
= create_complex_file(cli
, tctx
, inside
);
289 sfinfo
.disposition_info
.in
.file
.fnum
= fnum
;
290 sfinfo
.disposition_info
.in
.delete_on_close
= 1;
291 status
= smb_raw_setfileinfo(cli
->tree
, &sfinfo
);
292 CHECK_STATUS(status
, NT_STATUS_DIRECTORY_NOT_EMPTY
);
294 sfinfo
.disposition_info
.in
.file
.fnum
= fnum2
;
295 status
= smb_raw_setfileinfo(cli
->tree
, &sfinfo
);
296 CHECK_STATUS(status
, NT_STATUS_OK
);
298 sfinfo
.disposition_info
.in
.file
.fnum
= fnum
;
299 status
= smb_raw_setfileinfo(cli
->tree
, &sfinfo
);
300 CHECK_STATUS(status
, NT_STATUS_DIRECTORY_NOT_EMPTY
);
302 smbcli_close(cli
->tree
, fnum2
);
304 status
= smb_raw_setfileinfo(cli
->tree
, &sfinfo
);
305 CHECK_STATUS(status
, NT_STATUS_OK
);
307 smbcli_close(cli
->tree
, fnum
);
309 status
= smb_raw_rmdir(cli
->tree
, &dio
);
310 CHECK_STATUS(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
);
313 printf("Testing open dir with delete_on_close\n");
314 status
= create_directory_handle(cli
->tree
, dname
, &fnum
);
315 CHECK_STATUS(status
, NT_STATUS_OK
);
317 smbcli_close(cli
->tree
, fnum
);
318 fnum2
= create_complex_file(cli
, tctx
, inside
);
319 smbcli_close(cli
->tree
, fnum2
);
321 op
.generic
.level
= RAW_OPEN_NTCREATEX
;
322 op
.ntcreatex
.in
.root_fid
.fnum
= 0;
323 op
.ntcreatex
.in
.flags
= 0;
324 op
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
325 op
.ntcreatex
.in
.create_options
= NTCREATEX_OPTIONS_DIRECTORY
|NTCREATEX_OPTIONS_DELETE_ON_CLOSE
;
326 op
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
327 op
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
| NTCREATEX_SHARE_ACCESS_WRITE
;
328 op
.ntcreatex
.in
.alloc_size
= 0;
329 op
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN
;
330 op
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
331 op
.ntcreatex
.in
.security_flags
= 0;
332 op
.ntcreatex
.in
.fname
= dname
;
334 status
= smb_raw_open(cli
->tree
, tctx
, &op
);
335 CHECK_STATUS(status
, NT_STATUS_OK
);
336 fnum
= op
.ntcreatex
.out
.file
.fnum
;
338 smbcli_close(cli
->tree
, fnum
);
340 status
= smb_raw_rmdir(cli
->tree
, &dio
);
341 CHECK_STATUS(status
, NT_STATUS_DIRECTORY_NOT_EMPTY
);
343 smbcli_deltree(cli
->tree
, dname
);
345 printf("Testing double open dir with second delete_on_close\n");
346 status
= create_directory_handle(cli
->tree
, dname
, &fnum
);
347 CHECK_STATUS(status
, NT_STATUS_OK
);
348 smbcli_close(cli
->tree
, fnum
);
350 fnum2
= create_complex_file(cli
, tctx
, inside
);
351 smbcli_close(cli
->tree
, fnum2
);
353 op
.generic
.level
= RAW_OPEN_NTCREATEX
;
354 op
.ntcreatex
.in
.root_fid
.fnum
= 0;
355 op
.ntcreatex
.in
.flags
= 0;
356 op
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
357 op
.ntcreatex
.in
.create_options
= NTCREATEX_OPTIONS_DIRECTORY
|NTCREATEX_OPTIONS_DELETE_ON_CLOSE
;
358 op
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
359 op
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
| NTCREATEX_SHARE_ACCESS_WRITE
;
360 op
.ntcreatex
.in
.alloc_size
= 0;
361 op
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN
;
362 op
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
363 op
.ntcreatex
.in
.security_flags
= 0;
364 op
.ntcreatex
.in
.fname
= dname
;
366 status
= smb_raw_open(cli
->tree
, tctx
, &op
);
367 CHECK_STATUS(status
, NT_STATUS_OK
);
368 fnum2
= op
.ntcreatex
.out
.file
.fnum
;
370 smbcli_close(cli
->tree
, fnum2
);
372 status
= smb_raw_rmdir(cli
->tree
, &dio
);
373 CHECK_STATUS(status
, NT_STATUS_DIRECTORY_NOT_EMPTY
);
375 smbcli_deltree(cli
->tree
, dname
);
377 printf("Testing pre-existing open dir with second delete_on_close\n");
378 status
= create_directory_handle(cli
->tree
, dname
, &fnum
);
379 CHECK_STATUS(status
, NT_STATUS_OK
);
381 smbcli_close(cli
->tree
, fnum
);
383 fnum
= create_complex_file(cli
, tctx
, inside
);
384 smbcli_close(cli
->tree
, fnum
);
386 /* we have a dir with a file in it, no handles open */
388 op
.generic
.level
= RAW_OPEN_NTCREATEX
;
389 op
.ntcreatex
.in
.root_fid
.fnum
= 0;
390 op
.ntcreatex
.in
.flags
= 0;
391 op
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
392 op
.ntcreatex
.in
.create_options
= NTCREATEX_OPTIONS_DIRECTORY
|NTCREATEX_OPTIONS_DELETE_ON_CLOSE
;
393 op
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
394 op
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
| NTCREATEX_SHARE_ACCESS_WRITE
| NTCREATEX_SHARE_ACCESS_DELETE
;
395 op
.ntcreatex
.in
.alloc_size
= 0;
396 op
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN
;
397 op
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
398 op
.ntcreatex
.in
.security_flags
= 0;
399 op
.ntcreatex
.in
.fname
= dname
;
401 status
= smb_raw_open(cli
->tree
, tctx
, &op
);
402 CHECK_STATUS(status
, NT_STATUS_OK
);
403 fnum
= op
.ntcreatex
.out
.file
.fnum
;
405 /* open without delete on close */
406 op
.ntcreatex
.in
.create_options
= NTCREATEX_OPTIONS_DIRECTORY
;
407 status
= smb_raw_open(cli
->tree
, tctx
, &op
);
408 CHECK_STATUS(status
, NT_STATUS_OK
);
409 fnum2
= op
.ntcreatex
.out
.file
.fnum
;
411 /* close 2nd file handle */
412 smbcli_close(cli
->tree
, fnum2
);
414 status
= smb_raw_rmdir(cli
->tree
, &dio
);
415 CHECK_STATUS(status
, NT_STATUS_DIRECTORY_NOT_EMPTY
);
418 smbcli_close(cli
->tree
, fnum
);
420 status
= smb_raw_rmdir(cli
->tree
, &dio
);
421 CHECK_STATUS(status
, NT_STATUS_DIRECTORY_NOT_EMPTY
);
424 smb_raw_exit(cli
->session
);
425 smbcli_deltree(cli
->tree
, BASEDIR
);
430 struct unlink_defer_cli_state
{
431 struct torture_context
*tctx
;
432 struct smbcli_state
*cli1
;
436 * A handler function for oplock break requests. Ack it as a break to none
438 static bool oplock_handler_ack_to_none(struct smbcli_transport
*transport
,
439 uint16_t tid
, uint16_t fnum
,
440 uint8_t level
, void *private_data
)
442 struct unlink_defer_cli_state
*ud_cli_state
=
443 (struct unlink_defer_cli_state
*)private_data
;
444 union smb_setfileinfo sfinfo
;
446 struct smbcli_request
*req
= NULL
;
448 torture_comment(ud_cli_state
->tctx
, "delete the file before sending "
451 /* cli1: set delete on close */
452 sfinfo
.disposition_info
.level
= RAW_SFILEINFO_DISPOSITION_INFO
;
453 sfinfo
.disposition_info
.in
.file
.fnum
= fnum
;
454 sfinfo
.disposition_info
.in
.delete_on_close
= 1;
455 req
= smb_raw_setfileinfo_send(ud_cli_state
->cli1
->tree
, &sfinfo
);
457 torture_comment(ud_cli_state
->tctx
, "smb_raw_setfileinfo_send "
461 smbcli_close(ud_cli_state
->cli1
->tree
, fnum
);
463 torture_comment(ud_cli_state
->tctx
, "Acking the oplock to NONE\n");
465 ret
= smbcli_oplock_ack(ud_cli_state
->cli1
->tree
, fnum
,
466 OPLOCK_BREAK_TO_NONE
);
471 static bool test_unlink_defer(struct torture_context
*tctx
,
472 struct smbcli_state
*cli1
,
473 struct smbcli_state
*cli2
)
475 const char *fname
= BASEDIR
"\\test_unlink_defer.dat";
479 union smb_unlink unl
;
480 struct unlink_defer_cli_state ud_cli_state
= {};
482 if (!torture_setup_dir(cli1
, BASEDIR
)) {
487 smbcli_unlink(cli1
->tree
, fname
);
489 ud_cli_state
.tctx
= tctx
;
490 ud_cli_state
.cli1
= cli1
;
492 smbcli_oplock_handler(cli1
->transport
, oplock_handler_ack_to_none
,
495 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
496 io
.ntcreatex
.in
.root_fid
.fnum
= 0;
497 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
498 io
.ntcreatex
.in
.alloc_size
= 0;
499 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
500 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
|
501 NTCREATEX_SHARE_ACCESS_WRITE
|
502 NTCREATEX_SHARE_ACCESS_DELETE
;
503 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
504 io
.ntcreatex
.in
.create_options
= 0;
505 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
506 io
.ntcreatex
.in
.security_flags
= 0;
507 io
.ntcreatex
.in
.fname
= fname
;
509 /* cli1: open file with a batch oplock. */
510 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
|
511 NTCREATEX_FLAGS_REQUEST_OPLOCK
|
512 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK
;
514 status
= smb_raw_open(cli1
->tree
, tctx
, &io
);
515 CHECK_STATUS(status
, NT_STATUS_OK
);
517 /* cli2: Try to unlink it, but block on the oplock */
518 torture_comment(tctx
, "Try an unlink (should defer the open\n");
519 unl
.unlink
.in
.pattern
= fname
;
520 unl
.unlink
.in
.attrib
= 0;
521 status
= smb_raw_unlink(cli2
->tree
, &unl
);
524 smb_raw_exit(cli1
->session
);
525 smb_raw_exit(cli2
->session
);
526 smbcli_deltree(cli1
->tree
, BASEDIR
);
531 basic testing of unlink calls
533 struct torture_suite
*torture_raw_unlink(TALLOC_CTX
*mem_ctx
)
535 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "unlink");
537 torture_suite_add_1smb_test(suite
, "unlink", test_unlink
);
538 torture_suite_add_1smb_test(suite
, "delete_on_close", test_delete_on_close
);
539 torture_suite_add_2smb_test(suite
, "unlink-defer", test_unlink_defer
);