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 "system/filesys.h"
25 #include "librpc/gen_ndr/ndr_security.h"
26 #include "libcli/raw/libcliraw.h"
28 static BOOL check_delete_on_close(struct smbcli_state *cli, int fnum,
29 const char *fname, BOOL expect_it)
31 TALLOC_CTX *mem_ctx = talloc_init("single_search");
32 union smb_search_data data;
35 time_t c_time, a_time, m_time;
41 status = torture_single_search(cli, mem_ctx,
42 fname, RAW_SEARCH_FULL_DIRECTORY_INFO,
43 FILE_ATTRIBUTE_DIRECTORY,
45 if (!NT_STATUS_IS_OK(status)) {
46 printf("(%s) single_search failed (%s)\n",
47 __location__, nt_errstr(status));
53 union smb_fileinfo io;
54 int nlink = expect_it ? 0 : 1;
56 io.all_info.level = RAW_FILEINFO_ALL_INFO;
57 io.all_info.in.fnum = fnum;
59 status = smb_raw_fileinfo(cli->tree, mem_ctx, &io);
60 if (!NT_STATUS_IS_OK(status)) {
61 printf("(%s) qpathinfo failed (%s)\n", __location__,
67 if (expect_it != io.all_info.out.delete_pending) {
68 printf("Expected del_on_close flag %d, qfileinfo gave %d\n",
69 expect_it, io.all_info.out.delete_pending);
74 if (nlink != io.all_info.out.nlink) {
75 printf("Expected nlink %d, qfileinfo gave %d\n",
76 nlink, io.all_info.out.nlink);
81 io.standard_info.level = RAW_FILEINFO_STANDARD_INFO;
82 io.standard_info.in.fnum = fnum;
84 status = smb_raw_fileinfo(cli->tree, mem_ctx, &io);
85 if (!NT_STATUS_IS_OK(status)) {
86 printf("(%s) qpathinfo failed (%s)\n", __location__,
92 if (expect_it != io.standard_info.out.delete_pending) {
93 printf("Expected del_on_close flag %d, qfileinfo gave %d\n",
94 expect_it, io.standard_info.out.delete_pending);
99 if (nlink != io.standard_info.out.nlink) {
100 printf("Expected nlink %d, qfileinfo gave %d\n",
101 nlink, io.all_info.out.nlink);
108 status = smbcli_qpathinfo(cli->tree, fname,
109 &c_time, &a_time, &m_time,
113 if (!NT_STATUS_EQUAL(status, NT_STATUS_DELETE_PENDING)) {
114 printf("(%s) qpathinfo did not give correct error "
115 "code (%s) -- NT_STATUS_DELETE_PENDING "
116 "expected\n", __location__,
122 if (!NT_STATUS_IS_OK(status)) {
123 printf("(%s) qpathinfo failed (%s)\n", __location__,
131 talloc_free(mem_ctx);
135 #define CHECK_STATUS(_cli, _expected) do { \
136 if (!NT_STATUS_EQUAL(_cli->tree->session->transport->error.e.nt_status, _expected)) { \
137 printf("(%d) Incorrect status %s - should be %s\n", \
138 __LINE__, nt_errstr(_cli->tree->session->transport->error.e.nt_status), nt_errstr(_expected)); \
144 Test delete on close semantics.
146 BOOL torture_test_delete(void)
148 struct smbcli_state *cli1;
149 struct smbcli_state *cli2 = NULL;
150 const char *fname = "\\delete.file";
151 const char *fname_new = "\\delete.new";
152 const char *dirname = "\\delete.dir";
159 printf("starting delete test\n");
161 if (!torture_open_connection(&cli1)) {
165 smbcli_deltree(cli1->tree, dirname);
167 /* Test 1 - this should delete the file on close. */
169 smbcli_setatr(cli1->tree, fname, 0, 0);
170 smbcli_unlink(cli1->tree, fname);
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));
185 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
186 printf("(%s) close failed (%s)\n",
187 __location__, smbcli_errstr(cli1->tree));
192 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
194 printf("(%s) open of %s succeeded (should fail)\n",
195 __location__, fname);
200 printf("first delete on close test succeeded.\n");
202 /* Test 2 - this should delete the file on close. */
204 smbcli_setatr(cli1->tree, fname, 0, 0);
205 smbcli_unlink(cli1->tree, fname);
207 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
209 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_NONE,
210 NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
213 printf("(%s) open of %s failed (%s)\n",
214 __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));
226 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
227 printf("(%s) close failed (%s)\n",
228 __location__, smbcli_errstr(cli1->tree));
233 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
235 printf("(%s) open of %s succeeded should have been deleted on close !\n",
236 __location__, fname);
237 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
238 printf("(%s) close failed (%s)\n",
239 __location__, smbcli_errstr(cli1->tree));
243 smbcli_unlink(cli1->tree, fname);
245 printf("second delete on close test succeeded.\n");
248 smbcli_setatr(cli1->tree, fname, 0, 0);
249 smbcli_unlink(cli1->tree, fname);
251 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
253 FILE_ATTRIBUTE_NORMAL,
254 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE,
255 NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
258 printf("(%s) open - 1 of %s failed (%s)\n",
259 __location__, fname, smbcli_errstr(cli1->tree));
264 /* This should fail with a sharing violation - open for delete is only compatible
265 with SHARE_DELETE. */
267 fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0,
268 SEC_RIGHTS_FILE_READ,
269 FILE_ATTRIBUTE_NORMAL,
270 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE,
271 NTCREATEX_DISP_OPEN, 0, 0);
274 printf("(%s) open - 2 of %s succeeded - should have failed.\n",
275 __location__, fname);
280 /* This should succeed. */
282 fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0,
283 SEC_RIGHTS_FILE_READ,
284 FILE_ATTRIBUTE_NORMAL,
285 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE,
286 NTCREATEX_DISP_OPEN, 0, 0);
289 printf("(%s) open - 2 of %s failed (%s)\n",
290 __location__, fname, smbcli_errstr(cli1->tree));
295 if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1->tree, fnum1, True))) {
296 printf("(%s) setting delete_on_close failed (%s)\n",
297 __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));
309 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum2))) {
310 printf("(%s) close 2 failed (%s)\n",
311 __location__, smbcli_errstr(cli1->tree));
316 /* This should fail - file should no longer be there. */
318 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
320 printf("(%s) open of %s succeeded should have been deleted on close !\n",
321 __location__, fname);
322 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
323 printf("(%s) close failed (%s)\n",
324 __location__, smbcli_errstr(cli1->tree));
326 smbcli_unlink(cli1->tree, fname);
330 printf("third delete on close test succeeded.\n");
333 smbcli_setatr(cli1->tree, fname, 0, 0);
334 status = smbcli_unlink(cli1->tree, fname);
335 if (NT_STATUS_IS_OK(status)) {
336 printf("(%s) succeeded unlink of %s\n", __location__, fname);
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));
356 /* This should succeed. */
357 fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0,
358 SEC_RIGHTS_FILE_READ,
359 FILE_ATTRIBUTE_NORMAL,
360 NTCREATEX_SHARE_ACCESS_READ |
361 NTCREATEX_SHARE_ACCESS_WRITE |
362 NTCREATEX_SHARE_ACCESS_DELETE,
363 NTCREATEX_DISP_OPEN, 0, 0);
365 printf("(%s) open - 2 of %s failed (%s)\n",
366 __location__, fname, smbcli_errstr(cli1->tree));
371 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum2))) {
372 printf("(%s) close - 1 failed (%s)\n",
373 __location__, smbcli_errstr(cli1->tree));
378 if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1->tree, fnum1, True))) {
379 printf("(%s) setting delete_on_close failed (%s)\n",
380 __location__, smbcli_errstr(cli1->tree));
385 /* This should fail - no more opens once delete on close set. */
386 fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0,
387 SEC_RIGHTS_FILE_READ,
388 FILE_ATTRIBUTE_NORMAL,
389 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE,
390 NTCREATEX_DISP_OPEN, 0, 0);
392 printf("(%s) open - 3 of %s succeeded ! Should have failed.\n",
393 __location__, fname );
397 CHECK_STATUS(cli1, NT_STATUS_DELETE_PENDING);
399 printf("fourth delete on close test succeeded.\n");
401 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
402 printf("(%s) close - 2 failed (%s)\n",
403 __location__, smbcli_errstr(cli1->tree));
409 smbcli_setatr(cli1->tree, fname, 0, 0);
410 smbcli_unlink(cli1->tree, fname);
412 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
414 printf("(%s) open of %s failed (%s)\n",
415 __location__, fname, smbcli_errstr(cli1->tree));
420 /* This should fail - only allowed on NT opens with DELETE access. */
422 if (NT_STATUS_IS_OK(smbcli_nt_delete_on_close(cli1->tree, fnum1, True))) {
423 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));
436 printf("fifth delete on close test succeeded.\n");
439 smbcli_setatr(cli1->tree, fname, 0, 0);
440 smbcli_unlink(cli1->tree, fname);
442 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
443 SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
444 FILE_ATTRIBUTE_NORMAL,
445 NTCREATEX_SHARE_ACCESS_READ |
446 NTCREATEX_SHARE_ACCESS_WRITE |
447 NTCREATEX_SHARE_ACCESS_DELETE,
448 NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
451 printf("(%s) open of %s failed (%s)\n",
452 __location__, fname, smbcli_errstr(cli1->tree));
457 /* This should fail - only allowed on NT opens with DELETE access. */
459 if (NT_STATUS_IS_OK(smbcli_nt_delete_on_close(cli1->tree, fnum1, True))) {
460 printf("(%s) setting delete_on_close on file with no delete access succeeded - should fail !\n",
466 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
467 printf("(%s) close - 2 failed (%s)\n",
468 __location__, smbcli_errstr(cli1->tree));
473 printf("sixth delete on close test succeeded.\n");
476 smbcli_setatr(cli1->tree, fname, 0, 0);
477 smbcli_unlink(cli1->tree, fname);
479 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
481 SEC_FILE_WRITE_DATA |
483 FILE_ATTRIBUTE_NORMAL, 0,
484 NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
487 printf("(%s) open of %s failed (%s)\n",
488 __location__, fname, smbcli_errstr(cli1->tree));
493 if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1->tree, fnum1, True))) {
494 printf("(%s) setting delete_on_close on file failed !\n",
500 correct &= check_delete_on_close(cli1, fnum1, fname, True);
502 if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1->tree, fnum1, False))) {
503 printf("(%s) unsetting delete_on_close on file failed !\n",
509 correct &= check_delete_on_close(cli1, fnum1, fname, False);
511 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
512 printf("(%s) close - 2 failed (%s)\n",
513 __location__, smbcli_errstr(cli1->tree));
518 /* This next open should succeed - we reset the flag. */
520 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
522 printf("(%s) open of %s failed (%s)\n",
523 __location__, fname, smbcli_errstr(cli1->tree));
528 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
529 printf("(%s) close - 2 failed (%s)\n",
530 __location__, smbcli_errstr(cli1->tree));
535 printf("seventh delete on close test succeeded.\n");
538 smbcli_setatr(cli1->tree, fname, 0, 0);
539 smbcli_unlink(cli1->tree, fname);
541 if (!torture_open_connection(&cli2)) {
542 printf("(%s) failed to open second connection.\n",
548 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
552 FILE_ATTRIBUTE_NORMAL,
553 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE,
554 NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
557 printf("(%s) open of %s failed (%s)\n",
558 __location__, fname, smbcli_errstr(cli1->tree));
563 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0,
567 FILE_ATTRIBUTE_NORMAL,
568 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE,
569 NTCREATEX_DISP_OPEN, 0, 0);
572 printf("(%s) open of %s failed (%s)\n",
573 __location__, fname, smbcli_errstr(cli1->tree));
578 if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1->tree, fnum1, True))) {
579 printf("(%s) setting delete_on_close on file failed !\n",
585 correct &= check_delete_on_close(cli1, fnum1, fname, True);
586 correct &= check_delete_on_close(cli2, fnum2, fname, True);
588 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
589 printf("(%s) close - 1 failed (%s)\n",
590 __location__, smbcli_errstr(cli1->tree));
595 correct &= check_delete_on_close(cli1, -1, fname, True);
596 correct &= check_delete_on_close(cli2, fnum2, fname, True);
598 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
599 printf("(%s) close - 2 failed (%s)\n",
600 __location__, smbcli_errstr(cli2->tree));
605 /* This should fail.. */
606 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
608 printf("(%s) open of %s succeeded should have been deleted on close !\n",
609 __location__, fname);
613 printf("eighth delete on close test succeeded.\n");
615 /* This should fail - we need to set DELETE_ACCESS. */
616 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
617 SEC_FILE_READ_DATA|SEC_FILE_WRITE_DATA,
618 FILE_ATTRIBUTE_NORMAL,
619 NTCREATEX_SHARE_ACCESS_NONE,
620 NTCREATEX_DISP_OVERWRITE_IF,
621 NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
624 printf("(%s) open of %s succeeded should have failed!\n",
625 __location__, fname);
630 printf("ninth delete on close test succeeded.\n");
632 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
636 FILE_ATTRIBUTE_NORMAL,
637 NTCREATEX_SHARE_ACCESS_NONE,
638 NTCREATEX_DISP_OVERWRITE_IF,
639 NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
641 printf("(%s) open of %s failed (%s)\n",
642 __location__, fname, smbcli_errstr(cli1->tree));
647 /* This should delete the file. */
648 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
649 printf("(%s) close failed (%s)\n",
650 __location__, smbcli_errstr(cli1->tree));
655 /* This should fail.. */
656 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
658 printf("(%s) open of %s succeeded should have been deleted on close !\n",
659 __location__, fname);
663 printf("tenth delete on close test succeeded.\n");
665 /* test 11 - does having read only attribute still allow delete on close. */
667 smbcli_setatr(cli1->tree, fname, 0, 0);
668 smbcli_unlink(cli1->tree, fname);
670 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
672 FILE_ATTRIBUTE_READONLY,
673 NTCREATEX_SHARE_ACCESS_NONE,
674 NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
677 printf("(%s) open of %s failed (%s)\n",
678 __location__, fname, smbcli_errstr(cli1->tree));
683 status = smbcli_nt_delete_on_close(cli1->tree, fnum1, True);
685 if (!NT_STATUS_EQUAL(status, NT_STATUS_CANNOT_DELETE)) {
686 printf("(%s) setting delete_on_close should fail with NT_STATUS_CANNOT_DELETE. Got %s instead)\n",
687 __location__, smbcli_errstr(cli1->tree));
692 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
693 printf("(%s) close failed (%s)\n",
694 __location__, smbcli_errstr(cli1->tree));
699 smbcli_setatr(cli1->tree, fname, 0, 0);
700 smbcli_unlink(cli1->tree, fname);
701 printf("eleventh delete on close test succeeded.\n");
703 /* test 12 - does having read only attribute still allow delete on
704 * close at time of open. */
706 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
708 FILE_ATTRIBUTE_READONLY,
709 NTCREATEX_SHARE_ACCESS_DELETE,
710 NTCREATEX_DISP_OVERWRITE_IF,
711 NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
714 printf("(%s) open of %s succeeded. Should fail with "
715 "NT_STATUS_CANNOT_DELETE.\n", __location__, fname);
716 smbcli_close(cli1->tree, fnum1);
720 status = smbcli_nt_error(cli1->tree);
721 if (!NT_STATUS_EQUAL(status, NT_STATUS_CANNOT_DELETE)) {
722 printf("(%s) setting delete_on_close on open should "
723 "fail with NT_STATUS_CANNOT_DELETE. Got %s "
725 __location__, smbcli_errstr(cli1->tree));
731 printf("twelvth delete on close test succeeded.\n");
733 /* Test 13: Does resetting the delete on close flag affect a second
736 smbcli_setatr(cli1->tree, fname, 0, 0);
737 smbcli_unlink(cli1->tree, fname);
739 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
743 FILE_ATTRIBUTE_NORMAL,
744 NTCREATEX_SHARE_ACCESS_READ|
745 NTCREATEX_SHARE_ACCESS_WRITE|
746 NTCREATEX_SHARE_ACCESS_DELETE,
747 NTCREATEX_DISP_OVERWRITE_IF,
751 printf("(%s) open of %s failed (%s)\n",
752 __location__, fname, smbcli_errstr(cli1->tree));
757 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0,
761 FILE_ATTRIBUTE_NORMAL,
762 NTCREATEX_SHARE_ACCESS_READ|
763 NTCREATEX_SHARE_ACCESS_WRITE|
764 NTCREATEX_SHARE_ACCESS_DELETE,
765 NTCREATEX_DISP_OPEN, 0, 0);
768 printf("(%s) open of %s failed (%s)\n",
769 __location__, fname, smbcli_errstr(cli2->tree));
774 if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1->tree, fnum1,
776 printf("(%s) setting delete_on_close on file failed !\n",
782 correct &= check_delete_on_close(cli1, fnum1, fname, True);
783 correct &= check_delete_on_close(cli2, fnum2, fname, True);
785 if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli2->tree, fnum2,
787 printf("(%s) setting delete_on_close on file failed !\n",
793 correct &= check_delete_on_close(cli1, fnum1, fname, False);
794 correct &= check_delete_on_close(cli2, fnum2, fname, False);
796 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
797 printf("(%s) close - 1 failed (%s)\n",
798 __location__, smbcli_errstr(cli1->tree));
803 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
804 printf("(%s) close - 2 failed (%s)\n",
805 __location__, smbcli_errstr(cli2->tree));
810 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
813 printf("(%s) open of %s failed!\n",
814 __location__, fname);
819 smbcli_close(cli1->tree, fnum1);
820 smbcli_unlink(cli1->tree, fname);
822 printf("thirteenth delete on close test succeeded.\n");
824 /* Test 14 -- directory */
826 dnum1 = smbcli_nt_create_full(cli1->tree, dirname, 0,
830 FILE_ATTRIBUTE_DIRECTORY,
831 NTCREATEX_SHARE_ACCESS_READ|
832 NTCREATEX_SHARE_ACCESS_WRITE|
833 NTCREATEX_SHARE_ACCESS_DELETE,
834 NTCREATEX_DISP_CREATE, 0, 0);
836 printf("(%s) open of %s failed: %s!\n",
837 __location__, dirname, smbcli_errstr(cli1->tree));
842 check_delete_on_close(cli1, dnum1, dirname, False);
843 if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1->tree, dnum1, True))) {
844 printf("(%s) setting delete_on_close on file failed !\n",
849 check_delete_on_close(cli1, dnum1, dirname, True);
850 smbcli_close(cli1->tree, dnum1);
852 /* Now it should be gone... */
854 dnum1 = smbcli_nt_create_full(cli1->tree, dirname, 0,
858 FILE_ATTRIBUTE_DIRECTORY,
859 NTCREATEX_SHARE_ACCESS_READ|
860 NTCREATEX_SHARE_ACCESS_WRITE|
861 NTCREATEX_SHARE_ACCESS_DELETE,
862 NTCREATEX_DISP_OPEN, 0, 0);
864 printf("(%s) setting delete_on_close on file succeeded !\n",
870 printf("fourteenth delete on close test succeeded.\n");
872 /* Test 15 -- non-empty directory */
874 dnum1 = smbcli_nt_create_full(cli1->tree, dirname, 0,
878 FILE_ATTRIBUTE_DIRECTORY,
879 NTCREATEX_SHARE_ACCESS_READ|
880 NTCREATEX_SHARE_ACCESS_WRITE|
881 NTCREATEX_SHARE_ACCESS_DELETE,
882 NTCREATEX_DISP_CREATE,
883 NTCREATEX_OPTIONS_DIRECTORY, 0);
885 printf("(%s) open of %s failed: %s!\n",
886 __location__, dirname, smbcli_errstr(cli1->tree));
891 check_delete_on_close(cli1, dnum1, dirname, False);
892 status = smbcli_nt_delete_on_close(cli1->tree, dnum1, True);
896 asprintf(&fullname, "\\%s%s", dirname, fname);
897 fnum1 = smbcli_open(cli1->tree, fullname, O_CREAT|O_RDWR,
900 printf("(%s) smbcli_open succeeded, should have "
902 __location__, smbcli_errstr(cli1->tree));
907 if (!NT_STATUS_EQUAL(smbcli_nt_error(cli1->tree),
908 NT_STATUS_DELETE_PENDING)) {
909 printf("(%s) smbcli_open returned %s, expected "
910 "NT_STATUS_DELETE_PENDING\n",
911 __location__, smbcli_errstr(cli1->tree));
917 status = smbcli_nt_delete_on_close(cli1->tree, dnum1, False);
918 if (!NT_STATUS_IS_OK(status)) {
919 printf("(%s) setting delete_on_close on file failed !\n",
927 asprintf(&fullname, "\\%s%s", dirname, fname);
928 fnum1 = smbcli_open(cli1->tree, fullname, O_CREAT|O_RDWR,
931 printf("(%s) smbcli_open failed: %s\n",
932 __location__, smbcli_errstr(cli1->tree));
936 smbcli_close(cli1->tree, fnum1);
939 status = smbcli_nt_delete_on_close(cli1->tree, dnum1, True);
941 if (!NT_STATUS_EQUAL(status, NT_STATUS_DIRECTORY_NOT_EMPTY)) {
942 printf("(%s) setting delete_on_close returned %s, expected "
943 "NT_STATUS_DIRECTORY_NOT_EMPTY\n", __location__,
944 smbcli_errstr(cli1->tree));
949 smbcli_close(cli1->tree, dnum1);
951 /* Now it should be gone... */
953 printf("fifteenth delete on close test succeeded.\n");
955 /* Test 16: delete on close under rename */
957 smbcli_setatr(cli1->tree, fname, 0, 0);
958 smbcli_unlink(cli1->tree, fname);
959 smbcli_unlink(cli1->tree, fname_new);
961 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
963 FILE_ATTRIBUTE_NORMAL,
964 NTCREATEX_SHARE_ACCESS_READ|
965 NTCREATEX_SHARE_ACCESS_WRITE|
966 NTCREATEX_SHARE_ACCESS_DELETE,
967 NTCREATEX_DISP_OVERWRITE_IF,
971 printf("(%s) open - 1 of %s failed (%s)\n",
972 __location__, fname, smbcli_errstr(cli1->tree));
977 status = smbcli_rename(cli2->tree, fname, fname_new);
979 if (!NT_STATUS_IS_OK(status)) {
980 printf("(%s) renaming failed: %s !\n",
981 __location__, nt_errstr(status));
986 fnum2 = smbcli_nt_create_full(cli2->tree, fname_new, 0,
988 FILE_ATTRIBUTE_NORMAL,
989 NTCREATEX_SHARE_ACCESS_READ|
990 NTCREATEX_SHARE_ACCESS_WRITE|
991 NTCREATEX_SHARE_ACCESS_DELETE,
992 NTCREATEX_DISP_OVERWRITE_IF,
996 printf("(%s) open - 1 of %s failed (%s)\n",
997 __location__, fname_new, smbcli_errstr(cli1->tree));
1002 status = smbcli_nt_delete_on_close(cli2->tree, fnum2, True);
1004 if (!NT_STATUS_IS_OK(status)) {
1005 printf("(%s) setting delete_on_close on file failed !\n",
1011 smbcli_close(cli2->tree, fnum2);
1013 /* The file should be around under the new name, there's a second
1016 if (!check_delete_on_close(cli1, fnum1, fname_new, True)) {
1017 printf("(%s) checking delete on close on file %s failed!\n",
1018 __location__, fname_new);
1023 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0,
1025 FILE_ATTRIBUTE_NORMAL,
1026 NTCREATEX_SHARE_ACCESS_READ|
1027 NTCREATEX_SHARE_ACCESS_WRITE|
1028 NTCREATEX_SHARE_ACCESS_DELETE,
1029 NTCREATEX_DISP_OVERWRITE_IF,
1033 printf("(%s) open - 1 of %s failed (%s)\n",
1034 __location__, fname, smbcli_errstr(cli1->tree));
1039 smbcli_close(cli2->tree, fnum2);
1040 smbcli_close(cli1->tree, fnum1);
1042 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
1044 FILE_ATTRIBUTE_NORMAL,
1045 NTCREATEX_SHARE_ACCESS_READ|
1046 NTCREATEX_SHARE_ACCESS_WRITE|
1047 NTCREATEX_SHARE_ACCESS_DELETE,
1048 NTCREATEX_DISP_OPEN,
1052 printf("(%s) open - 1 of %s failed (%s)\n",
1053 __location__, fname, smbcli_errstr(cli1->tree));
1058 smbcli_close(cli1->tree, fnum1);
1060 fnum1 = smbcli_nt_create_full(cli1->tree, fname_new, 0,
1062 FILE_ATTRIBUTE_NORMAL,
1063 NTCREATEX_SHARE_ACCESS_READ|
1064 NTCREATEX_SHARE_ACCESS_WRITE|
1065 NTCREATEX_SHARE_ACCESS_DELETE,
1066 NTCREATEX_DISP_OPEN,
1070 printf("(%s) smbcli_open succeeded, should have "
1071 "failed\n", __location__);
1072 smbcli_close(cli1->tree, fnum1);
1077 printf("sixteenth delete on close test succeeded.\n");
1079 printf("finished delete test\n");
1082 /* FIXME: This will crash if we aborted before cli2 got
1083 * intialized, because these functions don't handle
1084 * uninitialized connections. */
1086 smbcli_close(cli1->tree, fnum1);
1087 smbcli_close(cli1->tree, fnum2);
1088 smbcli_setatr(cli1->tree, fname, 0, 0);
1089 smbcli_unlink(cli1->tree, fname);
1091 if (!torture_close_connection(cli1)) {
1094 if (!torture_close_connection(cli2)) {