2 Unix SMB/CIFS implementation.
4 delete on close testing
6 Copyright (C) Andrew Tridgell 2003
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #include "libcli/libcli.h"
25 #include "torture/torture.h"
26 #include "torture/util.h"
27 #include "system/filesys.h"
28 #include "libcli/raw/libcliraw.h"
30 #include "torture/raw/proto.h"
32 static BOOL
check_delete_on_close(struct smbcli_state
*cli
, int fnum
,
33 const char *fname
, BOOL expect_it
,
36 TALLOC_CTX
*mem_ctx
= talloc_init("single_search");
37 union smb_search_data data
;
40 time_t c_time
, a_time
, m_time
;
46 status
= torture_single_search(cli
, mem_ctx
,
47 fname
, RAW_SEARCH_FULL_DIRECTORY_INFO
,
48 FILE_ATTRIBUTE_DIRECTORY
,
50 if (!NT_STATUS_IS_OK(status
)) {
51 printf("(%s) single_search failed (%s)\n",
52 where
, nt_errstr(status
));
58 union smb_fileinfo io
;
59 int nlink
= expect_it
? 0 : 1;
61 io
.all_info
.level
= RAW_FILEINFO_ALL_INFO
;
62 io
.all_info
.in
.file
.fnum
= fnum
;
64 status
= smb_raw_fileinfo(cli
->tree
, mem_ctx
, &io
);
65 if (!NT_STATUS_IS_OK(status
)) {
66 printf("(%s) qfileinfo failed (%s)\n", where
,
72 if (expect_it
!= io
.all_info
.out
.delete_pending
) {
73 printf("%s - Expected del_on_close flag %d, qfileinfo/all_info gave %d\n",
74 where
, expect_it
, io
.all_info
.out
.delete_pending
);
79 if (nlink
!= io
.all_info
.out
.nlink
) {
80 printf("%s - Expected nlink %d, qfileinfo/all_info gave %d\n",
81 where
, nlink
, io
.all_info
.out
.nlink
);
86 io
.standard_info
.level
= RAW_FILEINFO_STANDARD_INFO
;
87 io
.standard_info
.in
.file
.fnum
= fnum
;
89 status
= smb_raw_fileinfo(cli
->tree
, mem_ctx
, &io
);
90 if (!NT_STATUS_IS_OK(status
)) {
91 printf("(%s) qpathinfo failed (%s)\n", where
,
97 if (expect_it
!= io
.standard_info
.out
.delete_pending
) {
98 printf("%s - Expected del_on_close flag %d, qfileinfo/standard_info gave %d\n",
99 where
, expect_it
, io
.standard_info
.out
.delete_pending
);
104 if (nlink
!= io
.standard_info
.out
.nlink
) {
105 printf("%s - Expected nlink %d, qfileinfo/standard_info gave %d\n",
106 where
, nlink
, io
.all_info
.out
.nlink
);
113 status
= smbcli_qpathinfo(cli
->tree
, fname
,
114 &c_time
, &a_time
, &m_time
,
118 if (!NT_STATUS_EQUAL(status
, NT_STATUS_DELETE_PENDING
)) {
119 printf("(%s) qpathinfo did not give correct error "
120 "code (%s) -- NT_STATUS_DELETE_PENDING "
127 if (!NT_STATUS_IS_OK(status
)) {
128 printf("(%s) qpathinfo failed (%s)\n", where
,
136 talloc_free(mem_ctx
);
140 #define CHECK_STATUS(_cli, _expected) do { \
141 if (!NT_STATUS_EQUAL(_cli->tree->session->transport->error.e.nt_status, _expected)) { \
142 printf("(%d) Incorrect status %s - should be %s\n", \
143 __LINE__, nt_errstr(_cli->tree->session->transport->error.e.nt_status), nt_errstr(_expected)); \
148 static const char *fname
= "\\delete.file";
149 static const char *fname_new
= "\\delete.new";
150 static const char *dname
= "\\delete.dir";
152 static void del_clean_area(struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
154 smbcli_deltree(cli1
->tree
, dname
);
155 smbcli_setatr(cli1
->tree
, fname
, 0, 0);
156 smbcli_unlink(cli1
->tree
, fname
);
157 smbcli_setatr(cli1
->tree
, fname_new
, 0, 0);
158 smbcli_unlink(cli1
->tree
, fname_new
);
160 smb_raw_exit(cli1
->session
);
161 smb_raw_exit(cli2
->session
);
164 /* Test 1 - this should delete the file on close. */
166 static BOOL
deltest1(struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
170 del_clean_area(cli1
, cli2
);
172 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
174 FILE_ATTRIBUTE_NORMAL
,
175 NTCREATEX_SHARE_ACCESS_DELETE
, NTCREATEX_DISP_OVERWRITE_IF
,
176 NTCREATEX_OPTIONS_DELETE_ON_CLOSE
, 0);
179 printf("(%s) open of %s failed (%s)\n",
180 __location__
, fname
, smbcli_errstr(cli1
->tree
));
184 if (NT_STATUS_IS_ERR(smbcli_close(cli1
->tree
, fnum1
))) {
185 printf("(%s) close failed (%s)\n",
186 __location__
, smbcli_errstr(cli1
->tree
));
190 fnum1
= smbcli_open(cli1
->tree
, fname
, O_RDWR
, DENY_NONE
);
192 printf("(%s) open of %s succeeded (should fail)\n",
193 __location__
, fname
);
197 printf("first delete on close test succeeded.\n");
201 /* Test 2 - this should delete the file on close. */
202 static BOOL
deltest2(struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
206 del_clean_area(cli1
, cli2
);
208 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
210 FILE_ATTRIBUTE_NORMAL
, NTCREATEX_SHARE_ACCESS_NONE
,
211 NTCREATEX_DISP_OVERWRITE_IF
, 0, 0);
214 printf("(%s) open of %s failed (%s)\n",
215 __location__
, fname
, smbcli_errstr(cli1
->tree
));
219 if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1
->tree
, fnum1
, True
))) {
220 printf("(%s) setting delete_on_close failed (%s)\n",
221 __location__
, smbcli_errstr(cli1
->tree
));
225 if (NT_STATUS_IS_ERR(smbcli_close(cli1
->tree
, fnum1
))) {
226 printf("(%s) close failed (%s)\n",
227 __location__
, smbcli_errstr(cli1
->tree
));
231 fnum1
= smbcli_open(cli1
->tree
, fname
, O_RDONLY
, DENY_NONE
);
233 printf("(%s) open of %s succeeded should have been deleted on close !\n",
234 __location__
, fname
);
235 if (NT_STATUS_IS_ERR(smbcli_close(cli1
->tree
, fnum1
))) {
236 printf("(%s) close failed (%s)\n",
237 __location__
, smbcli_errstr(cli1
->tree
));
240 smbcli_unlink(cli1
->tree
, fname
);
242 printf("second delete on close test succeeded.\n");
248 static BOOL
deltest3(struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
253 del_clean_area(cli1
, cli2
);
255 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
257 FILE_ATTRIBUTE_NORMAL
,
258 NTCREATEX_SHARE_ACCESS_READ
|NTCREATEX_SHARE_ACCESS_WRITE
,
259 NTCREATEX_DISP_OVERWRITE_IF
, 0, 0);
262 printf("(%s) open - 1 of %s failed (%s)\n",
263 __location__
, fname
, smbcli_errstr(cli1
->tree
));
267 /* This should fail with a sharing violation - open for delete is only compatible
268 with SHARE_DELETE. */
270 fnum2
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
271 SEC_RIGHTS_FILE_READ
,
272 FILE_ATTRIBUTE_NORMAL
,
273 NTCREATEX_SHARE_ACCESS_READ
|NTCREATEX_SHARE_ACCESS_WRITE
,
274 NTCREATEX_DISP_OPEN
, 0, 0);
277 printf("(%s) open - 2 of %s succeeded - should have failed.\n",
278 __location__
, fname
);
282 /* This should succeed. */
284 fnum2
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
285 SEC_RIGHTS_FILE_READ
,
286 FILE_ATTRIBUTE_NORMAL
,
287 NTCREATEX_SHARE_ACCESS_READ
|NTCREATEX_SHARE_ACCESS_WRITE
|NTCREATEX_SHARE_ACCESS_DELETE
,
288 NTCREATEX_DISP_OPEN
, 0, 0);
291 printf("(%s) open - 2 of %s failed (%s)\n",
292 __location__
, fname
, smbcli_errstr(cli1
->tree
));
296 if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1
->tree
, fnum1
, True
))) {
297 printf("(%s) setting delete_on_close failed (%s)\n",
298 __location__
, smbcli_errstr(cli1
->tree
));
302 if (NT_STATUS_IS_ERR(smbcli_close(cli1
->tree
, fnum1
))) {
303 printf("(%s) close 1 failed (%s)\n",
304 __location__
, smbcli_errstr(cli1
->tree
));
308 if (NT_STATUS_IS_ERR(smbcli_close(cli1
->tree
, fnum2
))) {
309 printf("(%s) close 2 failed (%s)\n",
310 __location__
, smbcli_errstr(cli1
->tree
));
314 /* This should fail - file should no longer be there. */
316 fnum1
= smbcli_open(cli1
->tree
, fname
, O_RDONLY
, DENY_NONE
);
318 printf("(%s) open of %s succeeded should have been deleted on close !\n",
319 __location__
, fname
);
320 if (NT_STATUS_IS_ERR(smbcli_close(cli1
->tree
, fnum1
))) {
321 printf("(%s) close failed (%s)\n",
322 __location__
, smbcli_errstr(cli1
->tree
));
324 smbcli_unlink(cli1
->tree
, fname
);
327 printf("third delete on close test succeeded.\n");
333 static BOOL
deltest4(struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
339 del_clean_area(cli1
, cli2
);
341 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
343 SEC_FILE_WRITE_DATA
|
345 FILE_ATTRIBUTE_NORMAL
,
346 NTCREATEX_SHARE_ACCESS_READ
|NTCREATEX_SHARE_ACCESS_WRITE
,
347 NTCREATEX_DISP_OVERWRITE_IF
, 0, 0);
350 printf("(%s) open of %s failed (%s)\n",
351 __location__
, fname
, smbcli_errstr(cli1
->tree
));
355 /* This should succeed. */
356 fnum2
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
357 SEC_RIGHTS_FILE_READ
,
358 FILE_ATTRIBUTE_NORMAL
,
359 NTCREATEX_SHARE_ACCESS_READ
|
360 NTCREATEX_SHARE_ACCESS_WRITE
|
361 NTCREATEX_SHARE_ACCESS_DELETE
,
362 NTCREATEX_DISP_OPEN
, 0, 0);
364 printf("(%s) open - 2 of %s failed (%s)\n",
365 __location__
, fname
, smbcli_errstr(cli1
->tree
));
369 if (NT_STATUS_IS_ERR(smbcli_close(cli1
->tree
, fnum2
))) {
370 printf("(%s) close - 1 failed (%s)\n",
371 __location__
, smbcli_errstr(cli1
->tree
));
375 if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1
->tree
, fnum1
, True
))) {
376 printf("(%s) setting delete_on_close failed (%s)\n",
377 __location__
, smbcli_errstr(cli1
->tree
));
381 /* This should fail - no more opens once delete on close set. */
382 fnum2
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
383 SEC_RIGHTS_FILE_READ
,
384 FILE_ATTRIBUTE_NORMAL
,
385 NTCREATEX_SHARE_ACCESS_READ
|NTCREATEX_SHARE_ACCESS_WRITE
|NTCREATEX_SHARE_ACCESS_DELETE
,
386 NTCREATEX_DISP_OPEN
, 0, 0);
388 printf("(%s) open - 3 of %s succeeded ! Should have failed.\n",
389 __location__
, fname
);
392 CHECK_STATUS(cli1
, NT_STATUS_DELETE_PENDING
);
394 if (NT_STATUS_IS_ERR(smbcli_close(cli1
->tree
, fnum1
))) {
395 printf("(%s) close - 2 failed (%s)\n",
396 __location__
, smbcli_errstr(cli1
->tree
));
400 printf("fourth delete on close test succeeded.\n");
408 static BOOL
deltest5(struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
412 del_clean_area(cli1
, cli2
);
414 fnum1
= smbcli_open(cli1
->tree
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
);
416 printf("(%s) open of %s failed (%s)\n",
417 __location__
, fname
, smbcli_errstr(cli1
->tree
));
421 /* This should fail - only allowed on NT opens with DELETE access. */
423 if (NT_STATUS_IS_OK(smbcli_nt_delete_on_close(cli1
->tree
, fnum1
, True
))) {
424 printf("(%s) setting delete_on_close on OpenX file succeeded - should fail !\n",
429 if (NT_STATUS_IS_ERR(smbcli_close(cli1
->tree
, fnum1
))) {
430 printf("(%s) close - 2 failed (%s)\n",
431 __location__
, smbcli_errstr(cli1
->tree
));
435 printf("fifth delete on close test succeeded.\n");
440 static BOOL
deltest6(struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
444 del_clean_area(cli1
, cli2
);
446 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
447 SEC_FILE_READ_DATA
| SEC_FILE_WRITE_DATA
,
448 FILE_ATTRIBUTE_NORMAL
,
449 NTCREATEX_SHARE_ACCESS_READ
|
450 NTCREATEX_SHARE_ACCESS_WRITE
|
451 NTCREATEX_SHARE_ACCESS_DELETE
,
452 NTCREATEX_DISP_OVERWRITE_IF
, 0, 0);
455 printf("(%s) open of %s failed (%s)\n",
456 __location__
, fname
, smbcli_errstr(cli1
->tree
));
460 /* This should fail - only allowed on NT opens with DELETE access. */
462 if (NT_STATUS_IS_OK(smbcli_nt_delete_on_close(cli1
->tree
, fnum1
, True
))) {
463 printf("(%s) setting delete_on_close on file with no delete access succeeded - should fail !\n",
468 if (NT_STATUS_IS_ERR(smbcli_close(cli1
->tree
, fnum1
))) {
469 printf("(%s) close - 2 failed (%s)\n",
470 __location__
, smbcli_errstr(cli1
->tree
));
474 printf("sixth delete on close test succeeded.\n");
479 static BOOL
deltest7(struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
484 del_clean_area(cli1
, cli2
);
486 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
488 SEC_FILE_WRITE_DATA
|
490 FILE_ATTRIBUTE_NORMAL
, 0,
491 NTCREATEX_DISP_OVERWRITE_IF
, 0, 0);
494 printf("(%s) open of %s failed (%s)\n",
495 __location__
, fname
, smbcli_errstr(cli1
->tree
));
500 if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1
->tree
, fnum1
, True
))) {
501 printf("(%s) setting delete_on_close on file failed !\n",
507 correct
&= check_delete_on_close(cli1
, fnum1
, fname
, True
, __location__
);
509 if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1
->tree
, fnum1
, False
))) {
510 printf("(%s) unsetting delete_on_close on file failed !\n",
516 correct
&= check_delete_on_close(cli1
, fnum1
, fname
, False
, __location__
);
518 if (NT_STATUS_IS_ERR(smbcli_close(cli1
->tree
, fnum1
))) {
519 printf("(%s) close - 2 failed (%s)\n",
520 __location__
, smbcli_errstr(cli1
->tree
));
525 /* This next open should succeed - we reset the flag. */
527 fnum1
= smbcli_open(cli1
->tree
, fname
, O_RDONLY
, DENY_NONE
);
529 printf("(%s) open of %s failed (%s)\n",
530 __location__
, fname
, smbcli_errstr(cli1
->tree
));
535 if (NT_STATUS_IS_ERR(smbcli_close(cli1
->tree
, fnum1
))) {
536 printf("(%s) close - 2 failed (%s)\n",
537 __location__
, smbcli_errstr(cli1
->tree
));
542 printf("seventh delete on close test succeeded.\n");
550 static BOOL
deltest8(struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
556 del_clean_area(cli1
, cli2
);
558 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
562 FILE_ATTRIBUTE_NORMAL
,
563 NTCREATEX_SHARE_ACCESS_READ
|NTCREATEX_SHARE_ACCESS_WRITE
|NTCREATEX_SHARE_ACCESS_DELETE
,
564 NTCREATEX_DISP_OVERWRITE_IF
, 0, 0);
567 printf("(%s) open of %s failed (%s)\n",
568 __location__
, fname
, smbcli_errstr(cli1
->tree
));
573 fnum2
= smbcli_nt_create_full(cli2
->tree
, fname
, 0,
577 FILE_ATTRIBUTE_NORMAL
,
578 NTCREATEX_SHARE_ACCESS_READ
|NTCREATEX_SHARE_ACCESS_WRITE
|NTCREATEX_SHARE_ACCESS_DELETE
,
579 NTCREATEX_DISP_OPEN
, 0, 0);
582 printf("(%s) open of %s failed (%s)\n",
583 __location__
, fname
, smbcli_errstr(cli1
->tree
));
588 if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1
->tree
, fnum1
, True
))) {
589 printf("(%s) setting delete_on_close on file failed !\n",
595 correct
&= check_delete_on_close(cli1
, fnum1
, fname
, True
, __location__
);
596 correct
&= check_delete_on_close(cli2
, fnum2
, fname
, True
, __location__
);
598 if (NT_STATUS_IS_ERR(smbcli_close(cli1
->tree
, fnum1
))) {
599 printf("(%s) close - 1 failed (%s)\n",
600 __location__
, smbcli_errstr(cli1
->tree
));
605 correct
&= check_delete_on_close(cli1
, -1, fname
, True
, __location__
);
606 correct
&= check_delete_on_close(cli2
, fnum2
, fname
, True
, __location__
);
608 if (NT_STATUS_IS_ERR(smbcli_close(cli2
->tree
, fnum2
))) {
609 printf("(%s) close - 2 failed (%s)\n",
610 __location__
, smbcli_errstr(cli2
->tree
));
615 /* This should fail.. */
616 fnum1
= smbcli_open(cli1
->tree
, fname
, O_RDONLY
, DENY_NONE
);
618 printf("(%s) open of %s succeeded should have been deleted on close !\n",
619 __location__
, fname
);
622 printf("eighth delete on close test succeeded.\n");
631 static BOOL
deltest9(struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
635 del_clean_area(cli1
, cli2
);
637 /* This should fail - we need to set DELETE_ACCESS. */
638 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
639 SEC_FILE_READ_DATA
|SEC_FILE_WRITE_DATA
,
640 FILE_ATTRIBUTE_NORMAL
,
641 NTCREATEX_SHARE_ACCESS_NONE
,
642 NTCREATEX_DISP_OVERWRITE_IF
,
643 NTCREATEX_OPTIONS_DELETE_ON_CLOSE
, 0);
646 printf("(%s) open of %s succeeded should have failed!\n",
647 __location__
, fname
);
651 printf("ninth delete on close test succeeded.\n");
656 static BOOL
deltest10(struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
661 del_clean_area(cli1
, cli2
);
663 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
667 FILE_ATTRIBUTE_NORMAL
,
668 NTCREATEX_SHARE_ACCESS_NONE
,
669 NTCREATEX_DISP_OVERWRITE_IF
,
670 NTCREATEX_OPTIONS_DELETE_ON_CLOSE
, 0);
672 printf("(%s) open of %s failed (%s)\n",
673 __location__
, fname
, smbcli_errstr(cli1
->tree
));
678 /* This should delete the file. */
679 if (NT_STATUS_IS_ERR(smbcli_close(cli1
->tree
, fnum1
))) {
680 printf("(%s) close failed (%s)\n",
681 __location__
, smbcli_errstr(cli1
->tree
));
686 /* This should fail.. */
687 fnum1
= smbcli_open(cli1
->tree
, fname
, O_RDONLY
, DENY_NONE
);
689 printf("(%s) open of %s succeeded should have been deleted on close !\n",
690 __location__
, fname
);
694 printf("tenth delete on close test succeeded.\n");
703 static BOOL
deltest11(struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
708 del_clean_area(cli1
, cli2
);
710 /* test 11 - does having read only attribute still allow delete on close. */
712 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
714 FILE_ATTRIBUTE_READONLY
,
715 NTCREATEX_SHARE_ACCESS_NONE
,
716 NTCREATEX_DISP_OVERWRITE_IF
, 0, 0);
719 printf("(%s) open of %s failed (%s)\n",
720 __location__
, fname
, smbcli_errstr(cli1
->tree
));
724 status
= smbcli_nt_delete_on_close(cli1
->tree
, fnum1
, True
);
726 if (!NT_STATUS_EQUAL(status
, NT_STATUS_CANNOT_DELETE
)) {
727 printf("(%s) setting delete_on_close should fail with NT_STATUS_CANNOT_DELETE. Got %s instead)\n",
728 __location__
, smbcli_errstr(cli1
->tree
));
732 if (NT_STATUS_IS_ERR(smbcli_close(cli1
->tree
, fnum1
))) {
733 printf("(%s) close failed (%s)\n",
734 __location__
, smbcli_errstr(cli1
->tree
));
738 printf("eleventh delete on close test succeeded.\n");
743 static BOOL
deltest12(struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
748 del_clean_area(cli1
, cli2
);
750 /* test 12 - does having read only attribute still allow delete on
751 * close at time of open. */
753 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
755 FILE_ATTRIBUTE_READONLY
,
756 NTCREATEX_SHARE_ACCESS_DELETE
,
757 NTCREATEX_DISP_OVERWRITE_IF
,
758 NTCREATEX_OPTIONS_DELETE_ON_CLOSE
, 0);
761 printf("(%s) open of %s succeeded. Should fail with "
762 "NT_STATUS_CANNOT_DELETE.\n", __location__
, fname
);
763 smbcli_close(cli1
->tree
, fnum1
);
766 status
= smbcli_nt_error(cli1
->tree
);
767 if (!NT_STATUS_EQUAL(status
, NT_STATUS_CANNOT_DELETE
)) {
768 printf("(%s) setting delete_on_close on open should "
769 "fail with NT_STATUS_CANNOT_DELETE. Got %s "
771 __location__
, smbcli_errstr(cli1
->tree
));
776 printf("twelvth delete on close test succeeded.\n");
781 static BOOL
deltest13(struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
787 del_clean_area(cli1
, cli2
);
789 /* Test 13: Does resetting the delete on close flag affect a second
792 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
796 FILE_ATTRIBUTE_NORMAL
,
797 NTCREATEX_SHARE_ACCESS_READ
|
798 NTCREATEX_SHARE_ACCESS_WRITE
|
799 NTCREATEX_SHARE_ACCESS_DELETE
,
800 NTCREATEX_DISP_OVERWRITE_IF
,
804 printf("(%s) open of %s failed (%s)\n",
805 __location__
, fname
, smbcli_errstr(cli1
->tree
));
810 fnum2
= smbcli_nt_create_full(cli2
->tree
, fname
, 0,
814 FILE_ATTRIBUTE_NORMAL
,
815 NTCREATEX_SHARE_ACCESS_READ
|
816 NTCREATEX_SHARE_ACCESS_WRITE
|
817 NTCREATEX_SHARE_ACCESS_DELETE
,
818 NTCREATEX_DISP_OPEN
, 0, 0);
821 printf("(%s) open of %s failed (%s)\n",
822 __location__
, fname
, smbcli_errstr(cli2
->tree
));
827 if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1
->tree
, fnum1
,
829 printf("(%s) setting delete_on_close on file failed !\n",
835 correct
&= check_delete_on_close(cli1
, fnum1
, fname
, True
, __location__
);
836 correct
&= check_delete_on_close(cli2
, fnum2
, fname
, True
, __location__
);
838 if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli2
->tree
, fnum2
,
840 printf("(%s) setting delete_on_close on file failed !\n",
846 correct
&= check_delete_on_close(cli1
, fnum1
, fname
, False
, __location__
);
847 correct
&= check_delete_on_close(cli2
, fnum2
, fname
, False
, __location__
);
849 if (NT_STATUS_IS_ERR(smbcli_close(cli1
->tree
, fnum1
))) {
850 printf("(%s) close - 1 failed (%s)\n",
851 __location__
, smbcli_errstr(cli1
->tree
));
856 if (NT_STATUS_IS_ERR(smbcli_close(cli2
->tree
, fnum2
))) {
857 printf("(%s) close - 2 failed (%s)\n",
858 __location__
, smbcli_errstr(cli2
->tree
));
863 fnum1
= smbcli_open(cli1
->tree
, fname
, O_RDONLY
, DENY_NONE
);
866 printf("(%s) open of %s failed!\n",
867 __location__
, fname
);
872 printf("thirteenth delete on close test succeeded.\n");
880 static BOOL
deltest14(struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
885 del_clean_area(cli1
, cli2
);
887 /* Test 14 -- directory */
889 dnum1
= smbcli_nt_create_full(cli1
->tree
, dname
, 0,
893 FILE_ATTRIBUTE_DIRECTORY
,
894 NTCREATEX_SHARE_ACCESS_READ
|
895 NTCREATEX_SHARE_ACCESS_WRITE
|
896 NTCREATEX_SHARE_ACCESS_DELETE
,
897 NTCREATEX_DISP_CREATE
, 0, 0);
899 printf("(%s) open of %s failed: %s!\n",
900 __location__
, dname
, smbcli_errstr(cli1
->tree
));
905 correct
&= check_delete_on_close(cli1
, dnum1
, dname
, False
, __location__
);
906 if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1
->tree
, dnum1
, True
))) {
907 printf("(%s) setting delete_on_close on file failed !\n",
912 correct
&= check_delete_on_close(cli1
, dnum1
, dname
, True
, __location__
);
913 smbcli_close(cli1
->tree
, dnum1
);
915 /* Now it should be gone... */
917 dnum1
= smbcli_nt_create_full(cli1
->tree
, dname
, 0,
921 FILE_ATTRIBUTE_DIRECTORY
,
922 NTCREATEX_SHARE_ACCESS_READ
|
923 NTCREATEX_SHARE_ACCESS_WRITE
|
924 NTCREATEX_SHARE_ACCESS_DELETE
,
925 NTCREATEX_DISP_OPEN
, 0, 0);
927 printf("(%s) setting delete_on_close on file succeeded !\n",
933 printf("fourteenth delete on close test succeeded.\n");
941 static BOOL
deltest15(struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
948 del_clean_area(cli1
, cli2
);
950 /* Test 15: delete on close under rename */
952 smbcli_setatr(cli1
->tree
, fname
, 0, 0);
953 smbcli_unlink(cli1
->tree
, fname
);
954 smbcli_unlink(cli1
->tree
, fname_new
);
956 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
958 FILE_ATTRIBUTE_NORMAL
,
959 NTCREATEX_SHARE_ACCESS_READ
|
960 NTCREATEX_SHARE_ACCESS_WRITE
|
961 NTCREATEX_SHARE_ACCESS_DELETE
,
962 NTCREATEX_DISP_OVERWRITE_IF
,
966 printf("(%s) open - 1 of %s failed (%s)\n",
967 __location__
, fname
, smbcli_errstr(cli1
->tree
));
972 status
= smbcli_rename(cli2
->tree
, fname
, fname_new
);
974 if (!NT_STATUS_IS_OK(status
)) {
975 printf("(%s) renaming failed: %s !\n",
976 __location__
, nt_errstr(status
));
981 fnum2
= smbcli_nt_create_full(cli2
->tree
, fname_new
, 0,
983 FILE_ATTRIBUTE_NORMAL
,
984 NTCREATEX_SHARE_ACCESS_READ
|
985 NTCREATEX_SHARE_ACCESS_WRITE
|
986 NTCREATEX_SHARE_ACCESS_DELETE
,
987 NTCREATEX_DISP_OVERWRITE_IF
,
991 printf("(%s) open - 1 of %s failed (%s)\n",
992 __location__
, fname_new
, smbcli_errstr(cli1
->tree
));
997 status
= smbcli_nt_delete_on_close(cli2
->tree
, fnum2
, True
);
999 if (!NT_STATUS_IS_OK(status
)) {
1000 printf("(%s) setting delete_on_close on file failed !\n",
1006 smbcli_close(cli2
->tree
, fnum2
);
1008 /* The file should be around under the new name, there's a second
1011 correct
&= check_delete_on_close(cli1
, fnum1
, fname_new
, True
, __location__
);
1013 fnum2
= smbcli_nt_create_full(cli2
->tree
, fname
, 0,
1015 FILE_ATTRIBUTE_NORMAL
,
1016 NTCREATEX_SHARE_ACCESS_READ
|
1017 NTCREATEX_SHARE_ACCESS_WRITE
|
1018 NTCREATEX_SHARE_ACCESS_DELETE
,
1019 NTCREATEX_DISP_OVERWRITE_IF
,
1023 printf("(%s) open - 1 of %s failed (%s)\n",
1024 __location__
, fname
, smbcli_errstr(cli1
->tree
));
1029 correct
&= check_delete_on_close(cli2
, fnum2
, fname
, False
, __location__
);
1031 smbcli_close(cli2
->tree
, fnum2
);
1032 smbcli_close(cli1
->tree
, fnum1
);
1034 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
1036 FILE_ATTRIBUTE_NORMAL
,
1037 NTCREATEX_SHARE_ACCESS_READ
|
1038 NTCREATEX_SHARE_ACCESS_WRITE
|
1039 NTCREATEX_SHARE_ACCESS_DELETE
,
1040 NTCREATEX_DISP_OPEN
,
1044 printf("(%s) open - 1 of %s failed (%s)\n",
1045 __location__
, fname
, smbcli_errstr(cli1
->tree
));
1050 smbcli_close(cli1
->tree
, fnum1
);
1052 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname_new
, 0,
1054 FILE_ATTRIBUTE_NORMAL
,
1055 NTCREATEX_SHARE_ACCESS_READ
|
1056 NTCREATEX_SHARE_ACCESS_WRITE
|
1057 NTCREATEX_SHARE_ACCESS_DELETE
,
1058 NTCREATEX_DISP_OPEN
,
1062 printf("(%s) smbcli_open succeeded, should have "
1063 "failed\n", __location__
);
1064 smbcli_close(cli1
->tree
, fnum1
);
1069 printf("fifteenth delete on close test succeeded.\n");
1077 static BOOL
deltest16(struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
1081 BOOL correct
= True
;
1083 del_clean_area(cli1
, cli2
);
1087 /* Ensure the file doesn't already exist. */
1088 smbcli_close(cli1
->tree
, fnum1
);
1089 smbcli_close(cli1
->tree
, fnum2
);
1090 smbcli_setatr(cli1
->tree
, fname
, 0, 0);
1091 smbcli_unlink(cli1
->tree
, fname
);
1093 /* Firstly create with all access, but delete on close. */
1094 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
1095 SEC_RIGHTS_FILE_ALL
,
1096 FILE_ATTRIBUTE_NORMAL
,
1097 NTCREATEX_SHARE_ACCESS_READ
|
1098 NTCREATEX_SHARE_ACCESS_WRITE
|
1099 NTCREATEX_SHARE_ACCESS_DELETE
,
1100 NTCREATEX_DISP_CREATE
,
1101 NTCREATEX_OPTIONS_DELETE_ON_CLOSE
, 0);
1104 printf("(%s) open - 1 of %s failed (%s)\n",
1105 __location__
, fname
, smbcli_errstr(cli1
->tree
));
1110 /* The delete on close bit is *not* reported as being set. */
1111 correct
&= check_delete_on_close(cli1
, fnum1
, fname
, False
, __location__
);
1113 /* The delete on close bit is *not* reported as being set. */
1114 correct
&= check_delete_on_close(cli1
, -1, fname
, False
, __location__
);
1115 correct
&= check_delete_on_close(cli2
, -1, fname
, False
, __location__
);
1117 /* Now try opening again for read-only. */
1118 fnum2
= smbcli_nt_create_full(cli2
->tree
, fname
, 0,
1119 SEC_RIGHTS_FILE_READ
,
1120 FILE_ATTRIBUTE_NORMAL
,
1121 NTCREATEX_SHARE_ACCESS_READ
|
1122 NTCREATEX_SHARE_ACCESS_WRITE
|
1123 NTCREATEX_SHARE_ACCESS_DELETE
,
1124 NTCREATEX_DISP_OPEN
,
1130 printf("(%s) open - 1 of %s failed (%s)\n",
1131 __location__
, fname
, smbcli_errstr(cli1
->tree
));
1136 correct
&= check_delete_on_close(cli1
, fnum1
, fname
, False
, __location__
);
1137 correct
&= check_delete_on_close(cli1
, -1, fname
, False
, __location__
);
1138 correct
&= check_delete_on_close(cli2
, fnum2
, fname
, False
, __location__
);
1139 correct
&= check_delete_on_close(cli2
, -1, fname
, False
, __location__
);
1141 smbcli_close(cli1
->tree
, fnum1
);
1143 correct
&= check_delete_on_close(cli2
, fnum2
, fname
, True
, __location__
);
1144 correct
&= check_delete_on_close(cli2
, -1, fname
, True
, __location__
);
1146 smbcli_close(cli2
->tree
, fnum2
);
1148 /* And the file should be deleted ! */
1149 fnum1
= smbcli_open(cli1
->tree
, fname
, O_RDWR
, DENY_NONE
);
1151 printf("(%s) open of %s succeeded (should fail)\n",
1152 __location__
, fname
);
1157 printf("sixteenth delete on close test succeeded.\n");
1165 static BOOL
deltest17(struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
1169 BOOL correct
= True
;
1171 del_clean_area(cli1
, cli2
);
1175 /* Ensure the file doesn't already exist. */
1176 smbcli_close(cli1
->tree
, fnum1
);
1177 smbcli_close(cli1
->tree
, fnum2
);
1178 smbcli_setatr(cli1
->tree
, fname
, 0, 0);
1179 smbcli_unlink(cli1
->tree
, fname
);
1181 /* Firstly open and create with all access */
1182 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
1183 SEC_RIGHTS_FILE_ALL
,
1184 FILE_ATTRIBUTE_NORMAL
,
1185 NTCREATEX_SHARE_ACCESS_READ
|
1186 NTCREATEX_SHARE_ACCESS_WRITE
|
1187 NTCREATEX_SHARE_ACCESS_DELETE
,
1188 NTCREATEX_DISP_CREATE
,
1191 printf("(%s) open - 1 of %s failed (%s)\n",
1192 __location__
, fname
, smbcli_errstr(cli1
->tree
));
1197 /* And close - just to create the file. */
1198 smbcli_close(cli1
->tree
, fnum1
);
1200 /* Next open with all access, but add delete on close. */
1201 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
1202 SEC_RIGHTS_FILE_ALL
,
1203 FILE_ATTRIBUTE_NORMAL
,
1204 NTCREATEX_SHARE_ACCESS_READ
|
1205 NTCREATEX_SHARE_ACCESS_WRITE
|
1206 NTCREATEX_SHARE_ACCESS_DELETE
,
1207 NTCREATEX_DISP_OPEN
,
1208 NTCREATEX_OPTIONS_DELETE_ON_CLOSE
, 0);
1211 printf("(%s) open - 1 of %s failed (%s)\n",
1212 __location__
, fname
, smbcli_errstr(cli1
->tree
));
1217 /* The delete on close bit is *not* reported as being set. */
1218 correct
&= check_delete_on_close(cli1
, fnum1
, fname
, False
, __location__
);
1220 /* Now try opening again for read-only. */
1221 fnum2
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
1222 SEC_RIGHTS_FILE_READ
|
1224 FILE_ATTRIBUTE_NORMAL
,
1225 NTCREATEX_SHARE_ACCESS_READ
|
1226 NTCREATEX_SHARE_ACCESS_WRITE
|
1227 NTCREATEX_SHARE_ACCESS_DELETE
,
1228 NTCREATEX_DISP_OPEN
,
1233 printf("(%s) open - 1 of %s failed (%s)\n",
1234 __location__
, fname
, smbcli_errstr(cli1
->tree
));
1239 /* still not reported as being set on either */
1240 correct
&= check_delete_on_close(cli1
, fnum1
, fname
, False
, __location__
);
1241 correct
&= check_delete_on_close(cli1
, fnum2
, fname
, False
, __location__
);
1243 smbcli_close(cli1
->tree
, fnum1
);
1245 correct
&= check_delete_on_close(cli1
, fnum2
, fname
, False
, __location__
);
1247 smbcli_close(cli1
->tree
, fnum2
);
1249 /* See if the file is deleted - shouldn't be.... */
1250 fnum1
= smbcli_open(cli1
->tree
, fname
, O_RDWR
, DENY_NONE
);
1252 printf("(%s) open of %s failed (should succeed) - %s\n",
1253 __location__
, fname
, smbcli_errstr(cli1
->tree
));
1258 printf("seventeenth delete on close test succeeded.\n");
1266 static BOOL
deltest18(struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
1270 BOOL correct
= True
;
1272 del_clean_area(cli1
, cli2
);
1274 /* Test 18. With directories. */
1276 /* Ensure the file doesn't already exist. */
1277 smbcli_close(cli1
->tree
, fnum1
);
1278 smbcli_close(cli1
->tree
, fnum2
);
1280 smbcli_deltree(cli1
->tree
, dname
);
1282 /* Firstly create with all access, but delete on close. */
1283 fnum1
= smbcli_nt_create_full(cli1
->tree
, dname
, 0,
1285 SEC_FILE_WRITE_DATA
|
1287 FILE_ATTRIBUTE_DIRECTORY
,
1288 NTCREATEX_SHARE_ACCESS_READ
|
1289 NTCREATEX_SHARE_ACCESS_WRITE
|
1290 NTCREATEX_SHARE_ACCESS_DELETE
,
1291 NTCREATEX_DISP_CREATE
,
1292 NTCREATEX_OPTIONS_DIRECTORY
|NTCREATEX_OPTIONS_DELETE_ON_CLOSE
, 0);
1295 printf("(%s) open - 1 of %s failed (%s)\n",
1296 __location__
, dname
, smbcli_errstr(cli1
->tree
));
1301 /* The delete on close bit is *not* reported as being set. */
1302 correct
&= check_delete_on_close(cli1
, fnum1
, dname
, False
, __location__
);
1304 /* Now try opening again for read-only. */
1305 fnum2
= smbcli_nt_create_full(cli1
->tree
, dname
, 0,
1306 SEC_RIGHTS_FILE_READ
,
1307 FILE_ATTRIBUTE_DIRECTORY
,
1308 NTCREATEX_SHARE_ACCESS_READ
|
1309 NTCREATEX_SHARE_ACCESS_WRITE
|
1310 NTCREATEX_SHARE_ACCESS_DELETE
,
1311 NTCREATEX_DISP_OPEN
,
1312 NTCREATEX_OPTIONS_DIRECTORY
, 0);
1317 printf("(%s) open - 1 of %s failed (%s)\n",
1318 __location__
, dname
, smbcli_errstr(cli1
->tree
));
1323 correct
&= check_delete_on_close(cli1
, fnum1
, dname
, False
, __location__
);
1324 correct
&= check_delete_on_close(cli1
, fnum2
, dname
, False
, __location__
);
1326 smbcli_close(cli1
->tree
, fnum1
);
1328 correct
&= check_delete_on_close(cli1
, fnum2
, dname
, True
, __location__
);
1330 smbcli_close(cli1
->tree
, fnum2
);
1332 /* And the directory should be deleted ! */
1333 fnum1
= smbcli_nt_create_full(cli1
->tree
, dname
, 0,
1334 SEC_RIGHTS_FILE_READ
,
1335 FILE_ATTRIBUTE_DIRECTORY
,
1336 NTCREATEX_SHARE_ACCESS_READ
|
1337 NTCREATEX_SHARE_ACCESS_WRITE
|
1338 NTCREATEX_SHARE_ACCESS_DELETE
,
1339 NTCREATEX_DISP_OPEN
,
1340 NTCREATEX_OPTIONS_DIRECTORY
, 0);
1342 printf("(%s) open of %s succeeded (should fail)\n",
1343 __location__
, dname
);
1348 printf("eighteenth delete on close test succeeded.\n");
1356 static BOOL
deltest19(struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
1360 BOOL correct
= True
;
1362 del_clean_area(cli1
, cli2
);
1366 smbcli_deltree(cli1
->tree
, dname
);
1368 /* Firstly open and create with all access */
1369 fnum1
= smbcli_nt_create_full(cli1
->tree
, dname
, 0,
1371 SEC_FILE_WRITE_DATA
|
1373 FILE_ATTRIBUTE_DIRECTORY
,
1374 NTCREATEX_SHARE_ACCESS_READ
|
1375 NTCREATEX_SHARE_ACCESS_WRITE
|
1376 NTCREATEX_SHARE_ACCESS_DELETE
,
1377 NTCREATEX_DISP_CREATE
,
1378 NTCREATEX_OPTIONS_DIRECTORY
, 0);
1381 printf("(%s) open - 1 of %s failed (%s)\n",
1382 __location__
, dname
, smbcli_errstr(cli1
->tree
));
1387 /* And close - just to create the directory. */
1388 smbcli_close(cli1
->tree
, fnum1
);
1390 /* Next open with all access, but add delete on close. */
1391 fnum1
= smbcli_nt_create_full(cli1
->tree
, dname
, 0,
1393 SEC_FILE_WRITE_DATA
|
1395 FILE_ATTRIBUTE_DIRECTORY
,
1396 NTCREATEX_SHARE_ACCESS_READ
|
1397 NTCREATEX_SHARE_ACCESS_WRITE
|
1398 NTCREATEX_SHARE_ACCESS_DELETE
,
1399 NTCREATEX_DISP_OPEN
,
1400 NTCREATEX_OPTIONS_DIRECTORY
|NTCREATEX_OPTIONS_DELETE_ON_CLOSE
, 0);
1403 printf("(%s) open - 1 of %s failed (%s)\n",
1404 __location__
, fname
, smbcli_errstr(cli1
->tree
));
1409 /* The delete on close bit is *not* reported as being set. */
1410 correct
&= check_delete_on_close(cli1
, fnum1
, dname
, False
, __location__
);
1412 /* Now try opening again for read-only. */
1413 fnum2
= smbcli_nt_create_full(cli1
->tree
, dname
, 0,
1414 SEC_RIGHTS_FILE_READ
,
1415 FILE_ATTRIBUTE_DIRECTORY
,
1416 NTCREATEX_SHARE_ACCESS_READ
|
1417 NTCREATEX_SHARE_ACCESS_WRITE
|
1418 NTCREATEX_SHARE_ACCESS_DELETE
,
1419 NTCREATEX_DISP_OPEN
,
1420 NTCREATEX_OPTIONS_DIRECTORY
, 0);
1424 printf("(%s) open - 1 of %s failed (%s)\n",
1425 __location__
, dname
, smbcli_errstr(cli1
->tree
));
1430 smbcli_close(cli1
->tree
, fnum1
);
1432 correct
&= check_delete_on_close(cli1
, fnum2
, dname
, True
, __location__
);
1434 smbcli_close(cli1
->tree
, fnum2
);
1436 /* See if the file is deleted - for a directory this seems to be true ! */
1437 fnum1
= smbcli_nt_create_full(cli1
->tree
, dname
, 0,
1438 SEC_RIGHTS_FILE_READ
,
1439 FILE_ATTRIBUTE_DIRECTORY
,
1440 NTCREATEX_SHARE_ACCESS_READ
|
1441 NTCREATEX_SHARE_ACCESS_WRITE
|
1442 NTCREATEX_SHARE_ACCESS_DELETE
,
1443 NTCREATEX_DISP_OPEN
,
1444 NTCREATEX_OPTIONS_DIRECTORY
, 0);
1446 CHECK_STATUS(cli1
, NT_STATUS_OBJECT_NAME_NOT_FOUND
);
1449 printf("(%s) open of %s succeeded (should fail)\n",
1450 __location__
, dname
);
1455 printf("nineteenth delete on close test succeeded.\n");
1463 static BOOL
deltest20(struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
1467 BOOL correct
= True
;
1470 del_clean_area(cli1
, cli2
);
1472 /* Test 20 -- non-empty directory hardest to get right... */
1474 smbcli_deltree(cli1
->tree
, dname
);
1476 dnum1
= smbcli_nt_create_full(cli1
->tree
, dname
, 0,
1478 SEC_FILE_WRITE_DATA
|
1480 FILE_ATTRIBUTE_DIRECTORY
,
1481 NTCREATEX_SHARE_ACCESS_READ
|
1482 NTCREATEX_SHARE_ACCESS_WRITE
|
1483 NTCREATEX_SHARE_ACCESS_DELETE
,
1484 NTCREATEX_DISP_CREATE
,
1485 NTCREATEX_OPTIONS_DIRECTORY
, 0);
1487 printf("(%s) open of %s failed: %s!\n",
1488 __location__
, dname
, smbcli_errstr(cli1
->tree
));
1493 correct
&= check_delete_on_close(cli1
, dnum1
, dname
, False
, __location__
);
1494 status
= smbcli_nt_delete_on_close(cli1
->tree
, dnum1
, True
);
1498 asprintf(&fullname
, "\\%s%s", dname
, fname
);
1499 fnum1
= smbcli_open(cli1
->tree
, fullname
, O_CREAT
|O_RDWR
,
1502 printf("(%s) smbcli_open succeeded, should have "
1503 "failed with NT_STATUS_DELETE_PENDING\n",
1509 if (!NT_STATUS_EQUAL(smbcli_nt_error(cli1
->tree
),
1510 NT_STATUS_DELETE_PENDING
)) {
1511 printf("(%s) smbcli_open returned %s, expected "
1512 "NT_STATUS_DELETE_PENDING\n",
1513 __location__
, smbcli_errstr(cli1
->tree
));
1519 status
= smbcli_nt_delete_on_close(cli1
->tree
, dnum1
, False
);
1520 if (!NT_STATUS_IS_OK(status
)) {
1521 printf("(%s) setting delete_on_close on file failed !\n",
1529 asprintf(&fullname
, "\\%s%s", dname
, fname
);
1530 fnum1
= smbcli_open(cli1
->tree
, fullname
, O_CREAT
|O_RDWR
,
1533 printf("(%s) smbcli_open failed: %s\n",
1534 __location__
, smbcli_errstr(cli1
->tree
));
1538 smbcli_close(cli1
->tree
, fnum1
);
1541 status
= smbcli_nt_delete_on_close(cli1
->tree
, dnum1
, True
);
1543 if (!NT_STATUS_EQUAL(status
, NT_STATUS_DIRECTORY_NOT_EMPTY
)) {
1544 printf("(%s) setting delete_on_close returned %s, expected "
1545 "NT_STATUS_DIRECTORY_NOT_EMPTY\n", __location__
,
1546 smbcli_errstr(cli1
->tree
));
1551 smbcli_close(cli1
->tree
, dnum1
);
1553 printf("twentieth delete on close test succeeded.\n");
1561 static BOOL
deltest21(struct smbcli_state
**ppcli1
, struct smbcli_state
**ppcli2
)
1564 struct smbcli_state
*cli1
= *ppcli1
;
1565 struct smbcli_state
*cli2
= *ppcli2
;
1566 BOOL correct
= True
;
1568 del_clean_area(cli1
, cli2
);
1570 /* Test 21 -- Test removal of file after socket close. */
1572 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
1573 SEC_RIGHTS_FILE_ALL
,
1574 FILE_ATTRIBUTE_NORMAL
, NTCREATEX_SHARE_ACCESS_NONE
,
1575 NTCREATEX_DISP_OVERWRITE_IF
, 0, 0);
1578 printf("(%s) open of %s failed (%s)\n",
1579 __location__
, fname
, smbcli_errstr(cli1
->tree
));
1583 if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1
->tree
, fnum1
, True
))) {
1584 printf("(%s) setting delete_on_close failed (%s)\n",
1585 __location__
, smbcli_errstr(cli1
->tree
));
1589 /* Ensure delete on close is set. */
1590 correct
&= check_delete_on_close(cli1
, fnum1
, fname
, True
, __location__
);
1592 /* Now yank the rug from under cli1. */
1593 smbcli_transport_dead(cli1
->transport
);
1597 if (!torture_open_connection(ppcli1
)) {
1603 /* File should not be there. */
1604 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
1605 SEC_RIGHTS_FILE_READ
,
1606 FILE_ATTRIBUTE_NORMAL
,
1607 NTCREATEX_SHARE_ACCESS_READ
|
1608 NTCREATEX_SHARE_ACCESS_WRITE
|
1609 NTCREATEX_SHARE_ACCESS_DELETE
,
1610 NTCREATEX_DISP_OPEN
,
1613 CHECK_STATUS(cli1
, NT_STATUS_OBJECT_NAME_NOT_FOUND
);
1615 printf("twenty-first delete on close test succeeded.\n");
1623 Test delete on close semantics.
1625 BOOL
torture_test_delete(struct torture_context
*torture
)
1627 struct smbcli_state
*cli1
= NULL
;
1628 struct smbcli_state
*cli2
= NULL
;
1629 BOOL correct
= True
;
1631 printf("starting delete test\n");
1633 if (!torture_open_connection(&cli1
)) {
1637 if (!torture_open_connection(&cli2
)) {
1638 printf("(%s) failed to open second connection.\n",
1644 correct
&= deltest1(cli1
, cli2
);
1645 correct
&= deltest2(cli1
, cli2
);
1646 correct
&= deltest3(cli1
, cli2
);
1647 correct
&= deltest4(cli1
, cli2
);
1648 correct
&= deltest5(cli1
, cli2
);
1649 correct
&= deltest6(cli1
, cli2
);
1650 correct
&= deltest7(cli1
, cli2
);
1651 correct
&= deltest8(cli1
, cli2
);
1652 correct
&= deltest9(cli1
, cli2
);
1653 correct
&= deltest10(cli1
, cli2
);
1654 correct
&= deltest11(cli1
, cli2
);
1655 correct
&= deltest12(cli1
, cli2
);
1656 correct
&= deltest13(cli1
, cli2
);
1657 correct
&= deltest14(cli1
, cli2
);
1658 correct
&= deltest15(cli1
, cli2
);
1659 if (!lp_parm_bool(-1, "target", "samba3", False
)) {
1660 correct
&= deltest16(cli1
, cli2
);
1661 correct
&= deltest17(cli1
, cli2
);
1662 correct
&= deltest18(cli1
, cli2
);
1663 correct
&= deltest19(cli1
, cli2
);
1664 correct
&= deltest20(cli1
, cli2
);
1666 correct
&= deltest21(&cli1
, &cli2
);
1669 printf("Failed delete test\n");
1671 printf("delete test ok !\n");
1675 del_clean_area(cli1
, cli2
);
1677 if (!torture_close_connection(cli1
)) {
1680 if (!torture_close_connection(cli2
)) {